aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.ci/before_install.sh17
-rwxr-xr-x.ci/install.sh14
-rw-r--r--.travis.yml19
-rw-r--r--CMakeLists.txt2
-rw-r--r--config/config.h.in1
-rw-r--r--runtime/autoload/man.vim149
-rw-r--r--runtime/doc/options.txt12
-rw-r--r--runtime/doc/various.txt19
-rw-r--r--runtime/doc/vim_diff.txt1
-rw-r--r--runtime/ftplugin/man.vim198
-rw-r--r--runtime/ftplugin/tutor.vim1
-rw-r--r--runtime/plugin/man.vim6
-rw-r--r--runtime/syntax/tutor.vim2
-rw-r--r--runtime/tutor/tutor.tutor4
-rw-r--r--src/nvim/CMakeLists.txt1
-rw-r--r--src/nvim/if_cscope.c267
-rw-r--r--src/nvim/menu.c4
-rw-r--r--src/nvim/normal.c59
-rw-r--r--src/nvim/options.lua6
-rw-r--r--src/nvim/path.c4
-rw-r--r--test/functional/normal/K_spec.lua39
-rw-r--r--test/functional/provider/python3_spec.lua18
-rw-r--r--test/functional/provider/python_spec.lua18
-rw-r--r--third-party/CMakeLists.txt4
-rw-r--r--third-party/cmake/BuildJeMalloc.cmake2
25 files changed, 469 insertions, 398 deletions
diff --git a/.ci/before_install.sh b/.ci/before_install.sh
index e70654c9be..2a1ac05569 100755
--- a/.ci/before_install.sh
+++ b/.ci/before_install.sh
@@ -10,4 +10,19 @@ fi
if [[ "${TRAVIS_OS_NAME}" == osx ]]; then
brew update
fi
-pip install --user --upgrade pip
+
+echo "Upgrade Python 2's pip."
+pip2.7 install --user --upgrade pip
+
+if [[ "${TRAVIS_OS_NAME}" == osx ]]; then
+ echo "Install Python 3."
+ brew install python3
+ echo "Upgrade Python 3's pip."
+ pip3 install --user --upgrade pip
+else
+ # TODO: Replace with upgrade when Travis gets python3-pip package.
+ echo "Install pip for Python 3."
+ curl -sSL https://bootstrap.pypa.io/get-pip.py -o "${HOME}/get-pip.py"
+ # After this, pip in PATH will refer to Python 3's pip.
+ python3.3 "${HOME}/get-pip.py" --user --upgrade
+fi
diff --git a/.ci/install.sh b/.ci/install.sh
index 42c8026396..ad3ef1b8b7 100755
--- a/.ci/install.sh
+++ b/.ci/install.sh
@@ -14,7 +14,17 @@ elif [[ "${BUILD_MINGW}" == ON ]]; then
# binutils-mingw-w64-i686 gcc-mingw-w64-i686 g++-mingw-w64-i686 mingw-w64-dev mingw-w64-tools
echo "Downloading MinGW..."
- wget -q -O - "http://downloads.sourceforge.net/project/mingw-w64/Toolchains%20targetting%20Win32/Personal%20Builds/rubenvb/gcc-4.8-release/i686-w64-mingw32-gcc-4.8.0-linux64_rubenvb.tar.xz" | tar xJf - -C "${HOME}/.local"
+ curl -sSL "http://downloads.sourceforge.net/project/mingw-w64/Toolchains%20targetting%20Win32/Personal%20Builds/rubenvb/gcc-4.8-release/i686-w64-mingw32-gcc-4.8.0-linux64_rubenvb.tar.xz" | tar xJf - -C "${HOME}/.local"
fi
-pip install --user --upgrade cpp-coveralls neovim
+# Set CC to default to avoid compilation problems
+# when installing Python modules.
+echo "Install neovim module and coveralls for Python 2."
+CC=cc pip2.7 install --user --upgrade neovim cpp-coveralls
+
+echo "Install neovim module for Python 3."
+if [[ "${TRAVIS_OS_NAME}" == osx ]]; then
+ CC=cc pip3 install --user --upgrade neovim
+else
+ CC=cc pip3.3 install --user --upgrade neovim
+fi
diff --git a/.travis.yml b/.travis.yml
index bd2c9b3938..f790c715ab 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,7 +9,7 @@ env:
# http://docs.travis-ci.com/user/speeding-up-the-build/#Paralellizing-your-build-on-one-VM
- MAKE_CMD="make -j2"
# Update PATH for pip and MinGW.
- - PATH="$(python -c 'import site; print(site.getuserbase())')/bin:$HOME/.local/mingw32/bin:$PATH"
+ - PATH="$(python2.7 -c 'import site; print(site.getuserbase())')/bin:$HOME/.local/mingw32/bin:$PATH"
# LLVM symbolizer path.
- LLVM_SYMBOLIZER="$(which llvm-symbolizer-3.6)"
# Force verification of DLOG macros.
@@ -101,28 +101,29 @@ after_success: .ci/after_success.sh
addons:
apt:
sources:
+ # TODO: Remove PPA when Travis gets Python >=3.3.
+ - deadsnakes
- llvm-toolchain-precise-3.6
- ubuntu-toolchain-r-test
packages:
- # Basic Neovim/test dependencies.
- autoconf
- automake
- build-essential
- - cmake
- - gdb
- - libtool
- - pkg-config
- - unzip
- - xclip
- # Additional compilers/tools.
- clang-3.6
+ - cmake
- g++-5-multilib
- g++-multilib
- gcc-5-multilib
- gcc-multilib
+ - gdb
- libc6-dev-i386
+ - libtool
- llvm-3.6-dev
+ - pkg-config
+ - python3.3-dev
+ - unzip
- valgrind
+ - xclip
branches:
except:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1c637ced90..5d6082b857 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -121,7 +121,7 @@ if(MSVC)
add_definitions(/W3 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
else()
add_definitions(-Wall -Wextra -pedantic -Wno-unused-parameter
- -Wstrict-prototypes -std=gnu99)
+ -Wstrict-prototypes -Wvla -std=gnu99)
endif()
if(MINGW)
diff --git a/config/config.h.in b/config/config.h.in
index 54a405727d..c234501820 100644
--- a/config/config.h.in
+++ b/config/config.h.in
@@ -53,7 +53,6 @@
#cmakedefine HAVE_WORKING_LIBINTL
#cmakedefine UNIX
#cmakedefine USE_FNAME_CASE
-#define USEMAN_S 1
#define FEAT_BROWSE
#define FEAT_CSCOPE
diff --git a/runtime/autoload/man.vim b/runtime/autoload/man.vim
new file mode 100644
index 0000000000..d481d9eaf0
--- /dev/null
+++ b/runtime/autoload/man.vim
@@ -0,0 +1,149 @@
+let s:man_tag_depth = 0
+let s:man_sect_arg = ''
+let s:man_find_arg = '-w'
+
+try
+ if !has('win32') && $OSTYPE !~? 'cygwin\|linux' && system('uname -s') =~? 'SunOS' && system('uname -r') =~? '^5'
+ let s:man_sect_arg = '-s'
+ let s:man_find_arg = '-l'
+ endif
+catch /E145:/
+ " Ignore the error in restricted mode
+endtry
+
+function man#get_page(...) abort
+ let invoked_from_man = (&filetype ==# 'man')
+
+ if a:0 == 0
+ echoerr 'argument required'
+ return
+ elseif a:0 > 2
+ echoerr 'too many arguments'
+ return
+ elseif a:0 == 2
+ let [page, sect] = [a:2, 0 + a:1]
+ elseif type(1) == type(a:1)
+ let [page, sect] = ['<cword>', a:1]
+ else
+ let [page, sect] = [a:1, '']
+ endif
+
+ if page == '<cword>'
+ let page = expand('<cword>')
+ endif
+
+ let [page, sect] = s:parse_page_and_section(sect, page)
+
+ if 0 + sect > 0 && s:find_page(sect, page) == 0
+ let sect = ''
+ endif
+
+ if s:find_page(sect, page) == 0
+ echo 'No manual entry for '.page
+ return
+ endif
+
+ exec 'let s:man_tag_buf_'.s:man_tag_depth.' = '.bufnr('%')
+ exec 'let s:man_tag_lin_'.s:man_tag_depth.' = '.line('.')
+ exec 'let s:man_tag_col_'.s:man_tag_depth.' = '.col('.')
+ let s:man_tag_depth = s:man_tag_depth + 1
+
+ let editcmd = 'edit'
+ " Use an existing 'man' window, else open a new one.
+ if &filetype !=# 'man'
+ let thiswin = winnr()
+ wincmd b
+ if winnr() > 1
+ exe "norm! " . thiswin . "\<C-W>w"
+ while 1
+ if &filetype == 'man'
+ break
+ endif
+ wincmd w
+ if thiswin == winnr()
+ break
+ endif
+ endwhile
+ endif
+
+ if &filetype !=# 'man'
+ let editcmd = 'tabnew'
+ endif
+ endif
+
+ silent exec editcmd.' man://'.page.(empty(sect)?'':'('.sect.')')
+
+ setlocal modifiable
+ silent keepjumps norm! 1G"_dG
+ let $MANWIDTH = winwidth(0)
+ silent exec 'r!/usr/bin/man '.s:cmd(sect, page).' | col -b'
+ " Remove blank lines from top and bottom.
+ while getline(1) =~ '^\s*$'
+ silent keepjumps norm! gg"_dd
+ endwhile
+ while getline('$') =~ '^\s*$'
+ silent keepjumps norm! G"_dd
+ endwhile
+ setlocal nomodified
+ setlocal filetype=man
+
+ if invoked_from_man || editcmd ==# 'tabnew'
+ call s:set_window_local_options()
+ endif
+endfunction
+
+function s:set_window_local_options() abort
+ setlocal colorcolumn=0 foldcolumn=0 nonumber
+ setlocal nolist norelativenumber nofoldenable
+endfunction
+
+function man#pop_page() abort
+ if s:man_tag_depth > 0
+ let s:man_tag_depth = s:man_tag_depth - 1
+ exec "let s:man_tag_buf=s:man_tag_buf_".s:man_tag_depth
+ exec "let s:man_tag_lin=s:man_tag_lin_".s:man_tag_depth
+ exec "let s:man_tag_col=s:man_tag_col_".s:man_tag_depth
+ exec s:man_tag_buf."b"
+ exec s:man_tag_lin
+ exec "norm! ".s:man_tag_col."|"
+ exec "unlet s:man_tag_buf_".s:man_tag_depth
+ exec "unlet s:man_tag_lin_".s:man_tag_depth
+ exec "unlet s:man_tag_col_".s:man_tag_depth
+ unlet s:man_tag_buf s:man_tag_lin s:man_tag_col
+ endif
+endfunction
+
+" Expects a string like 'access' or 'access(2)'.
+function s:parse_page_and_section(sect, str) abort
+ try
+ let save_isk = &iskeyword
+ setlocal iskeyword-=(,)
+ let page = substitute(a:str, '(*\(\k\+\).*', '\1', '')
+ let sect = substitute(a:str, '\(\k\+\)(\([^()]*\)).*', '\2', '')
+ if sect == page || -1 == match(sect, '^[0-9 ]\+$')
+ let sect = a:sect
+ endif
+ catch
+ let &l:iskeyword = save_isk
+ echoerr 'man.vim: failed to parse: "'.a:str.'"'
+ endtry
+
+ return [page, sect]
+endfunction
+
+function s:cmd(sect, page) abort
+ if 0 + a:sect > 0
+ return s:man_sect_arg.' '.a:sect.' '.a:page
+ endif
+ return a:page
+endfunction
+
+function s:find_page(sect, page) abort
+ let where = system('/usr/bin/man '.s:man_find_arg.' '.s:cmd(a:sect, a:page))
+ if where !~ "^/"
+ if matchstr(where, " [^ ]*$") !~ "^ /"
+ return 0
+ endif
+ endif
+ return 1
+endfunction
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 410e116064..897137ff42 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -3877,18 +3877,20 @@ A jump table for the options with a short description can be found at |Q_op|.
The 'keymodel' option is set by the |:behave| command.
*'keywordprg'* *'kp'*
-'keywordprg' 'kp' string (default "man" or "man -s", DOS: ":help")
+'keywordprg' 'kp' string (default ":Man", Windows: ":help")
global or local to buffer |global-local|
Program to use for the |K| command. Environment variables are
expanded |:set_env|. ":help" may be used to access the Vim internal
help. (Note that previously setting the global option to the empty
value did this, which is now deprecated.)
- When "man" is used, Vim will automatically translate a count for the
- "K" command to a section number. Also for "man -s", in which case the
- "-s" is removed when there is no count.
+ When the first character is ":", the command is invoked as a Vim
+ command prefixed with [count]. {Nvim}
+ When "man" or "man -s" is used, Vim will automatically translate
+ a [count] for the "K" command to a section number.
See |option-backslash| about including spaces and backslashes.
Example: >
:set keywordprg=man\ -s
+ :set keywordprg=:Man
< This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.
@@ -6965,7 +6967,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|hl-WildMenu|.
*'wildmode'* *'wim'*
-'wildmode' 'wim' string (default: "list:longest,full")
+'wildmode' 'wim' string (default: "full")
global
Completion mode that is used for the character specified with
'wildchar'. It is a comma separated list of up to four parts. Each
diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt
index 6b53b8e24f..3cc0e7c8ab 100644
--- a/runtime/doc/various.txt
+++ b/runtime/doc/various.txt
@@ -542,7 +542,7 @@ which it was defined is reported.
{not available when compiled without the |+eval| feature}
*K*
-K Run a program to lookup the keyword under the
+[count]K Run a program to lookup the keyword under the
cursor. The name of the program is given with the
'keywordprg' (kp) option (default is "man"). The
keyword is formed of letters, numbers and the
@@ -550,19 +550,18 @@ K Run a program to lookup the keyword under the
right of the cursor is used. The same can be done
with the command >
:!{program} {keyword}
-< There is an example of a program to use in the tools
- directory of Vim. It is called 'ref' and does a
- simple spelling check.
- Special cases:
+< Special cases:
+ - If 'keywordprg' begins with ":" it is invoked as
+ a Vim command with [count].
- If 'keywordprg' is empty, the ":help" command is
used. It's a good idea to include more characters
in 'iskeyword' then, to be able to find more help.
- - When 'keywordprg' is equal to "man", a count before
- "K" is inserted after the "man" command and before
- the keyword. For example, using "2K" while the
- cursor is on "mkdir", results in: >
+ - When 'keywordprg' is equal to "man", a [count]
+ before "K" is inserted after the "man" command and
+ before the keyword. For example, using "2K" while
+ the cursor is on "mkdir", results in: >
!man 2 mkdir
-< - When 'keywordprg' is equal to "man -s", a count
+< - When 'keywordprg' is equal to "man -s", a [count]
before "K" is inserted after the "-s". If there is
no count, the "-s" is removed.
diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt
index fe4b61815b..3e18cdd762 100644
--- a/runtime/doc/vim_diff.txt
+++ b/runtime/doc/vim_diff.txt
@@ -51,7 +51,6 @@ these differences.
- 'ttyfast' is always set
- 'viminfo' includes "!"
- 'wildmenu' is set by default
-- 'wildmode' defaults to "list:longest,full"
==============================================================================
3. Changed features *nvim-features-changed*
diff --git a/runtime/ftplugin/man.vim b/runtime/ftplugin/man.vim
index 11b2b0a665..133a28e626 100644
--- a/runtime/ftplugin/man.vim
+++ b/runtime/ftplugin/man.vim
@@ -1,191 +1,37 @@
" Vim filetype plugin file
" Language: man
" Maintainer: SungHyun Nam <goweol@gmail.com>
-" Last Change: 2014 Nov 12
-
-" To make the ":Man" command available before editing a manual page, source
-" this script from your startup vimrc file.
-
-" If 'filetype' isn't "man", we must have been called to only define ":Man".
-if &filetype == "man"
-
- " Only do this when not done yet for this buffer
- if exists("b:did_ftplugin")
- finish
- endif
- let b:did_ftplugin = 1
-
- " Ensure Vim is not recursively invoked (man-db does this)
- " when doing ctrl-[ on a man page reference.
- if exists("$MANPAGER")
- let $MANPAGER = ""
- endif
-
- " allow dot and dash in manual page name.
- setlocal iskeyword+=\.,-
-
- " Add mappings, unless the user didn't want this.
- if !exists("no_plugin_maps") && !exists("no_man_maps")
- if !hasmapto('<Plug>ManBS')
- nmap <buffer> <LocalLeader>h <Plug>ManBS
- endif
- nnoremap <buffer> <Plug>ManBS :%s/.\b//g<CR>:setl nomod<CR>''
-
- nnoremap <buffer> <c-]> :call <SID>PreGetPage(v:count)<CR>
- nnoremap <buffer> <c-t> :call <SID>PopPage()<CR>
- endif
-
- let b:undo_ftplugin = "setlocal iskeyword<"
+if has('vim_starting') && &filetype !=# 'man'
+ finish
endif
-if exists(":Man") != 2
- com -nargs=+ Man call s:GetPage(<f-args>)
- nmap <Leader>K :call <SID>PreGetPage(0)<CR>
+" Only do this when not done yet for this buffer
+if exists('b:did_ftplugin')
+ finish
endif
+let b:did_ftplugin = 1
-" Define functions only once.
-if !exists("s:man_tag_depth")
-
-let s:man_tag_depth = 0
-
-let s:man_sect_arg = ""
-let s:man_find_arg = "-w"
-try
- if !has("win32") && $OSTYPE !~ 'cygwin\|linux' && system('uname -s') =~ "SunOS" && system('uname -r') =~ "^5"
- let s:man_sect_arg = "-s"
- let s:man_find_arg = "-l"
- endif
-catch /E145:/
- " Ignore the error in restricted mode
-endtry
-
-func <SID>PreGetPage(cnt)
- if a:cnt == 0
- let old_isk = &iskeyword
- if &ft == 'man'
- setl iskeyword+=(,)
- endif
- let str = expand("<cword>")
- let &l:iskeyword = old_isk
- let page = substitute(str, '(*\(\k\+\).*', '\1', '')
- let sect = substitute(str, '\(\k\+\)(\([^()]*\)).*', '\2', '')
- if match(sect, '^[0-9 ]\+$') == -1
- let sect = ""
- endif
- if sect == page
- let sect = ""
- endif
- else
- let sect = a:cnt
- let page = expand("<cword>")
- endif
- call s:GetPage(sect, page)
-endfunc
-
-func <SID>GetCmdArg(sect, page)
- if a:sect == ''
- return a:page
- endif
- return s:man_sect_arg.' '.a:sect.' '.a:page
-endfunc
-
-func <SID>FindPage(sect, page)
- let where = system("/usr/bin/man ".s:man_find_arg.' '.s:GetCmdArg(a:sect, a:page))
- if where !~ "^/"
- if matchstr(where, " [^ ]*$") !~ "^ /"
- return 0
- endif
- endif
- return 1
-endfunc
-
-func <SID>GetPage(...)
- if a:0 >= 2
- let sect = a:1
- let page = a:2
- elseif a:0 >= 1
- let sect = ""
- let page = a:1
- else
- return
- endif
-
- " To support: nmap K :Man <cword>
- if page == '<cword>'
- let page = expand('<cword>')
- endif
+" Ensure Vim is not recursively invoked (man-db does this)
+" when doing ctrl-[ on a man page reference.
+if exists('$MANPAGER')
+ let $MANPAGER = ''
+endif
- if sect != "" && s:FindPage(sect, page) == 0
- let sect = ""
- endif
- if s:FindPage(sect, page) == 0
- echo "\nCannot find a '".page."'."
- return
- endif
- exec "let s:man_tag_buf_".s:man_tag_depth." = ".bufnr("%")
- exec "let s:man_tag_lin_".s:man_tag_depth." = ".line(".")
- exec "let s:man_tag_col_".s:man_tag_depth." = ".col(".")
- let s:man_tag_depth = s:man_tag_depth + 1
+setlocal iskeyword+=\.,-,(,)
- " Use an existing "man" window if it exists, otherwise open a new one.
- if &filetype != "man"
- let thiswin = winnr()
- exe "norm! \<C-W>b"
- if winnr() > 1
- exe "norm! " . thiswin . "\<C-W>w"
- while 1
- if &filetype == "man"
- break
- endif
- exe "norm! \<C-W>w"
- if thiswin == winnr()
- break
- endif
- endwhile
- endif
- if &filetype != "man"
- new
- setl nonu fdc=0
- endif
- endif
- silent exec "edit $HOME/".page.".".sect."~"
- " Avoid warning for editing the dummy file twice
- setl buftype=nofile noswapfile
+setlocal buftype=nofile noswapfile
+setlocal nomodifiable readonly bufhidden=hide nobuflisted tabstop=8
- setl ma nonu nornu nofen
- silent exec "norm 1GdG"
- let $MANWIDTH = winwidth(0)
- silent exec "r!/usr/bin/man ".s:GetCmdArg(sect, page)." | col -b"
- " Remove blank lines from top and bottom.
- while getline(1) =~ '^\s*$'
- silent norm ggdd
- endwhile
- while getline('$') =~ '^\s*$'
- silent norm Gdd
- endwhile
- 1
- setl ft=man nomod
- setl bufhidden=hide
- setl nobuflisted
-endfunc
-
-func <SID>PopPage()
- if s:man_tag_depth > 0
- let s:man_tag_depth = s:man_tag_depth - 1
- exec "let s:man_tag_buf=s:man_tag_buf_".s:man_tag_depth
- exec "let s:man_tag_lin=s:man_tag_lin_".s:man_tag_depth
- exec "let s:man_tag_col=s:man_tag_col_".s:man_tag_depth
- exec s:man_tag_buf."b"
- exec s:man_tag_lin
- exec "norm ".s:man_tag_col."|"
- exec "unlet s:man_tag_buf_".s:man_tag_depth
- exec "unlet s:man_tag_lin_".s:man_tag_depth
- exec "unlet s:man_tag_col_".s:man_tag_depth
- unlet s:man_tag_buf s:man_tag_lin s:man_tag_col
+if !exists("g:no_plugin_maps") && !exists("g:no_man_maps")
+ nnoremap <silent> <buffer> <C-]> :call man#get_page(v:count)<CR>
+ nnoremap <silent> <buffer> <C-T> :call man#pop_page()<CR>
+ nnoremap <silent> <nowait><buffer> q <C-W>c
+ if &keywordprg !=# ':Man'
+ nnoremap <silent> <buffer> K :call man#get_page(v:count)<CR>
endif
-endfunc
-
endif
+let b:undo_ftplugin = 'setlocal iskeyword<'
+
" vim: set sw=2:
diff --git a/runtime/ftplugin/tutor.vim b/runtime/ftplugin/tutor.vim
index 237176f5eb..0a28d7def4 100644
--- a/runtime/ftplugin/tutor.vim
+++ b/runtime/ftplugin/tutor.vim
@@ -4,6 +4,7 @@
call tutor#SetupVim()
" Buffer Settings: {{{1
+setlocal noreadonly
if !exists('g:tutor_debug') || g:tutor_debug == 0
setlocal buftype=nofile
setlocal concealcursor+=inv
diff --git a/runtime/plugin/man.vim b/runtime/plugin/man.vim
new file mode 100644
index 0000000000..8e5062a209
--- /dev/null
+++ b/runtime/plugin/man.vim
@@ -0,0 +1,6 @@
+if get(g:, 'loaded_man', 0)
+ finish
+endif
+let g:loaded_man = 1
+
+command! -count=0 -nargs=+ Man call man#get_page(<count>, <f-args>)
diff --git a/runtime/syntax/tutor.vim b/runtime/syntax/tutor.vim
index 99bcb78270..bce9189660 100644
--- a/runtime/syntax/tutor.vim
+++ b/runtime/syntax/tutor.vim
@@ -20,7 +20,7 @@ syn match tutorSectionBullet /#/ contained containedin=tutorSection
syn match tutorTOC /\ctable of contents:/
-syn match tutorConcealedEscapes /\\[`*!\[\]()«»:$-]\@=/ conceal
+syn match tutorConcealedEscapes /\\[`*!\[\]():$-]\@=/ conceal
syn region tutorEmphasis matchgroup=Delimiter start=/[\*]\@<!\*\*\@!/ end=/[\*]\@<!\*\*\@!/
\ concealends contains=tutorInlineCommand,tutorInlineNormal
diff --git a/runtime/tutor/tutor.tutor b/runtime/tutor/tutor.tutor
index 852c1ea74a..1ad64a18ff 100644
--- a/runtime/tutor/tutor.tutor
+++ b/runtime/tutor/tutor.tutor
@@ -60,7 +60,7 @@ is displayed like
1. Format the line below so it becomes a lesson description:
----> This is text with importat information {expect:This is text with **important information**}
+---> This is text with important information {expect:This is text with **important information**}
---> This is text with **important information** {expect:This is text with **important information**}
Note: Some words (e.g., NOTE, IMPORTANT, tip, ATTENTION, etc.) will also be
@@ -130,7 +130,7 @@ and are hidden by default. Links to them look like
# Tutorial links
-You can also have links to other tutorials. For this, you'll write the wnchor in the format
+You can also have links to other tutorials. For this, you'll write the anchor in the format
@tutor:TUTORIAL
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 608783f577..1038895b86 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -82,7 +82,6 @@ set(CONV_SOURCES
ex_getln.c
fileio.c
getchar.c
- if_cscope.c
mbyte.c
memline.c
message.c
diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c
index 5e1c5e9171..e5cbb58608 100644
--- a/src/nvim/if_cscope.c
+++ b/src/nvim/if_cscope.c
@@ -45,11 +45,9 @@
#endif
static csinfo_T * csinfo = NULL;
-static int csinfo_size = 0; /* number of items allocated in
- csinfo[] */
+static size_t csinfo_size = 0; // number of items allocated in csinfo[]
-static int eap_arg_len; /* length of eap->arg, set in
- cs_lookup_cmd() */
+static int eap_arg_len; // length of eap->arg, set in cs_lookup_cmd()
static cscmd_T cs_cmds[] =
{
{ "add", cs_add,
@@ -87,7 +85,6 @@ static enum {
char_u *get_cscope_name(expand_T *xp, int idx)
{
int current_idx;
- int i;
switch (expand_what) {
case EXP_CSCOPE_SUBCMD:
@@ -95,13 +92,16 @@ char_u *get_cscope_name(expand_T *xp, int idx)
* add, find, help, kill, reset, show */
return (char_u *)cs_cmds[idx].name;
case EXP_SCSCOPE_SUBCMD:
+ {
/* Complete with sub-commands of ":scscope": same sub-commands as
* ":cscope" but skip commands which don't support split windows */
+ int i;
for (i = 0, current_idx = 0; cs_cmds[i].name != NULL; i++)
if (cs_cmds[i].cansplit)
if (current_idx++ == idx)
break;
return (char_u *)cs_cmds[i].name;
+ }
case EXP_CSCOPE_FIND:
{
const char *query_type[] =
@@ -123,11 +123,12 @@ char_u *get_cscope_name(expand_T *xp, int idx)
* the pathname of the cscope database as argument. Only complete
* with connection numbers. -1 can also be used to kill all
* connections. */
+ size_t i;
for (i = 0, current_idx = 0; i < csinfo_size; i++) {
if (csinfo[i].fname == NULL)
continue;
if (current_idx++ == idx) {
- vim_snprintf(connection, sizeof(connection), "%d", i);
+ vim_snprintf(connection, sizeof(connection), "%zu", i);
return (char_u *)connection;
}
}
@@ -300,8 +301,8 @@ int cs_fgets(char_u *buf, int size)
{
char *p;
- if ((p = cs_manage_matches(NULL, NULL, -1, Get)) == NULL)
- return TRUE;
+ if ((p = cs_manage_matches(NULL, NULL, 0, Get)) == NULL)
+ return true;
STRLCPY(buf, p, size);
return FALSE;
@@ -315,7 +316,7 @@ int cs_fgets(char_u *buf, int size)
*/
void cs_free_tags(void)
{
- cs_manage_matches(NULL, NULL, -1, Free);
+ cs_manage_matches(NULL, NULL, 0, Free);
}
/*
@@ -325,7 +326,7 @@ void cs_free_tags(void)
*/
void cs_print_tags(void)
{
- cs_manage_matches(NULL, NULL, -1, Print);
+ cs_manage_matches(NULL, NULL, 0, Print);
}
/*
@@ -357,12 +358,10 @@ void cs_print_tags(void)
*/
int cs_connection(int num, char_u *dbpath, char_u *ppath)
{
- int i;
-
if (num < 0 || num > 4 || (num > 0 && !dbpath))
- return FALSE;
+ return false;
- for (i = 0; i < csinfo_size; i++) {
+ for (size_t i = 0; i < csinfo_size; i++) {
if (!csinfo[i].fname)
continue;
@@ -455,7 +454,6 @@ cs_add_common (
char *fname = NULL;
char *fname2 = NULL;
char *ppath = NULL;
- int i;
size_t usedlen = 0;
char_u *fbuf = NULL;
@@ -487,6 +485,7 @@ staterr:
goto staterr;
}
+ int i;
/* if filename is a directory, append the cscope database name to it */
if ((file_info.stat.st_mode & S_IFMT) == S_IFDIR) {
fname2 = (char *)xmalloc(strlen(CSCOPE_DBFILE) + strlen(fname) + 2);
@@ -523,9 +522,10 @@ staterr:
}
if (i != -1) {
- if (cs_create_connection(i) == CSCOPE_FAILURE
- || cs_read_prompt(i) == CSCOPE_FAILURE) {
- cs_release_csp(i, TRUE);
+ assert(i >= 0);
+ if (cs_create_connection((size_t)i) == CSCOPE_FAILURE
+ || cs_read_prompt((size_t)i) == CSCOPE_FAILURE) {
+ cs_release_csp((size_t)i, true);
goto add_err;
}
@@ -565,24 +565,22 @@ static int cs_check_for_tags(void)
*
* count the number of cscope connections
*/
-static int cs_cnt_connections(void)
+static size_t cs_cnt_connections(void)
{
- short i;
- short cnt = 0;
+ size_t cnt = 0;
- for (i = 0; i < csinfo_size; i++) {
+ for (size_t i = 0; i < csinfo_size; i++) {
if (csinfo[i].fname != NULL)
cnt++;
}
return cnt;
} /* cs_cnt_connections */
-static void
-cs_reading_emsg (
- int idx /* connection index */
+static void cs_reading_emsg(
+ size_t idx /* connection index */
)
{
- EMSGN(_("E262: error reading cscope connection %" PRId64), idx);
+ EMSGU(_("E262: error reading cscope connection %" PRIu64), idx);
}
#define CSREAD_BUFSIZE 2048
@@ -591,7 +589,7 @@ cs_reading_emsg (
*
* count the number of matches for a given cscope connection.
*/
-static int cs_cnt_matches(int idx)
+static int cs_cnt_matches(size_t idx)
{
char *stok;
int nlines;
@@ -605,7 +603,7 @@ static int cs_cnt_matches(int idx)
cs_reading_emsg(idx);
xfree(buf);
- return -1;
+ return CSCOPE_FAILURE;
}
/*
@@ -703,12 +701,11 @@ static char *cs_create_cmd(char *csoption, char *pattern)
* This piece of code was taken/adapted from nvi. do we need to add
* the BSD license notice?
*/
-static int cs_create_connection(int i)
+static int cs_create_connection(size_t i)
{
#ifdef UNIX
int to_cs[2], from_cs[2];
#endif
- int len;
char *prog, *cmd, *ppath = NULL;
#if defined(UNIX)
@@ -773,17 +770,17 @@ err_closing:
expand_env(p_csprg, (char_u *)prog, MAXPATHL);
/* alloc space to hold the cscope command */
- len = (int)(strlen(prog) + strlen(csinfo[i].fname) + 32);
+ size_t len = strlen(prog) + strlen(csinfo[i].fname) + 32;
if (csinfo[i].ppath) {
/* expand the prepend path for env var's */
ppath = xmalloc(MAXPATHL + 1);
expand_env((char_u *)csinfo[i].ppath, (char_u *)ppath, MAXPATHL);
- len += (int)strlen(ppath);
+ len += strlen(ppath);
}
if (csinfo[i].flags)
- len += (int)strlen(csinfo[i].flags);
+ len += strlen(csinfo[i].flags);
cmd = xmalloc(len);
@@ -896,7 +893,6 @@ err_closing:
static int cs_find(exarg_T *eap)
{
char *opt, *pat;
- int i;
if (cs_check_for_connections() == FALSE) {
(void)EMSG(_("E567: no cscope connections"));
@@ -918,7 +914,7 @@ static int cs_find(exarg_T *eap)
* Let's replace the NULs written by strtok() with spaces - we need the
* spaces to correctly display the quickfix/location list window's title.
*/
- for (i = 0; i < eap_arg_len; ++i)
+ for (int i = 0; i < eap_arg_len; ++i)
if (NUL == eap->arg[i])
eap->arg[i] = ' ';
@@ -932,12 +928,12 @@ static int cs_find(exarg_T *eap)
*
* common code for cscope find, shared by cs_find() and do_cstag()
*/
-static int cs_find_common(char *opt, char *pat, int forceit, int verbose, int use_ll, char_u *cmdline)
+static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
+ int use_ll, char_u *cmdline)
{
- int i;
char *cmd;
int *nummatches;
- int totmatches;
+ size_t totmatches;
char cmdletter;
char *qfpos;
@@ -1003,10 +999,10 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose, int us
/* Send query to all open connections, then count the total number
* of matches so we can alloc all in one swell foop. */
- for (i = 0; i < csinfo_size; i++)
+ for (size_t i = 0; i < csinfo_size; i++)
nummatches[i] = 0;
totmatches = 0;
- for (i = 0; i < csinfo_size; i++) {
+ for (size_t i = 0; i < csinfo_size; i++) {
if (csinfo[i].fname == NULL || csinfo[i].to_fp == NULL)
continue;
@@ -1017,7 +1013,7 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose, int us
nummatches[i] = cs_cnt_matches(i);
if (nummatches[i] > -1)
- totmatches += nummatches[i];
+ totmatches += (size_t)nummatches[i];
if (nummatches[i] == 0)
(void)cs_read_prompt(i);
@@ -1084,7 +1080,7 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose, int us
return TRUE;
} else {
char **matches = NULL, **contexts = NULL;
- int matched = 0;
+ size_t matched = 0;
/* read output */
cs_fill_results((char *)pat, totmatches, nummatches, &matches,
@@ -1136,11 +1132,11 @@ static int cs_help(exarg_T *eap)
}
wait_return(TRUE);
- return 0;
+ return CSCOPE_SUCCESS;
} /* cs_help */
-static void clear_csinfo(int i)
+static void clear_csinfo(size_t i)
{
csinfo[i].fname = NULL;
csinfo[i].ppath = NULL;
@@ -1175,22 +1171,24 @@ static char *GetWin32Error(void)
static int cs_insert_filelist(char *fname, char *ppath, char *flags,
FileInfo *file_info)
{
- short i, j;
+ size_t i = 0;
+ bool empty_found = false;
- i = -1; /* can be set to the index of an empty item in csinfo */
- for (j = 0; j < csinfo_size; j++) {
+ for (size_t j = 0; j < csinfo_size; j++) {
if (csinfo[j].fname != NULL
&& os_fileid_equal_fileinfo(&(csinfo[j].file_id), file_info)) {
if (p_csverbose)
(void)EMSG(_("E568: duplicate cscope database not added"));
- return -1;
+ return CSCOPE_FAILURE;
}
- if (csinfo[j].fname == NULL && i == -1)
+ if (csinfo[j].fname == NULL && !empty_found) {
i = j; /* remember first empty entry */
+ empty_found = true;
+ }
}
- if (i == -1) {
+ if (!empty_found) {
i = csinfo_size;
if (csinfo_size == 0) {
/* First time allocation: allocate only 1 connection. It should
@@ -1203,7 +1201,7 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags,
csinfo_size *= 2;
csinfo = xrealloc(csinfo, sizeof(csinfo_T)*csinfo_size);
}
- for (j = csinfo_size/2; j < csinfo_size; j++)
+ for (size_t j = csinfo_size/2; j < csinfo_size; j++)
clear_csinfo(j);
}
@@ -1224,7 +1222,8 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags,
csinfo[i].flags = NULL;
os_fileinfo_id(file_info, &(csinfo[i].file_id));
- return i;
+ assert(i <= INT_MAX);
+ return (int)i;
} /* cs_insert_filelist */
@@ -1265,42 +1264,55 @@ static cscmd_T * cs_lookup_cmd(exarg_T *eap)
static int cs_kill(exarg_T *eap)
{
char *stok;
- short i;
+ int num;
+ size_t i = 0;
+ bool killall = false;
if ((stok = strtok((char *)NULL, (const char *)" ")) == NULL) {
cs_usage_msg(Kill);
return CSCOPE_FAILURE;
}
- /* only single digit positive and negative integers are allowed */
+ // Check if string is a number, only single digit
+ // positive and negative integers are allowed
if ((strlen(stok) < 2 && ascii_isdigit((int)(stok[0])))
|| (strlen(stok) < 3 && stok[0] == '-'
- && ascii_isdigit((int)(stok[1]))))
- i = atoi(stok);
- else {
- /* It must be part of a name. We will try to find a match
- * within all the names in the csinfo data structure
- */
+ && ascii_isdigit((int)(stok[1])))) {
+ num = atoi(stok);
+ if (num == -1)
+ killall = true;
+ else if (num >= 0) {
+ i = (size_t)num;
+ } else { // All negative values besides -1 are invalid.
+ if (p_csverbose)
+ (void)EMSG2(_("E261: cscope connection %s not found"), stok);
+ return CSCOPE_FAILURE;
+ }
+ } else {
+ // Else it must be part of a name. We will try to find a match
+ // within all the names in the csinfo data structure
for (i = 0; i < csinfo_size; i++) {
if (csinfo[i].fname != NULL && strstr(csinfo[i].fname, stok))
break;
}
}
- if ((i != -1) && (i >= csinfo_size || i < -1 || csinfo[i].fname == NULL)) {
+ if (i >= csinfo_size || csinfo[i].fname == NULL) {
if (p_csverbose)
(void)EMSG2(_("E261: cscope connection %s not found"), stok);
+ return CSCOPE_FAILURE;
} else {
- if (i == -1) {
+ if (killall) {
for (i = 0; i < csinfo_size; i++) {
if (csinfo[i].fname)
cs_kill_execute(i, csinfo[i].fname);
}
- } else
- cs_kill_execute(i, stok);
+ } else {
+ cs_kill_execute((size_t)i, stok);
+ }
}
- return 0;
+ return CSCOPE_SUCCESS;
} /* cs_kill */
@@ -1309,9 +1321,8 @@ static int cs_kill(exarg_T *eap)
*
* Actually kills a specific cscope connection.
*/
-static void
-cs_kill_execute (
- int i, /* cscope table index */
+static void cs_kill_execute(
+ size_t i, /* cscope table index */
char *cname /* cscope database name */
)
{
@@ -1344,7 +1355,8 @@ cs_kill_execute (
* would still have to be modified to escape all the special regular expression
* characters to comply with ctags formatting.
*/
-static char *cs_make_vim_style_matches(char *fname, char *slno, char *search, char *tagstr)
+static char *cs_make_vim_style_matches(char *fname, char *slno, char *search,
+ char *tagstr)
{
/* vim style is ctags:
*
@@ -1394,12 +1406,13 @@ static char *cs_make_vim_style_matches(char *fname, char *slno, char *search, ch
*
* Print: prints the tags
*/
-static char *cs_manage_matches(char **matches, char **contexts, int totmatches, mcmd_e cmd)
+static char *cs_manage_matches(char **matches, char **contexts,
+ size_t totmatches, mcmd_e cmd)
{
static char **mp = NULL;
static char **cp = NULL;
- static int cnt = -1;
- static int next = -1;
+ static size_t cnt = 0;
+ static size_t next = 0;
char *p = NULL;
switch (cmd) {
@@ -1407,7 +1420,7 @@ static char *cs_manage_matches(char **matches, char **contexts, int totmatches,
assert(matches != NULL);
assert(totmatches > 0);
if (mp != NULL || cp != NULL)
- (void)cs_manage_matches(NULL, NULL, -1, Free);
+ (void)cs_manage_matches(NULL, NULL, 0, Free);
mp = matches;
cp = contexts;
cnt = totmatches;
@@ -1422,12 +1435,11 @@ static char *cs_manage_matches(char **matches, char **contexts, int totmatches,
break;
case Free:
if (mp != NULL) {
- if (cnt > 0)
- while (cnt--) {
- xfree(mp[cnt]);
- if (cp != NULL)
- xfree(cp[cnt]);
- }
+ while (cnt--) {
+ xfree(mp[cnt]);
+ if (cp != NULL)
+ xfree(cp[cnt]);
+ }
xfree(mp);
xfree(cp);
}
@@ -1453,7 +1465,8 @@ static char *cs_manage_matches(char **matches, char **contexts, int totmatches,
*
* parse cscope output
*/
-static char *cs_parse_results(int cnumber, char *buf, int bufsize, char **context, char **linenumber, char **search)
+static char *cs_parse_results(size_t cnumber, char *buf, int bufsize,
+ char **context, char **linenumber, char **search)
{
int ch;
char *p;
@@ -1508,7 +1521,6 @@ static char *cs_parse_results(int cnumber, char *buf, int bufsize, char **contex
*/
static void cs_file_results(FILE *f, int *nummatches_a)
{
- int i, j;
char *search, *slno;
char *fullname;
char *cntx;
@@ -1516,11 +1528,11 @@ static void cs_file_results(FILE *f, int *nummatches_a)
char *buf = xmalloc(CSREAD_BUFSIZE);
- for (i = 0; i < csinfo_size; i++) {
+ for (size_t i = 0; i < csinfo_size; i++) {
if (nummatches_a[i] < 1)
continue;
- for (j = 0; j < nummatches_a[i]; j++) {
+ for (int j = 0; j < nummatches_a[i]; j++) {
if ((fullname = cs_parse_results(i, buf, CSREAD_BUFSIZE, &cntx,
&slno, &search)) == NULL)
continue;
@@ -1554,12 +1566,13 @@ static void cs_file_results(FILE *f, int *nummatches_a)
* into ctags format
* When there are no matches sets "*matches_p" to NULL.
*/
-static void cs_fill_results(char *tagstr, int totmatches, int *nummatches_a, char ***matches_p, char ***cntxts_p, int *matched)
+static void cs_fill_results(char *tagstr, size_t totmatches, int *nummatches_a,
+ char ***matches_p, char ***cntxts_p,
+ size_t *matched)
{
- int i, j;
char *buf;
char *search, *slno;
- int totsofar = 0;
+ size_t totsofar = 0;
char **matches = NULL;
char **cntxts = NULL;
char *fullname;
@@ -1568,14 +1581,14 @@ static void cs_fill_results(char *tagstr, int totmatches, int *nummatches_a, cha
assert(totmatches > 0);
buf = xmalloc(CSREAD_BUFSIZE);
- matches = xmalloc(sizeof(char *) * totmatches);
- cntxts = xmalloc(sizeof(char *) * totmatches);
+ matches = xmalloc(sizeof(char *) * (size_t)totmatches);
+ cntxts = xmalloc(sizeof(char *) * (size_t)totmatches);
- for (i = 0; i < csinfo_size; i++) {
+ for (size_t i = 0; i < csinfo_size; i++) {
if (nummatches_a[i] < 1)
continue;
- for (j = 0; j < nummatches_a[i]; j++) {
+ for (int j = 0; j < nummatches_a[i]; j++) {
if ((fullname = cs_parse_results(i, buf, CSREAD_BUFSIZE, &cntx,
&slno, &search)) == NULL)
continue;
@@ -1617,19 +1630,13 @@ static void cs_fill_results(char *tagstr, int totmatches, int *nummatches_a, cha
/* get the requested path components */
static char *cs_pathcomponents(char *path)
{
- int i;
- char *s;
-
if (p_cspc == 0)
return path;
- s = path + strlen(path) - 1;
- for (i = 0; i < p_cspc; ++i)
- while (s > path && *--s != '/'
- )
- ;
- if ((s > path && *s == '/')
- )
+ char *s = path + strlen(path) - 1;
+ for (int i = 0; i < p_cspc; ++i)
+ while (s > path && *--s != '/') continue;
+ if ((s > path && *s == '/'))
++s;
return s;
}
@@ -1639,11 +1646,12 @@ static char *cs_pathcomponents(char *path)
*
* called from cs_manage_matches()
*/
-static void cs_print_tags_priv(char **matches, char **cntxts, int num_matches)
+static void cs_print_tags_priv(char **matches, char **cntxts,
+ size_t num_matches)
{
char *ptag;
char *fname, *lno, *extra, *tbuf;
- int i, idx, num;
+ size_t num;
char *globalcntx = "GLOBAL";
char *context;
char *cstag_msg = _("Cscope tag: %s");
@@ -1668,8 +1676,8 @@ static void cs_print_tags_priv(char **matches, char **cntxts, int num_matches)
MSG_PUTS_ATTR(_("filename / context / line\n"), hl_attr(HLF_T));
num = 1;
- for (i = 0; i < num_matches; i++) {
- idx = i;
+ for (size_t i = 0; i < num_matches; i++) {
+ size_t idx = i;
/* if we really wanted to, we could avoid this malloc and strcpy
* by parsing matches[i] on the fly and placing stuff into buf
@@ -1688,7 +1696,7 @@ static void cs_print_tags_priv(char **matches, char **cntxts, int num_matches)
lno[strlen(lno)-2] = '\0'; /* ignore ;" at the end */
- const char *csfmt_str = "%4d %6s ";
+ const char *csfmt_str = "%4zu %6s ";
/* hopefully 'num' (num of matches) will be less than 10^16 */
newsize = strlen(csfmt_str) + 16 + strlen(lno);
if (bufsize < newsize) {
@@ -1750,23 +1758,22 @@ static void cs_print_tags_priv(char **matches, char **cntxts, int num_matches)
*
* read a cscope prompt (basically, skip over the ">> ")
*/
-static int cs_read_prompt(int i)
+static int cs_read_prompt(size_t i)
{
- int ch;
+ char ch;
char *buf = NULL; /* buffer for possible error message from cscope */
- int bufpos = 0;
- char *cs_emsg;
- int maxlen;
+ size_t bufpos = 0;
+ char *cs_emsg = _("E609: Cscope error: %s");
+ size_t cs_emsg_len = strlen(cs_emsg);
static char *eprompt = "Press the RETURN key to continue:";
- int epromptlen = (int)strlen(eprompt);
- int n;
+ size_t epromptlen = strlen(eprompt);
- cs_emsg = _("E609: Cscope error: %s");
/* compute maximum allowed len for Cscope error message */
- maxlen = (int)(IOSIZE - strlen(cs_emsg));
+ assert(IOSIZE >= cs_emsg_len);
+ size_t maxlen = IOSIZE - cs_emsg_len;
for (;; ) {
- while ((ch = getc(csinfo[i].fr_fp)) != EOF && ch != CSCOPE_PROMPT[0])
+ while ((ch = (char)getc(csinfo[i].fr_fp)) != EOF && ch != CSCOPE_PROMPT[0])
/* if there is room and char is printable */
if (bufpos < maxlen - 1 && vim_isprintc(ch)) {
// lazy buffer allocation
@@ -1796,9 +1803,9 @@ static int cs_read_prompt(int i)
}
}
- for (n = 0; n < (int)strlen(CSCOPE_PROMPT); ++n) {
+ for (size_t n = 0; n < strlen(CSCOPE_PROMPT); ++n) {
if (n > 0)
- ch = getc(csinfo[i].fr_fp);
+ ch = (char)getc(csinfo[i].fr_fp);
if (ch == EOF) {
PERROR("cs_read_prompt EOF");
if (buf != NULL && buf[0] != NUL)
@@ -1842,7 +1849,7 @@ static void sig_handler(int s) {
* Does the actual free'ing for the cs ptr with an optional flag of whether
* or not to free the filename. Called by cs_kill and cs_reset.
*/
-static void cs_release_csp(int i, int freefnpp)
+static void cs_release_csp(size_t i, int freefnpp)
{
/*
* Trying to exit normally (not sure whether it is fit to UNIX cscope
@@ -1963,8 +1970,7 @@ static void cs_release_csp(int i, int freefnpp)
static int cs_reset(exarg_T *eap)
{
char **dblist = NULL, **pplist = NULL, **fllist = NULL;
- int i;
- char buf[20]; /* for sprintf " (#%d)" */
+ char buf[20]; /* for snprintf " (#%zu)" */
if (csinfo_size == 0)
return CSCOPE_SUCCESS;
@@ -1974,7 +1980,7 @@ static int cs_reset(exarg_T *eap)
pplist = xmalloc(csinfo_size * sizeof(char *));
fllist = xmalloc(csinfo_size * sizeof(char *));
- for (i = 0; i < csinfo_size; i++) {
+ for (size_t i = 0; i < csinfo_size; i++) {
dblist[i] = csinfo[i].fname;
pplist[i] = csinfo[i].ppath;
fllist[i] = csinfo[i].flags;
@@ -1983,7 +1989,7 @@ static int cs_reset(exarg_T *eap)
}
/* rebuild the cscope connection list */
- for (i = 0; i < csinfo_size; i++) {
+ for (size_t i = 0; i < csinfo_size; i++) {
if (dblist[i] != NULL) {
cs_add_common(dblist[i], pplist[i], fllist[i]);
if (p_csverbose) {
@@ -1991,7 +1997,7 @@ static int cs_reset(exarg_T *eap)
* connection number in the same line as
* "Added cscope database..."
*/
- sprintf(buf, " (#%d)", i);
+ snprintf(buf, ARRAY_SIZE(buf), " (#%zu)", i);
MSG_PUTS_ATTR(buf, hl_attr(HLF_R));
}
}
@@ -2020,7 +2026,7 @@ static int cs_reset(exarg_T *eap)
* ships with Solaris 2.6), the output never has the prefix prepended.
* Contrast this with my development system (Digital Unix), which does.
*/
-static char *cs_resolve_file(int i, char *name)
+static char *cs_resolve_file(size_t i, char *name)
{
char *fullname;
char_u *csdir = NULL;
@@ -2072,22 +2078,21 @@ static char *cs_resolve_file(int i, char *name)
*/
static int cs_show(exarg_T *eap)
{
- short i;
if (cs_cnt_connections() == 0)
MSG_PUTS(_("no cscope connections\n"));
else {
MSG_PUTS_ATTR(
_(" # pid database name prepend path\n"),
hl_attr(HLF_T));
- for (i = 0; i < csinfo_size; i++) {
+ for (size_t i = 0; i < csinfo_size; i++) {
if (csinfo[i].fname == NULL)
continue;
if (csinfo[i].ppath != NULL)
- (void)smsg("%2d %-5ld %-34s %-32s",
+ (void)smsg("%2zu %-5" PRId64 " %-34s %-32s",
i, (long)csinfo[i].pid, csinfo[i].fname, csinfo[i].ppath);
else
- (void)smsg("%2d %-5ld %-34s <none>",
+ (void)smsg("%2zu %-5" PRId64 " %-34s <none>",
i, (long)csinfo[i].pid, csinfo[i].fname);
}
}
@@ -2104,10 +2109,8 @@ static int cs_show(exarg_T *eap)
*/
void cs_end(void)
{
- int i;
-
- for (i = 0; i < csinfo_size; i++)
- cs_release_csp(i, TRUE);
+ for (size_t i = 0; i < csinfo_size; i++)
+ cs_release_csp(i, true);
xfree(csinfo);
csinfo_size = 0;
}
diff --git a/src/nvim/menu.c b/src/nvim/menu.c
index 434b92450c..1dece58dfe 100644
--- a/src/nvim/menu.c
+++ b/src/nvim/menu.c
@@ -65,7 +65,7 @@ ex_menu (
char_u *map_to;
int noremap;
bool silent = false;
- int special = FALSE;
+ bool special = false;
int unmenu;
char_u *map_buf;
char_u *arg;
@@ -91,7 +91,7 @@ ex_menu (
continue;
}
if (STRNCMP(arg, "<special>", 9) == 0) {
- special = TRUE;
+ special = true;
arg = skipwhite(arg + 9);
continue;
}
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 5b35af9209..467b74f9e6 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -4213,18 +4213,12 @@ void do_nv_ident(int c1, int c2)
static void nv_ident(cmdarg_T *cap)
{
char_u *ptr = NULL;
- char_u *buf;
- char_u *newbuf;
char_u *p;
- char_u *kp; /* value of 'keywordprg' */
- bool kp_help; /* 'keywordprg' is ":help" */
size_t n = 0; /* init for GCC */
int cmdchar;
bool g_cmd; /* "g" command */
bool tag_cmd = false;
char_u *aux_ptr;
- bool isman;
- bool isman_s;
if (cap->cmdchar == 'g') { /* "g*", "g#", "g]" and "gCTRL-]" */
cmdchar = cap->nchar;
@@ -4259,10 +4253,11 @@ static void nv_ident(cmdarg_T *cap)
/* Allocate buffer to put the command in. Inserting backslashes can
* double the length of the word. p_kp / curbuf->b_p_kp could be added
* and some numbers. */
- kp = (*curbuf->b_p_kp == NUL ? p_kp : curbuf->b_p_kp);
- kp_help = (*kp == NUL || STRCMP(kp, ":he") == 0
- || STRCMP(kp, ":help") == 0);
- buf = xmalloc(n * 2 + 30 + STRLEN(kp));
+ char_u *kp = *curbuf->b_p_kp == NUL ? p_kp : curbuf->b_p_kp; // 'keywordprg'
+ assert(*kp != NUL); // option.c:do_set() should default to ":help" if empty.
+ bool kp_ex = (*kp == ':'); // 'keywordprg' is an ex command
+ size_t buf_size = n * 2 + 30 + STRLEN(kp);
+ char *buf = xmalloc(buf_size);
buf[0] = NUL;
switch (cmdchar) {
@@ -4283,9 +4278,13 @@ static void nv_ident(cmdarg_T *cap)
break;
case 'K':
- if (kp_help)
- STRCPY(buf, "he! ");
- else {
+ if (kp_ex) {
+ if (cap->count0 != 0) { // Send the count to the ex command.
+ snprintf(buf, buf_size, "%" PRId64, (int64_t)(cap->count0));
+ }
+ STRCAT(buf, kp);
+ STRCAT(buf, " ");
+ } else {
/* An external command will probably use an argument starting
* with "-" as an option. To avoid trouble we skip the "-". */
while (*ptr == '-' && n > 0) {
@@ -4300,19 +4299,22 @@ static void nv_ident(cmdarg_T *cap)
/* When a count is given, turn it into a range. Is this
* really what we want? */
- isman = (STRCMP(kp, "man") == 0);
- isman_s = (STRCMP(kp, "man -s") == 0);
- if (cap->count0 != 0 && !(isman || isman_s))
- sprintf((char *)buf, ".,.+%" PRId64, (int64_t)(cap->count0 - 1));
+ bool isman = (STRCMP(kp, "man") == 0);
+ bool isman_s = (STRCMP(kp, "man -s") == 0);
+ if (cap->count0 != 0 && !(isman || isman_s)) {
+ snprintf(buf, buf_size, ".,.+%" PRId64, (int64_t)(cap->count0 - 1));
+ }
STRCAT(buf, "! ");
- if (cap->count0 == 0 && isman_s)
+ if (cap->count0 == 0 && isman_s) {
STRCAT(buf, "man");
- else
+ } else {
STRCAT(buf, kp);
+ }
STRCAT(buf, " ");
if (cap->count0 != 0 && (isman || isman_s)) {
- sprintf((char *)buf + STRLEN(buf), "%" PRId64, (int64_t)cap->count0);
+ snprintf(buf + STRLEN(buf), buf_size - STRLEN(buf), "%" PRId64,
+ (int64_t)cap->count0);
STRCAT(buf, " ");
}
}
@@ -4334,19 +4336,19 @@ static void nv_ident(cmdarg_T *cap)
if (g_cmd)
STRCPY(buf, "tj ");
else
- sprintf((char *)buf, "%" PRId64 "ta ", (int64_t)cap->count0);
+ snprintf(buf, buf_size, "%" PRId64 "ta ", (int64_t)cap->count0);
}
}
/*
* Now grab the chars in the identifier
*/
- if (cmdchar == 'K' && !kp_help) {
+ if (cmdchar == 'K' && !kp_ex) {
/* Escape the argument properly for a shell command */
ptr = vim_strnsave(ptr, n);
p = vim_strsave_shellescape(ptr, true, true);
xfree(ptr);
- newbuf = (char_u *)xrealloc(buf, STRLEN(buf) + STRLEN(p) + 1);
+ char *newbuf = xrealloc(buf, STRLEN(buf) + STRLEN(p) + 1);
buf = newbuf;
STRCAT(buf, p);
xfree(p);
@@ -4364,7 +4366,7 @@ static void nv_ident(cmdarg_T *cap)
} else
aux_ptr = (char_u *)"\\|\"\n*?[";
- p = buf + STRLEN(buf);
+ p = (char_u *)buf + STRLEN(buf);
while (n-- > 0) {
/* put a backslash before \ and some others */
if (vim_strchr(aux_ptr, *ptr) != NULL)
@@ -4391,10 +4393,11 @@ static void nv_ident(cmdarg_T *cap)
STRCAT(buf, "\\>");
/* put pattern in search history */
init_history();
- add_to_history(HIST_SEARCH, buf, true, NUL);
- (void)normal_search(cap, cmdchar == '*' ? '/' : '?', buf, 0);
- } else
- do_cmdline_cmd((char *)buf);
+ add_to_history(HIST_SEARCH, (char_u *)buf, true, NUL);
+ (void)normal_search(cap, cmdchar == '*' ? '/' : '?', (char_u *)buf, 0);
+ } else {
+ do_cmdline_cmd(buf);
+ }
xfree(buf);
}
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index 14f912f9e8..ca3882b8a0 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -1329,9 +1329,7 @@ return {
expand=true,
varname='p_kp',
defaults={
- condition='USEMAN_S',
- if_true={vi="man -s"},
- if_false={vi="man"},
+ if_true={vi=":Man"},
}
},
{
@@ -2662,7 +2660,7 @@ return {
deny_duplicates=true,
vim=true,
varname='p_wim',
- defaults={if_true={vi="", vim="list:longest,full"}}
+ defaults={if_true={vi="", vim="full"}}
},
{
full_name='wildoptions', abbreviation='wop',
diff --git a/src/nvim/path.c b/src/nvim/path.c
index 45ae12b78a..a9d1d052d4 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.c
@@ -2083,7 +2083,7 @@ static int path_get_absolute_path(const char_u *fname, char_u *buf, int len, int
char_u *p;
*buf = NUL;
- char relative_directory[len];
+ char *relative_directory = xmalloc(len);
char *end_of_path = (char *) fname;
// expand it if forced or not an absolute path
@@ -2105,9 +2105,11 @@ static int path_get_absolute_path(const char_u *fname, char_u *buf, int len, int
}
if (FAIL == path_full_dir_name(relative_directory, (char *) buf, len)) {
+ xfree(relative_directory);
return FAIL;
}
}
+ xfree(relative_directory);
return append_path((char *)buf, end_of_path, len);
}
diff --git a/test/functional/normal/K_spec.lua b/test/functional/normal/K_spec.lua
new file mode 100644
index 0000000000..dbda6dcb93
--- /dev/null
+++ b/test/functional/normal/K_spec.lua
@@ -0,0 +1,39 @@
+local helpers = require('test.functional.helpers')
+local execute, eq, clear, eval, feed, ok =
+ helpers.execute, helpers.eq, helpers.clear, helpers.eval,
+ helpers.feed, helpers.ok
+
+describe('K', function()
+ local test_file = 'K_spec_out'
+ before_each(function()
+ clear()
+ os.remove(test_file)
+ end)
+ after_each(function()
+ os.remove(test_file)
+ end)
+
+ it("invokes colon-prefixed 'keywordprg' as Vim command", function()
+ helpers.source([[
+ let @a='fnord'
+ set keywordprg=:put]])
+
+ -- K on the text "a" resolves to `:put a`.
+ feed('ia<ESC>K')
+ helpers.expect([[
+ a
+ fnord]])
+ end)
+
+ it("invokes non-prefixed 'keywordprg' as shell command", function()
+ helpers.source([[
+ let @a='fnord'
+ set keywordprg=echo\ fnord\ >>]])
+
+ -- K on the text "K_spec_out" resolves to `!echo fnord >> K_spec_out`.
+ feed('i'..test_file..'<ESC>K')
+ feed('<CR>') -- Press ENTER
+ eq({'fnord'}, eval("readfile('"..test_file.."')"))
+ end)
+
+end)
diff --git a/test/functional/provider/python3_spec.lua b/test/functional/provider/python3_spec.lua
index 5be5390370..5ecc1a0a91 100644
--- a/test/functional/provider/python3_spec.lua
+++ b/test/functional/provider/python3_spec.lua
@@ -1,19 +1,19 @@
+local helpers = require('test.functional.helpers')
+local eval, command, feed = helpers.eval, helpers.command, helpers.feed
+local eq, clear, insert = helpers.eq, helpers.clear, helpers.insert
+local expect, write_file = helpers.expect, helpers.write_file
+
do
- local proc = io.popen(
- [[python3 -c 'import neovim, sys; sys.stdout.write("ok")' 2> /dev/null]])
- if proc:read() ~= 'ok' then
+ command('let [g:interp, g:errors] = provider#pythonx#Detect(3)')
+ local errors = eval('g:errors')
+ if errors ~= '' then
pending(
- 'python3 (or the python3 neovim module) is broken or missing',
+ 'Python 3 (or the Python 3 neovim module) is broken or missing:\n' .. errors,
function() end)
return
end
end
-local helpers = require('test.functional.helpers')
-local eval, command, feed = helpers.eval, helpers.command, helpers.feed
-local eq, clear, insert = helpers.eq, helpers.clear, helpers.insert
-local expect, write_file = helpers.expect, helpers.write_file
-
describe('python3 commands and functions', function()
before_each(function()
clear()
diff --git a/test/functional/provider/python_spec.lua b/test/functional/provider/python_spec.lua
index ec1a853546..f37c16a26a 100644
--- a/test/functional/provider/python_spec.lua
+++ b/test/functional/provider/python_spec.lua
@@ -1,19 +1,19 @@
+local helpers = require('test.functional.helpers')
+local eval, command, feed = helpers.eval, helpers.command, helpers.feed
+local eq, clear, insert = helpers.eq, helpers.clear, helpers.insert
+local expect, write_file = helpers.expect, helpers.write_file
+
do
- local proc = io.popen(
- [[python -c 'import neovim, sys; sys.stdout.write("ok")' 2> /dev/null]])
- if proc:read() ~= 'ok' then
+ command('let [g:interp, g:errors] = provider#pythonx#Detect(2)')
+ local errors = eval('g:errors')
+ if errors ~= '' then
pending(
- 'python (or the python neovim module) is broken or missing',
+ 'Python 2 (or the Python 2 neovim module) is broken or missing:\n' .. errors,
function() end)
return
end
end
-local helpers = require('test.functional.helpers')
-local eval, command, feed = helpers.eval, helpers.command, helpers.feed
-local eq, clear, insert = helpers.eq, helpers.clear, helpers.insert
-local expect, write_file = helpers.expect, helpers.write_file
-
describe('python commands and functions', function()
before_each(function()
clear()
diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt
index b56f07adc4..4790eb3817 100644
--- a/third-party/CMakeLists.txt
+++ b/third-party/CMakeLists.txt
@@ -92,8 +92,8 @@ set(LIBTERMKEY_SHA256 21846369081e6c9a0b615f4b3889c4cb809321c5ccc6e6c1640eb138f1
set(LIBVTERM_URL https://github.com/neovim/libvterm/archive/1b745d29d45623aa8d22a7b9288c7b0e331c7088.tar.gz)
set(LIBVTERM_SHA256 3fc75908256c0d158d6c2a32d39f34e86bfd26364f5404b7d9c03bb70cdc3611)
-set(JEMALLOC_URL https://github.com/jemalloc/jemalloc/releases/download/3.6.0/jemalloc-3.6.0.tar.bz2)
-set(JEMALLOC_SHA256 e16c2159dd3c81ca2dc3b5c9ef0d43e1f2f45b04548f42db12e7c12d7bdf84fe)
+set(JEMALLOC_URL https://github.com/jemalloc/jemalloc/releases/download/4.0.2/jemalloc-4.0.2.tar.bz2)
+set(JEMALLOC_SHA256 0d8a9c8a98adb6983e0ccb521d45d9db1656ef3e71d0b14fb333f2c8138f4611)
if(USE_BUNDLED_UNIBILIUM)
include(BuildUnibilium)
diff --git a/third-party/cmake/BuildJeMalloc.cmake b/third-party/cmake/BuildJeMalloc.cmake
index 5aaad2f25c..8b0fac36a4 100644
--- a/third-party/cmake/BuildJeMalloc.cmake
+++ b/third-party/cmake/BuildJeMalloc.cmake
@@ -16,7 +16,7 @@ ExternalProject_Add(jemalloc
-DUSE_EXISTING_SRC_DIR=${USE_EXISTING_SRC_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/DownloadAndExtractFile.cmake
BUILD_IN_SOURCE 1
- CONFIGURE_COMMAND ${DEPS_BUILD_DIR}/src/jemalloc/configure --enable-cc-silence
+ CONFIGURE_COMMAND ${DEPS_BUILD_DIR}/src/jemalloc/configure
CC=${DEPS_C_COMPILER} --prefix=${DEPS_INSTALL_DIR}
BUILD_COMMAND ""
INSTALL_COMMAND ${MAKE_PRG} install_include install_lib)