diff options
125 files changed, 1453 insertions, 1127 deletions
diff --git a/.github/workflows/notes.md b/.github/workflows/notes.md index 3bd6c739a5..d752f10609 100644 --- a/.github/workflows/notes.md +++ b/.github/workflows/notes.md @@ -21,8 +21,9 @@ ${NVIM_VERSION} ### macOS 1. Download **nvim-macos.tar.gz** -2. Extract: `tar xzvf nvim-macos.tar.gz` -3. Run `./nvim-osx64/bin/nvim` +2. Run `xattr -c ./nvim-macos.tar.gz` (to avoid "unknown developer" warning) +3. Extract: `tar xzvf nvim-macos.tar.gz` +4. Run `./nvim-macos/bin/nvim` ### Linux (x64) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index aad76d0979..1c6e62abbb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -78,7 +78,7 @@ jobs: retention-days: 1 macOS: - runs-on: macos-10.15 + runs-on: macos-11 steps: - uses: actions/checkout@v3 with: @@ -91,27 +91,36 @@ jobs: run: printf 'NVIM_BUILD_TYPE=Release\n' >> $GITHUB_ENV - if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.tag_name == 'nightly') run: printf 'NVIM_BUILD_TYPE=RelWithDebInfo\n' >> $GITHUB_ENV + - name: Provision universal `libintl` + run: | + GETTEXT_PREFIX="$(brew --prefix gettext)" + printf 'GETTEXT_PREFIX=%s\n' "$GETTEXT_PREFIX" >> $GITHUB_ENV + bottle_tag="arm64_big_sur" + brew fetch --bottle-tag="$bottle_tag" gettext + cd "$(mktemp -d)" + tar xf "$(brew --cache)"/**/*gettext*${bottle_tag}*.tar.gz + lipo gettext/*/lib/libintl.a "${GETTEXT_PREFIX}/lib/libintl.a" -create -output libintl.a + mv -f libintl.a /usr/local/lib/ + - name: Ensure static linkage to `libintl` + run: | + # We're about to mangle `gettext`, so let's remove any potentially broken + # installs (e.g. curl, git) as those could interfere with our build. + brew uninstall $(brew uses --installed --recursive gettext) + brew unlink gettext + ln -sf "$(brew --prefix)/opt/$(readlink "${GETTEXT_PREFIX}")/bin"/* /usr/local/bin/ + rm -f "$GETTEXT_PREFIX" - name: Build release run: | - make CMAKE_BUILD_TYPE=${NVIM_BUILD_TYPE} CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX:PATH= -DCMAKE_OSX_DEPLOYMENT_TARGET=10.11" - make DESTDIR="$GITHUB_WORKSPACE/build/release/nvim-osx64" install + export MACOSX_DEPLOYMENT_TARGET="$(sw_vers -productVersion | cut -f1 -d.)" + OSX_FLAGS="-DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} -DCMAKE_OSX_ARCHITECTURES=arm64\;x86_64" + make CMAKE_BUILD_TYPE=${NVIM_BUILD_TYPE} \ + CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX:PATH= $OSX_FLAGS" \ + DEPS_CMAKE_FLAGS="$OSX_FLAGS" + make DESTDIR="$GITHUB_WORKSPACE/build/release/nvim-macos" install - name: Create package run: | cd "$GITHUB_WORKSPACE/build/release" - mkdir -p nvim-osx64/libs - libs=($(otool -L nvim-osx64/bin/nvim | sed 1d | sed -E -e 's|^[[:space:]]*||' -e 's| .*||')) - echo "libs:" - for lib in "${libs[@]}"; do - if echo "$lib" | grep -q -E 'libSystem|CoreServices' 2>/dev/null; then - echo " [skipped] $lib" - else - echo " $lib" - relname="libs/${lib##*/}" - cp -L "$lib" "nvim-osx64/$relname" - install_name_tool -change "$lib" "@executable_path/../$relname" nvim-osx64/bin/nvim - fi - done - tar cfz nvim-macos.tar.gz nvim-osx64 + tar cfz nvim-macos.tar.gz nvim-macos - uses: actions/upload-artifact@v3 with: name: nvim-macos diff --git a/CMakeLists.txt b/CMakeLists.txt index dad0093cf0..8434a8824c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -444,7 +444,7 @@ if(TS_HAS_SET_ALLOCATOR) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNVIM_TS_HAS_SET_ALLOCATOR") endif() -# Note: The test lib requires LuaJIT; it will be skipped if LuaJIT is missing. +# The unit test lib requires LuaJIT; it will be skipped if LuaJIT is missing. option(PREFER_LUA "Prefer Lua over LuaJIT in the nvim executable." OFF) if(PREFER_LUA) @@ -573,11 +573,7 @@ endif() message(STATUS "Using Lua interpreter: ${LUA_PRG}") -if(DEBUG) - option(COMPILE_LUA "Pre-compile Lua sources into bytecode (for sources that are included in the binary)" OFF) -else() - option(COMPILE_LUA "Pre-compile Lua sources into bytecode (for sources that are included in the binary)" ON) -endif() +option(COMPILE_LUA "Pre-compile Lua sources into bytecode (for sources that are included in the binary)" ON) if(COMPILE_LUA AND NOT WIN32) if(PREFER_LUA) @@ -645,7 +641,7 @@ endif() include(InstallHelpers) install_helper( - FILES ${CMAKE_SOURCE_DIR}/man/nvim.1 + FILES ${CMAKE_SOURCE_DIR}/src/man/nvim.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) # @@ -678,7 +674,7 @@ if(BUSTED_PRG) list(APPEND TEST_TARGET_ARGS "USES_TERMINAL") set(UNITTEST_PREREQS nvim-test unittest-headers) - set(FUNCTIONALTEST_PREREQS nvim printenv-test printargs-test shell-test streams-test tty-test ${GENERATED_HELP_TAGS}) + set(FUNCTIONALTEST_PREREQS nvim printenv-test printargs-test shell-test pwsh-test streams-test tty-test ${GENERATED_HELP_TAGS}) set(BENCHMARK_PREREQS nvim tty-test) check_lua_module(${LUA_PRG} "ffi" LUA_HAS_FFI) diff --git a/MAINTAIN.md b/MAINTAIN.md index c644b88ad7..3bf5ab3c85 100644 --- a/MAINTAIN.md +++ b/MAINTAIN.md @@ -52,7 +52,7 @@ has a major bug: 3. Cut a release from `release-x.y`. - Run `./scripts/release.sh` - Update (force-push) the remote `stable` tag. - - The [nightly job](https://github.com/neovim/neovim/blob/master/.github/workflows/release.yml#L4) + - The [CI job](https://github.com/neovim/neovim/blob/3d45706478cd030c3ee05b4f336164bb96138095/.github/workflows/release.yml#L11-L13) will update the release assets based on the `stable` tag. The neovim repository includes a backport [github action](https://github.com/zeebe-io/backport-action). diff --git a/contrib/luarc.json b/contrib/luarc.json index 770b023ac6..8d76d1261d 100644 --- a/contrib/luarc.json +++ b/contrib/luarc.json @@ -5,6 +5,7 @@ "globals": [ "vim", "describe", + "pending", "it", "before_each", "after_each", diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt index e105b5e556..3f3f1e6ba3 100644 --- a/runtime/doc/cmdline.txt +++ b/runtime/doc/cmdline.txt @@ -877,7 +877,7 @@ Note: these are typed literally, they are not special keys! When the match is with a file name, it is expanded to the full path. *:<sfile>* *<sfile>* - <sfile> When executing a ":source" command, is replaced with the + <sfile> When executing a `:source` command, is replaced with the file name of the sourced file. *E498* When executing a function, is replaced with: "function {function-name}[{lnum}]" @@ -886,7 +886,7 @@ Note: these are typed literally, they are not special keys! Note that filename-modifiers are useless when <sfile> is used inside a function. *:<slnum>* *<slnum>* - <slnum> When executing a ":source" command, is replaced with the + <slnum> When executing a `:source` command, is replaced with the line number. *E842* When executing a function it's the line number relative to the start of the function. diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt index b25d5e89bd..c19d9f482b 100644 --- a/runtime/doc/editing.txt +++ b/runtime/doc/editing.txt @@ -1173,7 +1173,7 @@ Examples: > If you want to always use ":confirm", set the 'confirm' option. - *:browse* *:bro* *E338* *E614* *E615* *E616* + *:browse* *:bro* *E338* *E614* *E615* *E616* :bro[wse] {command} Open a file selection dialog for an argument to {command}. At present this works for |:e|, |:w|, |:wall|, |:wq|, |:wqall|, |:x|, |:xall|, |:exit|, diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 71f5ad4536..17af40bdb9 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -119,7 +119,7 @@ You will not get an error if you try to change the type of a variable. 1.2 Function references ~ - *Funcref* *E695* *E718* + *Funcref* *E695* *E718* A Funcref variable is obtained with the |function()| function, the |funcref()| function or created with the lambda expression |expr-lambda|. It can be used in an expression in the place of a function name, before the parenthesis @@ -1123,7 +1123,7 @@ Generally, if a |List| index is equal to or higher than the length of the error. -expr8[expr1a : expr1b] substring or sublist *expr-[:]* +expr8[expr1a : expr1b] substring or |sublist| *expr-[:]* *substring* If expr8 is a String this results in the substring with the bytes or characters from expr1a to and including expr1b. expr8 is used as a String, diff --git a/runtime/doc/filetype.txt b/runtime/doc/filetype.txt index 4795dae5e9..0e28ddc545 100644 --- a/runtime/doc/filetype.txt +++ b/runtime/doc/filetype.txt @@ -141,7 +141,7 @@ variables can be used to overrule the filetype used for certain extensions: *.asp g:filetype_asp |ft-aspvbs-syntax| |ft-aspperl-syntax| *.bas g:filetype_bas |ft-basic-syntax| *.cfg g:filetype_cfg - *.csh g:filetype_csh |ft-csh-syntax| + *.csh g:filetype_csh |ft-csh-syntax| *.dat g:filetype_dat *.frm g:filetype_frm |ft-form-syntax| *.fs g:filetype_fs |ft-forth-syntax| diff --git a/runtime/doc/indent.txt b/runtime/doc/indent.txt index 3992b2d3d7..1a1d8e30b0 100644 --- a/runtime/doc/indent.txt +++ b/runtime/doc/indent.txt @@ -290,7 +290,7 @@ The examples below assume a 'shiftwidth' of 4. < *cino-g* gN Place C++ scope declarations N characters from the indent of the - block they are in. (default 'shiftwidth'). By default, a scope + block they are in. (default 'shiftwidth'). By default, a scope declaration is "public:", "protected:" or "private:". This can be adjusted with the 'cinscopedecls' option. diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index 9f8d4a8479..0e72e89672 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -1935,8 +1935,7 @@ input({opts}, {on_confirm}) *vim.ui.input()* Parameters: ~ {opts} (table) Additional options. See |input()| - • prompt (string|nil) Text of the prompt. - Defaults to `Input:`. + • prompt (string|nil) Text of the prompt • default (string|nil) Default reply to the input • completion (string|nil) Specifies type of @@ -2064,14 +2063,55 @@ add({filetypes}) *vim.filetype.add()* {filetypes} (table) A table containing new filetype maps (see example). -match({name}, {bufnr}) *vim.filetype.match()* - Find the filetype for the given filename and buffer. +match({arg}) *vim.filetype.match()* + Perform filetype detection. + + The filetype can be detected using one of three methods: + 1. Using an existing buffer + 2. Using only a file name + 3. Using only file contents + + Of these, option 1 provides the most accurate result as it + uses both the buffer's filename and (optionally) the buffer + contents. Options 2 and 3 can be used without an existing + buffer, but may not always provide a match in cases where the + filename (or contents) cannot unambiguously determine the + filetype. + + Each of the three options is specified using a key to the + single argument of this function. Example: +> + + -- Using a buffer number + vim.filetype.match({ buf = 42 }) + + -- Override the filename of the given buffer + vim.filetype.match({ buf = 42, filename = 'foo.c' }) + + -- Using a filename without a buffer + vim.filetype.match({ filename = 'main.lua' }) + + -- Using file contents + vim.filetype.match({ contents = {'#!/usr/bin/env bash'} }) +< Parameters: ~ - {name} (string) File name (can be an absolute or - relative path) - {bufnr} (number|nil) The buffer to set the filetype for. - Defaults to the current buffer. + {arg} (table) Table specifying which matching strategy to + use. Accepted keys are: + • buf (number): Buffer number to use for matching. + Mutually exclusive with {contents} + • filename (string): Filename to use for matching. + When {buf} is given, defaults to the filename of + the given buffer number. The file need not + actually exist in the filesystem. When used + without {buf} only the name of the file is used + for filetype matching. This may result in failure + to detect the filetype in cases where the + filename alone is not enough to disambiguate the + filetype. + • contents (table): An array of lines representing + file contents to use for matching. Can be used + with {filename}. Mutually exclusive with {buf}. Return: ~ (string|nil) If a match was found, the matched filetype. diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt index 05cf30e078..a4b4f06ffc 100644 --- a/runtime/doc/map.txt +++ b/runtime/doc/map.txt @@ -176,7 +176,8 @@ keys. After that white space and a comment may follow: > "<unique>" can be used in any order. They must appear right after the command, before any other arguments. - *:map-local* *:map-<buffer>* *:map-buffer* *E224* *E225* + *:map-local* *:map-<buffer>* *:map-buffer* + *E224* *E225* If the first argument to one of these commands is "<buffer>" the mapping will be effective in the current buffer only. Example: > :map <buffer> ,w /[.,;]<CR> diff --git a/runtime/doc/nvim_terminal_emulator.txt b/runtime/doc/nvim_terminal_emulator.txt index b19343e7ef..a4c25009a9 100644 --- a/runtime/doc/nvim_terminal_emulator.txt +++ b/runtime/doc/nvim_terminal_emulator.txt @@ -379,7 +379,7 @@ the "disasm_window_height" entry can be used to set the window height: > let g:termdebug_config['disasm_window_height'] = 15 or, if there is no g:termdebug_config: > let g:termdebug_disasm_window = 15 -Any value greater than 1 will set the Asm window height to that value: > +Any value greater than 1 will set the Asm window height to that value. Communication ~ *termdebug-communication* @@ -445,7 +445,7 @@ get this error: Then your gdb is too old. -Colors~ +Colors ~ *hl-debugPC* *hl-debugBreakpoint* The color of the signs can be adjusted with these highlight groups: - debugPC the current position @@ -460,7 +460,8 @@ When 'background' is "dark": hi debugBreakpoint term=reverse ctermbg=red guibg=red -Shortcuts *termdebug_shortcuts* +Shortcuts ~ + *termdebug_shortcuts* You can define your own shortcuts (mappings) to control gdb, that can work in any window, using the TermDebugSendCommand() function. Example: > @@ -468,7 +469,8 @@ any window, using the TermDebugSendCommand() function. Example: > The argument is the gdb command. -Vim window width *termdebug_wide* +Vim window width ~ + *termdebug_wide* To change the width of the Vim window when debugging starts and use a vertical split: > diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 20805377d8..30ceb4f18b 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -3798,10 +3798,11 @@ A jump table for the options with a short description can be found at |Q_op|. :set listchars+=tab:>-,lead:. < *lcs-leadmultispace* leadmultispace:c... - Like multispace value, but only for leading whitespace - Overrides |lcs-lead| for leading multiple spaces. - `:set listchars=leadmultispace:---+` shows ten consecutive - leading spaces as: + Like the |lcs-multispace| value, but for leading + spaces only. Also overrides |lcs-lead| for leading + multiple spaces. + `:set listchars=leadmultispace:---+` shows ten + consecutive leading spaces as: ---+---+--XXX ~ Where "XXX" denotes the first non-blank characters in the line. @@ -5292,9 +5293,9 @@ A jump table for the options with a short description can be found at |Q_op|. unescaping, so to keep yourself sane use |:let-&| like shown above. *shell-powershell* To use PowerShell: > - let &shell = has('win32') ? 'powershell' : 'pwsh' + let &shell = executable('pwsh') ? 'pwsh' : 'powershell' let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command [Console]::InputEncoding=[Console]::OutputEncoding=[System.Text.Encoding]::UTF8;' - let &shellredir = '2>&1 | Out-File -Encoding UTF8 %s; exit $LastExitCode' + let &shellredir = '-RedirectStandardOutput %s -NoNewWindow -Wait' let &shellpipe = '2>&1 | Out-File -Encoding UTF8 %s; exit $LastExitCode' set shellquote= shellxquote= @@ -6969,7 +6970,7 @@ A jump table for the options with a short description can be found at |Q_op|. 'wildoptions' 'wop' string (default "pum,tagfile") global List of words that change how |cmdline-completion| is done. - pum Display the completion matches using the popupmenu + pum Display the completion matches using the popup menu in the same style as the |ins-completion-menu|. tagfile When using CTRL-D to list matching tags, the kind of tag and the file of the tag is listed. Only one match diff --git a/runtime/doc/quickref.txt b/runtime/doc/quickref.txt index 1716ea025d..a380088e98 100644 --- a/runtime/doc/quickref.txt +++ b/runtime/doc/quickref.txt @@ -638,7 +638,7 @@ Short explanation of each option: *option-list* 'cinkeys' 'cink' keys that trigger indent when 'cindent' is set 'cinoptions' 'cino' how to do indenting when 'cindent' is set 'cinwords' 'cinw' words where 'si' and 'cin' add an indent -'cinscopedecls' 'cinsd' words that are recognized by 'cino-g' +'cinscopedecls' 'cinsd' words that are recognized by 'cino-g' 'clipboard' 'cb' use the clipboard as the unnamed register 'cmdheight' 'ch' number of lines to use for the command-line 'cmdwinheight' 'cwh' height of the command-line window diff --git a/runtime/doc/tabpage.txt b/runtime/doc/tabpage.txt index f06a6bcc34..9197710819 100644 --- a/runtime/doc/tabpage.txt +++ b/runtime/doc/tabpage.txt @@ -129,7 +129,7 @@ something else. :+tabclose " close the next tab page :1tabclose " close the first tab page :$tabclose " close the last tab page - :tabclose -2 " close the 2nd previous tab page + :tabclose -2 " close the 2nd previous tab page :tabclose + " close the next tab page :tabclose 3 " close the third tab page :tabclose $ " close the last tab page diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt index 562faeaa2c..9eb6470962 100644 --- a/runtime/doc/various.txt +++ b/runtime/doc/various.txt @@ -346,7 +346,11 @@ g8 Print the hex values of the bytes used in the Only string variables can be used. After the redirection starts, if the variable is removed or locked or the variable type is changed, then further - command output messages will cause errors. + command output messages will cause errors. When using + a local variable (l:var in a function or s:var in a + script) and another `:redir` causes the current one to + end, the scope might be different and the assignment + fails. To get the output of one command the |execute()| function can be used instead of redirection. diff --git a/runtime/filetype.lua b/runtime/filetype.lua index b002b8971b..35bb31edce 100644 --- a/runtime/filetype.lua +++ b/runtime/filetype.lua @@ -12,7 +12,7 @@ vim.api.nvim_create_augroup('filetypedetect', { clear = false }) vim.api.nvim_create_autocmd({ 'BufRead', 'BufNewFile' }, { group = 'filetypedetect', callback = function(args) - local ft, on_detect = vim.filetype.match(args.file, args.buf) + local ft, on_detect = vim.filetype.match({ buf = args.buf }) if ft then vim.api.nvim_buf_set_option(args.buf, 'filetype', ft) if on_detect then diff --git a/runtime/indent/testdir/vim.in b/runtime/indent/testdir/vim.in index 699e4c243d..873045bc2c 100644 --- a/runtime/indent/testdir/vim.in +++ b/runtime/indent/testdir/vim.in @@ -30,6 +30,12 @@ for x in [ eval 0 endfor +let t = [ +\ { +\ 'k': 'val', +\ }, +\ ] + " END_INDENT " START_INDENT diff --git a/runtime/indent/testdir/vim.ok b/runtime/indent/testdir/vim.ok index f597d97e80..8e70abe619 100644 --- a/runtime/indent/testdir/vim.ok +++ b/runtime/indent/testdir/vim.ok @@ -30,6 +30,12 @@ for x in [ eval 0 endfor +let t = [ + \ { + \ 'k': 'val', + \ }, + \ ] + " END_INDENT " START_INDENT diff --git a/runtime/indent/vim.vim b/runtime/indent/vim.vim index cd2d4982d8..8076b2df07 100644 --- a/runtime/indent/vim.vim +++ b/runtime/indent/vim.vim @@ -1,7 +1,7 @@ " Vim indent file " Language: Vim script " Maintainer: Bram Moolenaar <Bram@vim.org> -" Last Change: 2022 Mar 01 +" Last Change: 2022 Jun 24 " Only load this indent file when no other was loaded. if exists("b:did_indent") @@ -36,6 +36,14 @@ endfunc let s:lineContPat = '^\s*\(\\\|"\\ \)' function GetVimIndentIntern() + " If the current line has line continuation and the previous one too, use + " the same indent. This does not skip empty lines. + let cur_text = getline(v:lnum) + let cur_has_linecont = cur_text =~ s:lineContPat + if cur_has_linecont && v:lnum > 1 && getline(v:lnum - 1) =~ s:lineContPat + return indent(v:lnum - 1) + endif + " Find a non-blank line above the current line. let lnum = prevnonblank(v:lnum - 1) @@ -44,8 +52,7 @@ function GetVimIndentIntern() " If the current line doesn't start with '\' or '"\ ' and below a line that " starts with '\' or '"\ ', use the indent of the line above it. - let cur_text = getline(v:lnum) - if cur_text !~ s:lineContPat + if !cur_has_linecont while lnum > 0 && getline(lnum) =~ s:lineContPat let lnum = lnum - 1 endwhile diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index 320d6a2a5b..73605413ee 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -33,7 +33,7 @@ end function M.getlines(bufnr, start_lnum, end_lnum) if not end_lnum then -- Return a single line as a string - return api.nvim_buf_get_lines(bufnr, start_lnum - 1, start_lnum, false)[1] + return api.nvim_buf_get_lines(bufnr, start_lnum - 1, start_lnum, false)[1] or '' end return api.nvim_buf_get_lines(bufnr, start_lnum - 1, end_lnum, false) end @@ -2047,7 +2047,7 @@ local pattern = { end end, { priority = -math.huge + 1 }), ['XF86Config.*'] = starsetf(function(path, bufnr) - return require('vim.filetype.detect').xfree86(bufnr) + return require('vim.filetype.detect').xfree86() end), ['%.zcompdump.*'] = starsetf('zsh'), -- .zlog* and zlog* @@ -2185,17 +2185,24 @@ end local function dispatch(ft, path, bufnr, ...) local on_detect if type(ft) == 'function' then - ft, on_detect = ft(path, bufnr, ...) + if bufnr then + ft, on_detect = ft(path, bufnr, ...) + else + -- If bufnr is nil (meaning we are matching only against the filename), set it to an invalid + -- value (-1) and catch any errors from the filetype detection function. If the function tries + -- to use the buffer then it will fail, but this enables functions which do not need a buffer + -- to still work. + local ok + ok, ft, on_detect = pcall(ft, path, -1, ...) + if not ok then + return + end + end end if type(ft) == 'string' then return ft, on_detect end - - -- Any non-falsey value (that is, anything other than 'nil' or 'false') will - -- end filetype matching. This is useful for e.g. the dist#ft functions that - -- return 0, but set the buffer's filetype themselves - return ft end ---@private @@ -2214,29 +2221,86 @@ local function match_pattern(name, path, tail, pat) return matches end ---- Find the filetype for the given filename and buffer. +--- Perform filetype detection. +--- +--- The filetype can be detected using one of three methods: +--- 1. Using an existing buffer +--- 2. Using only a file name +--- 3. Using only file contents +--- +--- Of these, option 1 provides the most accurate result as it uses both the buffer's filename and +--- (optionally) the buffer contents. Options 2 and 3 can be used without an existing buffer, but +--- may not always provide a match in cases where the filename (or contents) cannot unambiguously +--- determine the filetype. +--- +--- Each of the three options is specified using a key to the single argument of this function. +--- Example: +--- +--- <pre> +--- -- Using a buffer number +--- vim.filetype.match({ buf = 42 }) +--- +--- -- Override the filename of the given buffer +--- vim.filetype.match({ buf = 42, filename = 'foo.c' }) --- ----@param name string File name (can be an absolute or relative path) ----@param bufnr number|nil The buffer to set the filetype for. Defaults to the current buffer. +--- -- Using a filename without a buffer +--- vim.filetype.match({ filename = 'main.lua' }) +--- +--- -- Using file contents +--- vim.filetype.match({ contents = {'#!/usr/bin/env bash'} }) +--- </pre> +--- +---@param arg table Table specifying which matching strategy to use. Accepted keys are: +--- * buf (number): Buffer number to use for matching. Mutually exclusive with +--- {contents} +--- * filename (string): Filename to use for matching. When {buf} is given, +--- defaults to the filename of the given buffer number. The +--- file need not actually exist in the filesystem. When used +--- without {buf} only the name of the file is used for +--- filetype matching. This may result in failure to detect +--- the filetype in cases where the filename alone is not +--- enough to disambiguate the filetype. +--- * contents (table): An array of lines representing file contents to use for +--- matching. Can be used with {filename}. Mutually exclusive +--- with {buf}. ---@return string|nil If a match was found, the matched filetype. ---@return function|nil A function that modifies buffer state when called (for example, to set some --- filetype specific buffer variables). The function accepts a buffer number as --- its only argument. -function M.match(name, bufnr) +function M.match(arg) vim.validate({ - name = { name, 's' }, - bufnr = { bufnr, 'n', true }, + arg = { arg, 't' }, }) - -- When fired from the main filetypedetect autocommand the {bufnr} argument is omitted, so we use - -- the current buffer. The {bufnr} argument is provided to allow extensibility in case callers - -- wish to perform filetype detection on buffers other than the current one. - bufnr = bufnr or api.nvim_get_current_buf() + if not (arg.buf or arg.filename or arg.contents) then + error('At least one of "buf", "filename", or "contents" must be given') + end + + if arg.buf and arg.contents then + error('Only one of "buf" or "contents" must be given') + end + + local bufnr = arg.buf + local name = arg.filename + local contents = arg.contents + + if bufnr and not name then + name = api.nvim_buf_get_name(bufnr) + end - name = normalize_path(name) + if name then + name = normalize_path(name) + end local ft, on_detect + if contents then + -- Sanity check: this should not happen + assert(not bufnr, '"buf" and "contents" are mutually exclusive') + -- TODO: "scripts.lua" content matching + return + end + -- First check for the simple case where the full path exists as a key local path = vim.fn.resolve(vim.fn.fnamemodify(name, ':p')) ft, on_detect = dispatch(filename[path], path, bufnr) diff --git a/runtime/lua/vim/filetype/detect.lua b/runtime/lua/vim/filetype/detect.lua index 48dd3cb088..ddef27a0f0 100644 --- a/runtime/lua/vim/filetype/detect.lua +++ b/runtime/lua/vim/filetype/detect.lua @@ -906,9 +906,11 @@ function M.rules(path) local dir = vim.fn.expand(path, ':h') for _, line in ipairs(config_lines) do local match = line:match(udev_rules_pattern) - local udev_rules = line:gsub(udev_rules_pattern, match, 1) - if dir == udev_rules then - return 'udevrules' + if match then + local udev_rules = line:gsub(udev_rules_pattern, match, 1) + if dir == udev_rules then + return 'udevrules' + end end end return 'hog' diff --git a/runtime/lua/vim/ui.lua b/runtime/lua/vim/ui.lua index 77bca7f6c4..6f1ce3089d 100644 --- a/runtime/lua/vim/ui.lua +++ b/runtime/lua/vim/ui.lua @@ -59,7 +59,7 @@ end --- ---@param opts table Additional options. See |input()| --- - prompt (string|nil) ---- Text of the prompt. Defaults to `Input: `. +--- Text of the prompt --- - default (string|nil) --- Default reply to the input --- - completion (string|nil) @@ -87,7 +87,7 @@ function M.input(opts, on_confirm) on_confirm = { on_confirm, 'function', false }, }) - opts = opts or {} + opts = (opts and not vim.tbl_isempty(opts)) and opts or vim.empty_dict() local input = vim.fn.input(opts) if #input > 0 then on_confirm(input) diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim index f76bdebe9b..c4e90eb373 100644 --- a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim +++ b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim @@ -2,7 +2,7 @@ " " Author: Bram Moolenaar " Copyright: Vim license applies, see ":help license" -" Last Change: 2022 Jun 22 +" Last Change: 2022 Jun 24 " " WORK IN PROGRESS - The basics works stable, more to come " Note: In general you need at least GDB 7.12 because this provides the @@ -539,6 +539,7 @@ func TermDebugSendCommand(cmd) endif sleep 10m endif + " TODO: should we prepend CTRL-U to clear the command? call chansend(s:gdb_job_id, a:cmd . "\r") if do_continue Continue diff --git a/runtime/syntax/doxygen.vim b/runtime/syntax/doxygen.vim index 36d527b551..357c4302cf 100644 --- a/runtime/syntax/doxygen.vim +++ b/runtime/syntax/doxygen.vim @@ -120,7 +120,7 @@ try " end=+\(\n\s*\*\=\s*\([@\\]\([npcbea]\>\|em\>\|ref\>\|link\>\|f\$\|[$\\&<>#]\)\@!\)\|\s*$\)\@=+ "syn region doxygenBriefLine contained start=+\<\k+ skip=+^\s*\(\*/\@!\s*\)\=\(\<\|[@\\]\<\([npcbea]\>\|em\>\|ref\|link\>\>\|f\$\|[$\\&<>#]\)\|[^ \t\\@*]\)+ end=+^+ contains=doxygenContinueCommentWhite,doxygenSmallSpecial,@doxygenHtmlGroup,doxygenTODO,doxygenHyperLink,doxygenHashLink,@Spell skipwhite keepend matchgroup=xxx -syn region doxygenBriefLine contained start=+\<\k+ skip=+^\s*\(\*/\@!\s*\)\=\(\<\|[@\\]\<\([npcbea]\>\|em\>\|ref\|link\>\>\|f\$\|[$\\&<>#]\)\|[^ \t\\@*]\)+ end=+^+ skipwhite keepend matchgroup=xxx +syn region doxygenBriefLine contained start=+\<\k+ skip=+^\s*\(\*/\@!\s*\)\=\(\<\|[@\\]\<\([npcbea]\>\|em\>\|ref\|link\>\>\|f\$\|[$\\&<>#]\)\|[^ \t\\@*]\)+ end=+^+ skipwhite keepend matchgroup=xxx contains=@Spell " syn region doxygenBriefLine matchgroup=xxxy contained start=+\<\k.\++ skip=+^\s*\k+ end=+end+ skipwhite keepend "doxygenFindBriefSpecial, "" syn region doxygenSpecialMultilineDesc start=+.\++ contained contains=doxygenSpecialContinueCommentWhite,doxygenSmallSpecial,doxygenHyperLink,doxygenHashLink,@doxygenHtmlGroup,@Spell skipwhite keepend diff --git a/scripts/gen_vimdoc.py b/scripts/gen_vimdoc.py index 220b099df5..22fd155d32 100755 --- a/scripts/gen_vimdoc.py +++ b/scripts/gen_vimdoc.py @@ -59,8 +59,8 @@ if sys.version_info < MIN_PYTHON_VERSION: print("requires Python {}.{}+".format(*MIN_PYTHON_VERSION)) sys.exit(1) -doxygen_version = tuple([int(i) for i in subprocess.check_output(["doxygen", "-v"], - universal_newlines=True).split()[0].split('.')]) +doxygen_version = tuple((int(i) for i in subprocess.check_output(["doxygen", "-v"], + universal_newlines=True).split()[0].split('.'))) if doxygen_version < MIN_DOXYGEN_VERSION: print("\nRequires doxygen {}.{}.{}+".format(*MIN_DOXYGEN_VERSION)) @@ -1096,7 +1096,6 @@ def main(config, args): docs = '' - i = 0 for filename in CONFIG[target]['section_order']: try: title, helptag, section_doc = sections.pop(filename) @@ -1104,7 +1103,6 @@ def main(config, args): msg(f'warning: empty docs, skipping (target={target}): {filename}') msg(f' existing docs: {sections.keys()}') continue - i += 1 if filename not in CONFIG[target]['append_only']: docs += sep docs += '\n%s%s' % (title, diff --git a/man/Makefile b/src/man/Makefile index 3c0457e2ab..3c0457e2ab 100644 --- a/man/Makefile +++ b/src/man/Makefile diff --git a/man/nvim.1 b/src/man/nvim.1 index 9f35014ee8..9f35014ee8 100644 --- a/man/nvim.1 +++ b/src/man/nvim.1 diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 37f3aa1a23..0b29abaf5f 100755 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -161,12 +161,10 @@ list(REMOVE_ITEM NVIM_SOURCES ${to_remove}) # Legacy files that do not yet pass -Wconversion. set(CONV_SOURCES - ex_cmds.c fileio.c lua/treesitter.c mbyte.c memline.c - message.c regexp.c screen.c search.c diff --git a/src/nvim/api/autocmd.c b/src/nvim/api/autocmd.c index 3a35e49dc8..bf6402f938 100644 --- a/src/nvim/api/autocmd.c +++ b/src/nvim/api/autocmd.c @@ -549,9 +549,7 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc int retval; - for (size_t i = 0; i < patterns.size; i++) { - Object pat = patterns.items[i]; - + FOREACH_ITEM(patterns, pat, { // See: TODO(sctx) WITH_SCRIPT_CONTEXT(channel_id, { retval = autocmd_register(autocmd_id, @@ -569,7 +567,7 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc api_set_error(err, kErrorTypeException, "Failed to set autocmd"); goto cleanup; } - } + }) }); cleanup: @@ -781,14 +779,12 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err) bool modeline = true; buf_T *buf = curbuf; - bool set_buf = false; - - char *pattern = NULL; - Object *data = NULL; - bool set_pattern = false; + Array patterns = ARRAY_DICT_INIT; Array event_array = ARRAY_DICT_INIT; + Object *data = NULL; + if (!unpack_string_or_array(&event_array, &event, "event", true, err)) { goto cleanup; } @@ -826,21 +822,18 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err) } buf = find_buffer_by_handle((Buffer)buf_obj.data.integer, err); - set_buf = true; if (ERROR_SET(err)) { goto cleanup; } } - if (opts->pattern.type != kObjectTypeNil) { - if (opts->pattern.type != kObjectTypeString) { - api_set_error(err, kErrorTypeValidation, "'pattern' must be a string"); - goto cleanup; - } + if (!get_patterns_from_pattern_or_buf(&patterns, opts->pattern, opts->buffer, err)) { + goto cleanup; + } - pattern = string_to_cstr(opts->pattern.data.string); - set_pattern = true; + if (patterns.size == 0) { + ADD(patterns, STRING_OBJ(STATIC_CSTR_TO_STRING(""))); } if (opts->data.type != kObjectTypeNil) { @@ -849,16 +842,15 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err) modeline = api_object_to_bool(opts->modeline, "modeline", true, err); - if (set_pattern && set_buf) { - api_set_error(err, kErrorTypeValidation, "must not set 'buffer' and 'pattern'"); - goto cleanup; - } - bool did_aucmd = false; FOREACH_ITEM(event_array, event_str, { GET_ONE_EVENT(event_nr, event_str, cleanup) - did_aucmd |= apply_autocmds_group(event_nr, pattern, NULL, true, au_group, buf, NULL, data); + FOREACH_ITEM(patterns, pat, { + char *fname = opts->buffer.type == kObjectTypeNil ? pat.data.string.data : NULL; + did_aucmd |= + apply_autocmds_group(event_nr, fname, NULL, true, au_group, buf, NULL, data); + }) }) if (did_aucmd && modeline) { @@ -867,13 +859,13 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err) cleanup: api_free_array(event_array); - XFREE_CLEAR(pattern); + api_free_array(patterns); } static bool check_autocmd_string_array(Array arr, char *k, Error *err) { - for (size_t i = 0; i < arr.size; i++) { - if (arr.items[i].type != kObjectTypeString) { + FOREACH_ITEM(arr, entry, { + if (entry.type != kObjectTypeString) { api_set_error(err, kErrorTypeValidation, "All entries in '%s' must be strings", @@ -882,13 +874,13 @@ static bool check_autocmd_string_array(Array arr, char *k, Error *err) } // Disallow newlines in the middle of the line. - const String l = arr.items[i].data.string; + const String l = entry.data.string; if (memchr(l.data, NL, l.size)) { api_set_error(err, kErrorTypeValidation, "String cannot contain newlines"); return false; } - } + }) return true; } @@ -975,8 +967,8 @@ static bool get_patterns_from_pattern_or_buf(Array *patterns, Object pattern, Ob } Array array = v->data.array; - for (size_t i = 0; i < array.size; i++) { - char *pat = array.items[i].data.string.data; + FOREACH_ITEM(array, entry, { + char *pat = entry.data.string.data; size_t patlen = aucmd_pattern_length(pat); while (patlen) { ADD(*patterns, STRING_OBJ(cbuf_to_string((char *)pat, patlen))); @@ -984,15 +976,15 @@ static bool get_patterns_from_pattern_or_buf(Array *patterns, Object pattern, Ob pat = aucmd_next_pattern(pat, patlen); patlen = aucmd_pattern_length(pat); } - } + }) } else { api_set_error(err, kErrorTypeValidation, - "'pattern' must be a string"); + "'pattern' must be a string or table"); return false; } } else if (buffer.type != kObjectTypeNil) { - if (buffer.type != kObjectTypeInteger) { + if (buffer.type != kObjectTypeInteger && buffer.type != kObjectTypeBuffer) { api_set_error(err, kErrorTypeValidation, "'buffer' must be an integer"); diff --git a/src/nvim/api/command.c b/src/nvim/api/command.c index 141e1256ff..80a5449d29 100644 --- a/src/nvim/api/command.c +++ b/src/nvim/api/command.c @@ -13,6 +13,7 @@ #include "nvim/ex_docmd.h" #include "nvim/lua/executor.h" #include "nvim/ops.h" +#include "nvim/regexp.h" #include "nvim/window.h" #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -94,6 +95,7 @@ Dictionary nvim_parse_cmd(String str, Dictionary opts, Error *err) } goto end; } + vim_regfree(cmdinfo.cmdmod.cmod_filter_regmatch.regprog); // Parse arguments Array args = ARRAY_DICT_INIT; @@ -411,7 +413,7 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error // Simply pass the first argument (if it exists) as the arg pointer to `set_cmd_addr_type()` // since it only ever checks the first argument. - set_cmd_addr_type(&ea, argc > 0 ? (char_u *)args[0] : NULL); + set_cmd_addr_type(&ea, argc > 0 ? args[0] : NULL); if (HAS_KEY(cmd->range)) { if (!(ea.argt & EX_RANGE)) { diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 19ce25f676..8c174fc129 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -162,6 +162,19 @@ void nvim_set_option_value(String name, Object value, Dict(option) *opts, Error return; } + // If: + // - window id is provided + // - scope is not provided + // - option is global or local to window (global-local) + // + // Then force scope to local since we don't want to change the global option + if (opt_type == SREQ_WIN && scope == 0) { + int flags = get_option_value_strict(name.data, NULL, NULL, opt_type, to); + if (flags & SOPT_GLOBAL) { + scope = OPT_LOCAL; + } + } + long numval = 0; char *stringval = NULL; @@ -460,11 +473,12 @@ void set_option_to(uint64_t channel_id, void *to, int type, String name, Object stringval = value.data.string.data; } - WITH_SCRIPT_CONTEXT(channel_id, { - const int opt_flags = (type == SREQ_WIN && !(flags & SOPT_GLOBAL)) - ? 0 : (type == SREQ_GLOBAL) - ? OPT_GLOBAL : OPT_LOCAL; + // For global-win-local options -> setlocal + // For win-local options -> setglobal and setlocal (opt_flags == 0) + const int opt_flags = (type == SREQ_WIN && !(flags & SOPT_GLOBAL)) ? 0 : + (type == SREQ_GLOBAL) ? OPT_GLOBAL : OPT_LOCAL; + WITH_SCRIPT_CONTEXT(channel_id, { access_option_value_for(name.data, &numval, &stringval, opt_flags, type, to, false, err); }); } diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index c5881dbc5f..bf3fb04a18 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2109,7 +2109,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * bool highlights = false; if (str.size < 2 || memcmp(str.data, "%!", 2)) { - const char *const errmsg = check_stl_option((char_u *)str.data); + const char *const errmsg = check_stl_option(str.data); if (errmsg) { api_set_error(err, kErrorTypeValidation, "%s", errmsg); return result; diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index 69f01afcb6..7301e07a06 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -174,7 +174,7 @@ static void aupat_show(AutoPat *ap, event_T event, int previous_group) } msg_col = 4; - msg_outtrans((char_u *)ap->pat); + msg_outtrans(ap->pat); for (AutoCmd *ac = ap->cmds; ac != NULL; ac = ac->next) { // skip removed commands @@ -195,10 +195,10 @@ static void aupat_show(AutoPat *ap, event_T event, int previous_group) size_t msglen = 100; char *msg = (char *)xmallocz(msglen); snprintf(msg, msglen, "%s [%s]", exec_to_string, ac->desc); - msg_outtrans((char_u *)msg); + msg_outtrans(msg); XFREE_CLEAR(msg); } else { - msg_outtrans((char_u *)exec_to_string); + msg_outtrans(exec_to_string); } XFREE_CLEAR(exec_to_string); if (p_verbose > 0) { @@ -471,7 +471,7 @@ void augroup_del(char *name, bool stupid_legacy_mode) FOR_ALL_AUEVENTS(event) { FOR_ALL_AUPATS_IN_EVENT(event, ap) { if (ap->group == i && ap->pat != NULL) { - give_warning((char_u *)_("W19: Deleting augroup that is still in use"), true); + give_warning(_("W19: Deleting augroup that is still in use"), true); map_put(String, int)(&map_augroup_name_to_id, cstr_as_string(name), AUGROUP_DELETED); augroup_map_del(ap->group, NULL); return; @@ -717,7 +717,7 @@ char *au_event_disable(char *what) } else { STRCAT(new_ei, what); } - set_string_option_direct("ei", -1, (char_u *)new_ei, OPT_FREE, SID_NONE); + set_string_option_direct("ei", -1, new_ei, OPT_FREE, SID_NONE); xfree(new_ei); return save_ei; @@ -726,7 +726,7 @@ char *au_event_disable(char *what) void au_event_restore(char *old_ei) { if (old_ei != NULL) { - set_string_option_direct("ei", -1, (char_u *)old_ei, OPT_FREE, SID_NONE); + set_string_option_direct("ei", -1, old_ei, OPT_FREE, SID_NONE); xfree(old_ei); } } diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 85e34e910d..46adb55746 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -948,7 +948,7 @@ char *do_bufdel(int command, char_u *arg, int addr_count, int start_bnr, int end int deleted = 0; // number of buffers deleted char *errormsg = NULL; // return value int bnr; // buffer number - char_u *p; + char *p; if (addr_count == 0) { (void)do_buffer(command, DOBUF_CURRENT, FORWARD, 0, forceit); @@ -985,13 +985,12 @@ char *do_bufdel(int command, char_u *arg, int addr_count, int start_bnr, int end break; } if (!ascii_isdigit(*arg)) { - p = skiptowhite_esc(arg); - bnr = buflist_findpat(arg, p, command == DOBUF_WIPE, - false, false); + p = (char *)skiptowhite_esc(arg); + bnr = buflist_findpat(arg, (char_u *)p, command == DOBUF_WIPE, false, false); if (bnr < 0) { // failed break; } - arg = p; + arg = (char_u *)p; } else { bnr = getdigits_int(&arg, false, 0); } @@ -1679,8 +1678,8 @@ static inline void buf_init_changedtick(buf_T *const buf) /// @return pointer to the buffer buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int flags) { - char_u *ffname = ffname_arg; - char_u *sfname = sfname_arg; + char *ffname = (char *)ffname_arg; + char *sfname = (char *)sfname_arg; buf_T *buf; fname_expand(curbuf, &ffname, &sfname); // will allocate ffname @@ -1690,11 +1689,9 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int fl // We can use inode numbers when the file exists. Works better // for hard links. FileID file_id; - bool file_id_valid = (sfname != NULL - && os_fileid((char *)sfname, &file_id)); + bool file_id_valid = (sfname != NULL && os_fileid(sfname, &file_id)); if (ffname != NULL && !(flags & (BLN_DUMMY | BLN_NEW)) - && (buf = buflist_findname_file_id(ffname, &file_id, - file_id_valid)) != NULL) { + && (buf = buflist_findname_file_id(ffname, &file_id, file_id_valid)) != NULL) { xfree(ffname); if (lnum != 0) { buflist_setfpos(buf, (flags & BLN_NOCURWIN) ? NULL : curwin, @@ -1749,8 +1746,8 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int fl } if (ffname != NULL) { - buf->b_ffname = ffname; - buf->b_sfname = vim_strsave(sfname); + buf->b_ffname = (char_u *)ffname; + buf->b_sfname = vim_strsave((char_u *)sfname); } clear_wininfo(buf); @@ -2045,20 +2042,20 @@ void buflist_getfpos(void) /// @return buffer or NULL if not found buf_T *buflist_findname_exp(char_u *fname) { - char_u *ffname; + char *ffname; buf_T *buf = NULL; // First make the name into a full path name - ffname = (char_u *)FullName_save((char *)fname, + ffname = FullName_save((char *)fname, #ifdef UNIX - // force expansion, get rid of symbolic links - true + // force expansion, get rid of symbolic links + true #else - false + false #endif - ); // NOLINT(whitespace/parens) + ); // NOLINT(whitespace/parens) if (ffname != NULL) { - buf = buflist_findname(ffname); + buf = buflist_findname((char_u *)ffname); xfree(ffname); } return buf; @@ -2073,14 +2070,14 @@ buf_T *buflist_findname(char_u *ffname) { FileID file_id; bool file_id_valid = os_fileid((char *)ffname, &file_id); - return buflist_findname_file_id(ffname, &file_id, file_id_valid); + return buflist_findname_file_id((char *)ffname, &file_id, file_id_valid); } /// Same as buflist_findname(), but pass the FileID structure to avoid /// getting it twice for the same file. /// /// @return buffer or NULL if not found -static buf_T *buflist_findname_file_id(char_u *ffname, FileID *file_id, bool file_id_valid) +static buf_T *buflist_findname_file_id(char *ffname, FileID *file_id, bool file_id_valid) FUNC_ATTR_PURE { // Start at the last buffer, expect to find a match sooner. @@ -2213,7 +2210,7 @@ int buflist_findpat(const char_u *pattern, const char_u *pattern_end, bool unlis typedef struct { buf_T *buf; - char_u *match; + char *match; } bufmatch_T; /// Compare functions for qsort() below, that compares b_last_used. @@ -2236,9 +2233,9 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) { int count = 0; int round; - char_u *p; + char *p; int attempt; - char_u *patc; + char *patc; bufmatch_T *matches = NULL; *num_file = 0; // return values in case of FAIL @@ -2254,20 +2251,20 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) STRCPY(patc, "\\(^\\|[\\/]\\)"); STRCPY(patc + 11, pat + 1); } else { - patc = pat; + patc = (char *)pat; } // attempt == 0: try match with '\<', match at start of word // attempt == 1: try match without '\<', match anywhere for (attempt = 0; attempt <= 1; attempt++) { - if (attempt > 0 && patc == pat) { + if (attempt > 0 && (char_u *)patc == pat) { break; // there was no anchor, no need to try again } regmatch_T regmatch; - regmatch.regprog = vim_regcomp((char *)patc + attempt * 11, RE_MAGIC); + regmatch.regprog = vim_regcomp(patc + attempt * 11, RE_MAGIC); if (regmatch.regprog == NULL) { - if (patc != pat) { + if ((char_u *)patc != pat) { xfree(patc); } return FAIL; @@ -2294,16 +2291,16 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) count++; } else { if (options & WILD_HOME_REPLACE) { - p = home_replace_save(buf, p); + p = (char *)home_replace_save(buf, (char_u *)p); } else { - p = vim_strsave(p); + p = xstrdup(p); } if (matches != NULL) { matches[count].buf = buf; matches[count].match = p; count++; } else { - (*file)[count++] = p; + (*file)[count++] = (char_u *)p; } } } @@ -2325,7 +2322,7 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) } } - if (patc != pat) { + if ((char_u *)patc != pat) { xfree(patc); } @@ -2337,12 +2334,12 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) // if the current buffer is first in the list, place it at the end if (matches[0].buf == curbuf) { for (int i = 1; i < count; i++) { - (*file)[i - 1] = matches[i].match; + (*file)[i - 1] = (char_u *)matches[i].match; } - (*file)[count - 1] = matches[0].match; + (*file)[count - 1] = (char_u *)matches[0].match; } else { for (int i = 0; i < count; i++) { - (*file)[i] = matches[i].match; + (*file)[i] = (char_u *)matches[i].match; } } xfree(matches); @@ -2355,12 +2352,12 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) /// Check for a match on the file name for buffer "buf" with regprog "prog". /// /// @param ignore_case When true, ignore case. Use 'fic' otherwise. -static char_u *buflist_match(regmatch_T *rmp, buf_T *buf, bool ignore_case) +static char *buflist_match(regmatch_T *rmp, buf_T *buf, bool ignore_case) { // First try the short file name, then the long file name. - char_u *match = fname_match(rmp, buf->b_sfname, ignore_case); + char *match = fname_match(rmp, (char *)buf->b_sfname, ignore_case); if (match == NULL && rmp->regprog != NULL) { - match = fname_match(rmp, buf->b_ffname, ignore_case); + match = fname_match(rmp, (char *)buf->b_ffname, ignore_case); } return match; } @@ -2370,20 +2367,20 @@ static char_u *buflist_match(regmatch_T *rmp, buf_T *buf, bool ignore_case) /// @param ignore_case When true, ignore case. Use 'fileignorecase' otherwise. /// /// @return "name" when there is a match, NULL when not. -static char_u *fname_match(regmatch_T *rmp, char_u *name, bool ignore_case) +static char *fname_match(regmatch_T *rmp, char *name, bool ignore_case) { - char_u *match = NULL; - char_u *p; + char *match = NULL; + char *p; if (name != NULL) { // Ignore case when 'fileignorecase' or the argument is set. rmp->rm_ic = p_fic || ignore_case; - if (vim_regexec(rmp, name, (colnr_T)0)) { + if (vim_regexec(rmp, (char_u *)name, (colnr_T)0)) { match = name; } else if (rmp->regprog != NULL) { // Replace $(HOME) with '~' and try matching again. - p = home_replace_save(NULL, name); - if (vim_regexec(rmp, p, (colnr_T)0)) { + p = (char *)home_replace_save(NULL, (char_u *)name); + if (vim_regexec(rmp, (char_u *)p, (colnr_T)0)) { match = name; } xfree(p); @@ -2658,7 +2655,7 @@ void buflist_list(exarg_T *eap) if (buf_spname(buf) != NULL) { STRLCPY(NameBuff, buf_spname(buf), MAXPATHL); } else { - home_replace(buf, (char_u *)buf->b_fname, NameBuff, MAXPATHL, true); + home_replace(buf, buf->b_fname, (char *)NameBuff, MAXPATHL, true); } if (message_filtered(NameBuff)) { @@ -2688,7 +2685,7 @@ void buflist_list(exarg_T *eap) } // put "line 999" in column 40 or after the file name - i = 40 - vim_strsize(IObuff); + i = 40 - vim_strsize((char *)IObuff); do { IObuff[len++] = ' '; } while (--i > 0 && len < IOSIZE - 18); @@ -2699,7 +2696,7 @@ void buflist_list(exarg_T *eap) buf == curbuf ? (int64_t)curwin->w_cursor.lnum : (int64_t)buflist_findlnum(buf)); } - msg_outtrans(IObuff); + msg_outtrans((char *)IObuff); line_breakcheck(); } @@ -2735,10 +2732,10 @@ int buflist_name_nr(int fnum, char_u **fname, linenr_T *lnum) /// @param message give message when buffer already exists /// /// @return FAIL for failure (file name already in use by other buffer) OK otherwise. -int setfname(buf_T *buf, char_u *ffname_arg, char_u *sfname_arg, bool message) +int setfname(buf_T *buf, char *ffname_arg, char *sfname_arg, bool message) { - char_u *ffname = ffname_arg; - char_u *sfname = sfname_arg; + char *ffname = ffname_arg; + char *sfname = sfname_arg; buf_T *obuf = NULL; FileID file_id; bool file_id_valid = false; @@ -2760,7 +2757,7 @@ int setfname(buf_T *buf, char_u *ffname_arg, char_u *sfname_arg, bool message) // If the file name is already used in another buffer: // - if the buffer is loaded, fail // - if the buffer is not loaded, delete it from the list - file_id_valid = os_fileid((char *)ffname, &file_id); + file_id_valid = os_fileid(ffname, &file_id); if (!(buf->b_flags & BF_DUMMY)) { obuf = buflist_findname_file_id(ffname, &file_id, file_id_valid); } @@ -2775,16 +2772,16 @@ int setfname(buf_T *buf, char_u *ffname_arg, char_u *sfname_arg, bool message) // delete from the list close_buffer(NULL, obuf, DOBUF_WIPE, false, false); } - sfname = vim_strsave(sfname); + sfname = xstrdup(sfname); #ifdef USE_FNAME_CASE - path_fix_case(sfname); // set correct case for short file name + path_fix_case((char_u *)sfname); // set correct case for short file name #endif if (buf->b_sfname != buf->b_ffname) { xfree(buf->b_sfname); } xfree(buf->b_ffname); - buf->b_ffname = ffname; - buf->b_sfname = sfname; + buf->b_ffname = (char_u *)ffname; + buf->b_sfname = (char_u *)sfname; } buf->b_fname = (char *)buf->b_sfname; if (!file_id_valid) { @@ -2814,7 +2811,7 @@ void buf_set_name(int fnum, char_u *name) buf->b_sfname = NULL; // Allocate ffname and expand into full path. Also resolves .lnk // files on Win32. - fname_expand(buf, &buf->b_ffname, &buf->b_sfname); + fname_expand(buf, (char **)&buf->b_ffname, (char **)&buf->b_sfname); buf->b_fname = (char *)buf->b_sfname; } } @@ -2859,16 +2856,16 @@ buf_T *setaltfname(char_u *ffname, char_u *sfname, linenr_T lnum) /// @param errmsg give error message char_u *getaltfname(bool errmsg) { - char_u *fname; + char *fname; linenr_T dummy; - if (buflist_name_nr(0, &fname, &dummy) == FAIL) { + if (buflist_name_nr(0, (char_u **)&fname, &dummy) == FAIL) { if (errmsg) { emsg(_(e_noalt)); } return NULL; } - return fname; + return (char_u *)fname; } /// Add a file name to the buflist and return its number. @@ -2916,7 +2913,7 @@ void buflist_altfpos(win_T *win) bool otherfile(char_u *ffname) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - return otherfile_buf(curbuf, ffname, NULL, false); + return otherfile_buf(curbuf, (char *)ffname, NULL, false); } /// Check that "ffname" is not the same file as the file loaded in "buf". @@ -2926,7 +2923,7 @@ bool otherfile(char_u *ffname) /// @param ffname full path name to check /// @param file_id_p information about the file at "ffname". /// @param file_id_valid whether a valid "file_id_p" was passed in. -static bool otherfile_buf(buf_T *buf, char_u *ffname, FileID *file_id_p, bool file_id_valid) +static bool otherfile_buf(buf_T *buf, char *ffname, FileID *file_id_p, bool file_id_valid) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { // no name is different @@ -2941,7 +2938,7 @@ static bool otherfile_buf(buf_T *buf, char_u *ffname, FileID *file_id_p, bool fi // If no struct stat given, get it now if (file_id_p == NULL) { file_id_p = &file_id; - file_id_valid = os_fileid((char *)ffname, file_id_p); + file_id_valid = os_fileid(ffname, file_id_p); } if (!file_id_valid) { // file_id not valid, assume files are different. @@ -2995,7 +2992,7 @@ static bool buf_same_file_id(buf_T *buf, FileID *file_id) /// @param fullname when non-zero print full path void fileinfo(int fullname, int shorthelp, int dont_truncate) { - char_u *name; + char *name; int n; char *p; char *buffer; @@ -3015,11 +3012,11 @@ void fileinfo(int fullname, int shorthelp, int dont_truncate) STRLCPY(p, buf_spname(curbuf), IOSIZE - (p - buffer)); } else { if (!fullname && curbuf->b_fname != NULL) { - name = (char_u *)curbuf->b_fname; + name = curbuf->b_fname; } else { - name = curbuf->b_ffname; + name = (char *)curbuf->b_ffname; } - home_replace(shorthelp ? curbuf : NULL, name, (char_u *)p, + home_replace(shorthelp ? curbuf : NULL, name, p, (size_t)(IOSIZE - (p - buffer)), true); } @@ -3069,7 +3066,7 @@ void fileinfo(int fullname, int shorthelp, int dont_truncate) (int)curwin->w_cursor.col + 1, (int)curwin->w_virtcol + 1); } - (void)append_arg_number(curwin, (char_u *)buffer, IOSIZE, !shortmess(SHM_FILE)); + (void)append_arg_number(curwin, buffer, IOSIZE, !shortmess(SHM_FILE)); if (dont_truncate) { // Temporarily set msg_scroll to avoid the message being truncated. @@ -3103,14 +3100,14 @@ void col_print(char_u *buf, size_t buflen, int col, int vcol) } } -static char_u *lasttitle = NULL; -static char_u *lasticon = NULL; +static char *lasttitle = NULL; +static char *lasticon = NULL; /// Put the title name in the title bar and icon of the window. void maketitle(void) { - char_u *title_str = NULL; - char_u *icon_str = NULL; + char *title_str = NULL; + char *icon_str = NULL; int maxlen = 0; int len; int mustset; @@ -3145,14 +3142,13 @@ void maketitle(void) build_stl_str_hl(curwin, buf, sizeof(buf), (char *)p_titlestring, use_sandbox, 0, maxlen, NULL, NULL); - title_str = (char_u *)buf; + title_str = buf; if (called_emsg) { - set_string_option_direct("titlestring", -1, (char_u *)"", - OPT_FREE, SID_ERROR); + set_string_option_direct("titlestring", -1, "", OPT_FREE, SID_ERROR); } called_emsg |= save_called_emsg; } else { - title_str = p_titlestring; + title_str = (char *)p_titlestring; } } else { // Format: "fname + (path) (1 of 2) - VIM". @@ -3195,7 +3191,7 @@ void maketitle(void) // Get path of file, replace home dir with ~. *buf_p++ = ' '; *buf_p++ = '('; - home_replace(curbuf, curbuf->b_ffname, (char_u *)buf_p, + home_replace(curbuf, (char *)curbuf->b_ffname, buf_p, (SPACE_FOR_DIR - (size_t)(buf_p - buf)), true); #ifdef BACKSLASH_IN_FILENAME // Avoid "c:/name" to be reduced to "c". @@ -3232,18 +3228,17 @@ void maketitle(void) *buf_p = NUL; } - append_arg_number(curwin, (char_u *)buf_p, - (int)(SPACE_FOR_ARGNR - (size_t)(buf_p - buf)), false); + append_arg_number(curwin, buf_p, (int)(SPACE_FOR_ARGNR - (size_t)(buf_p - buf)), false); xstrlcat(buf_p, " - NVIM", (sizeof(buf) - (size_t)(buf_p - buf))); if (maxlen > 0) { // Make it shorter by removing a bit in the middle. - if (vim_strsize((char_u *)buf) > maxlen) { + if (vim_strsize(buf) > maxlen) { trunc_string((char_u *)buf, (char_u *)buf, maxlen, sizeof(buf)); } } - title_str = (char_u *)buf; + title_str = buf; #undef SPACE_FOR_FNAME #undef SPACE_FOR_DIR #undef SPACE_FOR_ARGNR @@ -3252,7 +3247,7 @@ void maketitle(void) mustset = value_change(title_str, &lasttitle); if (p_icon) { - icon_str = (char_u *)buf; + icon_str = buf; if (*p_iconstring != NUL) { if (stl_syntax & STL_IN_ICON) { int use_sandbox = false; @@ -3260,34 +3255,33 @@ void maketitle(void) use_sandbox = was_set_insecurely(curwin, "iconstring", 0); called_emsg = false; - build_stl_str_hl(curwin, (char *)icon_str, sizeof(buf), + build_stl_str_hl(curwin, icon_str, sizeof(buf), (char *)p_iconstring, use_sandbox, 0, 0, NULL, NULL); if (called_emsg) { - set_string_option_direct("iconstring", -1, - (char_u *)"", OPT_FREE, SID_ERROR); + set_string_option_direct("iconstring", -1, "", OPT_FREE, SID_ERROR); } called_emsg |= save_called_emsg; } else { - icon_str = p_iconstring; + icon_str = (char *)p_iconstring; } } else { - char_u *buf_p; + char *buf_p; if (buf_spname(curbuf) != NULL) { buf_p = buf_spname(curbuf); } else { // use file name only in icon - buf_p = (char_u *)path_tail((char *)curbuf->b_ffname); + buf_p = path_tail((char *)curbuf->b_ffname); } *icon_str = NUL; // Truncate name at 100 bytes. len = (int)STRLEN(buf_p); if (len > 100) { len -= 100; - len += mb_tail_off(buf_p, buf_p + len) + 1; + len += mb_tail_off((char_u *)buf_p, (char_u *)buf_p + len) + 1; buf_p += len; } STRCPY(icon_str, buf_p); - trans_characters(icon_str, IOSIZE); + trans_characters((char_u *)icon_str, IOSIZE); } } @@ -3306,7 +3300,7 @@ void maketitle(void) /// @param[in,out] last current title string /// /// @return true if resettitle() is to be called. -static bool value_change(char_u *str, char_u **last) +static bool value_change(char *str, char **last) FUNC_ATTR_WARN_UNUSED_RESULT { if ((str == NULL) != (*last == NULL) @@ -3316,7 +3310,7 @@ static bool value_change(char_u *str, char_u **last) *last = NULL; resettitle(); } else { - *last = vim_strsave(str); + *last = xstrdup(str); return true; } } @@ -3326,8 +3320,8 @@ static bool value_change(char_u *str, char_u **last) /// Set current window title void resettitle(void) { - ui_call_set_icon(cstr_as_string((char *)lasticon)); - ui_call_set_title(cstr_as_string((char *)lasttitle)); + ui_call_set_icon(cstr_as_string(lasticon)); + ui_call_set_title(cstr_as_string(lasttitle)); ui_flush(); } @@ -3431,7 +3425,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san } // Get line & check if empty (cursorpos will show "0-1"). - const char_u *line_ptr = ml_get_buf(wp->w_buffer, lnum, false); + const char *line_ptr = (char *)ml_get_buf(wp->w_buffer, lnum, false); bool empty_line = (*line_ptr == NUL); // Get the byte value now, in case we need it below. This is more @@ -3445,7 +3439,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san wp->w_cursor.coladd = 0; byteval = 0; } else { - byteval = utf_ptr2char((char *)line_ptr + wp->w_cursor.col); + byteval = utf_ptr2char(line_ptr + wp->w_cursor.col); } int groupdepth = 0; @@ -3522,7 +3516,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san continue; } stl_items[curitem].type = Separate; - stl_items[curitem++].start = (char_u *)out_p; + stl_items[curitem++].start = out_p; continue; } @@ -3530,7 +3524,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san if (*fmt_p == STL_TRUNCMARK) { fmt_p++; stl_items[curitem].type = Trunc; - stl_items[curitem++].start = (char_u *)out_p; + stl_items[curitem++].start = out_p; continue; } @@ -3546,7 +3540,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // Determine how long the group is. // Note: We set the current output position to null // so `vim_strsize` will work. - char_u *t = stl_items[stl_groupitems[groupdepth]].start; + char *t = stl_items[stl_groupitems[groupdepth]].start; *out_p = NUL; long group_len = vim_strsize(t); @@ -3579,7 +3573,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san } if (n == curitem && group_start_userhl == group_end_userhl) { // empty group - out_p = (char *)t; + out_p = t; group_len = 0; for (n = stl_groupitems[groupdepth] + 1; n < curitem; n++) { // do not use the highlighting from the removed group @@ -3589,7 +3583,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // adjust the start position of TabPage to the next // item position if (stl_items[n].type == TabPage) { - stl_items[n].start = (char_u *)out_p; + stl_items[n].start = out_p; } } } @@ -3604,7 +3598,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san long n = 0; while (group_len >= stl_items[stl_groupitems[groupdepth]].maxwid) { group_len -= ptr2cells(t + n); - n += utfc_ptr2len((char *)t + n); + n += utfc_ptr2len(t + n); } // } @@ -3612,7 +3606,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san *t = '<'; // { Move the truncated output - memmove(t + 1, t + n, (size_t)((char_u *)out_p - (t + n))); + memmove(t + 1, t + n, (size_t)(out_p - (t + n))); out_p = out_p - n + 1; // Fill up space left over by half a double-wide char. while (++group_len < stl_items[stl_groupitems[groupdepth]].minwid) { @@ -3646,7 +3640,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san } else { // { Move the group to the right group_len = (min_group_width - group_len) * utf_char2len(fillchar); - memmove(t + group_len, t, (size_t)((char_u *)out_p - t)); + memmove(t + group_len, t, (size_t)(out_p - t)); if (out_p + group_len >= (out_end_p + 1)) { group_len = (long)(out_end_p - out_p); } @@ -3692,7 +3686,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // to denote the styling to use. if (*fmt_p == STL_USER_HL) { stl_items[curitem].type = Highlight; - stl_items[curitem].start = (char_u *)out_p; + stl_items[curitem].start = out_p; stl_items[curitem].minwid = minwid > 9 ? 1 : minwid; fmt_p++; curitem++; @@ -3738,7 +3732,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san } } stl_items[curitem].type = TabPage; - stl_items[curitem].start = (char_u *)out_p; + stl_items[curitem].start = out_p; stl_items[curitem].minwid = minwid; fmt_p++; curitem++; @@ -3755,7 +3749,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san break; } stl_items[curitem].type = ClickFunc; - stl_items[curitem].start = (char_u *)out_p; + stl_items[curitem].start = out_p; stl_items[curitem].cmd = xmemdupz(t, (size_t)(fmt_p - t)); stl_items[curitem].minwid = minwid; fmt_p++; @@ -3780,7 +3774,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san if (*fmt_p == '(') { stl_groupitems[groupdepth++] = curitem; stl_items[curitem].type = Group; - stl_items[curitem].start = (char_u *)out_p; + stl_items[curitem].start = out_p; stl_items[curitem].minwid = minwid; stl_items[curitem].maxwid = maxwid; fmt_p++; @@ -3821,9 +3815,9 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san if (buf_spname(wp->w_buffer) != NULL) { STRLCPY(NameBuff, buf_spname(wp->w_buffer), MAXPATHL); } else { - char_u *t = (opt == STL_FULLPATH) ? wp->w_buffer->b_ffname - : (char_u *)wp->w_buffer->b_fname; - home_replace(wp->w_buffer, t, NameBuff, MAXPATHL, true); + char *t = (opt == STL_FULLPATH) ? (char *)wp->w_buffer->b_ffname + : wp->w_buffer->b_fname; + home_replace(wp->w_buffer, t, (char *)NameBuff, MAXPATHL, true); } trans_characters(NameBuff, MAXPATHL); if (opt != STL_FILENAME) { @@ -3912,18 +3906,14 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san size_t parsed_usefmt = (size_t)(block_start - usefmt); size_t str_length = STRLEN(str); size_t fmt_length = STRLEN(fmt_p); - size_t new_fmt_len = parsed_usefmt - + str_length + fmt_length + 3; - char_u *new_fmt = (char_u *)xmalloc(new_fmt_len * sizeof(char_u)); - char_u *new_fmt_p = new_fmt; - - new_fmt_p = (char_u *)memcpy(new_fmt_p, usefmt, parsed_usefmt) - + parsed_usefmt; - new_fmt_p = (char_u *)memcpy(new_fmt_p, str, str_length) - + str_length; - new_fmt_p = (char_u *)memcpy(new_fmt_p, "%}", 2) + 2; - new_fmt_p = (char_u *)memcpy(new_fmt_p, fmt_p, fmt_length) - + fmt_length; + size_t new_fmt_len = parsed_usefmt + str_length + fmt_length + 3; + char *new_fmt = xmalloc(new_fmt_len * sizeof(char)); + char *new_fmt_p = new_fmt; + + new_fmt_p = (char *)memcpy(new_fmt_p, usefmt, parsed_usefmt) + parsed_usefmt; + new_fmt_p = (char *)memcpy(new_fmt_p, str, str_length) + str_length; + new_fmt_p = (char *)memcpy(new_fmt_p, "%}", 2) + 2; + new_fmt_p = (char *)memcpy(new_fmt_p, fmt_p, fmt_length) + fmt_length; *new_fmt_p = 0; new_fmt_p = NULL; @@ -3931,7 +3921,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san xfree(usefmt); } XFREE_CLEAR(str); - usefmt = (char *)new_fmt; + usefmt = new_fmt; fmt_p = usefmt + parsed_usefmt; evaldepth++; continue; @@ -3974,7 +3964,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // Store the position percentage in our temporary buffer. // Note: We cannot store the value in `num` because // `get_rel_pos` can return a named position. Ex: "Top" - get_rel_pos(wp, (char_u *)buf_tmp, TMPLEN); + get_rel_pos(wp, buf_tmp, TMPLEN); str = buf_tmp; break; @@ -3989,14 +3979,14 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // Note: The call will only return true if it actually // appended data to the `buf_tmp` buffer. - if (append_arg_number(wp, (char_u *)buf_tmp, (int)sizeof(buf_tmp), false)) { + if (append_arg_number(wp, buf_tmp, (int)sizeof(buf_tmp), false)) { str = buf_tmp; } break; case STL_KEYMAP: fillable = false; - if (get_keymap_str(wp, (char_u *)"<%s>", (char_u *)buf_tmp, TMPLEN)) { + if (get_keymap_str(wp, "<%s>", buf_tmp, TMPLEN)) { str = buf_tmp; } break; @@ -4066,11 +4056,10 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // (including the comma and null terminating character) if (*wp->w_buffer->b_p_ft != NUL && STRLEN(wp->w_buffer->b_p_ft) < TMPLEN - 2) { - vim_snprintf(buf_tmp, sizeof(buf_tmp), ",%s", - wp->w_buffer->b_p_ft); + vim_snprintf(buf_tmp, sizeof(buf_tmp), ",%s", wp->w_buffer->b_p_ft); // Uppercase the file extension - for (char_u *t = (char_u *)buf_tmp; *t != 0; t++) { - *t = (char_u)TOUPPER_LOC(*t); + for (char *t = buf_tmp; *t != 0; t++) { + *t = (char)TOUPPER_LOC(*t); } str = buf_tmp; } @@ -4121,8 +4110,8 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // Create a highlight item based on the name if (*fmt_p == '#') { stl_items[curitem].type = Highlight; - stl_items[curitem].start = (char_u *)out_p; - stl_items[curitem].minwid = -syn_name2id_len((char_u *)t, (size_t)(fmt_p - t)); + stl_items[curitem].start = out_p; + stl_items[curitem].minwid = -syn_name2id_len(t, (size_t)(fmt_p - t)); curitem++; fmt_p++; } @@ -4133,7 +4122,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // If we made it this far, the item is normal and starts at // our current position in the output buffer. // Non-normal items would have `continued`. - stl_items[curitem].start = (char_u *)out_p; + stl_items[curitem].start = out_p; stl_items[curitem].type = Normal; // Copy the item string into the output buffer @@ -4151,7 +4140,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san } // } - long l = vim_strsize((char_u *)t); + long l = vim_strsize(t); // If this item is non-empty, record that the last thing // we put in the output buffer was an item @@ -4162,7 +4151,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // If the item is too wide, truncate it from the beginning if (l > maxwid) { while (l >= maxwid) { - l -= ptr2cells((char_u *)t); + l -= ptr2cells(t); t += utfc_ptr2len(t); } @@ -4219,8 +4208,8 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san prevchar_isitem = true; // { Build the formatting string - char_u nstr[20]; - char_u *t = nstr; + char nstr[20]; + char *t = nstr; if (opt == STL_VIRTCOL_ALT) { *t++ = '-'; minwid--; @@ -4232,7 +4221,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // Note: The `*` means we take the width as one of the arguments *t++ = '*'; - *t++ = (char_u)(base == kNumBaseHexadecimal ? 'X' : 'd'); + *t++ = base == kNumBaseHexadecimal ? 'X' : 'd'; *t = 0; // } @@ -4279,9 +4268,9 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san *++t = 0; // } - vim_snprintf(out_p, remaining_buf_len, (char *)nstr, 0, num, n); + vim_snprintf(out_p, remaining_buf_len, nstr, 0, num, n); } else { - vim_snprintf(out_p, remaining_buf_len, (char *)nstr, minwid, num); + vim_snprintf(out_p, remaining_buf_len, nstr, minwid, num); } // Advance the output buffer position to the end of the @@ -4318,15 +4307,15 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // We have now processed the entire statusline format string. // What follows is post-processing to handle alignment and highlighting. - int width = vim_strsize((char_u *)out); + int width = vim_strsize(out); if (maxwidth > 0 && width > maxwidth) { // Result is too long, must truncate somewhere. int item_idx = 0; - char_u *trunc_p; + char *trunc_p; // If there are no items, truncate from beginning if (itemcnt == 0) { - trunc_p = (char_u *)out; + trunc_p = out; // Otherwise, look for the truncation item } else { @@ -4349,7 +4338,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san if (width - vim_strsize(trunc_p) >= maxwidth) { // Walk from the beginning of the // string to find the last character that will fit. - trunc_p = (char_u *)out; + trunc_p = out; width = 0; for (;;) { width += ptr2cells(trunc_p); @@ -4359,7 +4348,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // Note: Only advance the pointer if the next // character will fit in the available output space - trunc_p += utfc_ptr2len((char *)trunc_p); + trunc_p += utfc_ptr2len(trunc_p); } // Ignore any items in the statusline that occur after @@ -4381,12 +4370,12 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san long trunc_len = 0; while (width >= maxwidth) { width -= ptr2cells(trunc_p + trunc_len); - trunc_len += utfc_ptr2len((char *)trunc_p + trunc_len); + trunc_len += utfc_ptr2len(trunc_p + trunc_len); } // } // { Truncate the string - char_u *trunc_end_p = trunc_p + trunc_len; + char *trunc_end_p = trunc_p + trunc_len; STRMOVE(trunc_p + 1, trunc_end_p); // Put a `<` to mark where we truncated at @@ -4452,10 +4441,10 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san for (int i = 0; i < num_separators; i++) { int dislocation = (i == (num_separators - 1)) ? final_spaces : standard_spaces; dislocation *= utf_char2len(fillchar); - char_u *start = stl_items[stl_separator_locations[i]].start; - char_u *seploc = start + dislocation; + char *start = stl_items[stl_separator_locations[i]].start; + char *seploc = start + dislocation; STRMOVE(seploc, start); - for (char_u *s = start; s < seploc;) { + for (char *s = start; s < seploc;) { MB_CHAR2BYTES(fillchar, s); } @@ -4491,7 +4480,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san StlClickRecord *cur_tab_rec = stl_tabtab; for (long l = 0; l < itemcnt; l++) { if (stl_items[l].type == TabPage) { - cur_tab_rec->start = (char *)stl_items[l].start; + cur_tab_rec->start = stl_items[l].start; if (stl_items[l].minwid == 0) { cur_tab_rec->def.type = kStlClickDisabled; cur_tab_rec->def.tabnr = 0; @@ -4508,7 +4497,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san cur_tab_rec->def.func = NULL; cur_tab_rec++; } else if (stl_items[l].type == ClickFunc) { - cur_tab_rec->start = (char *)stl_items[l].start; + cur_tab_rec->start = stl_items[l].start; cur_tab_rec->def.type = kStlClickFuncRun; cur_tab_rec->def.tabnr = stl_items[l].minwid; cur_tab_rec->def.func = stl_items[l].cmd; @@ -4533,7 +4522,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san /// Get relative cursor position in window into "buf[buflen]", in the form 99%, /// using "Top", "Bot" or "All" when appropriate. -void get_rel_pos(win_T *wp, char_u *buf, int buflen) +void get_rel_pos(win_T *wp, char *buf, int buflen) { // Need at least 3 chars for writing. if (buflen < 3) { @@ -4556,7 +4545,7 @@ void get_rel_pos(win_T *wp, char_u *buf, int buflen) } else if (above <= 0) { STRLCPY(buf, _("Top"), buflen); } else { - vim_snprintf((char *)buf, (size_t)buflen, "%2d%%", above > 1000000L + vim_snprintf(buf, (size_t)buflen, "%2d%%", above > 1000000L ? (int)(above / ((above + below) / 100L)) : (int)(above * 100L / (above + below))); } @@ -4570,7 +4559,7 @@ void get_rel_pos(win_T *wp, char_u *buf, int buflen) /// @param add_file if true, add "file" before the arg number /// /// @return true if it was appended. -static bool append_arg_number(win_T *wp, char_u *buf, int buflen, bool add_file) +static bool append_arg_number(win_T *wp, char *buf, int buflen, bool add_file) FUNC_ATTR_NONNULL_ALL { // Nothing to do @@ -4578,7 +4567,7 @@ static bool append_arg_number(win_T *wp, char_u *buf, int buflen, bool add_file) return false; } - char_u *p = buf + STRLEN(buf); // go to the end of the buffer + char *p = buf + STRLEN(buf); // go to the end of the buffer // Early out if the string is getting too long if (p - buf + 35 >= buflen) { @@ -4591,7 +4580,7 @@ static bool append_arg_number(win_T *wp, char_u *buf, int buflen, bool add_file) STRCPY(p, "file "); p += 5; } - vim_snprintf((char *)p, (size_t)(buflen - (p - buf)), + vim_snprintf(p, (size_t)(buflen - (p - buf)), wp->w_arg_idx_invalid ? "(%d) of %d)" : "%d of %d)", wp->w_arg_idx + 1, ARGCOUNT); @@ -4604,7 +4593,7 @@ static bool append_arg_number(win_T *wp, char_u *buf, int buflen, bool add_file) /// allocated memory. /// The "*ffname" and "*sfname" pointer values on call will not be freed. /// Note that the resulting "*ffname" pointer should be considered not allocated. -void fname_expand(buf_T *buf, char_u **ffname, char_u **sfname) +void fname_expand(buf_T *buf, char **ffname, char **sfname) { if (*ffname == NULL) { // no file name given, nothing to do return; @@ -4612,7 +4601,7 @@ void fname_expand(buf_T *buf, char_u **ffname, char_u **sfname) if (*sfname == NULL) { // no short file name given, use ffname *sfname = *ffname; } - *ffname = (char_u *)fix_fname((char *)(*ffname)); // expand to full path + *ffname = fix_fname((*ffname)); // expand to full path #ifdef WIN32 if (!buf->b_p_bin) { @@ -4620,24 +4609,24 @@ void fname_expand(buf_T *buf, char_u **ffname, char_u **sfname) char *rfname = os_resolve_shortcut((const char *)(*ffname)); if (rfname != NULL) { xfree(*ffname); - *ffname = (char_u *)rfname; - *sfname = (char_u *)rfname; + *ffname = rfname; + *sfname = rfname; } } #endif } /// Get the file name for an argument list entry. -char_u *alist_name(aentry_T *aep) +char *alist_name(aentry_T *aep) { buf_T *bp; // Use the name from the associated buffer if it exists. bp = buflist_findnr(aep->ae_fnum); if (bp == NULL || bp->b_fname == NULL) { - return aep->ae_fname; + return (char *)aep->ae_fname; } - return (char_u *)bp->b_fname; + return bp->b_fname; } /// do_arg_all(): Open up to 'count' windows, one for each argument. @@ -4646,7 +4635,7 @@ char_u *alist_name(aentry_T *aep) /// @param keep_tabs keep current tabs, for ":tab drop file" void do_arg_all(int count, int forceit, int keep_tabs) { - char_u *opened; // Array of weight for which args are open: + uint8_t *opened; // Array of weight for which args are open: // 0: not opened // 1: opened in other tab // 2: opened in curtab @@ -4710,7 +4699,7 @@ void do_arg_all(int count, int forceit, int keep_tabs) if (i < alist->al_ga.ga_len && (AARGLIST(alist)[i].ae_fnum == buf->b_fnum || path_full_compare(alist_name(&AARGLIST(alist)[i]), - buf->b_ffname, + (char *)buf->b_ffname, true, true) & kEqualFiles)) { int weight = 1; @@ -4722,7 +4711,7 @@ void do_arg_all(int count, int forceit, int keep_tabs) } if (weight > (int)opened[i]) { - opened[i] = (char_u)weight; + opened[i] = (uint8_t)weight; if (i == 0) { if (new_curwin != NULL) { new_curwin->w_arg_idx = opened_len; @@ -4854,7 +4843,7 @@ void do_arg_all(int count, int forceit, int keep_tabs) new_curwin = curwin; new_curtab = curtab; } - (void)do_ecmd(0, (char *)alist_name(&AARGLIST(alist)[i]), NULL, NULL, ECMD_ONE, + (void)do_ecmd(0, alist_name(&AARGLIST(alist)[i]), NULL, NULL, ECMD_ONE, ((buf_hide(curwin->w_buffer) || bufIsChanged(curwin->w_buffer)) ? ECMD_HIDE : 0) + ECMD_OLDBUF, @@ -5131,18 +5120,18 @@ void do_modelines(int flags) /// @param flags Same as for do_modelines(). static int chk_modeline(linenr_T lnum, int flags) { - char_u *s; - char_u *e; - char_u *linecopy; // local copy of any modeline found + char *s; + char *e; + char *linecopy; // local copy of any modeline found int prev; intmax_t vers; int end; int retval = OK; - char_u *save_sourcing_name; + char *save_sourcing_name; linenr_T save_sourcing_lnum; prev = -1; - for (s = ml_get(lnum); *s != NUL; s++) { + for (s = (char *)ml_get(lnum); *s != NUL; s++) { if (prev == -1 || ascii_isspace(prev)) { if ((prev != -1 && STRNCMP(s, "ex:", (size_t)3) == 0) || STRNCMP(s, "vi:", (size_t)3) == 0) { @@ -5171,7 +5160,7 @@ static int chk_modeline(linenr_T lnum, int flags) } } } - prev = *s; + prev = (uint8_t)(*s); } if (!*s) { @@ -5182,16 +5171,16 @@ static int chk_modeline(linenr_T lnum, int flags) s++; } while (s[-1] != ':'); - s = linecopy = vim_strsave(s); // copy the line, it will change + s = linecopy = xstrdup(s); // copy the line, it will change save_sourcing_lnum = sourcing_lnum; - save_sourcing_name = (char_u *)sourcing_name; + save_sourcing_name = sourcing_name; sourcing_lnum = lnum; // prepare for emsg() sourcing_name = "modelines"; end = false; while (end == false) { - s = (char_u *)skipwhite((char *)s); + s = skipwhite(s); if (*s == NUL) { break; } @@ -5218,7 +5207,7 @@ static int chk_modeline(linenr_T lnum, int flags) break; } end = true; - s = (char_u *)vim_strchr((char *)s, ' ') + 1; + s = vim_strchr(s, ' ') + 1; } *e = NUL; // truncate the set command @@ -5243,7 +5232,7 @@ static int chk_modeline(linenr_T lnum, int flags) } sourcing_lnum = save_sourcing_lnum; - sourcing_name = (char *)save_sourcing_name; + sourcing_name = save_sourcing_name; xfree(linecopy); @@ -5328,26 +5317,26 @@ bool buf_hide(const buf_T *const buf) /// @return special buffer name or /// NULL when the buffer has a normal file name. -char_u *buf_spname(buf_T *buf) +char *buf_spname(buf_T *buf) { if (bt_quickfix(buf)) { // Differentiate between the quickfix and location list buffers using // the buffer number stored in the global quickfix stack. if (buf->b_fnum == qf_stack_get_bufnr()) { - return (char_u *)_(msg_qflist); + return _(msg_qflist); } - return (char_u *)_(msg_loclist); + return _(msg_loclist); } // There is no _file_ when 'buftype' is "nofile", b_sfname // contains the name as specified by the user. if (bt_nofile(buf)) { if (buf->b_fname != NULL) { - return (char_u *)buf->b_fname; + return buf->b_fname; } if (bt_prompt(buf)) { - return (char_u *)_("[Prompt]"); + return _("[Prompt]"); } - return (char_u *)_("[Scratch]"); + return _("[Scratch]"); } if (buf->b_fname == NULL) { return buf_get_fname(buf); @@ -5530,13 +5519,13 @@ int buf_signcols(buf_T *buf, int maximum) } /// Get "buf->b_fname", use "[No Name]" if it is NULL. -char_u *buf_get_fname(const buf_T *buf) +char *buf_get_fname(const buf_T *buf) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { if (buf->b_fname == NULL) { - return (char_u *)_("[No Name]"); + return _("[No Name]"); } - return (char_u *)buf->b_fname; + return buf->b_fname; } /// Set 'buflisted' for curbuf to "on" and trigger autocommands if it changed. @@ -5632,7 +5621,7 @@ void wipe_buffer(buf_T *buf, bool aucmd) void buf_open_scratch(handle_T bufnr, char *bufname) { (void)do_ecmd((int)bufnr, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL); - (void)setfname(curbuf, (char_u *)bufname, NULL, true); + (void)setfname(curbuf, bufname, NULL, true); set_option_value("bh", 0L, "hide", OPT_LOCAL); set_option_value("bt", 0L, "nofile", OPT_LOCAL); set_option_value("swf", 0L, NULL, OPT_LOCAL); diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index f1dd8aadeb..5d1135f91c 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -373,7 +373,7 @@ struct mapblock { /// Used for highlighting in the status line. typedef struct stl_hlrec stl_hlrec_t; struct stl_hlrec { - char_u *start; + char *start; int userhl; // 0: no HL, 1-9: User HL, < 0 for syn ID }; @@ -381,7 +381,7 @@ struct stl_hlrec { typedef struct stl_item stl_item_t; struct stl_item { // Where the item starts in the status line output buffer - char_u *start; + char *start; // Function to run for ClickFunc items. char *cmd; // The minimum width of the item diff --git a/src/nvim/change.c b/src/nvim/change.c index c0796386f1..a383fe6bb3 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -1393,7 +1393,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment) while (old_size < repl_size && p > leader) { MB_PTR_BACK(leader, p); - old_size += ptr2cells(p); + old_size += ptr2cells((char *)p); } l = lead_repl_len - (int)(endp - p); if (l != 0) { @@ -1413,7 +1413,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment) if (l > 1) { p -= l; - if (ptr2cells(p) > 1) { + if (ptr2cells((char *)p) > 1) { p[1] = ' '; l--; } @@ -1463,7 +1463,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment) int l = utfc_ptr2len((char *)p); if (l > 1) { - if (ptr2cells(p) > 1) { + if (ptr2cells((char *)p) > 1) { // Replace a double-wide char with // two spaces l--; diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 9bc0bef446..885ebca214 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -687,11 +687,12 @@ int char2cells(int c) /// @param p /// /// @return number of display cells. -int ptr2cells(const char_u *p) +int ptr2cells(const char *p_in) { + uint8_t *p = (uint8_t *)p_in; // For UTF-8 we need to look at more bytes if the first byte is >= 0x80. if (*p >= 0x80) { - return utf_ptr2cells((char *)p); + return utf_ptr2cells(p_in); } // For DBCS we can tell the cell count from the first byte. @@ -706,9 +707,9 @@ int ptr2cells(const char_u *p) /// @param s /// /// @return number of character cells. -int vim_strsize(char_u *s) +int vim_strsize(char *s) { - return vim_strnsize(s, MAXCOL); + return vim_strnsize((char_u *)s, MAXCOL); } /// Return the number of character cells string "s[len]" will take on the @@ -726,7 +727,7 @@ int vim_strnsize(char_u *s, int len) int size = 0; while (*s != NUL && --len >= 0) { int l = utfc_ptr2len((char *)s); - size += ptr2cells(s); + size += ptr2cells((char *)s); s += l; len -= l - 1; } @@ -1332,10 +1333,10 @@ char_u *skip_to_newline(const char_u *const p) /// @param[out] nr Number read from the string. /// /// @return true on success, false on error/overflow -bool try_getdigits(char_u **pp, intmax_t *nr) +bool try_getdigits(char **pp, intmax_t *nr) { errno = 0; - *nr = strtoimax((char *)(*pp), (char **)pp, 10); + *nr = strtoimax(*pp, pp, 10); if (errno == ERANGE && (*nr == INTMAX_MIN || *nr == INTMAX_MAX)) { return false; } @@ -1353,7 +1354,7 @@ bool try_getdigits(char_u **pp, intmax_t *nr) intmax_t getdigits(char_u **pp, bool strict, intmax_t def) { intmax_t number; - int ok = try_getdigits(pp, &number); + int ok = try_getdigits((char **)pp, &number); if (strict && !ok) { abort(); } diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c index 29dcddfc0d..803427dd17 100644 --- a/src/nvim/debugger.c +++ b/src/nvim/debugger.c @@ -687,7 +687,7 @@ void ex_breaklist(exarg_T *eap) for (int i = 0; i < dbg_breakp.ga_len; i++) { struct debuggy *bp = &BREAKP(i); if (bp->dbg_type == DBG_FILE) { - home_replace(NULL, bp->dbg_name, NameBuff, MAXPATHL, true); + home_replace(NULL, (char *)bp->dbg_name, (char *)NameBuff, MAXPATHL, true); } if (bp->dbg_type != DBG_EXPR) { smsg(_("%3d %s %s line %" PRId64), diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 700e79ac75..f22933ec3c 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1408,8 +1408,7 @@ void diff_win_options(win_T *wp, int addbuf) } wp->w_p_fdm_save = vim_strsave(wp->w_p_fdm); } - set_string_option_direct("fdm", -1, (char_u *)"diff", - OPT_LOCAL | OPT_FREE, 0); + set_string_option_direct("fdm", -1, "diff", OPT_LOCAL | OPT_FREE, 0); curwin = old_curwin; curbuf = curwin->w_buffer; diff --git a/src/nvim/digraph.c b/src/nvim/digraph.c index 99e99a8a9e..cbff15c84a 100644 --- a/src/nvim/digraph.c +++ b/src/nvim/digraph.c @@ -1846,7 +1846,7 @@ static void printdigraph(const digr_T *dp, result_T *previous) *p++ = dp->char2; *p++ = ' '; *p = NUL; - msg_outtrans(buf); + msg_outtrans((char *)buf); p = buf; // add a space to draw a composing char on @@ -1863,7 +1863,7 @@ static void printdigraph(const digr_T *dp, result_T *previous) } assert(p >= buf); vim_snprintf((char *)p, sizeof(buf) - (size_t)(p - buf), " %3d", dp->result); - msg_outtrans(buf); + msg_outtrans((char *)buf); } } diff --git a/src/nvim/edit.c b/src/nvim/edit.c index e0717ef8bc..1223d98fbf 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -4223,7 +4223,7 @@ static int ins_compl_get_exp(pos_T *ini) msg_hist_off = true; // reset in msg_trunc_attr() vim_snprintf((char *)IObuff, IOSIZE, _("Scanning: %s"), ins_buf->b_fname == NULL - ? buf_spname(ins_buf) + ? (char_u *)buf_spname(ins_buf) : ins_buf->b_sfname == NULL ? (char_u *)ins_buf->b_fname : ins_buf->b_sfname); @@ -4831,15 +4831,15 @@ static int ins_compl_next(int allow_get_expansion, int count, int insert_match, */ if (compl_shown_match->cp_fname != NULL) { char *lead = _("match in file"); - int space = sc_col - vim_strsize((char_u *)lead) - 2; - char_u *s; - char_u *e; + int space = sc_col - vim_strsize(lead) - 2; + char *s; + char *e; if (space > 0) { // We need the tail that fits. With double-byte encoding going // back from the end is very slow, thus go from the start and keep // the text that fits in "space" between "s" and "e". - for (s = e = compl_shown_match->cp_fname; *e != NUL; MB_PTR_ADV(e)) { + for (s = e = (char *)compl_shown_match->cp_fname; *e != NUL; MB_PTR_ADV(e)) { space -= ptr2cells(e); while (space < 0) { space += ptr2cells(s); @@ -4848,7 +4848,7 @@ static int ins_compl_next(int allow_get_expansion, int count, int insert_match, } msg_hist_off = true; vim_snprintf((char *)IObuff, IOSIZE, "%s %s%s", lead, - s > compl_shown_match->cp_fname ? "<" : "", s); + (char_u *)s > compl_shown_match->cp_fname ? "<" : "", s); msg((char *)IObuff); msg_hist_off = false; redraw_cmdline = false; // don't overwrite! @@ -5263,12 +5263,13 @@ static int ins_complete(int c, bool enable_pum) return FAIL; } - /* Return value -2 means the user complete function wants to - * cancel the complete without an error. - * Return value -3 does the same as -2 and leaves CTRL-X mode.*/ - if (col == -2) { + // Return value -2 means the user complete function wants to cancel the + // complete without an error, do the same if the function did not execute + // successfully. + if (col == -2 || aborting()) { return FAIL; } + // Return value -3 does the same as -2 and leaves CTRL-X mode. if (col == -3) { ctrl_x_mode = CTRL_X_NORMAL; edit_submode = NULL; @@ -6806,15 +6807,15 @@ void beginline(int flags) int oneright(void) { - char_u *ptr; + char *ptr; int l; if (virtual_active()) { pos_T prevpos = curwin->w_cursor; // Adjust for multi-wide char (excluding TAB) - ptr = get_cursor_pos_ptr(); - coladvance(getviscol() + ((*ptr != TAB && vim_isprintc(utf_ptr2char((char *)ptr))) ? + ptr = (char *)get_cursor_pos_ptr(); + coladvance(getviscol() + ((*ptr != TAB && vim_isprintc(utf_ptr2char(ptr))) ? ptr2cells(ptr) : 1)); curwin->w_set_curswant = true; // Return OK if the cursor moved, FAIL otherwise (at window edge). @@ -6822,12 +6823,12 @@ int oneright(void) || prevpos.coladd != curwin->w_cursor.coladd) ? OK : FAIL; } - ptr = get_cursor_pos_ptr(); + ptr = (char *)get_cursor_pos_ptr(); if (*ptr == NUL) { return FAIL; // already at the very end } - l = utfc_ptr2len((char *)ptr); + l = utfc_ptr2len(ptr); // move "l" bytes right, but don't end up on the NUL, unless 'virtualedit' // contains "onemore". @@ -6864,12 +6865,9 @@ int oneleft(void) } if (curwin->w_cursor.coladd == 1) { - char_u *ptr; - // Adjust for multi-wide char (not a TAB) - ptr = get_cursor_pos_ptr(); - if (*ptr != TAB && vim_isprintc(utf_ptr2char((char *)ptr)) - && ptr2cells(ptr) > 1) { + char *ptr = (char *)get_cursor_pos_ptr(); + if (*ptr != TAB && vim_isprintc(utf_ptr2char(ptr)) && ptr2cells(ptr) > 1) { curwin->w_cursor.coladd = 0; } } diff --git a/src/nvim/eval.c b/src/nvim/eval.c index be2df9488e..bb2404750b 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -469,7 +469,9 @@ void eval_clear(void) hash_clear(&compat_hashtab); free_scriptnames(); +# ifdef HAVE_WORKING_LIBINTL free_locales(); +# endif // global variables vars_clear(&globvarht); @@ -8966,7 +8968,7 @@ static void list_one_var_a(const char *prefix, const char *name, const ptrdiff_t msg_putchar(' '); } - msg_outtrans((char_u *)string); + msg_outtrans((char *)string); if (type == VAR_FUNC || type == VAR_PARTIAL) { msg_puts("()"); @@ -10122,7 +10124,7 @@ repeat: os_dirname((char_u *)dirname, MAXPATHL); if (has_homerelative) { s = xstrdup(dirname); - home_replace(NULL, (char_u *)s, (char_u *)dirname, MAXPATHL, true); + home_replace(NULL, s, dirname, MAXPATHL, true); xfree(s); } size_t namelen = STRLEN(dirname); @@ -10145,7 +10147,7 @@ repeat: } } } else { - home_replace(NULL, (char_u *)p, (char_u *)dirname, MAXPATHL, true); + home_replace(NULL, p, dirname, MAXPATHL, true); // Only replace it when it starts with '~' if (*dirname == '~') { s = xstrdup(dirname); diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 4fc6c587dd..6f5c879e0a 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -10691,7 +10691,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) // "./…" => "/home/foo/…" vim_FullName(cwd, (char *)NameBuff, sizeof(NameBuff), false); // "/home/foo/…" => "~/…" - size_t len = home_replace(NULL, NameBuff, IObuff, sizeof(IObuff), true); + size_t len = home_replace(NULL, (char *)NameBuff, (char *)IObuff, sizeof(IObuff), true); // Trim slash. if (len != 1 && (IObuff[len - 1] == '\\' || IObuff[len - 1] == '/')) { IObuff[len - 1] = '\0'; @@ -10709,7 +10709,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) // at this point the buffer has no terminal instance associated yet, so unset // the 'swapfile' option to ensure no swap file will be created curbuf->b_p_swf = false; - (void)setfname(curbuf, NameBuff, NULL, true); + (void)setfname(curbuf, (char *)NameBuff, NULL, true); // Save the job id and pid in b:terminal_job_{id,pid} Error err = ERROR_INIT; // deprecated: use 'channel' buffer option diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index 9938dc5012..8646520ec3 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -1044,9 +1044,8 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett if (tofree != NULL) { char *s = tofree; char buf[MSG_BUF_LEN]; - if (vim_strsize((char_u *)s) > MSG_BUF_CLEN) { - trunc_string((char_u *)s, (char_u *)buf, MSG_BUF_CLEN, - sizeof(buf)); + if (vim_strsize(s) > MSG_BUF_CLEN) { + trunc_string((char_u *)s, (char_u *)buf, MSG_BUF_CLEN, sizeof(buf)); s = buf; } msg_puts(s); @@ -1159,7 +1158,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett char *tofree = s; emsg_off--; if (s != NULL) { - if (vim_strsize((char_u *)s) > MSG_BUF_CLEN) { + if (vim_strsize(s) > MSG_BUF_CLEN) { trunc_string((char_u *)s, (char_u *)buf, MSG_BUF_CLEN, MSG_BUF_LEN); s = buf; } diff --git a/src/nvim/event/socket.c b/src/nvim/event/socket.c index 1722f0ee1f..9496a568b9 100644 --- a/src/nvim/event/socket.c +++ b/src/nvim/event/socket.c @@ -38,7 +38,7 @@ int socket_watcher_init(Loop *loop, SocketWatcher *watcher, const char *endpoint char *port = host_end + 1; intmax_t iport; - int ok = try_getdigits(&(char_u *){ (char_u *)port }, &iport); + int ok = try_getdigits(&(char *){ port }, &iport); if (!ok || iport < 0 || iport > UINT16_MAX) { ELOG("Invalid port: %s", port); return UV_EINVAL; diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index a1f0a123b1..8016c69bcb 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -144,17 +144,15 @@ void do_ascii(const exarg_T *const eap) dig = (char *)get_digraph_for_char(cval); if (dig != NULL) { - iobuff_len += ( - vim_snprintf((char *)IObuff + iobuff_len, - sizeof(IObuff) - iobuff_len, - _("<%s>%s%s %d, Hex %02x, Oct %03o, Digr %s"), - transchar(c), buf1, buf2, cval, cval, cval, dig)); + iobuff_len += (size_t)vim_snprintf((char *)IObuff + iobuff_len, + sizeof(IObuff) - iobuff_len, + _("<%s>%s%s %d, Hex %02x, Oct %03o, Digr %s"), + transchar(c), buf1, buf2, cval, cval, cval, dig); } else { - iobuff_len += ( - vim_snprintf((char *)IObuff + iobuff_len, - sizeof(IObuff) - iobuff_len, - _("<%s>%s%s %d, Hex %02x, Octal %03o"), - transchar(c), buf1, buf2, cval, cval, cval)); + iobuff_len += (size_t)vim_snprintf((char *)IObuff + iobuff_len, + sizeof(IObuff) - iobuff_len, + _("<%s>%s%s %d, Hex %02x, Octal %03o"), + transchar(c), buf1, buf2, cval, cval, cval); } c = cc[ci++]; @@ -190,25 +188,23 @@ void do_ascii(const exarg_T *const eap) if (utf_iscomposing(c)) { IObuff[iobuff_len++] = ' '; // Draw composing char on top of a space. } - iobuff_len += utf_char2bytes(c, (char *)IObuff + iobuff_len); + iobuff_len += (size_t)utf_char2bytes(c, (char *)IObuff + iobuff_len); dig = (char *)get_digraph_for_char(c); if (dig != NULL) { - iobuff_len += ( - vim_snprintf((char *)IObuff + iobuff_len, - sizeof(IObuff) - iobuff_len, - (c < 0x10000 - ? _("> %d, Hex %04x, Oct %o, Digr %s") - : _("> %d, Hex %08x, Oct %o, Digr %s")), - c, c, c, dig)); + iobuff_len += (size_t)vim_snprintf((char *)IObuff + iobuff_len, + sizeof(IObuff) - iobuff_len, + (c < 0x10000 + ? _("> %d, Hex %04x, Oct %o, Digr %s") + : _("> %d, Hex %08x, Oct %o, Digr %s")), + c, c, c, dig); } else { - iobuff_len += ( - vim_snprintf((char *)IObuff + iobuff_len, - sizeof(IObuff) - iobuff_len, - (c < 0x10000 - ? _("> %d, Hex %04x, Octal %o") - : _("> %d, Hex %08x, Octal %o")), - c, c, c)); + iobuff_len += (size_t)vim_snprintf((char *)IObuff + iobuff_len, + sizeof(IObuff) - iobuff_len, + (c < 0x10000 + ? _("> %d, Hex %04x, Octal %o") + : _("> %d, Hex %08x, Octal %o")), + c, c, c); } if (ci == MAX_MCO) { break; @@ -254,10 +250,10 @@ void ex_align(exarg_T *eap) * if invalid value, use 80 */ if (width <= 0) { - width = curbuf->b_p_tw; + width = (int)curbuf->b_p_tw; } if (width == 0 && curbuf->b_p_wm > 0) { - width = curwin->w_width_inner - curbuf->b_p_wm; + width = curwin->w_width_inner - (int)curbuf->b_p_wm; } if (width <= 0) { width = 80; @@ -325,7 +321,6 @@ static int linelen(int *has_tab) char *line; char *first; char *last; - int save; int len; // Get the line. If it's empty bail out early (could be the empty string @@ -340,7 +335,7 @@ static int linelen(int *has_tab) // find the character after the last non-blank character for (last = first + STRLEN(first); last > first && ascii_iswhite(last[-1]); last--) {} - save = (char_u)(*last); + char save = *last; *last = NUL; // Get line length. len = linetabsize((char_u *)line); @@ -428,10 +423,10 @@ static int sort_compare(const void *s1, const void *s2) // guarantee that the first pointer becomes invalid when obtaining the // second one. memcpy(sortbuf1, ml_get(l1.lnum) + l1.st_u.line.start_col_nr, - l1.st_u.line.end_col_nr - l1.st_u.line.start_col_nr + 1); + (size_t)(l1.st_u.line.end_col_nr - l1.st_u.line.start_col_nr + 1)); sortbuf1[l1.st_u.line.end_col_nr - l1.st_u.line.start_col_nr] = NUL; memcpy(sortbuf2, ml_get(l2.lnum) + l2.st_u.line.start_col_nr, - l2.st_u.line.end_col_nr - l2.st_u.line.start_col_nr + 1); + (size_t)(l2.st_u.line.end_col_nr - l2.st_u.line.start_col_nr + 1)); sortbuf2[l2.st_u.line.end_col_nr - l2.st_u.line.start_col_nr] = NUL; result = string_compare(sortbuf1, sortbuf2); @@ -451,7 +446,7 @@ void ex_sort(exarg_T *eap) int len; linenr_T lnum; long maxlen = 0; - size_t count = eap->line2 - eap->line1 + 1; + size_t count = (size_t)(eap->line2 - eap->line1) + 1; size_t i; char *p; char *s; @@ -635,8 +630,8 @@ void ex_sort(exarg_T *eap) } // Allocate a buffer that can hold the longest line. - sortbuf1 = xmalloc(maxlen + 1); - sortbuf2 = xmalloc(maxlen + 1); + sortbuf1 = xmalloc((size_t)maxlen + 1); + sortbuf2 = xmalloc((size_t)maxlen + 1); // Sort the array of line numbers. Note: can't be interrupted! qsort((void *)nrs, count, sizeof(sorti_T), sort_compare); @@ -660,7 +655,7 @@ void ex_sort(exarg_T *eap) s = (char *)ml_get(get_lnum); size_t bytelen = STRLEN(s) + 1; // include EOL in bytelen - old_count += bytelen; + old_count += (bcount_t)bytelen; if (!unique || i == 0 || string_compare(s, sortbuf1) != 0) { // Copy the line into a buffer, it may become invalid in // ml_append(). And it's needed for "unique". @@ -668,7 +663,7 @@ void ex_sort(exarg_T *eap) if (ml_append(lnum++, sortbuf1, (colnr_T)0, false) == FAIL) { break; } - new_count += bytelen; + new_count += (bcount_t)bytelen; } fast_breakcheck(); if (got_int) { @@ -686,21 +681,21 @@ void ex_sort(exarg_T *eap) } // Adjust marks for deleted (or added) lines and prepare for displaying. - deleted = (long)(count - (lnum - eap->line2)); + deleted = (long)count - (lnum - eap->line2); if (deleted > 0) { - mark_adjust(eap->line2 - deleted, eap->line2, (long)MAXLNUM, -deleted, + mark_adjust(eap->line2 - (linenr_T)deleted, eap->line2, (long)MAXLNUM, (linenr_T)(-deleted), kExtmarkNOOP); msgmore(-deleted); } else if (deleted < 0) { - mark_adjust(eap->line2, MAXLNUM, -deleted, 0L, kExtmarkNOOP); + mark_adjust(eap->line2, MAXLNUM, (linenr_T)(-deleted), 0L, kExtmarkNOOP); } if (change_occurred || deleted != 0) { extmark_splice(curbuf, eap->line1 - 1, 0, - count, 0, old_count, + (int)count, 0, old_count, lnum - eap->line2, 0, new_count, kExtmarkUndo); - changed_lines(eap->line1, 0, eap->line2 + 1, -deleted, true); + changed_lines(eap->line1, 0, eap->line2 + 1, (linenr_T)(-deleted), true); } curwin->w_cursor.lnum = eap->line1; @@ -757,7 +752,7 @@ void ex_retab(exarg_T *eap) new_vts_array = curbuf->b_p_vts_array; new_ts_str = NULL; } else { - new_ts_str = xstrnsave(new_ts_str, eap->arg - new_ts_str); + new_ts_str = xstrnsave(new_ts_str, (size_t)(eap->arg - new_ts_str)); } for (lnum = eap->line1; !got_int && lnum <= eap->line2; lnum++) { ptr = (char *)ml_get(lnum); @@ -786,7 +781,7 @@ void ex_retab(exarg_T *eap) if (!curbuf->b_p_et) { int t, s; - tabstop_fromto(start_vcol, vcol, + tabstop_fromto((colnr_T)start_vcol, (colnr_T)vcol, curbuf->b_p_ts, new_vts_array, &t, &s); num_tabs = t; num_spaces = s; @@ -810,7 +805,7 @@ void ex_retab(exarg_T *eap) emsg(_(e_resulting_text_too_long)); break; } - new_line = xmalloc(new_len); + new_line = xmalloc((size_t)new_len); if (start_col > 0) { memmove(new_line, ptr, (size_t)start_col); @@ -881,8 +876,7 @@ void ex_retab(exarg_T *eap) long *old_vts_ary = curbuf->b_p_vts_array; if (tabstop_count(old_vts_ary) > 0 || tabstop_count(new_vts_array) > 1) { - set_string_option_direct("vts", -1, (char_u *)new_ts_str, - OPT_FREE | OPT_LOCAL, 0); + set_string_option_direct("vts", -1, new_ts_str, OPT_FREE | OPT_LOCAL, 0); curbuf->b_p_vts_array = new_vts_array; xfree(old_vts_ary); } else { @@ -1139,7 +1133,7 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit, bool do_in, bool do_out char *t; char *p; char *trailarg; - int len; + size_t len; int scroll_save = msg_scroll; // @@ -1163,9 +1157,9 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit, bool do_in, bool do_out bool ins_prevcmd = forceit; trailarg = arg; do { - len = (int)STRLEN(trailarg) + 1; + len = STRLEN(trailarg) + 1; if (newcmd != NULL) { - len += (int)STRLEN(newcmd); + len += STRLEN(newcmd); } if (ins_prevcmd) { if (prevcmd == NULL) { @@ -1173,7 +1167,7 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit, bool do_in, bool do_out xfree(newcmd); return; } - len += (int)STRLEN(prevcmd); + len += STRLEN(prevcmd); } t = xmalloc(len); *t = NUL; @@ -1237,7 +1231,7 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit, bool do_in, bool do_out msg_start(); msg_putchar(':'); msg_putchar('!'); - msg_outtrans((char_u *)newcmd); + msg_outtrans(newcmd); msg_clr_eos(); ui_cursor_goto(msg_row, msg_col); @@ -1374,7 +1368,7 @@ static void do_filter(linenr_T line1, linenr_T line2, exarg_T *eap, char *cmd, b read_linecount = curbuf->b_ml.ml_line_count; // Pass on the kShellOptDoOut flag when the output is being redirected. - call_shell((char_u *)cmd_buf, kShellOptFilter | shell_flags, NULL); + call_shell((char_u *)cmd_buf, (ShellOpts)(kShellOptFilter | shell_flags), NULL); xfree(cmd_buf); did_check_timestamps = FALSE; @@ -1526,7 +1520,7 @@ void do_shell(char *cmd, int flags) // This ui_cursor_goto is required for when the '\n' resulted in a "delete line // 1" command to the terminal. ui_cursor_goto(msg_row, msg_col); - (void)call_shell((char_u *)cmd, flags, NULL); + (void)call_shell((char_u *)cmd, (ShellOpts)flags, NULL); msg_didout = true; did_check_timestamps = false; need_check_timestamps = true; @@ -1573,14 +1567,18 @@ char *make_filter_cmd(char *cmd, char *itmp, char *otmp) #else false; #endif + bool is_pwsh = STRNCMP(invocation_path_tail(p_sh, NULL), "pwsh", 4) == 0 + || STRNCMP(invocation_path_tail(p_sh, NULL), "powershell", 10) == 0; size_t len = STRLEN(cmd) + 1; // At least enough space for cmd + NULL. len += is_fish_shell ? sizeof("begin; " "; end") - 1 - : sizeof("(" ")") - 1; + : is_pwsh ? sizeof("Start-Process ") + : sizeof("(" ")") - 1; if (itmp != NULL) { - len += STRLEN(itmp) + sizeof(" { " " < " " } ") - 1; + len += is_pwsh ? STRLEN(itmp) + sizeof(" -RedirectStandardInput ") + : STRLEN(itmp) + sizeof(" { " " < " " } ") - 1; } if (otmp != NULL) { len += STRLEN(otmp) + STRLEN(p_srr) + 2; // two extra spaces (" "), @@ -1590,7 +1588,10 @@ char *make_filter_cmd(char *cmd, char *itmp, char *otmp) #if defined(UNIX) // Put delimiters around the command (for concatenated commands) when // redirecting input and/or output. - if (itmp != NULL || otmp != NULL) { + if (is_pwsh) { + xstrlcpy(buf, "Start-Process ", len); + xstrlcat(buf, cmd, len); + } else if (itmp != NULL || otmp != NULL) { char *fmt = is_fish_shell ? "begin; %s; end" : "(%s)"; vim_snprintf(buf, len, fmt, cmd); @@ -1599,13 +1600,22 @@ char *make_filter_cmd(char *cmd, char *itmp, char *otmp) } if (itmp != NULL) { - xstrlcat(buf, " < ", len - 1); - xstrlcat(buf, (const char *)itmp, len - 1); + if (is_pwsh) { + xstrlcat(buf, " -RedirectStandardInput ", len - 1); + } else { + xstrlcat(buf, " < ", len - 1); + } + xstrlcat(buf, itmp, len - 1); } #else // For shells that don't understand braces around commands, at least allow // the use of commands in a pipe. - xstrlcpy(buf, (char *)cmd, len); + if (is_pwsh) { + xstrlcpy(buf, "Start-Process ", len); + xstrlcat(buf, cmd, len); + } else { + xstrlcpy(buf, cmd, len); + } if (itmp != NULL) { // If there is a pipe, we have to put the '<' in front of it. // Don't do this when 'shellquote' is not empty, otherwise the @@ -1616,10 +1626,14 @@ char *make_filter_cmd(char *cmd, char *itmp, char *otmp) *p = NUL; } } - xstrlcat(buf, " < ", len); - xstrlcat(buf, (const char *)itmp, len); + if (is_pwsh) { + xstrlcat(buf, " -RedirectStandardInput ", len); + } else { + xstrlcat(buf, " < ", len); + } + xstrlcat(buf, itmp, len); if (*p_shq == NUL) { - const char *const p = find_pipe((const char *)cmd); + const char *const p = find_pipe(cmd); if (p != NULL) { xstrlcat(buf, " ", len - 1); // Insert a space before the '|' for DOS xstrlcat(buf, p, len - 1); @@ -1657,9 +1671,9 @@ void append_redir(char *const buf, const size_t buflen, const char *const opt, } if (p != NULL) { *end = ' '; // not really needed? Not with sh, ksh or bash - vim_snprintf(end + 1, (size_t)(buflen - (end + 1 - buf)), opt, fname); + vim_snprintf(end + 1, (size_t)((ptrdiff_t)buflen - (end + 1 - buf)), opt, fname); } else { - vim_snprintf(end, (size_t)(buflen - (end - buf)), " %s %s", opt, fname); + vim_snprintf(end, (size_t)((ptrdiff_t)buflen - (end - buf)), " %s %s", opt, fname); } } @@ -1723,7 +1737,7 @@ int rename_buffer(char *new_fname) xfname = curbuf->b_fname; curbuf->b_ffname = NULL; curbuf->b_sfname = NULL; - if (setfname(curbuf, (char_u *)new_fname, NULL, true) == FAIL) { + if (setfname(curbuf, new_fname, NULL, true) == FAIL) { curbuf->b_ffname = (char_u *)fname; curbuf->b_sfname = (char_u *)sfname; return FAIL; @@ -2203,7 +2217,7 @@ int getfile(int fnum, char *ffname_arg, char *sfname_arg, int setpm, linenr_T ln if (fnum == 0) { // make ffname full path, set sfname - fname_expand(curbuf, (char_u **)&ffname, (char_u **)&sfname); + fname_expand(curbuf, &ffname, &sfname); other = otherfile((char_u *)ffname); free_me = ffname; // has been allocated, free() later } else { @@ -2419,7 +2433,7 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum linenr_T tlnum = 0; if (command != NULL) { - tlnum = atol(command); + tlnum = (linenr_T)atol(command); if (tlnum <= 0) { tlnum = 1L; } @@ -2961,7 +2975,7 @@ void ex_append(exarg_T *eap) if (p == NULL) { p = eap->nextcmd + STRLEN(eap->nextcmd); } - theline = xstrnsave(eap->nextcmd, p - eap->nextcmd); + theline = xstrnsave(eap->nextcmd, (size_t)(p - eap->nextcmd)); if (*p != NUL) { p++; } @@ -3135,38 +3149,38 @@ void ex_z(exarg_T *eap) switch (*kind) { case '-': - start = lnum - bigness * (linenr_T)(x - kind) + 1; - end = start + bigness - 1; + start = lnum - (linenr_T)bigness * (linenr_T)(x - kind) + 1; + end = start + (linenr_T)bigness - 1; curs = end; break; case '=': - start = lnum - (bigness + 1) / 2 + 1; - end = lnum + (bigness + 1) / 2 - 1; + start = lnum - ((linenr_T)bigness + 1) / 2 + 1; + end = lnum + ((linenr_T)bigness + 1) / 2 - 1; curs = lnum; minus = 1; break; case '^': - start = lnum - bigness * 2; - end = lnum - bigness; - curs = lnum - bigness; + start = lnum - (linenr_T)bigness * 2; + end = lnum - (linenr_T)bigness; + curs = lnum - (linenr_T)bigness; break; case '.': - start = lnum - (bigness + 1) / 2 + 1; - end = lnum + (bigness + 1) / 2 - 1; + start = lnum - ((linenr_T)bigness + 1) / 2 + 1; + end = lnum + ((linenr_T)bigness + 1) / 2 - 1; curs = end; break; default: // '+' start = lnum; if (*kind == '+') { - start += bigness * (linenr_T)(x - kind - 1) + 1; + start += (linenr_T)bigness * (linenr_T)(x - kind - 1) + 1; } else if (eap->addr_count == 0) { ++start; } - end = start + bigness - 1; + end = start + (linenr_T)bigness - 1; curs = end; break; } @@ -3300,7 +3314,7 @@ static bool sub_joining_lines(exarg_T *eap, char *pat, char *sub, char *cmd, boo // plus one extra line if not at the end of file. + (eap->line2 < curbuf->b_ml.ml_line_count ? 1 : 0); if (joined_lines_count > 1) { - do_join(joined_lines_count, FALSE, TRUE, FALSE, true); + do_join((size_t)joined_lines_count, false, true, false, true); sub_nsubs = joined_lines_count - 1; sub_nlines = 1; do_sub_msg(false); @@ -3339,7 +3353,7 @@ static char *sub_grow_buf(char **new_start, int needed_len) // substitution into (and some extra space to avoid // too many calls to xmalloc()/free()). new_start_len = needed_len + 50; - *new_start = xmalloc(new_start_len); + *new_start = xmalloc((size_t)new_start_len); **new_start = NUL; new_end = *new_start; } else { @@ -3347,10 +3361,10 @@ static char *sub_grow_buf(char **new_start, int needed_len) // substitution into. If not, make it larger (with a bit // extra to avoid too many calls to xmalloc()/free()). size_t len = STRLEN(*new_start); - needed_len += len; + needed_len += (int)len; if (needed_len > new_start_len) { new_start_len = needed_len + 50; - *new_start = xrealloc(*new_start, new_start_len); + *new_start = xrealloc(*new_start, (size_t)new_start_len); } new_end = *new_start + len; } @@ -3467,7 +3481,7 @@ static int do_sub(exarg_T *eap, proftime_T timeout, long cmdpreview_ns, handle_T PreviewLines preview_lines = { KV_INITIAL_VALUE, 0 }; static int pre_hl_id = 0; pos_T old_cursor = curwin->w_cursor; - int start_nsubs; + long start_nsubs; bool did_save = false; @@ -3571,7 +3585,7 @@ static int do_sub(exarg_T *eap, proftime_T timeout, long cmdpreview_ns, handle_T return 0; } eap->line1 = eap->line2; - eap->line2 += i - 1; + eap->line2 += (linenr_T)i - 1; if (eap->line2 > curbuf->b_ml.ml_line_count) { eap->line2 = curbuf->b_ml.ml_line_count; } @@ -3853,10 +3867,10 @@ static int do_sub(exarg_T *eap, proftime_T timeout, long cmdpreview_ns, handle_T ec += numw; } - prompt = xmallocz(ec + 1); - memset(prompt, ' ', sc); - memset(prompt + sc, '^', ec - sc + 1); - resp = getcmdline_prompt(-1, prompt, 0, EXPAND_NOTHING, NULL, CALLBACK_NONE); + prompt = xmallocz((size_t)ec + 1); + memset(prompt, ' ', (size_t)sc); + memset(prompt + sc, '^', (size_t)(ec - sc) + 1); + resp = getcmdline_prompt((char)(-1), prompt, 0, EXPAND_NOTHING, NULL, CALLBACK_NONE); msg_putchar('\n'); xfree(prompt); if (resp != NULL) { @@ -3929,8 +3943,8 @@ static int do_sub(exarg_T *eap, proftime_T timeout, long cmdpreview_ns, handle_T msg_ext_set_kind("confirm_sub"); smsg_attr(HL_ATTR(HLF_R), // Same highlight as wait_return(). _("replace with %s (y/n/a/q/l/^E/^Y)?"), sub); - msg_no_more = FALSE; - msg_scroll = i; + msg_no_more = false; + msg_scroll = (int)i; showruler(true); ui_cursor_goto(msg_row, msg_col); RedrawingDisabled = temp; @@ -4011,7 +4025,7 @@ static int do_sub(exarg_T *eap, proftime_T timeout, long cmdpreview_ns, handle_T // go beyond the last line of the buffer. if (nmatch > curbuf->b_ml.ml_line_count - sub_firstlnum + 1) { nmatch = curbuf->b_ml.ml_line_count - sub_firstlnum + 1; - current_match.end.lnum = sub_firstlnum + nmatch; + current_match.end.lnum = sub_firstlnum + (linenr_T)nmatch; skip_match = true; } @@ -4020,7 +4034,7 @@ static int do_sub(exarg_T *eap, proftime_T timeout, long cmdpreview_ns, handle_T /* For a multi-line match, make a copy of the last matched */ \ /* line and continue in that one. */ \ if (nmatch > 1) { \ - sub_firstlnum += nmatch - 1; \ + sub_firstlnum += (linenr_T)nmatch - 1; \ xfree(sub_firstline); \ sub_firstline = (char *)vim_strsave(ml_get(sub_firstlnum)); \ /* When going beyond the last line, stop substituting. */ \ @@ -4045,12 +4059,12 @@ static int do_sub(exarg_T *eap, proftime_T timeout, long cmdpreview_ns, handle_T if (cmdpreview && !has_second_delim) { current_match.start.col = regmatch.startpos[0].col; if (current_match.end.lnum == 0) { - current_match.end.lnum = sub_firstlnum + nmatch - 1; + current_match.end.lnum = sub_firstlnum + (linenr_T)nmatch - 1; } current_match.end.col = regmatch.endpos[0].col; ADJUST_SUB_FIRSTLNUM(); - lnum += nmatch - 1; + lnum += (linenr_T)nmatch - 1; goto skip; } @@ -4098,13 +4112,13 @@ static int do_sub(exarg_T *eap, proftime_T timeout, long cmdpreview_ns, handle_T if (nmatch == 1) { p1 = sub_firstline; } else { - p1 = (char *)ml_get(sub_firstlnum + nmatch - 1); + p1 = (char *)ml_get(sub_firstlnum + (linenr_T)nmatch - 1); nmatch_tl += nmatch - 1; } - size_t copy_len = regmatch.startpos[0].col - copycol; + size_t copy_len = (size_t)(regmatch.startpos[0].col - copycol); new_end = sub_grow_buf(&new_start, - (STRLEN(p1) - regmatch.endpos[0].col) - + copy_len + sublen + 1); + (colnr_T)STRLEN(p1) - regmatch.endpos[0].col + + (colnr_T)copy_len + sublen + 1); // copy the text up to the part that matched memmove(new_end, sub_firstline + copycol, copy_len); @@ -4112,7 +4126,7 @@ static int do_sub(exarg_T *eap, proftime_T timeout, long cmdpreview_ns, handle_T // Finally, at this point we can know where the match actually will // start in the new text - int start_col = new_end - new_start; + int start_col = (int)(new_end - new_start); current_match.start.col = start_col; textlock++; @@ -4137,7 +4151,7 @@ static int do_sub(exarg_T *eap, proftime_T timeout, long cmdpreview_ns, handle_T bcount_t replaced_bytes = 0; lpos_T start = regmatch.startpos[0], end = regmatch.endpos[0]; for (i = 0; i < nmatch - 1; i++) { - replaced_bytes += STRLEN(ml_get(lnum_start + i)) + 1; + replaced_bytes += (bcount_t)STRLEN(ml_get((linenr_T)(lnum_start + i))) + 1; } replaced_bytes += end.col - start.col; @@ -4180,7 +4194,7 @@ static int do_sub(exarg_T *eap, proftime_T timeout, long cmdpreview_ns, handle_T p1 += utfc_ptr2len(p1) - 1; } } - size_t new_endcol = STRLEN(new_start); + colnr_T new_endcol = (colnr_T)STRLEN(new_start); current_match.end.col = new_endcol; current_match.end.lnum = lnum; @@ -4192,9 +4206,9 @@ static int do_sub(exarg_T *eap, proftime_T timeout, long cmdpreview_ns, handle_T u_save_cursor(); did_save = true; } - extmark_splice(curbuf, lnum_start - 1, start_col, + extmark_splice(curbuf, (int)lnum_start - 1, start_col, end.lnum - start.lnum, matchcols, replaced_bytes, - lnum - lnum_start, subcols, sublen - 1, kExtmarkUndo); + lnum - (linenr_T)lnum_start, subcols, sublen - 1, kExtmarkUndo); } // 4. If subflags.do_all is set, find next match. @@ -4263,13 +4277,13 @@ skip: for (i = 0; i < nmatch_tl; i++) { ml_delete(lnum, false); } - mark_adjust(lnum, lnum + nmatch_tl - 1, - (long)MAXLNUM, -nmatch_tl, kExtmarkNOOP); + mark_adjust(lnum, lnum + (linenr_T)nmatch_tl - 1, + (long)MAXLNUM, (linenr_T)(-nmatch_tl), kExtmarkNOOP); if (subflags.do_ask) { - deleted_lines(lnum, nmatch_tl); + deleted_lines(lnum, (linenr_T)nmatch_tl); } lnum--; - line2 -= nmatch_tl; // nr of lines decreases + line2 -= (linenr_T)nmatch_tl; // nr of lines decreases nmatch_tl = 0; } @@ -4365,7 +4379,7 @@ skip: // the line number before the change (same as adding the number of // deleted lines). i = curbuf->b_ml.ml_line_count - old_line_count; - changed_lines(first_line, 0, last_line - i, i, false); + changed_lines(first_line, 0, last_line - (linenr_T)i, (linenr_T)i, false); int64_t num_added = last_line - first_line; int64_t num_removed = num_added - i; @@ -4438,8 +4452,7 @@ skip: // Show 'inccommand' preview if there are matched lines. if (cmdpreview && !aborting()) { if (got_quit || profile_passed_limit(timeout)) { // Too slow, disable. - set_string_option_direct("icm", -1, (char_u *)"", OPT_FREE, - SID_NONE); + set_string_option_direct("icm", -1, "", OPT_FREE, SID_NONE); } else if (*p_icm != NUL && pat != NULL) { if (pre_hl_id == 0) { pre_hl_id = syn_check_group(S_LEN("Substitute")); @@ -4598,8 +4611,7 @@ void ex_global(exarg_T *eap) if (global_busy) { lnum = curwin->w_cursor.lnum; - match = vim_regexec_multi(®match, curwin, curbuf, lnum, - (colnr_T)0, NULL, NULL); + match = (int)vim_regexec_multi(®match, curwin, curbuf, lnum, 0, NULL, NULL); if ((type == 'g' && match) || (type == 'v' && !match)) { global_exe_one(cmd, lnum); } @@ -4607,8 +4619,7 @@ void ex_global(exarg_T *eap) // pass 1: set marks for each (not) matching line for (lnum = eap->line1; lnum <= eap->line2 && !got_int; lnum++) { // a match on this line? - match = vim_regexec_multi(®match, curwin, curbuf, lnum, - (colnr_T)0, NULL, NULL); + match = (int)vim_regexec_multi(®match, curwin, curbuf, lnum, 0, NULL, NULL); if (regmatch.regprog == NULL) { break; // re-compiling regprog failed } @@ -4729,7 +4740,7 @@ bool prepare_tagpreview(bool undo_sync) and 'cursorbind' */ curwin->w_p_diff = false; // no 'diff' set_string_option_direct("fdc", -1, // no 'foldcolumn' - (char_u *)"0", OPT_FREE, SID_NONE); + "0", OPT_FREE, SID_NONE); return true; } } @@ -4984,7 +4995,7 @@ int help_heuristic(char *matched_string, int offset, int wrong_case) if (matched_string[0] == '+' && matched_string[1] != NUL) { offset += 100; } - return (int)(100 * num_letters + STRLEN(matched_string) + offset); + return 100 * num_letters + (int)STRLEN(matched_string) + offset; } /// Compare functions for qsort() below, that checks the help heuristics number @@ -5165,7 +5176,7 @@ int find_help_tags(const char *arg, int *num_matches, char ***matches, bool keep STRCPY(d, "CTRL-"); d += 5; if (*s < ' ') { - *d++ = *s + '@'; + *d++ = (char)(*s + '@'); if (d[-1] == '\\') { *d++ = '\\'; // double a backslash } @@ -5259,8 +5270,7 @@ int find_help_tags(const char *arg, int *num_matches, char ***matches, bool keep static void prepare_help_buffer(void) { curbuf->b_help = true; - set_string_option_direct("buftype", -1, (char_u *)"help", - OPT_FREE|OPT_LOCAL, 0); + set_string_option_direct("buftype", -1, "help", OPT_FREE|OPT_LOCAL, 0); // Always set these options after jumping to a help tag, because the // user may have an autocommand that gets in the way. @@ -5269,14 +5279,13 @@ static void prepare_help_buffer(void) // Only set it when needed, buf_init_chartab() is some work. char *p = "!-~,^*,^|,^\",192-255"; if (STRCMP(curbuf->b_p_isk, p) != 0) { - set_string_option_direct("isk", -1, (char_u *)p, OPT_FREE|OPT_LOCAL, 0); + set_string_option_direct("isk", -1, p, OPT_FREE|OPT_LOCAL, 0); check_buf_options(curbuf); (void)buf_init_chartab(curbuf, FALSE); } // Don't use the global foldmethod. - set_string_option_direct("fdm", -1, (char_u *)"manual", - OPT_FREE|OPT_LOCAL, 0); + set_string_option_direct("fdm", -1, "manual", OPT_FREE|OPT_LOCAL, 0); curbuf->b_p_ts = 8; // 'tabstop' is 8. curwin->w_p_list = FALSE; // No list mode. @@ -5362,7 +5371,7 @@ void fix_help_buffer(void) copy_option_part((char_u **)&p, NameBuff, MAXPATHL, ","); char *const rt = vim_getenv("VIMRUNTIME"); if (rt != NULL - && path_full_compare((char_u *)rt, NameBuff, false, true) != kEqualFiles) { + && path_full_compare(rt, (char *)NameBuff, false, true) != kEqualFiles) { int fcount; char **fnames; char *s; @@ -5569,8 +5578,7 @@ static void helptags_one(char *dir, const char *ext, const char *tagfname, bool // add the "help-tags" tag. ga_init(&ga, (int)sizeof(char_u *), 100); if (add_help_tags - || path_full_compare((char_u *)"$VIMRUNTIME/doc", - (char_u *)dir, false, true) == kEqualFiles) { + || path_full_compare("$VIMRUNTIME/doc", dir, false, true) == kEqualFiles) { size_t s_len = 18 + STRLEN(tagfname); s = xmalloc(s_len); snprintf(s, s_len, "help-tags\t%s\t1\n", tagfname); @@ -5635,7 +5643,7 @@ static void helptags_one(char *dir, const char *ext, const char *tagfname, bool || s[1] == '\0')) { *p2 = '\0'; p1++; - size_t s_len= (p2 - p1) + STRLEN(fname) + 2; + size_t s_len= (size_t)(p2 - p1) + STRLEN(fname) + 2; s = xmalloc(s_len); GA_APPEND(char *, &ga, s); snprintf(s, s_len, "%s\t%s", p1, fname); @@ -5756,8 +5764,8 @@ static void do_helptags(char *dirname, bool add_help_tags, bool ignore_writeerr) && ASCII_ISALPHA(files[i][len - 2]) && TOLOWER_ASC(files[i][len - 1]) == 'x') { // ".abx" -> language "ab" - lang[0] = TOLOWER_ASC(files[i][len - 3]); - lang[1] = TOLOWER_ASC(files[i][len - 2]); + lang[0] = (char)TOLOWER_ASC(files[i][len - 3]); + lang[1] = (char)TOLOWER_ASC(files[i][len - 2]); } else { continue; } @@ -5771,8 +5779,8 @@ static void do_helptags(char *dirname, bool add_help_tags, bool ignore_writeerr) if (j == ga.ga_len) { // New language, add it. ga_grow(&ga, 2); - ((char_u *)ga.ga_data)[ga.ga_len++] = lang[0]; - ((char_u *)ga.ga_data)[ga.ga_len++] = lang[1]; + ((char *)ga.ga_data)[ga.ga_len++] = lang[0]; + ((char *)ga.ga_data)[ga.ga_len++] = lang[1]; } } @@ -5781,8 +5789,8 @@ static void do_helptags(char *dirname, bool add_help_tags, bool ignore_writeerr) */ for (j = 0; j < ga.ga_len; j += 2) { STRCPY(fname, "tags-xx"); - fname[5] = ((char_u *)ga.ga_data)[j]; - fname[6] = ((char_u *)ga.ga_data)[j + 1]; + fname[5] = ((char *)ga.ga_data)[j]; + fname[6] = ((char *)ga.ga_data)[j + 1]; if (fname[5] == 'e' && fname[6] == 'n') { // English is an exception: use ".txt" and "tags". fname[4] = NUL; @@ -5861,8 +5869,7 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i buf_T *cmdpreview_buf = NULL; // disable file info message - set_string_option_direct("shm", -1, (char_u *)"F", OPT_FREE, - SID_NONE); + set_string_option_direct("shm", -1, "F", OPT_FREE, SID_NONE); // Update the topline to ensure that main window is on the correct line update_topline(curwin); @@ -5889,7 +5896,7 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i if (lines.subresults.size > 0) { highest_num_line = kv_last(lines.subresults).end.lnum; - col_width = log10(highest_num_line) + 1 + 3; + col_width = (int)log10(highest_num_line) + 1 + 3; } } @@ -5934,7 +5941,7 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i line = ""; } else { line = (char *)ml_get_buf(orig_buf, next_linenr, false); - line_size = strlen(line) + col_width + 1; + line_size = strlen(line) + (size_t)col_width + 1; // Reallocate if line not long enough if (line_size > old_line_size) { @@ -5957,14 +5964,14 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i } linenr_origbuf = match.end.lnum; - bufhl_add_hl_pos_offset(cmdpreview_buf, cmdpreview_ns, hl_id, p_start, p_end, col_width); + bufhl_add_hl_pos_offset(cmdpreview_buf, (int)cmdpreview_ns, hl_id, p_start, p_end, col_width); } - bufhl_add_hl_pos_offset(orig_buf, cmdpreview_ns, hl_id, match.start, match.end, 0); + bufhl_add_hl_pos_offset(orig_buf, (int)cmdpreview_ns, hl_id, match.start, match.end, 0); } xfree(str); - set_string_option_direct("shm", -1, (char_u *)save_shm_p, OPT_FREE, SID_NONE); + set_string_option_direct("shm", -1, save_shm_p, OPT_FREE, SID_NONE); xfree(save_shm_p); return preview ? 2 : 1; @@ -5974,7 +5981,6 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i void ex_substitute(exarg_T *eap) { (void)do_sub(eap, profile_zero(), 0, 0); - return; } /// :substitute command preview callback. @@ -6065,7 +6071,7 @@ void ex_oldfiles(exarg_T *eap) if (!message_filtered((char_u *)fname)) { msg_outnum(nr); msg_puts(": "); - msg_outtrans((char_u *)tv_get_string(TV_LIST_ITEM_TV(li))); + msg_outtrans((char *)tv_get_string(TV_LIST_ITEM_TV(li))); msg_clr_eos(); msg_putchar('\n'); ui_flush(); // output one line at a time @@ -6082,7 +6088,7 @@ void ex_oldfiles(exarg_T *eap) nr = prompt_for_number(false); msg_starthere(); if (nr > 0 && nr <= tv_list_len(l)) { - const char *const p = tv_list_find_str(l, nr - 1); + const char *const p = tv_list_find_str(l, (int)nr - 1); if (p == NULL) { return; } diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 9b260f9091..621004103e 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -732,7 +732,7 @@ bool check_changed_any(bool hidden, bool unload) if ((buf->terminal && channel_job_running((uint64_t)buf->b_p_channel)) ? semsg(_("E947: Job still running in buffer \"%s\""), buf->b_fname) : semsg(_("E162: No write since last change for buffer \"%s\""), - buf_spname(buf) != NULL ? buf_spname(buf) : (char_u *)buf->b_fname)) { + buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname)) { save = no_wait_return; no_wait_return = false; wait_return(false); @@ -929,8 +929,7 @@ static int do_arglist(char *str, int what, int after, bool will_edit) didone = false; for (match = 0; match < ARGCOUNT; match++) { - if (vim_regexec(®match, alist_name(&ARGLIST[match]), - (colnr_T)0)) { + if (vim_regexec(®match, (char_u *)alist_name(&ARGLIST[match]), (colnr_T)0)) { didone = true; xfree(ARGLIST[match].ae_fname); memmove(ARGLIST + match, ARGLIST + match + 1, @@ -993,7 +992,8 @@ static bool editing_arg_idx(win_T *win) != WARGLIST(win)[win->w_arg_idx].ae_fnum && (win->w_buffer->b_ffname == NULL || !(path_full_compare(alist_name(&WARGLIST(win)[win->w_arg_idx]), - win->w_buffer->b_ffname, true, true) & kEqualFiles)))); + (char *)win->w_buffer->b_ffname, true, + true) & kEqualFiles)))); } /// Check if window "win" is editing the w_arg_idx file in its argument list. @@ -1011,7 +1011,7 @@ void check_arg_idx(win_T *win) && (win->w_buffer->b_fnum == GARGLIST[GARGCOUNT - 1].ae_fnum || (win->w_buffer->b_ffname != NULL && (path_full_compare(alist_name(&GARGLIST[GARGCOUNT - 1]), - win->w_buffer->b_ffname, true, true) + (char *)win->w_buffer->b_ffname, true, true) & kEqualFiles)))) { arg_had_last = true; } @@ -1050,7 +1050,7 @@ void ex_args(exarg_T *eap) // required and no wait_return(). gotocmdline(true); for (int i = 0; i < ARGCOUNT; i++) { - items[i] = (char *)alist_name(&ARGLIST[i]); + items[i] = alist_name(&ARGLIST[i]); } list_in_columns((char_u **)items, ARGCOUNT, curwin->w_arg_idx); xfree(items); @@ -1137,7 +1137,7 @@ void do_argfile(exarg_T *eap, int argn) // the same buffer other = true; if (buf_hide(curbuf)) { - p = fix_fname((char *)alist_name(&ARGLIST[argn])); + p = fix_fname(alist_name(&ARGLIST[argn])); other = otherfile((char_u *)p); xfree(p); } @@ -1159,7 +1159,7 @@ void do_argfile(exarg_T *eap, int argn) // Edit the file; always use the last known line number. // When it fails (e.g. Abort for already edited file) restore the // argument index. - if (do_ecmd(0, (char *)alist_name(&ARGLIST[curwin->w_arg_idx]), NULL, + if (do_ecmd(0, alist_name(&ARGLIST[curwin->w_arg_idx]), NULL, eap, ECMD_LAST, (buf_hide(curwin->w_buffer) ? ECMD_HIDE : 0) + (eap->forceit ? ECMD_FORCEIT : 0), curwin) == FAIL) { @@ -1568,7 +1568,7 @@ char *get_arglist_name(expand_T *xp FUNC_ATTR_UNUSED, int idx) if (idx >= ARGCOUNT) { return NULL; } - return (char *)alist_name(&ARGLIST[idx]); + return alist_name(&ARGLIST[idx]); } /// ":compiler[!] {name}" @@ -2206,11 +2206,11 @@ void ex_scriptnames(exarg_T *eap) for (int i = 1; i <= script_items.ga_len && !got_int; i++) { if (SCRIPT_ITEM(i).sn_name != NULL) { - home_replace(NULL, SCRIPT_ITEM(i).sn_name, NameBuff, MAXPATHL, true); + home_replace(NULL, (char *)SCRIPT_ITEM(i).sn_name, (char *)NameBuff, MAXPATHL, true); vim_snprintf((char *)IObuff, IOSIZE, "%3d: %s", i, NameBuff); if (!message_filtered(IObuff)) { msg_putchar('\n'); - msg_outtrans(IObuff); + msg_outtrans((char *)IObuff); line_breakcheck(); } } diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h index 8280f99547..9350a9f60b 100644 --- a/src/nvim/ex_cmds_defs.h +++ b/src/nvim/ex_cmds_defs.h @@ -274,7 +274,7 @@ typedef struct { int cmod_verbose; ///< 0 if not set, > 0 to set 'verbose' to cmod_verbose - 1 // values for undo_cmdmod() - char_u *cmod_save_ei; ///< saved value of 'eventignore' + char *cmod_save_ei; ///< saved value of 'eventignore' int cmod_did_sandbox; ///< set when "sandbox" was incremented long cmod_verbose_save; ///< if 'verbose' was set: value of p_verbose plus one int cmod_save_msg_silent; ///< if non-zero: saved value of msg_silent + 1 diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 671e83def6..48e6dad720 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -82,8 +82,13 @@ #include "nvim/vim.h" #include "nvim/window.h" -static char *e_no_such_user_defined_command_str = N_("E184: No such user-defined command: %s"); -static char *e_no_such_user_defined_command_in_current_buffer_str +static char e_no_such_user_defined_command_str[] + = N_("E184: No such user-defined command: %s"); +static char e_ambiguous_use_of_user_defined_command[] + = N_("E464: Ambiguous use of user-defined command"); +static char e_not_an_editor_command[] + = N_("E492: Not an editor command"); +static char e_no_such_user_defined_command_in_current_buffer_str[] = N_("E1237: No such user-defined command in current buffer: %s"); static int quitmore = 0; @@ -1207,7 +1212,7 @@ static char *skip_colon_white(const char *p, bool skipleadingwhite) /// Set the addr type for command /// /// @param p pointer to character after command name in cmdline -void set_cmd_addr_type(exarg_T *eap, char_u *p) +void set_cmd_addr_type(exarg_T *eap, char *p) { // ea.addr_type for user commands is set by find_ucmd if (IS_USER_CMDIDX(eap->cmdidx)) { @@ -1220,7 +1225,7 @@ void set_cmd_addr_type(exarg_T *eap, char_u *p) } // :wincmd range depends on the argument if (eap->cmdidx == CMD_wincmd && p != NULL) { - get_wincmd_addr_type(skipwhite((char *)p), eap); + get_wincmd_addr_type(skipwhite(p), eap); } // :.cc in quickfix window uses line number if ((eap->cmdidx == CMD_cc || eap->cmdidx == CMD_ll) && bt_quickfix(curbuf)) { @@ -1400,6 +1405,8 @@ bool is_cmd_ni(cmdidx_T cmdidx) } /// Parse command line and return information about the first command. +/// If parsing is done successfully, need to free cmod_filter_regmatch.regprog after calling, +/// usually done using undo_cmdmod() or execute_cmd(). /// /// @param cmdline Command line string /// @param[out] eap Ex command arguments @@ -1427,6 +1434,7 @@ bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **er // Parse command modifiers if (parse_command_modifiers(eap, errormsg, &cmdinfo->cmdmod, false) == FAIL) { + vim_regfree(cmdinfo->cmdmod.cmod_filter_regmatch.regprog); return false; } after_modifier = eap->cmd; @@ -1439,9 +1447,13 @@ bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **er eap->cmd = skipwhite(eap->cmd + 1); } p = find_ex_command(eap, NULL); + if (p == NULL) { + *errormsg = _(e_ambiguous_use_of_user_defined_command); + return false; + } // Set command address type and parse command range - set_cmd_addr_type(eap, (char_u *)p); + set_cmd_addr_type(eap, p); eap->cmd = cmd; if (parse_cmd_address(eap, errormsg, false) == FAIL) { return false; @@ -1455,7 +1467,7 @@ bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **er } // Fail if command is invalid if (eap->cmdidx == CMD_SIZE) { - STRCPY(IObuff, _("E492: Not an editor command")); + STRCPY(IObuff, _(e_not_an_editor_command)); // If the modifier was parsed OK the error must be in the following command char *cmdname = after_modifier ? after_modifier : cmdline; append_command(cmdname); @@ -1812,7 +1824,7 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter // The ea.cmd pointer is updated to point to the first character following the // range spec. If an initial address is found, but no second, the upper bound // is equal to the lower. - set_cmd_addr_type(&ea, (char_u *)p); + set_cmd_addr_type(&ea, p); ea.cmd = cmd; if (parse_cmd_address(&ea, &errormsg, false) == FAIL) { @@ -1886,14 +1898,14 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter if (p == NULL) { if (!ea.skip) { - errormsg = _("E464: Ambiguous use of user-defined command"); + errormsg = _(e_ambiguous_use_of_user_defined_command); } goto doend; } // Check for wrong commands. if (ea.cmdidx == CMD_SIZE) { if (!ea.skip) { - STRCPY(IObuff, _("E492: Not an editor command")); + STRCPY(IObuff, _(e_not_an_editor_command)); // If the modifier was parsed OK the error must be in the following // command char *cmdname = after_modifier ? after_modifier : *cmdlinep; @@ -2655,8 +2667,8 @@ static void apply_cmdmod(cmdmod_T *cmod) if ((cmod->cmod_flags & CMOD_NOAUTOCMD) && cmod->cmod_save_ei == NULL) { // Set 'eventignore' to "all". // First save the existing option value for restoring it later. - cmod->cmod_save_ei = vim_strsave(p_ei); - set_string_option_direct("ei", -1, (char_u *)"all", OPT_FREE, SID_NONE); + cmod->cmod_save_ei = (char *)vim_strsave(p_ei); + set_string_option_direct("ei", -1, "all", OPT_FREE, SID_NONE); } } @@ -2676,7 +2688,7 @@ static void undo_cmdmod(cmdmod_T *cmod) if (cmod->cmod_save_ei != NULL) { // Restore 'eventignore' to the value before ":noautocmd". - set_string_option_direct("ei", -1, (char_u *)cmod->cmod_save_ei, OPT_FREE, SID_NONE); + set_string_option_direct("ei", -1, cmod->cmod_save_ei, OPT_FREE, SID_NONE); free_string_option((char_u *)cmod->cmod_save_ei); cmod->cmod_save_ei = NULL; } @@ -5792,7 +5804,7 @@ static void uc_list(char *name, size_t name_len) } while (len < 25 - over); IObuff[len] = '\0'; - msg_outtrans(IObuff); + msg_outtrans((char *)IObuff); msg_outtrans_special(cmd->uc_rep, false, name_len == 0 ? Columns - 47 : 0); @@ -7562,7 +7574,7 @@ static void ex_recover(exarg_T *eap) | CCGD_EXCMD) && (*eap->arg == NUL - || setfname(curbuf, (char_u *)eap->arg, NULL, true) == OK)) { + || setfname(curbuf, eap->arg, NULL, true) == OK)) { ml_recover(true); } recoverymode = false; @@ -7750,9 +7762,9 @@ static void ex_tabs(exarg_T *eap) if (buf_spname(wp->w_buffer) != NULL) { STRLCPY(IObuff, buf_spname(wp->w_buffer), IOSIZE); } else { - home_replace(wp->w_buffer, (char_u *)wp->w_buffer->b_fname, IObuff, IOSIZE, true); + home_replace(wp->w_buffer, wp->w_buffer->b_fname, (char *)IObuff, IOSIZE, true); } - msg_outtrans(IObuff); + msg_outtrans((char *)IObuff); ui_flush(); // output one line at a time os_breakcheck(); } @@ -9634,7 +9646,7 @@ static char *arg_all(void) for (;;) { len = 0; for (idx = 0; idx < ARGCOUNT; idx++) { - p = (char *)alist_name(&ARGLIST[idx]); + p = alist_name(&ARGLIST[idx]); if (p == NULL) { continue; } @@ -10031,44 +10043,6 @@ static void ex_terminal(exarg_T *eap) do_cmdline_cmd(ex_cmd); } -/// Checks if `cmd` is "previewable" (i.e. supported by 'inccommand'). -/// -/// @param[in] cmd Commandline to check. May start with a range or modifier. -/// -/// @return true if `cmd` is previewable -bool cmd_can_preview(char *cmd) -{ - if (cmd == NULL) { - return false; - } - - // Ignore additional colons at the start... - cmd = skip_colon_white(cmd, true); - - // Ignore any leading modifiers (:keeppatterns, :verbose, etc.) - for (int len = modifier_len(cmd); len != 0; len = modifier_len(cmd)) { - cmd += len; - cmd = skip_colon_white(cmd, true); - } - - exarg_T ea; - memset(&ea, 0, sizeof(ea)); - // parse the command line - ea.cmd = skip_range(cmd, NULL); - if (*ea.cmd == '*') { - ea.cmd = skipwhite(ea.cmd + 1); - } - - if (find_ex_command(&ea, NULL) == NULL || ea.cmdidx == CMD_SIZE) { - return false; - } else if (!IS_USER_CMDIDX(ea.cmdidx)) { - // find_ex_command sets the flags for user commands automatically - ea.argt = cmdnames[(int)ea.cmdidx].cmd_argt; - } - - return (ea.argt & EX_PREVIEW); -} - /// Gets a map of maps describing user-commands defined for buffer `buf` or /// defined globally if `buf` is NULL. /// diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index e442c907b3..93758b9ec9 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -952,8 +952,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent, bool init need_wait_return = false; } - set_string_option_direct("icm", -1, s->save_p_icm, OPT_FREE, - SID_NONE); + set_string_option_direct("icm", -1, (char *)s->save_p_icm, OPT_FREE, SID_NONE); State = s->save_State; if (cmdpreview != save_cmdpreview) { cmdpreview = save_cmdpreview; // restore preview state @@ -2372,7 +2371,7 @@ static void cmdpreview_close_win(void) } } -/// Show 'inccommand' preview. It works like this: +/// Show 'inccommand' preview if command is previewable. It works like this: /// 1. Store current undo information so we can revert to current state later. /// 2. Execute the preview callback with the parsed command, preview buffer number and preview /// namespace number as arguments. The preview callback sets the highlight and does the @@ -2385,12 +2384,15 @@ static void cmdpreview_close_win(void) /// 5. If the return value of the preview callback is not 0, update the screen while the effects /// of the preview are still in place. /// 6. Revert all changes made by the preview callback. -static void cmdpreview_show(CommandLineState *s) +/// +/// @return whether preview is shown or not. +static bool cmdpreview_may_show(CommandLineState *s) { // Parse the command line and return if it fails. exarg_T ea; CmdParseInfo cmdinfo; // Copy the command line so we can modify it. + int cmdpreview_type = 0; char *cmdline = xstrdup((char *)ccline.cmdbuff); char *errormsg = NULL; emsg_off++; // Block errors when parsing the command line, and don't update v:errmsg @@ -2400,6 +2402,12 @@ static void cmdpreview_show(CommandLineState *s) } emsg_off--; + // Check if command is previewable, if not, don't attempt to show preview + if (!(ea.argt & EX_PREVIEW)) { + vim_regfree(cmdinfo.cmdmod.cmod_filter_regmatch.regprog); + goto end; + } + // Swap invalid command range if needed if ((ea.argt & EX_RANGE) && ea.line1 > ea.line2) { linenr_T lnum = ea.line1; @@ -2454,7 +2462,7 @@ static void cmdpreview_show(CommandLineState *s) // the preview. Error err = ERROR_INIT; try_start(); - int cmdpreview_type = execute_cmd(&ea, &cmdinfo, true); + cmdpreview_type = execute_cmd(&ea, &cmdinfo, true); if (try_end(&err)) { api_clear_error(&err); cmdpreview_type = 0; @@ -2518,14 +2526,9 @@ static void cmdpreview_show(CommandLineState *s) update_topline(curwin); redrawcmdline(); - - // If preview callback returned 0, update screen to clear remnants of an earlier preview. - if (cmdpreview_type == 0) { - cmdpreview = false; - update_screen(SOME_VALID); - } end: xfree(cmdline); + return cmdpreview_type != 0; } static int command_line_changed(CommandLineState *s) @@ -2564,9 +2567,9 @@ static int command_line_changed(CommandLineState *s) && *p_icm != NUL // 'inccommand' is set && curbuf->b_p_ma // buffer is modifiable && cmdline_star == 0 // not typing a password - && cmd_can_preview((char *)ccline.cmdbuff) - && !vpeekc_any()) { - cmdpreview_show(s); + && !vpeekc_any() + && cmdpreview_may_show(s)) { + // 'inccommand' preview has been shown. } else if (cmdpreview) { cmdpreview = false; update_screen(SOME_VALID); // Clear 'inccommand' preview. @@ -2747,7 +2750,7 @@ static int cmdline_charsize(int idx) if (cmdline_star > 0) { // showing '*', always 1 position return 1; } - return ptr2cells(ccline.cmdbuff + idx); + return ptr2cells((char *)ccline.cmdbuff + idx); } /// Compute the offset of the cursor on the command line for the prompt and @@ -3550,7 +3553,7 @@ void put_on_cmdline(char_u *str, int len, int redraw) } if (i != 0) { // Also backup the cursor position. - i = ptr2cells(ccline.cmdbuff + ccline.cmdpos); + i = ptr2cells((char *)ccline.cmdbuff + ccline.cmdpos); ccline.cmdspos -= i; msg_col -= i; if (msg_col < 0) { @@ -4547,10 +4550,10 @@ static int showmatches(expand_T *xp, int wildmenu) if (!showtail && (xp->xp_context == EXPAND_FILES || xp->xp_context == EXPAND_SHELLCMD || xp->xp_context == EXPAND_BUFFERS)) { - home_replace(NULL, files_found[i], NameBuff, MAXPATHL, TRUE); - j = vim_strsize(NameBuff); + home_replace(NULL, (char *)files_found[i], (char *)NameBuff, MAXPATHL, true); + j = vim_strsize((char *)NameBuff); } else { - j = vim_strsize(L_SHOWFILE(i)); + j = vim_strsize((char *)L_SHOWFILE(i)); } if (j > maxlen) { maxlen = j; @@ -4617,8 +4620,7 @@ static int showmatches(expand_T *xp, int wildmenu) if (showtail) { p = L_SHOWFILE(k); } else { - home_replace(NULL, files_found[k], NameBuff, MAXPATHL, - TRUE); + home_replace(NULL, (char *)files_found[k], (char *)NameBuff, MAXPATHL, true); p = NameBuff; } } else { @@ -6532,13 +6534,13 @@ void ex_history(exarg_T *eap) msg_putchar('\n'); snprintf((char *)IObuff, IOSIZE, "%c%6d ", i == idx ? '>' : ' ', hist[i].hisnum); - if (vim_strsize(hist[i].hisstr) > Columns - 10) { + if (vim_strsize((char *)hist[i].hisstr) > Columns - 10) { trunc_string(hist[i].hisstr, IObuff + STRLEN(IObuff), Columns - 10, IOSIZE - (int)STRLEN(IObuff)); } else { STRCAT(IObuff, hist[i].hisstr); } - msg_outtrans(IObuff); + msg_outtrans((char *)IObuff); ui_flush(); } if (i == idx) { diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c index e60be80923..08c232ea69 100644 --- a/src/nvim/ex_session.c +++ b/src/nvim/ex_session.c @@ -215,7 +215,7 @@ static int ses_arglist(FILE *fd, char *cmd, garray_T *gap, int fullname, unsigne } for (int i = 0; i < gap->ga_len; i++) { // NULL file names are skipped (only happens when out of memory). - s = alist_name(&((aentry_T *)gap->ga_data)[i]); + s = (char_u *)alist_name(&((aentry_T *)gap->ga_data)[i]); if (s != NULL) { if (fullname) { buf = xmalloc(MAXPATHL); diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 4c1dd63b8f..f53f70dcda 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -1697,7 +1697,7 @@ failed: save_file_ff(curbuf); // If editing a new file: set 'fenc' for the current buffer. // Also for ":read ++edit file". - set_string_option_direct("fenc", -1, (char_u *)fenc, OPT_FREE | OPT_LOCAL, 0); + set_string_option_direct("fenc", -1, fenc, OPT_FREE | OPT_LOCAL, 0); } if (fenc_alloced) { xfree(fenc); @@ -2057,7 +2057,7 @@ void set_forced_fenc(exarg_T *eap) { if (eap->force_enc != 0) { char_u *fenc = enc_canonize((char_u *)eap->cmd + eap->force_enc); - set_string_option_direct("fenc", -1, fenc, OPT_FREE|OPT_LOCAL, 0); + set_string_option_direct("fenc", -1, (char *)fenc, OPT_FREE|OPT_LOCAL, 0); xfree(fenc); } } @@ -3765,7 +3765,7 @@ static int set_rw_fname(char_u *fname, char_u *sfname) return FAIL; } - if (setfname(curbuf, fname, sfname, false) == OK) { + if (setfname(curbuf, (char *)fname, (char *)sfname, false) == OK) { curbuf->b_flags |= BF_NOTEDITED; } @@ -3805,8 +3805,7 @@ static void add_quoted_fname(char *const ret_buf, const size_t buf_len, const bu fname = "-stdin-"; } ret_buf[0] = '"'; - home_replace(buf, (const char_u *)fname, (char_u *)ret_buf + 1, - (int)buf_len - 4, true); + home_replace(buf, fname, ret_buf + 1, (int)buf_len - 4, true); xstrlcat(ret_buf, "\" ", buf_len); } diff --git a/src/nvim/fold.c b/src/nvim/fold.c index 93ad2a6926..3c3aaa1031 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -1813,7 +1813,7 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, foldinfo_T foldin p += len - 1; } else if (*p == TAB) { *p = ' '; - } else if (ptr2cells(p) > 1) { + } else if (ptr2cells((char *)p) > 1) { break; } } diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 4426f52353..6fdc10ae0b 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -1822,7 +1822,7 @@ static int handle_mapping(int *keylenp, bool *timedout, int *mapdepth) // - waiting for a char with --more-- // - in Ctrl-X mode, and we get a valid char for that mode tb_c1 = typebuf.tb_buf[typebuf.tb_off]; - if (no_mapping == 0 && is_maphash_valid() + if (no_mapping == 0 && (no_zero_mapping == 0 || tb_c1 != '0') && (typebuf.tb_maplen == 0 || is_plug_map || (!(typebuf.tb_noremap[typebuf.tb_off] & (RM_NONE|RM_ABBR)))) @@ -2501,7 +2501,7 @@ static int vgetorpeek(bool advance) && State != MODE_HITRETURN) { // this looks nice when typing a dead character map if (State & MODE_INSERT - && ptr2cells(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len - 1) == 1) { + && ptr2cells((char *)typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len - 1) == 1) { edit_putchar(typebuf.tb_buf[typebuf.tb_off + typebuf.tb_len - 1], false); setcursor(); // put cursor back where it belongs c1 = 1; @@ -2524,9 +2524,9 @@ static int vgetorpeek(bool advance) // this looks nice when typing a dead character map if ((State & MODE_CMDLINE) && cmdline_star == 0) { - char_u *p = typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len - 1; - if (ptr2cells(p) == 1 && *p < 128) { - putcmdline((char)(*p), false); + char *p = (char *)typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len - 1; + if (ptr2cells(p) == 1 && (uint8_t)(*p) < 128) { + putcmdline(*p, false); c1 = 1; } } diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c index aeccac060a..1dd0a5f3e8 100644 --- a/src/nvim/hardcopy.c +++ b/src/nvim/hardcopy.c @@ -658,7 +658,7 @@ void ex_hardcopy(exarg_T *eap) * PS.) */ if (mch_print_init(&settings, - curbuf->b_fname == NULL ? buf_spname(curbuf) : curbuf->b_sfname == + curbuf->b_fname == NULL ? (char_u *)buf_spname(curbuf) : curbuf->b_sfname == NULL ? (char_u *)curbuf->b_fname : curbuf->b_sfname, eap->forceit) == FAIL) { return; } diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c index ac7f6c4317..e5d9a9269c 100644 --- a/src/nvim/highlight_group.c +++ b/src/nvim/highlight_group.c @@ -811,7 +811,7 @@ void do_highlight(const char *line, const bool forceit, const bool init) // ":highlight {group-name}": list highlighting for one group. if (!doclear && !dolink && ends_excmd((uint8_t)(*linep))) { - id = syn_name2id_len((const char_u *)line, (size_t)(name_end - line)); + id = syn_name2id_len(line, (size_t)(name_end - line)); if (id == 0) { semsg(_("E411: highlight group not found: %s"), line); } else { @@ -1389,7 +1389,7 @@ static void highlight_list_one(const int id) didh = true; msg_puts_attr("links to", HL_ATTR(HLF_D)); msg_putchar(' '); - msg_outtrans(hl_table[hl_table[id - 1].sg_link - 1].sg_name); + msg_outtrans((char *)hl_table[hl_table[id - 1].sg_link - 1].sg_name); } if (!didh) { @@ -1450,14 +1450,14 @@ static bool highlight_list_arg(const int id, bool didh, const int type, int iarg } } - (void)syn_list_header(didh, vim_strsize((char_u *)ts) + (int)STRLEN(name) + 1, id, false); + (void)syn_list_header(didh, vim_strsize((char *)ts) + (int)STRLEN(name) + 1, id, false); didh = true; if (!got_int) { if (*name != NUL) { msg_puts_attr(name, HL_ATTR(HLF_D)); msg_puts_attr("=", HL_ATTR(HLF_D)); } - msg_outtrans((char_u *)ts); + msg_outtrans((char *)ts); } } return didh; @@ -1581,7 +1581,7 @@ bool syn_list_header(const bool did_header, const int outlen, const int id, bool if (got_int) { return true; } - msg_outtrans(hl_table[id - 1].sg_name); + msg_outtrans((char *)hl_table[id - 1].sg_name); name_col = msg_col; endcol = 15; } else if ((ui_has(kUIMessages) || msg_silent) && !force_newline) { @@ -1650,14 +1650,14 @@ static void set_hl_attr(int idx) int syn_name2id(const char *name) FUNC_ATTR_NONNULL_ALL { - return syn_name2id_len((char_u *)name, STRLEN(name)); + return syn_name2id_len(name, STRLEN(name)); } /// Lookup a highlight group name and return its ID. /// /// @param highlight name e.g. 'Cursor', 'Normal' /// @return the highlight id, else 0 if \p name does not exist -int syn_name2id_len(const char_u *name, size_t len) +int syn_name2id_len(const char *name, size_t len) FUNC_ATTR_NONNULL_ALL { char name_u[MAX_SYN_NAME + 1]; @@ -1719,7 +1719,7 @@ int syn_check_group(const char *name, size_t len) emsg(_(e_highlight_group_name_too_long)); return 0; } - int id = syn_name2id_len((char_u *)name, len); + int id = syn_name2id_len(name, len); if (id == 0) { // doesn't exist yet return syn_add_group(name, len); } @@ -1735,7 +1735,7 @@ static int syn_add_group(const char *name, size_t len) { // Check that the name is ASCII letters, digits and underscore. for (size_t i = 0; i < len; i++) { - int c = (int8_t)name[i]; + int c = (uint8_t)name[i]; if (!vim_isprintc(c)) { emsg(_("E669: Unprintable character in group name")); return 0; diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c index f01f4fc771..8d08c2fc19 100644 --- a/src/nvim/if_cscope.c +++ b/src/nvim/if_cscope.c @@ -1078,7 +1078,7 @@ static int cs_help(exarg_T *eap) (void)msg_puts(_("cscope commands:\n")); while (cmdp->name != NULL) { char *help = _(cmdp->help); - int space_cnt = 30 - vim_strsize((char_u *)help); + int space_cnt = 30 - vim_strsize(help); // Use %*s rather than %30s to ensure proper alignment in utf-8 if (space_cnt < 0) { diff --git a/src/nvim/indent.c b/src/nvim/indent.c index d71b3adb5c..8a5b4cbf0f 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -75,7 +75,7 @@ int get_indent_str(const char_u *ptr, int ts, bool list) } else { // In list mode, when tab is not set, count screen char width // for Tab, displays: ^I - count += ptr2cells(ptr); + count += ptr2cells((char *)ptr); } } else if (*ptr == ' ') { // Count a space for one. @@ -101,7 +101,7 @@ int get_indent_str_vtab(const char_u *ptr, long ts, long *vts, bool list) } else { // In list mode, when tab is not set, count screen char width // for Tab, displays: ^I - count += ptr2cells(ptr); + count += ptr2cells((char *)ptr); } } else if (*ptr == ' ') { count++; // count a space for one @@ -481,7 +481,7 @@ int get_breakindent_win(win_T *wp, char_u *line) // indent minus the length of the showbreak string if (wp->w_briopt_sbr) { - bri -= vim_strsize(get_showbreak_value(wp)); + bri -= vim_strsize((char *)get_showbreak_value(wp)); } // never indent past left window margin diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c index 29d3c5f95b..cb807dec24 100644 --- a/src/nvim/indent_c.c +++ b/src/nvim/indent_c.c @@ -2049,9 +2049,9 @@ int get_c_indent(void) if (!cin_iscomment(theline) && comment_pos != NULL) { // XXX int lead_start_len = 2; int lead_middle_len = 1; - char_u lead_start[COM_MAX_LEN]; // start-comment string - char_u lead_middle[COM_MAX_LEN]; // middle-comment string - char_u lead_end[COM_MAX_LEN]; // end-comment string + char lead_start[COM_MAX_LEN]; // start-comment string + char lead_middle[COM_MAX_LEN]; // middle-comment string + char lead_end[COM_MAX_LEN]; // end-comment string char_u *p; int start_align = 0; int start_off = 0; @@ -2084,7 +2084,7 @@ int get_c_indent(void) if (*p == ':') { p++; } - (void)copy_option_part(&p, lead_end, COM_MAX_LEN, ","); + (void)copy_option_part(&p, (char_u *)lead_end, COM_MAX_LEN, ","); if (what == COM_START) { STRCPY(lead_start, lead_end); lead_start_len = (int)STRLEN(lead_start); @@ -2120,8 +2120,7 @@ int get_c_indent(void) if (start_off != 0) { amount += start_off; } else if (start_align == COM_RIGHT) { - amount += vim_strsize(lead_start) - - vim_strsize(lead_middle); + amount += vim_strsize(lead_start) - vim_strsize(lead_middle); } break; } diff --git a/src/nvim/keycodes.c b/src/nvim/keycodes.c index e0ada32ec2..dd78ebe722 100644 --- a/src/nvim/keycodes.c +++ b/src/nvim/keycodes.c @@ -861,6 +861,9 @@ int get_mouse_button(int code, bool *is_click, bool *is_drag) /// @param[in] from What characters to replace. /// @param[in] from_len Length of the "from" argument. /// @param[out] bufp Location where results were saved in case of success (allocated). +/// if *bufp is non-NULL, it will be used directly. it is +/// assumed to be 128 bytes long (enough for transcoding LHS +/// of mapping) /// Will be set to NULL in case of failure. /// @param[in] flags REPTERM_FROM_PART see above /// REPTERM_DO_LT also translate <lt> @@ -885,10 +888,12 @@ char *replace_termcodes(const char *const from, const size_t from_len, char **co const bool do_backslash = !(cpo_flags & FLAG_CPO_BSLASH); // backslash is a special character const bool do_special = !(flags & REPTERM_NO_SPECIAL); + bool allocated = (*bufp == NULL); + // Allocate space for the translation. Worst case a single character is // replaced by 6 bytes (shifted special key), plus a NUL at the end. - const size_t buf_len = from_len * 6 + 1; - result = xmalloc(buf_len); + const size_t buf_len = allocated ? from_len * 6 + 1 : 128; + result = allocated ? xmalloc(buf_len) : *bufp; src = (char_u *)from; @@ -907,6 +912,9 @@ char *replace_termcodes(const char *const from, const size_t from_len, char **co // Copy each byte from *from to result[dlen] while (src <= end) { + if (!allocated && dlen + 64 > buf_len) { + return NULL; + } // Check for special <> keycodes, like "<C-S-LeftMouse>" if (do_special && ((flags & REPTERM_DO_LT) || ((end - src) >= 3 && STRNCMP(src, "<lt>", 4) != 0))) { @@ -1000,7 +1008,9 @@ char *replace_termcodes(const char *const from, const size_t from_len, char **co } result[dlen] = NUL; - *bufp = xrealloc(result, dlen + 1); + if (allocated) { + *bufp = xrealloc(result, dlen + 1); + } return *bufp; } diff --git a/src/nvim/main.c b/src/nvim/main.c index 124248508e..2b5a5a9033 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1357,9 +1357,8 @@ scripterror: char_u *p = vim_strsave((char_u *)argv[0]); if (parmp->diff_mode && os_isdir(p) && GARGCOUNT > 0 - && !os_isdir(alist_name(&GARGLIST[0]))) { - char_u *r = (char_u *)concat_fnames((char *)p, - path_tail((char *)alist_name(&GARGLIST[0])), true); + && !os_isdir((char_u *)alist_name(&GARGLIST[0]))) { + char_u *r = (char_u *)concat_fnames((char *)p, path_tail(alist_name(&GARGLIST[0])), true); xfree(p); p = r; } @@ -1477,7 +1476,7 @@ static void init_path(const char *exename) /// Get filename from command line, if any. static char_u *get_fname(mparm_T *parmp, char_u *cwd) { - return alist_name(&GARGLIST[0]); + return (char_u *)alist_name(&GARGLIST[0]); } /* @@ -1502,7 +1501,7 @@ static void handle_quickfix(mparm_T *paramp) { if (paramp->edit_type == EDIT_QF) { if (paramp->use_ef != NULL) { - set_string_option_direct("ef", -1, (char_u *)paramp->use_ef, OPT_FREE, SID_CARG); + set_string_option_direct("ef", -1, paramp->use_ef, OPT_FREE, SID_CARG); } vim_snprintf((char *)IObuff, IOSIZE, "cfile %s", p_ef); if (qf_init(NULL, (char *)p_ef, p_efm, true, (char *)IObuff, (char *)p_menc) < 0) { @@ -1743,7 +1742,7 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd) // at the ATTENTION prompt close the window. swap_exists_did_quit = false; (void)do_ecmd(0, arg_idx < GARGCOUNT - ? (char *)alist_name(&GARGLIST[arg_idx]) + ? alist_name(&GARGLIST[arg_idx]) : NULL, NULL, NULL, ECMD_LASTL, ECMD_HIDE, curwin); if (swap_exists_did_quit) { // abort or quit selected @@ -1946,9 +1945,7 @@ static bool do_user_initialization(void) if (do_source((char *)user_vimrc, true, DOSO_VIMRC) != FAIL) { do_exrc = p_exrc; if (do_exrc) { - do_exrc = (path_full_compare((char_u *)VIMRC_FILE, user_vimrc, - false, true) - != kEqualFiles); + do_exrc = (path_full_compare(VIMRC_FILE, (char *)user_vimrc, false, true) != kEqualFiles); } xfree(user_vimrc); return do_exrc; @@ -1974,8 +1971,7 @@ static bool do_user_initialization(void) if (do_source(vimrc, true, DOSO_VIMRC) != FAIL) { do_exrc = p_exrc; if (do_exrc) { - do_exrc = (path_full_compare((char_u *)VIMRC_FILE, (char_u *)vimrc, - false, true) != kEqualFiles); + do_exrc = (path_full_compare(VIMRC_FILE, vimrc, false, true) != kEqualFiles); } xfree(vimrc); xfree(config_dirs); diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c index 481ac8213a..d4f7450af4 100644 --- a/src/nvim/mapping.c +++ b/src/nvim/mapping.c @@ -37,8 +37,7 @@ static mapblock_T *first_abbr = NULL; // first entry in abbrlist // Each mapping is put in one of the MAX_MAPHASH hash lists, // to speed up finding it. -static mapblock_T *(maphash[MAX_MAPHASH]); -static bool maphash_valid = false; +static mapblock_T *(maphash[MAX_MAPHASH]) = { 0 }; // Make a hash value for a mapping. // "mode" is the lower 4 bits of the State for the mapping. @@ -80,20 +79,6 @@ mapblock_T *get_maphash(int index, buf_T *buf) return (buf == NULL) ? maphash[index] : buf->b_maphash[index]; } -bool is_maphash_valid(void) -{ - return maphash_valid; -} - -/// Initialize maphash[] for first use. -static void validate_maphash(void) -{ - if (!maphash_valid) { - memset(maphash, 0, sizeof(maphash)); - maphash_valid = true; - } -} - /// Delete one entry from the abbrlist or maphash[]. /// "mpp" is a pointer to the m_next field of the PREVIOUS entry! static void mapblock_free(mapblock_T **mpp) @@ -104,10 +89,10 @@ static void mapblock_free(mapblock_T **mpp) xfree(mp->m_keys); if (!mp->m_simplified) { NLUA_CLEAR_REF(mp->m_luaref); + xfree(mp->m_str); + xfree(mp->m_orig_str); } - XFREE_CLEAR(mp->m_str); - XFREE_CLEAR(mp->m_orig_str); - XFREE_CLEAR(mp->m_desc); + xfree(mp->m_desc); *mpp = mp->m_next; xfree(mp); } @@ -254,14 +239,12 @@ static void showmap(mapblock_T *mp, bool local) /// @param[in] orig_rhs_len `strlen` of orig_rhs. /// @param[in] cpo_flags See param docs for @ref replace_termcodes. /// @param[out] mapargs MapArguments struct holding the replaced strings. -static void set_maparg_lhs_rhs(const char *const orig_lhs, const size_t orig_lhs_len, +static bool set_maparg_lhs_rhs(const char *const orig_lhs, const size_t orig_lhs_len, const char *const orig_rhs, const size_t orig_rhs_len, const LuaRef rhs_lua, const int cpo_flags, MapArguments *const mapargs) { - char *lhs_buf = NULL; - char *alt_lhs_buf = NULL; - char *rhs_buf = NULL; + char lhs_buf[128]; // If mapping has been given as ^V<C_UP> say, then replace the term codes // with the appropriate two bytes. If it is a shifted special key, unshift @@ -273,13 +256,20 @@ static void set_maparg_lhs_rhs(const char *const orig_lhs, const size_t orig_lhs // If something like <C-H> is simplified to 0x08 then mark it as simplified. bool did_simplify = false; const int flags = REPTERM_FROM_PART | REPTERM_DO_LT; - char *replaced = replace_termcodes(orig_lhs, orig_lhs_len, &lhs_buf, flags, &did_simplify, + char *bufarg = lhs_buf; + char *replaced = replace_termcodes(orig_lhs, orig_lhs_len, &bufarg, flags, &did_simplify, cpo_flags); + if (replaced == NULL) { + return false; + } mapargs->lhs_len = STRLEN(replaced); STRLCPY(mapargs->lhs, replaced, sizeof(mapargs->lhs)); if (did_simplify) { - replaced = replace_termcodes(orig_lhs, orig_lhs_len, &alt_lhs_buf, flags | REPTERM_NO_SIMPLIFY, + replaced = replace_termcodes(orig_lhs, orig_lhs_len, &bufarg, flags | REPTERM_NO_SIMPLIFY, NULL, cpo_flags); + if (replaced == NULL) { + return false; + } mapargs->alt_lhs_len = STRLEN(replaced); STRLCPY(mapargs->alt_lhs, replaced, sizeof(mapargs->alt_lhs)); } else { @@ -298,14 +288,14 @@ static void set_maparg_lhs_rhs(const char *const orig_lhs, const size_t orig_lhs mapargs->rhs_len = 0; mapargs->rhs_is_noop = true; } else { + char *rhs_buf = NULL; replaced = replace_termcodes(orig_rhs, orig_rhs_len, &rhs_buf, REPTERM_DO_LT, NULL, cpo_flags); mapargs->rhs_len = STRLEN(replaced); // XXX: replace_termcodes may produce an empty string even if orig_rhs is non-empty // (e.g. a single ^V, see :h map-empty-rhs) mapargs->rhs_is_noop = orig_rhs_len != 0 && mapargs->rhs_len == 0; - mapargs->rhs = xcalloc(mapargs->rhs_len + 1, sizeof(char_u)); - STRLCPY(mapargs->rhs, replaced, mapargs->rhs_len + 1); + mapargs->rhs = (char_u *)replaced; } } else { char tmp_buf[64]; @@ -317,10 +307,7 @@ static void set_maparg_lhs_rhs(const char *const orig_lhs, const size_t orig_lhs (char_u)KS_EXTRA, KE_LUA, rhs_lua); mapargs->rhs = vim_strsave((char_u *)tmp_buf); } - - xfree(lhs_buf); - xfree(alt_lhs_buf); - xfree(rhs_buf); + return true; } /// Parse a string of |:map-arguments| into a @ref MapArguments struct. @@ -346,27 +333,26 @@ static int str_to_mapargs(const char_u *strargs, bool is_unmap, MapArguments *ma { const char_u *to_parse = strargs; to_parse = (char_u *)skipwhite((char *)to_parse); - MapArguments parsed_args; // copy these into mapargs "all at once" when done - memset(&parsed_args, 0, sizeof(parsed_args)); + memset(mapargs, 0, sizeof(*mapargs)); // Accept <buffer>, <nowait>, <silent>, <expr>, <script>, and <unique> in // any order. while (true) { if (STRNCMP(to_parse, "<buffer>", 8) == 0) { to_parse = (char_u *)skipwhite((char *)to_parse + 8); - parsed_args.buffer = true; + mapargs->buffer = true; continue; } if (STRNCMP(to_parse, "<nowait>", 8) == 0) { to_parse = (char_u *)skipwhite((char *)to_parse + 8); - parsed_args.nowait = true; + mapargs->nowait = true; continue; } if (STRNCMP(to_parse, "<silent>", 8) == 0) { to_parse = (char_u *)skipwhite((char *)to_parse + 8); - parsed_args.silent = true; + mapargs->silent = true; continue; } @@ -378,19 +364,19 @@ static int str_to_mapargs(const char_u *strargs, bool is_unmap, MapArguments *ma if (STRNCMP(to_parse, "<script>", 8) == 0) { to_parse = (char_u *)skipwhite((char *)to_parse + 8); - parsed_args.script = true; + mapargs->script = true; continue; } if (STRNCMP(to_parse, "<expr>", 6) == 0) { to_parse = (char_u *)skipwhite((char *)to_parse + 6); - parsed_args.expr = true; + mapargs->expr = true; continue; } if (STRNCMP(to_parse, "<unique>", 8) == 0) { to_parse = (char_u *)skipwhite((char *)to_parse + 8); - parsed_args.unique = true; + mapargs->unique = true; continue; } break; @@ -423,19 +409,20 @@ static int str_to_mapargs(const char_u *strargs, bool is_unmap, MapArguments *ma // Given {lhs} might be larger than MAXMAPLEN before replace_termcodes // (e.g. "<Space>" is longer than ' '), so first copy into a buffer. size_t orig_lhs_len = (size_t)((char_u *)lhs_end - to_parse); - char_u *lhs_to_replace = xcalloc(orig_lhs_len + 1, sizeof(char_u)); + if (orig_lhs_len >= 256) { + return 1; + } + char_u lhs_to_replace[256]; STRLCPY(lhs_to_replace, to_parse, orig_lhs_len + 1); size_t orig_rhs_len = STRLEN(rhs_start); - set_maparg_lhs_rhs((char *)lhs_to_replace, orig_lhs_len, - (char *)rhs_start, orig_rhs_len, LUA_NOREF, - CPO_TO_CPO_FLAGS, &parsed_args); - - xfree(lhs_to_replace); - - *mapargs = parsed_args; + if (!set_maparg_lhs_rhs((char *)lhs_to_replace, orig_lhs_len, + (char *)rhs_start, orig_rhs_len, LUA_NOREF, + CPO_TO_CPO_FLAGS, mapargs)) { + return 1; + } - if (parsed_args.lhs_len > MAXMAPLEN) { + if (mapargs->lhs_len > MAXMAPLEN) { return 1; } return 0; @@ -481,8 +468,6 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, noremap = REMAP_SCRIPT; } - validate_maphash(); - const bool has_lhs = (args->lhs[0] != NUL); const bool has_rhs = args->rhs_lua != LUA_NOREF || (args->rhs[0] != NUL) || args->rhs_is_noop; const bool do_print = !has_lhs || (maptype != 1 && !has_rhs); @@ -494,8 +479,6 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, } const char_u *lhs = (char_u *)&args->lhs; - const char_u *const rhs = args->rhs; - const char_u *const orig_rhs = args->orig_rhs; const bool did_simplify = args->alt_lhs_len != 0; // The following is done twice if we have two versions of keys @@ -635,16 +618,18 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, // "bar" because of the abbreviation. for (int round = 0; (round == 0 || maptype == 1) && round <= 1 && !did_it && !got_int; round++) { - // need to loop over all hash lists - for (int hash = 0; hash < 256 && !got_int; hash++) { - if (is_abbrev) { - if (hash > 0) { // there is only one abbreviation list - break; - } - mpp = abbr_table; - } else { - mpp = &(map_table[hash]); - } + int hash_start, hash_end; + if (has_lhs || is_abbrev) { + // just use one hash + hash_start = is_abbrev ? 0 : MAP_HASH(mode, lhs[0]); + hash_end = hash_start + 1; + } else { + // need to loop over all hash lists + hash_start = 0; + hash_end = 256; + } + for (int hash = hash_start; hash < hash_end && !got_int; hash++) { + mpp = is_abbrev ? abbr_table : &(map_table[hash]); for (mp = *mpp; mp != NULL && !got_int; mp = *mpp) { if ((mp->m_mode & mode) == 0) { // skip entries with wrong mode @@ -710,16 +695,20 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, // new rhs for existing entry mp->m_mode &= ~mode; // remove mode bits if (mp->m_mode == 0 && !did_it) { // reuse entry - XFREE_CLEAR(mp->m_str); - XFREE_CLEAR(mp->m_orig_str); XFREE_CLEAR(mp->m_desc); if (!mp->m_simplified) { NLUA_CLEAR_REF(mp->m_luaref); + XFREE_CLEAR(mp->m_str); + XFREE_CLEAR(mp->m_orig_str); } - - mp->m_str = vim_strsave(rhs); - mp->m_orig_str = vim_strsave(orig_rhs); + mp->m_str = args->rhs; + mp->m_orig_str = args->orig_rhs; mp->m_luaref = args->rhs_lua; + if (!keyround1_simplified) { + args->rhs = NULL; + args->orig_rhs = NULL; + args->rhs_lua = LUA_NOREF; + } mp->m_noremap = noremap; mp->m_nowait = args->nowait; mp->m_silent = args->silent; @@ -802,9 +791,14 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, } mp->m_keys = vim_strsave(lhs); - mp->m_str = vim_strsave(rhs); - mp->m_orig_str = vim_strsave(orig_rhs); + mp->m_str = args->rhs; + mp->m_orig_str = args->orig_rhs; mp->m_luaref = args->rhs_lua; + if (!keyround1_simplified) { + args->rhs = NULL; + args->orig_rhs = NULL; + args->rhs_lua = LUA_NOREF; + } mp->m_keylen = (int)STRLEN(mp->m_keys); mp->m_noremap = noremap; mp->m_nowait = args->nowait; @@ -975,8 +969,6 @@ void map_clear_int(buf_T *buf, int mode, bool local, bool abbr) int hash; int new_hash; - validate_maphash(); - for (hash = 0; hash < 256; hash++) { if (abbr) { if (hash > 0) { // there is only one abbrlist @@ -1037,7 +1029,7 @@ bool map_to_exists(const char *const str, const char *const modechars, const boo int mode = 0; int retval; - char_u *buf; + char_u *buf = NULL; const char_u *const rhs = (char_u *)replace_termcodes(str, strlen(str), (char **)&buf, REPTERM_DO_LT, NULL, CPO_TO_CPO_FLAGS); @@ -1080,8 +1072,6 @@ int map_to_exists_mode(const char *const rhs, const int mode, const bool abbr) int hash; bool exp_buffer = false; - validate_maphash(); - // Do it twice: once for global maps and once for local maps. for (;;) { for (hash = 0; hash < 256; hash++) { @@ -1249,8 +1239,6 @@ int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file) char_u *p; int i; - validate_maphash(); - *num_file = 0; // return values in case of FAIL *file = NULL; @@ -1597,8 +1585,6 @@ int makemap(FILE *fd, buf_T *buf) int hash; bool did_cpo = false; - validate_maphash(); - // Do the loop twice: Once for mappings, once for abbreviations. // Then loop over all map hash lists. for (abbr = 0; abbr < 2; abbr++) { @@ -1911,8 +1897,6 @@ char_u *check_map(char_u *keys, int mode, int exact, int ign_mod, int abbr, mapb mapblock_T *mp; *rhs_lua = LUA_NOREF; - validate_maphash(); - len = (int)STRLEN(keys); for (int local = 1; local >= 0; local--) { // loop over all hash lists @@ -2340,7 +2324,7 @@ void ex_map(exarg_T *eap) // print the mappings for security reasons. if (secure) { secure = 2; - msg_outtrans((char_u *)eap->cmd); + msg_outtrans(eap->cmd); msg_putchar('\n'); } do_exmap(eap, false); @@ -2409,9 +2393,13 @@ void modify_keymap(uint64_t channel_id, Buffer buffer, bool is_unmap, String mod } parsed_args.buffer = !global; - set_maparg_lhs_rhs(lhs.data, lhs.size, - rhs.data, rhs.size, lua_funcref, - CPO_TO_CPO_FLAGS, &parsed_args); + if (!set_maparg_lhs_rhs(lhs.data, lhs.size, + rhs.data, rhs.size, lua_funcref, + CPO_TO_CPO_FLAGS, &parsed_args)) { + api_set_error(err, kErrorTypeValidation, "LHS exceeds maximum map length: %s", lhs.data); + goto fail_and_free; + } + if (opts != NULL && opts->desc.type == kObjectTypeString) { parsed_args.desc = string_to_cstr(opts->desc.data.string); } else { @@ -2491,13 +2479,12 @@ void modify_keymap(uint64_t channel_id, Buffer buffer, bool is_unmap, String mod goto fail_and_free; } // switch - parsed_args.rhs_lua = LUA_NOREF; // don't clear ref on success fail_and_free: current_sctx = save_current_sctx; NLUA_CLEAR_REF(parsed_args.rhs_lua); xfree(parsed_args.rhs); xfree(parsed_args.orig_rhs); - XFREE_CLEAR(parsed_args.desc); + xfree(parsed_args.desc); } /// Get an array containing dictionaries describing mappings diff --git a/src/nvim/mark.c b/src/nvim/mark.c index 8d1a917600..a0fed19a98 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -637,7 +637,7 @@ static char_u *mark_line(pos_T *mp, int lead_len) // Truncate the line to fit it in the window len = 0; for (p = s; *p != NUL; MB_PTR_ADV(p)) { - len += ptr2cells(p); + len += ptr2cells((char *)p); if (len >= Columns - lead_len) { break; } @@ -733,7 +733,7 @@ static void show_one_mark(int c, char_u *arg, pos_T *p, char_u *name_arg, int cu msg_putchar('\n'); if (!got_int) { snprintf((char *)IObuff, IOSIZE, " %c %6" PRIdLINENR " %4d ", c, p->lnum, p->col); - msg_outtrans(IObuff); + msg_outtrans((char *)IObuff); if (name != NULL) { msg_outtrans_attr(name, current ? HL_ATTR(HLF_D) : 0); } @@ -864,7 +864,7 @@ void ex_jumps(exarg_T *eap) i == curwin->w_jumplistidx ? '>' : ' ', i > curwin->w_jumplistidx ? i - curwin->w_jumplistidx : curwin->w_jumplistidx - i, curwin->w_jumplist[i].fmark.mark.lnum, curwin->w_jumplist[i].fmark.mark.col); - msg_outtrans(IObuff); + msg_outtrans((char *)IObuff); msg_outtrans_attr(name, curwin->w_jumplist[i].fmark.fnum == curbuf->b_fnum ? HL_ATTR(HLF_D) : 0); @@ -908,7 +908,7 @@ void ex_changes(exarg_T *eap) : curwin->w_changelistidx - i, (long)curbuf->b_changelist[i].mark.lnum, curbuf->b_changelist[i].mark.col); - msg_outtrans(IObuff); + msg_outtrans((char *)IObuff); name = mark_line(&curbuf->b_changelist[i].mark, 17); msg_outtrans_attr(name, HL_ATTR(HLF_D)); xfree(name); @@ -1578,7 +1578,7 @@ void mark_mb_adjustpos(buf_T *buf, pos_T *lp) if (lp->coladd == 1 && p[lp->col] != TAB && vim_isprintc(utf_ptr2char((char *)p + lp->col)) - && ptr2cells(p + lp->col) > 1) { + && ptr2cells((char *)p + lp->col) > 1) { lp->coladd = 0; } } diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index 24d079ea2c..1032986a02 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -2012,7 +2012,7 @@ void mb_check_adjust_col(void *win_) // Column 0 is always valid. if (oldcol != 0) { - char_u *p = ml_get_buf(win->w_buffer, win->w_cursor.lnum, false); + char *p = (char *)ml_get_buf(win->w_buffer, win->w_cursor.lnum, false); colnr_T len = (colnr_T)STRLEN(p); // Empty line or invalid column? @@ -2024,13 +2024,13 @@ void mb_check_adjust_col(void *win_) win->w_cursor.col = len - 1; } // Move the cursor to the head byte. - win->w_cursor.col -= utf_head_off(p, p + win->w_cursor.col); + win->w_cursor.col -= utf_head_off((char_u *)p, (char_u *)p + win->w_cursor.col); } // Reset `coladd` when the cursor would be on the right half of a // double-wide character. if (win->w_cursor.coladd == 1 && p[win->w_cursor.col] != TAB - && vim_isprintc(utf_ptr2char((char *)p + win->w_cursor.col)) + && vim_isprintc(utf_ptr2char(p + win->w_cursor.col)) && ptr2cells(p + win->w_cursor.col) > 1) { win->w_cursor.coladd = 0; } diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 21b0ab89d7..9da5aa54c5 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -531,7 +531,7 @@ void ml_open_file(buf_T *buf) need_wait_return = true; // call wait_return later no_wait_return++; (void)semsg(_("E303: Unable to open swap file for \"%s\", recovery impossible"), - buf_spname(buf) != NULL ? buf_spname(buf) : (char_u *)buf->b_fname); + buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname); no_wait_return--; } @@ -665,8 +665,8 @@ static void set_b0_fname(ZERO_BL *b0p, buf_T *buf) * First replace home dir path with "~/" with home_replace(). * Then insert the user name to get "~user/". */ - home_replace(NULL, buf->b_ffname, b0p->b0_fname, - B0_FNAME_SIZE_CRYPT, TRUE); + home_replace(NULL, (char *)buf->b_ffname, (char *)b0p->b0_fname, + B0_FNAME_SIZE_CRYPT, true); if (b0p->b0_fname[0] == '~') { // If there is no user name or it is too long, don't use "~/" int retval = os_get_user_name(uname, B0_UNAME_SIZE); @@ -933,18 +933,18 @@ void ml_recover(bool checkext) */ if (directly) { expand_env(b0p->b0_fname, NameBuff, MAXPATHL); - if (setfname(curbuf, NameBuff, NULL, true) == FAIL) { + if (setfname(curbuf, (char *)NameBuff, NULL, true) == FAIL) { goto theend; } } - home_replace(NULL, mfp->mf_fname, NameBuff, MAXPATHL, TRUE); + home_replace(NULL, (char *)mfp->mf_fname, (char *)NameBuff, MAXPATHL, true); smsg(_("Using swap file \"%s\""), NameBuff); if (buf_spname(curbuf) != NULL) { STRLCPY(NameBuff, buf_spname(curbuf), MAXPATHL); } else { - home_replace(NULL, curbuf->b_ffname, NameBuff, MAXPATHL, TRUE); + home_replace(NULL, (char *)curbuf->b_ffname, (char *)NameBuff, MAXPATHL, true); } smsg(_("Original file \"%s\""), NameBuff); msg_putchar('\n'); @@ -1377,7 +1377,7 @@ int recover_names(char_u *fname, int list, int nr, char_u **fname_out) for (int i = 0; i < num_files; i++) { // Do not expand wildcards, on Windows would try to expand // "%tmp%" in "%tmp%file" - if (path_full_compare(p, files[i], true, false) & kEqualFiles) { + if (path_full_compare((char *)p, (char *)files[i], true, false) & kEqualFiles) { // Remove the name from files[i]. Move further entries // down. When the array becomes empty free it here, since // FreeWild() won't be called below. @@ -1520,7 +1520,7 @@ static time_t swapfile_info(char_u *fname) // print name of owner of the file if (os_get_uname(file_info.stat.st_uid, uname, B0_UNAME_SIZE) == OK) { msg_puts(_(" owned by: ")); - msg_outtrans((char_u *)uname); + msg_outtrans(uname); msg_puts(_(" dated: ")); } else #endif @@ -1547,7 +1547,7 @@ static time_t swapfile_info(char_u *fname) if (b0.b0_fname[0] == NUL) { msg_puts(_("[No Name]")); } else { - msg_outtrans(b0.b0_fname); + msg_outtrans((char *)b0.b0_fname); } msg_puts(_("\n modified: ")); @@ -1555,7 +1555,7 @@ static time_t swapfile_info(char_u *fname) if (*(b0.b0_uname) != NUL) { msg_puts(_("\n user name: ")); - msg_outtrans(b0.b0_uname); + msg_outtrans((char *)b0.b0_uname); } if (*(b0.b0_hname) != NUL) { @@ -1564,7 +1564,7 @@ static time_t swapfile_info(char_u *fname) } else { msg_puts(_("\n host name: ")); } - msg_outtrans(b0.b0_hname); + msg_outtrans((char *)b0.b0_hname); } if (char_to_long(b0.b0_pid) != 0L) { @@ -3317,7 +3317,7 @@ static void attention_message(buf_T *buf, char_u *fname) msg_puts("\"\n"); const time_t swap_mtime = swapfile_info(fname); msg_puts(_("While opening file \"")); - msg_outtrans((char_u *)buf->b_fname); + msg_outtrans(buf->b_fname); msg_puts("\"\n"); FileInfo file_info; if (!os_fileinfo(buf->b_fname, &file_info)) { @@ -3339,10 +3339,10 @@ static void attention_message(buf_T *buf, char_u *fname) " Quit, or continue with caution.\n")); msg_puts(_("(2) An edit session for this file crashed.\n")); msg_puts(_(" If this is the case, use \":recover\" or \"vim -r ")); - msg_outtrans((char_u *)buf->b_fname); + msg_outtrans(buf->b_fname); msg_puts(_("\"\n to recover the changes (see \":help recovery\").\n")); msg_puts(_(" If you did this already, delete the swap file \"")); - msg_outtrans(fname); + msg_outtrans((char *)fname); msg_puts(_("\"\n to avoid this message.\n")); cmdline_row = msg_row; --no_wait_return; @@ -3552,8 +3552,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_ char *const name = xmalloc(name_len); memcpy(name, sw_msg_1, sw_msg_1_len + 1); - home_replace(NULL, (char_u *)fname, (char_u *)&name[sw_msg_1_len], - fname_len, true); + home_replace(NULL, fname, &name[sw_msg_1_len], fname_len, true); xstrlcat(name, sw_msg_2, name_len); choice = do_dialog(VIM_WARNING, (char_u *)_("VIM - ATTENTION"), (char_u *)name, diff --git a/src/nvim/memory.c b/src/nvim/memory.c index a615802b36..29a1191bd6 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -15,6 +15,7 @@ #include "nvim/highlight.h" #include "nvim/highlight_group.h" #include "nvim/lua/executor.h" +#include "nvim/mapping.h" #include "nvim/memfile.h" #include "nvim/memory.h" #include "nvim/message.h" @@ -689,11 +690,9 @@ void free_all_mem(void) do_cmdline_cmd("menutranslate clear"); // Clear mappings, abbreviations, breakpoints. - do_cmdline_cmd("lmapclear"); - do_cmdline_cmd("xmapclear"); - do_cmdline_cmd("mapclear"); - do_cmdline_cmd("mapclear!"); - do_cmdline_cmd("abclear"); + // NB: curbuf not used with local=false arg + map_clear_int(curbuf, MAP_ALL_MODES, false, false); + map_clear_int(curbuf, MAP_ALL_MODES, false, true); do_cmdline_cmd("breakdel *"); do_cmdline_cmd("profdel *"); do_cmdline_cmd("set keymap="); diff --git a/src/nvim/menu.c b/src/nvim/menu.c index f4943c4031..80f8406ab0 100644 --- a/src/nvim/menu.c +++ b/src/nvim/menu.c @@ -232,6 +232,7 @@ void ex_menu(exarg_T *eap) } else if (modes & MENU_TIP_MODE) { map_buf = NULL; // Menu tips are plain text. } else { + map_buf = NULL; map_to = replace_termcodes(map_to, STRLEN(map_to), &map_buf, REPTERM_DO_LT, NULL, CPO_TO_CPO_FLAGS); } diff --git a/src/nvim/message.c b/src/nvim/message.c index e192af6aad..733b4808fe 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -136,7 +136,7 @@ static int msg_grid_scroll_discount = 0; static void ui_ext_msg_set_pos(int row, bool scrolled) { char buf[MAX_MCO + 1]; - size_t size = utf_char2bytes(curwin->w_p_fcs_chars.msgsep, buf); + size_t size = (size_t)utf_char2bytes(curwin->w_p_fcs_chars.msgsep, buf); buf[size] = '\0'; ui_call_msg_set_pos(msg_grid.handle, row, scrolled, (String){ .data = buf, .size = size }); @@ -164,7 +164,7 @@ void msg_grid_validate(void) { grid_assign_handle(&msg_grid); bool should_alloc = msg_use_grid(); - int max_rows = Rows - p_ch; + int max_rows = Rows - (int)p_ch; if (should_alloc && (msg_grid.rows != Rows || msg_grid.cols != Columns || !msg_grid.chars)) { // TODO(bfredl): eventually should be set to "invalid". I e all callers @@ -173,7 +173,7 @@ void msg_grid_validate(void) msg_grid.zindex = kZIndexMessages; xfree(msg_grid.dirty_col); - msg_grid.dirty_col = xcalloc(Rows, sizeof(*msg_grid.dirty_col)); + msg_grid.dirty_col = xcalloc((size_t)Rows, sizeof(*msg_grid.dirty_col)); // Tricky: allow resize while pager is active int pos = msg_scrolled ? msg_grid_pos : max_rows; @@ -248,7 +248,7 @@ void msg_multiline_attr(const char *s, int attr, bool check_int, bool *need_clea if (next_spec != NULL) { // Printing all char that are before the char found by strpbrk - msg_outtrans_len_attr((const char_u *)s, next_spec - s, attr); + msg_outtrans_len_attr((const char_u *)s, (int)(next_spec - s), attr); if (*next_spec != TAB && *need_clear) { msg_clr_eos(); @@ -348,7 +348,7 @@ bool msg_attr_keep(const char *s, int attr, bool keep, bool multiline) } retval = msg_end(); - if (keep && retval && vim_strsize((char_u *)s) < (Rows - cmdline_row - 1) * Columns + sc_col) { + if (keep && retval && vim_strsize((char *)s) < (Rows - cmdline_row - 1) * Columns + sc_col) { set_keep_msg((char *)s, 0); } @@ -374,7 +374,7 @@ char_u *msg_strtrunc(char_u *s, int force) if ((!msg_scroll && !need_wait_return && shortmess(SHM_TRUNCALL) && !exmode_active && msg_silent == 0 && !ui_has(kUIMessages)) || force) { - len = vim_strsize(s); + len = vim_strsize((char *)s); if (msg_scrolled != 0) { // Use all the columns. room = (Rows - msg_row) * Columns - 1; @@ -386,7 +386,7 @@ char_u *msg_strtrunc(char_u *s, int force) // may have up to 18 bytes per cell (6 per char, up to two // composing chars) len = (room + 2) * 18; - buf = xmalloc(len); + buf = xmalloc((size_t)len); trunc_string(s, buf, room, len); } } @@ -397,9 +397,9 @@ char_u *msg_strtrunc(char_u *s, int force) /// "s" and "buf" may be equal. void trunc_string(char_u *s, char_u *buf, int room_in, int buflen) { - size_t room = room_in - 3; // "..." takes 3 chars - size_t half; - size_t len = 0; + int room = room_in - 3; // "..." takes 3 chars + int half; + int len = 0; int e; int i; int n; @@ -423,7 +423,7 @@ void trunc_string(char_u *s, char_u *buf, int room_in, int buflen) buf[e] = NUL; return; } - n = ptr2cells(s + e); + n = ptr2cells((char *)s + e); if (len + n > half) { break; } @@ -443,7 +443,7 @@ void trunc_string(char_u *s, char_u *buf, int room_in, int buflen) do { half = half - utf_head_off(s, s + half - 1) - 1; } while (half > 0 && utf_iscomposing(utf_ptr2char((char *)s + half))); - n = ptr2cells(s + half); + n = ptr2cells((char *)s + half); if (len + n > room || half == 0) { break; } @@ -454,25 +454,25 @@ void trunc_string(char_u *s, char_u *buf, int room_in, int buflen) if (i <= e + 3) { // text fits without truncating if (s != buf) { - len = STRLEN(s); - if (len >= (size_t)buflen) { + len = (int)STRLEN(s); + if (len >= buflen) { len = buflen - 1; } len = len - e + 1; if (len < 1) { buf[e - 1] = NUL; } else { - memmove(buf + e, s + e, len); + memmove(buf + e, s + e, (size_t)len); } } } else if (e + 3 < buflen) { // set the middle and copy the last part memmove(buf + e, "...", (size_t)3); - len = STRLEN(s + i) + 1; - if (len >= (size_t)buflen - e - 3) { + len = (int)STRLEN(s + i) + 1; + if (len >= buflen - e - 3) { len = buflen - e - 3 - 1; } - memmove(buf + e + 3, s + i, len); + memmove(buf + e + 3, s + i, (size_t)len); buf[e + 3 + len - 1] = NUL; } else { // can't fit in the "...", just truncate it @@ -671,17 +671,17 @@ static bool emsg_multiline(const char *s, bool multiline) if (p != NULL) { const size_t p_len = strlen(p); p[p_len] = '\n'; - redir_write(p, p_len + 1); + redir_write(p, (ptrdiff_t)p_len + 1); xfree(p); } p = get_emsg_lnum(); if (p != NULL) { const size_t p_len = strlen(p); p[p_len] = '\n'; - redir_write(p, p_len + 1); + redir_write(p, (ptrdiff_t)p_len + 1); xfree(p); } - redir_write(s, strlen(s)); + redir_write(s, (ptrdiff_t)strlen(s)); } // Log (silent) errors as debug messages. @@ -892,7 +892,7 @@ char_u *msg_may_trunc(bool force, char_u *s) room = (Rows - cmdline_row - 1) * Columns + sc_col - 1; if ((force || (shortmess(SHM_TRUNC) && !exmode_active)) && (int)STRLEN(s) - room > 0) { - int size = vim_strsize(s); + int size = vim_strsize((char *)s); // There may be room anyway when there are multibyte chars. if (size <= room) { @@ -1275,7 +1275,7 @@ void wait_return(int redraw) emsg_on_display = false; // can delete error message now lines_left = -1; // reset lines_left at next msg_start() reset_last_sourcing(); - if (keep_msg != NULL && vim_strsize(keep_msg) >= + if (keep_msg != NULL && vim_strsize((char *)keep_msg) >= (Rows - cmdline_row - 1) * Columns + sc_col) { XFREE_CLEAR(keep_msg); // don't redisplay message, it's too long } @@ -1444,7 +1444,7 @@ void msg_putchar(int c) void msg_putchar_attr(int c, int attr) { - char_u buf[MB_MAXBYTES + 1]; + char buf[MB_MAXBYTES + 1]; if (IS_SPECIAL(c)) { buf[0] = (char)K_SPECIAL; @@ -1489,9 +1489,9 @@ static void msg_home_replace_attr(char_u *fname, int attr) /// Use attributes 'attr'. /// /// @return the number of characters it takes on the screen. -int msg_outtrans(char_u *str) +int msg_outtrans(char *str) { - return msg_outtrans_attr(str, 0); + return msg_outtrans_attr((char_u *)str, 0); } int msg_outtrans_attr(const char_u *str, int attr) @@ -1654,7 +1654,7 @@ int msg_outtrans_special(const char_u *strstart, bool from, int maxlen) // single-byte character or illegal byte text = (char *)transchar_byte((uint8_t)text[0]); } - const int len = vim_strsize((char_u *)text); + const int len = vim_strsize((char *)text); if (maxlen > 0 && retval + len >= maxlen) { break; } @@ -2025,7 +2025,7 @@ void msg_puts_attr(const char *const s, const int attr) void msg_puts_attr_len(const char *const str, const ptrdiff_t len, int attr) FUNC_ATTR_NONNULL_ALL { - assert(len < 0 || memchr(str, 0, len) == NULL); + assert(len < 0 || memchr(str, 0, (size_t)len) == NULL); // If redirection is on, also write to the redirection file. redir_write(str, len); @@ -2074,7 +2074,7 @@ void msg_puts_attr_len(const char *const str, const ptrdiff_t len, int attr) } } if (!msg_use_printf() || (headless_mode && default_grid.chars)) { - msg_puts_display((const char_u *)str, len, attr, false); + msg_puts_display((const char_u *)str, (int)len, attr, false); } need_fileinfo = false; @@ -2094,7 +2094,7 @@ void msg_printf_attr(const int attr, const char *const fmt, ...) va_list ap; va_start(ap, fmt); - const size_t len = vim_vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); + const size_t len = (size_t)vim_vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); va_end(ap); msg_scroll = true; @@ -2336,7 +2336,7 @@ bool message_filtered(char_u *msg) /// including horizontal separator int msg_scrollsize(void) { - return msg_scrolled + p_ch + 1; + return msg_scrolled + (int)p_ch + 1; } bool msg_use_msgsep(void) @@ -2364,7 +2364,7 @@ void msg_scroll_up(bool may_throttle) } else { grid_del_lines(&msg_grid, 0, 1, msg_grid.rows, 0, msg_grid.cols); memmove(msg_grid.dirty_col, msg_grid.dirty_col + 1, - (msg_grid.rows - 1) * sizeof(*msg_grid.dirty_col)); + (size_t)(msg_grid.rows - 1) * sizeof(*msg_grid.dirty_col)); msg_grid.dirty_col[msg_grid.rows - 1] = 0; } } else { @@ -2438,7 +2438,7 @@ void msg_reset_scroll(void) msg_grid.throttled = false; // TODO(bfredl): risk for extra flicker i e with // "nvim -o has_swap also_has_swap" - msg_grid_set_pos(Rows - p_ch, false); + msg_grid_set_pos(Rows - (int)p_ch, false); clear_cmdline = true; if (msg_grid.chars) { // non-displayed part of msg_grid is considered invalid. @@ -2509,11 +2509,11 @@ static void store_sb_text(char_u **sb_str, char_u *s, int attr, int *sb_col, int } if (s > *sb_str) { - mp = xmalloc((sizeof(msgchunk_T) + (s - *sb_str))); - mp->sb_eol = finish; + mp = xmalloc((sizeof(msgchunk_T) + (size_t)(s - *sb_str))); + mp->sb_eol = (char)finish; mp->sb_msg_col = *sb_col; mp->sb_attr = attr; - memcpy(mp->sb_text, *sb_str, s - *sb_str); + memcpy(mp->sb_text, *sb_str, (size_t)(s - *sb_str)); mp->sb_text[s - *sb_str] = NUL; if (last_msgchunk == NULL) { @@ -2691,7 +2691,7 @@ static void msg_puts_printf(const char *str, const ptrdiff_t maxlen) if (*s == '\n' && !info_message) { *p++ = '\r'; } - memcpy(p, s, len); + memcpy(p, s, (size_t)len); *(p + len) = '\0'; if (info_message) { mch_msg(buf); @@ -3027,7 +3027,7 @@ void msg_moremsg(int full) if (full) { grid_puts(&msg_grid_adj, (char_u *) _(" SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "), - Rows - 1, vim_strsize(s), attr); + Rows - 1, vim_strsize((char *)s), attr); } } @@ -3264,10 +3264,10 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen) ga_concat_len(capture_ga, str, len); } if (redir_reg) { - write_reg_contents(redir_reg, s, len, true); + write_reg_contents(redir_reg, s, (ssize_t)len, true); } if (redir_vname) { - var_redir_str((char *)s, maxlen); + var_redir_str((char *)s, (int)maxlen); } // Write and adjust the current column. @@ -3376,7 +3376,8 @@ int verbose_open(void) /// Give a warning message (for searching). /// Use 'w' highlighting and may repeat the message after redrawing -void give_warning(char_u *message, bool hl) FUNC_ATTR_NONNULL_ARG(1) +void give_warning(char *message, bool hl) + FUNC_ATTR_NONNULL_ARG(1) { // Don't do this for ":silent". if (msg_silent != 0) { @@ -3386,7 +3387,7 @@ void give_warning(char_u *message, bool hl) FUNC_ATTR_NONNULL_ARG(1) // Don't want a hit-enter prompt here. no_wait_return++; - set_vim_var_string(VV_WARNINGMSG, (char *)message, -1); + set_vim_var_string(VV_WARNINGMSG, message, -1); XFREE_CLEAR(keep_msg); if (hl) { keep_msg_attr = HL_ATTR(HLF_W); @@ -3399,7 +3400,7 @@ void give_warning(char_u *message, bool hl) FUNC_ATTR_NONNULL_ARG(1) } if (msg_attr((const char *)message, keep_msg_attr) && msg_scrolled == 0) { - set_keep_msg((char *)message, keep_msg_attr); + set_keep_msg(message, keep_msg_attr); } msg_didout = false; // Overwrite this message. msg_nowait = true; // Don't wait for this message. @@ -3411,7 +3412,7 @@ void give_warning(char_u *message, bool hl) FUNC_ATTR_NONNULL_ARG(1) void give_warning2(char_u *const message, char_u *const a1, bool hl) { vim_snprintf((char *)IObuff, IOSIZE, (char *)message, a1); - give_warning(IObuff, hl); + give_warning((char *)IObuff, hl); } /// Advance msg cursor to column "col". @@ -3615,10 +3616,10 @@ static char_u *console_dialog_alloc(const char_u *message, char_u *buttons, bool // Now allocate space for the strings xfree(confirm_msg); - confirm_msg = xmalloc(len); + confirm_msg = xmalloc((size_t)len); *confirm_msg = NUL; - return xmalloc(lenhotkey); + return xmalloc((size_t)lenhotkey); } /// Format the dialog string, and display it at the bottom of diff --git a/src/nvim/move.c b/src/nvim/move.c index cc811fca18..99ca5060cd 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -802,7 +802,7 @@ void curs_columns(win_T *wp, int may_scroll) // column char *const sbr = (char *)get_showbreak_value(wp); if (*sbr && *get_cursor_pos_ptr() == NUL - && wp->w_wcol == vim_strsize((char_u *)sbr)) { + && wp->w_wcol == vim_strsize(sbr)) { wp->w_wcol = 0; } } diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 5ed1a61b54..9637fe85e2 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -3287,7 +3287,7 @@ static bool nv_screengo(oparg_T *oap, int dir, long dist) validate_virtcol(); colnr_T virtcol = curwin->w_virtcol; if (virtcol > (colnr_T)width1 && *get_showbreak_value(curwin) != NUL) { - virtcol -= vim_strsize(get_showbreak_value(curwin)); + virtcol -= vim_strsize((char *)get_showbreak_value(curwin)); } int c = utf_ptr2char((char *)get_cursor_pos_ptr()); diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 20bbc5b440..fcff2517ab 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -3847,7 +3847,7 @@ void ex_display(exarg_T *eap) n -= 2; } for (p = (char_u *)yb->y_array[j]; - *p != NUL && (n -= ptr2cells(p)) >= 0; p++) { // -V1019 + *p != NUL && (n -= ptr2cells((char *)p)) >= 0; p++) { // -V1019 clen = utfc_ptr2len((char *)p); msg_outtrans_len(p, clen); p += clen - 1; @@ -3925,7 +3925,7 @@ static void dis_msg(const char_u *p, bool skip_esc) n = Columns - 6; while (*p != NUL && !(*p == ESC && skip_esc && *(p + 1) == NUL) - && (n -= ptr2cells(p)) >= 0) { + && (n -= ptr2cells((char *)p)) >= 0) { if ((l = utfc_ptr2len((char *)p)) > 1) { msg_outtrans_len(p, l); p += l; diff --git a/src/nvim/option.c b/src/nvim/option.c index f870f07e15..09a597f7e2 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -621,7 +621,7 @@ static void set_option_default(int opt_idx, int opt_flags) // freeing and allocating the value. if (options[opt_idx].indir != PV_NONE) { set_string_option_direct(NULL, opt_idx, - options[opt_idx].def_val, opt_flags, 0); + (char *)options[opt_idx].def_val, opt_flags, 0); } else { if ((opt_flags & OPT_FREE) && (flags & P_ALLOCED)) { free_string_option(*(char_u **)(varp)); @@ -944,7 +944,7 @@ void ex_set(exarg_T *eap) if (eap->forceit) { flags |= OPT_ONECOLUMN; } - (void)do_set((char_u *)eap->arg, flags); + (void)do_set(eap->arg, flags); } /// Parse 'arg' for option settings. @@ -962,7 +962,7 @@ void ex_set(exarg_T *eap) /// @param arg option string (may be written to!) /// /// @return FAIL if an error is detected, OK otherwise -int do_set(char_u *arg, int opt_flags) +int do_set(char *arg, int opt_flags) { int opt_idx; char *errmsg; @@ -990,7 +990,7 @@ int do_set(char_u *arg, int opt_flags) while (*arg != NUL) { // loop to process all options errmsg = NULL; - startarg = arg; // remember for error message + startarg = (char_u *)arg; // remember for error message if (STRNCMP(arg, "all", 3) == 0 && !isalpha(arg[3]) && !(opt_flags & OPT_MODELINE)) { @@ -1043,7 +1043,7 @@ int do_set(char_u *arg, int opt_flags) } len++; if (opt_idx == -1) { - key = find_key_option(arg + 1, true); + key = find_key_option((char_u *)arg + 1, true); } } else { len = 0; @@ -1057,12 +1057,12 @@ int do_set(char_u *arg, int opt_flags) } opt_idx = findoption_len((const char *)arg, (size_t)len); if (opt_idx == -1) { - key = find_key_option(arg, false); + key = find_key_option((char_u *)arg, false); } } // remember character after option name - afterchar = arg[len]; + afterchar = (uint8_t)arg[len]; // skip white space, allow ":set ai ?" while (ascii_iswhite(arg[len])) { @@ -1084,7 +1084,7 @@ int do_set(char_u *arg, int opt_flags) len++; } } - nextchar = arg[len]; + nextchar = (uint8_t)arg[len]; if (opt_idx == -1 && key == 0) { // found a mismatch: skip errmsg = N_("E518: Unknown option"); @@ -1282,14 +1282,14 @@ int do_set(char_u *arg, int opt_flags) || *arg == '^' || (*arg != NUL && (!arg[1] || ascii_iswhite(arg[1])) && !ascii_isdigit(*arg)))) { - value = string_to_key(arg); + value = string_to_key((char_u *)arg); if (value == 0 && (long *)varp != &p_wcm) { errmsg = e_invarg; goto skip; } } else if (*arg == '-' || ascii_isdigit(*arg)) { // Allow negative, octal and hex numbers. - vim_str2nr(arg, NULL, &i, STR2NR_ALL, &value, NULL, 0, true); + vim_str2nr((char_u *)arg, NULL, &i, STR2NR_ALL, &value, NULL, 0, true); if (i == 0 || (arg[i] != NUL && !ascii_iswhite(arg[i]))) { errmsg = N_("E521: Number required after ="); goto skip; @@ -1391,8 +1391,8 @@ int do_set(char_u *arg, int opt_flags) if (varp == (char_u *)&p_kp && (*arg == NUL || *arg == ' ')) { STRCPY(errbuf, ":help"); - save_arg = arg; - arg = (char_u *)errbuf; + save_arg = (char_u *)arg; + arg = errbuf; } /* * Convert 'backspace' number to string, for @@ -1435,7 +1435,7 @@ int do_set(char_u *arg, int opt_flags) else if (varp == (char_u *)&p_ww && ascii_isdigit(*arg)) { *errbuf = NUL; - i = getdigits_int(&arg, true, 0); + i = getdigits_int((char_u **)&arg, true, 0); if (i & 1) { STRLCAT(errbuf, "b,", sizeof(errbuf)); } @@ -1451,8 +1451,8 @@ int do_set(char_u *arg, int opt_flags) if (i & 16) { STRLCAT(errbuf, "[,],", sizeof(errbuf)); } - save_arg = arg; - arg = (char_u *)errbuf; + save_arg = (char_u *)arg; + arg = errbuf; } /* * Remove '>' before 'dir' and 'bdir', for @@ -1498,14 +1498,14 @@ int do_set(char_u *arg, int opt_flags) ) { arg++; // remove backslash } - i = utfc_ptr2len((char *)arg); + i = utfc_ptr2len(arg); if (i > 1) { // copy multibyte char memmove(s, arg, (size_t)i); arg += i; s += i; } else { - *s++ = *arg++; + *s++ = (uint8_t)(*arg++); } } *s = NUL; @@ -1622,7 +1622,7 @@ int do_set(char_u *arg, int opt_flags) } if (save_arg != NULL) { // number for 'whichwrap' - arg = save_arg; + arg = (char *)save_arg; } new_value_alloced = true; } @@ -1710,7 +1710,7 @@ skip: arg++; } } - arg = (char_u *)skipwhite((char *)arg); + arg = skipwhite(arg); if (*arg != '=') { break; } @@ -1720,12 +1720,12 @@ skip: if (errmsg != NULL) { STRLCPY(IObuff, _(errmsg), IOSIZE); i = (int)STRLEN(IObuff) + 2; - if (i + (arg - startarg) < IOSIZE) { + if (i + ((char_u *)arg - startarg) < IOSIZE) { // append the argument with the error STRCAT(IObuff, ": "); - assert(arg >= startarg); - memmove(IObuff + i, startarg, (size_t)(arg - startarg)); - IObuff[i + (arg - startarg)] = NUL; + assert((char_u *)arg >= startarg); + memmove(IObuff + i, startarg, (size_t)((char_u *)arg - startarg)); + IObuff[i + ((char_u *)arg - startarg)] = NUL; } // make sure all characters are printable trans_characters(IObuff, IOSIZE); @@ -1737,7 +1737,7 @@ skip: return FAIL; } - arg = (char_u *)skipwhite((char *)arg); + arg = skipwhite(arg); } theend: @@ -2181,11 +2181,11 @@ static int shada_idx = -1; /// "set_sid". /// /// @param opt_flags OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL -void set_string_option_direct(const char *name, int opt_idx, const char_u *val, int opt_flags, +void set_string_option_direct(const char *name, int opt_idx, const char *val, int opt_flags, int set_sid) { - char_u *s; - char_u **varp; + char *s; + char **varp; int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0; int idx = opt_idx; @@ -2204,18 +2204,17 @@ void set_string_option_direct(const char *name, int opt_idx, const char_u *val, assert((void *)options[idx].var != (void *)&p_shada); - s = vim_strsave(val); + s = xstrdup(val); { - varp = (char_u **)get_varp_scope(&(options[idx]), - both ? OPT_LOCAL : opt_flags); + varp = (char **)get_varp_scope(&(options[idx]), both ? OPT_LOCAL : opt_flags); if ((opt_flags & OPT_FREE) && (options[idx].flags & P_ALLOCED)) { - free_string_option(*varp); + free_string_option((char_u *)(*varp)); } *varp = s; // For buffer/window local option may also set the global value. if (both) { - set_string_option_global(idx, varp); + set_string_option_global(idx, (char_u **)varp); } options[idx].flags |= P_ALLOCED; @@ -2223,8 +2222,8 @@ void set_string_option_direct(const char *name, int opt_idx, const char_u *val, /* When setting both values of a global option with a local value, * make the local value empty, so that the global value is used. */ if (((int)options[idx].indir & PV_BOTH) && both) { - free_string_option(*varp); - *varp = empty_option; + free_string_option((char_u *)(*varp)); + *varp = (char *)empty_option; } if (set_sid != SID_NONE) { sctx_T script_ctx; @@ -2596,6 +2595,8 @@ ambw_end: // only encoding=utf-8 allowed if (STRCMP(p_enc, "utf-8") != 0) { errmsg = e_unsupportedoption; + } else { + spell_reload(); } } } @@ -2812,7 +2813,7 @@ ambw_end: } } else if (gvarp == &p_sbr) { // 'showbreak' for (s = *varp; *s;) { - if (ptr2cells(s) != 1) { + if (ptr2cells((char *)s) != 1) { errmsg = N_("E595: 'showbreak' contains unprintable or wide character"); } MB_PTR_ADV(s); @@ -2832,7 +2833,7 @@ ambw_end: int flagval = (varp == &p_titlestring) ? STL_IN_TITLE : STL_IN_ICON; // NULL => statusline syntax - if (vim_strchr((char *)(*varp), '%') && check_stl_option(*varp) == NULL) { + if (vim_strchr((char *)(*varp), '%') && check_stl_option((char *)(*varp)) == NULL) { stl_syntax |= flagval; } else { stl_syntax &= ~flagval; @@ -2941,14 +2942,14 @@ ambw_end: s++; } wid = getdigits_int(&s, true, 0); - if (wid && *s == '(' && (errmsg = check_stl_option(p_ruf)) == NULL) { + if (wid && *s == '(' && (errmsg = check_stl_option((char *)p_ruf)) == NULL) { ru_wid = wid; } else { - errmsg = check_stl_option(p_ruf); + errmsg = check_stl_option((char *)p_ruf); } } else if (varp == &p_ruf || s[0] != '%' || s[1] != '!') { // check 'statusline', 'winbar' or 'tabline' only if it doesn't start with "%!" - errmsg = check_stl_option(s); + errmsg = check_stl_option((char *)s); } if (varp == &p_ruf && errmsg == NULL) { comp_col(); @@ -3025,6 +3026,7 @@ ambw_end: } else if (varp == &p_pt) { // 'pastetoggle': translate key codes like in a mapping if (*p_pt) { + p = NULL; (void)replace_termcodes((char *)p_pt, STRLEN(p_pt), (char **)&p, REPTERM_FROM_PART | REPTERM_DO_LT, NULL, @@ -3783,7 +3785,7 @@ static char *set_chars_option(win_T *wp, char_u **varp, bool set) /// Check validity of options with the 'statusline' format. /// Return an untranslated error message or NULL. -char *check_stl_option(char_u *s) +char *check_stl_option(char *s) { int groupdepth = 0; static char errbuf[80]; @@ -5322,7 +5324,7 @@ static void showoptions(int all, int opt_flags) len = 1; // a toggle option fits always } else { option_value2string(p, opt_flags); - len = (int)STRLEN(p->fullname) + vim_strsize(NameBuff) + 1; + len = (int)STRLEN(p->fullname) + vim_strsize((char *)NameBuff) + 1; } if ((len <= INC - GAP && run == 1) || (len > INC - GAP && run == 2)) { @@ -5435,7 +5437,7 @@ static void showoneopt(vimoption_T *p, int opt_flags) msg_putchar('='); // put value string in NameBuff option_value2string(p, opt_flags); - msg_outtrans(NameBuff); + msg_outtrans((char *)NameBuff); } silent_mode = save_silent; @@ -5628,7 +5630,7 @@ static int put_setstring(FILE *fd, char *cmd, char *name, char_u **valuep, uint6 // replace home directory in the whole option value into "buf" buf = xmalloc(size); - home_replace(NULL, *valuep, buf, size, false); + home_replace(NULL, (char *)(*valuep), (char *)buf, size, false); // If the option value is longer than MAXPATHL, we need to append // each comma separated part of the option separately, so that it @@ -7039,7 +7041,7 @@ static void option_value2string(vimoption_T *opp, int opt_flags) if (varp == NULL) { // Just in case. NameBuff[0] = NUL; } else if (opp->flags & P_EXPAND) { - home_replace(NULL, varp, NameBuff, MAXPATHL, false); + home_replace(NULL, (char *)varp, (char *)NameBuff, MAXPATHL, false); // Translate 'pastetoggle' into special key names. } else if ((char_u **)opp->var == &p_pt) { str2specialbuf((const char *)p_pt, (char *)NameBuff, MAXPATHL); @@ -7960,11 +7962,7 @@ void set_fileformat(int eol_style, int opt_flags) // p is NULL if "eol_style" is EOL_UNKNOWN. if (p != NULL) { - set_string_option_direct("ff", - -1, - (char_u *)p, - OPT_FREE | opt_flags, - 0); + set_string_option_direct("ff", -1, p, OPT_FREE | opt_flags, 0); } // This may cause the buffer to become (un)modified. diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 4bc003bc7f..3a213605dc 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -1033,7 +1033,7 @@ char *vim_getenv(const char *name) /// a list of them. /// /// @return length of the string put into dst, does not include NUL byte. -size_t home_replace(const buf_T *const buf, const char_u *src, char_u *const dst, size_t dstlen, +size_t home_replace(const buf_T *const buf, const char *src, char *const dst, size_t dstlen, const bool one) FUNC_ATTR_NONNULL_ARG(3) { @@ -1085,9 +1085,9 @@ size_t home_replace(const buf_T *const buf, const char_u *src, char_u *const dst } if (!one) { - src = (char_u *)skipwhite((char *)src); + src = skipwhite((char *)src); } - char *dst_p = (char *)dst; + char *dst_p = dst; while (*src && dstlen > 0) { // Here we are at the beginning of a file name. // First, check to see if the beginning of the file name matches @@ -1123,11 +1123,11 @@ size_t home_replace(const buf_T *const buf, const char_u *src, char_u *const dst // if (!one) skip to separator: space or comma. while (*src && (one || (*src != ',' && *src != ' ')) && --dstlen > 0) { - *dst_p++ = (char)(*src++); + *dst_p++ = *src++; } // Skip separator. while ((*src == ' ' || *src == ',') && --dstlen > 0) { - *dst_p++ = (char)(*src++); + *dst_p++ = *src++; } } // If (dstlen == 0) out of space, what to do??? @@ -1137,7 +1137,7 @@ size_t home_replace(const buf_T *const buf, const char_u *src, char_u *const dst if (must_free) { xfree(homedir_env_mod); } - return (size_t)(dst_p - (char *)dst); + return (size_t)(dst_p - dst); } /// Like home_replace, store the replaced string in allocated memory. @@ -1149,9 +1149,9 @@ char_u *home_replace_save(buf_T *buf, char_u *src) FUNC_ATTR_NONNULL_RET if (src != NULL) { // just in case len += STRLEN(src); } - char_u *dst = xmalloc(len); - home_replace(buf, src, dst, len, true); - return dst; + char *dst = xmalloc(len); + home_replace(buf, (char *)src, dst, len, true); + return (char_u *)dst; } /// Function given to ExpandGeneric() to obtain an environment variable name. diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index d331bd21a2..9283ea2e42 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -854,9 +854,9 @@ static int do_os_system(char **argv, const char *input, size_t len, char **outpu // Failed, probably 'shell' is not executable. if (!silent) { msg_puts(_("\nshell failed to start: ")); - msg_outtrans((char_u *)os_strerror(status)); + msg_outtrans((char *)os_strerror(status)); msg_puts(": "); - msg_outtrans((char_u *)prog); + msg_outtrans(prog); msg_putchar('\n'); } multiqueue_free(events); diff --git a/src/nvim/path.c b/src/nvim/path.c index 9859ca7daa..f5c662ca88 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -52,27 +52,27 @@ /// @param checkname When both files don't exist, only compare their names. /// @param expandenv Whether to expand environment variables in file names. /// @return Enum of type FileComparison. @see FileComparison. -FileComparison path_full_compare(char_u *const s1, char_u *const s2, const bool checkname, +FileComparison path_full_compare(char *const s1, char *const s2, const bool checkname, const bool expandenv) { assert(s1 && s2); - char_u exp1[MAXPATHL]; - char_u full1[MAXPATHL]; - char_u full2[MAXPATHL]; + char exp1[MAXPATHL]; + char full1[MAXPATHL]; + char full2[MAXPATHL]; FileID file_id_1, file_id_2; if (expandenv) { - expand_env(s1, exp1, MAXPATHL); + expand_env((char_u *)s1, (char_u *)exp1, MAXPATHL); } else { STRLCPY(exp1, s1, MAXPATHL); } - bool id_ok_1 = os_fileid((char *)exp1, &file_id_1); - bool id_ok_2 = os_fileid((char *)s2, &file_id_2); + bool id_ok_1 = os_fileid(exp1, &file_id_1); + bool id_ok_2 = os_fileid(s2, &file_id_2); if (!id_ok_1 && !id_ok_2) { // If os_fileid() doesn't work, may compare the names. if (checkname) { - vim_FullName((char *)exp1, (char *)full1, MAXPATHL, false); - vim_FullName((char *)s2, (char *)full2, MAXPATHL, false); + vim_FullName(exp1, full1, MAXPATHL, false); + vim_FullName(s2, full2, MAXPATHL, false); if (FNAMECMP(full1, full2) == 0) { return kEqualFileNames; } diff --git a/src/nvim/plines.c b/src/nvim/plines.c index 35f2512ee3..70bdbd8b1d 100644 --- a/src/nvim/plines.c +++ b/src/nvim/plines.c @@ -229,7 +229,7 @@ int win_chartabsize(win_T *wp, char_u *p, colnr_T col) if (*p == TAB && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) { return tabstop_padding(col, buf->b_p_ts, buf->b_p_vts_array); } else { - return ptr2cells(p); + return ptr2cells((char *)p); } } @@ -408,7 +408,7 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he // Set *headp to the size of what we add. added = 0; - char_u *const sbr = get_showbreak_value(wp); + char *const sbr = (char *)get_showbreak_value(wp); if ((*sbr != NUL || wp->w_p_bri) && wp->w_p_wrap && col != 0) { colnr_T sbrlen = 0; int numberwidth = win_col_off(wp); @@ -423,7 +423,7 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he col %= numberextra; } if (*sbr != NUL) { - sbrlen = (colnr_T)mb_charlen(sbr); + sbrlen = (colnr_T)mb_charlen((char_u *)sbr); if (col >= sbrlen) { col -= sbrlen; } @@ -494,7 +494,7 @@ static int win_nolbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp) wp->w_buffer->b_p_ts, wp->w_buffer->b_p_vts_array); } - n = ptr2cells(s); + n = ptr2cells((char *)s); // Add one cell for a double-width character in the last column of the // window, displayed with a ">". diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index db1054eb1f..ecaeca005d 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -66,19 +66,19 @@ static void pum_compute_size(void) for (int i = 0; i < pum_size; i++) { int w; if (pum_array[i].pum_text != NULL) { - w = vim_strsize(pum_array[i].pum_text); + w = vim_strsize((char *)pum_array[i].pum_text); if (pum_base_width < w) { pum_base_width = w; } } if (pum_array[i].pum_kind != NULL) { - w = vim_strsize(pum_array[i].pum_kind) + 1; + w = vim_strsize((char *)pum_array[i].pum_kind) + 1; if (pum_kind_width < w) { pum_kind_width = w; } } if (pum_array[i].pum_extra != NULL) { - w = vim_strsize(pum_array[i].pum_extra) + 1; + w = vim_strsize((char *)pum_array[i].pum_extra) + 1; if (pum_extra_width < w) { pum_extra_width = w; } @@ -504,7 +504,7 @@ void pum_redraw(void) if (s == NULL) { s = p; } - w = ptr2cells(p); + w = ptr2cells((char *)p); if ((*p == NUL) || (*p == TAB) || (totwidth + w > pum_width)) { // Display the text that fits or comes before a Tab. @@ -517,13 +517,13 @@ void pum_redraw(void) *p = saved; if (pum_rl) { - char_u *rt = reverse_text(st); - char_u *rt_start = rt; + char *rt = (char *)reverse_text(st); + char *rt_start = rt; int size = vim_strsize(rt); if (size > pum_width) { do { - size -= utf_ptr2cells((char *)rt); + size -= utf_ptr2cells(rt); MB_PTR_ADV(rt); } while (size > pum_width); @@ -535,7 +535,7 @@ void pum_redraw(void) size++; } } - grid_puts_len(&pum_grid, rt, (int)STRLEN(rt), row, + grid_puts_len(&pum_grid, (char_u *)rt, (int)STRLEN(rt), row, grid_col - size + 1, attr); xfree(rt_start); xfree(st); diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 868a68969c..22e72669ee 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -4343,7 +4343,7 @@ static char *make_get_fullcmd(const char *makecmd, const char *fname) } msg_start(); msg_puts(":!"); - msg_outtrans((char_u *)cmd); // show what we are doing + msg_outtrans(cmd); // show what we are doing return cmd; } @@ -5100,7 +5100,7 @@ void ex_cfile(exarg_T *eap) } } if (*eap->arg != NUL) { - set_string_option_direct("ef", -1, (char_u *)eap->arg, OPT_FREE, 0); + set_string_option_direct("ef", -1, eap->arg, OPT_FREE, 0); } char *enc = (*curbuf->b_p_menc != NUL) ? (char *)curbuf->b_p_menc : (char *)p_menc; @@ -5199,9 +5199,9 @@ static void vgr_display_fname(char *fname) msg_start(); char *p = (char *)msg_strtrunc((char_u *)fname, true); if (p == NULL) { - msg_outtrans((char_u *)fname); + msg_outtrans(fname); } else { - msg_outtrans((char_u *)p); + msg_outtrans(p); xfree(p); } msg_clr_eos(); @@ -5716,7 +5716,7 @@ static buf_T *load_dummy_buffer(char *fname, char *dirname_start, char *resultin aucmd_prepbuf(&aco, newbuf); // Need to set the filename for autocommands. - (void)setfname(curbuf, (char_u *)fname, NULL, false); + (void)setfname(curbuf, fname, NULL, false); // Create swap file now to avoid the ATTENTION message. check_need_swap(true); diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 98f8e30391..ea75900ded 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -4718,7 +4718,7 @@ static int status_match_len(expand_T *xp, char_u *s) while (*s != NUL) { s += skip_status_match_char(xp, s); - len += ptr2cells(s); + len += ptr2cells((char *)s); MB_PTR_ADV(s); } @@ -4856,7 +4856,7 @@ void win_redr_status_matches(expand_T *xp, int num_matches, char_u **matches, in } else { for (; *s != NUL; ++s) { s += skip_status_match_char(xp, s); - clen += ptr2cells(s); + clen += ptr2cells((char *)s); if ((l = utfc_ptr2len((char *)s)) > 1) { STRNCPY(buf + len, s, l); // NOLINT(runtime/printf) s += l - 1; @@ -5034,7 +5034,7 @@ static void win_redr_status(win_T *wp) grid_fill(&default_grid, row, row + 1, len + col, this_ru_col + col, fillchar, fillchar, attr); - if (get_keymap_str(wp, (char_u *)"<%s>", NameBuff, MAXPATHL) + if (get_keymap_str(wp, "<%s>", (char *)NameBuff, MAXPATHL) && this_ru_col - len > (int)(STRLEN(NameBuff) + 1)) { grid_puts(&default_grid, NameBuff, row, (int)(this_ru_col - STRLEN(NameBuff) - 1), attr); @@ -5079,7 +5079,7 @@ static void redraw_custom_statusline(win_T *wp) // When there is an error disable the statusline, otherwise the // display is messed up with errors and a redraw triggers the problem // again and again. - set_string_option_direct("statusline", -1, (char_u *)"", + set_string_option_direct("statusline", -1, "", OPT_FREE | (*wp->w_p_stl != NUL ? OPT_LOCAL : OPT_GLOBAL), SID_ERROR); } @@ -5109,7 +5109,7 @@ static void win_redr_winbar(win_T *wp) // When there is an error disable the winbar, otherwise the // display is messed up with errors and a redraw triggers the problem // again and again. - set_string_option_direct("winbar", -1, (char_u *)"", + set_string_option_direct("winbar", -1, "", OPT_FREE | (*wp->w_p_stl != NUL ? OPT_LOCAL : OPT_GLOBAL), SID_ERROR); } @@ -5218,9 +5218,9 @@ static bool vsep_connected(win_T *wp, WindowCorner corner) /// @param fmt format string containing one %s item /// @param buf buffer for the result /// @param len length of buffer -bool get_keymap_str(win_T *wp, char_u *fmt, char_u *buf, int len) +bool get_keymap_str(win_T *wp, char *fmt, char *buf, int len) { - char_u *p; + char *p; if (wp->w_buffer->b_p_iminsert != B_IMODE_LMAP) { return false; @@ -5229,24 +5229,24 @@ bool get_keymap_str(win_T *wp, char_u *fmt, char_u *buf, int len) { buf_T *old_curbuf = curbuf; win_T *old_curwin = curwin; - char_u *s; + char *s; curbuf = wp->w_buffer; curwin = wp; STRCPY(buf, "b:keymap_name"); // must be writable emsg_skip++; - s = p = (char_u *)eval_to_string((char *)buf, NULL, false); + s = p = eval_to_string(buf, NULL, false); emsg_skip--; curbuf = old_curbuf; curwin = old_curwin; if (p == NULL || *p == NUL) { if (wp->w_buffer->b_kmap_state & KEYMAP_LOADED) { - p = wp->w_buffer->b_p_keymap; + p = (char *)wp->w_buffer->b_p_keymap; } else { - p = (char_u *)"lang"; + p = "lang"; } } - if (vim_snprintf((char *)buf, len, (char *)fmt, p) > len - 1) { + if (vim_snprintf(buf, len, fmt, p) > len - 1) { buf[0] = NUL; } xfree(s); @@ -5268,9 +5268,9 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) int n; int len; int fillchar; - char_u buf[MAXPATHL]; + char buf[MAXPATHL]; char_u *stl; - char_u *p; + char *p; stl_hlrec_t *hltab; StlClickRecord *tabtab; int use_sandbox = false; @@ -5389,20 +5389,20 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) * might change the option value and free the memory. */ stl = vim_strsave(stl); width = - build_stl_str_hl(ewp, (char *)buf, sizeof(buf), (char *)stl, use_sandbox, + build_stl_str_hl(ewp, buf, sizeof(buf), (char *)stl, use_sandbox, fillchar, maxwidth, &hltab, &tabtab); xfree(stl); ewp->w_p_crb = p_crb_save; // Make all characters printable. - p = (char_u *)transstr((const char *)buf, true); + p = transstr(buf, true); len = STRLCPY(buf, p, sizeof(buf)); len = (size_t)len < sizeof(buf) ? len : (int)sizeof(buf) - 1; xfree(p); // fill up with "fillchar" while (width < maxwidth && len < (int)sizeof(buf) - 1) { - len += utf_char2bytes(fillchar, (char *)buf + len); + len += utf_char2bytes(fillchar, buf + len); width++; } buf[len] = NUL; @@ -5416,8 +5416,8 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) p = buf; for (n = 0; hltab[n].start != NULL; n++) { int textlen = (int)(hltab[n].start - p); - grid_puts_len(grid, p, textlen, row, col, curattr); - col += vim_strnsize(p, textlen); + grid_puts_len(grid, (char_u *)p, textlen, row, col, curattr); + col += vim_strnsize((char_u *)p, textlen); p = hltab[n].start; if (hltab[n].userhl == 0) { @@ -5431,7 +5431,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) } } // Make sure to use an empty string instead of p, if p is beyond buf + len. - grid_puts(grid, p >= buf + len ? (char_u *)"" : p, row, col, + grid_puts(grid, p >= buf + len ? (char_u *)"" : (char_u *)p, row, col, curattr); grid_puts_line_flush(false); @@ -5453,11 +5453,11 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) .type = kStlClickDisabled, }; for (n = 0; tabtab[n].start != NULL; n++) { - len += vim_strnsize(p, (int)(tabtab[n].start - (char *)p)); + len += vim_strnsize((char_u *)p, (int)(tabtab[n].start - p)); while (col < len) { click_defs[col++] = cur_click_def; } - p = (char_u *)tabtab[n].start; + p = (char *)tabtab[n].start; cur_click_def = tabtab[n].def; if ((wp != NULL) && !(cur_click_def.type == kStlClickDisabled || cur_click_def.type == kStlClickFuncRun)) { @@ -5980,13 +5980,13 @@ int showmode(void) length = (Rows - msg_row) * Columns - 3; } if (edit_submode_extra != NULL) { - length -= vim_strsize(edit_submode_extra); + length -= vim_strsize((char *)edit_submode_extra); } if (length > 0) { if (edit_submode_pre != NULL) { - length -= vim_strsize(edit_submode_pre); + length -= vim_strsize((char *)edit_submode_pre); } - if (length - vim_strsize(edit_submode) > 0) { + if (length - vim_strsize((char *)edit_submode) > 0) { if (edit_submode_pre != NULL) { msg_puts_attr((const char *)edit_submode_pre, attr); } @@ -6028,8 +6028,8 @@ int showmode(void) if (State & MODE_LANGMAP) { if (curwin->w_p_arab) { msg_puts_attr(_(" Arabic"), attr); - } else if (get_keymap_str(curwin, (char_u *)" (%s)", - NameBuff, MAXPATHL)) { + } else if (get_keymap_str(curwin, " (%s)", + (char *)NameBuff, MAXPATHL)) { msg_puts_attr((char *)NameBuff, attr); } } @@ -6211,8 +6211,7 @@ void draw_tabline(void) did_emsg = false; win_redr_custom(NULL, false, false); if (did_emsg) { - set_string_option_direct("tabline", -1, - (char_u *)"", OPT_FREE, SID_ERROR); + set_string_option_direct("tabline", -1, "", OPT_FREE, SID_ERROR); } did_emsg |= saved_did_emsg; } else { @@ -6289,10 +6288,10 @@ void draw_tabline(void) // Get buffer name in NameBuff[] get_trans_bufname(cwp->w_buffer); shorten_dir(NameBuff); - len = vim_strsize(NameBuff); + len = vim_strsize((char *)NameBuff); p = NameBuff; while (len > room) { - len -= ptr2cells(p); + len -= ptr2cells((char *)p); MB_PTR_ADV(p); } if (len > Columns - col - 1) { @@ -6395,7 +6394,7 @@ void get_trans_bufname(buf_T *buf) if (buf_spname(buf) != NULL) { STRLCPY(NameBuff, buf_spname(buf), MAXPATHL); } else { - home_replace(buf, (char_u *)buf->b_fname, NameBuff, MAXPATHL, true); + home_replace(buf, buf->b_fname, (char *)NameBuff, MAXPATHL, true); } trans_characters(NameBuff, MAXPATHL); } @@ -6521,8 +6520,7 @@ static void win_redr_ruler(win_T *wp, bool always) called_emsg = false; win_redr_custom(wp, false, true); if (called_emsg) { - set_string_option_direct("rulerformat", -1, (char_u *)"", - OPT_FREE, SID_ERROR); + set_string_option_direct("rulerformat", -1, "", OPT_FREE, SID_ERROR); } called_emsg |= save_called_emsg; return; @@ -6588,17 +6586,17 @@ static void win_redr_ruler(win_T *wp, bool always) } #define RULER_BUF_LEN 70 - char_u buffer[RULER_BUF_LEN]; + char buffer[RULER_BUF_LEN]; /* * Some sprintfs return the length, some return a pointer. * To avoid portability problems we use strlen() here. */ - vim_snprintf((char *)buffer, RULER_BUF_LEN, "%" PRId64 ",", + vim_snprintf(buffer, RULER_BUF_LEN, "%" PRId64 ",", (wp->w_buffer->b_ml.ml_flags & ML_EMPTY) ? (int64_t)0L : (int64_t)wp->w_cursor.lnum); size_t len = STRLEN(buffer); - col_print(buffer + len, RULER_BUF_LEN - len, + col_print((char_u *)buffer + len, RULER_BUF_LEN - len, empty_line ? 0 : (int)wp->w_cursor.col + 1, (int)virtcol + 1); @@ -6625,7 +6623,7 @@ static void win_redr_ruler(win_T *wp, bool always) if (this_ru_col + o < width) { // Need at least 3 chars left for get_rel_pos() + NUL. while (this_ru_col + o < width && RULER_BUF_LEN > i + 4) { - i += utf_char2bytes(fillchar, (char *)buffer + i); + i += utf_char2bytes(fillchar, buffer + i); o++; } get_rel_pos(wp, buffer + i, RULER_BUF_LEN - i); @@ -6646,8 +6644,8 @@ static void win_redr_ruler(win_T *wp, bool always) } // Truncate at window boundary. o = 0; - for (i = 0; buffer[i] != NUL; i += utfc_ptr2len((char *)buffer + i)) { - o += utf_ptr2cells((char *)buffer + i); + for (i = 0; buffer[i] != NUL; i += utfc_ptr2len(buffer + i)) { + o += utf_ptr2cells(buffer + i); if (this_ru_col + o > width) { buffer[i] = NUL; break; @@ -6655,7 +6653,7 @@ static void win_redr_ruler(win_T *wp, bool always) } ScreenGrid *grid = part_of_status ? &default_grid : &msg_grid_adj; - grid_puts(grid, buffer, row, this_ru_col + off, attr); + grid_puts(grid, (char_u *)buffer, row, this_ru_col + off, attr); grid_fill(grid, row, row + 1, this_ru_col + off + (int)STRLEN(buffer), off + width, fillchar, fillchar, attr); diff --git a/src/nvim/search.c b/src/nvim/search.c index 1e862f10ec..a5c18bd03a 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -910,8 +910,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, lnum = 1; } if (!shortmess(SHM_SEARCH) && (options & SEARCH_MSG)) { - give_warning((char_u *)_(dir == BACKWARD - ? top_bot_msg : bot_top_msg), true); + give_warning(_(dir == BACKWARD ? top_bot_msg : bot_top_msg), true); } if (extra_arg != NULL) { extra_arg->sa_wrapped = true; @@ -1261,7 +1260,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count, memset(msgbuf + pat_len, ' ', r - msgbuf); } } - msg_outtrans(msgbuf); + msg_outtrans((char *)msgbuf); msg_clr_eos(); msg_check(); @@ -1452,7 +1451,7 @@ int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char_u *pat) if (p_ws) { pos->lnum = buf->b_ml.ml_line_count; if (!shortmess(SHM_SEARCH)) { - give_warning((char_u *)_(top_bot_msg), true); + give_warning(_(top_bot_msg), true); } } else { pos->lnum = 1; @@ -1462,7 +1461,7 @@ int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char_u *pat) if (p_ws) { pos->lnum = 1; if (!shortmess(SHM_SEARCH)) { - give_warning((char_u *)_(bot_top_msg), true); + give_warning(_(bot_top_msg), true); } } else { pos->lnum = 1; @@ -4515,7 +4514,7 @@ static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool sh // keep the message even after redraw, but don't put in history msg_hist_off = true; msg_ext_set_kind("search_count"); - give_warning(msgbuf, false); + give_warning((char *)msgbuf, false); msg_hist_off = false; } } @@ -5414,8 +5413,8 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo if (i == max_path_depth) { break; } - if (path_full_compare(new_fname, files[i].name, - true, true) & kEqualFiles) { + if (path_full_compare((char *)new_fname, (char *)files[i].name, true, + true) & kEqualFiles) { if (type != CHECK_PATH && action == ACTION_SHOW_ALL && files[i].matched) { msg_putchar('\n'); // cursor below last one */ diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 5410740d9e..32a0f3902d 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -3977,7 +3977,7 @@ static bool shada_removable(const char *name) for (p = (char *)p_shada; *p;) { (void)copy_option_part((char_u **)&p, (char_u *)part, ARRAY_SIZE(part), ", "); if (part[0] == 'r') { - home_replace(NULL, (char_u *)(part + 1), (char_u *)NameBuff, MAXPATHL, true); + home_replace(NULL, part + 1, (char *)NameBuff, MAXPATHL, true); size_t n = STRLEN(NameBuff); if (mb_strnicmp((char_u *)NameBuff, (char_u *)new_name, n) == 0) { retval = true; diff --git a/src/nvim/sign.c b/src/nvim/sign.c index 0e4d092025..940cd1d274 100644 --- a/src/nvim/sign.c +++ b/src/nvim/sign.c @@ -1630,12 +1630,12 @@ static void sign_list_defined(sign_T *sp) smsg("sign %s", sp->sn_name); if (sp->sn_icon != NULL) { msg_puts(" icon="); - msg_outtrans(sp->sn_icon); + msg_outtrans((char *)sp->sn_icon); msg_puts(_(" (not supported)")); } if (sp->sn_text != NULL) { msg_puts(" text="); - msg_outtrans(sp->sn_text); + msg_outtrans((char *)sp->sn_text); } if (sp->sn_line_hl > 0) { msg_puts(" linehl="); diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 8f84204481..e4805f3c4a 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -1576,7 +1576,7 @@ size_t spell_move_to(win_T *wp, int dir, bool allwords, bool curline, hlf_T *att lnum = wp->w_buffer->b_ml.ml_line_count; wrapped = true; if (!shortmess(SHM_SEARCH)) { - give_warning((char_u *)_(top_bot_msg), true); + give_warning(_(top_bot_msg), true); } } capcol = -1; @@ -1591,7 +1591,7 @@ size_t spell_move_to(win_T *wp, int dir, bool allwords, bool curline, hlf_T *att lnum = 1; wrapped = true; if (!shortmess(SHM_SEARCH)) { - give_warning((char_u *)_(bot_top_msg), true); + give_warning(_(bot_top_msg), true); } } @@ -2115,7 +2115,7 @@ char *did_set_spelllang(win_T *wp) // Check if we loaded this language before. for (slang = first_lang; slang != NULL; slang = slang->sl_next) { - if (path_full_compare(lang, slang->sl_fname, false, true) + if (path_full_compare((char *)lang, (char *)slang->sl_fname, false, true) == kEqualFiles) { break; } @@ -2164,7 +2164,7 @@ char *did_set_spelllang(win_T *wp) // Loop over the languages, there can be several files for "lang". for (slang = first_lang; slang != NULL; slang = slang->sl_next) { if (filename - ? path_full_compare(lang, slang->sl_fname, false, true) == kEqualFiles + ? path_full_compare((char *)lang, (char *)slang->sl_fname, false, true) == kEqualFiles : STRICMP(lang, slang->sl_name) == 0) { region_mask = REGION_ALL; if (!filename && region != NULL) { @@ -2222,7 +2222,7 @@ char *did_set_spelllang(win_T *wp) for (c = 0; c < ga.ga_len; ++c) { p = LANGP_ENTRY(ga, c)->lp_slang->sl_fname; if (p != NULL - && path_full_compare(spf_name, p, false, true) == kEqualFiles) { + && path_full_compare((char *)spf_name, (char *)p, false, true) == kEqualFiles) { break; } } @@ -2233,7 +2233,7 @@ char *did_set_spelllang(win_T *wp) // Check if it was loaded already. for (slang = first_lang; slang != NULL; slang = slang->sl_next) { - if (path_full_compare(spf_name, slang->sl_fname, false, true) + if (path_full_compare((char *)spf_name, (char *)slang->sl_fname, false, true) == kEqualFiles) { break; } @@ -3663,6 +3663,12 @@ static void suggest_try_change(suginfo_T *su) p = su->su_badptr + su->su_badlen; (void)spell_casefold(curwin, p, (int)STRLEN(p), fword + n, MAXWLEN - n); + // Make sure the resulting text is not longer than the original text. + n = (int)STRLEN(su->su_badptr); + if (n < MAXWLEN) { + fword[n] = NUL; + } + for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) { lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi); @@ -4375,7 +4381,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so #endif ++depth; sp = &stack[depth]; - ++sp->ts_fidx; + if (fword[sp->ts_fidx] != NUL) { + sp->ts_fidx++; + } tword[sp->ts_twordlen++] = c; sp->ts_arridx = idxs[arridx]; if (newscore == SCORE_SUBST) { @@ -4391,7 +4399,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so sp->ts_fcharstart = sp->ts_fidx - 1; sp->ts_isdiff = (newscore != 0) ? DIFF_YES : DIFF_NONE; - } else if (sp->ts_isdiff == DIFF_INSERT) { + } else if (sp->ts_isdiff == DIFF_INSERT && sp->ts_fidx > 0) { // When inserting trail bytes don't advance in the // bad word. sp->ts_fidx--; diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 2b6bb098d1..07f3d39886 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -1826,7 +1826,7 @@ static void spell_reload_one(char_u *fname, bool added_word) bool didit = false; for (slang = first_lang; slang != NULL; slang = slang->sl_next) { - if (path_full_compare(fname, slang->sl_fname, false, true) == kEqualFiles) { + if (path_full_compare((char *)fname, (char *)slang->sl_fname, false, true) == kEqualFiles) { slang_clear(slang); if (spell_load_file(fname, NULL, slang, false) == NULL) { // reloading failed, clear the language @@ -4903,7 +4903,7 @@ static void spell_make_sugfile(spellinfo_T *spin, char_u *wfname) // of the code for the soundfolding stuff. // It might have been done already by spell_reload_one(). for (slang = first_lang; slang != NULL; slang = slang->sl_next) { - if (path_full_compare(wfname, slang->sl_fname, false, true) + if (path_full_compare((char *)wfname, (char *)slang->sl_fname, false, true) == kEqualFiles) { break; } @@ -5598,9 +5598,8 @@ void spell_add_word(char_u *word, int len, SpellAddType what, int idx, bool undo if (fseek(fd, fpos, SEEK_SET) == 0) { fputc('#', fd); if (undo) { - home_replace(NULL, fname, NameBuff, MAXPATHL, TRUE); - smsg(_("Word '%.*s' removed from %s"), - len, word, NameBuff); + home_replace(NULL, (char *)fname, (char *)NameBuff, MAXPATHL, true); + smsg(_("Word '%.*s' removed from %s"), len, word, NameBuff); } } if (fseek(fd, fpos_next, SEEK_SET) != 0) { @@ -5648,7 +5647,7 @@ void spell_add_word(char_u *word, int len, SpellAddType what, int idx, bool undo } fclose(fd); - home_replace(NULL, fname, NameBuff, MAXPATHL, TRUE); + home_replace(NULL, (char *)fname, (char *)NameBuff, MAXPATHL, true); smsg(_("Word '%.*s' added to %s"), len, word, NameBuff); } } diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 0d43458b5b..9615423765 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -3171,9 +3171,9 @@ static void syn_cmd_iskeyword(exarg_T *eap, int syncing) msg_puts("\n"); if (curwin->w_s->b_syn_isk != empty_option) { msg_puts("syntax iskeyword "); - msg_outtrans(curwin->w_s->b_syn_isk); + msg_outtrans((char *)curwin->w_s->b_syn_isk); } else { - msg_outtrans((char_u *)_("syntax iskeyword not set")); + msg_outtrans(_("syntax iskeyword not set")); } } else { if (STRNICMP(arg, "clear", 5) == 0) { @@ -3382,7 +3382,7 @@ static void syn_cmd_clear(exarg_T *eap, int syncing) XFREE_CLEAR(SYN_CLSTR(curwin->w_s)[scl_id].scl_list); } } else { - id = syn_name2id_len(arg, (int)(arg_end - arg)); + id = syn_name2id_len((char *)arg, (int)(arg_end - arg)); if (id == 0) { semsg(_(e_nogroup), arg); break; @@ -3553,7 +3553,7 @@ static void syn_cmd_list(exarg_T *eap, int syncing) syn_list_cluster(id - SYNID_CLUSTER); } } else { - int id = syn_name2id_len(arg, (int)(arg_end - arg)); + int id = syn_name2id_len((char *)arg, (int)(arg_end - arg)); if (id == 0) { semsg(_(e_nogroup), arg); } else { @@ -3690,8 +3690,8 @@ static void syn_list_one(const int id, const bool syncing, const bool link_only) } msg_putchar(' '); if (spp->sp_sync_idx >= 0) { - msg_outtrans(highlight_group_name(SYN_ITEMS(curwin->w_s) - [spp->sp_sync_idx].sp_syn.id - 1)); + msg_outtrans((char *)highlight_group_name(SYN_ITEMS(curwin->w_s) + [spp->sp_sync_idx].sp_syn.id - 1)); } else { msg_puts("NONE"); } @@ -3704,7 +3704,7 @@ static void syn_list_one(const int id, const bool syncing, const bool link_only) (void)syn_list_header(did_header, 0, id, true); msg_puts_attr("links to", attr); msg_putchar(' '); - msg_outtrans(highlight_group_name(highlight_link_id(id - 1) - 1)); + msg_outtrans((char *)highlight_group_name(highlight_link_id(id - 1) - 1)); } } @@ -3729,7 +3729,7 @@ static void syn_list_cluster(int id) // slight hack: roughly duplicate the guts of syn_list_header() msg_putchar('\n'); - msg_outtrans(SYN_CLSTR(curwin->w_s)[id].scl_name); + msg_outtrans((char *)SYN_CLSTR(curwin->w_s)[id].scl_name); if (msg_col >= endcol) { // output at least one space endcol = msg_col + 1; @@ -3766,9 +3766,9 @@ static void put_id_list(const char *const name, const int16_t *const list, const int scl_id = *p - SYNID_CLUSTER; msg_putchar('@'); - msg_outtrans(SYN_CLSTR(curwin->w_s)[scl_id].scl_name); + msg_outtrans((char *)SYN_CLSTR(curwin->w_s)[scl_id].scl_name); } else { - msg_outtrans(highlight_group_name(*p - 1)); + msg_outtrans((char *)highlight_group_name(*p - 1)); } if (p[1]) { msg_putchar(','); @@ -3788,9 +3788,9 @@ static void put_pattern(const char *const s, const int c, const synpat_T *const msg_puts_attr("matchgroup", attr); msg_putchar('='); if (last_matchgroup == 0) { - msg_outtrans((char_u *)"NONE"); + msg_outtrans("NONE"); } else { - msg_outtrans(highlight_group_name(last_matchgroup - 1)); + msg_outtrans((char *)highlight_group_name(last_matchgroup - 1)); } msg_putchar(' '); } @@ -3807,7 +3807,7 @@ static void put_pattern(const char *const s, const int c, const synpat_T *const } } msg_putchar(sepchars[i]); - msg_outtrans(spp->sp_pattern); + msg_outtrans((char *)spp->sp_pattern); msg_putchar(sepchars[i]); // output any pattern options @@ -3917,7 +3917,7 @@ static bool syn_list_keywords(const int id, const hashtab_T *const ht, bool did_ prev_skipempty = (kp->flags & HL_SKIPEMPTY); } } - msg_outtrans(kp->keyword); + msg_outtrans((char *)kp->keyword); } } } @@ -6038,7 +6038,7 @@ static void syntime_report(void) msg_puts(profile_msg(p->average)); msg_puts(" "); msg_advance(50); - msg_outtrans(highlight_group_name(p->id - 1)); + msg_outtrans((char *)highlight_group_name(p->id - 1)); msg_puts(" "); msg_advance(69); diff --git a/src/nvim/tag.c b/src/nvim/tag.c index b9f6494459..796a2fa5f3 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -624,7 +624,7 @@ bool do_tag(char_u *tag, int type, int count, int forceit, int verbose) } msg_scroll = true; // Don't overwrite this message. } else { - give_warning(IObuff, ic); + give_warning((char *)IObuff, ic); } if (ic && !msg_scrolled && msg_silent == 0) { ui_flush(); @@ -784,7 +784,7 @@ static void print_tag_list(int new_tag, int use_tagstack, int num_matches, char_ // print all other extra fields attr = HL_ATTR(HLF_CM); while (*p && *p != '\r' && *p != '\n') { - if (msg_col + ptr2cells(p) >= Columns) { + if (msg_col + ptr2cells((char *)p) >= Columns) { msg_putchar('\n'); if (got_int) { break; @@ -830,7 +830,7 @@ static void print_tag_list(int new_tag, int use_tagstack, int num_matches, char_ } while (p != command_end) { - if (msg_col + (*p == TAB ? 1 : ptr2cells(p)) > Columns) { + if (msg_col + (*p == TAB ? 1 : ptr2cells((char *)p)) > Columns) { msg_putchar('\n'); } if (got_int) { @@ -1050,7 +1050,7 @@ void do_tags(exarg_T *eap) tagstack[i].cur_match + 1, tagstack[i].tagname, tagstack[i].fmark.mark.lnum); - msg_outtrans(IObuff); + msg_outtrans((char *)IObuff); msg_outtrans_attr(name, tagstack[i].fmark.fnum == curbuf->b_fnum ? HL_ATTR(HLF_D) : 0); xfree(name); @@ -3032,8 +3032,7 @@ static int test_for_current(char_u *fname, char_u *fname_end, char_u *tag_fname, *fname_end = NUL; } fullname = expand_tag_fname(fname, tag_fname, true); - retval = (path_full_compare(fullname, buf_ffname, true, true) - & kEqualFiles); + retval = (path_full_compare((char *)fullname, (char *)buf_ffname, true, true) & kEqualFiles); xfree(fullname); *fname_end = (char_u)c; } diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index 887c8e1593..8d1746be2f 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -305,7 +305,7 @@ func Test_getcompletion() call assert_equal([], l) let l = getcompletion('', 'dir') - call assert_true(index(l, expand('sautest/')) >= 0) + call assert_true(index(l, 'sautest/') >= 0) let l = getcompletion('NoMatch', 'dir') call assert_equal([], l) @@ -415,7 +415,7 @@ func Test_getcompletion() " Command line completion tests let l = getcompletion('cd ', 'cmdline') - call assert_true(index(l, expand('sautest/')) >= 0) + call assert_true(index(l, 'sautest/') >= 0) let l = getcompletion('cd NoMatch', 'cmdline') call assert_equal([], l) let l = getcompletion('let v:n', 'cmdline') @@ -539,7 +539,7 @@ func Test_expand_star_star() call mkdir('a/b', 'p') call writefile(['asdfasdf'], 'a/b/fileXname') call feedkeys(":find **/fileXname\<Tab>\<CR>", 'xt') - call assert_equal('find '.expand('a/b/fileXname'), getreg(':')) + call assert_equal('find a/b/fileXname', getreg(':')) bwipe! call delete('a', 'rf') endfunc diff --git a/src/nvim/testdir/test_ins_complete.vim b/src/nvim/testdir/test_ins_complete.vim index 90b57323af..c8104c6b73 100644 --- a/src/nvim/testdir/test_ins_complete.vim +++ b/src/nvim/testdir/test_ins_complete.vim @@ -287,6 +287,30 @@ func Test_omni_dash() set omnifunc= endfunc +func Test_omni_throw() + let g:CallCount = 0 + func Omni(findstart, base) + let g:CallCount += 1 + if a:findstart + throw "he he he" + endif + endfunc + set omnifunc=Omni + new + try + exe "normal ifoo\<C-x>\<C-o>" + call assert_false(v:true, 'command should have failed') + catch + call assert_exception('he he he') + call assert_equal(1, g:CallCount) + endtry + + bwipe! + delfunc Omni + unlet g:CallCount + set omnifunc= +endfunc + func Test_completefunc_args() let s:args = [] func! CompleteFunc(findstart, base) diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index e43db4d692..5826666cbb 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -1060,17 +1060,17 @@ func s:dir_stack_tests(cchar) let qf = g:Xgetlist() - call assert_equal(expand('dir1/a/habits2.txt'), bufname(qf[1].bufnr)) + call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr)) call assert_equal(1, qf[1].lnum) - call assert_equal(expand('dir1/a/b/habits3.txt'), bufname(qf[3].bufnr)) + call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr)) call assert_equal(2, qf[3].lnum) - call assert_equal(expand('dir1/a/habits2.txt'), bufname(qf[4].bufnr)) + call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr)) call assert_equal(7, qf[4].lnum) - call assert_equal(expand('dir1/c/habits4.txt'), bufname(qf[6].bufnr)) + call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr)) call assert_equal(3, qf[6].lnum) call assert_equal('habits1.txt', bufname(qf[9].bufnr)) call assert_equal(4, qf[9].lnum) - call assert_equal(expand('dir2/habits5.txt'), bufname(qf[11].bufnr)) + call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr)) call assert_equal(5, qf[11].lnum) let &efm=save_efm @@ -1300,7 +1300,7 @@ func Test_efm2() call assert_equal(8, len(l)) call assert_equal(89, l[4].lnum) call assert_equal(1, l[4].valid) - call assert_equal(expand('unittests/dbfacadeTest.py'), bufname(l[4].bufnr)) + call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr)) call assert_equal('W', l[4].type) " Test for %o @@ -2074,11 +2074,11 @@ func Test_two_windows() laddexpr 'one.txt:3:one one one' let loc_one = getloclist(one_id) - call assert_equal(expand('Xone/a/one.txt'), bufname(loc_one[1].bufnr)) + call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr)) call assert_equal(3, loc_one[1].lnum) let loc_two = getloclist(two_id) - call assert_equal(expand('Xtwo/a/two.txt'), bufname(loc_two[1].bufnr)) + call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr)) call assert_equal(5, loc_two[1].lnum) call win_gotoid(one_id) diff --git a/src/nvim/testdir/test_spell.vim b/src/nvim/testdir/test_spell.vim index ce21b8bdc9..215d4387d6 100644 --- a/src/nvim/testdir/test_spell.vim +++ b/src/nvim/testdir/test_spell.vim @@ -72,6 +72,16 @@ func Test_z_equal_on_invalid_utf8_word() bwipe! endfunc +func Test_z_equal_on_single_character() + " this was decrementing the index below zero + new + norm a0\ + norm zW + norm z= + + bwipe! +endfunc + " Test spellbadword() with argument func Test_spellbadword() set spell diff --git a/src/nvim/testdir/test_spell_utf8.vim b/src/nvim/testdir/test_spell_utf8.vim index 1d323df67e..3c07e0782b 100644 --- a/src/nvim/testdir/test_spell_utf8.vim +++ b/src/nvim/testdir/test_spell_utf8.vim @@ -576,7 +576,6 @@ endfunc "Compound words func Test_spell_compound() - throw 'skipped: TODO: ' call LoadAffAndDic(g:test_data_aff3, g:test_data_dic3) call RunGoodBad("foo m\u00EF foobar foofoobar barfoo barbarfoo", \ "bad: bar la foom\u00EF barm\u00EF m\u00EFfoo m\u00EFbar m\u00EFm\u00EF lala m\u00EFla lam\u00EF foola labar", @@ -624,14 +623,14 @@ endfunc " Test affix flags with two characters func Test_spell_affix() - throw 'skipped: TODO: ' + CheckNotMSWindows " FIXME: Why does this fail with MSVC? call LoadAffAndDic(g:test_data_aff5, g:test_data_dic5) call RunGoodBad("fooa1 fooa\u00E9 bar prebar barbork prebarbork startprebar start end startend startmiddleend nouend", \ "bad: foo fooa2 prabar probarbirk middle startmiddle middleend endstart startprobar startnouend", \ ["bar", "barbork", "end", "fooa1", "fooa\u00E9", "nouend", "prebar", "prebarbork", "start"], \ [ \ ["bad", ["bar", "end", "fooa1"]], - \ ["foo", ["fooa1", "fooa\u00E9", "bar"]], + \ ["foo", ["fooa1", "bar", "end"]], \ ["fooa2", ["fooa1", "fooa\u00E9", "bar"]], \ ["prabar", ["prebar", "bar", "bar bar"]], \ ["probarbirk", ["prebarbork"]], @@ -649,7 +648,7 @@ func Test_spell_affix() \ ["bar", "barbork", "end", "lead", "meea1", "meea\u00E9", "prebar", "prebarbork"], \ [ \ ["bad", ["bar", "end", "lead"]], - \ ["mee", ["meea1", "meea\u00E9", "bar"]], + \ ["mee", ["meea1", "bar", "end"]], \ ["meea2", ["meea1", "meea\u00E9", "lead"]], \ ["prabar", ["prebar", "bar", "leadbar"]], \ ["probarbirk", ["prebarbork"]], @@ -666,7 +665,7 @@ func Test_spell_affix() \ ["bar", "barmeat", "lead", "meea1", "meea\u00E9", "meezero", "prebar", "prebarmeat", "tail"], \ [ \ ["bad", ["bar", "lead", "tail"]], - \ ["mee", ["meea1", "meea\u00E9", "bar"]], + \ ["mee", ["meea1", "bar", "lead"]], \ ["meea2", ["meea1", "meea\u00E9", "lead"]], \ ["prabar", ["prebar", "bar", "leadbar"]], \ ["probarmaat", ["prebarmeat"]], @@ -700,7 +699,6 @@ endfunc " Affix flags func Test_spell_affix_flags() - throw 'skipped: TODO: ' call LoadAffAndDic(g:test_data_aff10, g:test_data_dic10) call RunGoodBad("drink drinkable drinkables drinktable drinkabletable", \ "bad: drinks drinkstable drinkablestable", @@ -761,11 +759,30 @@ func Test_spell_sal_and_addition() set spl=Xtest_ca.utf-8.spl call assert_equal("elequint", FirstSpellWord()) call assert_equal("elekwint", SecondSpellWord()) + + set spellfile= + set spl& endfunc func Test_spellfile_value() set spellfile=Xdir/Xtest.utf-8.add set spellfile=Xdir/Xtest.utf-8.add,Xtest_other.add + set spellfile= +endfunc + +func Test_no_crash_with_weird_text() + new + let lines =<< trim END + r<sfile> + + + + + END + call setline(1, lines) + exe "%norm \<C-v>ez=>\<C-v>wzG" + + bwipe! endfunc " Invalid bytes may cause trouble when creating the word list. @@ -773,5 +790,18 @@ func Test_check_for_valid_word() call assert_fails("spellgood! 0\xac", 'E1280:') endfunc +" This was going over the end of the word +func Test_word_index() + new + norm R0 + spellgood! fl0 + sil norm z= + + bwipe! + " clear the word list + set enc=utf-8 + call delete('Xtmpfile') +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 684a9cf99e..078cb6a210 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -1468,8 +1468,7 @@ void u_read_undo(char *name, const char_u *hash, const char_u *orig_name FUNC_AT if (name == NULL) { verbose_enter(); } - give_warning((char_u *) - _("File contents changed, cannot use undo info"), true); + give_warning(_("File contents changed, cannot use undo info"), true); if (name == NULL) { verbose_leave(); } diff --git a/src/nvim/version.c b/src/nvim/version.c index 1c8fdce1eb..a70778fdd9 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -2020,7 +2020,7 @@ void ex_version(exarg_T *eap) /// @param wrap static void version_msg_wrap(char *s, int wrap) { - int len = vim_strsize((char_u *)s) + (wrap ? 2 : 0); + int len = vim_strsize(s) + (wrap ? 2 : 0); if (!got_int && (len < Columns) @@ -2071,7 +2071,7 @@ void list_in_columns(char_u **items, int size, int current) // Find the length of the longest item, use that + 1 as the column width. int i; for (i = 0; size < 0 ? items[i] != NULL : i < size; i++) { - int l = vim_strsize(items[i]) + (i == current ? 2 : 0); + int l = vim_strsize((char *)items[i]) + (i == current ? 2 : 0); if (l > width) { width = l; @@ -2294,7 +2294,7 @@ static void do_intro_line(long row, char_u *mesg, int attr) int clen; // Center the message horizontally. - col = vim_strsize(mesg); + col = vim_strsize((char *)mesg); col = (Columns - col) / 2; @@ -2309,7 +2309,7 @@ static void do_intro_line(long row, char_u *mesg, int attr) for (l = 0; p[l] != NUL && (l == 0 || (p[l] != '<' && p[l - 1] != '>')); l++) { - clen += ptr2cells(p + l); + clen += ptr2cells((char *)p + l); l += utfc_ptr2len((char *)p + l) - 1; } assert(row <= INT_MAX && col <= INT_MAX); diff --git a/test/functional/api/autocmd_spec.lua b/test/functional/api/autocmd_spec.lua index 5dfcd09438..a923f5df0e 100644 --- a/test/functional/api/autocmd_spec.lua +++ b/test/functional/api/autocmd_spec.lua @@ -686,6 +686,26 @@ describe('autocmd api', function() eq(true, meths.get_var("autocmd_executed")) end) + it("can trigger multiple patterns", function() + meths.set_var("autocmd_executed", 0) + + meths.create_autocmd("BufReadPost", { + pattern = "*", + command = "let g:autocmd_executed += 1", + }) + + meths.exec_autocmds("BufReadPost", { pattern = { "*.lua", "*.vim" } }) + eq(2, meths.get_var("autocmd_executed")) + + meths.create_autocmd("BufReadPre", { + pattern = { "bar", "foo" }, + command = "let g:autocmd_executed += 10", + }) + + meths.exec_autocmds("BufReadPre", { pattern = { "foo", "bar", "baz", "frederick" }}) + eq(22, meths.get_var("autocmd_executed")) + end) + it("can pass the buffer", function() meths.set_var("buffer_executed", -1) eq(-1, meths.get_var("buffer_executed")) @@ -742,7 +762,7 @@ describe('autocmd api', function() meths.exec_autocmds("CursorHoldI", { buffer = 1 }) eq('none', meths.get_var("filename_executed")) - meths.exec_autocmds("CursorHoldI", { buffer = tonumber(meths.get_current_buf()) }) + meths.exec_autocmds("CursorHoldI", { buffer = meths.get_current_buf() }) eq('__init__.py', meths.get_var("filename_executed")) -- Reset filename diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index ef6798dea3..c05345dd4c 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -3520,6 +3520,9 @@ describe('API', function() pcall_err(meths.parse_cmd, 'Fubar!', {})) eq('Error while parsing command line: E481: No range allowed', pcall_err(meths.parse_cmd, '4,6Fubar', {})) + command('command! Foobar echo foo') + eq('Error while parsing command line: E464: Ambiguous use of user-defined command', + pcall_err(meths.parse_cmd, 'F', {})) end) end) describe('nvim_cmd', function() diff --git a/test/functional/autocmd/termxx_spec.lua b/test/functional/autocmd/termxx_spec.lua index 1e8f981437..c418a12faf 100644 --- a/test/functional/autocmd/termxx_spec.lua +++ b/test/functional/autocmd/termxx_spec.lua @@ -1,8 +1,8 @@ local luv = require('luv') local helpers = require('test.functional.helpers')(after_each) -local clear, command, nvim, nvim_dir = - helpers.clear, helpers.command, helpers.nvim, helpers.nvim_dir +local clear, command, nvim, testprg = + helpers.clear, helpers.command, helpers.nvim, helpers.testprg local eval, eq, neq, retry = helpers.eval, helpers.eq, helpers.neq, helpers.retry local ok = helpers.ok @@ -12,7 +12,7 @@ local iswin = helpers.iswin describe('autocmd TermClose', function() before_each(function() clear() - nvim('set_option', 'shell', nvim_dir .. '/shell-test') + nvim('set_option', 'shell', testprg('shell-test')) command('set shellcmdflag=EXE shellredir= shellpipe= shellquote= shellxquote=') end) diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua index 461a69f357..a6763ba3c7 100644 --- a/test/functional/core/job_spec.lua +++ b/test/functional/core/job_spec.lua @@ -1,9 +1,9 @@ local helpers = require('test.functional.helpers')(after_each) local clear, eq, eval, exc_exec, feed_command, feed, insert, neq, next_msg, nvim, - nvim_dir, ok, source, write_file, mkdir, rmdir = helpers.clear, + testprg, ok, source, write_file, mkdir, rmdir = helpers.clear, helpers.eq, helpers.eval, helpers.exc_exec, helpers.feed_command, helpers.feed, helpers.insert, helpers.neq, helpers.next_msg, helpers.nvim, - helpers.nvim_dir, helpers.ok, helpers.source, + helpers.testprg, helpers.ok, helpers.source, helpers.write_file, helpers.mkdir, helpers.rmdir local assert_alive = helpers.assert_alive local command = helpers.command @@ -1043,8 +1043,7 @@ describe('jobs', function() return a:data endfunction ]]) - local ext = iswin() and '.exe' or '' - insert(nvim_dir..'/tty-test'..ext) -- Full path to tty-test. + insert(testprg('tty-test')) nvim('command', 'let g:job_opts.pty = 1') nvim('command', 'let exec = [expand("<cfile>:p")]') nvim('command', "let j = jobstart(exec, g:job_opts)") diff --git a/test/functional/ex_cmds/ls_spec.lua b/test/functional/ex_cmds/ls_spec.lua index 9853084c47..2583d80269 100644 --- a/test/functional/ex_cmds/ls_spec.lua +++ b/test/functional/ex_cmds/ls_spec.lua @@ -5,7 +5,7 @@ local eq = helpers.eq local eval = helpers.eval local feed = helpers.feed local nvim = helpers.nvim -local nvim_dir = helpers.nvim_dir +local testprg = helpers.testprg local retry = helpers.retry describe(':ls', function() @@ -14,7 +14,7 @@ describe(':ls', function() end) it('R, F for :terminal buffers', function() - nvim('set_option', 'shell', string.format('"%s" INTERACT', nvim_dir..'/shell-test')) + nvim('set_option', 'shell', string.format('"%s" INTERACT', testprg('shell-test'))) command('edit foo') command('set hidden') diff --git a/test/functional/ex_cmds/make_spec.lua b/test/functional/ex_cmds/make_spec.lua index 3b4d22ab38..bf585ee44c 100644 --- a/test/functional/ex_cmds/make_spec.lua +++ b/test/functional/ex_cmds/make_spec.lua @@ -4,7 +4,7 @@ local eval = helpers.eval local has_powershell = helpers.has_powershell local matches = helpers.matches local nvim = helpers.nvim -local nvim_dir = helpers.nvim_dir +local testprg = helpers.testprg describe(':make', function() clear() @@ -22,7 +22,7 @@ describe(':make', function() end) it('captures stderr & non zero exit code #14349', function () - nvim('set_option', 'makeprg', nvim_dir..'/shell-test foo') + nvim('set_option', 'makeprg', testprg('shell-test')..' foo') local out = eval('execute("make")') -- Make program exit code correctly captured matches('\nshell returned 3', out) @@ -31,7 +31,7 @@ describe(':make', function() end) it('captures stderr & zero exit code #14349', function () - nvim('set_option', 'makeprg', nvim_dir..'/shell-test') + nvim('set_option', 'makeprg', testprg('shell-test')) local out = eval('execute("make")') -- Ensure there are no "shell returned X" messages between -- command and last line (indicating zero exit) diff --git a/test/functional/fixtures/CMakeLists.txt b/test/functional/fixtures/CMakeLists.txt index 6010fcaf1e..a5410c2f8c 100644 --- a/test/functional/fixtures/CMakeLists.txt +++ b/test/functional/fixtures/CMakeLists.txt @@ -2,6 +2,8 @@ add_executable(tty-test EXCLUDE_FROM_ALL tty-test.c) target_link_libraries(tty-test ${LIBUV_LIBRARIES}) add_executable(shell-test EXCLUDE_FROM_ALL shell-test.c) +# Fake pwsh (powershell) for testing make_filter_cmd(). #16271 +add_executable(pwsh-test EXCLUDE_FROM_ALL shell-test.c) add_executable(printargs-test EXCLUDE_FROM_ALL printargs-test.c) add_executable(printenv-test EXCLUDE_FROM_ALL printenv-test.c) if(MINGW) diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index d31d337b63..0c616e73fb 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -515,9 +515,17 @@ function module.has_powershell() return module.eval('executable("'..(iswin() and 'powershell' or 'pwsh')..'")') == 1 end -function module.set_shell_powershell() - local shell = iswin() and 'powershell' or 'pwsh' - assert(module.has_powershell()) +--- Sets Nvim shell to powershell. +--- +--- @param fake (boolean) If true, a fake will be used if powershell is not +--- found on the system. +--- @returns true if powershell was found on the system, else false. +function module.set_shell_powershell(fake) + local found = module.has_powershell() + if not fake then + assert(found) + end + local shell = found and (iswin() and 'powershell' or 'pwsh') or module.testprg('pwsh-test') local set_encoding = '[Console]::InputEncoding=[Console]::OutputEncoding=[System.Text.Encoding]::UTF8;' local cmd = set_encoding..'Remove-Item -Force '..table.concat(iswin() and {'alias:cat', 'alias:echo', 'alias:sleep'} @@ -525,10 +533,11 @@ function module.set_shell_powershell() module.exec([[ let &shell = ']]..shell..[[' set shellquote= shellxquote= - let &shellpipe = '2>&1 | Out-File -Encoding UTF8 %s; exit $LastExitCode' - let &shellredir = '2>&1 | Out-File -Encoding UTF8 %s; exit $LastExitCode' let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command ]]..cmd..[[' + let &shellpipe = '2>&1 | Out-File -Encoding UTF8 %s; exit $LastExitCode' + let &shellredir = '-RedirectStandardOutput %s -NoNewWindow -Wait' ]]) + return found end function module.nvim(method, ...) @@ -784,11 +793,21 @@ function module.get_pathsep() return iswin() and '\\' or '/' end +--- Gets the filesystem root dir, namely "/" or "C:/". function module.pathroot() local pathsep = package.config:sub(1,1) return iswin() and (module.nvim_dir:sub(1,2)..pathsep) or '/' end +--- Gets the full `…/build/bin/{name}` path of a test program produced by +--- `test/functional/fixtures/CMakeLists.txt`. +--- +--- @param name (string) Name of the test program. +function module.testprg(name) + local ext = module.iswin() and '.exe' or '' + return ('%s/%s%s'):format(module.nvim_dir, name, ext) +end + -- Returns a valid, platform-independent Nvim listen address. -- Useful for communicating with child instances. function module.new_pipename() diff --git a/test/functional/lua/filetype_spec.lua b/test/functional/lua/filetype_spec.lua index d0cef53c4b..be57b2db31 100644 --- a/test/functional/lua/filetype_spec.lua +++ b/test/functional/lua/filetype_spec.lua @@ -3,6 +3,7 @@ local exec_lua = helpers.exec_lua local eq = helpers.eq local clear = helpers.clear local pathroot = helpers.pathroot +local command = helpers.command local root = pathroot() @@ -23,7 +24,7 @@ describe('vim.filetype', function() rs = 'radicalscript', }, }) - return vim.filetype.match('main.rs') + return vim.filetype.match({ filename = 'main.rs' }) ]]) end) @@ -37,7 +38,7 @@ describe('vim.filetype', function() ['main.rs'] = 'somethingelse', }, }) - return vim.filetype.match('main.rs') + return vim.filetype.match({ filename = 'main.rs' }) ]]) end) @@ -48,7 +49,7 @@ describe('vim.filetype', function() ['s_O_m_e_F_i_l_e'] = 'nim', }, }) - return vim.filetype.match('s_O_m_e_F_i_l_e') + return vim.filetype.match({ filename = 's_O_m_e_F_i_l_e' }) ]]) eq('dosini', exec_lua([[ @@ -59,7 +60,7 @@ describe('vim.filetype', function() [root .. '/.config/fun/config'] = 'dosini', }, }) - return vim.filetype.match(root .. '/.config/fun/config') + return vim.filetype.match({ filename = root .. '/.config/fun/config' }) ]], root)) end) @@ -72,11 +73,13 @@ describe('vim.filetype', function() ['~/blog/.*%.txt'] = 'markdown', } }) - return vim.filetype.match('~/blog/why_neovim_is_awesome.txt') + return vim.filetype.match({ filename = '~/blog/why_neovim_is_awesome.txt' }) ]], root)) end) it('works with functions', function() + command('new') + command('file relevant_to_me') eq('foss', exec_lua [[ vim.filetype.add({ pattern = { @@ -87,7 +90,7 @@ describe('vim.filetype', function() end, } }) - return vim.filetype.match('relevant_to_me') + return vim.filetype.match({ buf = 0 }) ]]) end) end) diff --git a/test/functional/lua/ui_spec.lua b/test/functional/lua/ui_spec.lua index 2371939204..3fcb2dec8d 100644 --- a/test/functional/lua/ui_spec.lua +++ b/test/functional/lua/ui_spec.lua @@ -2,6 +2,8 @@ local helpers = require('test.functional.helpers')(after_each) local eq = helpers.eq local exec_lua = helpers.exec_lua local clear = helpers.clear +local feed = helpers.feed +local eval = helpers.eval describe('vim.ui', function() before_each(function() @@ -67,5 +69,19 @@ describe('vim.ui', function() eq('Inputted text', result[1]) eq('Input: ', result[2]) end) + + it('can input text on nil opt', function() + feed(':lua vim.ui.input(nil, function(input) result = input end)<cr>') + eq('', eval('v:errmsg')) + feed('Inputted text<cr>') + eq('Inputted text', exec_lua('return result')) + end) + + it('can input text on {} opt', function() + feed(':lua vim.ui.input({}, function(input) result = input end)<cr>') + eq('', eval('v:errmsg')) + feed('abcdefg<cr>') + eq('abcdefg', exec_lua('return result')) + end) end) end) diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index 646c5ac8ca..883e0e373b 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -1428,6 +1428,13 @@ describe('lua stdlib', function() vim.wo[1000].cole = 0 ]] eq(0, funcs.luaeval "vim.wo[1000].cole") + + -- Can handle global-local values + exec_lua [[vim.o.scrolloff = 100]] + exec_lua [[vim.wo.scrolloff = 200]] + eq(200, funcs.luaeval "vim.wo.scrolloff") + exec_lua [[vim.wo.scrolloff = -1]] + eq(100, funcs.luaeval "vim.wo.scrolloff") end) describe('vim.opt', function() diff --git a/test/functional/terminal/cursor_spec.lua b/test/functional/terminal/cursor_spec.lua index 6e06304acd..2d1c790d2f 100644 --- a/test/functional/terminal/cursor_spec.lua +++ b/test/functional/terminal/cursor_spec.lua @@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local thelpers = require('test.functional.terminal.helpers') local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim -local nvim_dir, command = helpers.nvim_dir, helpers.command +local testprg, command = helpers.testprg, helpers.command local nvim_prog = helpers.nvim_prog local eq, eval = helpers.eq, helpers.eval local matches = helpers.matches @@ -150,7 +150,7 @@ describe('cursor with customized highlighting', function() [3] = {bold = true}, }) screen:attach({rgb=false}) - command('call termopen(["'..nvim_dir..'/tty-test"])') + command('call termopen(["'..testprg('tty-test')..'"])') feed_command('startinsert') end) diff --git a/test/functional/terminal/edit_spec.lua b/test/functional/terminal/edit_spec.lua index e7025d6739..aeb4b7cc2e 100644 --- a/test/functional/terminal/edit_spec.lua +++ b/test/functional/terminal/edit_spec.lua @@ -3,7 +3,7 @@ local screen = require('test.functional.ui.screen') local curbufmeths = helpers.curbufmeths local curwinmeths = helpers.curwinmeths -local nvim_dir = helpers.nvim_dir +local testprg = helpers.testprg local command = helpers.command local funcs = helpers.funcs local meths = helpers.meths @@ -21,7 +21,7 @@ describe(':edit term://*', function() before_each(function() clear() - meths.set_option('shell', nvim_dir .. '/shell-test') + meths.set_option('shell', testprg('shell-test')) meths.set_option('shellcmdflag', 'EXE') end) diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua index b4f29a586a..23b69319f0 100644 --- a/test/functional/terminal/ex_terminal_spec.lua +++ b/test/functional/terminal/ex_terminal_spec.lua @@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local assert_alive = helpers.assert_alive local clear, poke_eventloop, nvim = helpers.clear, helpers.poke_eventloop, helpers.nvim -local nvim_dir, source, eq = helpers.nvim_dir, helpers.source, helpers.eq +local testprg, source, eq = helpers.testprg, helpers.source, helpers.eq local feed = helpers.feed local feed_command, eval = helpers.feed_command, helpers.eval local funcs = helpers.funcs @@ -28,7 +28,7 @@ describe(':terminal', function() echomsg "msg3" ]]) -- Invoke a command that emits frequent terminal activity. - feed([[:terminal "]]..nvim_dir..[[/shell-test" REP 9999 !terminal_output!<cr>]]) + feed([[:terminal "]]..testprg('shell-test')..[[" REP 9999 !terminal_output!<cr>]]) feed([[<C-\><C-N>]]) poke_eventloop() -- Wait for some terminal activity. @@ -131,7 +131,7 @@ describe(':terminal (with fake shell)', function() screen = Screen.new(50, 4) screen:attach({rgb=false}) -- shell-test.c is a fake shell that prints its arguments and exits. - nvim('set_option', 'shell', nvim_dir..'/shell-test') + nvim('set_option', 'shell', testprg('shell-test')) nvim('set_option', 'shellcmdflag', 'EXE') end) @@ -167,7 +167,7 @@ describe(':terminal (with fake shell)', function() it("with no argument, but 'shell' has arguments, acts like termopen()", function() if helpers.pending_win32(pending) then return end - nvim('set_option', 'shell', nvim_dir..'/shell-test -t jeff') + nvim('set_option', 'shell', testprg('shell-test')..' -t jeff') terminal_with_fake_shell() screen:expect([[ ^jeff $ | @@ -191,7 +191,7 @@ describe(':terminal (with fake shell)', function() it("executes a given command through the shell, when 'shell' has arguments", function() if helpers.pending_win32(pending) then return end - nvim('set_option', 'shell', nvim_dir..'/shell-test -t jeff') + nvim('set_option', 'shell', testprg('shell-test')..' -t jeff') command('set shellxquote=') -- win: avoid extra quotes terminal_with_fake_shell('echo hi') screen:expect([[ diff --git a/test/functional/terminal/helpers.lua b/test/functional/terminal/helpers.lua index 51ecae663a..bcfd3559e6 100644 --- a/test/functional/terminal/helpers.lua +++ b/test/functional/terminal/helpers.lua @@ -3,7 +3,7 @@ -- operate on the _host_ session, _not_ the child session. local helpers = require('test.functional.helpers')(nil) local Screen = require('test.functional.ui.screen') -local nvim_dir = helpers.nvim_dir +local testprg = helpers.testprg local feed_command, nvim = helpers.feed_command, helpers.nvim local function feed_data(data) @@ -37,7 +37,7 @@ local function clear_attrs() feed_termcode('[0;10m') end local function enable_mouse() feed_termcode('[?1002h') end local function disable_mouse() feed_termcode('[?1002l') end -local default_command = '["'..nvim_dir..'/tty-test'..'"]' +local default_command = '["'..testprg('tty-test')..'"]' local function screen_setup(extra_rows, command, cols, opts) extra_rows = extra_rows and extra_rows or 0 diff --git a/test/functional/terminal/highlight_spec.lua b/test/functional/terminal/highlight_spec.lua index 2a63971d48..1eb7223dce 100644 --- a/test/functional/terminal/highlight_spec.lua +++ b/test/functional/terminal/highlight_spec.lua @@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local thelpers = require('test.functional.terminal.helpers') local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim -local nvim_dir, command = helpers.nvim_dir, helpers.command +local testprg, command = helpers.testprg, helpers.command local nvim_prog_abs = helpers.nvim_prog_abs local eq, eval = helpers.eq, helpers.eval local funcs = helpers.funcs @@ -28,7 +28,7 @@ describe(':terminal highlight', function() [11] = {background = 11}, }) screen:attach({rgb=false}) - command('enew | call termopen(["'..nvim_dir..'/tty-test"])') + command(("enew | call termopen(['%s'])"):format(testprg('tty-test'))) feed('i') screen:expect([[ tty ready | @@ -173,7 +173,7 @@ describe(':terminal highlight forwarding', function() [4] = {{foreground = tonumber('0xff8000')}, {}}, }) screen:attach() - command('enew | call termopen(["'..nvim_dir..'/tty-test"])') + command(("enew | call termopen(['%s'])"):format(testprg('tty-test'))) feed('i') screen:expect([[ tty ready | @@ -225,7 +225,7 @@ describe(':terminal highlight with custom palette', function() }) screen:attach({rgb=true}) nvim('set_var', 'terminal_color_3', '#123456') - command('enew | call termopen(["'..nvim_dir..'/tty-test"])') + command(("enew | call termopen(['%s'])"):format(testprg('tty-test'))) feed('i') screen:expect([[ tty ready | diff --git a/test/functional/terminal/scrollback_spec.lua b/test/functional/terminal/scrollback_spec.lua index b1d3b502b2..b491cb2735 100644 --- a/test/functional/terminal/scrollback_spec.lua +++ b/test/functional/terminal/scrollback_spec.lua @@ -2,7 +2,7 @@ local Screen = require('test.functional.ui.screen') local helpers = require('test.functional.helpers')(after_each) local thelpers = require('test.functional.terminal.helpers') local clear, eq, curbuf = helpers.clear, helpers.eq, helpers.curbuf -local feed, nvim_dir, feed_command = helpers.feed, helpers.nvim_dir, helpers.feed_command +local feed, testprg, feed_command = helpers.feed, helpers.testprg, helpers.feed_command local iswin = helpers.iswin local eval = helpers.eval local command = helpers.command @@ -350,7 +350,7 @@ describe(':terminal prints more lines than the screen height and exits', functio clear() local screen = Screen.new(30, 7) screen:attach({rgb=false}) - feed_command('call termopen(["'..nvim_dir..'/tty-test", "10"]) | startinsert') + feed_command(("call termopen(['%s', '10']) | startinsert"):format(testprg('tty-test'))) poke_eventloop() screen:expect([[ line6 | @@ -382,7 +382,7 @@ describe("'scrollback' option", function() local function set_fake_shell() -- shell-test.c is a fake shell that prints its arguments and exits. - nvim('set_option', 'shell', nvim_dir..'/shell-test') + nvim('set_option', 'shell', testprg('shell-test')) nvim('set_option', 'shellcmdflag', 'EXE') end @@ -403,7 +403,7 @@ describe("'scrollback' option", function() end curbufmeths.set_option('scrollback', 0) - feed_data(nvim_dir..'/shell-test REP 31 line'..(iswin() and '\r' or '\n')) + feed_data(('%s REP 31 line%s'):format(testprg('shell-test'), iswin() and '\r' or '\n')) screen:expect{any='30: line '} retry(nil, nil, function() expect_lines(7) end) end) @@ -423,7 +423,7 @@ describe("'scrollback' option", function() -- Wait for prompt. screen:expect{any='%$'} - feed_data(nvim_dir.."/shell-test REP 31 line"..(iswin() and '\r' or '\n')) + feed_data(('%s REP 31 line%s'):format(testprg('shell-test'), iswin() and '\r' or '\n')) screen:expect{any='30: line '} retry(nil, nil, function() expect_lines(33, 2) end) @@ -436,7 +436,7 @@ describe("'scrollback' option", function() -- 'scrollback' option is synchronized with the internal sb_buffer. command('sleep 100m') - feed_data(nvim_dir.."/shell-test REP 41 line"..(iswin() and '\r' or '\n')) + feed_data(('%s REP 41 line%s'):format(testprg('shell-test'), iswin() and '\r' or '\n')) if iswin() then screen:expect{grid=[[ 37: line | diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua index 8c6cba4def..89704be820 100644 --- a/test/functional/terminal/tui_spec.lua +++ b/test/functional/terminal/tui_spec.lua @@ -14,7 +14,7 @@ local feed_command = helpers.feed_command local feed_data = thelpers.feed_data local clear = helpers.clear local command = helpers.command -local nvim_dir = helpers.nvim_dir +local testprg = helpers.testprg local retry = helpers.retry local nvim_prog = helpers.nvim_prog local nvim_set = helpers.nvim_set @@ -385,7 +385,7 @@ describe('TUI', function() return end feed_data(':set statusline=^^^^^^^\n') - feed_data(':terminal '..nvim_dir..'/tty-test\n') + feed_data(':terminal '..testprg('tty-test')..'\n') feed_data('i') screen:expect{grid=[[ tty ready | @@ -903,7 +903,7 @@ describe('TUI', function() feed_data(':set statusline=^^^^^^^\n') feed_data(':set termguicolors\n') - feed_data(':terminal '..nvim_dir..'/tty-test\n') + feed_data(':terminal '..testprg('tty-test')..'\n') -- Depending on platform the above might or might not fit in the cmdline -- so clear it for consistent behavior. feed_data(':\027') @@ -1130,7 +1130,7 @@ describe('TUI FocusGained/FocusLost', function() end) it('in terminal-mode', function() - feed_data(':set shell='..nvim_dir..'/shell-test\n') + feed_data(':set shell='..testprg('shell-test')..'\n') feed_data(':set noshowmode laststatus=0\n') feed_data(':terminal\n') diff --git a/test/functional/ui/hlstate_spec.lua b/test/functional/ui/hlstate_spec.lua index 925af11627..df7f34aa7f 100644 --- a/test/functional/ui/hlstate_spec.lua +++ b/test/functional/ui/hlstate_spec.lua @@ -5,7 +5,7 @@ local clear, insert = helpers.clear, helpers.insert local command = helpers.command local meths = helpers.meths local iswin = helpers.iswin -local nvim_dir = helpers.nvim_dir +local testprg = helpers.testprg local thelpers = require('test.functional.terminal.helpers') describe('ext_hlstate detailed highlights', function() @@ -191,7 +191,7 @@ describe('ext_hlstate detailed highlights', function() [6] = {{foreground = tonumber('0x40ffff'), fg_indexed=true}, {5, 1}}, [7] = {{}, {{hi_name = "MsgArea", ui_name = "MsgArea", kind = "ui"}}}, }) - command('enew | call termopen(["'..nvim_dir..'/tty-test"])') + command(("enew | call termopen(['%s'])"):format(testprg('tty-test'))) screen:expect([[ ^tty ready | {1: } | diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua index 98ed564966..4286446af7 100644 --- a/test/functional/ui/inccommand_spec.lua +++ b/test/functional/ui/inccommand_spec.lua @@ -17,7 +17,7 @@ local source = helpers.source local poke_eventloop = helpers.poke_eventloop local nvim = helpers.nvim local sleep = helpers.sleep -local nvim_dir = helpers.nvim_dir +local testprg = helpers.testprg local assert_alive = helpers.assert_alive local default_text = [[ @@ -2875,7 +2875,7 @@ it(':substitute with inccommand during :terminal activity', function() clear() command("set cmdwinheight=3") - feed([[:terminal "]]..nvim_dir..[[/shell-test" REP 5000 xxx<cr>]]) + feed(([[:terminal "%s" REP 5000 xxx<cr>]]):format(testprg('shell-test'))) command('file term') feed('G') -- Follow :terminal output. command('new') @@ -3008,3 +3008,16 @@ it('long :%s/ with inccommand does not collapse cmdline', function() AAAAAAA^ | ]]) end) + +it("with 'inccommand' typing :filter doesn't segfault or leak memory #19057", function() + clear() + common_setup(nil, 'nosplit') + feed(':filter s') + assert_alive() + feed(' ') + assert_alive() + feed('h') + assert_alive() + feed('i') + assert_alive() +end) diff --git a/test/functional/ui/output_spec.lua b/test/functional/ui/output_spec.lua index 50e5dfac84..71c6410013 100644 --- a/test/functional/ui/output_spec.lua +++ b/test/functional/ui/output_spec.lua @@ -9,6 +9,7 @@ local feed_command = helpers.feed_command local iswin = helpers.iswin local clear = helpers.clear local command = helpers.command +local testprg = helpers.testprg local nvim_dir = helpers.nvim_dir local has_powershell = helpers.has_powershell local set_shell_powershell = helpers.set_shell_powershell @@ -54,7 +55,7 @@ describe("shell command :!", function() if 'openbsd' == helpers.uname() then pending('FIXME #10804') end - child_session.feed_data(":!"..nvim_dir.."/shell-test REP 30001 foo\n") + child_session.feed_data((":!%s REP 30001 foo\n"):format(testprg('shell-test'))) -- If we observe any line starting with a dot, then throttling occurred. -- Avoid false failure on slow systems. @@ -207,12 +208,7 @@ describe("shell command :!", function() it('handles multibyte sequences split over buffer boundaries', function() command('cd '..nvim_dir) - local cmd - if iswin() then - cmd = '!shell-test UTF-8 ' - else - cmd = '!./shell-test UTF-8' - end + local cmd = iswin() and '!shell-test UTF-8 ' or '!./shell-test UTF-8' feed_command(cmd) -- Note: only the first example of split composed char works screen:expect([[ diff --git a/test/functional/ui/searchhl_spec.lua b/test/functional/ui/searchhl_spec.lua index cdb6256f77..c3b9af5e72 100644 --- a/test/functional/ui/searchhl_spec.lua +++ b/test/functional/ui/searchhl_spec.lua @@ -5,7 +5,7 @@ local command = helpers.command local feed_command = helpers.feed_command local eq = helpers.eq local eval = helpers.eval -local nvim_dir = helpers.nvim_dir +local testprg = helpers.testprg describe('search highlighting', function() local screen @@ -305,7 +305,7 @@ describe('search highlighting', function() end) it('is preserved during :terminal activity', function() - feed([[:terminal "]]..nvim_dir..[[/shell-test" REP 5000 foo<cr>]]) + feed((':terminal "%s" REP 5000 foo<cr>'):format(testprg('shell-test'))) feed(':file term<CR>') feed('G') -- Follow :terminal output. diff --git a/test/functional/ui/wildmode_spec.lua b/test/functional/ui/wildmode_spec.lua index 65c6fabfa8..98398bc7a1 100644 --- a/test/functional/ui/wildmode_spec.lua +++ b/test/functional/ui/wildmode_spec.lua @@ -7,7 +7,7 @@ local meths = helpers.meths local eq = helpers.eq local eval = helpers.eval local retry = helpers.retry -local nvim_dir = helpers.nvim_dir +local testprg = helpers.testprg describe("'wildmenu'", function() local screen @@ -114,7 +114,7 @@ describe("'wildmenu'", function() it('is preserved during :terminal activity', function() command('set wildmenu wildmode=full') command('set scrollback=4') - feed([[:terminal "]]..nvim_dir..[[/shell-test" REP 5000 !terminal_output!<cr>]]) + feed((':terminal "%s" REP 5000 !terminal_output!<cr>'):format(testprg('shell-test'))) feed('G') -- Follow :terminal output. feed([[:sign <Tab>]]) -- Invoke wildmenu. -- NB: in earlier versions terminal output was redrawn during cmdline mode. diff --git a/test/functional/vimscript/let_spec.lua b/test/functional/vimscript/let_spec.lua index 6e93655e32..85c9c690f9 100644 --- a/test/functional/vimscript/let_spec.lua +++ b/test/functional/vimscript/let_spec.lua @@ -7,7 +7,7 @@ local eval = helpers.eval local meths = helpers.meths local exec_capture = helpers.exec_capture local source = helpers.source -local nvim_dir = helpers.nvim_dir +local testprg = helpers.testprg before_each(clear) @@ -59,7 +59,7 @@ describe(':let', function() end) it("multibyte env var to child process #8398 #9267", function() - local cmd_get_child_env = "let g:env_from_child = system(['"..nvim_dir.."/printenv-test', 'NVIM_TEST_LET'])" + local cmd_get_child_env = ("let g:env_from_child = system(['%s', 'NVIM_TEST_LET'])"):format(testprg('printenv-test')) command("let $NVIM_TEST_LET = 'AìaB'") command(cmd_get_child_env) eq(eval('$NVIM_TEST_LET'), eval('g:env_from_child')) diff --git a/test/functional/vimscript/system_spec.lua b/test/functional/vimscript/system_spec.lua index 9cc6424d31..c915556c57 100644 --- a/test/functional/vimscript/system_spec.lua +++ b/test/functional/vimscript/system_spec.lua @@ -1,11 +1,13 @@ local helpers = require('test.functional.helpers')(after_each) local assert_alive = helpers.assert_alive -local nvim_dir = helpers.nvim_dir +local testprg = helpers.testprg 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 command = helpers.command +local insert = helpers.insert +local expect = helpers.expect local exc_exec = helpers.exc_exec local iswin = helpers.iswin local os_kill = helpers.os_kill @@ -30,10 +32,6 @@ describe('system()', function() before_each(clear) describe('command passed as a List', function() - local function printargs_path() - return nvim_dir..'/printargs-test' .. (iswin() and '.exe' or '') - end - it('throws error if cmd[0] is not executable', function() eq("Vim:E475: Invalid value for argument cmd: 'this-should-not-exist' is not executable", pcall_err(call, 'system', { 'this-should-not-exist' })) @@ -66,23 +64,23 @@ describe('system()', function() it('quotes arguments correctly #5280', function() local out = call('system', - { printargs_path(), [[1]], [[2 "3]], [[4 ' 5]], [[6 ' 7']] }) + { testprg('printargs-test'), [[1]], [[2 "3]], [[4 ' 5]], [[6 ' 7']] }) eq(0, eval('v:shell_error')) eq([[arg1=1;arg2=2 "3;arg3=4 ' 5;arg4=6 ' 7';]], out) - out = call('system', { printargs_path(), [['1]], [[2 "3]] }) + out = call('system', { testprg('printargs-test'), [['1]], [[2 "3]] }) eq(0, eval('v:shell_error')) eq([[arg1='1;arg2=2 "3;]], out) - out = call('system', { printargs_path(), "A\nB" }) + out = call('system', { testprg('printargs-test'), "A\nB" }) eq(0, eval('v:shell_error')) eq("arg1=A\nB;", out) end) it('calls executable in $PATH', function() - if 0 == eval("executable('python')") then pending("missing `python`") end - eq("foo\n", eval([[system(['python', '-c', 'print("foo")'])]])) + if 0 == eval("executable('python3')") then pending("missing `python3`") end + eq("foo\n", eval([[system(['python3', '-c', 'print("foo")'])]])) eq(0, eval('v:shell_error')) end) @@ -167,7 +165,7 @@ describe('system()', function() end end) - it('works with powershell', function() + it('with powershell', function() helpers.set_shell_powershell() eq('a\nb\n', eval([[system('Write-Output a b')]])) eq('C:\\\n', eval([[system('cd c:\; (Get-Location).Path')]])) @@ -175,12 +173,11 @@ describe('system()', function() end) end - it('works with powershell w/ UTF-8 text (#13713)', function() + it('powershell w/ UTF-8 text #13713', function() if not helpers.has_powershell() then - pending("not tested; powershell was not found", function() end) + pending("powershell not found", function() end) return end - -- Should work with recommended config used in helper helpers.set_shell_powershell() eq('ああ\n', eval([[system('Write-Output "ああ"')]])) -- Sanity test w/ default encoding @@ -430,7 +427,7 @@ describe('system()', function() end) it("with a program that doesn't close stdout will exit properly after passing input", function() - local out = eval(string.format("system('%s', 'clip-data')", nvim_dir..'/streams-test')) + local out = eval(string.format("system('%s', 'clip-data')", testprg('streams-test'))) assert(out:sub(0, 5) == 'pid: ', out) os_kill(out:match("%d+")) end) @@ -609,17 +606,16 @@ describe('systemlist()', function() end) it("with a program that doesn't close stdout will exit properly after passing input", function() - local out = eval(string.format("systemlist('%s', 'clip-data')", nvim_dir..'/streams-test')) + local out = eval(string.format("systemlist('%s', 'clip-data')", testprg('streams-test'))) assert(out[1]:sub(0, 5) == 'pid: ', out) os_kill(out[1]:match("%d+")) end) - it('works with powershell w/ UTF-8 text (#13713)', function() + it('powershell w/ UTF-8 text #13713', function() if not helpers.has_powershell() then - pending("not tested; powershell was not found", function() end) + pending("powershell not found", function() end) return end - -- Should work with recommended config used in helper helpers.set_shell_powershell() eq({iswin() and 'あ\r' or 'あ'}, eval([[systemlist('Write-Output あ')]])) -- Sanity test w/ default encoding @@ -630,3 +626,31 @@ describe('systemlist()', function() end) end) + +describe('shell :!', function() + before_each(clear) + + it(':{range}! with powershell filter/redirect #16271', function() + local screen = Screen.new(500, 8) + screen:attach() + local found = helpers.set_shell_powershell(true) + insert([[ + 3 + 1 + 4 + 2]]) + feed(':4verbose %!sort<cr>') + screen:expect{ + any=[[Executing command: .?Start%-Process sort %-RedirectStandardInput .* %-RedirectStandardOutput .* %-NoNewWindow %-Wait]] + } + feed('<CR>') + if found then + -- Not using fake powershell, so we can test the result. + expect([[ + 1 + 2 + 3 + 4]]) + end + end) +end) diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt index 9f1b3f0706..6fe5c2baf5 100644 --- a/third-party/CMakeLists.txt +++ b/third-party/CMakeLists.txt @@ -119,6 +119,19 @@ if(CMAKE_OSX_SYSROOT) endif() endif() +if(CMAKE_OSX_ARCHITECTURES) + string(REPLACE ";" "|" CMAKE_OSX_ARCHITECTURES_ALT_SEP "${CMAKE_OSX_ARCHITECTURES}") + # The LuaJIT build does not like being passed multiple `-arch` flags + # so we handle a universal build the old-fashioned way. + set(LUAJIT_C_COMPILER "${DEPS_C_COMPILER}") + foreach(ARCH IN LISTS CMAKE_OSX_ARCHITECTURES) + set(DEPS_C_COMPILER "${DEPS_C_COMPILER} -arch ${ARCH}") + if(DEPS_CXX_COMPILER) + set(DEPS_CXX_COMPILER "${DEPS_CXX_COMPILER} -arch ${ARCH}") + endif() + endforeach() +endif() + set(HOSTDEPS_INSTALL_DIR "${DEPS_INSTALL_DIR}") set(HOSTDEPS_BIN_DIR "${DEPS_BIN_DIR}") set(HOSTDEPS_LIB_DIR "${DEPS_LIB_DIR}") diff --git a/third-party/cmake/BuildLuajit.cmake b/third-party/cmake/BuildLuajit.cmake index fc8558588b..c8d5b39398 100644 --- a/third-party/cmake/BuildLuajit.cmake +++ b/third-party/cmake/BuildLuajit.cmake @@ -5,7 +5,7 @@ function(BuildLuajit) cmake_parse_arguments(_luajit "" "TARGET" - "CONFIGURE_COMMAND;BUILD_COMMAND;INSTALL_COMMAND" + "CONFIGURE_COMMAND;BUILD_COMMAND;INSTALL_COMMAND;DEPENDS" ${ARGN}) if(NOT _luajit_CONFIGURE_COMMAND AND NOT _luajit_BUILD_COMMAND AND NOT _luajit_INSTALL_COMMAND) @@ -30,13 +30,14 @@ function(BuildLuajit) CONFIGURE_COMMAND "${_luajit_CONFIGURE_COMMAND}" BUILD_IN_SOURCE 1 BUILD_COMMAND "${_luajit_BUILD_COMMAND}" - INSTALL_COMMAND "${_luajit_INSTALL_COMMAND}") + INSTALL_COMMAND "${_luajit_INSTALL_COMMAND}" + DEPENDS "${_luajit_DEPENDS}") # Create symlink for development version manually. if(UNIX) add_custom_command( TARGET ${_luajit_TARGET} - COMMAND ${CMAKE_COMMAND} -E create_symlink luajit-2.1.0-beta3 ${DEPS_BIN_DIR}/luajit) + COMMAND ${CMAKE_COMMAND} -E create_symlink luajit-2.1.0-beta3 ${DEPS_BIN_DIR}/${_luajit_TARGET}) endif() endfunction() @@ -51,30 +52,64 @@ if(CMAKE_SYSTEM_NAME MATCHES "OpenBSD") else() set(AMD64_ABI "") endif() -set(INSTALLCMD_UNIX ${MAKE_PRG} CFLAGS=-fPIC - CFLAGS+=-DLUA_USE_APICHECK - CFLAGS+=-funwind-tables - ${NO_STACK_CHECK} - ${AMD64_ABI} - CCDEBUG+=-g - Q= - install) +set(BUILDCMD_UNIX ${MAKE_PRG} CFLAGS=-fPIC + CFLAGS+=-DLUA_USE_APICHECK + CFLAGS+=-funwind-tables + ${NO_STACK_CHECK} + ${AMD64_ABI} + CCDEBUG+=-g + Q=) -if(UNIX) - if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") - if(CMAKE_OSX_DEPLOYMENT_TARGET) - set(DEPLOYMENT_TARGET "MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}") - else() - # Use the same target as our nightly builds - set(DEPLOYMENT_TARGET "MACOSX_DEPLOYMENT_TARGET=10.11") - endif() +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + if(CMAKE_OSX_DEPLOYMENT_TARGET) + set(DEPLOYMENT_TARGET "MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}") else() - set(DEPLOYMENT_TARGET "") + execute_process(COMMAND sw_vers -productVersion + OUTPUT_VARIABLE MACOS_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) + set(DEPLOYMENT_TARGET "MACOSX_DEPLOYMENT_TARGET=${MACOS_VERSION}") endif() +else() + set(DEPLOYMENT_TARGET "") +endif() - BuildLuaJit(INSTALL_COMMAND ${INSTALLCMD_UNIX} +if((UNIX AND NOT APPLE) OR (APPLE AND NOT CMAKE_OSX_ARCHITECTURES)) + BuildLuaJit(INSTALL_COMMAND ${BUILDCMD_UNIX} CC=${DEPS_C_COMPILER} PREFIX=${DEPS_INSTALL_DIR} - ${DEPLOYMENT_TARGET}) + ${DEPLOYMENT_TARGET} install) + +elseif(CMAKE_OSX_ARCHITECTURES AND APPLE) + + # Passing multiple `-arch` flags to the LuaJIT build will cause it to fail. + # To get a working universal build, we build each requested architecture slice + # individually then `lipo` them all up. + set(LUAJIT_SRC_DIR "${DEPS_BUILD_DIR}/src/luajit") + foreach(ARCH IN LISTS CMAKE_OSX_ARCHITECTURES) + set(STATIC_CC "${LUAJIT_C_COMPILER} -arch ${ARCH}") + set(DYNAMIC_CC "${LUAJIT_C_COMPILER} -arch ${ARCH} -fPIC") + set(TARGET_LD "${LUAJIT_C_COMPILER} -arch ${ARCH}") + list(APPEND LUAJIT_THIN_EXECUTABLES "${LUAJIT_SRC_DIR}-${ARCH}/src/luajit") + list(APPEND LUAJIT_THIN_STATIC_LIBS "${LUAJIT_SRC_DIR}-${ARCH}/src/libluajit.a") + list(APPEND LUAJIT_THIN_DYLIBS "${LUAJIT_SRC_DIR}-${ARCH}/src/libluajit.so") + list(APPEND LUAJIT_THIN_TARGETS "luajit-${ARCH}") + + # See https://luajit.org/install.html#cross. + BuildLuaJit(TARGET "luajit-${ARCH}" + BUILD_COMMAND ${BUILDCMD_UNIX} + CC=${LUAJIT_C_COMPILER} STATIC_CC=${STATIC_CC} + DYNAMIC_CC=${DYNAMIC_CC} TARGET_LD=${TARGET_LD} + PREFIX=${DEPS_INSTALL_DIR} + ${DEPLOYMENT_TARGET}) + endforeach() + BuildLuaJit( + CONFIGURE_COMMAND ${BUILDCMD_UNIX} CC=${LUAJIT_C_COMPILER} PREFIX=${DEPS_INSTALL_DIR} ${DEPLOYMENT_TARGET} + COMMAND ${CMAKE_COMMAND} -E rm -f ${LUAJIT_SRC_DIR}/src/luajit ${LUAJIT_SRC_DIR}/src/libluajit.so ${LUAJIT_SRC_DIR}/src/libluajit.a + BUILD_COMMAND lipo ${LUAJIT_THIN_EXECUTABLES} -create -output ${LUAJIT_SRC_DIR}/src/luajit + COMMAND lipo ${LUAJIT_THIN_STATIC_LIBS} -create -output ${LUAJIT_SRC_DIR}/src/libluajit.a + COMMAND lipo ${LUAJIT_THIN_DYLIBS} -create -output ${LUAJIT_SRC_DIR}/src/libluajit.so + INSTALL_COMMAND ${BUILDCMD_UNIX} CC=${LUAJIT_C_COMPILER} PREFIX=${DEPS_INSTALL_DIR} ${DEPLOYMENT_TARGET} install + DEPENDS ${LUAJIT_THIN_TARGETS} + ) elseif(MINGW) diff --git a/third-party/cmake/BuildLuv.cmake b/third-party/cmake/BuildLuv.cmake index 001f5a325a..6e9a333dc8 100644 --- a/third-party/cmake/BuildLuv.cmake +++ b/third-party/cmake/BuildLuv.cmake @@ -48,7 +48,8 @@ function(BuildLuv) PATCH_COMMAND "${_luv_PATCH_COMMAND}" CONFIGURE_COMMAND "${_luv_CONFIGURE_COMMAND}" BUILD_COMMAND "${_luv_BUILD_COMMAND}" - INSTALL_COMMAND "${_luv_INSTALL_COMMAND}") + INSTALL_COMMAND "${_luv_INSTALL_COMMAND}" + LIST_SEPARATOR |) endfunction() set(LUV_SRC_DIR ${DEPS_BUILD_DIR}/src/luv) @@ -65,6 +66,7 @@ set(LUV_CONFIGURE_COMMAND_COMMON -DCMAKE_GENERATOR=${CMAKE_GENERATOR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} + -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES_ALT_SEP} -DLUA_BUILD_TYPE=System -DLUA_COMPAT53_DIR=${DEPS_BUILD_DIR}/src/lua-compat-5.3 -DWITH_SHARED_LIBUV=ON diff --git a/third-party/cmake/BuildMsgpack.cmake b/third-party/cmake/BuildMsgpack.cmake index a89c1e34d0..10bf1c8e37 100644 --- a/third-party/cmake/BuildMsgpack.cmake +++ b/third-party/cmake/BuildMsgpack.cmake @@ -27,7 +27,8 @@ function(BuildMsgpack) -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/DownloadAndExtractFile.cmake CONFIGURE_COMMAND "${_msgpack_CONFIGURE_COMMAND}" BUILD_COMMAND "${_msgpack_BUILD_COMMAND}" - INSTALL_COMMAND "${_msgpack_INSTALL_COMMAND}") + INSTALL_COMMAND "${_msgpack_INSTALL_COMMAND}" + LIST_SEPARATOR |) endfunction() set(MSGPACK_CONFIGURE_COMMAND ${CMAKE_COMMAND} ${DEPS_BUILD_DIR}/src/msgpack @@ -36,6 +37,7 @@ set(MSGPACK_CONFIGURE_COMMAND ${CMAKE_COMMAND} ${DEPS_BUILD_DIR}/src/msgpack -DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES_ALT_SEP} "-DCMAKE_C_FLAGS:STRING=${CMAKE_C_COMPILER_ARG1} -fPIC" -DCMAKE_GENERATOR=${CMAKE_GENERATOR}) diff --git a/third-party/cmake/BuildTreesitterParsers.cmake b/third-party/cmake/BuildTreesitterParsers.cmake index 4ceb402455..11ffb792de 100644 --- a/third-party/cmake/BuildTreesitterParsers.cmake +++ b/third-party/cmake/BuildTreesitterParsers.cmake @@ -19,9 +19,11 @@ CMAKE_ARGS -DCMAKE_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} + -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES_ALT_SEP} # Pass toolchain -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DPARSERLANG=c BUILD_COMMAND ${CMAKE_COMMAND} --build . --config ${CMAKE_BUILD_TYPE} -INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install --config ${CMAKE_BUILD_TYPE}) +INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install --config ${CMAKE_BUILD_TYPE} +LIST_SEPARATOR |) |