Merge branch 'master' into luaviml'/lua
This commit is contained in:
commit
ab4d13e2fa
|
@ -25,7 +25,7 @@ env:
|
|||
- CMAKE_FLAGS="-DTRAVIS_CI_BUILD=ON
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX
|
||||
-DBUSTED_OUTPUT_TYPE=gtest
|
||||
-DBUSTED_OUTPUT_TYPE=nvim
|
||||
-DDEPS_PREFIX=$DEPS_BUILD_DIR/usr
|
||||
-DMIN_LOG_LEVEL=2"
|
||||
- DEPS_CMAKE_FLAGS="-DDEPS_DOWNLOAD_DIR:PATH=$DEPS_DOWNLOAD_DIR"
|
||||
|
@ -43,11 +43,6 @@ env:
|
|||
# If this file exists, we know that the cache contains compiled
|
||||
# dependencies and we can use it.
|
||||
- CACHE_MARKER="$HOME/.cache/nvim-deps/.travis_cache_marker"
|
||||
# Test success marker. If this file exists, we know that all tests
|
||||
# were successful. Required because we only want to update the cache
|
||||
# if the tests were successful, but don't have this information
|
||||
# available in before_cache (which is run before after_success).
|
||||
- SUCCESS_MARKER="$BUILD_DIR/.tests_successful"
|
||||
# default target name for functional tests
|
||||
- FUNCTIONALTEST=functionaltest
|
||||
- CI_TARGET=tests
|
||||
|
|
|
@ -275,7 +275,6 @@ else()
|
|||
endif()
|
||||
|
||||
add_definitions(-DINCLUDE_GENERATED_DECLARATIONS)
|
||||
add_definitions(-DHAVE_CONFIG_H)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined")
|
||||
|
|
|
@ -7,7 +7,7 @@ build_script:
|
|||
- call ci\build.bat
|
||||
cache:
|
||||
- C:\msys64\var\cache\pacman\pkg -> ci\build.bat
|
||||
- .deps -> third-party/CMakeLists.txt
|
||||
- .deps -> third-party/**
|
||||
artifacts:
|
||||
- path: build/Neovim.zip
|
||||
- path: build/bin/nvim.exe
|
||||
|
|
|
@ -0,0 +1,305 @@
|
|||
local s = require 'say'
|
||||
local pretty = require 'pl.pretty'
|
||||
local term = require 'term'
|
||||
|
||||
local colors
|
||||
|
||||
local isWindows = package.config:sub(1,1) == '\\'
|
||||
|
||||
if isWindows then
|
||||
colors = setmetatable({}, {__index = function() return function(s) return s end end})
|
||||
else
|
||||
colors = require 'term.colors'
|
||||
end
|
||||
|
||||
return function(options)
|
||||
local busted = require 'busted'
|
||||
local handler = require 'busted.outputHandlers.base'()
|
||||
|
||||
local c = {
|
||||
succ = function(s) return colors.bright(colors.green(s)) end,
|
||||
skip = function(s) return colors.bright(colors.yellow(s)) end,
|
||||
fail = function(s) return colors.bright(colors.magenta(s)) end,
|
||||
errr = function(s) return colors.bright(colors.red(s)) end,
|
||||
test = tostring,
|
||||
file = colors.cyan,
|
||||
time = colors.dim,
|
||||
note = colors.yellow,
|
||||
sect = function(s) return colors.green(colors.dim(s)) end,
|
||||
nmbr = colors.bright,
|
||||
}
|
||||
|
||||
local repeatSuiteString = '\nRepeating all tests (run %d of %d) . . .\n\n'
|
||||
local randomizeString = c.note('Note: Randomizing test order with a seed of %d.\n')
|
||||
local globalSetup = c.sect('[----------]') .. ' Global test environment setup.\n'
|
||||
local fileStartString = c.sect('[----------]') .. ' Running tests from ' .. c.file('%s') .. '\n'
|
||||
local runString = c.sect('[ RUN ]') .. ' ' .. c.test('%s') .. ': '
|
||||
local successString = c.succ('OK') .. '\n'
|
||||
local skippedString = c.skip('SKIP') .. '\n'
|
||||
local failureString = c.fail('FAIL') .. '\n'
|
||||
local errorString = c.errr('ERR') .. '\n'
|
||||
local fileEndString = c.sect('[----------]') .. ' '.. c.nmbr('%d') .. ' %s from ' .. c.file('%s') .. ' ' .. c.time('(%.2f ms total)') .. '\n\n'
|
||||
local globalTeardown = c.sect('[----------]') .. ' Global test environment teardown.\n'
|
||||
local suiteEndString = c.sect('[==========]') .. ' ' .. c.nmbr('%d') .. ' %s from ' .. c.nmbr('%d') .. ' test %s ran. ' .. c.time('(%.2f ms total)') .. '\n'
|
||||
local successStatus = c.succ('[ PASSED ]') .. ' ' .. c.nmbr('%d') .. ' %s.\n'
|
||||
local timeString = c.time('%.2f ms')
|
||||
|
||||
local summaryStrings = {
|
||||
skipped = {
|
||||
header = c.skip('[ SKIPPED ]') .. ' ' .. c.nmbr('%d') .. ' %s, listed below:\n',
|
||||
test = c.skip('[ SKIPPED ]') .. ' %s\n',
|
||||
footer = ' ' .. c.nmbr('%d') .. ' SKIPPED %s\n',
|
||||
},
|
||||
|
||||
failure = {
|
||||
header = c.fail('[ FAILED ]') .. ' ' .. c.nmbr('%d') .. ' %s, listed below:\n',
|
||||
test = c.fail('[ FAILED ]') .. ' %s\n',
|
||||
footer = ' ' .. c.nmbr('%d') .. ' FAILED %s\n',
|
||||
},
|
||||
|
||||
error = {
|
||||
header = c.errr('[ ERROR ]') .. ' ' .. c.nmbr('%d') .. ' %s, listed below:\n',
|
||||
test = c.errr('[ ERROR ]') .. ' %s\n',
|
||||
footer = ' ' .. c.nmbr('%d') .. ' %s\n',
|
||||
},
|
||||
}
|
||||
|
||||
c = nil
|
||||
|
||||
local fileCount = 0
|
||||
local fileTestCount = 0
|
||||
local testCount = 0
|
||||
local successCount = 0
|
||||
local skippedCount = 0
|
||||
local failureCount = 0
|
||||
local errorCount = 0
|
||||
|
||||
local pendingDescription = function(pending)
|
||||
local name = pending.name
|
||||
local string = ''
|
||||
|
||||
if type(pending.message) == 'string' then
|
||||
string = string .. pending.message .. '\n'
|
||||
elseif pending.message ~= nil then
|
||||
string = string .. pretty.write(pending.message) .. '\n'
|
||||
end
|
||||
|
||||
return string
|
||||
end
|
||||
|
||||
local failureDescription = function(failure)
|
||||
local string = failure.randomseed and ('Random seed: ' .. failure.randomseed .. '\n') or ''
|
||||
if type(failure.message) == 'string' then
|
||||
string = string .. failure.message
|
||||
elseif failure.message == nil then
|
||||
string = string .. 'Nil error'
|
||||
else
|
||||
string = string .. pretty.write(failure.message)
|
||||
end
|
||||
|
||||
string = string .. '\n'
|
||||
|
||||
if options.verbose and failure.trace and failure.trace.traceback then
|
||||
string = string .. failure.trace.traceback .. '\n'
|
||||
end
|
||||
|
||||
return string
|
||||
end
|
||||
|
||||
local getFileLine = function(element)
|
||||
local fileline = ''
|
||||
if element.trace or element.trace.short_src then
|
||||
fileline = colors.cyan(element.trace.short_src) .. ' @ ' ..
|
||||
colors.cyan(element.trace.currentline) .. ': '
|
||||
end
|
||||
return fileline
|
||||
end
|
||||
|
||||
local getTestList = function(status, count, list, getDescription)
|
||||
local string = ''
|
||||
local header = summaryStrings[status].header
|
||||
if count > 0 and header then
|
||||
local tests = (count == 1 and 'test' or 'tests')
|
||||
local errors = (count == 1 and 'error' or 'errors')
|
||||
string = header:format(count, status == 'error' and errors or tests)
|
||||
|
||||
local testString = summaryStrings[status].test
|
||||
if testString then
|
||||
for _, t in ipairs(list) do
|
||||
local fullname = getFileLine(t.element) .. colors.bright(t.name)
|
||||
string = string .. testString:format(fullname)
|
||||
string = string .. getDescription(t)
|
||||
end
|
||||
end
|
||||
end
|
||||
return string
|
||||
end
|
||||
|
||||
local getSummary = function(status, count)
|
||||
local string = ''
|
||||
local footer = summaryStrings[status].footer
|
||||
if count > 0 and footer then
|
||||
local tests = (count == 1 and 'TEST' or 'TESTS')
|
||||
local errors = (count == 1 and 'ERROR' or 'ERRORS')
|
||||
string = footer:format(count, status == 'error' and errors or tests)
|
||||
end
|
||||
return string
|
||||
end
|
||||
|
||||
local getSummaryString = function()
|
||||
local tests = (successCount == 1 and 'test' or 'tests')
|
||||
local string = successStatus:format(successCount, tests)
|
||||
|
||||
string = string .. getTestList('skipped', skippedCount, handler.pendings, pendingDescription)
|
||||
string = string .. getTestList('failure', failureCount, handler.failures, failureDescription)
|
||||
string = string .. getTestList('error', errorCount, handler.errors, failureDescription)
|
||||
|
||||
string = string .. ((skippedCount + failureCount + errorCount) > 0 and '\n' or '')
|
||||
string = string .. getSummary('skipped', skippedCount)
|
||||
string = string .. getSummary('failure', failureCount)
|
||||
string = string .. getSummary('error', errorCount)
|
||||
|
||||
return string
|
||||
end
|
||||
|
||||
handler.suiteReset = function()
|
||||
fileCount = 0
|
||||
fileTestCount = 0
|
||||
testCount = 0
|
||||
successCount = 0
|
||||
skippedCount = 0
|
||||
failureCount = 0
|
||||
errorCount = 0
|
||||
|
||||
return nil, true
|
||||
end
|
||||
|
||||
handler.suiteStart = function(suite, count, total, randomseed)
|
||||
if total > 1 then
|
||||
io.write(repeatSuiteString:format(count, total))
|
||||
end
|
||||
if randomseed then
|
||||
io.write(randomizeString:format(randomseed))
|
||||
end
|
||||
io.write(globalSetup)
|
||||
io.flush()
|
||||
|
||||
return nil, true
|
||||
end
|
||||
|
||||
local function getElapsedTime(tbl)
|
||||
if tbl.duration then
|
||||
return tbl.duration * 1000
|
||||
else
|
||||
return tonumber('nan')
|
||||
end
|
||||
end
|
||||
|
||||
handler.suiteEnd = function(suite, count, total)
|
||||
local elapsedTime_ms = getElapsedTime(suite)
|
||||
local tests = (testCount == 1 and 'test' or 'tests')
|
||||
local files = (fileCount == 1 and 'file' or 'files')
|
||||
io.write(globalTeardown)
|
||||
io.write(suiteEndString:format(testCount, tests, fileCount, files, elapsedTime_ms))
|
||||
io.write(getSummaryString())
|
||||
io.flush()
|
||||
|
||||
return nil, true
|
||||
end
|
||||
|
||||
handler.fileStart = function(file)
|
||||
fileTestCount = 0
|
||||
io.write(fileStartString:format(file.name))
|
||||
io.flush()
|
||||
return nil, true
|
||||
end
|
||||
|
||||
handler.fileEnd = function(file)
|
||||
local elapsedTime_ms = getElapsedTime(file)
|
||||
local tests = (fileTestCount == 1 and 'test' or 'tests')
|
||||
fileCount = fileCount + 1
|
||||
io.write(fileEndString:format(fileTestCount, tests, file.name, elapsedTime_ms))
|
||||
io.flush()
|
||||
return nil, true
|
||||
end
|
||||
|
||||
handler.testStart = function(element, parent)
|
||||
io.write(runString:format(handler.getFullName(element)))
|
||||
io.flush()
|
||||
|
||||
return nil, true
|
||||
end
|
||||
|
||||
handler.testEnd = function(element, parent, status, debug)
|
||||
local elapsedTime_ms = getElapsedTime(element)
|
||||
local string
|
||||
|
||||
fileTestCount = fileTestCount + 1
|
||||
testCount = testCount + 1
|
||||
if status == 'success' then
|
||||
successCount = successCount + 1
|
||||
string = successString
|
||||
elseif status == 'pending' then
|
||||
skippedCount = skippedCount + 1
|
||||
string = skippedString
|
||||
elseif status == 'failure' then
|
||||
failureCount = failureCount + 1
|
||||
string = nil
|
||||
elseif status == 'error' then
|
||||
errorCount = errorCount + 1
|
||||
string = nil
|
||||
end
|
||||
|
||||
if string ~= nil then
|
||||
if elapsedTime_ms == elapsedTime_ms then
|
||||
string = timeString:format(elapsedTime_ms) .. ' ' .. string
|
||||
end
|
||||
io.write(string)
|
||||
io.flush()
|
||||
end
|
||||
|
||||
return nil, true
|
||||
end
|
||||
|
||||
handler.testFailure = function(element, parent, message, debug)
|
||||
io.write(failureString)
|
||||
io.flush()
|
||||
|
||||
io.write(failureDescription(handler.failures[#handler.failures]))
|
||||
io.flush()
|
||||
return nil, true
|
||||
end
|
||||
|
||||
handler.testError = function(element, parent, message, debug)
|
||||
io.write(errorString)
|
||||
io.flush()
|
||||
|
||||
io.write(failureDescription(handler.errors[#handler.errors]))
|
||||
io.flush()
|
||||
return nil, true
|
||||
end
|
||||
|
||||
handler.error = function(element, parent, message, debug)
|
||||
if element.descriptor ~= 'it' then
|
||||
io.write(failureDescription(handler.errors[#handler.errors]))
|
||||
io.flush()
|
||||
errorCount = errorCount + 1
|
||||
end
|
||||
|
||||
return nil, true
|
||||
end
|
||||
|
||||
busted.subscribe({ 'suite', 'reset' }, handler.suiteReset)
|
||||
busted.subscribe({ 'suite', 'start' }, handler.suiteStart)
|
||||
busted.subscribe({ 'suite', 'end' }, handler.suiteEnd)
|
||||
busted.subscribe({ 'file', 'start' }, handler.fileStart)
|
||||
busted.subscribe({ 'file', 'end' }, handler.fileEnd)
|
||||
busted.subscribe({ 'test', 'start' }, handler.testStart, { predicate = handler.cancelOnPending })
|
||||
busted.subscribe({ 'test', 'end' }, handler.testEnd, { predicate = handler.cancelOnPending })
|
||||
busted.subscribe({ 'failure', 'it' }, handler.testFailure)
|
||||
busted.subscribe({ 'error', 'it' }, handler.testError)
|
||||
busted.subscribe({ 'failure' }, handler.error)
|
||||
busted.subscribe({ 'error' }, handler.error)
|
||||
|
||||
return handler
|
||||
end
|
|
@ -3,12 +3,15 @@
|
|||
set -e
|
||||
set -o pipefail
|
||||
|
||||
CI_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "${CI_DIR}/common/suite.sh"
|
||||
|
||||
# Don't cache pip's log and selfcheck.
|
||||
rm -rf "${HOME}/.cache/pip/log"
|
||||
rm -f "${HOME}/.cache/pip/selfcheck.json"
|
||||
|
||||
# Update the third-party dependency cache only if the build was successful.
|
||||
if [[ -f "${SUCCESS_MARKER}" ]]; then
|
||||
if ended_successfully; then
|
||||
rm -rf "${HOME}/.cache/nvim-deps"
|
||||
mv "${DEPS_BUILD_DIR}" "${HOME}/.cache/nvim-deps"
|
||||
touch "${CACHE_MARKER}"
|
||||
|
|
|
@ -38,7 +38,7 @@ cd ..
|
|||
:: Build Neovim
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DBUSTED_OUTPUT_TYPE=gtest -DGPERF_PRG="C:\msys64\usr\bin\gperf.exe" .. || goto :error
|
||||
cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DBUSTED_OUTPUT_TYPE=nvim -DGPERF_PRG="C:\msys64\usr\bin\gperf.exe" .. || goto :error
|
||||
mingw32-make VERBOSE=1 || goto :error
|
||||
bin\nvim --version || goto :error
|
||||
|
||||
|
|
|
@ -2,11 +2,18 @@
|
|||
NL="$(printf '\nE')"
|
||||
NL="${NL%E}"
|
||||
|
||||
FAILED=0
|
||||
|
||||
FAIL_SUMMARY=""
|
||||
|
||||
# Test success marker. If END_MARKER file exists, we know that all tests
|
||||
# finished. If FAIL_SUMMARY_FILE exists we know that some tests failed, this
|
||||
# file will contain information about failed tests. Build is considered
|
||||
# successful if tests ended without any of them failing.
|
||||
END_MARKER="$BUILD_DIR/.tests_finished"
|
||||
FAIL_SUMMARY_FILE="$BUILD_DIR/.test_errors"
|
||||
|
||||
enter_suite() {
|
||||
FAILED=0
|
||||
rm -f "${END_MARKER}"
|
||||
local suite_name="$1"
|
||||
export NVIM_TEST_CURRENT_SUITE="${NVIM_TEST_CURRENT_SUITE}/$suite_name"
|
||||
}
|
||||
|
@ -19,17 +26,16 @@ exit_suite() {
|
|||
export NVIM_TEST_CURRENT_SUITE="${NVIM_TEST_CURRENT_SUITE%/*}"
|
||||
if test "x$1" != "x--continue" ; then
|
||||
exit $FAILED
|
||||
else
|
||||
local saved_failed=$FAILED
|
||||
FAILED=0
|
||||
return $saved_failed
|
||||
fi
|
||||
}
|
||||
|
||||
fail() {
|
||||
local allow_failure=
|
||||
if test "x$1" = "x--allow-failure" ; then
|
||||
shift
|
||||
allow_failure=A
|
||||
fi
|
||||
local test_name="$1"
|
||||
local fail_char="$allow_failure$2"
|
||||
local fail_char="$2"
|
||||
local message="$3"
|
||||
|
||||
: ${fail_char:=F}
|
||||
|
@ -37,10 +43,9 @@ fail() {
|
|||
|
||||
local full_msg="$fail_char $NVIM_TEST_CURRENT_SUITE|$test_name :: $message"
|
||||
FAIL_SUMMARY="${FAIL_SUMMARY}${NL}${full_msg}"
|
||||
echo "${full_msg}" >> "${FAIL_SUMMARY_FILE}"
|
||||
echo "Failed: $full_msg"
|
||||
if test "x$allow_failure" = "x" ; then
|
||||
FAILED=1
|
||||
fi
|
||||
FAILED=1
|
||||
}
|
||||
|
||||
run_test() {
|
||||
|
@ -55,6 +60,12 @@ run_test() {
|
|||
}
|
||||
|
||||
run_test_wd() {
|
||||
local hang_ok=
|
||||
if test "x$1" = "x--allow-hang" ; then
|
||||
hang_ok=1
|
||||
shift
|
||||
fi
|
||||
|
||||
local timeout="$1"
|
||||
test $# -gt 0 && shift
|
||||
|
||||
|
@ -77,14 +88,13 @@ run_test_wd() {
|
|||
while test $restarts -gt 0 ; do
|
||||
: > "${status_file}"
|
||||
(
|
||||
FAILED=0
|
||||
if ! (
|
||||
set -o pipefail
|
||||
eval "$cmd" 2>&1 | tee -a "$output_file"
|
||||
) ; then
|
||||
fail "${test_name}" "$@"
|
||||
set -o pipefail
|
||||
ret=0
|
||||
if ! eval "$cmd" 2>&1 | tee -a "$output_file" ; then
|
||||
ret=1
|
||||
fi
|
||||
echo "$FAILED" > "$status_file"
|
||||
echo "$ret" > "$status_file"
|
||||
exit $ret
|
||||
) &
|
||||
local pid=$!
|
||||
while test "$(stat -c "%s" "$status_file")" -eq 0 ; do
|
||||
|
@ -101,7 +111,9 @@ run_test_wd() {
|
|||
# status file not updated, assuming hang
|
||||
kill -KILL $pid
|
||||
if test $restarts -eq 0 ; then
|
||||
fail "${test_name}" E "Test hang up"
|
||||
if test "x$hang_ok" = "x" ; then
|
||||
fail "${test_name}" E "Test hang up"
|
||||
fi
|
||||
else
|
||||
echo "Test ${test_name} hang up, restarting"
|
||||
eval "$restart_cmd"
|
||||
|
@ -116,6 +128,20 @@ run_test_wd() {
|
|||
done
|
||||
}
|
||||
|
||||
succeeded() {
|
||||
return $FAILED
|
||||
ended_successfully() {
|
||||
if [[ -f "${FAIL_SUMMARY_FILE}" ]]; then
|
||||
echo 'Test failed, complete summary:'
|
||||
cat "${FAIL_SUMMARY_FILE}"
|
||||
return 1
|
||||
fi
|
||||
if ! [[ -f "${END_MARKER}" ]] ; then
|
||||
echo 'ended_successfully called before end marker was touched'
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
end_tests() {
|
||||
touch "${END_MARKER}"
|
||||
ended_successfully
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
source "${CI_DIR}/common/build.sh"
|
||||
source "${CI_DIR}/common/suite.sh"
|
||||
|
||||
print_core() {
|
||||
local app="$1"
|
||||
|
@ -40,10 +41,9 @@ check_core_dumps() {
|
|||
print_core "$app" "$core"
|
||||
fi
|
||||
done
|
||||
if test "$app" = quiet ; then
|
||||
return 0
|
||||
if test "$app" != quiet ; then
|
||||
fail 'cores' E 'Core dumps found'
|
||||
fi
|
||||
exit 1
|
||||
}
|
||||
|
||||
check_logs() {
|
||||
|
@ -62,8 +62,7 @@ check_logs() {
|
|||
err=1
|
||||
done
|
||||
if [[ -n "${err}" ]]; then
|
||||
echo "Runtime errors detected."
|
||||
exit 1
|
||||
fail 'logs' E 'Runtime errors detected.'
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -75,50 +74,53 @@ asan_check() {
|
|||
check_logs "${1}" "*san.*"
|
||||
}
|
||||
|
||||
run_unittests() {
|
||||
run_unittests() {(
|
||||
enter_suite unittests
|
||||
ulimit -c unlimited
|
||||
if ! build_make unittest ; then
|
||||
check_core_dumps "$(which luajit)"
|
||||
exit 1
|
||||
fail 'unittests' F 'Unit tests failed'
|
||||
fi
|
||||
check_core_dumps "$(which luajit)"
|
||||
}
|
||||
exit_suite
|
||||
)}
|
||||
|
||||
run_functionaltests() {
|
||||
run_functionaltests() {(
|
||||
enter_suite functionaltests
|
||||
ulimit -c unlimited
|
||||
if ! build_make ${FUNCTIONALTEST}; then
|
||||
asan_check "${LOG_DIR}"
|
||||
valgrind_check "${LOG_DIR}"
|
||||
check_core_dumps
|
||||
exit 1
|
||||
fail 'functionaltests' F 'Functional tests failed'
|
||||
fi
|
||||
asan_check "${LOG_DIR}"
|
||||
valgrind_check "${LOG_DIR}"
|
||||
check_core_dumps
|
||||
}
|
||||
exit_suite
|
||||
)}
|
||||
|
||||
run_oldtests() {
|
||||
run_oldtests() {(
|
||||
enter_suite oldtests
|
||||
ulimit -c unlimited
|
||||
if ! make -C "${TRAVIS_BUILD_DIR}/src/nvim/testdir"; then
|
||||
reset
|
||||
asan_check "${LOG_DIR}"
|
||||
valgrind_check "${LOG_DIR}"
|
||||
check_core_dumps
|
||||
exit 1
|
||||
fail 'oldtests' F 'Legacy tests failed'
|
||||
fi
|
||||
asan_check "${LOG_DIR}"
|
||||
valgrind_check "${LOG_DIR}"
|
||||
check_core_dumps
|
||||
}
|
||||
exit_suite
|
||||
)}
|
||||
|
||||
install_nvim() {
|
||||
build_make install
|
||||
install_nvim() {(
|
||||
enter_suite 'install_nvim'
|
||||
if ! build_make install ; then
|
||||
fail 'install' E 'make install failed'
|
||||
exit_suite
|
||||
fi
|
||||
|
||||
"${INSTALL_PREFIX}/bin/nvim" --version
|
||||
"${INSTALL_PREFIX}/bin/nvim" -u NONE -e -c ':help' -c ':qall' || {
|
||||
echo "Running ':help' in the installed nvim failed."
|
||||
echo "Maybe the helptags have not been generated properly."
|
||||
exit 1
|
||||
fail 'help' F 'Failed running :help'
|
||||
}
|
||||
|
||||
local genvimsynf=syntax/vim/generated.vim
|
||||
|
@ -127,24 +129,22 @@ install_nvim() {
|
|||
cd runtime ; git ls-files | grep -e '.vim$' -e '.ps$' -e '.dict$' -e '.py$' -e '.tutor$'
|
||||
) ; do
|
||||
if ! test -e "${INSTALL_PREFIX}/share/nvim/runtime/$file" ; then
|
||||
echo "It appears that $file is not installed."
|
||||
exit 1
|
||||
fail 'runtime-install' F "It appears that $file is not installed."
|
||||
fi
|
||||
done
|
||||
|
||||
# Check that generated syntax file has function names, #5060.
|
||||
local gpat='syn keyword vimFuncName .*eval'
|
||||
if ! grep -q "$gpat" "${INSTALL_PREFIX}/share/nvim/runtime/$genvimsynf"; then
|
||||
echo "It appears that $genvimsynf does not contain $gpat."
|
||||
exit 1
|
||||
fail 'funcnames' F "It appears that $genvimsynf does not contain $gpat."
|
||||
fi
|
||||
|
||||
for file in $(
|
||||
cd runtime ; git ls-files | grep -e '.awk$' -e '.sh$' -e '.bat$'
|
||||
) ; do
|
||||
if ! test -x "${INSTALL_PREFIX}/share/nvim/runtime/$file" ; then
|
||||
echo "It appears that $file is not installed or is not executable."
|
||||
exit 1
|
||||
fail 'not-exe' F "It appears that $file is not installed or is not executable."
|
||||
fi
|
||||
done
|
||||
}
|
||||
exit_suite
|
||||
)}
|
||||
|
|
|
@ -20,9 +20,10 @@ csi_clean() {
|
|||
run_test 'top_make clint-full' clint
|
||||
run_test 'top_make testlint' testlint
|
||||
CLICOLOR_FORCE=1 run_test_wd \
|
||||
5s \
|
||||
--allow-hang \
|
||||
10s \
|
||||
'top_make check-single-includes' \
|
||||
'csi_clean' \
|
||||
single-includes
|
||||
|
||||
exit_suite
|
||||
end_tests
|
||||
|
|
|
@ -27,8 +27,4 @@ run_test run_oldtests
|
|||
|
||||
run_test install_nvim
|
||||
|
||||
if succeeded ; then
|
||||
touch "${SUCCESS_MARKER}"
|
||||
fi
|
||||
|
||||
exit_suite
|
||||
end_tests
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
file(GLOB_RECURSE JSON_FILES *.json)
|
||||
file(COPY ${JSON_FILES} DESTINATION "${TARGET}")
|
|
@ -2292,7 +2292,7 @@ tabpagebuflist([{arg}]) List list of buffer numbers in tab page
|
|||
tabpagenr([{arg}]) Number number of current or last tab page
|
||||
tabpagewinnr({tabarg}[, {arg}])
|
||||
Number number of current window in tab page
|
||||
taglist({expr}) List list of tags matching {expr}
|
||||
taglist({expr}[, {filename}]) List list of tags matching {expr}
|
||||
tagfiles() List tags files used
|
||||
tan({expr}) Float tangent of {expr}
|
||||
tanh({expr}) Float hyperbolic tangent of {expr}
|
||||
|
@ -4945,8 +4945,8 @@ json_decode({expr}) *json_decode()*
|
|||
|
||||
json_encode({expr}) *json_encode()*
|
||||
Convert {expr} into a JSON string. Accepts
|
||||
|msgpack-special-dict| as the input. Will not convert |Funcref|s,
|
||||
mappings with non-string keys (can be created as
|
||||
|msgpack-special-dict| as the input. Will not convert
|
||||
|Funcref|s, mappings with non-string keys (can be created as
|
||||
|msgpack-special-dict|), values with self-referencing
|
||||
containers, strings which contain non-UTF-8 characters,
|
||||
pseudo-UTF-8 strings which contain codepoints reserved for
|
||||
|
@ -7431,8 +7431,13 @@ tagfiles() Returns a |List| with the file names used to search for tags
|
|||
for the current buffer. This is the 'tags' option expanded.
|
||||
|
||||
|
||||
taglist({expr}) *taglist()*
|
||||
taglist({expr}[, {filename}]) *taglist()*
|
||||
Returns a list of tags matching the regular expression {expr}.
|
||||
|
||||
If {filename} is passed it is used to prioritize the results
|
||||
in the same way that |:tselect| does. See |tag-priority|.
|
||||
{filename} should be the full path of the file.
|
||||
|
||||
Each list item is a dictionary with at least the following
|
||||
entries:
|
||||
name Name of the tag.
|
||||
|
|
|
@ -5151,8 +5151,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||
saved. When not included, the value of 'history' is used.
|
||||
*shada-c*
|
||||
c Dummy option, kept for compatibility reasons. Has no actual
|
||||
effect. Current encoding state is described in
|
||||
|shada-encoding|.
|
||||
effect: ShaDa always uses UTF-8 and 'encoding' value is fixed
|
||||
to UTF-8 as well.
|
||||
*shada-f*
|
||||
f Whether file marks need to be stored. If zero, file marks ('0
|
||||
to '9, 'A to 'Z) are not stored. When not present or when
|
||||
|
|
|
@ -1097,23 +1097,6 @@ SHADA FILE NAME *shada-file-name*
|
|||
default and the name given with 'shada' or "-i" (unless it's NONE).
|
||||
|
||||
|
||||
CHARACTER ENCODING *shada-encoding*
|
||||
|
||||
The text in the ShaDa file is UTF-8-encoded. Normally you will always work
|
||||
with the same 'encoding' value, and this works just fine. However, if you
|
||||
read the ShaDa file with value for 'encoding' different from utf-8 and
|
||||
'encoding' used when writing ShaDa file, some of the text (non-ASCII
|
||||
characters) may be invalid as Neovim always attempts to convert the text in
|
||||
the ShaDa file from the UTF-8 to the current 'encoding' value. Filenames are
|
||||
never converted, affected elements are:
|
||||
|
||||
- history strings;
|
||||
- variable values;
|
||||
- register values;
|
||||
- last used search and substitute patterns;
|
||||
- last used substitute replacement string.
|
||||
|
||||
|
||||
MANUALLY READING AND WRITING *shada-read-write*
|
||||
|
||||
Two commands can be used to read and write the ShaDa file manually. This
|
||||
|
@ -1221,8 +1204,11 @@ exactly four MessagePack objects:
|
|||
3. Third goes the length of the fourth entry. Unsigned integer as well, used
|
||||
for fast skipping without parsing.
|
||||
4. Fourth is actual entry data. All currently used ShaDa entries use
|
||||
containers to hold data: either map or array. Exact format depends on the
|
||||
entry type:
|
||||
containers to hold data: either map or array. All string values in those
|
||||
containers are either binary (applies to filenames) or UTF-8, yet parser
|
||||
needs to expect that invalid bytes may be present in a UTF-8 string.
|
||||
|
||||
Exact format depends on the entry type:
|
||||
|
||||
Entry type (name) Entry data ~
|
||||
1 (Header) Map containing data that describes the generator
|
||||
|
|
|
@ -42,7 +42,10 @@ set(LINT_SUPPRESS_URL "${LINT_SUPPRESS_URL_BASE}/errors.json")
|
|||
set(LINT_PRG ${PROJECT_SOURCE_DIR}/src/clint.py)
|
||||
set(DOWNLOAD_SCRIPT ${PROJECT_SOURCE_DIR}/cmake/Download.cmake)
|
||||
set(LINT_SUPPRESSES_ROOT ${PROJECT_BINARY_DIR}/errors)
|
||||
set(LINT_SUPPRESSES_URL "https://raw.githubusercontent.com/neovim/doc/gh-pages/reports/clint/errors.tar.gz")
|
||||
set(LINT_SUPPRESSES_URL "${LINT_SUPPRESS_URL_BASE}/errors.tar.gz")
|
||||
set(LINT_SUPPRESSES_ARCHIVE ${LINT_SUPPRESSES_ROOT}/errors.tar.gz)
|
||||
set(LINT_SUPPRESSES_TOUCH_FILE "${TOUCHES_DIR}/unpacked-clint-errors-archive")
|
||||
set(LINT_SUPPRESSES_INSTALL_SCRIPT "${PROJECT_SOURCE_DIR}/cmake/InstallClintErrors.cmake")
|
||||
|
||||
file(GLOB UNICODE_FILES ${UNICODE_DIR}/*.txt)
|
||||
file(GLOB API_HEADERS api/*.h)
|
||||
|
@ -55,6 +58,8 @@ include_directories(${GENERATED_INCLUDES_DIR})
|
|||
file(MAKE_DIRECTORY ${TOUCHES_DIR})
|
||||
file(MAKE_DIRECTORY ${GENERATED_DIR})
|
||||
file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR})
|
||||
file(MAKE_DIRECTORY ${LINT_SUPPRESSES_ROOT})
|
||||
file(MAKE_DIRECTORY ${LINT_SUPPRESSES_ROOT}/src)
|
||||
|
||||
file(GLOB NVIM_SOURCES *.c)
|
||||
file(GLOB NVIM_HEADERS *.h)
|
||||
|
@ -495,26 +500,10 @@ function(get_test_target prefix sfile relative_path_var target_var)
|
|||
endfunction()
|
||||
|
||||
set(NO_SINGLE_CHECK_HEADERS
|
||||
cursor_shape.h
|
||||
digraph.h
|
||||
ex_cmds.h
|
||||
ex_getln.h
|
||||
file_search.h
|
||||
fold.h
|
||||
getchar.h
|
||||
hardcopy.h
|
||||
if_cscope.h
|
||||
if_cscope_defs.h
|
||||
mark.h
|
||||
mbyte.h
|
||||
memfile_defs.h
|
||||
memline.h
|
||||
memline_defs.h
|
||||
menu.h
|
||||
misc2.h
|
||||
move.h
|
||||
msgpack_rpc/server.h
|
||||
ops.h
|
||||
option.h
|
||||
os/shell.h
|
||||
os_unix.h
|
||||
|
@ -573,6 +562,21 @@ function(add_download output url allow_failure)
|
|||
)
|
||||
endfunction()
|
||||
|
||||
add_download(${LINT_SUPPRESSES_ARCHIVE} ${LINT_SUPPRESSES_URL} off)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${LINT_SUPPRESSES_TOUCH_FILE}
|
||||
WORKING_DIRECTORY ${LINT_SUPPRESSES_ROOT}/src
|
||||
COMMAND ${CMAKE_COMMAND} -E tar xfz ${LINT_SUPPRESSES_ARCHIVE}
|
||||
COMMAND
|
||||
${CMAKE_COMMAND}
|
||||
-DTARGET=${LINT_SUPPRESSES_ROOT}
|
||||
-P ${LINT_SUPPRESSES_INSTALL_SCRIPT}
|
||||
COMMAND ${CMAKE_COMMAND} -E touch ${LINT_SUPPRESSES_TOUCH_FILE}
|
||||
DEPENDS
|
||||
${LINT_SUPPRESSES_ARCHIVE} ${LINT_SUPPRESSES_INSTALL_SCRIPT}
|
||||
)
|
||||
|
||||
add_download(${LINT_SUPPRESS_FILE} ${LINT_SUPPRESS_URL} off)
|
||||
|
||||
set(LINT_NVIM_REL_SOURCES)
|
||||
|
@ -581,14 +585,13 @@ foreach(sfile ${LINT_NVIM_SOURCES})
|
|||
set(suppress_file ${LINT_SUPPRESSES_ROOT}/${suffix}.json)
|
||||
set(suppress_url "${LINT_SUPPRESS_URL_BASE}/${suffix}.json")
|
||||
set(rsfile src/nvim/${r})
|
||||
add_download(${suppress_file} ${suppress_url} on)
|
||||
set(touch_file "${TOUCHES_DIR}/ran-clint-${suffix}")
|
||||
add_custom_command(
|
||||
OUTPUT ${touch_file}
|
||||
COMMAND ${LINT_PRG} --suppress-errors=${suppress_file} ${rsfile}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E touch ${touch_file}
|
||||
DEPENDS ${LINT_PRG} ${sfile} ${suppress_file}
|
||||
DEPENDS ${LINT_PRG} ${sfile} ${LINT_SUPPRESSES_TOUCH_FILE}
|
||||
)
|
||||
list(APPEND LINT_TARGETS ${touch_file})
|
||||
list(APPEND LINT_NVIM_REL_SOURCES ${rsfile})
|
||||
|
|
|
@ -212,8 +212,8 @@ int buf_init_chartab(buf_T *buf, int global)
|
|||
// work properly when 'encoding' is "latin1" and the locale is
|
||||
// "C".
|
||||
if (!do_isalpha
|
||||
|| vim_islower(c)
|
||||
|| vim_isupper(c)
|
||||
|| mb_islower(c)
|
||||
|| mb_isupper(c)
|
||||
|| (p_altkeymap && (F_isalpha(c) || F_isdigit(c)))) {
|
||||
if (i == 0) {
|
||||
// (re)set ID flag
|
||||
|
@ -417,11 +417,11 @@ char_u* str_foldcase(char_u *str, int orglen, char_u *buf, int buflen)
|
|||
while (STR_CHAR(i) != NUL) {
|
||||
int c = utf_ptr2char(STR_PTR(i));
|
||||
int olen = utf_ptr2len(STR_PTR(i));
|
||||
int lc = utf_tolower(c);
|
||||
int lc = mb_tolower(c);
|
||||
|
||||
// Only replace the character when it is not an invalid
|
||||
// sequence (ASCII character or more than one byte) and
|
||||
// utf_tolower() doesn't return the original character.
|
||||
// mb_tolower() doesn't return the original character.
|
||||
if (((c < 0x80) || (olen > 1)) && (c != lc)) {
|
||||
int nlen = utf_char2len(lc);
|
||||
|
||||
|
@ -1506,67 +1506,6 @@ char_u* skiptohex(char_u *q)
|
|||
return p;
|
||||
}
|
||||
|
||||
// Vim's own character class functions. These exist because many library
|
||||
// islower()/toupper() etc. do not work properly: they crash when used with
|
||||
// invalid values or can't handle latin1 when the locale is C.
|
||||
// Speed is most important here.
|
||||
|
||||
/// Check that the character is lower-case
|
||||
///
|
||||
/// @param c character to check
|
||||
bool vim_islower(int c)
|
||||
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
if (c <= '@') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (c >= 0x80) {
|
||||
return utf_islower(c);
|
||||
}
|
||||
return islower(c);
|
||||
}
|
||||
|
||||
/// Check that the character is upper-case
|
||||
///
|
||||
/// @param c character to check
|
||||
bool vim_isupper(int c)
|
||||
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
if (c <= '@') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (c >= 0x80) {
|
||||
return utf_isupper(c);
|
||||
}
|
||||
return isupper(c);
|
||||
}
|
||||
|
||||
int vim_toupper(int c)
|
||||
{
|
||||
if (c <= '@') {
|
||||
return c;
|
||||
}
|
||||
|
||||
if (c >= 0x80) {
|
||||
return utf_toupper(c);
|
||||
}
|
||||
return TOUPPER_LOC(c);
|
||||
}
|
||||
|
||||
int vim_tolower(int c)
|
||||
{
|
||||
if (c <= '@') {
|
||||
return c;
|
||||
}
|
||||
|
||||
if (c >= 0x80) {
|
||||
return utf_tolower(c);
|
||||
}
|
||||
return TOLOWER_LOC(c);
|
||||
}
|
||||
|
||||
/// Skip over text until ' ' or '\t' or NUL
|
||||
///
|
||||
/// @param[in] p Text to skip over.
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#ifndef NVIM_CURSOR_SHAPE_H
|
||||
#define NVIM_CURSOR_SHAPE_H
|
||||
|
||||
#include "nvim/types.h"
|
||||
#include "nvim/api/private/defs.h"
|
||||
|
||||
/// struct to store values from 'guicursor' and 'mouseshape'
|
||||
/// Indexes in shape_table[]
|
||||
typedef enum {
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#ifndef NVIM_DIGRAPH_H
|
||||
#define NVIM_DIGRAPH_H
|
||||
|
||||
#include "nvim/types.h"
|
||||
#include "nvim/ex_cmds_defs.h"
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "digraph.h.generated.h"
|
||||
#endif
|
||||
|
|
|
@ -2037,12 +2037,12 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int
|
|||
} else {
|
||||
c = *(p++);
|
||||
}
|
||||
if (vim_islower(c)) {
|
||||
if (mb_islower(c)) {
|
||||
has_lower = true;
|
||||
if (vim_isupper(wca[i])) {
|
||||
if (mb_isupper(wca[i])) {
|
||||
// Rule 1 is satisfied.
|
||||
for (i = actual_compl_length; i < actual_len; i++) {
|
||||
wca[i] = vim_tolower(wca[i]);
|
||||
wca[i] = mb_tolower(wca[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2062,14 +2062,14 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int
|
|||
} else {
|
||||
c = *(p++);
|
||||
}
|
||||
if (was_letter && vim_isupper(c) && vim_islower(wca[i])) {
|
||||
if (was_letter && mb_isupper(c) && mb_islower(wca[i])) {
|
||||
// Rule 2 is satisfied.
|
||||
for (i = actual_compl_length; i < actual_len; i++) {
|
||||
wca[i] = vim_toupper(wca[i]);
|
||||
wca[i] = mb_toupper(wca[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
was_letter = vim_islower(c) || vim_isupper(c);
|
||||
was_letter = mb_islower(c) || mb_isupper(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2082,10 +2082,10 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int
|
|||
} else {
|
||||
c = *(p++);
|
||||
}
|
||||
if (vim_islower(c)) {
|
||||
wca[i] = vim_tolower(wca[i]);
|
||||
} else if (vim_isupper(c)) {
|
||||
wca[i] = vim_toupper(wca[i]);
|
||||
if (mb_islower(c)) {
|
||||
wca[i] = mb_tolower(wca[i]);
|
||||
} else if (mb_isupper(c)) {
|
||||
wca[i] = mb_toupper(wca[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2302,9 +2302,10 @@ static void ins_compl_longest_match(compl_T *match)
|
|||
c1 = *p;
|
||||
c2 = *s;
|
||||
}
|
||||
if (match->cp_icase ? (vim_tolower(c1) != vim_tolower(c2))
|
||||
: (c1 != c2))
|
||||
if (match->cp_icase ? (mb_tolower(c1) != mb_tolower(c2))
|
||||
: (c1 != c2)) {
|
||||
break;
|
||||
}
|
||||
if (has_mbyte) {
|
||||
mb_ptr_adv(p);
|
||||
mb_ptr_adv(s);
|
||||
|
|
|
@ -8729,10 +8729,10 @@ static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||
}
|
||||
fold_count = foldedCount(curwin, lnum, &foldinfo);
|
||||
if (fold_count > 0) {
|
||||
text = get_foldtext(curwin, lnum, lnum + fold_count - 1,
|
||||
&foldinfo, buf);
|
||||
if (text == buf)
|
||||
text = get_foldtext(curwin, lnum, lnum + fold_count - 1, &foldinfo, buf);
|
||||
if (text == buf) {
|
||||
text = vim_strsave(text);
|
||||
}
|
||||
rettv->vval.v_string = text;
|
||||
}
|
||||
}
|
||||
|
@ -16451,7 +16451,12 @@ static void f_taglist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||
return;
|
||||
}
|
||||
|
||||
(void)get_tags(tv_list_alloc_ret(rettv), (char_u *)tag_pattern);
|
||||
const char *fname = NULL;
|
||||
if (argvars[1].v_type != VAR_UNKNOWN) {
|
||||
fname = tv_get_string(&argvars[1]);
|
||||
}
|
||||
(void)get_tags(tv_list_alloc_ret(rettv), (char_u *)tag_pattern,
|
||||
(char_u *)fname);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -16801,30 +16806,9 @@ void timer_teardown(void)
|
|||
*/
|
||||
static void f_tolower(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
{
|
||||
char_u *p = (char_u *)xstrdup(tv_get_string(&argvars[0]));
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = p;
|
||||
|
||||
while (*p != NUL) {
|
||||
int l;
|
||||
|
||||
if (enc_utf8) {
|
||||
int c, lc;
|
||||
|
||||
c = utf_ptr2char(p);
|
||||
lc = utf_tolower(c);
|
||||
l = utf_ptr2len(p);
|
||||
/* TODO: reallocate string when byte count changes. */
|
||||
if (utf_char2len(lc) == l)
|
||||
utf_char2bytes(lc, p);
|
||||
p += l;
|
||||
} else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
|
||||
p += l; /* skip multi-byte character */
|
||||
else {
|
||||
*p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */
|
||||
++p;
|
||||
}
|
||||
}
|
||||
rettv->vval.v_string = (char_u *)strcase_save(tv_get_string(&argvars[0]),
|
||||
false);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -16833,7 +16817,8 @@ static void f_tolower(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||
static void f_toupper(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
{
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = (char_u *)strup_save(tv_get_string(&argvars[0]));
|
||||
rettv->vval.v_string = (char_u *)strcase_save(tv_get_string(&argvars[0]),
|
||||
true);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -301,7 +301,7 @@ return {
|
|||
tabpagenr={args={0, 1}},
|
||||
tabpagewinnr={args={1, 2}},
|
||||
tagfiles={},
|
||||
taglist={args=1},
|
||||
taglist={args={1, 2}},
|
||||
tan={args=1, func="float_op_wrapper", data="&tan"},
|
||||
tanh={args=1, func="float_op_wrapper", data="&tanh"},
|
||||
tempname={},
|
||||
|
|
|
@ -295,8 +295,6 @@ typval_T decode_string(const char *const s, const size_t len,
|
|||
|
||||
/// Parse JSON double-quoted string
|
||||
///
|
||||
/// @param[in] conv Defines conversion necessary to convert UTF-8 string to
|
||||
/// &encoding.
|
||||
/// @param[in] buf Buffer being converted.
|
||||
/// @param[in] buf_len Length of the buffer.
|
||||
/// @param[in,out] pp Pointer to the start of the string. Must point to '"'.
|
||||
|
@ -313,8 +311,7 @@ typval_T decode_string(const char *const s, const size_t len,
|
|||
/// value when decoder is restarted, otherwise unused.
|
||||
///
|
||||
/// @return OK in case of success, FAIL in case of error.
|
||||
static inline int parse_json_string(vimconv_T *const conv,
|
||||
const char *const buf, const size_t buf_len,
|
||||
static inline int parse_json_string(const char *const buf, const size_t buf_len,
|
||||
const char **const pp,
|
||||
ValuesStack *const stack,
|
||||
ContainerStack *const container_stack,
|
||||
|
@ -489,20 +486,6 @@ static inline int parse_json_string(vimconv_T *const conv,
|
|||
}
|
||||
PUT_FST_IN_PAIR(fst_in_pair, str_end);
|
||||
#undef PUT_FST_IN_PAIR
|
||||
if (conv->vc_type != CONV_NONE) {
|
||||
size_t str_len = (size_t) (str_end - str);
|
||||
char *const new_str = (char *) string_convert(conv, (char_u *) str,
|
||||
&str_len);
|
||||
if (new_str == NULL) {
|
||||
emsgf(_("E474: Failed to convert string \"%.*s\" from UTF-8"),
|
||||
(int) str_len, str);
|
||||
xfree(str);
|
||||
goto parse_json_string_fail;
|
||||
}
|
||||
xfree(str);
|
||||
str = new_str;
|
||||
str_end = new_str + str_len;
|
||||
}
|
||||
*str_end = NUL;
|
||||
typval_T obj = decode_string(
|
||||
str, (size_t)(str_end - str), hasnul ? kTrue : kFalse, false, true);
|
||||
|
@ -683,9 +666,6 @@ int json_decode_string(const char *const buf, const size_t buf_len,
|
|||
EMSG(_("E474: Attempt to decode a blank string"));
|
||||
return FAIL;
|
||||
}
|
||||
vimconv_T conv = { .vc_type = CONV_NONE };
|
||||
convert_setup(&conv, (char_u *) "utf-8", p_enc);
|
||||
conv.vc_fail = true;
|
||||
int ret = OK;
|
||||
ValuesStack stack = KV_INITIAL_VALUE;
|
||||
ContainerStack container_stack = KV_INITIAL_VALUE;
|
||||
|
@ -831,7 +811,7 @@ json_decode_string_cycle_start:
|
|||
break;
|
||||
}
|
||||
case '"': {
|
||||
if (parse_json_string(&conv, buf, buf_len, &p, &stack, &container_stack,
|
||||
if (parse_json_string(buf, buf_len, &p, &stack, &container_stack,
|
||||
&next_map_special, &didcomma, &didcolon)
|
||||
== FAIL) {
|
||||
// Error message was already given
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include <math.h>
|
||||
|
||||
#include "nvim/eval/encode.h"
|
||||
#include "nvim/buffer_defs.h" // vimconv_T
|
||||
#include "nvim/buffer_defs.h"
|
||||
#include "nvim/eval.h"
|
||||
#include "nvim/eval/typval.h"
|
||||
#include "nvim/garray.h"
|
||||
|
@ -29,10 +29,6 @@
|
|||
#define utf_ptr2char(b) utf_ptr2char((char_u *)b)
|
||||
#define utf_ptr2len(b) ((size_t)utf_ptr2len((char_u *)b))
|
||||
#define utf_char2len(b) ((size_t)utf_char2len(b))
|
||||
#define string_convert(a, b, c) \
|
||||
((char *)string_convert((vimconv_T *)a, (char_u *)b, c))
|
||||
#define convert_setup(vcp, from, to) \
|
||||
(convert_setup(vcp, (char_u *)from, (char_u *)to))
|
||||
|
||||
const char *const encode_special_var_names[] = {
|
||||
[kSpecialVarNull] = "null",
|
||||
|
@ -537,17 +533,6 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
/// Last used p_enc value
|
||||
///
|
||||
/// Generic pointer: it is not used as a string, only pointer comparisons are
|
||||
/// performed. Must not be freed.
|
||||
static const void *last_p_enc = NULL;
|
||||
|
||||
/// Conversion setup for converting from last_p_enc to UTF-8
|
||||
static vimconv_T p_enc_conv = {
|
||||
.vc_type = CONV_NONE,
|
||||
};
|
||||
|
||||
/// Escape sequences used in JSON
|
||||
static const char escapes[][3] = {
|
||||
[BS] = "\\b",
|
||||
|
@ -579,33 +564,15 @@ static inline int convert_to_json_string(garray_T *const gap,
|
|||
} else {
|
||||
size_t utf_len = len;
|
||||
char *tofree = NULL;
|
||||
if (last_p_enc != (const void *) p_enc) {
|
||||
p_enc_conv.vc_type = CONV_NONE;
|
||||
convert_setup(&p_enc_conv, p_enc, "utf-8");
|
||||
p_enc_conv.vc_fail = true;
|
||||
last_p_enc = p_enc;
|
||||
}
|
||||
if (p_enc_conv.vc_type != CONV_NONE) {
|
||||
tofree = string_convert(&p_enc_conv, buf, &utf_len);
|
||||
if (tofree == NULL) {
|
||||
emsgf(_("E474: Failed to convert string \"%.*s\" to UTF-8"),
|
||||
utf_len, utf_buf);
|
||||
return FAIL;
|
||||
}
|
||||
utf_buf = tofree;
|
||||
}
|
||||
size_t str_len = 0;
|
||||
// Encode character as \u0000 if
|
||||
// 1. It is an ASCII control character (0x0 .. 0x1F, 0x7F).
|
||||
// 2. &encoding is not UTF-8 and code point is above 0x7F.
|
||||
// 3. &encoding is UTF-8 and code point is not printable according to
|
||||
// utf_printable().
|
||||
// This is done to make it possible to :echo values when &encoding is not
|
||||
// UTF-8.
|
||||
#define ENCODE_RAW(p_enc_conv, ch) \
|
||||
(ch >= 0x20 && (p_enc_conv.vc_type == CONV_NONE \
|
||||
? utf_printable(ch) \
|
||||
: ch < 0x7F))
|
||||
// Encode character as \uNNNN if
|
||||
// 1. It is an ASCII control character (0x0 .. 0x1F; 0x7F not
|
||||
// utf_printable and thus not checked specially).
|
||||
// 2. Code point is not printable according to utf_printable().
|
||||
// This is done to make resulting values displayable on screen also not from
|
||||
// Neovim.
|
||||
#define ENCODE_RAW(ch) \
|
||||
(ch >= 0x20 && utf_printable(ch))
|
||||
for (size_t i = 0; i < utf_len;) {
|
||||
const int ch = utf_ptr2char(utf_buf + i);
|
||||
const size_t shift = (ch == 0? 1: utf_ptr2len(utf_buf + i));
|
||||
|
@ -636,7 +603,7 @@ static inline int convert_to_json_string(garray_T *const gap,
|
|||
utf_len - (i - shift), utf_buf + i - shift);
|
||||
xfree(tofree);
|
||||
return FAIL;
|
||||
} else if (ENCODE_RAW(p_enc_conv, ch)) {
|
||||
} else if (ENCODE_RAW(ch)) {
|
||||
str_len += shift;
|
||||
} else {
|
||||
str_len += ((sizeof("\\u1234") - 1)
|
||||
|
@ -666,7 +633,7 @@ static inline int convert_to_json_string(garray_T *const gap,
|
|||
break;
|
||||
}
|
||||
default: {
|
||||
if (ENCODE_RAW(p_enc_conv, ch)) {
|
||||
if (ENCODE_RAW(ch)) {
|
||||
ga_concat_len(gap, utf_buf + i, shift);
|
||||
} else if (ch < SURROGATE_FIRST_CHAR) {
|
||||
ga_concat_len(gap, ((const char[]) {
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "nvim/os/time.h"
|
||||
#include "nvim/pos.h"
|
||||
#include "nvim/eval/typval.h"
|
||||
#include "nvim/buffer_defs.h"
|
||||
#include "nvim/ex_cmds_defs.h"
|
||||
|
||||
// flags for do_ecmd()
|
||||
#define ECMD_HIDE 0x01 // don't free the current buffer
|
||||
|
|
|
@ -1231,7 +1231,7 @@ static int command_line_handle_key(CommandLineState *s)
|
|||
// command line has no uppercase characters, convert
|
||||
// the character to lowercase
|
||||
if (p_ic && p_scs && !pat_has_uppercase(ccline.cmdbuff)) {
|
||||
s->c = vim_tolower(s->c);
|
||||
s->c = mb_tolower(s->c);
|
||||
}
|
||||
|
||||
if (s->c != NUL) {
|
||||
|
@ -3018,7 +3018,7 @@ ExpandOne (
|
|||
|| xp->xp_context == EXPAND_FILES
|
||||
|| xp->xp_context == EXPAND_SHELLCMD
|
||||
|| xp->xp_context == EXPAND_BUFFERS)) {
|
||||
if (vim_tolower(c0) != vim_tolower(ci)) {
|
||||
if (mb_tolower(c0) != mb_tolower(ci)) {
|
||||
break;
|
||||
}
|
||||
} else if (c0 != ci) {
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include "nvim/eval/typval.h"
|
||||
#include "nvim/ex_cmds.h"
|
||||
#include "nvim/ex_cmds_defs.h"
|
||||
#include "nvim/os/time.h"
|
||||
#include "nvim/regexp_defs.h"
|
||||
|
||||
/* Values for nextwild() and ExpandOne(). See ExpandOne() for meaning. */
|
||||
#define WILD_FREE 1
|
||||
|
|
|
@ -1057,7 +1057,7 @@ static bool ff_wc_equal(char_u *s1, char_u *s2)
|
|||
c1 = PTR2CHAR(s1 + i);
|
||||
c2 = PTR2CHAR(s2 + j);
|
||||
|
||||
if ((p_fic ? vim_tolower(c1) != vim_tolower(c2) : c1 != c2)
|
||||
if ((p_fic ? mb_tolower(c1) != mb_tolower(c2) : c1 != c2)
|
||||
&& (prev1 != '*' || prev2 != '*')) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
#ifndef NVIM_FILE_SEARCH_H
|
||||
#define NVIM_FILE_SEARCH_H
|
||||
|
||||
#include <stdlib.h> // for size_t
|
||||
|
||||
#include "nvim/types.h" // for char_u
|
||||
#include "nvim/globals.h" // for CdScope
|
||||
|
||||
/* Flags for find_file_*() functions. */
|
||||
#define FINDFILE_FILE 0 /* only files */
|
||||
#define FINDFILE_DIR 1 /* only directories */
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
#ifndef NVIM_FOLD_H
|
||||
#define NVIM_FOLD_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "nvim/pos.h"
|
||||
#include "nvim/garray.h"
|
||||
#include "nvim/types.h"
|
||||
#include "nvim/buffer_defs.h"
|
||||
|
||||
/*
|
||||
* Info used to pass info about a fold from the fold-detection code to the
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
#define NVIM_HARDCOPY_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h> // for size_t
|
||||
|
||||
#include "nvim/types.h" // for char_u
|
||||
#include "nvim/ex_cmds_defs.h" // for exarg_T
|
||||
|
||||
/*
|
||||
* Structure to hold printing color and font attributes.
|
||||
|
|
|
@ -10,9 +10,7 @@
|
|||
// USE_ICONV, or to put the USE_ICONV definition in config.h.in directly. As
|
||||
// it stands, globals.h needs to be included alongside iconv.h.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "auto/config.h"
|
||||
#endif
|
||||
#include "auto/config.h"
|
||||
|
||||
// Use iconv() when it's available, either by linking to the library at
|
||||
// compile time or by loading it at runtime.
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#ifndef NVIM_IF_CSCOPE_H
|
||||
#define NVIM_IF_CSCOPE_H
|
||||
|
||||
#include "nvim/types.h" // for char_u and expand_T
|
||||
#include "nvim/ex_cmds_defs.h" // for exarg_T
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "if_cscope.h.generated.h"
|
||||
#endif
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
* toupper() and tolower() that use the current locale.
|
||||
* Careful: Only call TOUPPER_LOC() and TOLOWER_LOC() with a character in the
|
||||
* range 0 - 255. toupper()/tolower() on some systems can't handle others.
|
||||
* Note: It is often better to use vim_tolower() and vim_toupper(), because many
|
||||
* Note: It is often better to use mb_tolower() and mb_toupper(), because many
|
||||
* toupper() and tolower() implementations only work for ASCII.
|
||||
*/
|
||||
#define TOUPPER_LOC toupper
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "nvim/memory.h"
|
||||
#include "nvim/pos.h"
|
||||
#include "nvim/os/time.h"
|
||||
#include "nvim/ex_cmds_defs.h" // for exarg_T
|
||||
|
||||
/// Set fmark using given value
|
||||
#define SET_FMARK(fmarkp_, mark_, fnum_) \
|
||||
|
|
|
@ -1174,11 +1174,14 @@ int utf_fold(int a)
|
|||
return utf_convert(a, foldCase, ARRAY_SIZE(foldCase));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the upper-case equivalent of "a", which is a UCS-4 character. Use
|
||||
* simple case folding.
|
||||
*/
|
||||
int utf_toupper(int a)
|
||||
// Vim's own character class functions. These exist because many library
|
||||
// islower()/toupper() etc. do not work properly: they crash when used with
|
||||
// invalid values or can't handle latin1 when the locale is C.
|
||||
// Speed is most important here.
|
||||
|
||||
/// Return the upper-case equivalent of "a", which is a UCS-4 character. Use
|
||||
/// simple case folding.
|
||||
int mb_toupper(int a)
|
||||
{
|
||||
/* If 'casemap' contains "keepascii" use ASCII style toupper(). */
|
||||
if (a < 128 && (cmp_flags & CMP_KEEPASCII))
|
||||
|
@ -1198,17 +1201,15 @@ int utf_toupper(int a)
|
|||
return utf_convert(a, toUpper, ARRAY_SIZE(toUpper));
|
||||
}
|
||||
|
||||
bool utf_islower(int a)
|
||||
bool mb_islower(int a)
|
||||
{
|
||||
/* German sharp s is lower case but has no upper case equivalent. */
|
||||
return (utf_toupper(a) != a) || a == 0xdf;
|
||||
// German sharp s is lower case but has no upper case equivalent.
|
||||
return (mb_toupper(a) != a) || a == 0xdf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the lower-case equivalent of "a", which is a UCS-4 character. Use
|
||||
* simple case folding.
|
||||
*/
|
||||
int utf_tolower(int a)
|
||||
/// Return the lower-case equivalent of "a", which is a UCS-4 character. Use
|
||||
/// simple case folding.
|
||||
int mb_tolower(int a)
|
||||
{
|
||||
/* If 'casemap' contains "keepascii" use ASCII style tolower(). */
|
||||
if (a < 128 && (cmp_flags & CMP_KEEPASCII))
|
||||
|
@ -1228,9 +1229,9 @@ int utf_tolower(int a)
|
|||
return utf_convert(a, toLower, ARRAY_SIZE(toLower));
|
||||
}
|
||||
|
||||
bool utf_isupper(int a)
|
||||
bool mb_isupper(int a)
|
||||
{
|
||||
return utf_tolower(a) != a;
|
||||
return mb_tolower(a) != a;
|
||||
}
|
||||
|
||||
static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "nvim/iconv.h"
|
||||
#include "nvim/func_attr.h"
|
||||
#include "nvim/os/os_defs.h" // For WCHAR, indirect
|
||||
#include "nvim/types.h" // for char_u
|
||||
|
||||
/*
|
||||
* Return byte length of character that starts with byte "b".
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nvim/types.h"
|
||||
#include "nvim/pos.h"
|
||||
|
||||
/// A block number.
|
||||
///
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#define NVIM_MEMLINE_H
|
||||
|
||||
#include "nvim/types.h"
|
||||
#include "nvim/pos.h" // for pos_T, linenr_T, colnr_T
|
||||
#include "nvim/buffer_defs.h" // for buf_T
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "memline.h.generated.h"
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
#ifndef NVIM_MENU_H
|
||||
#define NVIM_MENU_H
|
||||
|
||||
#include <stdbool.h> // for bool
|
||||
|
||||
#include "nvim/types.h" // for char_u and expand_T
|
||||
#include "nvim/ex_cmds_defs.h" // for exarg_T
|
||||
|
||||
/* Indices into vimmenu_T->strings[] and vimmenu_T->noremap[] for each mode */
|
||||
#define MENU_INDEX_INVALID -1
|
||||
#define MENU_INDEX_NORMAL 0
|
||||
|
|
|
@ -2730,8 +2730,8 @@ do_dialog (
|
|||
break;
|
||||
}
|
||||
|
||||
/* Make the character lowercase, as chars in "hotkeys" are. */
|
||||
c = vim_tolower(c);
|
||||
// Make the character lowercase, as chars in "hotkeys" are.
|
||||
c = mb_tolower(c);
|
||||
retval = 1;
|
||||
for (i = 0; hotkeys[i]; ++i) {
|
||||
if (has_mbyte) {
|
||||
|
@ -2777,7 +2777,7 @@ copy_char (
|
|||
|
||||
if (has_mbyte) {
|
||||
if (lowercase) {
|
||||
c = vim_tolower((*mb_ptr2char)(from));
|
||||
c = mb_tolower((*mb_ptr2char)(from));
|
||||
return (*mb_char2bytes)(c, to);
|
||||
} else {
|
||||
len = (*mb_ptr2len)(from);
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#define NVIM_MOVE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "nvim/buffer_defs.h"
|
||||
#include "nvim/pos.h"
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "move.h.generated.h"
|
||||
|
|
|
@ -1956,16 +1956,18 @@ int swapchar(int op_type, pos_T *pos)
|
|||
if (enc_dbcs != 0 && c >= 0x100) /* No lower/uppercase letter */
|
||||
return FALSE;
|
||||
nc = c;
|
||||
if (vim_islower(c)) {
|
||||
if (op_type == OP_ROT13)
|
||||
if (mb_islower(c)) {
|
||||
if (op_type == OP_ROT13) {
|
||||
nc = ROT13(c, 'a');
|
||||
else if (op_type != OP_LOWER)
|
||||
nc = vim_toupper(c);
|
||||
} else if (vim_isupper(c)) {
|
||||
if (op_type == OP_ROT13)
|
||||
} else if (op_type != OP_LOWER) {
|
||||
nc = mb_toupper(c);
|
||||
}
|
||||
} else if (mb_isupper(c)) {
|
||||
if (op_type == OP_ROT13) {
|
||||
nc = ROT13(c, 'A');
|
||||
else if (op_type != OP_UPPER)
|
||||
nc = vim_tolower(c);
|
||||
} else if (op_type != OP_UPPER) {
|
||||
nc = mb_tolower(c);
|
||||
}
|
||||
}
|
||||
if (nc != c) {
|
||||
if (enc_utf8 && (c >= 0x80 || nc >= 0x80)) {
|
||||
|
@ -3327,10 +3329,11 @@ void ex_display(exarg_T *eap)
|
|||
|
||||
get_clipboard(name, &yb, true);
|
||||
|
||||
if (name == vim_tolower(redir_reg)
|
||||
|| (redir_reg == '"' && yb == y_previous))
|
||||
continue; /* do not list register being written to, the
|
||||
* pointer can be freed */
|
||||
if (name == mb_tolower(redir_reg)
|
||||
|| (redir_reg == '"' && yb == y_previous)) {
|
||||
continue; // do not list register being written to, the
|
||||
// pointer can be freed
|
||||
}
|
||||
|
||||
if (yb->y_array != NULL) {
|
||||
msg_putchar('\n');
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "nvim/types.h"
|
||||
#include "nvim/eval/typval.h"
|
||||
#include "nvim/os/time.h"
|
||||
#include "nvim/normal.h" // for MotionType and oparg_T
|
||||
#include "nvim/ex_cmds_defs.h" // for exarg_T
|
||||
|
||||
typedef int (*Indenter)(void);
|
||||
|
||||
|
|
|
@ -1853,7 +1853,7 @@ int pathcmp(const char *p, const char *q, int maxlen)
|
|||
break;
|
||||
}
|
||||
|
||||
if ((p_fic ? vim_toupper(c1) != vim_toupper(c2) : c1 != c2)
|
||||
if ((p_fic ? mb_toupper(c1) != mb_toupper(c2) : c1 != c2)
|
||||
#ifdef BACKSLASH_IN_FILENAME
|
||||
/* consider '/' and '\\' to be equal */
|
||||
&& !((c1 == '/' && c2 == '\\')
|
||||
|
@ -1864,8 +1864,8 @@ int pathcmp(const char *p, const char *q, int maxlen)
|
|||
return -1;
|
||||
if (vim_ispathsep(c2))
|
||||
return 1;
|
||||
return p_fic ? vim_toupper(c1) - vim_toupper(c2)
|
||||
: c1 - c2; /* no match */
|
||||
return p_fic ? mb_toupper(c1) - mb_toupper(c2)
|
||||
: c1 - c2; // no match
|
||||
}
|
||||
|
||||
i += MB_PTR2LEN((char_u *)p + i);
|
||||
|
|
|
@ -2350,7 +2350,7 @@ collection:
|
|||
break;
|
||||
case CLASS_LOWER:
|
||||
for (cu = 1; cu <= 255; cu++) {
|
||||
if (vim_islower(cu) && cu != 170 && cu != 186) {
|
||||
if (mb_islower(cu) && cu != 170 && cu != 186) {
|
||||
regmbc(cu);
|
||||
}
|
||||
}
|
||||
|
@ -2376,7 +2376,7 @@ collection:
|
|||
break;
|
||||
case CLASS_UPPER:
|
||||
for (cu = 1; cu <= 255; cu++) {
|
||||
if (vim_isupper(cu)) {
|
||||
if (mb_isupper(cu)) {
|
||||
regmbc(cu);
|
||||
}
|
||||
}
|
||||
|
@ -3474,7 +3474,7 @@ static long bt_regexec_both(char_u *line,
|
|||
|| (ireg_ic
|
||||
&& (((enc_utf8 && utf_fold(prog->regstart) == utf_fold(c)))
|
||||
|| (c < 255 && prog->regstart < 255
|
||||
&& vim_tolower(prog->regstart) == vim_tolower(c))))) {
|
||||
&& mb_tolower(prog->regstart) == mb_tolower(c))))) {
|
||||
retval = regtry(prog, col);
|
||||
} else {
|
||||
retval = 0;
|
||||
|
@ -4155,7 +4155,7 @@ regmatch (
|
|||
if (*opnd != *reginput
|
||||
&& (!ireg_ic
|
||||
|| (!enc_utf8
|
||||
&& vim_tolower(*opnd) != vim_tolower(*reginput)))) {
|
||||
&& mb_tolower(*opnd) != mb_tolower(*reginput)))) {
|
||||
status = RA_NOMATCH;
|
||||
} else if (*opnd == NUL) {
|
||||
// match empty string always works; happens when "~" is
|
||||
|
@ -4573,12 +4573,14 @@ regmatch (
|
|||
if (OP(next) == EXACTLY) {
|
||||
rst.nextb = *OPERAND(next);
|
||||
if (ireg_ic) {
|
||||
if (vim_isupper(rst.nextb))
|
||||
rst.nextb_ic = vim_tolower(rst.nextb);
|
||||
else
|
||||
rst.nextb_ic = vim_toupper(rst.nextb);
|
||||
} else
|
||||
if (mb_isupper(rst.nextb)) {
|
||||
rst.nextb_ic = mb_tolower(rst.nextb);
|
||||
} else {
|
||||
rst.nextb_ic = mb_toupper(rst.nextb);
|
||||
}
|
||||
} else {
|
||||
rst.nextb_ic = rst.nextb;
|
||||
}
|
||||
} else {
|
||||
rst.nextb = NUL;
|
||||
rst.nextb_ic = NUL;
|
||||
|
@ -5339,8 +5341,8 @@ do_class:
|
|||
* would have been used for it. It does handle single-byte
|
||||
* characters, such as latin1. */
|
||||
if (ireg_ic) {
|
||||
cu = vim_toupper(*opnd);
|
||||
cl = vim_tolower(*opnd);
|
||||
cu = mb_toupper(*opnd);
|
||||
cl = mb_tolower(*opnd);
|
||||
while (count < maxcount && (*scan == cu || *scan == cl)) {
|
||||
count++;
|
||||
scan++;
|
||||
|
@ -6312,14 +6314,15 @@ static char_u *cstrchr(char_u *s, int c)
|
|||
/* tolower() and toupper() can be slow, comparing twice should be a lot
|
||||
* faster (esp. when using MS Visual C++!).
|
||||
* For UTF-8 need to use folded case. */
|
||||
if (enc_utf8 && c > 0x80)
|
||||
if (c > 0x80) {
|
||||
cc = utf_fold(c);
|
||||
else if (vim_isupper(c))
|
||||
cc = vim_tolower(c);
|
||||
else if (vim_islower(c))
|
||||
cc = vim_toupper(c);
|
||||
else
|
||||
} else if (mb_isupper(c)) {
|
||||
cc = mb_tolower(c);
|
||||
} else if (mb_islower(c)) {
|
||||
cc = mb_toupper(c);
|
||||
} else {
|
||||
return vim_strchr(s, c);
|
||||
}
|
||||
|
||||
if (has_mbyte) {
|
||||
for (p = s; *p != NUL; p += (*mb_ptr2len)(p)) {
|
||||
|
@ -6348,28 +6351,28 @@ static char_u *cstrchr(char_u *s, int c)
|
|||
|
||||
static fptr_T do_upper(int *d, int c)
|
||||
{
|
||||
*d = vim_toupper(c);
|
||||
*d = mb_toupper(c);
|
||||
|
||||
return (fptr_T)NULL;
|
||||
}
|
||||
|
||||
static fptr_T do_Upper(int *d, int c)
|
||||
{
|
||||
*d = vim_toupper(c);
|
||||
*d = mb_toupper(c);
|
||||
|
||||
return (fptr_T)do_Upper;
|
||||
}
|
||||
|
||||
static fptr_T do_lower(int *d, int c)
|
||||
{
|
||||
*d = vim_tolower(c);
|
||||
*d = mb_tolower(c);
|
||||
|
||||
return (fptr_T)NULL;
|
||||
}
|
||||
|
||||
static fptr_T do_Lower(int *d, int c)
|
||||
{
|
||||
*d = vim_tolower(c);
|
||||
*d = mb_tolower(c);
|
||||
|
||||
return (fptr_T)do_Lower;
|
||||
}
|
||||
|
|
|
@ -4373,7 +4373,7 @@ static int check_char_class(int class, int c)
|
|||
return OK;
|
||||
break;
|
||||
case NFA_CLASS_LOWER:
|
||||
if (vim_islower(c) && c != 170 && c != 186) {
|
||||
if (mb_islower(c) && c != 170 && c != 186) {
|
||||
return OK;
|
||||
}
|
||||
break;
|
||||
|
@ -4391,8 +4391,9 @@ static int check_char_class(int class, int c)
|
|||
return OK;
|
||||
break;
|
||||
case NFA_CLASS_UPPER:
|
||||
if (vim_isupper(c))
|
||||
if (mb_isupper(c)) {
|
||||
return OK;
|
||||
}
|
||||
break;
|
||||
case NFA_CLASS_XDIGIT:
|
||||
if (ascii_isxdigit(c))
|
||||
|
@ -4892,7 +4893,7 @@ static long find_match_text(colnr_T startcol, int regstart, char_u *match_text)
|
|||
int c2_len = PTR2LEN(s2);
|
||||
int c2 = PTR2CHAR(s2);
|
||||
|
||||
if ((c1 != c2 && (!ireg_ic || vim_tolower(c1) != vim_tolower(c2)))
|
||||
if ((c1 != c2 && (!ireg_ic || mb_tolower(c1) != mb_tolower(c2)))
|
||||
|| c1_len != c2_len) {
|
||||
match = false;
|
||||
break;
|
||||
|
@ -5585,22 +5586,24 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
|
|||
break;
|
||||
}
|
||||
if (ireg_ic) {
|
||||
int curc_low = vim_tolower(curc);
|
||||
int done = FALSE;
|
||||
int curc_low = mb_tolower(curc);
|
||||
int done = false;
|
||||
|
||||
for (; c1 <= c2; ++c1)
|
||||
if (vim_tolower(c1) == curc_low) {
|
||||
for (; c1 <= c2; c1++) {
|
||||
if (mb_tolower(c1) == curc_low) {
|
||||
result = result_if_matched;
|
||||
done = TRUE;
|
||||
break;
|
||||
}
|
||||
if (done)
|
||||
}
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (state->c < 0 ? check_char_class(state->c, curc)
|
||||
: (curc == state->c
|
||||
|| (ireg_ic && vim_tolower(curc)
|
||||
== vim_tolower(state->c)))) {
|
||||
|| (ireg_ic && mb_tolower(curc)
|
||||
== mb_tolower(state->c)))) {
|
||||
result = result_if_matched;
|
||||
break;
|
||||
}
|
||||
|
@ -6003,8 +6006,9 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
|
|||
#endif
|
||||
result = (c == curc);
|
||||
|
||||
if (!result && ireg_ic)
|
||||
result = vim_tolower(c) == vim_tolower(curc);
|
||||
if (!result && ireg_ic) {
|
||||
result = mb_tolower(c) == mb_tolower(curc);
|
||||
}
|
||||
|
||||
// If ireg_icombine is not set only skip over the character
|
||||
// itself. When it is set skip over composing characters.
|
||||
|
@ -6152,8 +6156,8 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
|
|||
// Checking if the required start character matches is
|
||||
// cheaper than adding a state that won't match.
|
||||
c = PTR2CHAR(reginput + clen);
|
||||
if (c != prog->regstart && (!ireg_ic || vim_tolower(c)
|
||||
!= vim_tolower(prog->regstart))) {
|
||||
if (c != prog->regstart && (!ireg_ic || mb_tolower(c)
|
||||
!= mb_tolower(prog->regstart))) {
|
||||
#ifdef REGEXP_DEBUG
|
||||
fprintf(log_fd,
|
||||
" Skipping start state, regstart does not match\n");
|
||||
|
|
|
@ -335,23 +335,26 @@ int pat_has_uppercase(char_u *pat)
|
|||
while (*p != NUL) {
|
||||
int l;
|
||||
|
||||
if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) {
|
||||
if (enc_utf8 && utf_isupper(utf_ptr2char(p)))
|
||||
return TRUE;
|
||||
if ((l = mb_ptr2len(p)) > 1) {
|
||||
if (mb_isupper(utf_ptr2char(p))) {
|
||||
return true;
|
||||
}
|
||||
p += l;
|
||||
} else if (*p == '\\') {
|
||||
if (p[1] == '_' && p[2] != NUL) /* skip "\_X" */
|
||||
if (p[1] == '_' && p[2] != NUL) { // skip "\_X"
|
||||
p += 3;
|
||||
else if (p[1] == '%' && p[2] != NUL) /* skip "\%X" */
|
||||
} else if (p[1] == '%' && p[2] != NUL) { // skip "\%X"
|
||||
p += 3;
|
||||
else if (p[1] != NUL) /* skip "\X" */
|
||||
} else if (p[1] != NUL) { // skip "\X"
|
||||
p += 2;
|
||||
else
|
||||
} else {
|
||||
p += 1;
|
||||
} else if (vim_isupper(*p))
|
||||
return TRUE;
|
||||
else
|
||||
++p;
|
||||
}
|
||||
} else if (mb_isupper(*p)) {
|
||||
return true;
|
||||
} else {
|
||||
p++;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
|
230
src/nvim/shada.c
230
src/nvim/shada.c
|
@ -73,15 +73,10 @@ KHASH_SET_INIT_STR(strset)
|
|||
(vim_rename((char_u *)a, (char_u *)b))
|
||||
#define mb_strnicmp(a, b, c) \
|
||||
(mb_strnicmp((char_u *)a, (char_u *)b, c))
|
||||
#define has_non_ascii(a) (has_non_ascii((char_u *)a))
|
||||
#define string_convert(a, b, c) \
|
||||
((char *)string_convert((vimconv_T *)a, (char_u *)b, c))
|
||||
#define path_shorten_fname_if_possible(b) \
|
||||
((char *)path_shorten_fname_if_possible((char_u *)b))
|
||||
#define buflist_new(ffname, sfname, ...) \
|
||||
(buflist_new((char_u *)ffname, (char_u *)sfname, __VA_ARGS__))
|
||||
#define convert_setup(vcp, from, to) \
|
||||
(convert_setup(vcp, (char_u *)from, (char_u *)to))
|
||||
#define os_isdir(f) (os_isdir((char_u *) f))
|
||||
#define regtilde(s, m) ((char *) regtilde((char_u *) s, m))
|
||||
#define path_tail_with_sep(f) ((char *) path_tail_with_sep((char_u *)f))
|
||||
|
@ -413,8 +408,6 @@ typedef struct sd_read_def {
|
|||
const char *error; ///< Error message in case of error.
|
||||
uintmax_t fpos; ///< Current position (amount of bytes read since
|
||||
///< reader structure initialization). May overflow.
|
||||
vimconv_T sd_conv; ///< Structure used for converting encodings of some
|
||||
///< items.
|
||||
} ShaDaReadDef;
|
||||
|
||||
struct sd_write_def;
|
||||
|
@ -435,8 +428,6 @@ typedef struct sd_write_def {
|
|||
ShaDaWriteCloser close; ///< Close function.
|
||||
void *cookie; ///< Data describing object written to.
|
||||
const char *error; ///< Error message in case of error.
|
||||
vimconv_T sd_conv; ///< Structure used for converting encodings of some
|
||||
///< items.
|
||||
} ShaDaWriteDef;
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
|
@ -803,7 +794,7 @@ static int open_shada_file_for_reading(const char *const fname,
|
|||
return error;
|
||||
}
|
||||
|
||||
convert_setup(&sd_reader->sd_conv, "utf-8", p_enc);
|
||||
assert(STRCMP(p_enc, "utf-8") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1899,127 +1890,24 @@ shada_pack_entry_error:
|
|||
}
|
||||
#undef PACK_STRING
|
||||
|
||||
/// Write single ShaDa entry, converting it if needed
|
||||
/// Write single ShaDa entry and free it afterwards
|
||||
///
|
||||
/// @warning Frees entry after packing.
|
||||
/// Will not free if entry could not be freed.
|
||||
///
|
||||
/// @param[in] packer Packer used to write entry.
|
||||
/// @param[in] sd_conv Conversion definitions.
|
||||
/// @param[in] entry Entry written. If entry.can_free_entry is false then
|
||||
/// it assumes that entry was not converted, otherwise it
|
||||
/// is assumed that entry was already converted.
|
||||
/// @param[in] entry Entry written.
|
||||
/// @param[in] max_kbyte Maximum size of an item in KiB. Zero means no
|
||||
/// restrictions.
|
||||
static ShaDaWriteResult shada_pack_encoded_entry(msgpack_packer *const packer,
|
||||
const vimconv_T *const sd_conv,
|
||||
PossiblyFreedShadaEntry entry,
|
||||
const size_t max_kbyte)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
static inline ShaDaWriteResult shada_pack_pfreed_entry(
|
||||
msgpack_packer *const packer, PossiblyFreedShadaEntry entry,
|
||||
const size_t max_kbyte)
|
||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
|
||||
{
|
||||
ShaDaWriteResult ret = kSDWriteSuccessfull;
|
||||
ret = shada_pack_entry(packer, entry.data, max_kbyte);
|
||||
if (entry.can_free_entry) {
|
||||
ret = shada_pack_entry(packer, entry.data, max_kbyte);
|
||||
shada_free_shada_entry(&entry.data);
|
||||
return ret;
|
||||
}
|
||||
#define RUN_WITH_CONVERTED_STRING(cstr, code) \
|
||||
do { \
|
||||
bool did_convert = false; \
|
||||
if (sd_conv->vc_type != CONV_NONE && has_non_ascii((cstr))) { \
|
||||
char *const converted_string = string_convert(sd_conv, (cstr), NULL); \
|
||||
if (converted_string != NULL) { \
|
||||
(cstr) = converted_string; \
|
||||
did_convert = true; \
|
||||
} \
|
||||
} \
|
||||
code \
|
||||
if (did_convert) { \
|
||||
xfree((cstr)); \
|
||||
} \
|
||||
} while (0)
|
||||
switch (entry.data.type) {
|
||||
case kSDItemUnknown:
|
||||
case kSDItemMissing: {
|
||||
assert(false);
|
||||
}
|
||||
case kSDItemSearchPattern: {
|
||||
RUN_WITH_CONVERTED_STRING(entry.data.data.search_pattern.pat, {
|
||||
ret = shada_pack_entry(packer, entry.data, max_kbyte);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case kSDItemHistoryEntry: {
|
||||
RUN_WITH_CONVERTED_STRING(entry.data.data.history_item.string, {
|
||||
ret = shada_pack_entry(packer, entry.data, max_kbyte);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case kSDItemSubString: {
|
||||
RUN_WITH_CONVERTED_STRING(entry.data.data.sub_string.sub, {
|
||||
ret = shada_pack_entry(packer, entry.data, max_kbyte);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case kSDItemVariable: {
|
||||
if (sd_conv->vc_type != CONV_NONE) {
|
||||
typval_T tgttv;
|
||||
var_item_copy(sd_conv, &entry.data.data.global_var.value, &tgttv,
|
||||
true, 0);
|
||||
tv_clear(&entry.data.data.global_var.value);
|
||||
entry.data.data.global_var.value = tgttv;
|
||||
}
|
||||
ret = shada_pack_entry(packer, entry.data, max_kbyte);
|
||||
break;
|
||||
}
|
||||
case kSDItemRegister: {
|
||||
bool did_convert = false;
|
||||
if (sd_conv->vc_type != CONV_NONE) {
|
||||
size_t first_non_ascii = 0;
|
||||
for (size_t i = 0; i < entry.data.data.reg.contents_size; i++) {
|
||||
if (has_non_ascii(entry.data.data.reg.contents[i])) {
|
||||
first_non_ascii = i;
|
||||
did_convert = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (did_convert) {
|
||||
entry.data.data.reg.contents =
|
||||
xmemdup(entry.data.data.reg.contents,
|
||||
(entry.data.data.reg.contents_size
|
||||
* sizeof(entry.data.data.reg.contents[0])));
|
||||
for (size_t i = 0; i < entry.data.data.reg.contents_size; i++) {
|
||||
if (i >= first_non_ascii) {
|
||||
entry.data.data.reg.contents[i] = get_converted_string(
|
||||
sd_conv,
|
||||
entry.data.data.reg.contents[i],
|
||||
strlen(entry.data.data.reg.contents[i]));
|
||||
} else {
|
||||
entry.data.data.reg.contents[i] =
|
||||
xstrdup(entry.data.data.reg.contents[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = shada_pack_entry(packer, entry.data, max_kbyte);
|
||||
if (did_convert) {
|
||||
for (size_t i = 0; i < entry.data.data.reg.contents_size; i++) {
|
||||
xfree(entry.data.data.reg.contents[i]);
|
||||
}
|
||||
xfree(entry.data.data.reg.contents);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kSDItemHeader:
|
||||
case kSDItemGlobalMark:
|
||||
case kSDItemJump:
|
||||
case kSDItemBufferList:
|
||||
case kSDItemLocalMark:
|
||||
case kSDItemChange: {
|
||||
ret = shada_pack_entry(packer, entry.data, max_kbyte);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#undef RUN_WITH_CONVERTED_STRING
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2556,11 +2444,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
|
|||
break;
|
||||
}
|
||||
typval_T tgttv;
|
||||
if (sd_writer->sd_conv.vc_type != CONV_NONE) {
|
||||
var_item_copy(&sd_writer->sd_conv, &vartv, &tgttv, true, 0);
|
||||
} else {
|
||||
tv_copy(&vartv, &tgttv);
|
||||
}
|
||||
tv_copy(&vartv, &tgttv);
|
||||
ShaDaWriteResult spe_ret;
|
||||
if ((spe_ret = shada_pack_entry(packer, (ShadaEntry) {
|
||||
.type = kSDItemVariable,
|
||||
|
@ -2811,9 +2695,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
|
|||
do { \
|
||||
for (size_t i_ = 0; i_ < ARRAY_SIZE(wms_array); i_++) { \
|
||||
if (wms_array[i_].data.type != kSDItemMissing) { \
|
||||
if (shada_pack_encoded_entry(packer, &sd_writer->sd_conv, \
|
||||
wms_array[i_], \
|
||||
max_kbyte) == kSDWriteFailed) { \
|
||||
if (shada_pack_pfreed_entry(packer, wms_array[i_], max_kbyte) \
|
||||
== kSDWriteFailed) { \
|
||||
ret = kSDWriteFailed; \
|
||||
goto shada_write_exit; \
|
||||
} \
|
||||
|
@ -2823,8 +2706,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
|
|||
PACK_WMS_ARRAY(wms->global_marks);
|
||||
PACK_WMS_ARRAY(wms->registers);
|
||||
for (size_t i = 0; i < wms->jumps_size; i++) {
|
||||
if (shada_pack_encoded_entry(packer, &sd_writer->sd_conv, wms->jumps[i],
|
||||
max_kbyte) == kSDWriteFailed) {
|
||||
if (shada_pack_pfreed_entry(packer, wms->jumps[i], max_kbyte)
|
||||
== kSDWriteFailed) {
|
||||
ret = kSDWriteFailed;
|
||||
goto shada_write_exit;
|
||||
}
|
||||
|
@ -2832,8 +2715,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
|
|||
#define PACK_WMS_ENTRY(wms_entry) \
|
||||
do { \
|
||||
if (wms_entry.data.type != kSDItemMissing) { \
|
||||
if (shada_pack_encoded_entry(packer, &sd_writer->sd_conv, wms_entry, \
|
||||
max_kbyte) == kSDWriteFailed) { \
|
||||
if (shada_pack_pfreed_entry(packer, wms_entry, max_kbyte) \
|
||||
== kSDWriteFailed) { \
|
||||
ret = kSDWriteFailed; \
|
||||
goto shada_write_exit; \
|
||||
} \
|
||||
|
@ -2860,9 +2743,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
|
|||
for (size_t i = 0; i < file_markss_to_dump; i++) {
|
||||
PACK_WMS_ARRAY(all_file_markss[i]->marks);
|
||||
for (size_t j = 0; j < all_file_markss[i]->changes_size; j++) {
|
||||
if (shada_pack_encoded_entry(packer, &sd_writer->sd_conv,
|
||||
all_file_markss[i]->changes[j],
|
||||
max_kbyte) == kSDWriteFailed) {
|
||||
if (shada_pack_pfreed_entry(packer, all_file_markss[i]->changes[j],
|
||||
max_kbyte) == kSDWriteFailed) {
|
||||
ret = kSDWriteFailed;
|
||||
goto shada_write_exit;
|
||||
}
|
||||
|
@ -2886,8 +2768,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
|
|||
if (dump_one_history[i]) {
|
||||
hms_insert_whole_neovim_history(&wms->hms[i]);
|
||||
HMS_ITER(&wms->hms[i], cur_entry, {
|
||||
if (shada_pack_encoded_entry(
|
||||
packer, &sd_writer->sd_conv, (PossiblyFreedShadaEntry) {
|
||||
if (shada_pack_pfreed_entry(
|
||||
packer, (PossiblyFreedShadaEntry) {
|
||||
.data = cur_entry->data,
|
||||
.can_free_entry = cur_entry->can_free_entry,
|
||||
}, max_kbyte) == kSDWriteFailed) {
|
||||
|
@ -3038,8 +2920,6 @@ shada_write_file_nomerge: {}
|
|||
verbose_leave();
|
||||
}
|
||||
|
||||
convert_setup(&sd_writer.sd_conv, p_enc, "utf-8");
|
||||
|
||||
const ShaDaWriteResult sw_ret = shada_write(&sd_writer, (nomerge
|
||||
? NULL
|
||||
: &sd_reader));
|
||||
|
@ -3327,29 +3207,6 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader,
|
|||
return kSDReadStatusSuccess;
|
||||
}
|
||||
|
||||
/// Convert or copy and return a string
|
||||
///
|
||||
/// @param[in] sd_conv Conversion definition.
|
||||
/// @param[in] str String to convert.
|
||||
/// @param[in] len String length.
|
||||
///
|
||||
/// @return [allocated] converted string or copy of the original string.
|
||||
static inline char *get_converted_string(const vimconv_T *const sd_conv,
|
||||
const char *const str,
|
||||
const size_t len)
|
||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
if (!has_non_ascii_len(str, len)) {
|
||||
return xmemdupz(str, len);
|
||||
}
|
||||
size_t new_len = len;
|
||||
char *const new_str = string_convert(sd_conv, str, &new_len);
|
||||
if (new_str == NULL) {
|
||||
return xmemdupz(str, len);
|
||||
}
|
||||
return new_str;
|
||||
}
|
||||
|
||||
#define READERR(entry_name, error_desc) \
|
||||
RERR "Error while reading ShaDa file: " \
|
||||
entry_name " entry at position %" PRIu64 " " \
|
||||
|
@ -3427,10 +3284,7 @@ static inline char *get_converted_string(const vimconv_T *const sd_conv,
|
|||
sizeof(*unpacked.data.via.map.ptr)); \
|
||||
ad_ga.ga_len++; \
|
||||
}
|
||||
#define CONVERTED(str, len) ( \
|
||||
sd_reader->sd_conv.vc_type != CONV_NONE \
|
||||
? get_converted_string(&sd_reader->sd_conv, (str), (len)) \
|
||||
: xmemdupz((str), (len)))
|
||||
#define CONVERTED(str, len) (xmemdupz((str), (len)))
|
||||
#define BIN_CONVERTED(b) CONVERTED(b.ptr, b.size)
|
||||
#define SET_ADDITIONAL_DATA(tgt, name) \
|
||||
do { \
|
||||
|
@ -3803,30 +3657,14 @@ shada_read_next_item_start:
|
|||
(char) unpacked.data.via.array.ptr[2].via.u64;
|
||||
}
|
||||
size_t strsize;
|
||||
if (sd_reader->sd_conv.vc_type == CONV_NONE
|
||||
|| !has_non_ascii_len(unpacked.data.via.array.ptr[1].via.bin.ptr,
|
||||
unpacked.data.via.array.ptr[1].via.bin.size)) {
|
||||
shada_read_next_item_hist_no_conv:
|
||||
strsize = (
|
||||
unpacked.data.via.array.ptr[1].via.bin.size
|
||||
+ 1 // Zero byte
|
||||
+ 1); // Separator character
|
||||
entry->data.history_item.string = xmalloc(strsize);
|
||||
memcpy(entry->data.history_item.string,
|
||||
unpacked.data.via.array.ptr[1].via.bin.ptr,
|
||||
unpacked.data.via.array.ptr[1].via.bin.size);
|
||||
} else {
|
||||
size_t len = unpacked.data.via.array.ptr[1].via.bin.size;
|
||||
char *const converted = string_convert(
|
||||
&sd_reader->sd_conv, unpacked.data.via.array.ptr[1].via.bin.ptr,
|
||||
&len);
|
||||
if (converted != NULL) {
|
||||
strsize = len + 2;
|
||||
entry->data.history_item.string = xrealloc(converted, strsize);
|
||||
} else {
|
||||
goto shada_read_next_item_hist_no_conv;
|
||||
}
|
||||
}
|
||||
strsize = (
|
||||
unpacked.data.via.array.ptr[1].via.bin.size
|
||||
+ 1 // Zero byte
|
||||
+ 1); // Separator character
|
||||
entry->data.history_item.string = xmalloc(strsize);
|
||||
memcpy(entry->data.history_item.string,
|
||||
unpacked.data.via.array.ptr[1].via.bin.ptr,
|
||||
unpacked.data.via.array.ptr[1].via.bin.size);
|
||||
entry->data.history_item.string[strsize - 2] = 0;
|
||||
entry->data.history_item.string[strsize - 1] =
|
||||
entry->data.history_item.sep;
|
||||
|
@ -3859,16 +3697,6 @@ shada_read_next_item_hist_no_conv:
|
|||
"be converted to the VimL value")), initial_fpos);
|
||||
goto shada_read_next_item_error;
|
||||
}
|
||||
if (sd_reader->sd_conv.vc_type != CONV_NONE) {
|
||||
typval_T tgttv;
|
||||
var_item_copy(&sd_reader->sd_conv,
|
||||
&entry->data.global_var.value,
|
||||
&tgttv,
|
||||
true,
|
||||
0);
|
||||
tv_clear(&entry->data.global_var.value);
|
||||
entry->data.global_var.value = tgttv;
|
||||
}
|
||||
SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 2,
|
||||
entry->data.global_var.additional_elements,
|
||||
"variable");
|
||||
|
|
|
@ -2526,8 +2526,7 @@ void clear_spell_chartab(spelltab_T *sp)
|
|||
}
|
||||
}
|
||||
|
||||
// Init the chartab used for spelling. Only depends on 'encoding'.
|
||||
// Called once while starting up and when 'encoding' changes.
|
||||
// Init the chartab used for spelling. Called once while starting up.
|
||||
// The default is to use isalpha(), but the spell file should define the word
|
||||
// characters to make it possible that 'encoding' differs from the current
|
||||
// locale. For utf-8 we don't use isalpha() but our own functions.
|
||||
|
@ -2537,36 +2536,17 @@ void init_spell_chartab(void)
|
|||
|
||||
did_set_spelltab = false;
|
||||
clear_spell_chartab(&spelltab);
|
||||
if (enc_dbcs) {
|
||||
// DBCS: assume double-wide characters are word characters.
|
||||
for (i = 128; i <= 255; ++i)
|
||||
if (MB_BYTE2LEN(i) == 2)
|
||||
spelltab.st_isw[i] = true;
|
||||
} else if (enc_utf8) {
|
||||
for (i = 128; i < 256; ++i) {
|
||||
int f = utf_fold(i);
|
||||
int u = utf_toupper(i);
|
||||
for (i = 128; i < 256; i++) {
|
||||
int f = utf_fold(i);
|
||||
int u = mb_toupper(i);
|
||||
|
||||
spelltab.st_isu[i] = utf_isupper(i);
|
||||
spelltab.st_isw[i] = spelltab.st_isu[i] || utf_islower(i);
|
||||
// The folded/upper-cased value is different between latin1 and
|
||||
// utf8 for 0xb5, causing E763 for no good reason. Use the latin1
|
||||
// value for utf-8 to avoid this.
|
||||
spelltab.st_fold[i] = (f < 256) ? f : i;
|
||||
spelltab.st_upper[i] = (u < 256) ? u : i;
|
||||
}
|
||||
} else {
|
||||
// Rough guess: use locale-dependent library functions.
|
||||
for (i = 128; i < 256; ++i) {
|
||||
if (vim_isupper(i)) {
|
||||
spelltab.st_isw[i] = true;
|
||||
spelltab.st_isu[i] = true;
|
||||
spelltab.st_fold[i] = vim_tolower(i);
|
||||
} else if (vim_islower(i)) {
|
||||
spelltab.st_isw[i] = true;
|
||||
spelltab.st_upper[i] = vim_toupper(i);
|
||||
}
|
||||
}
|
||||
spelltab.st_isu[i] = mb_isupper(i);
|
||||
spelltab.st_isw[i] = spelltab.st_isu[i] || mb_islower(i);
|
||||
// The folded/upper-cased value is different between latin1 and
|
||||
// utf8 for 0xb5, causing E763 for no good reason. Use the latin1
|
||||
// value for utf-8 to avoid this.
|
||||
spelltab.st_fold[i] = (f < 256) ? f : i;
|
||||
spelltab.st_upper[i] = (u < 256) ? u : i;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -265,11 +265,11 @@ typedef struct trystate_S {
|
|||
: (c) < \
|
||||
256 ? (int)spelltab.st_fold[c] : (int)towlower(c))
|
||||
|
||||
#define SPELL_TOUPPER(c) (enc_utf8 && (c) >= 128 ? utf_toupper(c) \
|
||||
#define SPELL_TOUPPER(c) (enc_utf8 && (c) >= 128 ? mb_toupper(c) \
|
||||
: (c) < \
|
||||
256 ? (int)spelltab.st_upper[c] : (int)towupper(c))
|
||||
|
||||
#define SPELL_ISUPPER(c) (enc_utf8 && (c) >= 128 ? utf_isupper(c) \
|
||||
#define SPELL_ISUPPER(c) (enc_utf8 && (c) >= 128 ? mb_isupper(c) \
|
||||
: (c) < 256 ? spelltab.st_isu[c] : iswupper(c))
|
||||
|
||||
// First language that is loaded, start of the linked list of loaded
|
||||
|
|
|
@ -223,7 +223,9 @@
|
|||
// few bytes as possible, see offset2bytes())
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <wctype.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "nvim/vim.h"
|
||||
#include "nvim/spell_defs.h"
|
||||
|
@ -266,7 +268,7 @@
|
|||
#define SAL_REM_ACCENTS 4
|
||||
|
||||
#define VIMSPELLMAGIC "VIMspell" // string at start of Vim spell file
|
||||
#define VIMSPELLMAGICL 8
|
||||
#define VIMSPELLMAGICL (sizeof(VIMSPELLMAGIC) - 1)
|
||||
#define VIMSPELLVERSION 50
|
||||
|
||||
// Section IDs. Only renumber them when VIMSPELLVERSION changes!
|
||||
|
@ -493,6 +495,64 @@ typedef struct spellinfo_S {
|
|||
# include "spellfile.c.generated.h"
|
||||
#endif
|
||||
|
||||
/// Read n bytes from fd to buf, returning on errors
|
||||
///
|
||||
/// @param[out] buf Buffer to read to, must be at least n bytes long.
|
||||
/// @param[in] n Amount of bytes to read.
|
||||
/// @param fd FILE* to read from.
|
||||
/// @param exit_code Code to run before returning.
|
||||
///
|
||||
/// @return Allows to proceed if everything is OK, returns SP_TRUNCERROR if
|
||||
/// there are not enough bytes, returns SP_OTHERERROR if reading failed.
|
||||
#define SPELL_READ_BYTES(buf, n, fd, exit_code) \
|
||||
do { \
|
||||
const size_t n__SPRB = (n); \
|
||||
FILE *const fd__SPRB = (fd); \
|
||||
char *const buf__SPRB = (buf); \
|
||||
const size_t read_bytes__SPRB = fread(buf__SPRB, 1, n__SPRB, fd__SPRB); \
|
||||
if (read_bytes__SPRB != n__SPRB) { \
|
||||
exit_code; \
|
||||
return feof(fd__SPRB) ? SP_TRUNCERROR : SP_OTHERERROR; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/// Like #SPELL_READ_BYTES, but also error out if NUL byte was read
|
||||
///
|
||||
/// @return Allows to proceed if everything is OK, returns SP_TRUNCERROR if
|
||||
/// there are not enough bytes, returns SP_OTHERERROR if reading failed,
|
||||
/// returns SP_FORMERROR if read out a NUL byte.
|
||||
#define SPELL_READ_NONNUL_BYTES(buf, n, fd, exit_code) \
|
||||
do { \
|
||||
const size_t n__SPRNB = (n); \
|
||||
FILE *const fd__SPRNB = (fd); \
|
||||
char *const buf__SPRNB = (buf); \
|
||||
SPELL_READ_BYTES(buf__SPRNB, n__SPRNB, fd__SPRNB, exit_code); \
|
||||
if (memchr(buf__SPRNB, NUL, (size_t)n__SPRNB)) { \
|
||||
exit_code; \
|
||||
return SP_FORMERROR; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/// Check that spell file starts with a magic string
|
||||
///
|
||||
/// Does not check for version of the file.
|
||||
///
|
||||
/// @param fd File to check.
|
||||
///
|
||||
/// @return 0 in case of success, SP_TRUNCERROR if file contains not enough
|
||||
/// bytes, SP_FORMERROR if it does not match magic string and
|
||||
/// SP_OTHERERROR if reading file failed.
|
||||
static inline int spell_check_magic_string(FILE *const fd)
|
||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE
|
||||
{
|
||||
char buf[VIMSPELLMAGICL];
|
||||
SPELL_READ_BYTES(buf, VIMSPELLMAGICL, fd, ;);
|
||||
if (memcmp(buf, VIMSPELLMAGIC, VIMSPELLMAGICL) != 0) {
|
||||
return SP_FORMERROR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Load one spell file and store the info into a slang_T.
|
||||
//
|
||||
// This is invoked in three ways:
|
||||
|
@ -513,9 +573,7 @@ spell_load_file (
|
|||
)
|
||||
{
|
||||
FILE *fd;
|
||||
char_u buf[VIMSPELLMAGICL];
|
||||
char_u *p;
|
||||
int i;
|
||||
int n;
|
||||
int len;
|
||||
char_u *save_sourcing_name = sourcing_name;
|
||||
|
@ -557,11 +615,20 @@ spell_load_file (
|
|||
sourcing_lnum = 0;
|
||||
|
||||
// <HEADER>: <fileID>
|
||||
for (i = 0; i < VIMSPELLMAGICL; ++i)
|
||||
buf[i] = getc(fd); // <fileID>
|
||||
if (STRNCMP(buf, VIMSPELLMAGIC, VIMSPELLMAGICL) != 0) {
|
||||
EMSG(_("E757: This does not look like a spell file"));
|
||||
goto endFAIL;
|
||||
const int scms_ret = spell_check_magic_string(fd);
|
||||
switch (scms_ret) {
|
||||
case SP_FORMERROR:
|
||||
case SP_TRUNCERROR: {
|
||||
emsgf(_("E757: This does not look like a spell file"));
|
||||
goto endFAIL;
|
||||
}
|
||||
case SP_OTHERERROR: {
|
||||
emsgf(_("E5042: Failed to read spell file %s: %s"),
|
||||
fname, strerror(ferror(fd)));
|
||||
}
|
||||
case 0: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
c = getc(fd); // <versionnr>
|
||||
if (c < VIMSPELLVERSION) {
|
||||
|
@ -934,12 +1001,10 @@ static char_u *read_cnt_string(FILE *fd, int cnt_bytes, int *cntp)
|
|||
// Return SP_*ERROR flags.
|
||||
static int read_region_section(FILE *fd, slang_T *lp, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (len > 16)
|
||||
if (len > 16) {
|
||||
return SP_FORMERROR;
|
||||
for (i = 0; i < len; ++i)
|
||||
lp->sl_regions[i] = getc(fd); // <regionname>
|
||||
}
|
||||
SPELL_READ_NONNUL_BYTES((char *)lp->sl_regions, (size_t)len, fd, ;);
|
||||
lp->sl_regions[len] = NUL;
|
||||
return 0;
|
||||
}
|
||||
|
@ -982,35 +1047,30 @@ static int read_charflags_section(FILE *fd)
|
|||
// Return SP_*ERROR flags.
|
||||
static int read_prefcond_section(FILE *fd, slang_T *lp)
|
||||
{
|
||||
int cnt;
|
||||
int i;
|
||||
int n;
|
||||
char_u *p;
|
||||
char_u buf[MAXWLEN + 1];
|
||||
|
||||
// <prefcondcnt> <prefcond> ...
|
||||
cnt = get2c(fd); // <prefcondcnt>
|
||||
if (cnt <= 0)
|
||||
const int cnt = get2c(fd); // <prefcondcnt>
|
||||
if (cnt <= 0) {
|
||||
return SP_FORMERROR;
|
||||
}
|
||||
|
||||
lp->sl_prefprog = xcalloc(cnt, sizeof(regprog_T *));
|
||||
lp->sl_prefixcnt = cnt;
|
||||
|
||||
for (i = 0; i < cnt; ++i) {
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
// <prefcond> : <condlen> <condstr>
|
||||
n = getc(fd); // <condlen>
|
||||
if (n < 0 || n >= MAXWLEN)
|
||||
const int n = getc(fd); // <condlen>
|
||||
if (n < 0 || n >= MAXWLEN) {
|
||||
return SP_FORMERROR;
|
||||
}
|
||||
|
||||
// When <condlen> is zero we have an empty condition. Otherwise
|
||||
// compile the regexp program used to check for the condition.
|
||||
if (n > 0) {
|
||||
buf[0] = '^'; // always match at one position only
|
||||
p = buf + 1;
|
||||
while (n-- > 0)
|
||||
*p++ = getc(fd); // <condstr>
|
||||
*p = NUL;
|
||||
lp->sl_prefprog[i] = vim_regcomp(buf, RE_MAGIC + RE_STRING);
|
||||
char buf[MAXWLEN + 1];
|
||||
buf[0] = '^'; // always match at one position only
|
||||
SPELL_READ_NONNUL_BYTES(buf + 1, (size_t)n, fd, ;);
|
||||
buf[n + 1] = NUL;
|
||||
lp->sl_prefprog[i] = vim_regcomp((char_u *)buf, RE_MAGIC | RE_STRING);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -1063,7 +1123,6 @@ static int read_rep_section(FILE *fd, garray_T *gap, int16_t *first)
|
|||
// Return SP_*ERROR flags.
|
||||
static int read_sal_section(FILE *fd, slang_T *slang)
|
||||
{
|
||||
int i;
|
||||
int cnt;
|
||||
garray_T *gap;
|
||||
salitem_T *smp;
|
||||
|
@ -1073,13 +1132,16 @@ static int read_sal_section(FILE *fd, slang_T *slang)
|
|||
|
||||
slang->sl_sofo = false;
|
||||
|
||||
i = getc(fd); // <salflags>
|
||||
if (i & SAL_F0LLOWUP)
|
||||
const int flags = getc(fd); // <salflags>
|
||||
if (flags & SAL_F0LLOWUP) {
|
||||
slang->sl_followup = true;
|
||||
if (i & SAL_COLLAPSE)
|
||||
}
|
||||
if (flags & SAL_COLLAPSE) {
|
||||
slang->sl_collapse = true;
|
||||
if (i & SAL_REM_ACCENTS)
|
||||
}
|
||||
if (flags & SAL_REM_ACCENTS) {
|
||||
slang->sl_rem_accents = true;
|
||||
}
|
||||
|
||||
cnt = get2c(fd); // <salcount>
|
||||
if (cnt < 0)
|
||||
|
@ -1099,7 +1161,8 @@ static int read_sal_section(FILE *fd, slang_T *slang)
|
|||
smp->sm_lead = p;
|
||||
|
||||
// Read up to the first special char into sm_lead.
|
||||
for (i = 0; i < ccnt; ++i) {
|
||||
int i = 0;
|
||||
for (; i < ccnt; ++i) {
|
||||
c = getc(fd); // <salfrom>
|
||||
if (vim_strchr((char_u *)"0123456789(-<^$", c) != NULL)
|
||||
break;
|
||||
|
@ -1125,11 +1188,17 @@ static int read_sal_section(FILE *fd, slang_T *slang)
|
|||
|
||||
// Any following chars go in sm_rules.
|
||||
smp->sm_rules = p;
|
||||
if (i < ccnt)
|
||||
if (i < ccnt) {
|
||||
// store the char we got while checking for end of sm_lead
|
||||
*p++ = c;
|
||||
for (++i; i < ccnt; ++i)
|
||||
*p++ = getc(fd); // <salfrom>
|
||||
}
|
||||
i++;
|
||||
if (i < ccnt) {
|
||||
SPELL_READ_NONNUL_BYTES( // <salfrom>
|
||||
(char *)p, (size_t)(ccnt - i), fd, xfree(smp->sm_lead));
|
||||
p += (ccnt - i);
|
||||
i = ccnt;
|
||||
}
|
||||
*p++ = NUL;
|
||||
|
||||
// <saltolen> <salto>
|
||||
|
@ -1569,9 +1638,14 @@ spell_read_tree (
|
|||
|
||||
// The tree size was computed when writing the file, so that we can
|
||||
// allocate it as one long block. <nodecount>
|
||||
int len = get4c(fd);
|
||||
if (len < 0)
|
||||
long len = get4c(fd);
|
||||
if (len < 0) {
|
||||
return SP_TRUNCERROR;
|
||||
}
|
||||
if ((size_t)len >= SIZE_MAX / sizeof(int)) {
|
||||
// Invalid length, multiply with sizeof(int) would overflow.
|
||||
return SP_FORMERROR;
|
||||
}
|
||||
if (len > 0) {
|
||||
// Allocate the byte array.
|
||||
bp = xmalloc(len);
|
||||
|
|
|
@ -291,14 +291,15 @@ void vim_strup(char_u *p)
|
|||
}
|
||||
}
|
||||
|
||||
/// Make given string all upper-case
|
||||
/// Make given string all upper-case or all lower-case
|
||||
///
|
||||
/// Handels multi-byte characters as good as possible.
|
||||
/// Handles multi-byte characters as good as possible.
|
||||
///
|
||||
/// @param[in] orig Input string.
|
||||
/// @param[in] upper If true make uppercase, otherwise lowercase
|
||||
///
|
||||
/// @return [allocated] upper-cased string.
|
||||
char *strup_save(const char *const orig)
|
||||
char *strcase_save(const char *const orig, bool upper)
|
||||
FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
char *res = xstrdup(orig);
|
||||
|
@ -307,33 +308,25 @@ char *strup_save(const char *const orig)
|
|||
while (*p != NUL) {
|
||||
int l;
|
||||
|
||||
if (enc_utf8) {
|
||||
int c = utf_ptr2char((const char_u *)p);
|
||||
int uc = utf_toupper(c);
|
||||
int c = utf_ptr2char((const char_u *)p);
|
||||
int uc = upper ? mb_toupper(c) : mb_tolower(c);
|
||||
|
||||
// Reallocate string when byte count changes. This is rare,
|
||||
// thus it's OK to do another malloc()/free().
|
||||
l = utf_ptr2len((const char_u *)p);
|
||||
int newl = utf_char2len(uc);
|
||||
if (newl != l) {
|
||||
// TODO(philix): use xrealloc() in strup_save()
|
||||
char *s = xmalloc(STRLEN(res) + (size_t)(1 + newl - l));
|
||||
memcpy(s, res, (size_t)(p - res));
|
||||
STRCPY(s + (p - res) + newl, p + l);
|
||||
p = s + (p - res);
|
||||
xfree(res);
|
||||
res = s;
|
||||
}
|
||||
|
||||
utf_char2bytes(uc, (char_u *)p);
|
||||
p += newl;
|
||||
} else if (has_mbyte && (l = (*mb_ptr2len)((const char_u *)p)) > 1) {
|
||||
p += l; // Skip multi-byte character.
|
||||
} else {
|
||||
// note that toupper() can be a macro
|
||||
*p = (char)(uint8_t)TOUPPER_LOC(*p);
|
||||
p++;
|
||||
// Reallocate string when byte count changes. This is rare,
|
||||
// thus it's OK to do another malloc()/free().
|
||||
l = utf_ptr2len((const char_u *)p);
|
||||
int newl = utf_char2len(uc);
|
||||
if (newl != l) {
|
||||
// TODO(philix): use xrealloc() in strup_save()
|
||||
char *s = xmalloc(STRLEN(res) + (size_t)(1 + newl - l));
|
||||
memcpy(s, res, (size_t)(p - res));
|
||||
STRCPY(s + (p - res) + newl, p + l);
|
||||
p = s + (p - res);
|
||||
xfree(res);
|
||||
res = s;
|
||||
}
|
||||
|
||||
utf_char2bytes(uc, (char_u *)p);
|
||||
p += newl;
|
||||
}
|
||||
|
||||
return res;
|
||||
|
|
|
@ -4246,83 +4246,81 @@ static void syn_cmd_keyword(exarg_T *eap, int syncing)
|
|||
|
||||
if (rest != NULL) {
|
||||
syn_id = syn_check_group(arg, (int)(group_name_end - arg));
|
||||
if (syn_id != 0)
|
||||
/* allocate a buffer, for removing backslashes in the keyword */
|
||||
if (syn_id != 0) {
|
||||
// Allocate a buffer, for removing backslashes in the keyword.
|
||||
keyword_copy = xmalloc(STRLEN(rest) + 1);
|
||||
syn_opt_arg.flags = 0;
|
||||
syn_opt_arg.keyword = TRUE;
|
||||
syn_opt_arg.sync_idx = NULL;
|
||||
syn_opt_arg.has_cont_list = FALSE;
|
||||
syn_opt_arg.cont_in_list = NULL;
|
||||
syn_opt_arg.next_list = NULL;
|
||||
|
||||
/*
|
||||
* The options given apply to ALL keywords, so all options must be
|
||||
* found before keywords can be created.
|
||||
* 1: collect the options and copy the keywords to keyword_copy.
|
||||
*/
|
||||
cnt = 0;
|
||||
p = keyword_copy;
|
||||
for (; rest != NULL && !ends_excmd(*rest); rest = skipwhite(rest)) {
|
||||
rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
|
||||
if (rest == NULL || ends_excmd(*rest))
|
||||
break;
|
||||
/* Copy the keyword, removing backslashes, and add a NUL. */
|
||||
while (*rest != NUL && !ascii_iswhite(*rest)) {
|
||||
if (*rest == '\\' && rest[1] != NUL)
|
||||
++rest;
|
||||
*p++ = *rest++;
|
||||
}
|
||||
*p++ = NUL;
|
||||
++cnt;
|
||||
}
|
||||
if (keyword_copy != NULL) {
|
||||
syn_opt_arg.flags = 0;
|
||||
syn_opt_arg.keyword = true;
|
||||
syn_opt_arg.sync_idx = NULL;
|
||||
syn_opt_arg.has_cont_list = false;
|
||||
syn_opt_arg.cont_in_list = NULL;
|
||||
syn_opt_arg.next_list = NULL;
|
||||
|
||||
if (!eap->skip) {
|
||||
/* Adjust flags for use of ":syn include". */
|
||||
syn_incl_toplevel(syn_id, &syn_opt_arg.flags);
|
||||
|
||||
/*
|
||||
* 2: Add an entry for each keyword.
|
||||
*/
|
||||
for (kw = keyword_copy; --cnt >= 0; kw += STRLEN(kw) + 1) {
|
||||
for (p = vim_strchr(kw, '[');; ) {
|
||||
if (p != NULL)
|
||||
*p = NUL;
|
||||
add_keyword(kw, syn_id, syn_opt_arg.flags,
|
||||
syn_opt_arg.cont_in_list,
|
||||
syn_opt_arg.next_list, conceal_char);
|
||||
if (p == NULL)
|
||||
break;
|
||||
if (p[1] == NUL) {
|
||||
EMSG2(_("E789: Missing ']': %s"), kw);
|
||||
goto error;
|
||||
// The options given apply to ALL keywords, so all options must be
|
||||
// found before keywords can be created.
|
||||
// 1: collect the options and copy the keywords to keyword_copy.
|
||||
cnt = 0;
|
||||
p = keyword_copy;
|
||||
for (; rest != NULL && !ends_excmd(*rest); rest = skipwhite(rest)) {
|
||||
rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
|
||||
if (rest == NULL || ends_excmd(*rest)) {
|
||||
break;
|
||||
}
|
||||
// Copy the keyword, removing backslashes, and add a NUL.
|
||||
while (*rest != NUL && !ascii_iswhite(*rest)) {
|
||||
if (*rest == '\\' && rest[1] != NUL) {
|
||||
rest++;
|
||||
}
|
||||
if (p[1] == ']') {
|
||||
if (p[2] != NUL) {
|
||||
EMSG3(_("E890: trailing char after ']': %s]%s"),
|
||||
kw, &p[2]);
|
||||
*p++ = *rest++;
|
||||
}
|
||||
*p++ = NUL;
|
||||
cnt++;
|
||||
}
|
||||
|
||||
if (!eap->skip) {
|
||||
// Adjust flags for use of ":syn include".
|
||||
syn_incl_toplevel(syn_id, &syn_opt_arg.flags);
|
||||
|
||||
// 2: Add an entry for each keyword.
|
||||
for (kw = keyword_copy; --cnt >= 0; kw += STRLEN(kw) + 1) {
|
||||
for (p = vim_strchr(kw, '[');; ) {
|
||||
if (p != NULL) {
|
||||
*p = NUL;
|
||||
}
|
||||
add_keyword(kw, syn_id, syn_opt_arg.flags,
|
||||
syn_opt_arg.cont_in_list,
|
||||
syn_opt_arg.next_list, conceal_char);
|
||||
if (p == NULL) {
|
||||
break;
|
||||
}
|
||||
if (p[1] == NUL) {
|
||||
emsgf(_("E789: Missing ']': %s"), kw);
|
||||
goto error;
|
||||
}
|
||||
kw = p + 1;
|
||||
break; // skip over the "]"
|
||||
}
|
||||
if (has_mbyte) {
|
||||
int l = (*mb_ptr2len)(p + 1);
|
||||
if (p[1] == ']') {
|
||||
if (p[2] != NUL) {
|
||||
emsgf(_("E890: trailing char after ']': %s]%s"),
|
||||
kw, &p[2]);
|
||||
goto error;
|
||||
}
|
||||
kw = p + 1;
|
||||
break; // skip over the "]"
|
||||
}
|
||||
const int l = (*mb_ptr2len)(p + 1);
|
||||
|
||||
memmove(p, p + 1, l);
|
||||
p += l;
|
||||
} else {
|
||||
p[0] = p[1];
|
||||
++p;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
xfree(keyword_copy);
|
||||
xfree(syn_opt_arg.cont_in_list);
|
||||
xfree(syn_opt_arg.next_list);
|
||||
xfree(keyword_copy);
|
||||
xfree(syn_opt_arg.cont_in_list);
|
||||
xfree(syn_opt_arg.next_list);
|
||||
}
|
||||
}
|
||||
|
||||
if (rest != NULL)
|
||||
|
|
|
@ -1847,14 +1847,14 @@ parse_line:
|
|||
}
|
||||
}
|
||||
} else {
|
||||
#define TAG_SEP 0x01
|
||||
#define TAG_SEP 0x02
|
||||
size_t tag_fname_len = STRLEN(tag_fname);
|
||||
// Save the tag in a buffer.
|
||||
// Use 0x01 to separate fields (Can't use NUL, because the
|
||||
// Use 0x02 to separate fields (Can't use NUL, because the
|
||||
// hash key is terminated by NUL).
|
||||
// Emacs tag: <mtt><tag_fname><NUL><ebuf><NUL><lbuf>
|
||||
// other tag: <mtt><tag_fname><NUL><NUL><lbuf>
|
||||
// without Emacs tags: <mtt><tag_fname><NUL><lbuf>
|
||||
// Emacs tag: <mtt><tag_fname><0x02><ebuf><0x02><lbuf><NUL>
|
||||
// other tag: <mtt><tag_fname><0x02><0x02><lbuf><NUL>
|
||||
// without Emacs tags: <mtt><tag_fname><0x02><lbuf><NUL>
|
||||
// Here <mtt> is the "mtt" value plus 1 to avoid NUL.
|
||||
len = (int)tag_fname_len + (int)STRLEN(lbuf) + 3;
|
||||
mfp = xmalloc(sizeof(char_u) + len + 1);
|
||||
|
@ -2797,11 +2797,9 @@ add_tag_field (
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the tags matching the specified pattern to the list "list"
|
||||
* as a dictionary
|
||||
*/
|
||||
int get_tags(list_T *list, char_u *pat)
|
||||
/// Add the tags matching the specified pattern "pat" to the list "list"
|
||||
/// as a dictionary. Use "buf_fname" for priority, unless NULL.
|
||||
int get_tags(list_T *list, char_u *pat, char_u *buf_fname)
|
||||
{
|
||||
int num_matches, i, ret;
|
||||
char_u **matches, *p;
|
||||
|
@ -2811,7 +2809,7 @@ int get_tags(list_T *list, char_u *pat)
|
|||
bool is_static;
|
||||
|
||||
ret = find_tags(pat, &num_matches, &matches,
|
||||
TAG_REGEXP | TAG_NOIC, (int)MAXCOL, NULL);
|
||||
TAG_REGEXP | TAG_NOIC, (int)MAXCOL, buf_fname);
|
||||
if (ret == OK && num_matches > 0) {
|
||||
for (i = 0; i < num_matches; ++i) {
|
||||
int parse_result = parse_match(matches[i], &tp);
|
||||
|
|
|
@ -26,6 +26,7 @@ source test_tabline.vim
|
|||
" source test_tabpage.vim
|
||||
source test_tagcase.vim
|
||||
source test_tagjump.vim
|
||||
source test_taglist.vim
|
||||
source test_true_false.vim
|
||||
source test_unlet.vim
|
||||
source test_utf8.vim
|
||||
|
|
|
@ -29,3 +29,147 @@ func Test_setbufvar_options()
|
|||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_tolower()
|
||||
call assert_equal("", tolower(""))
|
||||
|
||||
" Test with all printable ASCII characters.
|
||||
call assert_equal(' !"#$%&''()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~',
|
||||
\ tolower(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'))
|
||||
|
||||
if !has('multi_byte')
|
||||
return
|
||||
endif
|
||||
|
||||
" Test with a few uppercase diacritics.
|
||||
call assert_equal("aàáâãäåāăąǎǟǡả", tolower("AÀÁÂÃÄÅĀĂĄǍǞǠẢ"))
|
||||
call assert_equal("bḃḇ", tolower("BḂḆ"))
|
||||
call assert_equal("cçćĉċč", tolower("CÇĆĈĊČ"))
|
||||
call assert_equal("dďđḋḏḑ", tolower("DĎĐḊḎḐ"))
|
||||
call assert_equal("eèéêëēĕėęěẻẽ", tolower("EÈÉÊËĒĔĖĘĚẺẼ"))
|
||||
call assert_equal("fḟ ", tolower("FḞ "))
|
||||
call assert_equal("gĝğġģǥǧǵḡ", tolower("GĜĞĠĢǤǦǴḠ"))
|
||||
call assert_equal("hĥħḣḧḩ", tolower("HĤĦḢḦḨ"))
|
||||
call assert_equal("iìíîïĩīĭįiǐỉ", tolower("IÌÍÎÏĨĪĬĮİǏỈ"))
|
||||
call assert_equal("jĵ", tolower("JĴ"))
|
||||
call assert_equal("kķǩḱḵ", tolower("KĶǨḰḴ"))
|
||||
call assert_equal("lĺļľŀłḻ", tolower("LĹĻĽĿŁḺ"))
|
||||
call assert_equal("mḿṁ", tolower("MḾṀ"))
|
||||
call assert_equal("nñńņňṅṉ", tolower("NÑŃŅŇṄṈ"))
|
||||
call assert_equal("oòóôõöøōŏőơǒǫǭỏ", tolower("OÒÓÔÕÖØŌŎŐƠǑǪǬỎ"))
|
||||
call assert_equal("pṕṗ", tolower("PṔṖ"))
|
||||
call assert_equal("q", tolower("Q"))
|
||||
call assert_equal("rŕŗřṙṟ", tolower("RŔŖŘṘṞ"))
|
||||
call assert_equal("sśŝşšṡ", tolower("SŚŜŞŠṠ"))
|
||||
call assert_equal("tţťŧṫṯ", tolower("TŢŤŦṪṮ"))
|
||||
call assert_equal("uùúûüũūŭůűųưǔủ", tolower("UÙÚÛÜŨŪŬŮŰŲƯǓỦ"))
|
||||
call assert_equal("vṽ", tolower("VṼ"))
|
||||
call assert_equal("wŵẁẃẅẇ", tolower("WŴẀẂẄẆ"))
|
||||
call assert_equal("xẋẍ", tolower("XẊẌ"))
|
||||
call assert_equal("yýŷÿẏỳỷỹ", tolower("YÝŶŸẎỲỶỸ"))
|
||||
call assert_equal("zźżžƶẑẕ", tolower("ZŹŻŽƵẐẔ"))
|
||||
|
||||
" Test with a few lowercase diacritics, which should remain unchanged.
|
||||
call assert_equal("aàáâãäåāăąǎǟǡả", tolower("aàáâãäåāăąǎǟǡả"))
|
||||
call assert_equal("bḃḇ", tolower("bḃḇ"))
|
||||
call assert_equal("cçćĉċč", tolower("cçćĉċč"))
|
||||
call assert_equal("dďđḋḏḑ", tolower("dďđḋḏḑ"))
|
||||
call assert_equal("eèéêëēĕėęěẻẽ", tolower("eèéêëēĕėęěẻẽ"))
|
||||
call assert_equal("fḟ", tolower("fḟ"))
|
||||
call assert_equal("gĝğġģǥǧǵḡ", tolower("gĝğġģǥǧǵḡ"))
|
||||
call assert_equal("hĥħḣḧḩẖ", tolower("hĥħḣḧḩẖ"))
|
||||
call assert_equal("iìíîïĩīĭįǐỉ", tolower("iìíîïĩīĭįǐỉ"))
|
||||
call assert_equal("jĵǰ", tolower("jĵǰ"))
|
||||
call assert_equal("kķǩḱḵ", tolower("kķǩḱḵ"))
|
||||
call assert_equal("lĺļľŀłḻ", tolower("lĺļľŀłḻ"))
|
||||
call assert_equal("mḿṁ ", tolower("mḿṁ "))
|
||||
call assert_equal("nñńņňʼnṅṉ", tolower("nñńņňʼnṅṉ"))
|
||||
call assert_equal("oòóôõöøōŏőơǒǫǭỏ", tolower("oòóôõöøōŏőơǒǫǭỏ"))
|
||||
call assert_equal("pṕṗ", tolower("pṕṗ"))
|
||||
call assert_equal("q", tolower("q"))
|
||||
call assert_equal("rŕŗřṙṟ", tolower("rŕŗřṙṟ"))
|
||||
call assert_equal("sśŝşšṡ", tolower("sśŝşšṡ"))
|
||||
call assert_equal("tţťŧṫṯẗ", tolower("tţťŧṫṯẗ"))
|
||||
call assert_equal("uùúûüũūŭůűųưǔủ", tolower("uùúûüũūŭůűųưǔủ"))
|
||||
call assert_equal("vṽ", tolower("vṽ"))
|
||||
call assert_equal("wŵẁẃẅẇẘ", tolower("wŵẁẃẅẇẘ"))
|
||||
call assert_equal("ẋẍ", tolower("ẋẍ"))
|
||||
call assert_equal("yýÿŷẏẙỳỷỹ", tolower("yýÿŷẏẙỳỷỹ"))
|
||||
call assert_equal("zźżžƶẑẕ", tolower("zźżžƶẑẕ"))
|
||||
|
||||
" According to https://twitter.com/jifa/status/625776454479970304
|
||||
" Ⱥ (U+023A) and Ⱦ (U+023E) are the *only* code points to increase
|
||||
" in length (2 to 3 bytes) when lowercased. So let's test them.
|
||||
call assert_equal("ⱥ ⱦ", tolower("Ⱥ Ⱦ"))
|
||||
endfunc
|
||||
|
||||
func Test_toupper()
|
||||
call assert_equal("", toupper(""))
|
||||
|
||||
" Test with all printable ASCII characters.
|
||||
call assert_equal(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~',
|
||||
\ toupper(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'))
|
||||
|
||||
if !has('multi_byte')
|
||||
return
|
||||
endif
|
||||
|
||||
" Test with a few lowercase diacritics.
|
||||
call assert_equal("AÀÁÂÃÄÅĀĂĄǍǞǠẢ", toupper("aàáâãäåāăąǎǟǡả"))
|
||||
call assert_equal("BḂḆ", toupper("bḃḇ"))
|
||||
call assert_equal("CÇĆĈĊČ", toupper("cçćĉċč"))
|
||||
call assert_equal("DĎĐḊḎḐ", toupper("dďđḋḏḑ"))
|
||||
call assert_equal("EÈÉÊËĒĔĖĘĚẺẼ", toupper("eèéêëēĕėęěẻẽ"))
|
||||
call assert_equal("FḞ", toupper("fḟ"))
|
||||
call assert_equal("GĜĞĠĢǤǦǴḠ", toupper("gĝğġģǥǧǵḡ"))
|
||||
call assert_equal("HĤĦḢḦḨẖ", toupper("hĥħḣḧḩẖ"))
|
||||
call assert_equal("IÌÍÎÏĨĪĬĮǏỈ", toupper("iìíîïĩīĭįǐỉ"))
|
||||
call assert_equal("JĴǰ", toupper("jĵǰ"))
|
||||
call assert_equal("KĶǨḰḴ", toupper("kķǩḱḵ"))
|
||||
call assert_equal("LĹĻĽĿŁḺ", toupper("lĺļľŀłḻ"))
|
||||
call assert_equal("MḾṀ ", toupper("mḿṁ "))
|
||||
call assert_equal("NÑŃŅŇʼnṄṈ", toupper("nñńņňʼnṅṉ"))
|
||||
call assert_equal("OÒÓÔÕÖØŌŎŐƠǑǪǬỎ", toupper("oòóôõöøōŏőơǒǫǭỏ"))
|
||||
call assert_equal("PṔṖ", toupper("pṕṗ"))
|
||||
call assert_equal("Q", toupper("q"))
|
||||
call assert_equal("RŔŖŘṘṞ", toupper("rŕŗřṙṟ"))
|
||||
call assert_equal("SŚŜŞŠṠ", toupper("sśŝşšṡ"))
|
||||
call assert_equal("TŢŤŦṪṮẗ", toupper("tţťŧṫṯẗ"))
|
||||
call assert_equal("UÙÚÛÜŨŪŬŮŰŲƯǓỦ", toupper("uùúûüũūŭůűųưǔủ"))
|
||||
call assert_equal("VṼ", toupper("vṽ"))
|
||||
call assert_equal("WŴẀẂẄẆẘ", toupper("wŵẁẃẅẇẘ"))
|
||||
call assert_equal("ẊẌ", toupper("ẋẍ"))
|
||||
call assert_equal("YÝŸŶẎẙỲỶỸ", toupper("yýÿŷẏẙỳỷỹ"))
|
||||
call assert_equal("ZŹŻŽƵẐẔ", toupper("zźżžƶẑẕ"))
|
||||
|
||||
" Test that uppercase diacritics, which should remain unchanged.
|
||||
call assert_equal("AÀÁÂÃÄÅĀĂĄǍǞǠẢ", toupper("AÀÁÂÃÄÅĀĂĄǍǞǠẢ"))
|
||||
call assert_equal("BḂḆ", toupper("BḂḆ"))
|
||||
call assert_equal("CÇĆĈĊČ", toupper("CÇĆĈĊČ"))
|
||||
call assert_equal("DĎĐḊḎḐ", toupper("DĎĐḊḎḐ"))
|
||||
call assert_equal("EÈÉÊËĒĔĖĘĚẺẼ", toupper("EÈÉÊËĒĔĖĘĚẺẼ"))
|
||||
call assert_equal("FḞ ", toupper("FḞ "))
|
||||
call assert_equal("GĜĞĠĢǤǦǴḠ", toupper("GĜĞĠĢǤǦǴḠ"))
|
||||
call assert_equal("HĤĦḢḦḨ", toupper("HĤĦḢḦḨ"))
|
||||
call assert_equal("IÌÍÎÏĨĪĬĮİǏỈ", toupper("IÌÍÎÏĨĪĬĮİǏỈ"))
|
||||
call assert_equal("JĴ", toupper("JĴ"))
|
||||
call assert_equal("KĶǨḰḴ", toupper("KĶǨḰḴ"))
|
||||
call assert_equal("LĹĻĽĿŁḺ", toupper("LĹĻĽĿŁḺ"))
|
||||
call assert_equal("MḾṀ", toupper("MḾṀ"))
|
||||
call assert_equal("NÑŃŅŇṄṈ", toupper("NÑŃŅŇṄṈ"))
|
||||
call assert_equal("OÒÓÔÕÖØŌŎŐƠǑǪǬỎ", toupper("OÒÓÔÕÖØŌŎŐƠǑǪǬỎ"))
|
||||
call assert_equal("PṔṖ", toupper("PṔṖ"))
|
||||
call assert_equal("Q", toupper("Q"))
|
||||
call assert_equal("RŔŖŘṘṞ", toupper("RŔŖŘṘṞ"))
|
||||
call assert_equal("SŚŜŞŠṠ", toupper("SŚŜŞŠṠ"))
|
||||
call assert_equal("TŢŤŦṪṮ", toupper("TŢŤŦṪṮ"))
|
||||
call assert_equal("UÙÚÛÜŨŪŬŮŰŲƯǓỦ", toupper("UÙÚÛÜŨŪŬŮŰŲƯǓỦ"))
|
||||
call assert_equal("VṼ", toupper("VṼ"))
|
||||
call assert_equal("WŴẀẂẄẆ", toupper("WŴẀẂẄẆ"))
|
||||
call assert_equal("XẊẌ", toupper("XẊẌ"))
|
||||
call assert_equal("YÝŶŸẎỲỶỸ", toupper("YÝŶŸẎỲỶỸ"))
|
||||
call assert_equal("ZŹŻŽƵẐẔ", toupper("ZŹŻŽƵẐẔ"))
|
||||
|
||||
call assert_equal("ⱥ ⱦ", tolower("Ⱥ Ⱦ"))
|
||||
endfunc
|
||||
|
||||
|
||||
|
|
|
@ -1606,6 +1606,40 @@ fun! Test_normal30_changecase()
|
|||
norm! V~
|
||||
call assert_equal('THIS IS A simple test: äüöss', getline('.'))
|
||||
|
||||
" Turkish ASCII turns to multi-byte. On Mac the Turkish locale is available
|
||||
" but toupper()/tolower() don't do the right thing.
|
||||
if !has('mac') && !has('osx')
|
||||
try
|
||||
lang tr_TR.UTF-8
|
||||
set casemap=
|
||||
call setline(1, 'iI')
|
||||
1normal gUU
|
||||
call assert_equal("\u0130I", getline(1))
|
||||
call assert_equal("\u0130I", toupper("iI"))
|
||||
|
||||
call setline(1, 'iI')
|
||||
1normal guu
|
||||
call assert_equal("i\u0131", getline(1))
|
||||
call assert_equal("i\u0131", tolower("iI"))
|
||||
|
||||
set casemap&
|
||||
call setline(1, 'iI')
|
||||
1normal gUU
|
||||
call assert_equal("II", getline(1))
|
||||
call assert_equal("II", toupper("iI"))
|
||||
|
||||
call setline(1, 'iI')
|
||||
1normal guu
|
||||
call assert_equal("ii", getline(1))
|
||||
call assert_equal("ii", tolower("iI"))
|
||||
|
||||
lang en_US.UTF-8
|
||||
catch /E197:/
|
||||
" can't use Turkish locale
|
||||
throw 'Skipped: Turkish locale not available'
|
||||
endtry
|
||||
endif
|
||||
|
||||
" clean up
|
||||
bw!
|
||||
endfunc
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
" test 'taglist' function
|
||||
|
||||
func Test_taglist()
|
||||
call writefile([
|
||||
\ "FFoo\tXfoo\t1",
|
||||
\ "FBar\tXfoo\t2",
|
||||
\ "BFoo\tXbar\t1",
|
||||
\ "BBar\tXbar\t2"
|
||||
\ ], 'Xtags')
|
||||
set tags=Xtags
|
||||
split Xtext
|
||||
|
||||
call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo"), {i, v -> v.name}))
|
||||
call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo", "Xtext"), {i, v -> v.name}))
|
||||
call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo", "Xfoo"), {i, v -> v.name}))
|
||||
call assert_equal(['BFoo', 'FFoo'], map(taglist("Foo", "Xbar"), {i, v -> v.name}))
|
||||
|
||||
call delete('Xtags')
|
||||
bwipe
|
||||
endfunc
|
||||
|
||||
func Test_taglist_native_etags()
|
||||
if !has('emacs_tags')
|
||||
return
|
||||
endif
|
||||
call writefile([
|
||||
\ "\x0c",
|
||||
\ "src/os_unix.c,13491",
|
||||
\ "set_signals(\x7f1335,32699",
|
||||
\ "reset_signals(\x7f1407,34136",
|
||||
\ ], 'Xtags')
|
||||
|
||||
set tags=Xtags
|
||||
|
||||
call assert_equal([['set_signals', '1335,32699'], ['reset_signals', '1407,34136']],
|
||||
\ map(taglist('set_signals'), {i, v -> [v.name, v.cmd]}))
|
||||
|
||||
call delete('Xtags')
|
||||
endfunc
|
||||
|
||||
func Test_taglist_ctags_etags()
|
||||
if !has('emacs_tags')
|
||||
return
|
||||
endif
|
||||
call writefile([
|
||||
\ "\x0c",
|
||||
\ "src/os_unix.c,13491",
|
||||
\ "set_signals(void)\x7fset_signals\x011335,32699",
|
||||
\ "reset_signals(void)\x7freset_signals\x011407,34136",
|
||||
\ ], 'Xtags')
|
||||
|
||||
set tags=Xtags
|
||||
|
||||
call assert_equal([['set_signals', '1335,32699'], ['reset_signals', '1407,34136']],
|
||||
\ map(taglist('set_signals'), {i, v -> [v.name, v.cmd]}))
|
||||
|
||||
call delete('Xtags')
|
||||
endfunc
|
|
@ -76,6 +76,7 @@
|
|||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
@ -966,12 +967,12 @@ static u_entry_T *unserialize_uep(bufinfo_T * bi, bool *error,
|
|||
uep->ue_lcount = undo_read_4c(bi);
|
||||
uep->ue_size = undo_read_4c(bi);
|
||||
|
||||
char_u **array;
|
||||
char_u **array = NULL;
|
||||
if (uep->ue_size > 0) {
|
||||
array = xmalloc(sizeof(char_u *) * (size_t)uep->ue_size);
|
||||
memset(array, 0, sizeof(char_u *) * (size_t)uep->ue_size);
|
||||
} else {
|
||||
array = NULL;
|
||||
if ((size_t)uep->ue_size < SIZE_MAX / sizeof(char_u *)) {
|
||||
array = xmalloc(sizeof(char_u *) * (size_t)uep->ue_size);
|
||||
memset(array, 0, sizeof(char_u *) * (size_t)uep->ue_size);
|
||||
}
|
||||
}
|
||||
uep->ue_array = array;
|
||||
|
||||
|
@ -1400,7 +1401,9 @@ void u_read_undo(char *name, char_u *hash, char_u *orig_name)
|
|||
// sequence numbers of the headers.
|
||||
// When there are no headers uhp_table is NULL.
|
||||
if (num_head > 0) {
|
||||
uhp_table = xmalloc((size_t)num_head * sizeof(u_header_T *));
|
||||
if ((size_t)num_head < SIZE_MAX / sizeof(*uhp_table)) {
|
||||
uhp_table = xmalloc((size_t)num_head * sizeof(*uhp_table));
|
||||
}
|
||||
}
|
||||
|
||||
long num_read_uhps = 0;
|
||||
|
|
|
@ -11,20 +11,16 @@
|
|||
#define RUNTIME_DIRNAME "runtime"
|
||||
/* end */
|
||||
|
||||
/* ============ the header file puzzle (ca. 50-100 pieces) ========= */
|
||||
|
||||
#ifdef HAVE_CONFIG_H /* GNU autoconf (or something else) was here */
|
||||
# include "auto/config.h"
|
||||
# define HAVE_PATHDEF
|
||||
#include "auto/config.h"
|
||||
#define HAVE_PATHDEF
|
||||
|
||||
/*
|
||||
* Check if configure correctly managed to find sizeof(int). If this failed,
|
||||
* it becomes zero. This is likely a problem of not being able to run the
|
||||
* test program. Other items from configure may also be wrong then!
|
||||
*/
|
||||
# if (SIZEOF_INT == 0)
|
||||
Error: configure did not run properly.Check auto/config.log.
|
||||
# endif
|
||||
#if (SIZEOF_INT == 0)
|
||||
# error Configure did not run properly.
|
||||
#endif
|
||||
|
||||
#include "nvim/os/os_defs.h" /* bring lots of system header files */
|
||||
|
@ -46,11 +42,6 @@ enum { NUMBUFLEN = 65 };
|
|||
#include "nvim/keymap.h"
|
||||
#include "nvim/macros.h"
|
||||
|
||||
|
||||
|
||||
|
||||
/* ================ end of the header file puzzle =============== */
|
||||
|
||||
#include "nvim/gettext.h"
|
||||
|
||||
/* special attribute addition: Put message in history */
|
||||
|
|
|
@ -5,7 +5,8 @@ for p in ("${TEST_INCLUDE_DIRS}" .. ";"):gmatch("[^;]+") do
|
|||
table.insert(module.include_paths, p)
|
||||
end
|
||||
|
||||
module.test_include_path = "${CMAKE_BINARY_DIR}/test/includes/post"
|
||||
module.test_build_dir = "${CMAKE_BINARY_DIR}"
|
||||
module.test_include_path = module.test_build_dir .. "/test/includes/post"
|
||||
module.test_libnvim_path = "${TEST_LIBNVIM_PATH}"
|
||||
module.test_source_path = "${CMAKE_SOURCE_DIR}"
|
||||
module.test_lua_prg = "${LUA_PRG}"
|
||||
|
|
|
@ -5,7 +5,7 @@ local curbufmeths, ok = helpers.curbufmeths, helpers.ok
|
|||
local funcs = helpers.funcs
|
||||
local request = helpers.request
|
||||
local exc_exec = helpers.exc_exec
|
||||
local execute = helpers.execute
|
||||
local feed_command = helpers.feed_command
|
||||
local insert = helpers.insert
|
||||
local NIL = helpers.NIL
|
||||
local meth_pcall = helpers.meth_pcall
|
||||
|
@ -246,7 +246,7 @@ describe('api/buf', function()
|
|||
end)
|
||||
|
||||
it("set_line on alternate buffer does not access invalid line (E315)", function()
|
||||
execute('set hidden')
|
||||
feed_command('set hidden')
|
||||
insert('Initial file')
|
||||
command('enew')
|
||||
insert([[
|
||||
|
@ -257,7 +257,7 @@ describe('api/buf', function()
|
|||
The
|
||||
Other
|
||||
Buffer]])
|
||||
execute('$')
|
||||
feed_command('$')
|
||||
local retval = exc_exec("call nvim_buf_set_lines(1, 0, 1, v:false, ['test'])")
|
||||
eq(0, retval)
|
||||
end)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local eq, clear, eval, execute, nvim, next_message =
|
||||
helpers.eq, helpers.clear, helpers.eval, helpers.execute, helpers.nvim,
|
||||
local eq, clear, eval, command, nvim, next_message =
|
||||
helpers.eq, helpers.clear, helpers.eval, helpers.command, helpers.nvim,
|
||||
helpers.next_message
|
||||
local meths = helpers.meths
|
||||
|
||||
|
@ -16,8 +16,8 @@ describe('notify', function()
|
|||
it('sends the notification/args to the corresponding channel', function()
|
||||
eval('rpcnotify('..channel..', "test-event", 1, 2, 3)')
|
||||
eq({'notification', 'test-event', {1, 2, 3}}, next_message())
|
||||
execute('au FileType lua call rpcnotify('..channel..', "lua!")')
|
||||
execute('set filetype=lua')
|
||||
command('au FileType lua call rpcnotify('..channel..', "lua!")')
|
||||
command('set filetype=lua')
|
||||
eq({'notification', 'lua!', {}}, next_message())
|
||||
end)
|
||||
end)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
-- Test server -> client RPC scenarios. Note: unlike `rpcnotify`, to evaluate
|
||||
-- `rpcrequest` calls we need the client event loop to be running.
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local Paths = require('test.config.paths')
|
||||
|
||||
local clear, nvim, eval = helpers.clear, helpers.nvim, helpers.eval
|
||||
local eq, neq, run, stop = helpers.eq, helpers.neq, helpers.run, helpers.stop
|
||||
local nvim_prog, command, funcs = helpers.nvim_prog, helpers.command, helpers.funcs
|
||||
|
@ -200,7 +202,7 @@ describe('server -> client', function()
|
|||
\ 'rpc': v:true
|
||||
\ }
|
||||
]])
|
||||
local lua_prog = arg[-1]
|
||||
local lua_prog = Paths.test_lua_prg
|
||||
meths.set_var("args", {lua_prog, 'test/functional/api/rpc_fixture.lua'})
|
||||
jobid = eval("jobstart(g:args, g:job_opts)")
|
||||
neq(0, 'jobid')
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
local helpers = require('test.functional.helpers')(after_each)
|
||||
|
||||
local clear = helpers.clear
|
||||
local command = helpers.command
|
||||
local eq = helpers.eq
|
||||
local eval = helpers.eval
|
||||
local clear = helpers.clear
|
||||
local meths = helpers.meths
|
||||
local expect = helpers.expect
|
||||
local command = helpers.command
|
||||
local exc_exec = helpers.exc_exec
|
||||
local curbufmeths = helpers.curbufmeths
|
||||
|
||||
describe('autocmds:', function()
|
||||
before_each(clear)
|
||||
|
@ -33,4 +37,22 @@ describe('autocmds:', function()
|
|||
it('v:vim_did_enter is 1 after VimEnter', function()
|
||||
eq(1, eval('v:vim_did_enter'))
|
||||
end)
|
||||
|
||||
describe('BufLeave autocommand', function()
|
||||
it('can wipe out the buffer created by :edit which triggered autocmd',
|
||||
function()
|
||||
meths.set_option('hidden', true)
|
||||
curbufmeths.set_lines(0, 1, false, {
|
||||
'start of test file xx',
|
||||
'end of test file xx'})
|
||||
|
||||
command('autocmd BufLeave * bwipeout yy')
|
||||
eq('Vim(edit):E143: Autocommands unexpectedly deleted new buffer yy',
|
||||
exc_exec('edit yy'))
|
||||
|
||||
expect([[
|
||||
start of test file xx
|
||||
end of test file xx]])
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
|
|
@ -4,7 +4,6 @@ local clear = helpers.clear
|
|||
local command = helpers.command
|
||||
local eq = helpers.eq
|
||||
local eval = helpers.eval
|
||||
local execute = helpers.execute
|
||||
local request = helpers.request
|
||||
local source = helpers.source
|
||||
|
||||
|
@ -28,7 +27,7 @@ describe('autocmd BufEnter', function()
|
|||
endtry
|
||||
endfunction
|
||||
]])
|
||||
execute("call Test()")
|
||||
command("call Test()")
|
||||
eq(1, eval("exists('g:dir_bufenter')")) -- Did BufEnter for the directory.
|
||||
eq(2, eval("bufnr('%')")) -- Switched to the dir buffer.
|
||||
end)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local clear, eval, eq = helpers.clear, helpers.eval, helpers.eq
|
||||
local feed, execute, expect, command = helpers.feed, helpers.execute, helpers.expect, helpers.command
|
||||
local feed, command, expect = helpers.feed, helpers.command, helpers.expect
|
||||
local curbufmeths, funcs, neq = helpers.curbufmeths, helpers.funcs, helpers.neq
|
||||
|
||||
describe('TextYankPost', function()
|
||||
|
@ -8,11 +8,11 @@ describe('TextYankPost', function()
|
|||
clear()
|
||||
|
||||
-- emulate the clipboard so system clipboard isn't affected
|
||||
execute('let &rtp = "test/functional/fixtures,".&rtp')
|
||||
command('let &rtp = "test/functional/fixtures,".&rtp')
|
||||
|
||||
execute('let g:count = 0')
|
||||
execute('autocmd TextYankPost * let g:event = copy(v:event)')
|
||||
execute('autocmd TextYankPost * let g:count += 1')
|
||||
command('let g:count = 0')
|
||||
command('autocmd TextYankPost * let g:event = copy(v:event)')
|
||||
command('autocmd TextYankPost * let g:count += 1')
|
||||
|
||||
curbufmeths.set_lines(0, -1, true, {
|
||||
'foo\0bar',
|
||||
|
@ -61,27 +61,27 @@ describe('TextYankPost', function()
|
|||
regtype = 'V'
|
||||
}, eval('g:event'))
|
||||
|
||||
execute('set debug=msg')
|
||||
command('set debug=msg')
|
||||
-- the regcontents should not be changed without copy.
|
||||
local status, err = pcall(command,'call extend(g:event.regcontents, ["more text"])')
|
||||
eq(status,false)
|
||||
neq(nil, string.find(err, ':E742:'))
|
||||
|
||||
-- can't mutate keys inside the autocommand
|
||||
execute('autocmd! TextYankPost * let v:event.regcontents = 0')
|
||||
command('autocmd! TextYankPost * let v:event.regcontents = 0')
|
||||
status, err = pcall(command,'normal yy')
|
||||
eq(status,false)
|
||||
neq(nil, string.find(err, ':E46:'))
|
||||
|
||||
-- can't add keys inside the autocommand
|
||||
execute('autocmd! TextYankPost * let v:event.mykey = 0')
|
||||
command('autocmd! TextYankPost * let v:event.mykey = 0')
|
||||
status, err = pcall(command,'normal yy')
|
||||
eq(status,false)
|
||||
neq(nil, string.find(err, ':E742:'))
|
||||
end)
|
||||
|
||||
it('is not invoked recursively', function()
|
||||
execute('autocmd TextYankPost * normal "+yy')
|
||||
command('autocmd TextYankPost * normal "+yy')
|
||||
feed('yy')
|
||||
eq({
|
||||
operator = 'y',
|
||||
|
@ -134,7 +134,7 @@ describe('TextYankPost', function()
|
|||
feed('"_yy')
|
||||
eq(0, eval('g:count'))
|
||||
|
||||
execute('delete _')
|
||||
command('delete _')
|
||||
eq(0, eval('g:count'))
|
||||
end)
|
||||
|
||||
|
@ -155,7 +155,7 @@ describe('TextYankPost', function()
|
|||
regtype = 'V'
|
||||
}, eval('g:event'))
|
||||
|
||||
execute("set clipboard=unnamed")
|
||||
command("set clipboard=unnamed")
|
||||
|
||||
-- regname still shows the name the user requested
|
||||
feed('yy')
|
||||
|
@ -176,7 +176,7 @@ describe('TextYankPost', function()
|
|||
end)
|
||||
|
||||
it('works with Ex commands', function()
|
||||
execute('1delete +')
|
||||
command('1delete +')
|
||||
eq({
|
||||
operator = 'd',
|
||||
regcontents = { 'foo\nbar' },
|
||||
|
@ -185,7 +185,7 @@ describe('TextYankPost', function()
|
|||
}, eval('g:event'))
|
||||
eq(1, eval('g:count'))
|
||||
|
||||
execute('yank')
|
||||
command('yank')
|
||||
eq({
|
||||
operator = 'y',
|
||||
regcontents = { 'baz text' },
|
||||
|
@ -194,7 +194,7 @@ describe('TextYankPost', function()
|
|||
}, eval('g:event'))
|
||||
eq(2, eval('g:count'))
|
||||
|
||||
execute('normal yw')
|
||||
command('normal yw')
|
||||
eq({
|
||||
operator = 'y',
|
||||
regcontents = { 'baz ' },
|
||||
|
@ -203,7 +203,7 @@ describe('TextYankPost', function()
|
|||
}, eval('g:event'))
|
||||
eq(3, eval('g:count'))
|
||||
|
||||
execute('normal! dd')
|
||||
command('normal! dd')
|
||||
eq({
|
||||
operator = 'd',
|
||||
regcontents = { 'baz text' },
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local Screen = require('test.functional.ui.screen')
|
||||
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
|
||||
local execute, expect, eq, eval = helpers.execute, helpers.expect, helpers.eq, helpers.eval
|
||||
local feed_command, expect, eq, eval = helpers.feed_command, helpers.expect, helpers.eq, helpers.eval
|
||||
|
||||
local function basic_register_test(noblock)
|
||||
insert("some words")
|
||||
|
@ -95,7 +95,7 @@ describe('clipboard usage', function()
|
|||
|
||||
before_each(function()
|
||||
reset()
|
||||
execute('call getreg("*")') -- force load of provider
|
||||
feed_command('call getreg("*")') -- force load of provider
|
||||
end)
|
||||
|
||||
it('has independent "* and unnamed registers per default', function()
|
||||
|
@ -140,8 +140,8 @@ describe('clipboard usage', function()
|
|||
end)
|
||||
|
||||
it('support autodectection of regtype', function()
|
||||
execute("let g:test_clip['*'] = ['linewise stuff','']")
|
||||
execute("let g:test_clip['+'] = ['charwise','stuff']")
|
||||
feed_command("let g:test_clip['*'] = ['linewise stuff','']")
|
||||
feed_command("let g:test_clip['+'] = ['charwise','stuff']")
|
||||
eq("V", eval("getregtype('*')"))
|
||||
eq("v", eval("getregtype('+')"))
|
||||
insert("just some text")
|
||||
|
@ -156,7 +156,7 @@ describe('clipboard usage', function()
|
|||
insert([[
|
||||
much
|
||||
text]])
|
||||
execute("let g:test_clip['*'] = [['very','block'],'b']")
|
||||
feed_command("let g:test_clip['*'] = [['very','block'],'b']")
|
||||
feed('gg"*P')
|
||||
expect([[
|
||||
very much
|
||||
|
@ -170,15 +170,15 @@ describe('clipboard usage', function()
|
|||
end)
|
||||
|
||||
it('supports setreg', function()
|
||||
execute('call setreg("*", "setted\\ntext", "c")')
|
||||
execute('call setreg("+", "explicitly\\nlines", "l")')
|
||||
feed_command('call setreg("*", "setted\\ntext", "c")')
|
||||
feed_command('call setreg("+", "explicitly\\nlines", "l")')
|
||||
feed('"+P"*p')
|
||||
expect([[
|
||||
esetted
|
||||
textxplicitly
|
||||
lines
|
||||
]])
|
||||
execute('call setreg("+", "blocky\\nindeed", "b")')
|
||||
feed_command('call setreg("+", "blocky\\nindeed", "b")')
|
||||
feed('"+p')
|
||||
expect([[
|
||||
esblockyetted
|
||||
|
@ -188,13 +188,13 @@ describe('clipboard usage', function()
|
|||
end)
|
||||
|
||||
it('supports let @+ (issue #1427)', function()
|
||||
execute("let @+ = 'some'")
|
||||
execute("let @* = ' other stuff'")
|
||||
feed_command("let @+ = 'some'")
|
||||
feed_command("let @* = ' other stuff'")
|
||||
eq({{'some'}, 'v'}, eval("g:test_clip['+']"))
|
||||
eq({{' other stuff'}, 'v'}, eval("g:test_clip['*']"))
|
||||
feed('"+p"*p')
|
||||
expect('some other stuff')
|
||||
execute("let @+ .= ' more'")
|
||||
feed_command("let @+ .= ' more'")
|
||||
feed('dd"+p')
|
||||
expect('some more')
|
||||
end)
|
||||
|
@ -202,7 +202,7 @@ describe('clipboard usage', function()
|
|||
it('pastes unnamed register if the provider fails', function()
|
||||
insert('the text')
|
||||
feed('yy')
|
||||
execute("let g:cliperror = 1")
|
||||
feed_command("let g:cliperror = 1")
|
||||
feed('"*p')
|
||||
expect([[
|
||||
the text
|
||||
|
@ -214,7 +214,7 @@ describe('clipboard usage', function()
|
|||
-- the basic behavior of unnamed register should be the same
|
||||
-- even when handled by clipboard provider
|
||||
before_each(function()
|
||||
execute('set clipboard=unnamed')
|
||||
feed_command('set clipboard=unnamed')
|
||||
end)
|
||||
|
||||
it('works', function()
|
||||
|
@ -222,7 +222,7 @@ describe('clipboard usage', function()
|
|||
end)
|
||||
|
||||
it('works with pure text clipboard', function()
|
||||
execute("let g:cliplossy = 1")
|
||||
feed_command("let g:cliplossy = 1")
|
||||
-- expect failure for block mode
|
||||
basic_register_test(true)
|
||||
end)
|
||||
|
@ -237,7 +237,7 @@ describe('clipboard usage', function()
|
|||
-- "+ shouldn't have changed
|
||||
eq({''}, eval("g:test_clip['+']"))
|
||||
|
||||
execute("let g:test_clip['*'] = ['linewise stuff','']")
|
||||
feed_command("let g:test_clip['*'] = ['linewise stuff','']")
|
||||
feed('p')
|
||||
expect([[
|
||||
words
|
||||
|
@ -247,7 +247,7 @@ describe('clipboard usage', function()
|
|||
it('does not clobber "0 when pasting', function()
|
||||
insert('a line')
|
||||
feed('yy')
|
||||
execute("let g:test_clip['*'] = ['b line','']")
|
||||
feed_command("let g:test_clip['*'] = ['b line','']")
|
||||
feed('"0pp"0p')
|
||||
expect([[
|
||||
a line
|
||||
|
@ -258,20 +258,20 @@ describe('clipboard usage', function()
|
|||
|
||||
it('supports v:register and getreg() without parameters', function()
|
||||
eq('*', eval('v:register'))
|
||||
execute("let g:test_clip['*'] = [['some block',''], 'b']")
|
||||
feed_command("let g:test_clip['*'] = [['some block',''], 'b']")
|
||||
eq('some block', eval('getreg()'))
|
||||
eq('\02210', eval('getregtype()'))
|
||||
end)
|
||||
|
||||
it('yanks visual selection when pasting', function()
|
||||
insert("indeed visual")
|
||||
execute("let g:test_clip['*'] = [['clipboard'], 'c']")
|
||||
feed_command("let g:test_clip['*'] = [['clipboard'], 'c']")
|
||||
feed("viwp")
|
||||
eq({{'visual'}, 'v'}, eval("g:test_clip['*']"))
|
||||
expect("indeed clipboard")
|
||||
|
||||
-- explicit "* should do the same
|
||||
execute("let g:test_clip['*'] = [['star'], 'c']")
|
||||
feed_command("let g:test_clip['*'] = [['star'], 'c']")
|
||||
feed('viw"*p')
|
||||
eq({{'clipboard'}, 'v'}, eval("g:test_clip['*']"))
|
||||
expect("indeed star")
|
||||
|
@ -280,7 +280,7 @@ describe('clipboard usage', function()
|
|||
it('unamed operations work even if the provider fails', function()
|
||||
insert('the text')
|
||||
feed('yy')
|
||||
execute("let g:cliperror = 1")
|
||||
feed_command("let g:cliperror = 1")
|
||||
feed('p')
|
||||
expect([[
|
||||
the text
|
||||
|
@ -294,11 +294,11 @@ describe('clipboard usage', function()
|
|||
match
|
||||
text
|
||||
]])
|
||||
execute('g/match/d')
|
||||
feed_command('g/match/d')
|
||||
eq('match\n', eval('getreg("*")'))
|
||||
feed('u')
|
||||
eval('setreg("*", "---")')
|
||||
execute('g/test/')
|
||||
feed_command('g/test/')
|
||||
feed('<esc>')
|
||||
eq('---', eval('getreg("*")'))
|
||||
end)
|
||||
|
@ -307,7 +307,7 @@ describe('clipboard usage', function()
|
|||
|
||||
describe('with clipboard=unnamedplus', function()
|
||||
before_each(function()
|
||||
execute('set clipboard=unnamedplus')
|
||||
feed_command('set clipboard=unnamedplus')
|
||||
end)
|
||||
|
||||
it('links the "+ and unnamed registers', function()
|
||||
|
@ -320,13 +320,13 @@ describe('clipboard usage', function()
|
|||
-- "* shouldn't have changed
|
||||
eq({''}, eval("g:test_clip['*']"))
|
||||
|
||||
execute("let g:test_clip['+'] = ['three']")
|
||||
feed_command("let g:test_clip['+'] = ['three']")
|
||||
feed('p')
|
||||
expect('twothree')
|
||||
end)
|
||||
|
||||
it('and unnamed, yanks to both', function()
|
||||
execute('set clipboard=unnamedplus,unnamed')
|
||||
feed_command('set clipboard=unnamedplus,unnamed')
|
||||
insert([[
|
||||
really unnamed
|
||||
text]])
|
||||
|
@ -340,8 +340,8 @@ describe('clipboard usage', function()
|
|||
|
||||
-- unnamedplus takes predecence when pasting
|
||||
eq('+', eval('v:register'))
|
||||
execute("let g:test_clip['+'] = ['the plus','']")
|
||||
execute("let g:test_clip['*'] = ['the star','']")
|
||||
feed_command("let g:test_clip['+'] = ['the plus','']")
|
||||
feed_command("let g:test_clip['*'] = ['the star','']")
|
||||
feed("p")
|
||||
expect([[
|
||||
text
|
||||
|
@ -356,11 +356,11 @@ describe('clipboard usage', function()
|
|||
match
|
||||
text
|
||||
]])
|
||||
execute('g/match/d')
|
||||
feed_command('g/match/d')
|
||||
eq('match\n', eval('getreg("+")'))
|
||||
feed('u')
|
||||
eval('setreg("+", "---")')
|
||||
execute('g/test/')
|
||||
feed_command('g/test/')
|
||||
feed('<esc>')
|
||||
eq('---', eval('getreg("+")'))
|
||||
end)
|
||||
|
@ -375,13 +375,13 @@ describe('clipboard usage', function()
|
|||
|
||||
it('supports :put', function()
|
||||
insert("a line")
|
||||
execute("let g:test_clip['*'] = ['some text']")
|
||||
execute("let g:test_clip['+'] = ['more', 'text', '']")
|
||||
execute(":put *")
|
||||
feed_command("let g:test_clip['*'] = ['some text']")
|
||||
feed_command("let g:test_clip['+'] = ['more', 'text', '']")
|
||||
feed_command(":put *")
|
||||
expect([[
|
||||
a line
|
||||
some text]])
|
||||
execute(":put +")
|
||||
feed_command(":put +")
|
||||
expect([[
|
||||
a line
|
||||
some text
|
||||
|
@ -392,9 +392,9 @@ describe('clipboard usage', function()
|
|||
it('supports "+ and "* in registers', function()
|
||||
local screen = Screen.new(60, 10)
|
||||
screen:attach()
|
||||
execute("let g:test_clip['*'] = ['some', 'star data','']")
|
||||
execute("let g:test_clip['+'] = ['such', 'plus', 'stuff']")
|
||||
execute("registers")
|
||||
feed_command("let g:test_clip['*'] = ['some', 'star data','']")
|
||||
feed_command("let g:test_clip['+'] = ['such', 'plus', 'stuff']")
|
||||
feed_command("registers")
|
||||
screen:expect([[
|
||||
~ |
|
||||
~ |
|
||||
|
@ -418,17 +418,17 @@ describe('clipboard usage', function()
|
|||
insert('s/s/t/')
|
||||
feed('gg"*y$:<c-r>*<cr>')
|
||||
expect('t/s/t/')
|
||||
execute("let g:test_clip['*'] = ['s/s/u']")
|
||||
feed_command("let g:test_clip['*'] = ['s/s/u']")
|
||||
feed(':<c-r>*<cr>')
|
||||
expect('t/u/t/')
|
||||
end)
|
||||
|
||||
it('supports :redir @*>', function()
|
||||
execute("let g:test_clip['*'] = ['stuff']")
|
||||
execute('redir @*>')
|
||||
feed_command("let g:test_clip['*'] = ['stuff']")
|
||||
feed_command('redir @*>')
|
||||
-- it is made empty
|
||||
eq({{''}, 'v'}, eval("g:test_clip['*']"))
|
||||
execute('let g:test = doesnotexist')
|
||||
feed_command('let g:test = doesnotexist')
|
||||
feed('<cr>')
|
||||
eq({{
|
||||
'',
|
||||
|
@ -436,7 +436,7 @@ describe('clipboard usage', function()
|
|||
'E121: Undefined variable: doesnotexist',
|
||||
'E15: Invalid expression: doesnotexist',
|
||||
}, 'v'}, eval("g:test_clip['*']"))
|
||||
execute(':echo "Howdy!"')
|
||||
feed_command(':echo "Howdy!"')
|
||||
eq({{
|
||||
'',
|
||||
'',
|
||||
|
@ -448,7 +448,7 @@ describe('clipboard usage', function()
|
|||
end)
|
||||
|
||||
it('handles middleclick correctly', function()
|
||||
execute('set mouse=a')
|
||||
feed_command('set mouse=a')
|
||||
|
||||
local screen = Screen.new(30, 5)
|
||||
screen:attach()
|
||||
|
@ -471,7 +471,7 @@ describe('clipboard usage', function()
|
|||
the a target]])
|
||||
|
||||
-- on error, fall back to unnamed register
|
||||
execute("let g:cliperror = 1")
|
||||
feed_command("let g:cliperror = 1")
|
||||
feed('<MiddleMouse><6,1>')
|
||||
expect([[
|
||||
the source
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local clear, eq, eval, exc_exec, execute, feed, insert, neq, next_msg, nvim,
|
||||
local clear, eq, eval, exc_exec, feed_command, feed, insert, neq, next_msg, nvim,
|
||||
nvim_dir, ok, source, write_file, mkdir, rmdir = helpers.clear,
|
||||
helpers.eq, helpers.eval, helpers.exc_exec, helpers.execute, helpers.feed,
|
||||
helpers.eq, helpers.eval, helpers.exc_exec, helpers.feed_command, helpers.feed,
|
||||
helpers.insert, helpers.neq, helpers.next_message, helpers.nvim,
|
||||
helpers.nvim_dir, helpers.ok, helpers.source,
|
||||
helpers.write_file, helpers.mkdir, helpers.rmdir
|
||||
|
@ -94,7 +94,7 @@ describe('jobs', function()
|
|||
|
||||
it('returns 0 when it fails to start', function()
|
||||
eq("", eval("v:errmsg"))
|
||||
execute("let g:test_jobid = jobstart([])")
|
||||
feed_command("let g:test_jobid = jobstart([])")
|
||||
eq(0, eval("g:test_jobid"))
|
||||
eq("E474:", string.match(eval("v:errmsg"), "E%d*:"))
|
||||
end)
|
||||
|
@ -470,7 +470,7 @@ describe('jobs', function()
|
|||
end)
|
||||
|
||||
it('will return -2 when interrupted', function()
|
||||
execute('call rpcnotify(g:channel, "ready") | '..
|
||||
feed_command('call rpcnotify(g:channel, "ready") | '..
|
||||
'call rpcnotify(g:channel, "wait", '..
|
||||
'jobwait([jobstart("sleep 10; exit 55")]))')
|
||||
eq({'notification', 'ready', {}}, next_msg())
|
||||
|
@ -514,7 +514,7 @@ describe('jobs', function()
|
|||
\ ])
|
||||
endfunction
|
||||
]])
|
||||
execute('call Run()')
|
||||
feed_command('call Run()')
|
||||
local r
|
||||
for i = 10, 1, -1 do
|
||||
r = next_msg()
|
||||
|
@ -668,7 +668,7 @@ describe("pty process teardown", function()
|
|||
it("does not prevent/delay exit. #4798 #4900", function()
|
||||
if helpers.pending_win32(pending) then return end
|
||||
-- Use a nested nvim (in :term) to test without --headless.
|
||||
execute(":terminal '"..helpers.nvim_prog
|
||||
feed_command(":terminal '"..helpers.nvim_prog
|
||||
-- Use :term again in the _nested_ nvim to get a PTY process.
|
||||
-- Use `sleep` to simulate a long-running child of the PTY.
|
||||
.."' +terminal +'!(sleep 300 &)' +qa")
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local Screen = require('test.functional.ui.screen')
|
||||
local lfs = require('lfs')
|
||||
local neq, eq, execute = helpers.neq, helpers.eq, helpers.execute
|
||||
local neq, eq, command = helpers.neq, helpers.eq, helpers.command
|
||||
local clear, curbufmeths = helpers.clear, helpers.curbufmeths
|
||||
local exc_exec, expect, eval = helpers.exc_exec, helpers.expect, helpers.eval
|
||||
local insert = helpers.insert
|
||||
|
@ -10,17 +10,17 @@ describe('api functions', function()
|
|||
before_each(clear)
|
||||
|
||||
it("work", function()
|
||||
execute("call nvim_command('let g:test = 1')")
|
||||
command("call nvim_command('let g:test = 1')")
|
||||
eq(1, eval("nvim_get_var('test')"))
|
||||
|
||||
local buf = eval("nvim_get_current_buf()")
|
||||
execute("call nvim_buf_set_lines("..buf..", 0, -1, v:true, ['aa', 'bb'])")
|
||||
command("call nvim_buf_set_lines("..buf..", 0, -1, v:true, ['aa', 'bb'])")
|
||||
expect([[
|
||||
aa
|
||||
bb]])
|
||||
|
||||
execute("call nvim_win_set_cursor(0, [1, 1])")
|
||||
execute("call nvim_input('ax<esc>')")
|
||||
command("call nvim_win_set_cursor(0, [1, 1])")
|
||||
command("call nvim_input('ax<esc>')")
|
||||
expect([[
|
||||
aax
|
||||
bb]])
|
||||
|
@ -57,7 +57,7 @@ describe('api functions', function()
|
|||
eq(bnr, bhnd)
|
||||
eq(wid, whnd)
|
||||
|
||||
execute("new") -- creates new buffer and new window
|
||||
command("new") -- creates new buffer and new window
|
||||
local bnr2 = eval("bufnr('')")
|
||||
local bhnd2 = eval("nvim_get_current_buf()")
|
||||
local wid2 = eval("win_getid()")
|
||||
|
@ -69,7 +69,7 @@ describe('api functions', function()
|
|||
-- 0 is synonymous to the current buffer
|
||||
eq(bnr2, eval("nvim_buf_get_number(0)"))
|
||||
|
||||
execute("bn") -- show old buffer in new window
|
||||
command("bn") -- show old buffer in new window
|
||||
eq(bnr, eval("nvim_get_current_buf()"))
|
||||
eq(bnr, eval("bufnr('')"))
|
||||
eq(bnr, eval("nvim_buf_get_number(0)"))
|
||||
|
@ -81,7 +81,7 @@ describe('api functions', function()
|
|||
curbufmeths.set_lines(0, -1, true, {"aa\0", "b\0b"})
|
||||
eq({'aa\n', 'b\nb'}, eval("nvim_buf_get_lines(0, 0, -1, 1)"))
|
||||
|
||||
execute('call nvim_buf_set_lines(0, 1, 2, v:true, ["xx", "\\nyy"])')
|
||||
command('call nvim_buf_set_lines(0, 1, 2, v:true, ["xx", "\\nyy"])')
|
||||
eq({'aa\0', 'xx', '\0yy'}, curbufmeths.get_lines(0, -1, 1))
|
||||
end)
|
||||
|
||||
|
@ -124,9 +124,9 @@ describe('api functions', function()
|
|||
[5] = {bold = true, foreground = Screen.colors.Blue},
|
||||
})
|
||||
|
||||
execute("set ft=vim")
|
||||
execute("let &rtp='build/runtime/,'.&rtp")
|
||||
execute("syntax on")
|
||||
command("set ft=vim")
|
||||
command("let &rtp='build/runtime/,'.&rtp")
|
||||
command("syntax on")
|
||||
insert([[
|
||||
call bufnr('%')
|
||||
call nvim_input('typing...')
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
local lfs = require('lfs')
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local clear, execute, eval, eq = helpers.clear, helpers.execute, helpers.eval, helpers.eq
|
||||
local clear, command, eval, eq = helpers.clear, helpers.command, helpers.eval, helpers.eq
|
||||
|
||||
before_each(function()
|
||||
clear()
|
||||
lfs.mkdir('test-glob')
|
||||
|
||||
-- Long path might cause "Press ENTER" prompt; use :silent to avoid it.
|
||||
execute('silent cd test-glob')
|
||||
command('silent cd test-glob')
|
||||
end)
|
||||
|
||||
after_each(function()
|
||||
|
|
|
@ -4,16 +4,17 @@ local funcs = helpers.funcs
|
|||
local meths = helpers.meths
|
||||
local eq = helpers.eq
|
||||
local eval = helpers.eval
|
||||
local execute = helpers.execute
|
||||
local command = helpers.command
|
||||
local exc_exec = helpers.exc_exec
|
||||
local redir_exec = helpers.redir_exec
|
||||
local NIL = helpers.NIL
|
||||
local source = helpers.source
|
||||
|
||||
describe('json_decode() function', function()
|
||||
local restart = function(...)
|
||||
clear(...)
|
||||
execute('language C')
|
||||
execute([[
|
||||
source([[
|
||||
language C
|
||||
function Eq(exp, act)
|
||||
let act = a:act
|
||||
let exp = a:exp
|
||||
|
@ -45,8 +46,6 @@ describe('json_decode() function', function()
|
|||
endif
|
||||
return 1
|
||||
endfunction
|
||||
]])
|
||||
execute([[
|
||||
function EvalEq(exp, act_expr)
|
||||
let act = eval(a:act_expr)
|
||||
if Eq(a:exp, act)
|
||||
|
@ -441,7 +440,7 @@ describe('json_decode() function', function()
|
|||
local sp_decode_eq = function(expected, json)
|
||||
meths.set_var('__json', json)
|
||||
speq(expected, 'json_decode(g:__json)')
|
||||
execute('unlet! g:__json')
|
||||
command('unlet! g:__json')
|
||||
end
|
||||
|
||||
it('parses strings with NUL properly', function()
|
||||
|
@ -527,7 +526,7 @@ end)
|
|||
describe('json_encode() function', function()
|
||||
before_each(function()
|
||||
clear()
|
||||
execute('language C')
|
||||
command('language C')
|
||||
end)
|
||||
|
||||
it('dumps strings', function()
|
||||
|
@ -576,94 +575,94 @@ describe('json_encode() function', function()
|
|||
|
||||
it('cannot dump generic mapping with generic mapping keys and values',
|
||||
function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
execute('let todumpv1 = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
execute('let todumpv2 = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
execute('call add(todump._VAL, [todumpv1, todumpv2])')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
command('let todumpv1 = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
command('let todumpv2 = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
command('call add(todump._VAL, [todumpv1, todumpv2])')
|
||||
eq('Vim(call):E474: Invalid key in special dictionary', exc_exec('call json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('cannot dump generic mapping with ext key', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.ext, "_VAL": [5, ["",""]]}')
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.ext, "_VAL": [5, ["",""]]}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}')
|
||||
eq('Vim(call):E474: Invalid key in special dictionary', exc_exec('call json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('cannot dump generic mapping with array key', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": [5, [""]]}')
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": [5, [""]]}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}')
|
||||
eq('Vim(call):E474: Invalid key in special dictionary', exc_exec('call json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('cannot dump generic mapping with UINT64_MAX key', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.integer}')
|
||||
execute('let todump._VAL = [1, 3, 0x7FFFFFFF, 0x7FFFFFFF]')
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.integer}')
|
||||
command('let todump._VAL = [1, 3, 0x7FFFFFFF, 0x7FFFFFFF]')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}')
|
||||
eq('Vim(call):E474: Invalid key in special dictionary', exc_exec('call json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('cannot dump generic mapping with floating-point key', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.float, "_VAL": 0.125}')
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.float, "_VAL": 0.125}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}')
|
||||
eq('Vim(call):E474: Invalid key in special dictionary', exc_exec('call json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('can dump generic mapping with STR special key and NUL', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.string, "_VAL": ["\\n"]}')
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.string, "_VAL": ["\\n"]}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}')
|
||||
eq('{"\\u0000": 1}', eval('json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('can dump generic mapping with BIN special key and NUL', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.binary, "_VAL": ["\\n"]}')
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.binary, "_VAL": ["\\n"]}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}')
|
||||
eq('{"\\u0000": 1}', eval('json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('can dump STR special mapping with NUL and NL', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.string, "_VAL": ["\\n", ""]}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.string, "_VAL": ["\\n", ""]}')
|
||||
eq('"\\u0000\\n"', eval('json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('can dump BIN special mapping with NUL and NL', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.binary, "_VAL": ["\\n", ""]}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.binary, "_VAL": ["\\n", ""]}')
|
||||
eq('"\\u0000\\n"', eval('json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('cannot dump special ext mapping', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.ext, "_VAL": [5, ["",""]]}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.ext, "_VAL": [5, ["",""]]}')
|
||||
eq('Vim(call):E474: Unable to convert EXT string to JSON', exc_exec('call json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('can dump special array mapping', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": [5, [""]]}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": [5, [""]]}')
|
||||
eq('[5, [""]]', eval('json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('can dump special UINT64_MAX mapping', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.integer}')
|
||||
execute('let todump._VAL = [1, 3, 0x7FFFFFFF, 0x7FFFFFFF]')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.integer}')
|
||||
command('let todump._VAL = [1, 3, 0x7FFFFFFF, 0x7FFFFFFF]')
|
||||
eq('18446744073709551615', eval('json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('can dump special INT64_MIN mapping', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.integer}')
|
||||
execute('let todump._VAL = [-1, 2, 0, 0]')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.integer}')
|
||||
command('let todump._VAL = [-1, 2, 0, 0]')
|
||||
eq('-9223372036854775808', eval('json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('can dump special BOOLEAN true mapping', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.boolean, "_VAL": 1}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.boolean, "_VAL": 1}')
|
||||
eq('true', eval('json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('can dump special BOOLEAN false mapping', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.boolean, "_VAL": 0}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.boolean, "_VAL": 0}')
|
||||
eq('false', eval('json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('can dump special NIL mapping', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.nil, "_VAL": 0}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.nil, "_VAL": 0}')
|
||||
eq('null', eval('json_encode(todump)'))
|
||||
end)
|
||||
|
||||
|
@ -673,7 +672,7 @@ describe('json_encode() function', function()
|
|||
end)
|
||||
|
||||
it('fails to dump a partial', function()
|
||||
execute('function T() dict\nendfunction')
|
||||
command('function T() dict\nendfunction')
|
||||
eq('Vim(call):E474: Error while dumping encode_tv2json() argument, itself: attempt to dump function reference',
|
||||
exc_exec('call json_encode(function("T", [1, 2], {}))'))
|
||||
end)
|
||||
|
@ -684,56 +683,56 @@ describe('json_encode() function', function()
|
|||
end)
|
||||
|
||||
it('fails to dump a recursive list', function()
|
||||
execute('let todump = [[[]]]')
|
||||
execute('call add(todump[0][0], todump)')
|
||||
command('let todump = [[[]]]')
|
||||
command('call add(todump[0][0], todump)')
|
||||
eq('Vim(call):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('call json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('fails to dump a recursive dict', function()
|
||||
execute('let todump = {"d": {"d": {}}}')
|
||||
execute('call extend(todump.d.d, {"d": todump})')
|
||||
command('let todump = {"d": {"d": {}}}')
|
||||
command('call extend(todump.d.d, {"d": todump})')
|
||||
eq('Vim(call):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('call json_encode([todump])'))
|
||||
end)
|
||||
|
||||
it('can dump dict with two same dicts inside', function()
|
||||
execute('let inter = {}')
|
||||
execute('let todump = {"a": inter, "b": inter}')
|
||||
command('let inter = {}')
|
||||
command('let todump = {"a": inter, "b": inter}')
|
||||
eq('{"a": {}, "b": {}}', eval('json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('can dump list with two same lists inside', function()
|
||||
execute('let inter = []')
|
||||
execute('let todump = [inter, inter]')
|
||||
command('let inter = []')
|
||||
command('let todump = [inter, inter]')
|
||||
eq('[[], []]', eval('json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('fails to dump a recursive list in a special dict', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}')
|
||||
execute('call add(todump._VAL, todump)')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}')
|
||||
command('call add(todump._VAL, todump)')
|
||||
eq('Vim(call):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('call json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('fails to dump a recursive (val) map in a special dict', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
execute('call add(todump._VAL, ["", todump])')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
command('call add(todump._VAL, ["", todump])')
|
||||
eq('Vim(call):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('call json_encode([todump])'))
|
||||
end)
|
||||
|
||||
it('fails to dump a recursive (val) map in a special dict, _VAL reference', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [["", []]]}')
|
||||
execute('call add(todump._VAL[0][1], todump._VAL)')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [["", []]]}')
|
||||
command('call add(todump._VAL[0][1], todump._VAL)')
|
||||
eq('Vim(call):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('call json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('fails to dump a recursive (val) special list in a special dict',
|
||||
function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}')
|
||||
execute('call add(todump._VAL, ["", todump._VAL])')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}')
|
||||
command('call add(todump._VAL, ["", todump._VAL])')
|
||||
eq('Vim(call):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('call json_encode(todump)'))
|
||||
end)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local clear, execute, write_file = helpers.clear, helpers.execute, helpers.write_file
|
||||
local clear, command, write_file = helpers.clear, helpers.command, helpers.write_file
|
||||
local eq, eval = helpers.eq, helpers.eval
|
||||
|
||||
describe("modeline", function()
|
||||
|
@ -12,7 +12,7 @@ describe("modeline", function()
|
|||
|
||||
it('does not crash with a large version number', function()
|
||||
write_file(tempfile, 'vim100000000000000000000000')
|
||||
execute('e! ' .. tempfile)
|
||||
command('e! ' .. tempfile)
|
||||
|
||||
eq(2, eval('1+1')) -- Still alive?
|
||||
end)
|
||||
|
|
|
@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each)
|
|||
local clear = helpers.clear
|
||||
local funcs = helpers.funcs
|
||||
local eval, eq = helpers.eval, helpers.eq
|
||||
local execute = helpers.execute
|
||||
local command = helpers.command
|
||||
local nvim = helpers.nvim
|
||||
local exc_exec = helpers.exc_exec
|
||||
|
||||
|
@ -331,9 +331,9 @@ describe('msgpack*() functions', function()
|
|||
obj_test('are able to dump and restore floating-point value', {0.125})
|
||||
|
||||
it('can restore and dump UINT64_MAX', function()
|
||||
execute('let dumped = ["\\xCF" . repeat("\\xFF", 8)]')
|
||||
execute('let parsed = msgpackparse(dumped)')
|
||||
execute('let dumped2 = msgpackdump(parsed)')
|
||||
command('let dumped = ["\\xCF" . repeat("\\xFF", 8)]')
|
||||
command('let parsed = msgpackparse(dumped)')
|
||||
command('let dumped2 = msgpackdump(parsed)')
|
||||
eq(1, eval('type(parsed[0]) == type(0) ' ..
|
||||
'|| parsed[0]._TYPE is v:msgpack_types.integer'))
|
||||
if eval('type(parsed[0]) == type(0)') == 1 then
|
||||
|
@ -345,9 +345,9 @@ describe('msgpack*() functions', function()
|
|||
end)
|
||||
|
||||
it('can restore and dump INT64_MIN', function()
|
||||
execute('let dumped = ["\\xD3\\x80" . repeat("\\n", 7)]')
|
||||
execute('let parsed = msgpackparse(dumped)')
|
||||
execute('let dumped2 = msgpackdump(parsed)')
|
||||
command('let dumped = ["\\xD3\\x80" . repeat("\\n", 7)]')
|
||||
command('let parsed = msgpackparse(dumped)')
|
||||
command('let dumped2 = msgpackdump(parsed)')
|
||||
eq(1, eval('type(parsed[0]) == type(0) ' ..
|
||||
'|| parsed[0]._TYPE is v:msgpack_types.integer'))
|
||||
if eval('type(parsed[0]) == type(0)') == 1 then
|
||||
|
@ -359,33 +359,33 @@ describe('msgpack*() functions', function()
|
|||
end)
|
||||
|
||||
it('can restore and dump BIN string with zero byte', function()
|
||||
execute('let dumped = ["\\xC4\\x01\\n"]')
|
||||
execute('let parsed = msgpackparse(dumped)')
|
||||
execute('let dumped2 = msgpackdump(parsed)')
|
||||
command('let dumped = ["\\xC4\\x01\\n"]')
|
||||
command('let parsed = msgpackparse(dumped)')
|
||||
command('let dumped2 = msgpackdump(parsed)')
|
||||
eq({{_TYPE={}, _VAL={'\n'}}}, eval('parsed'))
|
||||
eq(1, eval('parsed[0]._TYPE is v:msgpack_types.binary'))
|
||||
eq(1, eval('dumped ==# dumped2'))
|
||||
end)
|
||||
|
||||
it('can restore and dump STR string with zero byte', function()
|
||||
execute('let dumped = ["\\xA1\\n"]')
|
||||
execute('let parsed = msgpackparse(dumped)')
|
||||
execute('let dumped2 = msgpackdump(parsed)')
|
||||
command('let dumped = ["\\xA1\\n"]')
|
||||
command('let parsed = msgpackparse(dumped)')
|
||||
command('let dumped2 = msgpackdump(parsed)')
|
||||
eq({{_TYPE={}, _VAL={'\n'}}}, eval('parsed'))
|
||||
eq(1, eval('parsed[0]._TYPE is v:msgpack_types.string'))
|
||||
eq(1, eval('dumped ==# dumped2'))
|
||||
end)
|
||||
|
||||
it('can restore and dump BIN string with NL', function()
|
||||
execute('let dumped = ["\\xC4\\x01", ""]')
|
||||
execute('let parsed = msgpackparse(dumped)')
|
||||
execute('let dumped2 = msgpackdump(parsed)')
|
||||
command('let dumped = ["\\xC4\\x01", ""]')
|
||||
command('let parsed = msgpackparse(dumped)')
|
||||
command('let dumped2 = msgpackdump(parsed)')
|
||||
eq({"\n"}, eval('parsed'))
|
||||
eq(1, eval('dumped ==# dumped2'))
|
||||
end)
|
||||
|
||||
it('dump and restore special mapping with floating-point value', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.float, "_VAL": 0.125}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.float, "_VAL": 0.125}')
|
||||
eq({0.125}, eval('msgpackparse(msgpackdump([todump]))'))
|
||||
end)
|
||||
end)
|
||||
|
@ -394,52 +394,53 @@ describe('msgpackparse() function', function()
|
|||
before_each(clear)
|
||||
|
||||
it('restores nil as v:null', function()
|
||||
execute('let dumped = ["\\xC0"]')
|
||||
execute('let parsed = msgpackparse(dumped)')
|
||||
command('let dumped = ["\\xC0"]')
|
||||
command('let parsed = msgpackparse(dumped)')
|
||||
eq('[v:null]', eval('string(parsed)'))
|
||||
end)
|
||||
|
||||
it('restores boolean false as v:false', function()
|
||||
execute('let dumped = ["\\xC2"]')
|
||||
execute('let parsed = msgpackparse(dumped)')
|
||||
command('let dumped = ["\\xC2"]')
|
||||
command('let parsed = msgpackparse(dumped)')
|
||||
eq({false}, eval('parsed'))
|
||||
end)
|
||||
|
||||
it('restores boolean true as v:true', function()
|
||||
execute('let dumped = ["\\xC3"]')
|
||||
execute('let parsed = msgpackparse(dumped)')
|
||||
command('let dumped = ["\\xC3"]')
|
||||
command('let parsed = msgpackparse(dumped)')
|
||||
eq({true}, eval('parsed'))
|
||||
end)
|
||||
|
||||
it('restores FIXSTR as special dict', function()
|
||||
execute('let dumped = ["\\xa2ab"]')
|
||||
execute('let parsed = msgpackparse(dumped)')
|
||||
command('let dumped = ["\\xa2ab"]')
|
||||
command('let parsed = msgpackparse(dumped)')
|
||||
eq({{_TYPE={}, _VAL={'ab'}}}, eval('parsed'))
|
||||
eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.string'))
|
||||
end)
|
||||
|
||||
it('restores BIN 8 as string', function()
|
||||
execute('let dumped = ["\\xC4\\x02ab"]')
|
||||
command('let dumped = ["\\xC4\\x02ab"]')
|
||||
eq({'ab'}, eval('msgpackparse(dumped)'))
|
||||
end)
|
||||
|
||||
it('restores FIXEXT1 as special dictionary', function()
|
||||
execute('let dumped = ["\\xD4\\x10", ""]')
|
||||
execute('let parsed = msgpackparse(dumped)')
|
||||
command('let dumped = ["\\xD4\\x10", ""]')
|
||||
command('let parsed = msgpackparse(dumped)')
|
||||
eq({{_TYPE={}, _VAL={0x10, {"", ""}}}}, eval('parsed'))
|
||||
eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.ext'))
|
||||
end)
|
||||
|
||||
it('restores MAP with BIN key as special dictionary', function()
|
||||
execute('let dumped = ["\\x81\\xC4\\x01a\\xC4\\n"]')
|
||||
execute('let parsed = msgpackparse(dumped)')
|
||||
command('let dumped = ["\\x81\\xC4\\x01a\\xC4\\n"]')
|
||||
command('let parsed = msgpackparse(dumped)')
|
||||
eq({{_TYPE={}, _VAL={{'a', ''}}}}, eval('parsed'))
|
||||
eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map'))
|
||||
end)
|
||||
|
||||
it('restores MAP with duplicate STR keys as special dictionary', function()
|
||||
execute('let dumped = ["\\x82\\xA1a\\xC4\\n\\xA1a\\xC4\\n"]')
|
||||
execute('let parsed = msgpackparse(dumped)')
|
||||
command('let dumped = ["\\x82\\xA1a\\xC4\\n\\xA1a\\xC4\\n"]')
|
||||
-- FIXME Internal error bug
|
||||
command('silent! let parsed = msgpackparse(dumped)')
|
||||
eq({{_TYPE={}, _VAL={ {{_TYPE={}, _VAL={'a'}}, ''},
|
||||
{{_TYPE={}, _VAL={'a'}}, ''}}} }, eval('parsed'))
|
||||
eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map'))
|
||||
|
@ -448,8 +449,8 @@ describe('msgpackparse() function', function()
|
|||
end)
|
||||
|
||||
it('restores MAP with MAP key as special dictionary', function()
|
||||
execute('let dumped = ["\\x81\\x80\\xC4\\n"]')
|
||||
execute('let parsed = msgpackparse(dumped)')
|
||||
command('let dumped = ["\\x81\\x80\\xC4\\n"]')
|
||||
command('let parsed = msgpackparse(dumped)')
|
||||
eq({{_TYPE={}, _VAL={{{}, ''}}}}, eval('parsed'))
|
||||
eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map'))
|
||||
end)
|
||||
|
@ -494,7 +495,7 @@ describe('msgpackparse() function', function()
|
|||
end)
|
||||
|
||||
it('fails to parse a partial', function()
|
||||
execute('function T() dict\nendfunction')
|
||||
command('function T() dict\nendfunction')
|
||||
eq('Vim(call):E686: Argument of msgpackparse() must be a List',
|
||||
exc_exec('call msgpackparse(function("T", [1, 2], {}))'))
|
||||
end)
|
||||
|
@ -514,10 +515,10 @@ describe('msgpackdump() function', function()
|
|||
end)
|
||||
|
||||
it('can dump generic mapping with generic mapping keys and values', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
execute('let todumpv1 = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
execute('let todumpv2 = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
execute('call add(todump._VAL, [todumpv1, todumpv2])')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
command('let todumpv1 = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
command('let todumpv2 = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
command('call add(todump._VAL, [todumpv1, todumpv2])')
|
||||
eq({'\129\128\128'}, eval('msgpackdump([todump])'))
|
||||
end)
|
||||
|
||||
|
@ -530,130 +531,130 @@ describe('msgpackdump() function', function()
|
|||
end)
|
||||
|
||||
it('can v:null', function()
|
||||
execute('let todump = v:null')
|
||||
command('let todump = v:null')
|
||||
end)
|
||||
|
||||
it('can dump special bool mapping (true)', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.boolean, "_VAL": 1}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.boolean, "_VAL": 1}')
|
||||
eq({'\195'}, eval('msgpackdump([todump])'))
|
||||
end)
|
||||
|
||||
it('can dump special bool mapping (false)', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.boolean, "_VAL": 0}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.boolean, "_VAL": 0}')
|
||||
eq({'\194'}, eval('msgpackdump([todump])'))
|
||||
end)
|
||||
|
||||
it('can dump special nil mapping', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.nil, "_VAL": 0}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.nil, "_VAL": 0}')
|
||||
eq({'\192'}, eval('msgpackdump([todump])'))
|
||||
end)
|
||||
|
||||
it('can dump special ext mapping', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.ext, "_VAL": [5, ["",""]]}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.ext, "_VAL": [5, ["",""]]}')
|
||||
eq({'\212\005', ''}, eval('msgpackdump([todump])'))
|
||||
end)
|
||||
|
||||
it('can dump special array mapping', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": [5, [""]]}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": [5, [""]]}')
|
||||
eq({'\146\005\145\196\n'}, eval('msgpackdump([todump])'))
|
||||
end)
|
||||
|
||||
it('can dump special UINT64_MAX mapping', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.integer}')
|
||||
execute('let todump._VAL = [1, 3, 0x7FFFFFFF, 0x7FFFFFFF]')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.integer}')
|
||||
command('let todump._VAL = [1, 3, 0x7FFFFFFF, 0x7FFFFFFF]')
|
||||
eq({'\207\255\255\255\255\255\255\255\255'}, eval('msgpackdump([todump])'))
|
||||
end)
|
||||
|
||||
it('can dump special INT64_MIN mapping', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.integer}')
|
||||
execute('let todump._VAL = [-1, 2, 0, 0]')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.integer}')
|
||||
command('let todump._VAL = [-1, 2, 0, 0]')
|
||||
eq({'\211\128\n\n\n\n\n\n\n'}, eval('msgpackdump([todump])'))
|
||||
end)
|
||||
|
||||
it('fails to dump a function reference', function()
|
||||
execute('let Todump = function("tr")')
|
||||
command('let Todump = function("tr")')
|
||||
eq('Vim(call):E5004: Error while dumping msgpackdump() argument, index 0, itself: attempt to dump function reference',
|
||||
exc_exec('call msgpackdump([Todump])'))
|
||||
end)
|
||||
|
||||
it('fails to dump a partial', function()
|
||||
execute('function T() dict\nendfunction')
|
||||
execute('let Todump = function("T", [1, 2], {})')
|
||||
command('function T() dict\nendfunction')
|
||||
command('let Todump = function("T", [1, 2], {})')
|
||||
eq('Vim(call):E5004: Error while dumping msgpackdump() argument, index 0, itself: attempt to dump function reference',
|
||||
exc_exec('call msgpackdump([Todump])'))
|
||||
end)
|
||||
|
||||
it('fails to dump a function reference in a list', function()
|
||||
execute('let todump = [function("tr")]')
|
||||
command('let todump = [function("tr")]')
|
||||
eq('Vim(call):E5004: Error while dumping msgpackdump() argument, index 0, index 0: attempt to dump function reference',
|
||||
exc_exec('call msgpackdump([todump])'))
|
||||
end)
|
||||
|
||||
it('fails to dump a recursive list', function()
|
||||
execute('let todump = [[[]]]')
|
||||
execute('call add(todump[0][0], todump)')
|
||||
command('let todump = [[[]]]')
|
||||
command('call add(todump[0][0], todump)')
|
||||
eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0, index 0, index 0',
|
||||
exc_exec('call msgpackdump([todump])'))
|
||||
end)
|
||||
|
||||
it('fails to dump a recursive dict', function()
|
||||
execute('let todump = {"d": {"d": {}}}')
|
||||
execute('call extend(todump.d.d, {"d": todump})')
|
||||
command('let todump = {"d": {"d": {}}}')
|
||||
command('call extend(todump.d.d, {"d": todump})')
|
||||
eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key \'d\', key \'d\', key \'d\'',
|
||||
exc_exec('call msgpackdump([todump])'))
|
||||
end)
|
||||
|
||||
it('can dump dict with two same dicts inside', function()
|
||||
execute('let inter = {}')
|
||||
execute('let todump = {"a": inter, "b": inter}')
|
||||
command('let inter = {}')
|
||||
command('let todump = {"a": inter, "b": inter}')
|
||||
eq({"\130\161a\128\161b\128"}, eval('msgpackdump([todump])'))
|
||||
end)
|
||||
|
||||
it('can dump list with two same lists inside', function()
|
||||
execute('let inter = []')
|
||||
execute('let todump = [inter, inter]')
|
||||
command('let inter = []')
|
||||
command('let todump = [inter, inter]')
|
||||
eq({"\146\144\144"}, eval('msgpackdump([todump])'))
|
||||
end)
|
||||
|
||||
it('fails to dump a recursive list in a special dict', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}')
|
||||
execute('call add(todump._VAL, todump)')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}')
|
||||
command('call add(todump._VAL, todump)')
|
||||
eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0',
|
||||
exc_exec('call msgpackdump([todump])'))
|
||||
end)
|
||||
|
||||
it('fails to dump a recursive (key) map in a special dict', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
execute('call add(todump._VAL, [todump, 0])')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
command('call add(todump._VAL, [todump, 0])')
|
||||
eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 1',
|
||||
exc_exec('call msgpackdump([todump])'))
|
||||
end)
|
||||
|
||||
it('fails to dump a recursive (val) map in a special dict', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
execute('call add(todump._VAL, [0, todump])')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
command('call add(todump._VAL, [0, todump])')
|
||||
eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key 0 at index 0 from special map',
|
||||
exc_exec('call msgpackdump([todump])'))
|
||||
end)
|
||||
|
||||
it('fails to dump a recursive (key) map in a special dict, _VAL reference', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[[], []]]}')
|
||||
execute('call add(todump._VAL[0][0], todump._VAL)')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[[], []]]}')
|
||||
command('call add(todump._VAL[0][0], todump._VAL)')
|
||||
eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key [[[[...@0], []]]] at index 0 from special map, index 0',
|
||||
exc_exec('call msgpackdump([todump])'))
|
||||
end)
|
||||
|
||||
it('fails to dump a recursive (val) map in a special dict, _VAL reference', function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[[], []]]}')
|
||||
execute('call add(todump._VAL[0][1], todump._VAL)')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[[], []]]}')
|
||||
command('call add(todump._VAL[0][1], todump._VAL)')
|
||||
eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key [] at index 0 from special map, index 0',
|
||||
exc_exec('call msgpackdump([todump])'))
|
||||
end)
|
||||
|
||||
it('fails to dump a recursive (val) special list in a special dict',
|
||||
function()
|
||||
execute('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}')
|
||||
execute('call add(todump._VAL, [0, todump._VAL])')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}')
|
||||
command('call add(todump._VAL, [0, todump._VAL])')
|
||||
eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0, index 1',
|
||||
exc_exec('call msgpackdump([todump])'))
|
||||
end)
|
||||
|
@ -689,7 +690,7 @@ describe('msgpackdump() function', function()
|
|||
end)
|
||||
|
||||
it('fails to dump a partial', function()
|
||||
execute('function T() dict\nendfunction')
|
||||
command('function T() dict\nendfunction')
|
||||
eq('Vim(call):E686: Argument of msgpackdump() must be a List',
|
||||
exc_exec('call msgpackdump(function("T", [1, 2], {}))'))
|
||||
end)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local clear, eq, ok = helpers.clear, helpers.eq, helpers.ok
|
||||
local neq, execute, funcs = helpers.neq, helpers.execute, helpers.funcs
|
||||
local neq, command, funcs = helpers.neq, helpers.command, helpers.funcs
|
||||
local reltime, reltimestr, reltimefloat = funcs.reltime, funcs.reltimestr, funcs.reltimefloat
|
||||
|
||||
describe('reltimestr(), reltimefloat()', function()
|
||||
|
@ -8,7 +8,7 @@ describe('reltimestr(), reltimefloat()', function()
|
|||
|
||||
it('Checks', function()
|
||||
local now = reltime()
|
||||
execute('sleep 10m')
|
||||
command('sleep 10m')
|
||||
local later = reltime()
|
||||
local elapsed = reltime(now)
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ local setpos = helpers.funcs.setpos
|
|||
local getpos = helpers.funcs.getpos
|
||||
local insert = helpers.insert
|
||||
local clear = helpers.clear
|
||||
local execute = helpers.execute
|
||||
local command = helpers.command
|
||||
local eval = helpers.eval
|
||||
local eq = helpers.eq
|
||||
local exc_exec = helpers.exc_exec
|
||||
|
@ -16,7 +16,7 @@ describe('setpos() function', function()
|
|||
First line of text
|
||||
Second line of text
|
||||
Third line of text]])
|
||||
execute('new')
|
||||
command('new')
|
||||
insert([[
|
||||
Line of text 1
|
||||
Line of text 2
|
||||
|
@ -34,7 +34,8 @@ describe('setpos() function', function()
|
|||
it('can set lowercase marks in the current buffer', function()
|
||||
setpos("'d", {0, 2, 1, 0})
|
||||
eq(getpos("'d"), {0, 2, 1, 0})
|
||||
execute('undo', 'call setpos("\'d", [2, 3, 1, 0])')
|
||||
command('undo')
|
||||
command('call setpos("\'d", [2, 3, 1, 0])')
|
||||
eq(getpos("'d"), {0, 3, 1, 0})
|
||||
end)
|
||||
it('can set lowercase marks in other buffers', function()
|
||||
|
@ -42,7 +43,7 @@ describe('setpos() function', function()
|
|||
eq(0, retval)
|
||||
setpos("'d", {1, 2, 1, 0})
|
||||
eq(getpos("'d"), {0, 0, 0, 0})
|
||||
execute('wincmd w')
|
||||
command('wincmd w')
|
||||
eq(eval('bufnr("%")'), 1)
|
||||
eq(getpos("'d"), {0, 2, 1, 0})
|
||||
end)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local exc_exec = helpers.exc_exec
|
||||
local execute = helpers.execute
|
||||
local command = helpers.command
|
||||
local funcs = helpers.funcs
|
||||
local clear = helpers.clear
|
||||
local eval = helpers.eval
|
||||
|
@ -12,7 +12,7 @@ describe('Special values', function()
|
|||
before_each(clear)
|
||||
|
||||
it('do not cause error when freed', function()
|
||||
execute([[
|
||||
command([[
|
||||
function Test()
|
||||
try
|
||||
return v:true
|
||||
|
@ -109,7 +109,7 @@ describe('Special values', function()
|
|||
it('does not work with +=/-=/.=', function()
|
||||
meths.set_var('true', true)
|
||||
meths.set_var('false', false)
|
||||
execute('let null = v:null')
|
||||
command('let null = v:null')
|
||||
|
||||
eq('Vim(let):E734: Wrong variable type for +=', exc_exec('let true += 1'))
|
||||
eq('Vim(let):E734: Wrong variable type for +=', exc_exec('let false += 1'))
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local eq, call, clear, eval, execute, feed, nvim =
|
||||
helpers.eq, helpers.call, helpers.clear, helpers.eval, helpers.execute,
|
||||
|
||||
local nvim_dir = helpers.nvim_dir
|
||||
local eq, call, clear, eval, feed_command, feed, nvim =
|
||||
helpers.eq, helpers.call, helpers.clear, helpers.eval, helpers.feed_command,
|
||||
helpers.feed, helpers.nvim
|
||||
|
||||
local Screen = require('test.functional.ui.screen')
|
||||
|
@ -31,7 +33,7 @@ describe('system()', function()
|
|||
|
||||
describe('command passed as a List', function()
|
||||
local function printargs_path()
|
||||
return helpers.nvim_dir..'/printargs-test'
|
||||
return nvim_dir..'/printargs-test'
|
||||
.. (helpers.os_name() == 'windows' and '.exe' or '')
|
||||
end
|
||||
|
||||
|
@ -43,10 +45,10 @@ describe('system()', function()
|
|||
it('parameter validation does NOT modify v:shell_error', function()
|
||||
-- 1. Call system() with invalid parameters.
|
||||
-- 2. Assert that v:shell_error was NOT set.
|
||||
execute('call system({})')
|
||||
feed_command('call system({})')
|
||||
eq('E475: Invalid argument: expected String or List', eval('v:errmsg'))
|
||||
eq(0, eval('v:shell_error'))
|
||||
execute('call system([])')
|
||||
feed_command('call system([])')
|
||||
eq('E474: Invalid argument', eval('v:errmsg'))
|
||||
eq(0, eval('v:shell_error'))
|
||||
|
||||
|
@ -57,9 +59,9 @@ describe('system()', function()
|
|||
|
||||
-- 1. Call system() with invalid parameters.
|
||||
-- 2. Assert that v:shell_error was NOT modified.
|
||||
execute('call system({})')
|
||||
feed_command('call system({})')
|
||||
eq(old_val, eval('v:shell_error'))
|
||||
execute('call system([])')
|
||||
feed_command('call system([])')
|
||||
eq(old_val, eval('v:shell_error'))
|
||||
end)
|
||||
|
||||
|
@ -182,7 +184,7 @@ describe('system()', function()
|
|||
end)
|
||||
it('to backgrounded command does not crash', function()
|
||||
-- This is indeterminate, just exercise the codepath. May get E5677.
|
||||
execute('call system("echo -n echoed &")')
|
||||
feed_command('call system("echo -n echoed &")')
|
||||
local v_errnum = string.match(eval("v:errmsg"), "^E%d*:")
|
||||
if v_errnum then
|
||||
eq("E5677:", v_errnum)
|
||||
|
@ -197,7 +199,7 @@ describe('system()', function()
|
|||
end)
|
||||
it('to backgrounded command does not crash', function()
|
||||
-- This is indeterminate, just exercise the codepath. May get E5677.
|
||||
execute('call system("cat - &")')
|
||||
feed_command('call system("cat - &")')
|
||||
local v_errnum = string.match(eval("v:errmsg"), "^E%d*:")
|
||||
if v_errnum then
|
||||
eq("E5677:", v_errnum)
|
||||
|
|
|
@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each)
|
|||
local Screen = require('test.functional.ui.screen')
|
||||
local ok, feed, eq, eval = helpers.ok, helpers.feed, helpers.eq, helpers.eval
|
||||
local source, nvim_async, run = helpers.source, helpers.nvim_async, helpers.run
|
||||
local clear, execute, funcs = helpers.clear, helpers.execute, helpers.funcs
|
||||
local clear, command, funcs = helpers.clear, helpers.command, helpers.funcs
|
||||
local curbufmeths = helpers.curbufmeths
|
||||
|
||||
describe('timers', function()
|
||||
|
@ -17,14 +17,14 @@ describe('timers', function()
|
|||
end)
|
||||
|
||||
it('works one-shot', function()
|
||||
execute("call timer_start(50, 'MyHandler')")
|
||||
command("call timer_start(50, 'MyHandler')")
|
||||
eq(0,eval("g:val"))
|
||||
run(nil, nil, nil, 200)
|
||||
eq(1,eval("g:val"))
|
||||
end)
|
||||
|
||||
it('works one-shot when repeat=0', function()
|
||||
execute("call timer_start(50, 'MyHandler', {'repeat': 0})")
|
||||
command("call timer_start(50, 'MyHandler', {'repeat': 0})")
|
||||
eq(0,eval("g:val"))
|
||||
run(nil, nil, nil, 200)
|
||||
eq(1,eval("g:val"))
|
||||
|
@ -32,14 +32,14 @@ describe('timers', function()
|
|||
|
||||
|
||||
it('works with repeat two', function()
|
||||
execute("call timer_start(50, 'MyHandler', {'repeat': 2})")
|
||||
command("call timer_start(50, 'MyHandler', {'repeat': 2})")
|
||||
eq(0,eval("g:val"))
|
||||
run(nil, nil, nil, 300)
|
||||
eq(2,eval("g:val"))
|
||||
end)
|
||||
|
||||
it('are triggered during sleep', function()
|
||||
execute("call timer_start(50, 'MyHandler', {'repeat': 2})")
|
||||
command("call timer_start(50, 'MyHandler', {'repeat': 2})")
|
||||
nvim_async("command", "sleep 10")
|
||||
eq(0,eval("g:val"))
|
||||
run(nil, nil, nil, 300)
|
||||
|
@ -63,12 +63,12 @@ describe('timers', function()
|
|||
end)
|
||||
|
||||
it('are paused when event processing is disabled', function()
|
||||
execute("call timer_start(50, 'MyHandler', {'repeat': -1})")
|
||||
command("call timer_start(50, 'MyHandler', {'repeat': -1})")
|
||||
run(nil, nil, nil, 100)
|
||||
local count = eval("g:val")
|
||||
-- shows two line error message and thus invokes the return prompt.
|
||||
-- if we start to allow event processing here, we need to change this test.
|
||||
execute("throw 'fatal error'")
|
||||
feed(':throw "fatal error"<CR>')
|
||||
run(nil, nil, nil, 300)
|
||||
feed("<cr>")
|
||||
local diff = eval("g:val") - count
|
||||
|
@ -76,7 +76,7 @@ describe('timers', function()
|
|||
end)
|
||||
|
||||
it('are triggered in blocking getchar() call', function()
|
||||
execute("call timer_start(50, 'MyHandler', {'repeat': -1})")
|
||||
command("call timer_start(50, 'MyHandler', {'repeat': -1})")
|
||||
nvim_async("command", "let g:c = getchar()")
|
||||
run(nil, nil, nil, 300)
|
||||
feed("c")
|
||||
|
@ -157,7 +157,7 @@ describe('timers', function()
|
|||
endif
|
||||
endfunc
|
||||
]])
|
||||
execute("call timer_start(50, 'MyHandler', {'repeat': -1})")
|
||||
command("call timer_start(50, 'MyHandler', {'repeat': -1})")
|
||||
eq(0,eval("g:val"))
|
||||
run(nil, nil, nil, 300)
|
||||
eq(3,eval("g:val"))
|
||||
|
@ -170,8 +170,8 @@ describe('timers', function()
|
|||
let g:val2 += 1
|
||||
endfunc
|
||||
]])
|
||||
execute("call timer_start(50, 'MyHandler', {'repeat': 3})")
|
||||
execute("call timer_start(100, 'MyHandler2', {'repeat': 2})")
|
||||
command("call timer_start(50, 'MyHandler', {'repeat': 3})")
|
||||
command("call timer_start(100, 'MyHandler2', {'repeat': 2})")
|
||||
run(nil, nil, nil, 300)
|
||||
eq(3,eval("g:val"))
|
||||
eq(2,eval("g:val2"))
|
||||
|
@ -186,7 +186,7 @@ describe('timers', function()
|
|||
let g:val += 1
|
||||
endfunc
|
||||
]])
|
||||
execute("call timer_start(5, 'MyHandler', {'repeat': 1})")
|
||||
command("call timer_start(5, 'MyHandler', {'repeat': 1})")
|
||||
run(nil, nil, nil, 300)
|
||||
eq(1,eval("g:val"))
|
||||
end)
|
||||
|
@ -201,7 +201,7 @@ describe('timers', function()
|
|||
echo "evil"
|
||||
endfunc
|
||||
]])
|
||||
execute("call timer_start(100, 'MyHandler', {'repeat': 1})")
|
||||
command("call timer_start(100, 'MyHandler', {'repeat': 1})")
|
||||
feed(":good")
|
||||
screen:sleep(200)
|
||||
screen:expect([[
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
local helpers = require("test.functional.helpers")(after_each)
|
||||
local eq, execute, funcs = helpers.eq, helpers.execute, helpers.funcs
|
||||
local eq, command, funcs = helpers.eq, helpers.command, helpers.funcs
|
||||
local ok = helpers.ok
|
||||
local clear = helpers.clear
|
||||
|
||||
|
@ -9,15 +9,15 @@ describe(":argument", function()
|
|||
end)
|
||||
|
||||
it("does not restart :terminal buffer", function()
|
||||
execute("terminal")
|
||||
command("terminal")
|
||||
helpers.feed([[<C-\><C-N>]])
|
||||
execute("argadd")
|
||||
command("argadd")
|
||||
helpers.feed([[<C-\><C-N>]])
|
||||
local bufname_before = funcs.bufname("%")
|
||||
local bufnr_before = funcs.bufnr("%")
|
||||
helpers.ok(nil ~= string.find(bufname_before, "^term://")) -- sanity
|
||||
|
||||
execute("argument 1")
|
||||
command("argument 1")
|
||||
helpers.feed([[<C-\><C-N>]])
|
||||
|
||||
local bufname_after = funcs.bufname("%")
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
-- Specs for bang/filter commands
|
||||
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local feed, execute, clear = helpers.feed, helpers.execute, helpers.clear
|
||||
local feed, command, clear = helpers.feed, helpers.command, helpers.clear
|
||||
local mkdir, write_file, rmdir = helpers.mkdir, helpers.write_file, helpers.rmdir
|
||||
|
||||
if helpers.pending_win32(pending) then return end
|
||||
|
@ -28,7 +28,7 @@ describe('issues', function()
|
|||
end)
|
||||
|
||||
it('#3269 Last line of shell output is not truncated', function()
|
||||
execute([[nnoremap <silent>\l :!ls bang_filter_spec<cr>]])
|
||||
command([[nnoremap <silent>\l :!ls bang_filter_spec<cr>]])
|
||||
feed([[\l]])
|
||||
screen:expect([[
|
||||
~ |
|
||||
|
|
|
@ -6,7 +6,7 @@ local helpers = require('test.functional.helpers')(after_each)
|
|||
local eq = helpers.eq
|
||||
local call = helpers.call
|
||||
local clear = helpers.clear
|
||||
local execute = helpers.execute
|
||||
local command = helpers.command
|
||||
local exc_exec = helpers.exc_exec
|
||||
|
||||
if helpers.pending_win32(pending) then return end
|
||||
|
@ -58,7 +58,7 @@ for _, cmd in ipairs {'cd', 'chdir'} do
|
|||
eq(0, lwd(globalwin))
|
||||
eq(0, lwd(globalwin, tabnr))
|
||||
|
||||
execute('bot split')
|
||||
command('bot split')
|
||||
local localwin = call('winnr')
|
||||
-- Initial window is still using globalDir
|
||||
eq(globalDir, cwd(localwin))
|
||||
|
@ -66,7 +66,7 @@ for _, cmd in ipairs {'cd', 'chdir'} do
|
|||
eq(0, lwd(globalwin))
|
||||
eq(0, lwd(globalwin, tabnr))
|
||||
|
||||
execute('silent l' .. cmd .. ' ' .. directories.window)
|
||||
command('silent l' .. cmd .. ' ' .. directories.window)
|
||||
-- From window with local dir, the original window
|
||||
-- is still reporting the global dir
|
||||
eq(globalDir, cwd(globalwin))
|
||||
|
@ -80,7 +80,7 @@ for _, cmd in ipairs {'cd', 'chdir'} do
|
|||
eq(1, lwd(localwin))
|
||||
eq(1, lwd(localwin, tabnr))
|
||||
|
||||
execute('tabnew')
|
||||
command('tabnew')
|
||||
-- From new tab page, original window reports global dir
|
||||
eq(globalDir, cwd(globalwin, tabnr))
|
||||
eq(0, lwd(globalwin, tabnr))
|
||||
|
@ -100,8 +100,8 @@ for _, cmd in ipairs {'cd', 'chdir'} do
|
|||
eq(0, lwd(-1, 0))
|
||||
eq(0, lwd(-1, globaltab))
|
||||
|
||||
execute('tabnew')
|
||||
execute('silent t' .. cmd .. ' ' .. directories.tab)
|
||||
command('tabnew')
|
||||
command('silent t' .. cmd .. ' ' .. directories.tab)
|
||||
local localtab = call('tabpagenr')
|
||||
|
||||
-- From local tab page, original tab reports globalDir
|
||||
|
@ -114,7 +114,7 @@ for _, cmd in ipairs {'cd', 'chdir'} do
|
|||
eq(1, lwd(-1, 0))
|
||||
eq(1, lwd(-1, localtab))
|
||||
|
||||
execute('tabnext')
|
||||
command('tabnext')
|
||||
-- From original tab page, local reports as such
|
||||
eq(globalDir .. '/' .. directories.tab, cwd(-1, localtab))
|
||||
eq(1, lwd(-1, localtab))
|
||||
|
@ -128,13 +128,13 @@ for _, cmd in ipairs {'cd', 'chdir'} do
|
|||
end)
|
||||
|
||||
it('works with tab-local pwd', function()
|
||||
execute('silent t' .. cmd .. ' ' .. directories.tab)
|
||||
command('silent t' .. cmd .. ' ' .. directories.tab)
|
||||
eq(directories.start, cwd(-1, -1))
|
||||
eq(0, lwd(-1, -1))
|
||||
end)
|
||||
|
||||
it('works with window-local pwd', function()
|
||||
execute('silent l' .. cmd .. ' ' .. directories.window)
|
||||
command('silent l' .. cmd .. ' ' .. directories.window)
|
||||
eq(directories.start, cwd(-1, -1))
|
||||
eq(0, lwd(-1, -1))
|
||||
end)
|
||||
|
@ -145,18 +145,18 @@ for _, cmd in ipairs {'cd', 'chdir'} do
|
|||
local globalDir = directories.start
|
||||
|
||||
-- Create a new tab and change directory
|
||||
execute('tabnew')
|
||||
execute('silent t' .. cmd .. ' ' .. directories.tab)
|
||||
command('tabnew')
|
||||
command('silent t' .. cmd .. ' ' .. directories.tab)
|
||||
eq(globalDir .. '/' .. directories.tab, tcwd())
|
||||
|
||||
-- Create a new tab and verify it has inherited the directory
|
||||
execute('tabnew')
|
||||
command('tabnew')
|
||||
eq(globalDir .. '/' .. directories.tab, tcwd())
|
||||
|
||||
-- Change tab and change back, verify that directories are correct
|
||||
execute('tabnext')
|
||||
command('tabnext')
|
||||
eq(globalDir, tcwd())
|
||||
execute('tabprevious')
|
||||
command('tabprevious')
|
||||
eq(globalDir .. '/' .. directories.tab, tcwd())
|
||||
end)
|
||||
end)
|
||||
|
@ -164,7 +164,7 @@ for _, cmd in ipairs {'cd', 'chdir'} do
|
|||
it('works', function()
|
||||
local globalDir = directories.start
|
||||
-- Create a new tab first and verify that is has the same working dir
|
||||
execute('tabnew')
|
||||
command('tabnew')
|
||||
eq(globalDir, cwd())
|
||||
eq(globalDir, tcwd()) -- has no tab-local directory
|
||||
eq(0, tlwd())
|
||||
|
@ -172,7 +172,7 @@ for _, cmd in ipairs {'cd', 'chdir'} do
|
|||
eq(0, wlwd())
|
||||
|
||||
-- Change tab-local working directory and verify it is different
|
||||
execute('silent t' .. cmd .. ' ' .. directories.tab)
|
||||
command('silent t' .. cmd .. ' ' .. directories.tab)
|
||||
eq(globalDir .. '/' .. directories.tab, cwd())
|
||||
eq(cwd(), tcwd()) -- working directory maches tab directory
|
||||
eq(1, tlwd())
|
||||
|
@ -180,46 +180,46 @@ for _, cmd in ipairs {'cd', 'chdir'} do
|
|||
eq(0, wlwd())
|
||||
|
||||
-- Create a new window in this tab to test `:lcd`
|
||||
execute('new')
|
||||
command('new')
|
||||
eq(1, tlwd()) -- Still tab-local working directory
|
||||
eq(0, wlwd()) -- Still no window-local working directory
|
||||
eq(globalDir .. '/' .. directories.tab, cwd())
|
||||
execute('silent l' .. cmd .. ' ../' .. directories.window)
|
||||
command('silent l' .. cmd .. ' ../' .. directories.window)
|
||||
eq(globalDir .. '/' .. directories.window, cwd())
|
||||
eq(globalDir .. '/' .. directories.tab, tcwd())
|
||||
eq(1, wlwd())
|
||||
|
||||
-- Verify the first window still has the tab local directory
|
||||
execute('wincmd w')
|
||||
command('wincmd w')
|
||||
eq(globalDir .. '/' .. directories.tab, cwd())
|
||||
eq(globalDir .. '/' .. directories.tab, tcwd())
|
||||
eq(0, wlwd()) -- No window-local directory
|
||||
|
||||
-- Change back to initial tab and verify working directory has stayed
|
||||
execute('tabnext')
|
||||
command('tabnext')
|
||||
eq(globalDir, cwd() )
|
||||
eq(0, tlwd())
|
||||
eq(0, wlwd())
|
||||
|
||||
-- Verify global changes don't affect local ones
|
||||
execute('silent ' .. cmd .. ' ' .. directories.global)
|
||||
command('silent ' .. cmd .. ' ' .. directories.global)
|
||||
eq(globalDir .. '/' .. directories.global, cwd())
|
||||
execute('tabnext')
|
||||
command('tabnext')
|
||||
eq(globalDir .. '/' .. directories.tab, cwd())
|
||||
eq(globalDir .. '/' .. directories.tab, tcwd())
|
||||
eq(0, wlwd()) -- Still no window-local directory in this window
|
||||
|
||||
-- Unless the global change happened in a tab with local directory
|
||||
execute('silent ' .. cmd .. ' ..')
|
||||
command('silent ' .. cmd .. ' ..')
|
||||
eq(globalDir, cwd() )
|
||||
eq(0 , tlwd())
|
||||
eq(0 , wlwd())
|
||||
-- Which also affects the first tab
|
||||
execute('tabnext')
|
||||
command('tabnext')
|
||||
eq(globalDir, cwd())
|
||||
|
||||
-- But not in a window with its own local directory
|
||||
execute('tabnext | wincmd w')
|
||||
command('tabnext | wincmd w')
|
||||
eq(globalDir .. '/' .. directories.window, cwd() )
|
||||
eq(0 , tlwd())
|
||||
eq(globalDir .. '/' .. directories.window, wcwd())
|
||||
|
@ -280,8 +280,8 @@ describe("getcwd()", function ()
|
|||
end)
|
||||
|
||||
it("returns empty string if working directory does not exist", function()
|
||||
execute("cd "..directories.global)
|
||||
execute("call delete('../"..directories.global.."', 'd')")
|
||||
command("cd "..directories.global)
|
||||
command("call delete('../"..directories.global.."', 'd')")
|
||||
eq("", helpers.eval("getcwd()"))
|
||||
end)
|
||||
end)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local Screen = require('test.functional.ui.screen')
|
||||
local clear, feed, source = helpers.clear, helpers.feed, helpers.source
|
||||
local execute = helpers.execute
|
||||
local command = helpers.command
|
||||
|
||||
describe("CTRL-C (mapped)", function()
|
||||
before_each(function()
|
||||
|
@ -20,7 +20,7 @@ describe("CTRL-C (mapped)", function()
|
|||
nnoremap <C-C> <NOP>
|
||||
]])
|
||||
|
||||
execute("silent edit! test/functional/fixtures/bigfile.txt")
|
||||
command("silent edit! test/functional/fixtures/bigfile.txt")
|
||||
local screen = Screen.new(52, 6)
|
||||
screen:attach()
|
||||
screen:set_default_attr_ids({
|
||||
|
@ -47,7 +47,7 @@ describe("CTRL-C (mapped)", function()
|
|||
end
|
||||
|
||||
-- The test is time-sensitive. Try different sleep values.
|
||||
local ms_values = {1, 10, 100}
|
||||
local ms_values = {1, 10, 100, 1000, 10000}
|
||||
for i, ms in ipairs(ms_values) do
|
||||
if i < #ms_values then
|
||||
local status, _ = pcall(test_ctrl_c, ms)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local Screen = require('test.functional.ui.screen')
|
||||
local clear, feed, execute = helpers.clear, helpers.feed, helpers.execute
|
||||
local clear, feed, feed_command = helpers.clear, helpers.feed, helpers.feed_command
|
||||
|
||||
describe(":drop", function()
|
||||
local screen
|
||||
|
@ -15,7 +15,7 @@ describe(":drop", function()
|
|||
[2] = {reverse = true},
|
||||
[3] = {bold = true},
|
||||
})
|
||||
execute("set laststatus=2")
|
||||
feed_command("set laststatus=2")
|
||||
end)
|
||||
|
||||
after_each(function()
|
||||
|
@ -23,7 +23,7 @@ describe(":drop", function()
|
|||
end)
|
||||
|
||||
it("works like :e when called with only one window open", function()
|
||||
execute("drop tmp1.vim")
|
||||
feed_command("drop tmp1.vim")
|
||||
screen:expect([[
|
||||
^ |
|
||||
{0:~ }|
|
||||
|
@ -39,10 +39,10 @@ describe(":drop", function()
|
|||
end)
|
||||
|
||||
it("switches to an open window showing the buffer", function()
|
||||
execute("edit tmp1")
|
||||
execute("vsplit")
|
||||
execute("edit tmp2")
|
||||
execute("drop tmp1")
|
||||
feed_command("edit tmp1")
|
||||
feed_command("vsplit")
|
||||
feed_command("edit tmp2")
|
||||
feed_command("drop tmp1")
|
||||
screen:expect([[
|
||||
{2:|}^ |
|
||||
{0:~ }{2:|}{0:~ }|
|
||||
|
@ -58,11 +58,11 @@ describe(":drop", function()
|
|||
end)
|
||||
|
||||
it("splits off a new window when a buffer can't be abandoned", function()
|
||||
execute("edit tmp1")
|
||||
execute("vsplit")
|
||||
execute("edit tmp2")
|
||||
feed_command("edit tmp1")
|
||||
feed_command("vsplit")
|
||||
feed_command("edit tmp2")
|
||||
feed("iABC<esc>")
|
||||
execute("drop tmp3")
|
||||
feed_command("drop tmp3")
|
||||
screen:expect([[
|
||||
^ {2:|} |
|
||||
{0:~ }{2:|}{0:~ }|
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
local helpers = require("test.functional.helpers")(after_each)
|
||||
local eq, execute, funcs = helpers.eq, helpers.execute, helpers.funcs
|
||||
local eq, command, funcs = helpers.eq, helpers.command, helpers.funcs
|
||||
local ok = helpers.ok
|
||||
local clear = helpers.clear
|
||||
local feed = helpers.feed
|
||||
|
||||
describe(":edit", function()
|
||||
before_each(function()
|
||||
|
@ -9,13 +10,13 @@ describe(":edit", function()
|
|||
end)
|
||||
|
||||
it("without arguments does not restart :terminal buffer", function()
|
||||
execute("terminal")
|
||||
helpers.feed([[<C-\><C-N>]])
|
||||
command("terminal")
|
||||
feed([[<C-\><C-N>]])
|
||||
local bufname_before = funcs.bufname("%")
|
||||
local bufnr_before = funcs.bufnr("%")
|
||||
helpers.ok(nil ~= string.find(bufname_before, "^term://")) -- sanity
|
||||
|
||||
execute("edit")
|
||||
command("edit")
|
||||
|
||||
local bufname_after = funcs.bufname("%")
|
||||
local bufnr_after = funcs.bufnr("%")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local clear, execute, feed = helpers.clear, helpers.execute, helpers.feed
|
||||
local clear, feed_command, feed = helpers.clear, helpers.feed_command, helpers.feed
|
||||
local eq, neq, eval = helpers.eq, helpers.neq, helpers.eval
|
||||
|
||||
describe('&encoding', function()
|
||||
|
@ -12,7 +12,7 @@ describe('&encoding', function()
|
|||
end)
|
||||
|
||||
it('cannot be changed after setup', function()
|
||||
execute('set encoding=latin1')
|
||||
feed_command('set encoding=latin1')
|
||||
-- error message expected
|
||||
feed('<cr>')
|
||||
neq(nil, string.find(eval('v:errmsg'), '^E474:'))
|
||||
|
@ -31,7 +31,7 @@ describe('&encoding', function()
|
|||
end)
|
||||
|
||||
it('can be set to utf-8 without error', function()
|
||||
execute('set encoding=utf-8')
|
||||
feed_command('set encoding=utf-8')
|
||||
eq("", eval('v:errmsg'))
|
||||
|
||||
clear('--cmd', 'set enc=utf-8')
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local clear, execute, feed, ok, eval =
|
||||
helpers.clear, helpers.execute, helpers.feed, helpers.ok, helpers.eval
|
||||
local clear, feed_command, feed, ok, eval =
|
||||
helpers.clear, helpers.feed_command, helpers.feed, helpers.ok, helpers.eval
|
||||
|
||||
describe(':grep', function()
|
||||
before_each(clear)
|
||||
|
@ -11,10 +11,10 @@ describe(':grep', function()
|
|||
return
|
||||
end
|
||||
|
||||
execute([[set grepprg=grep\ -r]])
|
||||
feed_command([[set grepprg=grep\ -r]])
|
||||
-- Change to test directory so that the test does not run too long.
|
||||
execute('cd test')
|
||||
execute('grep a **/*')
|
||||
feed_command('cd test')
|
||||
feed_command('grep a **/*')
|
||||
feed('<cr>') -- Press ENTER
|
||||
ok(eval('len(getqflist())') > 9000) -- IT'S OVER 9000!!1
|
||||
end)
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local clear, execute, nvim = helpers.clear, helpers.execute, helpers.nvim
|
||||
local expect, feed, command = helpers.expect, helpers.feed, helpers.command
|
||||
local clear, command, nvim = helpers.clear, helpers.command, helpers.nvim
|
||||
local expect, feed = helpers.expect, helpers.feed
|
||||
local eq, eval = helpers.eq, helpers.eval
|
||||
|
||||
describe(':emenu', function()
|
||||
|
||||
before_each(function()
|
||||
clear()
|
||||
execute('nnoremenu Test.Test inormal<ESC>')
|
||||
execute('inoremenu Test.Test insert')
|
||||
execute('vnoremenu Test.Test x')
|
||||
execute('cnoremenu Test.Test cmdmode')
|
||||
command('nnoremenu Test.Test inormal<ESC>')
|
||||
command('inoremenu Test.Test insert')
|
||||
command('vnoremenu Test.Test x')
|
||||
command('cnoremenu Test.Test cmdmode')
|
||||
|
||||
execute('nnoremenu Edit.Paste p')
|
||||
execute('cnoremenu Edit.Paste <C-R>"')
|
||||
command('nnoremenu Edit.Paste p')
|
||||
command('cnoremenu Edit.Paste <C-R>"')
|
||||
end)
|
||||
|
||||
it('executes correct bindings in normal mode without using API', function()
|
||||
execute('emenu Test.Test')
|
||||
command('emenu Test.Test')
|
||||
expect('normal')
|
||||
end)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
local Screen = require('test.functional.ui.screen')
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
|
||||
local buf, eq, execute = helpers.curbufmeths, helpers.eq, helpers.execute
|
||||
local buf, eq, feed_command = helpers.curbufmeths, helpers.eq, helpers.feed_command
|
||||
local feed, nvim_prog, wait = helpers.feed, helpers.nvim_prog, helpers.wait
|
||||
local ok, set_session, spawn = helpers.ok, helpers.set_session, helpers.spawn
|
||||
|
||||
|
@ -27,12 +27,12 @@ describe(':oldfiles', function()
|
|||
it('shows most recently used files', function()
|
||||
local screen = Screen.new(100, 5)
|
||||
screen:attach()
|
||||
execute('edit testfile1')
|
||||
execute('edit testfile2')
|
||||
execute('wshada ' .. shada_file)
|
||||
execute('rshada! ' .. shada_file)
|
||||
feed_command('edit testfile1')
|
||||
feed_command('edit testfile2')
|
||||
feed_command('wshada ' .. shada_file)
|
||||
feed_command('rshada! ' .. shada_file)
|
||||
local oldfiles = helpers.meths.get_vvar('oldfiles')
|
||||
execute('oldfiles')
|
||||
feed_command('oldfiles')
|
||||
screen:expect([[
|
||||
testfile2 |
|
||||
1: ]].. add_padding(oldfiles[1]) ..[[ |
|
||||
|
@ -50,14 +50,14 @@ describe(':browse oldfiles', function()
|
|||
|
||||
before_each(function()
|
||||
_clear()
|
||||
execute('edit testfile1')
|
||||
feed_command('edit testfile1')
|
||||
filename = buf.get_name()
|
||||
execute('edit testfile2')
|
||||
feed_command('edit testfile2')
|
||||
filename2 = buf.get_name()
|
||||
execute('wshada ' .. shada_file)
|
||||
feed_command('wshada ' .. shada_file)
|
||||
wait()
|
||||
_clear()
|
||||
execute('rshada! ' .. shada_file)
|
||||
feed_command('rshada! ' .. shada_file)
|
||||
|
||||
-- Ensure nvim is out of "Press ENTER..." prompt.
|
||||
feed('<cr>')
|
||||
|
@ -70,7 +70,7 @@ describe(':browse oldfiles', function()
|
|||
ok(filename == oldfiles[1] or filename == oldfiles[2])
|
||||
ok(filename2 == oldfiles[1] or filename2 == oldfiles[2])
|
||||
|
||||
execute('browse oldfiles')
|
||||
feed_command('browse oldfiles')
|
||||
end)
|
||||
|
||||
after_each(function()
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local lfs = require('lfs')
|
||||
local execute, eq, clear, eval, feed, expect, source =
|
||||
helpers.execute, helpers.eq, helpers.clear, helpers.eval, helpers.feed,
|
||||
local feed_command, eq, clear, eval, feed, expect, source =
|
||||
helpers.feed_command, helpers.eq, helpers.clear, helpers.eval, helpers.feed,
|
||||
helpers.expect, helpers.source
|
||||
|
||||
if helpers.pending_win32(pending) then return end
|
||||
|
@ -13,7 +13,7 @@ describe(':recover', function()
|
|||
|
||||
it('fails if given a non-existent swapfile', function()
|
||||
local swapname = 'bogus-swapfile'
|
||||
execute('recover '..swapname) -- This should not segfault. #2117
|
||||
feed_command('recover '..swapname) -- This should not segfault. #2117
|
||||
eq('E305: No swap file found for '..swapname, eval('v:errmsg'))
|
||||
end)
|
||||
|
||||
|
@ -40,12 +40,12 @@ describe(':preserve', function()
|
|||
]]
|
||||
|
||||
source(init)
|
||||
execute('set swapfile fileformat=unix undolevels=-1')
|
||||
feed_command('set swapfile fileformat=unix undolevels=-1')
|
||||
-- Put swapdir at the start of the 'directory' list. #1836
|
||||
execute('set directory^='..swapdir..'//')
|
||||
execute('edit '..testfile)
|
||||
feed_command('set directory^='..swapdir..'//')
|
||||
feed_command('edit '..testfile)
|
||||
feed('isometext<esc>')
|
||||
execute('preserve')
|
||||
feed_command('preserve')
|
||||
source('redir => g:swapname | swapname | redir END')
|
||||
|
||||
local swappath1 = eval('g:swapname')
|
||||
|
@ -59,8 +59,8 @@ describe(':preserve', function()
|
|||
source(init)
|
||||
|
||||
-- Use the "SwapExists" event to choose the (R)ecover choice at the dialog.
|
||||
execute('autocmd SwapExists * let v:swapchoice = "r"')
|
||||
execute('silent edit '..testfile)
|
||||
feed_command('autocmd SwapExists * let v:swapchoice = "r"')
|
||||
feed_command('silent edit '..testfile)
|
||||
source('redir => g:swapname | swapname | redir END')
|
||||
|
||||
local swappath2 = eval('g:swapname')
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
local helpers = require('test.functional.helpers')(after_each)
|
||||
|
||||
local eq = helpers.eq
|
||||
local clear = helpers.clear
|
||||
local exc_exec = helpers.exc_exec
|
||||
|
||||
describe(':syntax', function()
|
||||
before_each(clear)
|
||||
|
||||
describe('keyword', function()
|
||||
it('does not crash when group name contains unprintable characters',
|
||||
function()
|
||||
eq('Vim(syntax):E669: Unprintable character in group name',
|
||||
exc_exec('syntax keyword \024 foo bar'))
|
||||
end)
|
||||
end)
|
||||
end)
|
|
@ -5,7 +5,7 @@ local clear = helpers.clear
|
|||
local insert = helpers.insert
|
||||
local feed = helpers.feed
|
||||
local expect = helpers.expect
|
||||
local execute = helpers.execute
|
||||
local feed_command = helpers.feed_command
|
||||
local exc_exec = helpers.exc_exec
|
||||
|
||||
describe(':undojoin command', function()
|
||||
|
@ -14,10 +14,10 @@ describe(':undojoin command', function()
|
|||
insert([[
|
||||
Line of text 1
|
||||
Line of text 2]])
|
||||
execute('goto 1')
|
||||
feed_command('goto 1')
|
||||
end)
|
||||
it('joins changes in a buffer', function()
|
||||
execute('undojoin | delete')
|
||||
feed_command('undojoin | delete')
|
||||
expect([[
|
||||
Line of text 2]])
|
||||
feed('u')
|
||||
|
@ -26,7 +26,7 @@ describe(':undojoin command', function()
|
|||
end)
|
||||
it('does not corrupt undolist when connected with redo', function()
|
||||
feed('ixx<esc>')
|
||||
execute('undojoin | redo')
|
||||
feed_command('undojoin | redo')
|
||||
expect([[
|
||||
xxLine of text 1
|
||||
Line of text 2]])
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local lfs = require('lfs')
|
||||
local eq, eval, clear, write_file, execute, source, insert =
|
||||
local eq, eval, clear, write_file, source, insert =
|
||||
helpers.eq, helpers.eval, helpers.clear, helpers.write_file,
|
||||
helpers.execute, helpers.source, helpers.insert
|
||||
helpers.source, helpers.insert
|
||||
local redir_exec = helpers.redir_exec
|
||||
local exc_exec = helpers.exc_exec
|
||||
local command = helpers.command
|
||||
local feed_command = helpers.feed_command
|
||||
local funcs = helpers.funcs
|
||||
local meths = helpers.meths
|
||||
|
||||
|
@ -33,9 +34,9 @@ describe(':write', function()
|
|||
end)
|
||||
|
||||
it('&backupcopy=auto preserves symlinks', function()
|
||||
execute('set backupcopy=auto')
|
||||
command('set backupcopy=auto')
|
||||
write_file('test_bkc_file.txt', 'content0')
|
||||
execute("silent !ln -s test_bkc_file.txt test_bkc_link.txt")
|
||||
command("silent !ln -s test_bkc_file.txt test_bkc_link.txt")
|
||||
source([[
|
||||
edit test_bkc_link.txt
|
||||
call setline(1, ['content1'])
|
||||
|
@ -46,9 +47,9 @@ describe(':write', function()
|
|||
end)
|
||||
|
||||
it('&backupcopy=no replaces symlink with new file', function()
|
||||
execute('set backupcopy=no')
|
||||
command('set backupcopy=no')
|
||||
write_file('test_bkc_file.txt', 'content0')
|
||||
execute("silent !ln -s test_bkc_file.txt test_bkc_link.txt")
|
||||
command("silent !ln -s test_bkc_file.txt test_bkc_link.txt")
|
||||
source([[
|
||||
edit test_bkc_link.txt
|
||||
call setline(1, ['content1'])
|
||||
|
@ -69,7 +70,7 @@ describe(':write', function()
|
|||
insert(text)
|
||||
|
||||
-- Blocks until a consumer reads the FIFO.
|
||||
execute("write >> test_fifo")
|
||||
feed_command("write >> test_fifo")
|
||||
|
||||
-- Read the FIFO, this will unblock the :write above.
|
||||
local fifo = assert(io.open("test_fifo"))
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
-- Specs for :wundo and underlying functions
|
||||
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local execute, clear, eval, feed, spawn, nvim_prog, set_session =
|
||||
helpers.execute, helpers.clear, helpers.eval, helpers.feed, helpers.spawn,
|
||||
local command, clear, eval, spawn, nvim_prog, set_session =
|
||||
helpers.command, helpers.clear, helpers.eval, helpers.spawn,
|
||||
helpers.nvim_prog, helpers.set_session
|
||||
|
||||
|
||||
describe(':wundo', function()
|
||||
before_each(clear)
|
||||
after_each(function()
|
||||
os.remove(eval('getcwd()') .. '/foo')
|
||||
end)
|
||||
|
||||
it('safely fails on new, non-empty buffer', function()
|
||||
feed('iabc<esc>')
|
||||
execute('wundo foo') -- This should not segfault. #1027
|
||||
command('normal! iabc')
|
||||
command('wundo foo') -- This should not segfault. #1027
|
||||
--TODO: check messages for error message
|
||||
|
||||
os.remove(eval('getcwd()') .. '/foo') --cleanup
|
||||
end)
|
||||
end)
|
||||
|
||||
|
@ -23,7 +24,7 @@ describe('u_* functions', function()
|
|||
local session = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed',
|
||||
'-c', 'set undodir=. undofile'})
|
||||
set_session(session)
|
||||
execute('echo "True"') -- Should not error out due to crashed Neovim
|
||||
command('echo "True"') -- Should not error out due to crashed Neovim
|
||||
session:close()
|
||||
end)
|
||||
end)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local lfs = require('lfs')
|
||||
local execute, eq, neq, spawn, nvim_prog, set_session, wait, write_file
|
||||
= helpers.execute, helpers.eq, helpers.neq, helpers.spawn,
|
||||
helpers.nvim_prog, helpers.set_session, helpers.wait, helpers.write_file
|
||||
local command, eq, neq, spawn, nvim_prog, set_session, write_file =
|
||||
helpers.command, helpers.eq, helpers.neq, helpers.spawn,
|
||||
helpers.nvim_prog, helpers.set_session, helpers.write_file
|
||||
|
||||
describe(':wshada', function()
|
||||
local shada_file = 'wshada_test'
|
||||
|
@ -24,8 +24,7 @@ describe(':wshada', function()
|
|||
it('creates a shada file', function()
|
||||
-- file should _not_ exist
|
||||
eq(nil, lfs.attributes(shada_file))
|
||||
execute('wsh! '..shada_file)
|
||||
wait()
|
||||
command('wsh! '..shada_file)
|
||||
-- file _should_ exist
|
||||
neq(nil, lfs.attributes(shada_file))
|
||||
end)
|
||||
|
@ -40,8 +39,7 @@ describe(':wshada', function()
|
|||
eq(text, io.open(shada_file):read())
|
||||
neq(nil, lfs.attributes(shada_file))
|
||||
|
||||
execute('wsh! '..shada_file)
|
||||
wait()
|
||||
command('wsh! '..shada_file)
|
||||
|
||||
-- File should have been overwritten with a shada file.
|
||||
local fp = io.open(shada_file, 'r')
|
||||
|
|
|
@ -8,6 +8,7 @@ local Session = require('nvim.session')
|
|||
local TcpStream = require('nvim.tcp_stream')
|
||||
local SocketStream = require('nvim.socket_stream')
|
||||
local ChildProcessStream = require('nvim.child_process_stream')
|
||||
local Paths = require('test.config.paths')
|
||||
|
||||
local check_cores = global_helpers.check_cores
|
||||
local check_logs = global_helpers.check_logs
|
||||
|
@ -20,7 +21,11 @@ local dedent = global_helpers.dedent
|
|||
|
||||
local start_dir = lfs.currentdir()
|
||||
-- XXX: NVIM_PROG takes precedence, QuickBuild sets it.
|
||||
local nvim_prog = os.getenv('NVIM_PROG') or os.getenv('NVIM_PRG') or 'build/bin/nvim'
|
||||
local nvim_prog = (
|
||||
os.getenv('NVIM_PROG')
|
||||
or os.getenv('NVIM_PRG')
|
||||
or Paths.test_build_dir .. '/bin/nvim'
|
||||
)
|
||||
-- Default settings for the test session.
|
||||
local nvim_set = 'set shortmess+=I background=light noswapfile noautoindent'
|
||||
..' laststatus=1 undodir=. directory=. viewdir=. backupdir=.'
|
||||
|
@ -246,12 +251,13 @@ local function retry(max, max_ms, fn)
|
|||
return result
|
||||
end
|
||||
if (max and tries >= max) or (luv.now() - start_time > timeout) then
|
||||
break
|
||||
if type(result) == "string" then
|
||||
result = "\nretry() attempts: "..tostring(tries).."\n"..result
|
||||
end
|
||||
error(result)
|
||||
end
|
||||
tries = tries + 1
|
||||
end
|
||||
-- Do not use pcall() for the final attempt, let the failure bubble up.
|
||||
return fn()
|
||||
end
|
||||
|
||||
local function clear(...)
|
||||
|
@ -304,7 +310,7 @@ end
|
|||
|
||||
-- Executes an ex-command by user input. Because nvim_input() is used, VimL
|
||||
-- errors will not manifest as client (lua) errors. Use command() for that.
|
||||
local function execute(...)
|
||||
local function feed_command(...)
|
||||
for _, v in ipairs({...}) do
|
||||
if v:sub(1, 1) ~= '/' then
|
||||
-- not a search command, prefix with colon
|
||||
|
@ -565,7 +571,7 @@ local module = {
|
|||
insert = insert,
|
||||
iswin = iswin,
|
||||
feed = feed,
|
||||
execute = execute,
|
||||
feed_command = feed_command,
|
||||
eval = nvim_eval,
|
||||
call = nvim_call,
|
||||
command = nvim_command,
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
|
||||
local execute, expect = helpers.execute, helpers.expect
|
||||
local feed_command, expect = helpers.feed_command, helpers.expect
|
||||
|
||||
describe('filename recognition', function()
|
||||
setup(clear)
|
||||
|
@ -17,17 +17,17 @@ describe('filename recognition', function()
|
|||
fourth test for URL:\\machine.name\tmp\vimtest2d, and other text]])
|
||||
|
||||
-- Go to the first URL and append it to the beginning
|
||||
execute('/^first', '/tmp', 'call append(0, expand("<cfile>"))')
|
||||
feed_command('/^first', '/tmp', 'call append(0, expand("<cfile>"))')
|
||||
|
||||
-- Repeat for the second URL
|
||||
-- this time, navigate to the word "URL" instead of "tmp"
|
||||
execute('/^second', '/URL', 'call append(1, expand("<cfile>"))')
|
||||
feed_command('/^second', '/URL', 'call append(1, expand("<cfile>"))')
|
||||
|
||||
-- Repeat for the remaining URLs. This time, the 'isfname' option must be
|
||||
-- set to allow '\' in filenames
|
||||
execute('set isf=@,48-57,/,.,-,_,+,,,$,:,~,\\')
|
||||
execute('/^third', '/name', 'call append(2, expand("<cfile>"))')
|
||||
execute('/^fourth', '/URL', 'call append(3, expand("<cfile>"))')
|
||||
feed_command('set isf=@,48-57,/,.,-,_,+,,,$,:,~,\\')
|
||||
feed_command('/^third', '/name', 'call append(2, expand("<cfile>"))')
|
||||
feed_command('/^fourth', '/URL', 'call append(3, expand("<cfile>"))')
|
||||
|
||||
-- Delete the initial text, which now starts at line 5
|
||||
feed('5GdG')
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,10 +1,9 @@
|
|||
-- vim: set foldmethod=marker foldmarker=[[,]] :
|
||||
-- Test for autocommand that changes current buffer on BufEnter event.
|
||||
-- Check if modelines are interpreted for the correct buffer.
|
||||
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
|
||||
local execute, expect = helpers.execute, helpers.expect
|
||||
local feed_command, expect = helpers.feed_command, helpers.expect
|
||||
|
||||
describe('BufEnter with modelines', function()
|
||||
setup(clear)
|
||||
|
@ -20,34 +19,34 @@ describe('BufEnter with modelines', function()
|
|||
this is a test
|
||||
end of test file Xxx]])
|
||||
|
||||
execute('au BufEnter Xxx brew')
|
||||
feed_command('au BufEnter Xxx brew')
|
||||
|
||||
-- Write test file Xxx
|
||||
execute('/start of')
|
||||
execute('.,/end of/w! Xxx')
|
||||
execute('set ai modeline modelines=3')
|
||||
feed_command('/start of')
|
||||
feed_command('.,/end of/w! Xxx')
|
||||
feed_command('set ai modeline modelines=3')
|
||||
|
||||
-- Split to Xxx, autocmd will do :brew
|
||||
execute('sp Xxx')
|
||||
feed_command('sp Xxx')
|
||||
|
||||
-- Append text with autoindent to this file
|
||||
feed('G?this is a<CR>')
|
||||
feed('othis should be auto-indented<Esc>')
|
||||
|
||||
-- Go to Xxx, no autocmd anymore
|
||||
execute('au! BufEnter Xxx')
|
||||
execute('buf Xxx')
|
||||
feed_command('au! BufEnter Xxx')
|
||||
feed_command('buf Xxx')
|
||||
|
||||
-- Append text without autoindent to Xxx
|
||||
feed('G?this is a<CR>')
|
||||
feed('othis should be in column 1<Esc>')
|
||||
execute('wq')
|
||||
feed_command('wq')
|
||||
|
||||
-- Include Xxx in the current file
|
||||
feed('G:r Xxx<CR>')
|
||||
|
||||
-- Vim issue #57 do not move cursor on <c-o> when autoindent is set
|
||||
execute('set fo+=r')
|
||||
feed_command('set fo+=r')
|
||||
feed('G')
|
||||
feed('o# abcdef<Esc>2hi<CR><c-o>d0<Esc>')
|
||||
feed('o# abcdef<Esc>2hi<c-o>d0<Esc>')
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
|
||||
local execute, expect = helpers.execute, helpers.expect
|
||||
local command, expect = helpers.command, helpers.expect
|
||||
local wait = helpers.wait
|
||||
|
||||
describe('test5', function()
|
||||
setup(clear)
|
||||
|
@ -18,35 +19,37 @@ describe('test5', function()
|
|||
this is a test
|
||||
end of test file Xxx]])
|
||||
|
||||
execute('w! Xxx0')
|
||||
execute('au BufLeave Xxx bwipe')
|
||||
execute('/start of')
|
||||
command('w! Xxx0')
|
||||
command('au BufLeave Xxx bwipe')
|
||||
command('/start of')
|
||||
|
||||
-- Write test file Xxx.
|
||||
execute('.,/end of/w! Xxx')
|
||||
command('.,/end of/w! Xxx')
|
||||
|
||||
-- Split to Xxx.
|
||||
execute('sp Xxx')
|
||||
command('sp Xxx')
|
||||
|
||||
-- Delete buffer Xxx, now we're back here.
|
||||
execute('bwipe')
|
||||
command('bwipe')
|
||||
feed('G?this is a<cr>')
|
||||
feed('othis is some more text<esc>')
|
||||
wait()
|
||||
|
||||
-- Append some text to this file.
|
||||
|
||||
-- Write current file contents.
|
||||
execute('?start?,$yank A')
|
||||
command('?start?,$yank A')
|
||||
|
||||
-- Delete current buffer, get an empty one.
|
||||
execute('bwipe!')
|
||||
command('bwipe!')
|
||||
-- Append an extra line to the output register.
|
||||
feed('ithis is another test line<esc>:yank A<cr>')
|
||||
wait()
|
||||
|
||||
-- Output results
|
||||
execute('%d')
|
||||
execute('0put a')
|
||||
execute('$d')
|
||||
command('%d')
|
||||
command('0put a')
|
||||
command('$d')
|
||||
|
||||
-- Assert buffer contents.
|
||||
expect([[
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue