aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.git-blame-ignore-revs20
-rwxr-xr-x.gitattributes1
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.yml6
-rw-r--r--.github/workflows/ci.yml26
-rw-r--r--.github/workflows/commitlint.config.js35
-rw-r--r--.github/workflows/commitlint.config_patch.js27
-rw-r--r--.github/workflows/commitlint.yml17
-rw-r--r--.github/workflows/labeler.yml16
-rw-r--r--.travis.yml2
-rw-r--r--CMakeLists.txt8
-rw-r--r--CONTRIBUTING.md30
-rw-r--r--LICENSE1
-rw-r--r--MAINTAIN.md22
-rw-r--r--Makefile8
-rwxr-xr-xci/before_install.sh13
-rw-r--r--ci/build.ps12
-rw-r--r--cmake/FindLibUV.cmake8
-rw-r--r--cmake/RunTests.cmake1
-rw-r--r--runtime/autoload/csscomplete.vim6
-rw-r--r--runtime/autoload/health.vim126
-rw-r--r--runtime/autoload/health/lsp.vim5
-rw-r--r--runtime/autoload/health/provider.vim2
-rw-r--r--runtime/autoload/health/treesitter.vim5
-rw-r--r--runtime/autoload/man.vim12
-rw-r--r--runtime/autoload/netrw.vim3
-rw-r--r--runtime/autoload/provider/pythonx.vim2
-rw-r--r--runtime/doc/api.txt631
-rw-r--r--runtime/doc/autocmd.txt49
-rw-r--r--runtime/doc/change.txt6
-rw-r--r--runtime/doc/deprecated.txt4
-rw-r--r--runtime/doc/dev_style.txt1159
-rw-r--r--runtime/doc/develop.txt2
-rw-r--r--runtime/doc/diagnostic.txt225
-rw-r--r--runtime/doc/editing.txt50
-rw-r--r--runtime/doc/eval.txt482
-rw-r--r--runtime/doc/filetype.txt8
-rw-r--r--runtime/doc/helphelp.txt12
-rw-r--r--runtime/doc/intro.txt3
-rw-r--r--runtime/doc/lsp.txt70
-rw-r--r--runtime/doc/lua.txt103
-rw-r--r--runtime/doc/mbyte.txt30
-rw-r--r--runtime/doc/nvim_terminal_emulator.txt6
-rw-r--r--runtime/doc/options.txt17
-rw-r--r--runtime/doc/pattern.txt2
-rw-r--r--runtime/doc/pi_health.txt153
-rw-r--r--runtime/doc/print.txt2
-rw-r--r--runtime/doc/starting.txt3
-rw-r--r--runtime/doc/treesitter.txt8
-rw-r--r--runtime/doc/usr_22.txt24
-rw-r--r--runtime/doc/usr_41.txt6
-rw-r--r--runtime/doc/various.txt2
-rw-r--r--runtime/doc/vim_diff.txt11
-rw-r--r--runtime/filetype.vim27
-rw-r--r--runtime/ftplugin/8th.vim10
-rw-r--r--runtime/ftplugin/c.vim10
-rw-r--r--runtime/ftplugin/context.vim67
-rw-r--r--runtime/ftplugin/csh.vim49
-rw-r--r--runtime/ftplugin/gprof.vim22
-rw-r--r--runtime/ftplugin/nginx.vim6
-rw-r--r--runtime/ftplugin/spec.vim4
-rw-r--r--runtime/ftplugin/tcsh.vim21
-rw-r--r--runtime/ftplugin/tmux.vim3
-rw-r--r--runtime/ftplugin/toml.vim23
-rw-r--r--runtime/indent/cdl.vim3
-rw-r--r--runtime/indent/cobol.vim3
-rw-r--r--runtime/indent/config.vim13
-rw-r--r--runtime/indent/css.vim12
-rw-r--r--runtime/indent/d.vim4
-rw-r--r--runtime/indent/dtd.vim9
-rw-r--r--runtime/indent/dylan.vim3
-rw-r--r--runtime/indent/elm.vim4
-rw-r--r--runtime/indent/eterm.vim9
-rw-r--r--runtime/indent/framescript.vim9
-rw-r--r--runtime/indent/hamster.vim21
-rw-r--r--runtime/indent/idlang.vim5
-rw-r--r--runtime/indent/ld.vim9
-rw-r--r--runtime/indent/mail.vim4
-rw-r--r--runtime/indent/make.vim9
-rw-r--r--runtime/indent/matlab.vim2
-rw-r--r--runtime/indent/mma.vim11
-rw-r--r--runtime/indent/nginx.vim17
-rw-r--r--runtime/indent/occam.vim3
-rw-r--r--runtime/indent/pascal.vim15
-rw-r--r--runtime/indent/postscr.vim7
-rw-r--r--runtime/indent/prolog.vim7
-rw-r--r--runtime/indent/python.vim4
-rw-r--r--runtime/indent/readline.vim9
-rw-r--r--runtime/indent/sdl.vim4
-rw-r--r--runtime/indent/sqlanywhere.vim22
-rw-r--r--runtime/indent/tcl.vim8
-rw-r--r--runtime/indent/tcsh.vim14
-rw-r--r--runtime/indent/zimbu.vim4
-rw-r--r--runtime/lua/health.lua23
-rw-r--r--runtime/lua/vim/diagnostic.lua543
-rw-r--r--runtime/lua/vim/lsp.lua172
-rw-r--r--runtime/lua/vim/lsp/buf.lua137
-rw-r--r--runtime/lua/vim/lsp/codelens.lua42
-rw-r--r--runtime/lua/vim/lsp/diagnostic.lua47
-rw-r--r--runtime/lua/vim/lsp/handlers.lua35
-rw-r--r--runtime/lua/vim/lsp/health.lua2
-rw-r--r--runtime/lua/vim/lsp/protocol.lua4
-rw-r--r--runtime/lua/vim/lsp/rpc.lua87
-rw-r--r--runtime/lua/vim/lsp/util.lua22
-rw-r--r--runtime/lua/vim/shared.lua46
-rw-r--r--runtime/lua/vim/treesitter/health.lua2
-rw-r--r--runtime/lua/vim/ui.lua36
-rw-r--r--runtime/lua/vim/uri.lua11
-rw-r--r--runtime/plugin/diagnostic.vim26
-rw-r--r--runtime/syntax/8th.vim535
-rw-r--r--runtime/syntax/chicken.vim4
-rw-r--r--runtime/syntax/css.vim27
-rw-r--r--runtime/syntax/go.vim6
-rw-r--r--runtime/syntax/gprof.vim5
-rw-r--r--runtime/syntax/nginx.vim2307
-rw-r--r--runtime/syntax/php.vim267
-rw-r--r--runtime/syntax/sml.vim7
-rw-r--r--runtime/syntax/tcl.vim4
-rw-r--r--runtime/syntax/tcsh.vim65
-rw-r--r--runtime/syntax/tmux.vim103
-rw-r--r--runtime/syntax/toml.vim81
-rw-r--r--runtime/syntax/typescriptcommon.vim5
-rw-r--r--runtime/syntax/xpm.vim7
-rwxr-xr-xscripts/finddeclarations.pl50
-rwxr-xr-xscripts/gen_vimdoc.py9
-rw-r--r--scripts/lintcommit.lua4
-rwxr-xr-xscripts/pvscheck.sh5
-rwxr-xr-xscripts/release.sh4
-rw-r--r--scripts/squash_typos.py94
-rwxr-xr-xscripts/vim-patch.sh43
-rw-r--r--src/cjson/fpconv.c211
-rw-r--r--src/cjson/fpconv.h22
-rw-r--r--src/cjson/lua_cjson.c1655
-rw-r--r--src/cjson/lua_cjson.h10
-rw-r--r--src/cjson/strbuf.c251
-rw-r--r--src/cjson/strbuf.h159
-rwxr-xr-xsrc/clint.py1
-rw-r--r--src/mpack/conv.c4
-rw-r--r--src/mpack/lmpack.c9
-rw-r--r--src/mpack/mpack_core.c3
-rw-r--r--src/mpack/object.c3
-rw-r--r--src/mpack/rpc.c3
-rw-r--r--src/nvim/CMakeLists.txt21
-rw-r--r--src/nvim/api/buffer.c501
-rw-r--r--src/nvim/api/deprecated.c16
-rw-r--r--src/nvim/api/keysets.lua62
-rw-r--r--src/nvim/api/private/defs.h16
-rw-r--r--src/nvim/api/private/dispatch.c3
-rw-r--r--src/nvim/api/private/helpers.c582
-rw-r--r--src/nvim/api/private/helpers.h16
-rw-r--r--src/nvim/api/ui.c3
-rw-r--r--src/nvim/api/vim.c515
-rw-r--r--src/nvim/api/win_config.c639
-rw-r--r--src/nvim/api/win_config.h11
-rw-r--r--src/nvim/api/window.c111
-rw-r--r--src/nvim/arabic.h4
-rw-r--r--src/nvim/ascii.h2
-rw-r--r--src/nvim/assert.h40
-rw-r--r--src/nvim/autocmd.c27
-rw-r--r--src/nvim/autocmd.h30
-rw-r--r--src/nvim/buffer.c285
-rw-r--r--src/nvim/buffer.h48
-rw-r--r--src/nvim/buffer_defs.h332
-rw-r--r--src/nvim/change.c31
-rw-r--r--src/nvim/channel.c8
-rw-r--r--src/nvim/channel.h51
-rw-r--r--src/nvim/charset.c30
-rw-r--r--src/nvim/charset.h6
-rw-r--r--src/nvim/context.h1
-rw-r--r--src/nvim/cursor.c8
-rw-r--r--src/nvim/cursor_shape.c5
-rw-r--r--src/nvim/cursor_shape.h44
-rw-r--r--src/nvim/debugger.c72
-rw-r--r--src/nvim/decoration.c68
-rw-r--r--src/nvim/decoration.h16
-rw-r--r--src/nvim/diff.c170
-rw-r--r--src/nvim/diff.h2
-rw-r--r--src/nvim/digraph.c32
-rw-r--r--src/nvim/digraph.h2
-rw-r--r--src/nvim/edit.c36
-rw-r--r--src/nvim/edit.h38
-rw-r--r--src/nvim/eval.c2214
-rw-r--r--src/nvim/eval.h260
-rw-r--r--src/nvim/eval.lua217
-rw-r--r--src/nvim/eval/decode.h3
-rw-r--r--src/nvim/eval/encode.c24
-rw-r--r--src/nvim/eval/encode.h6
-rw-r--r--src/nvim/eval/funcs.c406
-rw-r--r--src/nvim/eval/typval.c12
-rw-r--r--src/nvim/eval/typval.h177
-rw-r--r--src/nvim/eval/typval_encode.c.h789
-rw-r--r--src/nvim/eval/typval_encode.h38
-rw-r--r--src/nvim/eval/userfunc.c118
-rw-r--r--src/nvim/eval/userfunc.h2
-rw-r--r--src/nvim/event/defs.h2
-rw-r--r--src/nvim/event/loop.h7
-rw-r--r--src/nvim/event/process.h2
-rw-r--r--src/nvim/event/rstream.h1
-rw-r--r--src/nvim/event/stream.c2
-rw-r--r--src/nvim/event/stream.h3
-rw-r--r--src/nvim/event/wstream.h3
-rw-r--r--src/nvim/ex_cmds.c201
-rw-r--r--src/nvim/ex_cmds.h14
-rw-r--r--src/nvim/ex_cmds2.c390
-rw-r--r--src/nvim/ex_cmds2.h25
-rw-r--r--src/nvim/ex_cmds_defs.h26
-rw-r--r--src/nvim/ex_docmd.c278
-rw-r--r--src/nvim/ex_docmd.h3
-rw-r--r--src/nvim/ex_eval.c533
-rw-r--r--src/nvim/ex_eval.h56
-rw-r--r--src/nvim/ex_getln.c1368
-rw-r--r--src/nvim/ex_getln.h2
-rw-r--r--src/nvim/ex_session.c74
-rw-r--r--src/nvim/extmark.c116
-rw-r--r--src/nvim/extmark.h2
-rw-r--r--src/nvim/extmark_defs.h12
-rw-r--r--src/nvim/file_search.c782
-rw-r--r--src/nvim/file_search.h14
-rw-r--r--src/nvim/fileio.c238
-rw-r--r--src/nvim/fileio.h2
-rw-r--r--src/nvim/fold.c134
-rw-r--r--src/nvim/fold.h6
-rw-r--r--src/nvim/func_attr.h26
-rw-r--r--src/nvim/garray.c29
-rw-r--r--src/nvim/garray.h4
-rw-r--r--src/nvim/generators/c_grammar.lua4
-rw-r--r--src/nvim/generators/gen_api_dispatch.lua65
-rwxr-xr-xsrc/nvim/generators/gen_declarations.lua15
-rw-r--r--src/nvim/generators/gen_keysets.lua67
-rw-r--r--src/nvim/generators/hashy.lua122
-rw-r--r--src/nvim/getchar.c769
-rw-r--r--src/nvim/getchar.h6
-rw-r--r--src/nvim/globals.h239
-rw-r--r--src/nvim/grid_defs.h6
-rw-r--r--src/nvim/hardcopy.c750
-rw-r--r--src/nvim/hardcopy.h16
-rw-r--r--src/nvim/hashtab.c16
-rw-r--r--src/nvim/hashtab.h20
-rw-r--r--src/nvim/highlight.c136
-rw-r--r--src/nvim/highlight.h5
-rw-r--r--src/nvim/highlight_defs.h109
-rw-r--r--src/nvim/iconv.h18
-rw-r--r--src/nvim/if_cscope.c455
-rw-r--r--src/nvim/if_cscope.h4
-rw-r--r--src/nvim/if_cscope_defs.h30
-rw-r--r--src/nvim/indent.c23
-rw-r--r--src/nvim/indent_c.c2
-rw-r--r--src/nvim/keymap.c197
-rw-r--r--src/nvim/keymap.h228
-rw-r--r--src/nvim/lib/kbtree.h743
-rw-r--r--src/nvim/lib/khash.h503
-rw-r--r--src/nvim/lib/klist.h156
-rw-r--r--src/nvim/lib/kvec.h111
-rw-r--r--src/nvim/lib/queue.h2
-rw-r--r--src/nvim/lib/ringbuf.h391
-rw-r--r--src/nvim/log.c25
-rw-r--r--src/nvim/log.h10
-rw-r--r--src/nvim/lua/converter.c52
-rw-r--r--src/nvim/lua/converter.h2
-rw-r--r--src/nvim/lua/executor.c10
-rw-r--r--src/nvim/lua/executor.h16
-rw-r--r--src/nvim/lua/treesitter.c14
-rw-r--r--src/nvim/lua/treesitter.h2
-rw-r--r--src/nvim/lua/vim.lua54
-rw-r--r--src/nvim/lua/xdiff.c21
-rw-r--r--src/nvim/lua/xdiff.h2
-rw-r--r--src/nvim/macros.h68
-rw-r--r--src/nvim/main.c909
-rw-r--r--src/nvim/main.h2
-rw-r--r--src/nvim/map.c24
-rw-r--r--src/nvim/map.h6
-rw-r--r--src/nvim/map_defs.h4
-rw-r--r--src/nvim/mark.c575
-rw-r--r--src/nvim/mark.h56
-rw-r--r--src/nvim/mark_defs.h6
-rw-r--r--src/nvim/marktree.c59
-rw-r--r--src/nvim/marktree.h5
-rw-r--r--src/nvim/math.c9
-rw-r--r--src/nvim/mbyte.c74
-rw-r--r--src/nvim/mbyte.h26
-rw-r--r--src/nvim/memfile.c116
-rw-r--r--src/nvim/memfile_defs.h4
-rw-r--r--src/nvim/memline.c1554
-rw-r--r--src/nvim/memline.h4
-rw-r--r--src/nvim/memline_defs.h8
-rw-r--r--src/nvim/memory.c142
-rw-r--r--src/nvim/memory.h2
-rw-r--r--src/nvim/menu.c520
-rw-r--r--src/nvim/menu.h6
-rw-r--r--src/nvim/message.c621
-rw-r--r--src/nvim/message.h18
-rw-r--r--src/nvim/misc1.c273
-rw-r--r--src/nvim/misc1.h14
-rw-r--r--src/nvim/mouse.c186
-rw-r--r--src/nvim/mouse.h2
-rw-r--r--src/nvim/move.c446
-rw-r--r--src/nvim/move.h1
-rw-r--r--src/nvim/msgpack_rpc/channel.c14
-rw-r--r--src/nvim/msgpack_rpc/channel.h4
-rw-r--r--src/nvim/msgpack_rpc/channel_defs.h4
-rw-r--r--src/nvim/msgpack_rpc/helpers.c148
-rw-r--r--src/nvim/msgpack_rpc/helpers.h8
-rw-r--r--src/nvim/normal.c105
-rw-r--r--src/nvim/normal.h43
-rw-r--r--src/nvim/ops.c128
-rw-r--r--src/nvim/ops.h17
-rw-r--r--src/nvim/option.c1545
-rw-r--r--src/nvim/option.h8
-rw-r--r--src/nvim/option_defs.h696
-rw-r--r--src/nvim/os/env.c10
-rw-r--r--src/nvim/os/fs.c10
-rw-r--r--src/nvim/os/input.h2
-rw-r--r--src/nvim/os/os.h4
-rw-r--r--src/nvim/os/os_defs.h2
-rw-r--r--src/nvim/os/os_win_console.c26
-rw-r--r--src/nvim/os/process.h1
-rw-r--r--src/nvim/os/pty_process_unix.c2
-rw-r--r--src/nvim/os/shell.c12
-rw-r--r--src/nvim/os/signal.c2
-rw-r--r--src/nvim/os/time.h2
-rw-r--r--src/nvim/os/tty.c9
-rw-r--r--src/nvim/os/unix_defs.h2
-rw-r--r--src/nvim/os/users.c10
-rw-r--r--src/nvim/os/win_defs.h7
-rw-r--r--src/nvim/os_unix.c26
-rw-r--r--src/nvim/os_unix.h2
-rw-r--r--src/nvim/path.c393
-rw-r--r--src/nvim/path.h28
-rw-r--r--src/nvim/plines.c57
-rw-r--r--src/nvim/popupmnu.c43
-rw-r--r--src/nvim/popupmnu.h4
-rw-r--r--src/nvim/pos.h8
-rw-r--r--src/nvim/profile.c13
-rw-r--r--src/nvim/profile.h4
-rw-r--r--src/nvim/quickfix.c959
-rw-r--r--src/nvim/quickfix.h4
-rw-r--r--src/nvim/rbuffer.c4
-rw-r--r--src/nvim/rbuffer.h30
-rw-r--r--src/nvim/regexp.c14
-rw-r--r--src/nvim/regexp.h2
-rw-r--r--src/nvim/regexp_defs.h30
-rw-r--r--src/nvim/regexp_nfa.c81
-rw-r--r--src/nvim/runtime.c521
-rw-r--r--src/nvim/runtime.h21
-rw-r--r--src/nvim/screen.c238
-rw-r--r--src/nvim/screen.h14
-rw-r--r--src/nvim/search.c131
-rw-r--r--src/nvim/search.h48
-rw-r--r--src/nvim/sha256.c11
-rw-r--r--src/nvim/sha256.h2
-rw-r--r--src/nvim/shada.c2853
-rw-r--r--src/nvim/sign.c945
-rw-r--r--src/nvim/sign.h1
-rw-r--r--src/nvim/sign_defs.h33
-rw-r--r--src/nvim/spell.c1917
-rw-r--r--src/nvim/spell.h2
-rw-r--r--src/nvim/spell_defs.h78
-rw-r--r--src/nvim/spellfile.c1765
-rw-r--r--src/nvim/spellfile.h2
-rw-r--r--src/nvim/state.c22
-rw-r--r--src/nvim/state.h4
-rw-r--r--src/nvim/strings.c916
-rw-r--r--src/nvim/strings.h4
-rw-r--r--src/nvim/syntax.c192
-rw-r--r--src/nvim/syntax.h44
-rw-r--r--src/nvim/syntax_defs.h32
-rw-r--r--src/nvim/tag.c1630
-rw-r--r--src/nvim/tag.h32
-rw-r--r--src/nvim/terminal.c689
-rw-r--r--src/nvim/terminal.h2
-rw-r--r--src/nvim/testdir/samples/memfile_test.c2
-rw-r--r--src/nvim/testdir/test_arglist.vim2
-rw-r--r--src/nvim/testdir/test_autochdir.vim10
-rw-r--r--src/nvim/testdir/test_autocmd.vim73
-rw-r--r--src/nvim/testdir/test_breakindent.vim6
-rw-r--r--src/nvim/testdir/test_bufline.vim8
-rw-r--r--src/nvim/testdir/test_bufwintabinfo.vim6
-rw-r--r--src/nvim/testdir/test_cd.vim138
-rw-r--r--src/nvim/testdir/test_changelist.vim4
-rw-r--r--src/nvim/testdir/test_clientserver.vim12
-rw-r--r--src/nvim/testdir/test_cmdline.vim2
-rw-r--r--src/nvim/testdir/test_cursor_func.vim6
-rw-r--r--src/nvim/testdir/test_edit.vim6
-rw-r--r--src/nvim/testdir/test_environ.vim2
-rw-r--r--src/nvim/testdir/test_escaped_glob.vim6
-rw-r--r--src/nvim/testdir/test_eval_stuff.vim126
-rw-r--r--src/nvim/testdir/test_expand_func.vim9
-rw-r--r--src/nvim/testdir/test_expr.vim4
-rw-r--r--src/nvim/testdir/test_filetype.vim26
-rw-r--r--src/nvim/testdir/test_find_complete.vim8
-rw-r--r--src/nvim/testdir/test_findfile.vim8
-rw-r--r--src/nvim/testdir/test_float_func.vim1
-rw-r--r--src/nvim/testdir/test_fnameescape.vim2
-rw-r--r--src/nvim/testdir/test_fnamemodify.vim2
-rw-r--r--src/nvim/testdir/test_fold.vim8
-rw-r--r--src/nvim/testdir/test_functions.vim156
-rw-r--r--src/nvim/testdir/test_getcwd.vim6
-rw-r--r--src/nvim/testdir/test_getvar.vim8
-rw-r--r--src/nvim/testdir/test_glob2regpat.vim2
-rw-r--r--src/nvim/testdir/test_history.vim8
-rw-r--r--src/nvim/testdir/test_jumplist.vim2
-rw-r--r--src/nvim/testdir/test_lispwords.vim3
-rw-r--r--src/nvim/testdir/test_listdict.vim2
-rw-r--r--src/nvim/testdir/test_maparg.vim42
-rw-r--r--src/nvim/testdir/test_match.vim8
-rw-r--r--src/nvim/testdir/test_method.vim3
-rw-r--r--src/nvim/testdir/test_perl.vim2
-rw-r--r--src/nvim/testdir/test_popup.vim4
-rw-r--r--src/nvim/testdir/test_prompt_buffer.vim7
-rw-r--r--src/nvim/testdir/test_python2.vim2
-rw-r--r--src/nvim/testdir/test_python3.vim2
-rw-r--r--src/nvim/testdir/test_pyx2.vim2
-rw-r--r--src/nvim/testdir/test_registers.vim80
-rw-r--r--src/nvim/testdir/test_reltime.vim6
-rw-r--r--src/nvim/testdir/test_rename.vim2
-rw-r--r--src/nvim/testdir/test_search.vim2
-rw-r--r--src/nvim/testdir/test_startup.vim10
-rw-r--r--src/nvim/testdir/test_stat.vim6
-rw-r--r--src/nvim/testdir/test_syn_attr.vim2
-rw-r--r--src/nvim/testdir/test_tagjump.vim2
-rw-r--r--src/nvim/testdir/test_true_false.vim2
-rw-r--r--src/nvim/testdir/test_utf8.vim2
-rw-r--r--src/nvim/testdir/test_vimscript.vim2
-rw-r--r--src/nvim/tui/input.h2
-rw-r--r--src/nvim/tui/terminfo_defs.h2
-rw-r--r--src/nvim/tui/tui.c44
-rw-r--r--src/nvim/types.h2
-rw-r--r--src/nvim/ugrid.c9
-rw-r--r--src/nvim/ugrid.h2
-rw-r--r--src/nvim/ui.c72
-rw-r--r--src/nvim/ui.h5
-rw-r--r--src/nvim/ui_bridge.c27
-rw-r--r--src/nvim/ui_bridge.h4
-rw-r--r--src/nvim/ui_compositor.c69
-rw-r--r--src/nvim/ui_compositor.h2
-rw-r--r--src/nvim/undo.c706
-rw-r--r--src/nvim/undo.h2
-rw-r--r--src/nvim/undo_defs.h44
-rw-r--r--src/nvim/version.c42
-rw-r--r--src/nvim/version.h4
-rw-r--r--src/nvim/vim.h29
-rw-r--r--src/nvim/viml/parser/expressions.c10
-rw-r--r--src/nvim/viml/parser/expressions.h16
-rw-r--r--src/nvim/viml/parser/parser.h31
-rw-r--r--src/nvim/window.c193
-rw-r--r--src/nvim/window.h30
-rw-r--r--src/uncrustify.cfg (renamed from contrib/uncrustify.cfg)108
-rw-r--r--test/config/paths.lua.in1
-rw-r--r--test/functional/api/buffer_spec.lua55
-rw-r--r--test/functional/api/command_spec.lua2
-rw-r--r--test/functional/api/keymap_spec.lua12
-rw-r--r--test/functional/api/vim_spec.lua266
-rw-r--r--test/functional/api/window_spec.lua26
-rw-r--r--test/functional/autocmd/dirchanged_spec.lua120
-rw-r--r--test/functional/core/startup_spec.lua64
-rw-r--r--test/functional/editor/meta_key_spec.lua15
-rw-r--r--test/functional/editor/mode_visual_spec.lua1
-rw-r--r--test/functional/ex_cmds/source_spec.lua20
-rw-r--r--test/functional/fixtures/autoload/health/full_render.vim8
-rw-r--r--test/functional/fixtures/fake-lsp-server.lua62
-rw-r--r--test/functional/fixtures/lua/test_plug/autoload/health/test_plug.vim3
-rw-r--r--test/functional/fixtures/lua/test_plug/health/init.lua11
-rw-r--r--test/functional/fixtures/lua/test_plug/submodule/health.lua11
-rw-r--r--test/functional/fixtures/lua/test_plug/submodule_failed/health.lua12
-rw-r--r--test/functional/fixtures/middle/filen.lua1
-rw-r--r--test/functional/fixtures/pack/foo/opt/funky/filen.lua12
-rw-r--r--test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_y.lua1
-rw-r--r--test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_z.lua1
-rw-r--r--test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x.lua1
-rw-r--r--test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x/init.lua1
-rw-r--r--test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_y/init.lua2
-rw-r--r--test/functional/fixtures/start/nvim-leftpad/lua/async_leftpad.lua3
-rw-r--r--test/functional/legacy/delete_spec.lua9
-rw-r--r--test/functional/legacy/eval_spec.lua3
-rw-r--r--test/functional/legacy/expand_spec.lua2
-rw-r--r--test/functional/legacy/file_perm_spec.lua7
-rw-r--r--test/functional/legacy/fnamemodify_spec.lua11
-rw-r--r--test/functional/lua/api_spec.lua4
-rw-r--r--test/functional/lua/buffer_updates_spec.lua96
-rw-r--r--test/functional/lua/diagnostic_spec.lua472
-rw-r--r--test/functional/lua/ffi_spec.lua62
-rw-r--r--test/functional/lua/json_spec.lua133
-rw-r--r--test/functional/lua/luaeval_spec.lua7
-rw-r--r--test/functional/lua/ui_spec.lua46
-rw-r--r--test/functional/lua/uri_spec.lua17
-rw-r--r--test/functional/lua/vim_spec.lua78
-rw-r--r--test/functional/plugin/health_spec.lua157
-rw-r--r--test/functional/plugin/lsp/codelens_spec.lua28
-rw-r--r--test/functional/plugin/lsp/diagnostic_spec.lua26
-rw-r--r--test/functional/plugin/lsp_spec.lua295
-rw-r--r--test/functional/terminal/buffer_spec.lua24
-rw-r--r--test/functional/terminal/ex_terminal_spec.lua15
-rw-r--r--test/functional/terminal/mouse_spec.lua10
-rw-r--r--test/functional/terminal/window_split_tab_spec.lua2
-rw-r--r--test/functional/ui/decorations_spec.lua508
-rw-r--r--test/functional/ui/float_spec.lua443
-rw-r--r--test/functional/ui/inccommand_spec.lua23
-rw-r--r--test/functional/ui/mouse_spec.lua187
-rw-r--r--test/functional/vimscript/json_functions_spec.lua8
-rw-r--r--third-party/CMakeLists.txt22
-rw-r--r--third-party/cmake/BuildLibuv.cmake2
-rw-r--r--third-party/cmake/BuildLibvterm.cmake2
-rw-r--r--third-party/cmake/BuildLua.cmake2
-rw-r--r--third-party/cmake/BuildLuajit.cmake2
-rw-r--r--third-party/cmake/BuildLuarocks.cmake5
-rw-r--r--third-party/cmake/BuildLuv.cmake2
-rw-r--r--third-party/cmake/BuildMsgpack.cmake2
-rw-r--r--third-party/cmake/BuildTreesitter.cmake2
-rw-r--r--third-party/cmake/GetBinaryDeps.cmake3
508 files changed, 35444 insertions, 21780 deletions
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index d5e725e5c8..bbca6b3339 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -10,7 +10,7 @@
# symbol renames
6186df3562e33e92f04ed8c850204ceabc4746e1
-# style / uncrustify
+# style (uncrustify, etc.)
2d240024acbd68c2d3f82bc72cb12b1a4928c6bf
61178778230e609d68b271ffd53ffd993cd23c42
15af08ad176339d1f269ce264bb0efea283c9536
@@ -18,3 +18,21 @@
1e49a1c888a3d9a581f4aa409a26ada3ac2417cb
3b3dbcf7b7ba5466e6ab643e256f2374b520a6b2
e8067d1490a31ff76143d576dc9948b4f09c6c55
+d5b66e88601b4d2fde5d905f9d12847126ba4449
+07715044887d82f74254e64c4c32fa49b0501bea
+6ed43f8f1caad702f9590d174c5ec142f3d85b18
+0a83017fe95df0290adb98ec6bf457b96a3fab17
+867e8885991ae450019c18aa5e42546bd4b62c2c
+1f49268c46fcbe65f7e2e2cb620e6f51c059cf9e
+51a98aa0c2fe3231a0ffc8a78189bc6fafd6abf6
+853346a94d6aa78c97314a3b217fb5a5408a47f1
+30fefee684e641a0c6867446c6de30efa2f0a126
+f4ca3a29ddcb0c98e8e09c45a6342af709f8cc45
+48e67b229415b4e2b3315bd00b817e5f9ab970c8
+7a26eb8a567cbc831d4f629f9eccb767a44436b8
+2f9b9e61d7417183f2d9f36d804247c0926be9d4
+c0767bd4f3ce7b34bb77da0657c49ba10ba1b32e
+d90fb1c0bfc1e64c783c385a79e7de87013dadba
+9c268263b1792d00b3ffdfd7495af2575862656e
+8c74c895b300bcee5fa937a2329d1d4756567b42
+40be47e0faef7aa015eb4ba44ceb1ee1a03e97cf
diff --git a/.gitattributes b/.gitattributes
index 1deb4dea49..e09a918303 100755
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,7 +1,6 @@
*.h linguist-language=C
src/nvim/testdir/test42.in diff
.github/ export-ignore
-ci/ export-ignore
.travis.yml export-ignore
codecov.yml export-ignore
.builds/ export-ignore
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index fa8d05f6b5..11f27dde21 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -36,7 +36,7 @@ body:
- type: input
attributes:
label: "$TERM environment variable"
- placeholder: "echo $TERM"
+ placeholder: "xterm-256color"
validations:
required: true
@@ -52,11 +52,11 @@ body:
attributes:
label: "How to reproduce the issue"
description: |
- - Steps to reproduce using `nvim -u NORC` or `nvim -u NONE` (try both).
+ - Steps to reproduce using `nvim --clean` ("factory defaults").
- For build failures: list the exact steps including CMake flags (if any).
- For shell-related problems: try `env -i TERM=ansi-256color "$(which nvim)"`.
placeholder: |
- nvim -u NONE
+ nvim --clean
:edit foo
yiwp
validations:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f75320048b..968094a2a6 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -10,7 +10,7 @@ on:
jobs:
unixish:
- name: ${{ matrix.os }} ${{ matrix.flavor }} (cc=${{ matrix.cc }})
+ name: ${{ matrix.runner }} ${{ matrix.flavor }} (cc=${{ matrix.cc }})
strategy:
fail-fast: false
matrix:
@@ -30,10 +30,14 @@ jobs:
- cc: clang
runner: macos-10.15
os: osx
+ - cc: clang
+ runner: macos-11.0
+ os: osx
- flavor: functionaltest-lua
cc: gcc
runner: ubuntu-20.04
os: linux
+ cmake: minimum_required
runs-on: ${{ matrix.runner }}
timeout-minutes: 45
if: github.event.pull_request.draft == false
@@ -52,6 +56,24 @@ jobs:
sudo apt-get update
sudo apt-get install -y autoconf automake build-essential ccache cmake cpanminus cscope gcc-multilib gdb gettext gperf language-pack-tr libtool-bin locales ninja-build pkg-config python3 python3-pip python3-setuptools unzip valgrind xclip
+ - name: Install minimum required version of cmake
+ if: matrix.cmake == 'minimum_required'
+ env:
+ CMAKE_URL: 'https://cmake.org/files/v3.10/cmake-3.10.0-Linux-x86_64.sh'
+ CMAKE_VERSION: '3.10.0'
+ shell: bash
+ run: |
+ curl --retry 5 --silent --show-error --fail -o /tmp/cmake-installer.sh "$CMAKE_URL"
+ mkdir -p "$HOME/.local/bin" /opt/cmake-custom
+ chmod a+x /tmp/cmake-installer.sh
+ /tmp/cmake-installer.sh --prefix=/opt/cmake-custom --skip-license
+ ln -sfn /opt/cmake-custom/bin/cmake "$HOME/.local/bin/cmake"
+ cmake_version="$(cmake --version | head -1)"
+ echo "$cmake_version" | grep -qF "cmake version $CMAKE_VERSION" || {
+ echo "Unexpected CMake version: $cmake_version"
+ exit 1
+ }
+
- name: Install new clang
if: matrix.flavor == 'asan' || matrix.flavor == 'tsan'
run: |
@@ -80,7 +102,7 @@ jobs:
path: |
${{ env.CACHE_NVIM_DEPS_DIR }}
~/.ccache
- key: ${{ runner.os }}-${{ matrix.flavor }}-${{ matrix.cc }}-${{ hashFiles('cmake/*', 'third-party/**', '**/CMakeLists.txt') }}-${{ github.base_ref }}
+ key: ${{ matrix.runner }}-${{ matrix.flavor }}-${{ matrix.cc }}-${{ hashFiles('cmake/*', 'third-party/**', '**/CMakeLists.txt') }}-${{ github.base_ref }}
- name: Build third-party
run: ./ci/before_script.sh
diff --git a/.github/workflows/commitlint.config.js b/.github/workflows/commitlint.config.js
deleted file mode 100644
index 5f10ffc6f4..0000000000
--- a/.github/workflows/commitlint.config.js
+++ /dev/null
@@ -1,35 +0,0 @@
-module.exports = {
- rules: {
- 'body-leading-blank': [1, 'always'],
- 'body-max-line-length': [2, 'always', 100],
- 'footer-leading-blank': [1, 'always'],
- 'footer-max-line-length': [2, 'always', 100],
- 'header-max-length': [2, 'always', 100],
- 'scope-case': [2, 'always', 'lower-case'],
- 'subject-case': [
- 2,
- 'never',
- ['sentence-case', 'start-case', 'pascal-case', 'upper-case'],
- ],
- 'subject-empty': [2, 'never'],
- 'subject-full-stop': [2, 'never', '.'],
- 'type-case': [2, 'always', 'lower-case'],
- 'type-empty': [2, 'never'],
- 'type-enum': [
- 2,
- 'always',
- [
- 'build',
- 'chore',
- 'ci',
- 'docs',
- 'feat',
- 'fix',
- 'perf',
- 'refactor',
- 'revert',
- 'test',
- ],
- ],
- },
-};
diff --git a/.github/workflows/commitlint.config_patch.js b/.github/workflows/commitlint.config_patch.js
deleted file mode 100644
index ca398c45dc..0000000000
--- a/.github/workflows/commitlint.config_patch.js
+++ /dev/null
@@ -1,27 +0,0 @@
-module.exports = {
- parserPreset: {
- parserOpts: { headerPattern: /^([^\(\):]*)(?:\((.*)\))?!?:(.*)$/ }
- },
- rules: {
- 'body-leading-blank': [1, 'always'],
- 'body-max-line-length': [2, 'always', 100],
- 'footer-max-line-length': [2, 'always', 100],
- 'scope-case': [2, 'always', 'lower-case'],
- 'subject-case': [
- 2,
- 'never',
- ['sentence-case', 'start-case', 'pascal-case', 'upper-case'],
- ],
- 'subject-empty': [2, 'never'],
- 'subject-full-stop': [2, 'never', '.'],
- 'type-case': [2, 'always', 'lower-case'],
- 'type-empty': [2, 'never'],
- 'type-enum': [
- 2,
- 'always',
- [
- 'vim-patch',
- ],
- ],
- },
-};
diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml
index 9ae138fbd7..559d8eae83 100644
--- a/.github/workflows/commitlint.yml
+++ b/.github/workflows/commitlint.yml
@@ -1,18 +1,19 @@
name: "Commit Linter"
-on: pull_request
+on:
+ pull_request:
+ types: [opened, synchronize, reopened, ready_for_review]
jobs:
lint-commits:
runs-on: ubuntu-latest
+ if: github.event.pull_request.draft == false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v2.3.1
with:
fetch-depth: 0
- - run: npm install --save-dev @commitlint/cli
- - run: |
- if [[ "$(gh pr view ${{ github.event.pull_request.number }} --json commits --jq '.[][0].messageHeadline')" == vim-patch* ]];then
- npx commitlint --from HEAD~1 --to HEAD --verbose --help-url https://github.com/neovim/neovim/blob/master/CONTRIBUTING.md#commit-messages --config .github/workflows/commitlint.config_patch.js
- else
- npx commitlint --from HEAD~1 --to HEAD --verbose --help-url https://github.com/neovim/neovim/blob/master/CONTRIBUTING.md#commit-messages --config .github/workflows/commitlint.config.js
- fi
+ ref: ${{ github.event.pull_request.head.sha }}
+ - uses: rhysd/action-setup-vim@v1
+ with:
+ neovim: true
+ - run: nvim --clean -es +"lua require('scripts.lintcommit').main({trace=true})"
diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml
index 67ad4c0552..76fc8793fa 100644
--- a/.github/workflows/labeler.yml
+++ b/.github/workflows/labeler.yml
@@ -12,3 +12,19 @@ jobs:
- uses: actions/labeler@main
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
+ type-scope:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ pull-requests: write
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GH_REPO: ${{ github.repository }}
+ PR_NUMBER: ${{ github.event.pull_request.number }}
+ PR_TITLE: ${{ github.event.pull_request.title }}
+ steps:
+ # Extract type and try to add it as a label
+ - run: gh pr edit "$PR_NUMBER" --add-label "$(echo "$PR_TITLE" | sed -E 's|([[:alpha:]]+)(\(.*\))?!?:.*|\1|')" || true
+
+ # Extract scope and try to add it as a label
+ - run: gh pr edit "$PR_NUMBER" --add-label "$(echo "$PR_TITLE" | sed -E 's|[[:alpha:]]+\((.+)\)!?:.*|\1|')" || true
diff --git a/.travis.yml b/.travis.yml
index 06547febba..ec7e19b2f9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -133,8 +133,6 @@ jobs:
- BUILD_32BIT=ON
- CMAKE_FLAGS="$CMAKE_FLAGS -m32 -DCMAKE_TOOLCHAIN_FILE=$TRAVIS_BUILD_DIR/cmake/i386-linux-gnu.toolchain.cmake"
- DEPS_CMAKE_FLAGS="$DEPS_CMAKE_FLAGS -m32 -DCMAKE_TOOLCHAIN_FILE=$TRAVIS_BUILD_DIR/cmake/i386-linux-gnu.toolchain.cmake"
- # Minimum required CMake.
- - CMAKE_URL=https://cmake.org/files/v2.8/cmake-2.8.12-Linux-i386.sh
- *common-job-env
- name: big-endian
os: linux
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 26c60ffbf1..f44937b5ae 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,8 +2,8 @@
# intro: https://codingnest.com/basic-cmake/
# best practices (3.0+): https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1
-# Version should match the tested CMAKE_URL in .travis.yml.
-cmake_minimum_required(VERSION 2.8.12)
+# Version should match the tested CMAKE_URL in .github/workflows/ci.yml.
+cmake_minimum_required(VERSION 3.10)
project(nvim C)
if(POLICY CMP0065)
@@ -590,9 +590,7 @@ if(BUSTED_PRG)
# console pool: to do so we need to use the USES_TERMINAL
# option, but this is only available in CMake 3.2
set(TEST_TARGET_ARGS)
- if(NOT (${CMAKE_VERSION} VERSION_LESS 3.2.0))
- list(APPEND TEST_TARGET_ARGS "USES_TERMINAL")
- endif()
+ 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})
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 2a565574fa..e9c1173007 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -19,6 +19,7 @@ Reporting problems
- [Check the FAQ][wiki-faq].
- [Search existing issues][github-issues] (including closed!)
- Update Neovim to the latest version to see if your problem persists.
+- Try to reproduce with `nvim --clean` ("factory defaults").
- [Bisect](https://neovim.io/doc/user/starting.html#bisect) your config: disable plugins incrementally, to narrow down the cause of the issue.
- [Bisect][git-bisect] Neovim's source code to find the cause of a regression, if you can. This is _extremely_ helpful.
- When reporting a crash, [include a stacktrace](https://github.com/neovim/neovim/wiki/FAQ#backtrace-linux).
@@ -161,7 +162,7 @@ see potential bugs found by [PVS Studio](https://www.viva64.com/en/pvs-studio/).
- Use this format for commit messages (where `{id}` is the PVS warning-id)):
```
- PVS/V{id}: {description}
+ fix(PVS/V{id}): {description}
```
- Search the Neovim commit history to find examples:
```
@@ -177,7 +178,7 @@ master build. To view the defects, just request access; you will be approved.
- Use this format for commit messages (where `{id}` is the CID (Coverity ID);
([example](https://github.com/neovim/neovim/pull/804))):
```
- coverity/{id}: {description}
+ fix(coverity/{id}): {description}
```
- Search the Neovim commit history to find examples:
```
@@ -217,13 +218,21 @@ You can lint a single file (but this will _not_ exclude legacy errors):
### Style
-The repo includes a `.clang-format` config file which (mostly) matches the
-[style-guide]. You can use `clang-format` to format code with the `gq`
-operator in Nvim:
-
- if !empty(findfile('.clang-format', ';'))
- setlocal formatprg=clang-format\ -style=file
- endif
+- Style rules are (mostly) defined by `src/uncrustify.cfg` which tries to match
+ the [style-guide]. To use the Nvim `gq` command with `uncrustify`:
+ ```
+ if !empty(findfile('src/uncrustify.cfg', ';'))
+ setlocal formatprg=uncrustify\ -q\ -l\ C\ -c\ src/uncrustify.cfg\ --no-backup
+ endif
+ ```
+ The required version of `uncrustify` is specified in `uncrustify.cfg`.
+- There is also `.clang-format` which has drifted from the [style-guide], but
+ is available for reference. To use the Nvim `gq` command with `clang-format`:
+ ```
+ if !empty(findfile('.clang-format', ';'))
+ setlocal formatprg=clang-format\ -style=file
+ endif
+ ```
### Navigate
@@ -263,7 +272,7 @@ as context, use the `-W` argument as well.
[1820]: https://github.com/neovim/neovim/pull/1820
[hub]: https://hub.github.com/
[conventional_commits]: https://www.conventionalcommits.org
-[style-guide]: http://neovim.io/develop/style-guide.xml
+[style-guide]: https://neovim.io/doc/user/dev_style.html#dev-style
[ASan]: http://clang.llvm.org/docs/AddressSanitizer.html
[run-tests]: https://github.com/neovim/neovim/blob/master/test/README.md#running-tests
[wiki-faq]: https://github.com/neovim/neovim/wiki/FAQ
@@ -278,3 +287,4 @@ as context, use the `-W` argument as well.
[wiki-contribute-help]: https://github.com/neovim/neovim/wiki/contribute-%3Ahelp
[pr-draft]: https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request
[pr-ready]: https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-stage-of-a-pull-request
+[uncrustify]: https://formulae.brew.sh/formula/uncrustify
diff --git a/LICENSE b/LICENSE
index eabb27f5cd..c1b8286c4b 100644
--- a/LICENSE
+++ b/LICENSE
@@ -199,6 +199,7 @@ The externally maintained libraries used by Neovim are:
- lua-compat: MIT license
- tree-sitter: MIT license
- xdiff: LGPL license
+ - lua-cjson: MIT license
====
diff --git a/MAINTAIN.md b/MAINTAIN.md
index 73578a8c5d..681ba91e3f 100644
--- a/MAINTAIN.md
+++ b/MAINTAIN.md
@@ -55,6 +55,28 @@ has a major bug:
- The [nightly job](https://github.com/neovim/bot-ci/blob/master/ci/nightly.sh)
will update the release assets based on the `stable` tag.
+Third-party dependencies
+--------------
+
+These "bundled" dependencies can be updated by bumping their versions in `third-party/CMakeLists.txt`:
+ - [Lua](https://www.lua.org/download.html)
+ - [LuaJIT](https://github.com/LuaJIT/LuaJIT)
+ - [Luv](https://github.com/luvit/luv)
+ - [libtermkey](https://github.com/neovim/libtermkey)
+ - [libuv](https://github.com/libuv/libuv)
+ - [libvterm](http://www.leonerd.org.uk/code/libvterm/)
+ - [lua-compat](https://github.com/keplerproject/lua-compat-5.3)
+ - [tree-sitter](https://github.com/tree-sitter/tree-sitter)
+
+These dependencies are "vendored" (inlined), we need to update the sources manually:
+ - [libmpack](https://github.com/libmpack/libmpack)
+ - [xdiff](https://github.com/git/git/tree/master/xdiff)
+ - [lua-cjson](https://github.com/openresty/lua-cjson)
+ - [Klib](https://github.com/attractivechaos/klib)
+
+We also maintain some forks, particularly for Windows, if we are waiting on upstream changes:
+https://github.com/neovim/neovim/wiki/Deps
+
See also
--------
diff --git a/Makefile b/Makefile
index 1ddf810ce0..86e723df67 100644
--- a/Makefile
+++ b/Makefile
@@ -48,11 +48,11 @@ endif
ifeq (,$(BUILD_TOOL))
ifeq (Ninja,$(CMAKE_GENERATOR))
ifneq ($(shell $(CMAKE_PRG) --help 2>/dev/null | grep Ninja),)
- BUILD_TOOL := ninja
+ BUILD_TOOL = ninja
else
# User's version of CMake doesn't support Ninja
BUILD_TOOL = $(MAKE)
- BUILD_TYPE := Unix Makefiles
+ CMAKE_GENERATOR := Unix Makefiles
endif
else
BUILD_TOOL = $(MAKE)
@@ -60,12 +60,12 @@ ifeq (,$(BUILD_TOOL))
endif
-# Only need to handle Ninja here. Make will inherit the VERBOSE variable, and the -j and -n flags.
+# Only need to handle Ninja here. Make will inherit the VERBOSE variable, and the -j, -l, and -n flags.
ifeq ($(CMAKE_GENERATOR),Ninja)
ifneq ($(VERBOSE),)
BUILD_TOOL += -v
endif
- BUILD_TOOL += $(shell printf '%s' '$(MAKEFLAGS)' | grep -o -- '-j[0-9]\+')
+ BUILD_TOOL += $(shell printf '%s' '$(MAKEFLAGS)' | grep -o -- ' *-[jl][0-9]\+ *')
ifeq (n,$(findstring n,$(firstword -$(MAKEFLAGS))))
BUILD_TOOL += -n
endif
diff --git a/ci/before_install.sh b/ci/before_install.sh
index c3fd8bdbde..f12f972fe0 100755
--- a/ci/before_install.sh
+++ b/ci/before_install.sh
@@ -44,16 +44,3 @@ fi
source ~/.nvm/nvm.sh
nvm install 10
-
-if [[ -n "$CMAKE_URL" ]]; then
- echo "Installing custom CMake: $CMAKE_URL"
- curl --retry 5 --silent --show-error --fail -o /tmp/cmake-installer.sh "$CMAKE_URL"
- mkdir -p "$HOME/.local/bin" /opt/cmake-custom
- bash /tmp/cmake-installer.sh --prefix=/opt/cmake-custom --skip-license
- ln -sfn /opt/cmake-custom/bin/cmake "$HOME/.local/bin/cmake"
- cmake_version="$(cmake --version)"
- echo "$cmake_version" | grep -qF '2.8.12' || {
- echo "Unexpected CMake version: $cmake_version"
- exit 1
- }
-fi
diff --git a/ci/build.ps1 b/ci/build.ps1
index 53e4328e02..8876ac31ef 100644
--- a/ci/build.ps1
+++ b/ci/build.ps1
@@ -72,7 +72,7 @@ if ($compiler -eq 'MINGW') {
& C:\msys64\usr\bin\mkdir -p /var/cache/pacman/pkg
# Build third-party dependencies
- C:\msys64\usr\bin\bash -lc "pacman --verbose --noconfirm -Su" ; exitIfFailed
+ C:\msys64\usr\bin\bash -lc "pacman --verbose --noconfirm -Syu" ; exitIfFailed
C:\msys64\usr\bin\bash -lc "pacman --verbose --noconfirm --needed -S $mingwPackages" ; exitIfFailed
}
elseif ($compiler -eq 'MSVC') {
diff --git a/cmake/FindLibUV.cmake b/cmake/FindLibUV.cmake
index 951fb0435e..63babfea67 100644
--- a/cmake/FindLibUV.cmake
+++ b/cmake/FindLibUV.cmake
@@ -75,6 +75,14 @@ if(WIN32)
list(APPEND LIBUV_LIBRARIES ws2_32)
endif()
+find_package(Threads)
+if(Threads_FOUND)
+ # TODO: Fix the cmake file to properly handle static deps for bundled builds.
+ # Meanwhile just include the threads library if CMake tells us there's one to
+ # use.
+ list(APPEND LIBUV_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
+endif()
+
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LIBUV_FOUND to TRUE
diff --git a/cmake/RunTests.cmake b/cmake/RunTests.cmake
index 0c48a77b9a..e78392562f 100644
--- a/cmake/RunTests.cmake
+++ b/cmake/RunTests.cmake
@@ -10,6 +10,7 @@ set(ENV{VIMRUNTIME} ${WORKING_DIR}/runtime)
set(ENV{NVIM_RPLUGIN_MANIFEST} ${BUILD_DIR}/Xtest_rplugin_manifest)
set(ENV{XDG_CONFIG_HOME} ${BUILD_DIR}/Xtest_xdg/config)
set(ENV{XDG_DATA_HOME} ${BUILD_DIR}/Xtest_xdg/share)
+unset(ENV{XDG_DATA_DIRS})
if(NOT DEFINED ENV{NVIM_LOG_FILE})
set(ENV{NVIM_LOG_FILE} ${BUILD_DIR}/.nvimlog)
diff --git a/runtime/autoload/csscomplete.vim b/runtime/autoload/csscomplete.vim
index 85e40c862f..4b673ac9b8 100644
--- a/runtime/autoload/csscomplete.vim
+++ b/runtime/autoload/csscomplete.vim
@@ -4,7 +4,7 @@
" plus CSS Speech Module <http://www.w3.org/TR/css3-speech/>
" Maintainer: Kao, Wei-Ko(othree) ( othree AT gmail DOT com )
" Original Author: Mikolaj Machowski ( mikmach AT wp DOT pl )
-" Last Change: 2018 Jul 02
+" Last Change: 2021 Sep 21
let s:values = split("all additive-symbols align-content align-items align-self animation animation-delay animation-direction animation-duration animation-fill-mode animation-iteration-count animation-name animation-play-state animation-timing-function backface-visibility background background-attachment background-blend-mode background-clip background-color background-image background-origin background-position background-repeat background-size block-size border border-block-end border-block-end-color border-block-end-style border-block-end-width border-block-start border-block-start-color border-block-start-style border-block-start-width border-bottom border-bottom-color border-bottom-left-radius border-bottom-right-radius border-bottom-style border-bottom-width border-collapse border-color border-image border-image-outset border-image-repeat border-image-slice border-image-source border-image-width border-inline-end border-inline-end-color border-inline-end-style border-inline-end-width border-inline-start border-inline-start-color border-inline-start-style border-inline-start-width border-left border-left-color border-left-style border-left-width border-radius border-right border-right-color border-right-style border-right-width border-spacing border-style border-top border-top-color border-top-left-radius border-top-right-radius border-top-style border-top-width border-width bottom box-decoration-break box-shadow box-sizing break-after break-before break-inside caption-side clear clip clip-path color columns column-count column-fill column-gap column-rule column-rule-color column-rule-style column-rule-width column-span column-width content counter-increment counter-reset cue cue-before cue-after cursor direction display empty-cells fallback filter flex flex-basis flex-direction flex-flow flex-grow flex-shrink flex-wrap float font font-family font-feature-settings font-kerning font-language-override font-size font-size-adjust font-stretch font-style font-synthesis font-variant font-variant-alternates font-variant-caps font-variant-east-asian font-variant-ligatures font-variant-numeric font-variant-position font-weight grid grid-area grid-auto-columns grid-auto-flow grid-auto-position grid-auto-rows grid-column grid-column-start grid-column-end grid-row grid-row-start grid-row-end grid-template grid-template-areas grid-template-rows grid-template-columns height hyphens image-rendering image-resolution image-orientation ime-mode inline-size isolation justify-content left letter-spacing line-break line-height list-style list-style-image list-style-position list-style-type margin margin-block-end margin-block-start margin-bottom margin-inline-end margin-inline-start margin-left margin-right margin-top marks mask mask-type max-block-size max-height max-inline-size max-width max-zoom min-block-size min-height min-inline-size min-width min-zoom mix-blend-mode negative object-fit object-position offset-block-end offset-block-start offset-inline-end offset-inline-start opacity order orientation orphans outline outline-color outline-offset outline-style outline-width overflow overflow-wrap overflow-x overflow-y pad padding padding-block-end padding-block-start padding-bottom padding-inline-end padding-inline-start padding-left padding-right padding-top page-break-after page-break-before page-break-inside pause-before pause-after pause perspective perspective-origin pointer-events position prefix quotes range resize rest rest-before rest-after right ruby-align ruby-merge ruby-position scroll-behavior scroll-snap-coordinate scroll-snap-destination scroll-snap-points-x scroll-snap-points-y scroll-snap-type scroll-snap-type-x scroll-snap-type-y shape-image-threshold shape-margin shape-outside speak speak-as suffix symbols system table-layout tab-size text-align text-align-last text-combine-upright text-decoration text-decoration-color text-decoration-line text-emphasis text-emphasis-color text-emphasis-position text-emphasis-style text-indent text-orientation text-overflow text-rendering text-shadow text-transform text-underline-position top touch-action transform transform-box transform-origin transform-style transition transition-delay transition-duration transition-property transition-timing-function unicode-bidi unicode-range user-zoom vertical-align visibility voice-balance voice-duration voice-family voice-pitch voice-rate voice-range voice-stress voice-volume white-space widows width will-change word-break word-spacing word-wrap writing-mode z-index zoom")
@@ -38,12 +38,12 @@ function! csscomplete#CompleteCSS(findstart, base)
if exists("b:compl_context")
let line = getline('.')
let compl_begin = col('.') - 2
- let after = line[compl_begin:]
+ let b:after = line[compl_begin:]
let line = b:compl_context
unlet! b:compl_context
else
let line = a:base
- let after = ''
+ let b:after = ''
endif
let res = []
diff --git a/runtime/autoload/health.vim b/runtime/autoload/health.vim
index 0f7983f175..73c1459f86 100644
--- a/runtime/autoload/health.vim
+++ b/runtime/autoload/health.vim
@@ -26,8 +26,8 @@ endfunction
" Runs all discovered healthchecks if a:plugin_names is empty.
function! health#check(plugin_names) abort
let healthchecks = empty(a:plugin_names)
- \ ? s:discover_health_checks()
- \ : s:to_fn_names(a:plugin_names)
+ \ ? s:discover_healthchecks()
+ \ : s:get_healthcheck(a:plugin_names)
tabnew
setlocal wrap breakindent linebreak
@@ -41,25 +41,29 @@ function! health#check(plugin_names) abort
call setline(1, 'ERROR: No healthchecks found.')
else
redraw|echo 'Running healthchecks...'
- for c in healthchecks
- let output = ''
- call append('$', split(printf("\n%s\n%s", c, repeat('=',72)), "\n"))
+ for name in sort(keys(healthchecks))
+ let [func, type] = healthchecks[name]
+ let s:output = []
try
- let output = "\n\n".execute('call '.c.'()')
+ if func == ''
+ throw 'healthcheck_not_found'
+ endif
+ eval type == 'v' ? call(func, []) : luaeval(func)
catch
- if v:exception =~# '^Vim\%((\a\+)\)\=:E117.*\V'.c
- let output = execute(
- \ 'call health#report_error(''No healthcheck found for "'
- \ .s:to_plugin_name(c)
- \ .'" plugin.'')')
+ let s:output = [] " Clear the output
+ if v:exception =~# 'healthcheck_not_found'
+ call health#report_error('No healthcheck found for "'.name.'" plugin.')
else
- let output = execute(
- \ 'call health#report_error(''Failed to run healthcheck for "'
- \ .s:to_plugin_name(c)
- \ .'" plugin. Exception:''."\n".v:throwpoint."\n".v:exception)')
+ call health#report_error(printf(
+ \ "Failed to run healthcheck for \"%s\" plugin. Exception:\n%s\n%s",
+ \ name, v:throwpoint, v:exception))
endif
endtry
- call append('$', split(output, "\n") + [''])
+ let header = [name. ': ' . func, repeat('=', 72)]
+ " remove empty line after header from report_start
+ let s:output = s:output[0] == '' ? s:output[1:] : s:output
+ let s:output = header + s:output + ['']
+ call append('$', s:output)
redraw
endfor
endif
@@ -71,9 +75,13 @@ function! health#check(plugin_names) abort
redraw|echo ''
endfunction
+function! s:collect_output(output)
+ let s:output += split(a:output, "\n", 1)
+endfunction
+
" Starts a new report.
function! health#report_start(name) abort
- echo "\n## " . a:name
+ call s:collect_output("\n## " . a:name)
endfunction
" Indents lines *except* line 1 of a string if it contains newlines.
@@ -119,21 +127,21 @@ endfunction " }}}
" Use {msg} to report information in the current section
function! health#report_info(msg) abort " {{{
- echo s:format_report_message('INFO', a:msg)
+ call s:collect_output(s:format_report_message('INFO', a:msg))
endfunction " }}}
" Reports a successful healthcheck.
function! health#report_ok(msg) abort " {{{
- echo s:format_report_message('OK', a:msg)
+ call s:collect_output(s:format_report_message('OK', a:msg))
endfunction " }}}
" Reports a health warning.
" a:1: Optional advice (string or list)
function! health#report_warn(msg, ...) abort " {{{
if a:0 > 0
- echo s:format_report_message('WARNING', a:msg, a:1)
+ call s:collect_output(s:format_report_message('WARNING', a:msg, a:1))
else
- echo s:format_report_message('WARNING', a:msg)
+ call s:collect_output(s:format_report_message('WARNING', a:msg))
endif
endfunction " }}}
@@ -141,37 +149,73 @@ endfunction " }}}
" a:1: Optional advice (string or list)
function! health#report_error(msg, ...) abort " {{{
if a:0 > 0
- echo s:format_report_message('ERROR', a:msg, a:1)
+ call s:collect_output(s:format_report_message('ERROR', a:msg, a:1))
else
- echo s:format_report_message('ERROR', a:msg)
+ call s:collect_output(s:format_report_message('ERROR', a:msg))
endif
endfunction " }}}
-function! s:filepath_to_function(name) abort
- return substitute(substitute(substitute(a:name, '.*autoload[\/]', '', ''),
- \ '\.vim', '#check', ''), '[\/]', '#', 'g')
+" From a path return a list [{name}, {func}, {type}] representing a healthcheck
+function! s:filepath_to_healthcheck(path) abort
+ if a:path =~# 'vim$'
+ let name = matchstr(a:path, '\zs[^\/]*\ze\.vim$')
+ let func = 'health#'.name.'#check'
+ let type = 'v'
+ else
+ let base_path = substitute(a:path,
+ \ '.*lua[\/]\(.\{-}\)[\/]health\([\/]init\)\?\.lua$',
+ \ '\1', '')
+ let name = substitute(base_path, '[\/]', '.', 'g')
+ let func = 'require("'.name.'.health").check()'
+ let type = 'l'
+ endif
+ return [name, func, type]
endfunction
-function! s:discover_health_checks() abort
- let healthchecks = globpath(&runtimepath, 'autoload/health/*.vim', 1, 1)
- let healthchecks = map(healthchecks, '<SID>filepath_to_function(v:val)')
- return healthchecks
+function! s:discover_healthchecks() abort
+ return s:get_healthcheck('*')
+endfunction
+
+" Returns Dictionary {name: [func, type], ..} representing healthchecks
+function! s:get_healthcheck(plugin_names) abort
+ let health_list = s:get_healthcheck_list(a:plugin_names)
+ let healthchecks = {}
+ for c in health_list
+ let normalized_name = substitute(c[0], '-', '_', 'g')
+ let existent = get(healthchecks, normalized_name, [])
+ " Prefer Lua over vim entries
+ if existent != [] && existent[2] == 'l'
+ continue
+ else
+ let healthchecks[normalized_name] = c
+ endif
+ endfor
+ let output = {}
+ for v in values(healthchecks)
+ let output[v[0]] = v[1:]
+ endfor
+ return output
endfunction
-" Translates a list of plugin names to healthcheck function names.
-function! s:to_fn_names(plugin_names) abort
+" Returns list of lists [ [{name}, {func}, {type}] ] representing healthchecks
+function! s:get_healthcheck_list(plugin_names) abort
let healthchecks = []
- let plugin_names = type('') ==# type(a:plugin_names)
- \ ? split(a:plugin_names, '', v:false)
+ let plugin_names = type('') == type(a:plugin_names)
+ \ ? split(a:plugin_names, ' ', v:false)
\ : a:plugin_names
for p in plugin_names
- call add(healthchecks, 'health#'.p.'#check')
+ " support vim/lsp/health{/init/}.lua as :checkhealth vim.lsp
+ let p = substitute(p, '\.', '/', 'g')
+ let p = substitute(p, '*$', '**', 'g') " find all submodule e.g vim*
+ let paths = nvim_get_runtime_file('autoload/health/'.p.'.vim', v:true)
+ \ + nvim_get_runtime_file('lua/**/'.p.'/health/init.lua', v:true)
+ \ + nvim_get_runtime_file('lua/**/'.p.'/health.lua', v:true)
+ if len(paths) == 0
+ let healthchecks += [[p, '', '']] " healthchek not found
+ else
+ let healthchecks += map(uniq(sort(paths)),
+ \'<SID>filepath_to_healthcheck(v:val)')
+ end
endfor
return healthchecks
endfunction
-
-" Extracts 'foo' from 'health#foo#check'.
-function! s:to_plugin_name(fn_name) abort
- return substitute(a:fn_name,
- \ '\v.*health\#(.+)\#check.*', '\1', '')
-endfunction
diff --git a/runtime/autoload/health/lsp.vim b/runtime/autoload/health/lsp.vim
deleted file mode 100644
index 2d2ba91cdf..0000000000
--- a/runtime/autoload/health/lsp.vim
+++ /dev/null
@@ -1,5 +0,0 @@
-function! health#lsp#check() abort
- call health#report_start('Checking language server client configuration')
- lua require 'vim.lsp.health'.check_health()
-endfunction
-
diff --git a/runtime/autoload/health/provider.vim b/runtime/autoload/health/provider.vim
index 001379c85d..7b4dce3441 100644
--- a/runtime/autoload/health/provider.vim
+++ b/runtime/autoload/health/provider.vim
@@ -710,7 +710,7 @@ function! s:check_perl() abort
let latest_cpan = s:system(latest_cpan_cmd)
if s:shell_error || empty(latest_cpan)
- call health#report_error('Failed to run: '. latest_cpan_cmd,
+ call health#report_error('Failed to run: '. join(latest_cpan_cmd, " "),
\ ["Make sure you're connected to the internet.",
\ 'Are you behind a firewall or proxy?'])
return
diff --git a/runtime/autoload/health/treesitter.vim b/runtime/autoload/health/treesitter.vim
deleted file mode 100644
index 5f167310ce..0000000000
--- a/runtime/autoload/health/treesitter.vim
+++ /dev/null
@@ -1,5 +0,0 @@
-function! health#treesitter#check() abort
- call health#report_start('Checking treesitter configuration')
- lua require 'vim.treesitter.health'.check_health()
-endfunction
-
diff --git a/runtime/autoload/man.vim b/runtime/autoload/man.vim
index 4f132b6121..90d353f9de 100644
--- a/runtime/autoload/man.vim
+++ b/runtime/autoload/man.vim
@@ -197,13 +197,21 @@ function! s:extract_sect_and_name_ref(ref) abort
if empty(name)
throw 'manpage reference cannot contain only parentheses'
endif
- return ['', name]
+ return ['', s:spaces_to_underscores(name)]
endif
let left = split(ref, '(')
" see ':Man 3X curses' on why tolower.
" TODO(nhooyr) Not sure if this is portable across OSs
" but I have not seen a single uppercase section.
- return [tolower(split(left[1], ')')[0]), left[0]]
+ return [tolower(split(left[1], ')')[0]), s:spaces_to_underscores(left[0])]
+endfunction
+
+" replace spaces in a man page name with underscores
+" intended for PostgreSQL, which has man pages like 'CREATE_TABLE(7)';
+" while editing SQL source code, it's nice to visually select 'CREATE TABLE'
+" and hit 'K', which requires this transformation
+function! s:spaces_to_underscores(str)
+ return substitute(a:str, ' ', '_', 'g')
endfunction
function! s:get_path(sect, name) abort
diff --git a/runtime/autoload/netrw.vim b/runtime/autoload/netrw.vim
index b6edc4c4d8..ef0282848f 100644
--- a/runtime/autoload/netrw.vim
+++ b/runtime/autoload/netrw.vim
@@ -1711,7 +1711,8 @@ fun! s:NetrwOptionsSafe(islocal)
if &cpo =~ 'a' | call s:NetrwSetSafeSetting("&cpo",substitute(&cpo,'a','','g')) | endif
if &cpo =~ 'A' | call s:NetrwSetSafeSetting("&cpo",substitute(&cpo,'A','','g')) | endif
setl fo=nroql2
- call s:NetrwSetSafeSetting("&go","begmr")
+ " call s:NetrwSetSafeSetting("&go","begmr")
+ if &go =~ '\ca' | call s:NetrwSetSafeSetting("&go",substitute(&go,'\ca','','g')) | endif
call s:NetrwSetSafeSetting("&l:hid",0)
call s:NetrwSetSafeSetting("&l:im",0)
setl isk+=@ isk+=* isk+=/
diff --git a/runtime/autoload/provider/pythonx.vim b/runtime/autoload/provider/pythonx.vim
index c292b374b6..0eeb35cba8 100644
--- a/runtime/autoload/provider/pythonx.vim
+++ b/runtime/autoload/provider/pythonx.vim
@@ -96,7 +96,7 @@ function! provider#pythonx#CheckForModule(prog, module, major_version) abort
if prog_version !~ '^' . a:major_version
return [0, prog_path . ' is Python ' . prog_version . ' and cannot provide Python '
\ . a:major_version . '.']
- elseif prog_version =~ '^' . a:major_version && prog_version < min_version
+ elseif prog_version =~ '^' . a:major_version && str2nr(prog_version[2:]) < str2nr(min_version[2:])
return [0, prog_path . ' is Python ' . prog_version . ' and cannot provide Python >= '
\ . min_version . '.']
endif
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
index df345e4981..1573bec7ac 100644
--- a/runtime/doc/api.txt
+++ b/runtime/doc/api.txt
@@ -130,7 +130,9 @@ end of a range, -1 denotes the last line/column.
Exception: the following API functions use "mark-like" indexing (1-based
lines, 0-based columns):
+ |nvim_get_mark()|
|nvim_buf_get_mark()|
+ |nvim_buf_set_mark()|
|nvim_win_get_cursor()|
|nvim_win_set_cursor()|
@@ -529,6 +531,20 @@ nvim__get_hl_defs({ns_id}) *nvim__get_hl_defs()*
nvim__get_lib_dir() *nvim__get_lib_dir()*
TODO: Documentation
+nvim__get_runtime({pat}, {all}, {*opts}) *nvim__get_runtime()*
+ Find files in runtime directories
+
+ Attributes: ~
+ {fast}
+
+ Parameters: ~
+ {pat} pattern of files to search for
+ {all} whether to return all matches or only the first
+ {options} is_lua: only search lua subdirs
+
+ Return: ~
+ list of absolute paths to the found files
+
nvim__id({obj}) *nvim__id()*
Returns object given as argument.
@@ -580,6 +596,9 @@ nvim__id_float({flt}) *nvim__id_float()*
nvim__inspect_cell({grid}, {row}, {col}) *nvim__inspect_cell()*
TODO: Documentation
+nvim__runtime_inspect() *nvim__runtime_inspect()*
+ TODO: Documentation
+
nvim__screenshot({path}) *nvim__screenshot()*
TODO: Documentation
@@ -706,7 +725,7 @@ nvim_create_buf({listed}, {scratch}) *nvim_create_buf()*
buf_open_scratch
nvim_create_namespace({name}) *nvim_create_namespace()*
- Creates a new namespace, or gets an existing one.
+ Creates a new *namespace* or gets an existing one.
Namespaces are used for buffer highlights and virtual text,
see |nvim_buf_add_highlight()| and |nvim_buf_set_extmark()|.
@@ -735,6 +754,23 @@ nvim_del_keymap({mode}, {lhs}) *nvim_del_keymap()*
See also: ~
|nvim_set_keymap()|
+nvim_del_mark({name}) *nvim_del_mark()*
+ Deletes a uppercase/file named mark. See |mark-motions|.
+
+ Note:
+ fails with error if a lowercase or buffer local named mark
+ is used.
+
+ Parameters: ~
+ {name} Mark name
+
+ Return: ~
+ true if the mark was deleted, else false.
+
+ See also: ~
+ |nvim_buf_del_mark()|
+ |nvim_get_mark()|
+
nvim_del_var({name}) *nvim_del_var()*
Removes a global (g:) variable.
@@ -783,6 +819,39 @@ nvim_eval({expr}) *nvim_eval()*
Return: ~
Evaluation result or expanded object
+nvim_eval_statusline({str}, {*opts}) *nvim_eval_statusline()*
+ Evaluates statusline string.
+
+ Attributes: ~
+ {fast}
+
+ Parameters: ~
+ {str} Statusline string (see 'statusline').
+ {opts} Optional parameters.
+ • winid: (number) |window-ID| of the window to use
+ as context for statusline.
+ • maxwidth: (number) Maximum width of statusline.
+ • fillchar: (string) Character to fill blank
+ spaces in the statusline (see 'fillchars').
+ • highlights: (boolean) Return highlight
+ information.
+ • use_tabline: (boolean) Evaluate tabline instead
+ of statusline. When |TRUE|, {winid} is ignored.
+
+ Return: ~
+ Dictionary containing statusline information, with these
+ keys:
+ • str: (string) Characters that will be displayed on the
+ statusline.
+ • width: (number) Display width of the statusline.
+ • highlights: Array containing highlight information of
+ the statusline. Only included when the "highlights" key
+ in {opts} is |TRUE|. Each element of the array is a
+ |Dictionary| with these keys:
+ • start: (number) Byte index (0-based) of first
+ character that uses the highlight.
+ • group: (string) Name of highlight group.
+
nvim_exec({src}, {output}) *nvim_exec()*
Executes Vimscript (multiline block of Ex-commands), like
anonymous |:source|.
@@ -828,7 +897,7 @@ nvim_feedkeys({keys}, {mode}, {escape_csi}) *nvim_feedkeys()*
On execution error: does not fail, but updates v:errmsg.
To input sequences like <C-o> use |nvim_replace_termcodes()|
- (typically with escape_csi=true) to replace the keycodes. Then
+ (typically with escape_csi=true) to replace |keycodes|, then
pass the result to nvim_feedkeys().
Example: >
@@ -866,32 +935,33 @@ nvim_get_api_info() *nvim_get_api_info()*
{fast}
nvim_get_chan_info({chan}) *nvim_get_chan_info()*
- Get information about a channel.
+ Gets information about a channel.
Return: ~
Dictionary describing a channel, with these keys:
- • "stream" the stream underlying the channel
+ • "id" Channel id.
+ • "argv" (optional) Job arguments list.
+ • "stream" Stream underlying the channel.
• "stdio" stdin and stdout of this Nvim instance
• "stderr" stderr of this Nvim instance
• "socket" TCP/IP socket or named pipe
- • "job" job with communication over its stdio
-
- • "mode" how data received on the channel is interpreted
- • "bytes" send and receive raw bytes
- • "terminal" a |terminal| instance interprets ASCII
- sequences
- • "rpc" |RPC| communication on the channel is active
-
- • "pty" Name of pseudoterminal, if one is used (optional).
- On a POSIX system, this will be a device path like
- /dev/pts/1. Even if the name is unknown, the key will
- still be present to indicate a pty is used. This is
- currently the case when using winpty on windows.
- • "buffer" buffer with connected |terminal| instance
- (optional)
- • "client" information about the client on the other end
- of the RPC channel, if it has added it using
- |nvim_set_client_info()|. (optional)
+ • "job" Job with communication over its stdio.
+
+ • "mode" How data received on the channel is interpreted.
+ • "bytes" Send and receive raw bytes.
+ • "terminal" |terminal| instance interprets ASCII
+ sequences.
+ • "rpc" |RPC| communication on the channel is active.
+
+ • "pty" (optional) Name of pseudoterminal. On a POSIX
+ system this is a device path like "/dev/pts/1". If the
+ name is unknown, the key will still be present if a pty
+ is used (e.g. for winpty on Windows).
+ • "buffer" (optional) Buffer with connected |terminal|
+ instance.
+ • "client" (optional) Info about the peer (client on the
+ other end of the RPC channel), if provided by it via
+ |nvim_set_client_info()|.
nvim_get_color_by_name({name}) *nvim_get_color_by_name()*
Returns the 24-bit RGB value of a |nvim_get_color_map()| color
@@ -917,7 +987,7 @@ nvim_get_color_map() *nvim_get_color_map()*
Return: ~
Map of color names and RGB values.
-nvim_get_commands({opts}) *nvim_get_commands()*
+nvim_get_commands({*opts}) *nvim_get_commands()*
Gets a map of global (non-buffer-local) Ex commands.
Currently only |user-commands| are supported, not builtin Ex
@@ -930,7 +1000,7 @@ nvim_get_commands({opts}) *nvim_get_commands()*
Return: ~
Map of maps describing commands.
-nvim_get_context({opts}) *nvim_get_context()*
+nvim_get_context({*opts}) *nvim_get_context()*
Gets a map of the current editor state.
Parameters: ~
@@ -1008,6 +1078,27 @@ nvim_get_keymap({mode}) *nvim_get_keymap()*
Array of maparg()-like dictionaries describing mappings.
The "buffer" key is always zero.
+nvim_get_mark({name}) *nvim_get_mark()*
+ Return a tuple (row, col, buffer, buffername) representing the
+ position of the uppercase/file named mark. See |mark-motions|.
+
+ Marks are (1,0)-indexed. |api-indexing|
+
+ Note:
+ fails with error if a lowercase or buffer local named mark
+ is used.
+
+ Parameters: ~
+ {name} Mark name
+
+ Return: ~
+ 4-tuple (row, col, buffer, buffername), (0, 0, 0, '') if
+ the mark is not set.
+
+ See also: ~
+ |nvim_buf_set_mark()|
+ |nvim_del_mark()|
+
nvim_get_mode() *nvim_get_mode()*
Gets the current mode. |mode()| "blocking" is true if Nvim is
waiting for input.
@@ -1079,10 +1170,6 @@ nvim_get_runtime_file({name}, {all}) *nvim_get_runtime_file()*
It is not an error to not find any files. An empty array is
returned then.
- To find a directory, `name` must end with a forward slash,
- like "rplugin/python/". Without the slash it would instead
- look for an ordinary file called "rplugin/python".
-
Attributes: ~
{fast}
@@ -1251,7 +1338,7 @@ nvim_open_term({buffer}, {opts}) *nvim_open_term()*
For instance, for a floating display, first create an empty
buffer using |nvim_create_buf()|, then display it using
|nvim_open_win()|, and then call this function. Then
- |nvim_chan_send()| cal be called immediately to process
+ |nvim_chan_send()| can be called immediately to process
sequences in a virtual terminal having the intended size.
Parameters: ~
@@ -1261,156 +1348,6 @@ nvim_open_term({buffer}, {opts}) *nvim_open_term()*
Return: ~
Channel id, or 0 on error
-nvim_open_win({buffer}, {enter}, {config}) *nvim_open_win()*
- Open a new window.
-
- Currently this is used to open floating and external windows.
- Floats are windows that are drawn above the split layout, at
- some anchor position in some other window. Floats can be drawn
- internally or by external GUI with the |ui-multigrid|
- extension. External windows are only supported with multigrid
- GUIs, and are displayed as separate top-level windows.
-
- For a general overview of floats, see |api-floatwin|.
-
- Exactly one of `external` and `relative` must be specified.
- The `width` and `height` of the new window must be specified.
-
- With relative=editor (row=0,col=0) refers to the top-left
- corner of the screen-grid and (row=Lines-1,col=Columns-1)
- refers to the bottom-right corner. Fractional values are
- allowed, but the builtin implementation (used by non-multigrid
- UIs) will always round down to nearest integer.
-
- Out-of-bounds values, and configurations that make the float
- not fit inside the main editor, are allowed. The builtin
- implementation truncates values so floats are fully within the
- main screen grid. External GUIs could let floats hover outside
- of the main window like a tooltip, but this should not be used
- to specify arbitrary WM screen positions.
-
- Example (Lua): window-relative float >
- vim.api.nvim_open_win(0, false,
- {relative='win', row=3, col=3, width=12, height=3})
-<
-
- Example (Lua): buffer-relative float (travels as buffer is
- scrolled) >
- vim.api.nvim_open_win(0, false,
- {relative='win', width=12, height=3, bufpos={100,10}})
-<
-
- Attributes: ~
- not allowed when |textlock| is active
-
- Parameters: ~
- {buffer} Buffer to display, or 0 for current buffer
- {enter} Enter the window (make it the current window)
- {config} Map defining the window configuration. Keys:
- • `relative`: Sets the window layout to "floating", placed
- at (row,col) coordinates relative to:
- • "editor" The global editor grid
- • "win" Window given by the `win` field, or
- current window.
- • "cursor" Cursor position in current window.
-
- • `win` : |window-ID| for relative="win".
- • `anchor`: Decides which corner of the float to place
- at (row,col):
- • "NW" northwest (default)
- • "NE" northeast
- • "SW" southwest
- • "SE" southeast
-
- • `width` : Window width (in character cells).
- Minimum of 1.
- • `height` : Window height (in character cells).
- Minimum of 1.
- • `bufpos` : Places float relative to buffer
- text (only when relative="win"). Takes a tuple
- of zero-indexed [line, column]. `row` and
- `col` if given are applied relative to this
- position, else they default to `row=1` and
- `col=0` (thus like a tooltip near the buffer
- text).
- • `row` : Row position in units of "screen cell
- height", may be fractional.
- • `col` : Column position in units of "screen
- cell width", may be fractional.
- • `focusable` : Enable focus by user actions
- (wincmds, mouse events). Defaults to true.
- Non-focusable windows can be entered by
- |nvim_set_current_win()|.
- • `external` : GUI should display the window as
- an external top-level window. Currently
- accepts no other positioning configuration
- together with this.
- • `zindex`: Stacking order. floats with higher`zindex`go on top on floats with lower indices. Must
- be larger than zero. The following screen
- elements have hard-coded z-indices:
- • 100: insert completion popupmenu
- • 200: message scrollback
- • 250: cmdline completion popupmenu (when
- wildoptions+=pum) The default value for
- floats are 50. In general, values below 100
- are recommended, unless there is a good
- reason to overshadow builtin elements.
-
- • `style`: Configure the appearance of the window.
- Currently only takes one non-empty value:
- • "minimal" Nvim will display the window with
- many UI options disabled. This is useful
- when displaying a temporary float where the
- text should not be edited. Disables
- 'number', 'relativenumber', 'cursorline',
- 'cursorcolumn', 'foldcolumn', 'spell' and
- 'list' options. 'signcolumn' is changed to
- `auto` and 'colorcolumn' is cleared. The
- end-of-buffer region is hidden by setting
- `eob` flag of 'fillchars' to a space char,
- and clearing the |EndOfBuffer| region in
- 'winhighlight'.
-
- • `border`: Style of (optional) window border. This can
- either be a string or an array. The string
- values are
- • "none": No border (default).
- • "single": A single line box.
- • "double": A double line box.
- • "rounded": Like "single", but with rounded
- corners ("╭" etc.).
- • "solid": Adds padding by a single whitespace
- cell.
- • "shadow": A drop shadow effect by blending
- with the background.
- • If it is an array, it should have a length
- of eight or any divisor of eight. The array
- will specifify the eight chars building up
- the border in a clockwise fashion starting
- with the top-left corner. As an example, the
- double box style could be specified as [
- "╔", "═" ,"╗", "║", "╝", "═", "╚", "║" ]. If
- the number of chars are less than eight,
- they will be repeated. Thus an ASCII border
- could be specified as [ "/", "-", "\\", "|"
- ], or all chars the same as [ "x" ]. An
- empty string can be used to turn off a
- specific border, for instance, [ "", "", "",
- ">", "", "", "", "<" ] will only make
- vertical borders but not horizontal ones. By
- default, `FloatBorder` highlight is used,
- which links to `VertSplit` when not defined.
- It could also be specified by character: [
- {"+", "MyCorner"}, {"x", "MyBorder"} ].
-
- • `noautocmd` : If true then no buffer-related
- autocommand events such as |BufEnter|,
- |BufLeave| or |BufWinEnter| may fire from
- calling this function.
-
- Return: ~
- Window handle, or 0 on error
-
nvim_out_write({str}) *nvim_out_write()*
Writes a message to the Vim output buffer. Does not append
"\n", the message is buffered (won't display) until a linefeed
@@ -1779,7 +1716,7 @@ nvim_set_hl({ns_id}, {name}, {val}) *nvim_set_hl()*
default cterm attributes are same as attributes
of gui color
-nvim_set_keymap({mode}, {lhs}, {rhs}, {opts}) *nvim_set_keymap()*
+nvim_set_keymap({mode}, {lhs}, {rhs}, {*opts}) *nvim_set_keymap()*
Sets a global |mapping| for the given mode.
To set a buffer-local mapping, use |nvim_buf_set_keymap()|.
@@ -1940,7 +1877,7 @@ nvim_buf_attach({buffer}, {send_buffer}, {opts}) *nvim_buf_attach()*
callbacks.
{opts} Optional parameters.
• on_lines: Lua callback invoked on change.
- Return`true`to detach. Args:
+ Return `true` to detach. Args:
• the string "lines"
• buffer handle
• b:changedtick
@@ -1956,7 +1893,7 @@ nvim_buf_attach({buffer}, {send_buffer}, {opts}) *nvim_buf_attach()*
• on_bytes: lua callback invoked on change.
This callback receives more granular
information about the change compared to
- on_lines. Return`true`to detach. Args:
+ on_lines. Return `true` to detach. Args:
• the string "bytes"
• buffer handle
• b:changedtick
@@ -2063,6 +2000,24 @@ nvim_buf_del_keymap({buffer}, {mode}, {lhs}) *nvim_buf_del_keymap()*
See also: ~
|nvim_del_keymap()|
+nvim_buf_del_mark({buffer}, {name}) *nvim_buf_del_mark()*
+ Deletes a named mark in the buffer. See |mark-motions|.
+
+ Note:
+ only deletes marks set in the buffer, if the mark is not
+ set in the buffer it will return false.
+
+ Parameters: ~
+ {buffer} Buffer to set the mark on
+ {name} Mark name
+
+ Return: ~
+ true if the mark was deleted, else false.
+
+ See also: ~
+ |nvim_buf_set_mark()|
+ |nvim_del_mark()|
+
nvim_buf_del_var({buffer}, {name}) *nvim_buf_del_var()*
Removes a buffer-scoped (b:) variable
@@ -2107,7 +2062,7 @@ nvim_buf_get_changedtick({buffer}) *nvim_buf_get_changedtick()*
Return: ~
`b:changedtick` value.
-nvim_buf_get_commands({buffer}, {opts}) *nvim_buf_get_commands()*
+nvim_buf_get_commands({buffer}, {*opts}) *nvim_buf_get_commands()*
Gets a map of buffer-local |user-commands|.
Parameters: ~
@@ -2119,7 +2074,7 @@ nvim_buf_get_commands({buffer}, {opts}) *nvim_buf_get_commands()*
*nvim_buf_get_extmark_by_id()*
nvim_buf_get_extmark_by_id({buffer}, {ns_id}, {id}, {opts})
- Gets the position (0-indexed) of an extmark {id}.
+ Gets the position (0-indexed) of an extmark.
Parameters: ~
{buffer} Buffer handle, or 0 for current buffer
@@ -2170,12 +2125,12 @@ nvim_buf_get_extmarks({buffer}, {ns_id}, {start}, {end}, {opts})
Parameters: ~
{buffer} Buffer handle, or 0 for current buffer
{ns_id} Namespace id from |nvim_create_namespace()|
- {start} Start of range, given as 0-indexed (row, col) or
- valid extmark id (whose position defines the
- bound)
- {end} End of range (inclusive), given as 0-indexed
- (row, col) or valid extmark id (whose position
- defines the bound)
+ {start} Start of range: a 0-indexed (row, col) or valid
+ extmark id (whose position defines the bound).
+ |api-indexing|
+ {end} End of range (inclusive): a 0-indexed (row, col)
+ or valid extmark id (whose position defines the
+ bound). |api-indexing|
{opts} Optional parameters. Keys:
• limit: Maximum number of marks to return
• details Whether to include the details dict
@@ -2217,8 +2172,8 @@ nvim_buf_get_lines({buffer}, {start}, {end}, {strict_indexing})
Array of lines, or empty array for unloaded buffer.
nvim_buf_get_mark({buffer}, {name}) *nvim_buf_get_mark()*
- Return a tuple (row,col) representing the position of the
- named mark.
+ Returns a tuple (row,col) representing the position of the
+ named mark. See |mark-motions|.
Marks are (1,0)-indexed. |api-indexing|
@@ -2227,7 +2182,12 @@ nvim_buf_get_mark({buffer}, {name}) *nvim_buf_get_mark()*
{name} Mark name
Return: ~
- (row, col) tuple
+ (row, col) tuple, (0, 0) if the mark is not set, or is an
+ uppercase/file mark set in another buffer.
+
+ See also: ~
+ |nvim_buf_set_mark()|
+ |nvim_buf_del_mark()|
nvim_buf_get_name({buffer}) *nvim_buf_get_name()*
Gets the full file name for the buffer
@@ -2310,7 +2270,7 @@ nvim_buf_line_count({buffer}) *nvim_buf_line_count()*
Line count, or 0 for unloaded buffer. |api-buffer|
*nvim_buf_set_extmark()*
-nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {opts})
+nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {*opts})
Creates or updates an extmark.
To create a new extmark, pass id=0. The extmark id will be
@@ -2328,8 +2288,10 @@ nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {opts})
Parameters: ~
{buffer} Buffer handle, or 0 for current buffer
{ns_id} Namespace id from |nvim_create_namespace()|
- {line} Line where to place the mark, 0-based
- {col} Column where to place the mark, 0-based
+ {line} Line where to place the mark, 0-based.
+ |api-indexing|
+ {col} Column where to place the mark, 0-based.
+ |api-indexing|
{opts} Optional parameters.
• id : id of the extmark to edit.
• end_line : ending line of the mark, 0-based
@@ -2338,6 +2300,10 @@ nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {opts})
exclusive.
• hl_group : name of the highlight group used to
highlight this mark.
+ • hl_eol : when true, for a multiline highlight
+ covering the EOL of a line, continue the
+ highlight for the rest of the screen line
+ (just like for diff and cursorline highlight).
• virt_text : virtual text to link to this mark.
A list of [text, highlight] tuples, each
representing a text chunk with specified
@@ -2366,17 +2332,35 @@ nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {opts})
• hl_mode : control how highlights are combined
with the highlights of the text. Currently
only affects virt_text highlights, but might
- affect`hl_group`in later versions.
+ affect `hl_group` in later versions.
• "replace": only show the virt_text color.
This is the default
• "combine": combine with background text
color
• "blend": blend with background text color.
- • hl_eol : when true, for a multiline highlight
- covering the EOL of a line, continue the
- highlight for the rest of the screen line
- (just like for diff and cursorline highlight).
+ • virt_lines : virtual lines to add next to this
+ mark This should be an array over lines, where
+ each line in turn is an array over [text,
+ highlight] tuples. In general, buffer and
+ window options do not affect the display of
+ the text. In particular 'wrap' and 'linebreak'
+ options do not take effect, so the number of
+ extra screen lines will always match the size
+ of the array. However the 'tabstop' buffer
+ option is still used for hard tabs. By default
+ lines are placed below the buffer line
+ containing the mark. • Note: currently virtual lines are limited to
+ one block per buffer. Thus setting a new mark
+ disables any previous `virt_lines` decoration.
+ However plugins should not rely on this
+ behaviour, as this limitation is planned to be
+ removed.
+ • virt_lines_above: place virtual lines above
+ instead.
+ • virt_lines_leftcol: Place extmarks in the
+ leftmost column of the window, bypassing sign
+ and number columns.
• ephemeral : for use with
|nvim_set_decoration_provider| callbacks. The
mark will only be used for the current redraw
@@ -2399,7 +2383,7 @@ nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {opts})
Id of the created/updated extmark
*nvim_buf_set_keymap()*
-nvim_buf_set_keymap({buffer}, {mode}, {lhs}, {rhs}, {opts})
+nvim_buf_set_keymap({buffer}, {mode}, {lhs}, {rhs}, {*opts})
Sets a buffer-local |mapping| for the given mode.
Parameters: ~
@@ -2435,6 +2419,29 @@ nvim_buf_set_lines({buffer}, {start}, {end}, {strict_indexing}, {replacement})
error.
{replacement} Array of lines to use as replacement
+ *nvim_buf_set_mark()*
+nvim_buf_set_mark({buffer}, {name}, {line}, {col})
+ Sets a named mark in the given buffer, all marks are allowed
+ file/uppercase, visual, last change, etc. See |mark-motions|.
+
+ Marks are (1,0)-indexed. |api-indexing|
+
+ Note:
+ Passing 0 as line deletes the mark
+
+ Parameters: ~
+ {buffer} Buffer to set the mark on
+ {name} Mark name
+ {line} Line number
+ {col} Column/row number
+
+ Return: ~
+ true if the mark was set, else false.
+
+ See also: ~
+ |nvim_buf_del_mark()|
+ |nvim_buf_get_mark()|
+
nvim_buf_set_name({buffer}, {name}) *nvim_buf_set_name()*
Sets the full file name for a buffer
@@ -2534,20 +2541,6 @@ nvim_win_get_buf({window}) *nvim_win_get_buf()*
Return: ~
Buffer handle
-nvim_win_get_config({window}) *nvim_win_get_config()*
- Gets window configuration.
-
- The returned value may be given to |nvim_open_win()|.
-
- `relative` is empty for normal windows.
-
- Parameters: ~
- {window} Window handle, or 0 for current window
-
- Return: ~
- Map defining the window configuration, see
- |nvim_open_win()|
-
nvim_win_get_cursor({window}) *nvim_win_get_cursor()*
Gets the (1,0)-indexed cursor position in the window.
|api-indexing|
@@ -2658,23 +2651,6 @@ nvim_win_set_buf({window}, {buffer}) *nvim_win_set_buf()*
{window} Window handle, or 0 for current window
{buffer} Buffer handle
-nvim_win_set_config({window}, {config}) *nvim_win_set_config()*
- Configures window layout. Currently only for floating and
- external windows (including changing a split window to those
- layouts).
-
- When reconfiguring a floating window, absent option keys will
- not be changed. `row` / `col` and `relative` must be
- reconfigured together.
-
- Parameters: ~
- {window} Window handle, or 0 for current window
- {config} Map defining the window configuration, see
- |nvim_open_win()|
-
- See also: ~
- |nvim_open_win()|
-
nvim_win_set_cursor({window}, {pos}) *nvim_win_set_cursor()*
Sets the (1,0)-indexed cursor position in the window.
|api-indexing|
@@ -2718,6 +2694,195 @@ nvim_win_set_width({window}, {width}) *nvim_win_set_width()*
==============================================================================
+Win_Config Functions *api-win_config*
+
+nvim_open_win({buffer}, {enter}, {*config}) *nvim_open_win()*
+ Open a new window.
+
+ Currently this is used to open floating and external windows.
+ Floats are windows that are drawn above the split layout, at
+ some anchor position in some other window. Floats can be drawn
+ internally or by external GUI with the |ui-multigrid|
+ extension. External windows are only supported with multigrid
+ GUIs, and are displayed as separate top-level windows.
+
+ For a general overview of floats, see |api-floatwin|.
+
+ Exactly one of `external` and `relative` must be specified.
+ The `width` and `height` of the new window must be specified.
+
+ With relative=editor (row=0,col=0) refers to the top-left
+ corner of the screen-grid and (row=Lines-1,col=Columns-1)
+ refers to the bottom-right corner. Fractional values are
+ allowed, but the builtin implementation (used by non-multigrid
+ UIs) will always round down to nearest integer.
+
+ Out-of-bounds values, and configurations that make the float
+ not fit inside the main editor, are allowed. The builtin
+ implementation truncates values so floats are fully within the
+ main screen grid. External GUIs could let floats hover outside
+ of the main window like a tooltip, but this should not be used
+ to specify arbitrary WM screen positions.
+
+ Example (Lua): window-relative float >
+ vim.api.nvim_open_win(0, false,
+ {relative='win', row=3, col=3, width=12, height=3})
+<
+
+ Example (Lua): buffer-relative float (travels as buffer is
+ scrolled) >
+ vim.api.nvim_open_win(0, false,
+ {relative='win', width=12, height=3, bufpos={100,10}})
+<
+
+ Attributes: ~
+ not allowed when |textlock| is active
+
+ Parameters: ~
+ {buffer} Buffer to display, or 0 for current buffer
+ {enter} Enter the window (make it the current window)
+ {config} Map defining the window configuration. Keys:
+ • relative: Sets the window layout to
+ "floating", placed at (row,col) coordinates
+ relative to:
+ • "editor" The global editor grid
+ • "win" Window given by the `win` field, or
+ current window.
+ • "cursor" Cursor position in current window.
+
+ • win: |window-ID| for relative="win".
+ • anchor: Decides which corner of the float to
+ place at (row,col):
+ • "NW" northwest (default)
+ • "NE" northeast
+ • "SW" southwest
+ • "SE" southeast
+
+ • width: Window width (in character cells).
+ Minimum of 1.
+ • height: Window height (in character cells).
+ Minimum of 1.
+ • bufpos: Places float relative to buffer text
+ (only when relative="win"). Takes a tuple of
+ zero-indexed [line, column]. `row` and `col` if given are applied relative to this
+ position, else they default to:
+ • `row=1` and `col=0` if `anchor` is "NW" or
+ "NE"
+ • `row=0` and `col=0` if `anchor` is "SW" or
+ "SE" (thus like a tooltip near the buffer
+ text).
+
+ • row: Row position in units of "screen cell
+ height", may be fractional.
+ • col: Column position in units of "screen cell
+ width", may be fractional.
+ • focusable: Enable focus by user actions
+ (wincmds, mouse events). Defaults to true.
+ Non-focusable windows can be entered by
+ |nvim_set_current_win()|.
+ • external: GUI should display the window as an
+ external top-level window. Currently accepts
+ no other positioning configuration together
+ with this.
+ • zindex: Stacking order. floats with higher `zindex` go on top on floats with lower indices. Must
+ be larger than zero. The following screen
+ elements have hard-coded z-indices:
+ • 100: insert completion popupmenu
+ • 200: message scrollback
+ • 250: cmdline completion popupmenu (when
+ wildoptions+=pum) The default value for
+ floats are 50. In general, values below 100
+ are recommended, unless there is a good
+ reason to overshadow builtin elements.
+
+ • style: Configure the appearance of the window.
+ Currently only takes one non-empty value:
+ • "minimal" Nvim will display the window with
+ many UI options disabled. This is useful
+ when displaying a temporary float where the
+ text should not be edited. Disables
+ 'number', 'relativenumber', 'cursorline',
+ 'cursorcolumn', 'foldcolumn', 'spell' and
+ 'list' options. 'signcolumn' is changed to
+ `auto` and 'colorcolumn' is cleared. The
+ end-of-buffer region is hidden by setting
+ `eob` flag of 'fillchars' to a space char,
+ and clearing the |EndOfBuffer| region in
+ 'winhighlight'.
+
+ • border: Style of (optional) window border.
+ This can either be a string or an array. The
+ string values are
+ • "none": No border (default).
+ • "single": A single line box.
+ • "double": A double line box.
+ • "rounded": Like "single", but with rounded
+ corners ("╭" etc.).
+ • "solid": Adds padding by a single whitespace
+ cell.
+ • "shadow": A drop shadow effect by blending
+ with the background.
+ • If it is an array, it should have a length
+ of eight or any divisor of eight. The array
+ will specifify the eight chars building up
+ the border in a clockwise fashion starting
+ with the top-left corner. As an example, the
+ double box style could be specified as [
+ "╔", "═" ,"╗", "║", "╝", "═", "╚", "║" ]. If
+ the number of chars are less than eight,
+ they will be repeated. Thus an ASCII border
+ could be specified as [ "/", "-", "\\", "|"
+ ], or all chars the same as [ "x" ]. An
+ empty string can be used to turn off a
+ specific border, for instance, [ "", "", "",
+ ">", "", "", "", "<" ] will only make
+ vertical borders but not horizontal ones. By
+ default, `FloatBorder` highlight is used,
+ which links to `VertSplit` when not defined.
+ It could also be specified by character: [
+ {"+", "MyCorner"}, {"x", "MyBorder"} ].
+
+ • noautocmd: If true then no buffer-related
+ autocommand events such as |BufEnter|,
+ |BufLeave| or |BufWinEnter| may fire from
+ calling this function.
+
+ Return: ~
+ Window handle, or 0 on error
+
+nvim_win_get_config({window}) *nvim_win_get_config()*
+ Gets window configuration.
+
+ The returned value may be given to |nvim_open_win()|.
+
+ `relative` is empty for normal windows.
+
+ Parameters: ~
+ {window} Window handle, or 0 for current window
+
+ Return: ~
+ Map defining the window configuration, see
+ |nvim_open_win()|
+
+nvim_win_set_config({window}, {*config}) *nvim_win_set_config()*
+ Configures window layout. Currently only for floating and
+ external windows (including changing a split window to those
+ layouts).
+
+ When reconfiguring a floating window, absent option keys will
+ not be changed. `row` / `col` and `relative` must be
+ reconfigured together.
+
+ Parameters: ~
+ {window} Window handle, or 0 for current window
+ {config} Map defining the window configuration, see
+ |nvim_open_win()|
+
+ See also: ~
+ |nvim_open_win()|
+
+
+==============================================================================
Tabpage Functions *api-tabpage*
nvim_tabpage_del_var({tabpage}, {name}) *nvim_tabpage_del_var()*
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index 7a53f17a78..6c41dd3b10 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -519,11 +519,17 @@ DiffUpdated After diffs have been updated. Depending on
change or when doing |:diffupdate|.
*DirChanged*
DirChanged After the |current-directory| was changed.
+ The pattern can be:
+ "window" to trigger on `:lcd`
+ "tabpage" to trigger on `:tcd`
+ "global" to trigger on `:cd`
+ "auto" to trigger on 'autochdir'.
Sets these |v:event| keys:
cwd: current working directory
scope: "global", "tab", "window"
changed_window: v:true if we fired the event
switching window (or tab)
+ <afile> is set to the new directory name.
Non-recursive (event cannot trigger itself).
*FileAppendCmd*
FileAppendCmd Before appending to a file. Should do the
@@ -630,7 +636,7 @@ FilterReadPre Before reading a file from a filter command.
*FilterWritePost*
FilterWritePost After writing a file for a filter command or
making a diff with an external diff (see
- DiffUpdated for internal diff).
+ |DiffUpdated| for internal diff).
Vim checks the pattern against the name of
the current buffer as with FilterWritePre.
Not triggered when 'shelltemp' is off.
@@ -683,23 +689,6 @@ InsertCharPre When a character is typed in Insert mode,
Cannot change the text. |textlock|
Not triggered when 'paste' is set.
- *TextYankPost*
-TextYankPost Just after a |yank| or |deleting| command, but not
- if the black hole register |quote_| is used nor
- for |setreg()|. Pattern must be *.
- Sets these |v:event| keys:
- inclusive
- operator
- regcontents
- regname
- regtype
- visual
- The `inclusive` flag combined with the |'[|
- and |']| marks can be used to calculate the
- precise region of the operation.
-
- Non-recursive (event cannot trigger itself).
- Cannot change the text. |textlock|
*InsertEnter*
InsertEnter Just before starting Insert mode. Also for
Replace mode and Virtual Replace mode. The
@@ -948,6 +937,23 @@ TextChangedP After a change was made to the text in the
current buffer in Insert mode, only when the
popup menu is visible. Otherwise the same as
TextChanged.
+ *TextYankPost*
+TextYankPost Just after a |yank| or |deleting| command, but not
+ if the black hole register |quote_| is used nor
+ for |setreg()|. Pattern must be *.
+ Sets these |v:event| keys:
+ inclusive
+ operator
+ regcontents
+ regname
+ regtype
+ visual
+ The `inclusive` flag combined with the |'[|
+ and |']| marks can be used to calculate the
+ precise region of the operation.
+
+ Non-recursive (event cannot trigger itself).
+ Cannot change the text. |textlock|
*User*
User Not executed automatically. Use |:doautocmd|
to trigger this, typically for "custom events"
@@ -1232,6 +1238,13 @@ Example: >
This prevents having the autocommands defined twice (e.g., after sourcing the
vimrc file again).
+ *FileExplorer*
+There is one group that is recognized by Vim: FileExplorer. If this group
+exists Vim assumes that editing a directory is possible and will trigger a
+plugin that lists the files in that directory. This is used by the |netrw|
+plugin. This allows you to do: >
+ browse edit
+
==============================================================================
9. Executing autocommands *autocmd-execute*
diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt
index 2b799e3e27..ffdd8427f9 100644
--- a/runtime/doc/change.txt
+++ b/runtime/doc/change.txt
@@ -1129,9 +1129,6 @@ a register, a paste on a visual selected area will paste that single line on
each of the selected lines (thus replacing the blockwise selected region by a
block of the pasted line).
-Use |zP|/|zp| to paste a blockwise yanked register without appending trailing
-spaces.
-
*blockwise-register*
If you use a blockwise Visual mode command to get the text into the register,
the block of text will be inserted before ("P") or after ("p") the cursor
@@ -1142,6 +1139,9 @@ this happen. However, if the width of the block is not a multiple of a <Tab>
width and the text after the inserted block contains <Tab>s, that text may be
misaligned.
+Use |zP|/|zp| to paste a blockwise yanked register without appending trailing
+spaces.
+
Note that after a charwise yank command, Vim leaves the cursor on the first
yanked character that is closest to the start of the buffer. This means that
"yl" doesn't move the cursor, but "yh" moves the cursor one character left.
diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt
index a0c291964e..a7ce4135af 100644
--- a/runtime/doc/deprecated.txt
+++ b/runtime/doc/deprecated.txt
@@ -75,7 +75,9 @@ For each of the functions below, use the corresponding function in
*vim.lsp.diagnostic.get_prev()*
*vim.lsp.diagnostic.get_prev_pos()*
*vim.lsp.diagnostic.get_virtual_text_chunks_for_line()*
- Use |vim.diagnostic.get_virt_text_chunks()| instead.
+ No replacement. Use options provided by
+ |vim.diagnostic.config()| to customize
+ virtual text.
*vim.lsp.diagnostic.goto_next()*
*vim.lsp.diagnostic.goto_prev()*
*vim.lsp.diagnostic.redraw()* Use |vim.diagnostic.show()| instead.
diff --git a/runtime/doc/dev_style.txt b/runtime/doc/dev_style.txt
new file mode 100644
index 0000000000..82f279e781
--- /dev/null
+++ b/runtime/doc/dev_style.txt
@@ -0,0 +1,1159 @@
+*dev_style.txt* Nvim
+
+
+ NVIM REFERENCE MANUAL
+
+
+Nvim style guide *dev-style*
+
+This is style guide for developers working on Nvim's source code.
+
+License: CC-By 3.0 http://creativecommons.org/licenses/by/3.0/
+
+ Type |gO| to see the table of contents.
+
+==============================================================================
+Background
+
+One way in which we keep the code base manageable is by enforcing consistency.
+It is very important that any programmer be able to look at another's code and
+quickly understand it.
+
+Maintaining a uniform style and following conventions means that we can more
+easily use "pattern-matching" to infer what various symbols are and what
+invariants are true about them. Creating common, required idioms and patterns
+makes code much easier to understand.
+
+In some cases there might be good arguments for changing certain style rules,
+but we nonetheless keep things as they are in order to preserve consistency.
+
+
+==============================================================================
+Header Files *dev-style-header*
+
+
+The #define Guard ~
+
+All header files should have `#define` guards to prevent multiple inclusion.
+The format of the symbol name should be `NVIM_<DIRECTORY>_<FILE>_H`.
+
+ In foo/bar.h:
+>
+ #ifndef NVIM_FOO_BAR_H
+ #define NVIM_FOO_BAR_H
+
+ ...
+
+ #endif // NVIM_FOO_BAR_H
+<
+
+
+Names and Order of Includes ~
+
+Use standard order for readability and to avoid hidden dependencies: C
+library, other libraries' `.h`, your project's `.h`.
+
+ In foo.c order your includes as follows:
+
+ 1. C system files.
+ 2. Other libraries' `.h` files.
+ 3. Your project's `.h` files.
+
+ Exception: sometimes, system-specific code needs conditional includes.
+ Such code can put conditional includes after other includes. Of course,
+ keep your system-specific code small and localized.
+
+
+Constants ~
+
+Do not use macros to define constants in headers.
+
+Macro constants in header files cannot be used by unit tests.
+
+However, you are allowed to define a macro that holds the same value as a
+non-enum constant (defined in the same header) if the value of the constant
+represents the size of an array.
+
+
+==============================================================================
+Scoping *dev-style-scope*
+
+Local Variables ~
+
+Place a function's variables in the narrowest scope possible, and initialize
+variables in the declaration.
+
+C99 allows you to declare variables anywhere in a function. Declare them in as
+local a scope as possible, and as close to the first use as possible. This
+makes it easier for the reader to find the declaration and see what type the
+variable is and what it was initialized to. In particular, initialization
+should be used instead of declaration and assignment, e.g. >
+
+ int i;
+ i = f(); // BAD: initialization separate from declaration.
+
+ int j = g(); // GOOD: declaration has initialization.
+
+
+==============================================================================
+Nvim-Specific Magic
+
+clint ~
+
+Use `clint.py` to detect style errors.
+
+`src/clint.py` is a Python script that reads a source file and identifies
+style errors. It is not perfect, and has both false positives and false
+negatives, but it is still a valuable tool. False positives can be ignored by
+putting `// NOLINT` at the end of the line.
+
+uncrustify ~
+
+src/uncrustify.cfg is the authority for expected code formatting, for cases
+not covered by clint.py. We remove checks in clint.py if they are covered by
+uncrustify rules.
+
+==============================================================================
+Other C Features *dev-style-features*
+
+
+Variable-Length Arrays and alloca() ~
+
+We do not allow variable-length arrays or `alloca()`.
+
+Variable-length arrays can cause hard to detect stack overflows.
+
+
+Postincrement and Postdecrement ~
+
+Use postfix form (`i++`) in statements. >
+
+ for (int i = 0; i < 3; i++) { }
+ int j = ++i; // OK: ++i is used as an expression.
+
+ for (int i = 0; i < 3; ++i) { }
+ ++i; // BAD: ++i is used as a statement.
+
+
+Use of const ~
+
+Use `const` pointers whenever possible. Avoid `const` on non-pointer parameter definitions.
+
+ Where to put the const ~
+
+ Some people favor the form `int const *foo` to `const int *foo` . They
+ argue that this is more readable because it's more consistent: it keeps
+ the rule that `const` always follows the object it's describing. However,
+ this consistency argument doesn't apply in codebases with few
+ deeply-nested pointer expressions since most `const` expressions have only
+ one `const`, and it applies to the underlying value. In such cases, there's
+ no consistency to maintain. Putting the `const` first is arguably more
+ readable, since it follows English in putting the "adjective" (`const`)
+ before the "noun" (`int`).
+
+ That said, while we encourage putting `const` first, we do not require it.
+ But be consistent with the code around you! >
+
+ void foo(const char *p, int i);
+ }
+
+ int foo(const int a, const bool b) {
+ }
+
+ int foo(int *const p) {
+ }
+
+
+Integer Types ~
+
+Of the built-in integer types only use `char`, `int`, `uint8_t`, `int8_t`,
+`uint16_t`, `int16_t`, `uint32_t`, `int32_t`, `uint64_t`, `int64_t`,
+`uintmax_t`, `intmax_t`, `size_t`, `ssize_t`, `uintptr_t`, `intptr_t`, and
+`ptrdiff_t`.
+
+Use `int` for error codes and local, trivial variables only.
+
+Use care when converting integer types. Integer conversions and promotions can
+cause non-intuitive behavior. Note that the signedness of `char` is
+implementation defined.
+
+Public facing types must have fixed width (`uint8_t`, etc.)
+
+There are no convenient `printf` format placeholders for fixed width types.
+Cast to `uintmax_t` or `intmax_t` if you have to format fixed width integers.
+
+Type unsigned signed
+`char` `%hhu` `%hhd`
+`int` n/a `%d`
+`(u)intmax_t` `%ju` `%jd`
+`(s)size_t` `%zu` `%zd`
+`ptrdiff_t` `%tu` `%td`
+
+
+Booleans ~
+
+Use `bool` to represent boolean values. >
+
+ int loaded = 1; // BAD: loaded should have type bool.
+
+
+Variable declarations ~
+
+Declare only one variable per line. >
+
+ int i, j = 1
+
+
+Conditions ~
+
+Don't use "yoda-conditions". Use at most one assignment per condition. >
+
+ if (1 == x) {
+
+ if (x == 1) { //use this order
+
+ if ((x = f()) && (y = g())) {
+
+
+Function declarations ~
+
+Every function must not have a separate declaration.
+
+Function declarations are created by the gendeclarations.lua script. >
+
+ static void f(void);
+
+ static void f(void)
+ {
+ ...
+ }
+
+
+General translation unit layout ~
+
+The definitions of public functions precede the definitions of static
+functions. >
+
+ <HEADER>
+
+ <PUBLIC FUNCTION DEFINITIONS>
+
+ <STATIC FUNCTION DEFINITIONS>
+
+
+Integration with declarations generator ~
+
+Every C file must contain #include of the generated header file, guarded by
+#ifdef INCLUDE_GENERATED_DECLARATIONS.
+
+Include must go after other #includes and typedefs in .c files and after
+everything else in header files. It is allowed to omit #include in a .c file
+if .c file does not contain any static functions.
+
+Included file name consists of the .c file name without extension, preceded by
+the directory name relative to src/nvim. Name of the file containing static
+functions declarations ends with `.c.generated.h`, `*.h.generated.h` files
+contain only non-static function declarations. >
+
+ // src/nvim/foo.c file
+ #include <stddef.h>
+
+ typedef int FooType;
+
+ #ifdef INCLUDE_GENERATED_DECLARATIONS
+ # include "foo.c.generated.h"
+ #endif
+
+ …
+
+
+ // src/nvim/foo.h file
+ #ifndef NVIM_FOO_H
+ #define NVIM_FOO_H
+
+ …
+
+ #ifdef INCLUDE_GENERATED_DECLARATIONS
+ # include "foo.h.generated.h"
+ #endif
+ #endif // NVIM_FOO_H
+
+
+64-bit Portability ~
+
+Code should be 64-bit and 32-bit friendly. Bear in mind problems of printing,
+comparisons, and structure alignment.
+
+- Remember that `sizeof(void *)` != `sizeof(int)`. Use `intptr_t` if you want
+ a pointer-sized integer.
+
+- You may need to be careful with structure alignments, particularly for
+ structures being stored on disk. Any class/structure with a
+ `int64_t`/`uint64_t` member will by default end up being 8-byte aligned on a
+ 64-bit system. If you have such structures being shared on disk between
+ 32-bit and 64-bit code, you will need to ensure that they are packed the
+ same on both architectures. Most compilers offer a way to alter structure
+ alignment. For gcc, you can use `__attribute__((packed))`. MSVC offers
+ `#pragma pack()` and `__declspec(align())`.
+
+- Use the `LL` or `ULL` suffixes as needed to create 64-bit constants. For
+ example: >
+
+ int64_t my_value = 0x123456789LL;
+ uint64_t my_mask = 3ULL << 48;
+
+
+sizeof ~
+
+Prefer `sizeof(varname)` to `sizeof(type)`.
+
+Use `sizeof(varname)` when you take the size of a particular variable.
+`sizeof(varname)` will update appropriately if someone changes the variable
+type either now or later. You may use `sizeof(type)` for code unrelated to any
+particular variable, such as code that manages an external or internal data
+format where a variable of an appropriate C type is not convenient. >
+
+ Struct data;
+ memset(&data, 0, sizeof(data));
+
+ memset(&data, 0, sizeof(Struct));
+
+ if (raw_size < sizeof(int)) {
+ fprintf(stderr, "compressed record not big enough for count: %ju", raw_size);
+ return false;
+ }
+
+
+==============================================================================
+Naming *dev-style-naming*
+
+The most important consistency rules are those that govern naming. The style
+of a name immediately informs us what sort of thing the named entity is: a
+type, a variable, a function, a constant, a macro, etc., without requiring us
+to search for the declaration of that entity. The pattern-matching engine in
+our brains relies a great deal on these naming rules.
+
+Naming rules are pretty arbitrary, but we feel that consistency is more
+important than individual preferences in this area, so regardless of whether
+you find them sensible or not, the rules are the rules.
+
+
+General Naming Rules ~
+
+Function names, variable names, and filenames should be descriptive; eschew
+abbreviation.
+
+Give as descriptive a name as possible, within reason. Do not worry about
+saving horizontal space as it is far more important to make your code
+immediately understandable by a new reader. Do not use abbreviations that are
+ambiguous or unfamiliar to readers outside your project, and do not abbreviate
+by deleting letters within a word. >
+
+ int price_count_reader; // No abbreviation.
+ int num_errors; // "num" is a widespread convention.
+ int num_dns_connections; // Most people know what "DNS" stands for.
+
+ int n; // Meaningless.
+ int nerr; // Ambiguous abbreviation.
+ int n_comp_conns; // Ambiguous abbreviation.
+ int wgc_connections; // Only your group knows what this stands for.
+ int pc_reader; // Lots of things can be abbreviated "pc".
+ int cstmr_id; // Deletes internal letters.
+
+
+File Names ~
+
+Filenames should be all lowercase and can include underscores (`_`).
+
+Use underscores to separate words. Examples of acceptable file names: >
+
+ my_useful_file.c
+ getline_fix.c // OK: getline refers to the glibc function.
+
+C files should end in `.c` and header files should end in `.h`.
+
+Do not use filenames that already exist in `/usr/include`, such as `db.h`.
+
+In general, make your filenames very specific. For example, use
+`http_server_logs.h` rather than `logs.h`.
+
+
+Type Names ~
+
+Typedef-ed structs and enums start with a capital letter and have a capital
+letter for each new word, with no underscores: `MyExcitingStruct`.
+
+Non-Typedef-ed structs and enums are all lowercase with underscores between
+words: `struct my_exciting_struct` . >
+
+ struct my_struct {
+ ...
+ };
+ typedef struct my_struct MyAwesomeStruct;
+
+
+Variable Names ~
+
+Variable names are all lowercase, with underscores between words. For
+instance: `my_exciting_local_variable`.
+
+ Common Variable names ~
+
+ For example: >
+
+ string table_name; // OK: uses underscore.
+ string tablename; // OK: all lowercase.
+
+ string tableName; // BAD: mixed case.
+<
+
+ Struct Variables ~
+
+ Data members in structs should be named like regular variables. >
+
+ struct url_table_properties {
+ string name;
+ int num_entries;
+ }
+<
+
+ Global Variables ~
+
+ Don't use global variables unless absolutely necessary. Prefix global
+ variables with `g_`.
+
+
+Constant Names ~
+
+Use a `k` followed by mixed case: `kDaysInAWeek`.
+
+All compile-time constants, whether they are declared locally or globally,
+follow a slightly different naming convention from other variables. Use a `k`
+followed by words with uppercase first letters: >
+
+ const int kDaysInAWeek = 7;
+
+Function Names ~
+
+Function names are all lowercase, with underscores between words. For
+instance: `my_exceptional_function()`. All functions in the same header file
+should have a common prefix.
+
+In `os_unix.h`: >
+
+ void unix_open(const char *path);
+ void unix_user_id(void);
+
+If your function crashes upon an error, you should append `or_die` to the
+function name. This only applies to functions which could be used by
+production code and to errors that are reasonably likely to occur during
+normal operation.
+
+
+Enumerator Names ~
+
+Enumerators should be named like constants: `kEnumName`. >
+
+ enum url_table_errors {
+ kOK = 0,
+ kErrorOutOfMemory,
+ kErrorMalformedInput,
+ };
+
+
+Macro Names ~
+
+They're like this: `MY_MACRO_THAT_SCARES_CPP_DEVELOPERS`. >
+
+ #define ROUND(x) ...
+ #define PI_ROUNDED 5.0
+
+
+==============================================================================
+Comments *dev-style-comments*
+
+Comments are vital to keeping our code readable. The following rules describe
+what you should comment and where. But remember: while comments are very
+important, the best code is self-documenting.
+
+When writing your comments, write for your audience: the next contributor who
+will need to understand your code. Be generous — the next one may be you!
+
+Nvim uses Doxygen comments.
+
+
+Comment Style ~
+
+Use the `//`-style syntax only. >
+
+ // This is a comment spanning
+ // multiple lines
+ f();
+
+
+File Comments ~
+
+Start each file with a description of its contents.
+
+ Legal Notice ~
+
+ We have no such thing. These things are in LICENSE and only there.
+
+ File Contents ~
+
+ Every file should have a comment at the top describing its contents.
+
+ Generally a `.h` file will describe the variables and functions that are
+ declared in the file with an overview of what they are for and how they
+ are used. A `.c` file should contain more information about implementation
+ details or discussions of tricky algorithms. If you feel the
+ implementation details or a discussion of the algorithms would be useful
+ for someone reading the `.h`, feel free to put it there instead, but
+ mention in the `.c` that the documentation is in the `.h` file.
+
+ Do not duplicate comments in both the `.h` and the `.c`. Duplicated
+ comments diverge. >
+
+ /// A brief description of this file.
+ ///
+ /// A longer description of this file.
+ /// Be very generous here.
+
+
+Struct Comments ~
+
+Every struct definition should have accompanying comments that describes what
+it is for and how it should be used. >
+
+ /// Window info stored with a buffer.
+ ///
+ /// Two types of info are kept for a buffer which are associated with a
+ /// specific window:
+ /// 1. Each window can have a different line number associated with a
+ /// buffer.
+ /// 2. The window-local options for a buffer work in a similar way.
+ /// The window-info is kept in a list at g_wininfo. It is kept in
+ /// most-recently-used order.
+ struct win_info {
+ /// Next entry or NULL for last entry.
+ WinInfo *wi_next;
+ /// Previous entry or NULL for first entry.
+ WinInfo *wi_prev;
+ /// Pointer to window that did the wi_fpos.
+ Win *wi_win;
+ ...
+ };
+
+If the field comments are short, you can also put them next to the field. But
+be consistent within one struct. >
+
+ struct wininfo_S {
+ WinInfo *wi_next; /// Next entry or NULL for last entry.
+ WinInfo *wi_prev; /// Previous entry or NULL for first entry.
+ Win *wi_win; /// Pointer to window that did the wi_fpos.
+ ...
+ };
+
+If you have already described a struct in detail in the comments at the top of
+your file feel free to simply state "See comment at top of file for a complete
+description", but be sure to have some sort of comment.
+
+Document the synchronization assumptions the struct makes, if any. If an
+instance of the struct can be accessed by multiple threads, take extra care to
+document the rules and invariants surrounding multithreaded use.
+
+
+Function Comments ~
+
+Declaration comments describe use of the function; comments at the definition
+of a function describe operation.
+
+ Function Declarations ~
+
+ Every function declaration should have comments immediately preceding it
+ that describe what the function does and how to use it. These comments
+ should be descriptive ("Opens the file") rather than imperative ("Open the
+ file"); the comment describes the function, it does not tell the function
+ what to do. In general, these comments do not describe how the function
+ performs its task. Instead, that should be left to comments in the
+ function definition.
+
+ Types of things to mention in comments at the function declaration:
+
+ - If the function allocates memory that the caller must free.
+ - Whether any of the arguments can be a null pointer.
+ - If there are any performance implications of how a function is used.
+ - If the function is re-entrant. What are its synchronization assumptions?
+ >
+ /// Brief description of the function.
+ ///
+ /// Detailed description.
+ /// May span multiple paragraphs.
+ ///
+ /// @param arg1 Description of arg1
+ /// @param arg2 Description of arg2. May span
+ /// multiple lines.
+ ///
+ /// @return Description of the return value.
+ Iterator *get_iterator(void *arg1, void *arg2);
+<
+
+ Function Definitions ~
+
+ If there is anything tricky about how a function does its job, the
+ function definition should have an explanatory comment. For example, in
+ the definition comment you might describe any coding tricks you use, give
+ an overview of the steps you go through, or explain why you chose to
+ implement the function in the way you did rather than using a viable
+ alternative. For instance, you might mention why it must acquire a lock
+ for the first half of the function but why it is not needed for the second
+ half.
+
+ Note you should not just repeat the comments given with the function
+ declaration, in the `.h` file or wherever. It's okay to recapitulate
+ briefly what the function does, but the focus of the comments should be on
+ how it does it. >
+
+ // Note that we don't use Doxygen comments here.
+ Iterator *get_iterator(void *arg1, void *arg2)
+ {
+ ...
+ }
+
+
+Variable Comments ~
+
+In general the actual name of the variable should be descriptive enough to
+give a good idea of what the variable is used for. In certain cases, more
+comments are required.
+
+ Global Variables ~
+
+ All global variables should have a comment describing what they are and
+ what they are used for. For example: >
+
+ /// The total number of tests cases that we run
+ /// through in this regression test.
+ const int kNumTestCases = 6;
+
+
+Implementation Comments ~
+
+In your implementation you should have comments in tricky, non-obvious,
+interesting, or important parts of your code.
+
+ Line Comments ~
+
+ Also, lines that are non-obvious should get a comment at the end of the
+ line. These end-of-line comments should be separated from the code by 2
+ spaces. Example: >
+
+ // If we have enough memory, mmap the data portion too.
+ mmap_budget = max<int64>(0, mmap_budget - index_->length());
+ if (mmap_budget >= data_size_ && !MmapData(mmap_chunk_bytes, mlock)) {
+ return; // Error already logged.
+ }
+<
+ Note that there are both comments that describe what the code is doing,
+ and comments that mention that an error has already been logged when the
+ function returns.
+
+ If you have several comments on subsequent lines, it can often be more
+ readable to line them up: >
+
+ do_something(); // Comment here so the comments line up.
+ do_something_else_that_is_longer(); // Comment here so there are two spaces between
+ // the code and the comment.
+ { // One space before comment when opening a new scope is allowed,
+ // thus the comment lines up with the following comments and code.
+ do_something_else(); // Two spaces before line comments normally.
+ }
+<
+
+ NULL, true/false, 1, 2, 3... ~
+
+ When you pass in a null pointer, boolean, or literal integer values to
+ functions, you should consider adding a comment about what they are, or
+ make your code self-documenting by using constants. For example, compare:
+ >
+
+ bool success = calculate_something(interesting_value,
+ 10,
+ false,
+ NULL); // What are these arguments??
+<
+
+ versus: >
+
+ bool success = calculate_something(interesting_value,
+ 10, // Default base value.
+ false, // Not the first time we're calling this.
+ NULL); // No callback.
+<
+
+ Or alternatively, constants or self-describing variables: >
+
+ const int kDefaultBaseValue = 10;
+ const bool kFirstTimeCalling = false;
+ Callback *null_callback = NULL;
+ bool success = calculate_something(interesting_value,
+ kDefaultBaseValue,
+ kFirstTimeCalling,
+ null_callback);
+<
+
+ Don'ts ~
+
+ Note that you should never describe the code itself. Assume that the
+ person reading the code knows C better than you do, even though he or she
+ does not know what you are trying to do: >
+
+ // Now go through the b array and make sure that if i occurs,
+ // the next element is i+1.
+ ... // Geez. What a useless comment.
+
+
+Punctuation, Spelling and Grammar ~
+
+Pay attention to punctuation, spelling, and grammar; it is easier to read
+well-written comments than badly written ones.
+
+Comments should be as readable as narrative text, with proper capitalization
+and punctuation. In many cases, complete sentences are more readable than
+sentence fragments. Shorter comments, such as comments at the end of a line of
+code, can sometimes be less formal, but you should be consistent with your
+style.
+
+Although it can be frustrating to have a code reviewer point out that you are
+using a comma when you should be using a semicolon, it is very important that
+source code maintain a high level of clarity and readability. Proper
+punctuation, spelling, and grammar help with that goal.
+
+
+TODO Comments ~
+
+Use `TODO` comments for code that is temporary, a short-term solution, or
+good-enough but not perfect.
+
+`TODO`s should include the string `TODO` in all caps, followed by the name,
+email address, or other identifier of the person who can best provide context
+about the problem referenced by the `TODO`. The main purpose is to have a
+consistent `TODO` format that can be searched to find the person who can
+provide more details upon request. A `TODO` is not a commitment that the
+person referenced will fix the problem. Thus when you create a `TODO`, it is
+almost always your name that is given. >
+
+ // TODO(kl@gmail.com): Use a "*" here for concatenation operator.
+ // TODO(Zeke): change this to use relations.
+
+If your `TODO` is of the form "At a future date do something" make sure that
+you either include a very specific date ("Fix by November 2005") or a very
+specific event ("Remove this code when all clients can handle XML
+responses.").
+
+
+Deprecation Comments ~
+
+Mark deprecated interface points with `@deprecated` docstring token.
+
+You can mark an interface as deprecated by writing a comment containing the
+word `@deprecated` in all caps. The comment goes either before the declaration
+of the interface or on the same line as the declaration.
+
+After `@deprecated`, write your name, email, or other identifier in
+parentheses.
+
+A deprecation comment must include simple, clear directions for people to fix
+their callsites. In C, you can implement a deprecated function as an inline
+function that calls the new interface point.
+
+Marking an interface point `DEPRECATED` will not magically cause any callsites
+to change. If you want people to actually stop using the deprecated facility,
+you will have to fix the callsites yourself or recruit a crew to help you.
+
+New code should not contain calls to deprecated interface points. Use the new
+interface point instead. If you cannot understand the directions, find the
+person who created the deprecation and ask them for help using the new
+interface point.
+
+
+==============================================================================
+Formatting *dev-style-format*
+
+Coding style and formatting are pretty arbitrary, but a project is much easier
+to follow if everyone uses the same style. Individuals may not agree with
+every aspect of the formatting rules, and some of the rules may take some
+getting used to, but it is important that all project contributors follow the
+style rules so that they can all read and understand everyone's code easily.
+
+
+Line Length ~
+
+Each line of text in your code should be at most 100 characters long.
+
+Exception: if a comment line contains an example command or a literal URL
+longer than 100 characters, that line may be longer than 100 characters for ease
+of cut and paste.
+
+
+Non-ASCII Characters ~
+
+Non-ASCII characters should be rare, and must use UTF-8 formatting.
+
+You shouldn't hard-code user-facing text in source (OR SHOULD YOU?), even
+English, so use of non-ASCII characters should be rare. However, in certain
+cases it is appropriate to include such words in your code. For example, if
+your code parses data files from foreign sources, it may be appropriate to
+hard-code the non-ASCII string(s) used in those data files as delimiters. More
+commonly, unittest code (which does not need to be localized) might contain
+non-ASCII strings. In such cases, you should use UTF-8, since that is an
+encoding understood by most tools able to handle more than just ASCII.
+
+Hex encoding is also OK, and encouraged where it enhances readability — for
+example, `"\uFEFF"`, is the Unicode zero-width no-break space character, which
+would be invisible if included in the source as straight UTF-8.
+
+
+Spaces vs. Tabs ~
+
+Use only spaces, and indent 2 spaces at a time. Do not use tabs in your code.
+
+
+Function Declarations and Definitions ~
+
+Return type on the same line as function name, parameters on the same line if
+they fit.
+
+Functions look like this: >
+
+ ReturnType function_name(Type par_name1, Type par_name2)
+ {
+ do_something();
+ ...
+ }
+
+If you have too much text to fit on one line: >
+
+ ReturnType really_long_function_name(Type par_name1, Type par_name2,
+ Type par_name3)
+ {
+ do_something();
+ ...
+ }
+
+or if you cannot fit even the first parameter (but only then): >
+
+ ReturnType really_really_really_long_function_name(
+ Type par_name1, // 4 space indent
+ Type par_name2,
+ Type par_name3)
+ {
+ do_something(); // 2 space indent
+ ...
+ }
+
+Some points to note:
+
+- The open parenthesis is always on the same line as the function name.
+- There is never a space between the function name and the open parenthesis.
+- There is never a space between the parentheses and the parameters.
+- The open curly brace is always on the next line.
+- The close curly brace is always on the last line by itself.
+- There should be a space between the close parenthesis and the open curly
+ brace.
+- All parameters should be named, with identical names in the declaration and
+ implementation.
+- All parameters should be aligned if possible.
+- Default indentation is 2 spaces.
+- Wrapped parameters have a 4 space indent.
+
+
+Function Calls ~
+
+On one line if it fits; otherwise, wrap arguments at the parenthesis.
+
+Function calls have the following format: >
+
+ bool retval = do_something(argument1, argument2, argument3);
+
+If the arguments do not all fit on one line, they should be broken up onto
+multiple lines, with each subsequent line aligned with the first argument. Do
+not add spaces after the open paren or before the close paren: >
+
+ bool retval = do_something(averyveryveryverylongargument1,
+ argument2, argument3);
+
+If the function has many arguments, consider having one per line if this makes
+the code more readable: >
+
+ bool retval = do_something(argument1,
+ argument2,
+ argument3,
+ argument4);
+
+Arguments may optionally all be placed on subsequent lines, with one line per
+argument: >
+
+ if (...) {
+ ...
+ ...
+ if (...) {
+ do_something(
+ argument1, // 4 space indent
+ argument2,
+ argument3,
+ argument4);
+ }
+
+In particular, this should be done if the function signature is so long that
+it cannot fit within the maximum line length.
+
+
+Braced Initializer Lists ~
+
+Format a braced list exactly like you would format a function call in its
+place but with one space after the `{` and one space before the `}`
+
+If the braced list follows a name (e.g. a type or variable name), format as if
+the `{}` were the parentheses of a function call with that name. If there is
+no name, assume a zero-length name. >
+
+ struct my_struct m = { // Here, you could also break before {.
+ superlongvariablename1,
+ superlongvariablename2,
+ { short, interior, list },
+ { interiorwrappinglist,
+ interiorwrappinglist2 } };
+
+
+Conditionals ~
+
+Don't use spaces inside parentheses. Always use curly braces. >
+
+ if (condition) { // no spaces inside parentheses
+ ... // 2 space indent.
+ } else if (...) { // The else goes on the same line as the closing brace.
+ ...
+ } else {
+ ...
+ }
+
+You must have a space between the `if` and the open parenthesis. You must also
+have a space between the close parenthesis and the curly brace, if you're
+using one. >
+
+ if(condition) { // BAD: space missing after IF.
+ if (condition){ // BAD: space missing before {.
+ if (condition) { // GOOD: proper space after IF and before {.
+
+
+Loops and Switch Statements ~
+
+Annotate non-trivial fall-through between cases. Empty loop bodies should use
+`{}` or `continue`.
+
+If not conditional on an enumerated value, switch statements should always
+have a `default` case (in the case of an enumerated value, the compiler will
+warn you if any values are not handled). If the default case should never
+execute, simply `assert`: >
+
+ switch (var) {
+ case 0: // 2 space indent
+ ... // 4 space indent
+ break;
+ case 1:
+ ...
+ break;
+ default:
+ assert(false);
+ }
+
+Empty loop bodies should use `{}` or `continue`, but not a single semicolon. >
+
+ while (condition) {
+ // Repeat test until it returns false.
+ }
+ for (int i = 0; i < kSomeNumber; i++) {} // GOOD: empty body.
+ while (condition) continue; // GOOD: continue indicates no logic.
+
+ while (condition); // BAD: looks like part of do/while loop.
+
+Pointer Expressions ~
+
+No spaces around period or arrow. Pointer operators do not have trailing
+spaces.
+
+The following are examples of correctly-formatted pointer and reference
+expressions: >
+
+ x = *p;
+ p = &x;
+ x = r.y;
+ x = r->y;
+
+Note that:
+
+ - There are no spaces around the period or arrow when accessing a member.
+ - Pointer operators have no space after the * or &.
+
+When declaring a pointer variable or argument, place the asterisk adjacent to
+the variable name: >
+
+ char *c;
+
+ char * c; // BAD: spaces on both sides of *
+ char* c; // BAD
+
+
+Boolean Expressions ~
+
+When you have a boolean expression that is longer than the standard line
+length, keep operators at the start of the line. >
+
+ if (this_one_thing > this_other_thing
+ && a_third_thing == a_fourth_thing
+ && yet_another && last_one) {
+ ...
+ }
+
+Also note that you should always use the punctuation operators, such as `&&`
+and `~`, rather than the word operators, such as `and` and `compl`.
+
+
+Return Values ~
+
+Do not needlessly surround the `return` expression with parentheses.
+
+Use parentheses in `return expr`; only where you would use them in `x =
+expr;`. >
+
+ return result;
+ return (some_long_condition && another_condition);
+
+ return (value); // You wouldn't write var = (value);
+ return(result); // return is not a function!
+
+
+Preprocessor Directives ~
+
+The hash mark that starts a preprocessor directive should always be at the
+beginning of the line.
+
+Even when preprocessor directives are within the body of indented code, the
+directives should start at the beginning of the line.
+
+Nested directives should add one spaces after the hash mark for each level of
+indentation.
+
+ // GOOD: directives at beginning of line >
+ if (lopsided_score) {
+ #if DISASTER_PENDING // Correct -- Starts at beginning of line
+ drop_everything();
+ # if NOTIFY // One space after #
+ notify_client();
+ # endif
+ #endif
+ BackToNormal();
+ }
+
+< // BAD: indented directives >
+ if (lopsided_score) {
+ #if DISASTER_PENDING // Wrong! The "#if" should be at beginning of line
+ drop_everything();
+ #endif // Wrong! Do not indent "#endif"
+ back_to_normal();
+ }
+
+
+Horizontal Whitespace ~
+
+Use of horizontal whitespace depends on location. Never put trailing
+whitespace at the end of a line.
+
+ General ~
+>
+ if (x) { // Open braces should always have a space before them.
+ ...
+ }
+ int i = 0; // Semicolons usually have no space before them.
+ int x[] = { 0 }; // Spaces inside braces for braced-init-list.
+<
+
+ Variables ~
+>
+ int long_variable = 0; // Don't align assignments.
+ int i = 1;
+
+ struct my_struct { // Exception: struct arrays.
+ const char *boy;
+ const char *girl;
+ int pos;
+ } my_variable[] = {
+ { "Mia", "Michael", 8 },
+ { "Elizabeth", "Aiden", 10 },
+ { "Emma", "Mason", 2 },
+ };
+<
+
+ Macros ~
+>
+ #define FI(x) \ // Don't align \'s in macro definitions.
+ foo(); \
+ bar(); \
+ ...
+<
+
+ Loops and Conditionals ~
+>
+ if (b) { // Space after the keyword in condition.
+ } else { // Spaces around else.
+ }
+ while (test) {} // There is usually no space inside parentheses.
+ for (; i < 5; i++) { // For loops always have a space after the
+ ... // semicolon and no a space before the
+ ... // semicolon.
+ }
+ switch (i) {
+ case 1: // No space before colon in a switch case.
+ ...
+ case 2: break; // Space after a colon if there's code after it.
+<
+
+ Operators ~
+>
+ x = 0; // Assignment operators always have spaces around
+ // them.
+ x = -5; // No spaces separating unary operators and their
+ x++; // arguments.
+ if (x && !y)
+ ...
+ v = w*x + y/z; // Use spaces to indicate operator precedence.
+ v = w * (x + z); // Parentheses should have no spaces inside them.
+ i = (int)d; // No spaces after a cast operator.
+<
+
+Vertical Whitespace ~
+
+Minimize use of vertical whitespace.
+
+This is more a principle than a rule: don't use blank lines when you don't
+have to. In particular, don't put more than one or two blank lines between
+functions, resist starting functions with a blank line, don't end functions
+with a blank line, and be discriminating with your use of blank lines inside
+functions.
+
+The basic principle is: The more code that fits on one screen, the easier it
+is to follow and understand the control flow of the program. Of course,
+readability can suffer from code being too dense as well as too spread out, so
+use your judgment. But in general, minimize use of vertical whitespace.
+
+
+==============================================================================
+Parting Words
+
+The style guide is intended to make the code more readable. If you think you
+must violate its rules for the sake of clarity, do it! But please add a note
+to your pull request explaining your reasoning.
+
+
+ vim:tw=78:ts=8:et:ft=help:norl:
diff --git a/runtime/doc/develop.txt b/runtime/doc/develop.txt
index 14f35acce3..7127c74134 100644
--- a/runtime/doc/develop.txt
+++ b/runtime/doc/develop.txt
@@ -166,7 +166,7 @@ Docstring format:
- Use `<pre>` for code samples.
Example: the help for |nvim_open_win()| is generated from a docstring defined
-in src/nvim/api/vim.c like this: >
+in src/nvim/api/win_config.c like this: >
/// Opens a new window.
/// ...
diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt
index 59b73771a6..4d1e5ac997 100644
--- a/runtime/doc/diagnostic.txt
+++ b/runtime/doc/diagnostic.txt
@@ -47,6 +47,7 @@ A diagnostic is a Lua table with the following keys:
end_col: The final column of the diagnostic
severity: The severity of the diagnostic |vim.diagnostic.severity|
message: The diagnostic text
+ source: The source of the diagnostic
Diagnostics use the same indexing as the rest of the Nvim API (i.e. 0-based
rows and columns). |api-indexing|
@@ -186,6 +187,11 @@ can be customized using the following: >
sign define DiagnosticSignInfo text=I texthl=DiagnosticSignInfo linehl= numhl=
sign define DiagnosticSignHint text=H texthl=DiagnosticSignHint linehl= numhl=
+When the "severity_sort" option is set (see |vim.diagnostic.config()|) the
+priority of each sign depends on the severity of the associated diagnostic.
+Otherwise, all signs have the same priority (the value of the "priority"
+option in the "signs" table of |vim.diagnostic.config()| or 10 if unset).
+
==============================================================================
EVENTS *diagnostic-events*
@@ -195,7 +201,52 @@ DiagnosticsChanged After diagnostics have changed.
Example: >
autocmd User DiagnosticsChanged lua vim.diagnostic.setqflist({open = false })
<
-
+==============================================================================
+CUSTOMIZATION *diagnostic-config*
+
+If you need more customization over the way diagnostics are displayed than the
+built-in configuration options provide, you can override the display handler
+explicitly. For example, use the following to only show a sign for the highest
+severity diagnostic on a given line: >
+
+ -- Disable the default signs handler
+ vim.diagnostic.config({signs = false})
+
+ -- Create a namespace. This won't be used to add any diagnostics,
+ -- only to display them.
+ local ns = vim.api.nvim_create_namespace("my_namespace")
+
+ -- Create a reference to the original function
+ local orig_show = vim.diagnostic.show
+
+ local function set_signs(bufnr)
+ -- Get all diagnostics from the current buffer
+ local diagnostics = vim.diagnostic.get(bufnr)
+
+ -- Find the "worst" diagnostic per line
+ local max_severity_per_line = {}
+ for _, d in pairs(diagnostics) do
+ local m = max_severity_per_line[d.lnum]
+ if not m or d.severity < m.severity then
+ max_severity_per_line[d.lnum] = d
+ end
+ end
+
+ -- Show the filtered diagnostics using the custom namespace. Use the
+ -- reference to the original function to avoid a loop.
+ local filtered_diagnostics = vim.tbl_values(max_severity_per_line)
+ orig_show(ns, bufnr, filtered_diagnostics, {
+ virtual_text=false,
+ underline=false,
+ signs=true
+ })
+ end
+
+ function vim.diagnostic.show(namespace, bufnr, ...)
+ orig_show(namespace, bufnr, ...)
+ set_signs(bufnr)
+ end
+<
==============================================================================
Lua module: vim.diagnostic *diagnostic-api*
@@ -203,12 +254,31 @@ config({opts}, {namespace}) *vim.diagnostic.config()*
Configure diagnostic options globally or for a specific
diagnostic namespace.
+ Configuration can be specified globally, per-namespace, or
+ ephemerally (i.e. only for a single call to
+ |vim.diagnostic.set()| or |vim.diagnostic.show()|). Ephemeral
+ configuration has highest priority, followed by namespace
+ configuration, and finally global configuration.
+
+ For example, if a user enables virtual text globally with >
+
+ vim.diagnostic.config({virtual_text = true})
+<
+
+ and a diagnostic producer sets diagnostics with >
+
+ vim.diagnostic.set(ns, 0, diagnostics, {virtual_text = false})
+<
+
+ then virtual text will not be enabled for those diagnostics.
+
Note:
Each of the configuration options below accepts one of the
following:
• `false` : Disable this feature
• `true` : Enable this feature, use default settings.
- • `table` : Enable this feature with overrides.
+ • `table` : Enable this feature with overrides. Use an
+ empty table to use default values.
• `function` : Function with signature (namespace, bufnr)
that returns any of the above.
@@ -226,12 +296,45 @@ config({opts}, {namespace}) *vim.diagnostic.config()*
• severity: Only show virtual text for
diagnostics matching the given severity
|diagnostic-severity|
+ • source: (string) Include the diagnostic
+ source in virtual text. One of "always"
+ or "if_many".
+ • format: (function) A function that takes
+ a diagnostic as input and returns a
+ string. The return value is the text used
+ to display the diagnostic. Example: >
+
+ function(diagnostic)
+ if diagnostic.severity == vim.diagnostic.severity.ERROR then
+ return string.format("E: %s", diagnostic.message)
+ end
+ return diagnostic.message
+ end
+<
• signs: (default true) Use signs for
diagnostics. Options:
• severity: Only show signs for diagnostics
matching the given severity
|diagnostic-severity|
+ • priority: (number, default 10) Base
+ priority to use for signs. When
+ {severity_sort} is used, the priority of
+ a sign is adjusted based on its severity.
+ Otherwise, all signs use the same
+ priority.
+
+ • float: Options for floating windows:
+ • severity: See |diagnostic-severity|.
+ • show_header: (boolean, default true) Show
+ "Diagnostics:" header
+ • source: (string) Include the diagnostic
+ source in the message. One of "always" or
+ "if_many".
+ • format: (function) A function that takes
+ a diagnostic as input and returns a
+ string. The return value is the text used
+ to display the diagnostic.
• update_in_insert: (default false) Update
diagnostics in Insert mode (if false,
@@ -291,6 +394,13 @@ get({bufnr}, {opts}) *vim.diagnostic.get()*
Return: ~
table A list of diagnostic items |diagnostic-structure|.
+get_namespaces() *vim.diagnostic.get_namespaces()*
+ Get current diagnostic namespaces.
+
+ Return: ~
+ table A list of active diagnostic namespaces
+ |vim.diagnostic|.
+
get_next({opts}) *vim.diagnostic.get_next()*
Get the next diagnostic closest to the cursor position.
@@ -329,26 +439,6 @@ get_prev_pos({opts}) *vim.diagnostic.get_prev_pos()*
Return: ~
table Previous diagnostic position as a (row, col) tuple.
- *vim.diagnostic.get_virt_text_chunks()*
-get_virt_text_chunks({line_diags}, {opts})
- Get virtual text chunks to display using
- |nvim_buf_set_extmark()|.
-
- Parameters: ~
- {line_diags} table The diagnostics associated with the
- line.
- {opts} table|nil Configuration table with the
- following keys:
- • prefix: (string) Prefix to display before
- virtual text on line.
- • spacing: (number) Number of spaces to
- insert before virtual text.
-
- Return: ~
- array of ({text}, {hl_group}) tuples. This can be passed
- directly to the {virt_text} option of
- |nvim_buf_set_extmark()|.
-
goto_next({opts}) *vim.diagnostic.goto_next()*
Move to the next diagnostic.
@@ -364,12 +454,10 @@ goto_next({opts}) *vim.diagnostic.goto_next()*
• wrap: (boolean, default true) Whether to loop
around file or not. Similar to 'wrapscan'.
• severity: See |diagnostic-severity|.
- • enable_popup: (boolean, default true) Call
- |vim.diagnostic.show_line_diagnostics()| on
- jump.
- • popup_opts: (table) Table to pass as {opts}
- parameter to
- |vim.diagnostic.show_line_diagnostics()|
+ • float: (boolean or table, default true) If
+ "true", call |vim.diagnostic.open_float()| after
+ moving. If a table, pass the table as the {opts}
+ parameter to |vim.diagnostic.open_float()|.
• win_id: (number, default 0) Window ID
goto_prev({opts}) *vim.diagnostic.goto_prev()*
@@ -401,8 +489,9 @@ match({str}, {pat}, {groups}, {severity_map}, {defaults})
For example, consider a line of output from a linter: >
WARNING filename:27:3: Variable 'foo' does not exist
+<
- < This can be parsed into a diagnostic |diagnostic-structure|
+ This can be parsed into a diagnostic |diagnostic-structure|
with: >
local s = "WARNING filename:27:3: Variable 'foo' does not exist"
@@ -429,6 +518,46 @@ match({str}, {pat}, {groups}, {severity_map}, {defaults})
diagnostic |diagnostic-structure| or `nil` if {pat} fails
to match {str}.
+open_float({bufnr}, {opts}) *vim.diagnostic.open_float()*
+ Show diagnostics in a floating window.
+
+ Parameters: ~
+ {bufnr} number|nil Buffer number. Defaults to the current
+ buffer.
+ {opts} table|nil Configuration table with the same keys
+ as |vim.lsp.util.open_floating_preview()| in
+ addition to the following:
+ • namespace: (number) Limit diagnostics to the
+ given namespace
+ • scope: (string, default "buffer") Show
+ diagnostics from the whole buffer ("buffer"),
+ the current cursor line ("line"), or the
+ current cursor position ("cursor").
+ • pos: (number or table) If {scope} is "line" or
+ "cursor", use this position rather than the
+ cursor position. If a number, interpreted as a
+ line number; otherwise, a (row, col) tuple.
+ • severity_sort: (default false) Sort diagnostics
+ by severity. Overrides the setting from
+ |vim.diagnostic.config()|.
+ • severity: See |diagnostic-severity|. Overrides
+ the setting from |vim.diagnostic.config()|.
+ • show_header: (boolean, default true) Show
+ "Diagnostics:" header. Overrides the setting
+ from |vim.diagnostic.config()|.
+ • source: (string) Include the diagnostic source
+ in the message. One of "always" or "if_many".
+ Overrides the setting from
+ |vim.diagnostic.config()|.
+ • format: (function) A function that takes a
+ diagnostic as input and returns a string. The
+ return value is the text used to display the
+ diagnostic. Overrides the setting from
+ |vim.diagnostic.config()|.
+
+ Return: ~
+ tuple ({float_bufnr}, {win_id})
+
reset({namespace}, {bufnr}) *vim.diagnostic.reset()*
Remove all diagnostics from the given namespace.
@@ -502,44 +631,6 @@ show({namespace}, {bufnr}, {diagnostics}, {opts})
{opts} table|nil Display options. See
|vim.diagnostic.config()|.
- *vim.diagnostic.show_line_diagnostics()*
-show_line_diagnostics({opts}, {bufnr}, {lnum})
- Open a floating window with the diagnostics from the given
- line.
-
- Parameters: ~
- {opts} table Configuration table. See
- |vim.diagnostic.show_position_diagnostics()|.
- {bufnr} number|nil Buffer number. Defaults to the current
- buffer.
- {lnum} number|nil Line number. Defaults to line number
- of cursor.
-
- Return: ~
- tuple ({popup_bufnr}, {win_id})
-
- *vim.diagnostic.show_position_diagnostics()*
-show_position_diagnostics({opts}, {bufnr}, {position})
- Open a floating window with the diagnostics at the given
- position.
-
- Parameters: ~
- {opts} table|nil Configuration table with the same
- keys as |vim.lsp.util.open_floating_preview()|
- in addition to the following:
- • namespace: (number) Limit diagnostics to the
- given namespace
- • severity: See |diagnostic-severity|.
- • show_header: (boolean, default true) Show
- "Diagnostics:" header
- {bufnr} number|nil Buffer number. Defaults to the
- current buffer.
- {position} table|nil The (0,0)-indexed position. Defaults
- to the current cursor position.
-
- Return: ~
- tuple ({popup_bufnr}, {win_id})
-
toqflist({diagnostics}) *vim.diagnostic.toqflist()*
Convert a list of diagnostics to a list of quickfix items that
can be passed to |setqflist()| or |setloclist()|.
diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt
index 4700af41b7..4e3173cfa9 100644
--- a/runtime/doc/editing.txt
+++ b/runtime/doc/editing.txt
@@ -1183,7 +1183,8 @@ If you want to always use ":confirm", set the 'confirm' option.
|:diffsplit|, |:diffpatch|, |:pedit|, |:redir|,
|:source|, |:update|, |:visual|, |:vsplit|,
and |:qall| if 'confirm' is set.
- {only in Win32 GUI}
+ {only in Win32 GUI, in console `browse edit` works
+ if the FileExplorer autocommand group exists}
When ":browse" is not possible you get an error
message. If {command} doesn't support browsing, the
{command} is executed without a dialog.
@@ -1274,10 +1275,12 @@ exist, the next-higher scope in the hierarchy applies.
*:chd* *:chdir*
:chd[ir][!] [path] Same as |:cd|.
- *:tc* *:tcd* *E5000* *E5001* *E5002*
-:tc[d][!] {path} Like |:cd|, but set the current directory for the
- current tab and window. The current directory for
- other tabs and windows is not changed.
+ *:tc* *:tcd*
+:tc[d][!] {path} Like |:cd|, but only set the directory for the current
+ tab. The current window will also use this directory.
+ The current directory is not changed for windows in
+ other tabs and for windows in the current tab that
+ have their own window-local directory.
*:tcd-*
:tc[d][!] - Change to the previous current directory (before the
@@ -1301,23 +1304,39 @@ exist, the next-higher scope in the hierarchy applies.
*:pw* *:pwd* *E187*
:pw[d] Print the current directory name.
Also see |getcwd()|.
+ *:pwd-verbose*
+ When 'verbose' is non-zero, |:pwd| will also display
+ what scope the current directory was set. Example: >
-So long as no |:tcd| or |:lcd| command has been used, all windows share the
-same "current directory". Using a command to jump to another window doesn't
+ " Set by :cd
+ :verbose pwd
+ [global] /path/to/current
+
+ " Set by :lcd
+ :verbose pwd
+ [window] /path/to/current
+
+ " Set by :tcd
+ :verbose pwd
+ [tabpage] /path/to/current
+
+So long as no |:lcd| or |:tcd| command has been used, all windows share the
+same current directory. Using a command to jump to another window doesn't
change anything for the current directory.
When |:lcd| has been used for a window, the specified directory becomes the
current directory for that window. Windows where the |:lcd| command has not
been used stick to the global or tab-local directory. When jumping to another
-window the current directory will become the last specified local current
+window the current directory is changed to the last specified local current
directory. If none was specified, the global or tab-local directory is used.
When changing tabs the same behaviour applies. If the current tab has no
-local working directory the global working directory is used. When a |:cd|
-command is used, the current window and tab will lose their local current
-directories and will use the global current directory from now on. When
-a |:tcd| command is used, only the current window will lose its local working
-directory.
+local working directory the global working directory is used.
+
+When a |:cd| command is used, the current window and tab will lose their local
+current directories and will use the global current directory from now on.
+When a |:tcd| command is used, only the current window will lose its local
+working directory.
After using |:cd| the full path name will be used for reading and writing
files. On some networked file systems this may cause problems. The result of
@@ -1466,6 +1485,11 @@ It is also possible that you modified the file yourself, from another edit
session or with another command (e.g., a filter command). Then you will know
which version of the file you want to keep.
+The accuracy of the time check depends on the filesystem. On Unix it is
+usually sub-second. With old file sytems and on MS-Windows it is normally one
+second. Use has('nanotime') check if sub-second time stamp checks are
+available.
+
There is one situation where you get the message while there is nothing wrong:
On a Win32 system on the day daylight saving time starts. There is something
in the Win32 libraries that confuses Vim about the hour time difference. The
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index b3d5f4d7e9..6549d0b5f3 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -586,7 +586,7 @@ It is not necessary to use the "dict" attribute for a numbered function.
If you get an error for a numbered function, you can find out what it is with
a trick. Assuming the function is 42, the command is: >
- :function {42}
+ :function g:42
Functions for Dictionaries ~
@@ -1204,7 +1204,7 @@ next method: >
mylist->filter(filterexpr)->map(mapexpr)->sort()->join()
<
Example of using a lambda: >
- GetPercentage->{x -> x * 100}()->printf('%d%%')
+ GetPercentage()->{x -> x * 100}()->printf('%d%%')
<
When using -> the |expr7| operators will be applied first, thus: >
-1.234->string()
@@ -1307,7 +1307,7 @@ A string constant accepts these special characters:
\U.... same as \u but allows up to 8 hex numbers.
\b backspace <BS>
\e escape <Esc>
-\f formfeed <FF>
+\f formfeed 0x0C
\n newline <NL>
\r return <CR>
\t tab <Tab>
@@ -1316,7 +1316,7 @@ A string constant accepts these special characters:
\<xxx> Special key named "xxx". e.g. "\<C-W>" for CTRL-W. This is for use
in mappings, the 0x80 byte is escaped.
To use the double quote character it must be escaped: "<M-\">".
- Don't use <Char-xxxx> to get a utf-8 character, use \uxxxx as
+ Don't use <Char-xxxx> to get a UTF-8 character, use \uxxxx as
mentioned above.
Note that "\xff" is stored as the byte 255, which may be invalid in some
@@ -2313,9 +2313,10 @@ ceil({expr}) Float round {expr} up
changenr() Number current change number
chanclose({id}[, {stream}]) Number Closes a channel or one of its streams
chansend({id}, {data}) Number Writes {data} to channel
-char2nr({expr}[, {utf8}]) Number ASCII/UTF8 value of first char in {expr}
+char2nr({expr}[, {utf8}]) Number ASCII/UTF-8 value of first char in {expr}
charidx({string}, {idx} [, {countcc}])
Number char index of byte {idx} in {string}
+chdir({dir}) String change current working directory
cindent({lnum}) Number C indent for line {lnum}
clearmatches([{win}]) none clear all matches
col({expr}) Number column nr of cursor or mark
@@ -2431,13 +2432,15 @@ getloclist({nr}) List list of location list items
getloclist({nr}, {what}) Dict get specific location list properties
getmarklist([{buf}]) List list of global/local marks
getmatches([{win}]) List list of current matches
+getmousepos() Dict last known mouse position
getpid() Number process ID of Vim
getpos({expr}) List position of cursor, mark, etc.
getqflist() List list of quickfix items
getqflist({what}) Dict get specific quickfix list properties
getreg([{regname} [, 1 [, {list}]]])
- String or List contents of register
-getregtype([{regname}]) String type of register
+ String or List contents of a register
+getreginfo([{regname}]) Dict information about a register
+getregtype([{regname}]) String type of a register
gettabinfo([{expr}]) List list of tab pages
gettabvar({nr}, {varname} [, {def}])
any variable {varname} in tab {nr} or {def}
@@ -2458,7 +2461,8 @@ globpath({path}, {expr} [, {nosuf} [, {list} [, {alllinks}]]])
has({feature}) Number |TRUE| if feature {feature} supported
has_key({dict}, {key}) Number |TRUE| if {dict} has entry {key}
haslocaldir([{winnr} [, {tabnr}]])
- Number |TRUE| if current window executed |:lcd|
+ Number |TRUE| if the window executed |:lcd| or
+ the tab executed |:tcd|
hasmapto({what} [, {mode} [, {abbr}]])
Number |TRUE| if mapping to {what} exists
histadd({history}, {item}) String add an item to a history
@@ -2503,7 +2507,7 @@ keys({dict}) List keys in {dict}
len({expr}) Number the length of {expr}
libcall({lib}, {func}, {arg}) String call {func} in library {lib} with {arg}
libcallnr({lib}, {func}, {arg}) Number idem, but return a Number
-line({expr}) Number line nr of cursor, last line or mark
+line({expr} [, {winid}]) Number line nr of cursor, last line or mark
line2byte({lnum}) Number byte count of line {lnum}
lispindent({lnum}) Number Lisp indent for line {lnum}
list2str({list} [, {utf8}]) String turn numbers in {list} into a String
@@ -2542,7 +2546,7 @@ mode([expr]) String current editing mode
msgpackdump({list} [, {type}]) List/Blob dump objects to msgpack
msgpackparse({data}) List parse msgpack to a list of objects
nextnonblank({lnum}) Number line nr of non-blank line >= {lnum}
-nr2char({expr}[, {utf8}]) String single char with ASCII/UTF8 value {expr}
+nr2char({expr}[, {utf8}]) String single char with ASCII/UTF-8 value {expr}
nvim_...({args}...) any call nvim |api| functions
or({expr}, {expr}) Number bitwise OR
pathshorten({expr}) String shorten directory names in a path
@@ -2678,7 +2682,7 @@ stdioopen({dict}) Number open stdio in a headless instance.
stdpath({what}) String/List returns the standard path(s) for {what}
str2float({expr} [, {quoted}]) Float convert String to Float
str2list({expr} [, {utf8}]) List convert each character of {expr} to
- ASCII/UTF8 value
+ ASCII/UTF-8 value
str2nr({expr} [, {base} [, {quoted}]])
Number convert String to Number
strchars({expr} [, {skipcc}]) Number character length of the String {expr}
@@ -3278,6 +3282,27 @@ charidx({string}, {idx} [, {countcc}])
echo charidx('áb́ć', 6, 1) returns 4
echo charidx('áb́ć', 16) returns -1
+chdir({dir}) *chdir()*
+ Change the current working directory to {dir}. The scope of
+ the directory change depends on the directory of the current
+ window:
+ - If the current window has a window-local directory
+ (|:lcd|), then changes the window local directory.
+ - Otherwise, if the current tabpage has a local
+ directory (|:tcd|) then changes the tabpage local
+ directory.
+ - Otherwise, changes the global directory.
+ If successful, returns the previous working directory. Pass
+ this to another chdir() to restore the directory.
+ On failure, returns an empty string.
+
+ Example: >
+ let save_dir = chdir(newdir)
+ if save_dir
+ " ... do some work
+ call chdir(save_dir)
+ endif
+<
cindent({lnum}) *cindent()*
Get the amount of indent for line {lnum} according the C
indenting rules, as with 'cindent'.
@@ -3417,6 +3442,8 @@ complete_info([{what}]) *complete_info()*
"" Not in completion mode
"keyword" Keyword completion |i_CTRL-X_CTRL-N|
"ctrl_x" Just pressed CTRL-X |i_CTRL-X|
+ "scroll" Scrolling with |i_CTRL-X_CTRL-E| or
+ |i_CTRL-X_CTRL-Y|
"whole_line" Whole lines |i_CTRL-X_CTRL-L|
"files" File names |i_CTRL-X_CTRL-F|
"tags" Tags |i_CTRL-X_CTRL-]|
@@ -3827,6 +3854,9 @@ escape({string}, {chars}) *escape()*
c:\\program\ files\\vim
< Also see |shellescape()| and |fnameescape()|.
+ Can also be used as a |method|: >
+ GetText()->escape(' \')
+<
*eval()*
eval({string}) Evaluate {string} and return the result. Especially useful to
turn the result of |string()| back into the original value.
@@ -3866,6 +3896,9 @@ executable({expr}) *executable()*
-1 not implemented on this system
|exepath()| can be used to get the full path of an executable.
+ Can also be used as a |method|: >
+ GetCommand()->executable()
+
execute({command} [, {silent}]) *execute()*
Execute {command} and capture its output.
If {command} is a |String|, returns {command} output.
@@ -3893,12 +3926,18 @@ execute({command} [, {silent}]) *execute()*
To execute a command in another window than the current one
use `win_execute()`.
+ Can also be used as a |method|: >
+ GetCommand()->execute()
+
exepath({expr}) *exepath()*
Returns the full path of {expr} if it is an executable and
given as a (partial or full) path or is found in $PATH.
Returns empty string otherwise.
If {expr} starts with "./" the |current-directory| is used.
+ Can also be used as a |method|: >
+ GetCommand()->exepath()
+
*exists()*
exists({expr}) The result is a Number, which is |TRUE| if {expr} is
defined, zero otherwise.
@@ -3984,6 +4023,9 @@ exists({expr}) The result is a Number, which is |TRUE| if {expr} is
< This doesn't check for existence of the "bufcount" variable,
but gets the value of "bufcount", and checks if that exists.
+ Can also be used as a |method|: >
+ Varname()->exists()
+
exp({expr}) *exp()*
Return the exponential of {expr} as a |Float| in the range
[0, inf].
@@ -4090,6 +4132,9 @@ expand({string} [, {nosuf} [, {list}]]) *expand()*
See |glob()| for finding existing files. See |system()| for
getting the raw output of an external command.
+ Can also be used as a |method|: >
+ Getpattern()->expand()
+
expandcmd({expr}) *expandcmd()*
Expand special items in {expr} like what is done for an Ex
command such as `:edit`. This expands special keywords, like
@@ -4097,6 +4142,9 @@ expandcmd({expr}) *expandcmd()*
{expr}. "~user" and "~/path" are only expanded at the start.
Returns the expanded string. Example: >
:echo expandcmd('make %<.o')
+
+< Can also be used as a |method|: >
+ GetCommand()->expandcmd()
<
extend({expr1}, {expr2} [, {expr3}]) *extend()*
{expr1} and {expr2} must be both |Lists| or both
@@ -4182,6 +4230,9 @@ feedkeys({string} [, {mode}]) *feedkeys()*
Return value is always 0.
+ Can also be used as a |method|: >
+ GetInput()->feedkeys()
+
filereadable({file}) *filereadable()*
The result is a Number, which is |TRUE| when a file with the
name {file} exists, and can be read. If {file} doesn't exist,
@@ -4195,12 +4246,17 @@ filereadable({file}) *filereadable()*
echo filereadable(expand('~/.vimrc'))
1
+< Can also be used as a |method|: >
+ GetName()->filereadable()
+
filewritable({file}) *filewritable()*
The result is a Number, which is 1 when a file with the
name {file} exists, and can be written. If {file} doesn't
exist, or is not writable, the result is 0. If {file} is a
directory, and we can write to it, the result is 2.
+ Can also be used as a |method|: >
+ GetName()->filewriteable()
filter({expr1}, {expr2}) *filter()*
{expr1} must be a |List|, |Blob|, or a |Dictionary|.
@@ -4271,6 +4327,9 @@ finddir({name} [, {path} [, {count}]]) *finddir()*
This is quite similar to the ex-command `:find`.
+ Can also be used as a |method|: >
+ GetName()->finddir()
+
findfile({name} [, {path} [, {count}]]) *findfile()*
Just like |finddir()|, but find a file instead of a directory.
Uses 'suffixesadd'.
@@ -4279,6 +4338,9 @@ findfile({name} [, {path} [, {count}]]) *findfile()*
< Searches from the directory of the current file upwards until
it finds the file "tags.vim".
+ Can also be used as a |method|: >
+ GetName()->findfile()
+
flatten({list} [, {maxdepth}]) *flatten()*
Flatten {list} up to {maxdepth} levels. Without {maxdepth}
the result is a |List| without nesting, as if {maxdepth} is
@@ -4368,6 +4430,9 @@ fnameescape({string}) *fnameescape()*
:exe "edit " . fnameescape(fname)
< results in executing: >
edit \+some\ str\%nge\|name
+<
+ Can also be used as a |method|: >
+ GetName()->fnameescape()
fnamemodify({fname}, {mods}) *fnamemodify()*
Modify file name {fname} according to {mods}. {mods} is a
@@ -4381,6 +4446,9 @@ fnamemodify({fname}, {mods}) *fnamemodify()*
Note: Environment variables don't work in {fname}, use
|expand()| first then.
+ Can also be used as a |method|: >
+ GetName()->fnamemodify(':p:h')
+
foldclosed({lnum}) *foldclosed()*
The result is a Number. If the line {lnum} is in a closed
fold, the result is the number of the first line in that fold.
@@ -4388,6 +4456,9 @@ foldclosed({lnum}) *foldclosed()*
{lnum} is used like with |getline()|. Thus "." is the current
line, "'m" mark m, etc.
+ Can also be used as a |method|: >
+ GetLnum()->foldclosed()
+
foldclosedend({lnum}) *foldclosedend()*
The result is a Number. If the line {lnum} is in a closed
fold, the result is the number of the last line in that fold.
@@ -4395,6 +4466,9 @@ foldclosedend({lnum}) *foldclosedend()*
{lnum} is used like with |getline()|. Thus "." is the current
line, "'m" mark m, etc.
+ Can also be used as a |method|: >
+ GetLnum()->foldclosedend()
+
foldlevel({lnum}) *foldlevel()*
The result is a Number, which is the foldlevel of line {lnum}
in the current buffer. For nested folds the deepest level is
@@ -4407,6 +4481,9 @@ foldlevel({lnum}) *foldlevel()*
{lnum} is used like with |getline()|. Thus "." is the current
line, "'m" mark m, etc.
+ Can also be used as a |method|: >
+ GetLnum()->foldlevel()
+
*foldtext()*
foldtext() Returns a String, to be displayed for a closed fold. This is
the default function used for the 'foldtext' option and should
@@ -4432,6 +4509,9 @@ foldtextresult({lnum}) *foldtextresult()*
line, "'m" mark m, etc.
Useful when exporting folded text, e.g., to HTML.
+ Can also be used as a |method|: >
+ GetLnum()->foldtextresult()
+<
*foreground()*
foreground() Move the Vim window to the foreground. Useful when sent from
a client to a Vim server. |remote_send()|
@@ -4450,6 +4530,9 @@ funcref({name} [, {arglist}] [, {dict}])
Also for autoloaded functions. {name} cannot be a builtin
function.
+ Can also be used as a |method|: >
+ GetFuncname()->funcref([arg])
+<
*function()* *E700* *E922* *E923*
function({name} [, {arglist}] [, {dict}])
Return a |Funcref| variable that refers to function {name}.
@@ -4499,7 +4582,9 @@ function({name} [, {arglist}] [, {dict}])
call Func(500)
< Invokes the function as with: >
call context.Callback('one', 500)
-
+<
+ Can also be used as a |method|: >
+ GetFuncname()->function([arg])
garbagecollect([{atexit}]) *garbagecollect()*
Cleanup unused |Lists| and |Dictionaries| that have circular
@@ -4639,6 +4724,9 @@ getbufline({buf}, {lnum} [, {end}])
Example: >
:let lines = getbufline(bufnr("myfile"), 1, "$")
+< Can also be used as a |method|: >
+ GetBufnr()->getbufline(lnum)
+
getbufvar({buf}, {varname} [, {def}]) *getbufvar()*
The result is the value of option or local buffer variable
{varname} in buffer {buf}. Note that the name without "b:"
@@ -4659,8 +4747,11 @@ getbufvar({buf}, {varname} [, {def}]) *getbufvar()*
Examples: >
:let bufmodified = getbufvar(1, "&mod")
:echo "todo myvar = " . getbufvar("todo", "myvar")
+
+< Can also be used as a |method|: >
+ GetBufnr()->getbufvar(varname)
<
-getchangelist({buf}) *getchangelist()*
+getchangelist([{buf}]) *getchangelist()*
Returns the |changelist| for the buffer {buf}. For the use
of {buf}, see |bufname()| above. If buffer {buf} doesn't
exist, an empty list is returned.
@@ -4676,6 +4767,9 @@ getchangelist({buf}) *getchangelist()*
position refers to the position in the list. For other
buffers, it is set to the length of the list.
+ Can also be used as a |method|: >
+ GetBufnr()->getchangelist()
+
getchar([expr]) *getchar()*
Get a single character from the user or input stream.
If [expr] is omitted, wait until a character is available.
@@ -4708,7 +4802,8 @@ getchar([expr]) *getchar()*
When the user clicks a mouse button, the mouse event will be
returned. The position can then be found in |v:mouse_col|,
|v:mouse_lnum|, |v:mouse_winid| and |v:mouse_win|.
- Mouse move events will be ignored.
+ |getmousepos()| can also be used. Mouse move events will be
+ ignored.
This example positions the mouse as it would normally happen: >
let c = getchar()
if c == "\<LeftMouse>" && v:mouse_win > 0
@@ -4885,6 +4980,9 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
If there are no matches, an empty list is returned. An
invalid value for {type} produces an error.
+ Can also be used as a |method|: >
+ GetPattern()->getcompletion('color')
+<
*getcurpos()*
getcurpos() Get the position of the cursor. This is like getpos('.'), but
includes an extra "curswant" in the list:
@@ -4912,6 +5010,12 @@ getcwd([{winnr}[, {tabnr}]]) *getcwd()*
getcwd(0, 0)
< If {winnr} is -1 it is ignored, only the tab is resolved.
{winnr} can be the window number or the |window-ID|.
+ If both {winnr} and {tabnr} are -1 the global working
+ directory is returned.
+ Throw error if the arguments are invalid. |E5000| |E5001| |E5002|
+
+ Can also be used as a |method|: >
+ GetWinnr()->getcwd()
getenv({name}) *getenv()*
Return the value of environment variable {name}. The {name}
@@ -4922,6 +5026,9 @@ getenv({name}) *getenv()*
is different from a variable set to an empty string.
See also |expr-env|.
+ Can also be used as a |method|: >
+ GetVarname()->getenv()
+
getfontname([{name}]) *getfontname()*
Without an argument returns the name of the normal font being
used. Like what is used for the Normal highlight group
@@ -4949,6 +5056,9 @@ getfperm({fname}) *getfperm()*
< This will hopefully (from a security point of view) display
the string "rw-r--r--" or even "rw-------".
+ Can also be used as a |method|: >
+ GetFilename()->getfperm()
+<
For setting permissions use |setfperm()|.
getfsize({fname}) *getfsize()*
@@ -4959,6 +5069,9 @@ getfsize({fname}) *getfsize()*
If the size of {fname} is too big to fit in a Number then -2
is returned.
+ Can also be used as a |method|: >
+ GetFilename()->getfsize()
+
getftime({fname}) *getftime()*
The result is a Number, which is the last modification time of
the given file {fname}. The value is measured as seconds
@@ -4966,6 +5079,9 @@ getftime({fname}) *getftime()*
|localtime()| and |strftime()|.
If the file {fname} can't be found -1 is returned.
+ Can also be used as a |method|: >
+ GetFilename()->getftime()
+
getftype({fname}) *getftype()*
The result is a String, which is a description of the kind of
file of the given file {fname}.
@@ -4986,6 +5102,9 @@ getftype({fname}) *getftype()*
systems that support it. On some systems only "dir" and
"file" are returned.
+ Can also be used as a |method|: >
+ GetFilename()->getftype()
+
getjumplist([{winnr} [, {tabnr}]]) *getjumplist()*
Returns the |jumplist| for the specified window.
@@ -5005,7 +5124,10 @@ getjumplist([{winnr} [, {tabnr}]]) *getjumplist()*
filename filename if available
lnum line number
- *getline()*
+ Can also be used as a |method|: >
+ GetWinnr()->getjumplist()
+
+< *getline()*
getline({lnum} [, {end}])
Without {end} the result is a String, which is line {lnum}
from the current buffer. Example: >
@@ -5028,6 +5150,9 @@ getline({lnum} [, {end}])
:let end = search("^$") - 1
:let lines = getline(start, end)
+< Can also be used as a |method|: >
+ ComputeLnum()->getline()
+
< To get lines from another buffer see |getbufline()|
getloclist({nr},[, {what}]) *getloclist()*
@@ -5098,6 +5223,35 @@ getmatches([{win}]) *getmatches()*
'pattern': 'FIXME', 'priority': 10, 'id': 2}] >
:unlet m
<
+getmousepos() *getmousepos()*
+ Returns a Dictionary with the last known position of the
+ mouse. This can be used in a mapping for a mouse click. The
+ items are:
+ screenrow screen row
+ screencol screen column
+ winid Window ID of the click
+ winrow row inside "winid"
+ wincol column inside "winid"
+ line text line inside "winid"
+ column text column inside "winid"
+ All numbers are 1-based.
+
+ If not over a window, e.g. when in the command line, then only
+ "screenrow" and "screencol" are valid, the others are zero.
+
+ When on the status line below a window or the vertical
+ separater right of a window, the "line" and "column" values
+ are zero.
+
+ When the position is after the text then "column" is the
+ length of the text in bytes plus one.
+
+ If the mouse is over a focusable floating window then that
+ window is used.
+
+ When using |getchar()| the Vim variables |v:mouse_lnum|,
+ |v:mouse_col| and |v:mouse_winid| also provide these values.
+
*getpid()*
getpid() Return a Number which is the process ID of the Vim process.
This is a unique number, until Vim exits.
@@ -5129,6 +5283,8 @@ getpos({expr}) Get the position for String {expr}. For possible values of
call setpos("'a", save_a_mark)
< Also see |getcurpos()| and |setpos()|.
+ Can also be used as a |method|: >
+ GetMark()->getpos()
getqflist([{what}]) *getqflist()*
Returns a |List| with all the current quickfix errors. Each
@@ -5247,6 +5403,35 @@ getreg([{regname} [, 1 [, {list}]]]) *getreg()*
If {regname} is not specified, |v:register| is used.
+ Can also be used as a |method|: >
+ GetRegname()->getreg()
+
+getreginfo([{regname}]) *getreginfo()*
+ Returns detailed information about register {regname} as a
+ Dictionary with the following entries:
+ regcontents List of lines contained in register
+ {regname}, like
+ |getreg|({regname}, 1, 1).
+ regtype the type of register {regname}, as in
+ |getregtype()|.
+ isunnamed Boolean flag, v:true if this register
+ is currently pointed to by the unnamed
+ register.
+ points_to for the unnamed register, gives the
+ single letter name of the register
+ currently pointed to (see |quotequote|).
+ For example, after deleting a line
+ with `dd`, this field will be "1",
+ which is the register that got the
+ deleted text.
+
+ The {regname} argument is a string. If {regname} is invalid
+ or not set, an empty Dictionary will be returned.
+ If {regname} is not specified, |v:register| is used.
+ The returned Dictionary can be passed to |setreg()|.
+
+ Can also be used as a |method|: >
+ GetRegname()->getreginfo()
getregtype([{regname}]) *getregtype()*
The result is a String, which is type of register {regname}.
@@ -5259,6 +5444,9 @@ getregtype([{regname}]) *getregtype()*
The {regname} argument is a string. If {regname} is not
specified, |v:register| is used.
+ Can also be used as a |method|: >
+ GetRegname()->getregtype()
+
gettabinfo([{tabnr}]) *gettabinfo()*
If {tabnr} is not specified, then information about all the
tab pages is returned as a |List|. Each List item is a
@@ -5272,6 +5460,9 @@ gettabinfo([{tabnr}]) *gettabinfo()*
tabpage-local variables
windows List of |window-ID|s in the tab page.
+ Can also be used as a |method|: >
+ GetTabnr()->gettabinfo()
+
gettabvar({tabnr}, {varname} [, {def}]) *gettabvar()*
Get the value of a tab-local variable {varname} in tab page
{tabnr}. |t:var|
@@ -5282,6 +5473,9 @@ gettabvar({tabnr}, {varname} [, {def}]) *gettabvar()*
When the tab or variable doesn't exist {def} or an empty
string is returned, there is no error message.
+ Can also be used as a |method|: >
+ GetTabnr()->gettabvar(varname)
+
gettabwinvar({tabnr}, {winnr}, {varname} [, {def}]) *gettabwinvar()*
Get the value of window-local variable {varname} in window
{winnr} in tab page {tabnr}.
@@ -5308,6 +5502,9 @@ gettabwinvar({tabnr}, {winnr}, {varname} [, {def}]) *gettabwinvar()*
To obtain all window-local variables use: >
gettabwinvar({tabnr}, {winnr}, '&')
+< Can also be used as a |method|: >
+ GetTabnr()->gettabwinvar(winnr, varname)
+
gettagstack([{winnr}]) *gettagstack()*
The result is a Dict, which is the tag stack of window {winnr}.
{winnr} can be the window number or the |window-ID|.
@@ -5336,6 +5533,9 @@ gettagstack([{winnr}]) *gettagstack()*
See |tagstack| for more information about the tag stack.
+ Can also be used as a |method|: >
+ GetWinnr()->gettagstack()
+
getwininfo([{winid}]) *getwininfo()*
Returns information about windows as a |List| with Dictionaries.
@@ -5367,6 +5567,9 @@ getwininfo([{winid}]) *getwininfo()*
winrow topmost screen line of the window;
"row" from |win_screenpos()|
+ Can also be used as a |method|: >
+ GetWinnr()->getwininfo()
+
getwinpos([{timeout}]) *getwinpos()*
The result is a |List| with two numbers, the result of
|getwinposx()| and |getwinposy()| combined:
@@ -5387,6 +5590,9 @@ getwinpos([{timeout}]) *getwinpos()*
" Do some work here
endwhile
<
+ Can also be used as a |method|: >
+ GetTimeout()->getwinpos()
+<
*getwinposx()*
getwinposx() The result is a Number, which is the X coordinate in pixels of
the left hand side of the GUI Vim window. The result will be
@@ -5404,6 +5610,9 @@ getwinvar({winnr}, {varname} [, {def}]) *getwinvar()*
Examples: >
:let list_is_on = getwinvar(2, '&list')
:echo "myvar = " . getwinvar(1, 'myvar')
+
+< Can also be used as a |method|: >
+ GetWinnr()->getwinvar(varname)
<
glob({expr} [, {nosuf} [, {list} [, {alllinks}]]]) *glob()*
Expand the file wildcards in {expr}. See |wildcards| for the
@@ -5441,6 +5650,9 @@ glob({expr} [, {nosuf} [, {list} [, {alllinks}]]]) *glob()*
See |expand()| for expanding special Vim variables. See
|system()| for getting the raw output of an external command.
+ Can also be used as a |method|: >
+ GetExpr()->glob()
+
glob2regpat({string}) *glob2regpat()*
Convert a file pattern, as used by glob(), into a search
pattern. The result can be used to match with a string that
@@ -5453,7 +5665,9 @@ glob2regpat({string}) *glob2regpat()*
Note that the result depends on the system. On MS-Windows
a backslash usually means a path separator.
- *globpath()*
+ Can also be used as a |method|: >
+ GetExpr()->glob2regpat()
+< *globpath()*
globpath({path}, {expr} [, {nosuf} [, {list} [, {allinks}]]])
Perform glob() for String {expr} on all directories in {path}
and concatenate the results. Example: >
@@ -5489,6 +5703,10 @@ globpath({path}, {expr} [, {nosuf} [, {list} [, {allinks}]]])
< Upwards search and limiting the depth of "**" is not
supported, thus using 'path' will not always work properly.
+ Can also be used as a |method|, the base is passed as the
+ second argument: >
+ GetExpr()->globpath(&rtp)
+<
*has()*
has({feature}) Returns 1 if {feature} is supported, 0 otherwise. The
{feature} argument is a feature name like "nvim-0.2.1" or
@@ -5557,8 +5775,9 @@ has_key({dict}, {key}) *has_key()*
mydict->has_key(key)
haslocaldir([{winnr}[, {tabnr}]]) *haslocaldir()*
- The result is a Number, which is 1 when the tabpage or window
- has set a local path via |:tcd| or |:lcd|, otherwise 0.
+ The result is a Number, which is 1 when the window has set a
+ local path via |:lcd| or when {winnr} is -1 and the tabpage
+ has set a local path via |:tcd|, otherwise 0.
Tabs and windows are identified by their respective numbers,
0 means current tab or window. Missing argument implies 0.
@@ -5570,6 +5789,10 @@ haslocaldir([{winnr}[, {tabnr}]]) *haslocaldir()*
With {winnr} and {tabnr} use the window in that tabpage.
{winnr} can be the window number or the |window-ID|.
If {winnr} is -1 it is ignored, only the tab is resolved.
+ Throw error if the arguments are invalid. |E5000| |E5001| |E5002|
+
+ Can also be used as a |method|: >
+ GetWinnr()->haslocaldir()
hasmapto({what} [, {mode} [, {abbr}]]) *hasmapto()*
The result is a Number, which is TRUE if there is a mapping
@@ -5585,7 +5808,9 @@ hasmapto({what} [, {mode} [, {abbr}]]) *hasmapto()*
If no matching mapping is found FALSE is returned.
The following characters are recognized in {mode}:
n Normal mode
- v Visual mode
+ v Visual and Select mode
+ x Visual mode
+ s Select mode
o Operator-pending mode
i Insert mode
l Language-Argument ("r", "f", "t", etc.)
@@ -5600,6 +5825,9 @@ hasmapto({what} [, {mode} [, {abbr}]]) *hasmapto()*
< This installs the mapping to "\ABCdoit" only if there isn't
already a mapping to "\ABCdoit".
+ Can also be used as a |method|: >
+ GetRHS()->hasmapto()
+
histadd({history}, {item}) *histadd()*
Add the String {item} to the history {history} which can be
one of: *hist-names*
@@ -5621,6 +5849,10 @@ histadd({history}, {item}) *histadd()*
:let date=input("Enter date: ")
< This function is not available in the |sandbox|.
+ Can also be used as a |method|, the base is used for the
+ second argument: >
+ GetPattern()->histadd('search')
+
histdel({history} [, {item}]) *histdel()*
Clear {history}, i.e. delete all its entries. See |hist-names|
for the possible values of {history}.
@@ -5652,6 +5884,9 @@ histdel({history} [, {item}]) *histdel()*
the "n" command and 'hlsearch': >
:call histdel("search", -1)
:let @/ = histget("search", -1)
+<
+ Can also be used as a |method|: >
+ GetHistory()->histdel()
histget({history} [, {index}]) *histget()*
The result is a String, the entry with Number {index} from
@@ -5668,6 +5903,9 @@ histget({history} [, {index}]) *histget()*
the {num}th entry from the output of |:history|. >
:command -nargs=1 H execute histget("cmd", 0+<args>)
<
+ Can also be used as a |method|: >
+ GetHistory()->histget()
+
histnr({history}) *histnr()*
The result is the Number of the current entry in {history}.
See |hist-names| for the possible values of {history}.
@@ -5675,6 +5913,9 @@ histnr({history}) *histnr()*
Example: >
:let inp_index = histnr("expr")
+
+< Can also be used as a |method|: >
+ GetHistory()->histnr()
<
hlexists({name}) *hlexists()*
The result is a Number, which is TRUE if a highlight group
@@ -5683,6 +5924,9 @@ hlexists({name}) *hlexists()*
been defined for it, it may also have been used for a syntax
item.
+ Can also be used as a |method|: >
+ GetName()->hlexists()
+<
*hlID()*
hlID({name}) The result is a Number, which is the ID of the highlight group
with name {name}. When the highlight group doesn't exist,
@@ -5691,6 +5935,9 @@ hlID({name}) The result is a Number, which is the ID of the highlight group
group. For example, to get the background color of the
"Comment" group: >
:echo synIDattr(synIDtrans(hlID("Comment")), "bg")
+<
+ Can also be used as a |method|: >
+ GetName()->hlID()
hostname() *hostname()*
The result is a String, which is the name of the machine on
@@ -5709,6 +5956,9 @@ iconv({string}, {from}, {to}) *iconv()*
from/to UCS-2 is automatically changed to use UTF-8. You
cannot use UCS-2 in a string anyway, because of the NUL bytes.
+ Can also be used as a |method|: >
+ GetText()->iconv('latin1', 'utf-8')
+<
*indent()*
indent({lnum}) The result is a Number, which is indent of line {lnum} in the
current buffer. The indent is counted in spaces, the value
@@ -5716,6 +5966,8 @@ indent({lnum}) The result is a Number, which is indent of line {lnum} in the
|getline()|.
When {lnum} is invalid -1 is returned.
+ Can also be used as a |method|: >
+ GetLnum()->indent()
index({object}, {expr} [, {start} [, {ic}]]) *index()*
If {object} is a |List| return the lowest index where the item
@@ -5736,6 +5988,8 @@ index({object}, {expr} [, {start} [, {ic}]]) *index()*
:let idx = index(words, "the")
:if index(numbers, 123) >= 0
+< Can also be used as a |method|: >
+ GetObject()->index(what)
input({prompt} [, {text} [, {completion}]]) *input()*
input({opts})
@@ -5848,6 +6102,9 @@ input({opts})
: call inputrestore()
:endfunction
+< Can also be used as a |method|: >
+ GetPrompt()->input()
+
inputlist({textlist}) *inputlist()*
{textlist} must be a |List| of strings. This |List| is
displayed, one string per line. The user will be prompted to
@@ -5865,6 +6122,9 @@ inputlist({textlist}) *inputlist()*
let color = inputlist(['Select color:', '1. red',
\ '2. green', '3. blue'])
+< Can also be used as a |method|: >
+ GetChoices()->inputlist()
+
inputrestore() *inputrestore()*
Restore typeahead that was saved with a previous |inputsave()|.
Should be called the same number of times inputsave() is
@@ -5890,6 +6150,9 @@ inputsecret({prompt} [, {text}]) *inputsecret()*
typed on the command-line in response to the issued prompt.
NOTE: Command-line completion is not supported.
+ Can also be used as a |method|: >
+ GetPrompt()->inputsecret()
+
insert({object}, {item} [, {idx}]) *insert()*
When {object} is a |List| or a |Blob| insert {item} at the start
of it.
@@ -5936,6 +6199,9 @@ isdirectory({directory}) *isdirectory()*
exist, or isn't a directory, the result is |FALSE|. {directory}
is any expression, which is used as a String.
+ Can also be used as a |method|: >
+ GetName()->isdirectory()
+
isinf({expr}) *isinf()*
Return 1 if {expr} is a positive infinity, or -1 a negative
infinity, otherwise 0. >
@@ -5961,6 +6227,9 @@ islocked({expr}) *islocked()* *E786*
< When {expr} is a variable that does not exist you get an error
message. Use |exists()| to check for existence.
+ Can also be used as a |method|: >
+ GetName()->islocked()
+
id({expr}) *id()*
Returns a |String| which is a unique identifier of the
container type (|List|, |Dict|, |Blob| and |Partial|). It is
@@ -6145,6 +6414,9 @@ json_decode({expr}) *json_decode()*
recommended and the only one required to be supported.
Non-UTF-8 characters are an error.
+ Can also be used as a |method|: >
+ ReadObject()->json_decode()
+
json_encode({expr}) *json_encode()*
Convert {expr} into a JSON string. Accepts
|msgpack-special-dict| as the input. Will not convert
@@ -6157,6 +6429,9 @@ json_encode({expr}) *json_encode()*
or special escapes like "\t", other are dumped as-is.
|Blob|s are converted to arrays of the individual bytes.
+ Can also be used as a |method|: >
+ GetObject()->json_encode()
+
keys({dict}) *keys()*
Return a |List| with all the keys of {dict}. The |List| is in
arbitrary order. Also see |items()| and |values()|.
@@ -6220,6 +6495,10 @@ libcall({libname}, {funcname}, {argument})
object code must be compiled as position-independent ('PIC').
Examples: >
:echo libcall("libc.so", "getenv", "HOME")
+
+< Can also be used as a |method|, where the base is passed as
+ the argument to the called function: >
+ GetValue()->libcall("libc.so", "getenv")
<
*libcallnr()*
libcallnr({libname}, {funcname}, {argument})
@@ -6230,8 +6509,12 @@ libcallnr({libname}, {funcname}, {argument})
:call libcallnr("libc.so", "printf", "Hello World!\n")
:call libcallnr("libc.so", "sleep", 10)
<
- *line()*
-line({expr}) The result is a Number, which is the line number of the file
+ Can also be used as a |method|, where the base is passed as
+ the argument to the called function: >
+ GetValue()->libcallnr("libc.so", "printf")
+<
+line({expr} [, {winid}]) *line()*
+ The result is a Number, which is the line number of the file
position given with {expr}. The {expr} argument is a string.
The accepted positions are:
. the cursor position
@@ -6250,10 +6533,16 @@ line({expr}) The result is a Number, which is the line number of the file
then applies to another buffer.
To get the column number use |col()|. To get both use
|getpos()|.
+ With the optional {winid} argument the values are obtained for
+ that window instead of the current window.
Examples: >
line(".") line number of the cursor
+ line(".", winid) idem, in window "winid"
line("'t") line number of mark t
line("'" . marker) line number of mark marker
+<
+ Can also be used as a |method|: >
+ GetValue()->line()
line2byte({lnum}) *line2byte()*
Return the byte count from the start of the buffer for line
@@ -6268,6 +6557,9 @@ line2byte({lnum}) *line2byte()*
|getline()|. When {lnum} is invalid -1 is returned.
Also see |byte2line()|, |go| and |:goto|.
+ Can also be used as a |method|: >
+ GetLnum()->line2byte()
+
lispindent({lnum}) *lispindent()*
Get the amount of indent for line {lnum} according the lisp
indenting rules, as with 'lisp'.
@@ -6275,6 +6567,9 @@ lispindent({lnum}) *lispindent()*
relevant. {lnum} is used just like in |getline()|.
When {lnum} is invalid, -1 is returned.
+ Can also be used as a |method|: >
+ GetLnum()->lispindent()
+
list2str({list} [, {utf8}]) *list2str()*
Convert each number in {list} to a character string can
concatenate them all. Examples: >
@@ -6284,11 +6579,14 @@ list2str({list} [, {utf8}]) *list2str()*
join(map(list, {nr, val -> nr2char(val)}), '')
< |str2list()| does the opposite.
- When {utf8} is omitted or zero, the current 'encoding' is used.
- With {utf8} is 1, always return utf-8 characters.
- With utf-8 composing characters work as expected: >
+ UTF-8 encoding is always used, {utf8} option has no effect,
+ and exists only for backwards-compatibility.
+ With UTF-8 composing characters work as expected: >
list2str([97, 769]) returns "á"
<
+ Can also be used as a |method|: >
+ GetList()->list2str()
+
localtime() *localtime()*
Return the current time, measured as seconds since 1st Jan
1970. See also |strftime()|, |strptime()| and |getftime()|.
@@ -6323,6 +6621,9 @@ luaeval({expr}[, {expr}])
Evaluate Lua expression {expr} and return its result converted
to Vim data structures. See |lua-eval| for more details.
+ Can also be used as a |method|: >
+ GetExpr()->luaeval()
+
map({expr1}, {expr2}) *map()*
{expr1} must be a |List|, |Blob| or |Dictionary|.
Replace each item in {expr1} with the result of evaluating
@@ -6430,6 +6731,8 @@ maparg({name} [, {mode} [, {abbr} [, {dict}]]]) *maparg()*
mapped, and have it do the original mapping too. Sketch: >
exe 'nnoremap <Tab> ==' . maparg('<Tab>', 'n')
+< Can also be used as a |method|: >
+ GetKey()->maparg('n')
mapcheck({name} [, {mode} [, {abbr}]]) *mapcheck()*
Check if there is a mapping that matches with {name} in mode
@@ -6464,6 +6767,9 @@ mapcheck({name} [, {mode} [, {abbr}]]) *mapcheck()*
< This avoids adding the "_vv" mapping when there already is a
mapping for "_v" or for "_vvv".
+ Can also be used as a |method|: >
+ GetKey()->mapcheck('n')
+
match({expr}, {pat} [, {start} [, {count}]]) *match()*
When {expr} is a |List| then this returns the index of the
first item where {pat} matches. Each item is used as a
@@ -6526,6 +6832,9 @@ match({expr}, {pat} [, {start} [, {count}]]) *match()*
zero matches at the start instead of a number of matches
further down in the text.
+ Can also be used as a |method|: >
+ GetList()->match('word')
+<
*matchadd()* *E798* *E799* *E801* *E957*
matchadd({group}, {pattern}[, {priority}[, {id} [, {dict}]]])
Defines a pattern to be highlighted in the current window (a
@@ -6581,6 +6890,9 @@ matchadd({group}, {pattern}[, {priority}[, {id} [, {dict}]]])
available from |getmatches()|. All matches can be deleted in
one operation by |clearmatches()|.
+ Can also be used as a |method|: >
+ GetGroup()->matchadd('TODO')
+<
*matchaddpos()*
matchaddpos({group}, {pos} [, {priority} [, {id} [, {dict}]]])
Same as |matchadd()|, but requires a list of positions {pos}
@@ -6619,6 +6931,9 @@ matchaddpos({group}, {pos} [, {priority} [, {id} [, {dict}]]])
< Matches added by |matchaddpos()| are returned by
|getmatches()|.
+ Can also be used as a |method|: >
+ GetGroup()->matchaddpos([23, 11])
+
matcharg({nr}) *matcharg()*
Selects the {nr} match item, as set with a |:match|,
|:2match| or |:3match| command.
@@ -6631,6 +6946,9 @@ matcharg({nr}) *matcharg()*
Highlighting matches using the |:match| commands are limited
to three matches. |matchadd()| does not have this limitation.
+ Can also be used as a |method|: >
+ GetMatch()->matcharg()
+
matchdelete({id} [, {win}]) *matchdelete()* *E802* *E803*
Deletes a match with ID {id} previously defined by |matchadd()|
or one of the |:match| commands. Returns 0 if successful,
@@ -6639,6 +6957,9 @@ matchdelete({id} [, {win}]) *matchdelete()* *E802* *E803*
If {win} is specified, use the window with this number or
window ID instead of the current window.
+ Can also be used as a |method|: >
+ GetMatch()->matchdelete()
+
matchend({expr}, {pat} [, {start} [, {count}]]) *matchend()*
Same as |match()|, but return the index of first character
after the match. Example: >
@@ -6658,6 +6979,9 @@ matchend({expr}, {pat} [, {start} [, {count}]]) *matchend()*
< result is "-1".
When {expr} is a |List| the result is equal to |match()|.
+ Can also be used as a |method|: >
+ GetText()->matchend('word')
+
matchlist({expr}, {pat} [, {start} [, {count}]]) *matchlist()*
Same as |match()|, but return a |List|. The first item in the
list is the matched string, same as what matchstr() would
@@ -6668,6 +6992,9 @@ matchlist({expr}, {pat} [, {start} [, {count}]]) *matchlist()*
< Results in: ['acd', 'a', '', 'c', 'd', '', '', '', '', '']
When there is no match an empty list is returned.
+ Can also be used as a |method|: >
+ GetList()->matchlist('word')
+
matchstr({expr}, {pat} [, {start} [, {count}]]) *matchstr()*
Same as |match()|, but return the matched string. Example: >
:echo matchstr("testing", "ing")
@@ -6681,6 +7008,9 @@ matchstr({expr}, {pat} [, {start} [, {count}]]) *matchstr()*
When {expr} is a |List| then the matching item is returned.
The type isn't changed, it's not necessarily a String.
+ Can also be used as a |method|: >
+ GetText()->matchstr('word')
+
matchstrpos({expr}, {pat} [, {start} [, {count}]]) *matchstrpos()*
Same as |matchstr()|, but return the matched string, the start
position and the end position of the match. Example: >
@@ -6699,6 +7029,9 @@ matchstrpos({expr}, {pat} [, {start} [, {count}]]) *matchstrpos()*
< result is ["x", 1, 2, 3].
The type isn't changed, it's not necessarily a String.
+ Can also be used as a |method|: >
+ GetText()->matchstrpos('word')
+
*max()*
max({expr}) Return the maximum value of all items in {expr}.
{expr} can be a |List| or a |Dictionary|. For a Dictionary,
@@ -6789,6 +7122,9 @@ mkdir({name} [, {path} [, {prot}]])
successful or FALSE if the directory creation failed or partly
failed.
+ Can also be used as a |method|: >
+ GetName()->mkdir()
+<
*mode()*
mode([expr]) Return a string that indicates the current mode.
If [expr] is supplied and it evaluates to a non-zero Number or
@@ -6804,30 +7140,34 @@ mode([expr]) Return a string that indicates the current mode.
niI Normal using |i_CTRL-O| in |Insert-mode|
niR Normal using |i_CTRL-O| in |Replace-mode|
niV Normal using |i_CTRL-O| in |Virtual-Replace-mode|
+ nt Normal in |terminal-emulator| (insert goes to
+ Terminal mode)
v Visual by character
+ vs Visual by character using |v_CTRL-O| in Select mode
V Visual by line
+ Vs Visual by line using |v_CTRL-O| in Select mode
CTRL-V Visual blockwise
+ CTRL-Vs Visual blockwise using |v_CTRL-O| in Select mode
s Select by character
S Select by line
CTRL-S Select blockwise
- vs Visual by character using |v_CTRL-O| from
- Select mode
- Vs Visual by line using |v_CTRL-O| from Select mode
- CTRL-Vs Visual blockwise using |v_CTRL-O| from Select mode
i Insert
ic Insert mode completion |compl-generic|
ix Insert mode |i_CTRL-X| completion
R Replace |R|
Rc Replace mode completion |compl-generic|
- Rv Virtual Replace |gR|
Rx Replace mode |i_CTRL-X| completion
+ Rv Virtual Replace |gR|
+ Rvc Virtual Replace mode completion |compl-generic|
+ Rvx Virtual Replace mode |i_CTRL-X| completion
c Command-line editing
cv Vim Ex mode |Q| or |gQ|
r Hit-enter prompt
rm The -- more -- prompt
- r? |:confirm| query of some sort
+ r? A |:confirm| query of some sort
! Shell or external command is executing
t Terminal mode: keys go to the job
+
This is useful in the 'statusline' option or when used
with |remote_expr()| In most other places it always returns
"c" or "n".
@@ -6836,6 +7176,9 @@ mode([expr]) Return a string that indicates the current mode.
the leading character(s).
Also see |visualmode()|.
+ Can also be used as a |method|: >
+ DoFull()->mode()
+
msgpackdump({list} [, {type}]) *msgpackdump()*
Convert a list of VimL objects to msgpack. Returned value is a
|readfile()|-style list. When {type} contains "B", a |Blob| is
@@ -6938,6 +7281,9 @@ nextnonblank({lnum}) *nextnonblank()*
{lnum} is used like with |getline()|.
See also |prevnonblank()|.
+ Can also be used as a |method|: >
+ GetLnum()->nextnonblank()
+
nr2char({expr} [, {utf8}]) *nr2char()*
Return a string with a single character, which has the number
value {expr}. Examples: >
@@ -6952,6 +7298,9 @@ nr2char({expr} [, {utf8}]) *nr2char()*
characters. nr2char(0) is a real NUL and terminates the
string, thus results in an empty string.
+ Can also be used as a |method|: >
+ GetNumber()->nr2char()
+
nvim_...({...}) *E5555* *nvim_...()* *eval-api*
Call nvim |api| functions. The type checking of arguments will
be stricter than for most other builtins. For instance,
@@ -6980,6 +7329,9 @@ pathshorten({path}) *pathshorten()*
< ~/.c/n/a/file1.vim ~
It doesn't matter if the path exists or not.
+ Can also be used as a |method|: >
+ GetDirectories()->pathshorten()
+
perleval({expr}) *perleval()*
Evaluate |perl| expression {expr} and return its result
converted to Vim data structures.
@@ -6995,6 +7347,9 @@ perleval({expr}) *perleval()*
:echo perleval('[1 .. 4]')
< [1, 2, 3, 4]
+ Can also be used as a |method|: >
+ GetExpr()->perleval()
+
pow({x}, {y}) *pow()*
Return the power of {x} to the exponent {y} as a |Float|.
{x} and {y} must evaluate to a |Float| or a |Number|.
@@ -7018,6 +7373,8 @@ prevnonblank({lnum}) *prevnonblank()*
{lnum} is used like with |getline()|.
Also see |nextnonblank()|.
+ Can also be used as a |method|: >
+ GetLnum()->prevnonblank()
printf({fmt}, {expr1} ...) *printf()*
Return a String with {fmt}, where "%" items are replaced by
@@ -7250,6 +7607,9 @@ prompt_setcallback({buf}, {expr}) *prompt_setcallback()*
endif
endfunc
+< Can also be used as a |method|: >
+ GetBuffer()->prompt_setcallback(callback)
+
prompt_setinterrupt({buf}, {expr}) *prompt_setinterrupt()*
Set a callback for buffer {buf} to {expr}. When {expr} is an
empty string the callback is removed. This has only effect if
@@ -7259,12 +7619,18 @@ prompt_setinterrupt({buf}, {expr}) *prompt_setinterrupt()*
mode. Without setting a callback Vim will exit Insert mode,
as in any buffer.
+ Can also be used as a |method|: >
+ GetBuffer()->prompt_setinterrupt(callback)
+
prompt_setprompt({buf}, {text}) *prompt_setprompt()*
Set prompt for buffer {buf} to {text}. You most likely want
{text} to end in a space.
The result is only visible if {buf} has 'buftype' set to
"prompt". Example: >
call prompt_setprompt(bufnr(''), 'command: ')
+<
+ Can also be used as a |method|: >
+ GetBuffer()->prompt_setprompt('command: ')
pum_getpos() *pum_getpos()*
If the popup menu (see |ins-completion-menu|) is not visible,
@@ -7295,6 +7661,9 @@ py3eval({expr}) *py3eval()*
Dictionaries are represented as Vim |Dictionary| type with
keys converted to strings.
+ Can also be used as a |method|: >
+ GetExpr()->py3eval()
+<
*E858* *E859*
pyeval({expr}) *pyeval()*
Evaluate Python expression {expr} and return its result
@@ -7305,12 +7674,18 @@ pyeval({expr}) *pyeval()*
Dictionaries are represented as Vim |Dictionary| type,
non-string keys result in error.
+ Can also be used as a |method|: >
+ GetExpr()->pyeval()
+
pyxeval({expr}) *pyxeval()*
Evaluate Python expression {expr} and return its result
converted to Vim data structures.
Uses Python 2 or 3, see |python_x| and 'pyxversion'.
See also: |pyeval()|, |py3eval()|
+ Can also be used as a |method|: >
+ GetExpr()->pyxeval()
+<
*E726* *E727*
range({expr} [, {max} [, {stride}]]) *range()*
Returns a |List| with Numbers:
@@ -7330,6 +7705,9 @@ range({expr} [, {max} [, {stride}]]) *range()*
range(0) " []
range(2, 0) " error!
<
+ Can also be used as a |method|: >
+ GetExpr()->range()
+<
*readdir()*
readdir({directory} [, {expr}])
Return a list with file and directory names in {directory}.
@@ -7357,6 +7735,9 @@ readdir({directory} [, {expr}])
endfunction
echo s:tree(".")
<
+ Can also be used as a |method|: >
+ GetDirName()->readdir()
+<
*readfile()*
readfile({fname} [, {type} [, {max}]])
Read file {fname} and return a |List|, each line of the file
@@ -7390,6 +7771,9 @@ readfile({fname} [, {type} [, {max}]])
the result is an empty list.
Also see |writefile()|.
+ Can also be used as a |method|: >
+ GetFileName()->readfile()
+
reg_executing() *reg_executing()*
Returns the single letter name of the register being executed.
Returns an empty string when no register is being executed.
@@ -7417,6 +7801,9 @@ reltime([{start} [, {end}]]) *reltime()*
The {start} and {end} arguments must be values returned by
reltime().
+ Can also be used as a |method|: >
+ GetStart()->reltime()
+<
Note: |localtime()| returns the current (non-relative) time.
reltimefloat({time}) *reltimefloat()*
@@ -7430,6 +7817,9 @@ reltimefloat({time}) *reltimefloat()*
Also see |profiling|.
If there is an error an empty string is returned
+ Can also be used as a |method|: >
+ reltime(start)->reltimefloat()
+
reltimestr({time}) *reltimestr()*
Return a String that represents the time value of {time}.
This is the number of seconds, a dot and the number of
@@ -7444,6 +7834,9 @@ reltimestr({time}) *reltimestr()*
< Also see |profiling|.
If there is an error an empty string is returned
+ Can also be used as a |method|: >
+ reltime(start)->reltimestr()
+<
*remote_expr()* *E449*
remote_expr({server}, {string} [, {idvar} [, {timeout}]])
Send the {string} to {server}. The string is sent as an
@@ -7576,6 +7969,9 @@ rename({from}, {to}) *rename()*
NOTE: If {to} exists it is overwritten without warning.
This function is not available in the |sandbox|.
+ Can also be used as a |method|: >
+ GetOldName()->rename(newname)
+
repeat({expr}, {count}) *repeat()*
Repeat {expr} {count} times and return the concatenated
result. Example: >
@@ -7602,6 +7998,9 @@ resolve({filename}) *resolve()* *E655*
current directory (provided the result is still a relative
path name) and also keeps a trailing path separator.
+ Can also be used as a |method|: >
+ GetName()->resolve()
+<
*reverse()*
reverse({object})
Reverse the order of items in {object} in-place.
@@ -7656,6 +8055,9 @@ rubyeval({expr}) *rubyeval()*
Other objects are represented as strings resulted from their
"Object#to_s" method.
+ Can also be used as a |method|: >
+ GetRubyExpr()->rubyeval()
+
screenattr({row}, {col}) *screenattr()*
Like |screenchar()|, but return the attribute. This is a rather
arbitrary number that can only be used to compare to the
@@ -8219,6 +8621,9 @@ setfperm({fname}, {mode}) *setfperm()* *chmod*
Returns non-zero for success, zero for failure.
+ Can also be used as a |method|: >
+ GetFilename()->setfperm(mode)
+<
To read permissions see |getfperm()|.
setline({lnum}, {text}) *setline()*
@@ -8435,8 +8840,8 @@ setreg({regname}, {value} [, {options}])
Set the register {regname} to {value}.
The {regname} argument is a string.
- {value} may be any value returned by |getreg()|, including
- a |List|.
+ {value} may be any value returned by |getreg()| or
+ |getreginfo()|, including a |List| or |Dict|.
If {options} contains "a" or {regname} is upper case,
then the value is appended.
@@ -8466,9 +8871,13 @@ setreg({regname}, {value} [, {options}])
:call setreg(v:register, @*)
:call setreg('*', @%, 'ac')
:call setreg('a', "1\n2\n3", 'b5')
+ :call setreg('"', { 'points_to': 'a'})
< This example shows using the functions to save and restore a
register: >
+ :let var_a = getreginfo()
+ :call setreg('a', var_a)
+< or: >
:let var_a = getreg('a', 1, 1)
:let var_amode = getregtype('a')
....
@@ -8906,10 +9315,9 @@ str2list({string} [, {utf8}]) *str2list()*
str2list("ABC") returns [65, 66, 67]
< |list2str()| does the opposite.
- When {utf8} is omitted or zero, the current 'encoding' is used.
- With {utf8} set to TRUE, always treat the String as utf-8
- characters. With utf-8 composing characters are handled
- properly: >
+ UTF-8 encoding is always used, {utf8} option has no effect,
+ and exists only for backwards-compatibility.
+ With UTF-8 composing characters are handled properly: >
str2list("á") returns [97, 769]
< Can also be used as a |method|: >
@@ -10921,7 +11329,7 @@ text...
literal then the items also cannot be changed: >
const ll = [1, 2, 3]
let ll[1] = 5 " Error!
-< Nested references are not locked: >
+< Nested references are not locked: >
let lvar = ['a']
const lconst = [0, lvar]
let lconst[0] = 2 " Error!
diff --git a/runtime/doc/filetype.txt b/runtime/doc/filetype.txt
index 4d0fdd71cc..42a9993c8c 100644
--- a/runtime/doc/filetype.txt
+++ b/runtime/doc/filetype.txt
@@ -501,6 +501,14 @@ One command, :DiffGitCached, is provided to show a diff of the current commit
in the preview window. It is equivalent to calling "git diff --cached" plus
any arguments given to the command.
+GPROF *ft-gprof-plugin*
+
+The gprof filetype plugin defines a mapping <C-]> to jump from a function
+entry in the gprof flat profile or from a function entry in the call graph
+to the details of that function in the call graph.
+
+The mapping can be disabled with: >
+ let g:no_gprof_maps = 1
MAIL *ft-mail-plugin*
diff --git a/runtime/doc/helphelp.txt b/runtime/doc/helphelp.txt
index 4a94701b2e..aaa2a35fe1 100644
--- a/runtime/doc/helphelp.txt
+++ b/runtime/doc/helphelp.txt
@@ -389,17 +389,5 @@ highlighting. So do these:
You can find the details in $VIMRUNTIME/syntax/help.vim
- *inclusion*
-Vim is for everybody, no matter race, gender or anything. Some people make a
-big deal about using "he" or "his" when referring to the user, thinking it
-means we assume the user is male. That is not the case, it's just a habit of
-writing help text, which quite often is many years old. Also, a lot of the
-text is written by contributors for whom English is not their first language.
-We do not make any assumptions about the gender of the user, no matter how the
-text is phrased. Some people have suggested using "they", but that is not
-regular English. We do not want to spend much time on this discussion. The
-goal is that the reader understands how Vim works, the exact wording is
-secondary.
-
vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/intro.txt b/runtime/doc/intro.txt
index 2baf3a247f..a89263861b 100644
--- a/runtime/doc/intro.txt
+++ b/runtime/doc/intro.txt
@@ -55,7 +55,7 @@ Nvim on the interwebs *internet*
Nvim home page: https://neovim.io/
Nvim FAQ: https://github.com/neovim/neovim/wiki/FAQ
Downloads: https://github.com/neovim/neovim/releases
- Vim FAQ: https://vimhelp.appspot.com/vim_faq.txt.html
+ Vim FAQ: https://vimhelp.org/vim_faq.txt.html
*bugs* *bug-report*
@@ -312,7 +312,6 @@ notation meaning equivalent decimal value(s) ~
<Tab> tab CTRL-I 9 *tab* *Tab*
*linefeed*
<NL> linefeed CTRL-J 10 (used for <Nul>)
-<FF> formfeed CTRL-L 12 *formfeed*
<CR> carriage return CTRL-M 13 *carriage-return*
<Return> same as <CR> *<Return>*
<Enter> same as <CR> *<Enter>*
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt
index 48d65a22b6..5549d3c180 100644
--- a/runtime/doc/lsp.txt
+++ b/runtime/doc/lsp.txt
@@ -224,6 +224,11 @@ For |lsp-request|, each |lsp-handler| has this signature: >
The ID of the |vim.lsp.client|.
{bufnr} (Buffer)
Buffer handle, or 0 for current.
+
+ {params} (table|nil)
+ The parameters used in the original request
+ which resulted in this handler
+ call.
{config} (table)
Configuration for the handler.
@@ -234,6 +239,7 @@ For |lsp-request|, each |lsp-handler| has this signature: >
To configure a particular |lsp-handler|, see:
|lsp-handler-configuration|
+
Returns: ~
The |lsp-handler| can respond by returning two values: `result, err`
Where `err` must be shaped like an RPC error:
@@ -622,6 +628,10 @@ client_is_stopped({client_id}) *vim.lsp.client_is_stopped()*
flush({client}) *vim.lsp.flush()*
TODO: Documentation
+ *vim.lsp.for_each_buffer_client()*
+for_each_buffer_client({bufnr}, {fn})
+ TODO: Documentation
+
get_active_clients() *vim.lsp.get_active_clients()*
Gets all active clients.
@@ -660,7 +670,7 @@ omnifunc({findstart}, {base}) *vim.lsp.omnifunc()*
{base} If findstart=0, text to match against
Return: ~
- (number) Decided by`findstart`:
+ (number) Decided by {findstart}:
• findstart=0: column where the completion starts, or -2
or -3
• findstart=1: list of matches (actually just calls
@@ -863,12 +873,17 @@ clear_references() *vim.lsp.buf.clear_references()*
Removes document highlights from current buffer.
code_action({context}) *vim.lsp.buf.code_action()*
- Selects a code action from the input list that is available at
- the current cursor position.
+ Selects a code action available at the current cursor
+ position.
Parameters: ~
- {context} (table, optional) Valid `CodeActionContext`
- object
+ {context} table|nil `CodeActionContext` of the LSP specification:
+ • diagnostics: (table|nil) LSP`Diagnostic[]` . Inferred from the current position if not
+ provided.
+ • only: (string|nil) LSP `CodeActionKind` used
+ to filter the code actions. Most language
+ servers support values like `refactor` or
+ `quickfix` .
See also: ~
https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction
@@ -1004,13 +1019,21 @@ outgoing_calls() *vim.lsp.buf.outgoing_calls()*
cursor in the |quickfix| window. If the symbol can resolve to
multiple items, the user can pick one in the |inputlist|.
+prepare_rename({err}, {result}) *vim.lsp.buf.prepare_rename()*
+ TODO: Documentation
+
*vim.lsp.buf.range_code_action()*
range_code_action({context}, {start_pos}, {end_pos})
Performs |vim.lsp.buf.code_action()| for a given range.
Parameters: ~
- {context} (table, optional) Valid `CodeActionContext`
- object
+ {context} table|nil `CodeActionContext` of the LSP specification:
+ • diagnostics: (table|nil) LSP`Diagnostic[]` . Inferred from the current position if not
+ provided.
+ • only: (string|nil) LSP `CodeActionKind`
+ used to filter the code actions. Most
+ language servers support values like
+ `refactor` or `quickfix` .
{start_pos} ({number, number}, optional) mark-indexed
position. Defaults to the start of the last
visual selection.
@@ -1235,8 +1258,8 @@ apply_text_edits({text_edits}, {bufnr})
Applies a list of text edits to a buffer.
Parameters: ~
- {text_edits} (table) list of `TextEdit` objects
- {buf_nr} (number) Buffer id
+ {text_edits} table list of `TextEdit` objects
+ {bufnr} number Buffer id
See also: ~
https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textEdit
@@ -1456,6 +1479,13 @@ make_floating_popup_options({width}, {height}, {opts})
{width} (number) window width (in character cells)
{height} (number) window height (in character cells)
{opts} (table, optional)
+ • offset_x (number) offset to add to `col`
+ • offset_y (number) offset to add to `row`
+ • border (string or table) override `border`
+ • focusable (string or table) override
+ `focusable`
+ • zindex (string or table) override `zindex` ,
+ defaults to 50
Return: ~
(table) Options
@@ -1546,10 +1576,6 @@ open_floating_preview({contents}, {syntax}, {opts})
height when wrap is enabled
• max_width maximal width of floating window
• max_height maximal height of floating window
- • pad_left number of columns to pad contents
- at left
- • pad_right number of columns to pad contents
- at right
• pad_top number of lines to pad contents at
top
• pad_bottom number of lines to pad contents
@@ -1569,10 +1595,10 @@ parse_snippet({input}) *vim.lsp.util.parse_snippet()*
Parses snippets in a completion entry.
Parameters: ~
- {input} (string) unparsed snippet
+ {input} string unparsed snippet
Return: ~
- (string) parsed snippet
+ string parsed snippet
preview_location({location}, {opts}) *vim.lsp.util.preview_location()*
Previews a location in a floating window
@@ -1633,10 +1659,6 @@ stylize_markdown({bufnr}, {contents}, {opts})
height
• max_width maximal width of floating window
• max_height maximal height of floating window
- • pad_left number of columns to pad contents
- at left
- • pad_right number of columns to pad contents
- at right
• pad_top number of lines to pad contents at
top
• pad_bottom number of lines to pad contents
@@ -1703,6 +1725,16 @@ get_filename() *vim.lsp.log.get_filename()*
Return: ~
(string) log filename
+get_level() *vim.lsp.log.get_level()*
+ TODO: Documentation
+
+set_format_func({handle}) *vim.lsp.log.set_format_func()*
+ Sets formatting function used to format logs
+
+ Parameters: ~
+ {handle} function function to apply to logging arguments,
+ pass vim.inspect for multi-line formatting
+
set_level({level}) *vim.lsp.log.set_level()*
Sets the current log level.
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index 53d68fa5e6..fe94e89e2a 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -928,6 +928,7 @@ Example: >
vim.g.foo = 5 -- Set the g:foo Vimscript variable.
print(vim.g.foo) -- Get and print the g:foo Vimscript variable.
vim.g.foo = nil -- Delete (:unlet) the Vimscript variable.
+ vim.b[2].foo = 6 -- Set b:foo for buffer 2
vim.g *vim.g*
Global (|g:|) editor variables.
@@ -935,15 +936,18 @@ vim.g *vim.g*
vim.b *vim.b*
Buffer-scoped (|b:|) variables for the current buffer.
- Invalid or unset key returns `nil`.
+ Invalid or unset key returns `nil`. Can be indexed with
+ an integer to access variables for a specific buffer.
vim.w *vim.w*
Window-scoped (|w:|) variables for the current window.
- Invalid or unset key returns `nil`.
+ Invalid or unset key returns `nil`. Can be indexed with
+ an integer to access variables for a specific window.
vim.t *vim.t*
Tabpage-scoped (|t:|) variables for the current tabpage.
- Invalid or unset key returns `nil`.
+ Invalid or unset key returns `nil`. Can be indexed with
+ an integer to access variables for a specific tabpage.
vim.v *vim.v*
|v:| variables.
@@ -1206,6 +1210,36 @@ notify({msg}, {log_level}, {_opts}) *vim.notify()*
See also: ~
:help nvim_notify
+on_key({fn}, {ns_id}) *vim.on_key()*
+ Adds Lua function {fn} with namespace id {ns_id} as a listener
+ to every, yes every, input key.
+
+ The Nvim command-line option |-w| is related but does not
+ support callbacks and cannot be toggled dynamically.
+
+ Note:
+ {fn} will not be cleared by |nvim_buf_clear_namespace()|
+
+ Note:
+ {fn} will receive the keys after mappings have been
+ evaluated
+
+ Parameters: ~
+ {fn} function: Callback function. It should take one
+ string argument. On each key press, Nvim passes
+ the key char to fn(). |i_CTRL-V| If {fn} is nil,
+ it removes the callback for the associated
+ {ns_id}
+ {ns_id} number? Namespace ID. If nil or 0, generates and
+ returns a new |nvim_create_namesapce()| id.
+
+ Return: ~
+ number Namespace id associated with {fn}. Or count of all
+ callbacks if on_key() is called without arguments.
+
+ Note:
+ {fn} will be removed if an error occurs while calling.
+
paste({lines}, {phase}) *vim.paste()*
Paste handler, invoked by |nvim_paste()| when a conforming UI
(such as the |TUI|) pastes text into the editor.
@@ -1268,8 +1302,7 @@ schedule_wrap({cb}) *vim.schedule_wrap()*
deep_equal({a}, {b}) *vim.deep_equal()*
Deep compare values for equality
- Tables are compared recursively unless they both provide the `eq` methamethod.
- All other types are compared using the equality `==` operator.
+ Tables are compared recursively unless they both provide the `eq` methamethod. All other types are compared using the equality `==` operator.
Parameters: ~
{a} first value
@@ -1373,20 +1406,25 @@ pesc({s}) *vim.pesc()*
See also: ~
https://github.com/rxi/lume
-split({s}, {sep}, {plain}) *vim.split()*
+split({s}, {sep}, {kwargs}) *vim.split()*
Splits a string at each instance of a separator.
Examples: >
- split(":aa::b:", ":") --> {'','aa','','b',''}
- split("axaby", "ab?") --> {'','x','y'}
- split(x*yz*o, "*", true) --> {'x','yz','o'}
+
+ split(":aa::b:", ":") --> {'','aa','','b',''}
+ split("axaby", "ab?") --> {'','x','y'}
+ split("x*yz*o", "*", {plain=true}) --> {'x','yz','o'}
+ split("|x|y|z|", "|", {trimempty=true}) --> {'x', 'y', 'z'}
<
Parameters: ~
- {s} String to split
- {sep} Separator string or pattern
- {plain} If `true` use `sep` literally (passed to
- String.find)
+ {s} String to split
+ {sep} Separator string or pattern
+ {kwargs} Keyword arguments:
+ • plain: (boolean) If `true` use `sep` literally
+ (passed to string.find)
+ • trimempty: (boolean) If `true` remove empty
+ items from the front and back of the list
Return: ~
List-like table of the split components.
@@ -1484,7 +1522,7 @@ tbl_flatten({t}) *vim.tbl_flatten()*
Flattened copy of the given list-like table.
See also: ~
- Fromhttps://github.com/premake/premake-core/blob/master/src/base/table.lua
+ From https://github.com/premake/premake-core/blob/master/src/base/table.lua
tbl_isempty({t}) *vim.tbl_isempty()*
Checks if a table is empty.
@@ -1520,7 +1558,7 @@ tbl_keys({t}) *vim.tbl_keys()*
list of keys
See also: ~
- Fromhttps://github.com/premake/premake-core/blob/master/src/base/table.lua
+ From https://github.com/premake/premake-core/blob/master/src/base/table.lua
tbl_map({func}, {t}) *vim.tbl_map()*
Apply a function to all values of a table.
@@ -1571,12 +1609,14 @@ validate({opt}) *vim.validate()*
vim.validate{arg1={{'foo'}, 'table'}, arg2={'foo', 'string'}}
=> NOP (success)
-
- vim.validate{arg1={1, 'table'}}
- => error('arg1: expected table, got number')
-
- vim.validate{arg1={3, function(a) return (a % 2) == 0 end, 'even number'}}
- => error('arg1: expected even number, got 3')
+<
+>
+ vim.validate{arg1={1, 'table'}}
+ => error('arg1: expected table, got number')
+<
+>
+ vim.validate{arg1={3, function(a) return (a % 2) == 0 end, 'even number'}}
+ => error('arg1: expected even number, got 3')
<
Parameters: ~
@@ -1645,4 +1685,25 @@ uri_to_fname({uri}) *vim.uri_to_fname()*
Return: ~
Filename
+
+==============================================================================
+Lua module: ui *lua-ui*
+
+select({items}, {opts}, {on_choice}) *vim.ui.select()*
+ Prompts the user to pick a single item from a collection of
+ entries
+
+ Parameters: ~
+ {items} table Arbitrary items
+ {opts} table Additional options
+ • prompt (string|nil) Text of the prompt.
+ Defaults to `Select one of:`
+ • format_item (function item -> text)
+ Function to format an individual item from
+ `items` . Defaults to `tostring` .
+ {on_choice} function ((item|nil, idx|nil) -> ()) Called
+ once the user made a choice. `idx` is the
+ 1-based index of `item` within `item` . `nil`
+ if the user aborted the dialog.
+
vim:tw=78:ts=8:ft=help:norl:
diff --git a/runtime/doc/mbyte.txt b/runtime/doc/mbyte.txt
index a6c797a860..3bbf36c642 100644
--- a/runtime/doc/mbyte.txt
+++ b/runtime/doc/mbyte.txt
@@ -663,7 +663,7 @@ This file explains what characters are available in UTF-8 and CP1255 encodings,
and what the keymaps are to get those characters:
glyph encoding keymap ~
-Char utf-8 cp1255 hebrew hebrewp name ~
+Char UTF-8 cp1255 hebrew hebrewp name ~
א 0x5d0 0xe0 t a 'alef
ב 0x5d1 0xe1 c b bet
ג 0x5d2 0xe2 d g gimel
@@ -716,11 +716,11 @@ Vowel marks and special punctuation:
ױ 0x5f1 0xd5 VY VY vav-yod
ײ 0x5f2 0xd6 YY YY yod-yod
-The following are only available in utf-8
+The following are only available in UTF-8
Cantillation marks:
glyph
-Char utf-8 hebrew name
+Char UTF-8 hebrew name
ב֑ 0x591 C: etnahta
ב֒ 0x592 Cs segol
ב֓ 0x593 CS shalshelet
@@ -803,7 +803,7 @@ ASCII. On MS-Windows UTF-16 is also used (previously UCS-2), which uses
internally.
Vim has comprehensive UTF-8 support. It works well in:
-- xterm with utf-8 support enabled
+- xterm with UTF-8 support enabled
- MS-Windows GUI
- several other platforms
@@ -814,14 +814,14 @@ a space to fill the gap.
*bom-bytes*
When reading a file a BOM (Byte Order Mark) can be used to recognize the
Unicode encoding:
- EF BB BF utf-8
- FE FF utf-16 big endian
- FF FE utf-16 little endian
- 00 00 FE FF utf-32 big endian
- FF FE 00 00 utf-32 little endian
-
-Utf-8 is the recommended encoding. Note that it's difficult to tell utf-16
-and utf-32 apart. Utf-16 is often used on MS-Windows, utf-32 is not
+ EF BB BF UTF-8
+ FE FF UTF-16 big endian
+ FF FE UTF-16 little endian
+ 00 00 FE FF UTF-32 big endian
+ FF FE 00 00 UTF-32 little endian
+
+UTF-8 is the recommended encoding. Note that it's difficult to tell UTF-16
+and UTF-32 apart. UTF-16 is often used on MS-Windows, UTF-32 is not
widespread as file format.
@@ -888,10 +888,10 @@ Motif. Use the ":hi Menu font={fontname}" command for this. |:highlight|
TYPING UTF-8 *utf-8-typing*
If you are using X-Windows, you should find an input method that supports
-utf-8.
+UTF-8.
-If your system does not provide support for typing utf-8, you can use the
-'keymap' feature. This allows writing a keymap file, which defines a utf-8
+If your system does not provide support for typing UTF-8, you can use the
+'keymap' feature. This allows writing a keymap file, which defines a UTF-8
character as a sequence of ASCII characters. See |mbyte-keymap|.
If everything else fails, you can type any character as four hex bytes: >
diff --git a/runtime/doc/nvim_terminal_emulator.txt b/runtime/doc/nvim_terminal_emulator.txt
index 5ad69d1122..e83b17f9a0 100644
--- a/runtime/doc/nvim_terminal_emulator.txt
+++ b/runtime/doc/nvim_terminal_emulator.txt
@@ -53,7 +53,7 @@ next key is sent unless it is <C-N>. Use <C-\><C-N> to return to normal-mode.
Terminal-mode forces these local options:
- 'nocursorline'
+ 'cursorlineopt' = number
'nocursorcolumn'
'scrolloff' = 0
'sidescrolloff' = 0
@@ -171,7 +171,7 @@ program window A terminal window for the executed program. When "run" is
The current window is used to show the source code. When gdb pauses the
source file location will be displayed, if possible. A sign is used to
-highlight the current position, using highlight group debugPC.
+highlight the current position, using highlight group debugPC.
If the buffer in the current window is modified, another window will be opened
to display the current gdb position.
@@ -222,7 +222,7 @@ Put focus on the gdb window and type: >
run
Vim will start running in the program window. Put focus there and type: >
:help gui
-Gdb will run into the ex_help breakpoint. The source window now shows the
+Gdb will run into the ex_help breakpoint. The source window now shows the
ex_cmds.c file. A red "1 " marker will appear in the signcolumn where the
breakpoint was set. The line where the debugger stopped is highlighted. You
can now step through the program. You will see the highlighting move as the
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 853d774232..be397117b2 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1159,9 +1159,9 @@ A jump table for the options with a short description can be found at |Q_op|.
'cdpath' 'cd' string (default: equivalent to $CDPATH or ",,")
global
This is a list of directories which will be searched when using the
- |:cd| and |:lcd| commands, provided that the directory being searched
- for has a relative path, not an absolute part starting with "/", "./"
- or "../", the 'cdpath' option is not used then.
+ |:cd|, |:tcd| and |:lcd| commands, provided that the directory being
+ searched for has a relative path, not an absolute part starting with
+ "/", "./" or "../", the 'cdpath' option is not used then.
The 'cdpath' option's value has the same form and semantics as
|'path'|. Also see |file-searching|.
The default value is taken from $CDPATH, with a "," prepended to look
@@ -1409,9 +1409,9 @@ A jump table for the options with a short description can be found at |Q_op|.
When this option is set it overrules 'shellslash' for completion:
- When this option is set to "slash", a forward slash is used for path
completion in insert mode. This is useful when editing HTML tag, or
- Makefile with 'noshellslash' on Windows.
+ Makefile with 'noshellslash' on MS-Windows.
- When this option is set to "backslash", backslash is used. This is
- useful when editing a batch file with 'shellslash' set on Windows.
+ useful when editing a batch file with 'shellslash' set on MS-Windows.
- When this option is empty, same character is used as for
'shellslash'.
For Insert mode completion the buffer-local value is used. For
@@ -5981,13 +5981,13 @@ A jump table for the options with a short description can be found at |Q_op|.
return value of expr contains % items they will get expanded.
The expression can contain the } character, the end of
expression is denoted by %}.
- The For example: >
+ For example: >
func! Stl_filename() abort
return "%t"
endfunc
< `stl=%{Stl_filename()}` results in `"%t"`
`stl=%{%Stl_filename()%}` results in `"Name of current file"`
- } - End of `{%` expression
+ %} - End of `{%` expression
( - Start of item group. Can be used for setting the width and
alignment of a section. Must be followed by %) somewhere.
) - End of item group. No width fields allowed.
@@ -6821,8 +6821,9 @@ A jump table for the options with a short description can be found at |Q_op|.
More info here: |cmdline-completion|.
The character is not recognized when used inside a macro. See
'wildcharm' for that.
+ Some keys will not work, such as CTRL-C, <CR> and Enter.
Although 'wc' is a number option, you can set it to a special key: >
- :set wc=<Esc>
+ :set wc=<Tab>
<
*'wildcharm'* *'wcm'*
diff --git a/runtime/doc/pattern.txt b/runtime/doc/pattern.txt
index c49cc6d540..dfed39dba6 100644
--- a/runtime/doc/pattern.txt
+++ b/runtime/doc/pattern.txt
@@ -977,7 +977,7 @@ $ At end of pattern or in front of "\|", "\)" or "\n" ('magic' on):
/.*\%17v
< Column 17 is highlighted by 'hlsearch' because there is another match
where ".*" matches zero characters.
-<
+
Character classes:
\i identifier character (see 'isident' option) */\i*
diff --git a/runtime/doc/pi_health.txt b/runtime/doc/pi_health.txt
index bb688770fc..179c1066cd 100644
--- a/runtime/doc/pi_health.txt
+++ b/runtime/doc/pi_health.txt
@@ -5,7 +5,7 @@ Author: TJ DeVries <devries.timothyj@gmail.com>
Type |gO| to see the table of contents.
==============================================================================
-Introduction *health*
+Introduction *health*
health.vim is a minimal framework to help with troubleshooting user
configuration. Nvim ships with healthchecks for configuration, performance,
@@ -18,65 +18,136 @@ To run the healthchecks, use this command: >
Plugin authors are encouraged to write new healthchecks. |health-dev|
==============================================================================
-Commands *health-commands*
+Commands *health-commands*
- *:checkhealth* *:CheckHealth*
+ *:checkhealth* *:CheckHealth*
:checkhealth Run all healthchecks.
- *E5009*
- Nvim depends on |$VIMRUNTIME| and 'runtimepath' to find
- the standard "runtime files" for syntax highlighting,
- filetype-specific behavior, and standard plugins
- (including :checkhealth). If the runtime files cannot
- be found then those features will not work.
+ *E5009*
+ Nvim depends on |$VIMRUNTIME|, 'runtimepath' and 'packpath' to
+ find the standard "runtime files" for syntax highlighting,
+ filetype-specific behavior, and standard plugins (including
+ :checkhealth). If the runtime files cannot be found then
+ those features will not work.
:checkhealth {plugins}
- Run healthcheck(s) for one or more plugins. E.g. to run
- only the standard Nvim healthcheck: >
+ Run healthcheck(s) for one or more plugins. E.g. to run only
+ the standard Nvim healthcheck: >
:checkhealth nvim
-< To run the healthchecks for the "foo" and "bar" plugins
- (assuming these plugins are on your 'runtimepath' and
- they have implemented health#foo#check() and
- health#bar#check(), respectively): >
+<
+ To run the healthchecks for the "foo" and "bar" plugins
+ (assuming these plugins are on 'runtimepath' or 'packpath' and
+ they have implemented the Lua or Vimscript interface
+ require("foo.health").check() and health#bar#check(),
+ respectively): >
:checkhealth foo bar
<
+ To run healthchecks for lua submodules, use dot notation or
+ "*" to refer to all submodules. For example nvim provides
+ `vim.lsp` and `vim.treesitter` >
+ :checkhealth vim.lsp vim.treesitter
+ :checkhealth vim*
+<
==============================================================================
-Functions *health-functions*
+Lua Functions *health-functions-lua* *health-lua*
+
+The Lua "health" module can be used to create new healthchecks (see also
+|health-functions-vim|). To get started, simply use: >
+ local health = require('health')
+<
+health.report_start({name}) *health.report_start()*
+ Starts a new report. Most plugins should call this only once, but if
+ you want different sections to appear in your report, call this once
+ per section.
+
+health.report_info({msg}) *health.report_info()*
+ Reports an informational message.
+
+health.report_ok({msg}) *health.report_ok()*
+ Reports a "success" message.
+
+health.report_warn({msg} [, {advice}]) *health.report_warn()*
+ Reports a warning. {advice} is an optional List of suggestions.
+
+health.report_error({msg} [, {advice}]) *health.report_error()*
+ Reports an error. {advice} is an optional List of suggestions.
+
+==============================================================================
+Create a Lua healthcheck *health-dev-lua*
+
+Healthchecks are functions that check the user environment, configuration,
+etc. Nvim has built-in healthchecks in $VIMRUNTIME/autoload/health/.
-health.vim functions are for creating new healthchecks. They mostly just do
-some layout and formatting, to give users a consistent presentation.
+To add a new healthcheck for your own plugin, simply define a Lua module in
+your plugin that returns a table with a "check()" function. |:checkhealth|
+will automatically find and invoke this function.
-health#report_start({name}) *health#report_start*
- Starts a new report. Most plugins should call this only once, but if
+If your plugin is named "foo", then its healthcheck module should be a file in
+one of these locations on 'runtimepath' or 'packpath':
+ - lua/foo/health/init.lua
+ - lua/foo/health.lua
+
+If your plugin provides a submodule named "bar" for which you want a separate
+healthcheck, define the healthcheck at one of these locations on 'runtimepath'
+or 'packpath':
+ - lua/foo/bar/health/init.lua
+ - lua/foo/bar/health.lua
+
+All submodules should return a Lua table containing the method `check()`.
+
+Copy this sample code into `lua/foo/health/init.lua` or `lua/foo/health.lua`,
+replacing "foo" in the path with your plugin name: >
+
+ local M = {}
+ local health = require("health")
+
+ M.check = function()
+ health.report_start("my_plugin report")
+ -- make sure setup function parameters are ok
+ if check_setup() then
+ health.report_ok("Setup function is correct")
+ else
+ health.report_error("Setup function is incorrect")
+ end
+ -- do some more checking
+ -- ...
+ end
+
+ return M
+
+==============================================================================
+Vimscript Functions *health-functions-vimscript* *health-vimscript*
+
+health.vim functions are for creating new healthchecks. (See also
+|health-functions-lua|)
+
+health#report_start({name}) *health#report_start*
+ Starts a new report. Most plugins should call this only once, but if
you want different sections to appear in your report, call this once
per section.
-health#report_info({msg}) *health#report_info*
- Reports an informational message.
+health#report_info({msg}) *health#report_info*
+ Reports an informational message.
-health#report_ok({msg}) *health#report_ok*
- Reports a "success" message.
+health#report_ok({msg}) *health#report_ok*
+ Reports a "success" message.
-health#report_warn({msg}, [{advice}]) *health#report_warn*
+health#report_warn({msg} [, {advice}]) *health#report_warn*
Reports a warning. {advice} is an optional List of suggestions.
-health#report_error({msg}, [{advice}]) *health#report_error*
+health#report_error({msg} [, {advice}]) *health#report_error*
Reports an error. {advice} is an optional List of suggestions.
-health#{plugin}#check() *health.user_checker*
+health#{plugin}#check() *health.user_checker*
Healthcheck function for {plugin}. Called by |:checkhealth|
automatically. Example: >
- function! health#my_plug#check() abort
- silent call s:check_environment_vars()
- silent call s:check_python_configuration()
- endfunction
+ function! health#my_plug#check() abort
+ silent call s:check_environment_vars()
+ silent call s:check_python_configuration()
+ endfunction
<
- All output will be captured from the healthcheck. Use the
- health#report_* functions so that your healthcheck has a format
- consistent with the standard healthchecks.
-
==============================================================================
-Create a healthcheck *health-dev*
+Create a healthcheck *health-dev-vim*
Healthchecks are functions that check the user environment, configuration,
etc. Nvim has built-in healthchecks in $VIMRUNTIME/autoload/health/.
@@ -88,8 +159,8 @@ health#{plugin}#check() function in autoload/health/{plugin}.vim.
If your plugin is named "foo", then its healthcheck function must be >
health#foo#check()
-defined in this file on 'runtimepath': >
- autoload/health/foo.vim
+defined in this file on 'runtimepath' or 'packpath':
+ - autoload/health/foo.vim
Copy this sample code into autoload/health/foo.vim and replace "foo" with your
plugin name: >
@@ -97,7 +168,7 @@ plugin name: >
call health#report_start('sanity checks')
" perform arbitrary checks
" ...
-
+
if looks_good
call health#report_ok('found required dependencies')
else
@@ -106,6 +177,4 @@ plugin name: >
endif
endfunction
-==============================================================================
-
-vim:tw=78:ts=8:ft=help:fdm=marker
+vim:et:tw=78:ts=8:ft=help:fdm=marker
diff --git a/runtime/doc/print.txt b/runtime/doc/print.txt
index d9320ad315..f54d0429a6 100644
--- a/runtime/doc/print.txt
+++ b/runtime/doc/print.txt
@@ -690,7 +690,7 @@ There are a couple of points to bear in mind:
==============================================================================
8. Formfeed Characters *printing-formfeed*
-By default Vim does not do any special processing of |formfeed| control
+By default Vim does not do any special processing of formfeed control
characters. Setting the 'printoptions' formfeed item will make Vim recognize
formfeed characters and continue printing the current line at the beginning
of the first line on a new page. The use of formfeed characters provides
diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt
index 87a48e6d2a..bb775ec884 100644
--- a/runtime/doc/starting.txt
+++ b/runtime/doc/starting.txt
@@ -90,10 +90,11 @@ argument.
See |info-message| about capturing the text.
*--clean*
---clean Equivalent to "-u NONE -i NONE":
+--clean Mimics a fresh install of Nvim:
- Skips initializations from files and environment variables.
- No 'shada' file is read or written.
- Excludes user directories from 'runtimepath'
+ - Loads builtin plugins, unlike "-u NONE -i NONE".
*--noplugin*
--noplugin Skip loading plugins. Resets the 'loadplugins' option.
diff --git a/runtime/doc/treesitter.txt b/runtime/doc/treesitter.txt
index ac10aeec88..441ae13df4 100644
--- a/runtime/doc/treesitter.txt
+++ b/runtime/doc/treesitter.txt
@@ -531,9 +531,11 @@ Query:iter_matches({self}, {node}, {source}, {start}, {stop})
for id, node in pairs(match) do
local name = query.captures[id]
-- `node` was captured by the `name` capture in the match
-
- local node_data = metadata[id] -- Node level metadata
-
+<
+>
+ local node_data = metadata[id] -- Node level metadata
+<
+>
... use the info here ...
end
end
diff --git a/runtime/doc/usr_22.txt b/runtime/doc/usr_22.txt
index 56fe5ada2b..f53d578456 100644
--- a/runtime/doc/usr_22.txt
+++ b/runtime/doc/usr_22.txt
@@ -202,14 +202,28 @@ the other window. This is called a local directory. >
:pwd
/home/Bram/VeryLongFileName
-So long as no ":lcd" command has been used, all windows share the same current
-directory. Doing a ":cd" command in one window will also change the current
+So long as no `:lcd` command has been used, all windows share the same current
+directory. Doing a `:cd` command in one window will also change the current
directory of the other window.
- For a window where ":lcd" has been used a different current directory is
-remembered. Using ":cd" or ":lcd" in other windows will not change it.
- When using a ":cd" command in a window that uses a different current
+ For a window where `:lcd` has been used a different current directory is
+remembered. Using `:cd` or `:lcd` in other windows will not change it.
+ When using a `:cd` command in a window that uses a different current
directory, it will go back to using the shared directory.
+
+TAB LOCAL DIRECTORY
+
+When you open a new tab page, it uses the directory of the window in the
+previous tab page from which the new tab page was opened. You can change the
+directory of the current tab page using the `:tcd` command. All the windows in
+a tab page share this directory except for windows with a window-local
+directory. Any new windows opened in this tab page will use this directory as
+the current working directory. Using a `:cd` command in a tab page will not
+change the working directory of tab pages which have a tab local directory.
+When the global working directory is changed using the ":cd" command in a tab
+page, it will also change the current tab page working directory.
+
+
==============================================================================
*22.3* Finding a file
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index 5fddadcf01..6a9284dac9 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -785,9 +785,10 @@ System functions and manipulation of files:
isdirectory() check if a directory exists
getfsize() get the size of a file
getcwd() get the current working directory
- haslocaldir() check if current window used |:lcd|
+ haslocaldir() check if current window used |:lcd| or |:tcd|
tempname() get the name of a temporary file
mkdir() create a new directory
+ chdir() change current working directory
delete() delete a file
rename() rename a file
system() get the result of a shell command as a string
@@ -1025,6 +1026,7 @@ Various: *various-functions*
undotree() return the state of the undo tree
getreg() get contents of a register
+ getreginfo() get information about a register
getregtype() get type of a register
setreg() set contents and type of a register
reg_executing() return the name of the register being executed
@@ -1803,7 +1805,7 @@ First of all you must choose a name for your plugin. The features provided
by the plugin should be clear from its name. And it should be unlikely that
someone else writes a plugin with the same name but which does something
different. And please limit the name to 8 characters, to avoid problems on
-old Windows systems.
+old MS-Windows systems.
A script that corrects typing mistakes could be called "typecorr.vim". We
will use it here as an example.
diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt
index b06fa7518c..5484e27797 100644
--- a/runtime/doc/various.txt
+++ b/runtime/doc/various.txt
@@ -168,7 +168,7 @@ g8 Print the hex values of the bytes used in the
*:z!*
:[range]z![+-^.=][count]
- Like ":z:", but when [count] is not specified, it
+ Like ":z", but when [count] is not specified, it
defaults to the Vim window height minus one.
:[range]z[!]#[+-^.=][count] *:z#*
diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt
index 64824b2e3f..77bf1d29eb 100644
--- a/runtime/doc/vim_diff.txt
+++ b/runtime/doc/vim_diff.txt
@@ -248,6 +248,8 @@ Variables:
Nvim always builds with all features, in contrast to Vim which may have
certain features removed/added at compile-time. |feature-compile|
+Some Vim features were changed in Nvim, and vice versa.
+
If a Python interpreter is available on your `$PATH`, |:python| and |:python3|
are always available and may be used simultaneously. See |provider-python|.
@@ -423,6 +425,15 @@ Vimscript compatibility:
`shell_error` does not alias to |v:shell_error|
`this_session` does not alias to |v:this_session|
+Working directory (Vim implemented some of these later than Nvim):
+- |DirChanged| can be triggered when switching to another window.
+- |getcwd()| and |haslocaldir()| may throw errors if the tab page or window
+ cannot be found. *E5000* *E5001* *E5002*
+- |haslocaldir()| only checks for tab-local directory when -1 is passed as
+ window number, and its only possible returns values are 0 and 1.
+- `getcwd(-1)` is equivalent to `getcwd(-1, 0)` instead of returning the global
+ working directory. Use `getcwd(-1, -1)` to get the global working directory.
+
==============================================================================
5. Missing legacy features *nvim-features-missing*
diff --git a/runtime/filetype.vim b/runtime/filetype.vim
index 0de04e9774..75354968e9 100644
--- a/runtime/filetype.vim
+++ b/runtime/filetype.vim
@@ -1,7 +1,7 @@
" Vim support file to detect file types
"
" Maintainer: Bram Moolenaar <Bram@vim.org>
-" Last Change: 2021 Aug 23
+" Last Change: 2021 Oct 03
" Listen very carefully, I will say this only once
if exists("did_load_filetypes")
@@ -703,6 +703,7 @@ au BufNewFile,BufRead *.gpi setf gnuplot
" Go (Google)
au BufNewFile,BufRead *.go setf go
+au BufNewFile,BufRead Gopkg.lock setf toml
" GrADS scripts
au BufNewFile,BufRead *.gs setf grads
@@ -872,6 +873,9 @@ au BufNewFile,BufRead *.json-patch setf json
" Jupyter Notebook is also json
au BufNewFile,BufRead *.ipynb setf json
+" Other files that look like json
+au BufNewFile,BufRead .babelrc,.eslintrc,.prettierrc,.firebaserc setf json
+
" JSONC
au BufNewFile,BufRead *.jsonc setf jsonc
@@ -1106,6 +1110,9 @@ au BufNewFile,BufRead *.mysql setf mysql
" Mutt setup files (must be before catch *.rc)
au BufNewFile,BufRead */etc/Muttrc.d/* call s:StarSetf('muttrc')
+" Tcl Shell RC file
+au BufNewFile,BufRead tclsh.rc setf tcl
+
" M$ Resource files
au BufNewFile,BufRead *.rc,*.rch setf rc
@@ -1136,6 +1143,9 @@ au BufNewFile,BufRead Neomuttrc setf neomuttrc
" Netrc
au BufNewFile,BufRead .netrc setf netrc
+" Nginx
+au BufNewFile,BufRead *.nginx,nginx*.conf,*nginx.conf,*/etc/nginx/*,*/usr/local/nginx/conf/*,*/nginx/*.conf setf nginx
+
" Ninja file
au BufNewFile,BufRead *.ninja setf ninja
@@ -1274,7 +1284,7 @@ au BufNewFile,BufRead *.rcp setf pilrc
au BufNewFile,BufRead .pinerc,pinerc,.pinercex,pinercex setf pine
" Pipenv Pipfiles
-au BufNewFile,BufRead Pipfile setf config
+au BufNewFile,BufRead Pipfile setf toml
au BufNewFile,BufRead Pipfile.lock setf json
" PL/1, PL/I
@@ -1508,6 +1518,7 @@ au BufNewFile,BufRead [rR]antfile,*.rant,[rR]akefile,*.rake setf ruby
" Rust
au BufNewFile,BufRead *.rs setf rust
+au BufNewFile,BufRead Cargo.lock,*/.cargo/config,*/.cargo/credentials setf toml
" S-lang (or shader language, or SmallLisp)
au BufNewFile,BufRead *.sl setf slang
@@ -1798,7 +1809,7 @@ au BufRead,BufNewFile {pending,completed,undo}.data setf taskdata
au BufRead,BufNewFile *.task setf taskedit
" Tcl (JACL too)
-au BufNewFile,BufRead *.tcl,*.tk,*.itcl,*.itk,*.jacl setf tcl
+au BufNewFile,BufRead *.tcl,*.tm,*.tk,*.itcl,*.itk,*.jacl,.tclshrc,.wishrc setf tcl
" TealInfo
au BufNewFile,BufRead *.tli setf tli
@@ -1995,14 +2006,15 @@ au BufNewFile,BufRead *.ws[fc] setf wsh
" XHTML
au BufNewFile,BufRead *.xhtml,*.xht setf xhtml
-" X Pixmap (dynamically sets colors, use BufEnter to make it work better)
-au BufEnter *.xpm
+" X Pixmap (dynamically sets colors, this used to trigger on BufEnter to make
+" it work better, but that breaks setting 'filetype' manually)
+au BufNewFile,BufRead *.xpm
\ if getline(1) =~ "XPM2" |
\ setf xpm2 |
\ else |
\ setf xpm |
\ endif
-au BufEnter *.xpm2 setf xpm2
+au BufNewFile,BufRead *.xpm2 setf xpm2
" XFree86 config
au BufNewFile,BufRead XF86Config
@@ -2291,6 +2303,9 @@ au BufNewFile,BufRead .tcshrc* call dist#ft#SetFileTypeShell("tcsh")
" csh scripts ending in a star
au BufNewFile,BufRead .login*,.cshrc* call dist#ft#CSH()
+" tmux configuration with arbitrary extension
+au BufNewFile,BufRead {.,}tmux*.conf* setf tmux
+
" VHDL
au BufNewFile,BufRead *.vhdl_[0-9]* call s:StarSetf('vhdl')
diff --git a/runtime/ftplugin/8th.vim b/runtime/ftplugin/8th.vim
index 14301187d6..ad04f9ac84 100644
--- a/runtime/ftplugin/8th.vim
+++ b/runtime/ftplugin/8th.vim
@@ -1,9 +1,10 @@
" Vim ftplugin file
" Language: 8th
" Version: any
-" Last Change: 2015/11/08
+" Last Change: 2021 Sep 20
+" Last Change: 2021/09/20
" Maintainer: Ron Aaron <ron@aaron-tech.com>
-" URL: https://8th-dev.com/
+" URL: https://8th-dev.com/
" Filetypes: *.8th
" NOTE: 8th allows any non-whitespace in a name, so you need to do:
" setlocal iskeyword=!,@,33-35,%,$,38-64,A-Z,91-96,a-z,123-126,128-255
@@ -14,12 +15,13 @@ if exists("b:did_8thplugin")
finish
endif
-" Don't load another plugin for this buffer
+" Don't load another 8th plugin for this buffer
let b:did_8thplugin = 1
setlocal ts=2 sts=2 sw=2 et
-setlocal com=s1:/*,mb:*,ex:*/,:\|,:\\
+setlocal com=s1:/*,mb:*,ex:*/,b:--,be:\\
setlocal fo=tcrqol
setlocal matchpairs+=\::;
setlocal iskeyword=!,@,33-35,%,$,38-64,A-Z,91-96,a-z,123-126,128-255
setlocal suffixesadd=.8th
+let b:undo_ftplugin = "setlocal ts< sts< sw< et< com< fo< mps< isk< sua<"
diff --git a/runtime/ftplugin/c.vim b/runtime/ftplugin/c.vim
index 00937c2383..d4564a4aec 100644
--- a/runtime/ftplugin/c.vim
+++ b/runtime/ftplugin/c.vim
@@ -1,7 +1,7 @@
" Vim filetype plugin file
" Language: C
" Maintainer: Bram Moolenaar <Bram@vim.org>
-" Last Change: 2020 Feb 01
+" Last Change: 2021 Sep 21
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
@@ -35,8 +35,11 @@ setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
" When the matchit plugin is loaded, this makes the % command skip parens and
" braces in comments properly.
-let b:match_words = '^\s*#\s*if\(\|def\|ndef\)\>:^\s*#\s*elif\>:^\s*#\s*else\>:^\s*#\s*endif\>'
-let b:match_skip = 's:comment\|string\|character\|special'
+if !exists("b:match_words")
+ let b:match_words = '^\s*#\s*if\(\|def\|ndef\)\>:^\s*#\s*elif\>:^\s*#\s*else\>:^\s*#\s*endif\>'
+ let b:match_skip = 's:comment\|string\|character\|special'
+ let b:undo_ftplugin ..= " | unlet! b:match_skip b:match_words"
+endif
" Win32 can filter files in the browse dialog
if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
@@ -57,6 +60,7 @@ if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
\ "C++ Source Files (*.cpp *.c++)\t*.cpp;*.c++\n" .
\ "All Files (*.*)\t*.*\n"
endif
+ let b:undo_ftplugin ..= " | unlet! b:browsefilter"
endif
let b:man_default_sects = '3,2'
diff --git a/runtime/ftplugin/context.vim b/runtime/ftplugin/context.vim
index 10f1ae1648..37f7240d7b 100644
--- a/runtime/ftplugin/context.vim
+++ b/runtime/ftplugin/context.vim
@@ -2,7 +2,7 @@
" Language: ConTeXt typesetting engine
" Maintainer: Nicola Vitacolonna <nvitacolonna@gmail.com>
" Former Maintainers: Nikolai Weibull <now@bitwi.se>
-" Latest Revision: 2016 Oct 30
+" Latest Revision: 2021 Oct 15
if exists("b:did_ftplugin")
finish
@@ -17,7 +17,6 @@ if !exists('current_compiler')
endif
let b:undo_ftplugin = "setl com< cms< def< inc< sua< fo< ofu<"
- \ . "| unlet! b:match_ignorecase b:match_words b:match_skip"
setlocal comments=b:%D,b:%C,b:%M,:% commentstring=%\ %s formatoptions+=tjcroql2
if get(b:, 'context_metapost', get(g:, 'context_metapost', 1))
@@ -35,11 +34,12 @@ let &l:include = '^\s*\\\%(input\|component\|product\|project\|environment\)'
setlocal suffixesadd=.tex
-if exists("loaded_matchit")
+if exists("loaded_matchit") && !exists("b:match_words")
let b:match_ignorecase = 0
let b:match_skip = 'r:\\\@<!\%(\\\\\)*%'
let b:match_words = '(:),\[:],{:},\\(:\\),\\\[:\\],' .
\ '\\start\(\a\+\):\\stop\1'
+ let b:undo_ftplugin .= " | unlet! b:match_ignorecase b:match_words b:match_skip"
endif
let s:context_regex = {
@@ -57,19 +57,28 @@ function! s:move_around(count, what, flags, visual)
call map(range(2, a:count), 'search(s:context_regex[a:what], a:flags)')
endfunction
-" Move around macros.
-nnoremap <silent><buffer> [[ :<C-U>call <SID>move_around(v:count1, "beginsection", "bW", v:false) <CR>
-vnoremap <silent><buffer> [[ :<C-U>call <SID>move_around(v:count1, "beginsection", "bW", v:true) <CR>
-nnoremap <silent><buffer> ]] :<C-U>call <SID>move_around(v:count1, "beginsection", "W", v:false) <CR>
-vnoremap <silent><buffer> ]] :<C-U>call <SID>move_around(v:count1, "beginsection", "W", v:true) <CR>
-nnoremap <silent><buffer> [] :<C-U>call <SID>move_around(v:count1, "endsection", "bW", v:false) <CR>
-vnoremap <silent><buffer> [] :<C-U>call <SID>move_around(v:count1, "endsection", "bW", v:true) <CR>
-nnoremap <silent><buffer> ][ :<C-U>call <SID>move_around(v:count1, "endsection", "W", v:false) <CR>
-vnoremap <silent><buffer> ][ :<C-U>call <SID>move_around(v:count1, "endsection", "W", v:true) <CR>
-nnoremap <silent><buffer> [{ :<C-U>call <SID>move_around(v:count1, "beginblock", "bW", v:false) <CR>
-vnoremap <silent><buffer> [{ :<C-U>call <SID>move_around(v:count1, "beginblock", "bW", v:true) <CR>
-nnoremap <silent><buffer> ]} :<C-U>call <SID>move_around(v:count1, "endblock", "W", v:false) <CR>
-vnoremap <silent><buffer> ]} :<C-U>call <SID>move_around(v:count1, "endblock", "W", v:true) <CR>
+if !exists("no_plugin_maps") && !exists("no_context_maps")
+ " Move around macros.
+ nnoremap <silent><buffer> [[ :<C-U>call <SID>move_around(v:count1, "beginsection", "bW", v:false) <CR>
+ vnoremap <silent><buffer> [[ :<C-U>call <SID>move_around(v:count1, "beginsection", "bW", v:true) <CR>
+ nnoremap <silent><buffer> ]] :<C-U>call <SID>move_around(v:count1, "beginsection", "W", v:false) <CR>
+ vnoremap <silent><buffer> ]] :<C-U>call <SID>move_around(v:count1, "beginsection", "W", v:true) <CR>
+ nnoremap <silent><buffer> [] :<C-U>call <SID>move_around(v:count1, "endsection", "bW", v:false) <CR>
+ vnoremap <silent><buffer> [] :<C-U>call <SID>move_around(v:count1, "endsection", "bW", v:true) <CR>
+ nnoremap <silent><buffer> ][ :<C-U>call <SID>move_around(v:count1, "endsection", "W", v:false) <CR>
+ vnoremap <silent><buffer> ][ :<C-U>call <SID>move_around(v:count1, "endsection", "W", v:true) <CR>
+ nnoremap <silent><buffer> [{ :<C-U>call <SID>move_around(v:count1, "beginblock", "bW", v:false) <CR>
+ vnoremap <silent><buffer> [{ :<C-U>call <SID>move_around(v:count1, "beginblock", "bW", v:true) <CR>
+ nnoremap <silent><buffer> ]} :<C-U>call <SID>move_around(v:count1, "endblock", "W", v:false) <CR>
+ vnoremap <silent><buffer> ]} :<C-U>call <SID>move_around(v:count1, "endblock", "W", v:true) <CR>
+
+ let b:undo_ftplugin .= " | sil! exe 'nunmap <buffer> [[' | sil! exe 'vunmap <buffer> [['" .
+ \ " | sil! exe 'nunmap <buffer> ]]' | sil! exe 'vunmap <buffer> ]]'" .
+ \ " | sil! exe 'nunmap <buffer> []' | sil! exe 'vunmap <buffer> []'" .
+ \ " | sil! exe 'nunmap <buffer> ][' | sil! exe 'vunmap <buffer> ]['" .
+ \ " | sil! exe 'nunmap <buffer> [{' | sil! exe 'vunmap <buffer> [{'" .
+ \ " | sil! exe 'nunmap <buffer> ]}' | sil! exe 'vunmap <buffer> ]}'"
+end
" Other useful mappings
if get(g:, 'context_mappings', 1)
@@ -81,16 +90,22 @@ if get(g:, 'context_mappings', 1)
call cursor(search(s:tp_regex, 'W') - 1, 1)
endf
- " Reflow paragraphs with commands like gqtp ("gq TeX paragraph")
- onoremap <silent><buffer> tp :<c-u>call <sid>tp()<cr>
- " Select TeX paragraph
- vnoremap <silent><buffer> tp <esc>:<c-u>call <sid>tp()<cr>
-
- " $...$ text object
- onoremap <silent><buffer> i$ :<c-u>normal! T$vt$<cr>
- onoremap <silent><buffer> a$ :<c-u>normal! F$vf$<cr>
- vnoremap <buffer> i$ T$ot$
- vnoremap <buffer> a$ F$of$
+ if !exists("no_plugin_maps") && !exists("no_context_maps")
+ " Reflow paragraphs with commands like gqtp ("gq TeX paragraph")
+ onoremap <silent><buffer> tp :<c-u>call <sid>tp()<cr>
+ " Select TeX paragraph
+ vnoremap <silent><buffer> tp <esc>:<c-u>call <sid>tp()<cr>
+
+ " $...$ text object
+ onoremap <silent><buffer> i$ :<c-u>normal! T$vt$<cr>
+ onoremap <silent><buffer> a$ :<c-u>normal! F$vf$<cr>
+ vnoremap <buffer> i$ T$ot$
+ vnoremap <buffer> a$ F$of$
+
+ let b:undo_ftplugin .= " | sil! exe 'ounmap <buffer> tp' | sil! exe 'vunmap <buffer> tp'" .
+ \ " | sil! exe 'ounmap <buffer> i$' | sil! exe 'vunmap <buffer> i$'" .
+ \ " | sil! exe 'ounmap <buffer> a$' | sil! exe 'vunmap <buffer> a$'"
+ endif
endif
" Commands for asynchronous typesetting
diff --git a/runtime/ftplugin/csh.vim b/runtime/ftplugin/csh.vim
index 4ae09f91be..929823219c 100644
--- a/runtime/ftplugin/csh.vim
+++ b/runtime/ftplugin/csh.vim
@@ -1,21 +1,23 @@
" Vim filetype plugin file
-" Language: csh
-" Maintainer: Dan Sharp <dwsharp at users dot sourceforge dot net>
-" Last Changed: 20 Jan 2009
-" URL: http://dwsharp.users.sourceforge.net/vim/ftplugin
+" Language: csh
+" Maintainer: Doug Kearns <dougkearns@gmail.com>
+" Previous Maintainer: Dan Sharp <dwsharp at users dot sourceforge dot net>
+" Contributor: Johannes Zellner <johannes@zellner.org>
+" Last Change: 2021 Oct 15
if exists("b:did_ftplugin") | finish | endif
let b:did_ftplugin = 1
-" Make sure the continuation lines below do not cause problems in
-" compatibility mode.
let s:save_cpo = &cpo
set cpo-=C
+setlocal comments=:#
setlocal commentstring=#%s
setlocal formatoptions-=t
setlocal formatoptions+=crql
+let b:undo_ftplugin = "setlocal com< cms< fo<"
+
" Csh: thanks to Johannes Zellner
" - Both foreach and end must appear alone on separate lines.
" - The words else and endif must appear at the beginning of input lines;
@@ -23,26 +25,27 @@ setlocal formatoptions+=crql
" - Each case label and the default label must appear at the start of a
" line.
" - while and end must appear alone on their input lines.
-if exists("loaded_matchit")
- let b:match_words =
- \ '^\s*\<if\>.*(.*).*\<then\>:'.
- \ '^\s*\<else\>\s\+\<if\>.*(.*).*\<then\>:^\s*\<else\>:'.
- \ '^\s*\<endif\>,'.
- \ '\%(^\s*\<foreach\>\s\+\S\+\|^s*\<while\>\).*(.*):'.
- \ '\<break\>:\<continue\>:^\s*\<end\>,'.
- \ '^\s*\<switch\>.*(.*):^\s*\<case\>\s\+:^\s*\<default\>:^\s*\<endsw\>'
+if exists("loaded_matchit") && !exists("b:match_words")
+ let s:line_start = '\%(^\s*\)\@<='
+ let b:match_words =
+ \ s:line_start .. 'if\s*(.*)\s*then\>:' ..
+ \ s:line_start .. 'else\s\+if\s*(.*)\s*then\>:' .. s:line_start .. 'else\>:' ..
+ \ s:line_start .. 'endif\>,' ..
+ \ s:line_start .. '\%(\<foreach\s\+\h\w*\|while\)\s*(:' ..
+ \ '\<break\>:\<continue\>:' ..
+ \ s:line_start .. 'end\>,' ..
+ \ s:line_start .. 'switch\s*(:' ..
+ \ s:line_start .. 'case\s\+:' .. s:line_start .. 'default\>:\<breaksw\>:' ..
+ \ s:line_start .. 'endsw\>'
+ unlet s:line_start
+ let b:undo_ftplugin ..= " | unlet b:match_words"
endif
-" Change the :browse e filter to primarily show csh-related files.
-if has("gui_win32")
- let b:browsefilter="csh Scripts (*.csh)\t*.csh\n" .
- \ "All Files (*.*)\t*.*\n"
+if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
+ let b:browsefilter="csh Scripts (*.csh)\t*.csh\n" ..
+ \ "All Files (*.*)\t*.*\n"
+ let b:undo_ftplugin ..= " | unlet b:browsefilter"
endif
-" Undo the stuff we changed.
-let b:undo_ftplugin = "setlocal commentstring< formatoptions<" .
- \ " | unlet! b:match_words b:browsefilter"
-
-" Restore the saved compatibility options.
let &cpo = s:save_cpo
unlet s:save_cpo
diff --git a/runtime/ftplugin/gprof.vim b/runtime/ftplugin/gprof.vim
index d4547ae9a6..d8974bcc84 100644
--- a/runtime/ftplugin/gprof.vim
+++ b/runtime/ftplugin/gprof.vim
@@ -1,6 +1,7 @@
-" Language: gprof
-" Maintainer: Dominique Pelle <dominique.pelle@gmail.com>
-" Last Change: 2021 Apr 08
+" Language: gprof
+" Maintainer: Dominique Pelle <dominique.pelle@gmail.com>
+" Contributors: Doug Kearns <dougkearns@gmail.com>
+" Last Change: 2021 Sep 19
" When cursor is on one line of the gprof call graph,
" calling this function jumps to this function in the call graph.
@@ -9,7 +10,7 @@ if exists("b:did_ftplugin")
endif
let b:did_ftplugin=1
-fun! <SID>GprofJumpToFunctionIndex()
+func! <SID>GprofJumpToFunctionIndex()
let l:line = getline('.')
if l:line =~ '[\d\+\]$'
" We're in a line in the call graph.
@@ -22,11 +23,14 @@ fun! <SID>GprofJumpToFunctionIndex()
call search('^\[\d\+\].*\d\s\+' . escape(@", '[]*.') . '\>', 'sW')
norm! zz
endif
-endfun
+endfunc
-" Pressing <C-]> on a line in the gprof flat profile or in
-" the call graph, jumps to the corresponding function inside
-" the flat profile.
-map <buffer> <silent> <C-]> :call <SID>GprofJumpToFunctionIndex()<CR>
+if !exists("no_plugin_maps") && !exists("no_gprof_maps")
+ " Pressing <C-]> on a line in the gprof flat profile or in
+ " the call graph, jumps to the corresponding function inside
+ " the flat profile.
+ map <buffer> <silent> <C-]> :call <SID>GprofJumpToFunctionIndex()<CR>
+ let b:undo_ftplugin = "silent! unmap <buffer> <C-]>"
+endif
" vim:sw=2 fdm=indent
diff --git a/runtime/ftplugin/nginx.vim b/runtime/ftplugin/nginx.vim
new file mode 100644
index 0000000000..e808db1277
--- /dev/null
+++ b/runtime/ftplugin/nginx.vim
@@ -0,0 +1,6 @@
+" Vim filetype plugin
+" Language: nginx.conf
+" Maintainer: Chris Aumann <me@chr4.org>
+" Last Change: Apr 15, 2017
+
+setlocal commentstring=#\ %s
diff --git a/runtime/ftplugin/spec.vim b/runtime/ftplugin/spec.vim
index ce00021a69..75eebec56a 100644
--- a/runtime/ftplugin/spec.vim
+++ b/runtime/ftplugin/spec.vim
@@ -18,8 +18,8 @@ if !exists("no_plugin_maps") && !exists("no_spec_maps")
endif
endif
-if !hasmapto("call <SID>SpecChangelog(\"\")<CR>")
- noremap <buffer> <unique> <script> <Plug>SpecChangelog :call <SID>SpecChangelog("")<CR>
+if !hasmapto("call SpecChangelog(\"\")<CR>")
+ noremap <buffer> <unique> <script> <Plug>SpecChangelog :call SpecChangelog("")<CR>
endif
if !exists("*s:GetRelVer")
diff --git a/runtime/ftplugin/tcsh.vim b/runtime/ftplugin/tcsh.vim
index 7e2d959932..33f1aabf68 100644
--- a/runtime/ftplugin/tcsh.vim
+++ b/runtime/ftplugin/tcsh.vim
@@ -1,19 +1,17 @@
" Vim filetype plugin file
-" Language: tcsh
-" Maintainer: Dan Sharp <dwsharp at users dot sourceforge dot net>
-" Last Changed: 20 Jan 2009
-" URL: http://dwsharp.users.sourceforge.net/vim/ftplugin
+" Language: tcsh
+" Maintainer: Doug Kearns <dougkearns@gmail.com>
+" Previous Maintainer: Dan Sharp <dwsharp at users dot sourceforge dot net>
+" Last Change: 2021 Oct 15
if exists("b:did_ftplugin") | finish | endif
-" Make sure the continuation lines below do not cause problems in
-" compatibility mode.
let s:save_cpo = &cpo
set cpo-=C
" Define some defaults in case the included ftplugins don't set them.
let s:undo_ftplugin = ""
-let s:browsefilter = "csh Files (*.csh)\t*.csh\n" .
+let s:browsefilter = "csh Files (*.csh)\t*.csh\n" ..
\ "All Files (*.*)\t*.*\n"
runtime! ftplugin/csh.vim ftplugin/csh_*.vim ftplugin/csh/*.vim
@@ -27,14 +25,11 @@ if exists("b:browsefilter")
let s:browsefilter = b:browsefilter
endif
-" Change the :browse e filter to primarily show tcsh-related files.
-if has("gui_win32")
- let b:browsefilter="tcsh Scripts (*.tcsh)\t*.tcsh\n" . s:browsefilter
+if (has("gui_win32") || has("gui_gtk"))
+ let b:browsefilter="tcsh Scripts (*.tcsh)\t*.tcsh\n" .. s:browsefilter
endif
-" Undo the stuff we changed.
-let b:undo_ftplugin = "unlet! b:browsefilter | " . s:undo_ftplugin
+let b:undo_ftplugin = "unlet! b:browsefilter | " .. s:undo_ftplugin
-" Restore the saved compatibility options.
let &cpo = s:save_cpo
unlet s:save_cpo
diff --git a/runtime/ftplugin/tmux.vim b/runtime/ftplugin/tmux.vim
index ed9154924b..5c3461fefb 100644
--- a/runtime/ftplugin/tmux.vim
+++ b/runtime/ftplugin/tmux.vim
@@ -9,4 +9,7 @@ if exists("b:did_ftplugin")
endif
let b:did_ftplugin = 1
+let b:undo_ftplugin = "setlocal comments< commentstring<"
+
+setlocal comments=:#
setlocal commentstring=#\ %s
diff --git a/runtime/ftplugin/toml.vim b/runtime/ftplugin/toml.vim
new file mode 100644
index 0000000000..1ef09a16e3
--- /dev/null
+++ b/runtime/ftplugin/toml.vim
@@ -0,0 +1,23 @@
+" Vim filetype plugin
+" Language: TOML
+" Homepage: https://github.com/cespare/vim-toml
+" Maintainer: Aman Verma
+" Author: Kevin Ballard <kevin@sb.org>
+" Last Change: Sep 21, 2021
+
+if exists('b:did_ftplugin')
+ finish
+endif
+let b:did_ftplugin = 1
+
+let s:save_cpo = &cpo
+set cpo&vim
+let b:undo_ftplugin = 'setlocal commentstring< comments<'
+
+setlocal commentstring=#\ %s
+setlocal comments=:#
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+" vim: et sw=2 sts=2
diff --git a/runtime/indent/cdl.vim b/runtime/indent/cdl.vim
index fb4fe27310..0e3c6152b0 100644
--- a/runtime/indent/cdl.vim
+++ b/runtime/indent/cdl.vim
@@ -1,5 +1,6 @@
" Description: Comshare Dimension Definition Language (CDL)
-" Author: Raul Segura Acevedo <raulseguraaceved@netscape.net>
+" Maintainer: Raul Segura Acevedo <raulseguraaceved@netscape.net> (Invalid email address)
+" Doug Kearns <dougkearns@gmail.com>
" Last Change: Fri Nov 30 13:35:48 2001 CST
if exists("b:did_indent")
diff --git a/runtime/indent/cobol.vim b/runtime/indent/cobol.vim
index 590a729df4..01f7212602 100644
--- a/runtime/indent/cobol.vim
+++ b/runtime/indent/cobol.vim
@@ -7,6 +7,7 @@
" Ankit Jain 22.03.2019 Changes & fixes:
" Allow chars in 1st 6 columns
" #C22032019
+" Ankit Jain 24.09.2021 add b:undo_indent (request by tpope)
if exists("b:did_indent")
finish
@@ -18,6 +19,8 @@ setlocal indentexpr=GetCobolIndent(v:lnum)
setlocal indentkeys&
setlocal indentkeys+=0<*>,0/,0$,0=01,=~division,=~section,0=~end,0=~then,0=~else,0=~when,*<Return>,.
+let b:undo_indent = "setlocal expandtab< indentexpr< indentkeys<"
+
" Only define the function once.
if exists("*GetCobolIndent")
finish
diff --git a/runtime/indent/config.vim b/runtime/indent/config.vim
index c987a78d64..b840b1e391 100644
--- a/runtime/indent/config.vim
+++ b/runtime/indent/config.vim
@@ -1,9 +1,10 @@
" Vim indent file
-" Language: Autoconf configure.{ac,in} file
-" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
-" Latest Revision: 2006-12-20
-" TODO: how about nested [()]'s in one line
-" what's wrong with '\\\@!'?
+" Language: Autoconf configure.{ac,in} file
+" Maintainer: Doug Kearns <dougkearns@gmail.com>
+" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
+" Last Change: 24 Sep 2021
+
+" TODO: how about nested [()]'s in one line what's wrong with '\\\@!'?
" Only load this indent file when no other was loaded.
if exists("b:did_indent")
@@ -16,6 +17,8 @@ setlocal indentexpr=GetConfigIndent()
setlocal indentkeys=!^F,o,O,=then,=do,=else,=elif,=esac,=fi,=fin,=fil,=done
setlocal nosmartindent
+let b:undo_indent = "setl inde< indk< si<"
+
" Only define the function once.
if exists("*GetConfigIndent")
finish
diff --git a/runtime/indent/css.vim b/runtime/indent/css.vim
index 4d15b8d2dc..793f05820f 100644
--- a/runtime/indent/css.vim
+++ b/runtime/indent/css.vim
@@ -1,8 +1,10 @@
" Vim indent file
-" Language: CSS
-" Maintainer: Nikolai Weibull <now@bitwi.se>
-" Latest Revision: 2012-05-30
-" Use of shiftwidth() added by Oleg Zubchenko.
+" Language: CSS
+" Maintainer: Doug Kearns <dougkearns@gmail.com>
+" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
+" Last Change: 24 Sep 2021
+
+" Use of shiftwidth() added by Oleg Zubchenko.
if exists("b:did_indent")
finish
@@ -13,7 +15,7 @@ setlocal indentexpr=GetCSSIndent()
setlocal indentkeys=0{,0},!^F,o,O
setlocal nosmartindent
-let b:undo_indent = "setl smartindent< indentkeys< indentexpr<"
+let b:undo_indent = "setl inde< indk< si<"
if exists("*GetCSSIndent")
finish
diff --git a/runtime/indent/d.vim b/runtime/indent/d.vim
index b5dd5e8fa7..57f9125890 100644
--- a/runtime/indent/d.vim
+++ b/runtime/indent/d.vim
@@ -1,7 +1,7 @@
" Vim indent file for the D programming language (version 0.137).
-"
" Language: D
-" Maintainer: Jason Mills<jmills@cs.mun.ca>
+" Maintainer: Jason Mills <jmills@cs.mun.ca> (Invalid email address)
+" Doug Kearns <dougkearns@gmail.com>
" Last Change: 2005 Nov 22
" Version: 0.1
"
diff --git a/runtime/indent/dtd.vim b/runtime/indent/dtd.vim
index 30c06aa8b2..c2b3c0c58e 100644
--- a/runtime/indent/dtd.vim
+++ b/runtime/indent/dtd.vim
@@ -1,12 +1,15 @@
" Vim indent file
-" Language: DTD (Document Type Definition for XML)
-" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
-" Latest Revision: 2011-07-08
+" Language: DTD (Document Type Definition for XML)
+" Maintainer: Doug Kearns <dougkearns@gmail.com>
+" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
+" Last Change: 24 Sep 2021
setlocal indentexpr=GetDTDIndent()
setlocal indentkeys=!^F,o,O,>
setlocal nosmartindent
+let b:undo_indent = "setl inde< indk< si<"
+
if exists("*GetDTDIndent")
finish
endif
diff --git a/runtime/indent/dylan.vim b/runtime/indent/dylan.vim
index 6811ec4af5..55255ddfa9 100644
--- a/runtime/indent/dylan.vim
+++ b/runtime/indent/dylan.vim
@@ -1,8 +1,9 @@
" Vim indent file
" Language: Dylan
+" Maintainer: Brent A. Fulgham <bfulgham@debian.org> (Invalid email address)
+" Doug Kearns <dougkearns@gmail.com>
" Version: 0.01
" Last Change: 2017 Jun 13
-" Maintainer: Brent A. Fulgham <bfulgham@debian.org>
" Only load this indent file when no other was loaded.
if exists("b:did_indent")
diff --git a/runtime/indent/elm.vim b/runtime/indent/elm.vim
index 232c347c66..7b08de7126 100644
--- a/runtime/indent/elm.vim
+++ b/runtime/indent/elm.vim
@@ -4,7 +4,7 @@
" Original Author: Joseph Hager <ajhager@gmail.com>
" Copyright: Joseph Hager <ajhager@gmail.com>
" License: BSD3
-" Latest Revision: 2020-05-29
+" Latest Revision: 2021-09-29
" Only load this indent file when no other was loaded.
if exists('b:did_indent')
@@ -19,6 +19,8 @@ setlocal indentkeys+=0=else,0=if,0=of,0=import,0=then,0=type,0\|,0},0\],0),=-},0
setlocal nolisp
setlocal nosmartindent
+let b:undo_indent = "setl et< inde< indk< lisp< si<"
+
" Only define the function once.
if exists('*GetElmIndent')
finish
diff --git a/runtime/indent/eterm.vim b/runtime/indent/eterm.vim
index 8ee342fcfa..3accf9bff1 100644
--- a/runtime/indent/eterm.vim
+++ b/runtime/indent/eterm.vim
@@ -1,7 +1,8 @@
" Vim indent file
-" Language: Eterm configuration file
-" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
-" Latest Revision: 2006-12-20
+" Language: Eterm configuration file
+" Maintainer: Doug Kearns <dougkearns@gmail.com>
+" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
+" Last Change: 24 Sep 2021
if exists("b:did_indent")
finish
@@ -12,6 +13,8 @@ setlocal indentexpr=GetEtermIndent()
setlocal indentkeys=!^F,o,O,=end
setlocal nosmartindent
+let b:undo_indent = "setl inde< indk< si<"
+
if exists("*GetEtermIndent")
finish
endif
diff --git a/runtime/indent/framescript.vim b/runtime/indent/framescript.vim
index f9a274eab6..4611d34e85 100644
--- a/runtime/indent/framescript.vim
+++ b/runtime/indent/framescript.vim
@@ -1,7 +1,8 @@
" Vim indent file
-" Language: FrameScript
-" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
-" Latest Revision: 2008-07-19
+" Language: FrameScript
+" Maintainer: Doug Kearns <dougkearns@gmail.com>
+" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
+" Last Change: 24 Sep 2021
if exists("b:did_indent")
finish
@@ -12,6 +13,8 @@ setlocal indentexpr=GetFrameScriptIndent()
setlocal indentkeys=!^F,o,O,0=~Else,0=~EndIf,0=~EndLoop,0=~EndSub
setlocal nosmartindent
+let b:undo_indent = "setl inde< indk< si<"
+
if exists("*GetFrameScriptIndent")
finish
endif
diff --git a/runtime/indent/hamster.vim b/runtime/indent/hamster.vim
index b27a173924..ae5c3fdedd 100644
--- a/runtime/indent/hamster.vim
+++ b/runtime/indent/hamster.vim
@@ -1,8 +1,14 @@
" Vim indent file
" Language: Hamster Script
-" Version: 2.0.6.0
-" Last Change: Wed Nov 08 2006 12:02:42 PM
-" Maintainer: David Fishburn <fishburn@ianywhere.com>
+" Version: 2.0.6.1
+" Last Change: 2021 Oct 11
+" Maintainer: David Fishburn <dfishburn dot vim at gmail dot com>
+" Download: https://www.vim.org/scripts/script.php?script_id=1099
+"
+" 2.0.6.1 (Oct 2021)
+" Added b:undo_indent
+" Added cpo check
+"
" Only load this indent file when no other was loaded.
if exists("b:did_indent")
@@ -14,12 +20,17 @@ setlocal indentkeys+==~if,=~else,=~endif,=~endfor,=~endwhile
setlocal indentkeys+==~do,=~until,=~while,=~repeat,=~for,=~loop
setlocal indentkeys+==~sub,=~endsub
+let b:undo_indent = "setl indentkeys<"
+
" Define the appropriate indent function but only once
setlocal indentexpr=HamGetFreeIndent()
if exists("*HamGetFreeIndent")
finish
endif
+let s:keepcpo = &cpo
+set cpo&vim
+
function HamGetIndent(lnum)
let ind = indent(a:lnum)
let prevline=getline(a:lnum)
@@ -52,4 +63,8 @@ function HamGetFreeIndent()
return ind
endfunction
+" Restore:
+let &cpo = s:keepcpo
+unlet s:keepcpo
+
" vim:sw=2 tw=80
diff --git a/runtime/indent/idlang.vim b/runtime/indent/idlang.vim
index 7402e8688e..e6a1d73775 100644
--- a/runtime/indent/idlang.vim
+++ b/runtime/indent/idlang.vim
@@ -1,7 +1,8 @@
" IDL (Interactive Data Language) indent file.
-" Language: IDL (ft=idlang)
+" Language: IDL (ft=idlang)
+" Maintainer: Aleksandar Jelenak <ajelenak AT yahoo.com> (Invalid email address)
+" Doug Kearns <dougkearns@gmail.com>
" Last change: 2017 Jun 13
-" Maintainer: Aleksandar Jelenak <ajelenak AT yahoo.com>
" Only load this indent file when no other was loaded.
if exists("b:did_indent")
diff --git a/runtime/indent/ld.vim b/runtime/indent/ld.vim
index a72a3a9548..ddf003e2de 100644
--- a/runtime/indent/ld.vim
+++ b/runtime/indent/ld.vim
@@ -1,7 +1,8 @@
" Vim indent file
-" Language: ld(1) script
-" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
-" Latest Revision: 2006-12-20
+" Language: ld(1) script
+" Maintainer: Doug Kearns <dougkearns@gmail.com>
+" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
+" Last Change: 24 Sep 2021
if exists("b:did_indent")
finish
@@ -12,6 +13,8 @@ setlocal indentexpr=GetLDIndent()
setlocal indentkeys=0{,0},!^F,o,O
setlocal nosmartindent
+let b:undo_indent = "setl inde< indk< si<"
+
if exists("*GetLDIndent")
finish
endif
diff --git a/runtime/indent/mail.vim b/runtime/indent/mail.vim
index 6246b407e9..22bb0f7e12 100644
--- a/runtime/indent/mail.vim
+++ b/runtime/indent/mail.vim
@@ -1,7 +1,7 @@
" Vim indent file
" Language: Mail
" Maintainer: Bram Moolenaar
-" Last Change: 2009 Jun 03
+" Last Change: 2021 Sep 26
if exists("b:did_indent")
finish
@@ -11,3 +11,5 @@ let b:did_indent = 1
" What works best is auto-indenting, disable other indenting.
" For formatting see the ftplugin.
setlocal autoindent nosmartindent nocindent indentexpr=
+
+let b:undo_indent = "setl ai< cin< inde< si<"
diff --git a/runtime/indent/make.vim b/runtime/indent/make.vim
index 4483efdbd8..76c8f83399 100644
--- a/runtime/indent/make.vim
+++ b/runtime/indent/make.vim
@@ -1,7 +1,8 @@
" Vim indent file
-" Language: Makefile
-" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
-" Latest Revision: 2007-05-07
+" Language: Makefile
+" Maintainer: Doug Kearns <dougkearns@gmail.com>
+" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
+" Last Change: 24 Sep 2021
if exists("b:did_indent")
finish
@@ -12,6 +13,8 @@ setlocal indentexpr=GetMakeIndent()
setlocal indentkeys=!^F,o,O,<:>,=else,=endif
setlocal nosmartindent
+let b:undo_indent = "setl ai< inde< indk<"
+
if exists("*GetMakeIndent")
finish
endif
diff --git a/runtime/indent/matlab.vim b/runtime/indent/matlab.vim
index 6390445c60..10d84602af 100644
--- a/runtime/indent/matlab.vim
+++ b/runtime/indent/matlab.vim
@@ -2,6 +2,7 @@
" Language: MATLAB
" Maintainer: Axel Forsman <axelsfor@gmail.com>
" Previous maintainer: Christophe Poucet <christophe.poucet@pandora.be>
+" Last Update: 2021-10-01
" Only load if no other indent file is loaded
if exists('b:did_indent') | finish | endif
@@ -9,6 +10,7 @@ let b:did_indent = 1
setlocal indentexpr=GetMatlabIndent()
setlocal indentkeys=!,o,O,e,0=end,0=elseif,0=case,0=otherwise,0=catch,0=function,0=elsei
+let b:undo_indent = "setlocal indentexpr< indentkeys<"
" The value of the Function indenting format in
" MATLAB Editor/Debugger Language Preferences.
diff --git a/runtime/indent/mma.vim b/runtime/indent/mma.vim
index a76fa8ede0..ebf98b9a38 100644
--- a/runtime/indent/mma.vim
+++ b/runtime/indent/mma.vim
@@ -1,9 +1,10 @@
" Vim indent file
-" Language: Mathematica
-" Author: steve layland <layland@wolfram.com>
-" Last Change: Sat May 10 18:56:22 CDT 2005
-" Source: http://vim.sourceforge.net/scripts/script.php?script_id=1274
-" http://members.wolfram.com/layland/vim/indent/mma.vim
+" Language: Mathematica
+" Maintainer: Steve Layland <layland@wolfram.com> (Invalid email address)
+" Doug Kearns <dougkearns@gmail.com>
+" Last Change: Sat May 10 18:56:22 CDT 2005
+" Source: http://vim.sourceforge.net/scripts/script.php?script_id=1274
+" http://members.wolfram.com/layland/vim/indent/mma.vim
"
" NOTE:
" Empty .m files will automatically be presumed to be Matlab files
diff --git a/runtime/indent/nginx.vim b/runtime/indent/nginx.vim
new file mode 100644
index 0000000000..d4afec1c11
--- /dev/null
+++ b/runtime/indent/nginx.vim
@@ -0,0 +1,17 @@
+" Vim indent file
+" Language: nginx.conf
+" Maintainer: Chris Aumann <me@chr4.org>
+" Last Change: Apr 15, 2017
+
+if exists("b:did_indent")
+ finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=
+
+" cindent actually works for nginx' simple file structure
+setlocal cindent
+
+" Just make sure that the comments are not reset as defs would be.
+setlocal cinkeys-=0#
diff --git a/runtime/indent/occam.vim b/runtime/indent/occam.vim
index 4acd42e3c8..2979ac16ac 100644
--- a/runtime/indent/occam.vim
+++ b/runtime/indent/occam.vim
@@ -1,6 +1,7 @@
" Vim indent file
" Language: occam
-" Maintainer: Mario Schweigler <ms44@kent.ac.uk>
+" Maintainer: Mario Schweigler <ms44@kent.ac.uk> (Invalid email address)
+" Doug Kearns <dougkearns@gmail.com>
" Last Change: 23 April 2003
" Only load this indent file when no other was loaded.
diff --git a/runtime/indent/pascal.vim b/runtime/indent/pascal.vim
index 1f39fd1cad..b21b7256b2 100644
--- a/runtime/indent/pascal.vim
+++ b/runtime/indent/pascal.vim
@@ -2,11 +2,9 @@
" Language: Pascal
" Maintainer: Neil Carter <n.carter@swansea.ac.uk>
" Created: 2004 Jul 13
-" Last Change: 2021 Jul 01
+" Last Change: 2021 Sep 22
"
-" This is version 2.0, a complete rewrite.
-"
-" For further documentation, see http://psy.swansea.ac.uk/staff/carter/vim/
+" For further documentation, see https://psy.swansea.ac.uk/staff/carter/vim/
if exists("b:did_indent")
@@ -20,13 +18,14 @@ setlocal indentkeys+==end;,==const,==type,==var,==begin,==repeat,==until,==for
setlocal indentkeys+==program,==function,==procedure,==object,==private
setlocal indentkeys+==record,==if,==else,==case
-let b:undo_indent = "setl indentkeys< indentexpr<"
+let b:undo_indent = 'setlocal indentexpr< indentkeys<'
if exists("*GetPascalIndent")
finish
endif
+" ________________________________________________________________
function! s:GetPrevNonCommentLineNum( line_num )
" Skip lines starting with a comment
@@ -44,6 +43,7 @@ function! s:GetPrevNonCommentLineNum( line_num )
endfunction
+" ________________________________________________________________
function! s:PurifyCode( line_num )
" Strip any trailing comments and whitespace
let pureline = 'TODO'
@@ -51,6 +51,7 @@ function! s:PurifyCode( line_num )
endfunction
+" ________________________________________________________________
function! GetPascalIndent( line_num )
" Line 0 always goes at column 0
@@ -184,7 +185,7 @@ function! GetPascalIndent( line_num )
endif
-" ____________________________________________________________________
+" ________________________________________________________________
" Object/Borland Pascal/Delphi Extensions
"
" Note that extended-pascal is handled here, unless it is simpler to
@@ -222,8 +223,6 @@ function! GetPascalIndent( line_num )
endif
-" ____________________________________________________________________
-
" If nothing changed, return same indent.
return indnt
endfunction
diff --git a/runtime/indent/postscr.vim b/runtime/indent/postscr.vim
index 2592bcf62f..0691cd237c 100644
--- a/runtime/indent/postscr.vim
+++ b/runtime/indent/postscr.vim
@@ -1,7 +1,8 @@
" PostScript indent file
-" Language: PostScript
-" Maintainer: Mike Williams <mrw@netcomuk.co.uk>
-" Last Change: 2nd July 2001
+" Language: PostScript
+" Maintainer: Mike Williams <mrw@netcomuk.co.uk> (Invalid email address)
+" Doug Kearns <dougkearns@gmail.com>
+" Last Change: 2nd July 2001
"
" Only load this indent file when no other was loaded.
diff --git a/runtime/indent/prolog.vim b/runtime/indent/prolog.vim
index ecd0894166..ac03c28064 100644
--- a/runtime/indent/prolog.vim
+++ b/runtime/indent/prolog.vim
@@ -1,7 +1,8 @@
" vim: set sw=4 sts=4:
-" Maintainer : Gergely Kontra <kgergely@mcl.hu>
-" Revised on : 2002.02.18. 23:34:05
-" Language : Prolog
+" Language: Prolog
+" Maintainer: Gergely Kontra <kgergely@mcl.hu> (Invalid email address)
+" Doug Kearns <dougkearns@gmail.com>
+" Revised on: 2002.02.18. 23:34:05
" Last change by: Takuya Fujiwara, 2018 Sep 23
" TODO:
diff --git a/runtime/indent/python.vim b/runtime/indent/python.vim
index 307b7f656b..668122993e 100644
--- a/runtime/indent/python.vim
+++ b/runtime/indent/python.vim
@@ -2,7 +2,7 @@
" Language: Python
" Maintainer: Bram Moolenaar <Bram@vim.org>
" Original Author: David Bustos <bustos@caltech.edu>
-" Last Change: 2021 May 26
+" Last Change: 2021 Sep 26
" Only load this indent file when no other was loaded.
if exists("b:did_indent")
@@ -17,6 +17,8 @@ setlocal autoindent " indentexpr isn't much help otherwise
setlocal indentexpr=GetPythonIndent(v:lnum)
setlocal indentkeys+=<:>,=elif,=except
+let b:undo_indent = "setl ai< inde< indk< lisp<"
+
" Only define the function once.
if exists("*GetPythonIndent")
finish
diff --git a/runtime/indent/readline.vim b/runtime/indent/readline.vim
index e202ddfd89..0ab0f822c3 100644
--- a/runtime/indent/readline.vim
+++ b/runtime/indent/readline.vim
@@ -1,7 +1,8 @@
" Vim indent file
-" Language: readline configuration file
-" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
-" Latest Revision: 2006-12-20
+" Language: readline configuration file
+" Maintainer: Doug Kearns <dougkearns@gmail.com>
+" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
+" Last Change: 24 Sep 2021
if exists("b:did_indent")
finish
@@ -12,6 +13,8 @@ setlocal indentexpr=GetReadlineIndent()
setlocal indentkeys=!^F,o,O,=$else,=$endif
setlocal nosmartindent
+let b:undo_indent = "setl inde< indk< si<"
+
if exists("*GetReadlineIndent")
finish
endif
diff --git a/runtime/indent/sdl.vim b/runtime/indent/sdl.vim
index 6ce30b6797..40fe63fa7c 100644
--- a/runtime/indent/sdl.vim
+++ b/runtime/indent/sdl.vim
@@ -1,7 +1,7 @@
" Vim indent file
" Language: SDL
" Maintainer: Michael Piefel <entwurf@piefel.de>
-" Last Change: 10 December 2011
+" Last Change: 2021 Oct 03
" Shamelessly stolen from the Vim-Script indent file
@@ -14,6 +14,8 @@ let b:did_indent = 1
setlocal indentexpr=GetSDLIndent()
setlocal indentkeys+==~end,=~state,*<Return>
+let b:undo_indent = "setl inde< indk<"
+
" Only define the function once.
if exists("*GetSDLIndent")
" finish
diff --git a/runtime/indent/sqlanywhere.vim b/runtime/indent/sqlanywhere.vim
index d39fa3240e..4772b5951b 100644
--- a/runtime/indent/sqlanywhere.vim
+++ b/runtime/indent/sqlanywhere.vim
@@ -1,9 +1,8 @@
" Vim indent file
" Language: SQL
" Maintainer: David Fishburn <dfishburn dot vim at gmail dot com>
-" Last Change By Maintainer: 2017 Jun 13
-" Last Change: by Stephen Wall, #5578, 2020 Jun 07
-" Version: 3.0
+" Last Change: 2021 Oct 11
+" Version: 4.0
" Download: http://vim.sourceforge.net/script.php?script_id=495
" Notes:
@@ -21,6 +20,9 @@
" it, this can leave the indent hanging to the right one too many.
"
" History:
+" 4.0 (Oct 2021)
+" Added b:undo_indent
+"
" 3.0 (Dec 2012)
" Added cpo check
"
@@ -56,10 +58,13 @@ setlocal indentkeys+==~end,=~else,=~elseif,=~elsif,0=~when,0=)
" in the indentkeys is typed
setlocal indentexpr=GetSQLIndent()
+let b:undo_indent = "setl indentexpr< indentkeys<"
+
" Only define the functions once.
if exists("*GetSQLIndent")
finish
endif
+
let s:keepcpo= &cpo
set cpo&vim
@@ -68,14 +73,9 @@ set cpo&vim
" IS is excluded, since it is difficult to determine when the
" ending block is (especially for procedures/functions).
let s:SQLBlockStart = '^\s*\%('.
- \ 'if\>.*\<then\|'.
- \ 'then\|else\>\|'.
- \ 'elseif\>.*\<then\|'.
- \ 'elsif\>.(\<then\|'.
- \ 'while\>.*\<loop\|'.
- \ 'for\>.*\<loop\|'.
- \ 'foreach\>.*\<loop\|'.
- \ 'loop\|do\|declare\|begin\|'.
+ \ 'if\|else\|elseif\|elsif\|'.
+ \ 'while\|loop\|do\|for\|'.
+ \ 'begin\|'.
\ 'case\|when\|merge\|exception'.
\ '\)\>'
let s:SQLBlockEnd = '^\s*\(end\)\>'
diff --git a/runtime/indent/tcl.vim b/runtime/indent/tcl.vim
index eafb8dd568..c35150d0e0 100644
--- a/runtime/indent/tcl.vim
+++ b/runtime/indent/tcl.vim
@@ -1,8 +1,8 @@
" Vim indent file
-" Language: Tcl
-" Latest Update: Chris Heithoff <chrisheithoff@gmail.com>
+" Language: Tcl
+" Maintainer: Chris Heithoff <chrisheithoff@gmail.com>
" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
-" Latest Revision: 2018-12-05
+" Last Change: 24 Sep 2021
if exists("b:did_indent")
finish
@@ -13,6 +13,8 @@ setlocal indentexpr=GetTclIndent()
setlocal indentkeys=0{,0},!^F,o,O,0]
setlocal nosmartindent
+let b:undo_indent = "setl inde< indk< si<"
+
if exists("*GetTclIndent")
finish
endif
diff --git a/runtime/indent/tcsh.vim b/runtime/indent/tcsh.vim
index ed08e6c6e2..93d96e7789 100644
--- a/runtime/indent/tcsh.vim
+++ b/runtime/indent/tcsh.vim
@@ -1,7 +1,8 @@
" Vim indent file
" Language: C-shell (tcsh)
-" Maintainer: GI <a@b.c>, where a='gi1242+vim', b='gmail', c='com'
-" Last Modified: Sat 10 Dec 2011 09:23:00 AM EST
+" Maintainer: Doug Kearns <dougkearns@gmail.com>
+" Previous Maintainer: Gautam Iyer <gi1242+vim@NoSpam.com> where NoSpam=gmail (Original Author)
+" Last Change: 2021 Oct 15
" Only load this indent file when no other was loaded.
if exists("b:did_indent")
@@ -11,7 +12,10 @@ endif
let b:did_indent = 1
setlocal indentexpr=TcshGetIndent()
-setlocal indentkeys+=e,0=end,0=endsw indentkeys-=0{,0},0),:,0#
+setlocal indentkeys+=e,0=end
+setlocal indentkeys-=0{,0},0),:,0#
+
+let b:undo_indent = "setl inde< indk<"
" Only define the function once.
if exists("*TcshGetIndent")
@@ -39,9 +43,9 @@ function TcshGetIndent()
let ind = ind - shiftwidth()
endif
- " Subtract indent if current line has on end, endif, case commands
+ " Subtract indent if current line has on end, endif, endsw, case commands
let line = getline(v:lnum)
- if line =~ '\v^\s*%(else|end|endif)\s*$'
+ if line =~ '\v^\s*%(else|end|endif|endsw)\s*$'
let ind = ind - shiftwidth()
endif
diff --git a/runtime/indent/zimbu.vim b/runtime/indent/zimbu.vim
index 5451877ea7..0e6e2ab1d1 100644
--- a/runtime/indent/zimbu.vim
+++ b/runtime/indent/zimbu.vim
@@ -1,7 +1,7 @@
" Vim indent file
" Language: Zimbu
" Maintainer: Bram Moolenaar <Bram@vim.org>
-" Last Change: 2016 Jan 25
+" Last Change: 2021 Sep 26
" Only load this indent file when no other was loaded.
if exists("b:did_indent")
@@ -16,7 +16,7 @@ setlocal indentkeys=0{,0},!^F,o,O,0=ELSE,0=ELSEIF,0=CASE,0=DEFAULT,0=FINALLY
" We impose recommended defaults: no Tabs, 'shiftwidth' = 2
setlocal sw=2 et
-let b:undo_indent = "setl et< sw< ai< indentkeys< indentexpr="
+let b:undo_indent = "setl ai< cin< et< indentkeys< indentexpr< lisp< sw<"
" Only define the function once.
if exists("*GetZimbuIndent")
diff --git a/runtime/lua/health.lua b/runtime/lua/health.lua
new file mode 100644
index 0000000000..142a353bf2
--- /dev/null
+++ b/runtime/lua/health.lua
@@ -0,0 +1,23 @@
+local M = {}
+
+function M.report_start(msg)
+ vim.fn['health#report_start'](msg)
+end
+
+function M.report_info(msg)
+ vim.fn['health#report_info'](msg)
+end
+
+function M.report_ok(msg)
+ vim.fn['health#report_ok'](msg)
+end
+
+function M.report_warn(msg, ...)
+ vim.fn['health#report_warn'](msg, ...)
+end
+
+function M.report_error(msg, ...)
+ vim.fn['health#report_error'](msg, ...)
+end
+
+return M
diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua
index c977fe0109..4cf22282a2 100644
--- a/runtime/lua/vim/diagnostic.lua
+++ b/runtime/lua/vim/diagnostic.lua
@@ -19,6 +19,7 @@ local global_diagnostic_options = {
signs = true,
underline = true,
virtual_text = true,
+ float = true,
update_in_insert = false,
severity_sort = false,
}
@@ -27,7 +28,10 @@ local global_diagnostic_options = {
---@private
local function to_severity(severity)
- return type(severity) == 'string' and M.severity[string.upper(severity)] or severity
+ if type(severity) == 'string' then
+ return assert(M.severity[string.upper(severity)], string.format("Invalid severity: %s", severity))
+ end
+ return severity
end
---@private
@@ -48,25 +52,46 @@ local function filter_by_severity(severity, diagnostics)
end
---@private
-local function resolve_optional_value(option, namespace, bufnr)
- local enabled_val = {}
+local function prefix_source(source, diagnostics)
+ vim.validate { source = {source, function(v)
+ return v == "always" or v == "if_many"
+ end, "Invalid value for option 'source'" } }
+
+ if source == "if_many" then
+ local sources = {}
+ for _, d in pairs(diagnostics) do
+ if d.source then
+ sources[d.source] = true
+ end
+ end
+ if #vim.tbl_keys(sources) <= 1 then
+ return diagnostics
+ end
+ end
- if not option then
- return false
- elseif option == true then
- return enabled_val
- elseif type(option) == 'function' then
- local val = option(namespace, bufnr)
- if val == true then
- return enabled_val
- else
- return val
+ return vim.tbl_map(function(d)
+ if not d.source then
+ return d
end
- elseif type(option) == 'table' then
- return option
- else
- error("Unexpected option type: " .. vim.inspect(option))
+
+ local t = vim.deepcopy(d)
+ t.message = string.format("%s: %s", d.source, d.message)
+ return t
+ end, diagnostics)
+end
+
+---@private
+local function reformat_diagnostics(format, diagnostics)
+ vim.validate {
+ format = {format, 'f'},
+ diagnostics = {diagnostics, 't'},
+ }
+
+ local formatted = vim.deepcopy(diagnostics)
+ for _, diagnostic in ipairs(formatted) do
+ diagnostic.message = format(diagnostic)
end
+ return formatted
end
local all_namespaces = {}
@@ -82,9 +107,7 @@ local function get_namespace(ns)
end
end
- if not name then
- return vim.notify("namespace does not exist or is anonymous", vim.log.levels.ERROR)
- end
+ assert(name, "namespace does not exist or is anonymous")
all_namespaces[ns] = {
name = name,
@@ -96,12 +119,47 @@ local function get_namespace(ns)
end
---@private
+local function enabled_value(option, namespace)
+ local ns = namespace and get_namespace(namespace) or {}
+ if ns.opts and type(ns.opts[option]) == "table" then
+ return ns.opts[option]
+ end
+
+ if type(global_diagnostic_options[option]) == "table" then
+ return global_diagnostic_options[option]
+ end
+
+ return {}
+end
+
+---@private
+local function resolve_optional_value(option, value, namespace, bufnr)
+ if not value then
+ return false
+ elseif value == true then
+ return enabled_value(option, namespace)
+ elseif type(value) == 'function' then
+ local val = value(namespace, bufnr)
+ if val == true then
+ return enabled_value(option, namespace)
+ else
+ return val
+ end
+ elseif type(value) == 'table' then
+ return value
+ else
+ error("Unexpected option type: " .. vim.inspect(value))
+ end
+end
+
+---@private
local function get_resolved_options(opts, namespace, bufnr)
- local ns = get_namespace(namespace)
- local resolved = vim.tbl_extend('keep', opts or {}, ns.opts, global_diagnostic_options)
+ local ns = namespace and get_namespace(namespace) or {}
+ -- Do not use tbl_deep_extend so that an empty table can be used to reset to default values
+ local resolved = vim.tbl_extend('keep', opts or {}, ns.opts or {}, global_diagnostic_options)
for k in pairs(global_diagnostic_options) do
if resolved[k] ~= nil then
- resolved[k] = resolve_optional_value(resolved[k], namespace, bufnr)
+ resolved[k] = resolve_optional_value(k, resolved[k], namespace, bufnr)
end
end
return resolved
@@ -206,7 +264,7 @@ end
---@private
local function diagnostic_lines(diagnostics)
if not diagnostics then
- return
+ return {}
end
local diagnostics_by_line = {}
@@ -222,26 +280,14 @@ local function diagnostic_lines(diagnostics)
end
---@private
-local function set_diagnostic_cache(namespace, diagnostics, bufnr)
- local buf_line_count = vim.api.nvim_buf_line_count(bufnr)
+local function set_diagnostic_cache(namespace, bufnr, diagnostics)
for _, diagnostic in ipairs(diagnostics) do
- if diagnostic.severity == nil then
- diagnostic.severity = M.severity.ERROR
- end
-
+ diagnostic.severity = diagnostic.severity and to_severity(diagnostic.severity) or M.severity.ERROR
+ diagnostic.end_lnum = diagnostic.end_lnum or diagnostic.lnum
+ diagnostic.end_col = diagnostic.end_col or diagnostic.col
diagnostic.namespace = namespace
diagnostic.bufnr = bufnr
-
- if buf_line_count > 0 then
- diagnostic.lnum = math.max(math.min(
- diagnostic.lnum, buf_line_count - 1
- ), 0)
- diagnostic.end_lnum = math.max(math.min(
- diagnostic.end_lnum, buf_line_count - 1
- ), 0)
- end
end
-
diagnostic_cache[bufnr][namespace] = diagnostics
end
@@ -310,19 +356,15 @@ local function schedule_display(namespace, bufnr, args)
local key = make_augroup_key(namespace, bufnr)
if not registered_autocmds[key] then
- vim.cmd(string.format("augroup %s", key))
- vim.cmd(" au!")
- vim.cmd(
- string.format(
- [[autocmd %s <buffer=%s> lua vim.diagnostic._execute_scheduled_display(%s, %s)]],
- table.concat(insert_leave_auto_cmds, ","),
- bufnr,
- namespace,
- bufnr
- )
- )
- vim.cmd("augroup END")
-
+ vim.cmd(string.format([[augroup %s
+ au!
+ autocmd %s <buffer=%s> lua vim.diagnostic._execute_scheduled_display(%s, %s)
+ augroup END]],
+ key,
+ table.concat(insert_leave_auto_cmds, ","),
+ bufnr,
+ namespace,
+ bufnr))
registered_autocmds[key] = true
end
end
@@ -332,56 +374,14 @@ local function clear_scheduled_display(namespace, bufnr)
local key = make_augroup_key(namespace, bufnr)
if registered_autocmds[key] then
- vim.cmd(string.format("augroup %s", key))
- vim.cmd(" au!")
- vim.cmd("augroup END")
-
+ vim.cmd(string.format([[augroup %s
+ au!
+ augroup END]], key))
registered_autocmds[key] = nil
end
end
---@private
---- Open a floating window with the provided diagnostics
----@param opts table Configuration table
---- - show_header (boolean, default true): Show "Diagnostics:" header
---- - all opts for |vim.util.open_floating_preview()| can be used here
----@param diagnostics table: The diagnostics to display
----@return table {popup_bufnr, win_id}
-local function show_diagnostics(opts, diagnostics)
- if vim.tbl_isempty(diagnostics) then return end
- local lines = {}
- local highlights = {}
- local show_header = vim.F.if_nil(opts.show_header, true)
- if show_header then
- table.insert(lines, "Diagnostics:")
- table.insert(highlights, {0, "Bold"})
- end
-
- for i, diagnostic in ipairs(diagnostics) do
- local prefix = string.format("%d. ", i)
- local hiname = floating_highlight_map[diagnostic.severity]
- assert(hiname, 'unknown severity: ' .. tostring(diagnostic.severity))
-
- local message_lines = vim.split(diagnostic.message, '\n', true)
- table.insert(lines, prefix..message_lines[1])
- table.insert(highlights, {#prefix, hiname})
- for j = 2, #message_lines do
- table.insert(lines, string.rep(' ', #prefix) .. message_lines[j])
- table.insert(highlights, {0, hiname})
- end
- end
-
- local popup_bufnr, winnr = require('vim.lsp.util').open_floating_preview(lines, 'plaintext', opts)
- for i, hi in ipairs(highlights) do
- local prefixlen, hiname = unpack(hi)
- -- Start highlight after the prefix
- vim.api.nvim_buf_add_highlight(popup_bufnr, -1, hiname, i-1, prefixlen, -1)
- end
-
- return popup_bufnr, winnr
-end
-
----@private
local function set_list(loclist, opts)
opts = opts or {}
local open = vim.F.if_nil(opts.open, true)
@@ -404,12 +404,28 @@ local function set_list(loclist, opts)
end
---@private
+--- To (slightly) improve performance, modifies diagnostics in place.
+local function clamp_line_numbers(bufnr, diagnostics)
+ local buf_line_count = vim.api.nvim_buf_line_count(bufnr)
+ if buf_line_count == 0 then
+ return
+ end
+
+ for _, diagnostic in ipairs(diagnostics) do
+ diagnostic.lnum = math.max(math.min(diagnostic.lnum, buf_line_count - 1), 0)
+ diagnostic.end_lnum = math.max(math.min(diagnostic.end_lnum, buf_line_count - 1), 0)
+ end
+end
+
+---@private
local function next_diagnostic(position, search_forward, bufnr, opts, namespace)
position[1] = position[1] - 1
- bufnr = bufnr or vim.api.nvim_get_current_buf()
+ bufnr = get_bufnr(bufnr)
local wrap = vim.F.if_nil(opts.wrap, true)
local line_count = vim.api.nvim_buf_line_count(bufnr)
- opts.namespace = namespace
+ local diagnostics = M.get(bufnr, vim.tbl_extend("keep", opts, {namespace = namespace}))
+ clamp_line_numbers(bufnr, diagnostics)
+ local line_diagnostics = diagnostic_lines(diagnostics)
for i = 0, line_count do
local offset = i * (search_forward and 1 or -1)
local lnum = position[1] + offset
@@ -419,9 +435,7 @@ local function next_diagnostic(position, search_forward, bufnr, opts, namespace)
end
lnum = (lnum + line_count) % line_count
end
- opts.lnum = lnum
- local line_diagnostics = M.get(bufnr, opts)
- if line_diagnostics and not vim.tbl_isempty(line_diagnostics) then
+ if line_diagnostics[lnum] and not vim.tbl_isempty(line_diagnostics[lnum]) then
local sort_diagnostics, is_next
if search_forward then
sort_diagnostics = function(a, b) return a.col < b.col end
@@ -430,15 +444,15 @@ local function next_diagnostic(position, search_forward, bufnr, opts, namespace)
sort_diagnostics = function(a, b) return a.col > b.col end
is_next = function(diagnostic) return diagnostic.col < position[2] end
end
- table.sort(line_diagnostics, sort_diagnostics)
+ table.sort(line_diagnostics[lnum], sort_diagnostics)
if i == 0 then
- for _, v in pairs(line_diagnostics) do
+ for _, v in pairs(line_diagnostics[lnum]) do
if is_next(v) then
return v
end
end
else
- return line_diagnostics[1]
+ return line_diagnostics[lnum][1]
end
end
end
@@ -448,7 +462,7 @@ end
local function diagnostic_move_pos(opts, pos)
opts = opts or {}
- local enable_popup = vim.F.if_nil(opts.enable_popup, true)
+ local float = vim.F.if_nil(opts.float, true)
local win_id = opts.win_id or vim.api.nvim_get_current_win()
if not pos then
@@ -456,17 +470,22 @@ local function diagnostic_move_pos(opts, pos)
return
end
+ -- Save position in the window's jumplist
+ vim.api.nvim_win_call(win_id, function() vim.cmd("normal! m'") end)
+
vim.api.nvim_win_set_cursor(win_id, {pos[1] + 1, pos[2]})
- if enable_popup then
- -- This is a bit weird... I'm surprised that we need to wait til the next tick to do this.
+ if float then
+ local float_opts = type(float) == "table" and float or {}
vim.schedule(function()
- M.show_position_diagnostics(opts.popup_opts, vim.api.nvim_win_get_buf(win_id))
+ M.open_float(
+ vim.api.nvim_win_get_buf(win_id),
+ vim.tbl_extend("keep", float_opts, {scope="cursor"})
+ )
end)
end
end
-
-- }}}
-- Public API {{{
@@ -474,10 +493,27 @@ end
--- Configure diagnostic options globally or for a specific diagnostic
--- namespace.
---
+--- Configuration can be specified globally, per-namespace, or ephemerally
+--- (i.e. only for a single call to |vim.diagnostic.set()| or
+--- |vim.diagnostic.show()|). Ephemeral configuration has highest priority,
+--- followed by namespace configuration, and finally global configuration.
+---
+--- For example, if a user enables virtual text globally with
+--- <pre>
+--- vim.diagnostic.config({virtual_text = true})
+--- </pre>
+---
+--- and a diagnostic producer sets diagnostics with
+--- <pre>
+--- vim.diagnostic.set(ns, 0, diagnostics, {virtual_text = false})
+--- </pre>
+---
+--- then virtual text will not be enabled for those diagnostics.
+---
---@note Each of the configuration options below accepts one of the following:
--- - `false`: Disable this feature
--- - `true`: Enable this feature, use default settings.
---- - `table`: Enable this feature with overrides.
+--- - `table`: Enable this feature with overrides. Use an empty table to use default values.
--- - `function`: Function with signature (namespace, bufnr) that returns any of the above.
---
---@param opts table Configuration table with the following keys:
@@ -487,9 +523,32 @@ end
--- - virtual_text: (default true) Use virtual text for diagnostics. Options:
--- * severity: Only show virtual text for diagnostics matching the given
--- severity |diagnostic-severity|
+--- * source: (string) Include the diagnostic source in virtual
+--- text. One of "always" or "if_many".
+--- * format: (function) A function that takes a diagnostic as input and
+--- returns a string. The return value is the text used to display
+--- the diagnostic. Example:
+--- <pre>
+--- function(diagnostic)
+--- if diagnostic.severity == vim.diagnostic.severity.ERROR then
+--- return string.format("E: %s", diagnostic.message)
+--- end
+--- return diagnostic.message
+--- end
+--- </pre>
--- - signs: (default true) Use signs for diagnostics. Options:
--- * severity: Only show signs for diagnostics matching the given severity
--- |diagnostic-severity|
+--- * priority: (number, default 10) Base priority to use for signs. When
+--- {severity_sort} is used, the priority of a sign is adjusted based on
+--- its severity. Otherwise, all signs use the same priority.
+--- - float: Options for floating windows:
+--- * severity: See |diagnostic-severity|.
+--- * show_header: (boolean, default true) Show "Diagnostics:" header
+--- * source: (string) Include the diagnostic source in
+--- the message. One of "always" or "if_many".
+--- * format: (function) A function that takes a diagnostic as input and returns a
+--- string. The return value is the text used to display the diagnostic.
--- - update_in_insert: (default false) Update diagnostics in Insert mode (if false,
--- diagnostics are updated on InsertLeave)
--- - severity_sort: (default false) Sort diagnostics by severity. This affects the order in
@@ -551,32 +610,36 @@ function M.set(namespace, bufnr, diagnostics, opts)
}
if vim.tbl_isempty(diagnostics) then
- return M.reset(namespace, bufnr)
- end
-
- if not diagnostic_cleanup[bufnr][namespace] then
- diagnostic_cleanup[bufnr][namespace] = true
-
- -- Clean up our data when the buffer unloads.
- vim.api.nvim_buf_attach(bufnr, false, {
- on_detach = function(_, b)
- clear_diagnostic_cache(b, namespace)
- diagnostic_cleanup[b][namespace] = nil
- end
- })
+ clear_diagnostic_cache(namespace, bufnr)
+ else
+ if not diagnostic_cleanup[bufnr][namespace] then
+ diagnostic_cleanup[bufnr][namespace] = true
+
+ -- Clean up our data when the buffer unloads.
+ vim.api.nvim_buf_attach(bufnr, false, {
+ on_detach = function(_, b)
+ clear_diagnostic_cache(b, namespace)
+ diagnostic_cleanup[b][namespace] = nil
+ end
+ })
+ end
+ set_diagnostic_cache(namespace, bufnr, diagnostics)
end
- set_diagnostic_cache(namespace, diagnostics, bufnr)
-
if vim.api.nvim_buf_is_loaded(bufnr) then
M.show(namespace, bufnr, diagnostics, opts)
- elseif opts then
- M.config(opts, namespace)
end
vim.api.nvim_command("doautocmd <nomodeline> User DiagnosticsChanged")
end
+--- Get current diagnostic namespaces.
+---
+---@return table A list of active diagnostic namespaces |vim.diagnostic|.
+function M.get_namespaces()
+ return vim.deepcopy(all_namespaces)
+end
+
--- Get current diagnostics.
---
---@param bufnr number|nil Buffer number to get diagnostics from. Use 0 for
@@ -708,10 +771,9 @@ end
--- |nvim_win_get_cursor()|. Defaults to the current cursor position.
--- - wrap: (boolean, default true) Whether to loop around file or not. Similar to 'wrapscan'.
--- - severity: See |diagnostic-severity|.
---- - enable_popup: (boolean, default true) Call |vim.diagnostic.show_line_diagnostics()|
---- on jump.
---- - popup_opts: (table) Table to pass as {opts} parameter to
---- |vim.diagnostic.show_line_diagnostics()|
+--- - float: (boolean or table, default true) If "true", call |vim.diagnostic.open_float()|
+--- after moving. If a table, pass the table as the {opts} parameter to
+--- |vim.diagnostic.open_float()|.
--- - win_id: (number, default 0) Window ID
function M.goto_next(opts)
return diagnostic_move_pos(
@@ -740,16 +802,35 @@ function M._set_signs(namespace, bufnr, diagnostics, opts)
}
bufnr = get_bufnr(bufnr)
- opts = get_resolved_options({ signs = opts }, namespace, bufnr).signs
+ opts = get_resolved_options({ signs = opts }, namespace, bufnr)
- if opts and opts.severity then
- diagnostics = filter_by_severity(opts.severity, diagnostics)
+ if opts.signs and opts.signs.severity then
+ diagnostics = filter_by_severity(opts.signs.severity, diagnostics)
end
local ns = get_namespace(namespace)
define_default_signs()
+ -- 10 is the default sign priority when none is explicitly specified
+ local priority = opts.signs and opts.signs.priority or 10
+ local get_priority
+ if opts.severity_sort then
+ if type(opts.severity_sort) == "table" and opts.severity_sort.reverse then
+ get_priority = function(severity)
+ return priority + (severity - vim.diagnostic.severity.ERROR)
+ end
+ else
+ get_priority = function(severity)
+ return priority + (vim.diagnostic.severity.HINT - severity)
+ end
+ end
+ else
+ get_priority = function()
+ return priority
+ end
+ end
+
for _, diagnostic in ipairs(diagnostics) do
vim.fn.sign_place(
0,
@@ -757,7 +838,7 @@ function M._set_signs(namespace, bufnr, diagnostics, opts)
sign_highlight_map[diagnostic.severity],
bufnr,
{
- priority = opts and opts.priority,
+ priority = get_priority(diagnostic.severity),
lnum = diagnostic.lnum + 1
}
)
@@ -814,6 +895,8 @@ end
---@param opts table|nil Configuration table with the following keys:
--- - prefix: (string) Prefix to display before virtual text on line.
--- - spacing: (number) Number of spaces to insert before virtual text.
+--- - source: (string) Include the diagnostic source in virtual text. One of "always" or
+--- "if_many".
---@private
function M._set_virtual_text(namespace, bufnr, diagnostics, opts)
vim.validate {
@@ -826,12 +909,20 @@ function M._set_virtual_text(namespace, bufnr, diagnostics, opts)
bufnr = get_bufnr(bufnr)
opts = get_resolved_options({ virtual_text = opts }, namespace, bufnr).virtual_text
+ if opts and opts.format then
+ diagnostics = reformat_diagnostics(opts.format, diagnostics)
+ end
+
+ if opts and opts.source then
+ diagnostics = prefix_source(opts.source, diagnostics)
+ end
+
local buffer_line_diagnostics = diagnostic_lines(diagnostics)
for line, line_diagnostics in pairs(buffer_line_diagnostics) do
if opts and opts.severity then
line_diagnostics = filter_by_severity(opts.severity, line_diagnostics)
end
- local virt_texts = M.get_virt_text_chunks(line_diagnostics, opts)
+ local virt_texts = M._get_virt_text_chunks(line_diagnostics, opts)
if virt_texts then
vim.api.nvim_buf_set_extmark(bufnr, namespace, line, 0, {
@@ -844,13 +935,11 @@ end
--- Get virtual text chunks to display using |nvim_buf_set_extmark()|.
---
----@param line_diags table The diagnostics associated with the line.
----@param opts table|nil Configuration table with the following keys:
---- - prefix: (string) Prefix to display before virtual text on line.
---- - spacing: (number) Number of spaces to insert before virtual text.
----@return array of ({text}, {hl_group}) tuples. This can be passed directly to
---- the {virt_text} option of |nvim_buf_set_extmark()|.
-function M.get_virt_text_chunks(line_diags, opts)
+--- Exported for backward compatibility with
+--- vim.lsp.diagnostic.get_virtual_text_chunks_for_line(). When that function is eventually removed,
+--- this can be made local.
+---@private
+function M._get_virt_text_chunks(line_diags, opts)
if #line_diags == 0 then
return nil
end
@@ -983,6 +1072,8 @@ function M.show(namespace, bufnr, diagnostics, opts)
end
end
+ clamp_line_numbers(bufnr, diagnostics)
+
if opts.underline then
M._set_underline(namespace, bufnr, diagnostics, opts.underline)
end
@@ -998,61 +1089,136 @@ function M.show(namespace, bufnr, diagnostics, opts)
save_extmarks(namespace, bufnr)
end
---- Open a floating window with the diagnostics at the given position.
+--- Show diagnostics in a floating window.
---
+---@param bufnr number|nil Buffer number. Defaults to the current buffer.
---@param opts table|nil Configuration table with the same keys as
--- |vim.lsp.util.open_floating_preview()| in addition to the following:
--- - namespace: (number) Limit diagnostics to the given namespace
---- - severity: See |diagnostic-severity|.
---- - show_header: (boolean, default true) Show "Diagnostics:" header
----@param bufnr number|nil Buffer number. Defaults to the current buffer.
----@param position table|nil The (0,0)-indexed position. Defaults to the current cursor position.
----@return tuple ({popup_bufnr}, {win_id})
-function M.show_position_diagnostics(opts, bufnr, position)
+--- - scope: (string, default "buffer") Show diagnostics from the whole buffer ("buffer"),
+--- the current cursor line ("line"), or the current cursor position ("cursor").
+--- - pos: (number or table) If {scope} is "line" or "cursor", use this position rather
+--- than the cursor position. If a number, interpreted as a line number;
+--- otherwise, a (row, col) tuple.
+--- - severity_sort: (default false) Sort diagnostics by severity. Overrides the setting
+--- from |vim.diagnostic.config()|.
+--- - severity: See |diagnostic-severity|. Overrides the setting from
+--- |vim.diagnostic.config()|.
+--- - show_header: (boolean, default true) Show "Diagnostics:" header. Overrides the
+--- setting from |vim.diagnostic.config()|.
+--- - source: (string) Include the diagnostic source in the message. One of "always" or
+--- "if_many". Overrides the setting from |vim.diagnostic.config()|.
+--- - format: (function) A function that takes a diagnostic as input and returns a
+--- string. The return value is the text used to display the diagnostic.
+--- Overrides the setting from |vim.diagnostic.config()|.
+---@return tuple ({float_bufnr}, {win_id})
+function M.open_float(bufnr, opts)
vim.validate {
- opts = { opts, 't', true },
bufnr = { bufnr, 'n', true },
- position = { position, 't', true },
+ opts = { opts, 't', true },
}
opts = opts or {}
-
- opts.focus_id = "position_diagnostics"
bufnr = get_bufnr(bufnr)
- if not position then
- local curr_position = vim.api.nvim_win_get_cursor(0)
- curr_position[1] = curr_position[1] - 1
- position = curr_position
- end
- local match_position_predicate = function(diag)
- return position[1] == diag.lnum and
- position[2] >= diag.col and
- (position[2] <= diag.end_col or position[1] < diag.end_lnum)
- end
- local position_diagnostics = vim.tbl_filter(match_position_predicate, M.get(bufnr, opts))
- table.sort(position_diagnostics, function(a, b) return a.severity < b.severity end)
- return show_diagnostics(opts, position_diagnostics)
-end
+ local scope = opts.scope or "buffer"
+ local lnum, col
+ if scope == "line" or scope == "cursor" then
+ if not opts.pos then
+ local pos = vim.api.nvim_win_get_cursor(0)
+ lnum = pos[1] - 1
+ col = pos[2]
+ elseif type(opts.pos) == "number" then
+ lnum = opts.pos
+ elseif type(opts.pos) == "table" then
+ lnum, col = unpack(opts.pos)
+ else
+ error("Invalid value for option 'pos'")
+ end
+ elseif scope ~= "buffer" then
+ error("Invalid value for option 'scope'")
+ end
---- Open a floating window with the diagnostics from the given line.
----
----@param opts table Configuration table. See |vim.diagnostic.show_position_diagnostics()|.
----@param bufnr number|nil Buffer number. Defaults to the current buffer.
----@param lnum number|nil Line number. Defaults to line number of cursor.
----@return tuple ({popup_bufnr}, {win_id})
-function M.show_line_diagnostics(opts, bufnr, lnum)
- vim.validate {
- opts = { opts, 't', true },
- bufnr = { bufnr, 'n', true },
- lnum = { lnum, 'n', true },
- }
+ local diagnostics = M.get(bufnr, opts)
+ clamp_line_numbers(bufnr, diagnostics)
+
+ if scope == "line" then
+ diagnostics = vim.tbl_filter(function(d)
+ return d.lnum == lnum
+ end, diagnostics)
+ elseif scope == "cursor" then
+ -- LSP servers can send diagnostics with `end_col` past the length of the line
+ local line_length = #vim.api.nvim_buf_get_lines(bufnr, lnum, lnum + 1, true)[1]
+ diagnostics = vim.tbl_filter(function(d)
+ return d.lnum == lnum
+ and math.min(d.col, line_length - 1) <= col
+ and (d.end_col >= col or d.end_lnum > lnum)
+ end, diagnostics)
+ end
- opts = opts or {}
- opts.focus_id = "line_diagnostics"
- opts.lnum = lnum or (vim.api.nvim_win_get_cursor(0)[1] - 1)
- bufnr = get_bufnr(bufnr)
- local line_diagnostics = M.get(bufnr, opts)
- return show_diagnostics(opts, line_diagnostics)
+ if vim.tbl_isempty(diagnostics) then
+ return
+ end
+
+ local severity_sort = vim.F.if_nil(opts.severity_sort, global_diagnostic_options.severity_sort)
+ if severity_sort then
+ if type(severity_sort) == "table" and severity_sort.reverse then
+ table.sort(diagnostics, function(a, b) return a.severity > b.severity end)
+ else
+ table.sort(diagnostics, function(a, b) return a.severity < b.severity end)
+ end
+ end
+
+ do
+ -- Resolve options with user settings from vim.diagnostic.config
+ -- Unlike the other decoration functions (e.g. set_virtual_text, set_signs, etc.) `open_float`
+ -- does not have a dedicated table for configuration options; instead, the options are mixed in
+ -- with its `opts` table which also includes "keyword" parameters. So we create a dedicated
+ -- options table that inherits missing keys from the global configuration before resolving.
+ local t = global_diagnostic_options.float
+ local float_opts = vim.tbl_extend("keep", opts, type(t) == "table" and t or {})
+ opts = get_resolved_options({ float = float_opts }, nil, bufnr).float
+ end
+
+ local lines = {}
+ local highlights = {}
+ local show_header = vim.F.if_nil(opts.show_header, true)
+ if show_header then
+ table.insert(lines, "Diagnostics:")
+ table.insert(highlights, {0, "Bold"})
+ end
+
+ if opts.format then
+ diagnostics = reformat_diagnostics(opts.format, diagnostics)
+ end
+
+ if opts.source then
+ diagnostics = prefix_source(opts.source, diagnostics)
+ end
+
+ for i, diagnostic in ipairs(diagnostics) do
+ local prefix = string.format("%d. ", i)
+ local hiname = floating_highlight_map[diagnostic.severity]
+ local message_lines = vim.split(diagnostic.message, '\n')
+ table.insert(lines, prefix..message_lines[1])
+ table.insert(highlights, {#prefix, hiname})
+ for j = 2, #message_lines do
+ table.insert(lines, string.rep(' ', #prefix) .. message_lines[j])
+ table.insert(highlights, {0, hiname})
+ end
+ end
+
+ -- Used by open_floating_preview to allow the float to be focused
+ if not opts.focus_id then
+ opts.focus_id = scope
+ end
+ local float_bufnr, winnr = require('vim.lsp.util').open_floating_preview(lines, 'plaintext', opts)
+ for i, hi in ipairs(highlights) do
+ local prefixlen, hiname = unpack(hi)
+ -- Start highlight after the prefix
+ vim.api.nvim_buf_add_highlight(float_bufnr, -1, hiname, i-1, prefixlen, -1)
+ end
+
+ return float_bufnr, winnr
end
--- Remove all diagnostics from the given namespace.
@@ -1151,6 +1317,7 @@ end
--- <pre>
--- WARNING filename:27:3: Variable 'foo' does not exist
--- </pre>
+---
--- This can be parsed into a diagnostic |diagnostic-structure|
--- with:
--- <pre>
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 90c5872f11..9a008ac965 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -41,6 +41,7 @@ lsp._request_name_to_capability = {
['textDocument/documentSymbol'] = 'document_symbol';
['textDocument/prepareCallHierarchy'] = 'call_hierarchy';
['textDocument/rename'] = 'rename';
+ ['textDocument/prepareRename'] = 'rename';
['textDocument/codeAction'] = 'code_action';
['textDocument/codeLens'] = 'code_lens';
['codeLens/resolve'] = 'code_lens_resolve';
@@ -85,7 +86,7 @@ end
function lsp._unsupported_method(method)
local msg = string.format("method %s is not supported by any of the servers registered for the current buffer", method)
log.warn(msg)
- return lsp.rpc_response_error(protocol.ErrorCodes.MethodNotFound, msg)
+ return msg
end
---@private
@@ -121,24 +122,34 @@ local active_clients = {}
local all_buffer_active_clients = {}
local uninitialized_clients = {}
--- Tracks all buffers attached to a client.
-local all_client_active_buffers = {}
-
---@private
--- Invokes a function for each LSP client attached to the buffer {bufnr}.
---
---@param bufnr (Number) of buffer
---@param fn (function({client}, {client_id}, {bufnr}) Function to run on
---each client attached to that buffer.
-local function for_each_buffer_client(bufnr, fn)
+---@param restrict_client_ids table list of client ids on which to restrict function application.
+local function for_each_buffer_client(bufnr, fn, restrict_client_ids)
validate {
fn = { fn, 'f' };
+ restrict_client_ids = { restrict_client_ids, 't' , true};
}
bufnr = resolve_bufnr(bufnr)
local client_ids = all_buffer_active_clients[bufnr]
if not client_ids or tbl_isempty(client_ids) then
return
end
+
+ if restrict_client_ids and #restrict_client_ids > 0 then
+ local filtered_client_ids = {}
+ for client_id in pairs(client_ids) do
+ if vim.tbl_contains(restrict_client_ids, client_id) then
+ filtered_client_ids[client_id] = true
+ end
+ end
+ client_ids = filtered_client_ids
+ end
+
for client_id in pairs(client_ids) do
local client = active_clients[client_id]
if client then
@@ -728,7 +739,6 @@ function lsp.start_client(config)
lsp.diagnostic.reset(client_id, all_buffer_active_clients)
changetracking.reset(client_id)
- all_client_active_buffers[client_id] = nil
for _, client_ids in pairs(all_buffer_active_clients) do
client_ids[client_id] = nil
end
@@ -757,6 +767,7 @@ function lsp.start_client(config)
rpc = rpc;
offset_encoding = offset_encoding;
config = config;
+ attached_buffers = {};
handlers = handlers;
-- for $/progress report
@@ -830,7 +841,7 @@ function lsp.start_client(config)
rpc.request('initialize', initialize_params, function(init_err, result)
assert(not init_err, tostring(init_err))
assert(result, "server sent empty result")
- rpc.notify('initialized', {[vim.type_idx]=vim.types.dictionary})
+ rpc.notify('initialized', vim.empty_dict())
client.initialized = true
uninitialized_clients[client_id] = nil
client.workspaceFolders = initialize_params.workspaceFolders
@@ -896,7 +907,7 @@ function lsp.start_client(config)
local _ = log.debug() and log.debug(log_prefix, "client.request", client_id, method, params, handler, bufnr)
return rpc.request(method, params, function(err, result)
- handler(err, result, {method=method, client_id=client_id, bufnr=bufnr})
+ handler(err, result, {method=method, client_id=client_id, bufnr=bufnr, params=params})
end)
end
@@ -975,7 +986,6 @@ function lsp.start_client(config)
lsp.diagnostic.reset(client_id, all_buffer_active_clients)
changetracking.reset(client_id)
- all_client_active_buffers[client_id] = nil
for _, client_ids in pairs(all_buffer_active_clients) do
client_ids[client_id] = nil
end
@@ -1018,6 +1028,7 @@ function lsp.start_client(config)
-- TODO(ashkan) handle errors.
pcall(config.on_attach, client, bufnr)
end
+ client.attached_buffers[bufnr] = true
end
initialize()
@@ -1128,12 +1139,6 @@ function lsp.buf_attach_client(bufnr, client_id)
})
end
- if not all_client_active_buffers[client_id] then
- all_client_active_buffers[client_id] = {}
- end
-
- table.insert(all_client_active_buffers[client_id], bufnr)
-
if buffer_client_ids[client_id] then return end
-- This is our first time attaching this client to this buffer.
buffer_client_ids[client_id] = true
@@ -1158,7 +1163,7 @@ end
--- Gets a client by id, or nil if the id is invalid.
--- The returned client may not yet be fully initialized.
--
----@param client_id client id number
+---@param client_id number client id
---
---@returns |vim.lsp.client| object, or nil
function lsp.get_client_by_id(client_id)
@@ -1167,15 +1172,11 @@ end
--- Returns list of buffers attached to client_id.
--
----@param client_id client id
+---@param client_id number client id
---@returns list of buffer ids
function lsp.get_buffers_by_client_id(client_id)
- local active_client_buffers = all_client_active_buffers[client_id]
- if active_client_buffers then
- return active_client_buffers
- else
- return {}
- end
+ local client = lsp.get_client_by_id(client_id)
+ return client and vim.tbl_keys(client.attached_buffers) or {}
end
--- Stops a client(s).
@@ -1254,33 +1255,33 @@ function lsp.buf_request(bufnr, method, params, handler)
method = { method, 's' };
handler = { handler, 'f', true };
}
- local client_request_ids = {}
+ local supported_clients = {}
local method_supported = false
- for_each_buffer_client(bufnr, function(client, client_id, resolved_bufnr)
+ for_each_buffer_client(bufnr, function(client, client_id)
if client.supports_method(method) then
method_supported = true
- local request_success, request_id = client.request(method, params, handler, resolved_bufnr)
-
- -- This could only fail if the client shut down in the time since we looked
- -- it up and we did the request, which should be rare.
- if request_success then
- client_request_ids[client_id] = request_id
- end
+ table.insert(supported_clients, client_id)
end
end)
- -- if has client but no clients support the given method, call the callback with the proper
- -- error message.
+ -- if has client but no clients support the given method, notify the user
if not tbl_isempty(all_buffer_active_clients[resolve_bufnr(bufnr)] or {}) and not method_supported then
- local unsupported_err = lsp._unsupported_method(method)
- handler = handler or lsp.handlers[method]
- if handler then
- handler(unsupported_err, nil, {method=method, bufnr=bufnr})
- end
+ vim.notify(lsp._unsupported_method(method), vim.log.levels.ERROR)
+ vim.api.nvim_command("redraw")
return
end
+ local client_request_ids = {}
+ for_each_buffer_client(bufnr, function(client, client_id, resolved_bufnr)
+ local request_success, request_id = client.request(method, params, handler, resolved_bufnr)
+ -- This could only fail if the client shut down in the time since we looked
+ -- it up and we did the request, which should be rare.
+ if request_success then
+ client_request_ids[client_id] = request_id
+ end
+ end, supported_clients)
+
local function _cancel_all_requests()
for client_id, request_id in pairs(client_request_ids) do
local client = active_clients[client_id]
@@ -1308,12 +1309,13 @@ function lsp.buf_request_all(bufnr, method, params, callback)
local request_results = {}
local result_count = 0
local expected_result_count = 0
- local cancel, client_request_ids
- local set_expected_result_count = once(function()
- for _ in pairs(client_request_ids) do
- expected_result_count = expected_result_count + 1
- end
+ local set_expected_result_count = once(function ()
+ for_each_buffer_client(bufnr, function(client)
+ if client.supports_method(method) then
+ expected_result_count = expected_result_count + 1
+ end
+ end)
end)
local function _sync_handler(err, result, ctx)
@@ -1326,7 +1328,7 @@ function lsp.buf_request_all(bufnr, method, params, callback)
end
end
- client_request_ids, cancel = lsp.buf_request(bufnr, method, params, _sync_handler)
+ local _, cancel = lsp.buf_request(bufnr, method, params, _sync_handler)
return cancel
end
@@ -1383,6 +1385,29 @@ function lsp.buf_notify(bufnr, method, params)
return resp
end
+
+---@private
+local function adjust_start_col(lnum, line, items, encoding)
+ local min_start_char = nil
+ for _, item in pairs(items) do
+ if item.textEdit and item.textEdit.range.start.line == lnum - 1 then
+ if min_start_char and min_start_char ~= item.textEdit.range.start.character then
+ return nil
+ end
+ min_start_char = item.textEdit.range.start.character
+ end
+ end
+ if min_start_char then
+ if encoding == 'utf-8' then
+ return min_start_char
+ else
+ return vim.str_byteindex(line, min_start_char, encoding == 'utf-16')
+ end
+ else
+ return nil
+ end
+end
+
--- Implements 'omnifunc' compatible LSP completion.
---
---@see |complete-functions|
@@ -1392,7 +1417,7 @@ end
---@param findstart 0 or 1, decides behavior
---@param base If findstart=0, text to match against
---
----@returns (number) Decided by `findstart`:
+---@returns (number) Decided by {findstart}:
--- - findstart=0: column where the completion starts, or -2 or -3
--- - findstart=1: list of matches (actually just calls |complete()|)
function lsp.omnifunc(findstart, base)
@@ -1418,17 +1443,37 @@ function lsp.omnifunc(findstart, base)
-- Get the start position of the current keyword
local textMatch = vim.fn.match(line_to_cursor, '\\k*$')
- local prefix = line_to_cursor:sub(textMatch+1)
local params = util.make_position_params()
local items = {}
- lsp.buf_request(bufnr, 'textDocument/completion', params, function(err, result)
+ lsp.buf_request(bufnr, 'textDocument/completion', params, function(err, result, ctx)
if err or not result or vim.fn.mode() ~= "i" then return end
+
+ -- Completion response items may be relative to a position different than `textMatch`.
+ -- Concrete example, with sumneko/lua-language-server:
+ --
+ -- require('plenary.asy|
+ -- ▲ ▲ ▲
+ -- │ │ └── cursor_pos: 20
+ -- │ └────── textMatch: 17
+ -- └────────────── textEdit.range.start.character: 9
+ -- .newText = 'plenary.async'
+ -- ^^^
+ -- prefix (We'd remove everything not starting with `asy`,
+ -- so we'd eliminate the `plenary.async` result
+ --
+ -- `adjust_start_col` is used to prefer the language server boundary.
+ --
+ local client = lsp.get_client_by_id(ctx.client_id)
+ local encoding = client and client.offset_encoding or 'utf-16'
+ local candidates = util.extract_completion_items(result)
+ local startbyte = adjust_start_col(pos[1], line, candidates, encoding) or textMatch
+ local prefix = line:sub(startbyte + 1, pos[2])
local matches = util.text_document_completion_list_to_complete_items(result, prefix)
-- TODO(ashkan): is this the best way to do this?
vim.list_extend(items, matches)
- vim.fn.complete(textMatch+1, items)
+ vim.fn.complete(startbyte + 1, items)
end)
-- Return -2 to signal that we should continue completion so that we can
@@ -1534,5 +1579,34 @@ function lsp._with_extend(name, options, user_config)
return resulting_config
end
+
+--- Registry for client side commands.
+--- This is an extension point for plugins to handle custom commands which are
+--- not part of the core language server protocol specification.
+---
+--- The registry is a table where the key is a unique command name,
+--- and the value is a function which is called if any LSP action
+--- (code action, code lenses, ...) triggers the command.
+---
+--- If a LSP response contains a command for which no matching entry is
+--- available in this registry, the command will be executed via the LSP server
+--- using `workspace/executeCommand`.
+---
+--- The first argument to the function will be the `Command`:
+-- Command
+-- title: String
+-- command: String
+-- arguments?: any[]
+--
+--- The second argument is the `ctx` of |lsp-handler|
+lsp.commands = setmetatable({}, {
+ __newindex = function(tbl, key, value)
+ assert(type(key) == 'string', "The key for commands in `vim.lsp.commands` must be a string")
+ assert(type(value) == 'function', "Command added to `vim.lsp.commands` must be a function")
+ rawset(tbl, key, value)
+ end;
+})
+
+
return lsp
-- vim:sw=2 ts=2 et
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua
index 8bfcd90f12..245f29943e 100644
--- a/runtime/lua/vim/lsp/buf.lua
+++ b/runtime/lua/vim/lsp/buf.lua
@@ -289,7 +289,6 @@ function M.references(context)
params.context = context or {
includeDeclaration = true;
}
- params[vim.type_idx] = vim.types.dictionary
request('textDocument/references', params)
end
@@ -321,13 +320,21 @@ end
---@private
local function call_hierarchy(method)
local params = util.make_position_params()
- request('textDocument/prepareCallHierarchy', params, function(err, _, result)
+ request('textDocument/prepareCallHierarchy', params, function(err, result, ctx)
if err then
vim.notify(err.message, vim.log.levels.WARN)
return
end
local call_hierarchy_item = pick_call_hierarchy_item(result)
- vim.lsp.buf_request(0, method, { item = call_hierarchy_item })
+ local client = vim.lsp.get_client_by_id(ctx.client_id)
+ if client then
+ client.request(method, { item = call_hierarchy_item }, nil, ctx.bufnr)
+ else
+ vim.notify(string.format(
+ 'Client with id=%d disappeared during call hierarchy request', ctx.client_id),
+ vim.log.levels.WARN
+ )
+ end
end)
end
@@ -443,6 +450,93 @@ function M.clear_references()
util.buf_clear_references()
end
+
+---@private
+--
+--- This is not public because the main extension point is
+--- vim.ui.select which can be overridden independently.
+---
+--- Can't call/use vim.lsp.handlers['textDocument/codeAction'] because it expects
+--- `(err, CodeAction[] | Command[], ctx)`, but we want to aggregate the results
+--- from multiple clients to have 1 single UI prompt for the user, yet we still
+--- need to be able to link a `CodeAction|Command` to the right client for
+--- `codeAction/resolve`
+local function on_code_action_results(results, ctx)
+ local action_tuples = {}
+ for client_id, result in pairs(results) do
+ for _, action in pairs(result.result or {}) do
+ table.insert(action_tuples, { client_id, action })
+ end
+ end
+ if #action_tuples == 0 then
+ vim.notify('No code actions available', vim.log.levels.INFO)
+ return
+ end
+
+ ---@private
+ local function apply_action(action, client)
+ if action.edit then
+ util.apply_workspace_edit(action.edit)
+ end
+ if action.command then
+ local command = type(action.command) == 'table' and action.command or action
+ local fn = vim.lsp.commands[command.command]
+ if fn then
+ local enriched_ctx = vim.deepcopy(ctx)
+ enriched_ctx.client_id = client.id
+ fn(command, ctx)
+ else
+ M.execute_command(command)
+ end
+ end
+ end
+
+ ---@private
+ local function on_user_choice(action_tuple)
+ if not action_tuple then
+ return
+ end
+ -- textDocument/codeAction can return either Command[] or CodeAction[]
+ --
+ -- CodeAction
+ -- ...
+ -- edit?: WorkspaceEdit -- <- must be applied before command
+ -- command?: Command
+ --
+ -- Command:
+ -- title: string
+ -- command: string
+ -- arguments?: any[]
+ --
+ local client = vim.lsp.get_client_by_id(action_tuple[1])
+ local action = action_tuple[2]
+ if not action.edit
+ and client
+ and type(client.resolved_capabilities.code_action) == 'table'
+ and client.resolved_capabilities.code_action.resolveProvider then
+
+ client.request('codeAction/resolve', action, function(err, resolved_action)
+ if err then
+ vim.notify(err.code .. ': ' .. err.message, vim.log.levels.ERROR)
+ return
+ end
+ apply_action(resolved_action, client)
+ end)
+ else
+ apply_action(action, client)
+ end
+ end
+
+ vim.ui.select(action_tuples, {
+ prompt = 'Code actions:',
+ format_item = function(action_tuple)
+ local title = action_tuple[2].title:gsub('\r\n', '\\r\\n')
+ return title:gsub('\n', '\\n')
+ end,
+ }, on_user_choice)
+end
+
+
--- Requests code actions from all clients and calls the handler exactly once
--- with all aggregated results
---@private
@@ -450,22 +544,28 @@ local function code_action_request(params)
local bufnr = vim.api.nvim_get_current_buf()
local method = 'textDocument/codeAction'
vim.lsp.buf_request_all(bufnr, method, params, function(results)
- local actions = {}
- for _, r in pairs(results) do
- vim.list_extend(actions, r.result or {})
- end
- vim.lsp.handlers[method](nil, actions, {bufnr=bufnr, method=method})
+ on_code_action_results(results, { bufnr = bufnr, method = method, params = params })
end)
end
---- Selects a code action from the input list that is available at the current
+--- Selects a code action available at the current
--- cursor position.
---
----@param context: (table, optional) Valid `CodeActionContext` object
+---@param context table|nil `CodeActionContext` of the LSP specification:
+--- - diagnostics: (table|nil)
+--- LSP `Diagnostic[]`. Inferred from the current
+--- position if not provided.
+--- - only: (string|nil)
+--- LSP `CodeActionKind` used to filter the code actions.
+--- Most language servers support values like `refactor`
+--- or `quickfix`.
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction
function M.code_action(context)
validate { context = { context, 't', true } }
- context = context or { diagnostics = vim.lsp.diagnostic.get_line_diagnostics() }
+ context = context or {}
+ if not context.diagnostics then
+ context.diagnostics = vim.lsp.diagnostic.get_line_diagnostics()
+ end
local params = util.make_range_params()
params.context = context
code_action_request(params)
@@ -473,14 +573,25 @@ end
--- Performs |vim.lsp.buf.code_action()| for a given range.
---
----@param context: (table, optional) Valid `CodeActionContext` object
+---
+---@param context table|nil `CodeActionContext` of the LSP specification:
+--- - diagnostics: (table|nil)
+--- LSP `Diagnostic[]`. Inferred from the current
+--- position if not provided.
+--- - only: (string|nil)
+--- LSP `CodeActionKind` used to filter the code actions.
+--- Most language servers support values like `refactor`
+--- or `quickfix`.
---@param start_pos ({number, number}, optional) mark-indexed position.
---Defaults to the start of the last visual selection.
---@param end_pos ({number, number}, optional) mark-indexed position.
---Defaults to the end of the last visual selection.
function M.range_code_action(context, start_pos, end_pos)
validate { context = { context, 't', true } }
- context = context or { diagnostics = vim.lsp.diagnostic.get_line_diagnostics() }
+ context = context or {}
+ if not context.diagnostics then
+ context.diagnostics = vim.lsp.diagnostic.get_line_diagnostics()
+ end
local params = util.make_given_range_params(start_pos, end_pos)
params.context = context
code_action_request(params)
diff --git a/runtime/lua/vim/lsp/codelens.lua b/runtime/lua/vim/lsp/codelens.lua
index 9cedb2f1db..63fcbe430b 100644
--- a/runtime/lua/vim/lsp/codelens.lua
+++ b/runtime/lua/vim/lsp/codelens.lua
@@ -31,10 +31,24 @@ local function execute_lens(lens, bufnr, client_id)
local line = lens.range.start.line
api.nvim_buf_clear_namespace(bufnr, namespaces[client_id], line, line + 1)
+ local command = lens.command
+ local fn = vim.lsp.commands[command.command]
+ if fn then
+ fn(command, { bufnr = bufnr, client_id = client_id })
+ return
+ end
-- Need to use the client that returned the lens → must not use buf_request
local client = vim.lsp.get_client_by_id(client_id)
assert(client, 'Client is required to execute lens, client_id=' .. client_id)
- client.request('workspace/executeCommand', lens.command, function(...)
+ local command_provider = client.server_capabilities.executeCommandProvider
+ local commands = type(command_provider) == 'table' and command_provider.commands or {}
+ if not vim.tbl_contains(commands, command.command) then
+ vim.notify(string.format(
+ "Language server does not support command `%s`. This command may require a client extension.", command.command),
+ vim.log.levels.WARN)
+ return
+ end
+ client.request('workspace/executeCommand', command, function(...)
local result = vim.lsp.handlers['workspace/executeCommand'](...)
M.refresh()
return result
@@ -77,16 +91,16 @@ function M.run()
local option = options[1]
execute_lens(option.lens, bufnr, option.client)
else
- local options_strings = {"Code lenses:"}
- for i, option in ipairs(options) do
- table.insert(options_strings, string.format('%d. %s', i, option.lens.command.title))
- end
- local choice = vim.fn.inputlist(options_strings)
- if choice < 1 or choice > #options then
- return
- end
- local option = options[choice]
- execute_lens(option.lens, bufnr, option.client)
+ vim.ui.select(options, {
+ prompt = 'Code lenses:',
+ format_item = function(option)
+ return option.lens.command.title
+ end,
+ }, function(option)
+ if option then
+ execute_lens(option.lens, bufnr, option.client)
+ end
+ end)
end
end
@@ -124,7 +138,8 @@ function M.display(lenses, bufnr, client_id)
end
end
if #chunks > 0 then
- api.nvim_buf_set_extmark(bufnr, ns, i, 0, { virt_text = chunks })
+ api.nvim_buf_set_extmark(bufnr, ns, i, 0, { virt_text = chunks,
+ hl_mode="combine" })
end
end
end
@@ -185,7 +200,8 @@ local function resolve_lenses(lenses, bufnr, client_id, callback)
ns,
lens.range.start.line,
0,
- { virt_text = {{ lens.command.title, 'LspCodeLens' }} }
+ { virt_text = {{ lens.command.title, 'LspCodeLens' }},
+ hl_mode="combine" }
)
end
countdown()
diff --git a/runtime/lua/vim/lsp/diagnostic.lua b/runtime/lua/vim/lsp/diagnostic.lua
index 148836a93a..bea0e44aca 100644
--- a/runtime/lua/vim/lsp/diagnostic.lua
+++ b/runtime/lua/vim/lsp/diagnostic.lua
@@ -102,7 +102,17 @@ local function diagnostic_lsp_to_vim(diagnostics, bufnr, client_id)
end_lnum = _end.line,
end_col = line_byte_from_position(buf_lines, _end.line, _end.character, offset_encoding),
severity = severity_lsp_to_vim(diagnostic.severity),
- message = diagnostic.message
+ message = diagnostic.message,
+ source = diagnostic.source,
+ user_data = {
+ lsp = {
+ code = diagnostic.code,
+ codeDescription = diagnostic.codeDescription,
+ tags = diagnostic.tags,
+ relatedInformation = diagnostic.relatedInformation,
+ data = diagnostic.data,
+ },
+ },
}
end, diagnostics)
end
@@ -110,7 +120,7 @@ end
---@private
local function diagnostic_vim_to_lsp(diagnostics)
return vim.tbl_map(function(diagnostic)
- return {
+ return vim.tbl_extend("error", {
range = {
start = {
line = diagnostic.lnum,
@@ -123,7 +133,8 @@ local function diagnostic_vim_to_lsp(diagnostics)
},
severity = severity_vim_to_lsp(diagnostic.severity),
message = diagnostic.message,
- }
+ source = diagnostic.source,
+ }, diagnostic.user_data and (diagnostic.user_data.lsp or {}) or {})
end, diagnostics)
end
@@ -200,9 +211,14 @@ function M.on_publish_diagnostics(_, result, ctx, config)
end
end
end
+
+ -- Persist configuration to ensure buffer reloads use the same
+ -- configuration. To make lsp.with configuration work (See :help
+ -- lsp-handler-configuration)
+ vim.diagnostic.config(config, namespace)
end
- vim.diagnostic.set(namespace, bufnr, diagnostic_lsp_to_vim(diagnostics, bufnr, client_id), config)
+ vim.diagnostic.set(namespace, bufnr, diagnostic_lsp_to_vim(diagnostics, bufnr, client_id))
-- Keep old autocmd for back compat. This should eventually be removed.
vim.api.nvim_command("doautocmd <nomodeline> User LspDiagnosticsChanged")
@@ -518,7 +534,7 @@ end
---@return an array of [text, hl_group] arrays. This can be passed directly to
--- the {virt_text} option of |nvim_buf_set_extmark()|.
function M.get_virtual_text_chunks_for_line(bufnr, _, line_diags, opts)
- return vim.diagnostic.get_virt_text_chunks(diagnostic_lsp_to_vim(line_diags, bufnr), opts)
+ return vim.diagnostic._get_virt_text_chunks(diagnostic_lsp_to_vim(line_diags, bufnr), opts)
end
--- Open a floating window with the diagnostics from {position}
@@ -535,14 +551,15 @@ end
---@param position table|nil The (0,0)-indexed position
---@return table {popup_bufnr, win_id}
function M.show_position_diagnostics(opts, buf_nr, position)
- if opts then
- if opts.severity then
- opts.severity = severity_lsp_to_vim(opts.severity)
- elseif opts.severity_limit then
- opts.severity = {min=severity_lsp_to_vim(opts.severity_limit)}
- end
+ opts = opts or {}
+ opts.scope = "cursor"
+ opts.pos = position
+ if opts.severity then
+ opts.severity = severity_lsp_to_vim(opts.severity)
+ elseif opts.severity_limit then
+ opts.severity = {min=severity_lsp_to_vim(opts.severity_limit)}
end
- return vim.diagnostic.show_position_diagnostics(opts, buf_nr, position)
+ return vim.diagnostic.open_float(buf_nr, opts)
end
--- Open a floating window with the diagnostics from {line_nr}
@@ -557,11 +574,13 @@ end
---@param client_id number|nil the client id
---@return table {popup_bufnr, win_id}
function M.show_line_diagnostics(opts, buf_nr, line_nr, client_id)
+ opts = opts or {}
+ opts.scope = "line"
+ opts.pos = line_nr
if client_id then
- opts = opts or {}
opts.namespace = M.get_namespace(client_id)
end
- return vim.diagnostic.show_line_diagnostics(opts, buf_nr, line_nr)
+ return vim.diagnostic.open_float(buf_nr, opts)
end
--- Redraw diagnostics for the given buffer and client
diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua
index 918666ab27..eff27807be 100644
--- a/runtime/lua/vim/lsp/handlers.lua
+++ b/runtime/lua/vim/lsp/handlers.lua
@@ -3,7 +3,6 @@ local protocol = require 'vim.lsp.protocol'
local util = require 'vim.lsp.util'
local vim = vim
local api = vim.api
-local buf = require 'vim.lsp.buf'
local M = {}
@@ -109,40 +108,6 @@ M['client/registerCapability'] = function(_, _, ctx)
return vim.NIL
end
---see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction
-M['textDocument/codeAction'] = function(_, result)
- if result == nil or vim.tbl_isempty(result) then
- print("No code actions available")
- return
- end
-
- local option_strings = {"Code actions:"}
- for i, action in ipairs(result) do
- local title = action.title:gsub('\r\n', '\\r\\n')
- title = title:gsub('\n', '\\n')
- table.insert(option_strings, string.format("%d. %s", i, title))
- end
-
- local choice = vim.fn.inputlist(option_strings)
- if choice < 1 or choice > #result then
- return
- end
- local action_chosen = result[choice]
- -- textDocument/codeAction can return either Command[] or CodeAction[].
- -- If it is a CodeAction, it can have either an edit, a command or both.
- -- Edits should be executed first
- if action_chosen.edit or type(action_chosen.command) == "table" then
- if action_chosen.edit then
- util.apply_workspace_edit(action_chosen.edit)
- end
- if type(action_chosen.command) == "table" then
- buf.execute_command(action_chosen.command)
- end
- else
- buf.execute_command(action_chosen)
- end
-end
-
--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_applyEdit
M['workspace/applyEdit'] = function(_, workspace_edit)
if not workspace_edit then return end
diff --git a/runtime/lua/vim/lsp/health.lua b/runtime/lua/vim/lsp/health.lua
index 855679a2df..ed3eea59df 100644
--- a/runtime/lua/vim/lsp/health.lua
+++ b/runtime/lua/vim/lsp/health.lua
@@ -1,7 +1,7 @@
local M = {}
--- Performs a healthcheck for LSP
-function M.check_health()
+function M.check()
local report_info = vim.fn['health#report_info']
local report_warn = vim.fn['health#report_warn']
diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua
index 27703b4503..b3aa8b934f 100644
--- a/runtime/lua/vim/lsp/protocol.lua
+++ b/runtime/lua/vim/lsp/protocol.lua
@@ -645,6 +645,10 @@ function protocol.make_client_capabilities()
end)();
};
};
+ dataSupport = true;
+ resolveSupport = {
+ properties = { 'edit', }
+ };
};
completion = {
dynamicRegistration = false;
diff --git a/runtime/lua/vim/lsp/rpc.lua b/runtime/lua/vim/lsp/rpc.lua
index 7f31bbdf75..d9a684a738 100644
--- a/runtime/lua/vim/lsp/rpc.lua
+++ b/runtime/lua/vim/lsp/rpc.lua
@@ -4,34 +4,6 @@ local log = require('vim.lsp.log')
local protocol = require('vim.lsp.protocol')
local validate, schedule, schedule_wrap = vim.validate, vim.schedule, vim.schedule_wrap
--- TODO replace with a better implementation.
----@private
---- Encodes to JSON.
----
----@param data (table) Data to encode
----@returns (string) Encoded object
-local function json_encode(data)
- local status, result = pcall(vim.fn.json_encode, data)
- if status then
- return result
- else
- return nil, result
- end
-end
----@private
---- Decodes from JSON.
----
----@param data (string) Data to decode
----@returns (table) Decoded JSON object
-local function json_decode(data)
- local status, result = pcall(vim.fn.json_decode, data)
- if status then
- return result
- else
- return nil, result
- end
-end
-
---@private
--- Checks whether a given path exists and is a directory.
---@param filename (string) path to check
@@ -41,36 +13,6 @@ local function is_dir(filename)
return stat and stat.type == 'directory' or false
end
-local NIL = vim.NIL
-
----@private
-local recursive_convert_NIL
-recursive_convert_NIL = function(v, tbl_processed)
- if v == NIL then
- return nil
- elseif not tbl_processed[v] and type(v) == 'table' then
- tbl_processed[v] = true
- local inside_list = vim.tbl_islist(v)
- return vim.tbl_map(function(x)
- if not inside_list or (inside_list and type(x) == "table") then
- return recursive_convert_NIL(x, tbl_processed)
- else
- return x
- end
- end, v)
- end
-
- return v
-end
-
----@private
---- Returns its argument, but converts `vim.NIL` to Lua `nil`.
----@param v (any) Argument
----@returns (any)
-local function convert_NIL(v)
- return recursive_convert_NIL(v, {})
-end
-
---@private
--- Merges current process env with the given env and returns the result as
--- a list of "k=v" strings.
@@ -389,16 +331,13 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params)
--- Encodes {payload} into a JSON-RPC message and sends it to the remote
--- process.
---
- ---@param payload (table) Converted into a JSON string, see |json_encode()|
+ ---@param payload table
---@returns true if the payload could be scheduled, false if the main event-loop is in the process of closing.
local function encode_and_send(payload)
local _ = log.debug() and log.debug("rpc.send", payload)
if handle == nil or handle:is_closing() then return false end
- -- TODO(ashkan) remove this once we have a Lua json_encode
- schedule(function()
- local encoded = assert(json_encode(payload))
- stdin:write(format_message_with_content_length(encoded))
- end)
+ local encoded = vim.json.encode(payload)
+ stdin:write(format_message_with_content_length(encoded))
return true
end
@@ -488,16 +427,15 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params)
---@private
local function handle_body(body)
- local decoded, err = json_decode(body)
- if not decoded then
- -- on_error(client_errors.INVALID_SERVER_JSON, err)
+ local ok, decoded = pcall(vim.json.decode, body, { luanil = { object = true } })
+ if not ok then
+ on_error(client_errors.INVALID_SERVER_JSON, decoded)
return
end
local _ = log.debug() and log.debug("rpc.receive", decoded)
if type(decoded.method) == 'string' and decoded.id then
- -- Server Request
- decoded.params = convert_NIL(decoded.params)
+ local err
-- Schedule here so that the users functions don't trigger an error and
-- we can still use the result.
schedule(function()
@@ -524,22 +462,16 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params)
end)
-- This works because we are expecting vim.NIL here
elseif decoded.id and (decoded.result ~= vim.NIL or decoded.error ~= vim.NIL) then
- -- Server Result
- decoded.error = convert_NIL(decoded.error)
- decoded.result = convert_NIL(decoded.result)
-- We sent a number, so we expect a number.
local result_id = tonumber(decoded.id)
- -- Do not surface RequestCancelled or ContentModified to users, it is RPC-internal.
+ -- Do not surface RequestCancelled to users, it is RPC-internal.
if decoded.error then
local mute_error = false
if decoded.error.code == protocol.ErrorCodes.RequestCancelled then
local _ = log.debug() and log.debug("Received cancellation ack", decoded)
mute_error = true
- elseif decoded.error.code == protocol.ErrorCodes.ContentModified then
- local _ = log.debug() and log.debug("Received content modified ack", decoded)
- mute_error = true
end
if mute_error then
@@ -574,7 +506,6 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params)
end
elseif type(decoded.method) == 'string' then
-- Notification
- decoded.params = convert_NIL(decoded.params)
try_call(client_errors.NOTIFICATION_HANDLER_ERROR,
dispatchers.notification, decoded.method, decoded.params)
else
@@ -582,8 +513,6 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params)
on_error(client_errors.INVALID_SERVER_MESSAGE, decoded)
end
end
- -- TODO(ashkan) remove this once we have a Lua json_decode
- handle_body = schedule_wrap(handle_body)
local request_parser = coroutine.wrap(request_parser_loop)
request_parser()
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index e95f170427..952926b67e 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -193,6 +193,7 @@ function M.get_progress_messages()
title = ctx.title or "empty title",
message = ctx.message,
percentage = ctx.percentage,
+ done = ctx.done,
progress = true,
}
table.insert(new_messages, new_report)
@@ -334,10 +335,12 @@ function M.apply_text_edits(text_edits, bufnr)
end
if is_cursor_fixed then
- vim.api.nvim_win_set_cursor(0, {
- cursor.row + 1,
- math.min(cursor.col, #(vim.api.nvim_buf_get_lines(bufnr, cursor.row, cursor.row + 1, false)[1] or ''))
- })
+ local is_valid_cursor = true
+ is_valid_cursor = is_valid_cursor and cursor.row < vim.api.nvim_buf_line_count(bufnr)
+ is_valid_cursor = is_valid_cursor and cursor.col <= #(vim.api.nvim_buf_get_lines(bufnr, cursor.row, cursor.row + 1, false)[1] or '')
+ if is_valid_cursor then
+ vim.api.nvim_win_set_cursor(0, { cursor.row + 1, cursor.col })
+ end
end
-- Remove final line if needed
@@ -951,6 +954,11 @@ end
---@param width (number) window width (in character cells)
---@param height (number) window height (in character cells)
---@param opts (table, optional)
+--- - offset_x (number) offset to add to `col`
+--- - offset_y (number) offset to add to `row`
+--- - border (string or table) override `border`
+--- - focusable (string or table) override `focusable`
+--- - zindex (string or table) override `zindex`, defaults to 50
---@returns (table) Options
function M.make_floating_popup_options(width, height, opts)
validate {
@@ -975,7 +983,7 @@ function M.make_floating_popup_options(width, height, opts)
else
anchor = anchor..'S'
height = math.min(lines_above, height)
- row = -get_border_size(opts).height
+ row = 0
end
if vim.fn.wincol() + width + (opts.offset_x or 0) <= api.nvim_get_option('columns') then
@@ -1124,8 +1132,6 @@ end
--- - wrap_at character to wrap at for computing height
--- - max_width maximal width of floating window
--- - max_height maximal height of floating window
---- - pad_left number of columns to pad contents at left
---- - pad_right number of columns to pad contents at right
--- - pad_top number of lines to pad contents at top
--- - pad_bottom number of lines to pad contents at bottom
--- - separator insert separator after code block
@@ -1376,8 +1382,6 @@ end
--- - wrap_at character to wrap at for computing height when wrap is enabled
--- - max_width maximal width of floating window
--- - max_height maximal height of floating window
---- - pad_left number of columns to pad contents at left
---- - pad_right number of columns to pad contents at right
--- - pad_top number of lines to pad contents at top
--- - pad_bottom number of lines to pad contents at bottom
--- - focus_id if a popup with this id is opened, then focus it
diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua
index 18c1e21049..b57b7ad4ad 100644
--- a/runtime/lua/vim/shared.lua
+++ b/runtime/lua/vim/shared.lua
@@ -98,17 +98,53 @@ end
--- <pre>
--- split(":aa::b:", ":") --> {'','aa','','b',''}
--- split("axaby", "ab?") --> {'','x','y'}
---- split(x*yz*o, "*", true) --> {'x','yz','o'}
+--- split("x*yz*o", "*", {plain=true}) --> {'x','yz','o'}
+--- split("|x|y|z|", "|", {trimempty=true}) --> {'x', 'y', 'z'}
--- </pre>
---
+---
---@see |vim.gsplit()|
---
---@param s String to split
---@param sep Separator string or pattern
----@param plain If `true` use `sep` literally (passed to String.find)
+---@param kwargs Keyword arguments:
+--- - plain: (boolean) If `true` use `sep` literally (passed to string.find)
+--- - trimempty: (boolean) If `true` remove empty items from the front
+--- and back of the list
---@returns List-like table of the split components.
-function vim.split(s,sep,plain)
- local t={} for c in vim.gsplit(s, sep, plain) do table.insert(t,c) end
+function vim.split(s, sep, kwargs)
+ local plain
+ local trimempty = false
+ if type(kwargs) == 'boolean' then
+ -- Support old signature for backward compatibility
+ plain = kwargs
+ else
+ vim.validate { kwargs = {kwargs, 't', true} }
+ kwargs = kwargs or {}
+ plain = kwargs.plain
+ trimempty = kwargs.trimempty
+ end
+
+ local t = {}
+ local skip = trimempty
+ for c in vim.gsplit(s, sep, plain) do
+ if c ~= "" then
+ skip = false
+ end
+
+ if not skip then
+ table.insert(t, c)
+ end
+ end
+
+ if trimempty then
+ for i = #t, 1, -1 do
+ if t[i] ~= "" then
+ break
+ end
+ table.remove(t, i)
+ end
+ end
+
return t
end
diff --git a/runtime/lua/vim/treesitter/health.lua b/runtime/lua/vim/treesitter/health.lua
index e031ba1bd6..53ccc6e88d 100644
--- a/runtime/lua/vim/treesitter/health.lua
+++ b/runtime/lua/vim/treesitter/health.lua
@@ -9,7 +9,7 @@ function M.list_parsers()
end
--- Performs a healthcheck for treesitter integration
-function M.check_health()
+function M.check()
local report_info = vim.fn['health#report_info']
local report_ok = vim.fn['health#report_ok']
local report_error = vim.fn['health#report_error']
diff --git a/runtime/lua/vim/ui.lua b/runtime/lua/vim/ui.lua
new file mode 100644
index 0000000000..5eab20fc54
--- /dev/null
+++ b/runtime/lua/vim/ui.lua
@@ -0,0 +1,36 @@
+local M = {}
+
+--- Prompts the user to pick a single item from a collection of entries
+---
+---@param items table Arbitrary items
+---@param opts table Additional options
+--- - prompt (string|nil)
+--- Text of the prompt. Defaults to `Select one of:`
+--- - format_item (function item -> text)
+--- Function to format an
+--- individual item from `items`. Defaults to `tostring`.
+---@param on_choice function ((item|nil, idx|nil) -> ())
+--- Called once the user made a choice.
+--- `idx` is the 1-based index of `item` within `item`.
+--- `nil` if the user aborted the dialog.
+function M.select(items, opts, on_choice)
+ vim.validate {
+ items = { items, 'table', false },
+ on_choice = { on_choice, 'function', false },
+ }
+ opts = opts or {}
+ local choices = {opts.prompt or 'Select one of:'}
+ local format_item = opts.format_item or tostring
+ for i, item in pairs(items) do
+ table.insert(choices, string.format('%d: %s', i, format_item(item)))
+ end
+ local choice = vim.fn.inputlist(choices)
+ if choice < 1 or choice > #items then
+ on_choice(nil, nil)
+ else
+ on_choice(items[choice], choice)
+ end
+end
+
+
+return M
diff --git a/runtime/lua/vim/uri.lua b/runtime/lua/vim/uri.lua
index a3e79a0f2b..5d8d4fa169 100644
--- a/runtime/lua/vim/uri.lua
+++ b/runtime/lua/vim/uri.lua
@@ -75,13 +75,22 @@ local function uri_from_fname(path)
end
local URI_SCHEME_PATTERN = '^([a-zA-Z]+[a-zA-Z0-9+-.]*):.*'
+local WINDOWS_URI_SCHEME_PATTERN = '^([a-zA-Z]+[a-zA-Z0-9+-.]*):[a-zA-Z]:.*'
--- Get a URI from a bufnr
---@param bufnr (number): Buffer number
---@return URI
local function uri_from_bufnr(bufnr)
local fname = vim.api.nvim_buf_get_name(bufnr)
- local scheme = fname:match(URI_SCHEME_PATTERN)
+ local volume_path = fname:match("^([a-zA-Z]:).*")
+ local is_windows = volume_path ~= nil
+ local scheme
+ if is_windows then
+ fname = fname:gsub("\\", "/")
+ scheme = fname:match(WINDOWS_URI_SCHEME_PATTERN)
+ else
+ scheme = fname:match(URI_SCHEME_PATTERN)
+ end
if scheme then
return fname
else
diff --git a/runtime/plugin/diagnostic.vim b/runtime/plugin/diagnostic.vim
deleted file mode 100644
index 2183623ac8..0000000000
--- a/runtime/plugin/diagnostic.vim
+++ /dev/null
@@ -1,26 +0,0 @@
-" :help vim.diagnostic
-
-hi default DiagnosticError ctermfg=1 guifg=Red
-hi default DiagnosticWarn ctermfg=3 guifg=Orange
-hi default DiagnosticInfo ctermfg=4 guifg=LightBlue
-hi default DiagnosticHint ctermfg=7 guifg=LightGrey
-
-hi default DiagnosticUnderlineError cterm=underline gui=underline guisp=Red
-hi default DiagnosticUnderlineWarn cterm=underline gui=underline guisp=Orange
-hi default DiagnosticUnderlineInfo cterm=underline gui=underline guisp=LightBlue
-hi default DiagnosticUnderlineHint cterm=underline gui=underline guisp=LightGrey
-
-hi default link DiagnosticVirtualTextError DiagnosticError
-hi default link DiagnosticVirtualTextWarn DiagnosticWarn
-hi default link DiagnosticVirtualTextInfo DiagnosticInfo
-hi default link DiagnosticVirtualTextHint DiagnosticHint
-
-hi default link DiagnosticFloatingError DiagnosticError
-hi default link DiagnosticFloatingWarn DiagnosticWarn
-hi default link DiagnosticFloatingInfo DiagnosticInfo
-hi default link DiagnosticFloatingHint DiagnosticHint
-
-hi default link DiagnosticSignError DiagnosticError
-hi default link DiagnosticSignWarn DiagnosticWarn
-hi default link DiagnosticSignInfo DiagnosticInfo
-hi default link DiagnosticSignHint DiagnosticHint
diff --git a/runtime/syntax/8th.vim b/runtime/syntax/8th.vim
index d543489b72..ce27d10a44 100644
--- a/runtime/syntax/8th.vim
+++ b/runtime/syntax/8th.vim
@@ -1,6 +1,7 @@
" Vim syntax file
" Language: 8th
-" Version: 19.01d
+" Version: 21.08
+" Last Change: 2021 Sep 20
" Maintainer: Ron Aaron <ron@aaron-tech.com>
" URL: https://8th-dev.com/
" Filetypes: *.8th
@@ -30,246 +31,318 @@ syn match eighthClassWord "\<\S\+:.\+" contains=eighthClasses
syn keyword eighthEndOfColonDef ; i;
syn keyword eighthDefine var var,
-" Built in words
+" Built in words:
com! -nargs=+ Builtin syn keyword eighthBuiltin <args>
-"Builtin ^ < <# <#> = > - -- ,# ; ;; ! ??? / . .# ' () @ * */ \
-Builtin ! G:! #! G:#! ## G:## #> G:#> #if G:#if ' G:' ( G:( (* G:(* (:) G:(:) (code) G:(code) (getc) G:(getc)
-Builtin (gets) G:(gets) (interp) G:(interp) (needs) G:(needs) (putc) G:(putc) (puts) G:(puts) (putslim) G:(putslim)
-Builtin (say) G:(say) (stat) G:(stat) ) G:) +listener G:+listener +ref G:+ref ,# G:,# -- G:-- -----BEGIN G:-----BEGIN
-Builtin -Inf G:-Inf -Inf? G:-Inf? -listener G:-listener -ref G:-ref -rot G:-rot . G:. .# G:.# .needs G:.needs
-Builtin .r G:.r .s G:.s .stats G:.stats .ver G:.ver .with G:.with 0; G:0; 2dip G:2dip 2drop G:2drop
-Builtin 2dup G:2dup 2over G:2over 2swap G:2swap 3drop G:3drop 4drop G:4drop 8thdt? G:8thdt? 8thver? G:8thver?
-Builtin : G:: ; G:; ;; G:;; ;;; G:;;; ;then G:;then ;with G:;with <# G:<# <#> G:<#> >clip G:>clip >json G:>json
-Builtin >kind G:>kind >n G:>n >r G:>r >s G:>s ?: G:?: ??? G:??? @ G:@ Inf G:Inf Inf? G:Inf? NaN G:NaN
-Builtin NaN? G:NaN? SED-CHECK G:SED-CHECK SED: G:SED: SED: G:SED: \ G:\ ` G:` `` G:`` actor: G:actor:
-Builtin again G:again ahead G:ahead and G:and appname G:appname apropos G:apropos argc G:argc args G:args
-Builtin array? G:array? assert G:assert base G:base bi G:bi bits G:bits break G:break break? G:break?
-Builtin build? G:build? buildver? G:buildver? bye G:bye c# G:c# c/does G:c/does case G:case caseof G:caseof
-Builtin chdir G:chdir clip> G:clip> clone G:clone clone-shallow G:clone-shallow cold G:cold compat-level G:compat-level
-Builtin compile G:compile compile? G:compile? conflict G:conflict const G:const container? G:container?
-Builtin cr G:cr curlang G:curlang curry G:curry curry: G:curry: decimal G:decimal defer: G:defer: deg>rad G:deg>rad
-Builtin depth G:depth die G:die dip G:dip drop G:drop dstack G:dstack dump G:dump dup G:dup dup? G:dup?
-Builtin else G:else enum: G:enum: eval G:eval eval! G:eval! eval0 G:eval0 execnull G:execnull expect G:expect
-Builtin extra! G:extra! extra@ G:extra@ false G:false fnv G:fnv fourth G:fourth free G:free func: G:func:
-Builtin getc G:getc getcwd G:getcwd getenv G:getenv gets G:gets handler G:handler header G:header help G:help
-Builtin hex G:hex i: G:i: i; G:i; if G:if if; G:if; isa? G:isa? items-used G:items-used jcall G:jcall
-Builtin jclass G:jclass jmethod G:jmethod json-nesting G:json-nesting json-pretty G:json-pretty json-throw G:json-throw
-Builtin json> G:json> k32 G:k32 keep G:keep l: G:l: last G:last lib G:lib libbin G:libbin libc G:libc
+Builtin args #:args b #:b dhm #:dhm exec# #:exec# id2ns #:id2ns id? #:id? idd #:idd key #:key oa #:oa
+Builtin oid #:oid okey #:okey with #:with with! #:with! zip #:zip gen-secret 2fa:gen-secret gen-url 2fa:gen-url
+Builtin validate-code 2fa:validate-code ! G:! #! G:#! ## G:## #> G:#> #if G:#if ' G:' ( G:( (* G:(*
+Builtin (:) G:(:) (code) G:(code) (defer) G:(defer) (dump) G:(dump) (getc) G:(getc) (gets) G:(gets)
+Builtin (interp) G:(interp) (log) G:(log) (needs) G:(needs) (parseln) G:(parseln) (putc) G:(putc) (puts) G:(puts)
+Builtin (putslim) G:(putslim) (stat) G:(stat) (with) G:(with) ) G:) +hook G:+hook +listener G:+listener
+Builtin +ref G:+ref ,# G:,# -- G:-- -----BEGIN G:-----BEGIN -Inf G:-Inf -Inf? G:-Inf? -hook G:-hook
+Builtin -listener G:-listener -ref G:-ref -rot G:-rot . G:. .# G:.# .hook G:.hook .needs G:.needs .r G:.r
+Builtin .s G:.s .s-truncate G:.s-truncate .stats G:.stats .ver G:.ver .with G:.with 0; G:0; 2dip G:2dip
+Builtin 2drop G:2drop 2dup G:2dup 2over G:2over 2swap G:2swap 3drop G:3drop 3rev G:3rev 4drop G:4drop
+Builtin 8thdt? G:8thdt? 8thsku G:8thsku 8thver? G:8thver? 8thvernum? G:8thvernum? : G:: ; G:; ;; G:;;
+Builtin ;;; G:;;; ;with G:;with <# G:<# <#> G:<#> >clip G:>clip >json G:>json >kind G:>kind >n G:>n
+Builtin >r G:>r >s G:>s ?: G:?: @ G:@ BITMAP: G:BITMAP: ENUM: G:ENUM: FLAG: G:FLAG: Inf G:Inf Inf? G:Inf?
+Builtin NaN G:NaN NaN? G:NaN? SED-CHECK G:SED-CHECK SED: G:SED: SED: G:SED: \ G:\ _dup G:_dup _swap G:_swap
+Builtin actor: G:actor: again G:again ahead G:ahead and G:and appname G:appname apropos G:apropos argc G:argc
+Builtin args G:args array? G:array? assert G:assert base G:base bi G:bi bits G:bits break G:break break? G:break?
+Builtin breakif G:breakif build? G:build? buildver? G:buildver? bye G:bye c# G:c# c/does G:c/does case: G:case:
+Builtin catch G:catch chdir G:chdir clip> G:clip> clone G:clone clone-shallow G:clone-shallow cold G:cold
+Builtin compile G:compile compile? G:compile? compiling? G:compiling? conflict G:conflict const G:const
+Builtin container? G:container? counting-allocations G:counting-allocations cr G:cr curlang G:curlang
+Builtin curry G:curry curry: G:curry: decimal G:decimal default: G:default: defer: G:defer: deferred: G:deferred:
+Builtin deg>rad G:deg>rad depth G:depth die G:die dip G:dip drop G:drop dstack G:dstack dump G:dump
+Builtin dup G:dup dup>r G:dup>r dup? G:dup? e# G:e# enum: G:enum: error? G:error? eval G:eval eval! G:eval!
+Builtin eval0 G:eval0 execnull G:execnull expect G:expect extra! G:extra! extra@ G:extra@ false G:false
+Builtin fnv G:fnv fourth G:fourth free G:free func: G:func: getc G:getc getcwd G:getcwd getenv G:getenv
+Builtin gets G:gets handler G:handler header G:header help G:help hex G:hex i: G:i: i; G:i; isa? G:isa?
+Builtin items-used G:items-used jcall G:jcall jclass G:jclass jmethod G:jmethod json! G:json! json-8th> G:json-8th>
+Builtin json-nesting G:json-nesting json-pretty G:json-pretty json-throw G:json-throw json> G:json>
+Builtin json@ G:json@ k32 G:k32 keep G:keep l: G:l: last G:last lib G:lib libbin G:libbin libc G:libc
Builtin listener@ G:listener@ literal G:literal locals: G:locals: lock G:lock lock-to G:lock-to locked? G:locked?
-Builtin log G:log log-async G:log-async log-task G:log-task log-time G:log-time log-time-local G:log-time-local
-Builtin long-days G:long-days long-months G:long-months loop G:loop loop- G:loop- map? G:map? mark G:mark
-Builtin mark? G:mark? memfree G:memfree mobile? G:mobile? n# G:n# name>os G:name>os name>sem G:name>sem
-Builtin ndrop G:ndrop needs G:needs new G:new next-arg G:next-arg nip G:nip noop G:noop not G:not ns G:ns
-Builtin ns: G:ns: ns>ls G:ns>ls ns>s G:ns>s ns? G:ns? null G:null null; G:null; null? G:null? number? G:number?
-Builtin off G:off on G:on onexit G:onexit only G:only op! G:op! or G:or os G:os os-names G:os-names
-Builtin os>long-name G:os>long-name os>name G:os>name over G:over p: G:p: pack G:pack parse G:parse
-Builtin parsech G:parsech parseln G:parseln parsews G:parsews pick G:pick poke G:poke pool-clear G:pool-clear
-Builtin prior G:prior private G:private process-args G:process-args prompt G:prompt public G:public
-Builtin putc G:putc puts G:puts putslim G:putslim quote G:quote r! G:r! r> G:r> r@ G:r@ rad>deg G:rad>deg
-Builtin rand G:rand rand-pcg G:rand-pcg rand-pcg-seed G:rand-pcg-seed randbuf G:randbuf randbuf-pcg G:randbuf-pcg
-Builtin rdrop G:rdrop recurse G:recurse recurse-stack G:recurse-stack ref@ G:ref@ reg! G:reg! reg@ G:reg@
-Builtin regbin@ G:regbin@ remaining-args G:remaining-args repeat G:repeat reset G:reset roll G:roll
-Builtin rop! G:rop! rot G:rot rpick G:rpick rroll G:rroll rstack G:rstack rswap G:rswap rusage G:rusage
-Builtin s>ns G:s>ns same? G:same? scriptdir G:scriptdir scriptfile G:scriptfile sem G:sem sem-post G:sem-post
-Builtin sem-rm G:sem-rm sem-wait G:sem-wait sem-wait? G:sem-wait? sem>name G:sem>name semi-throw G:semi-throw
-Builtin set-wipe G:set-wipe setenv G:setenv settings! G:settings! settings![] G:settings![] settings@ G:settings@
-Builtin settings@? G:settings@? settings@[] G:settings@[] sh G:sh sh$ G:sh$ short-days G:short-days
-Builtin short-months G:short-months sleep G:sleep space G:space stack-check G:stack-check stack-size G:stack-size
-Builtin step G:step string? G:string? struct: G:struct: swap G:swap syslang G:syslang sysregion G:sysregion
+Builtin log G:log log-syslog G:log-syslog log-task G:log-task log-time G:log-time log-time-local G:log-time-local
+Builtin long-days G:long-days long-months G:long-months longjmp G:longjmp lookup G:lookup loop G:loop
+Builtin loop- G:loop- map? G:map? mark G:mark mark? G:mark? memfree G:memfree mobile? G:mobile? n# G:n#
+Builtin name>os G:name>os name>sem G:name>sem ndrop G:ndrop needs G:needs new G:new next-arg G:next-arg
+Builtin nip G:nip noop G:noop not G:not nothrow G:nothrow ns G:ns ns: G:ns: ns>ls G:ns>ls ns>s G:ns>s
+Builtin ns? G:ns? null G:null null; G:null; null? G:null? number? G:number? of: G:of: off G:off on G:on
+Builtin onexit G:onexit only G:only op! G:op! or G:or os G:os os-names G:os-names os>long-name G:os>long-name
+Builtin os>name G:os>name over G:over p: G:p: pack G:pack parse G:parse parse-csv G:parse-csv parsech G:parsech
+Builtin parseln G:parseln parsews G:parsews pick G:pick poke G:poke pool-clear G:pool-clear pool-clear-all G:pool-clear-all
+Builtin prior G:prior private G:private process-args G:process-args process-args-fancy G:process-args-fancy
+Builtin process-args-help G:process-args-help process-args-vars G:process-args-vars prompt G:prompt
+Builtin public G:public putc G:putc puts G:puts putslim G:putslim quote G:quote r! G:r! r> G:r> r@ G:r@
+Builtin rad>deg G:rad>deg rand-jit G:rand-jit rand-jsf G:rand-jsf rand-native G:rand-native rand-normal G:rand-normal
+Builtin rand-pcg G:rand-pcg rand-pcg-seed G:rand-pcg-seed rand-range G:rand-range rand-select G:rand-select
+Builtin randbuf-pcg G:randbuf-pcg random G:random rdrop G:rdrop recurse G:recurse recurse-stack G:recurse-stack
+Builtin ref@ G:ref@ reg! G:reg! reg@ G:reg@ regbin@ G:regbin@ remaining-args G:remaining-args repeat G:repeat
+Builtin required? G:required? requires G:requires reset G:reset roll G:roll rop! G:rop! rot G:rot rpick G:rpick
+Builtin rroll G:rroll rstack G:rstack rswap G:rswap rusage G:rusage s>ns G:s>ns same? G:same? scriptdir G:scriptdir
+Builtin scriptfile G:scriptfile sem G:sem sem-post G:sem-post sem-rm G:sem-rm sem-wait G:sem-wait sem-wait? G:sem-wait?
+Builtin sem>name G:sem>name semi-throw G:semi-throw set-wipe G:set-wipe setenv G:setenv setjmp G:setjmp
+Builtin settings! G:settings! settings![] G:settings![] settings@ G:settings@ settings@? G:settings@?
+Builtin settings@[] G:settings@[] sh G:sh sh$ G:sh$ short-days G:short-days short-months G:short-months
+Builtin sleep G:sleep sleep-until G:sleep-until slog G:slog space G:space stack-check G:stack-check
+Builtin stack-size G:stack-size step G:step sthrow G:sthrow string? G:string? struct: G:struct: swap G:swap
Builtin tab-hook G:tab-hook tell-conflict G:tell-conflict tempdir G:tempdir tempfilename G:tempfilename
-Builtin then G:then third G:third throw G:throw thrownull G:thrownull times G:times tlog G:tlog tri G:tri
-Builtin true G:true tuck G:tuck type-check G:type-check typeassert G:typeassert unlock G:unlock unpack G:unpack
-Builtin until G:until until! G:until! var G:var var, G:var, while G:while while! G:while! with: G:with:
+Builtin third G:third throw G:throw thrownull G:thrownull times G:times tlog G:tlog tri G:tri true G:true
+Builtin tuck G:tuck type-check G:type-check typeassert G:typeassert uid G:uid uname G:uname unlock G:unlock
+Builtin unpack G:unpack until G:until until! G:until! while G:while while! G:while! with: G:with: word? G:word?
Builtin words G:words words-like G:words-like words/ G:words/ xchg G:xchg xor G:xor >auth HTTP:>auth
-Builtin sh I:sh tpush I:tpush trace-word I:trace-word call JSONRPC:call auth-string OAuth:auth-string
-Builtin gen-nonce OAuth:gen-nonce params OAuth:params call SOAP:call ! a:! + a:+ - a:- 2each a:2each
-Builtin 2map a:2map 2map+ a:2map+ 2map= a:2map= = a:= >map a:>map @ a:@ @@ a:@@ bsearch a:bsearch clear a:clear
-Builtin close a:close diff a:diff dot a:dot each a:each each-slice a:each-slice exists? a:exists? filter a:filter
-Builtin generate a:generate group a:group indexof a:indexof insert a:insert intersect a:intersect join a:join
-Builtin len a:len map a:map map+ a:map+ map= a:map= mean a:mean mean&variance a:mean&variance new a:new
-Builtin op a:op op! a:op! op= a:op= open a:open pop a:pop push a:push qsort a:qsort randeach a:randeach
-Builtin reduce a:reduce reduce+ a:reduce+ rev a:rev shift a:shift shuffle a:shuffle slice a:slice slice+ a:slice+
-Builtin slide a:slide sort a:sort union a:union when a:when when! a:when! x a:x x-each a:x-each xchg a:xchg
-Builtin y a:y zip a:zip 8thdir app:8thdir asset app:asset atrun app:atrun atrun app:atrun atrun app:atrun
-Builtin basedir app:basedir current app:current datadir app:datadir exename app:exename isgui app:isgui
-Builtin main app:main oncrash app:oncrash orientation app:orientation pid app:pid restart app:restart
-Builtin resumed app:resumed shared? app:shared? standalone app:standalone subdir app:subdir suspended app:suspended
-Builtin sysquit app:sysquit (here) asm:(here) >n asm:>n avail asm:avail c, asm:c, here! asm:here! n> asm:n>
-Builtin used asm:used w, asm:w, ! b:! + b:+ / b:/ = b:= >base64 b:>base64 >hex b:>hex >mpack b:>mpack
-Builtin @ b:@ append b:append base64> b:base64> bit! b:bit! bit@ b:bit@ clear b:clear compress b:compress
-Builtin conv b:conv each b:each each-slice b:each-slice expand b:expand fill b:fill getb b:getb hex> b:hex>
-Builtin len b:len mem> b:mem> move b:move mpack-date b:mpack-date mpack-ignore b:mpack-ignore mpack> b:mpack>
-Builtin new b:new op b:op rev b:rev search b:search shmem b:shmem slice b:slice splice b:splice ungetb b:ungetb
-Builtin writable b:writable xor b:xor +block bc:+block .blocks bc:.blocks add-block bc:add-block block-hash bc:block-hash
+Builtin (curry) I:(curry) notimpl I:notimpl sh I:sh trace-word I:trace-word call JSONRPC:call auth-string OAuth:auth-string
+Builtin gen-nonce OAuth:gen-nonce params OAuth:params call SOAP:call ! a:! + a:+ - a:- / a:/ 2each a:2each
+Builtin 2map a:2map 2map+ a:2map+ 2map= a:2map= = a:= @ a:@ @? a:@? _@ a:_@ all a:all any a:any bsearch a:bsearch
+Builtin centroid a:centroid clear a:clear close a:close diff a:diff dot a:dot each a:each each! a:each!
+Builtin each-slice a:each-slice exists? a:exists? filter a:filter generate a:generate group a:group
+Builtin indexof a:indexof insert a:insert intersect a:intersect join a:join len a:len map a:map map+ a:map+
+Builtin map= a:map= mean a:mean mean&variance a:mean&variance merge a:merge new a:new op! a:op! open a:open
+Builtin pop a:pop push a:push qsort a:qsort randeach a:randeach reduce a:reduce reduce+ a:reduce+ remove a:remove
+Builtin rev a:rev shift a:shift shuffle a:shuffle slice a:slice slice+ a:slice+ slide a:slide smear a:smear
+Builtin sort a:sort union a:union x a:x x-each a:x-each xchg a:xchg y a:y zip a:zip 8thdir app:8thdir
+Builtin asset app:asset atrun app:atrun atrun app:atrun atrun app:atrun basedir app:basedir current app:current
+Builtin datadir app:datadir exename app:exename lowmem app:lowmem main app:main name app:name oncrash app:oncrash
+Builtin opts! app:opts! opts@ app:opts@ orientation app:orientation orientation! app:orientation! pid app:pid
+Builtin post-main app:post-main pre-main app:pre-main raise app:raise request-perm app:request-perm
+Builtin restart app:restart resumed app:resumed signal app:signal standalone app:standalone subdir app:subdir
+Builtin suspended app:suspended sysquit app:sysquit terminated app:terminated trap app:trap (here) asm:(here)
+Builtin >n asm:>n avail asm:avail c, asm:c, here! asm:here! n> asm:n> used asm:used w, asm:w, ! b:!
+Builtin + b:+ / b:/ 1+ b:1+ 1- b:1- = b:= >base16 b:>base16 >base32 b:>base32 >base64 b:>base64 >base85 b:>base85
+Builtin >hex b:>hex >mpack b:>mpack @ b:@ append b:append base16> b:base16> base32> b:base32> base64> b:base64>
+Builtin base85> b:base85> bit! b:bit! bit@ b:bit@ clear b:clear compress b:compress conv b:conv each b:each
+Builtin each! b:each! each-slice b:each-slice expand b:expand fill b:fill getb b:getb hex> b:hex> len b:len
+Builtin mem> b:mem> move b:move mpack-compat b:mpack-compat mpack-date b:mpack-date mpack-ignore b:mpack-ignore
+Builtin mpack> b:mpack> n! b:n! n+ b:n+ n@ b:n@ new b:new op b:op pad b:pad rev b:rev search b:search
+Builtin shmem b:shmem slice b:slice splice b:splice ungetb b:ungetb unpad b:unpad writable b:writable
+Builtin xor b:xor +block bc:+block .blocks bc:.blocks add-block bc:add-block block-hash bc:block-hash
Builtin block@ bc:block@ first-block bc:first-block hash bc:hash last-block bc:last-block load bc:load
Builtin new bc:new save bc:save set-sql bc:set-sql validate bc:validate validate-block bc:validate-block
Builtin add bloom:add filter bloom:filter in? bloom:in? accept bt:accept ch! bt:ch! ch@ bt:ch@ connect bt:connect
-Builtin disconnect bt:disconnect err? bt:err? leconnect bt:leconnect lescan bt:lescan listen bt:listen
+Builtin disconnect bt:disconnect init bt:init leconnect bt:leconnect lescan bt:lescan listen bt:listen
Builtin on? bt:on? read bt:read scan bt:scan service? bt:service? services? bt:services? write bt:write
Builtin * c:* * c:* + c:+ + c:+ = c:= = c:= >ri c:>ri >ri c:>ri abs c:abs abs c:abs arg c:arg arg c:arg
-Builtin conj c:conj conj c:conj im c:im n> c:n> new c:new new c:new re c:re >aes128gcm cr:>aes128gcm
-Builtin >aes256gcm cr:>aes256gcm >cp cr:>cp >cpe cr:>cpe >decrypt cr:>decrypt >edbox cr:>edbox >encrypt cr:>encrypt
-Builtin >nbuf cr:>nbuf >rsabox cr:>rsabox >uuid cr:>uuid CBC cr:CBC CFB cr:CFB CTR cr:CTR ECB cr:ECB
-Builtin GCM cr:GCM OFB cr:OFB aad? cr:aad? aes128box-sig cr:aes128box-sig aes128gcm> cr:aes128gcm>
-Builtin aes256box-sig cr:aes256box-sig aes256gcm> cr:aes256gcm> aesgcm cr:aesgcm blakehash cr:blakehash
-Builtin chacha20box-sig cr:chacha20box-sig chachapoly cr:chachapoly cipher! cr:cipher! cipher@ cr:cipher@
-Builtin cp> cr:cp> cpe> cr:cpe> decrypt cr:decrypt decrypt+ cr:decrypt+ decrypt> cr:decrypt> dh-genkey cr:dh-genkey
-Builtin dh-secret cr:dh-secret dh-sign cr:dh-sign dh-verify cr:dh-verify ebox-sig cr:ebox-sig ecc-genkey cr:ecc-genkey
-Builtin ecc-secret cr:ecc-secret ecc-sign cr:ecc-sign ecc-verify cr:ecc-verify edbox-sig cr:edbox-sig
-Builtin edbox> cr:edbox> encrypt cr:encrypt encrypt+ cr:encrypt+ encrypt> cr:encrypt> ensurekey cr:ensurekey
-Builtin err? cr:err? gcm-tag-size cr:gcm-tag-size genkey cr:genkey hash cr:hash hash! cr:hash! hash+ cr:hash+
-Builtin hash>b cr:hash>b hash>s cr:hash>s hash@ cr:hash@ hmac cr:hmac hotp cr:hotp iv? cr:iv? mode cr:mode
-Builtin mode@ cr:mode@ randkey cr:randkey restore cr:restore root-certs cr:root-certs rsa_decrypt cr:rsa_decrypt
-Builtin rsa_encrypt cr:rsa_encrypt rsa_sign cr:rsa_sign rsa_verify cr:rsa_verify rsabox-sig cr:rsabox-sig
-Builtin rsabox> cr:rsabox> rsagenkey cr:rsagenkey save cr:save sbox-sig cr:sbox-sig sha1-hmac cr:sha1-hmac
-Builtin shard cr:shard tag? cr:tag? totp cr:totp totp-epoch cr:totp-epoch totp-time-step cr:totp-time-step
-Builtin unshard cr:unshard uuid cr:uuid uuid> cr:uuid> validate-pgp-sig cr:validate-pgp-sig (.hebrew) d:(.hebrew)
-Builtin (.islamic) d:(.islamic) + d:+ +day d:+day +hour d:+hour +min d:+min +msec d:+msec - d:- .hebrew d:.hebrew
-Builtin .islamic d:.islamic .time d:.time / d:/ = d:= >fixed d:>fixed >hebepoch d:>hebepoch >msec d:>msec
-Builtin >unix d:>unix >ymd d:>ymd Adar d:Adar Adar2 d:Adar2 Adar2 d:Adar2 Av d:Av Elul d:Elul Fri d:Fri
-Builtin Heshvan d:Heshvan Iyar d:Iyar Kislev d:Kislev Mon d:Mon Nissan d:Nissan Sat d:Sat Shevat d:Shevat
-Builtin Sivan d:Sivan Sun d:Sun Tammuz d:Tammuz Tevet d:Tevet Thu d:Thu Tishrei d:Tishrei Tue d:Tue
-Builtin Wed d:Wed adjust-dst d:adjust-dst between d:between d. d:d. dawn d:dawn days-in-hebrew-year d:days-in-hebrew-year
-Builtin displaying-hebrew d:displaying-hebrew do-dawn d:do-dawn do-dusk d:do-dusk do-rise d:do-rise
-Builtin doy d:doy dst? d:dst? dstquery d:dstquery dstzones? d:dstzones? dusk d:dusk elapsed-timer d:elapsed-timer
-Builtin elapsed-timer-seconds d:elapsed-timer-seconds first-dow d:first-dow fixed> d:fixed> fixed>dow d:fixed>dow
-Builtin fixed>hebrew d:fixed>hebrew fixed>islamic d:fixed>islamic format d:format hanukkah d:hanukkah
-Builtin hebrew-epoch d:hebrew-epoch hebrew>fixed d:hebrew>fixed hebrewtoday d:hebrewtoday hmonth-name d:hmonth-name
-Builtin islamic.epoch d:islamic.epoch islamic>fixed d:islamic>fixed islamictoday d:islamictoday join d:join
-Builtin last-day-of-hebrew-month d:last-day-of-hebrew-month last-dow d:last-dow last-month d:last-month
-Builtin last-week d:last-week last-year d:last-year latitude d:latitude longitude d:longitude longitude d:longitude
-Builtin msec d:msec msec> d:msec> new d:new next-dow d:next-dow next-month d:next-month next-week d:next-week
-Builtin next-year d:next-year number>hebrew d:number>hebrew omer d:omer parse d:parse pesach d:pesach
+Builtin conj c:conj conj c:conj im c:im n> c:n> new c:new new c:new re c:re >redir con:>redir accept con:accept
+Builtin accept-pwd con:accept-pwd ansi? con:ansi? black con:black blue con:blue clreol con:clreol cls con:cls
+Builtin cyan con:cyan down con:down free con:free getxy con:getxy gotoxy con:gotoxy green con:green
+Builtin key con:key key? con:key? left con:left load-history con:load-history magenta con:magenta onBlack con:onBlack
+Builtin onBlue con:onBlue onCyan con:onCyan onGreen con:onGreen onMagenta con:onMagenta onRed con:onRed
+Builtin onWhite con:onWhite onYellow con:onYellow print con:print red con:red redir> con:redir> redir? con:redir?
+Builtin right con:right save-history con:save-history size? con:size? up con:up white con:white yellow con:yellow
+Builtin >aes128gcm cr:>aes128gcm >aes256gcm cr:>aes256gcm >cp cr:>cp >cpe cr:>cpe >decrypt cr:>decrypt
+Builtin >edbox cr:>edbox >encrypt cr:>encrypt >nbuf cr:>nbuf >rsabox cr:>rsabox >uuid cr:>uuid CBC cr:CBC
+Builtin CFB cr:CFB CTR cr:CTR ECB cr:ECB GCM cr:GCM OFB cr:OFB aad? cr:aad? aes128box-sig cr:aes128box-sig
+Builtin aes128gcm> cr:aes128gcm> aes256box-sig cr:aes256box-sig aes256gcm> cr:aes256gcm> aesgcm cr:aesgcm
+Builtin blakehash cr:blakehash chacha20box-sig cr:chacha20box-sig chachapoly cr:chachapoly cipher! cr:cipher!
+Builtin cipher@ cr:cipher@ cp> cr:cp> cpe> cr:cpe> decrypt cr:decrypt decrypt+ cr:decrypt+ decrypt> cr:decrypt>
+Builtin dh-genkey cr:dh-genkey dh-secret cr:dh-secret dh-sign cr:dh-sign dh-verify cr:dh-verify ebox-sig cr:ebox-sig
+Builtin ecc-genkey cr:ecc-genkey ecc-secret cr:ecc-secret ecc-sign cr:ecc-sign ecc-verify cr:ecc-verify
+Builtin edbox-sig cr:edbox-sig edbox> cr:edbox> encrypt cr:encrypt encrypt+ cr:encrypt+ encrypt> cr:encrypt>
+Builtin ensurekey cr:ensurekey gcm-tag-size cr:gcm-tag-size genkey cr:genkey hash cr:hash hash! cr:hash!
+Builtin hash+ cr:hash+ hash>b cr:hash>b hash>s cr:hash>s hash@ cr:hash@ hmac cr:hmac hotp cr:hotp iv? cr:iv?
+Builtin mode cr:mode mode@ cr:mode@ rand cr:rand randbuf cr:randbuf randkey cr:randkey restore cr:restore
+Builtin root-certs cr:root-certs rsa_decrypt cr:rsa_decrypt rsa_encrypt cr:rsa_encrypt rsa_sign cr:rsa_sign
+Builtin rsa_verify cr:rsa_verify rsabox-sig cr:rsabox-sig rsabox> cr:rsabox> rsagenkey cr:rsagenkey
+Builtin save cr:save sbox-sig cr:sbox-sig sha1-hmac cr:sha1-hmac shard cr:shard tag? cr:tag? totp cr:totp
+Builtin totp-epoch cr:totp-epoch totp-time-step cr:totp-time-step unshard cr:unshard uuid cr:uuid uuid> cr:uuid>
+Builtin validate-pgp-sig cr:validate-pgp-sig (.hebrew) d:(.hebrew) (.islamic) d:(.islamic) + d:+ +day d:+day
+Builtin +hour d:+hour +min d:+min +msec d:+msec - d:- .hebrew d:.hebrew .islamic d:.islamic .time d:.time
+Builtin / d:/ = d:= >fixed d:>fixed >hebepoch d:>hebepoch >jdn d:>jdn >msec d:>msec >unix d:>unix >ymd d:>ymd
+Builtin ?= d:?= Adar d:Adar Adar2 d:Adar2 Adar2 d:Adar2 Av d:Av Elul d:Elul Fri d:Fri Heshvan d:Heshvan
+Builtin Iyar d:Iyar Kislev d:Kislev Mon d:Mon Nissan d:Nissan Sat d:Sat Shevat d:Shevat Sivan d:Sivan
+Builtin Sun d:Sun Tammuz d:Tammuz Tevet d:Tevet Thu d:Thu Tishrei d:Tishrei Tue d:Tue Wed d:Wed adjust-dst d:adjust-dst
+Builtin approx! d:approx! approx? d:approx? approximates! d:approximates! between d:between d. d:d.
+Builtin dawn d:dawn days-in-hebrew-year d:days-in-hebrew-year displaying-hebrew d:displaying-hebrew
+Builtin do-dawn d:do-dawn do-dusk d:do-dusk do-rise d:do-rise doy d:doy dst? d:dst? dstquery d:dstquery
+Builtin dstzones? d:dstzones? dusk d:dusk elapsed-timer d:elapsed-timer elapsed-timer-seconds d:elapsed-timer-seconds
+Builtin first-dow d:first-dow fixed> d:fixed> fixed>dow d:fixed>dow fixed>hebrew d:fixed>hebrew fixed>islamic d:fixed>islamic
+Builtin format d:format hanukkah d:hanukkah hebrew-epoch d:hebrew-epoch hebrew>fixed d:hebrew>fixed
+Builtin hebrewtoday d:hebrewtoday hmonth-name d:hmonth-name islamic.epoch d:islamic.epoch islamic>fixed d:islamic>fixed
+Builtin islamictoday d:islamictoday jdn> d:jdn> join d:join last-day-of-hebrew-month d:last-day-of-hebrew-month
+Builtin last-dow d:last-dow last-month d:last-month last-week d:last-week last-year d:last-year latitude d:latitude
+Builtin longitude d:longitude longitude d:longitude msec d:msec msec> d:msec> new d:new next-dow d:next-dow
+Builtin next-month d:next-month next-week d:next-week next-year d:next-year number>hebrew d:number>hebrew
+Builtin omer d:omer parse d:parse parse-approx d:parse-approx parse-range d:parse-range pesach d:pesach
Builtin prev-dow d:prev-dow purim d:purim rosh-chodesh? d:rosh-chodesh? rosh-hashanah d:rosh-hashanah
Builtin shavuot d:shavuot start-timer d:start-timer sunrise d:sunrise taanit-esther d:taanit-esther
-Builtin ticks d:ticks ticks/sec d:ticks/sec timer d:timer tisha-beav d:tisha-beav tzadjust d:tzadjust
-Builtin unix> d:unix> updatetz d:updatetz year@ d:year@ ymd d:ymd ymd> d:ymd> yom-haatsmaut d:yom-haatsmaut
-Builtin yom-kippur d:yom-kippur add-func db:add-func bind db:bind close db:close col db:col col[] db:col[]
-Builtin col{} db:col{} err? db:err? errmsg db:errmsg exec db:exec exec-cb db:exec-cb key db:key mysql? db:mysql?
-Builtin odbc? db:odbc? open db:open open? db:open? prepare db:prepare query db:query query-all db:query-all
-Builtin rekey db:rekey sqlerrmsg db:sqlerrmsg bp dbg:bp except-task@ dbg:except-task@ go dbg:go line-info dbg:line-info
-Builtin prompt dbg:prompt stop dbg:stop trace dbg:trace trace-enter dbg:trace-enter trace-leave dbg:trace-leave
-Builtin abspath f:abspath append f:append associate f:associate atime f:atime canwrite? f:canwrite?
-Builtin chmod f:chmod close f:close copy f:copy copydir f:copydir create f:create ctime f:ctime dir? f:dir?
-Builtin dname f:dname eachbuf f:eachbuf eachline f:eachline enssep f:enssep eof? f:eof? err? f:err?
-Builtin exists? f:exists? flush f:flush fname f:fname getb f:getb getc f:getc getline f:getline getmod f:getmod
-Builtin glob f:glob glob-nocase f:glob-nocase include f:include launch f:launch link f:link link> f:link>
-Builtin link? f:link? mkdir f:mkdir mmap f:mmap mmap-range f:mmap-range mmap-range? f:mmap-range? mtime f:mtime
-Builtin mv f:mv open f:open open-ro f:open-ro popen f:popen print f:print read f:read relpath f:relpath
-Builtin rglob f:rglob rm f:rm rmdir f:rmdir seek f:seek sep f:sep show f:show size f:size slurp f:slurp
-Builtin stderr f:stderr stdin f:stdin stdout f:stdout tell f:tell times f:times trash f:trash ungetb f:ungetb
-Builtin ungetc f:ungetc unzip f:unzip unzip-entry f:unzip-entry watch f:watch write f:write writen f:writen
-Builtin zip+ f:zip+ zip@ f:zip@ zipentry f:zipentry zipnew f:zipnew zipopen f:zipopen zipsave f:zipsave
-Builtin bold font:bold face? font:face? glyph-path font:glyph-path glyph-pos font:glyph-pos info font:info
-Builtin italic font:italic ls font:ls measure font:measure new font:new pixels font:pixels pixels? font:pixels?
-Builtin points font:points points? font:points? styles font:styles styles? font:styles? underline font:underline
-Builtin +child g:+child +kind g:+kind +path g:+path -child g:-child /path g:/path >img g:>img >progress g:>progress
-Builtin add-items g:add-items adjustwidth g:adjustwidth allow-orient g:allow-orient arc g:arc arc2 g:arc2
-Builtin autohide g:autohide back g:back bezier g:bezier bg g:bg bg? g:bg? bounds g:bounds bounds? g:bounds?
-Builtin box-label g:box-label btn-font g:btn-font bubble g:bubble button-size g:button-size buttons-visible g:buttons-visible
-Builtin c-text g:c-text callout g:callout center g:center child g:child clear g:clear clearpath g:clearpath
-Builtin clr>n g:clr>n coleven g:coleven colordlg g:colordlg colwidth g:colwidth connectededges g:connectededges
-Builtin contrasting g:contrasting cp g:cp curmouse? g:curmouse? default-font g:default-font deselect-row g:deselect-row
-Builtin dismiss g:dismiss do g:do draw-fitted-text g:draw-fitted-text draw-text g:draw-text draw-text-at g:draw-text-at
-Builtin each g:each edit-on-double-click g:edit-on-double-click editable g:editable editdlg g:editdlg
-Builtin empty-text g:empty-text enable g:enable enabled? g:enabled? fade g:fade fb-files g:fb-files
-Builtin fcolor g:fcolor fg g:fg fg? g:fg? file-filter g:file-filter file-name g:file-name filedlg g:filedlg
-Builtin fill g:fill fillall g:fillall fit-text g:fit-text flex! g:flex! focus g:focus fontdlg g:fontdlg
-Builtin forward g:forward fullscreen g:fullscreen get-lasso-items g:get-lasso-items get-tab g:get-tab
-Builtin getclr g:getclr getfont g:getfont getimage g:getimage getpath g:getpath getroot g:getroot gradient g:gradient
-Builtin gui? g:gui? handle g:handle headerheight g:headerheight hide g:hide image g:image image-at g:image-at
-Builtin invalidate g:invalidate ix? g:ix? justify g:justify keyinfo g:keyinfo l-text g:l-text laf g:laf
-Builtin laf! g:laf! laf? g:laf? len g:len line-width g:line-width lineto g:lineto list+ g:list+ list- g:list-
-Builtin loadcontent g:loadcontent localize g:localize m! g:m! m@ g:m@ menu-font g:menu-font menu-update g:menu-update
-Builtin menuenabled g:menuenabled mouse? g:mouse? mousepos? g:mousepos? moveto g:moveto msgdlg g:msgdlg
-Builtin multi g:multi name g:name named-skin g:named-skin new g:new new-laf g:new-laf next g:next obj g:obj
-Builtin on g:on on? g:on? ontop g:ontop oshandle g:oshandle outlinethickness g:outlinethickness panel-size g:panel-size
-Builtin panel-size? g:panel-size? parent g:parent path g:path path>s g:path>s pie g:pie pix! g:pix!
-Builtin pop g:pop popmenu g:popmenu pos? g:pos? prev g:prev propval! g:propval! propval@ g:propval@
-Builtin push g:push qbezier g:qbezier quit g:quit r-text g:r-text readonly g:readonly rect g:rect refresh g:refresh
-Builtin restore g:restore root g:root root-item-visible g:root-item-visible rotate g:rotate rowheight g:rowheight
-Builtin rrect g:rrect s>path g:s>path save g:save say g:say scale g:scale scolor g:scolor scrollthickness g:scrollthickness
-Builtin sectionenable g:sectionenable select! g:select! select@ g:select@ selected-rows g:selected-rows
-Builtin set-lasso g:set-lasso set-long-press g:set-long-press set-popup-font g:set-popup-font set-range g:set-range
-Builtin set-swipe g:set-swipe set-value g:set-value setcursor g:setcursor setfont g:setfont setheader g:setheader
-Builtin sethtml g:sethtml setimage g:setimage setname g:setname setroot g:setroot settab g:settab show g:show
-Builtin show-line-numbers g:show-line-numbers show-pct g:show-pct showmenu g:showmenu showtooltip g:showtooltip
-Builtin size g:size size? g:size? skin g:skin skin-class g:skin-class stackix g:stackix state g:state
-Builtin state? g:state? stepsize g:stepsize stroke g:stroke stroke-fill g:stroke-fill style g:style
-Builtin tabname g:tabname text g:text text-box-style g:text-box-style text? g:text? textcolor g:textcolor
-Builtin textsize g:textsize timer! g:timer! timer@ g:timer@ toback g:toback tofront g:tofront toggle-row g:toggle-row
-Builtin tooltip g:tooltip top g:top transition g:transition translate g:translate tree-open g:tree-open
-Builtin triangle g:triangle update g:update updateitems g:updateitems url g:url user g:user user! g:user!
-Builtin vertical g:vertical view g:view visible? g:visible? vpos! g:vpos! vpos@ g:vpos@ waitcursor g:waitcursor
-Builtin winding g:winding xy g:xy xy? g:xy? +edge gr:+edge +edge+w gr:+edge+w +node gr:+node connect gr:connect
-Builtin edges gr:edges m! gr:m! m@ gr:m@ neighbors gr:neighbors new gr:new node-edges gr:node-edges
-Builtin nodes gr:nodes traverse gr:traverse + h:+ clear h:clear len h:len new h:new peek h:peek pop h:pop
-Builtin push h:push unique h:unique arm? hw:arm? camera hw:camera camera-fmt hw:camera-fmt camera-img hw:camera-img
-Builtin camera? hw:camera? cpu? hw:cpu? device? hw:device? displays? hw:displays? displaysize? hw:displaysize?
-Builtin err? hw:err? gpio hw:gpio gpio! hw:gpio! gpio-mmap hw:gpio-mmap gpio@ hw:gpio@ i2c hw:i2c i2c! hw:i2c!
-Builtin i2c!reg hw:i2c!reg i2c@ hw:i2c@ i2c@reg hw:i2c@reg isround? hw:isround? iswatch? hw:iswatch?
-Builtin mac? hw:mac? mem? hw:mem? poll hw:poll sensor hw:sensor start hw:start stop hw:stop fetch-full imap:fetch-full
-Builtin fetch-uid-mail imap:fetch-uid-mail login imap:login new imap:new select-inbox imap:select-inbox
-Builtin >file img:>file copy img:copy crop img:crop data img:data desat img:desat fill img:fill filter img:filter
-Builtin flip img:flip from-svg img:from-svg new img:new pix! img:pix! pix@ img:pix@ qr-gen img:qr-gen
-Builtin qr-parse img:qr-parse rotate img:rotate scale img:scale scroll img:scroll size img:size countries iso:countries
-Builtin find loc:find sort loc:sort ! m:! !? m:!? + m:+ +? m:+? - m:- @ m:@ @? m:@? @@ m:@@ clear m:clear
-Builtin data m:data each m:each exists? m:exists? iter m:iter iter-all m:iter-all keys m:keys len m:len
-Builtin map m:map new m:new op! m:op! open m:open vals m:vals xchg m:xchg ! mat:! * mat:* + mat:+ = mat:=
-Builtin @ mat:@ col mat:col data mat:data det mat:det dim? mat:dim? get-n mat:get-n ident mat:ident
-Builtin m. mat:m. minor mat:minor n* mat:n* new mat:new row mat:row same-size? mat:same-size? trans mat:trans
-Builtin ! n:! * n:* */ n:*/ + n:+ +! n:+! - n:- / n:/ /mod n:/mod 1+ n:1+ 1- n:1- < n:< = n:= > n:>
-Builtin BIGE n:BIGE BIGPI n:BIGPI E n:E PI n:PI ^ n:^ abs n:abs acos n:acos acos n:acos asin n:asin
-Builtin asin n:asin atan n:atan atan n:atan atan2 n:atan2 band n:band between n:between bfloat n:bfloat
-Builtin bic n:bic bint n:bint binv n:binv bnot n:bnot bor n:bor bxor n:bxor ceil n:ceil clamp n:clamp
-Builtin cmp n:cmp comb n:comb cos n:cos cosd n:cosd exp n:exp expmod n:expmod float n:float floor n:floor
+Builtin ticks d:ticks ticks/sec d:ticks/sec timer d:timer timer-ctrl d:timer-ctrl tisha-beav d:tisha-beav
+Builtin tzadjust d:tzadjust unix> d:unix> unknown d:unknown unknown? d:unknown? updatetz d:updatetz
+Builtin year@ d:year@ ymd d:ymd ymd> d:ymd> yom-haatsmaut d:yom-haatsmaut yom-kippur d:yom-kippur add-func db:add-func
+Builtin aes! db:aes! begin db:begin bind db:bind bind-exec db:bind-exec bind-exec[] db:bind-exec[]
+Builtin close db:close col db:col col[] db:col[] col{} db:col{} commit db:commit each db:each exec db:exec
+Builtin exec-cb db:exec-cb exec-name db:exec-name get db:get get-sub db:get-sub key db:key kind? db:kind?
+Builtin last-rowid db:last-rowid mysql? db:mysql? odbc? db:odbc? open db:open open? db:open? prep-name db:prep-name
+Builtin prepare db:prepare query db:query query-all db:query-all rekey db:rekey rollback db:rollback
+Builtin set db:set set-sub db:set-sub sql@ db:sql@ bp dbg:bp except-task@ dbg:except-task@ go dbg:go
+Builtin line-info dbg:line-info prompt dbg:prompt stop dbg:stop trace dbg:trace trace-enter dbg:trace-enter
+Builtin trace-leave dbg:trace-leave / f:/ abspath f:abspath absrel f:absrel append f:append associate f:associate
+Builtin atime f:atime canwrite? f:canwrite? chmod f:chmod close f:close copy f:copy copydir f:copydir
+Builtin create f:create ctime f:ctime dir? f:dir? dname f:dname eachbuf f:eachbuf eachline f:eachline
+Builtin enssep f:enssep eof? f:eof? exists? f:exists? flush f:flush fname f:fname getb f:getb getc f:getc
+Builtin getline f:getline getmod f:getmod glob f:glob glob-nocase f:glob-nocase homedir f:homedir homedir! f:homedir!
+Builtin include f:include ioctl f:ioctl join f:join launch f:launch link f:link link> f:link> link? f:link?
+Builtin mkdir f:mkdir mmap f:mmap mmap-range f:mmap-range mmap-range? f:mmap-range? mtime f:mtime mv f:mv
+Builtin name@ f:name@ open f:open open-ro f:open-ro popen f:popen print f:print read f:read read? f:read?
+Builtin relpath f:relpath rglob f:rglob rm f:rm rmdir f:rmdir seek f:seek sep f:sep size f:size slurp f:slurp
+Builtin sparse? f:sparse? spit f:spit stderr f:stderr stdin f:stdin stdout f:stdout tell f:tell times f:times
+Builtin tmpspit f:tmpspit trash f:trash truncate f:truncate ungetb f:ungetb ungetc f:ungetc unzip f:unzip
+Builtin unzip-entry f:unzip-entry watch f:watch write f:write writen f:writen zip+ f:zip+ zip@ f:zip@
+Builtin zipentry f:zipentry zipnew f:zipnew zipopen f:zipopen zipsave f:zipsave atlas! font:atlas!
+Builtin atlas@ font:atlas@ default-size font:default-size info font:info ls font:ls measure font:measure
+Builtin new font:new oversample font:oversample pixels font:pixels pixels? font:pixels? +edge gr:+edge
+Builtin +edge+w gr:+edge+w +node gr:+node connect gr:connect edges gr:edges edges! gr:edges! m! gr:m!
+Builtin m@ gr:m@ neighbors gr:neighbors new gr:new node-edges gr:node-edges nodes gr:nodes traverse gr:traverse
+Builtin weight! gr:weight! + h:+ clear h:clear cmp! h:cmp! len h:len max! h:max! new h:new peek h:peek
+Builtin pop h:pop push h:push unique h:unique arm? hw:arm? camera hw:camera camera-img hw:camera-img
+Builtin camera-limits hw:camera-limits camera? hw:camera? cpu? hw:cpu? device? hw:device? displays? hw:displays?
+Builtin displaysize? hw:displaysize? finger-match hw:finger-match finger-support hw:finger-support
+Builtin gpio hw:gpio gpio! hw:gpio! gpio-mmap hw:gpio-mmap gpio@ hw:gpio@ i2c hw:i2c i2c! hw:i2c! i2c!reg hw:i2c!reg
+Builtin i2c@ hw:i2c@ i2c@reg hw:i2c@reg isround? hw:isround? iswatch? hw:iswatch? mac? hw:mac? mem? hw:mem?
+Builtin model? hw:model? poll hw:poll sensor hw:sensor start hw:start stop hw:stop uid? hw:uid? fetch-full imap:fetch-full
+Builtin fetch-uid-mail imap:fetch-uid-mail login imap:login logout imap:logout new imap:new search imap:search
+Builtin select-inbox imap:select-inbox >file img:>file >fmt img:>fmt copy img:copy crop img:crop data img:data
+Builtin desat img:desat fill img:fill fillrect img:fillrect filter img:filter flip img:flip from-svg img:from-svg
+Builtin new img:new pix! img:pix! pix@ img:pix@ qr-gen img:qr-gen qr-parse img:qr-parse rotate img:rotate
+Builtin scale img:scale scroll img:scroll size img:size countries iso:countries find loc:find sort loc:sort
+Builtin ! m:! !? m:!? + m:+ +? m:+? - m:- >arr m:>arr @ m:@ @? m:@? _! m:_! _@ m:_@ arr> m:arr> bitmap m:bitmap
+Builtin clear m:clear data m:data each m:each exists? m:exists? filter m:filter iter m:iter iter-all m:iter-all
+Builtin keys m:keys len m:len map m:map merge m:merge new m:new op! m:op! open m:open slice m:slice
+Builtin vals m:vals xchg m:xchg zip m:zip ! mat:! * mat:* + mat:+ = mat:= @ mat:@ affine mat:affine
+Builtin col mat:col data mat:data det mat:det dim? mat:dim? get-n mat:get-n ident mat:ident inv mat:inv
+Builtin m. mat:m. minor mat:minor n* mat:n* new mat:new new-minor mat:new-minor rotate mat:rotate row mat:row
+Builtin same-size? mat:same-size? scale mat:scale shear mat:shear trans mat:trans translate mat:translate
+Builtin xform mat:xform 2console md:2console 2html md:2html 2nk md:2nk bounds meta:bounds color meta:color
+Builtin console meta:console end meta:end ffi meta:ffi ! n:! * n:* */ n:*/ + n:+ +! n:+! - n:- / n:/
+Builtin /mod n:/mod 1+ n:1+ 1- n:1- < n:< = n:= > n:> BIGE n:BIGE BIGPI n:BIGPI E n:E PI n:PI ^ n:^
+Builtin _mod n:_mod abs n:abs acos n:acos acos n:acos asin n:asin asin n:asin atan n:atan atan n:atan
+Builtin atan2 n:atan2 band n:band between n:between bfloat n:bfloat bic n:bic bint n:bint binv n:binv
+Builtin bnot n:bnot bor n:bor bxor n:bxor cast n:cast ceil n:ceil clamp n:clamp cmp n:cmp comb n:comb
+Builtin cos n:cos cosd n:cosd emod n:emod exp n:exp expm1 n:expm1 expmod n:expmod float n:float floor n:floor
Builtin fmod n:fmod frac n:frac gcd n:gcd int n:int invmod n:invmod kind? n:kind? lcm n:lcm ln n:ln
-Builtin max n:max median n:median min n:min mod n:mod neg n:neg odd? n:odd? perm n:perm prime? n:prime?
-Builtin quantize n:quantize quantize! n:quantize! r+ n:r+ range n:range rot32l n:rot32l rot32r n:rot32r
-Builtin round n:round round2 n:round2 running-variance n:running-variance running-variance-finalize n:running-variance-finalize
-Builtin sgn n:sgn shl n:shl shr n:shr sin n:sin sind n:sind sqr n:sqr sqrt n:sqrt tan n:tan tand n:tand
-Builtin trunc n:trunc ~= n:~= ! net:! >url net:>url @ net:@ DGRAM net:DGRAM INET4 net:INET4 INET6 net:INET6
-Builtin PROTO_TCP net:PROTO_TCP PROTO_UDP net:PROTO_UDP STREAM net:STREAM accept net:accept addrinfo>o net:addrinfo>o
-Builtin again? net:again? alloc-and-read net:alloc-and-read alloc-buf net:alloc-buf bind net:bind browse net:browse
-Builtin close net:close connect net:connect err>s net:err>s err? net:err? get net:get getaddrinfo net:getaddrinfo
-Builtin getpeername net:getpeername head net:head ifaces? net:ifaces? listen net:listen net-socket net:net-socket
-Builtin opts net:opts port-is-ssl? net:port-is-ssl? post net:post proxy! net:proxy! read net:read recvfrom net:recvfrom
-Builtin s>url net:s>url sendto net:sendto server net:server setsockopt net:setsockopt socket net:socket
-Builtin tlshello net:tlshello url> net:url> user-agent net:user-agent wait net:wait write net:write
-Builtin MAX ns:MAX cast ptr:cast len ptr:len pack ptr:pack unpack ptr:unpack unpack_orig ptr:unpack_orig
+Builtin ln1p n:ln1p max n:max median n:median min n:min mod n:mod neg n:neg odd? n:odd? perm n:perm
+Builtin prime? n:prime? quantize n:quantize quantize! n:quantize! r+ n:r+ range n:range rot32l n:rot32l
+Builtin rot32r n:rot32r round n:round round2 n:round2 rounding n:rounding running-variance n:running-variance
+Builtin running-variance-finalize n:running-variance-finalize sgn n:sgn shl n:shl shr n:shr sin n:sin
+Builtin sind n:sind sqr n:sqr sqrt n:sqrt tan n:tan tand n:tand trunc n:trunc ~= n:~= ! net:! !? net:!?
+Builtin - net:- >url net:>url @ net:@ @? net:@? DGRAM net:DGRAM INET4 net:INET4 INET6 net:INET6 PROTO_TCP net:PROTO_TCP
+Builtin PROTO_UDP net:PROTO_UDP STREAM net:STREAM accept net:accept addrinfo>o net:addrinfo>o again? net:again?
+Builtin alloc-and-read net:alloc-and-read alloc-buf net:alloc-buf bind net:bind close net:close closed? net:closed?
+Builtin connect net:connect debug? net:debug? delete net:delete get net:get getaddrinfo net:getaddrinfo
+Builtin getpeername net:getpeername head net:head ifaces? net:ifaces? listen net:listen map>url net:map>url
+Builtin net-socket net:net-socket opts net:opts port-is-ssl? net:port-is-ssl? post net:post proxy! net:proxy!
+Builtin put net:put read net:read read-all net:read-all recvfrom net:recvfrom s>url net:s>url sendto net:sendto
+Builtin server net:server setsockopt net:setsockopt socket net:socket tlshello net:tlshello url> net:url>
+Builtin user-agent net:user-agent wait net:wait write net:write (begin) nk:(begin) (chart-begin) nk:(chart-begin)
+Builtin (chart-begin-colored) nk:(chart-begin-colored) (chart-end) nk:(chart-end) (end) nk:(end) (group-begin) nk:(group-begin)
+Builtin (group-end) nk:(group-end) (property) nk:(property) >img nk:>img addfont nk:addfont anti-alias nk:anti-alias
+Builtin any-clicked? nk:any-clicked? bounds nk:bounds bounds! nk:bounds! button nk:button button-color nk:button-color
+Builtin button-label nk:button-label button-set-behavior nk:button-set-behavior button-symbol nk:button-symbol
+Builtin button-symbol-label nk:button-symbol-label chart-add-slot nk:chart-add-slot chart-add-slot-colored nk:chart-add-slot-colored
+Builtin chart-push nk:chart-push chart-push-slot nk:chart-push-slot checkbox nk:checkbox clicked? nk:clicked?
+Builtin close-this! nk:close-this! close-this? nk:close-this? close? nk:close? color-picker nk:color-picker
+Builtin combo nk:combo combo-begin-color nk:combo-begin-color combo-begin-label nk:combo-begin-label
+Builtin combo-cb nk:combo-cb combo-end nk:combo-end contextual-begin nk:contextual-begin contextual-close nk:contextual-close
+Builtin contextual-end nk:contextual-end contextual-item-image-text nk:contextual-item-image-text contextual-item-symbol-text nk:contextual-item-symbol-text
+Builtin contextual-item-text nk:contextual-item-text cp! nk:cp! cp@ nk:cp@ display-info nk:display-info
+Builtin display@ nk:display@ do nk:do down? nk:down? draw-image nk:draw-image draw-image-at nk:draw-image-at
+Builtin draw-image-centered nk:draw-image-centered draw-sub-image nk:draw-sub-image draw-text nk:draw-text
+Builtin draw-text-high nk:draw-text-high draw-text-wrap nk:draw-text-wrap edit-focus nk:edit-focus
+Builtin edit-string nk:edit-string event nk:event event-boost nk:event-boost event-msec nk:event-msec
+Builtin event-wait nk:event-wait fill-arc nk:fill-arc fill-circle nk:fill-circle fill-poly nk:fill-poly
+Builtin fill-rect nk:fill-rect fill-rect-color nk:fill-rect-color fill-triangle nk:fill-triangle flags! nk:flags!
+Builtin flags@ nk:flags@ fullscreen nk:fullscreen get nk:get get-row-height nk:get-row-height getfont nk:getfont
+Builtin getmap nk:getmap gl? nk:gl? grid nk:grid grid-push nk:grid-push group-scroll-ofs nk:group-scroll-ofs
+Builtin group-scroll-ofs! nk:group-scroll-ofs! hovered? nk:hovered? image nk:image init nk:init input-button nk:input-button
+Builtin input-key nk:input-key input-motion nk:input-motion input-scroll nk:input-scroll input-string nk:input-string
+Builtin key-down? nk:key-down? key-pressed? nk:key-pressed? key-released? nk:key-released? label nk:label
+Builtin label-colored nk:label-colored label-wrap nk:label-wrap label-wrap-colored nk:label-wrap-colored
+Builtin layout-bounds nk:layout-bounds layout-grid-begin nk:layout-grid-begin layout-grid-end nk:layout-grid-end
+Builtin layout-push-dynamic nk:layout-push-dynamic layout-push-static nk:layout-push-static layout-push-variable nk:layout-push-variable
+Builtin layout-ratio-from-pixel nk:layout-ratio-from-pixel layout-reset-row-height nk:layout-reset-row-height
+Builtin layout-row nk:layout-row layout-row-begin nk:layout-row-begin layout-row-dynamic nk:layout-row-dynamic
+Builtin layout-row-end nk:layout-row-end layout-row-height nk:layout-row-height layout-row-push nk:layout-row-push
+Builtin layout-row-static nk:layout-row-static layout-row-template-begin nk:layout-row-template-begin
+Builtin layout-row-template-end nk:layout-row-template-end layout-space-begin nk:layout-space-begin
+Builtin layout-space-end nk:layout-space-end layout-space-push nk:layout-space-push layout-widget-bounds nk:layout-widget-bounds
+Builtin list-begin nk:list-begin list-end nk:list-end list-new nk:list-new list-range nk:list-range
+Builtin m! nk:m! m@ nk:m@ make-style nk:make-style max-vertex-element nk:max-vertex-element measure nk:measure
+Builtin measure-font nk:measure-font menu-begin nk:menu-begin menu-close nk:menu-close menu-end nk:menu-end
+Builtin menu-item-image nk:menu-item-image menu-item-label nk:menu-item-label menu-item-symbol nk:menu-item-symbol
+Builtin menubar-begin nk:menubar-begin menubar-end nk:menubar-end mouse-pos nk:mouse-pos msgdlg nk:msgdlg
+Builtin option nk:option plot nk:plot plot-fn nk:plot-fn pop-font nk:pop-font popup-begin nk:popup-begin
+Builtin popup-close nk:popup-close popup-end nk:popup-end popup-scroll-ofs nk:popup-scroll-ofs popup-scroll-ofs! nk:popup-scroll-ofs!
+Builtin progress nk:progress prop-int nk:prop-int pt>local nk:pt>local pt>screen nk:pt>screen pts>rect nk:pts>rect
+Builtin push-font nk:push-font rect-center nk:rect-center rect-intersect nk:rect-intersect rect-ofs nk:rect-ofs
+Builtin rect-pad nk:rect-pad rect-shrink nk:rect-shrink rect-union nk:rect-union rect/high nk:rect/high
+Builtin rect/wide nk:rect/wide rect>center nk:rect>center rect>local nk:rect>local rect>pos nk:rect>pos
+Builtin rect>pts nk:rect>pts rect>screen nk:rect>screen rect>size nk:rect>size released? nk:released?
+Builtin render nk:render restore nk:restore rotate nk:rotate save nk:save scale nk:scale scancode? nk:scancode?
+Builtin screen-saver nk:screen-saver screen-size nk:screen-size screen-win-close nk:screen-win-close
+Builtin selectable nk:selectable set nk:set set-font nk:set-font set-num-vertices nk:set-num-vertices
+Builtin setpos nk:setpos setwin nk:setwin slider nk:slider slider-int nk:slider-int space nk:space
+Builtin spacing nk:spacing stroke-arc nk:stroke-arc stroke-circle nk:stroke-circle stroke-curve nk:stroke-curve
+Builtin stroke-line nk:stroke-line stroke-polygon nk:stroke-polygon stroke-polyline nk:stroke-polyline
+Builtin stroke-rect nk:stroke-rect stroke-tri nk:stroke-tri style-from-table nk:style-from-table sw-gl nk:sw-gl
+Builtin text? nk:text? tooltip nk:tooltip translate nk:translate tree-pop nk:tree-pop tree-state-push nk:tree-state-push
+Builtin use-style nk:use-style vsync nk:vsync widget nk:widget widget-bounds nk:widget-bounds widget-fitting nk:widget-fitting
+Builtin widget-high nk:widget-high widget-hovered? nk:widget-hovered? widget-mouse-click-down? nk:widget-mouse-click-down?
+Builtin widget-mouse-clicked? nk:widget-mouse-clicked? widget-pos nk:widget-pos widget-size nk:widget-size
+Builtin widget-wide nk:widget-wide win nk:win win-bounds nk:win-bounds win-bounds! nk:win-bounds! win-close nk:win-close
+Builtin win-closed? nk:win-closed? win-collapse nk:win-collapse win-collapsed? nk:win-collapsed? win-content-bounds nk:win-content-bounds
+Builtin win-focus nk:win-focus win-focused? nk:win-focused? win-hidden? nk:win-hidden? win-high nk:win-high
+Builtin win-hovered? nk:win-hovered? win-pos nk:win-pos win-scroll-ofs nk:win-scroll-ofs win-scroll-ofs! nk:win-scroll-ofs!
+Builtin win-show nk:win-show win-size nk:win-size win-wide nk:win-wide win? nk:win? MAX ns:MAX ! o:!
+Builtin + o:+ +? o:+? ??? o:??? @ o:@ class o:class exec o:exec isa o:isa method o:method mutate o:mutate
+Builtin new o:new super o:super devname os:devname env os:env lang os:lang mem-arenas os:mem-arenas
+Builtin notify os:notify region os:region cast ptr:cast len ptr:len null? ptr:null? pack ptr:pack unpack ptr:unpack
+Builtin unpack_orig ptr:unpack_orig publish pubsub:publish qsize pubsub:qsize subscribe pubsub:subscribe
Builtin + q:+ clear q:clear len q:len new q:new notify q:notify overwrite q:overwrite peek q:peek pick q:pick
-Builtin pop q:pop push q:push shift q:shift size q:size slide q:slide throwing q:throwing wait q:wait
-Builtin ++match r:++match +/ r:+/ +match r:+match / r:/ @ r:@ err? r:err? len r:len match r:match new r:new
-Builtin rx r:rx str r:str ! s:! * s:* + s:+ - s:- / s:/ /scripts s:/scripts <+ s:<+ = s:= =ic s:=ic
-Builtin >base64 s:>base64 >ucs2 s:>ucs2 @ s:@ append s:append base64> s:base64> clear s:clear cmp s:cmp
-Builtin cmpi s:cmpi compress s:compress days! s:days! each s:each eachline s:eachline expand s:expand
-Builtin fill s:fill fmt s:fmt gershayim s:gershayim globmatch s:globmatch hexupr s:hexupr insert s:insert
-Builtin intl s:intl intl! s:intl! lang s:lang lc s:lc len s:len lsub s:lsub ltrim s:ltrim map s:map
-Builtin months! s:months! new s:new replace s:replace replace! s:replace! rev s:rev rsearch s:rsearch
-Builtin rsub s:rsub rtrim s:rtrim script? s:script? search s:search size s:size slice s:slice strfmap s:strfmap
-Builtin strfmt s:strfmt trim s:trim tsub s:tsub uc s:uc ucs2> s:ucs2> utf8? s:utf8? zt s:zt close sio:close
-Builtin enum sio:enum open sio:open opts! sio:opts! opts@ sio:opts@ read sio:read write sio:write new smtp:new
-Builtin send smtp:send apply-filter snd:apply-filter devices? snd:devices? end-record snd:end-record
-Builtin filter snd:filter formats? snd:formats? freq snd:freq gain snd:gain gain? snd:gain? len snd:len
-Builtin loop snd:loop mix snd:mix new snd:new pause snd:pause play snd:play played snd:played rate snd:rate
-Builtin record snd:record seek snd:seek stop snd:stop stopall snd:stopall unmix snd:unmix volume snd:volume
-Builtin volume? snd:volume? + st:+ . st:. clear st:clear len st:len ndrop st:ndrop new st:new op! st:op!
-Builtin peek st:peek pick st:pick pop st:pop push st:push roll st:roll shift st:shift size st:size
-Builtin slide st:slide swap st:swap throwing st:throwing >buf struct:>buf arr> struct:arr> buf struct:buf
-Builtin buf> struct:buf> byte struct:byte double struct:double field! struct:field! field@ struct:field@
-Builtin float struct:float ignore struct:ignore int struct:int long struct:long struct; struct:struct;
-Builtin word struct:word ! t:! @ t:@ assign t:assign curtask t:curtask def-queue t:def-queue def-stack t:def-stack
-Builtin done? t:done? err! t:err! err? t:err? getq t:getq guitask t:guitask handler t:handler kill t:kill
-Builtin list t:list main t:main name! t:name! name@ t:name@ notify t:notify pop t:pop priority t:priority
-Builtin push t:push push< t:push< q-notify t:q-notify q-wait t:q-wait qlen t:qlen result t:result task t:task
-Builtin task-n t:task-n task-stop t:task-stop wait t:wait ! w:! @ w:@ alias: w:alias: cb w:cb deprecate w:deprecate
-Builtin exec w:exec exec? w:exec? ffifail w:ffifail find w:find forget w:forget is w:is undo w:undo
-Builtin >s xml:>s >txt xml:>txt parse xml:parse parse-html xml:parse-html parse-stream xml:parse-stream
+Builtin pop q:pop push q:push remove q:remove shift q:shift size q:size slide q:slide throwing q:throwing
+Builtin wait q:wait ++match r:++match +/ r:+/ +match r:+match / r:/ @ r:@ len r:len match r:match new r:new
+Builtin rx r:rx str r:str * rat:* + rat:+ - rat:- / rat:/ >n rat:>n >s rat:>s new rat:new proper rat:proper
+Builtin ! s:! * s:* + s:+ - s:- / s:/ /scripts s:/scripts <+ s:<+ = s:= =ic s:=ic >base64 s:>base64
+Builtin >ucs2 s:>ucs2 @ s:@ append s:append base64> s:base64> clear s:clear cmp s:cmp cmpi s:cmpi compress s:compress
+Builtin days! s:days! dist s:dist each s:each each! s:each! eachline s:eachline escape s:escape expand s:expand
+Builtin fill s:fill fmt s:fmt fold s:fold gershayim s:gershayim globmatch s:globmatch hexupr s:hexupr
+Builtin insert s:insert intl s:intl intl! s:intl! lang s:lang lc s:lc lc? s:lc? len s:len lsub s:lsub
+Builtin ltrim s:ltrim map s:map months! s:months! new s:new norm s:norm reduce s:reduce repinsert s:repinsert
+Builtin replace s:replace replace! s:replace! rev s:rev rsearch s:rsearch rsub s:rsub rtrim s:rtrim
+Builtin script? s:script? search s:search size s:size slice s:slice soundex s:soundex strfmap s:strfmap
+Builtin strfmt s:strfmt text-wrap s:text-wrap trim s:trim tsub s:tsub uc s:uc uc? s:uc? ucs2> s:ucs2>
+Builtin utf8? s:utf8? zt s:zt close sio:close enum sio:enum open sio:open opts! sio:opts! opts@ sio:opts@
+Builtin read sio:read write sio:write @ slv:@ auto slv:auto build slv:build constraint slv:constraint
+Builtin dump slv:dump edit slv:edit named-variable slv:named-variable new slv:new relation slv:relation
+Builtin reset slv:reset suggest slv:suggest term slv:term update slv:update v[] slv:v[] variable slv:variable
+Builtin v{} slv:v{} new smtp:new send smtp:send apply-filter snd:apply-filter devices? snd:devices?
+Builtin end-record snd:end-record filter snd:filter formats? snd:formats? freq snd:freq gain snd:gain
+Builtin gain? snd:gain? init snd:init len snd:len loop snd:loop loop? snd:loop? mix snd:mix new snd:new
+Builtin pause snd:pause play snd:play played snd:played rate snd:rate ready? snd:ready? record snd:record
+Builtin resume snd:resume seek snd:seek stop snd:stop stopall snd:stopall volume snd:volume volume? snd:volume?
+Builtin + st:+ . st:. clear st:clear len st:len ndrop st:ndrop new st:new op! st:op! peek st:peek pick st:pick
+Builtin pop st:pop push st:push roll st:roll shift st:shift size st:size slide st:slide swap st:swap
+Builtin throwing st:throwing >buf struct:>buf arr> struct:arr> buf struct:buf buf> struct:buf> byte struct:byte
+Builtin double struct:double field! struct:field! field@ struct:field@ float struct:float ignore struct:ignore
+Builtin int struct:int long struct:long struct; struct:struct; word struct:word ! t:! @ t:@ by-name t:by-name
+Builtin cor t:cor cor-drop t:cor-drop curtask t:curtask def-queue t:def-queue def-stack t:def-stack
+Builtin done? t:done? err! t:err! err? t:err? errno? t:errno? getq t:getq handler t:handler handler@ t:handler@
+Builtin kill t:kill list t:list main t:main max-exceptions t:max-exceptions name! t:name! name@ t:name@
+Builtin notify t:notify parent t:parent pop t:pop priority t:priority push t:push q-notify t:q-notify
+Builtin q-wait t:q-wait qlen t:qlen result t:result set-affinity t:set-affinity setq t:setq start t:start
+Builtin task t:task task-n t:task-n task-stop t:task-stop wait t:wait yield t:yield yield! t:yield!
+Builtin add tree:add binary tree:binary bk tree:bk btree tree:btree cmp! tree:cmp! data tree:data del tree:del
+Builtin find tree:find iter tree:iter next tree:next nodes tree:nodes parent tree:parent parse tree:parse
+Builtin prev tree:prev root tree:root search tree:search trie tree:trie ! w:! (is) w:(is) @ w:@ alias: w:alias:
+Builtin cb w:cb deprecate w:deprecate dlcall w:dlcall dlopen w:dlopen dlsym w:dlsym exec w:exec exec? w:exec?
+Builtin ffifail w:ffifail find w:find forget w:forget is w:is name w:name undo w:undo >s xml:>s >txt xml:>txt
+Builtin md-init xml:md-init md-parse xml:md-parse parse xml:parse parse-html xml:parse-html parse-stream xml:parse-stream
Builtin getmsg[] zmq:getmsg[] sendmsg[] zmq:sendmsg[]
+
" numbers
syn keyword eighthMath decimal hex base@ base!
syn match eighthInteger '\<-\=[0-9.]*[0-9.]\+\>'
+
" recognize hex and binary numbers, the '$' and '%' notation is for eighth
syn match eighthInteger '\<\$\x*\x\+\>' " *1* --- dont't mess
syn match eighthInteger '\<\x*\d\x*\>' " *2* --- this order!
@@ -280,20 +353,17 @@ syn match eighthInteger "\<'.\>"
syn region eighthString start=+\.\?\"+ skip=+"+ end=+$+
syn keyword jsonNull null
syn keyword jsonBool /\(true\|false\)/
- syn region eighthString start=/\<"/ end=/"\>/
+syn region eighthString start=/\<"/ end=/"\>/
syn match jsonObjEntry /"\"[^"]\+\"\ze\s*:/
-"syn region jsonObject start=/{/ end=/}/ contained contains=jsonObjEntry,jsonArray,jsonObject, jsonBool, eighthString
-"syn region jsonArray start=/\[/ end=/\]/ contained contains=jsonArray,jsonObject, jsonBool, eighthString
-
" Include files
-" syn match eighthInclude '\<\(libinclude\|include\|needs\)\s\+\S\+'
syn region eighthComment start="\zs\\" end="$" contains=eighthTodo
" Define the default highlighting.
if !exists("did_eighth_syntax_inits")
let did_eighth_syntax_inits=1
- " The default methods for highlighting. Can be overridden later.
+
+ " The default methods for highlighting. Can be overriden later.
hi def link eighthTodo Todo
hi def link eighthOperators Operator
hi def link eighthMath Number
@@ -320,16 +390,15 @@ if !exists("did_eighth_syntax_inits")
hi def link eighthBuiltin Define
hi def link eighthClasses Define
hi def link eighthClassWord Keyword
-
hi def link jsonObject Delimiter
hi def link jsonObjEntry Label
hi def link jsonArray Special
- hi def link jsonNull Function
- hi def link jsonBool Boolean
+ hi def link jsonNull Function
+ hi def link jsonBool Boolean
endif
let b:current_syntax = "8th"
let &cpo = s:cpo_save
unlet s:cpo_save
-" vim: ts=8:sw=4:nocindent:smartindent:
+" vim: ft=vim:ts=8:sw=4:nocindent:smartindent:
diff --git a/runtime/syntax/chicken.vim b/runtime/syntax/chicken.vim
index 806d08fbb7..f53d872e74 100644
--- a/runtime/syntax/chicken.vim
+++ b/runtime/syntax/chicken.vim
@@ -1,6 +1,6 @@
" Vim syntax file
" Language: Scheme (CHICKEN)
-" Last Change: 2021 Jul 30
+" Last Change: 2021 Oct 01
" Author: Evan Hanson <evhan@foldling.org>
" Maintainer: Evan Hanson <evhan@foldling.org>
" Repository: https://git.foldling.org/vim-scheme.git
@@ -37,7 +37,7 @@ if len(s:c)
syn region c matchgroup=schemeComment start=/#>/ end=/<#/ contains=@c
endif
-# SRFI 26
+" SRFI 26
syn match schemeSyntax /\(([ \t\n]*\)\@<=\(cut\|cute\)\>/
syn keyword schemeSyntax and-let*
diff --git a/runtime/syntax/css.vim b/runtime/syntax/css.vim
index 19326d01e4..67ad1ea335 100644
--- a/runtime/syntax/css.vim
+++ b/runtime/syntax/css.vim
@@ -2,12 +2,12 @@
" Language: Cascading Style Sheets
" Previous Contributor List:
" Jules Wang <w.jq0722@gmail.com>
-" Claudio Fleiner <claudio@fleiner.com> (Maintainer)
+" Claudio Fleiner <claudio@fleiner.com>
" Yeti (Add full CSS2, HTML4 support)
" Nikolai Weibull (Add CSS2 support)
-" URL: https://github.com/jsit/css.vim
+" URL: https://github.com/vim-language-dept/css-syntax.vim
" Maintainer: Jay Sitter <jay@jaysitter.com>
-" Last Change: 2019 Jul. 29
+" Last Change: 2021 Oct 15
" quit when a syntax file was already loaded
if !exists("main_syntax")
@@ -23,6 +23,8 @@ let s:cpo_save = &cpo
set cpo&vim
syn case ignore
+" Add dash to allowed keyword characters.
+syn iskeyword @,48-57,_,192-255,-
" HTML4 tags
syn keyword cssTagName abbr address area a b base
@@ -32,7 +34,7 @@ syn keyword cssTagName dfn div dl dt em fieldset form
syn keyword cssTagName h1 h2 h3 h4 h5 h6 head hr html img i
syn keyword cssTagName iframe input ins isindex kbd label legend li
syn keyword cssTagName link map menu meta noscript ol optgroup
-syn keyword cssTagName option p param pre q s samp script small
+syn keyword cssTagName option p param picture pre q s samp script small
syn keyword cssTagName span strong sub sup tbody td
syn keyword cssTagName textarea tfoot th thead title tr ul u var
syn keyword cssTagName object svg
@@ -127,7 +129,7 @@ syn region cssURL contained matchgroup=cssFunctionName start="\<\(uri\|url\|loca
syn region cssFunction contained matchgroup=cssFunctionName start="\<\(var\|calc\)\s*(" end=")" contains=cssCustomProp,cssValue.*,cssFunction,cssColor,cssStringQ,cssStringQQ oneline
syn region cssFunction contained matchgroup=cssFunctionName start="\<\(rgb\|clip\|attr\|counter\|rect\|cubic-bezier\|steps\)\s*(" end=")" oneline contains=cssValueInteger,cssValueNumber,cssValueLength,cssFunctionComma
syn region cssFunction contained matchgroup=cssFunctionName start="\<\(rgba\|hsl\|hsla\|color-stop\|from\|to\)\s*(" end=")" oneline contains=cssColor,cssValueInteger,cssValueNumber,cssValueLength,cssFunctionComma,cssFunction
-syn region cssFunction contained matchgroup=cssFunctionName start="\<\(linear-\|radial-\)\=\gradient\s*(" end=")" oneline contains=cssColor,cssValueInteger,cssValueNumber,cssValueLength,cssFunction,cssGradientAttr,cssFunctionComma
+syn region cssFunction contained matchgroup=cssFunctionName start="\<\(linear-\|radial-\|conic-\)\=\gradient\s*(" end=")" oneline contains=cssColor,cssValueInteger,cssValueNumber,cssValueLength,cssFunction,cssGradientAttr,cssFunctionComma
syn region cssFunction contained matchgroup=cssFunctionName start="\<\(matrix\(3d\)\=\|scale\(3d\|X\|Y\|Z\)\=\|translate\(3d\|X\|Y\|Z\)\=\|skew\(X\|Y\)\=\|rotate\(3d\|X\|Y\|Z\)\=\|perspective\)\s*(" end=")" oneline contains=cssValueInteger,cssValueNumber,cssValueLength,cssValueAngle,cssFunctionComma
syn region cssFunction contained matchgroup=cssFunctionName start="\<\(blur\|brightness\|contrast\|drop-shadow\|grayscale\|hue-rotate\|invert\|opacity\|saturate\|sepia\)\s*(" end=")" oneline contains=cssValueInteger,cssValueNumber,cssValueLength,cssValueAngle,cssFunctionComma
syn keyword cssGradientAttr contained top bottom left right cover center middle ellipse at
@@ -220,7 +222,7 @@ syn keyword cssFlexibleBoxProp contained order
syn match cssFlexibleBoxAttr contained "\<\(row\|column\|wrap\)\(-reverse\)\=\>"
syn keyword cssFlexibleBoxAttr contained nowrap stretch baseline center
syn match cssFlexibleBoxAttr contained "\<flex\(-\(start\|end\)\)\=\>"
-syn match cssFlexibleBoxAttr contained "\<space\(-\(between\|around\)\)\=\>"
+syn match cssFlexibleBoxAttr contained "\<space\(-\(between\|around\|evenly\)\)\=\>"
" CSS Fonts Module Level 3
" http://www.w3.org/TR/css-fonts-3/
@@ -234,9 +236,7 @@ syn keyword cssFontAttr contained larger smaller
syn match cssFontAttr contained "\<\(x\{1,2\}-\)\=\(large\|small\)\>"
syn match cssFontAttr contained "\<small-\(caps\|caption\)\>"
" font-family attributes
-syn match cssFontAttr contained "\<\(sans-\)\=serif\>"
-syn keyword cssFontAttr contained Antiqua Arial Black Book Charcoal Comic Courier Dingbats Gadget Geneva Georgia Grande Helvetica Impact Linotype Lucida MS Monaco Neue New Palatino Roboto Roman Symbol Tahoma Times Trebuchet Verdana Webdings Wingdings York Zapf
-syn keyword cssFontAttr contained cursive fantasy monospace
+syn keyword cssFontAttr contained sans-serif serif cursive fantasy monospace
" font-feature-settings attributes
syn keyword cssFontAttr contained on off
" font-stretch attributes
@@ -283,6 +283,7 @@ syn match cssGridProp contained "\<grid\>"
syn match cssGridProp contained "\<grid-template\(-\(columns\|rows\|areas\)\)\=\>"
syn match cssGridProp contained "\<grid-\(column\|row\)\(-\(start\|end\|gap\)\)\=\>"
syn match cssGridProp contained "\<grid-\(area\|gap\)\>"
+syn match cssGridProp contained "\<gap\>"
syn match cssGridProp contained "\<grid-auto-\(flow\|rows\|columns\)\>"
syn match cssHyerlinkProp contained "\<target\(-\(name\|new\|position\)\)\=\>"
@@ -294,6 +295,10 @@ syn match cssListAttr contained "\<\(decimal\(-leading-zero\)\=\|cjk-ideographic
syn keyword cssListAttr contained disc circle square hebrew armenian georgian
syn keyword cssListAttr contained inside outside
+" object-fit https://www.w3.org/TR/css-images-3/#the-object-fit
+syn match cssObjectProp contained "\<object-\(fit\|position\)\>"
+syn keyword cssObjectAttr contained fill contain cover scale-down
+
syn keyword cssPositioningProp contained bottom clear clip display float left
syn keyword cssPositioningProp contained position right top visibility
syn match cssPositioningProp contained "\<z-index\>"
@@ -303,7 +308,7 @@ syn keyword cssPositioningAttr contained left right both
syn match cssPositioningAttr contained "\<list-item\>"
syn match cssPositioningAttr contained "\<inline\(-\(block\|box\|table\|grid\|flex\)\)\=\>"
syn match cssPositioningAttr contained "\<flow\(-root\)\=\>"
-syn keyword cssPositioningAttr contained static relative absolute fixed subgrid
+syn keyword cssPositioningAttr contained static relative absolute fixed subgrid sticky
syn keyword cssPrintAttr contained landscape portrait crop cross always
@@ -548,6 +553,7 @@ hi def link cssMarqueeProp cssProp
hi def link cssMultiColumnProp cssProp
hi def link cssPagedMediaProp cssProp
hi def link cssPositioningProp cssProp
+hi def link cssObjectProp cssProp
hi def link cssPrintProp cssProp
hi def link cssRubyProp cssProp
hi def link cssSpeechProp cssProp
@@ -581,6 +587,7 @@ hi def link cssMultiColumnAttr cssAttr
hi def link cssPaddingAttr cssAttr
hi def link cssPagedMediaAttr cssAttr
hi def link cssPositioningAttr cssAttr
+hi def link cssObjectAttr cssAttr
hi def link cssGradientAttr cssAttr
hi def link cssPrintAttr cssAttr
hi def link cssRubyAttr cssAttr
diff --git a/runtime/syntax/go.vim b/runtime/syntax/go.vim
index 1439487f69..0c326254b8 100644
--- a/runtime/syntax/go.vim
+++ b/runtime/syntax/go.vim
@@ -5,7 +5,7 @@
" go.vim: Vim syntax file for Go.
" Language: Go
" Maintainer: Billie Cleek <bhcleek@gmail.com>
-" Latest Revision: 2021-06-26
+" Latest Revision: 2021-09-18
" License: BSD-style. See LICENSE file in source repository.
" Repository: https://github.com/fatih/vim-go
@@ -250,7 +250,7 @@ syn match goDecimalError "\<-\=\(_\(\d\+_*\)\+\|\([1-9]\d*_*\)\+__\(\
syn match goHexadecimalInt "\<-\=0[xX]_\?\(\x\+_\?\)\+\>"
syn match goHexadecimalError "\<-\=0[xX]_\?\(\x\+_\?\)*\(\([^ \t0-9A-Fa-f_)]\|__\)\S*\|_\)\>"
syn match goOctalInt "\<-\=0[oO]\?_\?\(\o\+_\?\)\+\>"
-syn match goOctalError "\<-\=0[0-7oO_]*\(\([^ \t0-7oOxX_/)\]\}\:]\|[oO]\{2,\}\|__\)\S*\|_\|[oOxX]\)\>"
+syn match goOctalError "\<-\=0[0-7oO_]*\(\([^ \t0-7oOxX_/)\]\}\:;]\|[oO]\{2,\}\|__\)\S*\|_\|[oOxX]\)\>"
syn match goBinaryInt "\<-\=0[bB]_\?\([01]\+_\?\)\+\>"
syn match goBinaryError "\<-\=0[bB]_\?[01_]*\([^ \t01_)]\S*\|__\S*\|_\)\>"
@@ -430,7 +430,7 @@ endif
" Build Constraints
if s:HighlightBuildConstraints()
- syn match goBuildKeyword display contained "+build"
+ syn match goBuildKeyword display contained "+build\|go:build"
" Highlight the known values of GOOS, GOARCH, and other +build options.
syn keyword goBuildDirectives contained
\ android darwin dragonfly freebsd linux nacl netbsd openbsd plan9
diff --git a/runtime/syntax/gprof.vim b/runtime/syntax/gprof.vim
index 880452a84b..d2c5cb4cab 100644
--- a/runtime/syntax/gprof.vim
+++ b/runtime/syntax/gprof.vim
@@ -1,15 +1,16 @@
" Vim syntax file
" Language: Syntax for Gprof Output
" Maintainer: Dominique Pelle <dominique.pelle@gmail.com>
-" Last Change: 2021 Apr 08
+" Last Change: 2021 Sep 19
" Quit when a syntax file was already loaded
if exists("b:current_syntax")
- finish
+ finish
endif
let s:keepcpo= &cpo
set cpo&vim
+syn spell notoplevel
syn case match
syn sync minlines=100
diff --git a/runtime/syntax/nginx.vim b/runtime/syntax/nginx.vim
new file mode 100644
index 0000000000..18dd50cbb2
--- /dev/null
+++ b/runtime/syntax/nginx.vim
@@ -0,0 +1,2307 @@
+" Vim syntax file
+" Language: nginx.conf
+" Maintainer: Chris Aumann <me@chr4.org>
+" Last Change: Apr 15, 2017
+
+if exists("b:current_syntax")
+ finish
+end
+
+let b:current_syntax = "nginx"
+
+syn match ngxVariable '\$\(\w\+\|{\w\+}\)'
+syn match ngxVariableBlock '\$\(\w\+\|{\w\+}\)' contained
+syn match ngxVariableString '\$\(\w\+\|{\w\+}\)' contained
+syn region ngxBlock start=+^+ end=+{+ skip=+\${\|{{\|{%+ contains=ngxComment,ngxInteger,ngxIPaddr,ngxDirectiveBlock,ngxVariableBlock,ngxString,ngxThirdPartyLuaBlock oneline
+syn region ngxString start=+[^:a-zA-Z>!\\@]\z(["']\)+lc=1 end=+\z1+ skip=+\\\\\|\\\z1+ contains=ngxVariableString,ngxSSLCipherInsecure
+syn match ngxComment ' *#.*$'
+
+" These regular expressions where taken (and adapted) from
+" http://vim.1045645.n5.nabble.com/IPv6-support-for-quot-dns-quot-zonefile-syntax-highlighting-td1197292.html
+syn match ngxInteger '\W\zs\(\d[0-9.]*\|[0-9.]*\d\)\w\?\ze\W'
+syn match ngxIPaddr '\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}'
+syn match ngxIPaddr '\[\(\x\{1,4}:\)\{6}\(\x\{1,4}:\x\{1,4}\|\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\]'
+syn match ngxIPaddr '\[::\(\(\x\{1,4}:\)\{,6}\x\{1,4}\|\(\x\{1,4}:\)\{,5}\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\]'
+syn match ngxIPaddr '\[\(\x\{1,4}:\)\{1}:\(\(\x\{1,4}:\)\{,5}\x\{1,4}\|\(\x\{1,4}:\)\{,4}\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\]'
+syn match ngxIPaddr '\[\(\x\{1,4}:\)\{2}:\(\(\x\{1,4}:\)\{,4}\x\{1,4}\|\(\x\{1,4}:\)\{,3}\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\]'
+syn match ngxIPaddr '\[\(\x\{1,4}:\)\{3}:\(\(\x\{1,4}:\)\{,3}\x\{1,4}\|\(\x\{1,4}:\)\{,2}\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\]'
+syn match ngxIPaddr '\[\(\x\{1,4}:\)\{4}:\(\(\x\{1,4}:\)\{,2}\x\{1,4}\|\(\x\{1,4}:\)\{,1}\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\]'
+syn match ngxIPaddr '\[\(\x\{1,4}:\)\{5}:\(\(\x\{1,4}:\)\{,1}\x\{1,4}\|\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\]'
+syn match ngxIPaddr '\[\(\x\{1,4}:\)\{6}:\x\{1,4}\]'
+
+" Highlight wildcard listening signs also as IPaddr
+syn match ngxIPaddr '\s\zs\[::]'
+syn match ngxIPaddr '\s\zs\*'
+
+syn keyword ngxBoolean on
+syn keyword ngxBoolean off
+
+syn keyword ngxDirectiveBlock http contained
+syn keyword ngxDirectiveBlock mail contained
+syn keyword ngxDirectiveBlock events contained
+syn keyword ngxDirectiveBlock server contained
+syn keyword ngxDirectiveBlock match contained
+syn keyword ngxDirectiveBlock types contained
+syn keyword ngxDirectiveBlock location contained
+syn keyword ngxDirectiveBlock upstream contained
+syn keyword ngxDirectiveBlock charset_map contained
+syn keyword ngxDirectiveBlock limit_except contained
+syn keyword ngxDirectiveBlock if contained
+syn keyword ngxDirectiveBlock geo contained
+syn keyword ngxDirectiveBlock map contained
+syn keyword ngxDirectiveBlock split_clients contained
+
+syn keyword ngxDirectiveImportant include
+syn keyword ngxDirectiveImportant root
+syn keyword ngxDirectiveImportant server contained
+syn region ngxDirectiveImportantServer matchgroup=ngxDirectiveImportant start=+^\s*\zsserver\ze\s.*;+ skip=+\\\\\|\\\;+ end=+;+he=e-1 contains=ngxUpstreamServerOptions,ngxString,ngxIPaddr,ngxBoolean,ngxInteger,ngxTemplateVar
+syn keyword ngxDirectiveImportant server_name
+syn keyword ngxDirectiveImportant listen contained
+syn region ngxDirectiveImportantListen matchgroup=ngxDirectiveImportant start=+listen+ skip=+\\\\\|\\\;+ end=+;+he=e-1 contains=ngxListenOptions,ngxString,ngxIPaddr,ngxBoolean,ngxInteger,ngxTemplateVar
+syn keyword ngxDirectiveImportant internal
+syn keyword ngxDirectiveImportant proxy_pass
+syn keyword ngxDirectiveImportant memcached_pass
+syn keyword ngxDirectiveImportant fastcgi_pass
+syn keyword ngxDirectiveImportant scgi_pass
+syn keyword ngxDirectiveImportant uwsgi_pass
+syn keyword ngxDirectiveImportant try_files
+syn keyword ngxDirectiveImportant error_page
+syn keyword ngxDirectiveImportant post_action
+
+syn keyword ngxUpstreamServerOptions weight contained
+syn keyword ngxUpstreamServerOptions max_conns contained
+syn keyword ngxUpstreamServerOptions max_fails contained
+syn keyword ngxUpstreamServerOptions fail_timeout contained
+syn keyword ngxUpstreamServerOptions backup contained
+syn keyword ngxUpstreamServerOptions down contained
+syn keyword ngxUpstreamServerOptions resolve contained
+syn keyword ngxUpstreamServerOptions route contained
+syn keyword ngxUpstreamServerOptions service contained
+syn keyword ngxUpstreamServerOptions default_server contained
+syn keyword ngxUpstreamServerOptions slow_start contained
+
+syn keyword ngxListenOptions default_server contained
+syn keyword ngxListenOptions ssl contained
+syn keyword ngxListenOptions http2 contained
+syn keyword ngxListenOptions spdy contained
+syn keyword ngxListenOptions proxy_protocol contained
+syn keyword ngxListenOptions setfib contained
+syn keyword ngxListenOptions fastopen contained
+syn keyword ngxListenOptions backlog contained
+syn keyword ngxListenOptions rcvbuf contained
+syn keyword ngxListenOptions sndbuf contained
+syn keyword ngxListenOptions accept_filter contained
+syn keyword ngxListenOptions deferred contained
+syn keyword ngxListenOptions bind contained
+syn keyword ngxListenOptions ipv6only contained
+syn keyword ngxListenOptions reuseport contained
+syn keyword ngxListenOptions so_keepalive contained
+syn keyword ngxListenOptions keepidle contained
+
+syn keyword ngxDirectiveControl break
+syn keyword ngxDirectiveControl return
+syn keyword ngxDirectiveControl rewrite
+syn keyword ngxDirectiveControl set
+
+syn keyword ngxDirectiveDeprecated connections
+syn keyword ngxDirectiveDeprecated imap
+syn keyword ngxDirectiveDeprecated limit_zone
+syn keyword ngxDirectiveDeprecated mysql_test
+syn keyword ngxDirectiveDeprecated open_file_cache_retest
+syn keyword ngxDirectiveDeprecated optimize_server_names
+syn keyword ngxDirectiveDeprecated satisfy_any
+syn keyword ngxDirectiveDeprecated so_keepalive
+
+syn keyword ngxDirective absolute_redirect
+syn keyword ngxDirective accept_mutex
+syn keyword ngxDirective accept_mutex_delay
+syn keyword ngxDirective acceptex_read
+syn keyword ngxDirective access_log
+syn keyword ngxDirective add_after_body
+syn keyword ngxDirective add_before_body
+syn keyword ngxDirective add_header
+syn keyword ngxDirective addition_types
+syn keyword ngxDirective aio
+syn keyword ngxDirective aio_write
+syn keyword ngxDirective alias
+syn keyword ngxDirective allow
+syn keyword ngxDirective ancient_browser
+syn keyword ngxDirective ancient_browser_value
+syn keyword ngxDirective auth_basic
+syn keyword ngxDirective auth_basic_user_file
+syn keyword ngxDirective auth_http
+syn keyword ngxDirective auth_http_header
+syn keyword ngxDirective auth_http_pass_client_cert
+syn keyword ngxDirective auth_http_timeout
+syn keyword ngxDirective auth_jwt
+syn keyword ngxDirective auth_jwt_key_file
+syn keyword ngxDirective auth_request
+syn keyword ngxDirective auth_request_set
+syn keyword ngxDirective autoindex
+syn keyword ngxDirective autoindex_exact_size
+syn keyword ngxDirective autoindex_format
+syn keyword ngxDirective autoindex_localtime
+syn keyword ngxDirective charset
+syn keyword ngxDirective charset_map
+syn keyword ngxDirective charset_types
+syn keyword ngxDirective chunked_transfer_encoding
+syn keyword ngxDirective client_body_buffer_size
+syn keyword ngxDirective client_body_in_file_only
+syn keyword ngxDirective client_body_in_single_buffer
+syn keyword ngxDirective client_body_temp_path
+syn keyword ngxDirective client_body_timeout
+syn keyword ngxDirective client_header_buffer_size
+syn keyword ngxDirective client_header_timeout
+syn keyword ngxDirective client_max_body_size
+syn keyword ngxDirective connection_pool_size
+syn keyword ngxDirective create_full_put_path
+syn keyword ngxDirective daemon
+syn keyword ngxDirective dav_access
+syn keyword ngxDirective dav_methods
+syn keyword ngxDirective debug_connection
+syn keyword ngxDirective debug_points
+syn keyword ngxDirective default_type
+syn keyword ngxDirective degradation
+syn keyword ngxDirective degrade
+syn keyword ngxDirective deny
+syn keyword ngxDirective devpoll_changes
+syn keyword ngxDirective devpoll_events
+syn keyword ngxDirective directio
+syn keyword ngxDirective directio_alignment
+syn keyword ngxDirective disable_symlinks
+syn keyword ngxDirective empty_gif
+syn keyword ngxDirective env
+syn keyword ngxDirective epoll_events
+syn keyword ngxDirective error_log
+syn keyword ngxDirective etag
+syn keyword ngxDirective eventport_events
+syn keyword ngxDirective expires
+syn keyword ngxDirective f4f
+syn keyword ngxDirective f4f_buffer_size
+syn keyword ngxDirective fastcgi_bind
+syn keyword ngxDirective fastcgi_buffer_size
+syn keyword ngxDirective fastcgi_buffering
+syn keyword ngxDirective fastcgi_buffers
+syn keyword ngxDirective fastcgi_busy_buffers_size
+syn keyword ngxDirective fastcgi_cache
+syn keyword ngxDirective fastcgi_cache_bypass
+syn keyword ngxDirective fastcgi_cache_key
+syn keyword ngxDirective fastcgi_cache_lock
+syn keyword ngxDirective fastcgi_cache_lock_age
+syn keyword ngxDirective fastcgi_cache_lock_timeout
+syn keyword ngxDirective fastcgi_cache_max_range_offset
+syn keyword ngxDirective fastcgi_cache_methods
+syn keyword ngxDirective fastcgi_cache_min_uses
+syn keyword ngxDirective fastcgi_cache_path
+syn keyword ngxDirective fastcgi_cache_purge
+syn keyword ngxDirective fastcgi_cache_revalidate
+syn keyword ngxDirective fastcgi_cache_use_stale
+syn keyword ngxDirective fastcgi_cache_valid
+syn keyword ngxDirective fastcgi_catch_stderr
+syn keyword ngxDirective fastcgi_connect_timeout
+syn keyword ngxDirective fastcgi_force_ranges
+syn keyword ngxDirective fastcgi_hide_header
+syn keyword ngxDirective fastcgi_ignore_client_abort
+syn keyword ngxDirective fastcgi_ignore_headers
+syn keyword ngxDirective fastcgi_index
+syn keyword ngxDirective fastcgi_intercept_errors
+syn keyword ngxDirective fastcgi_keep_conn
+syn keyword ngxDirective fastcgi_limit_rate
+syn keyword ngxDirective fastcgi_max_temp_file_size
+syn keyword ngxDirective fastcgi_next_upstream
+syn keyword ngxDirective fastcgi_next_upstream_timeout
+syn keyword ngxDirective fastcgi_next_upstream_tries
+syn keyword ngxDirective fastcgi_no_cache
+syn keyword ngxDirective fastcgi_param
+syn keyword ngxDirective fastcgi_pass_header
+syn keyword ngxDirective fastcgi_pass_request_body
+syn keyword ngxDirective fastcgi_pass_request_headers
+syn keyword ngxDirective fastcgi_read_timeout
+syn keyword ngxDirective fastcgi_request_buffering
+syn keyword ngxDirective fastcgi_send_lowat
+syn keyword ngxDirective fastcgi_send_timeout
+syn keyword ngxDirective fastcgi_split_path_info
+syn keyword ngxDirective fastcgi_store
+syn keyword ngxDirective fastcgi_store_access
+syn keyword ngxDirective fastcgi_temp_file_write_size
+syn keyword ngxDirective fastcgi_temp_path
+syn keyword ngxDirective flv
+syn keyword ngxDirective geoip_city
+syn keyword ngxDirective geoip_country
+syn keyword ngxDirective geoip_org
+syn keyword ngxDirective geoip_proxy
+syn keyword ngxDirective geoip_proxy_recursive
+syn keyword ngxDirective google_perftools_profiles
+syn keyword ngxDirective gunzip
+syn keyword ngxDirective gunzip_buffers
+syn keyword ngxDirective gzip nextgroup=ngxGzipOn,ngxGzipOff skipwhite
+syn keyword ngxGzipOn on contained
+syn keyword ngxGzipOff off contained
+syn keyword ngxDirective gzip_buffers
+syn keyword ngxDirective gzip_comp_level
+syn keyword ngxDirective gzip_disable
+syn keyword ngxDirective gzip_hash
+syn keyword ngxDirective gzip_http_version
+syn keyword ngxDirective gzip_min_length
+syn keyword ngxDirective gzip_no_buffer
+syn keyword ngxDirective gzip_proxied
+syn keyword ngxDirective gzip_static
+syn keyword ngxDirective gzip_types
+syn keyword ngxDirective gzip_vary
+syn keyword ngxDirective gzip_window
+syn keyword ngxDirective hash
+syn keyword ngxDirective health_check
+syn keyword ngxDirective health_check_timeout
+syn keyword ngxDirective hls
+syn keyword ngxDirective hls_buffers
+syn keyword ngxDirective hls_forward_args
+syn keyword ngxDirective hls_fragment
+syn keyword ngxDirective hls_mp4_buffer_size
+syn keyword ngxDirective hls_mp4_max_buffer_size
+syn keyword ngxDirective http2_chunk_size
+syn keyword ngxDirective http2_body_preread_size
+syn keyword ngxDirective http2_idle_timeout
+syn keyword ngxDirective http2_max_concurrent_streams
+syn keyword ngxDirective http2_max_field_size
+syn keyword ngxDirective http2_max_header_size
+syn keyword ngxDirective http2_max_requests
+syn keyword ngxDirective http2_recv_buffer_size
+syn keyword ngxDirective http2_recv_timeout
+syn keyword ngxDirective if_modified_since
+syn keyword ngxDirective ignore_invalid_headers
+syn keyword ngxDirective image_filter
+syn keyword ngxDirective image_filter_buffer
+syn keyword ngxDirective image_filter_interlace
+syn keyword ngxDirective image_filter_jpeg_quality
+syn keyword ngxDirective image_filter_sharpen
+syn keyword ngxDirective image_filter_transparency
+syn keyword ngxDirective image_filter_webp_quality
+syn keyword ngxDirective imap_auth
+syn keyword ngxDirective imap_capabilities
+syn keyword ngxDirective imap_client_buffer
+syn keyword ngxDirective index
+syn keyword ngxDirective iocp_threads
+syn keyword ngxDirective ip_hash
+syn keyword ngxDirective js_access
+syn keyword ngxDirective js_content
+syn keyword ngxDirective js_filter
+syn keyword ngxDirective js_include
+syn keyword ngxDirective js_preread
+syn keyword ngxDirective js_set
+syn keyword ngxDirective keepalive
+syn keyword ngxDirective keepalive_disable
+syn keyword ngxDirective keepalive_requests
+syn keyword ngxDirective keepalive_timeout
+syn keyword ngxDirective kqueue_changes
+syn keyword ngxDirective kqueue_events
+syn keyword ngxDirective large_client_header_buffers
+syn keyword ngxDirective least_conn
+syn keyword ngxDirective least_time
+syn keyword ngxDirective limit_conn
+syn keyword ngxDirective limit_conn_dry_run
+syn keyword ngxDirective limit_conn_log_level
+syn keyword ngxDirective limit_conn_status
+syn keyword ngxDirective limit_conn_zone
+syn keyword ngxDirective limit_except
+syn keyword ngxDirective limit_rate
+syn keyword ngxDirective limit_rate_after
+syn keyword ngxDirective limit_req
+syn keyword ngxDirective limit_req_dry_run
+syn keyword ngxDirective limit_req_log_level
+syn keyword ngxDirective limit_req_status
+syn keyword ngxDirective limit_req_zone
+syn keyword ngxDirective lingering_close
+syn keyword ngxDirective lingering_time
+syn keyword ngxDirective lingering_timeout
+syn keyword ngxDirective load_module
+syn keyword ngxDirective lock_file
+syn keyword ngxDirective log_format
+syn keyword ngxDirective log_not_found
+syn keyword ngxDirective log_subrequest
+syn keyword ngxDirective map_hash_bucket_size
+syn keyword ngxDirective map_hash_max_size
+syn keyword ngxDirective master_process
+syn keyword ngxDirective max_ranges
+syn keyword ngxDirective memcached_bind
+syn keyword ngxDirective memcached_buffer_size
+syn keyword ngxDirective memcached_connect_timeout
+syn keyword ngxDirective memcached_force_ranges
+syn keyword ngxDirective memcached_gzip_flag
+syn keyword ngxDirective memcached_next_upstream
+syn keyword ngxDirective memcached_next_upstream_timeout
+syn keyword ngxDirective memcached_next_upstream_tries
+syn keyword ngxDirective memcached_read_timeout
+syn keyword ngxDirective memcached_send_timeout
+syn keyword ngxDirective merge_slashes
+syn keyword ngxDirective min_delete_depth
+syn keyword ngxDirective modern_browser
+syn keyword ngxDirective modern_browser_value
+syn keyword ngxDirective mp4
+syn keyword ngxDirective mp4_buffer_size
+syn keyword ngxDirective mp4_max_buffer_size
+syn keyword ngxDirective mp4_limit_rate
+syn keyword ngxDirective mp4_limit_rate_after
+syn keyword ngxDirective msie_padding
+syn keyword ngxDirective msie_refresh
+syn keyword ngxDirective multi_accept
+syn keyword ngxDirective ntlm
+syn keyword ngxDirective open_file_cache
+syn keyword ngxDirective open_file_cache_errors
+syn keyword ngxDirective open_file_cache_events
+syn keyword ngxDirective open_file_cache_min_uses
+syn keyword ngxDirective open_file_cache_valid
+syn keyword ngxDirective open_log_file_cache
+syn keyword ngxDirective output_buffers
+syn keyword ngxDirective override_charset
+syn keyword ngxDirective pcre_jit
+syn keyword ngxDirective perl
+syn keyword ngxDirective perl_modules
+syn keyword ngxDirective perl_require
+syn keyword ngxDirective perl_set
+syn keyword ngxDirective pid
+syn keyword ngxDirective pop3_auth
+syn keyword ngxDirective pop3_capabilities
+syn keyword ngxDirective port_in_redirect
+syn keyword ngxDirective post_acceptex
+syn keyword ngxDirective postpone_gzipping
+syn keyword ngxDirective postpone_output
+syn keyword ngxDirective preread_buffer_size
+syn keyword ngxDirective preread_timeout
+syn keyword ngxDirective protocol nextgroup=ngxMailProtocol skipwhite
+syn keyword ngxMailProtocol imap pop3 smtp contained
+syn keyword ngxDirective proxy
+syn keyword ngxDirective proxy_bind
+syn keyword ngxDirective proxy_buffer
+syn keyword ngxDirective proxy_buffer_size
+syn keyword ngxDirective proxy_buffering
+syn keyword ngxDirective proxy_buffers
+syn keyword ngxDirective proxy_busy_buffers_size
+syn keyword ngxDirective proxy_cache
+syn keyword ngxDirective proxy_cache_bypass
+syn keyword ngxDirective proxy_cache_convert_head
+syn keyword ngxDirective proxy_cache_key
+syn keyword ngxDirective proxy_cache_lock
+syn keyword ngxDirective proxy_cache_lock_age
+syn keyword ngxDirective proxy_cache_lock_timeout
+syn keyword ngxDirective proxy_cache_max_range_offset
+syn keyword ngxDirective proxy_cache_methods
+syn keyword ngxDirective proxy_cache_min_uses
+syn keyword ngxDirective proxy_cache_path
+syn keyword ngxDirective proxy_cache_purge
+syn keyword ngxDirective proxy_cache_revalidate
+syn keyword ngxDirective proxy_cache_use_stale
+syn keyword ngxDirective proxy_cache_valid
+syn keyword ngxDirective proxy_connect_timeout
+syn keyword ngxDirective proxy_cookie_domain
+syn keyword ngxDirective proxy_cookie_path
+syn keyword ngxDirective proxy_download_rate
+syn keyword ngxDirective proxy_force_ranges
+syn keyword ngxDirective proxy_headers_hash_bucket_size
+syn keyword ngxDirective proxy_headers_hash_max_size
+syn keyword ngxDirective proxy_hide_header
+syn keyword ngxDirective proxy_http_version
+syn keyword ngxDirective proxy_ignore_client_abort
+syn keyword ngxDirective proxy_ignore_headers
+syn keyword ngxDirective proxy_intercept_errors
+syn keyword ngxDirective proxy_limit_rate
+syn keyword ngxDirective proxy_max_temp_file_size
+syn keyword ngxDirective proxy_method
+syn keyword ngxDirective proxy_next_upstream contained
+syn region ngxDirectiveProxyNextUpstream matchgroup=ngxDirective start=+^\s*\zsproxy_next_upstream\ze\s.*;+ skip=+\\\\\|\\\;+ end=+;+he=e-1 contains=ngxProxyNextUpstreamOptions,ngxString,ngxTemplateVar
+syn keyword ngxDirective proxy_next_upstream_timeout
+syn keyword ngxDirective proxy_next_upstream_tries
+syn keyword ngxDirective proxy_no_cache
+syn keyword ngxDirective proxy_pass_error_message
+syn keyword ngxDirective proxy_pass_header
+syn keyword ngxDirective proxy_pass_request_body
+syn keyword ngxDirective proxy_pass_request_headers
+syn keyword ngxDirective proxy_protocol
+syn keyword ngxDirective proxy_protocol_timeout
+syn keyword ngxDirective proxy_read_timeout
+syn keyword ngxDirective proxy_redirect
+syn keyword ngxDirective proxy_request_buffering
+syn keyword ngxDirective proxy_responses
+syn keyword ngxDirective proxy_send_lowat
+syn keyword ngxDirective proxy_send_timeout
+syn keyword ngxDirective proxy_set_body
+syn keyword ngxDirective proxy_set_header
+syn keyword ngxDirective proxy_ssl_certificate
+syn keyword ngxDirective proxy_ssl_certificate_key
+syn keyword ngxDirective proxy_ssl_ciphers
+syn keyword ngxDirective proxy_ssl_crl
+syn keyword ngxDirective proxy_ssl_name
+syn keyword ngxDirective proxy_ssl_password_file
+syn keyword ngxDirective proxy_ssl_protocols nextgroup=ngxSSLProtocol skipwhite
+syn keyword ngxDirective proxy_ssl_server_name
+syn keyword ngxDirective proxy_ssl_session_reuse
+syn keyword ngxDirective proxy_ssl_trusted_certificate
+syn keyword ngxDirective proxy_ssl_verify
+syn keyword ngxDirective proxy_ssl_verify_depth
+syn keyword ngxDirective proxy_store
+syn keyword ngxDirective proxy_store_access
+syn keyword ngxDirective proxy_temp_file_write_size
+syn keyword ngxDirective proxy_temp_path
+syn keyword ngxDirective proxy_timeout
+syn keyword ngxDirective proxy_upload_rate
+syn keyword ngxDirective queue
+syn keyword ngxDirective random_index
+syn keyword ngxDirective read_ahead
+syn keyword ngxDirective real_ip_header
+syn keyword ngxDirective real_ip_recursive
+syn keyword ngxDirective recursive_error_pages
+syn keyword ngxDirective referer_hash_bucket_size
+syn keyword ngxDirective referer_hash_max_size
+syn keyword ngxDirective request_pool_size
+syn keyword ngxDirective reset_timedout_connection
+syn keyword ngxDirective resolver
+syn keyword ngxDirective resolver_timeout
+syn keyword ngxDirective rewrite_log
+syn keyword ngxDirective rtsig_overflow_events
+syn keyword ngxDirective rtsig_overflow_test
+syn keyword ngxDirective rtsig_overflow_threshold
+syn keyword ngxDirective rtsig_signo
+syn keyword ngxDirective satisfy
+syn keyword ngxDirective scgi_bind
+syn keyword ngxDirective scgi_buffer_size
+syn keyword ngxDirective scgi_buffering
+syn keyword ngxDirective scgi_buffers
+syn keyword ngxDirective scgi_busy_buffers_size
+syn keyword ngxDirective scgi_cache
+syn keyword ngxDirective scgi_cache_bypass
+syn keyword ngxDirective scgi_cache_key
+syn keyword ngxDirective scgi_cache_lock
+syn keyword ngxDirective scgi_cache_lock_age
+syn keyword ngxDirective scgi_cache_lock_timeout
+syn keyword ngxDirective scgi_cache_max_range_offset
+syn keyword ngxDirective scgi_cache_methods
+syn keyword ngxDirective scgi_cache_min_uses
+syn keyword ngxDirective scgi_cache_path
+syn keyword ngxDirective scgi_cache_purge
+syn keyword ngxDirective scgi_cache_revalidate
+syn keyword ngxDirective scgi_cache_use_stale
+syn keyword ngxDirective scgi_cache_valid
+syn keyword ngxDirective scgi_connect_timeout
+syn keyword ngxDirective scgi_force_ranges
+syn keyword ngxDirective scgi_hide_header
+syn keyword ngxDirective scgi_ignore_client_abort
+syn keyword ngxDirective scgi_ignore_headers
+syn keyword ngxDirective scgi_intercept_errors
+syn keyword ngxDirective scgi_limit_rate
+syn keyword ngxDirective scgi_max_temp_file_size
+syn keyword ngxDirective scgi_next_upstream
+syn keyword ngxDirective scgi_next_upstream_timeout
+syn keyword ngxDirective scgi_next_upstream_tries
+syn keyword ngxDirective scgi_no_cache
+syn keyword ngxDirective scgi_param
+syn keyword ngxDirective scgi_pass_header
+syn keyword ngxDirective scgi_pass_request_body
+syn keyword ngxDirective scgi_pass_request_headers
+syn keyword ngxDirective scgi_read_timeout
+syn keyword ngxDirective scgi_request_buffering
+syn keyword ngxDirective scgi_send_timeout
+syn keyword ngxDirective scgi_store
+syn keyword ngxDirective scgi_store_access
+syn keyword ngxDirective scgi_temp_file_write_size
+syn keyword ngxDirective scgi_temp_path
+syn keyword ngxDirective secure_link
+syn keyword ngxDirective secure_link_md5
+syn keyword ngxDirective secure_link_secret
+syn keyword ngxDirective send_lowat
+syn keyword ngxDirective send_timeout
+syn keyword ngxDirective sendfile
+syn keyword ngxDirective sendfile_max_chunk
+syn keyword ngxDirective server_name_in_redirect
+syn keyword ngxDirective server_names_hash_bucket_size
+syn keyword ngxDirective server_names_hash_max_size
+syn keyword ngxDirective server_tokens
+syn keyword ngxDirective session_log
+syn keyword ngxDirective session_log_format
+syn keyword ngxDirective session_log_zone
+syn keyword ngxDirective set_real_ip_from
+syn keyword ngxDirective slice
+syn keyword ngxDirective smtp_auth
+syn keyword ngxDirective smtp_capabilities
+syn keyword ngxDirective smtp_client_buffer
+syn keyword ngxDirective smtp_greeting_delay
+syn keyword ngxDirective source_charset
+syn keyword ngxDirective spdy_chunk_size
+syn keyword ngxDirective spdy_headers_comp
+syn keyword ngxDirective spdy_keepalive_timeout
+syn keyword ngxDirective spdy_max_concurrent_streams
+syn keyword ngxDirective spdy_pool_size
+syn keyword ngxDirective spdy_recv_buffer_size
+syn keyword ngxDirective spdy_recv_timeout
+syn keyword ngxDirective spdy_streams_index_size
+syn keyword ngxDirective ssi
+syn keyword ngxDirective ssi_ignore_recycled_buffers
+syn keyword ngxDirective ssi_last_modified
+syn keyword ngxDirective ssi_min_file_chunk
+syn keyword ngxDirective ssi_silent_errors
+syn keyword ngxDirective ssi_types
+syn keyword ngxDirective ssi_value_length
+syn keyword ngxDirective ssl
+syn keyword ngxDirective ssl_buffer_size
+syn keyword ngxDirective ssl_certificate
+syn keyword ngxDirective ssl_certificate_key
+syn keyword ngxDirective ssl_ciphers
+syn keyword ngxDirective ssl_client_certificate
+syn keyword ngxDirective ssl_crl
+syn keyword ngxDirective ssl_dhparam
+syn keyword ngxDirective ssl_ecdh_curve
+syn keyword ngxDirective ssl_engine
+syn keyword ngxDirective ssl_handshake_timeout
+syn keyword ngxDirective ssl_password_file
+syn keyword ngxDirective ssl_prefer_server_ciphers nextgroup=ngxSSLPreferServerCiphersOff,ngxSSLPreferServerCiphersOn skipwhite
+syn keyword ngxSSLPreferServerCiphersOn on contained
+syn keyword ngxSSLPreferServerCiphersOff off contained
+syn keyword ngxDirective ssl_preread
+syn keyword ngxDirective ssl_protocols nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite
+syn match ngxSSLProtocol 'TLSv1' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite
+syn match ngxSSLProtocol 'TLSv1\.1' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite
+syn match ngxSSLProtocol 'TLSv1\.2' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite
+syn match ngxSSLProtocol 'TLSv1\.3' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite
+
+" Do not enable highlighting of insecure protocols if sslecure is loaded
+if !exists('g:loaded_sslsecure')
+ syn keyword ngxSSLProtocolDeprecated SSLv2 SSLv3 contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite
+else
+ syn match ngxSSLProtocol 'SSLv2' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite
+ syn match ngxSSLProtocol 'SSLv3' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite
+endif
+
+syn keyword ngxDirective ssl_session_cache
+syn keyword ngxDirective ssl_session_ticket_key
+syn keyword ngxDirective ssl_session_tickets nextgroup=ngxSSLSessionTicketsOn,ngxSSLSessionTicketsOff skipwhite
+syn keyword ngxSSLSessionTicketsOn on contained
+syn keyword ngxSSLSessionTicketsOff off contained
+syn keyword ngxDirective ssl_session_timeout
+syn keyword ngxDirective ssl_stapling
+syn keyword ngxDirective ssl_stapling_file
+syn keyword ngxDirective ssl_stapling_responder
+syn keyword ngxDirective ssl_stapling_verify
+syn keyword ngxDirective ssl_trusted_certificate
+syn keyword ngxDirective ssl_verify_client
+syn keyword ngxDirective ssl_verify_depth
+syn keyword ngxDirective starttls
+syn keyword ngxDirective state
+syn keyword ngxDirective status
+syn keyword ngxDirective status_format
+syn keyword ngxDirective status_zone
+syn keyword ngxDirective sticky contained
+syn keyword ngxDirective sticky_cookie_insert contained
+syn region ngxDirectiveSticky matchgroup=ngxDirective start=+^\s*\zssticky\ze\s.*;+ skip=+\\\\\|\\\;+ end=+;+he=e-1 contains=ngxCookieOptions,ngxString,ngxBoolean,ngxInteger,ngxTemplateVar
+syn keyword ngxDirective stub_status
+syn keyword ngxDirective sub_filter
+syn keyword ngxDirective sub_filter_last_modified
+syn keyword ngxDirective sub_filter_once
+syn keyword ngxDirective sub_filter_types
+syn keyword ngxDirective tcp_nodelay
+syn keyword ngxDirective tcp_nopush
+syn keyword ngxDirective thread_pool
+syn keyword ngxDirective thread_stack_size
+syn keyword ngxDirective timeout
+syn keyword ngxDirective timer_resolution
+syn keyword ngxDirective types_hash_bucket_size
+syn keyword ngxDirective types_hash_max_size
+syn keyword ngxDirective underscores_in_headers
+syn keyword ngxDirective uninitialized_variable_warn
+syn keyword ngxDirective upstream_conf
+syn keyword ngxDirective use
+syn keyword ngxDirective user
+syn keyword ngxDirective userid
+syn keyword ngxDirective userid_domain
+syn keyword ngxDirective userid_expires
+syn keyword ngxDirective userid_mark
+syn keyword ngxDirective userid_name
+syn keyword ngxDirective userid_p3p
+syn keyword ngxDirective userid_path
+syn keyword ngxDirective userid_service
+syn keyword ngxDirective uwsgi_bind
+syn keyword ngxDirective uwsgi_buffer_size
+syn keyword ngxDirective uwsgi_buffering
+syn keyword ngxDirective uwsgi_buffers
+syn keyword ngxDirective uwsgi_busy_buffers_size
+syn keyword ngxDirective uwsgi_cache
+syn keyword ngxDirective uwsgi_cache_bypass
+syn keyword ngxDirective uwsgi_cache_key
+syn keyword ngxDirective uwsgi_cache_lock
+syn keyword ngxDirective uwsgi_cache_lock_age
+syn keyword ngxDirective uwsgi_cache_lock_timeout
+syn keyword ngxDirective uwsgi_cache_methods
+syn keyword ngxDirective uwsgi_cache_min_uses
+syn keyword ngxDirective uwsgi_cache_path
+syn keyword ngxDirective uwsgi_cache_purge
+syn keyword ngxDirective uwsgi_cache_revalidate
+syn keyword ngxDirective uwsgi_cache_use_stale
+syn keyword ngxDirective uwsgi_cache_valid
+syn keyword ngxDirective uwsgi_connect_timeout
+syn keyword ngxDirective uwsgi_force_ranges
+syn keyword ngxDirective uwsgi_hide_header
+syn keyword ngxDirective uwsgi_ignore_client_abort
+syn keyword ngxDirective uwsgi_ignore_headers
+syn keyword ngxDirective uwsgi_intercept_errors
+syn keyword ngxDirective uwsgi_limit_rate
+syn keyword ngxDirective uwsgi_max_temp_file_size
+syn keyword ngxDirective uwsgi_modifier1
+syn keyword ngxDirective uwsgi_modifier2
+syn keyword ngxDirective uwsgi_next_upstream
+syn keyword ngxDirective uwsgi_next_upstream_timeout
+syn keyword ngxDirective uwsgi_next_upstream_tries
+syn keyword ngxDirective uwsgi_no_cache
+syn keyword ngxDirective uwsgi_param
+syn keyword ngxDirective uwsgi_pass
+syn keyword ngxDirective uwsgi_pass_header
+syn keyword ngxDirective uwsgi_pass_request_body
+syn keyword ngxDirective uwsgi_pass_request_headers
+syn keyword ngxDirective uwsgi_read_timeout
+syn keyword ngxDirective uwsgi_request_buffering
+syn keyword ngxDirective uwsgi_send_timeout
+syn keyword ngxDirective uwsgi_ssl_certificate
+syn keyword ngxDirective uwsgi_ssl_certificate_key
+syn keyword ngxDirective uwsgi_ssl_ciphers
+syn keyword ngxDirective uwsgi_ssl_crl
+syn keyword ngxDirective uwsgi_ssl_name
+syn keyword ngxDirective uwsgi_ssl_password_file
+syn keyword ngxDirective uwsgi_ssl_protocols nextgroup=ngxSSLProtocol skipwhite
+syn keyword ngxDirective uwsgi_ssl_server_name
+syn keyword ngxDirective uwsgi_ssl_session_reuse
+syn keyword ngxDirective uwsgi_ssl_trusted_certificate
+syn keyword ngxDirective uwsgi_ssl_verify
+syn keyword ngxDirective uwsgi_ssl_verify_depth
+syn keyword ngxDirective uwsgi_store
+syn keyword ngxDirective uwsgi_store_access
+syn keyword ngxDirective uwsgi_string
+syn keyword ngxDirective uwsgi_temp_file_write_size
+syn keyword ngxDirective uwsgi_temp_path
+syn keyword ngxDirective valid_referers
+syn keyword ngxDirective variables_hash_bucket_size
+syn keyword ngxDirective variables_hash_max_size
+syn keyword ngxDirective worker_aio_requests
+syn keyword ngxDirective worker_connections
+syn keyword ngxDirective worker_cpu_affinity
+syn keyword ngxDirective worker_priority
+syn keyword ngxDirective worker_processes
+syn keyword ngxDirective worker_rlimit_core
+syn keyword ngxDirective worker_rlimit_nofile
+syn keyword ngxDirective worker_rlimit_sigpending
+syn keyword ngxDirective worker_threads
+syn keyword ngxDirective working_directory
+syn keyword ngxDirective xclient
+syn keyword ngxDirective xml_entities
+syn keyword ngxDirective xslt_last_modified
+syn keyword ngxDirective xslt_param
+syn keyword ngxDirective xslt_string_param
+syn keyword ngxDirective xslt_stylesheet
+syn keyword ngxDirective xslt_types
+syn keyword ngxDirective zone
+
+" Do not enable highlighting of insecure ciphers if sslecure is loaded
+if !exists('g:loaded_sslsecure')
+ " Mark insecure SSL Ciphers (Note: List might not not complete)
+ " Reference: https://www.openssl.org/docs/man1.0.2/apps/ciphers.html
+ syn match ngxSSLCipherInsecure '[^!]\zsSSLv3'
+ syn match ngxSSLCipherInsecure '[^!]\zsSSLv2'
+ syn match ngxSSLCipherInsecure '[^!]\zsHIGH'
+ syn match ngxSSLCipherInsecure '[^!]\zsMEDIUM'
+ syn match ngxSSLCipherInsecure '[^!]\zsLOW'
+ syn match ngxSSLCipherInsecure '[^!]\zsDEFAULT'
+ syn match ngxSSLCipherInsecure '[^!]\zsCOMPLEMENTOFDEFAULT'
+ syn match ngxSSLCipherInsecure '[^!]\zsALL'
+ syn match ngxSSLCipherInsecure '[^!]\zsCOMPLEMENTOFALL'
+
+ " SHA ciphers are only used in HMAC with all known OpenSSL/ LibreSSL cipher suites and MAC
+ " usage is still considered safe
+ " syn match ngxSSLCipherInsecure '[^!]\zsSHA\ze\D' " Match SHA1 without matching SHA256+
+ " syn match ngxSSLCipherInsecure '[^!]\zsSHA1'
+ syn match ngxSSLCipherInsecure '[^!]\zsMD5'
+ syn match ngxSSLCipherInsecure '[^!]\zsRC2'
+ syn match ngxSSLCipherInsecure '[^!]\zsRC4'
+ syn match ngxSSLCipherInsecure '[^!]\zs3DES'
+ syn match ngxSSLCipherInsecure '[^!3]\zsDES'
+ syn match ngxSSLCipherInsecure '[^!]\zsaDSS'
+ syn match ngxSSLCipherInsecure '[^!a]\zsDSS'
+ syn match ngxSSLCipherInsecure '[^!]\zsPSK'
+ syn match ngxSSLCipherInsecure '[^!]\zsIDEA'
+ syn match ngxSSLCipherInsecure '[^!]\zsSEED'
+ syn match ngxSSLCipherInsecure '[^!]\zsEXP\w*' " Match all EXPORT ciphers
+ syn match ngxSSLCipherInsecure '[^!]\zsaGOST\w*' " Match all GOST ciphers
+ syn match ngxSSLCipherInsecure '[^!]\zskGOST\w*'
+ syn match ngxSSLCipherInsecure '[^!ak]\zsGOST\w*'
+ syn match ngxSSLCipherInsecure '[^!]\zs[kae]\?FZA' " Not implemented
+ syn match ngxSSLCipherInsecure '[^!]\zsECB'
+ syn match ngxSSLCipherInsecure '[^!]\zs[aes]NULL'
+
+ " Anonymous cipher suites should never be used
+ syn match ngxSSLCipherInsecure '[^!ECa]\zsDH\ze[^E]' " Try to match DH without DHE, EDH, EECDH, etc.
+ syn match ngxSSLCipherInsecure '[^!EA]\zsECDH\ze[^E]' " Do not match EECDH, ECDHE
+ syn match ngxSSLCipherInsecure '[^!]\zsADH'
+ syn match ngxSSLCipherInsecure '[^!]\zskDHE'
+ syn match ngxSSLCipherInsecure '[^!]\zskEDH'
+ syn match ngxSSLCipherInsecure '[^!]\zskECDHE'
+ syn match ngxSSLCipherInsecure '[^!]\zskEECDH'
+ syn match ngxSSLCipherInsecure '[^!E]\zsAECDH'
+endif
+
+syn keyword ngxProxyNextUpstreamOptions error contained
+syn keyword ngxProxyNextUpstreamOptions timeout contained
+syn keyword ngxProxyNextUpstreamOptions invalid_header contained
+syn keyword ngxProxyNextUpstreamOptions http_500 contained
+syn keyword ngxProxyNextUpstreamOptions http_502 contained
+syn keyword ngxProxyNextUpstreamOptions http_503 contained
+syn keyword ngxProxyNextUpstreamOptions http_504 contained
+syn keyword ngxProxyNextUpstreamOptions http_403 contained
+syn keyword ngxProxyNextUpstreamOptions http_404 contained
+syn keyword ngxProxyNextUpstreamOptions http_429 contained
+syn keyword ngxProxyNextUpstreamOptions non_idempotent contained
+syn keyword ngxProxyNextUpstreamOptions off contained
+
+syn keyword ngxStickyOptions cookie contained
+syn region ngxStickyOptionsCookie matchgroup=ngxStickyOptions start=+^\s*\zssticky\s\s*cookie\ze\s.*;+ skip=+\\\\\|\\\;+ end=+;+he=e-1 contains=ngxCookieOptions,ngxString,ngxBoolean,ngxInteger,ngxTemplateVar
+syn keyword ngxStickyOptions route contained
+syn keyword ngxStickyOptions learn contained
+
+syn keyword ngxCookieOptions expires contained
+syn keyword ngxCookieOptions domain contained
+syn keyword ngxCookieOptions httponly contained
+syn keyword ngxCookieOptions secure contained
+syn keyword ngxCookieOptions path contained
+
+" 3rd party module list:
+" https://www.nginx.com/resources/wiki/modules/
+
+" Accept Language Module <https://www.nginx.com/resources/wiki/modules/accept_language/>
+" Parses the Accept-Language header and gives the most suitable locale from a list of supported locales.
+syn keyword ngxDirectiveThirdParty set_from_accept_language
+
+" Access Key Module (DEPRECATED) <http://wiki.nginx.org/NginxHttpAccessKeyModule>
+" Denies access unless the request URL contains an access key.
+syn keyword ngxDirectiveDeprecated accesskey
+syn keyword ngxDirectiveDeprecated accesskey_arg
+syn keyword ngxDirectiveDeprecated accesskey_hashmethod
+syn keyword ngxDirectiveDeprecated accesskey_signature
+
+" Asynchronous FastCGI Module <https://github.com/rsms/afcgi>
+" Primarily a modified version of the Nginx FastCGI module which implements multiplexing of connections, allowing a single FastCGI server to handle many concurrent requests.
+" syn keyword ngxDirectiveThirdParty fastcgi_bind
+" syn keyword ngxDirectiveThirdParty fastcgi_buffer_size
+" syn keyword ngxDirectiveThirdParty fastcgi_buffers
+" syn keyword ngxDirectiveThirdParty fastcgi_busy_buffers_size
+" syn keyword ngxDirectiveThirdParty fastcgi_cache
+" syn keyword ngxDirectiveThirdParty fastcgi_cache_key
+" syn keyword ngxDirectiveThirdParty fastcgi_cache_methods
+" syn keyword ngxDirectiveThirdParty fastcgi_cache_min_uses
+" syn keyword ngxDirectiveThirdParty fastcgi_cache_path
+" syn keyword ngxDirectiveThirdParty fastcgi_cache_use_stale
+" syn keyword ngxDirectiveThirdParty fastcgi_cache_valid
+" syn keyword ngxDirectiveThirdParty fastcgi_catch_stderr
+" syn keyword ngxDirectiveThirdParty fastcgi_connect_timeout
+" syn keyword ngxDirectiveThirdParty fastcgi_hide_header
+" syn keyword ngxDirectiveThirdParty fastcgi_ignore_client_abort
+" syn keyword ngxDirectiveThirdParty fastcgi_ignore_headers
+" syn keyword ngxDirectiveThirdParty fastcgi_index
+" syn keyword ngxDirectiveThirdParty fastcgi_intercept_errors
+" syn keyword ngxDirectiveThirdParty fastcgi_max_temp_file_size
+" syn keyword ngxDirectiveThirdParty fastcgi_next_upstream
+" syn keyword ngxDirectiveThirdParty fastcgi_param
+" syn keyword ngxDirectiveThirdParty fastcgi_pass
+" syn keyword ngxDirectiveThirdParty fastcgi_pass_header
+" syn keyword ngxDirectiveThirdParty fastcgi_pass_request_body
+" syn keyword ngxDirectiveThirdParty fastcgi_pass_request_headers
+" syn keyword ngxDirectiveThirdParty fastcgi_read_timeout
+" syn keyword ngxDirectiveThirdParty fastcgi_send_lowat
+" syn keyword ngxDirectiveThirdParty fastcgi_send_timeout
+" syn keyword ngxDirectiveThirdParty fastcgi_split_path_info
+" syn keyword ngxDirectiveThirdParty fastcgi_store
+" syn keyword ngxDirectiveThirdParty fastcgi_store_access
+" syn keyword ngxDirectiveThirdParty fastcgi_temp_file_write_size
+" syn keyword ngxDirectiveThirdParty fastcgi_temp_path
+syn keyword ngxDirectiveDeprecated fastcgi_upstream_fail_timeout
+syn keyword ngxDirectiveDeprecated fastcgi_upstream_max_fails
+
+" Akamai G2O Module <https://github.com/kaltura/nginx_mod_akamai_g2o>
+" Nginx Module for Authenticating Akamai G2O requests
+syn keyword ngxDirectiveThirdParty g2o
+syn keyword ngxDirectiveThirdParty g2o_nonce
+syn keyword ngxDirectiveThirdParty g2o_key
+
+" Lua Module <https://github.com/alacner/nginx_lua_module>
+" You can be very simple to execute lua code for nginx
+syn keyword ngxDirectiveThirdParty lua_file
+
+" Array Variable Module <https://github.com/openresty/array-var-nginx-module>
+" Add support for array-typed variables to nginx config files
+syn keyword ngxDirectiveThirdParty array_split
+syn keyword ngxDirectiveThirdParty array_join
+syn keyword ngxDirectiveThirdParty array_map
+syn keyword ngxDirectiveThirdParty array_map_op
+
+" Nginx Audio Track for HTTP Live Streaming <https://github.com/flavioribeiro/nginx-audio-track-for-hls-module>
+" This nginx module generates audio track for hls streams on the fly.
+syn keyword ngxDirectiveThirdParty ngx_hls_audio_track
+syn keyword ngxDirectiveThirdParty ngx_hls_audio_track_rootpath
+syn keyword ngxDirectiveThirdParty ngx_hls_audio_track_output_format
+syn keyword ngxDirectiveThirdParty ngx_hls_audio_track_output_header
+
+" AWS Proxy Module <https://github.com/anomalizer/ngx_aws_auth>
+" Nginx module to proxy to authenticated AWS services
+syn keyword ngxDirectiveThirdParty aws_access_key
+syn keyword ngxDirectiveThirdParty aws_key_scope
+syn keyword ngxDirectiveThirdParty aws_signing_key
+syn keyword ngxDirectiveThirdParty aws_endpoint
+syn keyword ngxDirectiveThirdParty aws_s3_bucket
+syn keyword ngxDirectiveThirdParty aws_sign
+
+" Backtrace module <https://github.com/alibaba/nginx-backtrace>
+" A Nginx module to dump backtrace when a worker process exits abnormally
+syn keyword ngxDirectiveThirdParty backtrace_log
+syn keyword ngxDirectiveThirdParty backtrace_max_stack_size
+
+" Brotli Module <https://github.com/google/ngx_brotli>
+" Nginx module for Brotli compression
+syn keyword ngxDirectiveThirdParty brotli_static
+syn keyword ngxDirectiveThirdParty brotli
+syn keyword ngxDirectiveThirdParty brotli_types
+syn keyword ngxDirectiveThirdParty brotli_buffers
+syn keyword ngxDirectiveThirdParty brotli_comp_level
+syn keyword ngxDirectiveThirdParty brotli_window
+syn keyword ngxDirectiveThirdParty brotli_min_length
+
+" Cache Purge Module <https://github.com/FRiCKLE/ngx_cache_purge>
+" Adds ability to purge content from FastCGI, proxy, SCGI and uWSGI caches.
+syn keyword ngxDirectiveThirdParty fastcgi_cache_purge
+syn keyword ngxDirectiveThirdParty proxy_cache_purge
+" syn keyword ngxDirectiveThirdParty scgi_cache_purge
+" syn keyword ngxDirectiveThirdParty uwsgi_cache_purge
+
+" Chunkin Module (DEPRECATED) <http://wiki.nginx.org/NginxHttpChunkinModule>
+" HTTP 1.1 chunked-encoding request body support for Nginx.
+syn keyword ngxDirectiveDeprecated chunkin
+syn keyword ngxDirectiveDeprecated chunkin_keepalive
+syn keyword ngxDirectiveDeprecated chunkin_max_chunks_per_buf
+syn keyword ngxDirectiveDeprecated chunkin_resume
+
+" Circle GIF Module <https://github.com/evanmiller/nginx_circle_gif>
+" Generates simple circle images with the colors and size specified in the URL.
+syn keyword ngxDirectiveThirdParty circle_gif
+syn keyword ngxDirectiveThirdParty circle_gif_max_radius
+syn keyword ngxDirectiveThirdParty circle_gif_min_radius
+syn keyword ngxDirectiveThirdParty circle_gif_step_radius
+
+" Nginx-Clojure Module <http://nginx-clojure.github.io/index.html>
+" Parses the Accept-Language header and gives the most suitable locale from a list of supported locales.
+syn keyword ngxDirectiveThirdParty jvm_path
+syn keyword ngxDirectiveThirdParty jvm_var
+syn keyword ngxDirectiveThirdParty jvm_classpath
+syn keyword ngxDirectiveThirdParty jvm_classpath_check
+syn keyword ngxDirectiveThirdParty jvm_workers
+syn keyword ngxDirectiveThirdParty jvm_options
+syn keyword ngxDirectiveThirdParty jvm_handler_type
+syn keyword ngxDirectiveThirdParty jvm_init_handler_name
+syn keyword ngxDirectiveThirdParty jvm_init_handler_code
+syn keyword ngxDirectiveThirdParty jvm_exit_handler_name
+syn keyword ngxDirectiveThirdParty jvm_exit_handler_code
+syn keyword ngxDirectiveThirdParty handlers_lazy_init
+syn keyword ngxDirectiveThirdParty auto_upgrade_ws
+syn keyword ngxDirectiveThirdParty content_handler_type
+syn keyword ngxDirectiveThirdParty content_handler_name
+syn keyword ngxDirectiveThirdParty content_handler_code
+syn keyword ngxDirectiveThirdParty rewrite_handler_type
+syn keyword ngxDirectiveThirdParty rewrite_handler_name
+syn keyword ngxDirectiveThirdParty rewrite_handler_code
+syn keyword ngxDirectiveThirdParty access_handler_type
+syn keyword ngxDirectiveThirdParty access_handler_name
+syn keyword ngxDirectiveThirdParty access_handler_code
+syn keyword ngxDirectiveThirdParty header_filter_type
+syn keyword ngxDirectiveThirdParty header_filter_name
+syn keyword ngxDirectiveThirdParty header_filter_code
+syn keyword ngxDirectiveThirdParty content_handler_property
+syn keyword ngxDirectiveThirdParty rewrite_handler_property
+syn keyword ngxDirectiveThirdParty access_handler_property
+syn keyword ngxDirectiveThirdParty header_filter_property
+syn keyword ngxDirectiveThirdParty always_read_body
+syn keyword ngxDirectiveThirdParty shared_map
+syn keyword ngxDirectiveThirdParty write_page_size
+
+" Upstream Consistent Hash <https://www.nginx.com/resources/wiki/modules/consistent_hash/>
+" A load balancer that uses an internal consistent hash ring to select the right backend node.
+syn keyword ngxDirectiveThirdParty consistent_hash
+
+" Nginx Development Kit <https://github.com/simpl/ngx_devel_kit>
+" The NDK is an Nginx module that is designed to extend the core functionality of the excellent Nginx webserver in a way that can be used as a basis of other Nginx modules.
+" NDK_UPSTREAM_LIST
+" This submodule provides a directive that creates a list of upstreams, with optional weighting. This list can then be used by other modules to hash over the upstreams however they choose.
+syn keyword ngxDirectiveThirdParty upstream_list
+
+" Drizzle Module <https://www.nginx.com/resources/wiki/modules/drizzle/>
+" Upstream module for talking to MySQL and Drizzle directly
+syn keyword ngxDirectiveThirdParty drizzle_server
+syn keyword ngxDirectiveThirdParty drizzle_keepalive
+syn keyword ngxDirectiveThirdParty drizzle_query
+syn keyword ngxDirectiveThirdParty drizzle_pass
+syn keyword ngxDirectiveThirdParty drizzle_connect_timeout
+syn keyword ngxDirectiveThirdParty drizzle_send_query_timeout
+syn keyword ngxDirectiveThirdParty drizzle_recv_cols_timeout
+syn keyword ngxDirectiveThirdParty drizzle_recv_rows_timeout
+syn keyword ngxDirectiveThirdParty drizzle_buffer_size
+syn keyword ngxDirectiveThirdParty drizzle_module_header
+syn keyword ngxDirectiveThirdParty drizzle_status
+
+" Dynamic ETags Module <https://github.com/kali/nginx-dynamic-etags>
+" Attempt at handling ETag / If-None-Match on proxied content.
+syn keyword ngxDirectiveThirdParty dynamic_etags
+
+" Echo Module <https://www.nginx.com/resources/wiki/modules/echo/>
+" Bringing the power of "echo", "sleep", "time" and more to Nginx's config file
+syn keyword ngxDirectiveThirdParty echo
+syn keyword ngxDirectiveThirdParty echo_duplicate
+syn keyword ngxDirectiveThirdParty echo_flush
+syn keyword ngxDirectiveThirdParty echo_sleep
+syn keyword ngxDirectiveThirdParty echo_blocking_sleep
+syn keyword ngxDirectiveThirdParty echo_reset_timer
+syn keyword ngxDirectiveThirdParty echo_read_request_body
+syn keyword ngxDirectiveThirdParty echo_location_async
+syn keyword ngxDirectiveThirdParty echo_location
+syn keyword ngxDirectiveThirdParty echo_subrequest_async
+syn keyword ngxDirectiveThirdParty echo_subrequest
+syn keyword ngxDirectiveThirdParty echo_foreach_split
+syn keyword ngxDirectiveThirdParty echo_end
+syn keyword ngxDirectiveThirdParty echo_request_body
+syn keyword ngxDirectiveThirdParty echo_exec
+syn keyword ngxDirectiveThirdParty echo_status
+syn keyword ngxDirectiveThirdParty echo_before_body
+syn keyword ngxDirectiveThirdParty echo_after_body
+
+" Encrypted Session Module <https://github.com/openresty/encrypted-session-nginx-module>
+" Encrypt and decrypt nginx variable values
+syn keyword ngxDirectiveThirdParty encrypted_session_key
+syn keyword ngxDirectiveThirdParty encrypted_session_iv
+syn keyword ngxDirectiveThirdParty encrypted_session_expires
+syn keyword ngxDirectiveThirdParty set_encrypt_session
+syn keyword ngxDirectiveThirdParty set_decrypt_session
+
+" Enhanced Memcached Module <https://github.com/bpaquet/ngx_http_enhanced_memcached_module>
+" This module is based on the standard Nginx Memcached module, with some additonal features
+syn keyword ngxDirectiveThirdParty enhanced_memcached_pass
+syn keyword ngxDirectiveThirdParty enhanced_memcached_hash_keys_with_md5
+syn keyword ngxDirectiveThirdParty enhanced_memcached_allow_put
+syn keyword ngxDirectiveThirdParty enhanced_memcached_allow_delete
+syn keyword ngxDirectiveThirdParty enhanced_memcached_stats
+syn keyword ngxDirectiveThirdParty enhanced_memcached_flush
+syn keyword ngxDirectiveThirdParty enhanced_memcached_flush_namespace
+syn keyword ngxDirectiveThirdParty enhanced_memcached_bind
+syn keyword ngxDirectiveThirdParty enhanced_memcached_connect_timeout
+syn keyword ngxDirectiveThirdParty enhanced_memcached_send_timeout
+syn keyword ngxDirectiveThirdParty enhanced_memcached_buffer_size
+syn keyword ngxDirectiveThirdParty enhanced_memcached_read_timeout
+
+" Events Module (DEPRECATED) <http://docs.dutov.org/nginx_modules_events_en.html>
+" Provides options for start/stop events.
+syn keyword ngxDirectiveDeprecated on_start
+syn keyword ngxDirectiveDeprecated on_stop
+
+" EY Balancer Module <https://github.com/ezmobius/nginx-ey-balancer>
+" Adds a request queue to Nginx that allows the limiting of concurrent requests passed to the upstream.
+syn keyword ngxDirectiveThirdParty max_connections
+syn keyword ngxDirectiveThirdParty max_connections_max_queue_length
+syn keyword ngxDirectiveThirdParty max_connections_queue_timeout
+
+" Upstream Fair Balancer <https://www.nginx.com/resources/wiki/modules/fair_balancer/>
+" Sends an incoming request to the least-busy backend server, rather than distributing requests round-robin.
+syn keyword ngxDirectiveThirdParty fair
+syn keyword ngxDirectiveThirdParty upstream_fair_shm_size
+
+" Fancy Indexes Module <https://github.com/aperezdc/ngx-fancyindex>
+" Like the built-in autoindex module, but fancier.
+syn keyword ngxDirectiveThirdParty fancyindex
+syn keyword ngxDirectiveThirdParty fancyindex_default_sort
+syn keyword ngxDirectiveThirdParty fancyindex_directories_first
+syn keyword ngxDirectiveThirdParty fancyindex_css_href
+syn keyword ngxDirectiveThirdParty fancyindex_exact_size
+syn keyword ngxDirectiveThirdParty fancyindex_name_length
+syn keyword ngxDirectiveThirdParty fancyindex_footer
+syn keyword ngxDirectiveThirdParty fancyindex_header
+syn keyword ngxDirectiveThirdParty fancyindex_show_path
+syn keyword ngxDirectiveThirdParty fancyindex_ignore
+syn keyword ngxDirectiveThirdParty fancyindex_hide_symlinks
+syn keyword ngxDirectiveThirdParty fancyindex_localtime
+syn keyword ngxDirectiveThirdParty fancyindex_time_format
+
+" Form Auth Module <https://github.com/veruu/ngx_form_auth>
+" Provides authentication and authorization with credentials submitted via POST request
+syn keyword ngxDirectiveThirdParty form_auth
+syn keyword ngxDirectiveThirdParty form_auth_pam_service
+syn keyword ngxDirectiveThirdParty form_auth_login
+syn keyword ngxDirectiveThirdParty form_auth_password
+syn keyword ngxDirectiveThirdParty form_auth_remote_user
+
+" Form Input Module <https://github.com/calio/form-input-nginx-module>
+" Reads HTTP POST and PUT request body encoded in "application/x-www-form-urlencoded" and parses the arguments into nginx variables.
+syn keyword ngxDirectiveThirdParty set_form_input
+syn keyword ngxDirectiveThirdParty set_form_input_multi
+
+" GeoIP Module (DEPRECATED) <http://wiki.nginx.org/NginxHttp3rdPartyGeoIPModule>
+" Country code lookups via the MaxMind GeoIP API.
+syn keyword ngxDirectiveDeprecated geoip_country_file
+
+" GeoIP 2 Module <https://github.com/leev/ngx_http_geoip2_module>
+" Creates variables with values from the maxmind geoip2 databases based on the client IP
+syn keyword ngxDirectiveThirdParty geoip2
+
+" GridFS Module <https://github.com/mdirolf/nginx-gridfs>
+" Nginx module for serving files from MongoDB's GridFS
+syn keyword ngxDirectiveThirdParty gridfs
+
+" Headers More Module <https://github.com/openresty/headers-more-nginx-module>
+" Set and clear input and output headers...more than "add"!
+syn keyword ngxDirectiveThirdParty more_clear_headers
+syn keyword ngxDirectiveThirdParty more_clear_input_headers
+syn keyword ngxDirectiveThirdParty more_set_headers
+syn keyword ngxDirectiveThirdParty more_set_input_headers
+
+" Health Checks Upstreams Module <https://www.nginx.com/resources/wiki/modules/healthcheck/>
+" Polls backends and if they respond with HTTP 200 + an optional request body, they are marked good. Otherwise, they are marked bad.
+syn keyword ngxDirectiveThirdParty healthcheck_enabled
+syn keyword ngxDirectiveThirdParty healthcheck_delay
+syn keyword ngxDirectiveThirdParty healthcheck_timeout
+syn keyword ngxDirectiveThirdParty healthcheck_failcount
+syn keyword ngxDirectiveThirdParty healthcheck_send
+syn keyword ngxDirectiveThirdParty healthcheck_expected
+syn keyword ngxDirectiveThirdParty healthcheck_buffer
+syn keyword ngxDirectiveThirdParty healthcheck_status
+
+" HTTP Accounting Module <https://github.com/Lax/ngx_http_accounting_module>
+" Add traffic stat function to nginx. Useful for http accounting based on nginx configuration logic
+syn keyword ngxDirectiveThirdParty http_accounting
+syn keyword ngxDirectiveThirdParty http_accounting_log
+syn keyword ngxDirectiveThirdParty http_accounting_id
+syn keyword ngxDirectiveThirdParty http_accounting_interval
+syn keyword ngxDirectiveThirdParty http_accounting_perturb
+
+" Nginx Digest Authentication module <https://github.com/atomx/nginx-http-auth-digest>
+" Digest Authentication for Nginx
+syn keyword ngxDirectiveThirdParty auth_digest
+syn keyword ngxDirectiveThirdParty auth_digest_user_file
+syn keyword ngxDirectiveThirdParty auth_digest_timeout
+syn keyword ngxDirectiveThirdParty auth_digest_expires
+syn keyword ngxDirectiveThirdParty auth_digest_replays
+syn keyword ngxDirectiveThirdParty auth_digest_shm_size
+
+" Auth PAM Module <https://github.com/sto/ngx_http_auth_pam_module>
+" HTTP Basic Authentication using PAM.
+syn keyword ngxDirectiveThirdParty auth_pam
+syn keyword ngxDirectiveThirdParty auth_pam_service_name
+
+" HTTP Auth Request Module <http://nginx.org/en/docs/http/ngx_http_auth_request_module.html>
+" Implements client authorization based on the result of a subrequest
+" syn keyword ngxDirectiveThirdParty auth_request
+" syn keyword ngxDirectiveThirdParty auth_request_set
+
+" HTTP Concatenation module for Nginx <https://github.com/alibaba/nginx-http-concat>
+" A Nginx module for concatenating files in a given context: CSS and JS files usually
+syn keyword ngxDirectiveThirdParty concat
+syn keyword ngxDirectiveThirdParty concat_types
+syn keyword ngxDirectiveThirdParty concat_unique
+syn keyword ngxDirectiveThirdParty concat_max_files
+syn keyword ngxDirectiveThirdParty concat_delimiter
+syn keyword ngxDirectiveThirdParty concat_ignore_file_error
+
+" HTTP Dynamic Upstream Module <https://github.com/yzprofile/ngx_http_dyups_module>
+" Update upstreams' config by restful interface
+syn keyword ngxDirectiveThirdParty dyups_interface
+syn keyword ngxDirectiveThirdParty dyups_read_msg_timeout
+syn keyword ngxDirectiveThirdParty dyups_shm_zone_size
+syn keyword ngxDirectiveThirdParty dyups_upstream_conf
+syn keyword ngxDirectiveThirdParty dyups_trylock
+
+" HTTP Footer If Filter Module <https://github.com/flygoast/ngx_http_footer_if_filter>
+" The ngx_http_footer_if_filter_module is used to add given content to the end of the response according to the condition specified.
+syn keyword ngxDirectiveThirdParty footer_if
+
+" HTTP Footer Filter Module <https://github.com/alibaba/nginx-http-footer-filter>
+" This module implements a body filter that adds a given string to the page footer.
+syn keyword ngxDirectiveThirdParty footer
+syn keyword ngxDirectiveThirdParty footer_types
+
+" HTTP Internal Redirect Module <https://github.com/flygoast/ngx_http_internal_redirect>
+" Make an internal redirect to the uri specified according to the condition specified.
+syn keyword ngxDirectiveThirdParty internal_redirect_if
+syn keyword ngxDirectiveThirdParty internal_redirect_if_no_postponed
+
+" HTTP JavaScript Module <https://github.com/peter-leonov/ngx_http_js_module>
+" Embedding SpiderMonkey. Nearly full port on Perl module.
+syn keyword ngxDirectiveThirdParty js
+syn keyword ngxDirectiveThirdParty js_filter
+syn keyword ngxDirectiveThirdParty js_filter_types
+syn keyword ngxDirectiveThirdParty js_load
+syn keyword ngxDirectiveThirdParty js_maxmem
+syn keyword ngxDirectiveThirdParty js_require
+syn keyword ngxDirectiveThirdParty js_set
+syn keyword ngxDirectiveThirdParty js_utf8
+
+" HTTP Push Module (DEPRECATED) <http://pushmodule.slact.net/>
+" Turn Nginx into an adept long-polling HTTP Push (Comet) server.
+syn keyword ngxDirectiveDeprecated push_buffer_size
+syn keyword ngxDirectiveDeprecated push_listener
+syn keyword ngxDirectiveDeprecated push_message_timeout
+syn keyword ngxDirectiveDeprecated push_queue_messages
+syn keyword ngxDirectiveDeprecated push_sender
+
+" HTTP Redis Module <https://www.nginx.com/resources/wiki/modules/redis/>
+" Redis <http://code.google.com/p/redis/> support.
+syn keyword ngxDirectiveThirdParty redis_bind
+syn keyword ngxDirectiveThirdParty redis_buffer_size
+syn keyword ngxDirectiveThirdParty redis_connect_timeout
+syn keyword ngxDirectiveThirdParty redis_next_upstream
+syn keyword ngxDirectiveThirdParty redis_pass
+syn keyword ngxDirectiveThirdParty redis_read_timeout
+syn keyword ngxDirectiveThirdParty redis_send_timeout
+
+" Iconv Module <https://github.com/calio/iconv-nginx-module>
+" A character conversion nginx module using libiconv
+syn keyword ngxDirectiveThirdParty set_iconv
+syn keyword ngxDirectiveThirdParty iconv_buffer_size
+syn keyword ngxDirectiveThirdParty iconv_filter
+
+" IP Blocker Module <https://github.com/tmthrgd/nginx-ip-blocker>
+" An efficient shared memory IP blocking system for nginx.
+syn keyword ngxDirectiveThirdParty ip_blocker
+
+" IP2Location Module <https://github.com/chrislim2888/ip2location-nginx>
+" Allows user to lookup for geolocation information using IP2Location database
+syn keyword ngxDirectiveThirdParty ip2location_database
+
+" JS Module <https://github.com/peter-leonov/ngx_http_js_module>
+" Reflect the nginx functionality in JS
+syn keyword ngxDirectiveThirdParty js
+syn keyword ngxDirectiveThirdParty js_access
+syn keyword ngxDirectiveThirdParty js_load
+syn keyword ngxDirectiveThirdParty js_set
+
+" Limit Upload Rate Module <https://github.com/cfsego/limit_upload_rate>
+" Limit client-upload rate when they are sending request bodies to you
+syn keyword ngxDirectiveThirdParty limit_upload_rate
+syn keyword ngxDirectiveThirdParty limit_upload_rate_after
+
+" Limit Upstream Module <https://github.com/cfsego/nginx-limit-upstream>
+" Limit the number of connections to upstream for NGINX
+syn keyword ngxDirectiveThirdParty limit_upstream_zone
+syn keyword ngxDirectiveThirdParty limit_upstream_conn
+syn keyword ngxDirectiveThirdParty limit_upstream_log_level
+
+" Log If Module <https://github.com/cfsego/ngx_log_if>
+" Conditional accesslog for nginx
+syn keyword ngxDirectiveThirdParty access_log_bypass_if
+
+" Log Request Speed (DEPRECATED) <http://wiki.nginx.org/NginxHttpLogRequestSpeed>
+" Log the time it took to process each request.
+syn keyword ngxDirectiveDeprecated log_request_speed_filter
+syn keyword ngxDirectiveDeprecated log_request_speed_filter_timeout
+
+" Log ZeroMQ Module <https://github.com/alticelabs/nginx-log-zmq>
+" ZeroMQ logger module for nginx
+syn keyword ngxDirectiveThirdParty log_zmq_server
+syn keyword ngxDirectiveThirdParty log_zmq_endpoint
+syn keyword ngxDirectiveThirdParty log_zmq_format
+syn keyword ngxDirectiveThirdParty log_zmq_off
+
+" Lower/UpperCase Module <https://github.com/replay/ngx_http_lower_upper_case>
+" This module simply uppercases or lowercases a string and saves it into a new variable.
+syn keyword ngxDirectiveThirdParty lower
+syn keyword ngxDirectiveThirdParty upper
+
+" Lua Upstream Module <https://github.com/openresty/lua-upstream-nginx-module>
+" Nginx C module to expose Lua API to ngx_lua for Nginx upstreams
+
+" Lua Module <https://github.com/openresty/lua-nginx-module>
+" Embed the Power of Lua into NGINX HTTP servers
+syn keyword ngxDirectiveThirdParty lua_use_default_type
+syn keyword ngxDirectiveThirdParty lua_malloc_trim
+syn keyword ngxDirectiveThirdParty lua_code_cache
+syn keyword ngxDirectiveThirdParty lua_regex_cache_max_entries
+syn keyword ngxDirectiveThirdParty lua_regex_match_limit
+syn keyword ngxDirectiveThirdParty lua_package_path
+syn keyword ngxDirectiveThirdParty lua_package_cpath
+syn keyword ngxDirectiveThirdParty init_by_lua
+syn keyword ngxDirectiveThirdParty init_by_lua_file
+syn keyword ngxDirectiveThirdParty init_worker_by_lua
+syn keyword ngxDirectiveThirdParty init_worker_by_lua_file
+syn keyword ngxDirectiveThirdParty set_by_lua
+syn keyword ngxDirectiveThirdParty set_by_lua_file
+syn keyword ngxDirectiveThirdParty content_by_lua
+syn keyword ngxDirectiveThirdParty content_by_lua_file
+syn keyword ngxDirectiveThirdParty rewrite_by_lua
+syn keyword ngxDirectiveThirdParty rewrite_by_lua_file
+syn keyword ngxDirectiveThirdParty access_by_lua
+syn keyword ngxDirectiveThirdParty access_by_lua_file
+syn keyword ngxDirectiveThirdParty header_filter_by_lua
+syn keyword ngxDirectiveThirdParty header_filter_by_lua_file
+syn keyword ngxDirectiveThirdParty body_filter_by_lua
+syn keyword ngxDirectiveThirdParty body_filter_by_lua_file
+syn keyword ngxDirectiveThirdParty log_by_lua
+syn keyword ngxDirectiveThirdParty log_by_lua_file
+syn keyword ngxDirectiveThirdParty balancer_by_lua_file
+syn keyword ngxDirectiveThirdParty lua_need_request_body
+syn keyword ngxDirectiveThirdParty ssl_certificate_by_lua_file
+syn keyword ngxDirectiveThirdParty ssl_session_fetch_by_lua_file
+syn keyword ngxDirectiveThirdParty ssl_session_store_by_lua_file
+syn keyword ngxDirectiveThirdParty lua_shared_dict
+syn keyword ngxDirectiveThirdParty lua_socket_connect_timeout
+syn keyword ngxDirectiveThirdParty lua_socket_send_timeout
+syn keyword ngxDirectiveThirdParty lua_socket_send_lowat
+syn keyword ngxDirectiveThirdParty lua_socket_read_timeout
+syn keyword ngxDirectiveThirdParty lua_socket_buffer_size
+syn keyword ngxDirectiveThirdParty lua_socket_pool_size
+syn keyword ngxDirectiveThirdParty lua_socket_keepalive_timeout
+syn keyword ngxDirectiveThirdParty lua_socket_log_errors
+syn keyword ngxDirectiveThirdParty lua_ssl_ciphers
+syn keyword ngxDirectiveThirdParty lua_ssl_crl
+syn keyword ngxDirectiveThirdParty lua_ssl_protocols
+syn keyword ngxDirectiveThirdParty lua_ssl_trusted_certificate
+syn keyword ngxDirectiveThirdParty lua_ssl_verify_depth
+syn keyword ngxDirectiveThirdParty lua_http10_buffering
+syn keyword ngxDirectiveThirdParty rewrite_by_lua_no_postpone
+syn keyword ngxDirectiveThirdParty access_by_lua_no_postpone
+syn keyword ngxDirectiveThirdParty lua_transform_underscores_in_response_headers
+syn keyword ngxDirectiveThirdParty lua_check_client_abort
+syn keyword ngxDirectiveThirdParty lua_max_pending_timers
+syn keyword ngxDirectiveThirdParty lua_max_running_timers
+
+" MD5 Filter Module <https://github.com/kainswor/nginx_md5_filter>
+" A content filter for nginx, which returns the md5 hash of the content otherwise returned.
+syn keyword ngxDirectiveThirdParty md5_filter
+
+" Memc Module <https://github.com/openresty/memc-nginx-module>
+" An extended version of the standard memcached module that supports set, add, delete, and many more memcached commands.
+syn keyword ngxDirectiveThirdParty memc_buffer_size
+syn keyword ngxDirectiveThirdParty memc_cmds_allowed
+syn keyword ngxDirectiveThirdParty memc_connect_timeout
+syn keyword ngxDirectiveThirdParty memc_flags_to_last_modified
+syn keyword ngxDirectiveThirdParty memc_next_upstream
+syn keyword ngxDirectiveThirdParty memc_pass
+syn keyword ngxDirectiveThirdParty memc_read_timeout
+syn keyword ngxDirectiveThirdParty memc_send_timeout
+syn keyword ngxDirectiveThirdParty memc_upstream_fail_timeout
+syn keyword ngxDirectiveThirdParty memc_upstream_max_fails
+
+" Mod Security Module <https://github.com/SpiderLabs/ModSecurity>
+" ModSecurity is an open source, cross platform web application firewall (WAF) engine
+syn keyword ngxDirectiveThirdParty ModSecurityConfig
+syn keyword ngxDirectiveThirdParty ModSecurityEnabled
+syn keyword ngxDirectiveThirdParty pool_context
+syn keyword ngxDirectiveThirdParty pool_context_hash_size
+
+" Mogilefs Module <http://www.grid.net.ru/nginx/mogilefs.en.html>
+" MogileFS client for nginx web server.
+syn keyword ngxDirectiveThirdParty mogilefs_pass
+syn keyword ngxDirectiveThirdParty mogilefs_methods
+syn keyword ngxDirectiveThirdParty mogilefs_domain
+syn keyword ngxDirectiveThirdParty mogilefs_class
+syn keyword ngxDirectiveThirdParty mogilefs_tracker
+syn keyword ngxDirectiveThirdParty mogilefs_noverify
+syn keyword ngxDirectiveThirdParty mogilefs_connect_timeout
+syn keyword ngxDirectiveThirdParty mogilefs_send_timeout
+syn keyword ngxDirectiveThirdParty mogilefs_read_timeout
+
+" Mongo Module <https://github.com/simpl/ngx_mongo>
+" Upstream module that allows nginx to communicate directly with MongoDB database.
+syn keyword ngxDirectiveThirdParty mongo_auth
+syn keyword ngxDirectiveThirdParty mongo_pass
+syn keyword ngxDirectiveThirdParty mongo_query
+syn keyword ngxDirectiveThirdParty mongo_json
+syn keyword ngxDirectiveThirdParty mongo_bind
+syn keyword ngxDirectiveThirdParty mongo_connect_timeout
+syn keyword ngxDirectiveThirdParty mongo_send_timeout
+syn keyword ngxDirectiveThirdParty mongo_read_timeout
+syn keyword ngxDirectiveThirdParty mongo_buffering
+syn keyword ngxDirectiveThirdParty mongo_buffer_size
+syn keyword ngxDirectiveThirdParty mongo_buffers
+syn keyword ngxDirectiveThirdParty mongo_busy_buffers_size
+syn keyword ngxDirectiveThirdParty mongo_next_upstream
+
+" MP4 Streaming Lite Module <https://www.nginx.com/resources/wiki/modules/mp4_streaming/>
+" Will seek to a certain time within H.264/MP4 files when provided with a 'start' parameter in the URL.
+" syn keyword ngxDirectiveThirdParty mp4
+
+" NAXSI Module <https://github.com/nbs-system/naxsi>
+" NAXSI is an open-source, high performance, low rules maintenance WAF for NGINX
+syn keyword ngxDirectiveThirdParty DeniedUrl denied_url
+syn keyword ngxDirectiveThirdParty LearningMode learning_mode
+syn keyword ngxDirectiveThirdParty SecRulesEnabled rules_enabled
+syn keyword ngxDirectiveThirdParty SecRulesDisabled rules_disabled
+syn keyword ngxDirectiveThirdParty CheckRule check_rule
+syn keyword ngxDirectiveThirdParty BasicRule basic_rule
+syn keyword ngxDirectiveThirdParty MainRule main_rule
+syn keyword ngxDirectiveThirdParty LibInjectionSql libinjection_sql
+syn keyword ngxDirectiveThirdParty LibInjectionXss libinjection_xss
+
+" Nchan Module <https://nchan.slact.net/>
+" Fast, horizontally scalable, multiprocess pub/sub queuing server and proxy for HTTP, long-polling, Websockets and EventSource (SSE)
+syn keyword ngxDirectiveThirdParty nchan_channel_id
+syn keyword ngxDirectiveThirdParty nchan_channel_id_split_delimiter
+syn keyword ngxDirectiveThirdParty nchan_eventsource_event
+syn keyword ngxDirectiveThirdParty nchan_longpoll_multipart_response
+syn keyword ngxDirectiveThirdParty nchan_publisher
+syn keyword ngxDirectiveThirdParty nchan_publisher_channel_id
+syn keyword ngxDirectiveThirdParty nchan_publisher_upstream_request
+syn keyword ngxDirectiveThirdParty nchan_pubsub
+syn keyword ngxDirectiveThirdParty nchan_subscribe_request
+syn keyword ngxDirectiveThirdParty nchan_subscriber
+syn keyword ngxDirectiveThirdParty nchan_subscriber_channel_id
+syn keyword ngxDirectiveThirdParty nchan_subscriber_compound_etag_message_id
+syn keyword ngxDirectiveThirdParty nchan_subscriber_first_message
+syn keyword ngxDirectiveThirdParty nchan_subscriber_http_raw_stream_separator
+syn keyword ngxDirectiveThirdParty nchan_subscriber_last_message_id
+syn keyword ngxDirectiveThirdParty nchan_subscriber_message_id_custom_etag_header
+syn keyword ngxDirectiveThirdParty nchan_subscriber_timeout
+syn keyword ngxDirectiveThirdParty nchan_unsubscribe_request
+syn keyword ngxDirectiveThirdParty nchan_websocket_ping_interval
+syn keyword ngxDirectiveThirdParty nchan_authorize_request
+syn keyword ngxDirectiveThirdParty nchan_max_reserved_memory
+syn keyword ngxDirectiveThirdParty nchan_message_buffer_length
+syn keyword ngxDirectiveThirdParty nchan_message_timeout
+syn keyword ngxDirectiveThirdParty nchan_redis_idle_channel_cache_timeout
+syn keyword ngxDirectiveThirdParty nchan_redis_namespace
+syn keyword ngxDirectiveThirdParty nchan_redis_pass
+syn keyword ngxDirectiveThirdParty nchan_redis_ping_interval
+syn keyword ngxDirectiveThirdParty nchan_redis_server
+syn keyword ngxDirectiveThirdParty nchan_redis_storage_mode
+syn keyword ngxDirectiveThirdParty nchan_redis_url
+syn keyword ngxDirectiveThirdParty nchan_store_messages
+syn keyword ngxDirectiveThirdParty nchan_use_redis
+syn keyword ngxDirectiveThirdParty nchan_access_control_allow_origin
+syn keyword ngxDirectiveThirdParty nchan_channel_group
+syn keyword ngxDirectiveThirdParty nchan_channel_group_accounting
+syn keyword ngxDirectiveThirdParty nchan_group_location
+syn keyword ngxDirectiveThirdParty nchan_group_max_channels
+syn keyword ngxDirectiveThirdParty nchan_group_max_messages
+syn keyword ngxDirectiveThirdParty nchan_group_max_messages_disk
+syn keyword ngxDirectiveThirdParty nchan_group_max_messages_memory
+syn keyword ngxDirectiveThirdParty nchan_group_max_subscribers
+syn keyword ngxDirectiveThirdParty nchan_subscribe_existing_channels_only
+syn keyword ngxDirectiveThirdParty nchan_channel_event_string
+syn keyword ngxDirectiveThirdParty nchan_channel_events_channel_id
+syn keyword ngxDirectiveThirdParty nchan_stub_status
+syn keyword ngxDirectiveThirdParty nchan_max_channel_id_length
+syn keyword ngxDirectiveThirdParty nchan_max_channel_subscribers
+syn keyword ngxDirectiveThirdParty nchan_channel_timeout
+syn keyword ngxDirectiveThirdParty nchan_storage_engine
+
+" Nginx Notice Module <https://github.com/kr/nginx-notice>
+" Serve static file to POST requests.
+syn keyword ngxDirectiveThirdParty notice
+syn keyword ngxDirectiveThirdParty notice_type
+
+" OCSP Proxy Module <https://github.com/kyprizel/nginx_ocsp_proxy-module>
+" Nginx OCSP processing module designed for response caching
+syn keyword ngxDirectiveThirdParty ocsp_proxy
+syn keyword ngxDirectiveThirdParty ocsp_cache_timeout
+
+" Eval Module <https://github.com/openresty/nginx-eval-module>
+" Module for nginx web server evaluates response of proxy or memcached module into variables.
+syn keyword ngxDirectiveThirdParty eval
+syn keyword ngxDirectiveThirdParty eval_escalate
+syn keyword ngxDirectiveThirdParty eval_buffer_size
+syn keyword ngxDirectiveThirdParty eval_override_content_type
+syn keyword ngxDirectiveThirdParty eval_subrequest_in_memory
+
+" OpenSSL Version Module <https://github.com/apcera/nginx-openssl-version>
+" Nginx OpenSSL version check at startup
+syn keyword ngxDirectiveThirdParty openssl_version_minimum
+syn keyword ngxDirectiveThirdParty openssl_builddate_minimum
+
+" Owner Match Module <https://www.nginx.com/resources/wiki/modules/owner_match/>
+" Control access for specific owners and groups of files
+syn keyword ngxDirectiveThirdParty omallow
+syn keyword ngxDirectiveThirdParty omdeny
+
+" Accept Language Module <https://www.nginx.com/resources/wiki/modules/accept_language/>
+" Parses the Accept-Language header and gives the most suitable locale from a list of supported locales.
+syn keyword ngxDirectiveThirdParty pagespeed
+
+" PHP Memcache Standard Balancer Module <https://github.com/replay/ngx_http_php_memcache_standard_balancer>
+" Loadbalancer that is compatible to the standard loadbalancer in the php-memcache module
+syn keyword ngxDirectiveThirdParty hash_key
+
+" PHP Session Module <https://github.com/replay/ngx_http_php_session>
+" Nginx module to parse php sessions
+syn keyword ngxDirectiveThirdParty php_session_parse
+syn keyword ngxDirectiveThirdParty php_session_strip_formatting
+
+" Phusion Passenger Module <https://www.phusionpassenger.com/library/config/nginx/>
+" Passenger is an open source web application server.
+syn keyword ngxDirectiveThirdParty passenger_root
+syn keyword ngxDirectiveThirdParty passenger_enabled
+syn keyword ngxDirectiveThirdParty passenger_base_uri
+syn keyword ngxDirectiveThirdParty passenger_document_root
+syn keyword ngxDirectiveThirdParty passenger_ruby
+syn keyword ngxDirectiveThirdParty passenger_python
+syn keyword ngxDirectiveThirdParty passenger_nodejs
+syn keyword ngxDirectiveThirdParty passenger_meteor_app_settings
+syn keyword ngxDirectiveThirdParty passenger_app_env
+syn keyword ngxDirectiveThirdParty passenger_app_root
+syn keyword ngxDirectiveThirdParty passenger_app_group_name
+syn keyword ngxDirectiveThirdParty passenger_app_type
+syn keyword ngxDirectiveThirdParty passenger_startup_file
+syn keyword ngxDirectiveThirdParty passenger_restart_dir
+syn keyword ngxDirectiveThirdParty passenger_spawn_method
+syn keyword ngxDirectiveThirdParty passenger_env_var
+syn keyword ngxDirectiveThirdParty passenger_load_shell_envvars
+syn keyword ngxDirectiveThirdParty passenger_rolling_restarts
+syn keyword ngxDirectiveThirdParty passenger_resist_deployment_errors
+syn keyword ngxDirectiveThirdParty passenger_user_switching
+syn keyword ngxDirectiveThirdParty passenger_user
+syn keyword ngxDirectiveThirdParty passenger_group
+syn keyword ngxDirectiveThirdParty passenger_default_user
+syn keyword ngxDirectiveThirdParty passenger_default_group
+syn keyword ngxDirectiveThirdParty passenger_show_version_in_header
+syn keyword ngxDirectiveThirdParty passenger_friendly_error_pages
+syn keyword ngxDirectiveThirdParty passenger_disable_security_update_check
+syn keyword ngxDirectiveThirdParty passenger_security_update_check_proxy
+syn keyword ngxDirectiveThirdParty passenger_max_pool_size
+syn keyword ngxDirectiveThirdParty passenger_min_instances
+syn keyword ngxDirectiveThirdParty passenger_max_instances
+syn keyword ngxDirectiveThirdParty passenger_max_instances_per_app
+syn keyword ngxDirectiveThirdParty passenger_pool_idle_time
+syn keyword ngxDirectiveThirdParty passenger_max_preloader_idle_time
+syn keyword ngxDirectiveThirdParty passenger_force_max_concurrent_requests_per_process
+syn keyword ngxDirectiveThirdParty passenger_start_timeout
+syn keyword ngxDirectiveThirdParty passenger_concurrency_model
+syn keyword ngxDirectiveThirdParty passenger_thread_count
+syn keyword ngxDirectiveThirdParty passenger_max_requests
+syn keyword ngxDirectiveThirdParty passenger_max_request_time
+syn keyword ngxDirectiveThirdParty passenger_memory_limit
+syn keyword ngxDirectiveThirdParty passenger_stat_throttle_rate
+syn keyword ngxDirectiveThirdParty passenger_core_file_descriptor_ulimit
+syn keyword ngxDirectiveThirdParty passenger_app_file_descriptor_ulimit
+syn keyword ngxDirectiveThirdParty passenger_pre_start
+syn keyword ngxDirectiveThirdParty passenger_set_header
+syn keyword ngxDirectiveThirdParty passenger_max_request_queue_size
+syn keyword ngxDirectiveThirdParty passenger_request_queue_overflow_status_code
+syn keyword ngxDirectiveThirdParty passenger_sticky_sessions
+syn keyword ngxDirectiveThirdParty passenger_sticky_sessions_cookie_name
+syn keyword ngxDirectiveThirdParty passenger_abort_websockets_on_process_shutdown
+syn keyword ngxDirectiveThirdParty passenger_ignore_client_abort
+syn keyword ngxDirectiveThirdParty passenger_intercept_errors
+syn keyword ngxDirectiveThirdParty passenger_pass_header
+syn keyword ngxDirectiveThirdParty passenger_ignore_headers
+syn keyword ngxDirectiveThirdParty passenger_headers_hash_bucket_size
+syn keyword ngxDirectiveThirdParty passenger_headers_hash_max_size
+syn keyword ngxDirectiveThirdParty passenger_buffer_response
+syn keyword ngxDirectiveThirdParty passenger_response_buffer_high_watermark
+syn keyword ngxDirectiveThirdParty passenger_buffer_size, passenger_buffers, passenger_busy_buffers_size
+syn keyword ngxDirectiveThirdParty passenger_socket_backlog
+syn keyword ngxDirectiveThirdParty passenger_log_level
+syn keyword ngxDirectiveThirdParty passenger_log_file
+syn keyword ngxDirectiveThirdParty passenger_file_descriptor_log_file
+syn keyword ngxDirectiveThirdParty passenger_debugger
+syn keyword ngxDirectiveThirdParty passenger_instance_registry_dir
+syn keyword ngxDirectiveThirdParty passenger_data_buffer_dir
+syn keyword ngxDirectiveThirdParty passenger_fly_with
+syn keyword ngxDirectiveThirdParty union_station_support
+syn keyword ngxDirectiveThirdParty union_station_key
+syn keyword ngxDirectiveThirdParty union_station_proxy_address
+syn keyword ngxDirectiveThirdParty union_station_filter
+syn keyword ngxDirectiveThirdParty union_station_gateway_address
+syn keyword ngxDirectiveThirdParty union_station_gateway_port
+syn keyword ngxDirectiveThirdParty union_station_gateway_cert
+syn keyword ngxDirectiveDeprecated rails_spawn_method
+syn keyword ngxDirectiveDeprecated passenger_debug_log_file
+
+" Postgres Module <http://labs.frickle.com/nginx_ngx_postgres/>
+" Upstream module that allows nginx to communicate directly with PostgreSQL database.
+syn keyword ngxDirectiveThirdParty postgres_server
+syn keyword ngxDirectiveThirdParty postgres_keepalive
+syn keyword ngxDirectiveThirdParty postgres_pass
+syn keyword ngxDirectiveThirdParty postgres_query
+syn keyword ngxDirectiveThirdParty postgres_rewrite
+syn keyword ngxDirectiveThirdParty postgres_output
+syn keyword ngxDirectiveThirdParty postgres_set
+syn keyword ngxDirectiveThirdParty postgres_escape
+syn keyword ngxDirectiveThirdParty postgres_connect_timeout
+syn keyword ngxDirectiveThirdParty postgres_result_timeout
+
+" Pubcookie Module <https://www.vanko.me/book/page/pubcookie-module-nginx>
+" Authorizes users using encrypted cookies
+syn keyword ngxDirectiveThirdParty pubcookie_inactive_expire
+syn keyword ngxDirectiveThirdParty pubcookie_hard_expire
+syn keyword ngxDirectiveThirdParty pubcookie_app_id
+syn keyword ngxDirectiveThirdParty pubcookie_dir_depth
+syn keyword ngxDirectiveThirdParty pubcookie_catenate_app_ids
+syn keyword ngxDirectiveThirdParty pubcookie_app_srv_id
+syn keyword ngxDirectiveThirdParty pubcookie_login
+syn keyword ngxDirectiveThirdParty pubcookie_login_method
+syn keyword ngxDirectiveThirdParty pubcookie_post
+syn keyword ngxDirectiveThirdParty pubcookie_domain
+syn keyword ngxDirectiveThirdParty pubcookie_granting_cert_file
+syn keyword ngxDirectiveThirdParty pubcookie_session_key_file
+syn keyword ngxDirectiveThirdParty pubcookie_session_cert_file
+syn keyword ngxDirectiveThirdParty pubcookie_crypt_key_file
+syn keyword ngxDirectiveThirdParty pubcookie_end_session
+syn keyword ngxDirectiveThirdParty pubcookie_encryption
+syn keyword ngxDirectiveThirdParty pubcookie_session_reauth
+syn keyword ngxDirectiveThirdParty pubcookie_auth_type_names
+syn keyword ngxDirectiveThirdParty pubcookie_no_prompt
+syn keyword ngxDirectiveThirdParty pubcookie_on_demand
+syn keyword ngxDirectiveThirdParty pubcookie_addl_request
+syn keyword ngxDirectiveThirdParty pubcookie_no_obscure_cookies
+syn keyword ngxDirectiveThirdParty pubcookie_no_clean_creds
+syn keyword ngxDirectiveThirdParty pubcookie_egd_device
+syn keyword ngxDirectiveThirdParty pubcookie_no_blank
+syn keyword ngxDirectiveThirdParty pubcookie_super_debug
+syn keyword ngxDirectiveThirdParty pubcookie_set_remote_user
+
+" Push Stream Module <https://github.com/wandenberg/nginx-push-stream-module>
+" A pure stream http push technology for your Nginx setup
+syn keyword ngxDirectiveThirdParty push_stream_channels_statistics
+syn keyword ngxDirectiveThirdParty push_stream_publisher
+syn keyword ngxDirectiveThirdParty push_stream_subscriber
+syn keyword ngxDirectiveThirdParty push_stream_shared_memory_size
+syn keyword ngxDirectiveThirdParty push_stream_channel_deleted_message_text
+syn keyword ngxDirectiveThirdParty push_stream_channel_inactivity_time
+syn keyword ngxDirectiveThirdParty push_stream_ping_message_text
+syn keyword ngxDirectiveThirdParty push_stream_timeout_with_body
+syn keyword ngxDirectiveThirdParty push_stream_message_ttl
+syn keyword ngxDirectiveThirdParty push_stream_max_subscribers_per_channel
+syn keyword ngxDirectiveThirdParty push_stream_max_messages_stored_per_channel
+syn keyword ngxDirectiveThirdParty push_stream_max_channel_id_length
+syn keyword ngxDirectiveThirdParty push_stream_max_number_of_channels
+syn keyword ngxDirectiveThirdParty push_stream_max_number_of_wildcard_channels
+syn keyword ngxDirectiveThirdParty push_stream_wildcard_channel_prefix
+syn keyword ngxDirectiveThirdParty push_stream_events_channel_id
+syn keyword ngxDirectiveThirdParty push_stream_channels_path
+syn keyword ngxDirectiveThirdParty push_stream_store_messages
+syn keyword ngxDirectiveThirdParty push_stream_channel_info_on_publish
+syn keyword ngxDirectiveThirdParty push_stream_authorized_channels_only
+syn keyword ngxDirectiveThirdParty push_stream_header_template_file
+syn keyword ngxDirectiveThirdParty push_stream_header_template
+syn keyword ngxDirectiveThirdParty push_stream_message_template
+syn keyword ngxDirectiveThirdParty push_stream_footer_template
+syn keyword ngxDirectiveThirdParty push_stream_wildcard_channel_max_qtd
+syn keyword ngxDirectiveThirdParty push_stream_ping_message_interval
+syn keyword ngxDirectiveThirdParty push_stream_subscriber_connection_ttl
+syn keyword ngxDirectiveThirdParty push_stream_longpolling_connection_ttl
+syn keyword ngxDirectiveThirdParty push_stream_websocket_allow_publish
+syn keyword ngxDirectiveThirdParty push_stream_last_received_message_time
+syn keyword ngxDirectiveThirdParty push_stream_last_received_message_tag
+syn keyword ngxDirectiveThirdParty push_stream_last_event_id
+syn keyword ngxDirectiveThirdParty push_stream_user_agent
+syn keyword ngxDirectiveThirdParty push_stream_padding_by_user_agent
+syn keyword ngxDirectiveThirdParty push_stream_allowed_origins
+syn keyword ngxDirectiveThirdParty push_stream_allow_connections_to_events_channel
+
+" rDNS Module <https://github.com/flant/nginx-http-rdns>
+" Make a reverse DNS (rDNS) lookup for incoming connection and provides simple access control of incoming hostname by allow/deny rules
+syn keyword ngxDirectiveThirdParty rdns
+syn keyword ngxDirectiveThirdParty rdns_allow
+syn keyword ngxDirectiveThirdParty rdns_deny
+
+" RDS CSV Module <https://github.com/openresty/rds-csv-nginx-module>
+" Nginx output filter module to convert Resty-DBD-Streams (RDS) to Comma-Separated Values (CSV)
+syn keyword ngxDirectiveThirdParty rds_csv
+syn keyword ngxDirectiveThirdParty rds_csv_row_terminator
+syn keyword ngxDirectiveThirdParty rds_csv_field_separator
+syn keyword ngxDirectiveThirdParty rds_csv_field_name_header
+syn keyword ngxDirectiveThirdParty rds_csv_content_type
+syn keyword ngxDirectiveThirdParty rds_csv_buffer_size
+
+" RDS JSON Module <https://github.com/openresty/rds-json-nginx-module>
+" An output filter that formats Resty DBD Streams generated by ngx_drizzle and others to JSON
+syn keyword ngxDirectiveThirdParty rds_json
+syn keyword ngxDirectiveThirdParty rds_json_buffer_size
+syn keyword ngxDirectiveThirdParty rds_json_format
+syn keyword ngxDirectiveThirdParty rds_json_root
+syn keyword ngxDirectiveThirdParty rds_json_success_property
+syn keyword ngxDirectiveThirdParty rds_json_user_property
+syn keyword ngxDirectiveThirdParty rds_json_errcode_key
+syn keyword ngxDirectiveThirdParty rds_json_errstr_key
+syn keyword ngxDirectiveThirdParty rds_json_ret
+syn keyword ngxDirectiveThirdParty rds_json_content_type
+
+" Redis Module <https://www.nginx.com/resources/wiki/modules/redis/>
+" Use this module to perform simple caching
+syn keyword ngxDirectiveThirdParty redis_pass
+syn keyword ngxDirectiveThirdParty redis_bind
+syn keyword ngxDirectiveThirdParty redis_connect_timeout
+syn keyword ngxDirectiveThirdParty redis_read_timeout
+syn keyword ngxDirectiveThirdParty redis_send_timeout
+syn keyword ngxDirectiveThirdParty redis_buffer_size
+syn keyword ngxDirectiveThirdParty redis_next_upstream
+syn keyword ngxDirectiveThirdParty redis_gzip_flag
+
+" Redis 2 Module <https://github.com/openresty/redis2-nginx-module>
+" Nginx upstream module for the Redis 2.0 protocol
+syn keyword ngxDirectiveThirdParty redis2_query
+syn keyword ngxDirectiveThirdParty redis2_raw_query
+syn keyword ngxDirectiveThirdParty redis2_raw_queries
+syn keyword ngxDirectiveThirdParty redis2_literal_raw_query
+syn keyword ngxDirectiveThirdParty redis2_pass
+syn keyword ngxDirectiveThirdParty redis2_connect_timeout
+syn keyword ngxDirectiveThirdParty redis2_send_timeout
+syn keyword ngxDirectiveThirdParty redis2_read_timeout
+syn keyword ngxDirectiveThirdParty redis2_buffer_size
+syn keyword ngxDirectiveThirdParty redis2_next_upstream
+
+" Replace Filter Module <https://github.com/openresty/replace-filter-nginx-module>
+" Streaming regular expression replacement in response bodies
+syn keyword ngxDirectiveThirdParty replace_filter
+syn keyword ngxDirectiveThirdParty replace_filter_types
+syn keyword ngxDirectiveThirdParty replace_filter_max_buffered_size
+syn keyword ngxDirectiveThirdParty replace_filter_last_modified
+syn keyword ngxDirectiveThirdParty replace_filter_skip
+
+" Roboo Module <https://github.com/yuri-gushin/Roboo>
+" HTTP Robot Mitigator
+
+" RRD Graph Module <https://www.nginx.com/resources/wiki/modules/rrd_graph/>
+" This module provides an HTTP interface to RRDtool's graphing facilities.
+syn keyword ngxDirectiveThirdParty rrd_graph
+syn keyword ngxDirectiveThirdParty rrd_graph_root
+
+" RTMP Module <https://github.com/arut/nginx-rtmp-module>
+" NGINX-based Media Streaming Server
+syn keyword ngxDirectiveThirdParty rtmp
+" syn keyword ngxDirectiveThirdParty server
+" syn keyword ngxDirectiveThirdParty listen
+syn keyword ngxDirectiveThirdParty application
+" syn keyword ngxDirectiveThirdParty timeout
+syn keyword ngxDirectiveThirdParty ping
+syn keyword ngxDirectiveThirdParty ping_timeout
+syn keyword ngxDirectiveThirdParty max_streams
+syn keyword ngxDirectiveThirdParty ack_window
+syn keyword ngxDirectiveThirdParty chunk_size
+syn keyword ngxDirectiveThirdParty max_queue
+syn keyword ngxDirectiveThirdParty max_message
+syn keyword ngxDirectiveThirdParty out_queue
+syn keyword ngxDirectiveThirdParty out_cork
+" syn keyword ngxDirectiveThirdParty allow
+" syn keyword ngxDirectiveThirdParty deny
+syn keyword ngxDirectiveThirdParty exec_push
+syn keyword ngxDirectiveThirdParty exec_pull
+syn keyword ngxDirectiveThirdParty exec
+syn keyword ngxDirectiveThirdParty exec_options
+syn keyword ngxDirectiveThirdParty exec_static
+syn keyword ngxDirectiveThirdParty exec_kill_signal
+syn keyword ngxDirectiveThirdParty respawn
+syn keyword ngxDirectiveThirdParty respawn_timeout
+syn keyword ngxDirectiveThirdParty exec_publish
+syn keyword ngxDirectiveThirdParty exec_play
+syn keyword ngxDirectiveThirdParty exec_play_done
+syn keyword ngxDirectiveThirdParty exec_publish_done
+syn keyword ngxDirectiveThirdParty exec_record_done
+syn keyword ngxDirectiveThirdParty live
+syn keyword ngxDirectiveThirdParty meta
+syn keyword ngxDirectiveThirdParty interleave
+syn keyword ngxDirectiveThirdParty wait_key
+syn keyword ngxDirectiveThirdParty wait_video
+syn keyword ngxDirectiveThirdParty publish_notify
+syn keyword ngxDirectiveThirdParty drop_idle_publisher
+syn keyword ngxDirectiveThirdParty sync
+syn keyword ngxDirectiveThirdParty play_restart
+syn keyword ngxDirectiveThirdParty idle_streams
+syn keyword ngxDirectiveThirdParty record
+syn keyword ngxDirectiveThirdParty record_path
+syn keyword ngxDirectiveThirdParty record_suffix
+syn keyword ngxDirectiveThirdParty record_unique
+syn keyword ngxDirectiveThirdParty record_append
+syn keyword ngxDirectiveThirdParty record_lock
+syn keyword ngxDirectiveThirdParty record_max_size
+syn keyword ngxDirectiveThirdParty record_max_frames
+syn keyword ngxDirectiveThirdParty record_interval
+syn keyword ngxDirectiveThirdParty recorder
+syn keyword ngxDirectiveThirdParty record_notify
+syn keyword ngxDirectiveThirdParty play
+syn keyword ngxDirectiveThirdParty play_temp_path
+syn keyword ngxDirectiveThirdParty play_local_path
+syn keyword ngxDirectiveThirdParty pull
+syn keyword ngxDirectiveThirdParty push
+syn keyword ngxDirectiveThirdParty push_reconnect
+syn keyword ngxDirectiveThirdParty session_relay
+syn keyword ngxDirectiveThirdParty on_connect
+syn keyword ngxDirectiveThirdParty on_play
+syn keyword ngxDirectiveThirdParty on_publish
+syn keyword ngxDirectiveThirdParty on_done
+syn keyword ngxDirectiveThirdParty on_play_done
+syn keyword ngxDirectiveThirdParty on_publish_done
+syn keyword ngxDirectiveThirdParty on_record_done
+syn keyword ngxDirectiveThirdParty on_update
+syn keyword ngxDirectiveThirdParty notify_update_timeout
+syn keyword ngxDirectiveThirdParty notify_update_strict
+syn keyword ngxDirectiveThirdParty notify_relay_redirect
+syn keyword ngxDirectiveThirdParty notify_method
+syn keyword ngxDirectiveThirdParty hls
+syn keyword ngxDirectiveThirdParty hls_path
+syn keyword ngxDirectiveThirdParty hls_fragment
+syn keyword ngxDirectiveThirdParty hls_playlist_length
+syn keyword ngxDirectiveThirdParty hls_sync
+syn keyword ngxDirectiveThirdParty hls_continuous
+syn keyword ngxDirectiveThirdParty hls_nested
+syn keyword ngxDirectiveThirdParty hls_base_url
+syn keyword ngxDirectiveThirdParty hls_cleanup
+syn keyword ngxDirectiveThirdParty hls_fragment_naming
+syn keyword ngxDirectiveThirdParty hls_fragment_slicing
+syn keyword ngxDirectiveThirdParty hls_variant
+syn keyword ngxDirectiveThirdParty hls_type
+syn keyword ngxDirectiveThirdParty hls_keys
+syn keyword ngxDirectiveThirdParty hls_key_path
+syn keyword ngxDirectiveThirdParty hls_key_url
+syn keyword ngxDirectiveThirdParty hls_fragments_per_key
+syn keyword ngxDirectiveThirdParty dash
+syn keyword ngxDirectiveThirdParty dash_path
+syn keyword ngxDirectiveThirdParty dash_fragment
+syn keyword ngxDirectiveThirdParty dash_playlist_length
+syn keyword ngxDirectiveThirdParty dash_nested
+syn keyword ngxDirectiveThirdParty dash_cleanup
+" syn keyword ngxDirectiveThirdParty access_log
+" syn keyword ngxDirectiveThirdParty log_format
+syn keyword ngxDirectiveThirdParty max_connections
+syn keyword ngxDirectiveThirdParty rtmp_stat
+syn keyword ngxDirectiveThirdParty rtmp_stat_stylesheet
+syn keyword ngxDirectiveThirdParty rtmp_auto_push
+syn keyword ngxDirectiveThirdParty rtmp_auto_push_reconnect
+syn keyword ngxDirectiveThirdParty rtmp_socket_dir
+syn keyword ngxDirectiveThirdParty rtmp_control
+
+" RTMPT Module <https://github.com/kwojtek/nginx-rtmpt-proxy-module>
+" Module for nginx to proxy rtmp using http protocol
+syn keyword ngxDirectiveThirdParty rtmpt_proxy_target
+syn keyword ngxDirectiveThirdParty rtmpt_proxy_rtmp_timeout
+syn keyword ngxDirectiveThirdParty rtmpt_proxy_http_timeout
+syn keyword ngxDirectiveThirdParty rtmpt_proxy
+syn keyword ngxDirectiveThirdParty rtmpt_proxy_stat
+syn keyword ngxDirectiveThirdParty rtmpt_proxy_stylesheet
+
+" Syntactically Awesome Module <https://github.com/mneudert/sass-nginx-module>
+" Providing on-the-fly compiling of Sass files as an NGINX module.
+syn keyword ngxDirectiveThirdParty sass_compile
+syn keyword ngxDirectiveThirdParty sass_error_log
+syn keyword ngxDirectiveThirdParty sass_include_path
+syn keyword ngxDirectiveThirdParty sass_indent
+syn keyword ngxDirectiveThirdParty sass_is_indented_syntax
+syn keyword ngxDirectiveThirdParty sass_linefeed
+syn keyword ngxDirectiveThirdParty sass_precision
+syn keyword ngxDirectiveThirdParty sass_output_style
+syn keyword ngxDirectiveThirdParty sass_source_comments
+syn keyword ngxDirectiveThirdParty sass_source_map_embed
+
+" Secure Download Module <https://www.nginx.com/resources/wiki/modules/secure_download/>
+" Enables you to create links which are only valid until a certain datetime is reached
+syn keyword ngxDirectiveThirdParty secure_download
+syn keyword ngxDirectiveThirdParty secure_download_secret
+syn keyword ngxDirectiveThirdParty secure_download_path_mode
+
+" Selective Cache Purge Module <https://github.com/wandenberg/nginx-selective-cache-purge-module>
+" A module to purge cache by GLOB patterns. The supported patterns are the same as supported by Redis.
+syn keyword ngxDirectiveThirdParty selective_cache_purge_redis_unix_socket
+syn keyword ngxDirectiveThirdParty selective_cache_purge_redis_host
+syn keyword ngxDirectiveThirdParty selective_cache_purge_redis_port
+syn keyword ngxDirectiveThirdParty selective_cache_purge_redis_database
+syn keyword ngxDirectiveThirdParty selective_cache_purge_query
+
+" Set cconv Module <https://github.com/liseen/set-cconv-nginx-module>
+" Cconv rewrite set commands
+syn keyword ngxDirectiveThirdParty set_cconv_to_simp
+syn keyword ngxDirectiveThirdParty set_cconv_to_trad
+syn keyword ngxDirectiveThirdParty set_pinyin_to_normal
+
+" Set Hash Module <https://github.com/simpl/ngx_http_set_hash>
+" Nginx module that allows the setting of variables to the value of a variety of hashes
+syn keyword ngxDirectiveThirdParty set_md5
+syn keyword ngxDirectiveThirdParty set_md5_upper
+syn keyword ngxDirectiveThirdParty set_murmur2
+syn keyword ngxDirectiveThirdParty set_murmur2_upper
+syn keyword ngxDirectiveThirdParty set_sha1
+syn keyword ngxDirectiveThirdParty set_sha1_upper
+
+" Set Lang Module <https://github.com/simpl/ngx_http_set_lang>
+" Provides a variety of ways for setting a variable denoting the langauge that content should be returned in.
+syn keyword ngxDirectiveThirdParty set_lang
+syn keyword ngxDirectiveThirdParty set_lang_method
+syn keyword ngxDirectiveThirdParty lang_cookie
+syn keyword ngxDirectiveThirdParty lang_get_var
+syn keyword ngxDirectiveThirdParty lang_list
+syn keyword ngxDirectiveThirdParty lang_post_var
+syn keyword ngxDirectiveThirdParty lang_host
+syn keyword ngxDirectiveThirdParty lang_referer
+
+" Set Misc Module <https://github.com/openresty/set-misc-nginx-module>
+" Various set_xxx directives added to nginx's rewrite module
+syn keyword ngxDirectiveThirdParty set_if_empty
+syn keyword ngxDirectiveThirdParty set_quote_sql_str
+syn keyword ngxDirectiveThirdParty set_quote_pgsql_str
+syn keyword ngxDirectiveThirdParty set_quote_json_str
+syn keyword ngxDirectiveThirdParty set_unescape_uri
+syn keyword ngxDirectiveThirdParty set_escape_uri
+syn keyword ngxDirectiveThirdParty set_hashed_upstream
+syn keyword ngxDirectiveThirdParty set_encode_base32
+syn keyword ngxDirectiveThirdParty set_base32_padding
+syn keyword ngxDirectiveThirdParty set_misc_base32_padding
+syn keyword ngxDirectiveThirdParty set_base32_alphabet
+syn keyword ngxDirectiveThirdParty set_decode_base32
+syn keyword ngxDirectiveThirdParty set_encode_base64
+syn keyword ngxDirectiveThirdParty set_decode_base64
+syn keyword ngxDirectiveThirdParty set_encode_hex
+syn keyword ngxDirectiveThirdParty set_decode_hex
+syn keyword ngxDirectiveThirdParty set_sha1
+syn keyword ngxDirectiveThirdParty set_md5
+syn keyword ngxDirectiveThirdParty set_hmac_sha1
+syn keyword ngxDirectiveThirdParty set_random
+syn keyword ngxDirectiveThirdParty set_secure_random_alphanum
+syn keyword ngxDirectiveThirdParty set_secure_random_lcalpha
+syn keyword ngxDirectiveThirdParty set_rotate
+syn keyword ngxDirectiveThirdParty set_local_today
+syn keyword ngxDirectiveThirdParty set_formatted_gmt_time
+syn keyword ngxDirectiveThirdParty set_formatted_local_time
+
+" SFlow Module <https://github.com/sflow/nginx-sflow-module>
+" A binary, random-sampling nginx module designed for: lightweight, centralized, continuous, real-time monitoring of very large and very busy web farms.
+syn keyword ngxDirectiveThirdParty sflow
+
+" Shibboleth Module <https://github.com/nginx-shib/nginx-http-shibboleth>
+" Shibboleth auth request module for nginx
+syn keyword ngxDirectiveThirdParty shib_request
+syn keyword ngxDirectiveThirdParty shib_request_set
+syn keyword ngxDirectiveThirdParty shib_request_use_headers
+
+" Slice Module <https://github.com/alibaba/nginx-http-slice>
+" Nginx module for serving a file in slices (reverse byte-range)
+" syn keyword ngxDirectiveThirdParty slice
+syn keyword ngxDirectiveThirdParty slice_arg_begin
+syn keyword ngxDirectiveThirdParty slice_arg_end
+syn keyword ngxDirectiveThirdParty slice_header
+syn keyword ngxDirectiveThirdParty slice_footer
+syn keyword ngxDirectiveThirdParty slice_header_first
+syn keyword ngxDirectiveThirdParty slice_footer_last
+
+" SlowFS Cache Module <https://github.com/FRiCKLE/ngx_slowfs_cache/>
+" Module adding ability to cache static files.
+syn keyword ngxDirectiveThirdParty slowfs_big_file_size
+syn keyword ngxDirectiveThirdParty slowfs_cache
+syn keyword ngxDirectiveThirdParty slowfs_cache_key
+syn keyword ngxDirectiveThirdParty slowfs_cache_min_uses
+syn keyword ngxDirectiveThirdParty slowfs_cache_path
+syn keyword ngxDirectiveThirdParty slowfs_cache_purge
+syn keyword ngxDirectiveThirdParty slowfs_cache_valid
+syn keyword ngxDirectiveThirdParty slowfs_temp_path
+
+" Small Light Module <https://github.com/cubicdaiya/ngx_small_light>
+" Dynamic Image Transformation Module For nginx.
+syn keyword ngxDirectiveThirdParty small_light
+syn keyword ngxDirectiveThirdParty small_light_getparam_mode
+syn keyword ngxDirectiveThirdParty small_light_material_dir
+syn keyword ngxDirectiveThirdParty small_light_pattern_define
+syn keyword ngxDirectiveThirdParty small_light_radius_max
+syn keyword ngxDirectiveThirdParty small_light_sigma_max
+syn keyword ngxDirectiveThirdParty small_light_imlib2_temp_dir
+syn keyword ngxDirectiveThirdParty small_light_buffer
+
+" Sorted Querystring Filter Module <https://github.com/wandenberg/nginx-sorted-querystring-module>
+" Nginx module to expose querystring parameters sorted in a variable to be used on cache_key as example
+syn keyword ngxDirectiveThirdParty sorted_querystring_filter_parameter
+
+" Sphinx2 Module <https://github.com/reeteshranjan/sphinx2-nginx-module>
+" Nginx upstream module for Sphinx 2.x
+syn keyword ngxDirectiveThirdParty sphinx2_pass
+syn keyword ngxDirectiveThirdParty sphinx2_bind
+syn keyword ngxDirectiveThirdParty sphinx2_connect_timeout
+syn keyword ngxDirectiveThirdParty sphinx2_send_timeout
+syn keyword ngxDirectiveThirdParty sphinx2_buffer_size
+syn keyword ngxDirectiveThirdParty sphinx2_read_timeout
+syn keyword ngxDirectiveThirdParty sphinx2_next_upstream
+
+" HTTP SPNEGO auth Module <https://github.com/stnoonan/spnego-http-auth-nginx-module>
+" This module implements adds SPNEGO support to nginx(http://nginx.org). It currently supports only Kerberos authentication via GSSAPI
+syn keyword ngxDirectiveThirdParty auth_gss
+syn keyword ngxDirectiveThirdParty auth_gss_keytab
+syn keyword ngxDirectiveThirdParty auth_gss_realm
+syn keyword ngxDirectiveThirdParty auth_gss_service_name
+syn keyword ngxDirectiveThirdParty auth_gss_authorized_principal
+syn keyword ngxDirectiveThirdParty auth_gss_allow_basic_fallback
+
+" SR Cache Module <https://github.com/openresty/srcache-nginx-module>
+" Transparent subrequest-based caching layout for arbitrary nginx locations
+syn keyword ngxDirectiveThirdParty srcache_fetch
+syn keyword ngxDirectiveThirdParty srcache_fetch_skip
+syn keyword ngxDirectiveThirdParty srcache_store
+syn keyword ngxDirectiveThirdParty srcache_store_max_size
+syn keyword ngxDirectiveThirdParty srcache_store_skip
+syn keyword ngxDirectiveThirdParty srcache_store_statuses
+syn keyword ngxDirectiveThirdParty srcache_store_ranges
+syn keyword ngxDirectiveThirdParty srcache_header_buffer_size
+syn keyword ngxDirectiveThirdParty srcache_store_hide_header
+syn keyword ngxDirectiveThirdParty srcache_store_pass_header
+syn keyword ngxDirectiveThirdParty srcache_methods
+syn keyword ngxDirectiveThirdParty srcache_ignore_content_encoding
+syn keyword ngxDirectiveThirdParty srcache_request_cache_control
+syn keyword ngxDirectiveThirdParty srcache_response_cache_control
+syn keyword ngxDirectiveThirdParty srcache_store_no_store
+syn keyword ngxDirectiveThirdParty srcache_store_no_cache
+syn keyword ngxDirectiveThirdParty srcache_store_private
+syn keyword ngxDirectiveThirdParty srcache_default_expire
+syn keyword ngxDirectiveThirdParty srcache_max_expire
+
+" SSSD Info Module <https://github.com/veruu/ngx_sssd_info>
+" Retrives additional attributes from SSSD for current authentizated user
+syn keyword ngxDirectiveThirdParty sssd_info
+syn keyword ngxDirectiveThirdParty sssd_info_output_to
+syn keyword ngxDirectiveThirdParty sssd_info_groups
+syn keyword ngxDirectiveThirdParty sssd_info_group
+syn keyword ngxDirectiveThirdParty sssd_info_group_separator
+syn keyword ngxDirectiveThirdParty sssd_info_attributes
+syn keyword ngxDirectiveThirdParty sssd_info_attribute
+syn keyword ngxDirectiveThirdParty sssd_info_attribute_separator
+
+" Static Etags Module <https://github.com/mikewest/nginx-static-etags>
+" Generate etags for static content
+syn keyword ngxDirectiveThirdParty FileETag
+
+" Statsd Module <https://github.com/zebrafishlabs/nginx-statsd>
+" An nginx module for sending statistics to statsd
+syn keyword ngxDirectiveThirdParty statsd_server
+syn keyword ngxDirectiveThirdParty statsd_sample_rate
+syn keyword ngxDirectiveThirdParty statsd_count
+syn keyword ngxDirectiveThirdParty statsd_timing
+
+" Sticky Module <https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng>
+" Add a sticky cookie to be always forwarded to the same upstream server
+" syn keyword ngxDirectiveThirdParty sticky
+
+" Stream Echo Module <https://github.com/openresty/stream-echo-nginx-module>
+" TCP/stream echo module for NGINX (a port of ngx_http_echo_module)
+syn keyword ngxDirectiveThirdParty echo
+syn keyword ngxDirectiveThirdParty echo_duplicate
+syn keyword ngxDirectiveThirdParty echo_flush_wait
+syn keyword ngxDirectiveThirdParty echo_sleep
+syn keyword ngxDirectiveThirdParty echo_send_timeout
+syn keyword ngxDirectiveThirdParty echo_read_bytes
+syn keyword ngxDirectiveThirdParty echo_read_line
+syn keyword ngxDirectiveThirdParty echo_request_data
+syn keyword ngxDirectiveThirdParty echo_discard_request
+syn keyword ngxDirectiveThirdParty echo_read_buffer_size
+syn keyword ngxDirectiveThirdParty echo_read_timeout
+syn keyword ngxDirectiveThirdParty echo_client_error_log_level
+syn keyword ngxDirectiveThirdParty echo_lingering_close
+syn keyword ngxDirectiveThirdParty echo_lingering_time
+syn keyword ngxDirectiveThirdParty echo_lingering_timeout
+
+" Stream Lua Module <https://github.com/openresty/stream-lua-nginx-module>
+" Embed the power of Lua into Nginx stream/TCP Servers.
+syn keyword ngxDirectiveThirdParty lua_resolver
+syn keyword ngxDirectiveThirdParty lua_resolver_timeout
+syn keyword ngxDirectiveThirdParty lua_lingering_close
+syn keyword ngxDirectiveThirdParty lua_lingering_time
+syn keyword ngxDirectiveThirdParty lua_lingering_timeout
+
+" Stream Upsync Module <https://github.com/xiaokai-wang/nginx-stream-upsync-module>
+" Sync upstreams from consul or others, dynamiclly modify backend-servers attribute(weight, max_fails,...), needn't reload nginx.
+syn keyword ngxDirectiveThirdParty upsync
+syn keyword ngxDirectiveThirdParty upsync_dump_path
+syn keyword ngxDirectiveThirdParty upsync_lb
+syn keyword ngxDirectiveThirdParty upsync_show
+
+" Strip Module <https://github.com/evanmiller/mod_strip>
+" Whitespace remover.
+syn keyword ngxDirectiveThirdParty strip
+
+" Subrange Module <https://github.com/Qihoo360/ngx_http_subrange_module>
+" Split one big HTTP/Range request to multiple subrange requesets
+syn keyword ngxDirectiveThirdParty subrange
+
+" Substitutions Module <https://www.nginx.com/resources/wiki/modules/substitutions/>
+" A filter module which can do both regular expression and fixed string substitutions on response bodies.
+syn keyword ngxDirectiveThirdParty subs_filter
+syn keyword ngxDirectiveThirdParty subs_filter_types
+
+" Summarizer Module <https://github.com/reeteshranjan/summarizer-nginx-module>
+" Upstream nginx module to get summaries of documents using the summarizer daemon service
+syn keyword ngxDirectiveThirdParty smrzr_filename
+syn keyword ngxDirectiveThirdParty smrzr_ratio
+
+" Supervisord Module <https://github.com/FRiCKLE/ngx_supervisord/>
+" Module providing nginx with API to communicate with supervisord and manage (start/stop) backends on-demand.
+syn keyword ngxDirectiveThirdParty supervisord
+syn keyword ngxDirectiveThirdParty supervisord_inherit_backend_status
+syn keyword ngxDirectiveThirdParty supervisord_name
+syn keyword ngxDirectiveThirdParty supervisord_start
+syn keyword ngxDirectiveThirdParty supervisord_stop
+
+" Tarantool Upstream Module <https://github.com/tarantool/nginx_upstream_module>
+" Tarantool NginX upstream module (REST, JSON API, websockets, load balancing)
+syn keyword ngxDirectiveThirdParty tnt_pass
+syn keyword ngxDirectiveThirdParty tnt_http_methods
+syn keyword ngxDirectiveThirdParty tnt_http_rest_methods
+syn keyword ngxDirectiveThirdParty tnt_pass_http_request
+syn keyword ngxDirectiveThirdParty tnt_pass_http_request_buffer_size
+syn keyword ngxDirectiveThirdParty tnt_method
+syn keyword ngxDirectiveThirdParty tnt_http_allowed_methods - experemental
+syn keyword ngxDirectiveThirdParty tnt_send_timeout
+syn keyword ngxDirectiveThirdParty tnt_read_timeout
+syn keyword ngxDirectiveThirdParty tnt_buffer_size
+syn keyword ngxDirectiveThirdParty tnt_next_upstream
+syn keyword ngxDirectiveThirdParty tnt_connect_timeout
+syn keyword ngxDirectiveThirdParty tnt_next_upstream
+syn keyword ngxDirectiveThirdParty tnt_next_upstream_tries
+syn keyword ngxDirectiveThirdParty tnt_next_upstream_timeout
+
+" TCP Proxy Module <http://yaoweibin.github.io/nginx_tcp_proxy_module/>
+" Add the feature of tcp proxy with nginx, with health check and status monitor
+syn keyword ngxDirectiveBlock tcp
+" syn keyword ngxDirectiveThirdParty server
+" syn keyword ngxDirectiveThirdParty listen
+" syn keyword ngxDirectiveThirdParty allow
+" syn keyword ngxDirectiveThirdParty deny
+" syn keyword ngxDirectiveThirdParty so_keepalive
+" syn keyword ngxDirectiveThirdParty tcp_nodelay
+" syn keyword ngxDirectiveThirdParty timeout
+" syn keyword ngxDirectiveThirdParty server_name
+" syn keyword ngxDirectiveThirdParty resolver
+" syn keyword ngxDirectiveThirdParty resolver_timeout
+" syn keyword ngxDirectiveThirdParty upstream
+syn keyword ngxDirectiveThirdParty check
+syn keyword ngxDirectiveThirdParty check_http_send
+syn keyword ngxDirectiveThirdParty check_http_expect_alive
+syn keyword ngxDirectiveThirdParty check_smtp_send
+syn keyword ngxDirectiveThirdParty check_smtp_expect_alive
+syn keyword ngxDirectiveThirdParty check_shm_size
+syn keyword ngxDirectiveThirdParty check_status
+" syn keyword ngxDirectiveThirdParty ip_hash
+" syn keyword ngxDirectiveThirdParty proxy_pass
+" syn keyword ngxDirectiveThirdParty proxy_buffer
+" syn keyword ngxDirectiveThirdParty proxy_connect_timeout
+" syn keyword ngxDirectiveThirdParty proxy_read_timeout
+syn keyword ngxDirectiveThirdParty proxy_write_timeout
+
+" Testcookie Module <https://github.com/kyprizel/testcookie-nginx-module>
+" NGINX module for L7 DDoS attack mitigation
+syn keyword ngxDirectiveThirdParty testcookie
+syn keyword ngxDirectiveThirdParty testcookie_name
+syn keyword ngxDirectiveThirdParty testcookie_domain
+syn keyword ngxDirectiveThirdParty testcookie_expires
+syn keyword ngxDirectiveThirdParty testcookie_path
+syn keyword ngxDirectiveThirdParty testcookie_secret
+syn keyword ngxDirectiveThirdParty testcookie_session
+syn keyword ngxDirectiveThirdParty testcookie_arg
+syn keyword ngxDirectiveThirdParty testcookie_max_attempts
+syn keyword ngxDirectiveThirdParty testcookie_p3p
+syn keyword ngxDirectiveThirdParty testcookie_fallback
+syn keyword ngxDirectiveThirdParty testcookie_whitelist
+syn keyword ngxDirectiveThirdParty testcookie_pass
+syn keyword ngxDirectiveThirdParty testcookie_redirect_via_refresh
+syn keyword ngxDirectiveThirdParty testcookie_refresh_template
+syn keyword ngxDirectiveThirdParty testcookie_refresh_status
+syn keyword ngxDirectiveThirdParty testcookie_deny_keepalive
+syn keyword ngxDirectiveThirdParty testcookie_get_only
+syn keyword ngxDirectiveThirdParty testcookie_https_location
+syn keyword ngxDirectiveThirdParty testcookie_refresh_encrypt_cookie
+syn keyword ngxDirectiveThirdParty testcookie_refresh_encrypt_cookie_key
+syn keyword ngxDirectiveThirdParty testcookie_refresh_encrypt_iv
+syn keyword ngxDirectiveThirdParty testcookie_internal
+syn keyword ngxDirectiveThirdParty testcookie_httponly_flag
+syn keyword ngxDirectiveThirdParty testcookie_secure_flag
+
+" Types Filter Module <https://github.com/flygoast/ngx_http_types_filter>
+" Change the `Content-Type` output header depending on an extension variable according to a condition specified in the 'if' clause.
+syn keyword ngxDirectiveThirdParty types_filter
+syn keyword ngxDirectiveThirdParty types_filter_use_default
+
+" Unzip Module <https://github.com/youzee/nginx-unzip-module>
+" Enabling fetching of files that are stored in zipped archives.
+syn keyword ngxDirectiveThirdParty file_in_unzip_archivefile
+syn keyword ngxDirectiveThirdParty file_in_unzip_extract
+syn keyword ngxDirectiveThirdParty file_in_unzip
+
+" Upload Progress Module <https://www.nginx.com/resources/wiki/modules/upload_progress/>
+" An upload progress system, that monitors RFC1867 POST upload as they are transmitted to upstream servers
+syn keyword ngxDirectiveThirdParty upload_progress
+syn keyword ngxDirectiveThirdParty track_uploads
+syn keyword ngxDirectiveThirdParty report_uploads
+syn keyword ngxDirectiveThirdParty upload_progress_content_type
+syn keyword ngxDirectiveThirdParty upload_progress_header
+syn keyword ngxDirectiveThirdParty upload_progress_jsonp_parameter
+syn keyword ngxDirectiveThirdParty upload_progress_json_output
+syn keyword ngxDirectiveThirdParty upload_progress_jsonp_output
+syn keyword ngxDirectiveThirdParty upload_progress_template
+
+" Upload Module <https://www.nginx.com/resources/wiki/modules/upload/>
+" Parses request body storing all files being uploaded to a directory specified by upload_store directive
+syn keyword ngxDirectiveThirdParty upload_pass
+syn keyword ngxDirectiveThirdParty upload_resumable
+syn keyword ngxDirectiveThirdParty upload_store
+syn keyword ngxDirectiveThirdParty upload_state_store
+syn keyword ngxDirectiveThirdParty upload_store_access
+syn keyword ngxDirectiveThirdParty upload_set_form_field
+syn keyword ngxDirectiveThirdParty upload_aggregate_form_field
+syn keyword ngxDirectiveThirdParty upload_pass_form_field
+syn keyword ngxDirectiveThirdParty upload_cleanup
+syn keyword ngxDirectiveThirdParty upload_buffer_size
+syn keyword ngxDirectiveThirdParty upload_max_part_header_len
+syn keyword ngxDirectiveThirdParty upload_max_file_size
+syn keyword ngxDirectiveThirdParty upload_limit_rate
+syn keyword ngxDirectiveThirdParty upload_max_output_body_len
+syn keyword ngxDirectiveThirdParty upload_tame_arrays
+syn keyword ngxDirectiveThirdParty upload_pass_args
+
+" Upstream Fair Module <https://github.com/gnosek/nginx-upstream-fair>
+" The fair load balancer module for nginx http://nginx.localdomain.pl
+syn keyword ngxDirectiveThirdParty fair
+syn keyword ngxDirectiveThirdParty upstream_fair_shm_size
+
+" Upstream Hash Module (DEPRECATED) <http://wiki.nginx.org/NginxHttpUpstreamRequestHashModule>
+" Provides simple upstream load distribution by hashing a configurable variable.
+" syn keyword ngxDirectiveDeprecated hash
+syn keyword ngxDirectiveDeprecated hash_again
+
+" Upstream Domain Resolve Module <https://www.nginx.com/resources/wiki/modules/domain_resolve/>
+" A load-balancer that resolves an upstream domain name asynchronously.
+syn keyword ngxDirectiveThirdParty jdomain
+
+" Upsync Module <https://github.com/weibocom/nginx-upsync-module>
+" Sync upstreams from consul or others, dynamiclly modify backend-servers attribute(weight, max_fails,...), needn't reload nginx
+syn keyword ngxDirectiveThirdParty upsync
+syn keyword ngxDirectiveThirdParty upsync_dump_path
+syn keyword ngxDirectiveThirdParty upsync_lb
+syn keyword ngxDirectiveThirdParty upstream_show
+
+" URL Module <https://github.com/vozlt/nginx-module-url>
+" Nginx url encoding converting module
+syn keyword ngxDirectiveThirdParty url_encoding_convert
+syn keyword ngxDirectiveThirdParty url_encoding_convert_from
+syn keyword ngxDirectiveThirdParty url_encoding_convert_to
+
+" User Agent Module <https://github.com/alibaba/nginx-http-user-agent>
+" Match browsers and crawlers
+syn keyword ngxDirectiveThirdParty user_agent
+
+" Upstrema Ketama Chash Module <https://github.com/flygoast/ngx_http_upstream_ketama_chash>
+" Nginx load-balancer module implementing ketama consistent hashing.
+syn keyword ngxDirectiveThirdParty ketama_chash
+
+" Video Thumbextractor Module <https://github.com/wandenberg/nginx-video-thumbextractor-module>
+" Extract thumbs from a video file
+syn keyword ngxDirectiveThirdParty video_thumbextractor
+syn keyword ngxDirectiveThirdParty video_thumbextractor_video_filename
+syn keyword ngxDirectiveThirdParty video_thumbextractor_video_second
+syn keyword ngxDirectiveThirdParty video_thumbextractor_image_width
+syn keyword ngxDirectiveThirdParty video_thumbextractor_image_height
+syn keyword ngxDirectiveThirdParty video_thumbextractor_only_keyframe
+syn keyword ngxDirectiveThirdParty video_thumbextractor_next_time
+syn keyword ngxDirectiveThirdParty video_thumbextractor_tile_rows
+syn keyword ngxDirectiveThirdParty video_thumbextractor_tile_cols
+syn keyword ngxDirectiveThirdParty video_thumbextractor_tile_max_rows
+syn keyword ngxDirectiveThirdParty video_thumbextractor_tile_max_cols
+syn keyword ngxDirectiveThirdParty video_thumbextractor_tile_sample_interval
+syn keyword ngxDirectiveThirdParty video_thumbextractor_tile_color
+syn keyword ngxDirectiveThirdParty video_thumbextractor_tile_margin
+syn keyword ngxDirectiveThirdParty video_thumbextractor_tile_padding
+syn keyword ngxDirectiveThirdParty video_thumbextractor_threads
+syn keyword ngxDirectiveThirdParty video_thumbextractor_processes_per_worker
+
+" Eval Module <http://www.grid.net.ru/nginx/eval.en.html>
+" Module for nginx web server evaluates response of proxy or memcached module into variables.
+syn keyword ngxDirectiveThirdParty eval
+syn keyword ngxDirectiveThirdParty eval_escalate
+syn keyword ngxDirectiveThirdParty eval_override_content_type
+
+" VTS Module <https://github.com/vozlt/nginx-module-vts>
+" Nginx virtual host traffic status module
+syn keyword ngxDirectiveThirdParty vhost_traffic_status
+syn keyword ngxDirectiveThirdParty vhost_traffic_status_zone
+syn keyword ngxDirectiveThirdParty vhost_traffic_status_display
+syn keyword ngxDirectiveThirdParty vhost_traffic_status_display_format
+syn keyword ngxDirectiveThirdParty vhost_traffic_status_display_jsonp
+syn keyword ngxDirectiveThirdParty vhost_traffic_status_filter
+syn keyword ngxDirectiveThirdParty vhost_traffic_status_filter_by_host
+syn keyword ngxDirectiveThirdParty vhost_traffic_status_filter_by_set_key
+syn keyword ngxDirectiveThirdParty vhost_traffic_status_filter_check_duplicate
+syn keyword ngxDirectiveThirdParty vhost_traffic_status_limit
+syn keyword ngxDirectiveThirdParty vhost_traffic_status_limit_traffic
+syn keyword ngxDirectiveThirdParty vhost_traffic_status_limit_traffic_by_set_key
+syn keyword ngxDirectiveThirdParty vhost_traffic_status_limit_check_duplicate
+
+" XSS Module <https://github.com/openresty/xss-nginx-module>
+" Native support for cross-site scripting (XSS) in an nginx.
+syn keyword ngxDirectiveThirdParty xss_get
+syn keyword ngxDirectiveThirdParty xss_callback_arg
+syn keyword ngxDirectiveThirdParty xss_override_status
+syn keyword ngxDirectiveThirdParty xss_check_status
+syn keyword ngxDirectiveThirdParty xss_input_types
+
+" ZIP Module <https://www.nginx.com/resources/wiki/modules/zip/>
+" ZIP archiver for nginx
+
+" Contained LUA blocks for embedded syntax highlighting
+syn keyword ngxThirdPartyLuaBlock balancer_by_lua_block contained
+syn keyword ngxThirdPartyLuaBlock init_by_lua_block contained
+syn keyword ngxThirdPartyLuaBlock init_worker_by_lua_block contained
+syn keyword ngxThirdPartyLuaBlock set_by_lua_block contained
+syn keyword ngxThirdPartyLuaBlock content_by_lua_block contained
+syn keyword ngxThirdPartyLuaBlock rewrite_by_lua_block contained
+syn keyword ngxThirdPartyLuaBlock access_by_lua_block contained
+syn keyword ngxThirdPartyLuaBlock header_filter_by_lua_block contained
+syn keyword ngxThirdPartyLuaBlock body_filter_by_lua_block contained
+syn keyword ngxThirdPartyLuaBlock log_by_lua_block contained
+syn keyword ngxThirdPartyLuaBlock ssl_certificate_by_lua_block contained
+syn keyword ngxThirdPartyLuaBlock ssl_session_fetch_by_lua_block contained
+syn keyword ngxThirdPartyLuaBlock ssl_session_store_by_lua_block contained
+
+
+" Nested syntax in ERB templating statements
+" Subtype needs to be set to '', otherwise recursive errors occur when opening *.nginx files
+let b:eruby_subtype = ''
+unlet b:current_syntax
+syn include @ERB syntax/eruby.vim
+syn region ngxTemplate start=+<%[^\=]+ end=+%>+ oneline contains=@ERB
+syn region ngxTemplateVar start=+<%=+ end=+%>+ oneline
+let b:current_syntax = "nginx"
+
+" Nested syntax in Jinja templating statements
+" This dependend on https://github.com/lepture/vim-jinja
+unlet b:current_syntax
+try
+ syn include @JINJA syntax/jinja.vim
+ syn region ngxTemplate start=+{%+ end=+%}+ oneline contains=@JINJA
+ syn region ngxTemplateVar start=+{{+ end=+}}+ oneline
+catch
+endtry
+let b:current_syntax = "nginx"
+
+" Enable nested LUA syntax highlighting
+unlet b:current_syntax
+syn include @LUA syntax/lua.vim
+syn region ngxLua start=+^\s*\w\+_by_lua_block\s*{+ end=+}+me=s-1 contains=ngxBlock,@LUA
+let b:current_syntax = "nginx"
+
+
+" Highlight
+hi link ngxComment Comment
+hi link ngxVariable Identifier
+hi link ngxVariableBlock Identifier
+hi link ngxVariableString PreProc
+hi link ngxString String
+hi link ngxIPaddr Delimiter
+hi link ngxBoolean Boolean
+hi link ngxInteger Number
+hi link ngxDirectiveBlock Statement
+hi link ngxDirectiveImportant Type
+hi link ngxDirectiveControl Keyword
+hi link ngxDirectiveDeprecated Error
+hi link ngxDirective Function
+hi link ngxDirectiveThirdParty Function
+hi link ngxListenOptions PreProc
+hi link ngxUpstreamServerOptions PreProc
+hi link ngxProxyNextUpstreamOptions PreProc
+hi link ngxMailProtocol Keyword
+hi link ngxSSLProtocol PreProc
+hi link ngxSSLProtocolDeprecated Error
+hi link ngxStickyOptions ngxDirective
+hi link ngxCookieOptions PreProc
+hi link ngxTemplateVar Identifier
+
+hi link ngxSSLSessionTicketsOff ngxBoolean
+hi link ngxSSLSessionTicketsOn Error
+hi link ngxSSLPreferServerCiphersOn ngxBoolean
+hi link ngxSSLPreferServerCiphersOff Error
+hi link ngxGzipOff ngxBoolean
+hi link ngxGzipOn Error
+hi link ngxSSLCipherInsecure Error
+
+hi link ngxThirdPartyLuaBlock Function
diff --git a/runtime/syntax/php.vim b/runtime/syntax/php.vim
index 7b0085cd6e..80662d6750 100644
--- a/runtime/syntax/php.vim
+++ b/runtime/syntax/php.vim
@@ -1,7 +1,7 @@
" Vim syntax file
" Language: php PHP 3/4/5/7/8
" Maintainer: Tyson Andre <tysonandre775@hotmail.com>
-" Last Change: Dec 22, 2020
+" Last Change: Sep 18, 2021
" URL: https://github.com/TysonAndre/php-vim-syntax
" Former Maintainers:
" Jason Woofenden <jason@jasonwoof.com>
@@ -13,10 +13,32 @@
" than the default colourscheme, because elflord's colours will better
" highlight the break-points (Statements) in your code.
"
+" Note: This embeds a modified copy of the html.vim with (mostly) different symbols,
+" in order to implement php_htmlInStrings=2 can work as expected and correctly parse
+" `<?php $phpStartTag = '<?php';`.
+"
+" Credits for the original version of html.vim prior to modifications
+"
+" Previous Maintainer Jorge Maldonado Ventura <jorgesumle@freakspot.net>
+" Previous Maintainer Claudio Fleiner <claudio@fleiner.com>
+" Repository https://notabug.org/jorgesumle/vim-html-syntax
+" Last Change 2021 Mar 02
+" Included patch #7900 to fix comments
+" Included patch #7916 to fix a few more things
+"
" Options:
" Set to anything to enable:
" php_sql_query SQL syntax highlighting inside strings
" php_htmlInStrings HTML syntax highlighting inside strings
+"
+" By setting this to 2, this will use a local copy of
+" HTML syntax highlighting instead of the official
+" HTML syntax highlighting, and properly highlight
+" `<?php $startTag = '<?php';`.
+" This may become the new default in the future.
+"
+" By setting this to 3 (or any unrecognized value),
+" this will use the official installed top level html syntax highlighting rules.
" php_baselib highlighting baselib functions
" php_asp_tags highlighting ASP-style short tags
" php_parent_error_close highlighting parent error ] or )
@@ -62,6 +84,214 @@ if !exists("main_syntax")
let main_syntax = 'php'
endif
+" Start of copy of html for embedding in strings with {{{
+" This is a clone of https://notabug.org/jorgesumle/vim-html-syntax
+" from 2021 Mar 02 with changed symbols and modifications to rules. See the Note in the file header.
+"
+" The default behavior of php_htmlInStrings causes a bug
+" when you're working with code that contains the string literal `'<?php'`.
+" E.g. code that reads php files or generates the contents of php files or
+" generates snippets to `eval()`.
+"
+" When php_htmlInStrings was set to any value,
+" it would cause the html syntax rules to be embedded inside of the string
+" contents.
+"
+" However, php.vim extends html.vim by allowing the php start tag to be
+" included, meaning that this is parsed as `<?php';`, i.e. the start of a
+" new string literal.
+"
+" Work around that by using a different set of rules that don't allow
+" embedding php in most places (phpInnerHtmlPreProc).
+"
+" The default behavior may be changed to this in the future for constants other
+" than 2 or 3 if there are no issues.
+"
+" Many, but not all syntax rules were changed from html* to phpInnerHtml*
+if exists("php_htmlInStrings") && php_htmlInStrings==2
+ " mark illegal characters
+ syn match phpInnerHtmlError contained "[<>&]"
+
+ " tags
+ syn region phpInnerHtmlString contained start=+"+ end=+"+ contains=phpInnerHtmlSpecialChar,javaScriptExpression,@phpInnerHtmlPreproc
+ syn region phpInnerHtmlString contained start=+'+ end=+'+ contains=phpInnerHtmlSpecialChar,javaScriptExpression,@phpInnerHtmlPreproc
+ syn match phpInnerHtmlValue contained "=[\t ]*[^'" \t>][^ \t>]*"hs=s+1 contains=javaScriptExpression,@phpInnerHtmlPreproc
+ syn region phpInnerHtmlEndTag contained start=+</+ end=+>+ contains=phpInnerHtmlTagN,phpInnerHtmlTagError
+ syn region phpInnerHtmlTag contained start=+<[^/]+ end=+>+ fold contains=phpInnerHtmlTagN,phpInnerHtmlString,htmlArg,phpInnerHtmlValue,phpInnerHtmlTagError,phpInnerHtmlEvent,phpInnerHtmlCssDefinition,@phpInnerHtmlPreproc,@phpInnerHtmlArgCluster
+ syn match phpInnerHtmlTagN contained +<\s*[-a-zA-Z0-9]\++hs=s+1 contains=htmlTagName,htmlSpecialTagName,@phpInnerHtmlTagNameCluster
+ syn match phpInnerHtmlTagN contained +</\s*[-a-zA-Z0-9]\++hs=s+2 contains=htmlTagName,htmlSpecialTagName,@phpInnerHtmlTagNameCluster
+ syn match phpInnerHtmlTagError contained "[^>]<"ms=s+1
+
+
+ " special characters
+ syn match phpInnerHtmlSpecialChar "&#\=[0-9A-Za-z]\{1,8};"
+
+ " Comments (the real ones or the old netscape ones)
+ if exists("html_wrong_comments")
+ syn region phpInnerHtmlComment start=+<!--+ end=+--\s*>+ contains=@Spell
+ else
+ " The HTML 5.2 syntax 8.2.4.41: bogus comment is parser error; browser skips until next &gt
+ syn region phpInnerHtmlComment start=+<!+ end=+>+ contains=phpInnerHtmlCommentError keepend
+ " Idem 8.2.4.42,51: Comment starts with <!-- and ends with -->
+ " Idem 8.2.4.43,44: Except <!--> and <!---> are parser errors
+ " Idem 8.2.4.52: dash-dash-bang (--!>) is error ignored by parser, also closes comment
+ syn region phpInnerHtmlComment matchgroup=phpInnerHtmlComment start=+<!--\%(-\?>\)\@!+ end=+--!\?>+ contains=phpInnerHtmlCommentNested,@phpInnerHtmlPreProc,@Spell keepend
+ " Idem 8.2.4.49: nested comment is parser error, except <!--> is all right
+ syn match phpInnerHtmlCommentNested contained "<!-->\@!"
+ syn match phpInnerHtmlCommentError contained "[^><!]"
+ endif
+ syn region phpInnerHtmlComment start=+<!DOCTYPE+ end=+>+ keepend
+
+ " server-parsed commands
+ syn region phpInnerHtmlPreProc start=+<!--#+ end=+-->+ contains=phpInnerHtmlPreStmt,phpInnerHtmlPreError,phpInnerHtmlPreAttr
+ syn match phpInnerHtmlPreStmt contained "<!--#\(config\|echo\|exec\|fsize\|flastmod\|include\|printenv\|set\|if\|elif\|else\|endif\|geoguide\)\>"
+ syn match phpInnerHtmlPreError contained "<!--#\S*"ms=s+4
+ syn match phpInnerHtmlPreAttr contained "\w\+=[^"]\S\+" contains=phpInnerHtmlPreProcAttrError,phpInnerHtmlPreProcAttrName
+ syn region phpInnerHtmlPreAttr contained start=+\w\+="+ skip=+\\\\\|\\"+ end=+"+ contains=phpInnerHtmlPreProcAttrName keepend
+ syn match phpInnerHtmlPreProcAttrError contained "\w\+="he=e-1
+ syn match phpInnerHtmlPreProcAttrName contained "\(expr\|errmsg\|sizefmt\|timefmt\|var\|cgi\|cmd\|file\|virtual\|value\)="he=e-1
+
+ if !exists("html_no_rendering")
+ " rendering
+ syn cluster phpInnerHtmlTop contains=@Spell,phpInnerHtmlTag,phpInnerHtmlEndTag,phpInnerHtmlSpecialChar,phpInnerHtmlPreProc,phpInnerHtmlComment,phpInnerHtmlLink,javaScript,@phpInnerHtmlPreproc
+
+ syn region phpInnerHtmlStrike start="<del\>" end="</del\_s*>"me=s-1 contains=@phpInnerHtmlTop
+ syn region phpInnerHtmlStrike start="<strike\>" end="</strike\_s*>"me=s-1 contains=@phpInnerHtmlTop
+
+ syn region phpInnerHtmlBold start="<b\>" end="</b\_s*>"me=s-1 contains=@phpInnerHtmlTop,phpInnerHtmlBoldUnderline,phpInnerHtmlBoldItalic
+ syn region phpInnerHtmlBold start="<strong\>" end="</strong\_s*>"me=s-1 contains=@phpInnerHtmlTop,phpInnerHtmlBoldUnderline,phpInnerHtmlBoldItalic
+ syn region phpInnerHtmlBoldUnderline contained start="<u\>" end="</u\_s*>"me=s-1 contains=@phpInnerHtmlTop,phpInnerHtmlBoldUnderlineItalic
+ syn region phpInnerHtmlBoldItalic contained start="<i\>" end="</i\_s*>"me=s-1 contains=@phpInnerHtmlTop,phpInnerHtmlBoldItalicUnderline
+ syn region phpInnerHtmlBoldItalic contained start="<em\>" end="</em\_s*>"me=s-1 contains=@phpInnerHtmlTop,phpInnerHtmlBoldItalicUnderline
+ syn region phpInnerHtmlBoldUnderlineItalic contained start="<i\>" end="</i\_s*>"me=s-1 contains=@phpInnerHtmlTop
+ syn region phpInnerHtmlBoldUnderlineItalic contained start="<em\>" end="</em\_s*>"me=s-1 contains=@phpInnerHtmlTop
+ syn region phpInnerHtmlBoldItalicUnderline contained start="<u\>" end="</u\_s*>"me=s-1 contains=@phpInnerHtmlTop,phpInnerHtmlBoldUnderlineItalic
+
+ syn region phpInnerHtmlUnderline start="<u\>" end="</u\_s*>"me=s-1 contains=@phpInnerHtmlTop,phpInnerHtmlUnderlineBold,phpInnerHtmlUnderlineItalic
+ syn region phpInnerHtmlUnderlineBold contained start="<b\>" end="</b\_s*>"me=s-1 contains=@phpInnerHtmlTop,phpInnerHtmlUnderlineBoldItalic
+ syn region phpInnerHtmlUnderlineBold contained start="<strong\>" end="</strong\_s*>"me=s-1 contains=@phpInnerHtmlTop,phpInnerHtmlUnderlineBoldItalic
+ syn region phpInnerHtmlUnderlineItalic contained start="<i\>" end="</i\_s*>"me=s-1 contains=@phpInnerHtmlTop,phpInnerHtmlUnderlineItalicBold
+ syn region phpInnerHtmlUnderlineItalic contained start="<em\>" end="</em\_s*>"me=s-1 contains=@phpInnerHtmlTop,phpInnerHtmlUnderlineItalicBold
+ syn region phpInnerHtmlUnderlineItalicBold contained start="<b\>" end="</b\_s*>"me=s-1 contains=@phpInnerHtmlTop
+ syn region phpInnerHtmlUnderlineItalicBold contained start="<strong\>" end="</strong\_s*>"me=s-1 contains=@phpInnerHtmlTop
+ syn region phpInnerHtmlUnderlineBoldItalic contained start="<i\>" end="</i\_s*>"me=s-1 contains=@phpInnerHtmlTop
+ syn region phpInnerHtmlUnderlineBoldItalic contained start="<em\>" end="</em\_s*>"me=s-1 contains=@phpInnerHtmlTop
+
+ syn region phpInnerHtmlItalic start="<i\>" end="</i\_s*>"me=s-1 contains=@phpInnerHtmlTop,phpInnerHtmlItalicBold,phpInnerHtmlItalicUnderline
+ syn region phpInnerHtmlItalic start="<em\>" end="</em\_s*>"me=s-1 contains=@phpInnerHtmlTop
+ syn region phpInnerHtmlItalicBold contained start="<b\>" end="</b\_s*>"me=s-1 contains=@phpInnerHtmlTop,phpInnerHtmlItalicBoldUnderline
+ syn region phpInnerHtmlItalicBold contained start="<strong\>" end="</strong\_s*>"me=s-1 contains=@phpInnerHtmlTop,phpInnerHtmlItalicBoldUnderline
+ syn region phpInnerHtmlItalicBoldUnderline contained start="<u\>" end="</u\_s*>"me=s-1 contains=@phpInnerHtmlTop
+ syn region phpInnerHtmlItalicUnderline contained start="<u\>" end="</u\_s*>"me=s-1 contains=@phpInnerHtmlTop,phpInnerHtmlItalicUnderlineBold
+ syn region phpInnerHtmlItalicUnderlineBold contained start="<b\>" end="</b\_s*>"me=s-1 contains=@phpInnerHtmlTop
+ syn region phpInnerHtmlItalicUnderlineBold contained start="<strong\>" end="</strong\_s*>"me=s-1 contains=@phpInnerHtmlTop
+
+ syn match phpInnerHtmlLeadingSpace "^\s\+" contained
+ syn region phpInnerHtmlLink start="<a\>\_[^>]*\<href\>" end="</a\_s*>"me=s-1 contains=@Spell,phpInnerHtmlTag,phpInnerHtmlEndTag,phpInnerHtmlSpecialChar,phpInnerHtmlPreProc,phpInnerHtmlComment,phpInnerHtmlLeadingSpace,phpInnerJavaScript,@phpInnerHtmlPreproc
+ syn region phpInnerHtmlH1 start="<h1\>" end="</h1\_s*>"me=s-1 contains=@phpInnerHtmlTop
+ syn region phpInnerHtmlH2 start="<h2\>" end="</h2\_s*>"me=s-1 contains=@phpInnerHtmlTop
+ syn region phpInnerHtmlH3 start="<h3\>" end="</h3\_s*>"me=s-1 contains=@phpInnerHtmlTop
+ syn region phpInnerHtmlH4 start="<h4\>" end="</h4\_s*>"me=s-1 contains=@phpInnerHtmlTop
+ syn region phpInnerHtmlH5 start="<h5\>" end="</h5\_s*>"me=s-1 contains=@phpInnerHtmlTop
+ syn region phpInnerHtmlH6 start="<h6\>" end="</h6\_s*>"me=s-1 contains=@phpInnerHtmlTop
+ syn region phpInnerHtmlHead start="<head\>" end="</head\_s*>"me=s-1 end="<body\>"me=s-1 end="<h[1-6]\>"me=s-1 contains=phpInnerHtmlTag,phpInnerHtmlEndTag,phpInnerHtmlSpecialChar,phpInnerHtmlPreProc,phpInnerHtmlComment,phpInnerHtmlLink,phpInnerHtmlTitle,phpInnerJavaScript,phpInnerCssStyle,@phpInnerHtmlPreproc
+ syn region phpInnerHtmlTitle start="<title\>" end="</title\_s*>"me=s-1 contains=phpInnerHtmlTag,phpInnerHtmlEndTag,phpInnerHtmlSpecialChar,phpInnerHtmlPreProc,phpInnerHtmlComment,phpInnerJavaScript,@phpInnerHtmlPreproc
+ endif
+
+ if main_syntax != 'java' || exists("javascript")
+ " JAVA SCRIPT
+ " For example, $phpVar = '<img onload="foo()" />';
+ syn include @phpInnerHtmlJavaScript syntax/javascript.vim
+ unlet b:current_syntax
+ syn region phpInnerHtmlScriptTag contained start=+<script+ end=+>+ fold contains=phpInnerHtmlTagN,phpInnerHtmlString,phpInnerHtmlArg,phpInnerHtmlValue,phpInnerHtmlTagError,phpInnerHtmlEvent
+ hi def link phpInnerHtmlScriptTag phpInnerHtmlTag
+
+ " phpInnerHtml events (i.e. arguments that include phpInnerJavascript commands)
+ if exists("html_extended_events")
+ syn region phpInnerHtmlEvent contained start=+\<on\a\+\s*=[\t ]*'+ end=+'+ contains=phpInnerHtmlEventSQ
+ syn region phpInnerHtmlEvent contained start=+\<on\a\+\s*=[\t ]*"+ end=+"+ contains=phpInnerHtmlEventDQ
+ else
+ syn region phpInnerHtmlEvent contained start=+\<on\a\+\s*=[\t ]*'+ end=+'+ keepend contains=phpInnerHtmlEventSQ
+ syn region phpInnerHtmlEvent contained start=+\<on\a\+\s*=[\t ]*"+ end=+"+ keepend contains=phpInnerHtmlEventDQ
+ endif
+ syn region phpInnerHtmlEventSQ contained start=+'+ms=s+1 end=+'+me=s-1 contains=@phpInnerHtmlJavaScript
+ syn region phpInnerHtmlEventDQ contained start=+"+ms=s+1 end=+"+me=s-1 contains=@phpInnerHtmlJavaScript
+ hi def link phpInnerHtmlEventSQ phpInnerHtmlEvent
+ hi def link phpInnerHtmlEventDQ phpInnerHtmlEvent
+
+ " a phpInnerJavascript expression is used as an arg value
+ " syn region phpInnerJavaScriptExpression contained start=+&{+ keepend end=+};+ contains=@phpInnerHtmlJavaScript,@phpInnerHtmlPreproc
+ endif
+
+ syn cluster phpInnerHtmlJavaScript add=@phpInnerHtmlPreproc
+
+ " The default highlighting.
+ " NOTE: For now, this deliberately copies the definitions from html rather than link
+ " to the corresponding html tag name. If html is refactored to rename any
+ " keywords then html highlighting would unexpectedly be cleared.
+ hi def link phpInnerHtmlTag Function
+ hi def link phpInnerHtmlEndTag Identifier
+ hi def link phpInnerHtmlArg Type
+ hi def link phpInnerHtmlValue String
+ hi def link phpInnerHtmlSpecialChar Special
+
+ if !exists("html_no_rendering")
+ hi def link phpInnerHtmlH1 Title
+ hi def link phpInnerHtmlH2 phpInnerHtmlH1
+ hi def link phpInnerHtmlH3 phpInnerHtmlH2
+ hi def link phpInnerHtmlH4 phpInnerHtmlH3
+ hi def link phpInnerHtmlH5 phpInnerHtmlH4
+ hi def link phpInnerHtmlH6 phpInnerHtmlH5
+ hi def link phpInnerHtmlHead PreProc
+ hi def link phpInnerHtmlTitle Title
+ hi def link phpInnerHtmlBoldItalicUnderline phpInnerHtmlBoldUnderlineItalic
+ hi def link phpInnerHtmlUnderlineBold phpInnerHtmlBoldUnderline
+ hi def link phpInnerHtmlUnderlineItalicBold phpInnerHtmlBoldUnderlineItalic
+ hi def link phpInnerHtmlUnderlineBoldItalic phpInnerHtmlBoldUnderlineItalic
+ hi def link phpInnerHtmlItalicUnderline phpInnerHtmlUnderlineItalic
+ hi def link phpInnerHtmlItalicBold phpInnerHtmlBoldItalic
+ hi def link phpInnerHtmlItalicBoldUnderline phpInnerHtmlBoldUnderlineItalic
+ hi def link phpInnerHtmlItalicUnderlineBold phpInnerHtmlBoldUnderlineItalic
+ hi def link phpInnerHtmlLink Underlined
+ hi def link phpInnerHtmlLeadingSpace None
+ if !exists("html_my_rendering")
+ hi def phpInnerHtmlBold term=bold cterm=bold gui=bold
+ hi def phpInnerHtmlBoldUnderline term=bold,underline cterm=bold,underline gui=bold,underline
+ hi def phpInnerHtmlBoldItalic term=bold,italic cterm=bold,italic gui=bold,italic
+ hi def phpInnerHtmlBoldUnderlineItalic term=bold,italic,underline cterm=bold,italic,underline gui=bold,italic,underline
+ hi def phpInnerHtmlUnderline term=underline cterm=underline gui=underline
+ hi def phpInnerHtmlUnderlineItalic term=italic,underline cterm=italic,underline gui=italic,underline
+ hi def phpInnerHtmlItalic term=italic cterm=italic gui=italic
+ if v:version > 800 || v:version == 800 && has("patch1038")
+ hi def phpInnerHtmlStrike term=strikethrough cterm=strikethrough gui=strikethrough
+ else
+ hi def phpInnerHtmlStrike term=underline cterm=underline gui=underline
+ endif
+ endif
+ endif
+
+ hi def link phpInnerHtmlPreStmt PreProc
+ hi def link phpInnerHtmlPreError Error
+ hi def link phpInnerHtmlPreProc PreProc
+ hi def link phpInnerHtmlPreAttr String
+ hi def link phpInnerHtmlPreProcAttrName PreProc
+ hi def link phpInnerHtmlPreProcAttrError Error
+ hi def link phpInnerHtmlString String
+ hi def link phpInnerHtmlStatement Statement
+ hi def link phpInnerHtmlComment Comment
+ hi def link phpInnerHtmlCommentNested phpInnerHtmlError
+ hi def link phpInnerHtmlCommentError phpInnerHtmlError
+ hi def link phpInnerHtmlTagError phpInnerHtmlError
+ hi def link phpInnerHtmlEvent phpInnerJavaScript
+ hi def link phpInnerHtmlError Error
+
+ hi def link phpInnerJavaScript Special
+ hi def link phpInnerJavaScriptExpression phpInnerJavaScript
+ hi def link phpInnerHtmlCssStyleComment Comment
+ hi def link phpInnerHtmlCssDefinition Special
+endif
+
+
runtime! syntax/html.vim
unlet b:current_syntax
@@ -79,6 +309,8 @@ if exists("php_parentError") && !exists("php_parent_error_open") && !exists("php
let php_parent_error_open=1
endif
+" End of copy of html syntax for embedding in php strings }}}
+
syn cluster htmlPreproc add=phpRegion,phpRegionAsp,phpRegionSc
syn include @sqlTop syntax/sql.vim
@@ -90,7 +322,11 @@ if exists( "php_sql_query")
endif
if exists( "php_htmlInStrings")
- syn cluster phpAddStrings add=@htmlTop
+ if php_htmlInStrings==2
+ syn cluster phpAddStrings add=@phpInnerHtmlTop
+ else
+ syn cluster phpAddStrings add=@htmlTop
+ endif
endif
" make sure we can use \ at the beginning of the line to do a continuation
@@ -283,7 +519,7 @@ syn keyword phpStatement return break continue exit goto yield contained
syn keyword phpKeyword var const contained
" Type
-syn keyword phpType void bool boolean int integer real double float string array object NULL callable iterable mixed contained
+syn keyword phpType void bool boolean int integer real double float string array object NULL callable iterable mixed never contained
" Structure
syn keyword phpStructure namespace extends implements instanceof parent self contained
@@ -361,7 +597,7 @@ syn match phpFloatError "\%([eE.][0-9._+-]*\.\|__\|_\(\>\|[eE]\)\|\(\>\|[eE]\)_\
" Number
syn match phpNumber "\%(\.\)\@<!\<\%([1-9]\d*\|0\|0[xX]\(\x_\?\)*\x\)\>\%(\.\)\@!" contained display
-syn match phpNumber "\%(\.\)\@<!\<0\d\+\>\%(\.\)\@!" contained contains=phpOctalError display
+syn match phpNumber "\%(\.\)\@<!\<0\d\+\|0[oO]\d\+\>\%(\.\)\@!" contained contains=phpOctalError display
syn match phpBinaryError "[2-9]" contained display
syn match phpNumber "\%(\.\)\@<!\<0[bB]\(\d_\?\)*\d\>\%(\.\)\@!" contained contains=phpBinaryError display
@@ -446,7 +682,7 @@ syn cluster phpClTop contains=@phpClFunction,phpFoldFunction,phpFoldClass,phpFol
" Php Region
if exists("php_parent_error_open")
if exists("php_noShortTags")
- syn region phpRegion matchgroup=Delimiter start="<?php" end="?>" contains=@phpClTop
+ syn region phpRegion matchgroup=Delimiter start="<?\(php\|=\)" end="?>" contains=@phpClTop
else
syn region phpRegion matchgroup=Delimiter start="<?\(php\)\=" end="?>" contains=@phpClTop
endif
@@ -456,7 +692,7 @@ if exists("php_parent_error_open")
endif
else
if exists("php_noShortTags")
- syn region phpRegion matchgroup=Delimiter start="<?php" end="?>" contains=@phpClTop keepend
+ syn region phpRegion matchgroup=Delimiter start="<?\(php\|=\)" end="?>" contains=@phpClTop keepend
else
syn region phpRegion matchgroup=Delimiter start="<?\(php\)\=" end="?>" contains=@phpClTop keepend
endif
@@ -469,13 +705,13 @@ endif
" Fold
if exists("php_folding") && php_folding==1
" match one line constructs here and skip them at folding
- syn keyword phpSCKeyword abstract final private protected public static contained
+ syn keyword phpSCKeyword abstract final private protected public static readonly contained
syn keyword phpFCKeyword function contained
syn keyword phpDefine fn contained
syn keyword phpStorageClass global contained
syn match phpDefine "\(\s\|^\)\(abstract\s\+\|final\s\+\|private\s\+\|protected\s\+\|public\s\+\|static\s\+\)*function\(\s\+.*[;}]\)\@=" contained contains=phpSCKeyword
syn match phpStructure "\(\s\|^\)\(abstract\s\+\|final\s\+\)*\(trait\|class\)\(\s\+.*}\)\@=" contained
- syn match phpStructure "\(\s\|^\)interface\(\s\+.*}\)\@=" contained
+ syn match phpStructure "\(\s\|^\)\(interface\|enum\)\(\s\+.*}\)\@=" contained
syn match phpException "\(\s\|^\)try\(\s\+.*}\)\@=" contained
syn match phpException "\(\s\|^\)catch\(\s\+.*}\)\@=" contained
syn match phpException "\(\s\|^\)finally\(\s\+.*}\)\@=" contained
@@ -484,15 +720,15 @@ if exists("php_folding") && php_folding==1
syn region phpFoldHtmlInside matchgroup=Delimiter start="?>" end="<?\(php\)\=" contained transparent contains=@htmlTop
syn region phpFoldFunction matchgroup=Storageclass start="^\z(\s*\)\(abstract\s\+\|final\s\+\|private\s\+\|protected\s\+\|public\s\+\|static\s\+\)*function\s\([^};]*$\)\@="rs=e-9 matchgroup=Delimiter end="^\z1}" contains=@phpClFunction,phpFoldHtmlInside,phpFCKeyword contained transparent fold extend
syn region phpFoldFunction matchgroup=Define start="^function\s\([^};]*$\)\@=" matchgroup=Delimiter end="^}" contains=@phpClFunction,phpFoldHtmlInside contained transparent fold extend
- syn region phpFoldClass matchgroup=Structure start="^\z(\s*\)\(abstract\s\+\|final\s\+\)*\(trait\|class\)\s\+\([^}]*$\)\@=" matchgroup=Delimiter end="^\z1}" contains=@phpClFunction,phpFoldFunction,phpSCKeyword contained transparent fold extend
+ syn region phpFoldClass matchgroup=Structure start="^\z(\s*\)\(abstract\s\+\|final\s\+\)*\(trait\|class\|enum\)\s\+\([^}]*$\)\@=" matchgroup=Delimiter end="^\z1}" contains=@phpClFunction,phpFoldFunction,phpSCKeyword contained transparent fold extend
syn region phpFoldInterface matchgroup=Structure start="^\z(\s*\)interface\s\+\([^}]*$\)\@=" matchgroup=Delimiter end="^\z1}" contains=@phpClFunction,phpFoldFunction contained transparent fold extend
syn region phpFoldCatch matchgroup=Exception start="^\z(\s*\)catch\s\+\([^}]*$\)\@=" matchgroup=Delimiter end="^\z1}" contains=@phpClFunction,phpFoldFunction contained transparent fold extend
syn region phpFoldTry matchgroup=Exception start="^\z(\s*\)try\s\+\([^}]*$\)\@=" matchgroup=Delimiter end="^\z1}" contains=@phpClFunction,phpFoldFunction contained transparent fold extend
else
syn keyword phpDefine function fn contained
- syn keyword phpStructure abstract class trait interface contained
+ syn keyword phpStructure abstract class trait interface enum contained
syn keyword phpException catch throw try finally contained
- syn keyword phpStorageClass final global private protected public static contained
+ syn keyword phpStorageClass final global private protected public static readonly contained
if exists("php_folding") && php_folding==2
setlocal foldmethod=syntax
syn region phpFoldHtmlInside matchgroup=Delimiter start="?>" end="<?\(php\)\=" contained transparent contains=@htmlTop
@@ -512,9 +748,9 @@ syntax keyword phpStructure list contained
syntax keyword phpConditional switch contained
syntax keyword phpStatement die contained
-" Highlighting for PHP5's user-definable magic class methods
+" Highlighting for PHP's user-definable magic class methods
syntax keyword phpSpecialFunction containedin=ALLBUT,phpComment,phpStringDouble,phpStringSingle,phpIdentifier
- \ __construct __destruct __call __callStatic __get __set __isset __unset __sleep __wakeup __toString __invoke __set_state __clone __debugInfo
+ \ __construct __destruct __call __callStatic __get __set __isset __unset __sleep __wakeup __toString __invoke __set_state __clone __debugInfo __serialize __unserialize
" Highlighting for __autoload slightly different from line above
syntax keyword phpSpecialFunction containedin=ALLBUT,phpComment,phpStringDouble,phpStringSingle,phpIdentifier,phpMethodsVar
\ __autoload
@@ -638,7 +874,7 @@ endif
" Sync
if php_sync_method==-1
if exists("php_noShortTags")
- syn sync match phpRegionSync grouphere phpRegion "^\s*<?php\s*$"
+ syn sync match phpRegionSync grouphere phpRegion "^\s*<?\(php\|=\)\s*$"
else
syn sync match phpRegionSync grouphere phpRegion "^\s*<?\(php\)\=\s*$"
endif
@@ -658,7 +894,7 @@ endif
syntax match phpDocCustomTags "@[a-zA-Z]*\(\s\+\|\n\|\r\)" containedin=phpComment
syntax region phpDocTags start="{@\(example\|id\|internal\|inheritdoc\|link\|source\|toc\|tutorial\)" end="}" containedin=phpComment
-syntax match phpDocTags "@\(abstract\|access\|author\|category\|copyright\|deprecated\|example\|final\|global\|ignore\|internal\|license\|link\|method\|name\|package\|param\|property\|return\|see\|since\|static\|staticvar\|subpackage\|tutorial\|uses\|var\|version\|contributor\|modified\|filename\|description\|filesource\|throws\)\(\s\+\)\?" containedin=phpComment
+syntax match phpDocTags "@\(abstract\|access\|api\|author\|category\|copyright\|deprecated\|example\|final\|global\|ignore\|internal\|license\|link\|method\|name\|package\|param\|property\(-write\|-read\)\?\|return\|see\|since\|source\|static\|staticvar\|subpackage\|tutorial\|uses\|used-by\|var\|version\|contributor\|modified\|filename\|description\|filesource\|throws\)\(\s\+\)\?" containedin=phpComment
syntax match phpDocTodo "@\(todo\|fixme\|xxx\)\(\s\+\)\?" containedin=phpComment
" Define the default highlighting.
@@ -729,7 +965,6 @@ else
hi def link phpIdentifierSimply Identifier
endif
-
let b:current_syntax = "php"
if main_syntax == 'php'
diff --git a/runtime/syntax/sml.vim b/runtime/syntax/sml.vim
index afff5304e6..53ff12a859 100644
--- a/runtime/syntax/sml.vim
+++ b/runtime/syntax/sml.vim
@@ -3,19 +3,18 @@
" Filenames: *.sml *.sig
" Maintainers: Markus Mottl <markus.mottl@gmail.com>
" Fabrizio Zeno Cornelli <zeno@filibusta.crema.unimi.it>
-" Last Change: 2019 Oct 01 - Only spell check strings & comments (Chuan Wei Foo)
+" Last Change: 2021 Oct 04
" 2015 Aug 31 - Fixed opening of modules (Ramana Kumar)
" 2006 Oct 23 - Fixed character highlighting bug (MM)
" quit when a syntax file was already loaded
if exists("b:current_syntax")
+ finish
+endif
" Disable spell checking of syntax.
syn spell notoplevel
- finish
-endif
-
" SML is case sensitive.
syn case match
diff --git a/runtime/syntax/tcl.vim b/runtime/syntax/tcl.vim
index 64efd6fec4..73b2b3fa11 100644
--- a/runtime/syntax/tcl.vim
+++ b/runtime/syntax/tcl.vim
@@ -6,9 +6,9 @@
" (previously Matt Neumann <mattneu@purpleturtle.com>)
" (previously Allan Kelly <allan@fruitloaf.co.uk>)
" Original: Robin Becker <robin@jessikat.demon.co.uk>
-" Last Change: 2014-02-12
+" Last Change: 2021 Oct 03
" Version: 1.14
-" URL: http://bitbucket.org/taylor_venable/metasyntax/src/tip/Config/vim/syntax/tcl.vim
+" URL: (removed, no longer worked)
" quit when a syntax file was already loaded
if exists("b:current_syntax")
diff --git a/runtime/syntax/tcsh.vim b/runtime/syntax/tcsh.vim
index b535d11df8..6837125129 100644
--- a/runtime/syntax/tcsh.vim
+++ b/runtime/syntax/tcsh.vim
@@ -1,7 +1,9 @@
-" tcsh.vim: Vim syntax file for tcsh scripts
-" Maintainer: Gautam Iyer <gi1242@gmail.com>
-" Modified: Thu 17 Dec 2009 06:05:07 PM EST
-"
+" Vim syntax file
+" Language: tcsh scripts
+" Maintainer: Doug Kearns <dougkearns@gmail.com>
+" Previous Maintainer: Gautam Iyer <gi1242+vim@NoSpam.com> where NoSpam=gmail (Original Author)
+" Last Change: 2021 Oct 15
+
" Description: We break up each statement into a "command" and an "end" part.
" All groups are either a "command" or part of the "end" of a statement (ie
" everything after the "command"). This is because blindly highlighting tcsh
@@ -19,36 +21,36 @@ endif
let s:oldcpo = &cpo
set cpo&vim " Line continuation is used
-setlocal iskeyword+=-
+syn iskeyword @,48-57,_,192-255,-
syn case match
-" ----- Clusters -----
+" ----- Clusters ----- {{{1
syn cluster tcshModifiers contains=tcshModifier,tcshModifierError
syn cluster tcshQuoteList contains=tcshDQuote,tcshSQuote,tcshBQuote
-syn cluster tcshStatementEnds contains=@tcshQuoteList,tcshComment,@tcshVarList,tcshRedir,tcshMeta,tcshHereDoc,tcshSpecial,tcshArguement
+syn cluster tcshStatementEnds contains=@tcshQuoteList,tcshComment,@tcshVarList,tcshRedir,tcshMeta,tcshHereDoc,tcshSpecial,tcshArgument
syn cluster tcshStatements contains=tcshBuiltin,tcshCommands,tcshIf,tcshWhile
syn cluster tcshVarList contains=tcshUsrVar,tcshArgv,tcshSubst
syn cluster tcshConditions contains=tcshCmdSubst,tcshParenExpr,tcshOperator,tcshNumber,@tcshVarList
-" ----- Errors -----
+" ----- Errors ----- {{{1
" Define first, so can be easily overridden.
syn match tcshError contained '\v\S.+'
-" ----- Statements -----
+" ----- Statements ----- {{{1
" Tcsh commands: Any filename / modifiable variable (must be first!)
syn match tcshCommands '\v[a-zA-Z0-9\\./_$:-]+' contains=tcshSpecial,tcshUsrVar,tcshArgv,tcshVarError nextgroup=tcshStatementEnd
" Builtin commands except those treated specially. Currently (un)set(env),
" (un)alias, if, while, else, bindkey
-syn keyword tcshBuiltin nextgroup=tcshStatementEnd alloc bg break breaksw builtins bye case cd chdir complete continue default dirs echo echotc end endif endsw eval exec exit fg filetest foreach getspath getxvers glob goto hashstat history hup inlib jobs kill limit log login logout ls ls-F migrate newgrp nice nohup notify onintr popd printenv pushd rehash repeat rootnode sched setpath setspath settc setty setxvers shift source stop suspend switch telltc time umask uncomplete unhash universe unlimit ver wait warp watchlog where which
+syn keyword tcshBuiltin nextgroup=tcshStatementEnd alloc bg break breaksw builtins bye case cd chdir complete continue default dirs echo echotc end endif endsw eval exec exit fg filetest foreach getspath getxvers glob goto hashstat history hup inlib jobs kill limit log login logout ls ls-F migrate newgrp nice nohup notify onintr popd printenv pushd rehash repeat rootnode sched setpath setspath settc setty setxvers shift source stop suspend switch telltc termname time umask uncomplete unhash universe unlimit ver wait warp watchlog where which
" StatementEnd is anything after a built-in / command till the lexical end of a
" statement (;, |, ||, |&, && or end of line)
syn region tcshStatementEnd transparent contained matchgroup=tcshBuiltin start='' end='\v\\@<!(;|\|[|&]?|\&\&|$)' contains=@tcshStatementEnds
" set expressions (Contains shell variables)
-syn keyword tcshShellVar contained afsuser ampm argv autocorrect autoexpand autolist autologout backslash_quote catalog cdpath color colorcat command complete continue continue_args correct cwd dextract dirsfile dirstack dspmbyte dunique echo echo_style edit ellipsis fignore filec gid group histchars histdup histfile histlit history home ignoreeof implicitcd inputmode killdup killring listflags listjobs listlinks listmax listmaxrows loginsh logout mail matchbeep nobeep noclobber noding noglob nokanji nonomatch nostat notify oid owd path printexitvalue prompt prompt2 prompt3 promptchars pushdtohome pushdsilent recexact recognize_only_executables rmstar rprompt savedirs savehist sched shell shlvl status symlinks tcsh term time tperiod tty uid user verbose version visiblebell watch who wordchars
+syn keyword tcshShellVar contained addsuffix afsuser ampm anyerror argv autocorrect autoexpand autolist autologout autorehash backslash_quote catalog cdpath cdtohome color colorcat command compat_expr complete continue continue_args correct csubstnonl cwd dextract dirsfile dirstack dspmbyte dunique echo echo_style edit editors ellipsis euid euser fignore filec gid globdot globstar group highlight histchars histdup histfile histlit history home ignoreeof implicitcd inputmode killdup killring listflags listjobs listlinks listmax listmaxrows loginsh logout mail matchbeep nobeep noclobber noding noglob nokanji nonomatch nostat notify oid owd padhour parseoctal path printexitvalue prompt prompt2 prompt3 promptchars pushdtohome pushdsilent recexact recognize_only_executables rmstar rprompt savedirs savehist sched shell shlvl status symlinks tcsh term time tperiod tty uid user verbose version vimode visiblebell watch who wordchars
syn keyword tcshBuiltin nextgroup=tcshSetEnd set unset
syn region tcshSetEnd contained transparent matchgroup=tcshBuiltin start='' skip='\\$' end='$\|;' contains=tcshShellVar,@tcshStatementEnds
@@ -95,14 +97,15 @@ syn keyword tcshBindkeyFuncs contained backward-char backward-delete-char
\ history-search-forward insert-last-word i-search-fwd
\ i-search-back keyboard-quit kill-line kill-region
\ kill-whole-line list-choices list-choices-raw list-glob
- \ list-or-eof load-average magic-space newline normalize-path
- \ normalize-command overwrite-mode prefix-meta quoted-insert
- \ redisplay run-fg-editor run-help self-insert-command
- \ sequence-lead-in set-mark-command spell-word spell-line
- \ stuff-char toggle-literal-history transpose-chars
- \ transpose-gosling tty-dsusp tty-flush-output tty-sigintr
- \ tty-sigquit tty-sigtsusp tty-start-output tty-stop-output
- \ undefined-key universal-argument up-history upcase-word
+ \ list-or-eof load-average magic-space newline newline-and-hold
+ \ newline-and-down-history normalize-path normalize-command
+ \ overwrite-mode prefix-meta quoted-insert redisplay
+ \ run-fg-editor run-help self-insert-command sequence-lead-in
+ \ set-mark-command spell-word spell-line stuff-char
+ \ toggle-literal-history transpose-chars transpose-gosling
+ \ tty-dsusp tty-flush-output tty-sigintr tty-sigquit tty-sigtsusp
+ \ tty-start-output tty-stop-output undefined-key
+ \ universal-argument up-history upcase-word
\ vi-beginning-of-next-word vi-add vi-add-at-eol vi-chg-case
\ vi-chg-meta vi-chg-to-eol vi-cmd-mode vi-cmd-mode-complete
\ vi-delprev vi-delmeta vi-endword vi-eword vi-char-back
@@ -115,7 +118,7 @@ syn keyword tcshBindkeyFuncs contained backward-char backward-delete-char
\ e_paste_from_clipboard e_dosify_next e_dosify_prev e_page_up
\ e_page_down
syn keyword tcshBuiltin nextgroup=tcshBindkeyEnd bindkey
-syn region tcshBindkeyEnd contained transparent matchgroup=tcshBuiltin start='' skip='\\$' end='$' contains=@tcshQuoteList,tcshComment,@tcshVarList,tcshMeta,tcshSpecial,tcshArguement,tcshBindkeyFuncs
+syn region tcshBindkeyEnd contained transparent matchgroup=tcshBuiltin start='' skip='\\$' end='$' contains=@tcshQuoteList,tcshComment,@tcshVarList,tcshMeta,tcshSpecial,tcshArgument,tcshBindkeyFuncs
" Expressions start with @.
syn match tcshExprStart '\v\@\s+' nextgroup=tcshExprVar
@@ -125,20 +128,20 @@ syn match tcshExprOp contained '\v\s*\=' nextgroup=tcshExprEnd
syn match tcshExprEnd contained '\v.*$'hs=e+1 contains=@tcshConditions
syn match tcshExprEnd contained '\v.{-};'hs=e contains=@tcshConditions
-" ----- Comments: -----
+" ----- Comments: ----- {{{1
syn match tcshComment '#\s.*' contains=tcshTodo,tcshCommentTi,@Spell
syn match tcshComment '\v#($|\S.*)' contains=tcshTodo,tcshCommentTi
syn match tcshSharpBang '^#! .*$'
syn match tcshCommentTi contained '\v#\s*\u\w*(\s+\u\w*)*:'hs=s+1 contains=tcshTodo
syn match tcshTodo contained '\v\c<todo>'
-" ----- Strings -----
+" ----- Strings ----- {{{1
" Tcsh does not allow \" in strings unless the "backslash_quote" shell
" variable is set. Set the vim variable "tcsh_backslash_quote" to 0 if you
" want VIM to assume that no backslash quote constructs exist.
" Backquotes are treated as commands, and are not contained in anything
-if(exists('tcsh_backslash_quote') && tcsh_backslash_quote == 0)
+if exists('tcsh_backslash_quote') && tcsh_backslash_quote == 0
syn region tcshSQuote keepend contained start="\v\\@<!'" end="'"
syn region tcshDQuote keepend contained start='\v\\@<!"' end='"' contains=@tcshVarList,tcshSpecial,@Spell
syn region tcshBQuote keepend start='\v\\@<!`' end='`' contains=@tcshStatements
@@ -148,7 +151,7 @@ else
syn region tcshBQuote keepend matchgroup=tcshBQuoteGrp start='\v\\@<!`' skip='\v\\\\|\\`' end='`' contains=@tcshStatements
endif
-" ----- Variables -----
+" ----- Variables ----- {{{1
" Variable Errors. Must come first! \$ constructs will be flagged by
" tcshSpecial, so we don't consider them here.
syn match tcshVarError '\v\$\S*' contained
@@ -170,7 +173,7 @@ syn match tcshSubst contained '\v\$\{[%#?]%(\h\w*|\d+)%(:\S*)?\}' contains=tcshM
syn match tcshModifierError contained '\v:\S*'
syn match tcshModifier contained '\v:[ag]?[htreuls&qx]' nextgroup=@tcshModifiers
-" ----- Operators / Specials -----
+" ----- Operators / Specials ----- {{{1
" Standard redirects (except <<) [<, >, >>, >>&, >>!, >>&!]
syn match tcshRedir contained '\v\<|\>\>?\&?!?'
@@ -189,13 +192,13 @@ syn match tcshOperator contained '&&\|!\~\|!=\|<<\|<=\|==\|=\~\|>=\|>>\|\*\|\^\|
syn match tcshNumber contained '\v<-?\d+>'
" Arguments
-syn match tcshArguement contained '\v\s@<=-(\w|-)*'
+syn match tcshArgument contained '\v\s@<=-(\w|-)*'
" Special characters. \xxx, or backslashed characters.
"syn match tcshSpecial contained '\v\\@<!\\(\d{3}|.)'
syn match tcshSpecial contained '\v\\%([0-7]{3}|.)'
-" ----- Synchronising -----
+" ----- Synchronising ----- {{{1
if exists('tcsh_minlines')
if tcsh_minlines == 'fromstart'
syn sync fromstart
@@ -206,6 +209,7 @@ else
syn sync minlines=100 " Some completions can be quite long
endif
+" ----- Highlighting ----- {{{1
" Define highlighting of syntax groups
hi def link tcshError Error
hi def link tcshBuiltin Statement
@@ -232,17 +236,20 @@ hi def link tcshVarError Error
hi def link tcshUsrVar Type
hi def link tcshArgv tcshUsrVar
hi def link tcshSubst tcshUsrVar
-hi def link tcshModifier tcshArguement
+hi def link tcshModifier tcshArgument
hi def link tcshModifierError tcshVarError
hi def link tcshMeta tcshSubst
hi def link tcshRedir tcshOperator
hi def link tcshHereDoc tcshSQuote
hi def link tcshOperator Operator
hi def link tcshNumber Number
-hi def link tcshArguement Special
+hi def link tcshArgument Special
hi def link tcshSpecial SpecialChar
+" }}}
let &cpo = s:oldcpo
unlet s:oldcpo
let b:current_syntax = 'tcsh'
+
+" vim: nowrap sw=2 sts=2 ts=8 noet fdm=marker:
diff --git a/runtime/syntax/tmux.vim b/runtime/syntax/tmux.vim
index 4f435ab923..867c033cb5 100644
--- a/runtime/syntax/tmux.vim
+++ b/runtime/syntax/tmux.vim
@@ -1,5 +1,5 @@
" Language: tmux(1) configuration file
-" Version: 3.0 (git-48cbbb87)
+" Version: 3.2a (git-44ada9cd)
" URL: https://github.com/ericpruitt/tmux.vim/
" Maintainer: Eric Pruitt <eric.pruitt@gmail.com>
" License: 2-Clause BSD (http://opensource.org/licenses/BSD-2-Clause)
@@ -30,14 +30,14 @@ syn match tmuxVariable /\w\+=/ display
syn match tmuxVariableExpansion /\${\=\w\+}\=/ display
syn match tmuxControl /%\(if\|elif\|else\|endif\)/
-syn region tmuxComment start=/#/ skip=/\\\@<!\\$/ end=/$/ contains=tmuxTodo
+syn region tmuxComment start=/#/ skip=/\\\@<!\\$/ end=/$/ contains=tmuxTodo,@Spell
-syn region tmuxString start=+"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=tmuxFormatString
-syn region tmuxString start=+'+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end='$' contains=tmuxFormatString
+syn region tmuxString start=+"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=tmuxFormatString,@Spell
+syn region tmuxString start=+'+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end='$' contains=tmuxFormatString,@Spell
" TODO: Figure out how escaping works inside of #(...) and #{...} blocks.
syn region tmuxFormatString start=/#[#DFhHIPSTW]/ end=// contained keepend
-syn region tmuxFormatString start=/#{/ skip=/#{.\{-}}/ end=/}/ contained keepend
+syn region tmuxFormatString start=/#{/ skip=/#{.\{-}}/ end=/}/ keepend
syn region tmuxFormatString start=/#(/ skip=/#(.\{-})/ end=/)/ contained keepend
hi def link tmuxFormatString Identifier
@@ -55,62 +55,69 @@ hi def link tmuxTodo Todo
hi def link tmuxVariable Identifier
hi def link tmuxVariableExpansion Identifier
-" Make the foreground of colourXXX keywords match the color they represent.
+" Make the foreground of colourXXX keywords match the color they represent
+" when g:tmux_syntax_colors is unset or set to a non-zero value.
" Darker colors have their background set to white.
-for s:i in range(0, 255)
- let s:bg = (!s:i || s:i == 16 || (s:i > 231 && s:i < 235)) ? 15 : "none"
- exec "syn match tmuxColour" . s:i . " /\\<colour" . s:i . "\\>/ display"
-\ " | highlight tmuxColour" . s:i . " ctermfg=" . s:i . " ctermbg=" . s:bg
-endfor
+if get(g:, "tmux_syntax_colors", 1)
+ for s:i in range(0, 255)
+ let s:bg = (!s:i || s:i == 16 || (s:i > 231 && s:i < 235)) ? 15 : "none"
+ exec "syn match tmuxColour" . s:i . " /\\<colour" . s:i . "\\>/ display"
+\ " | highlight tmuxColour" . s:i . " ctermfg=" . s:i . " ctermbg=" . s:bg
+ endfor
+endif
syn keyword tmuxOptions
-\ backspace buffer-limit command-alias default-terminal escape-time
-\ exit-empty activity-action assume-paste-time base-index bell-action
-\ default-command default-shell default-size destroy-unattached
+\ backspace buffer-limit command-alias copy-command default-terminal editor
+\ escape-time exit-empty activity-action assume-paste-time base-index
+\ bell-action default-command default-shell default-size destroy-unattached
\ detach-on-destroy display-panes-active-colour display-panes-colour
-\ display-panes-time display-time exit-unattached focus-events history-file
-\ history-limit key-table lock-after-time lock-command message-command-style
-\ message-limit message-style aggressive-resize allow-rename
-\ alternate-screen automatic-rename automatic-rename-format
-\ clock-mode-colour clock-mode-style main-pane-height main-pane-width
-\ mode-keys mode-style monitor-activity monitor-bell monitor-silence mouse
-\ other-pane-height other-pane-width pane-active-border-style
-\ pane-base-index pane-border-format pane-border-status pane-border-style
-\ prefix prefix2 remain-on-exit renumber-windows repeat-time set-clipboard
-\ set-titles set-titles-string silence-action status status-bg status-fg
-\ status-format status-interval status-justify status-keys status-left
-\ status-left-length status-left-style status-position status-right
-\ status-right-length status-right-style status-style synchronize-panes
-\ terminal-overrides update-environment user-keys visual-activity
-\ visual-bell visual-silence window-active-style window-size
-\ window-status-activity-style window-status-bell-style
+\ display-panes-time display-time exit-unattached extended-keys focus-events
+\ history-file history-limit key-table lock-after-time lock-command
+\ message-command-style message-limit message-style aggressive-resize
+\ allow-rename alternate-screen automatic-rename automatic-rename-format
+\ clock-mode-colour clock-mode-style copy-mode-current-match-style
+\ copy-mode-mark-style copy-mode-match-style main-pane-height
+\ main-pane-width mode-keys mode-style monitor-activity monitor-bell
+\ monitor-silence mouse other-pane-height other-pane-width
+\ pane-active-border-style pane-base-index pane-border-format
+\ pane-border-lines pane-border-status pane-border-style pane-colours prefix
+\ prefix2 prompt-history-limit remain-on-exit renumber-windows repeat-time
+\ set-clipboard set-titles set-titles-string silence-action status status-bg
+\ status-fg status-format status-interval status-justify status-keys
+\ status-left status-left-length status-left-style status-position
+\ status-right status-right-length status-right-style status-style
+\ synchronize-panes terminal-features terminal-overrides update-environment
+\ user-keys visual-activity visual-bell visual-silence window-active-style
+\ window-size window-status-activity-style window-status-bell-style
\ window-status-current-format window-status-current-style
\ window-status-format window-status-last-style window-status-separator
-\ window-status-style window-style word-separators wrap-search xterm-keys
+\ window-status-style window-style word-separators wrap-search
syn keyword tmuxCommands
\ attach attach-session bind bind-key break-pane breakp capture-pane
\ capturep choose-buffer choose-client choose-tree clear-history clearhist
-\ clock-mode command-prompt confirm confirm-before copy-mode detach
-\ detach-client display display-menu display-message display-panes displayp
-\ find-window findw if if-shell join-pane joinp kill-pane kill-server
-\ kill-session kill-window killp has-session has killw link-window linkw
-\ list-buffers list-clients list-commands list-keys list-panes list-sessions
-\ list-windows load-buffer loadb lock lock-client lock-server lock-session
-\ lockc last-pane lastp locks ls last-window last lsb lsc delete-buffer
-\ deleteb lscm lsk lsp lsw menu move-pane move-window movep movew new
-\ new-session new-window neww next next-layout next-window nextl
-\ paste-buffer pasteb pipe-pane pipep prev previous-layout previous-window
-\ prevl refresh refresh-client rename rename-session rename-window renamew
-\ resize-pane resize-window resizep resizew respawn-pane respawn-window
-\ respawnp respawnw rotate-window rotatew run run-shell save-buffer saveb
+\ clock-mode command-prompt confirm confirm-before copy-mode customize-mode
+\ detach detach-client display display-menu display-message display-panes
+\ display-popup displayp find-window findw if if-shell join-pane joinp
+\ kill-pane kill-server kill-session kill-window killp has has-session killw
+\ link-window linkw list-buffers list-clients list-commands list-keys
+\ list-panes list-sessions list-windows load-buffer loadb lock lock-client
+\ lock-server lock-session lockc last-pane lastp locks ls last last-window
+\ lsb delete-buffer deleteb lsc lscm lsk lsp lsw menu move-pane move-window
+\ clear-prompt-history clearphist movep movew new new-session new-window
+\ neww next next-layout next-window nextl paste-buffer pasteb pipe-pane
+\ pipep popup prev previous-layout previous-window prevl refresh
+\ refresh-client rename rename-session rename-window renamew resize-pane
+\ resize-window resizep resizew respawn-pane respawn-window respawnp
+\ respawnw rotate-window rotatew run run-shell save-buffer saveb
\ select-layout select-pane select-window selectl selectp selectw send
\ send-keys send-prefix set set-buffer set-environment set-hook set-option
\ set-window-option setb setenv setw show show-buffer show-environment
-\ show-hooks show-messages show-options show-window-options showb showenv
-\ showmsgs showw source source-file split-window splitw start start-server
-\ suspend-client suspendc swap-pane swap-window swapp swapw switch-client
-\ switchc unbind unbind-key unlink-window unlinkw wait wait-for
+\ show-hooks show-messages show-options show-prompt-history
+\ show-window-options showb showenv showmsgs showphist showw source
+\ source-file split-window splitw start start-server suspend-client suspendc
+\ swap-pane swap-window swapp swapw switch-client switchc unbind unbind-key
+\ unlink-window unlinkw wait wait-for
let &cpo = s:original_cpo
unlet! s:original_cpo s:bg s:i
diff --git a/runtime/syntax/toml.vim b/runtime/syntax/toml.vim
new file mode 100644
index 0000000000..bcb1b0b9c9
--- /dev/null
+++ b/runtime/syntax/toml.vim
@@ -0,0 +1,81 @@
+" Vim syntax file
+" Language: TOML
+" Homepage: https://github.com/cespare/vim-toml
+" Maintainer: Aman Verma
+" Previous Maintainer: Caleb Spare <cespare@gmail.com>
+" Last Change: Oct 8, 2021
+
+if exists('b:current_syntax')
+ finish
+endif
+
+syn match tomlEscape /\\[btnfr"/\\]/ display contained
+syn match tomlEscape /\\u\x\{4}/ contained
+syn match tomlEscape /\\U\x\{8}/ contained
+syn match tomlLineEscape /\\$/ contained
+
+" Basic strings
+syn region tomlString oneline start=/"/ skip=/\\\\\|\\"/ end=/"/ contains=tomlEscape
+" Multi-line basic strings
+syn region tomlString start=/"""/ end=/"""/ contains=tomlEscape,tomlLineEscape
+" Literal strings
+syn region tomlString oneline start=/'/ end=/'/
+" Multi-line literal strings
+syn region tomlString start=/'''/ end=/'''/
+
+syn match tomlInteger /[+-]\=\<[1-9]\(_\=\d\)*\>/ display
+syn match tomlInteger /[+-]\=\<0\>/ display
+syn match tomlInteger /[+-]\=\<0x[[:xdigit:]]\(_\=[[:xdigit:]]\)*\>/ display
+syn match tomlInteger /[+-]\=\<0o[0-7]\(_\=[0-7]\)*\>/ display
+syn match tomlInteger /[+-]\=\<0b[01]\(_\=[01]\)*\>/ display
+syn match tomlInteger /[+-]\=\<\(inf\|nan\)\>/ display
+
+syn match tomlFloat /[+-]\=\<\d\(_\=\d\)*\.\d\+\>/ display
+syn match tomlFloat /[+-]\=\<\d\(_\=\d\)*\(\.\d\(_\=\d\)*\)\=[eE][+-]\=\d\(_\=\d\)*\>/ display
+
+syn match tomlBoolean /\<\%(true\|false\)\>/ display
+
+" https://tools.ietf.org/html/rfc3339
+syn match tomlDate /\d\{4\}-\d\{2\}-\d\{2\}/ display
+syn match tomlDate /\d\{2\}:\d\{2\}:\d\{2\}\%(\.\d\+\)\?/ display
+syn match tomlDate /\d\{4\}-\d\{2\}-\d\{2\}[T ]\d\{2\}:\d\{2\}:\d\{2\}\%(\.\d\+\)\?\%(Z\|[+-]\d\{2\}:\d\{2\}\)\?/ display
+
+syn match tomlDotInKey /\v[^.]+\zs\./ contained display
+syn match tomlKey /\v(^|[{,])\s*\zs[[:alnum:]._-]+\ze\s*\=/ contains=tomlDotInKey display
+syn region tomlKeyDq oneline start=/\v(^|[{,])\s*\zs"/ end=/"\ze\s*=/ contains=tomlEscape
+syn region tomlKeySq oneline start=/\v(^|[{,])\s*\zs'/ end=/'\ze\s*=/
+
+syn region tomlTable oneline start=/^\s*\[[^\[]/ end=/\]/ contains=tomlKey,tomlKeyDq,tomlKeySq,tomlDotInKey
+
+syn region tomlTableArray oneline start=/^\s*\[\[/ end=/\]\]/ contains=tomlKey,tomlKeyDq,tomlKeySq,tomlDotInKey
+
+syn region tomlKeyValueArray start=/=\s*\[\zs/ end=/\]/ contains=@tomlValue
+
+syn region tomlArray start=/\[/ end=/\]/ contains=@tomlValue contained
+
+syn cluster tomlValue contains=tomlArray,tomlString,tomlInteger,tomlFloat,tomlBoolean,tomlDate,tomlComment
+
+syn keyword tomlTodo TODO FIXME XXX BUG contained
+
+syn match tomlComment /#.*/ contains=@Spell,tomlTodo
+
+hi def link tomlComment Comment
+hi def link tomlTodo Todo
+hi def link tomlTableArray Title
+hi def link tomlTable Title
+hi def link tomlDotInKey Normal
+hi def link tomlKeySq Identifier
+hi def link tomlKeyDq Identifier
+hi def link tomlKey Identifier
+hi def link tomlDate Constant
+hi def link tomlBoolean Boolean
+hi def link tomlFloat Float
+hi def link tomlInteger Number
+hi def link tomlString String
+hi def link tomlLineEscape SpecialChar
+hi def link tomlEscape SpecialChar
+
+syn sync minlines=500
+let b:current_syntax = 'toml'
+
+" vim: et sw=2 sts=2
diff --git a/runtime/syntax/typescriptcommon.vim b/runtime/syntax/typescriptcommon.vim
index 4074f04a35..ef362fc721 100644
--- a/runtime/syntax/typescriptcommon.vim
+++ b/runtime/syntax/typescriptcommon.vim
@@ -1,7 +1,7 @@
" Vim syntax file
" Language: TypeScript and TypeScriptReact
" Maintainer: Bram Moolenaar, Herrington Darkholme
-" Last Change: 2020 Oct 27
+" Last Change: 2021 Sep 22
" Based On: Herrington Darkholme's yats.vim
" Changes: See https:github.com/HerringtonDarkholme/yats.vim
" Credits: See yats.vim on github
@@ -625,7 +625,8 @@ syntax keyword typescriptReadonlyArrayKeyword readonly
" extension
if get(g:, 'yats_host_keyword', 1)
syntax keyword typescriptGlobal containedin=typescriptIdentifierName Function Boolean
- syntax keyword typescriptGlobal containedin=typescriptIdentifierName Error EvalError
+ " use of nextgroup Suggested by Doug Kearns
+ syntax keyword typescriptGlobal containedin=typescriptIdentifierName Error EvalError nextgroup=typescriptFuncCallArg
syntax keyword typescriptGlobal containedin=typescriptIdentifierName InternalError
syntax keyword typescriptGlobal containedin=typescriptIdentifierName RangeError ReferenceError
syntax keyword typescriptGlobal containedin=typescriptIdentifierName StopIteration
diff --git a/runtime/syntax/xpm.vim b/runtime/syntax/xpm.vim
index 0667ca28ad..be9f38723e 100644
--- a/runtime/syntax/xpm.vim
+++ b/runtime/syntax/xpm.vim
@@ -1,19 +1,22 @@
" Vim syntax file
" Language: X Pixmap
" Maintainer: Ronald Schild <rs@scutum.de>
-" Last Change: 2017 Feb 01
+" Last Change: 2021 Oct 04
" Version: 5.4n.1
" Jemma Nelson added termguicolors support
+" Dominique Pellé fixed spelling support
" quit when a syntax file was already loaded
if exists("b:current_syntax")
finish
endif
+syn spell notoplevel
+
syn keyword xpmType char
syn keyword xpmStorageClass static
syn keyword xpmTodo TODO FIXME XXX contained
-syn region xpmComment start="/\*" end="\*/" contains=xpmTodo
+syn region xpmComment start="/\*" end="\*/" contains=xpmTodo,@Spell
syn region xpmPixelString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=@xpmColors
if has("gui_running") || has("termguicolors") && &termguicolors
diff --git a/scripts/finddeclarations.pl b/scripts/finddeclarations.pl
deleted file mode 100755
index 1b1a57b9b7..0000000000
--- a/scripts/finddeclarations.pl
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/perl
-
-use strict;
-use warnings;
-
-if ($ARGV[0] eq '--help') {
- print << "EOF";
-Usage:
-
- $0 definitions.c
-EOF
- exit;
-}
-
-my ($cfname, $sfname, $gfname, $cpp) = @ARGV;
-
-my $F;
-
-open $F, "<", $cfname;
-
-my $text = join "", <$F>;
-
-close $F;
-
-my $s = qr/(?>\s*)/aso;
-my $w = qr/(?>\w+)/aso;
-my $argname = qr/$w(?:\[(?>\w+)\])?/aso;
-my $type_regex = qr/(?:$w$s\**$s)+/aso;
-my $arg_regex = qr/(?:$type_regex$s$argname)/aso;
-
-while ($text =~ /
- (?<=\n) # Definition starts at the start of line
- $type_regex # Return type
- $s$w # Function name
- $s\($s
- (?:
- $arg_regex(?:$s,$s$arg_regex)*+
- ($s,$s\.\.\.)? # varargs function
- |void
- )?
- $s\)
- (?:$s FUNC_ATTR_$w(?:\((?>[^)]*)\))?)*+ # Optional attributes
- (?=$s;) # Ending semicolon
- /axsogp) {
- my $match = "${^MATCH}";
- my $s = "${^PREMATCH}";
- $s =~ s/[^\n]++//g;
- my $line = 1 + length $s;
- print "${cfname}:${line}: $match\n";
-}
diff --git a/scripts/gen_vimdoc.py b/scripts/gen_vimdoc.py
index 64ed8d61f6..7f4dccfd3c 100755
--- a/scripts/gen_vimdoc.py
+++ b/scripts/gen_vimdoc.py
@@ -91,6 +91,7 @@ CONFIG = {
'vim.c',
'buffer.c',
'window.c',
+ 'win_config.c',
'tabpage.c',
'ui.c',
],
@@ -123,11 +124,13 @@ CONFIG = {
'vim.lua',
'shared.lua',
'uri.lua',
+ 'ui.lua',
],
'files': ' '.join([
os.path.join(base_dir, 'src/nvim/lua/vim.lua'),
os.path.join(base_dir, 'runtime/lua/vim/shared.lua'),
os.path.join(base_dir, 'runtime/lua/vim/uri.lua'),
+ os.path.join(base_dir, 'runtime/lua/vim/ui.lua'),
]),
'file_patterns': '*.lua',
'fn_name_prefix': '',
@@ -141,6 +144,7 @@ CONFIG = {
# `shared` functions are exposed on the `vim` module.
'shared': 'vim',
'uri': 'vim',
+ 'ui': 'vim.ui',
},
'append_only': [
'shared.lua',
@@ -502,6 +506,11 @@ def render_node(n, text, prefix='', indent='', width=62):
text += indent + prefix + result
elif n.nodeName in ('para', 'heading'):
for c in n.childNodes:
+ if (is_inline(c)
+ and '' != get_text(c).strip()
+ and text
+ and ' ' != text[-1]):
+ text += ' '
text += render_node(c, text, indent=indent, width=width)
elif n.nodeName == 'itemizedlist':
for c in n.childNodes:
diff --git a/scripts/lintcommit.lua b/scripts/lintcommit.lua
index 11ad8eb9ef..c30a1b10da 100644
--- a/scripts/lintcommit.lua
+++ b/scripts/lintcommit.lua
@@ -91,7 +91,7 @@ local function validate_commit(commit_message)
-- Check that description doesn't end with a period
if vim.endswith(after_colon, ".") then
- return [[Description ends with a period (\".\").]]
+ return [[Description ends with a period (".").]]
end
-- Check that description has exactly one whitespace after colon, followed by
@@ -106,7 +106,7 @@ end
function M.main(opt)
_trace = not opt or not not opt.trace
- local branch = run({'git', 'branch', '--show-current'}, true)
+ local branch = run({'git', 'rev-parse', '--abbrev-ref', 'HEAD'}, true)
-- TODO(justinmk): check $GITHUB_REF
local ancestor = run({'git', 'merge-base', 'origin/master', branch})
if not ancestor then
diff --git a/scripts/pvscheck.sh b/scripts/pvscheck.sh
index aa27c94f29..195a76763f 100755
--- a/scripts/pvscheck.sh
+++ b/scripts/pvscheck.sh
@@ -373,13 +373,14 @@ run_analysis() {(
analyze \
--lic-file PVS-Studio.lic \
--threads "$(get_jobs_num)" \
- --exclude-path src/nvim/xdiff \
+ --exclude-path src/cjson \
+ --exclude-path src/xdiff \
--output-file PVS-studio.log \
--file build/compile_commands.json \
--sourcetree-root . || true
rm -rf PVS-studio.{xml,err,tsk,html.d}
- local plog_args="PVS-studio.log --srcRoot . --excludedCodes V011,V1042"
+ local plog_args="PVS-studio.log --srcRoot . --excludedCodes V011,V1042,V1051,V1074"
plog-converter $plog_args --renderTypes xml --output PVS-studio.xml
plog-converter $plog_args --renderTypes errorfile --output PVS-studio.err
plog-converter $plog_args --renderTypes tasklist --output PVS-studio.tsk
diff --git a/scripts/release.sh b/scripts/release.sh
index 4ec959d697..380503662d 100755
--- a/scripts/release.sh
+++ b/scripts/release.sh
@@ -80,8 +80,8 @@ _do_release_commit() {
_do_bump_commit() {
$__sed -i.bk 's/(NVIM_VERSION_PRERELEASE) ""/\1 "-dev"/' CMakeLists.txt
$__sed -i.bk 's/set\((NVIM_VERSION_PATCH) [[:digit:]]/set(\1 ?/' CMakeLists.txt
- rm CMakeLists.txt.bk
- rm runtime/nvim.appdata.xml.bk
+ rm -f CMakeLists.txt.bk
+ rm -f runtime/nvim.appdata.xml.bk
nvim +'/NVIM_VERSION' +1new +'exe "norm! iUpdate version numbers!!!"' \
-O CMakeLists.txt
diff --git a/scripts/squash_typos.py b/scripts/squash_typos.py
index 26be6010a2..b403a9b7c8 100644
--- a/scripts/squash_typos.py
+++ b/scripts/squash_typos.py
@@ -22,24 +22,40 @@ def get_authors_and_emails_from_pr():
# Get a list of all authors involved in the pull request (including co-authors).
authors = subprocess.check_output(
- ["gh", "pr", "view", "--json", "commits", "--jq", ".[][].authors.[].name"],
+ [
+ "gh",
+ "pr",
+ "view",
+ os.environ["PR_NUMBER"],
+ "--json",
+ "commits",
+ "--jq",
+ ".[][].authors.[].name",
+ ],
text=True,
).splitlines()
# Get a list of emails of the aforementioned authors.
emails = subprocess.check_output(
- ["gh", "pr", "view", "--json", "commits", "--jq", ".[][].authors.[].email"],
+ [
+ "gh",
+ "pr",
+ "view",
+ os.environ["PR_NUMBER"],
+ "--json",
+ "commits",
+ "--jq",
+ ".[][].authors.[].email",
+ ],
text=True,
).splitlines()
- authors_and_emails_unique = {
- (author, mail) for author, mail in zip(authors, emails)
- }
+ authors_and_emails = [(author, mail) for author, mail in zip(authors, emails)]
- return sorted(authors_and_emails_unique)
+ return authors_and_emails
-def rebase_squash_branch_onto_pr():
+def rebase_onto_pr():
"""
Rebase current branch onto the PR.
@@ -49,9 +65,7 @@ def rebase_squash_branch_onto_pr():
# Check out the pull request.
subprocess.call(["gh", "pr", "checkout", os.environ["PR_NUMBER"]])
- # Rebase onto master
- default_branch = f"{os.environ['GITHUB_BASE_REF']}"
- subprocess.check_call(["git", "rebase", default_branch])
+ rebase_onto_master()
# Change back to the original branch.
subprocess.call(["git", "switch", "-"])
@@ -87,7 +101,7 @@ def rebase_squash_branch_onto_pr():
)
-def rebase_squash_branch_onto_master():
+def rebase_onto_master():
"""
Rebase current branch onto the master i.e. make sure current branch is up
@@ -99,7 +113,7 @@ def rebase_squash_branch_onto_master():
subprocess.check_call(["git", "rebase", default_branch])
-def squash_all_commits():
+def squash_all_commits(message_body_before):
"""
Squash all commits on the PR into a single commit. Credit all authors by
@@ -111,8 +125,11 @@ def squash_all_commits():
subprocess.call(["git", "reset", "--soft", default_branch])
authors_and_emails = get_authors_and_emails_from_pr()
- commit_message_coauthors = "\n" + "\n".join(
- [f"Co-authored-by: {i[0]} <{i[1]}>" for i in authors_and_emails]
+ commit_message_coauthors = (
+ "\n"
+ + "\n".join([f"Co-authored-by: {i[0]} <{i[1]}>" for i in authors_and_emails])
+ + "\n"
+ + message_body_before
)
subprocess.call(
["git", "commit", "-m", "chore: typo fixes", "-m", commit_message_coauthors]
@@ -164,7 +181,7 @@ def checkout_branch(branch):
return False
-def get_all_pr_urls(squash_branch_exists):
+def get_all_pr_urls(pr_branch_exists):
"""
Return a list of URLs for the pull requests with the typo fixes. If a
@@ -173,7 +190,7 @@ def get_all_pr_urls(squash_branch_exists):
"""
all_pr_urls = ""
- if squash_branch_exists:
+ if pr_branch_exists:
all_pr_urls += subprocess.check_output(
["gh", "pr", "view", "--json", "body", "--jq", ".body"], text=True
)
@@ -187,15 +204,21 @@ def get_all_pr_urls(squash_branch_exists):
def main():
- squash_branch = "marvim/squash-typos"
+ pr_branch = "marvim/squash-typos"
- squash_branch_exists = checkout_branch(squash_branch)
+ pr_branch_exists = checkout_branch(pr_branch)
- rebase_squash_branch_onto_master()
- force_push(squash_branch)
+ rebase_onto_master()
+ force_push(pr_branch)
+
+ message_body_before = "\n".join(
+ subprocess.check_output(
+ ["git", "log", "--format=%B", "-n1", pr_branch], text=True
+ ).splitlines()[2:]
+ )
- rebase_squash_branch_onto_pr()
- force_push(squash_branch)
+ rebase_onto_pr()
+ force_push(pr_branch)
subprocess.call(
[
@@ -204,20 +227,37 @@ def main():
"create",
"--fill",
"--head",
- squash_branch,
+ pr_branch,
"--title",
"chore: typo fixes (automated)",
- ]
+ ],
+ text=True,
)
- squash_all_commits()
- force_push(squash_branch)
+ squash_all_commits(message_body_before)
+ force_push(pr_branch)
- all_pr_urls = get_all_pr_urls(squash_branch_exists)
+ all_pr_urls = get_all_pr_urls(pr_branch_exists)
subprocess.call(["gh", "pr", "edit", "--add-label", "typo", "--body", all_pr_urls])
subprocess.call(["gh", "pr", "close", os.environ["PR_NUMBER"]])
+ squash_url = subprocess.check_output(
+ ["gh", "pr", "view", "--json", "url", "--jq", ".url"], text=True
+ ).strip()
+ subprocess.call(
+ [
+ "gh",
+ "pr",
+ "comment",
+ os.environ["PR_NUMBER"],
+ "--body",
+ f"Thank you for your contribution! We collect all typo fixes \
+ into a single pull request and merge it once it gets big enough: \
+ {squash_url}",
+ ]
+ )
+
if __name__ == "__main__":
main()
diff --git a/scripts/vim-patch.sh b/scripts/vim-patch.sh
index f4b817dfff..d92480abb9 100755
--- a/scripts/vim-patch.sh
+++ b/scripts/vim-patch.sh
@@ -125,8 +125,12 @@ commit_message() {
}
find_git_remote() {
- git_remote=$(git remote -v \
- | awk '$2 ~ /github.com[:\/]neovim\/neovim/ && $3 == "(fetch)" {print $1; exit}')
+ local git_remote
+ if [[ "${1-}" == fork ]]; then
+ git_remote=$(git remote -v | awk '$2 !~ /github.com[:\/]neovim\/neovim/ && $3 == "(fetch)" {print $1; exit}')
+ else
+ git_remote=$(git remote -v | awk '$2 ~ /github.com[:\/]neovim\/neovim/ && $3 == "(fetch)" {print $1; exit}')
+ fi
if [[ -z "$git_remote" ]]; then
git_remote="origin"
fi
@@ -268,8 +272,8 @@ stage_patch() {
get_vimpatch "$1"
local try_apply="${2:-}"
- local git_remote
- git_remote="$(find_git_remote)"
+ local nvim_remote
+ nvim_remote="$(find_git_remote)"
local checked_out_branch
checked_out_branch="$(git rev-parse --abbrev-ref HEAD)"
@@ -277,16 +281,16 @@ stage_patch() {
msg_ok "Current branch '${checked_out_branch}' seems to be a vim-patch"
echo " branch; not creating a new branch."
else
- printf '\nFetching "%s/master".\n' "${git_remote}"
- output="$(git fetch "${git_remote}" master 2>&1)" &&
+ printf '\nFetching "%s/master".\n' "${nvim_remote}"
+ output="$(git fetch "${nvim_remote}" master 2>&1)" &&
msg_ok "${output}" ||
(msg_err "${output}"; false)
local nvim_branch="${BRANCH_PREFIX}${vim_version}"
echo
- echo "Creating new branch '${nvim_branch}' based on '${git_remote}/master'."
+ echo "Creating new branch '${nvim_branch}' based on '${nvim_remote}/master'."
cd "${NVIM_SOURCE_DIR}"
- output="$(git checkout -b "${nvim_branch}" "${git_remote}/master" 2>&1)" &&
+ output="$(git checkout -b "${nvim_branch}" "${nvim_remote}/master" 2>&1)" &&
msg_ok "${output}" ||
(msg_err "${output}"; false)
fi
@@ -362,13 +366,13 @@ submit_pr() {
exit 1
fi
- local git_remote
- git_remote="$(find_git_remote)"
+ local nvim_remote
+ nvim_remote="$(find_git_remote)"
local pr_body
- pr_body="$(git log --grep=vim-patch --reverse --format='#### %s%n%n%b%n' "${git_remote}"/master..HEAD)"
+ pr_body="$(git log --grep=vim-patch --reverse --format='#### %s%n%n%b%n' "${nvim_remote}"/master..HEAD)"
local patches
# Extract just the "vim-patch:X.Y.ZZZZ" or "vim-patch:sha" portion of each log
- patches=("$(git log --grep=vim-patch --reverse --format='%s' "${git_remote}"/master..HEAD | sed 's/: .*//')")
+ patches=("$(git log --grep=vim-patch --reverse --format='%s' "${nvim_remote}"/master..HEAD | sed 's/: .*//')")
# shellcheck disable=SC2206
patches=(${patches[@]//vim-patch:}) # Remove 'vim-patch:' prefix for each item in array.
local pr_title="${patches[*]}" # Create space-separated string from array.
@@ -376,8 +380,19 @@ submit_pr() {
pr_title="$(printf 'vim-patch:%s' "${pr_title#,}")"
if [[ $push_first -ne 0 ]]; then
- echo "Pushing to 'origin/${checked_out_branch}'."
- output="$(git push origin "${checked_out_branch}" 2>&1)" &&
+ local push_remote
+ push_remote="$(git config --get branch."${checked_out_branch}".pushRemote || true)"
+ if [[ -z "$push_remote" ]]; then
+ push_remote="$(git config --get remote.pushDefault || true)"
+ if [[ -z "$push_remote" ]]; then
+ push_remote="$(git config --get branch."${checked_out_branch}".remote || true)"
+ if [[ -z "$push_remote" ]] || [[ "$push_remote" == "$nvim_remote" ]]; then
+ push_remote="$(find_git_remote fork)"
+ fi
+ fi
+ fi
+ echo "Pushing to '${push_remote}/${checked_out_branch}'."
+ output="$(git push "${push_remote}" "${checked_out_branch}" 2>&1)" &&
msg_ok "${output}" ||
(msg_err "${output}"; false)
diff --git a/src/cjson/fpconv.c b/src/cjson/fpconv.c
new file mode 100644
index 0000000000..b2f7a214c2
--- /dev/null
+++ b/src/cjson/fpconv.c
@@ -0,0 +1,211 @@
+/* fpconv - Floating point conversion routines
+ *
+ * Copyright (c) 2011-2012 Mark Pulford <mark@kyne.com.au>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* JSON uses a '.' decimal separator. strtod() / sprintf() under C libraries
+ * with locale support will break when the decimal separator is a comma.
+ *
+ * fpconv_* will around these issues with a translation buffer if required.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include "fpconv.h"
+
+/* Workaround for MSVC */
+#ifdef _MSC_VER
+#define inline __inline
+#define snprintf sprintf_s
+#endif
+
+/* Lua CJSON assumes the locale is the same for all threads within a
+ * process and doesn't change after initialisation.
+ *
+ * This avoids the need for per thread storage or expensive checks
+ * for call. */
+static char locale_decimal_point = '.';
+
+/* In theory multibyte decimal_points are possible, but
+ * Lua CJSON only supports UTF-8 and known locales only have
+ * single byte decimal points ([.,]).
+ *
+ * localconv() may not be thread safe (=>crash), and nl_langinfo() is
+ * not supported on some platforms. Use sprintf() instead - if the
+ * locale does change, at least Lua CJSON won't crash. */
+static void fpconv_update_locale(void)
+{
+ char buf[8];
+
+ snprintf(buf, sizeof(buf), "%g", 0.5);
+
+ /* Failing this test might imply the platform has a buggy dtoa
+ * implementation or wide characters */
+ if (buf[0] != '0' || buf[2] != '5' || buf[3] != 0) {
+ fprintf(stderr, "Error: wide characters found or printf() bug.");
+ abort();
+ }
+
+ locale_decimal_point = buf[1];
+}
+
+/* Check for a valid number character: [-+0-9a-yA-Y.]
+ * Eg: -0.6e+5, infinity, 0xF0.F0pF0
+ *
+ * Used to find the probable end of a number. It doesn't matter if
+ * invalid characters are counted - strtod() will find the valid
+ * number if it exists. The risk is that slightly more memory might
+ * be allocated before a parse error occurs. */
+static inline int valid_number_character(char ch)
+{
+ char lower_ch;
+
+ if ('0' <= ch && ch <= '9')
+ return 1;
+ if (ch == '-' || ch == '+' || ch == '.')
+ return 1;
+
+ /* Hex digits, exponent (e), base (p), "infinity",.. */
+ lower_ch = ch | 0x20;
+ if ('a' <= lower_ch && lower_ch <= 'y')
+ return 1;
+
+ return 0;
+}
+
+/* Calculate the size of the buffer required for a strtod locale
+ * conversion. */
+static int strtod_buffer_size(const char *s)
+{
+ const char *p = s;
+
+ while (valid_number_character(*p))
+ p++;
+
+ return p - s;
+}
+
+/* Similar to strtod(), but must be passed the current locale's decimal point
+ * character. Guaranteed to be called at the start of any valid number in a string */
+double fpconv_strtod(const char *nptr, char **endptr)
+{
+ char localbuf[FPCONV_G_FMT_BUFSIZE];
+ char *buf, *endbuf, *dp;
+ int buflen;
+ double value;
+
+ /* System strtod() is fine when decimal point is '.' */
+ if (locale_decimal_point == '.')
+ return strtod(nptr, endptr);
+
+ buflen = strtod_buffer_size(nptr);
+ if (!buflen) {
+ /* No valid characters found, standard strtod() return */
+ *endptr = (char *)nptr;
+ return 0;
+ }
+
+ /* Duplicate number into buffer */
+ if (buflen >= FPCONV_G_FMT_BUFSIZE) {
+ /* Handle unusually large numbers */
+ buf = malloc(buflen + 1);
+ if (!buf) {
+ fprintf(stderr, "Out of memory");
+ abort();
+ }
+ } else {
+ /* This is the common case.. */
+ buf = localbuf;
+ }
+ memcpy(buf, nptr, buflen);
+ buf[buflen] = 0;
+
+ /* Update decimal point character if found */
+ dp = strchr(buf, '.');
+ if (dp)
+ *dp = locale_decimal_point;
+
+ value = strtod(buf, &endbuf);
+ *endptr = (char *)&nptr[endbuf - buf];
+ if (buflen >= FPCONV_G_FMT_BUFSIZE)
+ free(buf);
+
+ return value;
+}
+
+/* "fmt" must point to a buffer of at least 6 characters */
+static void set_number_format(char *fmt, int precision)
+{
+ int d1, d2, i;
+
+ assert(1 <= precision && precision <= 16);
+
+ /* Create printf format (%.14g) from precision */
+ d1 = precision / 10;
+ d2 = precision % 10;
+ fmt[0] = '%';
+ fmt[1] = '.';
+ i = 2;
+ if (d1) {
+ fmt[i++] = '0' + d1;
+ }
+ fmt[i++] = '0' + d2;
+ fmt[i++] = 'g';
+ fmt[i] = 0;
+}
+
+/* Assumes there is always at least 32 characters available in the target buffer */
+int fpconv_g_fmt(char *str, double num, int precision)
+{
+ char buf[FPCONV_G_FMT_BUFSIZE];
+ char fmt[6];
+ int len;
+ char *b;
+
+ set_number_format(fmt, precision);
+
+ /* Pass through when decimal point character is dot. */
+ if (locale_decimal_point == '.')
+ return snprintf(str, FPCONV_G_FMT_BUFSIZE, fmt, num);
+
+ /* snprintf() to a buffer then translate for other decimal point characters */
+ len = snprintf(buf, FPCONV_G_FMT_BUFSIZE, fmt, num);
+
+ /* Copy into target location. Translate decimal point if required */
+ b = buf;
+ do {
+ *str++ = (*b == locale_decimal_point ? '.' : *b);
+ } while(*b++);
+
+ return len;
+}
+
+void fpconv_init()
+{
+ fpconv_update_locale();
+}
+
+/* vi:ai et sw=4 ts=4:
+ */
diff --git a/src/cjson/fpconv.h b/src/cjson/fpconv.h
new file mode 100644
index 0000000000..6ac97808b6
--- /dev/null
+++ b/src/cjson/fpconv.h
@@ -0,0 +1,22 @@
+/* Lua CJSON floating point conversion routines */
+
+/* Buffer required to store the largest string representation of a double.
+ *
+ * Longest double printed with %.14g is 21 characters long:
+ * -1.7976931348623e+308 */
+# define FPCONV_G_FMT_BUFSIZE 32
+
+#ifdef USE_INTERNAL_FPCONV
+static inline void fpconv_init()
+{
+ /* Do nothing - not required */
+}
+#else
+extern void fpconv_init(void);
+#endif
+
+extern int fpconv_g_fmt(char*, double, int);
+extern double fpconv_strtod(const char*, char**);
+
+/* vi:ai et sw=4 ts=4:
+ */
diff --git a/src/cjson/lua_cjson.c b/src/cjson/lua_cjson.c
new file mode 100644
index 0000000000..cf9e82c38e
--- /dev/null
+++ b/src/cjson/lua_cjson.c
@@ -0,0 +1,1655 @@
+/* Lua CJSON - JSON support for Lua
+ *
+ * Copyright (c) 2010-2012 Mark Pulford <mark@kyne.com.au>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* Caveats:
+ * - JSON "null" values are represented as lightuserdata since Lua
+ * tables cannot contain "nil". Compare with cjson.null.
+ * - Invalid UTF-8 characters are not detected and will be passed
+ * untouched. If required, UTF-8 error checking should be done
+ * outside this library.
+ * - Javascript comments are not part of the JSON spec, and are not
+ * currently supported.
+ *
+ * Note: Decoding is slower than encoding. Lua spends significant
+ * time (30%) managing tables when parsing JSON since it is
+ * difficult to know object/array sizes ahead of time.
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+#include <math.h>
+#include <limits.h>
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "nvim/lua/executor.h"
+
+#include "lua_cjson.h"
+#include "strbuf.h"
+#include "fpconv.h"
+
+#ifndef CJSON_MODNAME
+#define CJSON_MODNAME "cjson"
+#endif
+
+#ifndef CJSON_VERSION
+#define CJSON_VERSION "2.1.0.9"
+#endif
+
+#ifdef _MSC_VER
+#define snprintf sprintf_s
+
+#ifndef isnan
+#include <float.h>
+#define isnan(x) _isnan(x)
+#endif
+
+#endif
+
+/* Workaround for Solaris platforms missing isinf() */
+#if !defined(isinf) && (defined(USE_INTERNAL_ISINF) || defined(MISSING_ISINF))
+#define isinf(x) (!isnan(x) && isnan((x) - (x)))
+#endif
+
+#define DEFAULT_SPARSE_CONVERT 0
+#define DEFAULT_SPARSE_RATIO 2
+#define DEFAULT_SPARSE_SAFE 10
+#define DEFAULT_ENCODE_MAX_DEPTH 1000
+#define DEFAULT_DECODE_MAX_DEPTH 1000
+#define DEFAULT_ENCODE_INVALID_NUMBERS 0
+#define DEFAULT_DECODE_INVALID_NUMBERS 1
+#define DEFAULT_ENCODE_KEEP_BUFFER 1
+#define DEFAULT_ENCODE_NUMBER_PRECISION 14
+#define DEFAULT_ENCODE_EMPTY_TABLE_AS_OBJECT 0
+#define DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT 0
+#define DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH 1
+
+#ifdef DISABLE_INVALID_NUMBERS
+#undef DEFAULT_DECODE_INVALID_NUMBERS
+#define DEFAULT_DECODE_INVALID_NUMBERS 0
+#endif
+
+#ifdef _MSC_VER
+/* Microsoft C compiler lacks strncasecmp and strcasecmp. */
+#define strncasecmp _strnicmp
+#define strcasecmp _stricmp
+#endif
+
+#if LONG_MAX > ((1UL << 31) - 1)
+#define json_lightudata_mask(ludata) \
+ ((void *) ((uintptr_t) (ludata) & ((1UL << 47) - 1)))
+
+#else
+#define json_lightudata_mask(ludata) (ludata)
+#endif
+
+#if LUA_VERSION_NUM > 501
+#define lua_objlen(L,i) lua_rawlen(L, (i))
+#endif
+
+static const char * const *json_empty_array;
+static const char * const *json_array;
+
+typedef enum {
+ T_OBJ_BEGIN,
+ T_OBJ_END,
+ T_ARR_BEGIN,
+ T_ARR_END,
+ T_STRING,
+ T_NUMBER,
+ T_BOOLEAN,
+ T_NULL,
+ T_COLON,
+ T_COMMA,
+ T_END,
+ T_WHITESPACE,
+ T_ERROR,
+ T_UNKNOWN
+} json_token_type_t;
+
+static const char *json_token_type_name[] = {
+ "T_OBJ_BEGIN",
+ "T_OBJ_END",
+ "T_ARR_BEGIN",
+ "T_ARR_END",
+ "T_STRING",
+ "T_NUMBER",
+ "T_BOOLEAN",
+ "T_NULL",
+ "T_COLON",
+ "T_COMMA",
+ "T_END",
+ "T_WHITESPACE",
+ "T_ERROR",
+ "T_UNKNOWN",
+ NULL
+};
+
+typedef struct {
+ json_token_type_t ch2token[256];
+ char escape2char[256]; /* Decoding */
+
+ /* encode_buf is only allocated and used when
+ * encode_keep_buffer is set */
+ strbuf_t encode_buf;
+
+ int encode_sparse_convert;
+ int encode_sparse_ratio;
+ int encode_sparse_safe;
+ int encode_max_depth;
+ int encode_invalid_numbers; /* 2 => Encode as "null" */
+ int encode_number_precision;
+ int encode_keep_buffer;
+ int encode_empty_table_as_object;
+ int encode_escape_forward_slash;
+
+ int decode_invalid_numbers;
+ int decode_max_depth;
+ int decode_array_with_array_mt;
+} json_config_t;
+
+typedef struct {
+ /* convert null in json objects to lua nil instead of vim.NIL */
+ int luanil_object;
+ /* convert null in json arrays to lua nil instead of vim.NIL */
+ int luanil_array;
+} json_options_t;
+
+typedef struct {
+ const char *data;
+ const char *ptr;
+ strbuf_t *tmp; /* Temporary storage for strings */
+ json_config_t *cfg;
+ json_options_t *options;
+ int current_depth;
+} json_parse_t;
+
+typedef struct {
+ json_token_type_t type;
+ int index;
+ union {
+ const char *string;
+ double number;
+ int boolean;
+ } value;
+ int string_len;
+} json_token_t;
+
+static const char *char2escape[256] = {
+ "\\u0000", "\\u0001", "\\u0002", "\\u0003",
+ "\\u0004", "\\u0005", "\\u0006", "\\u0007",
+ "\\b", "\\t", "\\n", "\\u000b",
+ "\\f", "\\r", "\\u000e", "\\u000f",
+ "\\u0010", "\\u0011", "\\u0012", "\\u0013",
+ "\\u0014", "\\u0015", "\\u0016", "\\u0017",
+ "\\u0018", "\\u0019", "\\u001a", "\\u001b",
+ "\\u001c", "\\u001d", "\\u001e", "\\u001f",
+ NULL, NULL, "\\\"", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\\/",
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\\\\", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\\u007f",
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+};
+
+/* ===== CONFIGURATION ===== */
+
+static json_config_t *json_fetch_config(lua_State *l)
+{
+ json_config_t *cfg;
+
+ cfg = lua_touserdata(l, lua_upvalueindex(1));
+ if (!cfg)
+ luaL_error(l, "BUG: Unable to fetch CJSON configuration");
+
+ return cfg;
+}
+
+/* Ensure the correct number of arguments have been provided.
+ * Pad with nil to allow other functions to simply check arg[i]
+ * to find whether an argument was provided */
+static json_config_t *json_arg_init(lua_State *l, int args)
+{
+ luaL_argcheck(l, lua_gettop(l) <= args, args + 1,
+ "found too many arguments");
+
+ while (lua_gettop(l) < args)
+ lua_pushnil(l);
+
+ return json_fetch_config(l);
+}
+
+/* Process integer options for configuration functions */
+static int json_integer_option(lua_State *l, int optindex, int *setting,
+ int min, int max)
+{
+ char errmsg[64];
+ int value;
+
+ if (!lua_isnil(l, optindex)) {
+ value = luaL_checkinteger(l, optindex);
+ snprintf(errmsg, sizeof(errmsg), "expected integer between %d and %d", min, max);
+ luaL_argcheck(l, min <= value && value <= max, 1, errmsg);
+ *setting = value;
+ }
+
+ lua_pushinteger(l, *setting);
+
+ return 1;
+}
+
+/* Process enumerated arguments for a configuration function */
+static int json_enum_option(lua_State *l, int optindex, int *setting,
+ const char **options, int bool_true)
+{
+ static const char *bool_options[] = { "off", "on", NULL };
+
+ if (!options) {
+ options = bool_options;
+ bool_true = 1;
+ }
+
+ if (!lua_isnil(l, optindex)) {
+ if (bool_true && lua_isboolean(l, optindex))
+ *setting = lua_toboolean(l, optindex) * bool_true;
+ else
+ *setting = luaL_checkoption(l, optindex, NULL, options);
+ }
+
+ if (bool_true && (*setting == 0 || *setting == bool_true))
+ lua_pushboolean(l, *setting);
+ else
+ lua_pushstring(l, options[*setting]);
+
+ return 1;
+}
+
+/* Configures handling of extremely sparse arrays:
+ * convert: Convert extremely sparse arrays into objects? Otherwise error.
+ * ratio: 0: always allow sparse; 1: never allow sparse; >1: use ratio
+ * safe: Always use an array when the max index <= safe */
+static int json_cfg_encode_sparse_array(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 3);
+
+ json_enum_option(l, 1, &cfg->encode_sparse_convert, NULL, 1);
+ json_integer_option(l, 2, &cfg->encode_sparse_ratio, 0, INT_MAX);
+ json_integer_option(l, 3, &cfg->encode_sparse_safe, 0, INT_MAX);
+
+ return 3;
+}
+
+/* Configures the maximum number of nested arrays/objects allowed when
+ * encoding */
+static int json_cfg_encode_max_depth(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ return json_integer_option(l, 1, &cfg->encode_max_depth, 1, INT_MAX);
+}
+
+/* Configures the maximum number of nested arrays/objects allowed when
+ * encoding */
+static int json_cfg_decode_max_depth(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ return json_integer_option(l, 1, &cfg->decode_max_depth, 1, INT_MAX);
+}
+
+/* Configures number precision when converting doubles to text */
+static int json_cfg_encode_number_precision(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ return json_integer_option(l, 1, &cfg->encode_number_precision, 1, 16);
+}
+
+/* Configures how to treat empty table when encode lua table */
+static int json_cfg_encode_empty_table_as_object(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ return json_enum_option(l, 1, &cfg->encode_empty_table_as_object, NULL, 1);
+}
+
+/* Configures how to decode arrays */
+static int json_cfg_decode_array_with_array_mt(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ json_enum_option(l, 1, &cfg->decode_array_with_array_mt, NULL, 1);
+
+ return 1;
+}
+
+/* Configures JSON encoding buffer persistence */
+static int json_cfg_encode_keep_buffer(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+ int old_value;
+
+ old_value = cfg->encode_keep_buffer;
+
+ json_enum_option(l, 1, &cfg->encode_keep_buffer, NULL, 1);
+
+ /* Init / free the buffer if the setting has changed */
+ if (old_value ^ cfg->encode_keep_buffer) {
+ if (cfg->encode_keep_buffer)
+ strbuf_init(&cfg->encode_buf, 0);
+ else
+ strbuf_free(&cfg->encode_buf);
+ }
+
+ return 1;
+}
+
+#if defined(DISABLE_INVALID_NUMBERS) && !defined(USE_INTERNAL_FPCONV)
+void json_verify_invalid_number_setting(lua_State *l, int *setting)
+{
+ if (*setting == 1) {
+ *setting = 0;
+ luaL_error(l, "Infinity, NaN, and/or hexadecimal numbers are not supported.");
+ }
+}
+#else
+#define json_verify_invalid_number_setting(l, s) do { } while(0)
+#endif
+
+static int json_cfg_encode_invalid_numbers(lua_State *l)
+{
+ static const char *options[] = { "off", "on", "null", NULL };
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ json_enum_option(l, 1, &cfg->encode_invalid_numbers, options, 1);
+
+ json_verify_invalid_number_setting(l, &cfg->encode_invalid_numbers);
+
+ return 1;
+}
+
+static int json_cfg_decode_invalid_numbers(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ json_enum_option(l, 1, &cfg->decode_invalid_numbers, NULL, 1);
+
+ json_verify_invalid_number_setting(l, &cfg->encode_invalid_numbers);
+
+ return 1;
+}
+
+static int json_cfg_encode_escape_forward_slash(lua_State *l)
+{
+ int ret;
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ ret = json_enum_option(l, 1, &cfg->encode_escape_forward_slash, NULL, 1);
+ if (cfg->encode_escape_forward_slash) {
+ char2escape['/'] = "\\/";
+ } else {
+ char2escape['/'] = NULL;
+ }
+ return ret;
+}
+
+static int json_destroy_config(lua_State *l)
+{
+ json_config_t *cfg;
+
+ cfg = lua_touserdata(l, 1);
+ if (cfg)
+ strbuf_free(&cfg->encode_buf);
+ cfg = NULL;
+
+ return 0;
+}
+
+static void json_create_config(lua_State *l)
+{
+ json_config_t *cfg;
+ int i;
+
+ cfg = lua_newuserdata(l, sizeof(*cfg));
+
+ /* Create GC method to clean up strbuf */
+ lua_newtable(l);
+ lua_pushcfunction(l, json_destroy_config);
+ lua_setfield(l, -2, "__gc");
+ lua_setmetatable(l, -2);
+
+ cfg->encode_sparse_convert = DEFAULT_SPARSE_CONVERT;
+ cfg->encode_sparse_ratio = DEFAULT_SPARSE_RATIO;
+ cfg->encode_sparse_safe = DEFAULT_SPARSE_SAFE;
+ cfg->encode_max_depth = DEFAULT_ENCODE_MAX_DEPTH;
+ cfg->decode_max_depth = DEFAULT_DECODE_MAX_DEPTH;
+ cfg->encode_invalid_numbers = DEFAULT_ENCODE_INVALID_NUMBERS;
+ cfg->decode_invalid_numbers = DEFAULT_DECODE_INVALID_NUMBERS;
+ cfg->encode_keep_buffer = DEFAULT_ENCODE_KEEP_BUFFER;
+ cfg->encode_number_precision = DEFAULT_ENCODE_NUMBER_PRECISION;
+ cfg->encode_empty_table_as_object = DEFAULT_ENCODE_EMPTY_TABLE_AS_OBJECT;
+ cfg->decode_array_with_array_mt = DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT;
+ cfg->encode_escape_forward_slash = DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH;
+
+#if DEFAULT_ENCODE_KEEP_BUFFER > 0
+ strbuf_init(&cfg->encode_buf, 0);
+#endif
+
+ /* Decoding init */
+
+ /* Tag all characters as an error */
+ for (i = 0; i < 256; i++)
+ cfg->ch2token[i] = T_ERROR;
+
+ /* Set tokens that require no further processing */
+ cfg->ch2token['{'] = T_OBJ_BEGIN;
+ cfg->ch2token['}'] = T_OBJ_END;
+ cfg->ch2token['['] = T_ARR_BEGIN;
+ cfg->ch2token[']'] = T_ARR_END;
+ cfg->ch2token[','] = T_COMMA;
+ cfg->ch2token[':'] = T_COLON;
+ cfg->ch2token['\0'] = T_END;
+ cfg->ch2token[' '] = T_WHITESPACE;
+ cfg->ch2token['\t'] = T_WHITESPACE;
+ cfg->ch2token['\n'] = T_WHITESPACE;
+ cfg->ch2token['\r'] = T_WHITESPACE;
+
+ /* Update characters that require further processing */
+ cfg->ch2token['f'] = T_UNKNOWN; /* false? */
+ cfg->ch2token['i'] = T_UNKNOWN; /* inf, ininity? */
+ cfg->ch2token['I'] = T_UNKNOWN;
+ cfg->ch2token['n'] = T_UNKNOWN; /* null, nan? */
+ cfg->ch2token['N'] = T_UNKNOWN;
+ cfg->ch2token['t'] = T_UNKNOWN; /* true? */
+ cfg->ch2token['"'] = T_UNKNOWN; /* string? */
+ cfg->ch2token['+'] = T_UNKNOWN; /* number? */
+ cfg->ch2token['-'] = T_UNKNOWN;
+ for (i = 0; i < 10; i++)
+ cfg->ch2token['0' + i] = T_UNKNOWN;
+
+ /* Lookup table for parsing escape characters */
+ for (i = 0; i < 256; i++)
+ cfg->escape2char[i] = 0; /* String error */
+ cfg->escape2char['"'] = '"';
+ cfg->escape2char['\\'] = '\\';
+ cfg->escape2char['/'] = '/';
+ cfg->escape2char['b'] = '\b';
+ cfg->escape2char['t'] = '\t';
+ cfg->escape2char['n'] = '\n';
+ cfg->escape2char['f'] = '\f';
+ cfg->escape2char['r'] = '\r';
+ cfg->escape2char['u'] = 'u'; /* Unicode parsing required */
+}
+
+/* ===== ENCODING ===== */
+
+static void json_encode_exception(lua_State *l, json_config_t *cfg, strbuf_t *json, int lindex,
+ const char *reason)
+{
+ if (!cfg->encode_keep_buffer)
+ strbuf_free(json);
+ luaL_error(l, "Cannot serialise %s: %s",
+ lua_typename(l, lua_type(l, lindex)), reason);
+}
+
+/* json_append_string args:
+ * - lua_State
+ * - JSON strbuf
+ * - String (Lua stack index)
+ *
+ * Returns nothing. Doesn't remove string from Lua stack */
+static void json_append_string(lua_State *l, strbuf_t *json, int lindex)
+{
+ const char *escstr;
+ unsigned i;
+ const char *str;
+ size_t len;
+
+ str = lua_tolstring(l, lindex, &len);
+
+ /* Worst case is len * 6 (all unicode escapes).
+ * This buffer is reused constantly for small strings
+ * If there are any excess pages, they won't be hit anyway.
+ * This gains ~5% speedup. */
+ strbuf_ensure_empty_length(json, len * 6 + 2);
+
+ strbuf_append_char_unsafe(json, '\"');
+ for (i = 0; i < len; i++) {
+ escstr = char2escape[(unsigned char)str[i]];
+ if (escstr)
+ strbuf_append_string(json, escstr);
+ else
+ strbuf_append_char_unsafe(json, str[i]);
+ }
+ strbuf_append_char_unsafe(json, '\"');
+}
+
+/* Find the size of the array on the top of the Lua stack
+ * -1 object (not a pure array)
+ * >=0 elements in array
+ */
+static int lua_array_length(lua_State *l, json_config_t *cfg, strbuf_t *json)
+{
+ double k;
+ int max;
+ int items;
+
+ max = 0;
+ items = 0;
+
+ lua_pushnil(l);
+ /* table, startkey */
+ while (lua_next(l, -2) != 0) {
+ /* table, key, value */
+ if (lua_type(l, -2) == LUA_TNUMBER &&
+ (k = lua_tonumber(l, -2))) {
+ /* Integer >= 1 ? */
+ if (floor(k) == k && k >= 1) {
+ if (k > max)
+ max = k;
+ items++;
+ lua_pop(l, 1);
+ continue;
+ }
+ }
+
+ /* Must not be an array (non integer key) */
+ lua_pop(l, 2);
+ return -1;
+ }
+
+ /* Encode excessively sparse arrays as objects (if enabled) */
+ if (cfg->encode_sparse_ratio > 0 &&
+ max > items * cfg->encode_sparse_ratio &&
+ max > cfg->encode_sparse_safe) {
+ if (!cfg->encode_sparse_convert)
+ json_encode_exception(l, cfg, json, -1, "excessively sparse array");
+
+ return -1;
+ }
+
+ return max;
+}
+
+static void json_check_encode_depth(lua_State *l, json_config_t *cfg,
+ int current_depth, strbuf_t *json)
+{
+ /* Ensure there are enough slots free to traverse a table (key,
+ * value) and push a string for a potential error message.
+ *
+ * Unlike "decode", the key and value are still on the stack when
+ * lua_checkstack() is called. Hence an extra slot for luaL_error()
+ * below is required just in case the next check to lua_checkstack()
+ * fails.
+ *
+ * While this won't cause a crash due to the EXTRA_STACK reserve
+ * slots, it would still be an improper use of the API. */
+ if (current_depth <= cfg->encode_max_depth && lua_checkstack(l, 3))
+ return;
+
+ if (!cfg->encode_keep_buffer)
+ strbuf_free(json);
+
+ luaL_error(l, "Cannot serialise, excessive nesting (%d)",
+ current_depth);
+}
+
+static void json_append_data(lua_State *l, json_config_t *cfg,
+ int current_depth, strbuf_t *json);
+
+/* json_append_array args:
+ * - lua_State
+ * - JSON strbuf
+ * - Size of passwd Lua array (top of stack) */
+static void json_append_array(lua_State *l, json_config_t *cfg, int current_depth,
+ strbuf_t *json, int array_length)
+{
+ int comma, i;
+
+ strbuf_append_char(json, '[');
+
+ comma = 0;
+ for (i = 1; i <= array_length; i++) {
+ if (comma)
+ strbuf_append_char(json, ',');
+ else
+ comma = 1;
+
+ lua_rawgeti(l, -1, i);
+ json_append_data(l, cfg, current_depth, json);
+ lua_pop(l, 1);
+ }
+
+ strbuf_append_char(json, ']');
+}
+
+static void json_append_number(lua_State *l, json_config_t *cfg,
+ strbuf_t *json, int lindex)
+{
+ double num = lua_tonumber(l, lindex);
+ int len;
+
+ if (cfg->encode_invalid_numbers == 0) {
+ /* Prevent encoding invalid numbers */
+ if (isinf(num) || isnan(num))
+ json_encode_exception(l, cfg, json, lindex,
+ "must not be NaN or Infinity");
+ } else if (cfg->encode_invalid_numbers == 1) {
+ /* Encode NaN/Infinity separately to ensure Javascript compatible
+ * values are used. */
+ if (isnan(num)) {
+ strbuf_append_mem(json, "NaN", 3);
+ return;
+ }
+ if (isinf(num)) {
+ if (num < 0)
+ strbuf_append_mem(json, "-Infinity", 9);
+ else
+ strbuf_append_mem(json, "Infinity", 8);
+ return;
+ }
+ } else {
+ /* Encode invalid numbers as "null" */
+ if (isinf(num) || isnan(num)) {
+ strbuf_append_mem(json, "null", 4);
+ return;
+ }
+ }
+
+ strbuf_ensure_empty_length(json, FPCONV_G_FMT_BUFSIZE);
+ len = fpconv_g_fmt(strbuf_empty_ptr(json), num, cfg->encode_number_precision);
+ strbuf_extend_length(json, len);
+}
+
+static void json_append_object(lua_State *l, json_config_t *cfg,
+ int current_depth, strbuf_t *json)
+{
+ int comma, keytype;
+
+ /* Object */
+ strbuf_append_char(json, '{');
+
+ lua_pushnil(l);
+ /* table, startkey */
+ comma = 0;
+ while (lua_next(l, -2) != 0) {
+ if (comma)
+ strbuf_append_char(json, ',');
+ else
+ comma = 1;
+
+ /* table, key, value */
+ keytype = lua_type(l, -2);
+ if (keytype == LUA_TNUMBER) {
+ strbuf_append_char(json, '"');
+ json_append_number(l, cfg, json, -2);
+ strbuf_append_mem(json, "\":", 2);
+ } else if (keytype == LUA_TSTRING) {
+ json_append_string(l, json, -2);
+ strbuf_append_char(json, ':');
+ } else {
+ json_encode_exception(l, cfg, json, -2,
+ "table key must be a number or string");
+ /* never returns */
+ }
+
+ /* table, key, value */
+ json_append_data(l, cfg, current_depth, json);
+ lua_pop(l, 1);
+ /* table, key */
+ }
+
+ strbuf_append_char(json, '}');
+}
+
+/* Serialise Lua data into JSON string. */
+static void json_append_data(lua_State *l, json_config_t *cfg,
+ int current_depth, strbuf_t *json)
+{
+ int len;
+ int as_array = 0;
+ int as_empty_dict = 0;
+ int has_metatable;
+
+ switch (lua_type(l, -1)) {
+ case LUA_TSTRING:
+ json_append_string(l, json, -1);
+ break;
+ case LUA_TNUMBER:
+ json_append_number(l, cfg, json, -1);
+ break;
+ case LUA_TBOOLEAN:
+ if (lua_toboolean(l, -1))
+ strbuf_append_mem(json, "true", 4);
+ else
+ strbuf_append_mem(json, "false", 5);
+ break;
+ case LUA_TTABLE:
+ current_depth++;
+ json_check_encode_depth(l, cfg, current_depth, json);
+
+ has_metatable = lua_getmetatable(l, -1);
+
+ if (has_metatable) {
+
+ nlua_pushref(l, nlua_empty_dict_ref);
+ if (lua_rawequal(l, -2, -1)) {
+ as_empty_dict = true;
+ } else {
+ lua_pop(l, 1);
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_array));
+ lua_rawget(l, LUA_REGISTRYINDEX);
+ as_array = lua_rawequal(l, -1, -2);
+ }
+ lua_pop(l, 2);
+ }
+
+ if (as_array) {
+ len = lua_objlen(l, -1);
+ json_append_array(l, cfg, current_depth, json, len);
+ } else {
+ len = lua_array_length(l, cfg, json);
+
+ if (len > 0 || (len == 0 && !cfg->encode_empty_table_as_object && !as_empty_dict)) {
+ json_append_array(l, cfg, current_depth, json, len);
+ } else {
+ if (has_metatable) {
+ lua_getmetatable(l, -1);
+ lua_pushlightuserdata(l, json_lightudata_mask(
+ &json_empty_array));
+ lua_rawget(l, LUA_REGISTRYINDEX);
+ as_array = lua_rawequal(l, -1, -2);
+ lua_pop(l, 2); /* pop pointer + metatable */
+ if (as_array) {
+ json_append_array(l, cfg, current_depth, json, 0);
+ break;
+ }
+ }
+ json_append_object(l, cfg, current_depth, json);
+ }
+ }
+ break;
+ case LUA_TNIL:
+ strbuf_append_mem(json, "null", 4);
+ break;
+ case LUA_TLIGHTUSERDATA:
+ if (lua_touserdata(l, -1) == &json_array) {
+ json_append_array(l, cfg, current_depth, json, 0);
+ }
+ break;
+ case LUA_TUSERDATA:
+ nlua_pushref(l, nlua_nil_ref);
+ bool is_nil = lua_rawequal(l, -2, -1);
+ lua_pop(l, 1);
+ if (is_nil) {
+ strbuf_append_mem(json, "null", 4);
+ break;
+ } else {
+ FALLTHROUGH;
+ }
+ default:
+ /* Remaining types (LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD,
+ * and LUA_TLIGHTUSERDATA) cannot be serialised */
+ json_encode_exception(l, cfg, json, -1, "type not supported");
+ /* never returns */
+ }
+}
+
+static int json_encode(lua_State *l)
+{
+ json_config_t *cfg = json_fetch_config(l);
+ strbuf_t local_encode_buf;
+ strbuf_t *encode_buf;
+ char *json;
+ int len;
+
+ luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument");
+
+ if (!cfg->encode_keep_buffer) {
+ /* Use private buffer */
+ encode_buf = &local_encode_buf;
+ strbuf_init(encode_buf, 0);
+ } else {
+ /* Reuse existing buffer */
+ encode_buf = &cfg->encode_buf;
+ strbuf_reset(encode_buf);
+ }
+
+ json_append_data(l, cfg, 0, encode_buf);
+ json = strbuf_string(encode_buf, &len);
+
+ lua_pushlstring(l, json, len);
+
+ if (!cfg->encode_keep_buffer)
+ strbuf_free(encode_buf);
+
+ return 1;
+}
+
+/* ===== DECODING ===== */
+
+static void json_process_value(lua_State *l, json_parse_t *json,
+ json_token_t *token, bool use_luanil);
+
+static int hexdigit2int(char hex)
+{
+ if ('0' <= hex && hex <= '9')
+ return hex - '0';
+
+ /* Force lowercase */
+ hex |= 0x20;
+ if ('a' <= hex && hex <= 'f')
+ return 10 + hex - 'a';
+
+ return -1;
+}
+
+static int decode_hex4(const char *hex)
+{
+ int digit[4];
+ int i;
+
+ /* Convert ASCII hex digit to numeric digit
+ * Note: this returns an error for invalid hex digits, including
+ * NULL */
+ for (i = 0; i < 4; i++) {
+ digit[i] = hexdigit2int(hex[i]);
+ if (digit[i] < 0) {
+ return -1;
+ }
+ }
+
+ return (digit[0] << 12) +
+ (digit[1] << 8) +
+ (digit[2] << 4) +
+ digit[3];
+}
+
+/* Converts a Unicode codepoint to UTF-8.
+ * Returns UTF-8 string length, and up to 4 bytes in *utf8 */
+static int codepoint_to_utf8(char *utf8, int codepoint)
+{
+ /* 0xxxxxxx */
+ if (codepoint <= 0x7F) {
+ utf8[0] = codepoint;
+ return 1;
+ }
+
+ /* 110xxxxx 10xxxxxx */
+ if (codepoint <= 0x7FF) {
+ utf8[0] = (codepoint >> 6) | 0xC0;
+ utf8[1] = (codepoint & 0x3F) | 0x80;
+ return 2;
+ }
+
+ /* 1110xxxx 10xxxxxx 10xxxxxx */
+ if (codepoint <= 0xFFFF) {
+ utf8[0] = (codepoint >> 12) | 0xE0;
+ utf8[1] = ((codepoint >> 6) & 0x3F) | 0x80;
+ utf8[2] = (codepoint & 0x3F) | 0x80;
+ return 3;
+ }
+
+ /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
+ if (codepoint <= 0x1FFFFF) {
+ utf8[0] = (codepoint >> 18) | 0xF0;
+ utf8[1] = ((codepoint >> 12) & 0x3F) | 0x80;
+ utf8[2] = ((codepoint >> 6) & 0x3F) | 0x80;
+ utf8[3] = (codepoint & 0x3F) | 0x80;
+ return 4;
+ }
+
+ return 0;
+}
+
+
+/* Called when index pointing to beginning of UTF-16 code escape: \uXXXX
+ * \u is guaranteed to exist, but the remaining hex characters may be
+ * missing.
+ * Translate to UTF-8 and append to temporary token string.
+ * Must advance index to the next character to be processed.
+ * Returns: 0 success
+ * -1 error
+ */
+static int json_append_unicode_escape(json_parse_t *json)
+{
+ char utf8[4]; /* Surrogate pairs require 4 UTF-8 bytes */
+ int codepoint;
+ int surrogate_low;
+ int len;
+ int escape_len = 6;
+
+ /* Fetch UTF-16 code unit */
+ codepoint = decode_hex4(json->ptr + 2);
+ if (codepoint < 0)
+ return -1;
+
+ /* UTF-16 surrogate pairs take the following 2 byte form:
+ * 11011 x yyyyyyyyyy
+ * When x = 0: y is the high 10 bits of the codepoint
+ * x = 1: y is the low 10 bits of the codepoint
+ *
+ * Check for a surrogate pair (high or low) */
+ if ((codepoint & 0xF800) == 0xD800) {
+ /* Error if the 1st surrogate is not high */
+ if (codepoint & 0x400)
+ return -1;
+
+ /* Ensure the next code is a unicode escape */
+ if (*(json->ptr + escape_len) != '\\' ||
+ *(json->ptr + escape_len + 1) != 'u') {
+ return -1;
+ }
+
+ /* Fetch the next codepoint */
+ surrogate_low = decode_hex4(json->ptr + 2 + escape_len);
+ if (surrogate_low < 0)
+ return -1;
+
+ /* Error if the 2nd code is not a low surrogate */
+ if ((surrogate_low & 0xFC00) != 0xDC00)
+ return -1;
+
+ /* Calculate Unicode codepoint */
+ codepoint = (codepoint & 0x3FF) << 10;
+ surrogate_low &= 0x3FF;
+ codepoint = (codepoint | surrogate_low) + 0x10000;
+ escape_len = 12;
+ }
+
+ /* Convert codepoint to UTF-8 */
+ len = codepoint_to_utf8(utf8, codepoint);
+ if (!len)
+ return -1;
+
+ /* Append bytes and advance parse index */
+ strbuf_append_mem_unsafe(json->tmp, utf8, len);
+ json->ptr += escape_len;
+
+ return 0;
+}
+
+static void json_set_token_error(json_token_t *token, json_parse_t *json,
+ const char *errtype)
+{
+ token->type = T_ERROR;
+ token->index = json->ptr - json->data;
+ token->value.string = errtype;
+}
+
+static void json_next_string_token(json_parse_t *json, json_token_t *token)
+{
+ char *escape2char = json->cfg->escape2char;
+ char ch;
+
+ /* Caller must ensure a string is next */
+ assert(*json->ptr == '"');
+
+ /* Skip " */
+ json->ptr++;
+
+ /* json->tmp is the temporary strbuf used to accumulate the
+ * decoded string value.
+ * json->tmp is sized to handle JSON containing only a string value.
+ */
+ strbuf_reset(json->tmp);
+
+ while ((ch = *json->ptr) != '"') {
+ if (!ch) {
+ /* Premature end of the string */
+ json_set_token_error(token, json, "unexpected end of string");
+ return;
+ }
+
+ /* Handle escapes */
+ if (ch == '\\') {
+ /* Fetch escape character */
+ ch = *(json->ptr + 1);
+
+ /* Translate escape code and append to tmp string */
+ ch = escape2char[(unsigned char)ch];
+ if (ch == 'u') {
+ if (json_append_unicode_escape(json) == 0)
+ continue;
+
+ json_set_token_error(token, json,
+ "invalid unicode escape code");
+ return;
+ }
+ if (!ch) {
+ json_set_token_error(token, json, "invalid escape code");
+ return;
+ }
+
+ /* Skip '\' */
+ json->ptr++;
+ }
+ /* Append normal character or translated single character
+ * Unicode escapes are handled above */
+ strbuf_append_char_unsafe(json->tmp, ch);
+ json->ptr++;
+ }
+ json->ptr++; /* Eat final quote (") */
+
+ strbuf_ensure_null(json->tmp);
+
+ token->type = T_STRING;
+ token->value.string = strbuf_string(json->tmp, &token->string_len);
+}
+
+/* JSON numbers should take the following form:
+ * -?(0|[1-9]|[1-9][0-9]+)(.[0-9]+)?([eE][-+]?[0-9]+)?
+ *
+ * json_next_number_token() uses strtod() which allows other forms:
+ * - numbers starting with '+'
+ * - NaN, -NaN, infinity, -infinity
+ * - hexadecimal numbers
+ * - numbers with leading zeros
+ *
+ * json_is_invalid_number() detects "numbers" which may pass strtod()'s
+ * error checking, but should not be allowed with strict JSON.
+ *
+ * json_is_invalid_number() may pass numbers which cause strtod()
+ * to generate an error.
+ */
+static int json_is_invalid_number(json_parse_t *json)
+{
+ const char *p = json->ptr;
+
+ /* Reject numbers starting with + */
+ if (*p == '+')
+ return 1;
+
+ /* Skip minus sign if it exists */
+ if (*p == '-')
+ p++;
+
+ /* Reject numbers starting with 0x, or leading zeros */
+ if (*p == '0') {
+ int ch2 = *(p + 1);
+
+ if ((ch2 | 0x20) == 'x' || /* Hex */
+ ('0' <= ch2 && ch2 <= '9')) /* Leading zero */
+ return 1;
+
+ return 0;
+ } else if (*p <= '9') {
+ return 0; /* Ordinary number */
+ }
+
+ /* Reject inf/nan */
+ if (!strncasecmp(p, "inf", 3))
+ return 1;
+ if (!strncasecmp(p, "nan", 3))
+ return 1;
+
+ /* Pass all other numbers which may still be invalid, but
+ * strtod() will catch them. */
+ return 0;
+}
+
+static void json_next_number_token(json_parse_t *json, json_token_t *token)
+{
+ char *endptr;
+
+ token->type = T_NUMBER;
+ token->value.number = fpconv_strtod(json->ptr, &endptr);
+ if (json->ptr == endptr)
+ json_set_token_error(token, json, "invalid number");
+ else
+ json->ptr = endptr; /* Skip the processed number */
+
+ return;
+}
+
+/* Fills in the token struct.
+ * T_STRING will return a pointer to the json_parse_t temporary string
+ * T_ERROR will leave the json->ptr pointer at the error.
+ */
+static void json_next_token(json_parse_t *json, json_token_t *token)
+{
+ const json_token_type_t *ch2token = json->cfg->ch2token;
+ int ch;
+
+ /* Eat whitespace. */
+ while (1) {
+ ch = (unsigned char)*(json->ptr);
+ token->type = ch2token[ch];
+ if (token->type != T_WHITESPACE)
+ break;
+ json->ptr++;
+ }
+
+ /* Store location of new token. Required when throwing errors
+ * for unexpected tokens (syntax errors). */
+ token->index = json->ptr - json->data;
+
+ /* Don't advance the pointer for an error or the end */
+ if (token->type == T_ERROR) {
+ json_set_token_error(token, json, "invalid token");
+ return;
+ }
+
+ if (token->type == T_END) {
+ return;
+ }
+
+ /* Found a known single character token, advance index and return */
+ if (token->type != T_UNKNOWN) {
+ json->ptr++;
+ return;
+ }
+
+ /* Process characters which triggered T_UNKNOWN
+ *
+ * Must use strncmp() to match the front of the JSON string.
+ * JSON identifier must be lowercase.
+ * When strict_numbers if disabled, either case is allowed for
+ * Infinity/NaN (since we are no longer following the spec..) */
+ if (ch == '"') {
+ json_next_string_token(json, token);
+ return;
+ } else if (ch == '-' || ('0' <= ch && ch <= '9')) {
+ if (!json->cfg->decode_invalid_numbers && json_is_invalid_number(json)) {
+ json_set_token_error(token, json, "invalid number");
+ return;
+ }
+ json_next_number_token(json, token);
+ return;
+ } else if (!strncmp(json->ptr, "true", 4)) {
+ token->type = T_BOOLEAN;
+ token->value.boolean = 1;
+ json->ptr += 4;
+ return;
+ } else if (!strncmp(json->ptr, "false", 5)) {
+ token->type = T_BOOLEAN;
+ token->value.boolean = 0;
+ json->ptr += 5;
+ return;
+ } else if (!strncmp(json->ptr, "null", 4)) {
+ token->type = T_NULL;
+ json->ptr += 4;
+ return;
+ } else if (json->cfg->decode_invalid_numbers &&
+ json_is_invalid_number(json)) {
+ /* When decode_invalid_numbers is enabled, only attempt to process
+ * numbers we know are invalid JSON (Inf, NaN, hex)
+ * This is required to generate an appropriate token error,
+ * otherwise all bad tokens will register as "invalid number"
+ */
+ json_next_number_token(json, token);
+ return;
+ }
+
+ /* Token starts with t/f/n but isn't recognised above. */
+ json_set_token_error(token, json, "invalid token");
+}
+
+/* This function does not return.
+ * DO NOT CALL WITH DYNAMIC MEMORY ALLOCATED.
+ * The only supported exception is the temporary parser string
+ * json->tmp struct.
+ * json and token should exist on the stack somewhere.
+ * luaL_error() will long_jmp and release the stack */
+static void json_throw_parse_error(lua_State *l, json_parse_t *json,
+ const char *exp, json_token_t *token)
+{
+ const char *found;
+
+ strbuf_free(json->tmp);
+
+ if (token->type == T_ERROR)
+ found = token->value.string;
+ else
+ found = json_token_type_name[token->type];
+
+ /* Note: token->index is 0 based, display starting from 1 */
+ luaL_error(l, "Expected %s but found %s at character %d",
+ exp, found, token->index + 1);
+}
+
+static inline void json_decode_ascend(json_parse_t *json)
+{
+ json->current_depth--;
+}
+
+static void json_decode_descend(lua_State *l, json_parse_t *json, int slots)
+{
+ json->current_depth++;
+
+ if (json->current_depth <= json->cfg->decode_max_depth &&
+ lua_checkstack(l, slots)) {
+ return;
+ }
+
+ strbuf_free(json->tmp);
+ luaL_error(l, "Found too many nested data structures (%d) at character %d",
+ json->current_depth, json->ptr - json->data);
+}
+
+static void json_parse_object_context(lua_State *l, json_parse_t *json)
+{
+ json_token_t token;
+
+ /* 3 slots required:
+ * .., table, key, value */
+ json_decode_descend(l, json, 3);
+
+ lua_newtable(l);
+
+ json_next_token(json, &token);
+
+ /* Handle empty objects */
+ if (token.type == T_OBJ_END) {
+ nlua_pushref(l, nlua_empty_dict_ref); \
+ lua_setmetatable(l, -2); \
+ json_decode_ascend(json);
+ return;
+ }
+
+ while (1) {
+ if (token.type != T_STRING)
+ json_throw_parse_error(l, json, "object key string", &token);
+
+ /* Push key */
+ lua_pushlstring(l, token.value.string, token.string_len);
+
+ json_next_token(json, &token);
+ if (token.type != T_COLON)
+ json_throw_parse_error(l, json, "colon", &token);
+
+ /* Fetch value */
+ json_next_token(json, &token);
+ json_process_value(l, json, &token, json->options->luanil_object);
+
+ /* Set key = value */
+ lua_rawset(l, -3);
+
+ json_next_token(json, &token);
+
+ if (token.type == T_OBJ_END) {
+ json_decode_ascend(json);
+ return;
+ }
+
+ if (token.type != T_COMMA)
+ json_throw_parse_error(l, json, "comma or object end", &token);
+
+ json_next_token(json, &token);
+ }
+}
+
+/* Handle the array context */
+static void json_parse_array_context(lua_State *l, json_parse_t *json)
+{
+ json_token_t token;
+ int i;
+
+ /* 2 slots required:
+ * .., table, value */
+ json_decode_descend(l, json, 2);
+
+ lua_newtable(l);
+
+ /* set array_mt on the table at the top of the stack */
+ if (json->cfg->decode_array_with_array_mt) {
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_array));
+ lua_rawget(l, LUA_REGISTRYINDEX);
+ lua_setmetatable(l, -2);
+ }
+
+ json_next_token(json, &token);
+
+ /* Handle empty arrays */
+ if (token.type == T_ARR_END) {
+ json_decode_ascend(json);
+ return;
+ }
+
+ for (i = 1; ; i++) {
+ json_process_value(l, json, &token, json->options->luanil_array);
+ lua_rawseti(l, -2, i); /* arr[i] = value */
+
+ json_next_token(json, &token);
+
+ if (token.type == T_ARR_END) {
+ json_decode_ascend(json);
+ return;
+ }
+
+ if (token.type != T_COMMA)
+ json_throw_parse_error(l, json, "comma or array end", &token);
+
+ json_next_token(json, &token);
+ }
+}
+
+/* Handle the "value" context */
+static void json_process_value(lua_State *l, json_parse_t *json,
+ json_token_t *token, bool use_luanil)
+{
+ switch (token->type) {
+ case T_STRING:
+ lua_pushlstring(l, token->value.string, token->string_len);
+ break;;
+ case T_NUMBER:
+ lua_pushnumber(l, token->value.number);
+ break;;
+ case T_BOOLEAN:
+ lua_pushboolean(l, token->value.boolean);
+ break;;
+ case T_OBJ_BEGIN:
+ json_parse_object_context(l, json);
+ break;;
+ case T_ARR_BEGIN:
+ json_parse_array_context(l, json);
+ break;;
+ case T_NULL:
+ if (use_luanil) {
+ lua_pushnil(l);
+ } else {
+ nlua_pushref(l, nlua_nil_ref);
+ }
+ break;;
+ default:
+ json_throw_parse_error(l, json, "value", token);
+ }
+}
+
+static int json_decode(lua_State *l)
+{
+ json_parse_t json;
+ json_token_t token;
+ json_options_t options = { .luanil_object = false, .luanil_array = false };
+
+
+ size_t json_len;
+
+ switch (lua_gettop(l)) {
+ case 1:
+ break;
+ case 2:
+ luaL_checktype(l, 2, LUA_TTABLE);
+ lua_getfield(l, 2, "luanil");
+
+ /* We only handle the luanil option for now */
+ if (lua_isnil(l, -1)) {
+ lua_pop(l, 1);
+ break;
+ }
+
+ luaL_checktype(l, -1, LUA_TTABLE);
+
+ lua_getfield(l, -1, "object");
+ if (!lua_isnil(l, -1)) {
+ options.luanil_object = true;
+ }
+ lua_pop(l, 1);
+
+ lua_getfield(l, -1, "array");
+ if (!lua_isnil(l, -1)) {
+ options.luanil_array = true;
+ }
+ /* Also pop the luanil table */
+ lua_pop(l, 2);
+ break;
+ default:
+ return luaL_error (l, "expected 1 or 2 arguments");
+ }
+
+ json.cfg = json_fetch_config(l);
+ json.data = luaL_checklstring(l, 1, &json_len);
+ json.options = &options;
+ json.current_depth = 0;
+ json.ptr = json.data;
+
+ /* Detect Unicode other than UTF-8 (see RFC 4627, Sec 3)
+ *
+ * CJSON can support any simple data type, hence only the first
+ * character is guaranteed to be ASCII (at worst: '"'). This is
+ * still enough to detect whether the wrong encoding is in use. */
+ if (json_len >= 2 && (!json.data[0] || !json.data[1]))
+ luaL_error(l, "JSON parser does not support UTF-16 or UTF-32");
+
+ /* Ensure the temporary buffer can hold the entire string.
+ * This means we no longer need to do length checks since the decoded
+ * string must be smaller than the entire json string */
+ json.tmp = strbuf_new(json_len);
+
+ json_next_token(&json, &token);
+ json_process_value(l, &json, &token, json.options->luanil_object);
+
+ /* Ensure there is no more input left */
+ json_next_token(&json, &token);
+
+ if (token.type != T_END)
+ json_throw_parse_error(l, &json, "the end", &token);
+
+ strbuf_free(json.tmp);
+
+ return 1;
+}
+
+/* ===== INITIALISATION ===== */
+
+#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
+/* Compatibility for Lua 5.1 and older LuaJIT.
+ *
+ * compat_luaL_setfuncs() is used to create a module table where the functions
+ * have json_config_t as their first upvalue. Code borrowed from Lua 5.2
+ * source's luaL_setfuncs().
+ */
+static void compat_luaL_setfuncs(lua_State *l, const luaL_Reg *reg, int nup)
+{
+ int i;
+
+ luaL_checkstack(l, nup, "too many upvalues");
+ for (; reg->name != NULL; reg++) { /* fill the table with given functions */
+ for (i = 0; i < nup; i++) /* copy upvalues to the top */
+ lua_pushvalue(l, -nup);
+ lua_pushcclosure(l, reg->func, nup); /* closure with those upvalues */
+ lua_setfield(l, -(nup + 2), reg->name);
+ }
+ lua_pop(l, nup); /* remove upvalues */
+}
+#else
+#define compat_luaL_setfuncs(L, reg, nup) luaL_setfuncs(L, reg, nup)
+#endif
+
+/* Call target function in protected mode with all supplied args.
+ * Assumes target function only returns a single non-nil value.
+ * Convert and return thrown errors as: nil, "error message" */
+static int json_protect_conversion(lua_State *l)
+{
+ int err;
+
+ /* Deliberately throw an error for invalid arguments */
+ luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument");
+
+ /* pcall() the function stored as upvalue(1) */
+ lua_pushvalue(l, lua_upvalueindex(1));
+ lua_insert(l, 1);
+ err = lua_pcall(l, 1, 1, 0);
+ if (!err)
+ return 1;
+
+ if (err == LUA_ERRRUN) {
+ lua_pushnil(l);
+ lua_insert(l, -2);
+ return 2;
+ }
+
+ /* Since we are not using a custom error handler, the only remaining
+ * errors are memory related */
+ return luaL_error(l, "Memory allocation error in CJSON protected call");
+}
+
+/* Return cjson module table */
+int lua_cjson_new(lua_State *l)
+{
+ luaL_Reg reg[] = {
+ { "encode", json_encode },
+ { "decode", json_decode },
+ { "encode_empty_table_as_object", json_cfg_encode_empty_table_as_object },
+ { "decode_array_with_array_mt", json_cfg_decode_array_with_array_mt },
+ { "encode_sparse_array", json_cfg_encode_sparse_array },
+ { "encode_max_depth", json_cfg_encode_max_depth },
+ { "decode_max_depth", json_cfg_decode_max_depth },
+ { "encode_number_precision", json_cfg_encode_number_precision },
+ { "encode_keep_buffer", json_cfg_encode_keep_buffer },
+ { "encode_invalid_numbers", json_cfg_encode_invalid_numbers },
+ { "decode_invalid_numbers", json_cfg_decode_invalid_numbers },
+ { "encode_escape_forward_slash", json_cfg_encode_escape_forward_slash },
+ { "new", lua_cjson_new },
+ { NULL, NULL }
+ };
+
+ /* Initialise number conversions */
+ fpconv_init();
+
+ /* Test if array metatables are in registry */
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_empty_array));
+ lua_rawget(l, LUA_REGISTRYINDEX);
+ if (lua_isnil(l, -1)) {
+ /* Create array metatables.
+ *
+ * If multiple calls to lua_cjson_new() are made,
+ * this prevents overriding the tables at the given
+ * registry's index with a new one.
+ */
+ lua_pop(l, 1);
+
+ /* empty_array_mt */
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_empty_array));
+ lua_newtable(l);
+ lua_rawset(l, LUA_REGISTRYINDEX);
+
+ /* array_mt */
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_array));
+ lua_newtable(l);
+ lua_rawset(l, LUA_REGISTRYINDEX);
+ }
+
+ /* cjson module table */
+ lua_newtable(l);
+
+ /* Register functions with config data as upvalue */
+ json_create_config(l);
+ compat_luaL_setfuncs(l, reg, 1);
+
+ /* Set cjson.null */
+ nlua_pushref(l, nlua_nil_ref);
+ lua_setfield(l, -2, "null");
+
+ /* Set cjson.empty_array_mt */
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_empty_array));
+ lua_rawget(l, LUA_REGISTRYINDEX);
+ lua_setfield(l, -2, "empty_array_mt");
+
+ /* Set cjson.array_mt */
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_array));
+ lua_rawget(l, LUA_REGISTRYINDEX);
+ lua_setfield(l, -2, "array_mt");
+
+ /* Set cjson.empty_array */
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_array));
+ lua_setfield(l, -2, "empty_array");
+
+ /* Set module name / version fields */
+ lua_pushliteral(l, CJSON_MODNAME);
+ lua_setfield(l, -2, "_NAME");
+ lua_pushliteral(l, CJSON_VERSION);
+ lua_setfield(l, -2, "_VERSION");
+
+ return 1;
+}
+
+/* Return cjson.safe module table */
+static int lua_cjson_safe_new(lua_State *l)
+{
+ const char *func[] = { "decode", "encode", NULL };
+ int i;
+
+ lua_cjson_new(l);
+
+ /* Fix new() method */
+ lua_pushcfunction(l, lua_cjson_safe_new);
+ lua_setfield(l, -2, "new");
+
+ for (i = 0; func[i]; i++) {
+ lua_getfield(l, -1, func[i]);
+ lua_pushcclosure(l, json_protect_conversion, 1);
+ lua_setfield(l, -2, func[i]);
+ }
+
+ return 1;
+}
+
+int luaopen_cjson(lua_State *l)
+{
+ lua_cjson_new(l);
+
+#ifdef ENABLE_CJSON_GLOBAL
+ /* Register a global "cjson" table. */
+ lua_pushvalue(l, -1);
+ lua_setglobal(l, CJSON_MODNAME);
+#endif
+
+ /* Return cjson table */
+ return 1;
+}
+
+int luaopen_cjson_safe(lua_State *l)
+{
+ lua_cjson_safe_new(l);
+
+ /* Return cjson.safe table */
+ return 1;
+}
+
+/* vi:ai et sw=4 ts=4:
+ */
diff --git a/src/cjson/lua_cjson.h b/src/cjson/lua_cjson.h
new file mode 100644
index 0000000000..3f70b679be
--- /dev/null
+++ b/src/cjson/lua_cjson.h
@@ -0,0 +1,10 @@
+#ifndef CJSON_LUACJSON_H
+#define CJSON_LUACJSON_H
+
+#include "lua.h"
+
+int lua_cjson_new(lua_State *l);
+int luaopen_cjson(lua_State *l);
+int luaopen_cjson_safe(lua_State *l);
+
+#endif // CJSON_LUACJSON_H
diff --git a/src/cjson/strbuf.c b/src/cjson/strbuf.c
new file mode 100644
index 0000000000..f0f7f4b9a3
--- /dev/null
+++ b/src/cjson/strbuf.c
@@ -0,0 +1,251 @@
+/* strbuf - String buffer routines
+ *
+ * Copyright (c) 2010-2012 Mark Pulford <mark@kyne.com.au>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "strbuf.h"
+
+static void die(const char *fmt, ...)
+{
+ va_list arg;
+
+ va_start(arg, fmt);
+ vfprintf(stderr, fmt, arg);
+ va_end(arg);
+ fprintf(stderr, "\n");
+
+ exit(-1);
+}
+
+void strbuf_init(strbuf_t *s, int len)
+{
+ int size;
+
+ if (len <= 0)
+ size = STRBUF_DEFAULT_SIZE;
+ else
+ size = len + 1; /* \0 terminator */
+
+ s->buf = NULL;
+ s->size = size;
+ s->length = 0;
+ s->increment = STRBUF_DEFAULT_INCREMENT;
+ s->dynamic = 0;
+ s->reallocs = 0;
+ s->debug = 0;
+
+ s->buf = malloc(size);
+ if (!s->buf)
+ die("Out of memory");
+
+ strbuf_ensure_null(s);
+}
+
+strbuf_t *strbuf_new(int len)
+{
+ strbuf_t *s;
+
+ s = malloc(sizeof(strbuf_t));
+ if (!s)
+ die("Out of memory");
+
+ strbuf_init(s, len);
+
+ /* Dynamic strbuf allocation / deallocation */
+ s->dynamic = 1;
+
+ return s;
+}
+
+void strbuf_set_increment(strbuf_t *s, int increment)
+{
+ /* Increment > 0: Linear buffer growth rate
+ * Increment < -1: Exponential buffer growth rate */
+ if (increment == 0 || increment == -1)
+ die("BUG: Invalid string increment");
+
+ s->increment = increment;
+}
+
+static inline void debug_stats(strbuf_t *s)
+{
+ if (s->debug) {
+ fprintf(stderr, "strbuf(%lx) reallocs: %d, length: %d, size: %d\n",
+ (long)s, s->reallocs, s->length, s->size);
+ }
+}
+
+/* If strbuf_t has not been dynamically allocated, strbuf_free() can
+ * be called any number of times strbuf_init() */
+void strbuf_free(strbuf_t *s)
+{
+ debug_stats(s);
+
+ if (s->buf) {
+ free(s->buf);
+ s->buf = NULL;
+ }
+ if (s->dynamic)
+ free(s);
+}
+
+char *strbuf_free_to_string(strbuf_t *s, int *len)
+{
+ char *buf;
+
+ debug_stats(s);
+
+ strbuf_ensure_null(s);
+
+ buf = s->buf;
+ if (len)
+ *len = s->length;
+
+ if (s->dynamic)
+ free(s);
+
+ return buf;
+}
+
+static int calculate_new_size(strbuf_t *s, int len)
+{
+ int reqsize, newsize;
+
+ if (len <= 0)
+ die("BUG: Invalid strbuf length requested");
+
+ /* Ensure there is room for optional NULL termination */
+ reqsize = len + 1;
+
+ /* If the user has requested to shrink the buffer, do it exactly */
+ if (s->size > reqsize)
+ return reqsize;
+
+ newsize = s->size;
+ if (s->increment < 0) {
+ /* Exponential sizing */
+ while (newsize < reqsize)
+ newsize *= -s->increment;
+ } else {
+ /* Linear sizing */
+ newsize = ((newsize + s->increment - 1) / s->increment) * s->increment;
+ }
+
+ return newsize;
+}
+
+
+/* Ensure strbuf can handle a string length bytes long (ignoring NULL
+ * optional termination). */
+void strbuf_resize(strbuf_t *s, int len)
+{
+ int newsize;
+
+ newsize = calculate_new_size(s, len);
+
+ if (s->debug > 1) {
+ fprintf(stderr, "strbuf(%lx) resize: %d => %d\n",
+ (long)s, s->size, newsize);
+ }
+
+ s->size = newsize;
+ s->buf = realloc(s->buf, s->size);
+ if (!s->buf)
+ die("Out of memory");
+ s->reallocs++;
+}
+
+void strbuf_append_string(strbuf_t *s, const char *str)
+{
+ int space, i;
+
+ space = strbuf_empty_length(s);
+
+ for (i = 0; str[i]; i++) {
+ if (space < 1) {
+ strbuf_resize(s, s->length + 1);
+ space = strbuf_empty_length(s);
+ }
+
+ s->buf[s->length] = str[i];
+ s->length++;
+ space--;
+ }
+}
+
+/* strbuf_append_fmt() should only be used when an upper bound
+ * is known for the output string. */
+void strbuf_append_fmt(strbuf_t *s, int len, const char *fmt, ...)
+{
+ va_list arg;
+ int fmt_len;
+
+ strbuf_ensure_empty_length(s, len);
+
+ va_start(arg, fmt);
+ fmt_len = vsnprintf(s->buf + s->length, len, fmt, arg);
+ va_end(arg);
+
+ if (fmt_len < 0)
+ die("BUG: Unable to convert number"); /* This should never happen.. */
+
+ s->length += fmt_len;
+}
+
+/* strbuf_append_fmt_retry() can be used when the there is no known
+ * upper bound for the output string. */
+void strbuf_append_fmt_retry(strbuf_t *s, const char *fmt, ...)
+{
+ va_list arg;
+ int fmt_len, try;
+ int empty_len;
+
+ /* If the first attempt to append fails, resize the buffer appropriately
+ * and try again */
+ for (try = 0; ; try++) {
+ va_start(arg, fmt);
+ /* Append the new formatted string */
+ /* fmt_len is the length of the string required, excluding the
+ * trailing NULL */
+ empty_len = strbuf_empty_length(s);
+ /* Add 1 since there is also space to store the terminating NULL. */
+ fmt_len = vsnprintf(s->buf + s->length, empty_len + 1, fmt, arg);
+ va_end(arg);
+
+ if (fmt_len <= empty_len)
+ break; /* SUCCESS */
+ if (try > 0)
+ die("BUG: length of formatted string changed");
+
+ strbuf_resize(s, s->length + fmt_len);
+ }
+
+ s->length += fmt_len;
+}
+
+/* vi:ai et sw=4 ts=4:
+ */
diff --git a/src/cjson/strbuf.h b/src/cjson/strbuf.h
new file mode 100644
index 0000000000..5df0b7bea3
--- /dev/null
+++ b/src/cjson/strbuf.h
@@ -0,0 +1,159 @@
+/* strbuf - String buffer routines
+ *
+ * Copyright (c) 2010-2012 Mark Pulford <mark@kyne.com.au>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+/* Workaround for MSVC */
+#ifdef _MSC_VER
+#define inline __inline
+#endif
+
+/* Size: Total bytes allocated to *buf
+ * Length: String length, excluding optional NULL terminator.
+ * Increment: Allocation increments when resizing the string buffer.
+ * Dynamic: True if created via strbuf_new()
+ */
+
+typedef struct {
+ char *buf;
+ int size;
+ int length;
+ int increment;
+ int dynamic;
+ int reallocs;
+ int debug;
+} strbuf_t;
+
+#ifndef STRBUF_DEFAULT_SIZE
+#define STRBUF_DEFAULT_SIZE 1023
+#endif
+#ifndef STRBUF_DEFAULT_INCREMENT
+#define STRBUF_DEFAULT_INCREMENT -2
+#endif
+
+/* Initialise */
+extern strbuf_t *strbuf_new(int len);
+extern void strbuf_init(strbuf_t *s, int len);
+extern void strbuf_set_increment(strbuf_t *s, int increment);
+
+/* Release */
+extern void strbuf_free(strbuf_t *s);
+extern char *strbuf_free_to_string(strbuf_t *s, int *len);
+
+/* Management */
+extern void strbuf_resize(strbuf_t *s, int len);
+static int strbuf_empty_length(strbuf_t *s);
+static int strbuf_length(strbuf_t *s);
+static char *strbuf_string(strbuf_t *s, int *len);
+static void strbuf_ensure_empty_length(strbuf_t *s, int len);
+static char *strbuf_empty_ptr(strbuf_t *s);
+static void strbuf_extend_length(strbuf_t *s, int len);
+
+/* Update */
+extern void strbuf_append_fmt(strbuf_t *s, int len, const char *fmt, ...);
+extern void strbuf_append_fmt_retry(strbuf_t *s, const char *format, ...);
+static void strbuf_append_mem(strbuf_t *s, const char *c, int len);
+extern void strbuf_append_string(strbuf_t *s, const char *str);
+static void strbuf_append_char(strbuf_t *s, const char c);
+static void strbuf_ensure_null(strbuf_t *s);
+
+/* Reset string for before use */
+static inline void strbuf_reset(strbuf_t *s)
+{
+ s->length = 0;
+}
+
+static inline int strbuf_allocated(strbuf_t *s)
+{
+ return s->buf != NULL;
+}
+
+/* Return bytes remaining in the string buffer
+ * Ensure there is space for a NULL terminator. */
+static inline int strbuf_empty_length(strbuf_t *s)
+{
+ return s->size - s->length - 1;
+}
+
+static inline void strbuf_ensure_empty_length(strbuf_t *s, int len)
+{
+ if (len > strbuf_empty_length(s))
+ strbuf_resize(s, s->length + len);
+}
+
+static inline char *strbuf_empty_ptr(strbuf_t *s)
+{
+ return s->buf + s->length;
+}
+
+static inline void strbuf_extend_length(strbuf_t *s, int len)
+{
+ s->length += len;
+}
+
+static inline int strbuf_length(strbuf_t *s)
+{
+ return s->length;
+}
+
+static inline void strbuf_append_char(strbuf_t *s, const char c)
+{
+ strbuf_ensure_empty_length(s, 1);
+ s->buf[s->length++] = c;
+}
+
+static inline void strbuf_append_char_unsafe(strbuf_t *s, const char c)
+{
+ s->buf[s->length++] = c;
+}
+
+static inline void strbuf_append_mem(strbuf_t *s, const char *c, int len)
+{
+ strbuf_ensure_empty_length(s, len);
+ memcpy(s->buf + s->length, c, len);
+ s->length += len;
+}
+
+static inline void strbuf_append_mem_unsafe(strbuf_t *s, const char *c, int len)
+{
+ memcpy(s->buf + s->length, c, len);
+ s->length += len;
+}
+
+static inline void strbuf_ensure_null(strbuf_t *s)
+{
+ s->buf[s->length] = 0;
+}
+
+static inline char *strbuf_string(strbuf_t *s, int *len)
+{
+ if (len)
+ *len = s->length;
+
+ return s->buf;
+}
+
+/* vi:ai et sw=4 ts=4:
+ */
diff --git a/src/clint.py b/src/clint.py
index e7d76366b0..4b7bf002e6 100755
--- a/src/clint.py
+++ b/src/clint.py
@@ -2544,6 +2544,7 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
r'(?<!\bPMap)'
r'(?<!\bArrayOf)'
r'(?<!\bDictionaryOf)'
+ r'(?<!\bDict)'
r'\((?:const )?(?:struct )?[a-zA-Z_]\w*(?: *\*(?:const)?)*\)'
r' +'
r'-?(?:\*+|&)?(?:\w+|\+\+|--|\()', cast_line)
diff --git a/src/mpack/conv.c b/src/mpack/conv.c
index 203b13fadb..6bd446ca49 100644
--- a/src/mpack/conv.c
+++ b/src/mpack/conv.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include "conv.h"
static int mpack_fits_single(double v);
@@ -298,7 +301,6 @@ MPACK_API double mpack_unpack_number(mpack_token_t t)
*/
if (!hi) {
assert(t.length <= 4);
- hi = 0;
lo = (~lo & (((mpack_uint32_t)1 << ((t.length * 8) - 1)) - 1));
} else {
hi = ~hi;
diff --git a/src/mpack/lmpack.c b/src/mpack/lmpack.c
index 99207246c8..24d27fd17a 100644
--- a/src/mpack/lmpack.c
+++ b/src/mpack/lmpack.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* This module exports three classes, and each instance of those classes has its
* own private registry for temporary reference storage(keeping state between
@@ -201,14 +204,14 @@ static void lmpack_pushnil(lua_State *L)
static mpack_uint32_t lmpack_objlen(lua_State *L, int *is_array)
{
size_t len, max;
- int isarr, type;
+ int isarr;
lua_Number n;
#ifndef NDEBUG
int top = lua_gettop(L);
assert(top);
#endif
- if ((type = lua_type(L, -1)) != LUA_TTABLE) {
+ if ((lua_type(L, -1)) != LUA_TTABLE) {
#if LUA_VERSION_NUM >= 502
len = lua_rawlen(L, -1);
#elif LUA_VERSION_NUM == 501
@@ -442,7 +445,6 @@ static int lmpack_unpacker_unpack_str(lua_State *L, Unpacker *unpacker,
if (rv == MPACK_NOMEM) {
unpacker->parser = lmpack_grow_parser(unpacker->parser);
if (!unpacker->parser) {
- unpacker->unpacking = 0;
return luaL_error(L, "failed to grow Unpacker capacity");
}
}
@@ -796,7 +798,6 @@ static int lmpack_packer_pack(lua_State *L)
if (result == MPACK_NOMEM) {
packer->parser = lmpack_grow_parser(packer->parser);
if (!packer->parser) {
- packer->packing = 0;
return luaL_error(L, "Failed to grow Packer capacity");
}
}
diff --git a/src/mpack/mpack_core.c b/src/mpack/mpack_core.c
index 0ad09bd46a..f8ca63b7a3 100644
--- a/src/mpack/mpack_core.c
+++ b/src/mpack/mpack_core.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <string.h>
#include "mpack_core.h"
diff --git a/src/mpack/object.c b/src/mpack/object.c
index 0c7759ee51..e2d893bc88 100644
--- a/src/mpack/object.c
+++ b/src/mpack/object.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <string.h>
#include "object.h"
diff --git a/src/mpack/rpc.c b/src/mpack/rpc.c
index 3b2b328065..2d251284ba 100644
--- a/src/mpack/rpc.c
+++ b/src/mpack/rpc.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <string.h>
#include "rpc.h"
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 331ab16dd7..185d55daed 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -27,6 +27,7 @@ set(BINARY_LIB_DIR ${PROJECT_BINARY_DIR}/lib/nvim/)
set(API_DISPATCH_GENERATOR ${GENERATOR_DIR}/gen_api_dispatch.lua)
set(API_UI_EVENTS_GENERATOR ${GENERATOR_DIR}/gen_api_ui_events.lua)
set(GENERATOR_C_GRAMMAR ${GENERATOR_DIR}/c_grammar.lua)
+set(GENERATOR_HASHY ${GENERATOR_DIR}/hashy.lua)
set(API_METADATA ${PROJECT_BINARY_DIR}/api_metadata.mpack)
set(FUNCS_DATA ${PROJECT_BINARY_DIR}/funcs_data.mpack)
set(LUA_API_C_BINDINGS ${GENERATED_DIR}/lua_api_c_bindings.generated.c)
@@ -42,12 +43,15 @@ set(GENERATED_UI_EVENTS_METADATA ${GENERATED_DIR}/api/private/ui_events_metadata
set(GENERATED_EX_CMDS_ENUM ${GENERATED_INCLUDES_DIR}/ex_cmds_enum.generated.h)
set(GENERATED_EX_CMDS_DEFS ${GENERATED_DIR}/ex_cmds_defs.generated.h)
set(GENERATED_FUNCS ${GENERATED_DIR}/funcs.generated.h)
+set(GENERATED_KEYSETS ${GENERATED_DIR}/keysets.generated.h)
+set(GENERATED_KEYSETS_DEFS ${GENERATED_DIR}/keysets_defs.generated.h)
set(GENERATED_EVENTS_ENUM ${GENERATED_INCLUDES_DIR}/auevents_enum.generated.h)
set(GENERATED_EVENTS_NAMES_MAP ${GENERATED_DIR}/auevents_name_map.generated.h)
set(GENERATED_OPTIONS ${GENERATED_DIR}/options.generated.h)
set(EX_CMDS_GENERATOR ${GENERATOR_DIR}/gen_ex_cmds.lua)
set(FUNCS_GENERATOR ${GENERATOR_DIR}/gen_eval.lua)
set(EVENTS_GENERATOR ${GENERATOR_DIR}/gen_events.lua)
+set(KEYSETS_GENERATOR ${GENERATOR_DIR}/gen_keysets.lua)
set(OPTIONS_GENERATOR ${GENERATOR_DIR}/gen_options.lua)
set(UNICODE_TABLES_GENERATOR ${GENERATOR_DIR}/gen_unicode_tables.lua)
set(UNICODE_DIR ${PROJECT_SOURCE_DIR}/unicode)
@@ -87,8 +91,8 @@ file(MAKE_DIRECTORY ${LINT_SUPPRESSES_ROOT}/src)
file(GLOB NVIM_SOURCES *.c)
file(GLOB NVIM_HEADERS *.h)
-file(GLOB EXTERNAL_SOURCES ../xdiff/*.c ../mpack/*.c)
-file(GLOB EXTERNAL_HEADERS ../xdiff/*.h ../mpack/*.h)
+file(GLOB EXTERNAL_SOURCES ../xdiff/*.c ../mpack/*.c ../cjson/*.c)
+file(GLOB EXTERNAL_HEADERS ../xdiff/*.h ../mpack/*.h ../cjson/*.h)
foreach(subdir
os
@@ -171,7 +175,7 @@ foreach(sfile ${CONV_SOURCES})
message(FATAL_ERROR "${sfile} doesn't exist (it was added to CONV_SOURCES)")
endif()
endforeach()
-# xdiff, mpack: inlined external project, we don't maintain it. #9306
+# xdiff, mpack, lua-cjson: inlined external project, we don't maintain it. #9306
list(APPEND CONV_SOURCES ${EXTERNAL_SOURCES})
if(NOT MSVC)
@@ -227,8 +231,6 @@ endfunction()
set(use_git_version 0)
if(NVIM_VERSION_MEDIUM)
message(STATUS "NVIM_VERSION_MEDIUM: ${NVIM_VERSION_MEDIUM}")
-elseif(${CMAKE_VERSION} VERSION_LESS "3.2.0")
- message(STATUS "Skipping version-string generation (requires CMake 3.2.0+)")
elseif(EXISTS ${PROJECT_SOURCE_DIR}/.git)
find_program(GIT_EXECUTABLE git)
if(GIT_EXECUTABLE)
@@ -261,6 +263,7 @@ foreach(sfile ${NVIM_SOURCES}
"${GENERATED_UI_EVENTS_CALL}"
"${GENERATED_UI_EVENTS_REMOTE}"
"${GENERATED_UI_EVENTS_BRIDGE}"
+ "${GENERATED_KEYSETS}"
)
get_filename_component(full_d ${sfile} PATH)
file(RELATIVE_PATH d "${CMAKE_CURRENT_LIST_DIR}" "${full_d}")
@@ -364,12 +367,14 @@ add_custom_command(
list(APPEND NVIM_GENERATED_FOR_HEADERS
"${GENERATED_EX_CMDS_ENUM}"
"${GENERATED_EVENTS_ENUM}"
+ "${GENERATED_KEYSETS_DEFS}"
)
list(APPEND NVIM_GENERATED_FOR_SOURCES
"${GENERATED_API_DISPATCH}"
"${GENERATED_EX_CMDS_DEFS}"
"${GENERATED_EVENTS_NAMES_MAP}"
+ "${GENERATED_KEYSETS}"
"${GENERATED_OPTIONS}"
"${GENERATED_UNICODE_TABLES}"
"${VIM_MODULE_FILE}"
@@ -404,6 +409,12 @@ add_custom_command(OUTPUT ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP}
DEPENDS ${EVENTS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/auevents.lua
)
+add_custom_command(OUTPUT ${GENERATED_KEYSETS} ${GENERATED_KEYSETS_DEFS}
+ COMMAND ${LUA_PRG} ${KEYSETS_GENERATOR}
+ ${CMAKE_CURRENT_LIST_DIR} ${LUA_SHARED_MODULE_SOURCE} ${GENERATED_KEYSETS} ${GENERATED_KEYSETS_DEFS}
+ DEPENDS ${KEYSETS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/api/keysets.lua ${GENERATOR_HASHY}
+)
+
add_custom_command(OUTPUT ${GENERATED_OPTIONS}
COMMAND ${LUA_PRG} ${OPTIONS_GENERATOR}
${CMAKE_CURRENT_LIST_DIR} ${GENERATED_OPTIONS}
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 8973f8fef6..31d44c68bf 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -418,7 +418,7 @@ void nvim_buf_set_lines(uint64_t channel_id, Buffer buffer, Integer start, Integ
try_start();
aco_save_T aco;
- aucmd_prepbuf(&aco, (buf_T *)buf);
+ aucmd_prepbuf(&aco, buf);
if (!MODIFIABLE(buf)) {
api_set_error(err, kErrorTypeException, "Buffer is not 'modifiable'");
@@ -624,7 +624,8 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In
if (replacement.size == 1) {
firstlen += last_part_len;
}
- char *first = xmallocz(firstlen), *last = NULL;
+ char *first = xmallocz(firstlen);
+ char *last = NULL;
memcpy(first, str_at_start, (size_t)start_col);
memcpy(first+start_col, first_item.data, first_item.size);
memchrsub(first+start_col, NUL, NL, first_item.size);
@@ -637,7 +638,7 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In
memcpy(last+last_item.size, str_at_end+end_col, last_part_len);
}
- char **lines = (new_len != 0) ? xcalloc(new_len, sizeof(char *)) : NULL;
+ char **lines = xcalloc(new_len, sizeof(char *));
lines[0] = first;
new_byte += (bcount_t)(first_item.size);
for (size_t i = 1; i < new_len-1; i++) {
@@ -656,7 +657,7 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In
try_start();
aco_save_T aco;
- aucmd_prepbuf(&aco, (buf_T *)buf);
+ aucmd_prepbuf(&aco, buf);
if (!MODIFIABLE(buf)) {
api_set_error(err, kErrorTypeException, "Buffer is not 'modifiable'");
@@ -858,7 +859,7 @@ ArrayOf(Dictionary) nvim_buf_get_keymap(Buffer buffer, String mode, Error *err)
/// @see |nvim_set_keymap()|
///
/// @param buffer Buffer handle, or 0 for current buffer
-void nvim_buf_set_keymap(Buffer buffer, String mode, String lhs, String rhs, Dictionary opts,
+void nvim_buf_set_keymap(Buffer buffer, String mode, String lhs, String rhs, Dict(keymap) *opts,
Error *err)
FUNC_API_SINCE(6)
{
@@ -874,8 +875,7 @@ void nvim_buf_del_keymap(Buffer buffer, String mode, String lhs, Error *err)
FUNC_API_SINCE(6)
{
String rhs = { .data = "", .size = 0 };
- Dictionary opts = ARRAY_DICT_INIT;
- modify_keymap(buffer, true, mode, lhs, rhs, opts, err);
+ modify_keymap(buffer, true, mode, lhs, rhs, NULL, err);
}
/// Gets a map of buffer-local |user-commands|.
@@ -885,22 +885,13 @@ void nvim_buf_del_keymap(Buffer buffer, String mode, String lhs, Error *err)
/// @param[out] err Error details, if any.
///
/// @returns Map of maps describing commands.
-Dictionary nvim_buf_get_commands(Buffer buffer, Dictionary opts, Error *err)
+Dictionary nvim_buf_get_commands(Buffer buffer, Dict(get_commands) *opts, Error *err)
FUNC_API_SINCE(4)
{
bool global = (buffer == -1);
- bool builtin = false;
-
- for (size_t i = 0; i < opts.size; i++) {
- String k = opts.items[i].key;
- Object v = opts.items[i].value;
- if (!strequal("builtin", k.data)) {
- api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data);
- return (Dictionary)ARRAY_DICT_INIT;
- }
- if (strequal("builtin", k.data)) {
- builtin = v.data.boolean;
- }
+ bool builtin = api_object_to_bool(opts->builtin, "builtin", false, err);
+ if (ERROR_SET(err)) {
+ return (Dictionary)ARRAY_DICT_INIT;
}
if (global) {
@@ -1118,14 +1109,96 @@ Boolean nvim_buf_is_valid(Buffer buffer)
return ret;
}
-/// Return a tuple (row,col) representing the position of the named mark.
+/// Deletes a named mark in the buffer. See |mark-motions|.
+///
+/// @note only deletes marks set in the buffer, if the mark is not set
+/// in the buffer it will return false.
+/// @param buffer Buffer to set the mark on
+/// @param name Mark name
+/// @return true if the mark was deleted, else false.
+/// @see |nvim_buf_set_mark()|
+/// @see |nvim_del_mark()|
+Boolean nvim_buf_del_mark(Buffer buffer, String name, Error *err)
+ FUNC_API_SINCE(8)
+{
+ bool res = false;
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+
+ if (!buf) {
+ return res;
+ }
+
+ if (name.size != 1) {
+ api_set_error(err, kErrorTypeValidation,
+ "Mark name must be a single character");
+ return res;
+ }
+
+ pos_T *pos = getmark_buf(buf, *name.data, false);
+
+ // pos point to NULL when there's no mark with name
+ if (pos == NULL) {
+ api_set_error(err, kErrorTypeValidation, "Invalid mark name: '%c'",
+ *name.data);
+ return res;
+ }
+
+ // pos->lnum is 0 when the mark is not valid in the buffer, or is not set.
+ if (pos->lnum != 0) {
+ // since the mark belongs to the buffer delete it.
+ res = set_mark(buf, name, 0, 0, err);
+ }
+
+ return res;
+}
+
+/// Sets a named mark in the given buffer, all marks are allowed
+/// file/uppercase, visual, last change, etc. See |mark-motions|.
+///
+/// Marks are (1,0)-indexed. |api-indexing|
+///
+/// @note Passing 0 as line deletes the mark
+///
+/// @param buffer Buffer to set the mark on
+/// @param name Mark name
+/// @param line Line number
+/// @param col Column/row number
+/// @return true if the mark was set, else false.
+/// @see |nvim_buf_del_mark()|
+/// @see |nvim_buf_get_mark()|
+Boolean nvim_buf_set_mark(Buffer buffer, String name, Integer line, Integer col, Error *err)
+ FUNC_API_SINCE(8)
+{
+ bool res = false;
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+
+ if (!buf) {
+ return res;
+ }
+
+ if (name.size != 1) {
+ api_set_error(err, kErrorTypeValidation,
+ "Mark name must be a single character");
+ return res;
+ }
+
+ res = set_mark(buf, name, line, col, err);
+
+ return res;
+}
+
+/// Returns a tuple (row,col) representing the position of the named mark. See
+/// |mark-motions|.
///
/// Marks are (1,0)-indexed. |api-indexing|
///
/// @param buffer Buffer handle, or 0 for current buffer
/// @param name Mark name
/// @param[out] err Error details, if any
-/// @return (row, col) tuple
+/// @return (row, col) tuple, (0, 0) if the mark is not set, or is an
+/// uppercase/file mark set in another buffer.
+/// @see |nvim_buf_set_mark()|
+/// @see |nvim_buf_del_mark()|
ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err)
FUNC_API_SINCE(1)
{
@@ -1267,7 +1340,7 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id,
if (extmark.row < 0) {
return rv;
}
- return extmark_to_array(extmark, false, (bool)details);
+ return extmark_to_array(extmark, false, details);
}
/// Gets extmarks in "traversal order" from a |charwise| region defined by
@@ -1415,6 +1488,10 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e
/// - end_col : ending col of the mark, 0-based exclusive.
/// - hl_group : name of the highlight group used to highlight
/// this mark.
+/// - hl_eol : when true, for a multiline highlight covering the
+/// EOL of a line, continue the highlight for the rest
+/// of the screen line (just like for diff and
+/// cursorline highlight).
/// - virt_text : virtual text to link to this mark.
/// A list of [text, highlight] tuples, each representing a
/// text chunk with specified highlight. `highlight` element
@@ -1442,10 +1519,28 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e
/// default
/// - "combine": combine with background text color
/// - "blend": blend with background text color.
-/// - hl_eol : when true, for a multiline highlight covering the
-/// EOL of a line, continue the highlight for the rest
-/// of the screen line (just like for diff and
-/// cursorline highlight).
+///
+/// - virt_lines : virtual lines to add next to this mark
+/// This should be an array over lines, where each line in
+/// turn is an array over [text, highlight] tuples. In
+/// general, buffer and window options do not affect the
+/// display of the text. In particular 'wrap'
+/// and 'linebreak' options do not take effect, so
+/// the number of extra screen lines will always match
+/// the size of the array. However the 'tabstop' buffer
+/// option is still used for hard tabs. By default lines are
+/// placed below the buffer line containing the mark.
+///
+/// Note: currently virtual lines are limited to one block
+/// per buffer. Thus setting a new mark disables any previous
+/// `virt_lines` decoration. However plugins should not rely
+/// on this behaviour, as this limitation is planned to be
+/// removed.
+///
+/// - virt_lines_above: place virtual lines above instead.
+/// - virt_lines_leftcol: Place extmarks in the leftmost
+/// column of the window, bypassing
+/// sign and number columns.
///
/// - ephemeral : for use with |nvim_set_decoration_provider|
/// callbacks. The mark will only be used for the current
@@ -1463,193 +1558,189 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e
/// @param[out] err Error details, if any
/// @return Id of the created/updated extmark
Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer col,
- Dictionary opts, Error *err)
+ Dict(set_extmark) *opts, Error *err)
FUNC_API_SINCE(7)
{
+ Decoration decor = DECORATION_INIT;
+
buf_T *buf = find_buffer_by_handle(buffer, err);
if (!buf) {
- return 0;
+ goto error;
}
if (!ns_initialized((uint64_t)ns_id)) {
api_set_error(err, kErrorTypeValidation, "Invalid ns_id");
- return 0;
+ goto error;
}
- bool ephemeral = false;
-
uint64_t id = 0;
+ if (opts->id.type == kObjectTypeInteger && opts->id.data.integer > 0) {
+ id = (uint64_t)opts->id.data.integer;
+ } else if (HAS_KEY(opts->id)) {
+ api_set_error(err, kErrorTypeValidation, "id is not a positive integer");
+ goto error;
+ }
+
int line2 = -1;
- Decoration decor = DECORATION_INIT;
+ if (opts->end_line.type == kObjectTypeInteger) {
+ Integer val = opts->end_line.data.integer;
+ if (val < 0 || val > buf->b_ml.ml_line_count) {
+ api_set_error(err, kErrorTypeValidation, "end_line value outside range");
+ goto error;
+ } else {
+ line2 = (int)val;
+ }
+ } else if (HAS_KEY(opts->end_line)) {
+ api_set_error(err, kErrorTypeValidation, "end_line is not an integer");
+ goto error;
+ }
+
colnr_T col2 = -1;
+ if (opts->end_col.type == kObjectTypeInteger) {
+ Integer val = opts->end_col.data.integer;
+ if (val < 0 || val > MAXCOL) {
+ api_set_error(err, kErrorTypeValidation, "end_col value outside range");
+ goto error;
+ } else {
+ col2 = (int)val;
+ }
+ } else if (HAS_KEY(opts->end_col)) {
+ api_set_error(err, kErrorTypeValidation, "end_col is not an integer");
+ goto error;
+ }
- bool right_gravity = true;
- bool end_right_gravity = false;
- bool end_gravity_set = false;
+ if (HAS_KEY(opts->hl_group)) {
+ decor.hl_id = object_to_hl_id(opts->hl_group, "hl_group", err);
+ if (ERROR_SET(err)) {
+ goto error;
+ }
+ }
- for (size_t i = 0; i < opts.size; i++) {
- String k = opts.items[i].key;
- Object *v = &opts.items[i].value;
- if (strequal("id", k.data)) {
- if (v->type != kObjectTypeInteger || v->data.integer <= 0) {
- api_set_error(err, kErrorTypeValidation,
- "id is not a positive integer");
- goto error;
- }
+ if (opts->virt_text.type == kObjectTypeArray) {
+ decor.virt_text = parse_virt_text(opts->virt_text.data.array, err,
+ &decor.virt_text_width);
+ if (ERROR_SET(err)) {
+ goto error;
+ }
+ } else if (HAS_KEY(opts->virt_text)) {
+ api_set_error(err, kErrorTypeValidation, "virt_text is not an Array");
+ goto error;
+ }
+
+ if (opts->virt_text_pos.type == kObjectTypeString) {
+ String str = opts->virt_text_pos.data.string;
+ if (strequal("eol", str.data)) {
+ decor.virt_text_pos = kVTEndOfLine;
+ } else if (strequal("overlay", str.data)) {
+ decor.virt_text_pos = kVTOverlay;
+ } else if (strequal("right_align", str.data)) {
+ decor.virt_text_pos = kVTRightAlign;
+ } else {
+ api_set_error(err, kErrorTypeValidation, "virt_text_pos: invalid value");
+ goto error;
+ }
+ } else if (HAS_KEY(opts->virt_text_pos)) {
+ api_set_error(err, kErrorTypeValidation, "virt_text_pos is not a String");
+ goto error;
+ }
- id = (uint64_t)v->data.integer;
- } else if (strequal("end_line", k.data)) {
- if (v->type != kObjectTypeInteger) {
- api_set_error(err, kErrorTypeValidation,
- "end_line is not an integer");
- goto error;
- }
- if (v->data.integer < 0 || v->data.integer > buf->b_ml.ml_line_count) {
- api_set_error(err, kErrorTypeValidation,
- "end_line value outside range");
- goto error;
- }
+ if (opts->virt_text_win_col.type == kObjectTypeInteger) {
+ decor.col = (int)opts->virt_text_win_col.data.integer;
+ decor.virt_text_pos = kVTWinCol;
+ } else if (HAS_KEY(opts->virt_text_win_col)) {
+ api_set_error(err, kErrorTypeValidation,
+ "virt_text_win_col is not a Number of the correct size");
+ goto error;
+ }
- line2 = (int)v->data.integer;
- } else if (strequal("end_col", k.data)) {
- if (v->type != kObjectTypeInteger) {
- api_set_error(err, kErrorTypeValidation,
- "end_col is not an integer");
- goto error;
- }
- if (v->data.integer < 0 || v->data.integer > MAXCOL) {
- api_set_error(err, kErrorTypeValidation,
- "end_col value outside range");
- goto error;
- }
+#define OPTION_TO_BOOL(target, name, val) \
+ target = api_object_to_bool(opts-> name, #name, val, err); \
+ if (ERROR_SET(err)) { \
+ goto error; \
+ }
- col2 = (colnr_T)v->data.integer;
- } else if (strequal("hl_group", k.data)) {
- String hl_group;
- switch (v->type) {
- case kObjectTypeString:
- hl_group = v->data.string;
- decor.hl_id = syn_check_group((char_u *)(hl_group.data),
- (int)hl_group.size);
- break;
- case kObjectTypeInteger:
- decor.hl_id = (int)v->data.integer;
- break;
- default:
- api_set_error(err, kErrorTypeValidation,
- "hl_group is not valid.");
- goto error;
- }
- } else if (strequal("virt_text", k.data)) {
- if (v->type != kObjectTypeArray) {
- api_set_error(err, kErrorTypeValidation,
- "virt_text is not an Array");
- goto error;
- }
- decor.virt_text = parse_virt_text(v->data.array, err,
- &decor.virt_text_width);
- if (ERROR_SET(err)) {
- goto error;
- }
- } else if (strequal("virt_text_pos", k.data)) {
- if (v->type != kObjectTypeString) {
- api_set_error(err, kErrorTypeValidation,
- "virt_text_pos is not a String");
- goto error;
- }
- String str = v->data.string;
- if (strequal("eol", str.data)) {
- decor.virt_text_pos = kVTEndOfLine;
- } else if (strequal("overlay", str.data)) {
- decor.virt_text_pos = kVTOverlay;
- } else if (strequal("right_align", str.data)) {
- decor.virt_text_pos = kVTRightAlign;
- } else {
- api_set_error(err, kErrorTypeValidation,
- "virt_text_pos: invalid value");
- goto error;
- }
- } else if (strequal("virt_text_win_col", k.data)) {
- if (v->type != kObjectTypeInteger) {
- api_set_error(err, kErrorTypeValidation,
- "virt_text_win_col is not a Number of the correct size");
- goto error;
- }
+ OPTION_TO_BOOL(decor.virt_text_hide, virt_text_hide, false);
+ OPTION_TO_BOOL(decor.hl_eol, hl_eol, false);
- decor.col = (int)v->data.integer;
- decor.virt_text_pos = kVTWinCol;
- } else if (strequal("virt_text_hide", k.data)) {
- decor.virt_text_hide = api_object_to_bool(*v,
- "virt_text_hide", false, err);
- if (ERROR_SET(err)) {
- goto error;
- }
- } else if (strequal("hl_eol", k.data)) {
- decor.hl_eol = api_object_to_bool(*v, "hl_eol", false, err);
- if (ERROR_SET(err)) {
- goto error;
- }
- } else if (strequal("hl_mode", k.data)) {
- if (v->type != kObjectTypeString) {
- api_set_error(err, kErrorTypeValidation,
- "hl_mode is not a String");
- goto error;
- }
- String str = v->data.string;
- if (strequal("replace", str.data)) {
- decor.hl_mode = kHlModeReplace;
- } else if (strequal("combine", str.data)) {
- decor.hl_mode = kHlModeCombine;
- } else if (strequal("blend", str.data)) {
- decor.hl_mode = kHlModeBlend;
- } else {
- api_set_error(err, kErrorTypeValidation,
- "virt_text_pos: invalid value");
+ if (opts->hl_mode.type == kObjectTypeString) {
+ String str = opts->hl_mode.data.string;
+ if (strequal("replace", str.data)) {
+ decor.hl_mode = kHlModeReplace;
+ } else if (strequal("combine", str.data)) {
+ decor.hl_mode = kHlModeCombine;
+ } else if (strequal("blend", str.data)) {
+ decor.hl_mode = kHlModeBlend;
+ } else {
+ api_set_error(err, kErrorTypeValidation,
+ "virt_text_pos: invalid value");
+ goto error;
+ }
+ } else if (HAS_KEY(opts->hl_mode)) {
+ api_set_error(err, kErrorTypeValidation, "hl_mode is not a String");
+ goto error;
+ }
+
+ VirtLines virt_lines = KV_INITIAL_VALUE;
+ bool virt_lines_above = false;
+ bool virt_lines_leftcol = false;
+
+ if (opts->virt_lines.type == kObjectTypeArray) {
+ Array a = opts->virt_lines.data.array;
+ for (size_t j = 0; j < a.size; j++) {
+ if (a.items[j].type != kObjectTypeArray) {
+ api_set_error(err, kErrorTypeValidation, "virt_text_line item is not an Array");
goto error;
}
- } else if (strequal("ephemeral", k.data)) {
- ephemeral = api_object_to_bool(*v, "ephemeral", false, err);
+ int dummig;
+ VirtText jtem = parse_virt_text(a.items[j].data.array, err, &dummig);
+ kv_push(virt_lines, jtem);
if (ERROR_SET(err)) {
goto error;
}
- } else if (strequal("priority", k.data)) {
- if (v->type != kObjectTypeInteger) {
- api_set_error(err, kErrorTypeValidation,
- "priority is not a Number of the correct size");
- goto error;
- }
+ }
+ } else if (HAS_KEY(opts->virt_lines)) {
+ api_set_error(err, kErrorTypeValidation, "virt_lines is not an Array");
+ goto error;
+ }
- if (v->data.integer < 0 || v->data.integer > UINT16_MAX) {
- api_set_error(err, kErrorTypeValidation,
- "priority is not a valid value");
- goto error;
- }
- decor.priority = (DecorPriority)v->data.integer;
- } else if (strequal("right_gravity", k.data)) {
- if (v->type != kObjectTypeBoolean) {
- api_set_error(err, kErrorTypeValidation,
- "right_gravity must be a boolean");
- goto error;
- }
- right_gravity = v->data.boolean;
- } else if (strequal("end_right_gravity", k.data)) {
- if (v->type != kObjectTypeBoolean) {
- api_set_error(err, kErrorTypeValidation,
- "end_right_gravity must be a boolean");
- goto error;
- }
- end_right_gravity = v->data.boolean;
- end_gravity_set = true;
- } else {
- api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data);
+ OPTION_TO_BOOL(virt_lines_above, virt_lines_above, false);
+ OPTION_TO_BOOL(virt_lines_leftcol, virt_lines_leftcol, false);
+
+ if (opts->priority.type == kObjectTypeInteger) {
+ Integer val = opts->priority.data.integer;
+
+ if (val < 0 || val > UINT16_MAX) {
+ api_set_error(err, kErrorTypeValidation, "priority is not a valid value");
goto error;
}
+ decor.priority = (DecorPriority)val;
+ } else if (HAS_KEY(opts->priority)) {
+ api_set_error(err, kErrorTypeValidation, "priority is not a Number of the correct size");
+ goto error;
+ }
+
+ bool right_gravity = true;
+ OPTION_TO_BOOL(right_gravity, right_gravity, true);
+
+ // Only error out if they try to set end_right_gravity without
+ // setting end_col or end_line
+ if (line2 == -1 && col2 == -1 && HAS_KEY(opts->end_right_gravity)) {
+ api_set_error(err, kErrorTypeValidation,
+ "cannot set end_right_gravity without setting end_line or end_col");
+ goto error;
}
+ bool end_right_gravity = false;
+ OPTION_TO_BOOL(end_right_gravity, end_right_gravity, false);
+
size_t len = 0;
+
+ bool ephemeral = false;
+ OPTION_TO_BOOL(ephemeral, ephemeral, false);
+
if (line < 0 || line > buf->b_ml.ml_line_count) {
api_set_error(err, kErrorTypeValidation, "line value outside range");
- return 0;
+ goto error;
} else if (line < buf->b_ml.ml_line_count) {
len = ephemeral ? MAXCOL : STRLEN(ml_get_buf(buf, (linenr_T)line+1, false));
}
@@ -1658,16 +1749,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
col = (Integer)len;
} else if (col < -1 || col > (Integer)len) {
api_set_error(err, kErrorTypeValidation, "col value outside range");
- return 0;
- }
-
-
- // Only error out if they try to set end_right_gravity without
- // setting end_col or end_line
- if (line2 == -1 && col2 == -1 && end_gravity_set) {
- api_set_error(err, kErrorTypeValidation,
- "cannot set end_right_gravity "
- "without setting end_line or end_col");
+ goto error;
}
if (col2 >= 0) {
@@ -1688,15 +1770,6 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
col2 = 0;
}
- if (decor.virt_text_pos == kVTRightAlign) {
- decor.col = 0;
- for (size_t i = 0; i < kv_size(decor.virt_text); i++) {
- decor.col
- += (int)mb_string2cells((char_u *)kv_A(decor.virt_text, i).text);
- }
- }
-
-
Decoration *d = NULL;
if (ephemeral) {
@@ -1721,9 +1794,23 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
goto error;
}
- id = extmark_set(buf, (uint64_t)ns_id, id, (int)line, (colnr_T)col,
- line2, col2, d, right_gravity,
- end_right_gravity, kExtmarkNoUndo);
+ if (kv_size(virt_lines) && buf->b_virt_line_mark) {
+ mtpos_t pos = marktree_lookup(buf->b_marktree, buf->b_virt_line_mark, NULL);
+ clear_virt_lines(buf, pos.row); // handles pos.row == -1
+ }
+
+ uint64_t mark = extmark_set(buf, (uint64_t)ns_id, &id, (int)line, (colnr_T)col,
+ line2, col2, d, right_gravity,
+ end_right_gravity, kExtmarkNoUndo);
+
+ if (kv_size(virt_lines)) {
+ buf->b_virt_lines = virt_lines;
+ buf->b_virt_line_mark = mark;
+ buf->b_virt_line_pos = -1;
+ buf->b_virt_line_above = virt_lines_above;
+ buf->b_virt_line_leftcol = virt_lines_leftcol;
+ redraw_buf_line_later(buf, MIN(buf->b_ml.ml_line_count, line+1+(virt_lines_above?0:1)));
+ }
}
return (Integer)id;
@@ -1816,7 +1903,7 @@ Integer nvim_buf_add_highlight(Buffer buffer, Integer ns_id, String hl_group, In
int hl_id = 0;
if (hl_group.size > 0) {
- hl_id = syn_check_group((char_u *)hl_group.data, (int)hl_group.size);
+ hl_id = syn_check_group(hl_group.data, (int)hl_group.size);
} else {
return ns_id;
}
@@ -1827,7 +1914,7 @@ Integer nvim_buf_add_highlight(Buffer buffer, Integer ns_id, String hl_group, In
end_line++;
}
- extmark_set(buf, ns, 0,
+ extmark_set(buf, ns, NULL,
(int)line, (colnr_T)col_start,
end_line, (colnr_T)col_end,
decor_hl(hl_id), true, false, kExtmarkNoUndo);
@@ -1895,7 +1982,7 @@ Object nvim_buf_call(Buffer buffer, LuaRef fun, Error *err)
}
try_start();
aco_save_T aco;
- aucmd_prepbuf(&aco, (buf_T *)buf);
+ aucmd_prepbuf(&aco, buf);
Array args = ARRAY_DICT_INIT;
Object res = nlua_call_ref(fun, NULL, args, true, err);
diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c
index 21b9db85c0..907d09e5b7 100644
--- a/src/nvim/api/deprecated.c
+++ b/src/nvim/api/deprecated.c
@@ -150,7 +150,7 @@ Integer nvim_buf_set_virtual_text(Buffer buffer, Integer src_id, Integer line, A
decor->virt_text = virt_text;
decor->virt_text_width = width;
- extmark_set(buf, ns_id, 0, (int)line, 0, -1, -1, decor, true,
+ extmark_set(buf, ns_id, NULL, (int)line, 0, -1, -1, decor, true,
false, kExtmarkNoUndo);
return src_id;
}
@@ -165,6 +165,7 @@ Integer nvim_buf_set_virtual_text(Buffer buffer, Integer src_id, Integer line, A
/// @param lines Array of lines
/// @param[out] err Error details, if any
void buffer_insert(Buffer buffer, Integer lnum, ArrayOf(String) lines, Error *err)
+ FUNC_API_DEPRECATED_SINCE(1)
{
// "lnum" will be the index of the line after inserting,
// no matter if it is negative or not
@@ -184,6 +185,7 @@ void buffer_insert(Buffer buffer, Integer lnum, ArrayOf(String) lines, Error *er
/// @param[out] err Error details, if any
/// @return Line string
String buffer_get_line(Buffer buffer, Integer index, Error *err)
+ FUNC_API_DEPRECATED_SINCE(1)
{
String rv = { .size = 0 };
@@ -212,6 +214,7 @@ String buffer_get_line(Buffer buffer, Integer index, Error *err)
/// @param line Contents of the new line
/// @param[out] err Error details, if any
void buffer_set_line(Buffer buffer, Integer index, String line, Error *err)
+ FUNC_API_DEPRECATED_SINCE(1)
{
Object l = STRING_OBJ(line);
Array array = { .items = &l, .size = 1 };
@@ -230,6 +233,7 @@ void buffer_set_line(Buffer buffer, Integer index, String line, Error *err)
/// @param index line index
/// @param[out] err Error details, if any
void buffer_del_line(Buffer buffer, Integer index, Error *err)
+ FUNC_API_DEPRECATED_SINCE(1)
{
Array array = ARRAY_DICT_INIT;
index = convert_index(index);
@@ -255,6 +259,7 @@ ArrayOf(String) buffer_get_line_slice(Buffer buffer,
Boolean include_start,
Boolean include_end,
Error *err)
+ FUNC_API_DEPRECATED_SINCE(1)
{
start = convert_index(start) + !include_start;
end = convert_index(end) + include_end;
@@ -278,6 +283,7 @@ ArrayOf(String) buffer_get_line_slice(Buffer buffer,
/// @param[out] err Error details, if any
void buffer_set_line_slice(Buffer buffer, Integer start, Integer end, Boolean include_start,
Boolean include_end, ArrayOf(String) replacement, Error *err)
+ FUNC_API_DEPRECATED_SINCE(1)
{
start = convert_index(start) + !include_start;
end = convert_index(end) + include_end;
@@ -298,6 +304,7 @@ void buffer_set_line_slice(Buffer buffer, Integer start, Integer end, Boolean in
/// @warning It may return nil if there was no previous value
/// or if previous value was `v:null`.
Object buffer_set_var(Buffer buffer, String name, Object value, Error *err)
+ FUNC_API_DEPRECATED_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -317,6 +324,7 @@ Object buffer_set_var(Buffer buffer, String name, Object value, Error *err)
/// @param[out] err Error details, if any
/// @return Old value
Object buffer_del_var(Buffer buffer, String name, Error *err)
+ FUNC_API_DEPRECATED_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -340,6 +348,7 @@ Object buffer_del_var(Buffer buffer, String name, Error *err)
/// @warning It may return nil if there was no previous value
/// or if previous value was `v:null`.
Object window_set_var(Window window, String name, Object value, Error *err)
+ FUNC_API_DEPRECATED_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -359,6 +368,7 @@ Object window_set_var(Window window, String name, Object value, Error *err)
/// @param[out] err Error details, if any
/// @return Old value
Object window_del_var(Window window, String name, Error *err)
+ FUNC_API_DEPRECATED_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -382,6 +392,7 @@ Object window_del_var(Window window, String name, Error *err)
/// @warning It may return nil if there was no previous value
/// or if previous value was `v:null`.
Object tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err)
+ FUNC_API_DEPRECATED_SINCE(1)
{
tabpage_T *tab = find_tab_by_handle(tabpage, err);
@@ -401,6 +412,7 @@ Object tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err)
/// @param[out] err Error details, if any
/// @return Old value
Object tabpage_del_var(Tabpage tabpage, String name, Error *err)
+ FUNC_API_DEPRECATED_SINCE(1)
{
tabpage_T *tab = find_tab_by_handle(tabpage, err);
@@ -417,6 +429,7 @@ Object tabpage_del_var(Tabpage tabpage, String name, Error *err)
/// OR if previous value was `v:null`.
/// @return Old value or nil if there was no previous value.
Object vim_set_var(String name, Object value, Error *err)
+ FUNC_API_DEPRECATED_SINCE(1)
{
return dict_set_var(&globvardict, name, value, false, true, err);
}
@@ -424,6 +437,7 @@ Object vim_set_var(String name, Object value, Error *err)
/// @deprecated
/// @see nvim_del_var
Object vim_del_var(String name, Error *err)
+ FUNC_API_DEPRECATED_SINCE(1)
{
return dict_set_var(&globvardict, name, NIL, true, true, err);
}
diff --git a/src/nvim/api/keysets.lua b/src/nvim/api/keysets.lua
new file mode 100644
index 0000000000..144c252687
--- /dev/null
+++ b/src/nvim/api/keysets.lua
@@ -0,0 +1,62 @@
+return {
+ context = {
+ "types";
+ };
+ set_extmark = {
+ "id";
+ "end_line";
+ "end_col";
+ "hl_group";
+ "virt_text";
+ "virt_text_pos";
+ "virt_text_win_col";
+ "virt_text_hide";
+ "hl_eol";
+ "hl_mode";
+ "ephemeral";
+ "priority";
+ "right_gravity";
+ "end_right_gravity";
+ "virt_lines";
+ "virt_lines_above";
+ "virt_lines_leftcol";
+ };
+ keymap = {
+ "noremap";
+ "nowait";
+ "silent";
+ "script";
+ "expr";
+ "unique";
+ };
+ get_commands = {
+ "builtin";
+ };
+ float_config = {
+ "row";
+ "col";
+ "width";
+ "height";
+ "anchor";
+ "relative";
+ "win";
+ "bufpos";
+ "external";
+ "focusable";
+ "zindex";
+ "border";
+ "style";
+ "noautocmd";
+ };
+ runtime = {
+ "is_lua";
+ };
+ eval_statusline = {
+ "winid";
+ "maxwidth";
+ "fillchar";
+ "highlights";
+ "use_tabline";
+ };
+}
+
diff --git a/src/nvim/api/private/defs.h b/src/nvim/api/private/defs.h
index f0d48bf145..663d1e16b5 100644
--- a/src/nvim/api/private/defs.h
+++ b/src/nvim/api/private/defs.h
@@ -1,15 +1,15 @@
#ifndef NVIM_API_PRIVATE_DEFS_H
#define NVIM_API_PRIVATE_DEFS_H
-#include <stdint.h>
#include <stdbool.h>
+#include <stdint.h>
#include <string.h>
#include "nvim/func_attr.h"
#include "nvim/types.h"
-#define ARRAY_DICT_INIT {.size = 0, .capacity = 0, .items = NULL}
-#define STRING_INIT {.data = NULL, .size = 0}
+#define ARRAY_DICT_INIT { .size = 0, .capacity = 0, .items = NULL }
+#define STRING_INIT { .data = NULL, .size = 0 }
#define OBJECT_INIT { .type = kObjectTypeNil }
#define ERROR_INIT { .type = kErrorTypeNone, .msg = NULL }
#define REMOTE_TYPE(type) typedef handle_T type
@@ -19,6 +19,7 @@
#ifdef INCLUDE_GENERATED_DECLARATIONS
# define ArrayOf(...) Array
# define DictionaryOf(...) Dictionary
+# define Dict(name) KeyDict_##name
#endif
// Basic types
@@ -129,5 +130,14 @@ struct key_value_pair {
Object value;
};
+typedef Object *(*field_hash)(void *retval, const char *str, size_t len);
+typedef struct {
+ char *str;
+ size_t ptr_off;
+} KeySetLink;
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "keysets_defs.generated.h"
+#endif
#endif // NVIM_API_PRIVATE_DEFS_H
diff --git a/src/nvim/api/private/dispatch.c b/src/nvim/api/private/dispatch.c
index 38ce7ca78c..519bf8ff14 100644
--- a/src/nvim/api/private/dispatch.c
+++ b/src/nvim/api/private/dispatch.c
@@ -14,6 +14,7 @@
#include "nvim/api/tabpage.h"
#include "nvim/api/ui.h"
#include "nvim/api/vim.h"
+#include "nvim/api/win_config.h"
#include "nvim/api/window.h"
#include "nvim/log.h"
#include "nvim/map.h"
@@ -45,5 +46,5 @@ MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name, size_t na
}
#ifdef INCLUDE_GENERATED_DECLARATIONS
-#include "api/private/dispatch_wrappers.generated.h"
+# include "api/private/dispatch_wrappers.generated.h"
#endif
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index 541793e528..f1259c8a18 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -4,6 +4,7 @@
#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
+#include <stddef.h>
#include <stdlib.h>
#include <string.h>
@@ -24,6 +25,7 @@
#include "nvim/lua/executor.h"
#include "nvim/map.h"
#include "nvim/map_defs.h"
+#include "nvim/mark.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/msgpack_rpc/helpers.h"
@@ -395,7 +397,7 @@ void set_option_to(uint64_t channel_id, void *to, int type, String name, Object
return;
}
- stringval = (char *)value.data.string.data;
+ stringval = value.data.string.data;
}
const sctx_T save_current_sctx = current_sctx;
@@ -814,15 +816,8 @@ Array string_to_array(const String input, bool crlf)
/// buffer, or -1 to signify global behavior ("all buffers")
/// @param is_unmap When true, removes the mapping that matches {lhs}.
void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String rhs,
- Dictionary opts, Error *err)
+ Dict(keymap) *opts, Error *err)
{
- char *err_msg = NULL; // the error message to report, if any
- char *err_arg = NULL; // argument for the error message format string
- ErrorType err_type = kErrorTypeNone;
-
- char_u *lhs_buf = NULL;
- char_u *rhs_buf = NULL;
-
bool global = (buffer == -1);
if (global) {
buffer = 0;
@@ -833,10 +828,21 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String
return;
}
- MapArguments parsed_args;
- memset(&parsed_args, 0, sizeof(parsed_args));
- if (parse_keymap_opts(opts, &parsed_args, err)) {
- goto fail_and_free;
+ MapArguments parsed_args = MAP_ARGUMENTS_INIT;
+ if (opts) {
+#define KEY_TO_BOOL(name) \
+ parsed_args. name = api_object_to_bool(opts-> name, #name, false, err); \
+ if (ERROR_SET(err)) { \
+ goto fail_and_free; \
+ }
+
+ KEY_TO_BOOL(nowait);
+ KEY_TO_BOOL(noremap);
+ KEY_TO_BOOL(silent);
+ KEY_TO_BOOL(script);
+ KEY_TO_BOOL(expr);
+ KEY_TO_BOOL(unique);
+#undef KEY_TO_BOOL
}
parsed_args.buffer = !global;
@@ -845,17 +851,13 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String
CPO_TO_CPO_FLAGS, &parsed_args);
if (parsed_args.lhs_len > MAXMAPLEN) {
- err_msg = "LHS exceeds maximum map length: %s";
- err_arg = lhs.data;
- err_type = kErrorTypeValidation;
- goto fail_with_message;
+ api_set_error(err, kErrorTypeValidation, "LHS exceeds maximum map length: %s", lhs.data);
+ goto fail_and_free;
}
if (mode.size > 1) {
- err_msg = "Shortname is too long: %s";
- err_arg = mode.data;
- err_type = kErrorTypeValidation;
- goto fail_with_message;
+ api_set_error(err, kErrorTypeValidation, "Shortname is too long: %s", mode.data);
+ goto fail_and_free;
}
int mode_val; // integer value of the mapping mode, to be passed to do_map()
char_u *p = (char_u *)((mode.size) ? mode.data : "m");
@@ -867,18 +869,14 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String
&& mode.size > 0) {
// get_map_mode() treats unrecognized mode shortnames as ":map".
// This is an error unless the given shortname was empty string "".
- err_msg = "Invalid mode shortname: \"%s\"";
- err_arg = (char *)p;
- err_type = kErrorTypeValidation;
- goto fail_with_message;
+ api_set_error(err, kErrorTypeValidation, "Invalid mode shortname: \"%s\"", (char *)p);
+ goto fail_and_free;
}
}
if (parsed_args.lhs_len == 0) {
- err_msg = "Invalid (empty) LHS";
- err_arg = "";
- err_type = kErrorTypeValidation;
- goto fail_with_message;
+ api_set_error(err, kErrorTypeValidation, "Invalid (empty) LHS");
+ goto fail_and_free;
}
bool is_noremap = parsed_args.noremap;
@@ -891,16 +889,13 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String
// the given RHS was nonempty and not a <Nop>, but was parsed as if it
// were empty?
assert(false && "Failed to parse nonempty RHS!");
- err_msg = "Parsing of nonempty RHS failed: %s";
- err_arg = rhs.data;
- err_type = kErrorTypeException;
- goto fail_with_message;
+ api_set_error(err, kErrorTypeValidation, "Parsing of nonempty RHS failed: %s", rhs.data);
+ goto fail_and_free;
}
} else if (is_unmap && parsed_args.rhs_len) {
- err_msg = "Gave nonempty RHS in unmap command: %s";
- err_arg = (char *)parsed_args.rhs;
- err_type = kErrorTypeValidation;
- goto fail_with_message;
+ api_set_error(err, kErrorTypeValidation,
+ "Gave nonempty RHS in unmap command: %s", parsed_args.rhs);
+ goto fail_and_free;
}
// buf_do_map() reads noremap/unmap as its own argument.
@@ -929,113 +924,12 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String
goto fail_and_free;
} // switch
- xfree(lhs_buf);
- xfree(rhs_buf);
- xfree(parsed_args.rhs);
- xfree(parsed_args.orig_rhs);
-
- return;
-
-fail_with_message:
- api_set_error(err, err_type, err_msg, err_arg);
-
fail_and_free:
- xfree(lhs_buf);
- xfree(rhs_buf);
xfree(parsed_args.rhs);
xfree(parsed_args.orig_rhs);
return;
}
-/// Read in the given opts, setting corresponding flags in `out`.
-///
-/// @param opts A dictionary passed to @ref nvim_set_keymap or
-/// @ref nvim_buf_set_keymap.
-/// @param[out] out MapArguments object in which to set parsed
-/// |:map-arguments| flags.
-/// @param[out] err Error details, if any.
-///
-/// @returns Zero on success, nonzero on failure.
-Integer parse_keymap_opts(Dictionary opts, MapArguments *out, Error *err)
-{
- char *err_msg = NULL; // the error message to report, if any
- char *err_arg = NULL; // argument for the error message format string
- ErrorType err_type = kErrorTypeNone;
-
- out->buffer = false;
- out->nowait = false;
- out->silent = false;
- out->script = false;
- out->expr = false;
- out->unique = false;
-
- for (size_t i = 0; i < opts.size; i++) {
- KeyValuePair *key_and_val = &opts.items[i];
- char *optname = key_and_val->key.data;
-
- if (key_and_val->value.type != kObjectTypeBoolean) {
- err_msg = "Gave non-boolean value for an opt: %s";
- err_arg = optname;
- err_type = kErrorTypeValidation;
- goto fail_with_message;
- }
-
- bool was_valid_opt = false;
- switch (optname[0]) {
- // note: strncmp up to and including the null terminator, so that
- // "nowaitFoobar" won't match against "nowait"
-
- // don't recognize 'buffer' as a key; user shouldn't provide <buffer>
- // when calling nvim_set_keymap or nvim_buf_set_keymap, since it can be
- // inferred from which function they called
- case 'n':
- if (STRNCMP(optname, "noremap", 8) == 0) {
- was_valid_opt = true;
- out->noremap = key_and_val->value.data.boolean;
- } else if (STRNCMP(optname, "nowait", 7) == 0) {
- was_valid_opt = true;
- out->nowait = key_and_val->value.data.boolean;
- }
- break;
- case 's':
- if (STRNCMP(optname, "silent", 7) == 0) {
- was_valid_opt = true;
- out->silent = key_and_val->value.data.boolean;
- } else if (STRNCMP(optname, "script", 7) == 0) {
- was_valid_opt = true;
- out->script = key_and_val->value.data.boolean;
- }
- break;
- case 'e':
- if (STRNCMP(optname, "expr", 5) == 0) {
- was_valid_opt = true;
- out->expr = key_and_val->value.data.boolean;
- }
- break;
- case 'u':
- if (STRNCMP(optname, "unique", 7) == 0) {
- was_valid_opt = true;
- out->unique = key_and_val->value.data.boolean;
- }
- break;
- default:
- break;
- } // switch
- if (!was_valid_opt) {
- err_msg = "Invalid key: %s";
- err_arg = optname;
- err_type = kErrorTypeValidation;
- goto fail_with_message;
- }
- } // for
-
- return 0;
-
-fail_with_message:
- api_set_error(err, err_type, err_msg, err_arg);
- return 1;
-}
-
/// Collects `n` buffer lines into array `l`, optionally replacing newlines
/// with NUL.
///
@@ -1413,8 +1307,10 @@ static void set_option_value_for(char *key, int numval, char *stringval, int opt
switch (opt_type)
{
case SREQ_WIN:
- if (switch_win(&save_curwin, &save_curtab, (win_T *)from,
- win_find_tabpage((win_T *)from), false) == FAIL) {
+ if (switch_win_noblock(&save_curwin, &save_curtab, (win_T *)from,
+ win_find_tabpage((win_T *)from), true)
+ == FAIL) {
+ restore_win_noblock(save_curwin, save_curtab, true);
if (try_end(err)) {
return;
}
@@ -1424,7 +1320,7 @@ static void set_option_value_for(char *key, int numval, char *stringval, int opt
return;
}
set_option_value_err(key, numval, stringval, opt_flags, err);
- restore_win(save_curwin, save_curtab, true);
+ restore_win_noblock(save_curwin, save_curtab, true);
break;
case SREQ_BUF:
aucmd_prepbuf(&aco, (buf_T *)from);
@@ -1625,7 +1521,7 @@ VirtText parse_virt_text(Array chunks, Error *err, int *width)
}
}
- char *text = transstr(str.size > 0 ? str.data : ""); // allocates
+ char *text = transstr(str.size > 0 ? str.data : "", false); // allocates
w += (int)mb_string2cells((char_u *)text);
kv_push(virt_text, ((VirtTextChunk){ .text = text, .hl_id = hl_id }));
@@ -1663,7 +1559,7 @@ int object_to_hl_id(Object obj, const char *what, Error *err)
{
if (obj.type == kObjectTypeString) {
String str = obj.data.string;
- return str.size ? syn_check_group((char_u *)str.data, (int)str.size) : 0;
+ return str.size ? syn_check_group(str.data, (int)str.size) : 0;
} else if (obj.type == kObjectTypeInteger) {
return MAX((int)obj.data.integer, 0);
} else {
@@ -1697,7 +1593,7 @@ HlMessage parse_hl_msg(Array chunks, Error *err)
String hl = chunk.items[1].data.string;
if (hl.size > 0) {
// TODO(bfredl): use object_to_hl_id and allow integer
- int hl_id = syn_check_group((char_u *)hl.data, (int)hl.size);
+ int hl_id = syn_check_group(hl.data, (int)hl.size);
attr = hl_id > 0 ? syn_id2attr(hl_id) : 0;
}
}
@@ -1723,367 +1619,77 @@ const char *describe_ns(NS ns_id)
return "(UNKNOWN PLUGIN)";
}
-static bool parse_float_anchor(String anchor, FloatAnchor *out)
+bool api_dict_to_keydict(void *rv, field_hash hashy, Dictionary dict, Error *err)
{
- if (anchor.size == 0) {
- *out = (FloatAnchor)0;
- }
- char *str = anchor.data;
- if (striequal(str, "NW")) {
- *out = 0; // NW is the default
- } else if (striequal(str, "NE")) {
- *out = kFloatAnchorEast;
- } else if (striequal(str, "SW")) {
- *out = kFloatAnchorSouth;
- } else if (striequal(str, "SE")) {
- *out = kFloatAnchorSouth | kFloatAnchorEast;
- } else {
- return false;
- }
- return true;
-}
+ for (size_t i = 0; i < dict.size; i++) {
+ String k = dict.items[i].key;
+ Object *field = hashy(rv, k.data, k.size);
+ if (!field) {
+ api_set_error(err, kErrorTypeValidation, "Invalid key: '%.*s'", (int)k.size, k.data);
+ return false;
+ }
-static bool parse_float_relative(String relative, FloatRelative *out)
-{
- char *str = relative.data;
- if (striequal(str, "editor")) {
- *out = kFloatRelativeEditor;
- } else if (striequal(str, "win")) {
- *out = kFloatRelativeWindow;
- } else if (striequal(str, "cursor")) {
- *out = kFloatRelativeCursor;
- } else {
- return false;
+ *field = dict.items[i].value;
}
+
return true;
}
-static bool parse_float_bufpos(Array bufpos, lpos_T *out)
+void api_free_keydict(void *dict, KeySetLink *table)
{
- if (bufpos.size != 2
- || bufpos.items[0].type != kObjectTypeInteger
- || bufpos.items[1].type != kObjectTypeInteger) {
- return false;
+ for (size_t i = 0; table[i].str; i++) {
+ api_free_object(*(Object *)((char *)dict + table[i].ptr_off));
}
- out->lnum = bufpos.items[0].data.integer;
- out->col = (colnr_T)bufpos.items[1].data.integer;
- return true;
}
-static void parse_border_style(Object style, FloatConfig *fconfig, Error *err)
+/// Set a named mark
+/// buffer and mark name must be validated already
+/// @param buffer Buffer to set the mark on
+/// @param name Mark name
+/// @param line Line number
+/// @param col Column/row number
+/// @return true if the mark was set, else false
+bool set_mark(buf_T *buf, String name, Integer line, Integer col, Error *err)
{
- struct {
- const char *name;
- schar_T chars[8];
- bool shadow_color;
- } defaults[] = {
- { "double", { "╔", "═", "╗", "║", "╝", "═", "╚", "║" }, false },
- { "single", { "┌", "─", "┐", "│", "┘", "─", "└", "│" }, false },
- { "shadow", { "", "", " ", " ", " ", " ", " ", "" }, true },
- { "rounded", { "╭", "─", "╮", "│", "╯", "─", "╰", "│" }, false },
- { "solid", { " ", " ", " ", " ", " ", " ", " ", " " }, false },
- { NULL, { { NUL } }, false },
- };
-
- schar_T *chars = fconfig->border_chars;
- int *hl_ids = fconfig->border_hl_ids;
-
- fconfig->border = true;
-
- if (style.type == kObjectTypeArray) {
- Array arr = style.data.array;
- size_t size = arr.size;
- if (!size || size > 8 || (size & (size-1))) {
- api_set_error(err, kErrorTypeValidation,
- "invalid number of border chars");
- return;
- }
- for (size_t i = 0; i < size; i++) {
- Object iytem = arr.items[i];
- String string;
- int hl_id = 0;
- if (iytem.type == kObjectTypeArray) {
- Array iarr = iytem.data.array;
- if (!iarr.size || iarr.size > 2) {
- api_set_error(err, kErrorTypeValidation, "invalid border char");
- return;
- }
- if (iarr.items[0].type != kObjectTypeString) {
- api_set_error(err, kErrorTypeValidation, "invalid border char");
- return;
- }
- string = iarr.items[0].data.string;
- if (iarr.size == 2) {
- hl_id = object_to_hl_id(iarr.items[1], "border char highlight", err);
- if (ERROR_SET(err)) {
- return;
- }
- }
- } else if (iytem.type == kObjectTypeString) {
- string = iytem.data.string;
- } else {
- api_set_error(err, kErrorTypeValidation, "invalid border char");
- return;
- }
- if (string.size
- && mb_string2cells_len((char_u *)string.data, string.size) > 1) {
- api_set_error(err, kErrorTypeValidation,
- "border chars must be one cell");
- return;
- }
- size_t len = MIN(string.size, sizeof(*chars)-1);
- if (len) {
- memcpy(chars[i], string.data, len);
- }
- chars[i][len] = NUL;
- hl_ids[i] = hl_id;
- }
- while (size < 8) {
- memcpy(chars+size, chars, sizeof(*chars) * size);
- memcpy(hl_ids+size, hl_ids, sizeof(*hl_ids) * size);
- size <<= 1;
- }
- if ((chars[7][0] && chars[1][0] && !chars[0][0])
- || (chars[1][0] && chars[3][0] && !chars[2][0])
- || (chars[3][0] && chars[5][0] && !chars[4][0])
- || (chars[5][0] && chars[7][0] && !chars[6][0])) {
- api_set_error(err, kErrorTypeValidation,
- "corner between used edges must be specified");
- }
- } else if (style.type == kObjectTypeString) {
- String str = style.data.string;
- if (str.size == 0 || strequal(str.data, "none")) {
- fconfig->border = false;
- return;
+ buf = buf == NULL ? curbuf : buf;
+ // If line == 0 the marks is being deleted
+ bool res = false;
+ bool deleting = false;
+ if (line == 0) {
+ col = 0;
+ deleting = true;
+ } else {
+ if (col > MAXCOL) {
+ api_set_error(err, kErrorTypeValidation, "Column value outside range");
+ return res;
}
- for (size_t i = 0; defaults[i].name; i++) {
- if (strequal(str.data, defaults[i].name)) {
- memcpy(chars, defaults[i].chars, sizeof(defaults[i].chars));
- memset(hl_ids, 0, 8 * sizeof(*hl_ids));
- if (defaults[i].shadow_color) {
- int hl_blend = SYN_GROUP_STATIC("FloatShadow");
- int hl_through = SYN_GROUP_STATIC("FloatShadowThrough");
- hl_ids[2] = hl_through;
- hl_ids[3] = hl_blend;
- hl_ids[4] = hl_blend;
- hl_ids[5] = hl_blend;
- hl_ids[6] = hl_through;
- }
- return;
- }
+ if (line < 1 || line > buf->b_ml.ml_line_count) {
+ api_set_error(err, kErrorTypeValidation, "Line value outside range");
+ return res;
}
- api_set_error(err, kErrorTypeValidation,
- "invalid border style \"%s\"", str.data);
}
-}
-
-bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf, bool new_win,
- Error *err)
-{
- // TODO(bfredl): use a get/has_key interface instead and get rid of extra
- // flags
- bool has_row = false, has_col = false, has_relative = false;
- bool has_external = false, has_window = false;
- bool has_width = false, has_height = false;
- bool has_bufpos = false;
-
- for (size_t i = 0; i < config.size; i++) {
- char *key = config.items[i].key.data;
- Object val = config.items[i].value;
- if (!strcmp(key, "row")) {
- has_row = true;
- if (val.type == kObjectTypeInteger) {
- fconfig->row = (double)val.data.integer;
- } else if (val.type == kObjectTypeFloat) {
- fconfig->row = val.data.floating;
- } else {
- api_set_error(err, kErrorTypeValidation,
- "'row' key must be Integer or Float");
- return false;
- }
- } else if (!strcmp(key, "col")) {
- has_col = true;
- if (val.type == kObjectTypeInteger) {
- fconfig->col = (double)val.data.integer;
- } else if (val.type == kObjectTypeFloat) {
- fconfig->col = val.data.floating;
- } else {
- api_set_error(err, kErrorTypeValidation,
- "'col' key must be Integer or Float");
- return false;
- }
- } else if (strequal(key, "width")) {
- has_width = true;
- if (val.type == kObjectTypeInteger && val.data.integer > 0) {
- fconfig->width = (int)val.data.integer;
- } else {
- api_set_error(err, kErrorTypeValidation,
- "'width' key must be a positive Integer");
- return false;
- }
- } else if (strequal(key, "height")) {
- has_height = true;
- if (val.type == kObjectTypeInteger && val.data.integer > 0) {
- fconfig->height = (int)val.data.integer;
- } else {
- api_set_error(err, kErrorTypeValidation,
- "'height' key must be a positive Integer");
- return false;
- }
- } else if (!strcmp(key, "anchor")) {
- if (val.type != kObjectTypeString) {
- api_set_error(err, kErrorTypeValidation,
- "'anchor' key must be String");
- return false;
- }
- if (!parse_float_anchor(val.data.string, &fconfig->anchor)) {
- api_set_error(err, kErrorTypeValidation,
- "Invalid value of 'anchor' key");
- return false;
- }
- } else if (!strcmp(key, "relative")) {
- if (val.type != kObjectTypeString) {
- api_set_error(err, kErrorTypeValidation,
- "'relative' key must be String");
- return false;
- }
- // ignore empty string, to match nvim_win_get_config
- if (val.data.string.size > 0) {
- has_relative = true;
- if (!parse_float_relative(val.data.string, &fconfig->relative)) {
- api_set_error(err, kErrorTypeValidation,
- "Invalid value of 'relative' key");
- return false;
- }
- }
- } else if (!strcmp(key, "win")) {
- has_window = true;
- if (val.type != kObjectTypeInteger
- && val.type != kObjectTypeWindow) {
- api_set_error(err, kErrorTypeValidation,
- "'win' key must be Integer or Window");
- return false;
- }
- fconfig->window = (Window)val.data.integer;
- } else if (!strcmp(key, "bufpos")) {
- if (val.type != kObjectTypeArray) {
- api_set_error(err, kErrorTypeValidation,
- "'bufpos' key must be Array");
- return false;
- }
- if (!parse_float_bufpos(val.data.array, &fconfig->bufpos)) {
- api_set_error(err, kErrorTypeValidation,
- "Invalid value of 'bufpos' key");
- return false;
- }
- has_bufpos = true;
- } else if (!strcmp(key, "external")) {
- has_external = fconfig->external
- = api_object_to_bool(val, "'external' key", false, err);
- if (ERROR_SET(err)) {
- return false;
- }
- } else if (!strcmp(key, "focusable")) {
- fconfig->focusable
- = api_object_to_bool(val, "'focusable' key", true, err);
- if (ERROR_SET(err)) {
- return false;
- }
- } else if (strequal(key, "zindex")) {
- if (val.type == kObjectTypeInteger && val.data.integer > 0) {
- fconfig->zindex = (int)val.data.integer;
- } else {
- api_set_error(err, kErrorTypeValidation,
- "'zindex' key must be a positive Integer");
- return false;
- }
- } else if (!strcmp(key, "border")) {
- parse_border_style(val, fconfig, err);
- if (ERROR_SET(err)) {
- return false;
- }
- } else if (!strcmp(key, "style")) {
- if (val.type != kObjectTypeString) {
- api_set_error(err, kErrorTypeValidation,
- "'style' key must be String");
- return false;
- }
- if (val.data.string.data[0] == NUL) {
- fconfig->style = kWinStyleUnused;
- } else if (striequal(val.data.string.data, "minimal")) {
- fconfig->style = kWinStyleMinimal;
- } else {
- api_set_error(err, kErrorTypeValidation,
- "Invalid value of 'style' key");
- }
- } else if (strequal(key, "noautocmd") && new_win) {
- fconfig->noautocmd
- = api_object_to_bool(val, "'noautocmd' key", false, err);
- if (ERROR_SET(err)) {
- return false;
- }
+ pos_T pos = { line, (int)col, (int)col };
+ res = setmark_pos(*name.data, &pos, buf->handle);
+ if (!res) {
+ if (deleting) {
+ api_set_error(err, kErrorTypeException,
+ "Failed to delete named mark: %c", *name.data);
} else {
- api_set_error(err, kErrorTypeValidation,
- "Invalid key '%s'", key);
- return false;
- }
- }
-
- if (has_window && !(has_relative
- && fconfig->relative == kFloatRelativeWindow)) {
- api_set_error(err, kErrorTypeValidation,
- "'win' key is only valid with relative='win'");
- return false;
- }
-
- if ((has_relative && fconfig->relative == kFloatRelativeWindow)
- && (!has_window || fconfig->window == 0)) {
- fconfig->window = curwin->handle;
- }
-
- if (has_window && !has_bufpos) {
- fconfig->bufpos.lnum = -1;
- }
-
- if (has_bufpos) {
- if (!has_row) {
- fconfig->row = (fconfig->anchor & kFloatAnchorSouth) ? 0 : 1;
- has_row = true;
- }
- if (!has_col) {
- fconfig->col = 0;
- has_col = true;
+ api_set_error(err, kErrorTypeException,
+ "Failed to set named mark: %c", *name.data);
}
}
+ return res;
+}
- if (has_relative && has_external) {
- api_set_error(err, kErrorTypeValidation,
- "Only one of 'relative' and 'external' must be used");
- return false;
- } else if (!reconf && !has_relative && !has_external) {
- api_set_error(err, kErrorTypeValidation,
- "One of 'relative' and 'external' must be used");
- return false;
- } else if (has_relative) {
- fconfig->external = false;
- }
-
- if (!reconf && !(has_height && has_width)) {
- api_set_error(err, kErrorTypeValidation,
- "Must specify 'width' and 'height'");
- return false;
- }
-
- if (fconfig->external && !ui_has(kUIMultigrid)) {
- api_set_error(err, kErrorTypeValidation,
- "UI doesn't support external windows");
- return false;
- }
-
- if (has_relative != has_row || has_row != has_col) {
- api_set_error(err, kErrorTypeValidation,
- "'relative' requires 'row'/'col' or 'bufpos'");
- return false;
+/// Get default statusline highlight for window
+const char *get_default_stl_hl(win_T *wp)
+{
+ if (wp == NULL) {
+ return "TabLineFill";
+ } else if (wp == curwin) {
+ return "StatusLine";
+ } else {
+ return "StatusLineNC";
}
- return true;
}
diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h
index ecce6afa26..08d2c8d90c 100644
--- a/src/nvim/api/private/helpers.h
+++ b/src/nvim/api/private/helpers.h
@@ -4,12 +4,12 @@
#include <stdbool.h>
#include "nvim/api/private/defs.h"
-#include "nvim/vim.h"
-#include "nvim/getchar.h"
-#include "nvim/memory.h"
#include "nvim/decoration.h"
#include "nvim/ex_eval.h"
+#include "nvim/getchar.h"
#include "nvim/lib/kvec.h"
+#include "nvim/memory.h"
+#include "nvim/vim.h"
#define OBJECT_OBJ(o) o
@@ -59,6 +59,9 @@
#define NIL ((Object)OBJECT_INIT)
#define NULL_STRING ((String)STRING_INIT)
+// currently treat key=vim.NIL as if the key was missing
+#define HAS_KEY(o) ((o).type != kObjectTypeNil)
+
#define PUT(dict, k, v) \
kv_push(dict, ((KeyValuePair) { .key = cstr_to_string(k), .value = v }))
@@ -73,7 +76,7 @@
name.size = fixsize; \
name.items = name##__items; \
-#define STATIC_CSTR_AS_STRING(s) ((String) {.data = s, .size = sizeof(s) - 1})
+#define STATIC_CSTR_AS_STRING(s) ((String) { .data = s, .size = sizeof(s) - 1 })
/// Create a new String instance, putting data in allocated memory
///
@@ -134,10 +137,13 @@ typedef struct {
msg_list = &private_msg_list; \
private_msg_list = NULL; \
code \
- msg_list = saved_msg_list; /* Restore the exception context. */ \
+ msg_list = saved_msg_list; /* Restore the exception context. */ \
} while (0)
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "api/private/helpers.h.generated.h"
+# include "keysets.h.generated.h"
#endif
+
+
#endif // NVIM_API_PRIVATE_HELPERS_H
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index 9b200dcba2..d86aecc318 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.c
@@ -40,7 +40,6 @@ typedef struct {
static PMap(uint64_t) connected_uis = MAP_INIT;
void remote_ui_disconnect(uint64_t channel_id)
- FUNC_API_NOEXPORT
{
UI *ui = pmap_get(uint64_t)(&connected_uis, channel_id);
if (!ui) {
@@ -57,7 +56,6 @@ void remote_ui_disconnect(uint64_t channel_id)
/// Wait until ui has connected on stdio channel.
void remote_ui_wait_for_attach(void)
- FUNC_API_NOEXPORT
{
Channel *channel = find_channel(CHAN_STDIO);
if (!channel) {
@@ -172,6 +170,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, Dictiona
/// @deprecated
void ui_attach(uint64_t channel_id, Integer width, Integer height, Boolean enable_rgb, Error *err)
+ FUNC_API_DEPRECATED_SINCE(1)
{
Dictionary opts = ARRAY_DICT_INIT;
PUT(opts, "rgb", BOOLEAN_OBJ(enable_rgb));
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 3be45d0cf7..b5cc02e761 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -17,6 +17,7 @@
#include "nvim/api/window.h"
#include "nvim/ascii.h"
#include "nvim/buffer.h"
+#include "nvim/buffer_defs.h"
#include "nvim/context.h"
#include "nvim/decoration.h"
#include "nvim/edit.h"
@@ -59,7 +60,6 @@
#endif
void api_vim_free_all_mem(void)
- FUNC_API_NOEXPORT
{
String name;
handle_T id;
@@ -196,7 +196,7 @@ Dictionary nvim_get_hl_by_id(Integer hl_id, Boolean rgb, Error *err)
Integer nvim_get_hl_id_by_name(String name)
FUNC_API_SINCE(7)
{
- return syn_check_group((const char_u *)name.data, (int)name.size);
+ return syn_check_group(name.data, (int)name.size);
}
Dictionary nvim__get_hl_defs(Integer ns_id, Error *err)
@@ -228,7 +228,7 @@ Dictionary nvim__get_hl_defs(Integer ns_id, Error *err)
void nvim_set_hl(Integer ns_id, String name, Dictionary val, Error *err)
FUNC_API_SINCE(7)
{
- int hl_id = syn_check_group( (char_u *)(name.data), (int)name.size);
+ int hl_id = syn_check_group(name.data, (int)name.size);
int link_id = -1;
HlAttrs attrs = dict2hlattrs(val, true, &link_id, err);
@@ -264,7 +264,6 @@ void nvim__set_hl_ns(Integer ns_id, Error *err)
}
static void on_redraw_event(void **argv)
- FUNC_API_NOEXPORT
{
redraw_all_later(NOT_VALID);
}
@@ -714,7 +713,7 @@ Object nvim_call_dict_function(Object dict, String fn, Array args, Error *err)
}
fn = (String) {
.data = (char *)di->di_tv.vval.v_string,
- .size = strlen((char *)di->di_tv.vval.v_string),
+ .size = STRLEN(di->di_tv.vval.v_string),
};
}
@@ -758,6 +757,11 @@ ArrayOf(String) nvim_list_runtime_paths(Error *err)
return nvim_get_runtime_file(NULL_STRING, true, err);
}
+Array nvim__runtime_inspect(void)
+{
+ return runtime_inspect();
+}
+
/// Find files in runtime directories
///
/// 'name' can contain wildcards. For example
@@ -796,6 +800,25 @@ String nvim__get_lib_dir(void)
return cstr_as_string(get_lib_dir());
}
+/// Find files in runtime directories
+///
+/// @param pat pattern of files to search for
+/// @param all whether to return all matches or only the first
+/// @param options
+/// is_lua: only search lua subdirs
+/// @return list of absolute paths to the found files
+ArrayOf(String) nvim__get_runtime(Array pat, Boolean all, Dict(runtime) *opts, Error *err)
+ FUNC_API_SINCE(8)
+ FUNC_API_FAST
+{
+ bool is_lua = api_object_to_bool(opts->is_lua, "is_lua", false, err);
+ if (ERROR_SET(err)) {
+ return (Array)ARRAY_DICT_INIT;
+ }
+ return runtime_get_named(is_lua, pat, all);
+}
+
+
/// Changes the global working directory.
///
/// @param dir Directory path
@@ -1221,14 +1244,20 @@ fail:
/// buffer in a configured window before calling this. For instance, for a
/// floating display, first create an empty buffer using |nvim_create_buf()|,
/// then display it using |nvim_open_win()|, and then call this function.
-/// Then |nvim_chan_send()| cal be called immediately to process sequences
+/// Then |nvim_chan_send()| can be called immediately to process sequences
/// in a virtual terminal having the intended size.
///
/// @param buffer the buffer to use (expected to be empty)
-/// @param opts Optional parameters. Reserved for future use.
+/// @param opts Optional parameters.
+/// - on_input: lua callback for input sent, i e keypresses in terminal
+/// mode. Note: keypresses are sent raw as they would be to the pty
+/// master end. For instance, a carriage return is sent
+/// as a "\r", not as a "\n". |textlock| applies. It is possible
+/// to call |nvim_chan_send| directly in the callback however.
+/// ["input", term, bufnr, data]
/// @param[out] err Error details, if any
/// @return Channel id, or 0 on error
-Integer nvim_open_term(Buffer buffer, Dictionary opts, Error *err)
+Integer nvim_open_term(Buffer buffer, DictionaryOf(LuaRef) opts, Error *err)
FUNC_API_SINCE(7)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -1236,13 +1265,27 @@ Integer nvim_open_term(Buffer buffer, Dictionary opts, Error *err)
return 0;
}
- if (opts.size > 0) {
- api_set_error(err, kErrorTypeValidation, "opts dict isn't empty");
- return 0;
+ LuaRef cb = LUA_NOREF;
+ for (size_t i = 0; i < opts.size; i++) {
+ String k = opts.items[i].key;
+ Object *v = &opts.items[i].value;
+ if (strequal("on_input", k.data)) {
+ if (v->type != kObjectTypeLuaRef) {
+ api_set_error(err, kErrorTypeValidation,
+ "%s is not a function", "on_input");
+ return 0;
+ }
+ cb = v->data.luaref;
+ v->data.luaref = LUA_NOREF;
+ break;
+ } else {
+ api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data);
+ }
}
TerminalOptions topts;
Channel *chan = channel_alloc(kChannelStreamInternal);
+ chan->stream.internal.cb = cb;
topts.data = chan;
// NB: overridden in terminal_check_size if a window is already
// displaying the buffer
@@ -1260,7 +1303,18 @@ Integer nvim_open_term(Buffer buffer, Dictionary opts, Error *err)
static void term_write(char *buf, size_t size, void *data)
{
- // TODO(bfredl): lua callback
+ Channel *chan = data;
+ LuaRef cb = chan->stream.internal.cb;
+ if (cb == LUA_NOREF) {
+ return;
+ }
+ FIXED_TEMP_ARRAY(args, 3);
+ args.items[0] = INTEGER_OBJ((Integer)chan->id);
+ args.items[1] = BUFFER_OBJ(terminal_buf(chan->term));
+ args.items[2] = STRING_OBJ(((String){ .data = buf, .size = size }));
+ textlock++;
+ nlua_call_ref(cb, "input", args, false, NULL);
+ textlock--;
}
static void term_resize(uint16_t width, uint16_t height, void *data)
@@ -1305,153 +1359,6 @@ void nvim_chan_send(Integer chan, String data, Error *err)
}
}
-/// Open a new window.
-///
-/// Currently this is used to open floating and external windows.
-/// Floats are windows that are drawn above the split layout, at some anchor
-/// position in some other window. Floats can be drawn internally or by external
-/// GUI with the |ui-multigrid| extension. External windows are only supported
-/// with multigrid GUIs, and are displayed as separate top-level windows.
-///
-/// For a general overview of floats, see |api-floatwin|.
-///
-/// Exactly one of `external` and `relative` must be specified. The `width` and
-/// `height` of the new window must be specified.
-///
-/// With relative=editor (row=0,col=0) refers to the top-left corner of the
-/// screen-grid and (row=Lines-1,col=Columns-1) refers to the bottom-right
-/// corner. Fractional values are allowed, but the builtin implementation
-/// (used by non-multigrid UIs) will always round down to nearest integer.
-///
-/// Out-of-bounds values, and configurations that make the float not fit inside
-/// the main editor, are allowed. The builtin implementation truncates values
-/// so floats are fully within the main screen grid. External GUIs
-/// could let floats hover outside of the main window like a tooltip, but
-/// this should not be used to specify arbitrary WM screen positions.
-///
-/// Example (Lua): window-relative float
-/// <pre>
-/// vim.api.nvim_open_win(0, false,
-/// {relative='win', row=3, col=3, width=12, height=3})
-/// </pre>
-///
-/// Example (Lua): buffer-relative float (travels as buffer is scrolled)
-/// <pre>
-/// vim.api.nvim_open_win(0, false,
-/// {relative='win', width=12, height=3, bufpos={100,10}})
-/// </pre>
-///
-/// @param buffer Buffer to display, or 0 for current buffer
-/// @param enter Enter the window (make it the current window)
-/// @param config Map defining the window configuration. Keys:
-/// - `relative`: Sets the window layout to "floating", placed at (row,col)
-/// coordinates relative to:
-/// - "editor" The global editor grid
-/// - "win" Window given by the `win` field, or current window.
-/// - "cursor" Cursor position in current window.
-/// - `win`: |window-ID| for relative="win".
-/// - `anchor`: Decides which corner of the float to place at (row,col):
-/// - "NW" northwest (default)
-/// - "NE" northeast
-/// - "SW" southwest
-/// - "SE" southeast
-/// - `width`: Window width (in character cells). Minimum of 1.
-/// - `height`: Window height (in character cells). Minimum of 1.
-/// - `bufpos`: Places float relative to buffer text (only when
-/// relative="win"). Takes a tuple of zero-indexed [line, column].
-/// `row` and `col` if given are applied relative to this
-/// position, else they default to `row=1` and `col=0`
-/// (thus like a tooltip near the buffer text).
-/// - `row`: Row position in units of "screen cell height", may be fractional.
-/// - `col`: Column position in units of "screen cell width", may be
-/// fractional.
-/// - `focusable`: Enable focus by user actions (wincmds, mouse events).
-/// Defaults to true. Non-focusable windows can be entered by
-/// |nvim_set_current_win()|.
-/// - `external`: GUI should display the window as an external
-/// top-level window. Currently accepts no other positioning
-/// configuration together with this.
-/// - `zindex`: Stacking order. floats with higher `zindex` go on top on
-/// floats with lower indices. Must be larger than zero. The
-/// following screen elements have hard-coded z-indices:
-/// - 100: insert completion popupmenu
-/// - 200: message scrollback
-/// - 250: cmdline completion popupmenu (when wildoptions+=pum)
-/// The default value for floats are 50. In general, values below 100 are
-/// recommended, unless there is a good reason to overshadow builtin
-/// elements.
-/// - `style`: Configure the appearance of the window. Currently only takes
-/// one non-empty value:
-/// - "minimal" Nvim will display the window with many UI options
-/// disabled. This is useful when displaying a temporary
-/// float where the text should not be edited. Disables
-/// 'number', 'relativenumber', 'cursorline', 'cursorcolumn',
-/// 'foldcolumn', 'spell' and 'list' options. 'signcolumn'
-/// is changed to `auto` and 'colorcolumn' is cleared. The
-/// end-of-buffer region is hidden by setting `eob` flag of
-/// 'fillchars' to a space char, and clearing the
-/// |EndOfBuffer| region in 'winhighlight'.
-/// - `border`: Style of (optional) window border. This can either be a string
-/// or an array. The string values are
-/// - "none": No border (default).
-/// - "single": A single line box.
-/// - "double": A double line box.
-/// - "rounded": Like "single", but with rounded corners ("╭" etc.).
-/// - "solid": Adds padding by a single whitespace cell.
-/// - "shadow": A drop shadow effect by blending with the background.
-/// - If it is an array, it should have a length of eight or any divisor of
-/// eight. The array will specifify the eight chars building up the border
-/// in a clockwise fashion starting with the top-left corner. As an
-/// example, the double box style could be specified as
-/// [ "╔", "═" ,"╗", "║", "╝", "═", "╚", "║" ].
-/// If the number of chars are less than eight, they will be repeated. Thus
-/// an ASCII border could be specified as
-/// [ "/", "-", "\\", "|" ],
-/// or all chars the same as
-/// [ "x" ].
-/// An empty string can be used to turn off a specific border, for instance,
-/// [ "", "", "", ">", "", "", "", "<" ]
-/// will only make vertical borders but not horizontal ones.
-/// By default, `FloatBorder` highlight is used, which links to `VertSplit`
-/// when not defined. It could also be specified by character:
-/// [ {"+", "MyCorner"}, {"x", "MyBorder"} ].
-/// - `noautocmd`: If true then no buffer-related autocommand events such as
-/// |BufEnter|, |BufLeave| or |BufWinEnter| may fire from
-/// calling this function.
-///
-/// @param[out] err Error details, if any
-///
-/// @return Window handle, or 0 on error
-Window nvim_open_win(Buffer buffer, Boolean enter, Dictionary config, Error *err)
- FUNC_API_SINCE(6)
- FUNC_API_CHECK_TEXTLOCK
-{
- FloatConfig fconfig = FLOAT_CONFIG_INIT;
- if (!parse_float_config(config, &fconfig, false, true, err)) {
- return 0;
- }
- win_T *wp = win_new_float(NULL, fconfig, err);
- if (!wp) {
- return 0;
- }
- if (enter) {
- win_enter(wp, false);
- }
- if (!win_valid(wp)) {
- api_set_error(err, kErrorTypeException, "Window was closed immediately");
- return 0;
- }
- if (buffer > 0) {
- win_set_buf(wp->handle, buffer, fconfig.noautocmd, err);
- }
-
- if (fconfig.style == kWinStyleMinimal) {
- win_set_minimal_style(wp);
- didset_window_options(wp);
- }
- return wp->handle;
-}
-
/// Gets the current list of tabpage handles.
///
/// @return List of tabpage handles
@@ -1507,7 +1414,7 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err)
}
}
-/// Creates a new *namespace*, or gets an existing one.
+/// Creates a new \*namespace\* or gets an existing one.
///
/// Namespaces are used for buffer highlights and virtual text, see
/// |nvim_buf_add_highlight()| and |nvim_buf_set_extmark()|.
@@ -1758,24 +1665,15 @@ Dictionary nvim_get_color_map(void)
/// @param[out] err Error details, if any
///
/// @return map of global |context|.
-Dictionary nvim_get_context(Dictionary opts, Error *err)
+Dictionary nvim_get_context(Dict(context) *opts, Error *err)
FUNC_API_SINCE(6)
{
Array types = ARRAY_DICT_INIT;
- for (size_t i = 0; i < opts.size; i++) {
- String k = opts.items[i].key;
- Object v = opts.items[i].value;
- if (strequal("types", k.data)) {
- if (v.type != kObjectTypeArray) {
- api_set_error(err, kErrorTypeValidation, "invalid value for key: %s",
- k.data);
- return (Dictionary)ARRAY_DICT_INIT;
- }
- types = v.data.array;
- } else {
- api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data);
- return (Dictionary)ARRAY_DICT_INIT;
- }
+ if (opts->types.type == kObjectTypeArray) {
+ types = opts->types.data.array;
+ } else if (opts->types.type != kObjectTypeNil) {
+ api_set_error(err, kErrorTypeValidation, "invalid value for key: types");
+ return (Dictionary)ARRAY_DICT_INIT;
}
int int_types = types.size > 0 ? 0 : kCtxAll;
@@ -1885,7 +1783,7 @@ ArrayOf(Dictionary) nvim_get_keymap(String mode)
/// as keys excluding |<buffer>| but including |noremap|.
/// Values are Booleans. Unknown key is an error.
/// @param[out] err Error details, if any.
-void nvim_set_keymap(String mode, String lhs, String rhs, Dictionary opts, Error *err)
+void nvim_set_keymap(String mode, String lhs, String rhs, Dict(keymap) *opts, Error *err)
FUNC_API_SINCE(6)
{
modify_keymap(-1, false, mode, lhs, rhs, opts, err);
@@ -1911,7 +1809,7 @@ void nvim_del_keymap(String mode, String lhs, Error *err)
/// @param[out] err Error details, if any.
///
/// @returns Map of maps describing commands.
-Dictionary nvim_get_commands(Dictionary opts, Error *err)
+Dictionary nvim_get_commands(Dict(get_commands) *opts, Error *err)
FUNC_API_SINCE(4)
{
return nvim_buf_get_commands(-1, opts, err);
@@ -2937,3 +2835,266 @@ void nvim_set_decoration_provider(Integer ns_id, DictionaryOf(LuaRef) opts, Erro
error:
decor_provider_clear(p);
}
+
+/// Deletes a uppercase/file named mark. See |mark-motions|.
+///
+/// @note fails with error if a lowercase or buffer local named mark is used.
+/// @param name Mark name
+/// @return true if the mark was deleted, else false.
+/// @see |nvim_buf_del_mark()|
+/// @see |nvim_get_mark()|
+Boolean nvim_del_mark(String name, Error *err)
+ FUNC_API_SINCE(8)
+{
+ bool res = false;
+ if (name.size != 1) {
+ api_set_error(err, kErrorTypeValidation,
+ "Mark name must be a single character");
+ return res;
+ }
+ // Only allow file/uppercase marks
+ // TODO(muniter): Refactor this ASCII_ISUPPER macro to a proper function
+ if (ASCII_ISUPPER(*name.data) || ascii_isdigit(*name.data)) {
+ res = set_mark(NULL, name, 0, 0, err);
+ } else {
+ api_set_error(err, kErrorTypeValidation,
+ "Only file/uppercase marks allowed, invalid mark name: '%c'",
+ *name.data);
+ }
+ return res;
+}
+
+/// Return a tuple (row, col, buffer, buffername) representing the position of
+/// the uppercase/file named mark. See |mark-motions|.
+///
+/// Marks are (1,0)-indexed. |api-indexing|
+///
+/// @note fails with error if a lowercase or buffer local named mark is used.
+/// @param name Mark name
+/// @return 4-tuple (row, col, buffer, buffername), (0, 0, 0, '') if the mark is
+/// not set.
+/// @see |nvim_buf_set_mark()|
+/// @see |nvim_del_mark()|
+Array nvim_get_mark(String name, Error *err)
+ FUNC_API_SINCE(8)
+{
+ Array rv = ARRAY_DICT_INIT;
+
+ if (name.size != 1) {
+ api_set_error(err, kErrorTypeValidation,
+ "Mark name must be a single character");
+ return rv;
+ } else if (!(ASCII_ISUPPER(*name.data) || ascii_isdigit(*name.data))) {
+ api_set_error(err, kErrorTypeValidation,
+ "Only file/uppercase marks allowed, invalid mark name: '%c'",
+ *name.data);
+ return rv;
+ }
+
+ xfmark_T mark = get_global_mark(*name.data);
+ pos_T pos = mark.fmark.mark;
+ bool allocated = false;
+ int bufnr;
+ char *filename;
+
+ // Marks are from an open buffer it fnum is non zero
+ if (mark.fmark.fnum != 0) {
+ bufnr = mark.fmark.fnum;
+ filename = (char *)buflist_nr2name(bufnr, true, true);
+ allocated = true;
+ // Marks comes from shada
+ } else {
+ filename = (char *)mark.fname;
+ bufnr = 0;
+ }
+
+ bool exists = filename != NULL;
+ Integer row;
+ Integer col;
+
+ if (!exists || pos.lnum <= 0) {
+ if (allocated) {
+ xfree(filename);
+ allocated = false;
+ }
+ filename = "";
+ bufnr = 0;
+ row = 0;
+ col = 0;
+ } else {
+ row = pos.lnum;
+ col = pos.col;
+ }
+
+ ADD(rv, INTEGER_OBJ(row));
+ ADD(rv, INTEGER_OBJ(col));
+ ADD(rv, INTEGER_OBJ(bufnr));
+ ADD(rv, STRING_OBJ(cstr_to_string(filename)));
+
+ if (allocated) {
+ xfree(filename);
+ }
+
+ return rv;
+}
+
+/// Evaluates statusline string.
+///
+/// @param str Statusline string (see 'statusline').
+/// @param opts Optional parameters.
+/// - winid: (number) |window-ID| of the window to use as context for statusline.
+/// - maxwidth: (number) Maximum width of statusline.
+/// - fillchar: (string) Character to fill blank spaces in the statusline (see
+/// 'fillchars').
+/// - highlights: (boolean) Return highlight information.
+/// - use_tabline: (boolean) Evaluate tabline instead of statusline. When |TRUE|, {winid}
+/// is ignored.
+///
+/// @param[out] err Error details, if any.
+/// @return Dictionary containing statusline information, with these keys:
+/// - str: (string) Characters that will be displayed on the statusline.
+/// - width: (number) Display width of the statusline.
+/// - highlights: Array containing highlight information of the statusline. Only included when
+/// the "highlights" key in {opts} is |TRUE|. Each element of the array is a
+/// |Dictionary| with these keys:
+/// - start: (number) Byte index (0-based) of first character that uses the highlight.
+/// - group: (string) Name of highlight group.
+Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error *err)
+ FUNC_API_SINCE(8) FUNC_API_FAST
+{
+ Dictionary result = ARRAY_DICT_INIT;
+
+ int maxwidth;
+ char fillchar = 0;
+ Window window = 0;
+ bool use_tabline = false;
+ bool highlights = false;
+
+ if (HAS_KEY(opts->winid)) {
+ if (opts->winid.type != kObjectTypeInteger) {
+ api_set_error(err, kErrorTypeValidation, "winid must be an integer");
+ return result;
+ }
+
+ window = (Window)opts->winid.data.integer;
+ }
+
+ if (HAS_KEY(opts->fillchar)) {
+ if (opts->fillchar.type != kObjectTypeString || opts->fillchar.data.string.size > 1) {
+ api_set_error(err, kErrorTypeValidation, "fillchar must be an ASCII character");
+ return result;
+ }
+
+ fillchar = opts->fillchar.data.string.data[0];
+ }
+
+ if (HAS_KEY(opts->highlights)) {
+ highlights = api_object_to_bool(opts->highlights, "highlights", false, err);
+
+ if (ERROR_SET(err)) {
+ return result;
+ }
+ }
+
+ if (HAS_KEY(opts->use_tabline)) {
+ use_tabline = api_object_to_bool(opts->use_tabline, "use_tabline", false, err);
+
+ if (ERROR_SET(err)) {
+ return result;
+ }
+ }
+
+ win_T *wp, *ewp;
+
+ if (use_tabline) {
+ wp = NULL;
+ ewp = curwin;
+ fillchar = ' ';
+ } else {
+ wp = find_window_by_handle(window, err);
+ ewp = wp;
+
+ if (fillchar == 0) {
+ int attr;
+ fillchar = (char)fillchar_status(&attr, wp);
+ }
+ }
+
+ if (HAS_KEY(opts->maxwidth)) {
+ if (opts->maxwidth.type != kObjectTypeInteger) {
+ api_set_error(err, kErrorTypeValidation, "maxwidth must be an integer");
+ return result;
+ }
+
+ maxwidth = (int)opts->maxwidth.data.integer;
+ } else {
+ maxwidth = use_tabline ? Columns : wp->w_width;
+ }
+
+ char buf[MAXPATHL];
+ stl_hlrec_t *hltab;
+ stl_hlrec_t **hltab_ptr = highlights ? &hltab : NULL;
+
+ // Temporarily reset 'cursorbind' to prevent side effects from moving the cursor away and back.
+ int p_crb_save = ewp->w_p_crb;
+ ewp->w_p_crb = false;
+
+ int width = build_stl_str_hl(
+ ewp,
+ (char_u *)buf,
+ sizeof(buf),
+ (char_u *)str.data,
+ false,
+ (char_u)fillchar,
+ maxwidth,
+ hltab_ptr,
+ NULL);
+
+ PUT(result, "width", INTEGER_OBJ(width));
+
+ // Restore original value of 'cursorbind'
+ ewp->w_p_crb = p_crb_save;
+
+ if (highlights) {
+ Array hl_values = ARRAY_DICT_INIT;
+ const char *grpname;
+ char user_group[6];
+
+ // If first character doesn't have a defined highlight,
+ // add the default highlight at the beginning of the highlight list
+ if (hltab->start == NULL || ((char *)hltab->start - buf) != 0) {
+ Dictionary hl_info = ARRAY_DICT_INIT;
+ grpname = get_default_stl_hl(wp);
+
+ PUT(hl_info, "start", INTEGER_OBJ(0));
+ PUT(hl_info, "group", CSTR_TO_OBJ(grpname));
+
+ ADD(hl_values, DICTIONARY_OBJ(hl_info));
+ }
+
+ for (stl_hlrec_t *sp = hltab; sp->start != NULL; sp++) {
+ Dictionary hl_info = ARRAY_DICT_INIT;
+
+ PUT(hl_info, "start", INTEGER_OBJ((char *)sp->start - buf));
+
+ if (sp->userhl == 0) {
+ grpname = get_default_stl_hl(wp);
+ } else if (sp->userhl < 0) {
+ grpname = (char *)syn_id2name(-sp->userhl);
+ } else {
+ snprintf(user_group, sizeof(user_group), "User%d", sp->userhl);
+ grpname = user_group;
+ }
+
+ PUT(hl_info, "group", CSTR_TO_OBJ(grpname));
+
+ ADD(hl_values, DICTIONARY_OBJ(hl_info));
+ }
+
+ PUT(result, "highlights", ARRAY_OBJ(hl_values));
+ }
+
+ PUT(result, "str", CSTR_TO_OBJ((char *)buf));
+
+ return result;
+}
diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c
new file mode 100644
index 0000000000..ceb7f71423
--- /dev/null
+++ b/src/nvim/api/win_config.c
@@ -0,0 +1,639 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "nvim/api/private/defs.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/api/win_config.h"
+#include "nvim/ascii.h"
+#include "nvim/option.h"
+#include "nvim/screen.h"
+#include "nvim/strings.h"
+#include "nvim/syntax.h"
+#include "nvim/ui.h"
+#include "nvim/window.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "api/win_config.c.generated.h"
+#endif
+
+
+/// Open a new window.
+///
+/// Currently this is used to open floating and external windows.
+/// Floats are windows that are drawn above the split layout, at some anchor
+/// position in some other window. Floats can be drawn internally or by external
+/// GUI with the |ui-multigrid| extension. External windows are only supported
+/// with multigrid GUIs, and are displayed as separate top-level windows.
+///
+/// For a general overview of floats, see |api-floatwin|.
+///
+/// Exactly one of `external` and `relative` must be specified. The `width` and
+/// `height` of the new window must be specified.
+///
+/// With relative=editor (row=0,col=0) refers to the top-left corner of the
+/// screen-grid and (row=Lines-1,col=Columns-1) refers to the bottom-right
+/// corner. Fractional values are allowed, but the builtin implementation
+/// (used by non-multigrid UIs) will always round down to nearest integer.
+///
+/// Out-of-bounds values, and configurations that make the float not fit inside
+/// the main editor, are allowed. The builtin implementation truncates values
+/// so floats are fully within the main screen grid. External GUIs
+/// could let floats hover outside of the main window like a tooltip, but
+/// this should not be used to specify arbitrary WM screen positions.
+///
+/// Example (Lua): window-relative float
+/// <pre>
+/// vim.api.nvim_open_win(0, false,
+/// {relative='win', row=3, col=3, width=12, height=3})
+/// </pre>
+///
+/// Example (Lua): buffer-relative float (travels as buffer is scrolled)
+/// <pre>
+/// vim.api.nvim_open_win(0, false,
+/// {relative='win', width=12, height=3, bufpos={100,10}})
+/// </pre>
+///
+/// @param buffer Buffer to display, or 0 for current buffer
+/// @param enter Enter the window (make it the current window)
+/// @param config Map defining the window configuration. Keys:
+/// - relative: Sets the window layout to "floating", placed at (row,col)
+/// coordinates relative to:
+/// - "editor" The global editor grid
+/// - "win" Window given by the `win` field, or current window.
+/// - "cursor" Cursor position in current window.
+/// - win: |window-ID| for relative="win".
+/// - anchor: Decides which corner of the float to place at (row,col):
+/// - "NW" northwest (default)
+/// - "NE" northeast
+/// - "SW" southwest
+/// - "SE" southeast
+/// - width: Window width (in character cells). Minimum of 1.
+/// - height: Window height (in character cells). Minimum of 1.
+/// - bufpos: Places float relative to buffer text (only when
+/// relative="win"). Takes a tuple of zero-indexed [line, column].
+/// `row` and `col` if given are applied relative to this
+/// position, else they default to:
+/// - `row=1` and `col=0` if `anchor` is "NW" or "NE"
+/// - `row=0` and `col=0` if `anchor` is "SW" or "SE"
+/// (thus like a tooltip near the buffer text).
+/// - row: Row position in units of "screen cell height", may be fractional.
+/// - col: Column position in units of "screen cell width", may be
+/// fractional.
+/// - focusable: Enable focus by user actions (wincmds, mouse events).
+/// Defaults to true. Non-focusable windows can be entered by
+/// |nvim_set_current_win()|.
+/// - external: GUI should display the window as an external
+/// top-level window. Currently accepts no other positioning
+/// configuration together with this.
+/// - zindex: Stacking order. floats with higher `zindex` go on top on
+/// floats with lower indices. Must be larger than zero. The
+/// following screen elements have hard-coded z-indices:
+/// - 100: insert completion popupmenu
+/// - 200: message scrollback
+/// - 250: cmdline completion popupmenu (when wildoptions+=pum)
+/// The default value for floats are 50. In general, values below 100 are
+/// recommended, unless there is a good reason to overshadow builtin
+/// elements.
+/// - style: Configure the appearance of the window. Currently only takes
+/// one non-empty value:
+/// - "minimal" Nvim will display the window with many UI options
+/// disabled. This is useful when displaying a temporary
+/// float where the text should not be edited. Disables
+/// 'number', 'relativenumber', 'cursorline', 'cursorcolumn',
+/// 'foldcolumn', 'spell' and 'list' options. 'signcolumn'
+/// is changed to `auto` and 'colorcolumn' is cleared. The
+/// end-of-buffer region is hidden by setting `eob` flag of
+/// 'fillchars' to a space char, and clearing the
+/// |EndOfBuffer| region in 'winhighlight'.
+/// - border: Style of (optional) window border. This can either be a string
+/// or an array. The string values are
+/// - "none": No border (default).
+/// - "single": A single line box.
+/// - "double": A double line box.
+/// - "rounded": Like "single", but with rounded corners ("╭" etc.).
+/// - "solid": Adds padding by a single whitespace cell.
+/// - "shadow": A drop shadow effect by blending with the background.
+/// - If it is an array, it should have a length of eight or any divisor of
+/// eight. The array will specifify the eight chars building up the border
+/// in a clockwise fashion starting with the top-left corner. As an
+/// example, the double box style could be specified as
+/// [ "╔", "═" ,"╗", "║", "╝", "═", "╚", "║" ].
+/// If the number of chars are less than eight, they will be repeated. Thus
+/// an ASCII border could be specified as
+/// [ "/", "-", "\\", "|" ],
+/// or all chars the same as
+/// [ "x" ].
+/// An empty string can be used to turn off a specific border, for instance,
+/// [ "", "", "", ">", "", "", "", "<" ]
+/// will only make vertical borders but not horizontal ones.
+/// By default, `FloatBorder` highlight is used, which links to `VertSplit`
+/// when not defined. It could also be specified by character:
+/// [ {"+", "MyCorner"}, {"x", "MyBorder"} ].
+/// - noautocmd: If true then no buffer-related autocommand events such as
+/// |BufEnter|, |BufLeave| or |BufWinEnter| may fire from
+/// calling this function.
+///
+/// @param[out] err Error details, if any
+///
+/// @return Window handle, or 0 on error
+Window nvim_open_win(Buffer buffer, Boolean enter, Dict(float_config) *config, Error *err)
+ FUNC_API_SINCE(6)
+ FUNC_API_CHECK_TEXTLOCK
+{
+ FloatConfig fconfig = FLOAT_CONFIG_INIT;
+ if (!parse_float_config(config, &fconfig, false, true, err)) {
+ return 0;
+ }
+ win_T *wp = win_new_float(NULL, fconfig, err);
+ if (!wp) {
+ return 0;
+ }
+ if (enter) {
+ win_enter(wp, false);
+ }
+ // autocmds in win_enter or win_set_buf below may close the window
+ if (win_valid(wp) && buffer > 0) {
+ win_set_buf(wp->handle, buffer, fconfig.noautocmd, err);
+ }
+ if (!win_valid(wp)) {
+ api_set_error(err, kErrorTypeException, "Window was closed immediately");
+ return 0;
+ }
+
+ if (fconfig.style == kWinStyleMinimal) {
+ win_set_minimal_style(wp);
+ didset_window_options(wp);
+ }
+ return wp->handle;
+}
+
+/// Configures window layout. Currently only for floating and external windows
+/// (including changing a split window to those layouts).
+///
+/// When reconfiguring a floating window, absent option keys will not be
+/// changed. `row`/`col` and `relative` must be reconfigured together.
+///
+/// @see |nvim_open_win()|
+///
+/// @param window Window handle, or 0 for current window
+/// @param config Map defining the window configuration,
+/// see |nvim_open_win()|
+/// @param[out] err Error details, if any
+void nvim_win_set_config(Window window, Dict(float_config) *config, Error *err)
+ FUNC_API_SINCE(6)
+{
+ win_T *win = find_window_by_handle(window, err);
+ if (!win) {
+ return;
+ }
+ bool new_float = !win->w_floating;
+ // reuse old values, if not overridden
+ FloatConfig fconfig = new_float ? FLOAT_CONFIG_INIT : win->w_float_config;
+
+ if (!parse_float_config(config, &fconfig, !new_float, false, err)) {
+ return;
+ }
+ if (new_float) {
+ if (!win_new_float(win, fconfig, err)) {
+ return;
+ }
+ redraw_later(win, NOT_VALID);
+ } else {
+ win_config_float(win, fconfig);
+ win->w_pos_changed = true;
+ }
+ if (fconfig.style == kWinStyleMinimal) {
+ win_set_minimal_style(win);
+ didset_window_options(win);
+ }
+}
+
+/// Gets window configuration.
+///
+/// The returned value may be given to |nvim_open_win()|.
+///
+/// `relative` is empty for normal windows.
+///
+/// @param window Window handle, or 0 for current window
+/// @param[out] err Error details, if any
+/// @return Map defining the window configuration, see |nvim_open_win()|
+Dictionary nvim_win_get_config(Window window, Error *err)
+ FUNC_API_SINCE(6)
+{
+ Dictionary rv = ARRAY_DICT_INIT;
+
+ win_T *wp = find_window_by_handle(window, err);
+ if (!wp) {
+ return rv;
+ }
+
+ FloatConfig *config = &wp->w_float_config;
+
+ PUT(rv, "focusable", BOOLEAN_OBJ(config->focusable));
+ PUT(rv, "external", BOOLEAN_OBJ(config->external));
+
+ if (wp->w_floating) {
+ PUT(rv, "width", INTEGER_OBJ(config->width));
+ PUT(rv, "height", INTEGER_OBJ(config->height));
+ if (!config->external) {
+ if (config->relative == kFloatRelativeWindow) {
+ PUT(rv, "win", INTEGER_OBJ(config->window));
+ if (config->bufpos.lnum >= 0) {
+ Array pos = ARRAY_DICT_INIT;
+ ADD(pos, INTEGER_OBJ(config->bufpos.lnum));
+ ADD(pos, INTEGER_OBJ(config->bufpos.col));
+ PUT(rv, "bufpos", ARRAY_OBJ(pos));
+ }
+ }
+ PUT(rv, "anchor", STRING_OBJ(cstr_to_string(float_anchor_str[config->anchor])));
+ PUT(rv, "row", FLOAT_OBJ(config->row));
+ PUT(rv, "col", FLOAT_OBJ(config->col));
+ PUT(rv, "zindex", INTEGER_OBJ(config->zindex));
+ }
+ if (config->border) {
+ Array border = ARRAY_DICT_INIT;
+ for (size_t i = 0; i < 8; i++) {
+ Array tuple = ARRAY_DICT_INIT;
+
+ String s = cstrn_to_string((const char *)config->border_chars[i], sizeof(schar_T));
+
+ int hi_id = config->border_hl_ids[i];
+ char_u *hi_name = syn_id2name(hi_id);
+ if (hi_name[0]) {
+ ADD(tuple, STRING_OBJ(s));
+ ADD(tuple, STRING_OBJ(cstr_to_string((const char *)hi_name)));
+ ADD(border, ARRAY_OBJ(tuple));
+ } else {
+ ADD(border, STRING_OBJ(s));
+ }
+ }
+ PUT(rv, "border", ARRAY_OBJ(border));
+ }
+ }
+
+ const char *rel = (wp->w_floating && !config->external
+ ? float_relative_str[config->relative] : "");
+ PUT(rv, "relative", STRING_OBJ(cstr_to_string(rel)));
+
+ return rv;
+}
+
+static bool parse_float_anchor(String anchor, FloatAnchor *out)
+{
+ if (anchor.size == 0) {
+ *out = (FloatAnchor)0;
+ }
+ char *str = anchor.data;
+ if (striequal(str, "NW")) {
+ *out = 0; // NW is the default
+ } else if (striequal(str, "NE")) {
+ *out = kFloatAnchorEast;
+ } else if (striequal(str, "SW")) {
+ *out = kFloatAnchorSouth;
+ } else if (striequal(str, "SE")) {
+ *out = kFloatAnchorSouth | kFloatAnchorEast;
+ } else {
+ return false;
+ }
+ return true;
+}
+
+static bool parse_float_relative(String relative, FloatRelative *out)
+{
+ char *str = relative.data;
+ if (striequal(str, "editor")) {
+ *out = kFloatRelativeEditor;
+ } else if (striequal(str, "win")) {
+ *out = kFloatRelativeWindow;
+ } else if (striequal(str, "cursor")) {
+ *out = kFloatRelativeCursor;
+ } else {
+ return false;
+ }
+ return true;
+}
+
+static bool parse_float_bufpos(Array bufpos, lpos_T *out)
+{
+ if (bufpos.size != 2
+ || bufpos.items[0].type != kObjectTypeInteger
+ || bufpos.items[1].type != kObjectTypeInteger) {
+ return false;
+ }
+ out->lnum = bufpos.items[0].data.integer;
+ out->col = (colnr_T)bufpos.items[1].data.integer;
+ return true;
+}
+
+static void parse_border_style(Object style, FloatConfig *fconfig, Error *err)
+{
+ struct {
+ const char *name;
+ schar_T chars[8];
+ bool shadow_color;
+ } defaults[] = {
+ { "double", { "╔", "═", "╗", "║", "╝", "═", "╚", "║" }, false },
+ { "single", { "┌", "─", "┐", "│", "┘", "─", "└", "│" }, false },
+ { "shadow", { "", "", " ", " ", " ", " ", " ", "" }, true },
+ { "rounded", { "╭", "─", "╮", "│", "╯", "─", "╰", "│" }, false },
+ { "solid", { " ", " ", " ", " ", " ", " ", " ", " " }, false },
+ { NULL, { { NUL } }, false },
+ };
+
+ schar_T *chars = fconfig->border_chars;
+ int *hl_ids = fconfig->border_hl_ids;
+
+ fconfig->border = true;
+
+ if (style.type == kObjectTypeArray) {
+ Array arr = style.data.array;
+ size_t size = arr.size;
+ if (!size || size > 8 || (size & (size-1))) {
+ api_set_error(err, kErrorTypeValidation,
+ "invalid number of border chars");
+ return;
+ }
+ for (size_t i = 0; i < size; i++) {
+ Object iytem = arr.items[i];
+ String string;
+ int hl_id = 0;
+ if (iytem.type == kObjectTypeArray) {
+ Array iarr = iytem.data.array;
+ if (!iarr.size || iarr.size > 2) {
+ api_set_error(err, kErrorTypeValidation, "invalid border char");
+ return;
+ }
+ if (iarr.items[0].type != kObjectTypeString) {
+ api_set_error(err, kErrorTypeValidation, "invalid border char");
+ return;
+ }
+ string = iarr.items[0].data.string;
+ if (iarr.size == 2) {
+ hl_id = object_to_hl_id(iarr.items[1], "border char highlight", err);
+ if (ERROR_SET(err)) {
+ return;
+ }
+ }
+ } else if (iytem.type == kObjectTypeString) {
+ string = iytem.data.string;
+ } else {
+ api_set_error(err, kErrorTypeValidation, "invalid border char");
+ return;
+ }
+ if (string.size
+ && mb_string2cells_len((char_u *)string.data, string.size) > 1) {
+ api_set_error(err, kErrorTypeValidation,
+ "border chars must be one cell");
+ return;
+ }
+ size_t len = MIN(string.size, sizeof(*chars)-1);
+ if (len) {
+ memcpy(chars[i], string.data, len);
+ }
+ chars[i][len] = NUL;
+ hl_ids[i] = hl_id;
+ }
+ while (size < 8) {
+ memcpy(chars+size, chars, sizeof(*chars) * size);
+ memcpy(hl_ids+size, hl_ids, sizeof(*hl_ids) * size);
+ size <<= 1;
+ }
+ if ((chars[7][0] && chars[1][0] && !chars[0][0])
+ || (chars[1][0] && chars[3][0] && !chars[2][0])
+ || (chars[3][0] && chars[5][0] && !chars[4][0])
+ || (chars[5][0] && chars[7][0] && !chars[6][0])) {
+ api_set_error(err, kErrorTypeValidation,
+ "corner between used edges must be specified");
+ }
+ } else if (style.type == kObjectTypeString) {
+ String str = style.data.string;
+ if (str.size == 0 || strequal(str.data, "none")) {
+ fconfig->border = false;
+ return;
+ }
+ for (size_t i = 0; defaults[i].name; i++) {
+ if (strequal(str.data, defaults[i].name)) {
+ memcpy(chars, defaults[i].chars, sizeof(defaults[i].chars));
+ memset(hl_ids, 0, 8 * sizeof(*hl_ids));
+ if (defaults[i].shadow_color) {
+ int hl_blend = SYN_GROUP_STATIC("FloatShadow");
+ int hl_through = SYN_GROUP_STATIC("FloatShadowThrough");
+ hl_ids[2] = hl_through;
+ hl_ids[3] = hl_blend;
+ hl_ids[4] = hl_blend;
+ hl_ids[5] = hl_blend;
+ hl_ids[6] = hl_through;
+ }
+ return;
+ }
+ }
+ api_set_error(err, kErrorTypeValidation,
+ "invalid border style \"%s\"", str.data);
+ }
+}
+
+static bool parse_float_config(Dict(float_config) *config, FloatConfig *fconfig, bool reconf,
+ bool new_win, Error *err)
+{
+ bool has_relative = false, relative_is_win = false;
+ if (config->relative.type == kObjectTypeString) {
+ // ignore empty string, to match nvim_win_get_config
+ if (config->relative.data.string.size > 0) {
+ if (!parse_float_relative(config->relative.data.string, &fconfig->relative)) {
+ api_set_error(err, kErrorTypeValidation, "Invalid value of 'relative' key");
+ return false;
+ }
+
+ if (!(HAS_KEY(config->row) && HAS_KEY(config->col)) && !HAS_KEY(config->bufpos)) {
+ api_set_error(err, kErrorTypeValidation,
+ "'relative' requires 'row'/'col' or 'bufpos'");
+ return false;
+ }
+
+ has_relative = true;
+ fconfig->external = false;
+ if (fconfig->relative == kFloatRelativeWindow) {
+ relative_is_win = true;
+ fconfig->bufpos.lnum = -1;
+ }
+ }
+ } else if (HAS_KEY(config->relative)) {
+ api_set_error(err, kErrorTypeValidation, "'relative' key must be String");
+ return false;
+ }
+
+ if (config->anchor.type == kObjectTypeString) {
+ if (!parse_float_anchor(config->anchor.data.string, &fconfig->anchor)) {
+ api_set_error(err, kErrorTypeValidation, "Invalid value of 'anchor' key");
+ return false;
+ }
+ } else if (HAS_KEY(config->anchor)) {
+ api_set_error(err, kErrorTypeValidation, "'anchor' key must be String");
+ return false;
+ }
+
+ if (HAS_KEY(config->row)) {
+ if (!has_relative) {
+ api_set_error(err, kErrorTypeValidation, "non-float cannot have 'row'");
+ return false;
+ } else if (config->row.type == kObjectTypeInteger) {
+ fconfig->row = (double)config->row.data.integer;
+ } else if (config->row.type == kObjectTypeFloat) {
+ fconfig->row = config->row.data.floating;
+ } else {
+ api_set_error(err, kErrorTypeValidation,
+ "'row' key must be Integer or Float");
+ return false;
+ }
+ }
+
+ if (HAS_KEY(config->col)) {
+ if (!has_relative) {
+ api_set_error(err, kErrorTypeValidation, "non-float cannot have 'col'");
+ return false;
+ } else if (config->col.type == kObjectTypeInteger) {
+ fconfig->col = (double)config->col.data.integer;
+ } else if (config->col.type == kObjectTypeFloat) {
+ fconfig->col = config->col.data.floating;
+ } else {
+ api_set_error(err, kErrorTypeValidation,
+ "'col' key must be Integer or Float");
+ return false;
+ }
+ }
+
+ if (HAS_KEY(config->bufpos)) {
+ if (!has_relative) {
+ api_set_error(err, kErrorTypeValidation, "non-float cannot have 'bufpos'");
+ return false;
+ } else if (config->bufpos.type == kObjectTypeArray) {
+ if (!parse_float_bufpos(config->bufpos.data.array, &fconfig->bufpos)) {
+ api_set_error(err, kErrorTypeValidation, "Invalid value of 'bufpos' key");
+ return false;
+ }
+
+ if (!HAS_KEY(config->row)) {
+ fconfig->row = (fconfig->anchor & kFloatAnchorSouth) ? 0 : 1;
+ }
+ if (!HAS_KEY(config->col)) {
+ fconfig->col = 0;
+ }
+ } else {
+ api_set_error(err, kErrorTypeValidation, "'bufpos' key must be Array");
+ return false;
+ }
+ }
+
+ if (config->width.type == kObjectTypeInteger && config->width.data.integer > 0) {
+ fconfig->width = (int)config->width.data.integer;
+ } else if (HAS_KEY(config->width)) {
+ api_set_error(err, kErrorTypeValidation, "'width' key must be a positive Integer");
+ return false;
+ } else if (!reconf) {
+ api_set_error(err, kErrorTypeValidation, "Must specify 'width'");
+ return false;
+ }
+
+ if (config->height.type == kObjectTypeInteger && config->height.data.integer > 0) {
+ fconfig->height = (int)config->height.data.integer;
+ } else if (HAS_KEY(config->height)) {
+ api_set_error(err, kErrorTypeValidation, "'height' key must be a positive Integer");
+ return false;
+ } else if (!reconf) {
+ api_set_error(err, kErrorTypeValidation, "Must specify 'height'");
+ return false;
+ }
+
+ if (relative_is_win) {
+ fconfig->window = curwin->handle;
+ if (config->win.type == kObjectTypeInteger || config->win.type == kObjectTypeWindow) {
+ if (config->win.data.integer > 0) {
+ fconfig->window = (Window)config->win.data.integer;
+ }
+ } else if (HAS_KEY(config->win)) {
+ api_set_error(err, kErrorTypeValidation, "'win' key must be Integer or Window");
+ return false;
+ }
+ } else {
+ if (HAS_KEY(config->win)) {
+ api_set_error(err, kErrorTypeValidation, "'win' key is only valid with relative='win'");
+ return false;
+ }
+ }
+
+ if (HAS_KEY(config->external)) {
+ fconfig->external = api_object_to_bool(config->external, "'external' key", false, err);
+ if (ERROR_SET(err)) {
+ return false;
+ }
+ if (has_relative && fconfig->external) {
+ api_set_error(err, kErrorTypeValidation,
+ "Only one of 'relative' and 'external' must be used");
+ return false;
+ }
+ if (fconfig->external && !ui_has(kUIMultigrid)) {
+ api_set_error(err, kErrorTypeValidation,
+ "UI doesn't support external windows");
+ return false;
+ }
+ }
+
+ if (!reconf && (!has_relative && !fconfig->external)) {
+ api_set_error(err, kErrorTypeValidation,
+ "One of 'relative' and 'external' must be used");
+ return false;
+ }
+
+
+ if (HAS_KEY(config->focusable)) {
+ fconfig->focusable = api_object_to_bool(config->focusable, "'focusable' key", false, err);
+ if (ERROR_SET(err)) {
+ return false;
+ }
+ }
+
+ if (config->zindex.type == kObjectTypeInteger && config->zindex.data.integer > 0) {
+ fconfig->zindex = (int)config->zindex.data.integer;
+ } else if (HAS_KEY(config->zindex)) {
+ api_set_error(err, kErrorTypeValidation, "'zindex' key must be a positive Integer");
+ return false;
+ }
+
+ if (HAS_KEY(config->border)) {
+ parse_border_style(config->border, fconfig, err);
+ if (ERROR_SET(err)) {
+ return false;
+ }
+ }
+
+ if (config->style.type == kObjectTypeString) {
+ if (config->style.data.string.data[0] == NUL) {
+ fconfig->style = kWinStyleUnused;
+ } else if (striequal(config->style.data.string.data, "minimal")) {
+ fconfig->style = kWinStyleMinimal;
+ } else {
+ api_set_error(err, kErrorTypeValidation, "Invalid value of 'style' key");
+ }
+ } else if (HAS_KEY(config->style)) {
+ api_set_error(err, kErrorTypeValidation, "'style' key must be String");
+ return false;
+ }
+
+ if (HAS_KEY(config->noautocmd)) {
+ if (!new_win) {
+ api_set_error(err, kErrorTypeValidation, "Invalid key: 'noautocmd'");
+ return false;
+ }
+ fconfig->noautocmd = api_object_to_bool(config->noautocmd, "'noautocmd' key", false, err);
+ if (ERROR_SET(err)) {
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/src/nvim/api/win_config.h b/src/nvim/api/win_config.h
new file mode 100644
index 0000000000..9271c35f23
--- /dev/null
+++ b/src/nvim/api/win_config.h
@@ -0,0 +1,11 @@
+#ifndef NVIM_API_WIN_CONFIG_H
+#define NVIM_API_WIN_CONFIG_H
+
+#include <stdint.h>
+
+#include "nvim/api/private/defs.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "api/win_config.h.generated.h"
+#endif
+#endif // NVIM_API_WIN_CONFIG_H
diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c
index 99ba297111..6e68c057dc 100644
--- a/src/nvim/api/window.c
+++ b/src/nvim/api/window.c
@@ -373,117 +373,6 @@ Boolean nvim_win_is_valid(Window window)
}
-/// Configures window layout. Currently only for floating and external windows
-/// (including changing a split window to those layouts).
-///
-/// When reconfiguring a floating window, absent option keys will not be
-/// changed. `row`/`col` and `relative` must be reconfigured together.
-///
-/// @see |nvim_open_win()|
-///
-/// @param window Window handle, or 0 for current window
-/// @param config Map defining the window configuration,
-/// see |nvim_open_win()|
-/// @param[out] err Error details, if any
-void nvim_win_set_config(Window window, Dictionary config, Error *err)
- FUNC_API_SINCE(6)
-{
- win_T *win = find_window_by_handle(window, err);
- if (!win) {
- return;
- }
- bool new_float = !win->w_floating;
- // reuse old values, if not overridden
- FloatConfig fconfig = new_float ? FLOAT_CONFIG_INIT : win->w_float_config;
-
- if (!parse_float_config(config, &fconfig, !new_float, false, err)) {
- return;
- }
- if (new_float) {
- if (!win_new_float(win, fconfig, err)) {
- return;
- }
- redraw_later(win, NOT_VALID);
- } else {
- win_config_float(win, fconfig);
- win->w_pos_changed = true;
- }
- if (fconfig.style == kWinStyleMinimal) {
- win_set_minimal_style(win);
- didset_window_options(win);
- }
-}
-
-/// Gets window configuration.
-///
-/// The returned value may be given to |nvim_open_win()|.
-///
-/// `relative` is empty for normal windows.
-///
-/// @param window Window handle, or 0 for current window
-/// @param[out] err Error details, if any
-/// @return Map defining the window configuration, see |nvim_open_win()|
-Dictionary nvim_win_get_config(Window window, Error *err)
- FUNC_API_SINCE(6)
-{
- Dictionary rv = ARRAY_DICT_INIT;
-
- win_T *wp = find_window_by_handle(window, err);
- if (!wp) {
- return rv;
- }
-
- FloatConfig *config = &wp->w_float_config;
-
- PUT(rv, "focusable", BOOLEAN_OBJ(config->focusable));
- PUT(rv, "external", BOOLEAN_OBJ(config->external));
-
- if (wp->w_floating) {
- PUT(rv, "width", INTEGER_OBJ(config->width));
- PUT(rv, "height", INTEGER_OBJ(config->height));
- if (!config->external) {
- if (config->relative == kFloatRelativeWindow) {
- PUT(rv, "win", INTEGER_OBJ(config->window));
- if (config->bufpos.lnum >= 0) {
- Array pos = ARRAY_DICT_INIT;
- ADD(pos, INTEGER_OBJ(config->bufpos.lnum));
- ADD(pos, INTEGER_OBJ(config->bufpos.col));
- PUT(rv, "bufpos", ARRAY_OBJ(pos));
- }
- }
- PUT(rv, "anchor", STRING_OBJ(cstr_to_string(float_anchor_str[config->anchor])));
- PUT(rv, "row", FLOAT_OBJ(config->row));
- PUT(rv, "col", FLOAT_OBJ(config->col));
- PUT(rv, "zindex", INTEGER_OBJ(config->zindex));
- }
- if (config->border) {
- Array border = ARRAY_DICT_INIT;
- for (size_t i = 0; i < 8; i++) {
- Array tuple = ARRAY_DICT_INIT;
-
- String s = cstrn_to_string((const char *)config->border_chars[i], sizeof(schar_T));
-
- int hi_id = config->border_hl_ids[i];
- char_u *hi_name = syn_id2name(hi_id);
- if (hi_name[0]) {
- ADD(tuple, STRING_OBJ(s));
- ADD(tuple, STRING_OBJ(cstr_to_string((const char *)hi_name)));
- ADD(border, ARRAY_OBJ(tuple));
- } else {
- ADD(border, STRING_OBJ(s));
- }
- }
- PUT(rv, "border", ARRAY_OBJ(border));
- }
- }
-
- const char *rel = (wp->w_floating && !config->external
- ? float_relative_str[config->relative] : "");
- PUT(rv, "relative", STRING_OBJ(cstr_to_string(rel)));
-
- return rv;
-}
-
/// Closes the window and hide the buffer it contains (like |:hide| with a
/// |window-ID|).
///
diff --git a/src/nvim/arabic.h b/src/nvim/arabic.h
index 7ea728ed47..eaab463777 100644
--- a/src/nvim/arabic.h
+++ b/src/nvim/arabic.h
@@ -6,8 +6,8 @@
/// Whether c belongs to the range of Arabic characters that might be shaped.
static inline bool arabic_char(int c)
{
- // return c >= a_HAMZA && c <= a_MINI_ALEF;
- return c >= 0x0621 && c <= 0x0670;
+ // return c >= a_HAMZA && c <= a_MINI_ALEF;
+ return c >= 0x0621 && c <= 0x0670;
}
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/ascii.h b/src/nvim/ascii.h
index 7b5e82cd3f..44ed94d2fc 100644
--- a/src/nvim/ascii.h
+++ b/src/nvim/ascii.h
@@ -3,8 +3,8 @@
#include <stdbool.h>
-#include "nvim/macros.h"
#include "nvim/func_attr.h"
+#include "nvim/macros.h"
#include "nvim/os/os_defs.h"
// Definitions of various common control characters.
diff --git a/src/nvim/assert.h b/src/nvim/assert.h
index 1361879876..fc1a4be164 100644
--- a/src/nvim/assert.h
+++ b/src/nvim/assert.h
@@ -49,11 +49,11 @@
#define STATIC_ASSERT_PRAGMA_START
#define STATIC_ASSERT_PRAGMA_END
#define STATIC_ASSERT(cond, msg) \
- do { \
- STATIC_ASSERT_PRAGMA_START \
- STATIC_ASSERT_STATEMENT(cond, msg); \
- STATIC_ASSERT_PRAGMA_END \
- } while (0)
+ do { \
+ STATIC_ASSERT_PRAGMA_START \
+ STATIC_ASSERT_STATEMENT(cond, msg); \
+ STATIC_ASSERT_PRAGMA_END \
+ } while (0)
// the easiest case, when the mode is C11 (generic compiler) or Clang
// advertises explicit support for c_static_assert, meaning it won't warn.
@@ -68,19 +68,19 @@
# undef STATIC_ASSERT_PRAGMA_START
-#if __GNUC__ >= 6
-# define STATIC_ASSERT_PRAGMA_START \
- _Pragma("GCC diagnostic push") \
- _Pragma("GCC diagnostic ignored \"-Wpedantic\"")
-#else
-# define STATIC_ASSERT_PRAGMA_START \
- _Pragma("GCC diagnostic push") \
- _Pragma("GCC diagnostic ignored \"-pedantic\"")
-#endif
+# if __GNUC__ >= 6
+# define STATIC_ASSERT_PRAGMA_START \
+ _Pragma("GCC diagnostic push")\
+ _Pragma("GCC diagnostic ignored \"-Wpedantic\"")
+# else
+# define STATIC_ASSERT_PRAGMA_START \
+ _Pragma("GCC diagnostic push")\
+ _Pragma("GCC diagnostic ignored \"-pedantic\"")
+# endif
# undef STATIC_ASSERT_PRAGMA_END
# define STATIC_ASSERT_PRAGMA_END \
- _Pragma("GCC diagnostic pop")
+ _Pragma("GCC diagnostic pop")
// the same goes for clang in C99 mode, but we suppress a different warning
#elif defined(__clang__) && __has_extension(c_static_assert)
@@ -89,12 +89,12 @@
# undef STATIC_ASSERT_PRAGMA_START
# define STATIC_ASSERT_PRAGMA_START \
- _Pragma("clang diagnostic push") \
- _Pragma("clang diagnostic ignored \"-Wc11-extensions\"")
+ _Pragma("clang diagnostic push")\
+ _Pragma("clang diagnostic ignored \"-Wc11-extensions\"")
# undef STATIC_ASSERT_PRAGMA_END
# define STATIC_ASSERT_PRAGMA_END \
- _Pragma("clang diagnostic pop")
+ _Pragma("clang diagnostic pop")
// TODO(aktau): verify that this works, don't have MSVC on hand.
#elif _MSC_VER >= 1600
@@ -113,14 +113,14 @@
// These can't be used after statements in c89.
#ifdef __COUNTER__
# define STATIC_ASSERT_EXPR(e, m) \
- ((enum { ASSERT_CONCAT(static_assert_, __COUNTER__) = 1/(!!(e)) }) 0)
+ ((enum { ASSERT_CONCAT(static_assert_, __COUNTER__) = 1/(!!(e)) }) 0)
#else
// This can't be used twice on the same line so ensure if using in headers
// that the headers are not included twice (by wrapping in #ifndef...#endif)
// Note it doesn't cause an issue when used on same line of separate modules
// compiled with gcc -combine -fwhole-program.
# define STATIC_ASSERT_EXPR(e, m) \
- ((enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)) }) 0)
+ ((enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)) }) 0)
#endif
/// @def STRICT_ADD
diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c
index 4c502b53d4..d991b88131 100644
--- a/src/nvim/autocmd.c
+++ b/src/nvim/autocmd.c
@@ -24,8 +24,8 @@
#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
-#include "auevents_name_map.generated.h"
-#include "autocmd.c.generated.h"
+# include "auevents_name_map.generated.h"
+# include "autocmd.c.generated.h"
#endif
//
@@ -199,7 +199,7 @@ static void au_cleanup(void)
}
// Loop over all events.
- for (event = (event_T)0; (int)event < (int)NUM_EVENTS;
+ for (event = (event_T)0; (int)event < NUM_EVENTS;
event = (event_T)((int)event + 1)) {
// Loop over all autocommand patterns.
prev_ap = &(first_autopat[(int)event]);
@@ -266,7 +266,7 @@ void aubuflocal_remove(buf_T *buf)
}
// invalidate buflocals looping through events
- for (event = (event_T)0; (int)event < (int)NUM_EVENTS;
+ for (event = (event_T)0; (int)event < NUM_EVENTS;
event = (event_T)((int)event + 1)) {
// loop over all autocommand patterns
for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next) {
@@ -321,7 +321,7 @@ static void au_del_group(char_u *name)
AutoPat *ap;
int in_use = false;
- for (event = (event_T)0; (int)event < (int)NUM_EVENTS;
+ for (event = (event_T)0; (int)event < NUM_EVENTS;
event = (event_T)((int)event + 1)) {
for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next) {
if (ap->group == i && ap->pat != NULL) {
@@ -475,7 +475,7 @@ static char_u *find_end_event(char_u *arg, int have_group)
pat = arg + 1;
} else {
for (pat = arg; *pat && *pat != '|' && !ascii_iswhite(*pat); pat = p) {
- if ((int)event_name2nr(pat, &p) >= (int)NUM_EVENTS) {
+ if ((int)event_name2nr(pat, &p) >= NUM_EVENTS) {
if (have_group) {
EMSG2(_("E216: No such event: %s"), pat);
} else {
@@ -701,7 +701,7 @@ void do_autocmd(char_u *arg_in, int forceit)
if (!forceit && *cmd != NUL) {
EMSG(_(e_cannot_define_autocommands_for_all_events));
} else {
- for (event_T event = (event_T)0; event < (int)NUM_EVENTS;
+ for (event_T event = (event_T)0; event < NUM_EVENTS;
event = (event_T)(event + 1)) {
if (do_autocmd_event(event, pat, once, nested, cmd, forceit, group)
== FAIL) {
@@ -956,10 +956,11 @@ static int do_autocmd_event(event_T event, char_u *pat, bool once, int nested, c
return OK;
}
-// Implementation of ":doautocmd [group] event [fname]".
-// Return OK for success, FAIL for failure;
-int do_doautocmd(char_u *arg, bool do_msg, // give message for no matching autocmds?
- bool *did_something)
+/// Implementation of ":doautocmd [group] event [fname]".
+/// Return OK for success, FAIL for failure;
+///
+/// @param do_msg give message for no matching autocmds?
+int do_doautocmd(char_u *arg, bool do_msg, bool *did_something)
{
char_u *fname;
int nothing_done = true;
@@ -1916,8 +1917,8 @@ char_u *get_augroup_name(expand_T *xp, int idx)
return (char_u *)AUGROUP_NAME(idx);
}
-char_u *set_context_in_autocmd(expand_T *xp, char_u *arg, int doautocmd // true for :doauto*, false for :autocmd
- )
+/// @param doautocmd true for :doauto*, false for :autocmd
+char_u *set_context_in_autocmd(expand_T *xp, char_u *arg, int doautocmd)
{
char_u *p;
int group;
diff --git a/src/nvim/autocmd.h b/src/nvim/autocmd.h
index 1c0f88f08f..ac12e2acf3 100644
--- a/src/nvim/autocmd.h
+++ b/src/nvim/autocmd.h
@@ -17,22 +17,22 @@ typedef struct {
} aco_save_T;
typedef struct AutoCmd {
- char_u *cmd; // Command to be executed (NULL when
- // command has been removed)
+ char_u *cmd; // Command to be executed (NULL when
+ // command has been removed)
bool once; // "One shot": removed after execution
bool nested; // If autocommands nest here
bool last; // last command in list
sctx_T script_ctx; // script context where defined
- struct AutoCmd *next; // Next AutoCmd in list
+ struct AutoCmd *next; // Next AutoCmd in list
} AutoCmd;
typedef struct AutoPat {
- struct AutoPat *next; // next AutoPat in AutoPat list; MUST
- // be the first entry
- char_u *pat; // pattern as typed (NULL when pattern
- // has been removed)
- regprog_T *reg_prog; // compiled regprog for pattern
- AutoCmd *cmds; // list of commands to do
+ struct AutoPat *next; // next AutoPat in AutoPat list; MUST
+ // be the first entry
+ char_u *pat; // pattern as typed (NULL when pattern
+ // has been removed)
+ regprog_T *reg_prog; // compiled regprog for pattern
+ AutoCmd *cmds; // list of commands to do
int group; // group ID
int patlen; // strlen() of pat
int buflocal_nr; // !=0 for buffer-local AutoPat
@@ -48,16 +48,16 @@ typedef struct AutoPat {
/// Struct used to keep status while executing autocommands for an event.
///
typedef struct AutoPatCmd {
- AutoPat *curpat; // next AutoPat to examine
- AutoCmd *nextcmd; // next AutoCmd to execute
+ AutoPat *curpat; // next AutoPat to examine
+ AutoCmd *nextcmd; // next AutoCmd to execute
int group; // group being used
- char_u *fname; // fname to match with
- char_u *sfname; // sfname to match with
- char_u *tail; // tail of fname
+ char_u *fname; // fname to match with
+ char_u *sfname; // sfname to match with
+ char_u *tail; // tail of fname
event_T event; // current event
int arg_bufnr; // initially equal to <abuf>, set to zero when
// buf is deleted
- struct AutoPatCmd *next; // chain of active apc-s for auto-invalidation
+ struct AutoPatCmd *next; // chain of active apc-s for auto-invalidation
} AutoPatCmd;
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 1893bdba0c..826a197454 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -65,6 +65,7 @@
#include "nvim/os/time.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
+#include "nvim/plines.h"
#include "nvim/quickfix.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
@@ -98,13 +99,15 @@ typedef enum {
kBffInitChangedtick = 2,
} BufFreeFlags;
-// Read data from buffer for retrying.
-static int read_buffer(int read_stdin, // read file from stdin, otherwise fifo
- exarg_T *eap, // for forced 'ff' and 'fenc' or NULL
- int flags) // extra flags for readfile()
+/// Read data from buffer for retrying.
+///
+/// @param read_stdin read file from stdin, otherwise fifo
+/// @param eap for forced 'ff' and 'fenc' or NULL
+/// @param flags extra flags for readfile()
+static int read_buffer(int read_stdin, exarg_T *eap, int flags)
{
- int retval = OK;
- linenr_T line_count;
+ int retval = OK;
+ linenr_T line_count;
//
// Read from the buffer which the text is already filled in and append at
@@ -114,7 +117,7 @@ static int read_buffer(int read_stdin, // read file from stdin, otherwis
line_count = curbuf->b_ml.ml_line_count;
retval = readfile(read_stdin ? NULL : curbuf->b_ffname,
read_stdin ? NULL : curbuf->b_fname,
- (linenr_T)line_count, (linenr_T)0, (linenr_T)MAXLNUM, eap,
+ line_count, (linenr_T)0, (linenr_T)MAXLNUM, eap,
flags | READ_BUFFER);
if (retval == OK) {
// Delete the binary lines.
@@ -146,16 +149,18 @@ static int read_buffer(int read_stdin, // read file from stdin, otherwis
return retval;
}
-// Open current buffer, that is: open the memfile and read the file into
-// memory.
-// Return FAIL for failure, OK otherwise.
-int open_buffer(int read_stdin, // read file from stdin
- exarg_T *eap, // for forced 'ff' and 'fenc' or NULL
- int flags // extra flags for readfile()
- )
+/// Open current buffer, that is: open the memfile and read the file into
+/// memory.
+///
+/// @param read_stdin read file from stdin
+/// @param eap for forced 'ff' and 'fenc' or NULL
+/// @param flags extra flags for readfile()
+///
+/// @return FAIL for failure, OK otherwise.
+int open_buffer(int read_stdin, exarg_T *eap, int flags)
{
int retval = OK;
- bufref_T old_curbuf;
+ bufref_T old_curbuf;
long old_tw = curbuf->b_p_tw;
int read_fifo = false;
@@ -521,8 +526,8 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last)
diff_buf_delete(buf); // Clear 'diff' for hidden buffer.
}
- /* Return when a window is displaying the buffer or when it's not
- * unloaded. */
+ // Return when a window is displaying the buffer or when it's not
+ // unloaded.
if (buf->b_nwindows > 0 || !unload_buf) {
return false;
}
@@ -588,9 +593,6 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last)
buf->b_nwindows--;
}
- // Change directories when the 'acd' option is set.
- do_autochdir();
-
// Disable buffer-updates for the current buffer.
// No need to check `unload_buf`: in that case the function returned above.
buf_updates_unload(buf, false);
@@ -816,6 +818,7 @@ static void free_buffer_stuff(buf_T *buf, int free_flags)
uc_clear(&buf->b_ucmds); // clear local user commands
buf_delete_signs(buf, (char_u *)"*"); // delete any signs
extmark_free_all(buf); // delete any extmarks
+ clear_virt_lines(buf, -1);
map_clear_int(buf, MAP_ALL_MODES, true, false); // clear local mappings
map_clear_int(buf, MAP_ALL_MODES, true, true); // clear local abbrevs
XFREE_CLEAR(buf->b_start_fenc);
@@ -939,23 +942,22 @@ void handle_swap_exists(bufref_T *old_curbuf)
swap_exists_action = SEA_NONE; // -V519
}
-/*
- * do_bufdel() - delete or unload buffer(s)
- *
- * addr_count == 0: ":bdel" - delete current buffer
- * addr_count == 1: ":N bdel" or ":bdel N [N ..]" - first delete
- * buffer "end_bnr", then any other arguments.
- * addr_count == 2: ":N,N bdel" - delete buffers in range
- *
- * command can be DOBUF_UNLOAD (":bunload"), DOBUF_WIPE (":bwipeout") or
- * DOBUF_DEL (":bdel")
- *
- * Returns error message or NULL
- */
-char_u *do_bufdel(int command, char_u *arg, // pointer to extra arguments
- int addr_count, int start_bnr, // first buffer number in a range
- int end_bnr, // buffer nr or last buffer nr in a range
- int forceit)
+/// do_bufdel() - delete or unload buffer(s)
+///
+/// addr_count == 0: ":bdel" - delete current buffer
+/// addr_count == 1: ":N bdel" or ":bdel N [N ..]" - first delete
+/// buffer "end_bnr", then any other arguments.
+/// addr_count == 2: ":N,N bdel" - delete buffers in range
+///
+/// command can be DOBUF_UNLOAD (":bunload"), DOBUF_WIPE (":bwipeout") or
+/// DOBUF_DEL (":bdel")
+///
+/// @param arg pointer to extra arguments
+/// @param start_bnr first buffer number in a range
+/// @param end_bnr buffer nr or last buffer nr in a range
+///
+/// @return error message or NULL
+char_u *do_bufdel(int command, char_u *arg, int addr_count, int start_bnr, int end_bnr, int forceit)
{
int do_current = 0; // delete current buffer?
int deleted = 0; // number of buffers deleted
@@ -1097,26 +1099,26 @@ static int empty_curbuf(int close_others, int forceit, int action)
return retval;
}
-/*
- * Implementation of the commands for the buffer list.
- *
- * action == DOBUF_GOTO go to specified buffer
- * action == DOBUF_SPLIT split window and go to specified buffer
- * action == DOBUF_UNLOAD unload specified buffer(s)
- * action == DOBUF_DEL delete specified buffer(s) from buffer list
- * action == DOBUF_WIPE delete specified buffer(s) really
- *
- * start == DOBUF_CURRENT go to "count" buffer from current buffer
- * start == DOBUF_FIRST go to "count" buffer from first buffer
- * start == DOBUF_LAST go to "count" buffer from last buffer
- * start == DOBUF_MOD go to "count" modified buffer from current buffer
- *
- * Return FAIL or OK.
- */
-int do_buffer(int action, int start, int dir, // FORWARD or BACKWARD
- int count, // buffer number or number of buffers
- int forceit // true for :...!
- )
+
+/// Implementation of the commands for the buffer list.
+///
+/// action == DOBUF_GOTO go to specified buffer
+/// action == DOBUF_SPLIT split window and go to specified buffer
+/// action == DOBUF_UNLOAD unload specified buffer(s)
+/// action == DOBUF_DEL delete specified buffer(s) from buffer list
+/// action == DOBUF_WIPE delete specified buffer(s) really
+///
+/// start == DOBUF_CURRENT go to "count" buffer from current buffer
+/// start == DOBUF_FIRST go to "count" buffer from first buffer
+/// start == DOBUF_LAST go to "count" buffer from last buffer
+/// start == DOBUF_MOD go to "count" modified buffer from current buffer
+///
+/// @param dir FORWARD or BACKWARD
+/// @param count buffer number or number of buffers
+/// @param forceit true for :...!
+///
+/// @return FAIL or OK.
+int do_buffer(int action, int start, int dir, int count, int forceit)
{
buf_T *buf;
buf_T *bp;
@@ -1586,8 +1588,8 @@ void enter_buffer(buf_T *buf)
apply_autocmds(EVENT_BUFWINENTER, NULL, NULL, false, curbuf);
}
- /* If autocommands did not change the cursor position, restore cursor lnum
- * and possibly cursor col. */
+ // If autocommands did not change the cursor position, restore cursor lnum
+ // and possibly cursor col.
if (curwin->w_cursor.lnum == 1 && inindent(0)) {
buflist_getfpos();
}
@@ -1623,7 +1625,7 @@ void do_autochdir(void)
if (p_acd) {
if (starting == 0
&& curbuf->b_ffname != NULL
- && vim_chdirfile(curbuf->b_ffname) == OK) {
+ && vim_chdirfile(curbuf->b_ffname, kCdCauseAuto) == OK) {
post_chdir(kCdScopeGlobal, false);
shorten_fnames(true);
}
@@ -1749,8 +1751,8 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int fl
if ((flags & BLN_CURBUF) && curbuf_reusable()) {
assert(curbuf != NULL);
buf = curbuf;
- /* It's like this buffer is deleted. Watch out for autocommands that
- * change curbuf! If that happens, allocate a new buffer anyway. */
+ // It's like this buffer is deleted. Watch out for autocommands that
+ // change curbuf! If that happens, allocate a new buffer anyway.
if (curbuf->b_p_bl) {
apply_autocmds(EVENT_BUFDELETE, NULL, NULL, false, curbuf);
}
@@ -2154,11 +2156,13 @@ static buf_T *buflist_findname_file_id(char_u *ffname, FileID *file_id, bool fil
/// Find file in buffer list by a regexp pattern.
/// Return fnum of the found buffer.
/// Return < 0 for error.
-int buflist_findpat(const char_u *pattern, const char_u *pattern_end, // pointer to first char after pattern
- bool unlisted, // find unlisted buffers
- bool diffmode, // find diff-mode buffers only
- bool curtab_only // find buffers in current tab only
- )
+///
+/// @param pattern_end pointer to first char after pattern
+/// @param unlisted find unlisted buffers
+/// @param diffmode find diff-mode buffers only
+/// @param curtab_only find buffers in current tab only
+int buflist_findpat(const char_u *pattern, const char_u *pattern_end, bool unlisted, bool diffmode,
+ bool curtab_only)
FUNC_ATTR_NONNULL_ARG(1)
{
int match = -1;
@@ -2250,8 +2254,8 @@ int buflist_findpat(const char_u *pattern, const char_u *pattern_end, // pointe
}
}
- /* Only search for unlisted buffers if there was no match with
- * a listed buffer. */
+ // Only search for unlisted buffers if there was no match with
+ // a listed buffer.
if (!unlisted || !find_listed || match != -1) {
break;
}
@@ -2466,14 +2470,14 @@ buf_T *buflist_findnr(int nr)
return handle_get_buffer((handle_T)nr);
}
-/*
- * Get name of file 'n' in the buffer list.
- * When the file has no name an empty string is returned.
- * home_replace() is used to shorten the file name (used for marks).
- * Returns a pointer to allocated memory, of NULL when failed.
- */
-char_u *buflist_nr2name(int n, int fullname, int helptail // for help buffers return tail only
- )
+/// Get name of file 'n' in the buffer list.
+/// When the file has no name an empty string is returned.
+/// home_replace() is used to shorten the file name (used for marks).
+///
+/// @param helptail for help buffers return tail only
+///
+/// @return a pointer to allocated memory, of NULL when failed.
+char_u *buflist_nr2name(int n, int fullname, int helptail)
{
buf_T *buf;
@@ -2546,8 +2550,6 @@ void buflist_setfpos(buf_T *const buf, win_T *const win, linenr_T lnum, colnr_T
if (wip->wi_next) {
wip->wi_next->wi_prev = wip;
}
-
- return;
}
@@ -2706,21 +2708,21 @@ void buflist_list(exarg_T *eap)
const bool job_running = buf->terminal && terminal_running(buf->terminal);
// skip unspecified buffers
- if ((!buf->b_p_bl && !eap->forceit && !strchr((char *)eap->arg, 'u'))
- || (strchr((char *)eap->arg, 'u') && buf->b_p_bl)
- || (strchr((char *)eap->arg, '+')
+ if ((!buf->b_p_bl && !eap->forceit && !vim_strchr(eap->arg, 'u'))
+ || (vim_strchr(eap->arg, 'u') && buf->b_p_bl)
+ || (vim_strchr(eap->arg, '+')
&& ((buf->b_flags & BF_READERR) || !bufIsChanged(buf)))
- || (strchr((char *)eap->arg, 'a')
+ || (vim_strchr(eap->arg, 'a')
&& (buf->b_ml.ml_mfp == NULL || buf->b_nwindows == 0))
- || (strchr((char *)eap->arg, 'h')
+ || (vim_strchr(eap->arg, 'h')
&& (buf->b_ml.ml_mfp == NULL || buf->b_nwindows != 0))
- || (strchr((char *)eap->arg, 'R') && (!is_terminal || !job_running))
- || (strchr((char *)eap->arg, 'F') && (!is_terminal || job_running))
- || (strchr((char *)eap->arg, '-') && buf->b_p_ma)
- || (strchr((char *)eap->arg, '=') && !buf->b_p_ro)
- || (strchr((char *)eap->arg, 'x') && !(buf->b_flags & BF_READERR))
- || (strchr((char *)eap->arg, '%') && buf != curbuf)
- || (strchr((char *)eap->arg, '#')
+ || (vim_strchr(eap->arg, 'R') && (!is_terminal || !job_running))
+ || (vim_strchr(eap->arg, 'F') && (!is_terminal || job_running))
+ || (vim_strchr(eap->arg, '-') && buf->b_p_ma)
+ || (vim_strchr(eap->arg, '=') && !buf->b_p_ro)
+ || (vim_strchr(eap->arg, 'x') && !(buf->b_flags & BF_READERR))
+ || (vim_strchr(eap->arg, '%') && buf != curbuf)
+ || (vim_strchr(eap->arg, '#')
&& (buf == curbuf || curwin->w_alt_fnum != buf->b_fnum))) {
continue;
}
@@ -2800,13 +2802,14 @@ int buflist_name_nr(int fnum, char_u **fname, linenr_T *lnum)
return OK;
}
-// Set the file name for "buf" to "ffname_arg", short file name to
-// "sfname_arg".
-// The file name with the full path is also remembered, for when :cd is used.
-// Returns 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 // give message when buffer already exists
- )
+/// Set the file name for "buf" to "ffname_arg", short file name to
+/// "sfname_arg".
+/// The file name with the full path is also remembered, for when :cd is used.
+///
+/// @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)
{
char_u *ffname = ffname_arg;
char_u *sfname = sfname_arg;
@@ -2887,8 +2890,8 @@ void buf_set_name(int fnum, char_u *name)
xfree(buf->b_ffname);
buf->b_ffname = vim_strsave(name);
buf->b_sfname = NULL;
- /* Allocate ffname and expand into full path. Also resolves .lnk
- * files on Win32. */
+ // Allocate ffname and expand into full path. Also resolves .lnk
+ // files on Win32.
fname_expand(buf, &buf->b_ffname, &buf->b_sfname);
buf->b_fname = buf->b_sfname;
}
@@ -2934,12 +2937,11 @@ buf_T *setaltfname(char_u *ffname, char_u *sfname, linenr_T lnum)
return buf;
}
-/*
- * Get alternate file name for current window.
- * Return NULL if there isn't any, and give error message if requested.
- */
-char_u * getaltfname(bool errmsg // give error message
- )
+/// Get alternate file name for current window.
+/// Return NULL if there isn't any, and give error message if requested.
+///
+/// @param errmsg give error message
+char_u *getaltfname(bool errmsg)
{
char_u *fname;
linenr_T dummy;
@@ -3078,11 +3080,10 @@ static bool buf_same_file_id(buf_T *buf, FileID *file_id)
return buf->file_id_valid && os_fileid_equal(&(buf->file_id), file_id);
}
-/*
- * Print info about the current buffer.
- */
-void fileinfo(int fullname, // when non-zero print full path
- int shorthelp, int dont_truncate)
+/// Print info about the current buffer.
+///
+/// @param fullname when non-zero print full path
+void fileinfo(int fullname, int shorthelp, int dont_truncate)
{
char_u *name;
int n;
@@ -3112,12 +3113,13 @@ void fileinfo(int fullname, // when non-zero print full path
(size_t)(IOSIZE - (p - buffer)), true);
}
+ bool dontwrite = bt_dontwrite(curbuf);
vim_snprintf_add((char *)buffer, IOSIZE, "\"%s%s%s%s%s%s",
curbufIsChanged()
? (shortmess(SHM_MOD) ? " [+]" : _(" [Modified]")) : " ",
- (curbuf->b_flags & BF_NOTEDITED) && !bt_dontwrite(curbuf)
+ (curbuf->b_flags & BF_NOTEDITED) && !dontwrite
? _("[Not edited]") : "",
- (curbuf->b_flags & BF_NEW) && !bt_dontwrite(curbuf)
+ (curbuf->b_flags & BF_NEW) && !dontwrite
? new_file_message() : "",
(curbuf->b_flags & BF_READERR)
? _("[Read errors]") : "",
@@ -3161,8 +3163,8 @@ void fileinfo(int fullname, // when non-zero print full path
(void)append_arg_number(curwin, buffer, IOSIZE, !shortmess(SHM_FILE));
if (dont_truncate) {
- /* Temporarily set msg_scroll to avoid the message being truncated.
- * First call msg_start() to get the message in the right place. */
+ // Temporarily set msg_scroll to avoid the message being truncated.
+ // First call msg_start() to get the message in the right place.
msg_start();
n = msg_scroll;
msg_scroll = true;
@@ -3230,7 +3232,7 @@ void maketitle(void)
int use_sandbox = false;
int save_called_emsg = called_emsg;
- use_sandbox = was_set_insecurely(curwin, (char_u *)"titlestring", 0);
+ use_sandbox = was_set_insecurely(curwin, "titlestring", 0);
called_emsg = false;
build_stl_str_hl(curwin, (char_u *)buf, sizeof(buf),
p_titlestring, use_sandbox,
@@ -3257,7 +3259,7 @@ void maketitle(void)
buf_p += MIN(size, SPACE_FOR_FNAME);
} else {
buf_p += transstr_buf((const char *)path_tail(curbuf->b_fname),
- buf_p, SPACE_FOR_FNAME + 1);
+ buf_p, SPACE_FOR_FNAME + 1, true);
}
switch (bufIsChanged(curbuf)
@@ -3306,7 +3308,7 @@ void maketitle(void)
// room for the server name. When there is no room (very long
// file name) use (...).
if ((size_t)(buf_p - buf) < SPACE_FOR_DIR) {
- char *const tbuf = transstr(buf_p);
+ char *const tbuf = transstr(buf_p, true);
const size_t free_space = SPACE_FOR_DIR - (size_t)(buf_p - buf) + 1;
const size_t dir_len = xstrlcpy(buf_p, tbuf, free_space);
buf_p += MIN(dir_len, free_space - 1);
@@ -3348,7 +3350,7 @@ void maketitle(void)
int use_sandbox = false;
int save_called_emsg = called_emsg;
- use_sandbox = was_set_insecurely(curwin, (char_u *)"iconstring", 0);
+ use_sandbox = was_set_insecurely(curwin, "iconstring", 0);
called_emsg = false;
build_stl_str_hl(curwin, icon_str, sizeof(buf),
p_iconstring, use_sandbox,
@@ -3422,14 +3424,14 @@ void resettitle(void)
ui_flush();
}
-# if defined(EXITFREE)
+#if defined(EXITFREE)
void free_titles(void)
{
xfree(lasttitle);
xfree(lasticon);
}
-# endif
+#endif
/// Enumeration specifying the valid numeric bases that can
/// be used when printing numbers in the status line.
@@ -4652,7 +4654,7 @@ void get_rel_pos(win_T *wp, char_u *buf, int buflen)
long below; // number of lines below window
above = wp->w_topline - 1;
- above += diff_check_fill(wp, wp->w_topline) - wp->w_topfill;
+ above += win_get_fill(wp, wp->w_topline) - wp->w_topfill;
if (wp->w_topline == 1 && wp->w_topfill >= 1) {
// All buffer lines are displayed and there is an indication
// of filler lines, that can be considered seeing all lines.
@@ -4750,12 +4752,11 @@ char_u *alist_name(aentry_T *aep)
return bp->b_fname;
}
-/*
- * do_arg_all(): Open up to 'count' windows, one for each argument.
- */
-void do_arg_all(int count, int forceit, // hide buffers in current windows
- int keep_tabs // keep current tabs, for ":tab drop file"
- )
+/// do_arg_all(): Open up to 'count' windows, one for each argument.
+///
+/// @param forceit hide buffers in current windows
+/// @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:
// 0: not opened
@@ -5229,8 +5230,8 @@ void do_modelines(int flags)
return;
}
- /* Disallow recursive entry here. Can happen when executing a modeline
- * triggers an autocommand, which reloads modelines with a ":do". */
+ // Disallow recursive entry here. Can happen when executing a modeline
+ // triggers an autocommand, which reloads modelines with a ":do".
if (entered) {
return;
}
@@ -5253,12 +5254,11 @@ void do_modelines(int flags)
entered--;
}
-/*
- * chk_modeline() - check a single line for a mode string
- * Return FAIL if an error encountered.
- */
-static int chk_modeline(linenr_T lnum, int flags // Same as for do_modelines().
- )
+/// chk_modeline() - check a single line for a mode string
+/// Return FAIL if an error encountered.
+///
+/// @param flags Same as for do_modelines().
+static int chk_modeline(linenr_T lnum, int flags)
{
char_u *s;
char_u *e;
@@ -5630,13 +5630,12 @@ bool buf_contents_changed(buf_T *buf)
return differ;
}
-/*
- * Wipe out a buffer and decrement the last buffer number if it was used for
- * this buffer. Call this to wipe out a temp buffer that does not contain any
- * marks.
- */
-void wipe_buffer(buf_T *buf, bool aucmd // When true trigger autocommands.
- )
+/// Wipe out a buffer and decrement the last buffer number if it was used for
+/// this buffer. Call this to wipe out a temp buffer that does not contain any
+/// marks.
+///
+/// @param aucmd When true trigger autocommands.
+void wipe_buffer(buf_T *buf, bool aucmd)
{
if (!aucmd) {
// Don't trigger BufDelete autocommands here.
diff --git a/src/nvim/buffer.h b/src/nvim/buffer.h
index 02a2ac36f7..0484c8550d 100644
--- a/src/nvim/buffer.h
+++ b/src/nvim/buffer.h
@@ -1,21 +1,21 @@
#ifndef NVIM_BUFFER_H
#define NVIM_BUFFER_H
-#include "nvim/vim.h"
-#include "nvim/window.h"
-#include "nvim/pos.h" // for linenr_T
+#include "nvim/eval.h"
#include "nvim/ex_cmds_defs.h" // for exarg_T
-#include "nvim/screen.h" // for StlClickRecord
#include "nvim/func_attr.h"
-#include "nvim/eval.h"
#include "nvim/macros.h"
#include "nvim/memline.h"
+#include "nvim/pos.h" // for linenr_T
+#include "nvim/screen.h" // for StlClickRecord
+#include "nvim/vim.h"
+#include "nvim/window.h"
// Values for buflist_getfile()
enum getf_values {
- GETF_SETMARK = 0x01, // set pcmark before jumping
- GETF_ALT = 0x02, // jumping to alternate file (not buf num)
- GETF_SWITCH = 0x04, // respect 'switchbuf' settings when jumping
+ GETF_SETMARK = 0x01, // set pcmark before jumping
+ GETF_ALT = 0x02, // jumping to alternate file (not buf num)
+ GETF_SWITCH = 0x04, // respect 'switchbuf' settings when jumping
};
// Return values of getfile()
@@ -41,26 +41,26 @@ enum bln_values {
// Values for action argument for do_buffer()
enum dobuf_action_values {
- DOBUF_GOTO = 0, // go to specified buffer
- DOBUF_SPLIT = 1, // split window and go to specified buffer
- DOBUF_UNLOAD = 2, // unload specified buffer(s)
- DOBUF_DEL = 3, // delete specified buffer(s) from buflist
- DOBUF_WIPE = 4, // delete specified buffer(s) really
+ DOBUF_GOTO = 0, // go to specified buffer
+ DOBUF_SPLIT = 1, // split window and go to specified buffer
+ DOBUF_UNLOAD = 2, // unload specified buffer(s)
+ DOBUF_DEL = 3, // delete specified buffer(s) from buflist
+ DOBUF_WIPE = 4, // delete specified buffer(s) really
};
// Values for start argument for do_buffer()
enum dobuf_start_values {
- DOBUF_CURRENT = 0, // "count" buffer from current buffer
- DOBUF_FIRST = 1, // "count" buffer from first buffer
- DOBUF_LAST = 2, // "count" buffer from last buffer
- DOBUF_MOD = 3, // "count" mod. buffer from current buffer
+ DOBUF_CURRENT = 0, // "count" buffer from current buffer
+ DOBUF_FIRST = 1, // "count" buffer from first buffer
+ DOBUF_LAST = 2, // "count" buffer from last buffer
+ DOBUF_MOD = 3, // "count" mod. buffer from current buffer
};
// flags for buf_freeall()
enum bfa_values {
- BFA_DEL = 1, // buffer is going to be deleted
- BFA_WIPE = 2, // buffer is going to be wiped out
- BFA_KEEP_UNDO = 4, // do not free undo information
+ BFA_DEL = 1, // buffer is going to be deleted
+ BFA_WIPE = 2, // buffer is going to be wiped out
+ BFA_KEEP_UNDO = 4, // do not free undo information
};
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -75,14 +75,12 @@ static inline void buf_set_changedtick(buf_T *const buf,
///
/// @param[out] buf Buffer to set changedtick in.
/// @param[in] changedtick New value.
-static inline void buf_set_changedtick(buf_T *const buf,
- const varnumber_T changedtick)
+static inline void buf_set_changedtick(buf_T *const buf, const varnumber_T changedtick)
{
typval_T old_val = buf->changedtick_di.di_tv;
#ifndef NDEBUG
- dictitem_T *const changedtick_di = tv_dict_find(
- buf->b_vars, S_LEN("changedtick"));
+ dictitem_T *const changedtick_di = tv_dict_find(buf->b_vars, S_LEN("changedtick"));
assert(changedtick_di != NULL);
assert(changedtick_di->di_tv.v_type == VAR_NUMBER);
assert(changedtick_di->di_tv.v_lock == VAR_FIXED);
@@ -132,7 +130,7 @@ static inline void buf_inc_changedtick(buf_T *const buf)
static inline bool buf_is_empty(buf_T *buf)
{
return buf->b_ml.ml_line_count == 1
- && *ml_get_buf(buf, (linenr_T)1, false) == '\0';
+ && *ml_get_buf(buf, (linenr_T)1, false) == '\0';
}
#endif // NVIM_BUFFER_H
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index ba2bcd7223..19b0a3c5c6 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -6,14 +6,14 @@
// for FILE
#include <stdio.h>
-typedef struct file_buffer buf_T; // Forward declaration
+typedef struct file_buffer buf_T; // Forward declaration
// Reference to a buffer that stores the value of buf_free_count.
// bufref_valid() only needs to check "buf" when the count differs.
typedef struct {
buf_T *br_buf;
- int br_fnum;
- int br_buf_free_count;
+ int br_fnum;
+ int br_buf_free_count;
} bufref_T;
// for garray_T
@@ -111,16 +111,15 @@ typedef uint16_t disptick_T; // display tick type
// for synstate_T (needs reg_extmatch_T, win_T, buf_T)
#include "nvim/syntax_defs.h"
// for sign_entry_T
-#include "nvim/sign_defs.h"
-
#include "nvim/os/fs_defs.h" // for FileID
+#include "nvim/sign_defs.h"
#include "nvim/terminal.h" // for Terminal
/*
* The taggy struct is used to store the information about a :tag command.
*/
typedef struct taggy {
- char_u *tagname; // tag name
+ char_u *tagname; // tag name
fmark_T fmark; // cursor position BEFORE ":tag"
int cur_match; // match number
int cur_fnum; // buffer number used for cur_match
@@ -161,45 +160,45 @@ typedef struct
*/
typedef struct {
int wo_arab;
-# define w_p_arab w_onebuf_opt.wo_arab // 'arabic'
+#define w_p_arab w_onebuf_opt.wo_arab // 'arabic'
int wo_bri;
-# define w_p_bri w_onebuf_opt.wo_bri // 'breakindent'
+#define w_p_bri w_onebuf_opt.wo_bri // 'breakindent'
char_u *wo_briopt;
-# define w_p_briopt w_onebuf_opt.wo_briopt // 'breakindentopt'
+#define w_p_briopt w_onebuf_opt.wo_briopt // 'breakindentopt'
int wo_diff;
-# define w_p_diff w_onebuf_opt.wo_diff // 'diff'
+#define w_p_diff w_onebuf_opt.wo_diff // 'diff'
char_u *wo_fdc;
-# define w_p_fdc w_onebuf_opt.wo_fdc // 'foldcolumn'
+#define w_p_fdc w_onebuf_opt.wo_fdc // 'foldcolumn'
char_u *wo_fdc_save;
-# define w_p_fdc_save w_onebuf_opt.wo_fdc_save // 'fdc' saved for diff mode
+#define w_p_fdc_save w_onebuf_opt.wo_fdc_save // 'fdc' saved for diff mode
int wo_fen;
-# define w_p_fen w_onebuf_opt.wo_fen // 'foldenable'
+#define w_p_fen w_onebuf_opt.wo_fen // 'foldenable'
int wo_fen_save;
// 'foldenable' saved for diff mode
-# define w_p_fen_save w_onebuf_opt.wo_fen_save
- char_u *wo_fdi;
-# define w_p_fdi w_onebuf_opt.wo_fdi // 'foldignore'
+#define w_p_fen_save w_onebuf_opt.wo_fen_save
+ char_u *wo_fdi;
+#define w_p_fdi w_onebuf_opt.wo_fdi // 'foldignore'
long wo_fdl;
-# define w_p_fdl w_onebuf_opt.wo_fdl // 'foldlevel'
+#define w_p_fdl w_onebuf_opt.wo_fdl // 'foldlevel'
int wo_fdl_save;
// 'foldlevel' state saved for diff mode
-# define w_p_fdl_save w_onebuf_opt.wo_fdl_save
- char_u *wo_fdm;
-# define w_p_fdm w_onebuf_opt.wo_fdm // 'foldmethod'
- char_u *wo_fdm_save;
-# define w_p_fdm_save w_onebuf_opt.wo_fdm_save // 'fdm' saved for diff mode
+#define w_p_fdl_save w_onebuf_opt.wo_fdl_save
+ char_u *wo_fdm;
+#define w_p_fdm w_onebuf_opt.wo_fdm // 'foldmethod'
+ char_u *wo_fdm_save;
+#define w_p_fdm_save w_onebuf_opt.wo_fdm_save // 'fdm' saved for diff mode
long wo_fml;
-# define w_p_fml w_onebuf_opt.wo_fml // 'foldminlines'
+#define w_p_fml w_onebuf_opt.wo_fml // 'foldminlines'
long wo_fdn;
-# define w_p_fdn w_onebuf_opt.wo_fdn // 'foldnestmax'
- char_u *wo_fde;
-# define w_p_fde w_onebuf_opt.wo_fde // 'foldexpr'
- char_u *wo_fdt;
-# define w_p_fdt w_onebuf_opt.wo_fdt // 'foldtext'
- char_u *wo_fmr;
-# define w_p_fmr w_onebuf_opt.wo_fmr // 'foldmarker'
+#define w_p_fdn w_onebuf_opt.wo_fdn // 'foldnestmax'
+ char_u *wo_fde;
+#define w_p_fde w_onebuf_opt.wo_fde // 'foldexpr'
+ char_u *wo_fdt;
+#define w_p_fdt w_onebuf_opt.wo_fdt // 'foldtext'
+ char_u *wo_fmr;
+#define w_p_fmr w_onebuf_opt.wo_fmr // 'foldmarker'
int wo_lbr;
-# define w_p_lbr w_onebuf_opt.wo_lbr // 'linebreak'
+#define w_p_lbr w_onebuf_opt.wo_lbr // 'linebreak'
int wo_list;
#define w_p_list w_onebuf_opt.wo_list // 'list'
int wo_nu;
@@ -207,64 +206,64 @@ typedef struct {
int wo_rnu;
#define w_p_rnu w_onebuf_opt.wo_rnu // 'relativenumber'
long wo_nuw;
-# define w_p_nuw w_onebuf_opt.wo_nuw // 'numberwidth'
+#define w_p_nuw w_onebuf_opt.wo_nuw // 'numberwidth'
int wo_wfh;
-# define w_p_wfh w_onebuf_opt.wo_wfh // 'winfixheight'
+#define w_p_wfh w_onebuf_opt.wo_wfh // 'winfixheight'
int wo_wfw;
-# define w_p_wfw w_onebuf_opt.wo_wfw // 'winfixwidth'
+#define w_p_wfw w_onebuf_opt.wo_wfw // 'winfixwidth'
int wo_pvw;
-# define w_p_pvw w_onebuf_opt.wo_pvw // 'previewwindow'
+#define w_p_pvw w_onebuf_opt.wo_pvw // 'previewwindow'
int wo_rl;
-# define w_p_rl w_onebuf_opt.wo_rl // 'rightleft'
- char_u *wo_rlc;
-# define w_p_rlc w_onebuf_opt.wo_rlc // 'rightleftcmd'
+#define w_p_rl w_onebuf_opt.wo_rl // 'rightleft'
+ char_u *wo_rlc;
+#define w_p_rlc w_onebuf_opt.wo_rlc // 'rightleftcmd'
long wo_scr;
#define w_p_scr w_onebuf_opt.wo_scr // 'scroll'
int wo_spell;
-# define w_p_spell w_onebuf_opt.wo_spell // 'spell'
+#define w_p_spell w_onebuf_opt.wo_spell // 'spell'
int wo_cuc;
-# define w_p_cuc w_onebuf_opt.wo_cuc // 'cursorcolumn'
+#define w_p_cuc w_onebuf_opt.wo_cuc // 'cursorcolumn'
int wo_cul;
-# define w_p_cul w_onebuf_opt.wo_cul // 'cursorline'
- char_u *wo_culopt;
-# define w_p_culopt w_onebuf_opt.wo_culopt // 'cursorlineopt'
- char_u *wo_cc;
-# define w_p_cc w_onebuf_opt.wo_cc // 'colorcolumn'
- char_u *wo_sbr;
-# define w_p_sbr w_onebuf_opt.wo_sbr // 'showbreak'
- char_u *wo_stl;
+#define w_p_cul w_onebuf_opt.wo_cul // 'cursorline'
+ char_u *wo_culopt;
+#define w_p_culopt w_onebuf_opt.wo_culopt // 'cursorlineopt'
+ char_u *wo_cc;
+#define w_p_cc w_onebuf_opt.wo_cc // 'colorcolumn'
+ char_u *wo_sbr;
+#define w_p_sbr w_onebuf_opt.wo_sbr // 'showbreak'
+ char_u *wo_stl;
#define w_p_stl w_onebuf_opt.wo_stl // 'statusline'
int wo_scb;
-# define w_p_scb w_onebuf_opt.wo_scb // 'scrollbind'
+#define w_p_scb w_onebuf_opt.wo_scb // 'scrollbind'
int wo_diff_saved; // options were saved for starting diff mode
-# define w_p_diff_saved w_onebuf_opt.wo_diff_saved
+#define w_p_diff_saved w_onebuf_opt.wo_diff_saved
int wo_scb_save; // 'scrollbind' saved for diff mode
-# define w_p_scb_save w_onebuf_opt.wo_scb_save
+#define w_p_scb_save w_onebuf_opt.wo_scb_save
int wo_wrap;
#define w_p_wrap w_onebuf_opt.wo_wrap // 'wrap'
int wo_wrap_save; // 'wrap' state saved for diff mode
-# define w_p_wrap_save w_onebuf_opt.wo_wrap_save
- char_u *wo_cocu; // 'concealcursor'
-# define w_p_cocu w_onebuf_opt.wo_cocu
+#define w_p_wrap_save w_onebuf_opt.wo_wrap_save
+ char_u *wo_cocu; // 'concealcursor'
+#define w_p_cocu w_onebuf_opt.wo_cocu
long wo_cole; // 'conceallevel'
-# define w_p_cole w_onebuf_opt.wo_cole
+#define w_p_cole w_onebuf_opt.wo_cole
int wo_crb;
-# define w_p_crb w_onebuf_opt.wo_crb // 'cursorbind'
+#define w_p_crb w_onebuf_opt.wo_crb // 'cursorbind'
int wo_crb_save; // 'cursorbind' state saved for diff mode
-# define w_p_crb_save w_onebuf_opt.wo_crb_save
+#define w_p_crb_save w_onebuf_opt.wo_crb_save
char_u *wo_scl;
-# define w_p_scl w_onebuf_opt.wo_scl // 'signcolumn'
+#define w_p_scl w_onebuf_opt.wo_scl // 'signcolumn'
char_u *wo_winhl;
-# define w_p_winhl w_onebuf_opt.wo_winhl // 'winhighlight'
+#define w_p_winhl w_onebuf_opt.wo_winhl // 'winhighlight'
char_u *wo_fcs;
-# define w_p_fcs w_onebuf_opt.wo_fcs // 'fillchars'
+#define w_p_fcs w_onebuf_opt.wo_fcs // 'fillchars'
char_u *wo_lcs;
-# define w_p_lcs w_onebuf_opt.wo_lcs // 'listchars'
+#define w_p_lcs w_onebuf_opt.wo_lcs // 'listchars'
long wo_winbl;
-# define w_p_winbl w_onebuf_opt.wo_winbl // 'winblend'
+#define w_p_winbl w_onebuf_opt.wo_winbl // 'winblend'
LastSet wo_script_ctx[WV_COUNT]; // SCTXs for window-local options
-# define w_p_script_ctx w_onebuf_opt.wo_script_ctx
+#define w_p_script_ctx w_onebuf_opt.wo_script_ctx
} winopt_T;
/*
@@ -278,9 +277,9 @@ typedef struct {
* most-recently-used order.
*/
struct wininfo_S {
- wininfo_T *wi_next; // next entry or NULL for last entry
- wininfo_T *wi_prev; // previous entry or NULL for first entry
- win_T *wi_win; // pointer to window that did set wi_fpos
+ wininfo_T *wi_next; // next entry or NULL for last entry
+ wininfo_T *wi_prev; // previous entry or NULL for first entry
+ win_T *wi_win; // pointer to window that did set wi_fpos
pos_T wi_fpos; // last cursor position in the file
bool wi_optset; // true when wi_opt has useful values
winopt_T wi_opt; // local window options
@@ -306,11 +305,11 @@ typedef struct arglist {
//
// TODO(Felipe): move aentry_T to another header
typedef struct argentry {
- char_u *ae_fname; // file name as specified
+ char_u *ae_fname; // file name as specified
int ae_fnum; // buffer number with expanded file name
} aentry_T;
-# define ALIST(win) (win)->w_alist
+#define ALIST(win) (win)->w_alist
#define GARGLIST ((aentry_T *)global_alist.al_ga.ga_data)
#define ARGLIST ((aentry_T *)ALIST(curwin)->al_ga.ga_data)
#define WARGLIST(wp) ((aentry_T *)ALIST(wp)->al_ga.ga_data)
@@ -323,8 +322,8 @@ typedef struct argentry {
* Used for the typeahead buffer: typebuf.
*/
typedef struct {
- char_u *tb_buf; // buffer for typed characters
- char_u *tb_noremap; // mapping flags for characters in tb_buf[]
+ char_u *tb_buf; // buffer for typed characters
+ char_u *tb_noremap; // mapping flags for characters in tb_buf[]
int tb_buflen; // size of tb_buf[]
int tb_off; // current position in tb_buf[]
int tb_len; // number of valid bytes in tb_buf[]
@@ -350,10 +349,10 @@ typedef struct {
*/
typedef struct mapblock mapblock_T;
struct mapblock {
- mapblock_T *m_next; // next mapblock in list
- char_u *m_keys; // mapped from, lhs
- char_u *m_str; // mapped to, rhs
- char_u *m_orig_str; // rhs as entered by the user
+ mapblock_T *m_next; // next mapblock in list
+ char_u *m_keys; // mapped from, lhs
+ char_u *m_str; // mapped to, rhs
+ char_u *m_orig_str; // rhs as entered by the user
int m_keylen; // strlen(m_keys)
int m_mode; // valid mode
int m_noremap; // if non-zero no re-mapping for m_str
@@ -366,7 +365,7 @@ struct mapblock {
/// Used for highlighting in the status line.
typedef struct stl_hlrec stl_hlrec_t;
struct stl_hlrec {
- char_u *start;
+ char_u *start;
int userhl; // 0: no HL, 1-9: User HL, < 0 for syn ID
};
@@ -403,7 +402,7 @@ struct stl_item {
#define SYNFLD_MINIMUM 1 // use lowest local minimum level on line
// avoid #ifdefs for when b_spell is not available
-# define B_SPELL(buf) ((buf)->b_spell)
+#define B_SPELL(buf) ((buf)->b_spell)
typedef struct qf_info_S qf_info_T;
@@ -440,8 +439,8 @@ typedef struct {
long b_syn_sync_minlines; // minimal sync lines offset
long b_syn_sync_maxlines; // maximal sync lines offset
long b_syn_sync_linebreaks; // offset for multi-line pattern
- char_u *b_syn_linecont_pat; // line continuation pattern
- regprog_T *b_syn_linecont_prog; // line continuation program
+ char_u *b_syn_linecont_pat; // line continuation pattern
+ regprog_T *b_syn_linecont_prog; // line continuation program
syn_time_T b_syn_linecont_time;
int b_syn_linecont_ic; // ignore-case flag for above
int b_syn_topgrp; // for ":syntax include"
@@ -460,10 +459,10 @@ typedef struct {
// b_sst_freecount number of free entries in b_sst_array[]
// b_sst_check_lnum entries after this lnum need to be checked for
// validity (MAXLNUM means no check needed)
- synstate_T *b_sst_array;
+ synstate_T *b_sst_array;
int b_sst_len;
- synstate_T *b_sst_first;
- synstate_T *b_sst_firstfree;
+ synstate_T *b_sst_first;
+ synstate_T *b_sst_firstfree;
int b_sst_freecount;
linenr_T b_sst_check_lnum;
disptick_T b_sst_lasttick; // last display tick
@@ -471,12 +470,12 @@ typedef struct {
// for spell checking
garray_T b_langp; // list of pointers to slang_T, see spell.c
bool b_spell_ismw[256]; // flags: is midword char
- char_u *b_spell_ismw_mb; // multi-byte midword chars
- char_u *b_p_spc; // 'spellcapcheck'
- regprog_T *b_cap_prog; // program for 'spellcapcheck'
- char_u *b_p_spf; // 'spellfile'
- char_u *b_p_spl; // 'spelllang'
- char_u *b_p_spo; // 'spelloptions'
+ char_u *b_spell_ismw_mb; // multi-byte midword chars
+ char_u *b_p_spc; // 'spellcapcheck'
+ regprog_T *b_cap_prog; // program for 'spellcapcheck'
+ char_u *b_p_spf; // 'spellfile'
+ char_u *b_p_spl; // 'spelllang'
+ char_u *b_p_spo; // 'spelloptions'
int b_cjk; // all CJK letters as OK
char_u b_syn_chartab[32]; // syntax iskeyword option
char_u *b_syn_isk; // iskeyword option
@@ -521,8 +520,8 @@ struct file_buffer {
memline_T b_ml; // associated memline (also contains line count
- buf_T *b_next; // links in list of buffers
- buf_T *b_prev;
+ buf_T *b_next; // links in list of buffers
+ buf_T *b_prev;
int b_nwindows; // nr of windows open on this buffer
@@ -538,11 +537,11 @@ struct file_buffer {
// b_fname is the same as b_sfname, unless ":cd" has been done,
// then it is the same as b_ffname (NULL for no name).
//
- char_u *b_ffname; // full path file name, allocated
- char_u *b_sfname; // short file name, allocated, may be equal to
- // b_ffname
- char_u *b_fname; // current file name, points to b_ffname or
- // b_sfname
+ char_u *b_ffname; // full path file name, allocated
+ char_u *b_sfname; // short file name, allocated, may be equal to
+ // b_ffname
+ char_u *b_fname; // current file name, points to b_ffname or
+ // b_sfname
bool file_id_valid;
FileID file_id;
@@ -577,7 +576,7 @@ struct file_buffer {
// change
long b_mod_xlines; // number of extra buffer lines inserted;
// negative when lines were deleted
- wininfo_T *b_wininfo; // list of last used info for each window
+ wininfo_T *b_wininfo; // list of last used info for each window
int b_mod_tick_syn; // last display tick syntax was updated
int b_mod_tick_decor; // last display tick decoration providers
// where invoked
@@ -614,10 +613,10 @@ struct file_buffer {
uint64_t b_chartab[4];
// Table used for mappings local to a buffer.
- mapblock_T *(b_maphash[MAX_MAPHASH]);
+ mapblock_T *(b_maphash[MAX_MAPHASH]);
// First abbreviation local to a buffer.
- mapblock_T *b_first_abbr;
+ mapblock_T *b_first_abbr;
// User commands local to the buffer.
garray_T b_ucmds;
/*
@@ -632,10 +631,10 @@ struct file_buffer {
/*
* The following only used in undo.c.
*/
- u_header_T *b_u_oldhead; // pointer to oldest header
- u_header_T *b_u_newhead; // pointer to newest header; may not be valid
- // if b_u_curhead is not NULL
- u_header_T *b_u_curhead; // pointer to current header
+ u_header_T *b_u_oldhead; // pointer to oldest header
+ u_header_T *b_u_newhead; // pointer to newest header; may not be valid
+ // if b_u_curhead is not NULL
+ u_header_T *b_u_curhead; // pointer to current header
int b_u_numhead; // current number of headers
bool b_u_synced; // entry lists are synced
long b_u_seq_last; // last used undo sequence number
@@ -647,7 +646,7 @@ struct file_buffer {
/*
* variables for "U" command in undo.c
*/
- char_u *b_u_line_ptr; // saved line for "U" command
+ char_u *b_u_line_ptr; // saved line for "U" command
linenr_T b_u_line_lnum; // line number of line in u_line
colnr_T b_u_line_colnr; // optional column number
@@ -659,11 +658,11 @@ struct file_buffer {
#define B_IMODE_USE_INSERT -1 // Use b_p_iminsert value for search
#define B_IMODE_NONE 0 // Input via none
#define B_IMODE_LMAP 1 // Input via langmap
-# define B_IMODE_LAST 1
+#define B_IMODE_LAST 1
int16_t b_kmap_state; // using "lmap" mappings
-# define KEYMAP_INIT 1 // 'keymap' was set, call keymap_init()
-# define KEYMAP_LOADED 2 // 'keymap' mappings have been loaded
+#define KEYMAP_INIT 1 // 'keymap' was set, call keymap_init()
+#define KEYMAP_LOADED 2 // 'keymap' mappings have been loaded
garray_T b_kmap_ga; // the keymap table
/*
@@ -818,7 +817,7 @@ struct file_buffer {
int b_start_eol; // last line had eol when it was read
int b_start_ffc; // first char of 'ff' when edit started
- char_u *b_start_fenc; // 'fileencoding' when edit started or NULL
+ char_u *b_start_fenc; // 'fileencoding' when edit started or NULL
int b_bad_char; // "++bad=" argument when edit started or 0
int b_start_bomb; // 'bomb' when it was read
@@ -868,6 +867,12 @@ struct file_buffer {
Map(uint64_t, ExtmarkItem) b_extmark_index[1];
Map(uint64_t, ExtmarkNs) b_extmark_ns[1]; // extmark namespaces
+ VirtLines b_virt_lines;
+ uint64_t b_virt_line_mark;
+ int b_virt_line_pos;
+ bool b_virt_line_above;
+ bool b_virt_line_leftcol;
+
// array of channel_id:s which have asked to receive updates for this
// buffer.
kvec_t(uint64_t) update_channels;
@@ -895,7 +900,7 @@ struct file_buffer {
/*
* Stuff for diff mode.
*/
-# define DB_COUNT 8 // up to four buffers can be diff'ed
+#define DB_COUNT 8 // up to four buffers can be diff'ed
/*
* Each diffblock defines where a block of lines starts in each of the buffers
@@ -913,14 +918,14 @@ struct file_buffer {
*/
typedef struct diffblock_S diff_T;
struct diffblock_S {
- diff_T *df_next;
+ diff_T *df_next;
linenr_T df_lnum[DB_COUNT]; // line number in buffer
linenr_T df_count[DB_COUNT]; // nr of inserted/changed lines
};
#define SNAP_HELP_IDX 0
-# define SNAP_AUCMD_IDX 1
-# define SNAP_COUNT 2
+#define SNAP_AUCMD_IDX 1
+#define SNAP_COUNT 2
/// Tab pages point to the top frame of each tab page.
/// Note: Most values are NOT valid for the current tab page! Use "curwin",
@@ -929,25 +934,26 @@ struct diffblock_S {
typedef struct tabpage_S tabpage_T;
struct tabpage_S {
handle_T handle;
- tabpage_T *tp_next; ///< next tabpage or NULL
- frame_T *tp_topframe; ///< topframe for the windows
- win_T *tp_curwin; ///< current window in this Tab page
- win_T *tp_prevwin; ///< previous window in this Tab page
- win_T *tp_firstwin; ///< first window in this Tab page
- win_T *tp_lastwin; ///< last window in this Tab page
+ tabpage_T *tp_next; ///< next tabpage or NULL
+ frame_T *tp_topframe; ///< topframe for the windows
+ win_T *tp_curwin; ///< current window in this Tab page
+ win_T *tp_prevwin; ///< previous window in this Tab page
+ win_T *tp_firstwin; ///< first window in this Tab page
+ win_T *tp_lastwin; ///< last window in this Tab page
long tp_old_Rows; ///< Rows when Tab page was left
long tp_old_Columns; ///< Columns when Tab page was left
long tp_ch_used; ///< value of 'cmdheight' when frame size
///< was set
- diff_T *tp_first_diff;
- buf_T *(tp_diffbuf[DB_COUNT]);
+ diff_T *tp_first_diff;
+ buf_T *(tp_diffbuf[DB_COUNT]);
int tp_diff_invalid; ///< list of diffs is outdated
int tp_diff_update; ///< update diffs before redrawing
- frame_T *(tp_snapshot[SNAP_COUNT]); ///< window layout snapshots
+ frame_T *(tp_snapshot[SNAP_COUNT]); ///< window layout snapshots
ScopeDictDictItem tp_winvar; ///< Variable for "t:" Dictionary.
- dict_T *tp_vars; ///< Internal variables, local to tab page.
- char_u *tp_localdir; ///< Absolute path of local cwd or NULL.
+ dict_T *tp_vars; ///< Internal variables, local to tab page.
+ char_u *tp_localdir; ///< Absolute path of local cwd or NULL.
+ char_u *tp_prevdir; ///< Previous directory.
};
/*
@@ -980,14 +986,14 @@ struct frame_S {
int fr_newwidth; // new width used in win_equal_rec()
int fr_height;
int fr_newheight; // new height used in win_equal_rec()
- frame_T *fr_parent; // containing frame or NULL
- frame_T *fr_next; // frame right or below in same parent, NULL
- // for last
- frame_T *fr_prev; // frame left or above in same parent, NULL
- // for first
+ frame_T *fr_parent; // containing frame or NULL
+ frame_T *fr_next; // frame right or below in same parent, NULL
+ // for last
+ frame_T *fr_prev; // frame left or above in same parent, NULL
+ // for first
// fr_child and fr_win are mutually exclusive
- frame_T *fr_child; // first contained frame
- win_T *fr_win; // window that fills this frame
+ frame_T *fr_child; // first contained frame
+ win_T *fr_win; // window that fills this frame
};
#define FR_LEAF 0 // frame is a leaf
@@ -1003,7 +1009,7 @@ struct frame_S {
typedef struct {
regmmatch_T rm; // points to the regexp program; contains last found
// match (may continue in next line)
- buf_T *buf; // the buffer to search for a match
+ buf_T *buf; // the buffer to search for a match
linenr_T lnum; // the line to search for a match
int attr; // attributes to be used for a match
int attr_cur; // attributes currently active in win_line()
@@ -1020,9 +1026,9 @@ typedef struct {
/// Same as lpos_T, but with additional field len.
typedef struct
{
- linenr_T lnum; ///< line number
- colnr_T col; ///< column number
- int len; ///< length: 0 - to the end of line
+ linenr_T lnum; ///< line number
+ colnr_T col; ///< column number
+ int len; ///< length: 0 - to the end of line
} llpos_T;
/// posmatch_T provides an array for storing match items for matchaddpos()
@@ -1030,10 +1036,10 @@ typedef struct
typedef struct posmatch posmatch_T;
struct posmatch
{
- llpos_T pos[MAXPOSMATCH]; ///< array of positions
- int cur; ///< internal position counter
- linenr_T toplnum; ///< top buffer line
- linenr_T botlnum; ///< bottom buffer line
+ llpos_T pos[MAXPOSMATCH]; ///< array of positions
+ int cur; ///< internal position counter
+ linenr_T toplnum; ///< top buffer line
+ linenr_T botlnum; ///< bottom buffer line
};
/*
@@ -1138,20 +1144,20 @@ typedef struct VimMenu vimmenu_T;
struct VimMenu {
int modes; ///< Which modes is this menu visible for
int enabled; ///< for which modes the menu is enabled
- char_u *name; ///< Name of menu, possibly translated
- char_u *dname; ///< Displayed Name ("name" without '&')
- char_u *en_name; ///< "name" untranslated, NULL when
- ///< was not translated
- char_u *en_dname; ///< NULL when "dname" untranslated
+ char_u *name; ///< Name of menu, possibly translated
+ char_u *dname; ///< Displayed Name ("name" without '&')
+ char_u *en_name; ///< "name" untranslated, NULL when
+ ///< was not translated
+ char_u *en_dname; ///< NULL when "dname" untranslated
int mnemonic; ///< mnemonic key (after '&')
- char_u *actext; ///< accelerator text (after TAB)
+ char_u *actext; ///< accelerator text (after TAB)
long priority; ///< Menu order priority
- char_u *strings[MENU_MODES]; ///< Mapped string for each mode
+ char_u *strings[MENU_MODES]; ///< Mapped string for each mode
int noremap[MENU_MODES]; ///< A \ref REMAP_VALUES flag for each mode
bool silent[MENU_MODES]; ///< A silent flag for each mode
- vimmenu_T *children; ///< Children of sub-menu
- vimmenu_T *parent; ///< Parent of menu
- vimmenu_T *next; ///< Next item in menu
+ vimmenu_T *children; ///< Children of sub-menu
+ vimmenu_T *parent; ///< Parent of menu
+ vimmenu_T *next; ///< Next item in menu
};
/// Structure which contains all information that belongs to a window.
@@ -1160,10 +1166,10 @@ struct VimMenu {
struct window_S {
handle_T handle; ///< unique identifier for the window
- buf_T *w_buffer; ///< buffer we are a window into (used
- ///< often, keep it the first item!)
+ buf_T *w_buffer; ///< buffer we are a window into (used
+ ///< often, keep it the first item!)
- synblock_T *w_s; ///< for :ownsyntax
+ synblock_T *w_s; ///< for :ownsyntax
int w_hl_id_normal; ///< 'winhighlight' normal id
int w_hl_attr_normal; ///< 'winhighlight' normal final attrs
@@ -1173,12 +1179,12 @@ struct window_S {
int w_hl_needs_update; ///< attrs need to be recalculated
- win_T *w_prev; ///< link to previous window
- win_T *w_next; ///< link to next window
+ win_T *w_prev; ///< link to previous window
+ win_T *w_next; ///< link to next window
bool w_closing; ///< window is being closed, don't let
/// autocommands close it too.
- frame_T *w_frame; ///< frame containing this window
+ frame_T *w_frame; ///< frame containing this window
pos_T w_cursor; ///< cursor position in buffer
@@ -1339,7 +1345,7 @@ struct window_S {
* This is used for efficient redrawing.
*/
int w_lines_valid; // number of valid entries
- wline_T *w_lines;
+ wline_T *w_lines;
garray_T w_folds; // array of nested folds
bool w_fold_manual; // when true: some folds are opened/closed
@@ -1371,13 +1377,13 @@ struct window_S {
int w_alt_fnum; // alternate file (for # and CTRL-^)
- alist_T *w_alist; // pointer to arglist for this window
+ alist_T *w_alist; // pointer to arglist for this window
int w_arg_idx; // current index in argument list (can be
// out of range!)
int w_arg_idx_invalid; // editing another file than w_arg_idx
- char_u *w_localdir; /* absolute path of local directory or
- NULL */
+ char_u *w_localdir; // absolute path of local directory or NULL
+ char_u *w_prevdir; // previous directory
// Options local to a window.
// They are local because they influence the layout of the window or
// depend on the window layout.
@@ -1390,10 +1396,10 @@ struct window_S {
uint32_t w_p_stl_flags; // flags for 'statusline'
uint32_t w_p_fde_flags; // flags for 'foldexpr'
uint32_t w_p_fdt_flags; // flags for 'foldtext'
- int *w_p_cc_cols; // array of columns to highlight or NULL
- char_u w_p_culopt_flags; // flags for cursorline highlighting
- long w_p_siso; // 'sidescrolloff' local value
- long w_p_so; // 'scrolloff' local value
+ int *w_p_cc_cols; // array of columns to highlight or NULL
+ char_u w_p_culopt_flags; // flags for cursorline highlighting
+ long w_p_siso; // 'sidescrolloff' local value
+ long w_p_so; // 'scrolloff' local value
int w_briopt_min; // minimum width for breakindent
int w_briopt_shift; // additional shift for breakindent
@@ -1457,10 +1463,10 @@ struct window_S {
* was computed. */
int w_nrwidth_width; // nr of chars to print line count.
- qf_info_T *w_llist; // Location list for this window
+ qf_info_T *w_llist; // Location list for this window
// Location list reference used in the location list window.
// In a non-location list window, w_llist_ref is NULL.
- qf_info_T *w_llist_ref;
+ qf_info_T *w_llist_ref;
};
static inline int win_hl_attr(win_T *wp, int hlf)
@@ -1470,6 +1476,6 @@ static inline int win_hl_attr(win_T *wp, int hlf)
/// Macros defined in Vim, but not in Neovim
#define CHANGEDTICK(buf) \
- (=== Include buffer.h & use buf_(get|set|inc)_changedtick ===)
+ (=== Include buffer.h & use buf_(get|set|inc) _changedtick ===)
#endif // NVIM_BUFFER_DEFS_H
diff --git a/src/nvim/change.c b/src/nvim/change.c
index ccceb0e320..2450c56838 100644
--- a/src/nvim/change.c
+++ b/src/nvim/change.c
@@ -413,7 +413,11 @@ void deleted_lines(linenr_T lnum, long count)
/// be triggered to display the cursor.
void deleted_lines_mark(linenr_T lnum, long count)
{
- mark_adjust(lnum, (linenr_T)(lnum + count - 1), (long)MAXLNUM, -count,
+ // if we deleted the entire buffer, we need to implicity add a new empty line
+ bool made_empty = (count > 0) && curbuf->b_ml.ml_flags & ML_EMPTY;
+
+ mark_adjust(lnum, (linenr_T)(lnum + count - 1), (long)MAXLNUM,
+ -count + (made_empty?1:0),
kExtmarkUndo);
changed_lines(lnum, 0, lnum + count, -count, true);
}
@@ -461,15 +465,15 @@ void changed_lines_buf(buf_T *buf, linenr_T lnum, linenr_T lnume, long xtra)
/// When only inserting lines, "lnum" and "lnume" are equal.
/// Takes care of calling changed() and updating b_mod_*.
/// Careful: may trigger autocommands that reload the buffer.
-void changed_lines(linenr_T lnum, // first line with change
- colnr_T col, // column in first line with change
- linenr_T lnume, // line below last changed line
- long xtra, // number of extra lines (negative when deleting)
- bool do_buf_event // some callers like undo/redo call changed_lines()
- // and then increment changedtick *again*. This flag
- // allows these callers to send the nvim_buf_lines_event
- // events after they're done modifying changedtick.
- )
+///
+/// @param lnum first line with change
+/// @param col column in first line with change
+/// @param lnume line below last changed line
+/// @param xtra number of extra lines (negative when deleting)
+/// @param do_buf_event some callers like undo/redo call changed_lines() and
+/// then increment changedtick *again*. This flag allows these callers to send
+/// the nvim_buf_lines_event events after they're done modifying changedtick.
+void changed_lines(linenr_T lnum, colnr_T col, linenr_T lnume, long xtra, bool do_buf_event)
{
changed_lines_buf(curbuf, lnum, lnume, xtra);
@@ -625,7 +629,7 @@ void ins_char_bytes(char_u *buf, size_t charlen)
// Copy bytes before the cursor.
if (col > 0) {
- memmove(newp, oldp, (size_t)col);
+ memmove(newp, oldp, col);
}
// Copy bytes after the changed character(s).
@@ -950,9 +954,10 @@ int copy_indent(int size, char_u *src)
/// "second_line_indent": indent for after ^^D in Insert mode or if flag
/// OPENLINE_COM_LIST
///
+/// @param dir FORWARD or BACKWARD
+///
/// @return true on success, false on failure
-int open_line(int dir, // FORWARD or BACKWARD
- int flags, int second_line_indent)
+int open_line(int dir, int flags, int second_line_indent)
{
char_u *next_line = NULL; // copy of the next line
char_u *p_extra = NULL; // what goes to next line
diff --git a/src/nvim/channel.c b/src/nvim/channel.c
index 30243a3102..313eefd562 100644
--- a/src/nvim/channel.c
+++ b/src/nvim/channel.c
@@ -8,6 +8,7 @@
#include "nvim/eval/encode.h"
#include "nvim/event/socket.h"
#include "nvim/fileio.h"
+#include "nvim/lua/executor.h"
#include "nvim/msgpack_rpc/channel.h"
#include "nvim/msgpack_rpc/server.h"
#include "nvim/os/shell.h"
@@ -87,7 +88,7 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error)
break;
case kChannelStreamProc:
- proc = (Process *)&chan->stream.proc;
+ proc = &chan->stream.proc;
if (part == kChannelPartStdin || close_main) {
stream_may_close(&proc->in);
}
@@ -136,6 +137,8 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error)
*error = (const char *)e_invstream;
return false;
}
+ api_free_luaref(chan->stream.internal.cb);
+ chan->stream.internal.cb = LUA_NOREF;
break;
default:
@@ -335,7 +338,7 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout, CallbackReader
chan->stream.uv = libuv_process_init(&main_loop, chan);
}
- Process *proc = (Process *)&chan->stream.proc;
+ Process *proc = &chan->stream.proc;
proc->argv = argv;
proc->cb = channel_process_exit_cb;
proc->events = chan->events;
@@ -420,6 +423,7 @@ uint64_t channel_connect(bool tcp, const char *address, bool rpc, CallbackReader
// Create a loopback channel. This avoids deadlock if nvim connects to
// its own named pipe.
channel = channel_alloc(kChannelStreamInternal);
+ channel->stream.internal.cb = LUA_NOREF;
rpc_start(channel);
goto end;
}
diff --git a/src/nvim/channel.h b/src/nvim/channel.h
index 9bc0df3615..8d14f465c1 100644
--- a/src/nvim/channel.h
+++ b/src/nvim/channel.h
@@ -1,13 +1,13 @@
#ifndef NVIM_CHANNEL_H
#define NVIM_CHANNEL_H
-#include "nvim/main.h"
-#include "nvim/event/socket.h"
-#include "nvim/event/process.h"
-#include "nvim/os/pty_process.h"
-#include "nvim/event/libuv_process.h"
#include "nvim/eval/typval.h"
+#include "nvim/event/libuv_process.h"
+#include "nvim/event/process.h"
+#include "nvim/event/socket.h"
+#include "nvim/main.h"
#include "nvim/msgpack_rpc/channel_defs.h"
+#include "nvim/os/pty_process.h"
#define CHAN_STDIO 1
#define CHAN_STDERR 2
@@ -43,6 +43,10 @@ typedef struct {
} StderrState;
typedef struct {
+ LuaRef cb;
+} InternalState;
+
+typedef struct {
Callback cb;
dict_T *self;
garray_T buffer;
@@ -74,6 +78,7 @@ struct Channel {
Stream socket;
StdioPair stdio;
StderrState err;
+ InternalState internal;
} stream;
bool is_rpc;
@@ -105,18 +110,18 @@ static inline Stream *channel_instream(Channel *chan)
FUNC_ATTR_NONNULL_ALL
{
switch (chan->streamtype) {
- case kChannelStreamProc:
- return &chan->stream.proc.in;
+ case kChannelStreamProc:
+ return &chan->stream.proc.in;
- case kChannelStreamSocket:
- return &chan->stream.socket;
+ case kChannelStreamSocket:
+ return &chan->stream.socket;
- case kChannelStreamStdio:
- return &chan->stream.stdio.out;
+ case kChannelStreamStdio:
+ return &chan->stream.stdio.out;
- case kChannelStreamInternal:
- case kChannelStreamStderr:
- abort();
+ case kChannelStreamInternal:
+ case kChannelStreamStderr:
+ abort();
}
abort();
}
@@ -125,18 +130,18 @@ static inline Stream *channel_outstream(Channel *chan)
FUNC_ATTR_NONNULL_ALL
{
switch (chan->streamtype) {
- case kChannelStreamProc:
- return &chan->stream.proc.out;
+ case kChannelStreamProc:
+ return &chan->stream.proc.out;
- case kChannelStreamSocket:
- return &chan->stream.socket;
+ case kChannelStreamSocket:
+ return &chan->stream.socket;
- case kChannelStreamStdio:
- return &chan->stream.stdio.in;
+ case kChannelStreamStdio:
+ return &chan->stream.stdio.in;
- case kChannelStreamInternal:
- case kChannelStreamStderr:
- abort();
+ case kChannelStreamInternal:
+ case kChannelStreamStderr:
+ abort();
}
abort();
}
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index 21e04128dc..d2f95ad81c 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -310,7 +310,7 @@ void trans_characters(char_u *buf, int bufsize)
///
/// @return number of bytes needed to hold a translation of `s`, NUL byte not
/// included.
-size_t transstr_len(const char *const s)
+size_t transstr_len(const char *const s, bool untab)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
{
const char *p = s;
@@ -331,6 +331,9 @@ size_t transstr_len(const char *const s)
}
}
p += l;
+ } else if (*p == TAB && !untab) {
+ len += 1;
+ p++;
} else {
const int b2c_l = byte2cells((uint8_t)(*p++));
// Illegal byte sequence may occupy up to 4 characters.
@@ -346,9 +349,10 @@ size_t transstr_len(const char *const s)
/// @param[out] buf Buffer to which result should be saved.
/// @param[in] len Buffer length. Resulting string may not occupy more then
/// len - 1 bytes (one for trailing NUL byte).
+/// @param[in] untab remove tab characters
///
/// @return length of the resulting string, without the NUL byte.
-size_t transstr_buf(const char *const s, char *const buf, const size_t len)
+size_t transstr_buf(const char *const s, char *const buf, const size_t len, bool untab)
FUNC_ATTR_NONNULL_ALL
{
const char *p = s;
@@ -379,6 +383,8 @@ size_t transstr_buf(const char *const s, char *const buf, const size_t len)
}
}
p += l;
+ } else if (*p == TAB && !untab) {
+ *buf_p++ = *p++;
} else {
const char *const tb = (const char *)transchar_byte((uint8_t)(*p++));
const size_t tb_len = strlen(tb);
@@ -401,14 +407,14 @@ size_t transstr_buf(const char *const s, char *const buf, const size_t len)
/// @param[in] s String to replace characters from.
///
/// @return [allocated] translated string
-char *transstr(const char *const s)
+char *transstr(const char *const s, bool untab)
FUNC_ATTR_NONNULL_RET
{
// Compute the length of the result, taking account of unprintable
// multi-byte characters.
- const size_t len = transstr_len((const char *)s) + 1;
+ const size_t len = transstr_len(s, untab) + 1;
char *const buf = xmalloc(len);
- transstr_buf(s, buf, len);
+ transstr_buf(s, buf, len, untab);
return buf;
}
@@ -417,7 +423,7 @@ char *transstr(const char *const s)
///
/// When "buf" is NULL, return an allocated string.
/// Otherwise, put the result in buf, limited by buflen, and return buf.
-char_u * str_foldcase(char_u *str, int orglen, char_u *buf, int buflen)
+char_u *str_foldcase(char_u *str, int orglen, char_u *buf, int buflen)
FUNC_ATTR_NONNULL_RET
{
garray_T ga;
@@ -1209,7 +1215,7 @@ char_u *skipdigits(const char_u *q)
/// @param q pointer to string
///
/// @return Pointer to the character after the skipped digits.
-const char * skipbin(const char *q)
+const char *skipbin(const char *q)
FUNC_ATTR_PURE
FUNC_ATTR_NONNULL_ALL
FUNC_ATTR_NONNULL_RET
@@ -1228,7 +1234,7 @@ const char * skipbin(const char *q)
///
/// @return Pointer to the character after the skipped digits and hex
/// characters.
-char_u * skiphex(char_u *q)
+char_u *skiphex(char_u *q)
{
char_u *p = q;
while (ascii_isxdigit(*p)) {
@@ -1243,7 +1249,7 @@ char_u * skiphex(char_u *q)
/// @param q
///
/// @return Pointer to the digit or (NUL after the string).
-char_u * skiptodigit(char_u *q)
+char_u *skiptodigit(char_u *q)
{
char_u *p = q;
while (*p != NUL && !ascii_isdigit(*p)) {
@@ -1258,7 +1264,7 @@ char_u * skiptodigit(char_u *q)
/// @param q pointer to string
///
/// @return Pointer to the binary character or (NUL after the string).
-const char * skiptobin(const char *q)
+const char *skiptobin(const char *q)
FUNC_ATTR_PURE
FUNC_ATTR_NONNULL_ALL
FUNC_ATTR_NONNULL_RET
@@ -1276,7 +1282,7 @@ const char * skiptobin(const char *q)
/// @param q
///
/// @return Pointer to the hex character or (NUL after the string).
-char_u * skiptohex(char_u *q)
+char_u *skiptohex(char_u *q)
{
char_u *p = q;
while (*p != NUL && !ascii_isxdigit(*p)) {
@@ -1305,7 +1311,7 @@ char_u *skiptowhite(const char_u *p)
/// @param p
///
/// @return Pointer to the next whitespace character.
-char_u * skiptowhite_esc(char_u *p) {
+char_u *skiptowhite_esc(char_u *p) {
while (*p != ' ' && *p != '\t' && *p != NUL) {
if (((*p == '\\') || (*p == Ctrl_V)) && (*(p + 1) != NUL)) {
++p;
diff --git a/src/nvim/charset.h b/src/nvim/charset.h
index 2fef4d78a2..47d89717e8 100644
--- a/src/nvim/charset.h
+++ b/src/nvim/charset.h
@@ -1,11 +1,11 @@
#ifndef NVIM_CHARSET_H
#define NVIM_CHARSET_H
-#include "nvim/types.h"
-#include "nvim/pos.h"
#include "nvim/buffer_defs.h"
#include "nvim/eval/typval.h"
#include "nvim/option_defs.h"
+#include "nvim/pos.h"
+#include "nvim/types.h"
/// Return the folded-case equivalent of the given character
///
@@ -13,7 +13,7 @@
///
/// @return Folded variant.
#define CH_FOLD(c) \
- utf_fold((sizeof(c) == sizeof(char)) \
+ utf_fold((sizeof(c) == sizeof(char)) \
?((int)(uint8_t)(c)) \
:((int)(c)))
diff --git a/src/nvim/context.h b/src/nvim/context.h
index 7edd63ced2..c2deca12c9 100644
--- a/src/nvim/context.h
+++ b/src/nvim/context.h
@@ -2,6 +2,7 @@
#define NVIM_CONTEXT_H
#include <msgpack.h>
+
#include "nvim/api/private/defs.h"
#include "nvim/lib/kvec.h"
diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c
index 2eced03c03..e334fd166e 100644
--- a/src/nvim/cursor.c
+++ b/src/nvim/cursor.c
@@ -93,10 +93,10 @@ int coladvance(colnr_T wcol)
return rc;
}
-static int coladvance2(pos_T *pos, bool addspaces, // change the text to achieve our goal?
- bool finetune, // change char offset for the exact column
- colnr_T wcol_arg // column to move to (can be negative)
- )
+/// @param addspaces change the text to achieve our goal?
+/// @param finetune change char offset for the exact column
+/// @param wcol_arg column to move to (can be negative)
+static int coladvance2(pos_T *pos, bool addspaces, bool finetune, colnr_T wcol_arg)
{
colnr_T wcol = wcol_arg;
int idx;
diff --git a/src/nvim/cursor_shape.c b/src/nvim/cursor_shape.c
index 128bc480da..18cade1052 100644
--- a/src/nvim/cursor_shape.c
+++ b/src/nvim/cursor_shape.c
@@ -230,12 +230,11 @@ char_u *parse_shape_opt(int what)
slashp = vim_strchr(p, '/');
if (slashp != NULL && slashp < endp) {
// "group/langmap_group"
- i = syn_check_group(p, (int)(slashp - p));
+ i = syn_check_group((char *)p, (int)(slashp - p));
p = slashp + 1;
}
if (round == 2) {
- shape_table[idx].id = syn_check_group(p,
- (int)(endp - p));
+ shape_table[idx].id = syn_check_group((char *)p, (int)(endp - p));
shape_table[idx].id_lm = shape_table[idx].id;
if (slashp != NULL && slashp < endp) {
shape_table[idx].id = i;
diff --git a/src/nvim/cursor_shape.h b/src/nvim/cursor_shape.h
index a23fa6836d..06eaa431a0 100644
--- a/src/nvim/cursor_shape.h
+++ b/src/nvim/cursor_shape.h
@@ -1,36 +1,36 @@
#ifndef NVIM_CURSOR_SHAPE_H
#define NVIM_CURSOR_SHAPE_H
-#include "nvim/types.h"
#include "nvim/api/private/defs.h"
+#include "nvim/types.h"
/// struct to store values from 'guicursor' and 'mouseshape'
/// Indexes in shape_table[]
typedef enum {
-SHAPE_IDX_N = 0, ///< Normal mode
-SHAPE_IDX_V = 1, ///< Visual mode
-SHAPE_IDX_I = 2, ///< Insert mode
-SHAPE_IDX_R = 3, ///< Replace mode
-SHAPE_IDX_C = 4, ///< Command line Normal mode
-SHAPE_IDX_CI = 5, ///< Command line Insert mode
-SHAPE_IDX_CR = 6, ///< Command line Replace mode
-SHAPE_IDX_O = 7, ///< Operator-pending mode
-SHAPE_IDX_VE = 8, ///< Visual mode with 'selection' exclusive
-SHAPE_IDX_CLINE = 9, ///< On command line
-SHAPE_IDX_STATUS = 10, ///< On status line
-SHAPE_IDX_SDRAG = 11, ///< dragging a status line
-SHAPE_IDX_VSEP = 12, ///< On vertical separator line
-SHAPE_IDX_VDRAG = 13, ///< dragging a vertical separator line
-SHAPE_IDX_MORE = 14, ///< Hit-return or More
-SHAPE_IDX_MOREL = 15, ///< Hit-return or More in last line
-SHAPE_IDX_SM = 16, ///< showing matching paren
-SHAPE_IDX_COUNT = 17
+ SHAPE_IDX_N = 0, ///< Normal mode
+ SHAPE_IDX_V = 1, ///< Visual mode
+ SHAPE_IDX_I = 2, ///< Insert mode
+ SHAPE_IDX_R = 3, ///< Replace mode
+ SHAPE_IDX_C = 4, ///< Command line Normal mode
+ SHAPE_IDX_CI = 5, ///< Command line Insert mode
+ SHAPE_IDX_CR = 6, ///< Command line Replace mode
+ SHAPE_IDX_O = 7, ///< Operator-pending mode
+ SHAPE_IDX_VE = 8, ///< Visual mode with 'selection' exclusive
+ SHAPE_IDX_CLINE = 9, ///< On command line
+ SHAPE_IDX_STATUS = 10, ///< On status line
+ SHAPE_IDX_SDRAG = 11, ///< dragging a status line
+ SHAPE_IDX_VSEP = 12, ///< On vertical separator line
+ SHAPE_IDX_VDRAG = 13, ///< dragging a vertical separator line
+ SHAPE_IDX_MORE = 14, ///< Hit-return or More
+ SHAPE_IDX_MOREL = 15, ///< Hit-return or More in last line
+ SHAPE_IDX_SM = 16, ///< showing matching paren
+ SHAPE_IDX_COUNT = 17
} ModeShape;
typedef enum {
-SHAPE_BLOCK = 0, ///< block cursor
-SHAPE_HOR = 1, ///< horizontal bar cursor
-SHAPE_VER = 2 ///< vertical bar cursor
+ SHAPE_BLOCK = 0, ///< block cursor
+ SHAPE_HOR = 1, ///< horizontal bar cursor
+ SHAPE_VER = 2 ///< vertical bar cursor
} CursorShape;
#define MSHAPE_NUMBERED 1000 // offset for shapes identified by number
diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c
index 73665009ff..aeaf2555b1 100644
--- a/src/nvim/debugger.c
+++ b/src/nvim/debugger.c
@@ -60,9 +60,9 @@ void do_debug(char_u *cmd)
int save_ignore_script = 0;
int save_ex_normal_busy;
int n;
- char_u *cmdline = NULL;
- char_u *p;
- char *tail = NULL;
+ char_u *cmdline = NULL;
+ char_u *p;
+ char *tail = NULL;
static int last_cmd = 0;
#define CMD_CONT 1
#define CMD_NEXT 2
@@ -145,13 +145,16 @@ void do_debug(char_u *cmd)
p = skipwhite(cmdline);
if (*p != NUL) {
switch (*p) {
- case 'c': last_cmd = CMD_CONT;
+ case 'c':
+ last_cmd = CMD_CONT;
tail = "ont";
break;
- case 'n': last_cmd = CMD_NEXT;
+ case 'n':
+ last_cmd = CMD_NEXT;
tail = "ext";
break;
- case 's': last_cmd = CMD_STEP;
+ case 's':
+ last_cmd = CMD_STEP;
tail = "tep";
break;
case 'f':
@@ -164,10 +167,12 @@ void do_debug(char_u *cmd)
tail = "inish";
}
break;
- case 'q': last_cmd = CMD_QUIT;
+ case 'q':
+ last_cmd = CMD_QUIT;
tail = "uit";
break;
- case 'i': last_cmd = CMD_INTERRUPT;
+ case 'i':
+ last_cmd = CMD_INTERRUPT;
tail = "nterrupt";
break;
case 'b':
@@ -190,7 +195,8 @@ void do_debug(char_u *cmd)
last_cmd = CMD_DOWN;
tail = "own";
break;
- default: last_cmd = 0;
+ default:
+ last_cmd = 0;
}
if (last_cmd != 0) {
// Check that the tail matches.
@@ -366,7 +372,7 @@ void ex_debug(exarg_T *eap)
debug_break_level = debug_break_level_save;
}
-static char_u *debug_breakpoint_name = NULL;
+static char_u *debug_breakpoint_name = NULL;
static linenr_T debug_breakpoint_lnum;
/// When debugging or a breakpoint is set on a skipped command, no debug prompt
@@ -375,7 +381,7 @@ static linenr_T debug_breakpoint_lnum;
/// a skipped command decides itself that a debug prompt should be displayed, it
/// can do so by calling dbg_check_skipped().
static int debug_skipped;
-static char_u *debug_skipped_name;
+static char_u *debug_skipped_name;
/// Go to debug mode when a breakpoint was encountered or "ex_nesting_level" is
/// at or below the break level. But only when the line is actually
@@ -384,7 +390,7 @@ static char_u *debug_skipped_name;
/// Called from do_one_cmd() before executing a command.
void dbg_check_breakpoint(exarg_T *eap)
{
- char_u *p;
+ char *p;
debug_skipped = false;
if (debug_breakpoint_name != NULL) {
@@ -392,10 +398,10 @@ void dbg_check_breakpoint(exarg_T *eap)
// replace K_SNR with "<SNR>"
if (debug_breakpoint_name[0] == K_SPECIAL
&& debug_breakpoint_name[1] == KS_EXTRA
- && debug_breakpoint_name[2] == (int)KE_SNR) {
- p = (char_u *)"<SNR>";
+ && debug_breakpoint_name[2] == KE_SNR) {
+ p = "<SNR>";
} else {
- p = (char_u *)"";
+ p = "";
}
smsg(_("Breakpoint in \"%s%s\" line %" PRId64),
p,
@@ -474,8 +480,8 @@ static typval_T *eval_expr_no_emsg(struct debuggy *const bp)
/// @param gap either &dbg_breakp or &prof_ga
static int dbg_parsearg(char_u *arg, garray_T *gap)
{
- char_u *p = arg;
- char_u *q;
+ char_u *p = arg;
+ char_u *q;
struct debuggy *bp;
bool here = false;
@@ -559,7 +565,7 @@ static int dbg_parsearg(char_u *arg, garray_T *gap)
void ex_breakadd(exarg_T *eap)
{
struct debuggy *bp;
- garray_T *gap;
+ garray_T *gap;
gap = &dbg_breakp;
if (eap->cmdidx == CMD_profile) {
@@ -614,7 +620,7 @@ void ex_breakdel(exarg_T *eap)
int todel = -1;
bool del_all = false;
linenr_T best_lnum = 0;
- garray_T *gap;
+ garray_T *gap;
gap = &dbg_breakp;
if (eap->cmdidx == CMD_profdel) {
@@ -712,12 +718,11 @@ void ex_breaklist(exarg_T *eap)
/// Find a breakpoint for a function or sourced file.
/// Returns line number at which to break; zero when no matching breakpoint.
-linenr_T
-dbg_find_breakpoint(
- bool file, // true for a file, false for a function
- char_u *fname, // file or function name
- linenr_T after // after this line number
-)
+///
+/// @param file true for a file, false for a function
+/// @param fname file or function name
+/// @param after after this line number
+linenr_T dbg_find_breakpoint(bool file, char_u *fname, linenr_T after)
{
return debuggy_find(file, fname, after, &dbg_breakp, NULL);
}
@@ -734,18 +739,17 @@ bool has_profiling(bool file, char_u *fname, bool *fp)
}
/// Common code for dbg_find_breakpoint() and has_profiling().
-static linenr_T
-debuggy_find(
- bool file, // true for a file, false for a function
- char_u *fname, // file or function name
- linenr_T after, // after this line number
- garray_T *gap, // either &dbg_breakp or &prof_ga
- bool *fp // if not NULL: return forceit
-)
+///
+/// @param file true for a file, false for a function
+/// @param fname file or function name
+/// @param after after this line number
+/// @param gap either &dbg_breakp or &prof_ga
+/// @param fp if not NULL: return forceit
+static linenr_T debuggy_find(bool file, char_u *fname, linenr_T after, garray_T *gap, bool *fp)
{
struct debuggy *bp;
linenr_T lnum = 0;
- char_u *name = fname;
+ char_u *name = fname;
int prev_got_int;
// Return quickly when there are no breakpoints.
diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c
index 5168ed6d0f..4e80528c74 100644
--- a/src/nvim/decoration.c
+++ b/src/nvim/decoration.c
@@ -1,13 +1,13 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-#include "nvim/vim.h"
-#include "nvim/lua/executor.h"
-#include "nvim/extmark.h"
#include "nvim/decoration.h"
+#include "nvim/extmark.h"
+#include "nvim/highlight.h"
+#include "nvim/lua/executor.h"
#include "nvim/screen.h"
#include "nvim/syntax.h"
-#include "nvim/highlight.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "decoration.c.generated.h"
@@ -28,11 +28,7 @@ static PMap(uint64_t) hl_decors;
/// @param pos_start Cursor position to start the highlighting at
/// @param pos_end Cursor position to end the highlighting at
/// @param offset Move the whole highlighting this many columns to the right
-void bufhl_add_hl_pos_offset(buf_T *buf,
- int src_id,
- int hl_id,
- lpos_T pos_start,
- lpos_T pos_end,
+void bufhl_add_hl_pos_offset(buf_T *buf, int src_id, int hl_id, lpos_T pos_start, lpos_T pos_end,
colnr_T offset)
{
colnr_T hl_start = 0;
@@ -41,7 +37,7 @@ void bufhl_add_hl_pos_offset(buf_T *buf,
decor->priority = DECOR_PRIORITY_BASE;
// TODO(bfredl): if decoration had blocky mode, we could avoid this loop
- for (linenr_T lnum = pos_start.lnum; lnum <= pos_end.lnum; lnum ++) {
+ for (linenr_T lnum = pos_start.lnum; lnum <= pos_end.lnum; lnum++) {
int end_off = 0;
if (pos_start.lnum < lnum && lnum < pos_end.lnum) {
// TODO(bfredl): This is quite ad-hoc, but the space between |num| and
@@ -63,7 +59,7 @@ void bufhl_add_hl_pos_offset(buf_T *buf,
hl_start = pos_start.col + offset;
hl_end = pos_end.col + offset;
}
- (void)extmark_set(buf, (uint64_t)src_id, 0,
+ (void)extmark_set(buf, (uint64_t)src_id, NULL,
(int)lnum-1, hl_start, (int)lnum-1+end_off, hl_end,
decor, true, false, kExtmarkNoUndo);
}
@@ -172,7 +168,7 @@ bool decor_redraw_start(buf_T *buf, int top_row, DecorState *state)
ExtmarkItem *item = map_ref(uint64_t, ExtmarkItem)(buf->b_extmark_index,
start_id, false);
if (!item || !item->decor) {
- // TODO(bfredl): dedicated flag for being a decoration?
+ // TODO(bfredl): dedicated flag for being a decoration?
goto next_mark;
}
Decoration *decor = item->decor;
@@ -217,14 +213,14 @@ bool decor_redraw_line(buf_T *buf, int row, DecorState *state)
return true; // TODO(bfredl): be more precise
}
-static void decor_add(DecorState *state, int start_row, int start_col,
- int end_row, int end_col, Decoration *decor, bool owned)
+static void decor_add(DecorState *state, int start_row, int start_col, int end_row, int end_col,
+ Decoration *decor, bool owned)
{
int attr_id = decor->hl_id > 0 ? syn_id2attr(decor->hl_id) : 0;
DecorRange range = { start_row, start_col, end_row, end_col,
*decor, attr_id,
- kv_size(decor->virt_text) && owned, -1 };
+ kv_size(decor->virt_text) && owned, -1 };
kv_pushp(state->active);
size_t index;
@@ -238,8 +234,7 @@ static void decor_add(DecorState *state, int start_row, int start_col,
kv_A(state->active, index) = range;
}
-int decor_redraw_col(buf_T *buf, int col, int win_col, bool hidden,
- DecorState *state)
+int decor_redraw_col(buf_T *buf, int col, int win_col, bool hidden, DecorState *state)
{
if (col <= state->col_until) {
return state->current;
@@ -257,7 +252,7 @@ int decor_redraw_col(buf_T *buf, int col, int win_col, bool hidden,
}
if ((mark.id&MARKTREE_END_FLAG)) {
- // TODO(bfredl): check decoration flag
+ // TODO(bfredl): check decoration flag
goto next_mark;
}
mtpos_t endpos = marktree_lookup(buf->b_marktree,
@@ -266,7 +261,7 @@ int decor_redraw_col(buf_T *buf, int col, int win_col, bool hidden,
ExtmarkItem *item = map_ref(uint64_t, ExtmarkItem)(buf->b_extmark_index,
mark.id, false);
if (!item || !item->decor) {
- // TODO(bfredl): dedicated flag for being a decoration?
+ // TODO(bfredl): dedicated flag for being a decoration?
goto next_mark;
}
Decoration *decor = item->decor;
@@ -355,8 +350,7 @@ bool decor_redraw_eol(buf_T *buf, DecorState *state, int *eol_attr, int eol_col)
return has_virttext;
}
-void decor_add_ephemeral(int start_row, int start_col, int end_row, int end_col,
- Decoration *decor)
+void decor_add_ephemeral(int start_row, int start_col, int end_row, int end_col, Decoration *decor)
{
if (end_row == -1) {
end_row = start_row;
@@ -418,3 +412,35 @@ void decor_free_all_mem(void)
}
kv_destroy(decor_providers);
}
+
+
+int decor_virtual_lines(win_T *wp, linenr_T lnum)
+{
+ buf_T *buf = wp->w_buffer;
+ if (!buf->b_virt_line_mark) {
+ return 0;
+ }
+ if (buf->b_virt_line_pos < 0) {
+ mtpos_t pos = marktree_lookup(buf->b_marktree, buf->b_virt_line_mark, NULL);
+ if (pos.row < 0) {
+ buf->b_virt_line_mark = 0;
+ }
+ buf->b_virt_line_pos = pos.row + (buf->b_virt_line_above ? 0 : 1);
+ }
+
+ return (lnum-1 == buf->b_virt_line_pos) ? (int)kv_size(buf->b_virt_lines) : 0;
+}
+
+void clear_virt_lines(buf_T *buf, int row)
+{
+ if (row > -1) {
+ redraw_buf_line_later(buf, MIN(buf->b_ml.ml_line_count,
+ row+1+(buf->b_virt_line_above?0:1)));
+ }
+ for (size_t i = 0; i < kv_size(buf->b_virt_lines); i++) {
+ clear_virttext(&kv_A(buf->b_virt_lines, i));
+ }
+ kv_destroy(buf->b_virt_lines); // re-initializes
+ buf->b_virt_line_pos = -1;
+ buf->b_virt_line_mark = 0;
+}
diff --git a/src/nvim/decoration.h b/src/nvim/decoration.h
index 28dabeeada..e44fbab0a5 100644
--- a/src/nvim/decoration.h
+++ b/src/nvim/decoration.h
@@ -1,20 +1,12 @@
#ifndef NVIM_DECORATION_H
#define NVIM_DECORATION_H
-#include "nvim/pos.h"
#include "nvim/buffer_defs.h"
#include "nvim/extmark_defs.h"
+#include "nvim/pos.h"
// actual Decoration data is in extmark_defs.h
-typedef struct {
- char *text;
- int hl_id;
-} VirtTextChunk;
-
-typedef kvec_t(VirtTextChunk) VirtText;
-#define VIRTTEXT_EMPTY ((VirtText)KV_INITIAL_VALUE)
-
typedef uint16_t DecorPriority;
#define DECOR_PRIORITY_BASE 0x1000
@@ -90,9 +82,9 @@ EXTERN DecorState decor_state INIT(= { 0 });
EXTERN bool provider_active INIT(= false);
#define DECORATION_PROVIDER_INIT(ns_id) (DecorProvider) \
- { ns_id, false, LUA_NOREF, LUA_NOREF, \
- LUA_NOREF, LUA_NOREF, LUA_NOREF, \
- LUA_NOREF, -1 }
+ { ns_id, false, LUA_NOREF, LUA_NOREF, \
+ LUA_NOREF, LUA_NOREF, LUA_NOREF, \
+ LUA_NOREF, -1 }
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "decoration.h.generated.h"
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index fd5b2c6599..80b8920a7f 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -13,14 +13,12 @@
#include <inttypes.h>
#include <stdbool.h>
-#include "nvim/vim.h"
-#include "xdiff/xdiff.h"
#include "nvim/ascii.h"
-#include "nvim/diff.h"
#include "nvim/buffer.h"
#include "nvim/change.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/diff.h"
#include "nvim/eval.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_docmd.h"
@@ -29,19 +27,21 @@
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
+#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/memory.h"
#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/option.h"
+#include "nvim/os/os.h"
+#include "nvim/os/shell.h"
#include "nvim/path.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/undo.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/os/os.h"
-#include "nvim/os/shell.h"
+#include "xdiff/xdiff.h"
static int diff_busy = false; // using diff structs, don't change them
static bool diff_need_update = false; // ex_diffupdate needs to be called
@@ -72,22 +72,22 @@ static TriState diff_a_works = kNone;
// used for diff input
typedef struct {
- char_u *din_fname; // used for external diff
- mmfile_t din_mmfile; // used for internal diff
+ char_u *din_fname; // used for external diff
+ mmfile_t din_mmfile; // used for internal diff
} diffin_T;
// used for diff result
typedef struct {
- char_u *dout_fname; // used for external diff
- garray_T dout_ga; // used for internal diff
+ char_u *dout_fname; // used for external diff
+ garray_T dout_ga; // used for internal diff
} diffout_T;
// two diff inputs and one result
typedef struct {
- diffin_T dio_orig; // original file input
- diffin_T dio_new; // new file input
- diffout_T dio_diff; // diff result
- int dio_internal; // using internal diff
+ diffin_T dio_orig; // original file input
+ diffin_T dio_new; // new file input
+ diffout_T dio_diff; // diff result
+ int dio_internal; // using internal diff
} diffio_T;
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -119,7 +119,6 @@ void diff_buf_delete(buf_T *buf)
/// @param win
void diff_buf_adjust(win_T *win)
{
-
if (!win->w_p_diff) {
// When there is no window showing a diff for this buffer, remove
// it from the diffs.
@@ -242,8 +241,7 @@ void diff_invalidate(buf_T *buf)
/// @param line2
/// @param amount
/// @param amount_after
-void diff_mark_adjust(linenr_T line1, linenr_T line2, long amount,
- long amount_after)
+void diff_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after)
{
// Handle all tab pages that use the current buffer in a diff.
FOR_ALL_TABS(tp) {
@@ -267,8 +265,8 @@ void diff_mark_adjust(linenr_T line1, linenr_T line2, long amount,
/// @param line2
/// @param amount
/// @amount_after
-static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1,
- linenr_T line2, long amount, long amount_after)
+static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1, linenr_T line2, long amount,
+ long amount_after)
{
if (diff_internal()) {
// Will update diffs before redrawing. Set _invalid to update the
@@ -299,7 +297,7 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1,
diff_T *dp = tp->tp_first_diff;
linenr_T last;
- linenr_T lnum_deleted = line1; // lnum of remaining deletion
+ linenr_T lnum_deleted = line1; // lnum of remaining deletion
int n;
int off;
for (;;) {
@@ -323,8 +321,8 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1,
dnext->df_lnum[i] = line1;
} else {
dnext->df_lnum[i] = line1
- + (dprev->df_lnum[i] + dprev->df_count[i])
- - (dprev->df_lnum[idx] + dprev->df_count[idx]);
+ + (dprev->df_lnum[i] + dprev->df_count[i])
+ - (dprev->df_lnum[idx] + dprev->df_count[idx]);
}
dnext->df_count[i] = deleted;
}
@@ -393,7 +391,7 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1,
off = 0;
if (last < line2) {
- // 2. delete at end of of diff
+ // 2. delete at end of diff
dp->df_count[idx] -= last - lnum_deleted + 1;
if ((dp->df_next != NULL)
@@ -509,7 +507,7 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1,
/// @param dp
///
/// @return The new diff block.
-static diff_T* diff_alloc_new(tabpage_T *tp, diff_T *dprev, diff_T *dp)
+static diff_T *diff_alloc_new(tabpage_T *tp, diff_T *dprev, diff_T *dp)
{
diff_T *dnew = xmalloc(sizeof(*dnew));
@@ -704,10 +702,10 @@ static void clear_diffout(diffout_T *dout)
/// @return FAIL for failure.
static int diff_write_buffer(buf_T *buf, diffin_T *din)
{
- linenr_T lnum;
- char_u *s;
- long len = 0;
- char_u *ptr;
+ linenr_T lnum;
+ char_u *s;
+ long len = 0;
+ char_u *ptr;
// xdiff requires one big block of memory with all the text.
for (lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++) {
@@ -734,7 +732,7 @@ static int diff_write_buffer(buf_T *buf, diffin_T *din)
for (lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++) {
for (s = ml_get_buf(buf, lnum, false); *s != NUL; ) {
if (diff_flags & DIFF_ICASE) {
- char_u cbuf[MB_MAXBYTES + 1];
+ char_u cbuf[MB_MAXBYTES + 1];
// xdiff doesn't support ignoring case, fold-case the text.
int c = PTR2CHAR(s);
@@ -789,12 +787,10 @@ static int diff_write(buf_T *buf, diffin_T *din)
/// @param dio
/// @param idx_orig
/// @param eap can be NULL
-static void diff_try_update(diffio_T *dio,
- int idx_orig,
- exarg_T *eap)
+static void diff_try_update(diffio_T *dio, int idx_orig, exarg_T *eap)
{
buf_T *buf;
- int idx_new;
+ int idx_new;
if (dio->dio_internal) {
ga_init(&dio->dio_diff.dout_ga, sizeof(char *), 1000);
@@ -932,7 +928,7 @@ void ex_diffupdate(exarg_T *eap)
}
// Only use the internal method if it did not fail for one of the buffers.
- diffio_T diffio;
+ diffio_T diffio;
memset(&diffio, 0, sizeof(diffio));
diffio.dio_internal = diff_internal() && !diff_internal_failed();
@@ -1048,9 +1044,9 @@ static int check_external_diff(diffio_T *diffio)
///
static int diff_file_internal(diffio_T *diffio)
{
- xpparam_t param;
- xdemitconf_t emit_cfg;
- xdemitcb_t emit_cb;
+ xpparam_t param;
+ xdemitconf_t emit_cfg;
+ xdemitcb_t emit_cb;
memset(&param, 0, sizeof(param));
memset(&emit_cfg, 0, sizeof(emit_cfg));
@@ -1090,9 +1086,9 @@ static int diff_file_internal(diffio_T *diffio)
/// @return OK or FAIL
static int diff_file(diffio_T *dio)
{
- char *tmp_orig = (char *)dio->dio_orig.din_fname;
- char *tmp_new = (char *)dio->dio_new.din_fname;
- char *tmp_diff = (char *)dio->dio_diff.dout_fname;
+ char *tmp_orig = (char *)dio->dio_orig.din_fname;
+ char *tmp_new = (char *)dio->dio_new.din_fname;
+ char *tmp_diff = (char *)dio->dio_diff.dout_fname;
if (*p_dex != NUL) {
// Use 'diffexpr' to generate the diff file.
eval_diff(tmp_orig, tmp_new, tmp_diff);
@@ -1114,7 +1110,7 @@ static int diff_file(diffio_T *dio)
// Build the diff command and execute it. Always use -a, binary
// differences are of no use. Ignore errors, diff returns
// non-zero when differences have been found.
- vim_snprintf((char *)cmd, len, "diff %s%s%s%s%s%s%s%s %s",
+ vim_snprintf(cmd, len, "diff %s%s%s%s%s%s%s%s %s",
diff_a_works == kFalse ? "" : "-a ",
"",
(diff_flags & DIFF_IWHITE) ? "-b " : "",
@@ -1123,9 +1119,9 @@ static int diff_file(diffio_T *dio)
(diff_flags & DIFF_IBLANK) ? "-B " : "",
(diff_flags & DIFF_ICASE) ? "-i " : "",
tmp_orig, tmp_new);
- append_redir(cmd, len, (char *) p_srr, tmp_diff);
+ append_redir(cmd, len, (char *)p_srr, tmp_diff);
block_autocmds(); // Avoid ShellCmdPost stuff
- (void)call_shell((char_u *) cmd,
+ (void)call_shell((char_u *)cmd,
kShellOptFilter | kShellOptSilent | kShellOptDoOut,
NULL);
unblock_autocmds();
@@ -1171,8 +1167,8 @@ void ex_diffpatch(exarg_T *eap)
#ifdef UNIX
// Get the absolute path of the patchfile, changing directory below.
fullname = FullName_save((char *)eap->arg, false);
- esc_name = vim_strsave_shellescape(
- (fullname != NULL ? (char_u *)fullname : eap->arg), true, true);
+ esc_name =
+ vim_strsave_shellescape((fullname != NULL ? (char_u *)fullname : eap->arg), true, true);
#else
esc_name = vim_strsave_shellescape(eap->arg, true, true);
#endif
@@ -1324,8 +1320,8 @@ void ex_diffsplit(exarg_T *eap)
if (bufref_valid(&old_curbuf)) {
// Move the cursor position to that of the old window.
- curwin->w_cursor.lnum = diff_get_corresponding_line(
- old_curbuf.br_buf, old_curwin->w_cursor.lnum);
+ curwin->w_cursor.lnum = diff_get_corresponding_line(old_curbuf.br_buf,
+ old_curwin->w_cursor.lnum);
}
}
// Now that lines are folded scroll to show the cursor at the same
@@ -1344,15 +1340,15 @@ void ex_diffthis(exarg_T *eap)
static void set_diff_option(win_T *wp, int value)
{
- win_T *old_curwin = curwin;
-
- curwin = wp;
- curbuf = curwin->w_buffer;
- curbuf->b_ro_locked++;
- set_option_value("diff", (long)value, NULL, OPT_LOCAL);
- curbuf->b_ro_locked--;
- curwin = old_curwin;
- curbuf = curwin->w_buffer;
+ win_T *old_curwin = curwin;
+
+ curwin = wp;
+ curbuf = curwin->w_buffer;
+ curbuf->b_ro_locked++;
+ set_option_value("diff", (long)value, NULL, OPT_LOCAL);
+ curbuf->b_ro_locked--;
+ curwin = old_curwin;
+ curbuf = curwin->w_buffer;
}
@@ -1724,8 +1720,7 @@ static void diff_read(int idx_orig, int idx_new, diffout_T *dout)
/// @param dp
/// @param idx_orig
/// @param idx_new
-static void diff_copy_entry(diff_T *dprev, diff_T *dp, int idx_orig,
- int idx_new)
+static void diff_copy_entry(diff_T *dprev, diff_T *dp, int idx_orig, int idx_new)
{
long off;
@@ -1769,7 +1764,7 @@ void diff_clear(tabpage_T *tp)
/// @return diff status.
int diff_check(win_T *wp, linenr_T lnum)
{
- int idx; // index in tp_diffbuf[] for this buffer
+ int idx; // index in tp_diffbuf[] for this buffer
diff_T *dp;
int maxcount;
int i;
@@ -1912,8 +1907,7 @@ static bool diff_equal_entry(diff_T *dp, int idx1, int idx2)
// Compare the characters at "p1" and "p2". If they are equal (possibly
// ignoring case) return true and set "len" to the number of bytes.
-static bool diff_equal_char(const char_u *const p1, const char_u *const p2,
- int *const len)
+static bool diff_equal_char(const char_u *const p1, const char_u *const p2, int *const len)
{
const int l = utfc_ptr2len(p1);
@@ -1991,26 +1985,6 @@ static int diff_cmp(char_u *s1, char_u *s2)
return 0;
}
-/// Return the number of filler lines above "lnum".
-///
-/// @param wp
-/// @param lnum
-///
-/// @return Number of filler lines above lnum
-int diff_check_fill(win_T *wp, linenr_T lnum)
-{
- // be quick when there are no filler lines
- if (!(diff_flags & DIFF_FILLER)) {
- return 0;
- }
- int n = diff_check(wp, lnum);
-
- if (n <= 0) {
- return 0;
- }
- return n;
-}
-
/// Set the topline of "towin" to match the position in "fromwin", so that they
/// show the same diff'ed lines.
///
@@ -2036,6 +2010,7 @@ void diff_set_topline(win_T *fromwin, win_T *towin)
}
towin->w_topfill = 0;
+
// search for a change that includes "lnum" in the list of diffblocks.
for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next) {
if (lnum <= dp->df_lnum[fromidx] + dp->df_count[fromidx]) {
@@ -2261,6 +2236,13 @@ bool diffopt_closeoff(void)
return (diff_flags & DIFF_CLOSE_OFF) != 0;
}
+// Return true if 'diffopt' contains "filler".
+bool diffopt_filler(void)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ return (diff_flags & DIFF_FILLER) != 0;
+}
+
/// Find the difference within a changed line.
///
/// @param wp window whose current buffer to check
@@ -2537,7 +2519,7 @@ void ex_diffgetput(exarg_T *eap)
if ((curtab->tp_diffbuf[i] != curbuf)
&& (curtab->tp_diffbuf[i] != NULL)
&& ((eap->cmdidx != CMD_diffput)
- || MODIFIABLE(curtab->tp_diffbuf[i]))) {
+ || MODIFIABLE(curtab->tp_diffbuf[i]))) {
EMSG(_("E101: More than two buffers in diff mode, don't know "
"which one to use"));
return;
@@ -2958,7 +2940,7 @@ static linenr_T diff_get_corresponding_line_int(buf_T *buf1, linenr_T lnum1)
return curwin->w_cursor.lnum;
}
baseline = (dp->df_lnum[idx1] + dp->df_count[idx1])
- - (dp->df_lnum[idx2] + dp->df_count[idx2]);
+ - (dp->df_lnum[idx2] + dp->df_count[idx2]);
}
// If we get here then the cursor is after the last diff
@@ -3035,15 +3017,12 @@ linenr_T diff_lnum_win(linenr_T lnum, win_T *wp)
/// Handle an ED style diff line.
/// Return FAIL if the line does not contain diff info.
///
-static int parse_diff_ed(char_u *line,
- linenr_T *lnum_orig,
- long *count_orig,
- linenr_T *lnum_new,
- long *count_new)
+static int parse_diff_ed(char_u *line, linenr_T *lnum_orig, long *count_orig, linenr_T *lnum_new,
+ long *count_new)
{
char_u *p;
- long f1, l1, f2, l2;
- int difftype;
+ long f1, l1, f2, l2;
+ int difftype;
// The line must be one of three formats:
// change: {first}[,{last}]c{first}[,{last}]
@@ -3093,14 +3072,11 @@ static int parse_diff_ed(char_u *line,
/// Parses unified diff with zero(!) context lines.
/// Return FAIL if there is no diff information in "line".
///
-static int parse_diff_unified(char_u *line,
- linenr_T *lnum_orig,
- long *count_orig,
- linenr_T *lnum_new,
- long *count_new)
+static int parse_diff_unified(char_u *line, linenr_T *lnum_orig, long *count_orig,
+ linenr_T *lnum_new, long *count_new)
{
char_u *p;
- long oldline, oldcount, newline, newcount;
+ long oldline, oldcount, newline, newcount;
// Parse unified diff hunk header:
// @@ -oldline,oldcount +newline,newcount @@
@@ -3153,7 +3129,7 @@ static int parse_diff_unified(char_u *line,
static int xdiff_out(void *priv, mmbuffer_t *mb, int nbuf)
{
diffout_T *dout = (diffout_T *)priv;
- char_u *p;
+ char_u *p;
// The header line always comes by itself, text lines in at least two
// parts. We drop the text part.
diff --git a/src/nvim/diff.h b/src/nvim/diff.h
index 99a60381bd..53fc5aa077 100644
--- a/src/nvim/diff.h
+++ b/src/nvim/diff.h
@@ -1,8 +1,8 @@
#ifndef NVIM_DIFF_H
#define NVIM_DIFF_H
-#include "nvim/pos.h"
#include "nvim/ex_cmds_defs.h"
+#include "nvim/pos.h"
// Value set from 'diffopt'.
EXTERN int diff_context INIT(= 6); // context for folds
diff --git a/src/nvim/digraph.c b/src/nvim/digraph.c
index 07e484c178..0fa6ebcd94 100644
--- a/src/nvim/digraph.c
+++ b/src/nvim/digraph.c
@@ -6,26 +6,26 @@
/// code for digraphs
#include <assert.h>
-#include <stdbool.h>
#include <inttypes.h>
+#include <stdbool.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/digraph.h"
#include "nvim/charset.h"
+#include "nvim/digraph.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
-#include "nvim/misc1.h"
#include "nvim/mbyte.h"
-#include "nvim/message.h"
#include "nvim/memory.h"
-#include "nvim/garray.h"
+#include "nvim/message.h"
+#include "nvim/misc1.h"
#include "nvim/normal.h"
+#include "nvim/os/input.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
-#include "nvim/os/input.h"
+#include "nvim/vim.h"
typedef int result_T;
@@ -40,7 +40,7 @@ typedef struct digraph {
# include "digraph.c.generated.h"
#endif
// digraphs added by the user
-static garray_T user_digraphs = {0, 0, (int)sizeof(digr_T), 10, NULL};
+static garray_T user_digraphs = { 0, 0, (int)sizeof(digr_T), 10, NULL };
/// Note: Characters marked with XX are not included literally, because some
/// compilers cannot handle them (Amiga SAS/C is the most picky one).
@@ -49,7 +49,7 @@ static digr_T digraphdefault[] =
// digraphs for Unicode from RFC1345
// (also work for ISO-8859-1 aka latin1)
{
- { 'N', 'U', 0x0a }, // LF for NUL
+ { 'N', 'U', 0x0a }, // LF for NUL
{ 'S', 'H', 0x01 },
{ 'S', 'X', 0x02 },
{ 'E', 'X', 0x03 },
@@ -1452,12 +1452,12 @@ static digr_T digraphdefault[] =
/// @return The digraph.
int do_digraph(int c)
{
- static int backspaced; // character before K_BS
+ static int backspaced; // character before K_BS
static int lastchar; // last typed character
if (c == -1) { // init values
backspaced = -1;
- } else if (p_dg) {
+ } else if (p_dg) {
if (backspaced >= 0) {
c = getdigraph(backspaced, c, false);
}
@@ -1557,7 +1557,7 @@ static int getexactdigraph(int char1, int char2, bool meta_char)
// Search user digraphs first.
digr_T *dp = (digr_T *)user_digraphs.ga_data;
for (int i = 0; i < user_digraphs.ga_len; ++i) {
- if (((int) dp->char1 == char1) && ((int) dp->char2 == char2)) {
+ if (((int)dp->char1 == char1) && ((int)dp->char2 == char2)) {
retval = dp->result;
break;
}
@@ -1569,7 +1569,7 @@ static int getexactdigraph(int char1, int char2, bool meta_char)
dp = digraphdefault;
for (int i = 0; dp->char1 != 0; ++i) {
- if (((int) dp->char1 == char1) && ((int) dp->char2 == char2)) {
+ if (((int)dp->char1 == char1) && ((int)dp->char2 == char2)) {
retval = dp->result;
break;
}
@@ -1821,7 +1821,7 @@ typedef struct {
/// @return NULL if OK, an error message for failure. This only needs to be
/// used when setting the option, not later when the value has already
/// been checked.
-char_u* keymap_init(void)
+char_u *keymap_init(void)
{
curbuf->b_kmap_state &= ~KEYMAP_INIT;
@@ -1843,12 +1843,12 @@ char_u* keymap_init(void)
vim_snprintf(buf, buflen, "keymap/%s_%s.vim",
curbuf->b_p_keymap, p_enc);
- if (source_runtime((char_u *)buf, 0) == FAIL) {
+ if (source_runtime(buf, 0) == FAIL) {
// try finding "keymap/'keymap'.vim" in 'runtimepath'
vim_snprintf(buf, buflen, "keymap/%s.vim",
curbuf->b_p_keymap);
- if (source_runtime((char_u *)buf, 0) == FAIL) {
+ if (source_runtime(buf, 0) == FAIL) {
xfree(buf);
return (char_u *)N_("E544: Keymap file not found");
}
diff --git a/src/nvim/digraph.h b/src/nvim/digraph.h
index 1b73ccaf3f..71330ae9b1 100644
--- a/src/nvim/digraph.h
+++ b/src/nvim/digraph.h
@@ -1,8 +1,8 @@
#ifndef NVIM_DIGRAPH_H
#define NVIM_DIGRAPH_H
-#include "nvim/types.h"
#include "nvim/ex_cmds_defs.h"
+#include "nvim/types.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "digraph.h.generated.h"
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index aeab1cdad4..b3a08971e9 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -116,7 +116,7 @@ static char *ctrl_x_msgs[] =
static char *ctrl_x_mode_names[] = {
"keyword",
"ctrl_x",
- "unknown", // CTRL_X_SCROLL
+ "scroll",
"whole_line",
"files",
"tags",
@@ -147,7 +147,7 @@ struct compl_S {
compl_T *cp_prev;
char_u *cp_str; // matched text
char_u *(cp_text[CPT_COUNT]); // text for the menu
- typval_T cp_user_data;
+ typval_T cp_user_data;
char_u *cp_fname; // file containing the match, allocated when
// cp_flags has CP_FREE_FNAME
int cp_flags; // CP_ values
@@ -3327,9 +3327,9 @@ void get_complete_info(list_T *what_list, dict_T *retdict)
}
// Return Insert completion mode name string
-static char_u * ins_compl_mode(void)
+static char_u *ins_compl_mode(void)
{
- if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET || compl_started) {
+ if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET || ctrl_x_mode == CTRL_X_SCROLL || compl_started) {
return (char_u *)ctrl_x_mode_names[ctrl_x_mode & ~CTRL_X_WANT_IDENT];
}
return (char_u *)"";
@@ -3344,12 +3344,10 @@ static char_u * ins_compl_mode(void)
*/
static int ins_compl_bs(void)
{
- char_u *line;
- char_u *p;
-
- line = get_cursor_line_ptr();
- p = line + curwin->w_cursor.col;
+ char_u *line = get_cursor_line_ptr();
+ char_u *p = line + curwin->w_cursor.col;
MB_PTR_BACK(line, p);
+ ptrdiff_t p_off = p - line;
// Stop completion when the whole word was deleted. For Omni completion
// allow the word to be deleted, we won't match everything.
@@ -3369,8 +3367,12 @@ static int ins_compl_bs(void)
ins_compl_restart();
}
+ // ins_compl_restart() calls update_screen(0) which may invalidate the pointer
+ // TODO(bfredl): get rid of random update_screen() calls deep inside completion logic
+ line = get_cursor_line_ptr();
+
xfree(compl_leader);
- compl_leader = vim_strnsave(line + compl_col, (int)(p - line) - compl_col);
+ compl_leader = vim_strnsave(line + compl_col, (int)p_off - compl_col);
ins_compl_new_leader();
if (compl_shown_match != NULL) {
// Make sure current match is not a hidden item.
@@ -5121,7 +5123,7 @@ static int ins_complete(int c, bool enable_pum)
))) {
prefix = (char_u *)"";
}
- STRCPY((char *)compl_pattern, prefix);
+ STRCPY(compl_pattern, prefix);
(void)quote_meta(compl_pattern + STRLEN(prefix),
line + compl_col, compl_length);
} else if (--startcol < 0
@@ -5150,13 +5152,13 @@ static int ins_complete(int c, bool enable_pum)
* xmalloc(7) is enough -- Acevedo
*/
compl_pattern = xmalloc(7);
- STRCPY((char *)compl_pattern, "\\<");
+ STRCPY(compl_pattern, "\\<");
(void)quote_meta(compl_pattern + 2, line + compl_col, 1);
- STRCAT((char *)compl_pattern, "\\k");
+ STRCAT(compl_pattern, "\\k");
} else {
compl_pattern = xmalloc(quote_meta(NULL, line + compl_col,
compl_length) + 2);
- STRCPY((char *)compl_pattern, "\\<");
+ STRCPY(compl_pattern, "\\<");
(void)quote_meta(compl_pattern + 2, line + compl_col,
compl_length);
}
@@ -5679,7 +5681,7 @@ static void insert_special(int c, int allow_modmask, int ctrlv)
* stop and defer processing to the "normal" mechanism.
* '0' and '^' are special, because they can be followed by CTRL-D.
*/
-# define ISSPECIAL(c) ((c) < ' ' || (c) >= DEL || (c) == '0' || (c) == '^')
+#define ISSPECIAL(c) ((c) < ' ' || (c) >= DEL || (c) == '0' || (c) == '^')
#define WHITECHAR(cc) ( \
ascii_iswhite(cc) \
@@ -6214,8 +6216,8 @@ static void internal_format(int textwidth, int second_indent, int flags, int for
open_line(FORWARD, OPENLINE_DELSPACES + OPENLINE_MARKFIX
+ (fo_white_par ? OPENLINE_KEEPTRAIL : 0)
+ (do_comments ? OPENLINE_DO_COM : 0)
- + ((flags & INSCHAR_COM_LIST) ? OPENLINE_COM_LIST : 0)
- , ((flags & INSCHAR_COM_LIST) ? second_indent : old_indent));
+ + ((flags & INSCHAR_COM_LIST) ? OPENLINE_COM_LIST : 0),
+ ((flags & INSCHAR_COM_LIST) ? second_indent : old_indent));
if (!(flags & INSCHAR_COM_LIST)) {
old_indent = 0;
}
diff --git a/src/nvim/edit.h b/src/nvim/edit.h
index ef5dce738a..894e23ee9f 100644
--- a/src/nvim/edit.h
+++ b/src/nvim/edit.h
@@ -24,27 +24,27 @@ typedef enum {
typedef int (*IndentGetter)(void);
-/* Values for in_cinkeys() */
+// Values for in_cinkeys()
#define KEY_OPEN_FORW 0x101
#define KEY_OPEN_BACK 0x102
-#define KEY_COMPLETE 0x103 /* end of completion */
-
-/* Values for change_indent() */
-#define INDENT_SET 1 /* set indent */
-#define INDENT_INC 2 /* increase indent */
-#define INDENT_DEC 3 /* decrease indent */
-
-/* flags for beginline() */
-#define BL_WHITE 1 /* cursor on first non-white in the line */
-#define BL_SOL 2 /* use 'sol' option */
-#define BL_FIX 4 /* don't leave cursor on a NUL */
-
-/* flags for insertchar() */
-#define INSCHAR_FORMAT 1 /* force formatting */
-#define INSCHAR_DO_COM 2 /* format comments */
-#define INSCHAR_CTRLV 4 /* char typed just after CTRL-V */
-#define INSCHAR_NO_FEX 8 /* don't use 'formatexpr' */
-#define INSCHAR_COM_LIST 16 /* format comments with list/2nd line indent */
+#define KEY_COMPLETE 0x103 // end of completion
+
+// Values for change_indent()
+#define INDENT_SET 1 // set indent
+#define INDENT_INC 2 // increase indent
+#define INDENT_DEC 3 // decrease indent
+
+// flags for beginline()
+#define BL_WHITE 1 // cursor on first non-white in the line
+#define BL_SOL 2 // use 'sol' option
+#define BL_FIX 4 // don't leave cursor on a NUL
+
+// flags for insertchar()
+#define INSCHAR_FORMAT 1 // force formatting
+#define INSCHAR_DO_COM 2 // format comments
+#define INSCHAR_CTRLV 4 // char typed just after CTRL-V
+#define INSCHAR_NO_FEX 8 // don't use 'formatexpr'
+#define INSCHAR_COM_LIST 16 // format comments with list/2nd line indent
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "edit.h.generated.h"
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 2736e9a14f..e6a3901dcf 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -20,12 +20,12 @@
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/edit.h"
-#include "nvim/eval/userfunc.h"
#include "nvim/eval.h"
#include "nvim/eval/encode.h"
#include "nvim/eval/executor.h"
#include "nvim/eval/gc.h"
#include "nvim/eval/typval.h"
+#include "nvim/eval/userfunc.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
@@ -66,7 +66,7 @@ static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary");
static char *e_illvar = N_("E461: Illegal variable name: %s");
static char *e_cannot_mod = N_("E995: Cannot modify existing variable");
static char *e_nowhitespace
- = N_("E274: No white space allowed before parenthesis");
+ = N_("E274: No white space allowed before parenthesis");
static char *e_invalwindow = N_("E957: Invalid window number");
static char *e_lock_unlock = N_("E940: Cannot lock or unlock variable %s");
static char *e_write2 = N_("E80: Error while writing: %s");
@@ -97,7 +97,7 @@ typedef struct {
dict_T sv_dict;
} scriptvar_T;
-static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T *), 4, NULL};
+static garray_T ga_scripts = { 0, 0, sizeof(scriptvar_T *), 4, NULL };
#define SCRIPT_SV(id) (((scriptvar_T **)ga_scripts.ga_data)[(id) - 1])
#define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab)
@@ -113,7 +113,7 @@ typedef struct {
int fi_semicolon; // TRUE if ending in '; var]'
int fi_varcount; // nr of variables in the list
listwatch_T fi_lw; // keep an eye on the item used.
- list_T *fi_list; // list being used
+ list_T *fi_list; // list being used
int fi_bi; // index of blob
blob_T *fi_blob; // blob being used
} forinfo_T;
@@ -139,7 +139,7 @@ typedef struct {
// The reason to use this table anyway is for very quick access to the
// variables with the VV_ defines.
static struct vimvar {
- char *vv_name; ///< Name of the variable, without v:.
+ char *vv_name; ///< Name of the variable, without v:.
TV_DICTITEM_STRUCT(17) vv_di; ///< Value and name for key (max 16 chars).
char vv_flags; ///< Flags: #VV_COMPAT, #VV_RO, #VV_RO_SBX.
} vimvars[] =
@@ -334,7 +334,7 @@ void eval_init(void)
{
vimvars[VV_VERSION].vv_nr = VIM_VERSION_100;
- struct vimvar *p;
+ struct vimvar *p;
init_var_dict(&globvardict, &globvars_var, VAR_DEF_SCOPE);
init_var_dict(&vimvardict, &vimvars_var, VAR_SCOPE);
@@ -346,12 +346,13 @@ void eval_init(void)
p = &vimvars[i];
assert(STRLEN(p->vv_name) <= 16);
STRCPY(p->vv_di.di_key, p->vv_name);
- if (p->vv_flags & VV_RO)
+ if (p->vv_flags & VV_RO) {
p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
- else if (p->vv_flags & VV_RO_SBX)
+ } else if (p->vv_flags & VV_RO_SBX) {
p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX;
- else
+ } else {
p->vv_di.di_flags = DI_FLAGS_FIX;
+ }
// add to v: scope dict, unless the value is not always available
if (p->vv_type != VAR_UNKNOWN) {
@@ -424,7 +425,7 @@ void eval_init(void)
#if defined(EXITFREE)
void eval_clear(void)
{
- struct vimvar *p;
+ struct vimvar *p;
for (size_t i = 0; i < ARRAY_SIZE(vimvars); i++) {
p = &vimvars[i];
@@ -451,10 +452,12 @@ void eval_clear(void)
/* Script-local variables. First clear all the variables and in a second
* loop free the scriptvar_T, because a variable in one script might hold
* a reference to the whole scope of another script. */
- for (int i = 1; i <= ga_scripts.ga_len; ++i)
+ for (int i = 1; i <= ga_scripts.ga_len; ++i) {
vars_clear(&SCRIPT_VARS(i));
- for (int i = 1; i <= ga_scripts.ga_len; ++i)
+ }
+ for (int i = 1; i <= ga_scripts.ga_len; ++i) {
xfree(SCRIPT_SV(i));
+ }
ga_clear(&ga_scripts);
// unreferenced lists and dicts
@@ -481,20 +484,16 @@ void set_internal_string_var(const char *name, char_u *value)
set_var(name, strlen(name), &tv, true);
}
-static lval_T *redir_lval = NULL;
+static lval_T *redir_lval = NULL;
static garray_T redir_ga; // Only valid when redir_lval is not NULL.
static char_u *redir_endp = NULL;
-static char_u *redir_varname = NULL;
+static char_u *redir_varname = NULL;
-/*
- * Start recording command output to a variable
- * Returns OK if successfully completed the setup. FAIL otherwise.
- */
-int
-var_redir_start(
- char_u *name,
- int append // append to an existing variable
-)
+/// Start recording command output to a variable
+/// Returns OK if successfully completed the setup. FAIL otherwise.
+///
+/// @param append append to an existing variable
+int var_redir_start(char_u *name, int append)
{
int save_emsg;
int err;
@@ -515,8 +514,8 @@ var_redir_start(
ga_init(&redir_ga, (int)sizeof(char), 500);
// Parse the variable name (can be a dict or list entry).
- redir_endp = (char_u *)get_lval(redir_varname, NULL, redir_lval, false, false,
- 0, FNE_CHECK_START);
+ redir_endp = get_lval(redir_varname, NULL, redir_lval, false, false,
+ 0, FNE_CHECK_START);
if (redir_endp == NULL || redir_lval->ll_name == NULL
|| *redir_endp != NUL) {
clear_lval(redir_lval);
@@ -567,8 +566,9 @@ void var_redir_str(char_u *value, int value_len)
{
int len;
- if (redir_lval == NULL)
+ if (redir_lval == NULL) {
return;
+ }
if (value_len == -1) {
len = (int)STRLEN(value); // Append the entire string
@@ -597,8 +597,8 @@ void var_redir_stop(void)
tv.vval.v_string = redir_ga.ga_data;
// Call get_lval() again, if it's inside a Dict or List it may
// have changed.
- redir_endp = (char_u *)get_lval(redir_varname, NULL, redir_lval,
- false, false, 0, FNE_CHECK_START);
+ redir_endp = get_lval(redir_varname, NULL, redir_lval,
+ false, false, 0, FNE_CHECK_START);
if (redir_endp != NULL && redir_lval->ll_name != NULL) {
set_var_lval(redir_lval, redir_endp, &tv, false, false, ".");
}
@@ -655,8 +655,7 @@ int eval_printexpr(const char *const fname, const char *const args)
return OK;
}
-void eval_diff(const char *const origfile, const char *const newfile,
- const char *const outfile)
+void eval_diff(const char *const origfile, const char *const newfile, const char *const outfile)
{
bool err = false;
@@ -669,8 +668,7 @@ void eval_diff(const char *const origfile, const char *const newfile,
set_vim_var_string(VV_FNAME_OUT, NULL, -1);
}
-void eval_patch(const char *const origfile, const char *const difffile,
- const char *const outfile)
+void eval_patch(const char *const origfile, const char *const difffile, const char *const outfile)
{
bool err = false;
@@ -683,18 +681,13 @@ void eval_patch(const char *const origfile, const char *const difffile,
set_vim_var_string(VV_FNAME_OUT, NULL, -1);
}
-/*
- * Top level evaluation function, returning a boolean.
- * Sets "error" to TRUE if there was an error.
- * Return TRUE or FALSE.
- */
-int
-eval_to_bool(
- char_u *arg,
- bool *error,
- char_u **nextcmd,
- int skip // only parse, don't execute
-)
+/// Top level evaluation function, returning a boolean.
+/// Sets "error" to TRUE if there was an error.
+///
+/// @param skip only parse, don't execute
+///
+/// @return TRUE or FALSE.
+int eval_to_bool(char_u *arg, bool *error, char_u **nextcmd, int skip)
{
typval_T tv;
bool retval = false;
@@ -741,8 +734,7 @@ static int eval1_emsg(char_u **arg, typval_T *rettv, bool evaluate)
return ret;
}
-int eval_expr_typval(const typval_T *expr, typval_T *argv,
- int argc, typval_T *rettv)
+int eval_expr_typval(const typval_T *expr, typval_T *argv, int argc, typval_T *rettv)
FUNC_ATTR_NONNULL_ARG(1, 2, 4)
{
funcexe_T funcexe = FUNCEXE_INIT;
@@ -811,8 +803,7 @@ bool eval_expr_to_bool(const typval_T *expr, bool *error)
///
/// @return [allocated] string result of evaluation or NULL in case of error or
/// when skipping.
-char *eval_to_string_skip(const char *arg, const char **nextcmd,
- const bool skip)
+char *eval_to_string_skip(const char *arg, const char **nextcmd, const bool skip)
FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT
{
typval_T tv;
@@ -890,7 +881,7 @@ char_u *eval_to_string(char_u *arg, char_u **nextcmd, bool convert)
*/
char_u *eval_to_string_safe(char_u *arg, char_u **nextcmd, int use_sandbox)
{
- char_u *retval;
+ char_u *retval;
funccal_entry_T funccal_entry;
save_funccal(&funccal_entry);
@@ -916,7 +907,7 @@ varnumber_T eval_to_number(char_u *expr)
{
typval_T rettv;
varnumber_T retval;
- char_u *p = skipwhite(expr);
+ char_u *p = skipwhite(expr);
++emsg_off;
@@ -951,8 +942,9 @@ typval_T *eval_expr(char_u *arg)
void prepare_vimvar(int idx, typval_T *save_tv)
{
*save_tv = vimvars[idx].vv_tv;
- if (vimvars[idx].vv_type == VAR_UNKNOWN)
+ if (vimvars[idx].vv_type == VAR_UNKNOWN) {
hash_add(&vimvarht, vimvars[idx].vv_di.di_key);
+ }
}
/*
@@ -961,7 +953,7 @@ void prepare_vimvar(int idx, typval_T *save_tv)
*/
void restore_vimvar(int idx, typval_T *save_tv)
{
- hashitem_T *hi;
+ hashitem_T *hi;
vimvars[idx].vv_tv = *save_tv;
if (vimvars[idx].vv_type == VAR_UNKNOWN) {
@@ -994,15 +986,16 @@ list_T *eval_spell_expr(char_u *badword, char_u *expr)
{
typval_T save_val;
typval_T rettv;
- list_T *list = NULL;
- char_u *p = skipwhite(expr);
+ list_T *list = NULL;
+ char_u *p = skipwhite(expr);
// Set "v:val" to the bad word.
prepare_vimvar(VV_VAL, &save_val);
vimvars[VV_VAL].vv_type = VAR_STRING;
vimvars[VV_VAL].vv_str = badword;
- if (p_verbose == 0)
+ if (p_verbose == 0) {
++emsg_off;
+ }
if (eval1(&p, &rettv, true) == OK) {
if (rettv.v_type != VAR_LIST) {
@@ -1012,8 +1005,9 @@ list_T *eval_spell_expr(char_u *badword, char_u *expr)
}
}
- if (p_verbose == 0)
+ if (p_verbose == 0) {
--emsg_off;
+ }
restore_vimvar(VV_VAL, &save_val);
return list;
@@ -1052,12 +1046,7 @@ int get_spellword(list_T *const list, const char **ret_word)
// should have type VAR_UNKNOWN.
//
// Return OK or FAIL.
-int call_vim_function(
- const char_u *func,
- int argc,
- typval_T *argv,
- typval_T *rettv
-)
+int call_vim_function(const char_u *func, int argc, typval_T *argv, typval_T *rettv)
FUNC_ATTR_NONNULL_ALL
{
int ret;
@@ -1096,8 +1085,7 @@ fail:
/// @param[in] argv Array with typval_T arguments.
///
/// @return -1 when calling function fails, result of function otherwise.
-varnumber_T call_func_retnr(const char_u *func, int argc,
- typval_T *argv)
+varnumber_T call_func_retnr(const char_u *func, int argc, typval_T *argv)
FUNC_ATTR_NONNULL_ALL
{
typval_T rettv;
@@ -1118,8 +1106,7 @@ varnumber_T call_func_retnr(const char_u *func, int argc,
///
/// @return [allocated] NULL when calling function fails, allocated string
/// otherwise.
-char *call_func_retstr(const char *const func, int argc,
- typval_T *argv)
+char *call_func_retstr(const char *const func, int argc, typval_T *argv)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
{
typval_T rettv;
@@ -1159,14 +1146,12 @@ void *call_func_retlist(const char_u *func, int argc, typval_T *argv)
return rettv.vval.v_list;
}
-/*
- * Prepare profiling for entering a child or something else that is not
- * counted for the script/function itself.
- * Should always be called in pair with prof_child_exit().
- */
-void prof_child_enter(
- proftime_T *tm // place to store waittime
-)
+/// Prepare profiling for entering a child or something else that is not
+/// counted for the script/function itself.
+/// Should always be called in pair with prof_child_exit().
+///
+/// @param tm place to store waittime
+void prof_child_enter(proftime_T *tm)
{
funccall_T *fc = get_current_funccal();
@@ -1177,13 +1162,11 @@ void prof_child_enter(
script_prof_save(tm);
}
-/*
- * Take care of time spent in a child.
- * Should always be called after prof_child_enter().
- */
-void prof_child_exit(
- proftime_T *tm // where waittime was stored
-)
+/// Take care of time spent in a child.
+/// Should always be called after prof_child_enter().
+///
+/// @param tm where waittime was stored
+void prof_child_exit(proftime_T *tm)
{
funccall_T *fc = get_current_funccal();
@@ -1208,11 +1191,12 @@ int eval_foldexpr(char_u *arg, int *cp)
{
typval_T tv;
varnumber_T retval;
- int use_sandbox = was_set_insecurely(curwin, (char_u *)"foldexpr", OPT_LOCAL);
+ int use_sandbox = was_set_insecurely(curwin, "foldexpr", OPT_LOCAL);
++emsg_off;
- if (use_sandbox)
+ if (use_sandbox) {
++sandbox;
+ }
++textlock;
*cp = NUL;
if (eval0(arg, &tv, NULL, true) == FAIL) {
@@ -1235,8 +1219,9 @@ int eval_foldexpr(char_u *arg, int *cp)
tv_clear(&tv);
}
--emsg_off;
- if (use_sandbox)
+ if (use_sandbox) {
--sandbox;
+ }
--textlock;
return (int)retval;
@@ -1262,8 +1247,7 @@ void ex_const(exarg_T *eap)
// marker, then the leading indentation before the lines (matching the
// indentation in the 'cmd' line) is stripped.
// Returns a List with {lines} or NULL.
-static list_T *
-heredoc_get(exarg_T *eap, char_u *cmd)
+static list_T *heredoc_get(exarg_T *eap, char_u *cmd)
{
char_u *marker;
char_u *p;
@@ -1327,29 +1311,29 @@ heredoc_get(exarg_T *eap, char_u *cmd)
// marker
if (marker_indent_len > 0
&& STRNCMP(theline, *eap->cmdlinep, marker_indent_len) == 0) {
- mi = marker_indent_len;
+ mi = marker_indent_len;
}
if (STRCMP(marker, theline + mi) == 0) {
xfree(theline);
break;
}
if (text_indent_len == -1 && *theline != NUL) {
- // set the text indent from the first line.
- p = theline;
- text_indent_len = 0;
- while (ascii_iswhite(*p)) {
- p++;
- text_indent_len++;
- }
- text_indent = vim_strnsave(theline, text_indent_len);
+ // set the text indent from the first line.
+ p = theline;
+ text_indent_len = 0;
+ while (ascii_iswhite(*p)) {
+ p++;
+ text_indent_len++;
+ }
+ text_indent = vim_strnsave(theline, text_indent_len);
}
// with "trim": skip the indent matching the first line
if (text_indent != NULL) {
- for (ti = 0; ti < text_indent_len; ti++) {
- if (theline[ti] != text_indent[ti]) {
- break;
- }
+ for (ti = 0; ti < text_indent_len; ti++) {
+ if (theline[ti] != text_indent[ti]) {
+ break;
}
+ }
}
tv_list_append_string(l, (char *)(theline + ti), -1);
@@ -1379,14 +1363,14 @@ void ex_let(exarg_T *eap)
static void ex_let_const(exarg_T *eap, const bool is_const)
{
- char_u *arg = eap->arg;
- char_u *expr = NULL;
+ char_u *arg = eap->arg;
+ char_u *expr = NULL;
typval_T rettv;
int i;
int var_count = 0;
int semicolon = 0;
char_u op[2];
- char_u *argend;
+ char_u *argend;
int first = TRUE;
argend = (char_u *)skip_var_list(arg, &var_count, &semicolon);
@@ -1444,8 +1428,9 @@ static void ex_let_const(exarg_T *eap, const bool is_const)
expr = skipwhite(expr + 1);
}
- if (eap->skip)
+ if (eap->skip) {
++emsg_skip;
+ }
i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip);
if (eap->skip) {
if (i != FAIL) {
@@ -1460,21 +1445,20 @@ static void ex_let_const(exarg_T *eap, const bool is_const)
}
}
-/*
- * Assign the typevalue "tv" to the variable or variables at "arg_start".
- * Handles both "var" with any type and "[var, var; var]" with a list type.
- * When "op" is not NULL it points to a string with characters that
- * must appear after the variable(s). Use "+", "-" or "." for add, subtract
- * or concatenate.
- * Returns OK or FAIL;
- */
-static int ex_let_vars(char_u *arg_start,
- typval_T *tv,
- int copy, // copy values from "tv", don't move
- int semicolon, // from skip_var_list()
- int var_count, // from skip_var_list()
- int is_const, // lock variables for :const
- char_u *op)
+/// Assign the typevalue "tv" to the variable or variables at "arg_start".
+/// Handles both "var" with any type and "[var, var; var]" with a list type.
+/// When "op" is not NULL it points to a string with characters that
+/// must appear after the variable(s). Use "+", "-" or "." for add, subtract
+/// or concatenate.
+///
+/// @param copy copy values from "tv", don't move
+/// @param semicolon from skip_var_list()
+/// @param var_count from skip_var_list()
+/// @param is_const lock variables for :const
+///
+/// @return OK or FAIL;
+static int ex_let_vars(char_u *arg_start, typval_T *tv, int copy, int semicolon, int var_count,
+ int is_const, char_u *op)
{
char_u *arg = arg_start;
typval_T ltv;
@@ -1559,8 +1543,7 @@ static int ex_let_vars(char_u *arg_start,
* for "[var, var; var]" set "semicolon".
* Return NULL for an error.
*/
-static const char_u *skip_var_list(const char_u *arg, int *var_count,
- int *semicolon)
+static const char_u *skip_var_list(const char_u *arg, int *var_count, int *semicolon)
{
const char_u *p;
const char_u *s;
@@ -1578,9 +1561,9 @@ static const char_u *skip_var_list(const char_u *arg, int *var_count,
++*var_count;
p = skipwhite(s);
- if (*p == ']')
+ if (*p == ']') {
break;
- else if (*p == ';') {
+ } else if (*p == ';') {
if (*semicolon == 1) {
EMSG(_("E452: Double ; in list of variables"));
return NULL;
@@ -1592,8 +1575,9 @@ static const char_u *skip_var_list(const char_u *arg, int *var_count,
}
}
return p + 1;
- } else
+ } else {
return skip_var_one(arg);
+ }
}
/*
@@ -1602,21 +1586,21 @@ static const char_u *skip_var_list(const char_u *arg, int *var_count,
*/
static const char_u *skip_var_one(const char_u *arg)
{
- if (*arg == '@' && arg[1] != NUL)
+ if (*arg == '@' && arg[1] != NUL) {
return arg + 2;
+ }
return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg,
- NULL, NULL, FNE_INCL_BR | FNE_CHECK_START);
+ NULL, NULL, FNE_INCL_BR | FNE_CHECK_START);
}
/*
* List variables for hashtab "ht" with prefix "prefix".
* If "empty" is TRUE also list NULL strings as empty strings.
*/
-void list_hashtable_vars(hashtab_T *ht, const char *prefix, int empty,
- int *first)
+void list_hashtable_vars(hashtab_T *ht, const char *prefix, int empty, int *first)
{
- hashitem_T *hi;
- dictitem_T *di;
+ hashitem_T *hi;
+ dictitem_T *di;
int todo;
todo = (int)ht->ht_used;
@@ -1727,7 +1711,7 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first)
if (tofree != NULL) {
name = tofree;
}
- if (get_var_tv((const char *)name, len, &tv, NULL, true, false)
+ if (get_var_tv(name, len, &tv, NULL, true, false)
== FAIL) {
error = true;
} else {
@@ -1740,13 +1724,20 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first)
} else {
if (arg == arg_subsc && len == 2 && name[1] == ':') {
switch (*name) {
- case 'g': list_glob_vars(first); break;
- case 'b': list_buf_vars(first); break;
- case 'w': list_win_vars(first); break;
- case 't': list_tab_vars(first); break;
- case 'v': list_vim_vars(first); break;
- case 's': list_script_vars(first); break;
- case 'l': list_func_vars(first); break;
+ case 'g':
+ list_glob_vars(first); break;
+ case 'b':
+ list_buf_vars(first); break;
+ case 'w':
+ list_win_vars(first); break;
+ case 't':
+ list_tab_vars(first); break;
+ case 'v':
+ list_vim_vars(first); break;
+ case 's':
+ list_script_vars(first); break;
+ case 'l':
+ list_func_vars(first); break;
default:
EMSG2(_("E738: Can't list variables for %s"), name);
}
@@ -1789,8 +1780,7 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first)
///
/// @return a pointer to the char just after the var name or NULL in case of
/// error.
-static char_u *ex_let_one(char_u *arg, typval_T *const tv,
- const bool copy, const bool is_const,
+static char_u *ex_let_one(char_u *arg, typval_T *const tv, const bool copy, const bool is_const,
const char_u *const endchars, const char_u *const op)
FUNC_ATTR_NONNULL_ARG(1, 2) FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -1848,9 +1838,9 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv,
xfree(tofree);
}
}
- // ":let &option = expr": Set option value.
- // ":let &l:option = expr": Set local option value.
- // ":let &g:option = expr": Set global option value.
+ // ":let &option = expr": Set option value.
+ // ":let &l:option = expr": Set local option value.
+ // ":let &g:option = expr": Set global option value.
} else if (*arg == '&') {
if (is_const) {
EMSG(_("E996: Cannot lock an option"));
@@ -1885,11 +1875,16 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv,
} else {
if (opt_type == 1) { // number
switch (*op) {
- case '+': n = numval + n; break;
- case '-': n = numval - n; break;
- case '*': n = numval * n; break;
- case '/': n = num_divide(numval, n); break;
- case '%': n = num_modulus(numval, n); break;
+ case '+':
+ n = numval + n; break;
+ case '-':
+ n = numval - n; break;
+ case '*':
+ n = numval * n; break;
+ case '/':
+ n = num_divide(numval, n); break;
+ case '%':
+ n = num_modulus(numval, n); break;
}
} else if (opt_type == 0 && stringval != NULL) { // string
char *const oldstringval = stringval;
@@ -1908,7 +1903,7 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv,
*p = c1;
xfree(stringval);
}
- // ":let @r = expr": Set register contents.
+ // ":let @r = expr": Set register contents.
} else if (*arg == '@') {
if (is_const) {
EMSG(_("E996: Cannot lock a register"));
@@ -1921,7 +1916,7 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv,
&& vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) {
EMSG(_(e_letunexp));
} else {
- char_u *s;
+ char_u *s;
char_u *ptofree = NULL;
const char *p = tv_get_string_chk(tv);
@@ -1958,8 +1953,9 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv,
}
}
clear_lval(&lv);
- } else
+ } else {
EMSG2(_(e_invarg2), arg);
+ }
return arg_end;
}
@@ -1989,16 +1985,15 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv,
///
/// @return A pointer to just after the name, including indexes. Returns NULL
/// for a parsing error, but it is still needed to free items in lp.
-char_u *get_lval(char_u *const name, typval_T *const rettv,
- lval_T *const lp, const bool unlet, const bool skip,
- const int flags, const int fne_flags)
+char_u *get_lval(char_u *const name, typval_T *const rettv, lval_T *const lp, const bool unlet,
+ const bool skip, const int flags, const int fne_flags)
FUNC_ATTR_NONNULL_ARG(1, 3)
{
- dictitem_T *v;
+ dictitem_T *v;
typval_T var1;
typval_T var2;
int empty1 = FALSE;
- listitem_T *ni;
+ listitem_T *ni;
hashtab_T *ht = NULL;
int quiet = flags & GLV_QUIET;
@@ -2028,7 +2023,7 @@ char_u *get_lval(char_u *const name, typval_T *const rettv,
}
lp->ll_exp_name = (char *)make_expanded_name(name, expr_start, expr_end,
- (char_u *)p);
+ p);
lp->ll_name = lp->ll_exp_name;
if (lp->ll_exp_name == NULL) {
/* Report an invalid expression in braces, unless the
@@ -2080,8 +2075,9 @@ char_u *get_lval(char_u *const name, typval_T *const rettv,
return NULL;
}
if (lp->ll_range) {
- if (!quiet)
+ if (!quiet) {
EMSG(_("E708: [:] must come last"));
+ }
return NULL;
}
@@ -2233,7 +2229,7 @@ char_u *get_lval(char_u *const name, typval_T *const rettv,
}
tv_clear(&var1);
break;
- // existing variable, need to check if it can be changed
+ // existing variable, need to check if it can be changed
} else if (!(flags & GLV_READ_ONLY) && var_check_ro(lp->ll_di->di_flags,
(const char *)name,
(size_t)(p - name))) {
@@ -2312,8 +2308,9 @@ char_u *get_lval(char_u *const name, typval_T *const rettv,
if (lp->ll_n2 < 0) {
ni = tv_list_find(lp->ll_list, lp->ll_n2);
if (ni == NULL) {
- if (!quiet)
+ if (!quiet) {
EMSGN(_(e_listidx), lp->ll_n2);
+ }
return NULL;
}
lp->ll_n2 = tv_list_idx_of_item(lp->ll_list, ni);
@@ -2358,12 +2355,12 @@ void clear_lval(lval_T *lp)
* "op" is NULL, "+" for "+=", "-" for "-=", "*" for "*=", "/" for "/=",
* "%" for "%=", "." for ".=" or "=" for "=".
*/
-static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv,
- int copy, const bool is_const, const char *op)
+static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, const bool is_const,
+ const char *op)
{
int cc;
- listitem_T *ri;
- dictitem_T *di;
+ listitem_T *ri;
+ dictitem_T *di;
if (lp->ll_tv == NULL) {
cc = *endp;
@@ -2422,7 +2419,7 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv,
// handle +=, -=, *=, /=, %= and .=
di = NULL;
- if (get_var_tv((const char *)lp->ll_name, (int)STRLEN(lp->ll_name),
+ if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name),
&tv, &di, true, false) == OK) {
if ((di == NULL
|| (!var_check_ro(di->di_flags, lp->ll_name, TV_CSTRING)
@@ -2568,16 +2565,17 @@ notify:
*/
void *eval_for_line(const char_u *arg, bool *errp, char_u **nextcmdp, int skip)
{
- forinfo_T *fi = xcalloc(1, sizeof(forinfo_T));
+ forinfo_T *fi = xcalloc(1, sizeof(forinfo_T));
const char_u *expr;
typval_T tv;
- list_T *l;
+ list_T *l;
*errp = true; // Default: there is an error.
expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon);
- if (expr == NULL)
+ if (expr == NULL) {
return fi;
+ }
expr = skipwhite(expr);
if (expr[0] != 'i' || expr[1] != 'n' || !ascii_iswhite(expr[2])) {
@@ -2585,8 +2583,9 @@ void *eval_for_line(const char_u *arg, bool *errp, char_u **nextcmdp, int skip)
return fi;
}
- if (skip)
+ if (skip) {
++emsg_skip;
+ }
if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) {
*errp = false;
if (!skip) {
@@ -2619,8 +2618,9 @@ void *eval_for_line(const char_u *arg, bool *errp, char_u **nextcmdp, int skip)
}
}
}
- if (skip)
+ if (skip) {
--emsg_skip;
+ }
return fi;
}
@@ -2667,7 +2667,7 @@ bool next_for_item(void *fi_void, char_u *arg)
*/
void free_for_info(void *fi_void)
{
- forinfo_T *fi = (forinfo_T *)fi_void;
+ forinfo_T *fi = (forinfo_T *)fi_void;
if (fi != NULL && fi->fi_list != NULL) {
tv_list_watch_remove(fi->fi_list, &fi->fi_lw);
@@ -2685,7 +2685,7 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
{
int got_eq = FALSE;
int c;
- char_u *p;
+ char_u *p;
if (cmdidx == CMD_let || cmdidx == CMD_const) {
xp->xp_context = EXPAND_USER_VARS;
@@ -2700,11 +2700,12 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
}
return;
}
- } else
+ } else {
xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS
- : EXPAND_EXPRESSION;
+ : EXPAND_EXPRESSION;
+ }
while ((xp->xp_pattern = vim_strpbrk(arg,
- (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) {
+ (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) {
c = *xp->xp_pattern;
if (c == '&') {
c = xp->xp_pattern[1];
@@ -2714,9 +2715,9 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
? EXPAND_EXPRESSION : EXPAND_NOTHING;
} else if (c != ' ') {
xp->xp_context = EXPAND_SETTINGS;
- if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':')
+ if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') {
xp->xp_pattern += 2;
-
+ }
}
} else if (c == '$') {
// environment variable
@@ -2750,14 +2751,17 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
if (xp->xp_pattern[1] == '|') {
++xp->xp_pattern;
xp->xp_context = EXPAND_EXPRESSION;
- } else
+ } else {
xp->xp_context = EXPAND_COMMANDS;
- } else
+ }
+ } else {
xp->xp_context = EXPAND_EXPRESSION;
- } else
+ }
+ } else {
/* Doesn't look like something valid, expand as an expression
* anyway. */
xp->xp_context = EXPAND_EXPRESSION;
+ }
arg = xp->xp_pattern;
if (*arg != NUL) {
while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) {
@@ -2819,8 +2823,7 @@ void ex_lockvar(exarg_T *eap)
/// @param[in] deep Levels to (un)lock for :(un)lockvar, -1 to (un)lock
/// everything.
/// @param[in] callback Appropriate handler for the command.
-static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep,
- ex_unletlock_callback callback)
+static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep, ex_unletlock_callback callback)
FUNC_ATTR_NONNULL_ALL
{
char_u *arg = argstart;
@@ -2884,8 +2887,7 @@ static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep,
/// @param[in] deep Unused.
///
/// @return OK on success, or FAIL on failure.
-static int do_unlet_var(lval_T *lp, char_u *name_end, exarg_T *eap,
- int deep FUNC_ATTR_UNUSED)
+static int do_unlet_var(lval_T *lp, char_u *name_end, exarg_T *eap, int deep FUNC_ATTR_UNUSED)
FUNC_ATTR_NONNULL_ALL
{
int forceit = eap->forceit;
@@ -2989,7 +2991,7 @@ int do_unlet(const char *const name, const size_t name_len, const bool forceit)
if (ht == &globvarht) {
d = &globvardict;
} else if (ht == &compat_hashtab) {
- d = &vimvardict;
+ d = &vimvardict;
} else {
dictitem_T *const di = find_var_in_ht(ht, *name, "", 0, false);
d = di->di_tv.vval.v_dict;
@@ -3002,12 +3004,12 @@ int do_unlet(const char *const name, const size_t name_len, const bool forceit)
hashitem_T *hi = hash_find(ht, (const char_u *)varname);
if (HASHITEM_EMPTY(hi)) {
- hi = find_hi_in_scoped_ht((const char *)name, &ht);
+ hi = find_hi_in_scoped_ht(name, &ht);
}
if (hi != NULL && !HASHITEM_EMPTY(hi)) {
dictitem_T *const di = TV_DICT_HI2DI(hi);
- if (var_check_fixed(di->di_flags, (const char *)name, TV_CSTRING)
- || var_check_ro(di->di_flags, (const char *)name, TV_CSTRING)
+ if (var_check_fixed(di->di_flags, name, TV_CSTRING)
+ || var_check_ro(di->di_flags, name, TV_CSTRING)
|| var_check_lock(d->dv_lock, name, TV_CSTRING)) {
return FAIL;
}
@@ -3032,8 +3034,9 @@ int do_unlet(const char *const name, const size_t name_len, const bool forceit)
return OK;
}
}
- if (forceit)
+ if (forceit) {
return OK;
+ }
EMSG2(_("E108: No such variable: \"%s\""), name);
return FAIL;
}
@@ -3050,8 +3053,7 @@ int do_unlet(const char *const name, const size_t name_len, const bool forceit)
/// @param[in] deep Levels to (un)lock, -1 to (un)lock everything.
///
/// @return OK on success, or FAIL on failure.
-static int do_lock_var(lval_T *lp, char_u *name_end FUNC_ATTR_UNUSED,
- exarg_T *eap, int deep)
+static int do_lock_var(lval_T *lp, char_u *name_end FUNC_ATTR_UNUSED, exarg_T *eap, int deep)
FUNC_ATTR_NONNULL_ARG(1, 3)
{
bool lock = eap->cmdidx == CMD_lockvar;
@@ -3067,9 +3069,8 @@ static int do_lock_var(lval_T *lp, char_u *name_end FUNC_ATTR_UNUSED,
ret = FAIL;
} else {
// Normal name or expanded name.
- dictitem_T *const di = find_var(
- (const char *)lp->ll_name, lp->ll_name_len, NULL,
- true);
+ dictitem_T *const di = find_var(lp->ll_name, lp->ll_name_len, NULL,
+ true);
if (di == NULL) {
ret = FAIL;
} else if ((di->di_flags & DI_FLAGS_FIX)
@@ -3089,7 +3090,7 @@ static int do_lock_var(lval_T *lp, char_u *name_end FUNC_ATTR_UNUSED,
}
}
} else if (lp->ll_range) {
- listitem_T *li = lp->ll_li;
+ listitem_T *li = lp->ll_li;
// (un)lock a range of List items.
while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) {
@@ -3129,7 +3130,7 @@ void del_menutrans_vars(void)
*/
-static char_u *varnamebuf = NULL;
+static char_u *varnamebuf = NULL;
static size_t varnamebuflen = 0;
/*
@@ -3163,7 +3164,7 @@ char_u *get_user_var_name(expand_T *xp, int idx)
static size_t wdone;
static size_t tdone;
static size_t vidx;
- static hashitem_T *hi;
+ static hashitem_T *hi;
if (idx == 0) {
gdone = bdone = wdone = vidx = 0;
@@ -3172,14 +3173,17 @@ char_u *get_user_var_name(expand_T *xp, int idx)
// Global variables
if (gdone < globvarht.ht_used) {
- if (gdone++ == 0)
+ if (gdone++ == 0) {
hi = globvarht.ht_array;
- else
+ } else {
++hi;
- while (HASHITEM_EMPTY(hi))
+ }
+ while (HASHITEM_EMPTY(hi)) {
++hi;
- if (STRNCMP("g:", xp->xp_pattern, 2) == 0)
+ }
+ if (STRNCMP("g:", xp->xp_pattern, 2) == 0) {
return cat_prefix_varname('g', hi->hi_key);
+ }
return hi->hi_key;
}
@@ -3189,12 +3193,14 @@ char_u *get_user_var_name(expand_T *xp, int idx)
? &prevwin->w_buffer->b_vars->dv_hashtab
: &curbuf->b_vars->dv_hashtab;
if (bdone < ht->ht_used) {
- if (bdone++ == 0)
+ if (bdone++ == 0) {
hi = ht->ht_array;
- else
+ } else {
++hi;
- while (HASHITEM_EMPTY(hi))
+ }
+ while (HASHITEM_EMPTY(hi)) {
++hi;
+ }
return cat_prefix_varname('b', hi->hi_key);
}
@@ -3204,24 +3210,28 @@ char_u *get_user_var_name(expand_T *xp, int idx)
? &prevwin->w_vars->dv_hashtab
: &curwin->w_vars->dv_hashtab;
if (wdone < ht->ht_used) {
- if (wdone++ == 0)
+ if (wdone++ == 0) {
hi = ht->ht_array;
- else
+ } else {
++hi;
- while (HASHITEM_EMPTY(hi))
+ }
+ while (HASHITEM_EMPTY(hi)) {
++hi;
+ }
return cat_prefix_varname('w', hi->hi_key);
}
// t: variables
ht = &curtab->tp_vars->dv_hashtab;
if (tdone < ht->ht_used) {
- if (tdone++ == 0)
+ if (tdone++ == 0) {
hi = ht->ht_array;
- else
+ } else {
++hi;
- while (HASHITEM_EMPTY(hi))
+ }
+ while (HASHITEM_EMPTY(hi)) {
++hi;
+ }
return cat_prefix_varname('t', hi->hi_key);
}
@@ -3265,8 +3275,7 @@ static int pattern_match(char_u *pat, char_u *text, bool ic)
//
/// @return OK or FAIL.
static int eval_func(char_u **const arg, char_u *const name, const int name_len,
- typval_T *const rettv, const bool evaluate,
- typval_T *const basetv)
+ typval_T *const rettv, const bool evaluate, typval_T *const basetv)
FUNC_ATTR_NONNULL_ARG(1, 2, 4)
{
char_u *s = name;
@@ -3334,7 +3343,7 @@ static int eval_func(char_u **const arg, char_u *const name, const int name_len,
int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)
{
int ret;
- char_u *p;
+ char_u *p;
const int did_emsg_before = did_emsg;
const int called_emsg_before = called_emsg;
@@ -3354,8 +3363,9 @@ int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)
}
ret = FAIL;
}
- if (nextcmd != NULL)
+ if (nextcmd != NULL) {
*nextcmd = check_nextcmd(p);
+ }
return ret;
}
@@ -3364,7 +3374,7 @@ int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)
/*
* Handle top level expression:
- * expr2 ? expr1 : expr1
+ * expr2 ? expr1 : expr1
*
* "arg" must point to the first non-white of the expression.
* "arg" is advanced to the next non-white after the recognized expression.
@@ -3381,8 +3391,9 @@ int eval1(char_u **arg, typval_T *rettv, int evaluate)
/*
* Get the first variable.
*/
- if (eval2(arg, rettv, evaluate) == FAIL)
+ if (eval2(arg, rettv, evaluate) == FAIL) {
return FAIL;
+ }
if ((*arg)[0] == '?') {
result = FALSE;
@@ -3427,8 +3438,9 @@ int eval1(char_u **arg, typval_T *rettv, int evaluate)
}
return FAIL;
}
- if (evaluate && !result)
+ if (evaluate && !result) {
*rettv = var2;
+ }
}
return OK;
@@ -3438,7 +3450,7 @@ int eval1(char_u **arg, typval_T *rettv, int evaluate)
/*
* Handle first level expression:
- * expr2 || expr2 || expr2 logical OR
+ * expr2 || expr2 || expr2 logical OR
*
* "arg" must point to the first non-white of the expression.
* "arg" is advanced to the next non-white after the recognized expression.
@@ -3455,8 +3467,9 @@ static int eval2(char_u **arg, typval_T *rettv, int evaluate)
/*
* Get the first variable.
*/
- if (eval3(arg, rettv, evaluate) == FAIL)
+ if (eval3(arg, rettv, evaluate) == FAIL) {
return FAIL;
+ }
/*
* Repeat until there is no following "||".
@@ -3479,8 +3492,9 @@ static int eval2(char_u **arg, typval_T *rettv, int evaluate)
* Get the second variable.
*/
*arg = skipwhite(*arg + 2);
- if (eval3(arg, &var2, evaluate && !result) == FAIL)
+ if (eval3(arg, &var2, evaluate && !result) == FAIL) {
return FAIL;
+ }
/*
* Compute the result.
@@ -3507,7 +3521,7 @@ static int eval2(char_u **arg, typval_T *rettv, int evaluate)
/*
* Handle second level expression:
- * expr3 && expr3 && expr3 logical AND
+ * expr3 && expr3 && expr3 logical AND
*
* "arg" must point to the first non-white of the expression.
* "arg" is advanced to the next non-white after the recognized expression.
@@ -3524,8 +3538,9 @@ static int eval3(char_u **arg, typval_T *rettv, int evaluate)
/*
* Get the first variable.
*/
- if (eval4(arg, rettv, evaluate) == FAIL)
+ if (eval4(arg, rettv, evaluate) == FAIL) {
return FAIL;
+ }
/*
* Repeat until there is no following "&&".
@@ -3548,8 +3563,9 @@ static int eval3(char_u **arg, typval_T *rettv, int evaluate)
* Get the second variable.
*/
*arg = skipwhite(*arg + 2);
- if (eval4(arg, &var2, evaluate && result) == FAIL)
+ if (eval4(arg, &var2, evaluate && result) == FAIL) {
return FAIL;
+ }
/*
* Compute the result.
@@ -3576,16 +3592,16 @@ static int eval3(char_u **arg, typval_T *rettv, int evaluate)
/*
* Handle third level expression:
- * var1 == var2
- * var1 =~ var2
- * var1 != var2
- * var1 !~ var2
- * var1 > var2
- * var1 >= var2
- * var1 < var2
- * var1 <= var2
- * var1 is var2
- * var1 isnot var2
+ * var1 == var2
+ * var1 =~ var2
+ * var1 != var2
+ * var1 !~ var2
+ * var1 > var2
+ * var1 >= var2
+ * var1 < var2
+ * var1 <= var2
+ * var1 is var2
+ * var1 isnot var2
*
* "arg" must point to the first non-white of the expression.
* "arg" is advanced to the next non-white after the recognized expression.
@@ -3595,7 +3611,7 @@ static int eval3(char_u **arg, typval_T *rettv, int evaluate)
static int eval4(char_u **arg, typval_T *rettv, int evaluate)
{
typval_T var2;
- char_u *p;
+ char_u *p;
exprtype_T type = EXPR_UNKNOWN;
int len = 2;
bool ic;
@@ -3603,8 +3619,9 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
/*
* Get the first variable.
*/
- if (eval5(arg, rettv, evaluate) == FAIL)
+ if (eval5(arg, rettv, evaluate) == FAIL) {
return FAIL;
+ }
p = *arg;
switch (p[0]) {
@@ -3638,14 +3655,15 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
type = EXPR_SEQUAL;
}
break;
- case 'i': if (p[1] == 's') {
+ case 'i':
+ if (p[1] == 's') {
if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') {
len = 5;
}
if (!isalnum(p[len]) && p[len] != '_') {
type = len == 2 ? EXPR_IS : EXPR_ISNOT;
}
- }
+ }
break;
}
@@ -3685,10 +3703,10 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
/*
* Handle fourth level expression:
- * + number addition
- * - number subtraction
- * . string concatenation
- * .. string concatenation
+ * + number addition
+ * - number subtraction
+ * . string concatenation
+ * .. string concatenation
*
* "arg" must point to the first non-white of the expression.
* "arg" is advanced to the next non-white after the recognized expression.
@@ -3702,21 +3720,23 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate)
int op;
varnumber_T n1, n2;
float_T f1 = 0, f2 = 0;
- char_u *p;
+ char_u *p;
/*
* Get the first variable.
*/
- if (eval6(arg, rettv, evaluate, FALSE) == FAIL)
+ if (eval6(arg, rettv, evaluate, FALSE) == FAIL) {
return FAIL;
+ }
/*
* Repeat computing, until no '+', '-' or '.' is following.
*/
for (;; ) {
op = **arg;
- if (op != '+' && op != '-' && op != '.')
+ if (op != '+' && op != '-' && op != '.') {
break;
+ }
if ((op != '+' || (rettv->v_type != VAR_LIST && rettv->v_type != VAR_BLOB))
&& (op == '.' || rettv->v_type != VAR_FLOAT)) {
@@ -3807,8 +3827,9 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate)
tv_clear(&var2);
return FAIL;
}
- if (var2.v_type == VAR_FLOAT)
+ if (var2.v_type == VAR_FLOAT) {
f1 = n1;
+ }
}
if (var2.v_type == VAR_FLOAT) {
f2 = var2.vval.v_float;
@@ -3820,24 +3841,27 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate)
tv_clear(&var2);
return FAIL;
}
- if (rettv->v_type == VAR_FLOAT)
+ if (rettv->v_type == VAR_FLOAT) {
f2 = n2;
+ }
}
tv_clear(rettv);
// If there is a float on either side the result is a float.
if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) {
- if (op == '+')
+ if (op == '+') {
f1 = f1 + f2;
- else
+ } else {
f1 = f1 - f2;
+ }
rettv->v_type = VAR_FLOAT;
rettv->vval.v_float = f1;
} else {
- if (op == '+')
+ if (op == '+') {
n1 = n1 + n2;
- else
+ } else {
n1 = n1 - n2;
+ }
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = n1;
}
@@ -3876,8 +3900,9 @@ static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string)
/*
* Get the first variable.
*/
- if (eval7(arg, rettv, evaluate, want_string) == FAIL)
+ if (eval7(arg, rettv, evaluate, want_string) == FAIL) {
return FAIL;
+ }
/*
* Repeat computing, until no '*', '/' or '%' is following.
@@ -3908,8 +3933,9 @@ static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string)
* Get the second variable.
*/
*arg = skipwhite(*arg + 1);
- if (eval7(arg, &var2, evaluate, FALSE) == FAIL)
+ if (eval7(arg, &var2, evaluate, FALSE) == FAIL) {
return FAIL;
+ }
if (evaluate) {
if (var2.v_type == VAR_FLOAT) {
@@ -3942,15 +3968,15 @@ static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string)
f1 = (f2 == 0
? (
#ifdef NAN
- f1 == 0
+ f1 == 0
? NAN
:
#endif
- (f1 > 0
+ (f1 > 0
? INFINITY
: -INFINITY)
- )
- : f1 / f2);
+ )
+ : f1 / f2);
} else {
EMSG(_("E804: Cannot use '%' with Float"));
return FAIL;
@@ -3976,39 +4002,36 @@ static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string)
// TODO(ZyX-I): move to eval/expressions
-// Handle sixth level expression:
-// number number constant
-// 0zFFFFFFFF Blob constant
-// "string" string constant
-// 'string' literal string constant
-// &option-name option value
-// @r register contents
-// identifier variable value
-// function() function call
-// $VAR environment variable
-// (expression) nested expression
-// [expr, expr] List
-// {key: val, key: val} Dictionary
-// #{key: val, key: val} Dictionary with literal keys
-//
-// Also handle:
-// ! in front logical NOT
-// - in front unary minus
-// + in front unary plus (ignored)
-// trailing [] subscript in String or List
-// trailing .name entry in Dictionary
-// trailing ->name() method call
-//
-// "arg" must point to the first non-white of the expression.
-// "arg" is advanced to the next non-white after the recognized expression.
-//
-// Return OK or FAIL.
-static int eval7(
- char_u **arg,
- typval_T *rettv,
- int evaluate,
- int want_string // after "." operator
-)
+/// Handle sixth level expression:
+/// number number constant
+/// 0zFFFFFFFF Blob constant
+/// "string" string constant
+/// 'string' literal string constant
+/// &option-name option value
+/// @r register contents
+/// identifier variable value
+/// function() function call
+/// $VAR environment variable
+/// (expression) nested expression
+/// [expr, expr] List
+/// {key: val, key: val} Dictionary
+/// #{key: val, key: val} Dictionary with literal keys
+///
+/// Also handle:
+/// ! in front logical NOT
+/// - in front unary minus
+/// + in front unary plus (ignored)
+/// trailing [] subscript in String or List
+/// trailing .name entry in Dictionary
+/// trailing ->name() method call
+///
+/// "arg" must point to the first non-white of the expression.
+/// "arg" is advanced to the next non-white after the recognized expression.
+///
+/// @param want_string after "." operator
+///
+/// @return OK or FAIL.
+static int eval7(char_u **arg, typval_T *rettv, int evaluate, int want_string)
{
varnumber_T n;
int len;
@@ -4039,8 +4062,7 @@ static int eval7(
case '6':
case '7':
case '8':
- case '9':
- {
+ case '9': {
char_u *p = skipdigits(*arg + 1);
int get_float = false;
@@ -4070,7 +4092,7 @@ static int eval7(
if (get_float) {
float_T f;
- *arg += string2float((char *) *arg, &f);
+ *arg += string2float((char *)*arg, &f);
if (evaluate) {
rettv->v_type = VAR_FLOAT;
rettv->vval.v_float = f;
@@ -4122,15 +4144,18 @@ static int eval7(
}
// String constant: "string".
- case '"': ret = get_string_tv(arg, rettv, evaluate);
+ case '"':
+ ret = get_string_tv(arg, rettv, evaluate);
break;
// Literal string constant: 'str''ing'.
- case '\'': ret = get_lit_string_tv(arg, rettv, evaluate);
+ case '\'':
+ ret = get_lit_string_tv(arg, rettv, evaluate);
break;
// List: [expr, expr]
- case '[': ret = get_list_tv(arg, rettv, evaluate);
+ case '[':
+ ret = get_list_tv(arg, rettv, evaluate);
break;
// Dictionary: #{key: val, key: val}
@@ -4145,23 +4170,25 @@ static int eval7(
// Lambda: {arg, arg -> expr}
// Dictionary: {'key': val, 'key': val}
- case '{': ret = get_lambda_tv(arg, rettv, evaluate);
- if (ret == NOTDONE) {
- ret = dict_get_tv(arg, rettv, evaluate, false);
- }
+ case '{':
+ ret = get_lambda_tv(arg, rettv, evaluate);
+ if (ret == NOTDONE) {
+ ret = dict_get_tv(arg, rettv, evaluate, false);
+ }
break;
// Option value: &name
- case '&': {
+ case '&':
ret = get_option_tv((const char **)arg, rettv, evaluate);
break;
- }
// Environment variable: $VAR.
- case '$': ret = get_env_tv(arg, rettv, evaluate);
+ case '$':
+ ret = get_env_tv(arg, rettv, evaluate);
break;
// Register contents: @r.
- case '@': ++*arg;
+ case '@':
+ ++*arg;
if (evaluate) {
rettv->v_type = VAR_STRING;
rettv->vval.v_string = get_reg_contents(**arg, kGRegExprSrc);
@@ -4172,7 +4199,8 @@ static int eval7(
break;
// nested expression: (expression).
- case '(': *arg = skipwhite(*arg + 1);
+ case '(':
+ *arg = skipwhite(*arg + 1);
ret = eval1(arg, rettv, evaluate); // recursive!
if (**arg == ')') {
++*arg;
@@ -4183,7 +4211,8 @@ static int eval7(
}
break;
- default: ret = NOTDONE;
+ default:
+ ret = NOTDONE;
break;
}
@@ -4284,11 +4313,8 @@ static int eval7_leader(typval_T *const rettv, const char_u *const start_leader,
/// to the name of the Lua function to call (after the
/// "v:lua." prefix).
/// @return OK on success, FAIL on failure.
-static int call_func_rettv(char_u **const arg,
- typval_T *const rettv,
- const bool evaluate,
- dict_T *const selfdict,
- typval_T *const basetv,
+static int call_func_rettv(char_u **const arg, typval_T *const rettv, const bool evaluate,
+ dict_T *const selfdict, typval_T *const basetv,
const char_u *const lua_funcname)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
@@ -4322,7 +4348,7 @@ static int call_func_rettv(char_u **const arg,
funcexe.selfdict = selfdict;
funcexe.basetv = basetv;
const int ret = get_func_tv(funcname, is_lua ? *arg - funcname : -1, rettv,
- (char_u **)arg, &funcexe);
+ arg, &funcexe);
// Clear the funcref afterwards, so that deleting it while
// evaluating the arguments is possible (see test55).
@@ -4337,8 +4363,8 @@ static int call_func_rettv(char_u **const arg,
/// @param verbose if true, give error messages.
/// @note "*arg" points to the '-'.
/// @return FAIL or OK. @note "*arg" is advanced to after the ')'.
-static int eval_lambda(char_u **const arg, typval_T *const rettv,
- const bool evaluate, const bool verbose)
+static int eval_lambda(char_u **const arg, typval_T *const rettv, const bool evaluate,
+ const bool verbose)
FUNC_ATTR_NONNULL_ALL
{
// Skip over the ->.
@@ -4375,8 +4401,8 @@ static int eval_lambda(char_u **const arg, typval_T *const rettv,
/// Evaluate "->method()" or "->v:lua.method()".
/// @note "*arg" points to the '-'.
/// @return FAIL or OK. "*arg" is advanced to after the ')'.
-static int eval_method(char_u **const arg, typval_T *const rettv,
- const bool evaluate, const bool verbose)
+static int eval_method(char_u **const arg, typval_T *const rettv, const bool evaluate,
+ const bool verbose)
FUNC_ATTR_NONNULL_ALL
{
// Skip over the ->.
@@ -4445,60 +4471,49 @@ static int eval_method(char_u **const arg, typval_T *const rettv,
// TODO(ZyX-I): move to eval/expressions
-/*
- * Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key".
- * "*arg" points to the '[' or '.'.
- * Returns FAIL or OK. "*arg" is advanced to after the ']'.
- */
-static int
-eval_index(
- char_u **arg,
- typval_T *rettv,
- int evaluate,
- int verbose // give error messages
-)
+/// Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key".
+/// "*arg" points to the '[' or '.'.
+/// Returns FAIL or OK. "*arg" is advanced to after the ']'.
+///
+/// @param verbose give error messages
+static int eval_index(char_u **arg, typval_T *rettv, int evaluate, int verbose)
{
bool empty1 = false;
bool empty2 = false;
long n1, n2 = 0;
ptrdiff_t len = -1;
int range = false;
- char_u *key = NULL;
+ char_u *key = NULL;
switch (rettv->v_type) {
- case VAR_FUNC:
- case VAR_PARTIAL: {
- if (verbose) {
- EMSG(_("E695: Cannot index a Funcref"));
- }
- return FAIL;
- }
- case VAR_FLOAT: {
- if (verbose) {
- EMSG(_(e_float_as_string));
- }
- return FAIL;
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ if (verbose) {
+ EMSG(_("E695: Cannot index a Funcref"));
}
- case VAR_BOOL:
- case VAR_SPECIAL: {
- if (verbose) {
- EMSG(_("E909: Cannot index a special variable"));
- }
- return FAIL;
+ return FAIL;
+ case VAR_FLOAT:
+ if (verbose) {
+ EMSG(_(e_float_as_string));
}
- case VAR_UNKNOWN: {
- if (evaluate) {
- return FAIL;
- }
- FALLTHROUGH;
+ return FAIL;
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ if (verbose) {
+ EMSG(_("E909: Cannot index a special variable"));
}
- case VAR_STRING:
- case VAR_NUMBER:
- case VAR_LIST:
- case VAR_DICT:
- case VAR_BLOB: {
- break;
+ return FAIL;
+ case VAR_UNKNOWN:
+ if (evaluate) {
+ return FAIL;
}
+ FALLTHROUGH;
+ case VAR_STRING:
+ case VAR_NUMBER:
+ case VAR_LIST:
+ case VAR_DICT:
+ case VAR_BLOB:
+ break;
}
typval_T var1 = TV_INITIAL_VALUE;
@@ -4508,10 +4523,12 @@ eval_index(
* dict.name
*/
key = *arg + 1;
- for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len)
+ for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) {
;
- if (len == 0)
+ }
+ if (len == 0) {
return FAIL;
+ }
*arg = skipwhite(key + len);
} else {
/*
@@ -4583,180 +4600,177 @@ eval_index(
}
switch (rettv->v_type) {
- case VAR_NUMBER:
- case VAR_STRING: {
- const char *const s = tv_get_string(rettv);
- char *v;
- len = (ptrdiff_t)strlen(s);
- if (range) {
- // The resulting variable is a substring. If the indexes
- // are out of range the result is empty.
+ case VAR_NUMBER:
+ case VAR_STRING: {
+ const char *const s = tv_get_string(rettv);
+ char *v;
+ len = (ptrdiff_t)strlen(s);
+ if (range) {
+ // The resulting variable is a substring. If the indexes
+ // are out of range the result is empty.
+ if (n1 < 0) {
+ n1 = len + n1;
if (n1 < 0) {
- n1 = len + n1;
- if (n1 < 0) {
- n1 = 0;
- }
- }
- if (n2 < 0) {
- n2 = len + n2;
- } else if (n2 >= len) {
- n2 = len;
- }
- if (n1 >= len || n2 < 0 || n1 > n2) {
- v = NULL;
- } else {
- v = xmemdupz(s + n1, (size_t)(n2 - n1 + 1));
+ n1 = 0;
}
+ }
+ if (n2 < 0) {
+ n2 = len + n2;
+ } else if (n2 >= len) {
+ n2 = len;
+ }
+ if (n1 >= len || n2 < 0 || n1 > n2) {
+ v = NULL;
} else {
- // The resulting variable is a string of a single
- // character. If the index is too big or negative the
- // result is empty.
- if (n1 >= len || n1 < 0) {
- v = NULL;
- } else {
- v = xmemdupz(s + n1, 1);
- }
+ v = xmemdupz(s + n1, (size_t)(n2 - n1 + 1));
+ }
+ } else {
+ // The resulting variable is a string of a single
+ // character. If the index is too big or negative the
+ // result is empty.
+ if (n1 >= len || n1 < 0) {
+ v = NULL;
+ } else {
+ v = xmemdupz(s + n1, 1);
}
- tv_clear(rettv);
- rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)v;
- break;
}
- case VAR_BLOB: {
- len = tv_blob_len(rettv->vval.v_blob);
- if (range) {
- // The resulting variable is a sub-blob. If the indexes
- // are out of range the result is empty.
+ tv_clear(rettv);
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = (char_u *)v;
+ break;
+ }
+ case VAR_BLOB:
+ len = tv_blob_len(rettv->vval.v_blob);
+ if (range) {
+ // The resulting variable is a sub-blob. If the indexes
+ // are out of range the result is empty.
+ if (n1 < 0) {
+ n1 = len + n1;
if (n1 < 0) {
- n1 = len + n1;
- if (n1 < 0) {
- n1 = 0;
- }
- }
- if (n2 < 0) {
- n2 = len + n2;
- } else if (n2 >= len) {
- n2 = len - 1;
- }
- if (n1 >= len || n2 < 0 || n1 > n2) {
- tv_clear(rettv);
- rettv->v_type = VAR_BLOB;
- rettv->vval.v_blob = NULL;
- } else {
- blob_T *const blob = tv_blob_alloc();
- ga_grow(&blob->bv_ga, n2 - n1 + 1);
- blob->bv_ga.ga_len = n2 - n1 + 1;
- for (long i = n1; i <= n2; i++) {
- tv_blob_set(blob, i - n1, tv_blob_get(rettv->vval.v_blob, i));
- }
- tv_clear(rettv);
- tv_blob_set_ret(rettv, blob);
+ n1 = 0;
}
+ }
+ if (n2 < 0) {
+ n2 = len + n2;
+ } else if (n2 >= len) {
+ n2 = len - 1;
+ }
+ if (n1 >= len || n2 < 0 || n1 > n2) {
+ tv_clear(rettv);
+ rettv->v_type = VAR_BLOB;
+ rettv->vval.v_blob = NULL;
} else {
- // The resulting variable is a byte value.
- // If the index is too big or negative that is an error.
- if (n1 < 0) {
- n1 = len + n1;
- }
- if (n1 < len && n1 >= 0) {
- const int v = (int)tv_blob_get(rettv->vval.v_blob, n1);
- tv_clear(rettv);
- rettv->v_type = VAR_NUMBER;
- rettv->vval.v_number = v;
- } else {
- EMSGN(_(e_blobidx), n1);
+ blob_T *const blob = tv_blob_alloc();
+ ga_grow(&blob->bv_ga, n2 - n1 + 1);
+ blob->bv_ga.ga_len = n2 - n1 + 1;
+ for (long i = n1; i <= n2; i++) {
+ tv_blob_set(blob, i - n1, tv_blob_get(rettv->vval.v_blob, i));
}
+ tv_clear(rettv);
+ tv_blob_set_ret(rettv, blob);
}
- break;
- }
- case VAR_LIST: {
- len = tv_list_len(rettv->vval.v_list);
+ } else {
+ // The resulting variable is a byte value.
+ // If the index is too big or negative that is an error.
if (n1 < 0) {
n1 = len + n1;
}
- if (!empty1 && (n1 < 0 || n1 >= len)) {
- // For a range we allow invalid values and return an empty
- // list. A list index out of range is an error.
- if (!range) {
- if (verbose) {
- EMSGN(_(e_listidx), n1);
- }
- return FAIL;
- }
- n1 = len;
- }
- if (range) {
- list_T *l;
- listitem_T *item;
-
- if (n2 < 0) {
- n2 = len + n2;
- } else if (n2 >= len) {
- n2 = len - 1;
- }
- if (!empty2 && (n2 < 0 || n2 + 1 < n1)) {
- n2 = -1;
- }
- l = tv_list_alloc(n2 - n1 + 1);
- item = tv_list_find(rettv->vval.v_list, n1);
- while (n1++ <= n2) {
- tv_list_append_tv(l, TV_LIST_ITEM_TV(item));
- item = TV_LIST_ITEM_NEXT(rettv->vval.v_list, item);
- }
+ if (n1 < len && n1 >= 0) {
+ const int v = (int)tv_blob_get(rettv->vval.v_blob, n1);
tv_clear(rettv);
- tv_list_set_ret(rettv, l);
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = v;
} else {
- tv_copy(TV_LIST_ITEM_TV(tv_list_find(rettv->vval.v_list, n1)), &var1);
- tv_clear(rettv);
- *rettv = var1;
+ EMSGN(_(e_blobidx), n1);
}
- break;
}
- case VAR_DICT: {
- if (range) {
+ break;
+ case VAR_LIST:
+ len = tv_list_len(rettv->vval.v_list);
+ if (n1 < 0) {
+ n1 = len + n1;
+ }
+ if (!empty1 && (n1 < 0 || n1 >= len)) {
+ // For a range we allow invalid values and return an empty
+ // list. A list index out of range is an error.
+ if (!range) {
if (verbose) {
- EMSG(_(e_dictrange));
- }
- if (len == -1) {
- tv_clear(&var1);
+ EMSGN(_(e_listidx), n1);
}
return FAIL;
}
+ n1 = len;
+ }
+ if (range) {
+ list_T *l;
+ listitem_T *item;
- if (len == -1) {
- key = (char_u *)tv_get_string_chk(&var1);
- if (key == NULL) {
- tv_clear(&var1);
- return FAIL;
- }
+ if (n2 < 0) {
+ n2 = len + n2;
+ } else if (n2 >= len) {
+ n2 = len - 1;
}
-
- dictitem_T *const item = tv_dict_find(rettv->vval.v_dict,
- (const char *)key, len);
-
- if (item == NULL && verbose) {
- emsgf(_(e_dictkey), key);
+ if (!empty2 && (n2 < 0 || n2 + 1 < n1)) {
+ n2 = -1;
+ }
+ l = tv_list_alloc(n2 - n1 + 1);
+ item = tv_list_find(rettv->vval.v_list, n1);
+ while (n1++ <= n2) {
+ tv_list_append_tv(l, TV_LIST_ITEM_TV(item));
+ item = TV_LIST_ITEM_NEXT(rettv->vval.v_list, item);
+ }
+ tv_clear(rettv);
+ tv_list_set_ret(rettv, l);
+ } else {
+ tv_copy(TV_LIST_ITEM_TV(tv_list_find(rettv->vval.v_list, n1)), &var1);
+ tv_clear(rettv);
+ *rettv = var1;
+ }
+ break;
+ case VAR_DICT: {
+ if (range) {
+ if (verbose) {
+ EMSG(_(e_dictrange));
}
if (len == -1) {
tv_clear(&var1);
}
- if (item == NULL || tv_is_luafunc(&item->di_tv)) {
+ return FAIL;
+ }
+
+ if (len == -1) {
+ key = (char_u *)tv_get_string_chk(&var1);
+ if (key == NULL) {
+ tv_clear(&var1);
return FAIL;
}
+ }
- tv_copy(&item->di_tv, &var1);
- tv_clear(rettv);
- *rettv = var1;
- break;
+ dictitem_T *const item = tv_dict_find(rettv->vval.v_dict,
+ (const char *)key, len);
+
+ if (item == NULL && verbose) {
+ emsgf(_(e_dictkey), key);
}
- case VAR_BOOL:
- case VAR_SPECIAL:
- case VAR_FUNC:
- case VAR_FLOAT:
- case VAR_PARTIAL:
- case VAR_UNKNOWN: {
- break; // Not evaluating, skipping over subscript
+ if (len == -1) {
+ tv_clear(&var1);
+ }
+ if (item == NULL || tv_is_luafunc(&item->di_tv)) {
+ return FAIL;
}
+
+ tv_copy(&item->di_tv, &var1);
+ tv_clear(rettv);
+ *rettv = var1;
+ break;
+ }
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ case VAR_FUNC:
+ case VAR_FLOAT:
+ case VAR_PARTIAL:
+ case VAR_UNKNOWN:
+ break; // Not evaluating, skipping over subscript
}
}
@@ -4773,12 +4787,11 @@ eval_index(
/// @param[in] evaluate If not true, rettv is not populated.
///
/// @return OK or FAIL.
-int get_option_tv(const char **const arg, typval_T *const rettv,
- const bool evaluate)
+int get_option_tv(const char **const arg, typval_T *const rettv, const bool evaluate)
FUNC_ATTR_NONNULL_ARG(1)
{
long numval;
- char_u *stringval;
+ char_u *stringval;
int opt_type;
int c;
bool working = (**arg == '+'); // has("+option")
@@ -4809,7 +4822,7 @@ int get_option_tv(const char **const arg, typval_T *const rettv,
EMSG2(_("E113: Unknown option: %s"), *arg);
}
ret = FAIL;
- } else if (rettv != NULL) {
+ } else if (rettv != NULL) {
if (opt_type == -2) { // hidden string option
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
@@ -4823,8 +4836,9 @@ int get_option_tv(const char **const arg, typval_T *const rettv,
rettv->v_type = VAR_STRING;
rettv->vval.v_string = stringval;
}
- } else if (working && (opt_type == -2 || opt_type == -1))
+ } else if (working && (opt_type == -2 || opt_type == -1)) {
ret = FAIL;
+ }
*option_end = c; // put back for error messages
*arg = option_end;
@@ -4838,7 +4852,7 @@ int get_option_tv(const char **const arg, typval_T *const rettv,
*/
static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
{
- char_u *p;
+ char_u *p;
unsigned int extra = 0;
/*
@@ -4880,12 +4894,18 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
for (p = *arg + 1; *p != NUL && *p != '"'; ) {
if (*p == '\\') {
switch (*++p) {
- case 'b': *name++ = BS; ++p; break;
- case 'e': *name++ = ESC; ++p; break;
- case 'f': *name++ = FF; ++p; break;
- case 'n': *name++ = NL; ++p; break;
- case 'r': *name++ = CAR; ++p; break;
- case 't': *name++ = TAB; ++p; break;
+ case 'b':
+ *name++ = BS; ++p; break;
+ case 'e':
+ *name++ = ESC; ++p; break;
+ case 'f':
+ *name++ = FF; ++p; break;
+ case 'n':
+ *name++ = NL; ++p; break;
+ case 'r':
+ *name++ = CAR; ++p; break;
+ case 't':
+ *name++ = TAB; ++p; break;
case 'X': // hex: "\x1", "\x12"
case 'x':
@@ -4926,11 +4946,13 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
case '4':
case '5':
case '6':
- case '7': *name = *p++ - '0';
+ case '7':
+ *name = *p++ - '0';
if (*p >= '0' && *p <= '7') {
*name = (*name << 3) + *p++ - '0';
- if (*p >= '0' && *p <= '7')
+ if (*p >= '0' && *p <= '7') {
*name = (*name << 3) + *p++ - '0';
+ }
}
++name;
break;
@@ -4947,12 +4969,13 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
}
FALLTHROUGH;
- default: MB_COPY_CHAR(p, name);
+ default:
+ MB_COPY_CHAR(p, name);
break;
}
- } else
+ } else {
MB_COPY_CHAR(p, name);
-
+ }
}
*name = NUL;
if (*p != NUL) { // just in case
@@ -4969,8 +4992,8 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
*/
static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate)
{
- char_u *p;
- char_u *str;
+ char_u *p;
+ char_u *str;
int reduce = 0;
/*
@@ -4978,8 +5001,9 @@ static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate)
*/
for (p = *arg + 1; *p != NUL; MB_PTR_ADV(p)) {
if (*p == '\'') {
- if (p[1] != '\'')
+ if (p[1] != '\'') {
break;
+ }
++reduce;
++p;
}
@@ -5005,8 +5029,9 @@ static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate)
for (p = *arg + 1; *p != NUL; ) {
if (*p == '\'') {
- if (p[1] != '\'')
+ if (p[1] != '\'') {
break;
+ }
++p;
}
MB_COPY_CHAR(p, str);
@@ -5059,7 +5084,7 @@ void partial_unref(partial_T *pt)
/// Return OK or FAIL.
static int get_list_tv(char_u **arg, typval_T *rettv, int evaluate)
{
- list_T *l = NULL;
+ list_T *l = NULL;
if (evaluate) {
l = tv_list_alloc(kListLenShouldKnow);
@@ -5103,23 +5128,20 @@ failret:
return OK;
}
-bool func_equal(
- typval_T *tv1,
- typval_T *tv2,
- bool ic // ignore case
-) {
+/// @param ic ignore case
+bool func_equal(typval_T *tv1, typval_T *tv2, bool ic) {
char_u *s1, *s2;
dict_T *d1, *d2;
int a1, a2;
// empty and NULL function name considered the same
s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string
- : partial_name(tv1->vval.v_partial);
+ : partial_name(tv1->vval.v_partial);
if (s1 != NULL && *s1 == NUL) {
s1 = NULL;
}
s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string
- : partial_name(tv2->vval.v_partial);
+ : partial_name(tv2->vval.v_partial);
if (s2 != NULL && *s2 == NUL) {
s2 = NULL;
}
@@ -5180,9 +5202,9 @@ int get_copyID(void)
* are no longer used. But for composite items it's possible that it becomes
* unused while the reference count is > 0: When there is a recursive
* reference. Example:
- * :let l = [1, 2, 3]
- * :let d = {9: l}
- * :let l[1] = d
+ * :let l = [1, 2, 3]
+ * :let d = {9: l}
+ * :let l[1] = d
*
* Since this is quite unusual we handle this with garbage collection: every
* once in a while find out which lists and dicts are not referenced from any
@@ -5190,7 +5212,7 @@ int get_copyID(void)
*
* Here is a good reference text about garbage collection (refers to Python
* but it applies to all reference-counting mechanisms):
- * http://python.ca/nas/python/gc/
+ * http://python.ca/nas/python/gc/
*/
/// Do garbage collection for lists and dicts.
@@ -5366,8 +5388,7 @@ bool garbage_collect(bool testing)
// This may call us back recursively.
did_free = free_unref_funccal(copyID, testing) || did_free;
} else if (p_verbose > 0) {
- verb_msg(_(
- "Not enough memory to set references, garbage collection aborted!"));
+ verb_msg(_("Not enough memory to set references, garbage collection aborted!"));
}
#undef ABORTING
return did_free;
@@ -5461,8 +5482,7 @@ bool set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack)
// it is added to ht_stack, if it contains a list it is added to
// list_stack.
HASHTAB_ITER(cur_ht, hi, {
- abort = abort || set_ref_in_item(
- &TV_DICT_HI2DI(hi)->di_tv, copyID, &ht_stack, list_stack);
+ abort = abort || set_ref_in_item(&TV_DICT_HI2DI(hi)->di_tv, copyID, &ht_stack, list_stack);
});
}
@@ -5528,87 +5548,85 @@ bool set_ref_in_list(list_T *l, int copyID, ht_stack_T **ht_stack)
/// @param list_stack Used to add lists to be marked. Can be NULL.
///
/// @returns true if setting references failed somehow.
-bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack,
- list_stack_T **list_stack)
+bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack, list_stack_T **list_stack)
FUNC_ATTR_WARN_UNUSED_RESULT
{
bool abort = false;
switch (tv->v_type) {
- case VAR_DICT: {
- dict_T *dd = tv->vval.v_dict;
- if (dd != NULL && dd->dv_copyID != copyID) {
- // Didn't see this dict yet.
- dd->dv_copyID = copyID;
- if (ht_stack == NULL) {
- abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
- } else {
- ht_stack_T *const newitem = xmalloc(sizeof(ht_stack_T));
- newitem->ht = &dd->dv_hashtab;
- newitem->prev = *ht_stack;
- *ht_stack = newitem;
- }
+ case VAR_DICT: {
+ dict_T *dd = tv->vval.v_dict;
+ if (dd != NULL && dd->dv_copyID != copyID) {
+ // Didn't see this dict yet.
+ dd->dv_copyID = copyID;
+ if (ht_stack == NULL) {
+ abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
+ } else {
+ ht_stack_T *const newitem = xmalloc(sizeof(ht_stack_T));
+ newitem->ht = &dd->dv_hashtab;
+ newitem->prev = *ht_stack;
+ *ht_stack = newitem;
+ }
- QUEUE *w = NULL;
- DictWatcher *watcher = NULL;
- QUEUE_FOREACH(w, &dd->watchers, {
+ QUEUE *w = NULL;
+ DictWatcher *watcher = NULL;
+ QUEUE_FOREACH(w, &dd->watchers, {
watcher = tv_dict_watcher_node_data(w);
set_ref_in_callback(&watcher->callback, copyID, ht_stack, list_stack);
})
- }
- break;
}
+ break;
+ }
- case VAR_LIST: {
- list_T *ll = tv->vval.v_list;
- if (ll != NULL && ll->lv_copyID != copyID) {
- // Didn't see this list yet.
- ll->lv_copyID = copyID;
- if (list_stack == NULL) {
- abort = set_ref_in_list(ll, copyID, ht_stack);
- } else {
- list_stack_T *const newitem = xmalloc(sizeof(list_stack_T));
- newitem->list = ll;
- newitem->prev = *list_stack;
- *list_stack = newitem;
- }
+ case VAR_LIST: {
+ list_T *ll = tv->vval.v_list;
+ if (ll != NULL && ll->lv_copyID != copyID) {
+ // Didn't see this list yet.
+ ll->lv_copyID = copyID;
+ if (list_stack == NULL) {
+ abort = set_ref_in_list(ll, copyID, ht_stack);
+ } else {
+ list_stack_T *const newitem = xmalloc(sizeof(list_stack_T));
+ newitem->list = ll;
+ newitem->prev = *list_stack;
+ *list_stack = newitem;
}
- break;
}
+ break;
+ }
- case VAR_PARTIAL: {
- partial_T *pt = tv->vval.v_partial;
+ case VAR_PARTIAL: {
+ partial_T *pt = tv->vval.v_partial;
- // A partial does not have a copyID, because it cannot contain itself.
- if (pt != NULL) {
- abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID);
- if (pt->pt_dict != NULL) {
- typval_T dtv;
+ // A partial does not have a copyID, because it cannot contain itself.
+ if (pt != NULL) {
+ abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID);
+ if (pt->pt_dict != NULL) {
+ typval_T dtv;
- dtv.v_type = VAR_DICT;
- dtv.vval.v_dict = pt->pt_dict;
- abort = abort || set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
- }
+ dtv.v_type = VAR_DICT;
+ dtv.vval.v_dict = pt->pt_dict;
+ abort = abort || set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
+ }
- for (int i = 0; i < pt->pt_argc; i++) {
- abort = abort || set_ref_in_item(&pt->pt_argv[i], copyID,
- ht_stack, list_stack);
- }
+ for (int i = 0; i < pt->pt_argc; i++) {
+ abort = abort || set_ref_in_item(&pt->pt_argv[i], copyID,
+ ht_stack, list_stack);
}
- break;
- }
- case VAR_FUNC:
- abort = set_ref_in_func(tv->vval.v_string, NULL, copyID);
- break;
- case VAR_UNKNOWN:
- case VAR_BOOL:
- case VAR_SPECIAL:
- case VAR_FLOAT:
- case VAR_NUMBER:
- case VAR_STRING:
- case VAR_BLOB: {
- break;
}
+ break;
+ }
+ case VAR_FUNC:
+ abort = set_ref_in_func(tv->vval.v_string, NULL, copyID);
+ break;
+ case VAR_UNKNOWN:
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ case VAR_FLOAT:
+ case VAR_NUMBER:
+ case VAR_STRING:
+ case VAR_BLOB:
+ break;
}
return abort;
}
@@ -5684,15 +5702,14 @@ static int get_literal_key(char_u **arg, typval_T *tv)
// Allocate a variable for a Dictionary and fill it from "*arg".
// "literal" is true for *{key: val}
// Return OK or FAIL. Returns NOTDONE for {expr}.
-static int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate,
- bool literal)
+static int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate, bool literal)
{
- dict_T *d = NULL;
+ dict_T *d = NULL;
typval_T tvkey;
typval_T tv;
- char_u *key = NULL;
- dictitem_T *item;
- char_u *start = skipwhite(*arg + 1);
+ char_u *key = NULL;
+ dictitem_T *item;
+ char_u *start = skipwhite(*arg + 1);
char buf[NUMBUFLEN];
/*
@@ -5762,8 +5779,9 @@ static int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate,
}
tv_clear(&tvkey);
- if (**arg == '}')
+ if (**arg == '}') {
break;
+ }
if (**arg != ',') {
EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg);
goto failret;
@@ -5816,7 +5834,7 @@ size_t string2float(const char *const text, float_T *const ret_value)
return 3;
}
*ret_value = strtod(text, &s);
- return (size_t) (s - text);
+ return (size_t)(s - text);
}
/// Get the value of an environment variable.
@@ -5830,8 +5848,8 @@ static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate)
{
char_u *name;
char_u *string = NULL;
- int len;
- int cc;
+ int len;
+ int cc;
++*arg;
name = *arg;
@@ -5863,8 +5881,7 @@ static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate)
}
/// Get the argument list for a given window
-void get_arglist_as_rettv(aentry_T *arglist, int argcount,
- typval_T *rettv)
+void get_arglist_as_rettv(aentry_T *arglist, int argcount, typval_T *rettv)
{
tv_list_alloc_ret(rettv, argcount);
if (arglist != NULL) {
@@ -5882,17 +5899,17 @@ void prepare_assert_error(garray_T *gap)
ga_init(gap, 1, 100);
if (sourcing_name != NULL) {
- ga_concat(gap, sourcing_name);
+ ga_concat(gap, (char *)sourcing_name);
if (sourcing_lnum > 0) {
- ga_concat(gap, (char_u *)" ");
+ ga_concat(gap, " ");
}
}
if (sourcing_lnum > 0) {
vim_snprintf(buf, ARRAY_SIZE(buf), "line %" PRId64, (int64_t)sourcing_lnum);
- ga_concat(gap, (char_u *)buf);
+ ga_concat(gap, buf);
}
if (sourcing_name != NULL || sourcing_lnum > 0) {
- ga_concat(gap, (char_u *)": ");
+ ga_concat(gap, ": ");
}
}
@@ -5906,24 +5923,31 @@ static void ga_concat_esc(garray_T *gap, const char_u *p, int clen)
if (clen > 1) {
memmove(buf, p, clen);
buf[clen] = NUL;
- ga_concat(gap, buf);
+ ga_concat(gap, (char *)buf);
} else {
switch (*p) {
- case BS: ga_concat(gap, (char_u *)"\\b"); break;
- case ESC: ga_concat(gap, (char_u *)"\\e"); break;
- case FF: ga_concat(gap, (char_u *)"\\f"); break;
- case NL: ga_concat(gap, (char_u *)"\\n"); break;
- case TAB: ga_concat(gap, (char_u *)"\\t"); break;
- case CAR: ga_concat(gap, (char_u *)"\\r"); break;
- case '\\': ga_concat(gap, (char_u *)"\\\\"); break;
- default:
- if (*p < ' ') {
- vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p);
- ga_concat(gap, buf);
- } else {
- ga_append(gap, *p);
- }
- break;
+ case BS:
+ ga_concat(gap, "\\b"); break;
+ case ESC:
+ ga_concat(gap, "\\e"); break;
+ case FF:
+ ga_concat(gap, "\\f"); break;
+ case NL:
+ ga_concat(gap, "\\n"); break;
+ case TAB:
+ ga_concat(gap, "\\t"); break;
+ case CAR:
+ ga_concat(gap, "\\r"); break;
+ case '\\':
+ ga_concat(gap, "\\\\"); break;
+ default:
+ if (*p < ' ') {
+ vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p);
+ ga_concat(gap, (char *)buf);
+ } else {
+ ga_append(gap, *p);
+ }
+ break;
}
}
}
@@ -5936,7 +5960,7 @@ static void ga_concat_shorten_esc(garray_T *gap, const char_u *str)
char_u buf[NUMBUFLEN];
if (str == NULL) {
- ga_concat(gap, (char_u *)"NULL");
+ ga_concat(gap, "NULL");
return;
}
@@ -5950,12 +5974,12 @@ static void ga_concat_shorten_esc(garray_T *gap, const char_u *str)
s += clen;
}
if (same_len > 20) {
- ga_concat(gap, (char_u *)"\\[");
+ ga_concat(gap, "\\[");
ga_concat_esc(gap, p, clen);
- ga_concat(gap, (char_u *)" occurs ");
+ ga_concat(gap, " occurs ");
vim_snprintf((char *)buf, NUMBUFLEN, "%d", same_len);
- ga_concat(gap, buf);
- ga_concat(gap, (char_u *)" times]");
+ ga_concat(gap, (char *)buf);
+ ga_concat(gap, " times]");
p = s - 1;
} else {
ga_concat_esc(gap, p, clen);
@@ -5964,25 +5988,24 @@ static void ga_concat_shorten_esc(garray_T *gap, const char_u *str)
}
// Fill "gap" with information about an assert error.
-void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv,
- char_u *exp_str, typval_T *exp_tv,
+void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, char_u *exp_str, typval_T *exp_tv,
typval_T *got_tv, assert_type_T atype)
{
char_u *tofree;
if (opt_msg_tv->v_type != VAR_UNKNOWN) {
tofree = (char_u *)encode_tv2echo(opt_msg_tv, NULL);
- ga_concat(gap, tofree);
+ ga_concat(gap, (char *)tofree);
xfree(tofree);
- ga_concat(gap, (char_u *)": ");
+ ga_concat(gap, ": ");
}
if (atype == ASSERT_MATCH || atype == ASSERT_NOTMATCH) {
- ga_concat(gap, (char_u *)"Pattern ");
+ ga_concat(gap, "Pattern ");
} else if (atype == ASSERT_NOTEQUAL) {
- ga_concat(gap, (char_u *)"Expected not equal to ");
+ ga_concat(gap, "Expected not equal to ");
} else {
- ga_concat(gap, (char_u *)"Expected ");
+ ga_concat(gap, "Expected ");
}
if (exp_str == NULL) {
@@ -5995,11 +6018,11 @@ void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv,
if (atype != ASSERT_NOTEQUAL) {
if (atype == ASSERT_MATCH) {
- ga_concat(gap, (char_u *)" does not match ");
+ ga_concat(gap, " does not match ");
} else if (atype == ASSERT_NOTMATCH) {
- ga_concat(gap, (char_u *)" does match ");
+ ga_concat(gap, " does match ");
} else {
- ga_concat(gap, (char_u *)" but got ");
+ ga_concat(gap, " but got ");
}
tofree = (char_u *)encode_tv2string(got_tv, NULL);
ga_concat_shorten_esc(gap, tofree);
@@ -6103,21 +6126,21 @@ int assert_equalfile(typval_T *argvars)
prepare_assert_error(&ga);
if (argvars[2].v_type != VAR_UNKNOWN) {
char *const tofree = encode_tv2echo(&argvars[2], NULL);
- ga_concat(&ga, (char_u *)tofree);
+ ga_concat(&ga, tofree);
xfree(tofree);
- ga_concat(&ga, (char_u *)": ");
+ ga_concat(&ga, ": ");
}
- ga_concat(&ga, IObuff);
+ ga_concat(&ga, (char *)IObuff);
if (lineidx > 0) {
line1[lineidx] = NUL;
line2[lineidx] = NUL;
- ga_concat(&ga, (char_u *)" after \"");
- ga_concat(&ga, (char_u *)line1);
+ ga_concat(&ga, " after \"");
+ ga_concat(&ga, line1);
if (STRCMP(line1, line2) != 0) {
- ga_concat(&ga, (char_u *)"\" vs \"");
- ga_concat(&ga, (char_u *)line2);
+ ga_concat(&ga, "\" vs \"");
+ ga_concat(&ga, line2);
}
- ga_concat(&ga, (char_u *)"\"");
+ ga_concat(&ga, "\"");
}
assert_error(&ga);
ga_clear(&ga);
@@ -6143,13 +6166,13 @@ int assert_inrange(typval_T *argvars)
prepare_assert_error(&ga);
if (argvars[3].v_type != VAR_UNKNOWN) {
char_u *const tofree = (char_u *)encode_tv2string(&argvars[3], NULL);
- ga_concat(&ga, tofree);
+ ga_concat(&ga, (char *)tofree);
xfree(tofree);
} else {
char msg[80];
vim_snprintf(msg, sizeof(msg), "Expected range %g - %g, but got %g",
flower, fupper, factual);
- ga_concat(&ga, (char_u *)msg);
+ ga_concat(&ga, msg);
}
assert_error(&ga);
ga_clear(&ga);
@@ -6170,7 +6193,7 @@ int assert_inrange(typval_T *argvars)
char msg[55];
vim_snprintf(msg, sizeof(msg),
"range %" PRIdVARNUMBER " - %" PRIdVARNUMBER ",",
- lower, upper);
+ lower, upper); // -V576
fill_assert_error(&ga, &argvars[3], (char_u *)msg, NULL, &argvars[2],
ASSERT_INRANGE);
assert_error(&ga);
@@ -6215,7 +6238,7 @@ int assert_exception(typval_T *argvars)
const char *const error = tv_get_string_chk(&argvars[0]);
if (vimvars[VV_EXCEPTION].vv_str == NULL) {
prepare_assert_error(&ga);
- ga_concat(&ga, (char_u *)"v:exception is not set");
+ ga_concat(&ga, "v:exception is not set");
assert_error(&ga);
ga_clear(&ga);
return 1;
@@ -6231,16 +6254,15 @@ int assert_exception(typval_T *argvars)
return 0;
}
-static void assert_append_cmd_or_arg(garray_T *gap, typval_T *argvars,
- const char *cmd)
+static void assert_append_cmd_or_arg(garray_T *gap, typval_T *argvars, const char *cmd)
FUNC_ATTR_NONNULL_ALL
{
if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) {
char *const tofree = encode_tv2echo(&argvars[2], NULL);
- ga_concat(gap, (char_u *)tofree);
+ ga_concat(gap, tofree);
xfree(tofree);
} else {
- ga_concat(gap, (char_u *)cmd);
+ ga_concat(gap, cmd);
}
}
@@ -6258,11 +6280,11 @@ int assert_beeps(typval_T *argvars, bool no_beep)
garray_T ga;
prepare_assert_error(&ga);
if (no_beep) {
- ga_concat(&ga, (const char_u *)"command did beep: ");
+ ga_concat(&ga, "command did beep: ");
} else {
- ga_concat(&ga, (const char_u *)"command did not beep: ");
+ ga_concat(&ga, "command did not beep: ");
}
- ga_concat(&ga, (const char_u *)cmd);
+ ga_concat(&ga, cmd);
assert_error(&ga);
ga_clear(&ga);
ret = 1;
@@ -6277,9 +6299,9 @@ int assert_fails(typval_T *argvars)
FUNC_ATTR_NONNULL_ALL
{
const char *const cmd = tv_get_string_chk(&argvars[0]);
- garray_T ga;
+ garray_T ga;
int ret = 0;
- int save_trylevel = trylevel;
+ int save_trylevel = trylevel;
// trylevel must be zero for a ":throw" command to be considered failed
trylevel = 0;
@@ -6290,7 +6312,7 @@ int assert_fails(typval_T *argvars)
do_cmdline_cmd(cmd);
if (!called_emsg) {
prepare_assert_error(&ga);
- ga_concat(&ga, (const char_u *)"command did not fail: ");
+ ga_concat(&ga, "command did not fail: ");
assert_append_cmd_or_arg(&ga, argvars, cmd);
assert_error(&ga);
ga_clear(&ga);
@@ -6304,7 +6326,7 @@ int assert_fails(typval_T *argvars)
prepare_assert_error(&ga);
fill_assert_error(&ga, &argvars[2], NULL, &argvars[1],
&vimvars[VV_ERRMSG].vv_tv, ASSERT_OTHER);
- ga_concat(&ga, (char_u *)": ");
+ ga_concat(&ga, ": ");
assert_append_cmd_or_arg(&ga, argvars, cmd);
assert_error(&ga);
ga_clear(&ga);
@@ -6345,7 +6367,7 @@ int assert_match_common(typval_T *argvars, assert_type_T atype)
/// Find a window: When using a Window ID in any tab page, when using a number
/// in the current tab page.
-win_T * find_win_by_nr_or_id(typval_T *vp)
+win_T *find_win_by_nr_or_id(typval_T *vp)
{
int nr = (int)tv_get_number_chk(vp, NULL);
@@ -6361,12 +6383,12 @@ win_T * find_win_by_nr_or_id(typval_T *vp)
*/
void filter_map(typval_T *argvars, typval_T *rettv, int map)
{
- typval_T *expr;
- list_T *l = NULL;
- dictitem_T *di;
- hashtab_T *ht;
- hashitem_T *hi;
- dict_T *d = NULL;
+ typval_T *expr;
+ list_T *l = NULL;
+ dictitem_T *di;
+ hashtab_T *ht;
+ hashitem_T *hi;
+ dict_T *d = NULL;
typval_T save_val;
typval_T save_key;
blob_T *b = NULL;
@@ -6543,11 +6565,10 @@ theend:
return retval;
}
-void common_function(typval_T *argvars, typval_T *rettv,
- bool is_funcref, FunPtr fptr)
+void common_function(typval_T *argvars, typval_T *rettv, bool is_funcref, FunPtr fptr)
{
- char_u *s;
- char_u *name;
+ char_u *s;
+ char_u *name;
bool use_string = false;
partial_T *arg_pt = NULL;
char_u *trans_name = NULL;
@@ -6584,7 +6605,7 @@ void common_function(typval_T *argvars, typval_T *rettv,
// Don't check an autoload name for existence here.
} else if (trans_name != NULL
&& (is_funcref ? find_func(trans_name) == NULL
- : !translated_function_exists((const char *)trans_name))) {
+ : !translated_function_exists((const char *)trans_name))) {
emsgf(_("E700: Unknown function: %s"), s);
} else {
int dict_idx = 0;
@@ -6760,8 +6781,7 @@ dict_T *get_buffer_info(buf_T *buf)
/// be NULL, in this case "$" results in zero return.
///
/// @return Line number or 0 in case of error.
-linenr_T tv_get_lnum_buf(const typval_T *const tv,
- const buf_T *const buf)
+linenr_T tv_get_lnum_buf(const typval_T *const tv, const buf_T *const buf)
FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT
{
if (tv->v_type == VAR_STRING
@@ -6773,8 +6793,7 @@ linenr_T tv_get_lnum_buf(const typval_T *const tv,
return tv_get_number_chk(tv, NULL);
}
-void get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg,
- typval_T *rettv)
+void get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg, typval_T *rettv)
{
if (what_arg->v_type == VAR_UNKNOWN) {
tv_list_alloc_ret(rettv, kListLenMayKnow);
@@ -6845,12 +6864,10 @@ dict_T *get_win_info(win_T *wp, int16_t tpnr, int16_t winnr)
return dict;
}
-// Find window specified by "vp" in tabpage "tp".
-win_T *
-find_win_by_nr(
- typval_T *vp,
- tabpage_T *tp // NULL for current tab page
-)
+/// Find window specified by "vp" in tabpage "tp".
+///
+/// @param tp NULL for current tab page
+win_T *find_win_by_nr(typval_T *vp, tabpage_T *tp)
{
int nr = (int)tv_get_number_chk(vp, NULL);
@@ -6864,7 +6881,7 @@ find_win_by_nr(
// This method accepts NULL as an alias for curtab.
if (tp == NULL) {
- tp = curtab;
+ tp = curtab;
}
FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
@@ -6905,15 +6922,10 @@ win_T *find_tabwin(typval_T *wvp, typval_T *tvp)
return wp;
}
-/*
- * getwinvar() and gettabwinvar()
- */
-void
-getwinvar(
- typval_T *argvars,
- typval_T *rettv,
- int off // 1 for gettabwinvar()
-)
+/// getwinvar() and gettabwinvar()
+///
+/// @param off 1 for gettabwinvar()
+void getwinvar(typval_T *argvars, typval_T *rettv, int off)
{
win_T *win, *oldcurwin;
dictitem_T *v;
@@ -6984,9 +6996,7 @@ getwinvar(
* prompt. The third argument to f_inputdialog() specifies the value to return
* when the user cancels the prompt.
*/
-void get_user_input(const typval_T *const argvars,
- typval_T *const rettv,
- const bool inputdialog,
+void get_user_input(const typval_T *const argvars, typval_T *const rettv, const bool inputdialog,
const bool secret)
FUNC_ATTR_NONNULL_ALL
{
@@ -7121,8 +7131,7 @@ void get_user_input(const typval_T *const argvars,
/// a dictionary, will give an error if not.
/// @param[out] rettv Location where result will be saved.
/// @param[in] what What to save in rettv.
-void dict_list(typval_T *const tv, typval_T *const rettv,
- const DictListType what)
+void dict_list(typval_T *const tv, typval_T *const rettv, const DictListType what)
{
if (tv->v_type != VAR_DICT) {
EMSG(_(e_dictreq));
@@ -7138,32 +7147,30 @@ void dict_list(typval_T *const tv, typval_T *const rettv,
typval_T tv_item = { .v_lock = VAR_UNLOCKED };
switch (what) {
- case kDictListKeys: {
- tv_item.v_type = VAR_STRING;
- tv_item.vval.v_string = vim_strsave(di->di_key);
- break;
- }
- case kDictListValues: {
- tv_copy(&di->di_tv, &tv_item);
- break;
- }
- case kDictListItems: {
- // items()
- list_T *const sub_l = tv_list_alloc(2);
- tv_item.v_type = VAR_LIST;
- tv_item.vval.v_list = sub_l;
- tv_list_ref(sub_l);
-
- tv_list_append_owned_tv(sub_l, (typval_T) {
+ case kDictListKeys:
+ tv_item.v_type = VAR_STRING;
+ tv_item.vval.v_string = vim_strsave(di->di_key);
+ break;
+ case kDictListValues:
+ tv_copy(&di->di_tv, &tv_item);
+ break;
+ case kDictListItems: {
+ // items()
+ list_T *const sub_l = tv_list_alloc(2);
+ tv_item.v_type = VAR_LIST;
+ tv_item.vval.v_list = sub_l;
+ tv_list_ref(sub_l);
+
+ tv_list_append_owned_tv(sub_l, (typval_T) {
.v_type = VAR_STRING,
.v_lock = VAR_UNLOCKED,
.vval.v_string = (char_u *)xstrdup((const char *)di->di_key),
});
- tv_list_append_tv(sub_l, &di->di_tv);
+ tv_list_append_tv(sub_l, &di->di_tv);
- break;
- }
+ break;
+ }
}
tv_list_append_owned_tv(rettv->vval.v_list, tv_item);
@@ -7244,9 +7251,7 @@ char **tv_to_argv(typval_T *cmd_tv, const char **cmd, bool *executable)
/// @param mp The maphash that contains the mapping information
/// @param buffer_value The "buffer" value
/// @param compatible True for compatible with old maparg() dict
-void mapblock_fill_dict(dict_T *const dict,
- const mapblock_T *const mp,
- long buffer_value,
+void mapblock_fill_dict(dict_T *const dict, const mapblock_T *const mp, long buffer_value,
bool compatible)
FUNC_ATTR_NONNULL_ALL
{
@@ -7284,8 +7289,7 @@ void mapblock_fill_dict(dict_T *const dict,
tv_dict_add_allocated_str(dict, S_LEN("mode"), mapmode);
}
-int matchadd_dict_arg(typval_T *tv, const char **conceal_char,
- win_T **win)
+int matchadd_dict_arg(typval_T *tv, const char **conceal_char, win_T **win)
{
dictitem_T *di;
@@ -7333,18 +7337,18 @@ void screenchar_adjust_grid(ScreenGrid **grid, int *row, int *col)
}
/// Set line or list of lines in buffer "buf".
-void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append,
- const typval_T *lines, typval_T *rettv)
+void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T *lines,
+ typval_T *rettv)
FUNC_ATTR_NONNULL_ARG(4, 5)
{
linenr_T lnum = lnum_arg + (append ? 1 : 0);
const char *line = NULL;
- list_T *l = NULL;
- listitem_T *li = NULL;
- long added = 0;
+ list_T *l = NULL;
+ listitem_T *li = NULL;
+ long added = 0;
linenr_T append_lnum;
- buf_T *curbuf_save = NULL;
- win_T *curwin_save = NULL;
+ buf_T *curbuf_save = NULL;
+ win_T *curwin_save = NULL;
const bool is_curbuf = buf == curbuf;
// When using the current buffer ml_mfp will be set if needed. Useful when
@@ -7444,8 +7448,8 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append,
}
if (!is_curbuf) {
- curbuf = curbuf_save;
- curwin = curwin_save;
+ curbuf = curbuf_save;
+ curwin = curwin_save;
}
}
@@ -7470,8 +7474,8 @@ void setwinvar(typval_T *argvars, typval_T *rettv, int off)
typval_T *varp = &argvars[off + 2];
if (win != NULL && varname != NULL && varp != NULL) {
- win_T *save_curwin;
- tabpage_T *save_curtab;
+ win_T *save_curwin;
+ tabpage_T *save_curtab;
bool need_switch_win = tp != curtab || win != curwin;
if (!need_switch_win
|| switch_win(&save_curwin, &save_curtab, win, tp, true) == OK) {
@@ -7539,8 +7543,7 @@ static list_T *string_to_list(const char *str, size_t len, const bool keepempty)
}
// os_system wrapper. Handles 'verbose', :profile, and v:shell_error.
-void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
- bool retlist)
+void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv, bool retlist)
{
proftime_T wait_time;
bool profiling = do_profiling == PROF_YES;
@@ -7595,14 +7598,14 @@ void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
xfree(input);
- set_vim_var_nr(VV_SHELL_ERROR, (long) status);
+ set_vim_var_nr(VV_SHELL_ERROR, (long)status);
if (res == NULL) {
if (retlist) {
// return an empty list when there's no output
tv_list_alloc_ret(rettv, 0);
} else {
- rettv->vval.v_string = (char_u *) xstrdup("");
+ rettv->vval.v_string = (char_u *)xstrdup("");
}
return;
}
@@ -7634,7 +7637,7 @@ void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
*d = NUL;
#endif
- rettv->vval.v_string = (char_u *) res;
+ rettv->vval.v_string = (char_u *)res;
}
}
@@ -7687,29 +7690,29 @@ bool callback_from_typval(Callback *const callback, typval_T *const arg)
return true;
}
-bool callback_call(Callback *const callback, const int argcount_in,
- typval_T *const argvars_in, typval_T *const rettv)
+bool callback_call(Callback *const callback, const int argcount_in, typval_T *const argvars_in,
+ typval_T *const rettv)
FUNC_ATTR_NONNULL_ALL
{
partial_T *partial;
char_u *name;
switch (callback->type) {
- case kCallbackFuncref:
- name = callback->data.funcref;
- partial = NULL;
- break;
+ case kCallbackFuncref:
+ name = callback->data.funcref;
+ partial = NULL;
+ break;
- case kCallbackPartial:
- partial = callback->data.partial;
- name = partial_name(partial);
- break;
+ case kCallbackPartial:
+ partial = callback->data.partial;
+ name = partial_name(partial);
+ break;
- case kCallbackNone:
- return false;
- break;
+ case kCallbackNone:
+ return false;
+ break;
- default:
- abort();
+ default:
+ abort();
}
funcexe_T funcexe = FUNCEXE_INIT;
@@ -7720,31 +7723,29 @@ bool callback_call(Callback *const callback, const int argcount_in,
return call_func(name, -1, rettv, argcount_in, argvars_in, &funcexe);
}
-static bool set_ref_in_callback(Callback *callback, int copyID,
- ht_stack_T **ht_stack,
+static bool set_ref_in_callback(Callback *callback, int copyID, ht_stack_T **ht_stack,
list_stack_T **list_stack)
{
typval_T tv;
switch (callback->type) {
- case kCallbackFuncref:
- case kCallbackNone:
- break;
+ case kCallbackFuncref:
+ case kCallbackNone:
+ break;
- case kCallbackPartial:
- tv.v_type = VAR_PARTIAL;
- tv.vval.v_partial = callback->data.partial;
- return set_ref_in_item(&tv, copyID, ht_stack, list_stack);
- break;
+ case kCallbackPartial:
+ tv.v_type = VAR_PARTIAL;
+ tv.vval.v_partial = callback->data.partial;
+ return set_ref_in_item(&tv, copyID, ht_stack, list_stack);
+ break;
- default:
- abort();
+ default:
+ abort();
}
return false;
}
-static bool set_ref_in_callback_reader(CallbackReader *reader, int copyID,
- ht_stack_T **ht_stack,
+static bool set_ref_in_callback_reader(CallbackReader *reader, int copyID, ht_stack_T **ht_stack,
list_stack_T **list_stack)
{
if (set_ref_in_callback(&reader->cb, copyID, ht_stack, list_stack)) {
@@ -7762,7 +7763,7 @@ static bool set_ref_in_callback_reader(CallbackReader *reader, int copyID,
timer_T *find_timer_by_nr(varnumber_T xx)
{
- return pmap_get(uint64_t)(&timers, xx);
+ return pmap_get(uint64_t)(&timers, xx);
}
void add_timer_info(typval_T *rettv, timer_T *timer)
@@ -7851,9 +7852,7 @@ void timer_due_cb(TimeWatcher *tw, void *data)
timer_decref(timer);
}
-uint64_t timer_start(const long timeout,
- const int repeat_count,
- const Callback *const callback)
+uint64_t timer_start(const long timeout, const int repeat_count, const Callback *const callback)
{
timer_T *timer = xmalloc(sizeof *timer);
timer->refcount = 1;
@@ -7924,8 +7923,7 @@ void timer_teardown(void)
/// @param[in] binary Whether to write in binary mode.
///
/// @return true in case of success, false otherwise.
-bool write_list(FileDescriptor *const fp, const list_T *const list,
- const bool binary)
+bool write_list(FileDescriptor *const fp, const list_T *const list, const bool binary)
FUNC_ATTR_NONNULL_ARG(1)
{
int error = 0;
@@ -8123,16 +8121,15 @@ char *save_tv_as_string(typval_T *tv, ptrdiff_t *const len, bool endnl)
/// @param[out] ret_fnum Set to fnum for marks.
///
/// @return Pointer to position or NULL in case of error (e.g. invalid type).
-pos_T *var2fpos(const typval_T *const tv, const bool dollar_lnum,
- int *const ret_fnum)
+pos_T *var2fpos(const typval_T *const tv, const bool dollar_lnum, int *const ret_fnum)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
static pos_T pos;
- pos_T *pp;
+ pos_T *pp;
// Argument can be [lnum, col, coladd].
if (tv->v_type == VAR_LIST) {
- list_T *l;
+ list_T *l;
int len;
bool error = false;
listitem_T *li;
@@ -8350,10 +8347,7 @@ int get_id_len(const char **const arg)
* If the name contains 'magic' {}'s, expand them and return the
* expanded name in an allocated string via 'alias' - caller must free.
*/
-int get_name_len(const char **const arg,
- char **alias,
- bool evaluate,
- bool verbose)
+int get_name_len(const char **const arg, char **alias, bool evaluate, bool verbose)
{
int len;
@@ -8372,8 +8366,8 @@ int get_name_len(const char **const arg,
}
// Find the end of the name; check for {} construction.
- char_u *expr_start;
- char_u *expr_end;
+ char_u *expr_start;
+ char_u *expr_end;
const char *p = (const char *)find_name_end((char_u *)(*arg),
(const char_u **)&expr_start,
(const char_u **)&expr_end,
@@ -8415,8 +8409,8 @@ int get_name_len(const char **const arg,
// "flags" can have FNE_INCL_BR and FNE_CHECK_START.
// Return a pointer to just after the name. Equal to "arg" if there is no
// valid name.
-const char_u *find_name_end(const char_u *arg, const char_u **expr_start,
- const char_u **expr_end, int flags)
+const char_u *find_name_end(const char_u *arg, const char_u **expr_start, const char_u **expr_end,
+ int flags)
{
int mb_nest = 0;
int br_nest = 0;
@@ -8497,24 +8491,25 @@ const char_u *find_name_end(const char_u *arg, const char_u **expr_start,
* Note that this can call itself recursively, to deal with
* constructs like foo{bar}{baz}{bam}
* The four pointer arguments point to "foo{expre}ss{ion}bar"
- * "in_start" ^
- * "expr_start" ^
- * "expr_end" ^
- * "in_end" ^
+ * "in_start" ^
+ * "expr_start" ^
+ * "expr_end" ^
+ * "in_end" ^
*
* Returns a new allocated string, which the caller must free.
* Returns NULL for failure.
*/
-static char_u *make_expanded_name(const char_u *in_start, char_u *expr_start,
- char_u *expr_end, char_u *in_end)
+static char_u *make_expanded_name(const char_u *in_start, char_u *expr_start, char_u *expr_end,
+ char_u *in_end)
{
char_u c1;
- char_u *retval = NULL;
- char_u *temp_result;
- char_u *nextcmd = NULL;
+ char_u *retval = NULL;
+ char_u *temp_result;
+ char_u *nextcmd = NULL;
- if (expr_end == NULL || in_end == NULL)
+ if (expr_end == NULL || in_end == NULL) {
return NULL;
+ }
*expr_start = NUL;
*expr_end = NUL;
c1 = *in_end;
@@ -8541,7 +8536,7 @@ static char_u *make_expanded_name(const char_u *in_start, char_u *expr_start,
if (expr_start != NULL) {
// Further expansion!
temp_result = make_expanded_name(retval, expr_start,
- expr_end, temp_result);
+ expr_end, temp_result);
xfree(retval);
retval = temp_result;
}
@@ -8617,8 +8612,9 @@ void set_vim_var_char(int c)
*/
void set_vcount(long count, long count1, int set_prevcount)
{
- if (set_prevcount)
+ if (set_prevcount) {
vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr;
+ }
vimvars[VV_COUNT].vv_nr = count;
vimvars[VV_COUNT1].vv_nr = count1;
}
@@ -8662,17 +8658,16 @@ void set_vim_var_special(const VimVarIndex idx, const SpecialVarValue val)
/// @param[in] val Value to set to. Will be copied.
/// @param[in] len Length of that value or -1 in which case strlen() will be
/// used.
-void set_vim_var_string(const VimVarIndex idx, const char *const val,
- const ptrdiff_t len)
+void set_vim_var_string(const VimVarIndex idx, const char *const val, const ptrdiff_t len)
{
tv_clear(&vimvars[idx].vv_di.di_tv);
vimvars[idx].vv_type = VAR_STRING;
if (val == NULL) {
vimvars[idx].vv_str = NULL;
} else if (len == -1) {
- vimvars[idx].vv_str = (char_u *) xstrdup(val);
+ vimvars[idx].vv_str = (char_u *)xstrdup(val);
} else {
- vimvars[idx].vv_str = (char_u *) xstrndup(val, (size_t) len);
+ vimvars[idx].vv_str = (char_u *)xstrndup(val, (size_t)len);
}
}
@@ -8748,8 +8743,9 @@ void set_reg_var(int c)
*/
char_u *v_exception(char_u *oldval)
{
- if (oldval == NULL)
+ if (oldval == NULL) {
return vimvars[VV_EXCEPTION].vv_str;
+ }
vimvars[VV_EXCEPTION].vv_str = oldval;
return NULL;
@@ -8763,8 +8759,9 @@ char_u *v_exception(char_u *oldval)
*/
char_u *v_throwpoint(char_u *oldval)
{
- if (oldval == NULL)
+ if (oldval == NULL) {
return vimvars[VV_THROWPOINT].vv_str;
+ }
vimvars[VV_THROWPOINT].vv_str = oldval;
return NULL;
@@ -8786,13 +8783,15 @@ char_u *set_cmdarg(exarg_T *eap, char_u *oldarg)
}
size_t len = 0;
- if (eap->force_bin == FORCE_BIN)
+ if (eap->force_bin == FORCE_BIN) {
len = 6;
- else if (eap->force_bin == FORCE_NOBIN)
+ } else if (eap->force_bin == FORCE_NOBIN) {
len = 8;
+ }
- if (eap->read_edit)
+ if (eap->read_edit) {
len += 7;
+ }
if (eap->force_ff != 0) {
len += 10; // " ++ff=unix"
@@ -8807,15 +8806,17 @@ char_u *set_cmdarg(exarg_T *eap, char_u *oldarg)
const size_t newval_len = len + 1;
char_u *newval = xmalloc(newval_len);
- if (eap->force_bin == FORCE_BIN)
- sprintf((char *)newval, " ++bin");
- else if (eap->force_bin == FORCE_NOBIN)
- sprintf((char *)newval, " ++nobin");
- else
+ if (eap->force_bin == FORCE_BIN) {
+ snprintf((char *)newval, newval_len, " ++bin");
+ } else if (eap->force_bin == FORCE_NOBIN) {
+ snprintf((char *)newval, newval_len, " ++nobin");
+ } else {
*newval = NUL;
+ }
- if (eap->read_edit)
+ if (eap->read_edit) {
STRCAT(newval, " ++edit");
+ }
if (eap->force_ff != 0) {
snprintf((char *)newval + STRLEN(newval), newval_len, " ++ff=%s",
@@ -8838,20 +8839,20 @@ char_u *set_cmdarg(exarg_T *eap, char_u *oldarg)
return oldval;
}
-// Get the value of internal variable "name".
-// Return OK or FAIL. If OK is returned "rettv" must be cleared.
-int get_var_tv(
- const char *name,
- int len, // length of "name"
- typval_T *rettv, // NULL when only checking existence
- dictitem_T **dip, // non-NULL when typval's dict item is needed
- int verbose, // may give error message
- int no_autoload // do not use script autoloading
-)
+/// Get the value of internal variable "name".
+/// Return OK or FAIL. If OK is returned "rettv" must be cleared.
+///
+/// @param len length of "name"
+/// @param rettv NULL when only checking existence
+/// @param dip non-NULL when typval's dict item is needed
+/// @param verbose may give error message
+/// @param no_autoload do not use script autoloading
+int get_var_tv(const char *name, int len, typval_T *rettv, dictitem_T **dip, int verbose,
+ int no_autoload)
{
int ret = OK;
- typval_T *tv = NULL;
- dictitem_T *v;
+ typval_T *tv = NULL;
+ dictitem_T *v;
v = find_var(name, (size_t)len, NULL, no_autoload);
if (v != NULL) {
@@ -8934,15 +8935,13 @@ int check_luafunc_name(const char *const str, const bool paren)
/// - method call: var->method()
///
/// Can all be combined in any order: dict.func(expr)[idx]['func'](expr)->len()
-int
-handle_subscript(
- const char **const arg,
- typval_T *rettv,
- int evaluate, // do more than finding the end
- int verbose, // give error messages
- const char_u *const start_leader, // start of '!' and '-' prefixes
- const char_u **const end_leaderp // end of '!' and '-' prefixes
-)
+///
+/// @param evaluate do more than finding the end
+/// @param verbose give error messages
+/// @param start_leader start of '!' and '-' prefixes
+/// @param end_leaderp end of '!' and '-' prefixes
+int handle_subscript(const char **const arg, typval_T *rettv, int evaluate, int verbose,
+ const char_u *const start_leader, const char_u **const end_leaderp)
{
int ret = OK;
dict_T *selfdict = NULL;
@@ -9005,10 +9004,12 @@ handle_subscript(
tv_dict_unref(selfdict);
if (rettv->v_type == VAR_DICT) {
selfdict = rettv->vval.v_dict;
- if (selfdict != NULL)
+ if (selfdict != NULL) {
++selfdict->dv_refcount;
- } else
+ }
+ } else {
selfdict = NULL;
+ }
if (eval_index((char_u **)arg, rettv, evaluate, verbose) == FAIL) {
tv_clear(rettv);
ret = FAIL;
@@ -9041,8 +9042,8 @@ void set_selfdict(typval_T *const rettv, dict_T *const selfdict)
// Careful: "a:0" variables don't have a name.
// When "htp" is not NULL we are writing to the variable, set "htp" to the
// hashtab_T used.
-dictitem_T *find_var(const char *const name, const size_t name_len,
- hashtab_T **htp, int no_autoload)
+dictitem_T *find_var(const char *const name, const size_t name_len, hashtab_T **htp,
+ int no_autoload)
{
const char *varname;
hashtab_T *const ht = find_var_ht(name, name_len, &varname);
@@ -9076,26 +9077,31 @@ dictitem_T *find_var(const char *const name, const size_t name_len,
///
/// @return pointer to the dictionary item with the found variable or NULL if it
/// was not found.
-dictitem_T *find_var_in_ht(hashtab_T *const ht,
- int htname,
- const char *const varname,
- const size_t varname_len,
- int no_autoload)
+dictitem_T *find_var_in_ht(hashtab_T *const ht, int htname, const char *const varname,
+ const size_t varname_len, int no_autoload)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- hashitem_T *hi;
+ hashitem_T *hi;
if (varname_len == 0) {
// Must be something like "s:", otherwise "ht" would be NULL.
switch (htname) {
- case 's': return (dictitem_T *)&SCRIPT_SV(current_sctx.sc_sid)->sv_var;
- case 'g': return (dictitem_T *)&globvars_var;
- case 'v': return (dictitem_T *)&vimvars_var;
- case 'b': return (dictitem_T *)&curbuf->b_bufvar;
- case 'w': return (dictitem_T *)&curwin->w_winvar;
- case 't': return (dictitem_T *)&curtab->tp_winvar;
- case 'l': return get_funccal_local_var();
- case 'a': return get_funccal_args_var();
+ case 's':
+ return (dictitem_T *)&SCRIPT_SV(current_sctx.sc_sid)->sv_var;
+ case 'g':
+ return (dictitem_T *)&globvars_var;
+ case 'v':
+ return (dictitem_T *)&vimvars_var;
+ case 'b':
+ return (dictitem_T *)&curbuf->b_bufvar;
+ case 'w':
+ return (dictitem_T *)&curwin->w_winvar;
+ case 't':
+ return (dictitem_T *)&curtab->tp_winvar;
+ case 'l':
+ return get_funccal_local_var();
+ case 'a':
+ return get_funccal_args_var();
}
return NULL;
}
@@ -9130,8 +9136,8 @@ dictitem_T *find_var_in_ht(hashtab_T *const ht,
/// @param[out] d Scope dictionary.
///
/// @return Scope hashtab, NULL if name is not valid.
-static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len,
- const char **varname, dict_T **d)
+static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len, const char **varname,
+ dict_T **d)
{
hashitem_T *hi;
funccall_T *funccal = get_funccal();
@@ -9185,8 +9191,12 @@ static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len,
} else if (*name == 'l' && funccal != NULL) { // local variable
*d = &funccal->l_vars;
} else if (*name == 's' // script variable
- && current_sctx.sc_sid > 0
+ && (current_sctx.sc_sid > 0 || current_sctx.sc_sid == SID_STR)
&& current_sctx.sc_sid <= ga_scripts.ga_len) {
+ // For anonymous scripts without a script item, create one now so script vars can be used
+ if (current_sctx.sc_sid == SID_STR) {
+ new_script_item(NULL, &current_sctx.sc_sid);
+ }
*d = &SCRIPT_SV(current_sctx.sc_sid)->sv_dict;
}
@@ -9202,8 +9212,7 @@ end:
/// prefix.
///
/// @return Scope hashtab, NULL if name is not valid.
-hashtab_T *find_var_ht(const char *name, const size_t name_len,
- const char **varname)
+hashtab_T *find_var_ht(const char *name, const size_t name_len, const char **varname)
{
dict_T *d;
return find_var_ht_dict(name, name_len, varname, &d);
@@ -9216,7 +9225,7 @@ hashtab_T *find_var_ht(const char *name, const size_t name_len,
*/
char_u *get_var_value(const char *const name)
{
- dictitem_T *v;
+ dictitem_T *v;
v = find_var(name, strlen(name), NULL, false);
if (v == NULL) {
@@ -9231,7 +9240,7 @@ char_u *get_var_value(const char *const name)
*/
void new_script_vars(scid_T id)
{
- hashtab_T *ht;
+ hashtab_T *ht;
scriptvar_T *sv;
ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len));
@@ -9241,8 +9250,9 @@ void new_script_vars(scid_T id)
* at its init value. Also reset "v_dict", it's always the same. */
for (int i = 1; i <= ga_scripts.ga_len; ++i) {
ht = &SCRIPT_VARS(i);
- if (ht->ht_mask == HT_INIT_SIZE - 1)
+ if (ht->ht_mask == HT_INIT_SIZE - 1) {
ht->ht_array = ht->ht_smallarray;
+ }
sv = SCRIPT_SV(i);
sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict;
}
@@ -9301,8 +9311,8 @@ void vars_clear(hashtab_T *ht)
void vars_clear_ext(hashtab_T *ht, int free_val)
{
int todo;
- hashitem_T *hi;
- dictitem_T *v;
+ hashitem_T *hi;
+ dictitem_T *v;
hash_lock(ht);
todo = (int)ht->ht_used;
@@ -9332,7 +9342,7 @@ void vars_clear_ext(hashtab_T *ht, int free_val)
*/
static void delete_var(hashtab_T *ht, hashitem_T *hi)
{
- dictitem_T *di = TV_DICT_HI2DI(hi);
+ dictitem_T *di = TV_DICT_HI2DI(hi);
hash_remove(ht, hi);
tv_clear(&di->di_tv);
@@ -9353,9 +9363,8 @@ static void list_one_var(dictitem_T *v, const char *prefix, int *first)
/// @param[in] name_len Length of the name. May be -1, in this case strlen()
/// will be used.
/// @param[in,out] first When true clear rest of screen and set to false.
-static void list_one_var_a(const char *prefix, const char *name,
- const ptrdiff_t name_len, const int type,
- const char *string, int *first)
+static void list_one_var_a(const char *prefix, const char *name, const ptrdiff_t name_len,
+ const int type, const char *string, int *first)
{
// don't use msg() or msg_attr() to avoid overwriting "v:statusmsg"
msg_start();
@@ -9371,14 +9380,17 @@ static void list_one_var_a(const char *prefix, const char *name,
msg_putchar('*');
} else if (type == VAR_LIST) {
msg_putchar('[');
- if (*string == '[')
+ if (*string == '[') {
++string;
+ }
} else if (type == VAR_DICT) {
msg_putchar('{');
- if (*string == '{')
+ if (*string == '{') {
++string;
- } else
+ }
+ } else {
msg_putchar(' ');
+ }
msg_outtrans((char_u *)string);
@@ -9400,8 +9412,7 @@ static void list_one_var_a(const char *prefix, const char *name,
/// @param[in] name_len Length of the variable name.
/// @param tv Variable value.
/// @param[in] copy True if value in tv is to be copied.
-void set_var(const char *name, const size_t name_len, typval_T *const tv,
- const bool copy)
+void set_var(const char *name, const size_t name_len, typval_T *const tv, const bool copy)
FUNC_ATTR_NONNULL_ALL
{
set_var_const(name, name_len, tv, copy, false);
@@ -9417,13 +9428,12 @@ void set_var(const char *name, const size_t name_len, typval_T *const tv,
/// @param tv Variable value.
/// @param[in] copy True if value in tv is to be copied.
/// @param[in] is_const True if value in tv is to be locked.
-static void set_var_const(const char *name, const size_t name_len,
- typval_T *const tv, const bool copy,
- const bool is_const)
+static void set_var_const(const char *name, const size_t name_len, typval_T *const tv,
+ const bool copy, const bool is_const)
FUNC_ATTR_NONNULL_ALL
{
- dictitem_T *v;
- hashtab_T *ht;
+ dictitem_T *v;
+ hashtab_T *ht;
dict_T *dict;
const char *varname;
@@ -9438,7 +9448,7 @@ static void set_var_const(const char *name, const size_t name_len,
// Search in parent scope which is possible to reference from lambda
if (v == NULL) {
- v = find_var_in_scoped_ht((const char *)name, name_len, true);
+ v = find_var_in_scoped_ht(name, name_len, true);
}
if (tv_is_func(*tv) && !var_check_func_name(name, v == NULL)) {
@@ -9567,8 +9577,7 @@ static void set_var_const(const char *name, const size_t name_len,
///
/// @return True if variable is read-only: either always or in sandbox when
/// sandbox is enabled, false otherwise.
-bool var_check_ro(const int flags, const char *name,
- size_t name_len)
+bool var_check_ro(const int flags, const char *name, size_t name_len)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
const char *error_message = NULL;
@@ -9611,8 +9620,7 @@ bool var_check_ro(const int flags, const char *name,
/// gettext.
///
/// @return True if variable is fixed, false otherwise.
-bool var_check_fixed(const int flags, const char *name,
- size_t name_len)
+bool var_check_fixed(const int flags, const char *name, size_t name_len)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
if (flags & DI_FLAGS_FIX) {
@@ -9650,7 +9658,7 @@ bool var_check_func_name(const char *const name, const bool new_var)
// Don't allow hiding a function. When "v" is not NULL we might be
// assigning another function to the same var, the type is checked
// below.
- if (new_var && function_exists((const char *)name, false)) {
+ if (new_var && function_exists(name, false)) {
EMSG2(_("E705: Variable name conflicts with existing function: %s"),
name);
return false;
@@ -9696,11 +9704,8 @@ bool valid_varname(const char *varname)
/// a copy with (`copy[0] isnot copy[1]`), with non-zero it
/// will emit a copy with (`copy[0] is copy[1]`) like in the
/// original list. Not used when deep is false.
-int var_item_copy(const vimconv_T *const conv,
- typval_T *const from,
- typval_T *const to,
- const bool deep,
- const int copyID)
+int var_item_copy(const vimconv_T *const conv, typval_T *const from, typval_T *const to,
+ const bool deep, const int copyID)
FUNC_ATTR_NONNULL_ARG(2, 3)
{
static int recurse = 0;
@@ -9732,7 +9737,7 @@ int var_item_copy(const vimconv_T *const conv,
from->vval.v_string,
NULL))
== NULL) {
- to->vval.v_string = (char_u *) xstrdup((char *) from->vval.v_string);
+ to->vval.v_string = (char_u *)xstrdup((char *)from->vval.v_string);
}
}
break;
@@ -9780,21 +9785,22 @@ int var_item_copy(const vimconv_T *const conv,
}
/*
- * ":echo expr1 ..." print each argument separated with a space, add a
- * newline at the end.
- * ":echon expr1 ..." print each argument plain.
+ * ":echo expr1 ..." print each argument separated with a space, add a
+ * newline at the end.
+ * ":echon expr1 ..." print each argument plain.
*/
void ex_echo(exarg_T *eap)
{
- char_u *arg = eap->arg;
+ char_u *arg = eap->arg;
typval_T rettv;
bool atstart = true;
bool need_clear = true;
const int did_emsg_before = did_emsg;
const int called_emsg_before = called_emsg;
- if (eap->skip)
+ if (eap->skip) {
++emsg_skip;
+ }
while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) {
// If eval1() causes an error message the text from the command may
// still need to be cleared. E.g., "echo 22,44".
@@ -9865,9 +9871,9 @@ void ex_echohl(exarg_T *eap)
}
/*
- * ":execute expr1 ..." execute the result of an expression.
- * ":echomsg expr1 ..." Print a message
- * ":echoerr expr1 ..." Print an error
+ * ":execute expr1 ..." execute the result of an expression.
+ * ":echomsg expr1 ..." Print a message
+ * ":echoerr expr1 ..." Print an error
* Each gets spaces around each argument and a newline at the end for
* echo commands
*/
@@ -9881,8 +9887,9 @@ void ex_execute(exarg_T *eap)
ga_init(&ga, 1, 80);
- if (eap->skip)
+ if (eap->skip) {
++emsg_skip;
+ }
while (*arg != NUL && *arg != '|' && *arg != '\n') {
ret = eval1_emsg(&arg, &rettv, !eap->skip);
if (ret == FAIL) {
@@ -9928,17 +9935,20 @@ void ex_execute(exarg_T *eap)
save_did_emsg = did_emsg;
msg_ext_set_kind("echoerr");
EMSG((char_u *)ga.ga_data);
- if (!force_abort)
+ if (!force_abort) {
did_emsg = save_did_emsg;
- } else if (eap->cmdidx == CMD_execute)
+ }
+ } else if (eap->cmdidx == CMD_execute) {
do_cmdline((char_u *)ga.ga_data,
- eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE);
+ eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE);
+ }
}
ga_clear(&ga);
- if (eap->skip)
+ if (eap->skip) {
--emsg_skip;
+ }
eap->nextcmd = check_nextcmd(arg);
}
@@ -10016,10 +10026,10 @@ void func_do_profile(ufunc_T *fp)
*/
void func_dump_profile(FILE *fd)
{
- hashitem_T *hi;
+ hashitem_T *hi;
int todo;
- ufunc_T *fp;
- ufunc_T **sorttab;
+ ufunc_T *fp;
+ ufunc_T **sorttab;
int st_len = 0;
todo = (int)func_hashtab.ht_used;
@@ -10045,7 +10055,7 @@ void func_dump_profile(FILE *fd)
bool should_free;
const LastSet last_set = (LastSet){
.script_ctx = fp->uf_script_ctx,
- .channel_id = 0,
+ .channel_id = 0,
};
char_u *p = get_scriptname(last_set, &should_free);
fprintf(fd, " Defined: %s:%" PRIdLINENR "\n",
@@ -10065,10 +10075,11 @@ void func_dump_profile(FILE *fd)
fprintf(fd, "count total (s) self (s)\n");
for (int i = 0; i < fp->uf_lines.ga_len; ++i) {
- if (FUNCLINE(fp, i) == NULL)
+ if (FUNCLINE(fp, i) == NULL) {
continue;
+ }
prof_func_line(fd, fp->uf_tml_count[i],
- &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE);
+ &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE);
fprintf(fd, "%s\n", FUNCLINE(fp, i));
}
fprintf(fd, "\n");
@@ -10078,65 +10089,58 @@ void func_dump_profile(FILE *fd)
if (st_len > 0) {
qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *),
- prof_total_cmp);
+ prof_total_cmp);
prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE);
qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *),
- prof_self_cmp);
+ prof_self_cmp);
prof_sort_list(fd, sorttab, st_len, "SELF", TRUE);
}
xfree(sorttab);
}
-static void
-prof_sort_list(
- FILE *fd,
- ufunc_T **sorttab,
- int st_len,
- char *title,
- int prefer_self // when equal print only self time
-)
+/// @param prefer_self when equal print only self time
+static void prof_sort_list(FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)
{
int i;
- ufunc_T *fp;
+ ufunc_T *fp;
fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title);
fprintf(fd, "count total (s) self (s) function\n");
for (i = 0; i < 20 && i < st_len; ++i) {
fp = sorttab[i];
prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self,
- prefer_self);
- if (fp->uf_name[0] == K_SPECIAL)
+ prefer_self);
+ if (fp->uf_name[0] == K_SPECIAL) {
fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3);
- else
+ } else {
fprintf(fd, " %s()\n", fp->uf_name);
+ }
}
fprintf(fd, "\n");
}
-/*
- * Print the count and times for one function or function line.
- */
-static void prof_func_line(
- FILE *fd,
- int count,
- proftime_T *total,
- proftime_T *self,
- int prefer_self // when equal print only self time
-)
+/// Print the count and times for one function or function line.
+///
+/// @param prefer_self when equal print only self time
+static void prof_func_line(FILE *fd, int count, proftime_T *total, proftime_T *self,
+ int prefer_self)
{
if (count > 0) {
fprintf(fd, "%5d ", count);
- if (prefer_self && profile_equal(*total, *self))
+ if (prefer_self && profile_equal(*total, *self)) {
fprintf(fd, " ");
- else
+ } else {
fprintf(fd, "%s ", profile_msg(*total));
- if (!prefer_self && profile_equal(*total, *self))
+ }
+ if (!prefer_self && profile_equal(*total, *self)) {
fprintf(fd, " ");
- else
+ } else {
fprintf(fd, "%s ", profile_msg(*self));
- } else
+ }
+ } else {
fprintf(fd, " ");
+ }
}
/*
@@ -10194,8 +10198,7 @@ char *autoload_name(const char *const name, const size_t name_len)
/// @param[in] reload If true, load script again when already loaded.
///
/// @return true if a package was loaded.
-bool script_autoload(const char *const name, const size_t name_len,
- const bool reload)
+bool script_autoload(const char *const name, const size_t name_len, const bool reload)
{
// If there is no '#' after name[0] there is no package name.
const char *p = memchr(name, AUTOLOAD_CHAR, name_len);
@@ -10225,7 +10228,7 @@ bool script_autoload(const char *const name, const size_t name_len,
}
// Try loading the package from $VIMRUNTIME/autoload/<name>.vim
- if (source_runtime((char_u *)scriptname, 0) == OK) {
+ if (source_runtime(scriptname, 0) == OK) {
ret = true;
}
}
@@ -10242,8 +10245,8 @@ bool script_autoload(const char *const name, const size_t name_len,
*/
void func_line_start(void *cookie)
{
- funccall_T *fcp = (funccall_T *)cookie;
- ufunc_T *fp = fcp->func;
+ funccall_T *fcp = (funccall_T *)cookie;
+ ufunc_T *fp = fcp->func;
if (fp->uf_profiling && sourcing_lnum >= 1
&& sourcing_lnum <= fp->uf_lines.ga_len) {
@@ -10264,11 +10267,12 @@ void func_line_start(void *cookie)
*/
void func_line_exec(void *cookie)
{
- funccall_T *fcp = (funccall_T *)cookie;
- ufunc_T *fp = fcp->func;
+ funccall_T *fcp = (funccall_T *)cookie;
+ ufunc_T *fp = fcp->func;
- if (fp->uf_profiling && fp->uf_tml_idx >= 0)
+ if (fp->uf_profiling && fp->uf_tml_idx >= 0) {
fp->uf_tml_execed = TRUE;
+ }
}
/*
@@ -10276,8 +10280,8 @@ void func_line_exec(void *cookie)
*/
void func_line_end(void *cookie)
{
- funccall_T *fcp = (funccall_T *)cookie;
- ufunc_T *fp = fcp->func;
+ funccall_T *fcp = (funccall_T *)cookie;
+ ufunc_T *fp = fcp->func;
if (fp->uf_profiling && fp->uf_tml_idx >= 0) {
if (fp->uf_tml_execed) {
@@ -10288,7 +10292,7 @@ void func_line_end(void *cookie)
profile_add(fp->uf_tml_total[fp->uf_tml_idx], fp->uf_tml_start);
fp->uf_tml_self[fp->uf_tml_idx] =
profile_self(fp->uf_tml_self[fp->uf_tml_idx], fp->uf_tml_start,
- fp->uf_tml_children);
+ fp->uf_tml_children);
}
fp->uf_tml_idx = -1;
}
@@ -10299,10 +10303,11 @@ static var_flavour_T var_flavour(char_u *varname)
char_u *p = varname;
if (ASCII_ISUPPER(*p)) {
- while (*(++p))
+ while (*(++p)) {
if (ASCII_ISLOWER(*p)) {
return VAR_FLAVOUR_SESSION;
}
+ }
return VAR_FLAVOUR_SHADA;
} else {
return VAR_FLAVOUR_DEFAULT;
@@ -10320,26 +10325,26 @@ static var_flavour_T var_flavour(char_u *varname)
///
/// @return Pointer that needs to be passed to next `var_shada_iter` invocation
/// or NULL to indicate that iteration is over.
-const void *var_shada_iter(const void *const iter, const char **const name,
- typval_T *rettv, var_flavour_T flavour)
+const void *var_shada_iter(const void *const iter, const char **const name, typval_T *rettv,
+ var_flavour_T flavour)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(2, 3)
{
const hashitem_T *hi;
const hashitem_T *hifirst = globvarht.ht_array;
- const size_t hinum = (size_t) globvarht.ht_mask + 1;
+ const size_t hinum = (size_t)globvarht.ht_mask + 1;
*name = NULL;
if (iter == NULL) {
hi = globvarht.ht_array;
- while ((size_t) (hi - hifirst) < hinum
+ while ((size_t)(hi - hifirst) < hinum
&& (HASHITEM_EMPTY(hi)
|| !(var_flavour(hi->hi_key) & flavour))) {
hi++;
}
- if ((size_t) (hi - hifirst) == hinum) {
+ if ((size_t)(hi - hifirst) == hinum) {
return NULL;
}
} else {
- hi = (const hashitem_T *) iter;
+ hi = (const hashitem_T *)iter;
}
*name = (char *)TV_DICT_HI2DI(hi)->di_key;
tv_copy(&TV_DICT_HI2DI(hi)->di_tv, rettv);
@@ -10368,9 +10373,8 @@ int store_session_globals(FILE *fd)
&& var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) {
// Escape special characters with a backslash. Turn a LF and
// CR into \n and \r.
- char_u *const p = vim_strsave_escaped(
- (const char_u *)tv_get_string(&this_var->di_tv),
- (const char_u *)"\\\"\n\r");
+ char_u *const p = vim_strsave_escaped((const char_u *)tv_get_string(&this_var->di_tv),
+ (const char_u *)"\\\"\n\r");
for (char_u *t = p; *t != NUL; t++) {
if (*t == '\n') {
*t = 'n';
@@ -10381,10 +10385,10 @@ int store_session_globals(FILE *fd)
if ((fprintf(fd, "let %s = %c%s%c",
this_var->di_key,
((this_var->di_tv.v_type == VAR_STRING) ? '"'
- : ' '),
+ : ' '),
p,
((this_var->di_tv.v_type == VAR_STRING) ? '"'
- : ' ')) < 0)
+ : ' ')) < 0)
|| put_eol(fd) == FAIL) {
xfree(p);
return FAIL;
@@ -10451,26 +10455,24 @@ void reset_v_option_vars(void)
set_vim_var_string(VV_OPTION_TYPE, NULL, -1);
}
-/*
- * Adjust a filename, according to a string of modifiers.
- * *fnamep must be NUL terminated when called. When returning, the length is
- * determined by *fnamelen.
- * Returns VALID_ flags or -1 for failure.
- * When there is an error, *fnamep is set to NULL.
- */
-int
-modify_fname(
- char_u *src, // string with modifiers
- bool tilde_file, // "~" is a file name, not $HOME
- size_t *usedlen, // characters after src that are used
- char_u **fnamep, // file name so far
- char_u **bufp, // buffer for allocated file name or NULL
- size_t *fnamelen // length of fnamep
-)
+/// Adjust a filename, according to a string of modifiers.
+/// *fnamep must be NUL terminated when called. When returning, the length is
+/// determined by *fnamelen.
+/// Returns VALID_ flags or -1 for failure.
+/// When there is an error, *fnamep is set to NULL.
+///
+/// @param src string with modifiers
+/// @param tilde_file "~" is a file name, not $HOME
+/// @param usedlen characters after src that are used
+/// @param fnamep file name so far
+/// @param bufp buffer for allocated file name or NULL
+/// @param fnamelen length of fnamep
+int modify_fname(char_u *src, bool tilde_file, size_t *usedlen, char_u **fnamep, char_u **bufp,
+ size_t *fnamelen)
{
int valid = 0;
- char_u *tail;
- char_u *s, *p, *pbuf;
+ char_u *tail;
+ char_u *s, *p, *pbuf;
char_u dirname[MAXPATHL];
int c;
int has_fullname = 0;
@@ -10492,13 +10494,13 @@ repeat:
# endif
|| (*fnamep)[1] == NUL)
#endif
- && !(tilde_file && (*fnamep)[1] == NUL)
- ) {
+ && !(tilde_file && (*fnamep)[1] == NUL)) {
*fnamep = expand_env_save(*fnamep);
xfree(*bufp); // free any allocated file name
*bufp = *fnamep;
- if (*fnamep == NULL)
+ if (*fnamep == NULL) {
return -1;
+ }
}
// When "/." or "/.." is used: force expansion to get rid of it.
@@ -10518,8 +10520,9 @@ repeat:
*fnamep = (char_u *)FullName_save((char *)(*fnamep), *p != NUL);
xfree(*bufp); // free any allocated file name
*bufp = *fnamep;
- if (*fnamep == NULL)
+ if (*fnamep == NULL) {
return -1;
+ }
}
// Append a path separator to a directory.
@@ -10528,8 +10531,9 @@ repeat:
*fnamep = vim_strnsave(*fnamep, STRLEN(*fnamep) + 2);
xfree(*bufp); // free any allocated file name
*bufp = *fnamep;
- if (*fnamep == NULL)
+ if (*fnamep == NULL) {
return -1;
+ }
add_pathsep((char *)*fnamep);
}
}
@@ -10546,12 +10550,14 @@ repeat:
pbuf = NULL;
// Need full path first (use expand_env() to remove a "~/")
if (!has_fullname) {
- if (c == '.' && **fnamep == '~')
+ if (c == '.' && **fnamep == '~') {
p = pbuf = expand_env_save(*fnamep);
- else
+ } else {
p = pbuf = (char_u *)FullName_save((char *)*fnamep, FALSE);
- } else
+ }
+ } else {
p = *fnamep;
+ }
has_fullname = 0;
@@ -10678,7 +10684,7 @@ repeat:
&& (src[*usedlen + 1] == 's'
|| (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) {
int sep;
- char_u *flags;
+ char_u *flags;
int didit = FALSE;
flags = (char_u *)"";
@@ -10742,17 +10748,16 @@ repeat:
/// When "sub" is NULL "expr" is used, must be a VAR_FUNC or VAR_PARTIAL.
/// "flags" can be "g" to do a global substitute.
/// Returns an allocated string, NULL for error.
-char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub,
- typval_T *expr, char_u *flags)
+char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, typval_T *expr, char_u *flags)
{
int sublen;
regmatch_T regmatch;
int do_all;
- char_u *tail;
- char_u *end;
+ char_u *tail;
+ char_u *end;
garray_T ga;
- char_u *save_cpo;
- char_u *zero_width = NULL;
+ char_u *save_cpo;
+ char_u *zero_width = NULL;
// Make 'cpoptions' empty, so that the 'l' flag doesn't work here
save_cpo = p_cpo;
@@ -10788,7 +10793,7 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub,
// - The text after the match.
sublen = vim_regsub(&regmatch, sub, expr, tail, false, true, false);
ga_grow(&ga, (int)((end - tail) + sublen -
- (regmatch.endp[0] - regmatch.startp[0])));
+ (regmatch.endp[0] - regmatch.startp[0])));
// copy the text up to where the match is
int i = (int)(regmatch.startp[0] - tail);
@@ -10798,14 +10803,17 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub,
+ ga.ga_len + i, true, true, false);
ga.ga_len += i + sublen - 1;
tail = regmatch.endp[0];
- if (*tail == NUL)
+ if (*tail == NUL) {
break;
- if (!do_all)
+ }
+ if (!do_all) {
break;
+ }
}
- if (ga.ga_data != NULL)
+ if (ga.ga_data != NULL) {
STRCPY((char *)ga.ga_data + ga.ga_len, tail);
+ }
vim_regfree(regmatch.regprog);
}
@@ -10825,9 +10833,7 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub,
/// common code for getting job callbacks for jobstart, termopen and rpcstart
///
/// @return true/false on success/failure.
-bool common_job_callbacks(dict_T *vopts,
- CallbackReader *on_stdout,
- CallbackReader *on_stderr,
+bool common_job_callbacks(dict_T *vopts, CallbackReader *on_stdout, CallbackReader *on_stderr,
Callback *on_exit)
{
if (tv_dict_get_callback(vopts, S_LEN("on_stdout"), &on_stdout->cb)
@@ -10888,8 +10894,7 @@ void script_host_eval(char *name, typval_T *argvars, typval_T *rettv)
/// @param discard Clears the value returned by the provider and returns
/// an empty typval_T.
-typval_T eval_call_provider(char *provider, char *method, list_T *arguments,
- bool discard)
+typval_T eval_call_provider(char *provider, char *method, list_T *arguments, bool discard)
{
if (!eval_has_provider(provider)) {
emsgf("E319: No \"%s\" provider found. Run \":checkhealth provider\"",
@@ -11052,59 +11057,59 @@ void ex_checkhealth(exarg_T *eap)
void invoke_prompt_callback(void)
{
- typval_T rettv;
- typval_T argv[2];
- char_u *text;
- char_u *prompt;
- linenr_T lnum = curbuf->b_ml.ml_line_count;
-
- // Add a new line for the prompt before invoking the callback, so that
- // text can always be inserted above the last line.
- ml_append(lnum, (char_u *)"", 0, false);
- curwin->w_cursor.lnum = lnum + 1;
- curwin->w_cursor.col = 0;
-
- if (curbuf->b_prompt_callback.type == kCallbackNone) {
- return;
- }
- text = ml_get(lnum);
- prompt = prompt_text();
- if (STRLEN(text) >= STRLEN(prompt)) {
- text += STRLEN(prompt);
- }
- argv[0].v_type = VAR_STRING;
- argv[0].vval.v_string = vim_strsave(text);
- argv[1].v_type = VAR_UNKNOWN;
+ typval_T rettv;
+ typval_T argv[2];
+ char_u *text;
+ char_u *prompt;
+ linenr_T lnum = curbuf->b_ml.ml_line_count;
+
+ // Add a new line for the prompt before invoking the callback, so that
+ // text can always be inserted above the last line.
+ ml_append(lnum, (char_u *)"", 0, false);
+ curwin->w_cursor.lnum = lnum + 1;
+ curwin->w_cursor.col = 0;
+
+ if (curbuf->b_prompt_callback.type == kCallbackNone) {
+ return;
+ }
+ text = ml_get(lnum);
+ prompt = prompt_text();
+ if (STRLEN(text) >= STRLEN(prompt)) {
+ text += STRLEN(prompt);
+ }
+ argv[0].v_type = VAR_STRING;
+ argv[0].vval.v_string = vim_strsave(text);
+ argv[1].v_type = VAR_UNKNOWN;
- callback_call(&curbuf->b_prompt_callback, 1, argv, &rettv);
- tv_clear(&argv[0]);
- tv_clear(&rettv);
+ callback_call(&curbuf->b_prompt_callback, 1, argv, &rettv);
+ tv_clear(&argv[0]);
+ tv_clear(&rettv);
}
// Return true When the interrupt callback was invoked.
bool invoke_prompt_interrupt(void)
{
- typval_T rettv;
- typval_T argv[1];
+ typval_T rettv;
+ typval_T argv[1];
- if (curbuf->b_prompt_interrupt.type == kCallbackNone) {
- return false;
- }
- argv[0].v_type = VAR_UNKNOWN;
+ if (curbuf->b_prompt_interrupt.type == kCallbackNone) {
+ return false;
+ }
+ argv[0].v_type = VAR_UNKNOWN;
- got_int = false; // don't skip executing commands
- callback_call(&curbuf->b_prompt_interrupt, 0, argv, &rettv);
- tv_clear(&rettv);
- return true;
+ got_int = false; // don't skip executing commands
+ callback_call(&curbuf->b_prompt_interrupt, 0, argv, &rettv);
+ tv_clear(&rettv);
+ return true;
}
-// Compare "typ1" and "typ2". Put the result in "typ1".
-int typval_compare(
- typval_T *typ1, // first operand
- typval_T *typ2, // second operand
- exprtype_T type, // operator
- bool ic // ignore case
-)
+/// Compare "typ1" and "typ2". Put the result in "typ1".
+///
+/// @param typ1 first operand
+/// @param typ2 second operand
+/// @param type operator
+/// @param ic ignore case
+int typval_compare(typval_T *typ1, typval_T *typ2, exprtype_T type, bool ic)
FUNC_ATTR_NONNULL_ALL
{
varnumber_T n1, n2;
@@ -11140,7 +11145,7 @@ int typval_compare(
} else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST) {
if (type_is) {
n1 = typ1->v_type == typ2->v_type
- && typ1->vval.v_list == typ2->vval.v_list;
+ && typ1->vval.v_list == typ2->vval.v_list;
if (type == EXPR_ISNOT) {
n1 = !n1;
}
@@ -11163,7 +11168,7 @@ int typval_compare(
} else if (typ1->v_type == VAR_DICT || typ2->v_type == VAR_DICT) {
if (type_is) {
n1 = typ1->v_type == typ2->v_type
- && typ1->vval.v_dict == typ2->vval.v_dict;
+ && typ1->vval.v_dict == typ2->vval.v_dict;
if (type == EXPR_ISNOT) {
n1 = !n1;
}
@@ -11218,17 +11223,24 @@ int typval_compare(
const float_T f2 = tv_get_float(typ2);
n1 = false;
switch (type) {
- case EXPR_IS:
- case EXPR_EQUAL: n1 = f1 == f2; break;
- case EXPR_ISNOT:
- case EXPR_NEQUAL: n1 = f1 != f2; break;
- case EXPR_GREATER: n1 = f1 > f2; break;
- case EXPR_GEQUAL: n1 = f1 >= f2; break;
- case EXPR_SMALLER: n1 = f1 < f2; break;
- case EXPR_SEQUAL: n1 = f1 <= f2; break;
- case EXPR_UNKNOWN:
- case EXPR_MATCH:
- case EXPR_NOMATCH: break; // avoid gcc warning
+ case EXPR_IS:
+ case EXPR_EQUAL:
+ n1 = f1 == f2; break;
+ case EXPR_ISNOT:
+ case EXPR_NEQUAL:
+ n1 = f1 != f2; break;
+ case EXPR_GREATER:
+ n1 = f1 > f2; break;
+ case EXPR_GEQUAL:
+ n1 = f1 >= f2; break;
+ case EXPR_SMALLER:
+ n1 = f1 < f2; break;
+ case EXPR_SEQUAL:
+ n1 = f1 <= f2; break;
+ case EXPR_UNKNOWN:
+ case EXPR_MATCH:
+ case EXPR_NOMATCH:
+ break; // avoid gcc warning
}
} else if ((typ1->v_type == VAR_NUMBER || typ2->v_type == VAR_NUMBER)
&& type != EXPR_MATCH && type != EXPR_NOMATCH) {
@@ -11237,17 +11249,24 @@ int typval_compare(
n1 = tv_get_number(typ1);
n2 = tv_get_number(typ2);
switch (type) {
- case EXPR_IS:
- case EXPR_EQUAL: n1 = n1 == n2; break;
- case EXPR_ISNOT:
- case EXPR_NEQUAL: n1 = n1 != n2; break;
- case EXPR_GREATER: n1 = n1 > n2; break;
- case EXPR_GEQUAL: n1 = n1 >= n2; break;
- case EXPR_SMALLER: n1 = n1 < n2; break;
- case EXPR_SEQUAL: n1 = n1 <= n2; break;
- case EXPR_UNKNOWN:
- case EXPR_MATCH:
- case EXPR_NOMATCH: break; // avoid gcc warning
+ case EXPR_IS:
+ case EXPR_EQUAL:
+ n1 = n1 == n2; break;
+ case EXPR_ISNOT:
+ case EXPR_NEQUAL:
+ n1 = n1 != n2; break;
+ case EXPR_GREATER:
+ n1 = n1 > n2; break;
+ case EXPR_GEQUAL:
+ n1 = n1 >= n2; break;
+ case EXPR_SMALLER:
+ n1 = n1 < n2; break;
+ case EXPR_SEQUAL:
+ n1 = n1 <= n2; break;
+ case EXPR_UNKNOWN:
+ case EXPR_MATCH:
+ case EXPR_NOMATCH:
+ break; // avoid gcc warning
}
} else {
char buf1[NUMBUFLEN];
@@ -11262,23 +11281,30 @@ int typval_compare(
}
n1 = false;
switch (type) {
- case EXPR_IS:
- case EXPR_EQUAL: n1 = i == 0; break;
- case EXPR_ISNOT:
- case EXPR_NEQUAL: n1 = i != 0; break;
- case EXPR_GREATER: n1 = i > 0; break;
- case EXPR_GEQUAL: n1 = i >= 0; break;
- case EXPR_SMALLER: n1 = i < 0; break;
- case EXPR_SEQUAL: n1 = i <= 0; break;
-
- case EXPR_MATCH:
- case EXPR_NOMATCH:
- n1 = pattern_match((char_u *)s2, (char_u *)s1, ic);
- if (type == EXPR_NOMATCH) {
- n1 = !n1;
- }
- break;
- case EXPR_UNKNOWN: break; // avoid gcc warning
+ case EXPR_IS:
+ case EXPR_EQUAL:
+ n1 = i == 0; break;
+ case EXPR_ISNOT:
+ case EXPR_NEQUAL:
+ n1 = i != 0; break;
+ case EXPR_GREATER:
+ n1 = i > 0; break;
+ case EXPR_GEQUAL:
+ n1 = i >= 0; break;
+ case EXPR_SMALLER:
+ n1 = i < 0; break;
+ case EXPR_SEQUAL:
+ n1 = i <= 0; break;
+
+ case EXPR_MATCH:
+ case EXPR_NOMATCH:
+ n1 = pattern_match((char_u *)s2, (char_u *)s1, ic);
+ if (type == EXPR_NOMATCH) {
+ n1 = !n1;
+ }
+ break;
+ case EXPR_UNKNOWN:
+ break; // avoid gcc warning
}
}
tv_clear(typ1);
@@ -11303,7 +11329,7 @@ bool var_exists(const char *var)
// get_name_len() takes care of expanding curly braces
const char *name = var;
- const int len = get_name_len((const char **)&var, &tofree, true, false);
+ const int len = get_name_len(&var, &tofree, true, false);
if (len > 0) {
typval_T tv;
diff --git a/src/nvim/eval.h b/src/nvim/eval.h
index 2452a0a8c8..3d656656de 100644
--- a/src/nvim/eval.h
+++ b/src/nvim/eval.h
@@ -3,7 +3,7 @@
#include "nvim/buffer_defs.h"
#include "nvim/channel.h"
-#include "nvim/eval/funcs.h" // For FunPtr
+#include "nvim/eval/funcs.h" // For FunPtr
#include "nvim/event/time.h" // For TimeWatcher
#include "nvim/ex_cmds_defs.h" // For exarg_T
#include "nvim/os/fileio.h" // For FileDescriptor
@@ -24,46 +24,46 @@ EXTERN ufunc_T dumuf;
/*
* Structure returned by get_lval() and used by set_var_lval().
* For a plain name:
- * "name" points to the variable name.
- * "exp_name" is NULL.
- * "tv" is NULL
+ * "name" points to the variable name.
+ * "exp_name" is NULL.
+ * "tv" is NULL
* For a magic braces name:
- * "name" points to the expanded variable name.
- * "exp_name" is non-NULL, to be freed later.
- * "tv" is NULL
+ * "name" points to the expanded variable name.
+ * "exp_name" is non-NULL, to be freed later.
+ * "tv" is NULL
* For an index in a list:
- * "name" points to the (expanded) variable name.
- * "exp_name" NULL or non-NULL, to be freed later.
- * "tv" points to the (first) list item value
- * "li" points to the (first) list item
- * "range", "n1", "n2" and "empty2" indicate what items are used.
+ * "name" points to the (expanded) variable name.
+ * "exp_name" NULL or non-NULL, to be freed later.
+ * "tv" points to the (first) list item value
+ * "li" points to the (first) list item
+ * "range", "n1", "n2" and "empty2" indicate what items are used.
* For an existing Dict item:
- * "name" points to the (expanded) variable name.
- * "exp_name" NULL or non-NULL, to be freed later.
- * "tv" points to the dict item value
- * "newkey" is NULL
+ * "name" points to the (expanded) variable name.
+ * "exp_name" NULL or non-NULL, to be freed later.
+ * "tv" points to the dict item value
+ * "newkey" is NULL
* For a non-existing Dict item:
- * "name" points to the (expanded) variable name.
- * "exp_name" NULL or non-NULL, to be freed later.
- * "tv" points to the Dictionary typval_T
- * "newkey" is the key for the new item.
+ * "name" points to the (expanded) variable name.
+ * "exp_name" NULL or non-NULL, to be freed later.
+ * "tv" points to the Dictionary typval_T
+ * "newkey" is the key for the new item.
*/
typedef struct lval_S {
- const char *ll_name; ///< Start of variable name (can be NULL).
- size_t ll_name_len; ///< Length of the .ll_name.
- char *ll_exp_name; ///< NULL or expanded name in allocated memory.
- typval_T *ll_tv; ///< Typeval of item being used. If "newkey"
- ///< isn't NULL it's the Dict to which to add the item.
- listitem_T *ll_li; ///< The list item or NULL.
- list_T *ll_list; ///< The list or NULL.
- bool ll_range; ///< true when a [i:j] range was used.
- bool ll_empty2; ///< Second index is empty: [i:].
- long ll_n1; ///< First index for list.
- long ll_n2; ///< Second index for list range.
- dict_T *ll_dict; ///< The Dictionary or NULL.
- dictitem_T *ll_di; ///< The dictitem or NULL.
- char_u *ll_newkey; ///< New key for Dict in allocated memory or NULL.
- blob_T *ll_blob; ///< The Blob or NULL.
+ const char *ll_name; ///< Start of variable name (can be NULL).
+ size_t ll_name_len; ///< Length of the .ll_name.
+ char *ll_exp_name; ///< NULL or expanded name in allocated memory.
+ typval_T *ll_tv; ///< Typeval of item being used. If "newkey"
+ ///< isn't NULL it's the Dict to which to add the item.
+ listitem_T *ll_li; ///< The list item or NULL.
+ list_T *ll_list; ///< The list or NULL.
+ bool ll_range; ///< true when a [i:j] range was used.
+ bool ll_empty2; ///< Second index is empty: [i:].
+ long ll_n1; ///< First index for list.
+ long ll_n2; ///< Second index for list range.
+ dict_T *ll_dict; ///< The Dictionary or NULL.
+ dictitem_T *ll_di; ///< The dictitem or NULL.
+ char_u *ll_newkey; ///< New key for Dict in allocated memory or NULL.
+ blob_T *ll_blob; ///< The Blob or NULL.
} lval_T;
/// enum used by var_flavour()
@@ -75,100 +75,100 @@ typedef enum {
/// Defines for Vim variables
typedef enum {
- VV_COUNT,
- VV_COUNT1,
- VV_PREVCOUNT,
- VV_ERRMSG,
- VV_WARNINGMSG,
- VV_STATUSMSG,
- VV_SHELL_ERROR,
- VV_THIS_SESSION,
- VV_VERSION,
- VV_LNUM,
- VV_TERMRESPONSE,
- VV_FNAME,
- VV_LANG,
- VV_LC_TIME,
- VV_CTYPE,
- VV_CC_FROM,
- VV_CC_TO,
- VV_FNAME_IN,
- VV_FNAME_OUT,
- VV_FNAME_NEW,
- VV_FNAME_DIFF,
- VV_CMDARG,
- VV_FOLDSTART,
- VV_FOLDEND,
- VV_FOLDDASHES,
- VV_FOLDLEVEL,
- VV_PROGNAME,
- VV_SEND_SERVER,
- VV_DYING,
- VV_EXCEPTION,
- VV_THROWPOINT,
- VV_REG,
- VV_CMDBANG,
- VV_INSERTMODE,
- VV_VAL,
- VV_KEY,
- VV_PROFILING,
- VV_FCS_REASON,
- VV_FCS_CHOICE,
- VV_BEVAL_BUFNR,
- VV_BEVAL_WINNR,
- VV_BEVAL_WINID,
- VV_BEVAL_LNUM,
- VV_BEVAL_COL,
- VV_BEVAL_TEXT,
- VV_SCROLLSTART,
- VV_SWAPNAME,
- VV_SWAPCHOICE,
- VV_SWAPCOMMAND,
- VV_CHAR,
- VV_MOUSE_WIN,
- VV_MOUSE_WINID,
- VV_MOUSE_LNUM,
- VV_MOUSE_COL,
- VV_OP,
- VV_SEARCHFORWARD,
- VV_HLSEARCH,
- VV_OLDFILES,
- VV_WINDOWID,
- VV_PROGPATH,
- VV_COMPLETED_ITEM,
- VV_OPTION_NEW,
- VV_OPTION_OLD,
- VV_OPTION_TYPE,
- VV_ERRORS,
- VV_FALSE,
- VV_TRUE,
- VV_NULL,
- VV_NUMBERMAX,
- VV_NUMBERMIN,
- VV_NUMBERSIZE,
- VV_VIM_DID_ENTER,
- VV_TESTING,
- VV_TYPE_NUMBER,
- VV_TYPE_STRING,
- VV_TYPE_FUNC,
- VV_TYPE_LIST,
- VV_TYPE_DICT,
- VV_TYPE_FLOAT,
- VV_TYPE_BOOL,
- VV_TYPE_BLOB,
- VV_EVENT,
- VV_ECHOSPACE,
- VV_ARGV,
- VV_COLLATE,
- VV_EXITING,
- // Neovim
- VV_STDERR,
- VV_MSGPACK_TYPES,
- VV__NULL_STRING, // String with NULL value. For test purposes only.
- VV__NULL_LIST, // List with NULL value. For test purposes only.
- VV__NULL_DICT, // Dictionary with NULL value. For test purposes only.
- VV__NULL_BLOB, // Blob with NULL value. For test purposes only.
- VV_LUA,
+ VV_COUNT,
+ VV_COUNT1,
+ VV_PREVCOUNT,
+ VV_ERRMSG,
+ VV_WARNINGMSG,
+ VV_STATUSMSG,
+ VV_SHELL_ERROR,
+ VV_THIS_SESSION,
+ VV_VERSION,
+ VV_LNUM,
+ VV_TERMRESPONSE,
+ VV_FNAME,
+ VV_LANG,
+ VV_LC_TIME,
+ VV_CTYPE,
+ VV_CC_FROM,
+ VV_CC_TO,
+ VV_FNAME_IN,
+ VV_FNAME_OUT,
+ VV_FNAME_NEW,
+ VV_FNAME_DIFF,
+ VV_CMDARG,
+ VV_FOLDSTART,
+ VV_FOLDEND,
+ VV_FOLDDASHES,
+ VV_FOLDLEVEL,
+ VV_PROGNAME,
+ VV_SEND_SERVER,
+ VV_DYING,
+ VV_EXCEPTION,
+ VV_THROWPOINT,
+ VV_REG,
+ VV_CMDBANG,
+ VV_INSERTMODE,
+ VV_VAL,
+ VV_KEY,
+ VV_PROFILING,
+ VV_FCS_REASON,
+ VV_FCS_CHOICE,
+ VV_BEVAL_BUFNR,
+ VV_BEVAL_WINNR,
+ VV_BEVAL_WINID,
+ VV_BEVAL_LNUM,
+ VV_BEVAL_COL,
+ VV_BEVAL_TEXT,
+ VV_SCROLLSTART,
+ VV_SWAPNAME,
+ VV_SWAPCHOICE,
+ VV_SWAPCOMMAND,
+ VV_CHAR,
+ VV_MOUSE_WIN,
+ VV_MOUSE_WINID,
+ VV_MOUSE_LNUM,
+ VV_MOUSE_COL,
+ VV_OP,
+ VV_SEARCHFORWARD,
+ VV_HLSEARCH,
+ VV_OLDFILES,
+ VV_WINDOWID,
+ VV_PROGPATH,
+ VV_COMPLETED_ITEM,
+ VV_OPTION_NEW,
+ VV_OPTION_OLD,
+ VV_OPTION_TYPE,
+ VV_ERRORS,
+ VV_FALSE,
+ VV_TRUE,
+ VV_NULL,
+ VV_NUMBERMAX,
+ VV_NUMBERMIN,
+ VV_NUMBERSIZE,
+ VV_VIM_DID_ENTER,
+ VV_TESTING,
+ VV_TYPE_NUMBER,
+ VV_TYPE_STRING,
+ VV_TYPE_FUNC,
+ VV_TYPE_LIST,
+ VV_TYPE_DICT,
+ VV_TYPE_FLOAT,
+ VV_TYPE_BOOL,
+ VV_TYPE_BLOB,
+ VV_EVENT,
+ VV_ECHOSPACE,
+ VV_ARGV,
+ VV_COLLATE,
+ VV_EXITING,
+ // Neovim
+ VV_STDERR,
+ VV_MSGPACK_TYPES,
+ VV__NULL_STRING, // String with NULL value. For test purposes only.
+ VV__NULL_LIST, // List with NULL value. For test purposes only.
+ VV__NULL_DICT, // Dictionary with NULL value. For test purposes only.
+ VV__NULL_BLOB, // Blob with NULL value. For test purposes only.
+ VV_LUA,
} VimVarIndex;
/// All recognized msgpack types
@@ -208,7 +208,7 @@ typedef enum {
} GetLvalFlags;
/// flags for find_name_end()
-#define FNE_INCL_BR 1 /* find_name_end(): include [] in name */
+#define FNE_INCL_BR 1 // find_name_end(): include [] in name
#define FNE_CHECK_START 2 /* find_name_end(): check name starts with
valid character */
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index c0a18b3236..dfc51d80af 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -72,6 +72,7 @@ return {
chansend={args=2},
char2nr={args={1, 2}, base=1},
charidx={args={2, 3}},
+ chdir={args=1, base=1},
cindent={args=1, base=1},
clearmatches={args={0, 1}, base=1},
col={args=1, base=1},
@@ -102,44 +103,44 @@ return {
diff_hlID={args=2, base=1},
empty={args=1, base=1},
environ={},
- escape={args=2},
+ escape={args=2, base=1},
eval={args=1, base=1},
eventhandler={},
- executable={args=1},
- execute={args={1, 2}},
- exepath={args=1},
- exists={args=1},
+ executable={args=1, base=1},
+ execute={args={1, 2}, base=1},
+ exepath={args=1, base=1},
+ exists={args=1, base=1},
exp={args=1, base=1, func="float_op_wrapper", data="&exp"},
- expand={args={1, 3}},
- expandcmd={args=1},
+ expand={args={1, 3}, base=1},
+ expandcmd={args=1, base=1},
extend={args={2, 3}, base=1},
- feedkeys={args={1, 2}},
- file_readable={args=1, func='f_filereadable'}, -- obsolete
- filereadable={args=1},
- filewritable={args=1},
+ feedkeys={args={1, 2}, base=1},
+ file_readable={args=1, base=1, func='f_filereadable'}, -- obsolete
+ filereadable={args=1, base=1},
+ filewritable={args=1, base=1},
filter={args=2, base=1},
- finddir={args={1, 3}},
- findfile={args={1, 3}},
+ finddir={args={1, 3}, base=1},
+ findfile={args={1, 3}, base=1},
flatten={args={1, 2}},
float2nr={args=1, base=1},
floor={args=1, base=1, func="float_op_wrapper", data="&floor"},
fmod={args=2, base=1},
- fnameescape={args=1},
- fnamemodify={args=2},
- foldclosed={args=1},
- foldclosedend={args=1},
- foldlevel={args=1},
+ fnameescape={args=1, base=1},
+ fnamemodify={args=2, base=1},
+ foldclosed={args=1, base=1},
+ foldclosedend={args=1, base=1},
+ foldlevel={args=1, base=1},
foldtext={},
- foldtextresult={args=1},
+ foldtextresult={args=1, base=1},
foreground={},
- funcref={args={1, 3}},
- ['function']={args={1, 3}},
+ funcref={args={1, 3}, base=1},
+ ['function']={args={1, 3}, base=1},
garbagecollect={args={0, 1}},
get={args={2, 3}, base=1},
getbufinfo={args={0, 1}},
- getbufline={args={2, 3}},
- getbufvar={args={2, 3}},
- getchangelist={args={1, 1}},
+ getbufline={args={2, 3}, base=1},
+ getbufvar={args={2, 3}, base=1},
+ getchangelist={args={0, 1}, base=1},
getchar={args={0, 1}},
getcharmod={},
getcharsearch={},
@@ -148,65 +149,67 @@ return {
getcmdpos={},
getcmdtype={},
getcmdwintype={},
- getcompletion={args={2, 3}},
+ getcompletion={args={2, 3}, base=1},
getcurpos={},
- getcwd={args={0,2}},
- getenv={args={1}},
+ getcwd={args={0, 2}, base=1},
+ getenv={args={1}, base=1},
getfontname={args={0, 1}},
- getfperm={args=1},
- getfsize={args=1},
- getftime={args=1},
- getftype={args=1},
- getjumplist={args={0, 2}},
- getline={args={1, 2}},
+ getfperm={args=1, base=1},
+ getfsize={args=1, base=1},
+ getftime={args=1, base=1},
+ getftype={args=1, base=1},
+ getjumplist={args={0, 2}, base=1},
+ getline={args={1, 2}, base=1},
getloclist={args={1, 2}},
getmarklist={args={0, 1}},
getmatches={args={0, 1}},
+ getmousepos={},
getpid={},
- getpos={args=1},
+ getpos={args=1, base=1},
getqflist={args={0, 1}},
- getreg={args={0, 3}},
- getregtype={args={0, 1}},
- gettabinfo={args={0, 1}},
- gettabvar={args={2, 3}},
- gettabwinvar={args={3, 4}},
- gettagstack={args={0, 1}},
- getwininfo={args={0, 1}},
- getwinpos={args={0, 1}},
+ getreg={args={0, 3}, base=1},
+ getreginfo={args={0, 1}, base=1},
+ getregtype={args={0, 1}, base=1},
+ gettabinfo={args={0, 1}, base=1},
+ gettabvar={args={2, 3}, base=1},
+ gettabwinvar={args={3, 4}, base=1},
+ gettagstack={args={0, 1}, base=1},
+ getwininfo={args={0, 1}, base=1},
+ getwinpos={args={0, 1}, base=1},
getwinposx={},
getwinposy={},
- getwinvar={args={2, 3}},
- glob={args={1, 4}},
- glob2regpat={args=1},
- globpath={args={2, 5}},
+ getwinvar={args={2, 3}, base=1},
+ glob={args={1, 4}, base=1},
+ glob2regpat={args=1, base=1},
+ globpath={args={2, 5}, base=2},
has={args=1},
has_key={args=2, base=1},
- haslocaldir={args={0,2}},
- hasmapto={args={1, 3}},
- highlightID={args=1, func='f_hlID'}, -- obsolete
- highlight_exists={args=1, func='f_hlexists'}, -- obsolete
- histadd={args=2},
- histdel={args={1, 2}},
- histget={args={1, 2}},
- histnr={args=1},
- hlID={args=1},
- hlexists={args=1},
+ haslocaldir={args={0, 2}, base=1},
+ hasmapto={args={1, 3}, base=1},
+ highlightID={args=1, base=1, func='f_hlID'}, -- obsolete
+ highlight_exists={args=1, base=1, func='f_hlexists'}, -- obsolete
+ histadd={args=2, base=2},
+ histdel={args={1, 2}, base=1},
+ histget={args={1, 2}, base=1},
+ histnr={args=1, base=1},
+ hlID={args=1, base=1},
+ hlexists={args=1, base=1},
hostname={},
- iconv={args=3},
- indent={args=1},
+ iconv={args=3, base=1},
+ indent={args=1, base=1},
index={args={2, 4}, base=1},
- input={args={1, 3}},
- inputdialog={args={1, 3}},
- inputlist={args=1},
+ input={args={1, 3}, base=1},
+ inputdialog={args={1, 3}, base=1},
+ inputlist={args=1, base=1},
inputrestore={},
inputsave={},
- inputsecret={args={1, 2}},
+ inputsecret={args={1, 2}, base=1},
insert={args={2, 3}, base=1},
interrupt={args=0},
invert={args=1, base=1},
- isdirectory={args=1},
+ isdirectory={args=1, base=1},
isinf={args=1, base=1},
- islocked={args=1},
+ islocked={args=1, base=1},
isnan={args=1, base=1},
id={args=1},
items={args=1, base=1},
@@ -218,76 +221,76 @@ return {
jobstop={args=1},
jobwait={args={1, 2}},
join={args={1, 2}, base=1},
- json_decode={args=1},
- json_encode={args=1},
+ json_decode={args=1, base=1},
+ json_encode={args=1, base=1},
keys={args=1, base=1},
last_buffer_nr={}, -- obsolete
len={args=1, base=1},
- libcall={args=3},
- libcallnr={args=3},
- line={args={1, 2}},
- line2byte={args=1},
- lispindent={args=1},
- list2str={args={1, 2}},
+ libcall={args=3, base=3},
+ libcallnr={args=3, base=3},
+ line={args={1, 2}, base=1},
+ line2byte={args=1, base=1},
+ lispindent={args=1, base=1},
+ list2str={args={1, 2}, base=1},
localtime={},
log={args=1, base=1, func="float_op_wrapper", data="&log"},
log10={args=1, base=1, func="float_op_wrapper", data="&log10"},
- luaeval={args={1, 2}},
+ luaeval={args={1, 2}, base=1},
map={args=2, base=1},
- maparg={args={1, 4}},
- mapcheck={args={1, 3}},
- match={args={2, 4}},
- matchadd={args={2, 5}},
- matchaddpos={args={2, 5}},
- matcharg={args=1},
- matchdelete={args={1, 2}},
- matchend={args={2, 4}},
- matchlist={args={2, 4}},
- matchstr={args={2, 4}},
- matchstrpos={args={2,4}},
+ maparg={args={1, 4}, base=1},
+ mapcheck={args={1, 3}, base=1},
+ match={args={2, 4}, base=1},
+ matchadd={args={2, 5}, base=1},
+ matchaddpos={args={2, 5}, base=1},
+ matcharg={args=1, base=1},
+ matchdelete={args={1, 2}, base=1},
+ matchend={args={2, 4}, base=1},
+ matchlist={args={2, 4}, base=1},
+ matchstr={args={2, 4}, base=1},
+ matchstrpos={args={2,4}, base=1},
max={args=1, base=1},
menu_get={args={1, 2}},
min={args=1, base=1},
- mkdir={args={1, 3}},
- mode={args={0, 1}},
+ mkdir={args={1, 3}, base=1},
+ mode={args={0, 1}, base=1},
msgpackdump={args={1, 2}},
msgpackparse={args=1},
- nextnonblank={args=1},
- nr2char={args={1, 2}},
+ nextnonblank={args=1, base=1},
+ nr2char={args={1, 2}, base=1},
['or']={args=2, base=1},
- pathshorten={args=1},
+ pathshorten={args=1, base=1},
pow={args=2, base=1},
- prevnonblank={args=1},
+ prevnonblank={args=1, base=1},
printf={args=varargs(1), base=2},
prompt_getprompt={args=1},
- prompt_setcallback={args={2, 2}},
- prompt_setinterrupt={args={2, 2}},
- prompt_setprompt={args={2, 2}},
+ prompt_setcallback={args={2, 2}, base=1},
+ prompt_setinterrupt={args={2, 2}, base=1},
+ prompt_setprompt={args={2, 2}, base=1},
pum_getpos={},
pumvisible={},
- py3eval={args=1},
- pyeval={args=1},
- pyxeval={args=1},
- perleval={args=1},
- range={args={1, 3}},
- readdir={args={1, 2}},
- readfile={args={1, 3}},
+ py3eval={args=1, base=1},
+ pyeval={args=1, base=1},
+ pyxeval={args=1, base=1},
+ perleval={args=1, base=1},
+ range={args={1, 3}, base=1},
+ readdir={args={1, 2}, base=1},
+ readfile={args={1, 3}, base=1},
reg_executing={},
reg_recording={},
- reltime={args={0, 2}},
- reltimefloat={args=1},
- reltimestr={args=1},
+ reltime={args={0, 2}, base=1},
+ reltimefloat={args=1, base=1},
+ reltimestr={args=1, base=1},
remove={args={2, 3}, base=1},
- rename={args=2},
+ rename={args=2, base=1},
['repeat']={args=2, base=1},
- resolve={args=1},
+ resolve={args=1, base=1},
reverse={args=1, base=1},
round={args=1, base=1, func="float_op_wrapper", data="&round"},
rpcnotify={args=varargs(2)},
rpcrequest={args=varargs(2)},
rpcstart={args={1, 2}},
rpcstop={args=1},
- rubyeval={args=1},
+ rubyeval={args=1, base=1},
screenattr={args=2},
screenchar={args=2},
screenchars={args=2},
@@ -309,7 +312,7 @@ return {
setcharsearch={args=1},
setcmdpos={args=1},
setenv={args=2},
- setfperm={args=2},
+ setfperm={args=2, base=1},
setline={args=2},
setloclist={args={2, 4}},
setmatches={args={1, 2}},
diff --git a/src/nvim/eval/decode.h b/src/nvim/eval/decode.h
index 77fc4c78c2..f1be5a1f69 100644
--- a/src/nvim/eval/decode.h
+++ b/src/nvim/eval/decode.h
@@ -1,9 +1,8 @@
#ifndef NVIM_EVAL_DECODE_H
#define NVIM_EVAL_DECODE_H
-#include <stddef.h>
-
#include <msgpack.h>
+#include <stddef.h>
#include "nvim/eval/typval.h"
#include "nvim/globals.h"
diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c
index 1c0afc89f5..2d4d9fdea9 100644
--- a/src/nvim/eval/encode.c
+++ b/src/nvim/eval/encode.c
@@ -29,7 +29,6 @@
#include "nvim/message.h"
#include "nvim/vim.h" // For _()
-#define ga_concat(a, b) ga_concat(a, (char_u *)b)
#define utf_ptr2char(b) utf_ptr2char((char_u *)b)
#define utf_ptr2len(b) ((size_t)utf_ptr2len((char_u *)b))
#define utf_char2len(b) ((size_t)utf_char2len(b))
@@ -142,7 +141,7 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
char *const key = encode_tv2string(&key_tv, NULL);
vim_snprintf((char *)IObuff, IOSIZE, key_msg, key);
xfree(key);
- ga_concat(&msg_ga, IObuff);
+ ga_concat(&msg_ga, (char *)IObuff);
break;
}
case kMPConvPairs:
@@ -163,7 +162,7 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
|| (TV_LIST_ITEM_TV(li)->v_type != VAR_LIST
&& tv_list_len(TV_LIST_ITEM_TV(li)->vval.v_list) <= 0)) {
vim_snprintf((char *)IObuff, IOSIZE, idx_msg, idx);
- ga_concat(&msg_ga, IObuff);
+ ga_concat(&msg_ga, (char *)IObuff);
} else {
assert(li != NULL);
listitem_T *const first_item =
@@ -173,7 +172,7 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
char *const key = encode_tv2echo(&key_tv, NULL);
vim_snprintf((char *)IObuff, IOSIZE, key_pair_msg, key, idx);
xfree(key);
- ga_concat(&msg_ga, IObuff);
+ ga_concat(&msg_ga, (char *)IObuff);
}
break;
}
@@ -193,7 +192,7 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
case kMPConvPartialList: {
const int idx = (int)(v.data.a.arg - v.data.a.argv) - 1;
vim_snprintf((char *)IObuff, IOSIZE, partial_arg_i_msg, idx);
- ga_concat(&msg_ga, IObuff);
+ ga_concat(&msg_ga, (char *)IObuff);
break;
}
}
@@ -268,9 +267,8 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
|| TV_LIST_ITEM_TV(state->li)->vval.v_string != NULL);
for (size_t i = state->offset; i < state->li_length && p < buf_end; i++) {
assert(TV_LIST_ITEM_TV(state->li)->vval.v_string != NULL);
- const char ch = (char)(
- TV_LIST_ITEM_TV(state->li)->vval.v_string[state->offset++]);
- *p++ = (char)((char)ch == (char)NL ? (char)NUL : (char)ch);
+ const char ch = (char)(TV_LIST_ITEM_TV(state->li)->vval.v_string[state->offset++]);
+ *p++ = (char)(ch == (char)NL ? (char)NUL : ch);
}
if (p < buf_end) {
state->li = TV_LIST_ITEM_NEXT(state->list, state->li);
@@ -356,20 +354,20 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
const float_T flt_ = (flt); \
switch (xfpclassify(flt_)) { \
case FP_NAN: { \
- ga_concat(gap, (char_u *)"str2float('nan')"); \
+ ga_concat(gap, "str2float('nan')"); \
break; \
} \
case FP_INFINITE: { \
if (flt_ < 0) { \
ga_append(gap, '-'); \
} \
- ga_concat(gap, (char_u *)"str2float('inf')"); \
+ ga_concat(gap, "str2float('inf')"); \
break; \
} \
default: { \
char numbuf[NUMBUFLEN]; \
vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%g", flt_); \
- ga_concat(gap, (char_u *)numbuf); \
+ ga_concat(gap, numbuf); \
} \
} \
} while (0)
@@ -570,7 +568,7 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
default: { \
char numbuf[NUMBUFLEN]; \
vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%g", flt_); \
- ga_concat(gap, (char_u *)numbuf); \
+ ga_concat(gap, numbuf); \
break; \
} \
} \
@@ -875,7 +873,7 @@ char *encode_tv2echo(typval_T *tv, size_t *len)
ga_init(&ga, (int)sizeof(char), 80);
if (tv->v_type == VAR_STRING || tv->v_type == VAR_FUNC) {
if (tv->vval.v_string != NULL) {
- ga_concat(&ga, tv->vval.v_string);
+ ga_concat(&ga, (char *)tv->vval.v_string);
}
} else {
const int eve_ret = encode_vim_to_echo(&ga, tv, N_(":echo argument"));
diff --git a/src/nvim/eval/encode.h b/src/nvim/eval/encode.h
index 596bb49ae0..8755ff48ac 100644
--- a/src/nvim/eval/encode.h
+++ b/src/nvim/eval/encode.h
@@ -1,9 +1,8 @@
#ifndef NVIM_EVAL_ENCODE_H
#define NVIM_EVAL_ENCODE_H
-#include <stddef.h>
-
#include <msgpack.h>
+#include <stddef.h>
#include "nvim/eval.h"
#include "nvim/garray.h"
@@ -49,8 +48,7 @@ static inline ListReaderState encode_init_lrstate(const list_T *const list)
.offset = 0,
.li_length = (TV_LIST_ITEM_TV(tv_list_first(list))->vval.v_string == NULL
? 0
- : STRLEN(TV_LIST_ITEM_TV(
- tv_list_first(list))->vval.v_string)),
+ : STRLEN(TV_LIST_ITEM_TV(tv_list_first(list))->vval.v_string)),
};
}
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index b17b462ed0..946bde060d 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -28,6 +28,7 @@
#include "nvim/file_search.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
+#include "nvim/globals.h"
#include "nvim/if_cscope.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
@@ -80,16 +81,16 @@ KHASH_MAP_INIT_STR(functions, VimLFuncDef)
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/funcs.c.generated.h"
-#ifdef _MSC_VER
+# ifdef _MSC_VER
// This prevents MSVC from replacing the functions with intrinsics,
// and causing errors when trying to get their addresses in funcs.generated.h
-#pragma function(ceil)
-#pragma function(floor)
-#endif
+# pragma function(ceil)
+# pragma function(floor)
+# endif
PRAGMA_DIAG_PUSH_IGNORE_MISSING_PROTOTYPES
PRAGMA_DIAG_PUSH_IGNORE_IMPLICIT_FALLTHROUGH
-#include "funcs.generated.h"
+# include "funcs.generated.h"
PRAGMA_DIAG_POP
PRAGMA_DIAG_POP
#endif
@@ -248,7 +249,7 @@ static int non_zero_arg(typval_T *argvars)
static void float_op_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
float_T f;
- float_T (*function)(float_T) = (float_T (*)(float_T))fptr;
+ float_T (*function)(float_T) = (float_T (*)(float_T)) fptr;
rettv->v_type = VAR_FLOAT;
if (tv_get_float_chk(argvars, &f)) {
@@ -491,7 +492,7 @@ static void f_assert_report(typval_T *argvars, typval_T *rettv, FunPtr fptr)
garray_T ga;
prepare_assert_error(&ga);
- ga_concat(&ga, (const char_u *)tv_get_string(&argvars[0]));
+ ga_concat(&ga, tv_get_string(&argvars[0]));
assert_error(&ga);
ga_clear(&ga);
rettv->vval.v_number = 1;
@@ -803,7 +804,7 @@ buf_T *tv_get_buf_from_arg(typval_T *const tv) FUNC_ATTR_NONNULL_ALL
/// Get the buffer from "arg" and give an error and return NULL if it is not
/// valid.
-buf_T * get_buf_arg(typval_T *arg)
+buf_T *get_buf_arg(typval_T *arg)
{
buf_T *buf;
@@ -1062,6 +1063,45 @@ static void f_charidx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = len > 0 ? len - 1 : 0;
}
+// "chdir(dir)" function
+static void f_chdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ char_u *cwd;
+ CdScope scope = kCdScopeGlobal;
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+
+ if (argvars[0].v_type != VAR_STRING) {
+ // Returning an empty string means it failed.
+ // No error message, for historic reasons.
+ return;
+ }
+
+ // Return the current directory
+ cwd = xmalloc(MAXPATHL);
+ if (cwd != NULL) {
+ if (os_dirname(cwd, MAXPATHL) != FAIL) {
+#ifdef BACKSLASH_IN_FILENAME
+ slash_adjust(cwd);
+#endif
+ rettv->vval.v_string = vim_strsave(cwd);
+ }
+ xfree(cwd);
+ }
+
+ if (curwin->w_localdir != NULL) {
+ scope = kCdScopeWindow;
+ } else if (curtab->tp_localdir != NULL) {
+ scope = kCdScopeTabpage;
+ }
+
+ if (!changedir_func(argvars[0].vval.v_string, scope)) {
+ // Directory change failed
+ XFREE_CLEAR(rettv->vval.v_string);
+ }
+}
+
/*
* "cindent(lnum)" function
*/
@@ -1081,7 +1121,7 @@ static void f_cindent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-static win_T * get_optional_window(typval_T *argvars, int idx)
+static win_T *get_optional_window(typval_T *argvars, int idx)
{
win_T *win = curwin;
@@ -1802,7 +1842,7 @@ static void f_did_filetype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_diff_filler(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = diff_check_fill(curwin, tv_get_lnum(argvars));
+ rettv->vval.v_number = MAX(0, diff_check(curwin, tv_get_lnum(argvars)));
}
/*
@@ -1923,13 +1963,13 @@ static void f_environ(typval_T *argvars, typval_T *rettv, FunPtr fptr)
os_copy_fullenv(env, env_size);
for (ssize_t i = env_size - 1; i >= 0; i--) {
- const char * str = env[i];
+ const char *str = env[i];
const char * const end = strchr(str + (str[0] == '=' ? 1 : 0),
'=');
assert(end != NULL);
ptrdiff_t len = end - str;
assert(len > 0);
- const char * value = str + len + 1;
+ const char *value = str + len + 1;
char c = env[i][len];
env[i][len] = NUL;
@@ -2695,13 +2735,13 @@ static void f_foldlevel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T foldstart;
- linenr_T foldend;
+ linenr_T foldstart;
+ linenr_T foldend;
char_u *dashes;
- linenr_T lnum;
+ linenr_T lnum;
char_u *s;
char_u *r;
- int len;
+ int len;
char *txt;
rettv->v_type = VAR_STRING;
@@ -3088,10 +3128,16 @@ f_getbufvar_end:
static void f_getchangelist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_list_alloc_ret(rettv, 2);
- vim_ignored = tv_get_number(&argvars[0]); // issue errmsg if type error
- emsg_off++;
- const buf_T *const buf = tv_get_buf(&argvars[0], false);
- emsg_off--;
+
+ const buf_T *buf;
+ if (argvars[0].v_type == VAR_UNKNOWN) {
+ buf = curbuf;
+ } else {
+ vim_ignored = tv_get_number(&argvars[0]); // issue errmsg if type error
+ emsg_off++;
+ buf = tv_get_buf(&argvars[0], false);
+ emsg_off--;
+ }
if (buf == NULL) {
return;
}
@@ -3310,10 +3356,10 @@ static void f_getcmdwintype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char_u *pat;
- expand_T xpc;
- bool filtered = false;
- int options = WILD_SILENT | WILD_USE_NL | WILD_ADD_SLASH
- | WILD_NO_BEEP;
+ expand_T xpc;
+ bool filtered = false;
+ int options = WILD_SILENT | WILD_USE_NL | WILD_ADD_SLASH
+ | WILD_NO_BEEP;
if (argvars[1].v_type != VAR_STRING) {
EMSG2(_(e_invarg2), "type must be a string");
@@ -3399,8 +3445,8 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// Numbers of the scope objects (window, tab) we want the working directory
// of. A `-1` means to skip this scope, a `0` means the current object.
int scope_number[] = {
- [kCdScopeWindow] = 0, // Number of window to look at.
- [kCdScopeTab ] = 0, // Number of tab to look at.
+ [kCdScopeWindow ] = 0, // Number of window to look at.
+ [kCdScopeTabpage] = 0, // Number of tab to look at.
};
char_u *cwd = NULL; // Current working directory to print
@@ -3443,8 +3489,8 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
// Find the tabpage by number
- if (scope_number[kCdScopeTab] > 0) {
- tp = find_tabpage(scope_number[kCdScopeTab]);
+ if (scope_number[kCdScopeTabpage] > 0) {
+ tp = find_tabpage(scope_number[kCdScopeTabpage]);
if (!tp) {
EMSG(_("E5000: Cannot find tab number."));
return;
@@ -3453,7 +3499,7 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// Find the window in `tp` by number, `NULL` if none.
if (scope_number[kCdScopeWindow] >= 0) {
- if (scope_number[kCdScopeTab] < 0) {
+ if (scope_number[kCdScopeTabpage] < 0) {
EMSG(_("E5001: Higher scope cannot be -1 if lower scope is >= 0."));
return;
}
@@ -3477,7 +3523,7 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
break;
}
FALLTHROUGH;
- case kCdScopeTab:
+ case kCdScopeTabpage:
assert(tp);
from = tp->tp_localdir;
if (from) {
@@ -3741,7 +3787,7 @@ static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (cur->conceal_char) {
char buf[MB_MAXBYTES + 1];
- buf[utf_char2bytes((int)cur->conceal_char, (char_u *)buf)] = NUL;
+ buf[utf_char2bytes(cur->conceal_char, (char_u *)buf)] = NUL;
tv_dict_add_str(dict, S_LEN("conceal"), buf);
}
@@ -3750,6 +3796,59 @@ static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
+// "getmousepos()" function
+void f_getmousepos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ dict_T *d;
+ win_T *wp;
+ int row = mouse_row;
+ int col = mouse_col;
+ int grid = mouse_grid;
+ varnumber_T winid = 0;
+ varnumber_T winrow = 0;
+ varnumber_T wincol = 0;
+ linenr_T line = 0;
+ varnumber_T column = 0;
+
+ tv_dict_alloc_ret(rettv);
+ d = rettv->vval.v_dict;
+
+ tv_dict_add_nr(d, S_LEN("screenrow"), (varnumber_T)mouse_row + 1);
+ tv_dict_add_nr(d, S_LEN("screencol"), (varnumber_T)mouse_col + 1);
+
+ wp = mouse_find_win(&grid, &row, &col);
+ if (wp != NULL) {
+ int height = wp->w_height + wp->w_status_height;
+ // The height is adjusted by 1 when there is a bottom border. This is not
+ // necessary for a top border since `row` starts at -1 in that case.
+ if (row < height + wp->w_border_adj[2]) {
+ winid = wp->handle;
+ winrow = row + 1 + wp->w_border_adj[0]; // Adjust by 1 for top border
+ wincol = col + 1 + wp->w_border_adj[3]; // Adjust by 1 for left border
+ if (row >= 0 && row < wp->w_height && col >= 0 && col < wp->w_width) {
+ char_u *p;
+ int count;
+
+ mouse_comp_pos(wp, &row, &col, &line);
+
+ // limit to text length plus one
+ p = ml_get_buf(wp->w_buffer, line, false);
+ count = (int)STRLEN(p);
+ if (col > count) {
+ col = count;
+ }
+
+ column = col + 1;
+ }
+ }
+ }
+ tv_dict_add_nr(d, S_LEN("winid"), winid);
+ tv_dict_add_nr(d, S_LEN("winrow"), winrow);
+ tv_dict_add_nr(d, S_LEN("wincol"), wincol);
+ tv_dict_add_nr(d, S_LEN("line"), (varnumber_T)line);
+ tv_dict_add_nr(d, S_LEN("column"), column);
+}
+
/*
* "getpid()" function
*/
@@ -4113,8 +4212,8 @@ static void f_win_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
//
static void win_move_into_split(win_T *wp, win_T *targetwin, int size, int flags)
{
- int dir;
- int height = wp->w_height;
+ int dir;
+ int height = wp->w_height;
win_T *oldwin = curwin;
if (wp == targetwin) {
@@ -4153,7 +4252,7 @@ static void f_win_splitmove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
win_T *wp;
win_T *targetwin;
- int flags = 0, size = 0;
+ int flags = 0, size = 0;
wp = find_win_by_nr_or_id(&argvars[0]);
targetwin = find_win_by_nr_or_id(&argvars[1]);
@@ -4303,7 +4402,7 @@ static void f_globpath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
globpath((char_u *)tv_get_string(&argvars[0]), (char_u *)file, &ga, flags);
if (rettv->v_type == VAR_STRING) {
- rettv->vval.v_string = ga_concat_strings_sep(&ga, "\n");
+ rettv->vval.v_string = (char_u *)ga_concat_strings_sep(&ga, "\n");
} else {
tv_list_alloc_ret(rettv, ga.ga_len);
for (int i = 0; i < ga.ga_len; i++) {
@@ -4553,8 +4652,8 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// Numbers of the scope objects (window, tab) we want the working directory
// of. A `-1` means to skip this scope, a `0` means the current object.
int scope_number[] = {
- [kCdScopeWindow] = 0, // Number of window to look at.
- [kCdScopeTab ] = 0, // Number of tab to look at.
+ [kCdScopeWindow ] = 0, // Number of window to look at.
+ [kCdScopeTabpage] = 0, // Number of tab to look at.
};
tabpage_T *tp = curtab; // The tabpage to look at.
@@ -4592,8 +4691,8 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
// Find the tabpage by number
- if (scope_number[kCdScopeTab] > 0) {
- tp = find_tabpage(scope_number[kCdScopeTab]);
+ if (scope_number[kCdScopeTabpage] > 0) {
+ tp = find_tabpage(scope_number[kCdScopeTabpage]);
if (!tp) {
EMSG(_("E5000: Cannot find tab number."));
return;
@@ -4602,7 +4701,7 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// Find the window in `tp` by number, `NULL` if none.
if (scope_number[kCdScopeWindow] >= 0) {
- if (scope_number[kCdScopeTab] < 0) {
+ if (scope_number[kCdScopeTabpage] < 0) {
EMSG(_("E5001: Higher scope cannot be -1 if lower scope is >= 0."));
return;
}
@@ -4621,7 +4720,7 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
assert(win);
rettv->vval.v_number = win->w_localdir ? 1 : 0;
break;
- case kCdScopeTab:
+ case kCdScopeTabpage:
assert(tp);
rettv->vval.v_number = tp->tp_localdir ? 1 : 0;
break;
@@ -5096,7 +5195,7 @@ static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr)
EMSG(_(e_trailing));
} else {
if (lv.ll_tv == NULL) {
- di = find_var((const char *)lv.ll_name, lv.ll_name_len, NULL, true);
+ di = find_var(lv.ll_name, lv.ll_name_len, NULL, true);
if (di != NULL) {
// Consider a variable locked when:
// 1. the variable itself is locked
@@ -5177,7 +5276,7 @@ static void f_jobpid(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- Process *proc = (Process *)&data->stream.proc;
+ Process *proc = &data->stream.proc;
rettv->vval.v_number = proc->pid;
}
@@ -5246,7 +5345,7 @@ static const char *required_env_vars[] = {
static dict_T *create_environment(const dictitem_T *job_env, const bool clear_env, const bool pty,
const char * const pty_term_name)
{
- dict_T * env = tv_dict_alloc();
+ dict_T *env = tv_dict_alloc();
if (!clear_env) {
typval_T temp_env = TV_INITIAL_VALUE;
@@ -5475,7 +5574,7 @@ static void f_jobstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// Ignore return code, but show error later.
(void)channel_close(data->id, kChannelPartRpc, &error);
}
- process_stop((Process *)&data->stream.proc);
+ process_stop(&data->stream.proc);
rettv->vval.v_number = 1;
if (error) {
EMSG(error);
@@ -5850,7 +5949,7 @@ static void f_list2str(typval_T *argvars, typval_T *rettv, FunPtr fptr)
TV_LIST_ITER_CONST(l, li, {
buf[utf_char2bytes(tv_get_number(TV_LIST_ITEM_TV(li)), buf)] = NUL;
- ga_concat(&ga, buf);
+ ga_concat(&ga, (char *)buf);
});
ga_append(&ga, NUL);
@@ -5931,7 +6030,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
static void f_luaeval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
FUNC_ATTR_NONNULL_ALL
{
- const char *const str = (const char *)tv_get_string_chk(&argvars[0]);
+ const char *const str = tv_get_string_chk(&argvars[0]);
if (str == NULL) {
return;
}
@@ -5968,7 +6067,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
const SomeMatchType type)
{
char_u *str = NULL;
- long len = 0;
+ long len = 0;
char_u *expr = NULL;
regmatch_T regmatch;
char_u *save_cpo;
@@ -6082,7 +6181,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
}
}
- match = vim_regexec_nl(&regmatch, str, (colnr_T)startcol);
+ match = vim_regexec_nl(&regmatch, str, startcol);
if (match && --nth <= 0) {
break;
@@ -6293,7 +6392,7 @@ static void f_matcharg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
: 0));
if (id >= 1 && id <= 3) {
- matchitem_T *const m = (matchitem_T *)get_match(curwin, id);
+ matchitem_T *const m = get_match(curwin, id);
if (m != NULL) {
tv_list_append_string(rettv->vval.v_list,
@@ -6940,7 +7039,7 @@ static void f_range(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} else {
tv_list_alloc_ret(rettv, (end - start) / stride);
for (i = start; stride > 0 ? i <= end : i >= end; i += stride) {
- tv_list_append_number(rettv->vval.v_list, (varnumber_T)i);
+ tv_list_append_number(rettv->vval.v_list, i);
}
}
}
@@ -7218,6 +7317,62 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
fclose(fd);
}
+/// "getreginfo()" function
+static void f_getreginfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ const char *strregname;
+ if (argvars[0].v_type != VAR_UNKNOWN) {
+ strregname = tv_get_string_chk(&argvars[0]);
+ if (strregname == NULL) {
+ return;
+ }
+ } else {
+ strregname = (const char *)get_vim_var_str(VV_REG);
+ }
+
+ int regname = (strregname == NULL ? '"' : *strregname);
+ if (regname == 0 || regname == '@') {
+ regname = '"';
+ }
+
+ tv_dict_alloc_ret(rettv);
+ dict_T *const dict = rettv->vval.v_dict;
+
+ list_T *const list = get_reg_contents(regname, kGRegExprSrc | kGRegList);
+ if (list == NULL) {
+ return;
+ }
+ (void)tv_dict_add_list(dict, S_LEN("regcontents"), list);
+
+ char buf[NUMBUFLEN + 2];
+ buf[0] = NUL;
+ buf[1] = NUL;
+ colnr_T reglen = 0;
+ switch (get_reg_type(regname, &reglen)) {
+ case kMTLineWise:
+ buf[0] = 'V';
+ break;
+ case kMTCharWise:
+ buf[0] = 'v';
+ break;
+ case kMTBlockWise:
+ vim_snprintf(buf, sizeof(buf), "%c%d", Ctrl_V, reglen + 1);
+ break;
+ case kMTUnknown:
+ abort();
+ }
+ (void)tv_dict_add_str(dict, S_LEN("regtype"), buf);
+
+ buf[0] = get_register_name(get_unname_register());
+ buf[1] = NUL;
+ if (regname == '"') {
+ (void)tv_dict_add_str(dict, S_LEN("points_to"), buf);
+ } else {
+ (void)tv_dict_add_bool(dict, S_LEN("isunnamed"),
+ regname == buf[0] ? kBoolVarTrue : kBoolVarFalse);
+ }
+}
+
// "reg_executing()" function
static void f_reg_executing(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -8365,20 +8520,22 @@ static void f_searchpairpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_list_append_number(rettv->vval.v_list, (varnumber_T)col);
}
-/*
- * Search for a start/middle/end thing.
- * Used by searchpair(), see its documentation for the details.
- * Returns 0 or -1 for no match,
- */
-long do_searchpair(const char *spat, // start pattern
- const char *mpat, // middle pattern
- const char *epat, // end pattern
- int dir, // BACKWARD or FORWARD
- const typval_T *skip, // skip expression
- int flags, // SP_SETPCMARK and other SP_ values
- pos_T *match_pos, linenr_T lnum_stop, // stop at this line if not zero
- long time_limit // stop after this many msec
- )
+/// Search for a start/middle/end thing.
+/// Used by searchpair(), see its documentation for the details.
+///
+/// @param spat start pattern
+/// @param mpat middle pattern
+/// @param epat end pattern
+/// @param dir BACKWARD or FORWARD
+/// @param skip skip expression
+/// @param flags SP_SETPCMARK and other SP_ values
+/// @param lnum_stop stop at this line if not zero
+/// @param time_limit stop after this many msec
+///
+/// @returns 0 or -1 for no match,
+long do_searchpair(const char *spat, const char *mpat, const char *epat, int dir,
+ const typval_T *skip, int flags, pos_T *match_pos, linenr_T lnum_stop,
+ long time_limit)
FUNC_ATTR_NONNULL_ARG(1, 2, 3)
{
char_u *save_cpo;
@@ -9001,7 +9158,7 @@ static void f_setpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
pos_T pos;
int fnum;
- colnr_T curswant = -1;
+ colnr_T curswant = -1;
rettv->vval.v_number = -1;
const char *const name = tv_get_string_chk(argvars);
@@ -9039,6 +9196,36 @@ static void f_setqflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
set_qf_ll_list(NULL, argvars, rettv);
}
+/// Translate a register type string to the yank type and block length
+static int get_yank_type(char_u **const pp, MotionType *const yank_type, long *const block_len)
+ FUNC_ATTR_NONNULL_ALL
+{
+ char_u *stropt = *pp;
+ switch (*stropt) {
+ case 'v':
+ case 'c': // character-wise selection
+ *yank_type = kMTCharWise;
+ break;
+ case 'V':
+ case 'l': // line-wise selection
+ *yank_type = kMTLineWise;
+ break;
+ case 'b':
+ case Ctrl_V: // block-wise selection
+ *yank_type = kMTBlockWise;
+ if (ascii_isdigit(stropt[1])) {
+ stropt++;
+ *block_len = getdigits_long(&stropt, false, 0) - 1;
+ stropt--;
+ }
+ break;
+ default:
+ return FAIL;
+ }
+ *pp = stropt;
+ return OK;
+}
+
/*
* "setreg()" function
*/
@@ -9063,8 +9250,53 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
regname = '"';
}
+ const typval_T *regcontents = NULL;
+ int pointreg = 0;
+ if (argvars[1].v_type == VAR_DICT) {
+ dict_T *const d = argvars[1].vval.v_dict;
+
+ if (tv_dict_len(d) == 0) {
+ // Empty dict, clear the register (like setreg(0, []))
+ char_u *lstval[2] = { NULL, NULL };
+ write_reg_contents_lst(regname, lstval, false, kMTUnknown, -1);
+ return;
+ }
+
+ dictitem_T *const di = tv_dict_find(d, "regcontents", -1);
+ if (di != NULL) {
+ regcontents = &di->di_tv;
+ }
+
+ const char *stropt = tv_dict_get_string(d, "regtype", false);
+ if (stropt != NULL) {
+ const int ret = get_yank_type((char_u **)&stropt, &yank_type, &block_len);
+
+ if (ret == FAIL || *(++stropt) != NUL) {
+ EMSG2(_(e_invargval), "value");
+ return;
+ }
+ }
+
+ if (regname == '"') {
+ stropt = tv_dict_get_string(d, "points_to", false);
+ if (stropt != NULL) {
+ pointreg = *stropt;
+ regname = pointreg;
+ }
+ } else if (tv_dict_get_number(d, "isunnamed")) {
+ pointreg = regname;
+ }
+ } else {
+ regcontents = &argvars[1];
+ }
+
bool set_unnamed = false;
if (argvars[2].v_type != VAR_UNKNOWN) {
+ if (yank_type != kMTUnknown) {
+ EMSG2(_(e_toomanyarg), "setreg");
+ return;
+ }
+
const char *stropt = tv_get_string_chk(&argvars[2]);
if (stropt == NULL) {
return; // Type error.
@@ -9075,33 +9307,18 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
case 'A': // append
append = true;
break;
- case 'v':
- case 'c': // character-wise selection
- yank_type = kMTCharWise;
- break;
- case 'V':
- case 'l': // line-wise selection
- yank_type = kMTLineWise;
- break;
- case 'b':
- case Ctrl_V: // block-wise selection
- yank_type = kMTBlockWise;
- if (ascii_isdigit(stropt[1])) {
- stropt++;
- block_len = getdigits_long((char_u **)&stropt, true, 0) - 1;
- stropt--;
- }
- break;
case 'u':
case '"': // unnamed register
set_unnamed = true;
break;
+ default:
+ get_yank_type((char_u **)&stropt, &yank_type, &block_len);
}
}
}
- if (argvars[1].v_type == VAR_LIST) {
- list_T *ll = argvars[1].vval.v_list;
+ if (regcontents != NULL && regcontents->v_type == VAR_LIST) {
+ list_T *const ll = regcontents->vval.v_list;
// If the list is NULL handle like an empty list.
const int len = tv_list_len(ll);
@@ -9137,14 +9354,17 @@ free_lstval:
xfree(*--curallocval);
}
xfree(lstval);
- } else {
- const char *strval = tv_get_string_chk(&argvars[1]);
+ } else if (regcontents != NULL) {
+ const char *const strval = tv_get_string_chk(regcontents);
if (strval == NULL) {
return;
}
write_reg_contents_ex(regname, (const char_u *)strval, STRLEN(strval),
append, yank_type, block_len);
}
+ if (pointreg != 0) {
+ get_yank_register(pointreg, YREG_YANK);
+ }
rettv->vval.v_number = 0;
if (set_unnamed) {
@@ -9201,7 +9421,7 @@ static void f_settagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static char *e_invact2 = N_("E962: Invalid action: '%s'");
win_T *wp;
dict_T *d;
- int action = 'r';
+ int action = 'r';
rettv->vval.v_number = -1;
@@ -9424,7 +9644,7 @@ static void f_sign_jump(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
// Sign group
- const char * sign_group_chk = tv_get_string_chk(&argvars[1]);
+ const char *sign_group_chk = tv_get_string_chk(&argvars[1]);
if (sign_group_chk == NULL) {
return;
}
@@ -10683,7 +10903,7 @@ static void f_strridx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_strtrans(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)transstr(tv_get_string(&argvars[0]));
+ rettv->vval.v_string = (char_u *)transstr(tv_get_string(&argvars[0]), true);
}
/*
@@ -11187,7 +11407,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (new_cwd && *new_cwd != NUL) {
cwd = new_cwd;
// The new cwd must be a directory.
- if (!os_isdir_executable((const char *)cwd)) {
+ if (!os_isdir_executable(cwd)) {
EMSG2(_(e_invarg2), "expected valid directory");
shell_free_argv(argv);
return;
@@ -11834,10 +12054,10 @@ static void f_winrestcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
snprintf((char *)buf, sizeof(buf), "%dresize %d|", winnr,
wp->w_height);
- ga_concat(&ga, buf);
+ ga_concat(&ga, (char *)buf);
snprintf((char *)buf, sizeof(buf), "vert %dresize %d|", winnr,
wp->w_width);
- ga_concat(&ga, buf);
+ ga_concat(&ga, (char *)buf);
winnr++;
}
}
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index 3bc4ec9381..6300ce6150 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -100,7 +100,7 @@ void list_write_log(const char *const fname)
}
}
-#ifdef EXITFREE
+# ifdef EXITFREE
/// Free list log
void list_free_log(void)
{
@@ -110,7 +110,7 @@ void list_free_log(void)
chunk = list_log_first;
}
}
-#endif
+# endif
#endif
//{{{2 List item
@@ -789,12 +789,12 @@ static int list_join_inner(garray_T *const gap, list_T *const l, const char *con
if (first) {
first = false;
} else {
- ga_concat(gap, (const char_u *)sep);
+ ga_concat(gap, sep);
}
const Join *const p = ((const Join *)join_gap->ga_data) + i;
if (p->s != NULL) {
- ga_concat(gap, p->s);
+ ga_concat(gap, (char *)p->s);
}
line_breakcheck();
}
@@ -2861,7 +2861,7 @@ bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic, const boo
char buf2[NUMBUFLEN];
const char *s1 = tv_get_string_buf(tv1, buf1);
const char *s2 = tv_get_string_buf(tv2, buf2);
- return mb_strcmp_ic((bool)ic, s1, s2) == 0;
+ return mb_strcmp_ic(ic, s1, s2) == 0;
}
case VAR_BOOL:
return tv1->vval.v_bool == tv2->vval.v_bool;
@@ -3260,7 +3260,7 @@ const char *tv_get_string(const typval_T *const tv)
const char *tv_get_string_buf(const typval_T *const tv, char *const buf)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
{
- const char *const res = (const char *)tv_get_string_buf_chk(tv, buf);
+ const char *const res = tv_get_string_buf_chk(tv, buf);
return res != NULL ? res : "";
}
diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h
index 5aecaccee9..a28feffd0b 100644
--- a/src/nvim/eval/typval.h
+++ b/src/nvim/eval/typval.h
@@ -1,23 +1,23 @@
#ifndef NVIM_EVAL_TYPVAL_H
#define NVIM_EVAL_TYPVAL_H
+#include <assert.h>
#include <inttypes.h>
+#include <stdbool.h>
#include <stddef.h>
#include <string.h>
-#include <stdbool.h>
-#include <assert.h>
-#include "nvim/types.h"
-#include "nvim/hashtab.h"
-#include "nvim/garray.h"
-#include "nvim/mbyte.h"
#include "nvim/func_attr.h"
-#include "nvim/lib/queue.h"
-#include "nvim/profile.h" // for proftime_T
-#include "nvim/pos.h" // for linenr_T
+#include "nvim/garray.h"
#include "nvim/gettext.h"
-#include "nvim/message.h"
+#include "nvim/hashtab.h"
+#include "nvim/lib/queue.h"
#include "nvim/macros.h"
+#include "nvim/mbyte.h"
+#include "nvim/message.h"
+#include "nvim/pos.h" // for linenr_T
+#include "nvim/profile.h" // for proftime_T
+#include "nvim/types.h"
#ifdef LOG_LIST_ACTIONS
# include "nvim/memory.h"
#endif
@@ -156,8 +156,8 @@ typedef enum {
typedef struct listitem_S listitem_T;
struct listitem_S {
- listitem_T *li_next; ///< Next item in list.
- listitem_T *li_prev; ///< Previous item in list.
+ listitem_T *li_next; ///< Next item in list.
+ listitem_T *li_prev; ///< Previous item in list.
typval_T li_tv; ///< Item value.
};
@@ -195,25 +195,25 @@ typedef struct {
} staticList10_T;
#define TV_LIST_STATIC10_INIT { \
- .sl_list = { \
- .lv_first = NULL, \
- .lv_last = NULL, \
- .lv_refcount = 0, \
- .lv_len = 0, \
- .lv_watch = NULL, \
- .lv_idx_item = NULL, \
- .lv_lock = VAR_FIXED, \
- .lv_used_next = NULL, \
- .lv_used_prev = NULL, \
- }, \
- }
+ .sl_list = { \
+ .lv_first = NULL, \
+ .lv_last = NULL, \
+ .lv_refcount = 0, \
+ .lv_len = 0, \
+ .lv_watch = NULL, \
+ .lv_idx_item = NULL, \
+ .lv_lock = VAR_FIXED, \
+ .lv_used_next = NULL, \
+ .lv_used_prev = NULL, \
+ }, \
+}
#define TV_DICTITEM_STRUCT(...) \
- struct { \
- typval_T di_tv; /* Structure that holds scope dictionary itself. */ \
- uint8_t di_flags; /* Flags. */ \
- char_u di_key[__VA_ARGS__]; /* Key value. */ \
- }
+ struct { \
+ typval_T di_tv; /* Structure that holds scope dictionary itself. */ \
+ uint8_t di_flags; /* Flags. */ \
+ char_u di_key[__VA_ARGS__]; /* Key value. */ \
+ }
/// Structure to hold a scope dictionary
///
@@ -321,40 +321,40 @@ struct funccall_S {
/// Structure to hold info for a user function.
struct ufunc {
- int uf_varargs; ///< variable nr of arguments
- int uf_flags;
- int uf_calls; ///< nr of active calls
- bool uf_cleared; ///< func_clear() was already called
- garray_T uf_args; ///< arguments
- garray_T uf_def_args; ///< default argument expressions
- garray_T uf_lines; ///< function lines
- int uf_profiling; ///< true when func is being profiled
- int uf_prof_initialized;
+ int uf_varargs; ///< variable nr of arguments
+ int uf_flags;
+ int uf_calls; ///< nr of active calls
+ bool uf_cleared; ///< func_clear() was already called
+ garray_T uf_args; ///< arguments
+ garray_T uf_def_args; ///< default argument expressions
+ garray_T uf_lines; ///< function lines
+ int uf_profiling; ///< true when func is being profiled
+ int uf_prof_initialized;
// Managing cfuncs
- cfunc_T uf_cb; ///< C function extension callback
+ cfunc_T uf_cb; ///< C function extension callback
cfunc_free_T uf_cb_free; ///< C function extension free callback
- void *uf_cb_state; ///< State of C function extension.
+ void *uf_cb_state; ///< State of C function extension.
// Profiling the function as a whole.
- int uf_tm_count; ///< nr of calls
- proftime_T uf_tm_total; ///< time spent in function + children
- proftime_T uf_tm_self; ///< time spent in function itself
- proftime_T uf_tm_children; ///< time spent in children this call
+ int uf_tm_count; ///< nr of calls
+ proftime_T uf_tm_total; ///< time spent in function + children
+ proftime_T uf_tm_self; ///< time spent in function itself
+ proftime_T uf_tm_children; ///< time spent in children this call
// Profiling the function per line.
- int *uf_tml_count; ///< nr of times line was executed
- proftime_T *uf_tml_total; ///< time spent in a line + children
- proftime_T *uf_tml_self; ///< time spent in a line itself
- proftime_T uf_tml_start; ///< start time for current line
- proftime_T uf_tml_children; ///< time spent in children for this line
- proftime_T uf_tml_wait; ///< start wait time for current line
- int uf_tml_idx; ///< index of line being timed; -1 if none
- int uf_tml_execed; ///< line being timed was executed
- sctx_T uf_script_ctx; ///< SCTX where function was defined,
- ///< used for s: variables
- int uf_refcount; ///< reference count, see func_name_refcount()
- funccall_T *uf_scoped; ///< l: local variables for closure
- char_u uf_name[]; ///< Name of function (actual size equals name);
- ///< can start with <SNR>123_
- ///< (<SNR> is K_SPECIAL KS_EXTRA KE_SNR)
+ int *uf_tml_count; ///< nr of times line was executed
+ proftime_T *uf_tml_total; ///< time spent in a line + children
+ proftime_T *uf_tml_self; ///< time spent in a line itself
+ proftime_T uf_tml_start; ///< start time for current line
+ proftime_T uf_tml_children; ///< time spent in children for this line
+ proftime_T uf_tml_wait; ///< start wait time for current line
+ int uf_tml_idx; ///< index of line being timed; -1 if none
+ int uf_tml_execed; ///< line being timed was executed
+ sctx_T uf_script_ctx; ///< SCTX where function was defined,
+ ///< used for s: variables
+ int uf_refcount; ///< reference count, see func_name_refcount()
+ funccall_T *uf_scoped; ///< l: local variables for closure
+ char_u uf_name[]; ///< Name of function (actual size equals name);
+ ///< can start with <SNR>123_
+ ///< (<SNR> is K_SPECIAL KS_EXTRA KE_SNR)
};
struct partial_S {
@@ -452,10 +452,8 @@ static inline void list_log(const list_T *const l,
/// @param[in] li1 List item 1.
/// @param[in] li2 List item 2, often used for integers and not list items.
/// @param[in] action Logged action.
-static inline void list_log(const list_T *const l,
- const listitem_T *const li1,
- const listitem_T *const li2,
- const char *const action)
+static inline void list_log(const list_T *const l, const listitem_T *const li1,
+ const listitem_T *const li2, const char *const action)
{
ListLog *tgt;
if (list_log_first == NULL) {
@@ -484,7 +482,7 @@ static inline void list_log(const list_T *const l,
/// Convert a hashitem pointer to a dictitem pointer
#define TV_DICT_HI2DI(hi) \
- ((dictitem_T *)((hi)->hi_key - offsetof(dictitem_T, di_key)))
+ ((dictitem_T *)((hi)->hi_key - offsetof(dictitem_T, di_key)))
static inline void tv_list_ref(list_T *const l)
REAL_FATTR_ALWAYS_INLINE;
@@ -538,8 +536,7 @@ static inline VarLockStatus tv_list_locked(const list_T *const l)
///
/// @param[out] l List to modify.
/// @param[in] lock New lock status.
-static inline void tv_list_set_lock(list_T *const l,
- const VarLockStatus lock)
+static inline void tv_list_set_lock(list_T *const l, const VarLockStatus lock)
{
if (l == NULL) {
assert(lock == VAR_FIXED);
@@ -554,8 +551,7 @@ static inline void tv_list_set_lock(list_T *const l,
///
/// @param[out] l List to modify.
/// @param[in] copyid New copyID.
-static inline void tv_list_set_copyid(list_T *const l,
- const int copyid)
+static inline void tv_list_set_copyid(list_T *const l, const int copyid)
FUNC_ATTR_NONNULL_ALL
{
l->lv_copyID = copyid;
@@ -793,10 +789,10 @@ static inline void tv_init(typval_T *const tv)
}
#define TV_INITIAL_VALUE \
- ((typval_T) { \
- .v_type = VAR_UNKNOWN, \
- .v_lock = VAR_UNLOCKED, \
- })
+ ((typval_T) { \
+ .v_type = VAR_UNKNOWN, \
+ .v_lock = VAR_UNLOCKED, \
+ })
/// Empty string
///
@@ -815,16 +811,16 @@ extern bool tv_in_free_unref_items;
/// @param li Name of the variable with current listitem_T entry.
/// @param code Cycle body.
#define _TV_LIST_ITER_MOD(modifier, l, li, code) \
- do { \
- modifier list_T *const l_ = (l); \
- list_log(l_, NULL, NULL, "iter" #modifier); \
- if (l_ != NULL) { \
- for (modifier listitem_T *li = l_->lv_first; \
- li != NULL; li = li->li_next) { \
- code \
- } \
+ do { \
+ modifier list_T *const l_ = (l); \
+ list_log(l_, NULL, NULL, "iter" #modifier); \
+ if (l_ != NULL) { \
+ for (modifier listitem_T *li = l_->lv_first; \
+ li != NULL; li = li->li_next) { \
+ code \
} \
- } while (0)
+ } \
+ } while (0)
/// Iterate over a list
///
@@ -835,7 +831,7 @@ extern bool tv_in_free_unref_items;
/// @param li Name of the variable with current listitem_T entry.
/// @param code Cycle body.
#define TV_LIST_ITER(l, li, code) \
- _TV_LIST_ITER_MOD(, l, li, code)
+ _TV_LIST_ITER_MOD(, l, li, code)
/// Iterate over a list
///
@@ -846,7 +842,7 @@ extern bool tv_in_free_unref_items;
/// @param li Name of the variable with current listitem_T entry.
/// @param code Cycle body.
#define TV_LIST_ITER_CONST(l, li, code) \
- _TV_LIST_ITER_MOD(const, l, li, code)
+ _TV_LIST_ITER_MOD(const, l, li, code)
// Below macros are macros to avoid duplicating code for functionally identical
// const and non-const function variants.
@@ -883,14 +879,14 @@ extern bool tv_in_free_unref_items;
/// @param di Name of the variable with current dictitem_T entry.
/// @param code Cycle body.
#define TV_DICT_ITER(d, di, code) \
- HASHTAB_ITER(&(d)->dv_hashtab, di##hi_, { \
+ HASHTAB_ITER(&(d)->dv_hashtab, di##hi_, { \
+ { \
+ dictitem_T *const di = TV_DICT_HI2DI(di##hi_); \
{ \
- dictitem_T *const di = TV_DICT_HI2DI(di##hi_); \
- { \
- code \
- } \
+ code \
} \
- })
+ } \
+ })
static inline bool tv_get_float_chk(const typval_T *const tv,
float_T *const ret_f)
@@ -907,8 +903,7 @@ bool emsgf(const char *const fmt, ...);
/// @param[out] ret_f Location where resulting float is stored.
///
/// @return true in case of success, false if tv is not a number or float.
-static inline bool tv_get_float_chk(const typval_T *const tv,
- float_T *const ret_f)
+static inline bool tv_get_float_chk(const typval_T *const tv, float_T *const ret_f)
{
if (tv->v_type == VAR_FLOAT) {
*ret_f = tv->vval.v_float;
diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h
index cd1be1eecc..ece51cb046 100644
--- a/src/nvim/eval/typval_encode.c.h
+++ b/src/nvim/eval/typval_encode.c.h
@@ -240,15 +240,15 @@
///
/// This name will only be used by one of the above macros which are defined by
/// the caller. Functions defined here do not use first argument directly.
-#include <stddef.h>
-#include <inttypes.h>
#include <assert.h>
+#include <inttypes.h>
+#include <stddef.h>
-#include "nvim/lib/kvec.h"
-#include "nvim/eval/typval.h"
#include "nvim/eval/encode.h"
-#include "nvim/func_attr.h"
+#include "nvim/eval/typval.h"
#include "nvim/eval/typval_encode.h"
+#include "nvim/func_attr.h"
+#include "nvim/lib/kvec.h"
/// Dummy variable used because some macros need lvalue
///
@@ -257,12 +257,12 @@
const dict_T *const TYPVAL_ENCODE_NODICT_VAR = NULL;
static inline int _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(
- TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME,
- void *const val, int *const val_copyID,
- const MPConvStack *const mpstack, const int copyID,
- const MPConvStackValType conv_type,
- const char *const objname)
- REAL_FATTR_NONNULL_ARG(2, 3, 4, 7) REAL_FATTR_WARN_UNUSED_RESULT
+ TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME,
+ void *const val, int *const val_copyID,
+ const MPConvStack *const mpstack, const int copyID,
+ const MPConvStackValType conv_type,
+ const char *const objname)
+REAL_FATTR_NONNULL_ARG(2, 3, 4, 7) REAL_FATTR_WARN_UNUSED_RESULT
REAL_FATTR_ALWAYS_INLINE;
/// Function for checking whether container references itself
@@ -280,11 +280,9 @@ static inline int _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(
///
/// @return NOTDONE in case of success, what to return in case of failure.
static inline int _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(
- TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME,
- void *const val, int *const val_copyID,
- const MPConvStack *const mpstack, const int copyID,
- const MPConvStackValType conv_type,
- const char *const objname)
+ TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, void *const val, int *const val_copyID,
+ const MPConvStack *const mpstack, const int copyID, const MPConvStackValType conv_type,
+ const char *const objname)
{
if (*val_copyID == copyID) {
TYPVAL_ENCODE_CONV_RECURSE(val, conv_type);
@@ -295,11 +293,11 @@ static inline int _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(
}
static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
- TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME,
- MPConvStack *const mpstack, MPConvStackVal *const cur_mpsv,
- typval_T *const tv, const int copyID,
- const char *const objname)
- REAL_FATTR_NONNULL_ARG(2, 4, 6) REAL_FATTR_WARN_UNUSED_RESULT;
+ TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME,
+ MPConvStack *const mpstack, MPConvStackVal *const cur_mpsv,
+ typval_T *const tv, const int copyID,
+ const char *const objname)
+REAL_FATTR_NONNULL_ARG(2, 4, 6) REAL_FATTR_WARN_UNUSED_RESULT;
/// Convert single value
///
@@ -319,42 +317,35 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
///
/// @return OK in case of success, FAIL in case of failure.
static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
- TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME,
- MPConvStack *const mpstack, MPConvStackVal *const cur_mpsv,
- typval_T *const tv, const int copyID,
- const char *const objname)
+ TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, MPConvStack *const mpstack,
+ MPConvStackVal *const cur_mpsv, typval_T *const tv, const int copyID, const char *const objname)
{
switch (tv->v_type) {
- case VAR_STRING: {
- TYPVAL_ENCODE_CONV_STRING(tv, tv->vval.v_string, tv_strlen(tv));
- break;
- }
- case VAR_NUMBER: {
- TYPVAL_ENCODE_CONV_NUMBER(tv, tv->vval.v_number);
- break;
- }
- case VAR_FLOAT: {
- TYPVAL_ENCODE_CONV_FLOAT(tv, tv->vval.v_float);
- break;
- }
- case VAR_BLOB: {
- TYPVAL_ENCODE_CONV_BLOB(tv, tv->vval.v_blob,
- tv_blob_len(tv->vval.v_blob));
- break;
- }
- case VAR_FUNC: {
- TYPVAL_ENCODE_CONV_FUNC_START(tv, tv->vval.v_string);
- TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, 0);
- TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1);
- TYPVAL_ENCODE_CONV_FUNC_END(tv);
- break;
- }
- case VAR_PARTIAL: {
- partial_T *const pt = tv->vval.v_partial;
- (void)pt;
- TYPVAL_ENCODE_CONV_FUNC_START( // -V547
- tv, (pt == NULL ? NULL : partial_name(pt)));
- _mp_push(*mpstack, ((MPConvStackVal) { // -V779
+ case VAR_STRING:
+ TYPVAL_ENCODE_CONV_STRING(tv, tv->vval.v_string, tv_strlen(tv));
+ break;
+ case VAR_NUMBER:
+ TYPVAL_ENCODE_CONV_NUMBER(tv, tv->vval.v_number);
+ break;
+ case VAR_FLOAT:
+ TYPVAL_ENCODE_CONV_FLOAT(tv, tv->vval.v_float);
+ break;
+ case VAR_BLOB:
+ TYPVAL_ENCODE_CONV_BLOB(tv, tv->vval.v_blob,
+ tv_blob_len(tv->vval.v_blob));
+ break;
+ case VAR_FUNC:
+ TYPVAL_ENCODE_CONV_FUNC_START(tv, tv->vval.v_string);
+ TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, 0);
+ TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1);
+ TYPVAL_ENCODE_CONV_FUNC_END(tv);
+ break;
+ case VAR_PARTIAL: {
+ partial_T *const pt = tv->vval.v_partial;
+ (void)pt;
+ TYPVAL_ENCODE_CONV_FUNC_START( // -V547
+ tv, (pt == NULL ? NULL : partial_name(pt)));
+ _mp_push(*mpstack, ((MPConvStackVal) { // -V779
.type = kMPConvPartial,
.tv = tv,
.saved_copyID = copyID - 1,
@@ -365,19 +356,19 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
},
},
}));
+ break;
+ }
+ case VAR_LIST: {
+ if (tv->vval.v_list == NULL || tv_list_len(tv->vval.v_list) == 0) {
+ TYPVAL_ENCODE_CONV_EMPTY_LIST(tv);
break;
}
- case VAR_LIST: {
- if (tv->vval.v_list == NULL || tv_list_len(tv->vval.v_list) == 0) {
- TYPVAL_ENCODE_CONV_EMPTY_LIST(tv);
- break;
- }
- const int saved_copyID = tv_list_copyid(tv->vval.v_list);
- _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_list, lv_copyID, copyID,
- kMPConvList);
- TYPVAL_ENCODE_CONV_LIST_START(tv, tv_list_len(tv->vval.v_list));
- assert(saved_copyID != copyID);
- _mp_push(*mpstack, ((MPConvStackVal) {
+ const int saved_copyID = tv_list_copyid(tv->vval.v_list);
+ _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_list, lv_copyID, copyID,
+ kMPConvList);
+ TYPVAL_ENCODE_CONV_LIST_START(tv, tv_list_len(tv->vval.v_list));
+ assert(saved_copyID != copyID);
+ _mp_push(*mpstack, ((MPConvStackVal) {
.type = kMPConvList,
.tv = tv,
.saved_copyID = saved_copyID,
@@ -388,159 +379,151 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
},
},
}));
- TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, _mp_last(*mpstack));
+ TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, _mp_last(*mpstack));
+ break;
+ }
+ case VAR_BOOL:
+ switch (tv->vval.v_bool) {
+ case kBoolVarTrue:
+ case kBoolVarFalse:
+ TYPVAL_ENCODE_CONV_BOOL(tv, tv->vval.v_bool == kBoolVarTrue);
break;
}
- case VAR_BOOL: {
- switch (tv->vval.v_bool) {
- case kBoolVarTrue:
- case kBoolVarFalse: {
- TYPVAL_ENCODE_CONV_BOOL(tv, tv->vval.v_bool == kBoolVarTrue);
- break;
- }
- }
+ break;
+ case VAR_SPECIAL:
+ switch (tv->vval.v_special) {
+ case kSpecialVarNull:
+ TYPVAL_ENCODE_CONV_NIL(tv); // -V1037
break;
}
- case VAR_SPECIAL: {
- switch (tv->vval.v_special) {
- case kSpecialVarNull: {
- TYPVAL_ENCODE_CONV_NIL(tv); // -V1037
+ break;
+ case VAR_DICT: {
+ if (tv->vval.v_dict == NULL
+ || tv->vval.v_dict->dv_hashtab.ht_used == 0) {
+ TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, tv->vval.v_dict);
+ break;
+ }
+ const dictitem_T *type_di;
+ const dictitem_T *val_di;
+ if (TYPVAL_ENCODE_ALLOW_SPECIALS
+ && tv->vval.v_dict->dv_hashtab.ht_used == 2
+ && (type_di = tv_dict_find((dict_T *)tv->vval.v_dict,
+ S_LEN("_TYPE"))) != NULL
+ && type_di->di_tv.v_type == VAR_LIST
+ && (val_di = tv_dict_find((dict_T *)tv->vval.v_dict,
+ S_LEN("_VAL"))) != NULL) {
+ size_t i;
+ for (i = 0; i < ARRAY_SIZE(eval_msgpack_type_lists); i++) {
+ if (type_di->di_tv.vval.v_list == eval_msgpack_type_lists[i]) {
break;
}
}
- break;
- }
- case VAR_DICT: {
- if (tv->vval.v_dict == NULL
- || tv->vval.v_dict->dv_hashtab.ht_used == 0) {
- TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, tv->vval.v_dict);
- break;
+ if (i == ARRAY_SIZE(eval_msgpack_type_lists)) {
+ goto _convert_one_value_regular_dict;
}
- const dictitem_T *type_di;
- const dictitem_T *val_di;
- if (TYPVAL_ENCODE_ALLOW_SPECIALS
- && tv->vval.v_dict->dv_hashtab.ht_used == 2
- && (type_di = tv_dict_find((dict_T *)tv->vval.v_dict,
- S_LEN("_TYPE"))) != NULL
- && type_di->di_tv.v_type == VAR_LIST
- && (val_di = tv_dict_find((dict_T *)tv->vval.v_dict,
- S_LEN("_VAL"))) != NULL) {
- size_t i;
- for (i = 0; i < ARRAY_SIZE(eval_msgpack_type_lists); i++) {
- if (type_di->di_tv.vval.v_list == eval_msgpack_type_lists[i]) {
- break;
- }
+ switch ((MessagePackType)i) {
+ case kMPNil:
+ TYPVAL_ENCODE_CONV_NIL(tv);
+ break;
+ case kMPBoolean:
+ if (val_di->di_tv.v_type != VAR_NUMBER) {
+ goto _convert_one_value_regular_dict;
}
- if (i == ARRAY_SIZE(eval_msgpack_type_lists)) {
+ TYPVAL_ENCODE_CONV_BOOL(tv, val_di->di_tv.vval.v_number);
+ break;
+ case kMPInteger: {
+ const list_T *val_list;
+ varnumber_T sign;
+ varnumber_T highest_bits;
+ varnumber_T high_bits;
+ varnumber_T low_bits;
+ // List of 4 integers; first is signed (should be 1 or -1, but
+ // this is not checked), second is unsigned and have at most
+ // one (sign is -1) or two (sign is 1) non-zero bits (number of
+ // bits is not checked), other unsigned and have at most 31
+ // non-zero bits (number of bits is not checked).
+ if (val_di->di_tv.v_type != VAR_LIST
+ || tv_list_len(val_list = val_di->di_tv.vval.v_list) != 4) {
goto _convert_one_value_regular_dict;
}
- switch ((MessagePackType)i) {
- case kMPNil: {
- TYPVAL_ENCODE_CONV_NIL(tv);
- break;
- }
- case kMPBoolean: {
- if (val_di->di_tv.v_type != VAR_NUMBER) {
- goto _convert_one_value_regular_dict;
- }
- TYPVAL_ENCODE_CONV_BOOL(tv, val_di->di_tv.vval.v_number);
- break;
- }
- case kMPInteger: {
- const list_T *val_list;
- varnumber_T sign;
- varnumber_T highest_bits;
- varnumber_T high_bits;
- varnumber_T low_bits;
- // List of 4 integers; first is signed (should be 1 or -1, but
- // this is not checked), second is unsigned and have at most
- // one (sign is -1) or two (sign is 1) non-zero bits (number of
- // bits is not checked), other unsigned and have at most 31
- // non-zero bits (number of bits is not checked).
- if (val_di->di_tv.v_type != VAR_LIST
- || tv_list_len(val_list = val_di->di_tv.vval.v_list) != 4) {
- goto _convert_one_value_regular_dict;
- }
- const listitem_T *const sign_li = tv_list_first(val_list);
- if (TV_LIST_ITEM_TV(sign_li)->v_type != VAR_NUMBER
- || (sign = TV_LIST_ITEM_TV(sign_li)->vval.v_number) == 0) {
- goto _convert_one_value_regular_dict;
- }
+ const listitem_T *const sign_li = tv_list_first(val_list);
+ if (TV_LIST_ITEM_TV(sign_li)->v_type != VAR_NUMBER
+ || (sign = TV_LIST_ITEM_TV(sign_li)->vval.v_number) == 0) {
+ goto _convert_one_value_regular_dict;
+ }
- const listitem_T *const highest_bits_li = (
- TV_LIST_ITEM_NEXT(val_list, sign_li));
- if (TV_LIST_ITEM_TV(highest_bits_li)->v_type != VAR_NUMBER
- || ((highest_bits
- = TV_LIST_ITEM_TV(highest_bits_li)->vval.v_number)
- < 0)) {
- goto _convert_one_value_regular_dict;
- }
+ const listitem_T *const highest_bits_li = (
+ TV_LIST_ITEM_NEXT(val_list, sign_li));
+ if (TV_LIST_ITEM_TV(highest_bits_li)->v_type != VAR_NUMBER
+ || ((highest_bits
+ = TV_LIST_ITEM_TV(highest_bits_li)->vval.v_number)
+ < 0)) {
+ goto _convert_one_value_regular_dict;
+ }
- const listitem_T *const high_bits_li = (
- TV_LIST_ITEM_NEXT(val_list, highest_bits_li));
- if (TV_LIST_ITEM_TV(high_bits_li)->v_type != VAR_NUMBER
- || ((high_bits = TV_LIST_ITEM_TV(high_bits_li)->vval.v_number)
- < 0)) {
- goto _convert_one_value_regular_dict;
- }
+ const listitem_T *const high_bits_li = (
+ TV_LIST_ITEM_NEXT(val_list, highest_bits_li));
+ if (TV_LIST_ITEM_TV(high_bits_li)->v_type != VAR_NUMBER
+ || ((high_bits = TV_LIST_ITEM_TV(high_bits_li)->vval.v_number)
+ < 0)) {
+ goto _convert_one_value_regular_dict;
+ }
- const listitem_T *const low_bits_li = tv_list_last(val_list);
- if (TV_LIST_ITEM_TV(low_bits_li)->v_type != VAR_NUMBER
- || ((low_bits = TV_LIST_ITEM_TV(low_bits_li)->vval.v_number)
- < 0)) {
- goto _convert_one_value_regular_dict;
- }
+ const listitem_T *const low_bits_li = tv_list_last(val_list);
+ if (TV_LIST_ITEM_TV(low_bits_li)->v_type != VAR_NUMBER
+ || ((low_bits = TV_LIST_ITEM_TV(low_bits_li)->vval.v_number)
+ < 0)) {
+ goto _convert_one_value_regular_dict;
+ }
- const uint64_t number = ((uint64_t)(((uint64_t)highest_bits) << 62)
- | (uint64_t)(((uint64_t)high_bits) << 31)
- | (uint64_t)low_bits);
- if (sign > 0) {
- TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, number);
- } else {
- TYPVAL_ENCODE_CONV_NUMBER(tv, -number);
- }
- break;
- }
- case kMPFloat: {
- if (val_di->di_tv.v_type != VAR_FLOAT) {
- goto _convert_one_value_regular_dict;
- }
- TYPVAL_ENCODE_CONV_FLOAT(tv, val_di->di_tv.vval.v_float);
- break;
- }
- case kMPString:
- case kMPBinary: {
- const bool is_string = ((MessagePackType)i == kMPString);
- if (val_di->di_tv.v_type != VAR_LIST) {
- goto _convert_one_value_regular_dict;
- }
- size_t len;
- char *buf;
- if (!encode_vim_list_to_buf(val_di->di_tv.vval.v_list, &len,
- &buf)) {
- goto _convert_one_value_regular_dict;
- }
- if (is_string) {
- TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len);
- } else { // -V523
- TYPVAL_ENCODE_CONV_STRING(tv, buf, len);
- }
- xfree(buf);
- break;
- }
- case kMPArray: {
- if (val_di->di_tv.v_type != VAR_LIST) {
- goto _convert_one_value_regular_dict;
- }
- const int saved_copyID = tv_list_copyid(val_di->di_tv.vval.v_list);
- _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_di->di_tv.vval.v_list,
- lv_copyID, copyID,
- kMPConvList);
- TYPVAL_ENCODE_CONV_LIST_START(
- tv, tv_list_len(val_di->di_tv.vval.v_list));
- assert(saved_copyID != copyID && saved_copyID != copyID - 1);
- _mp_push(*mpstack, ((MPConvStackVal) {
+ const uint64_t number = ((uint64_t)(((uint64_t)highest_bits) << 62)
+ | (uint64_t)(((uint64_t)high_bits) << 31)
+ | (uint64_t)low_bits);
+ if (sign > 0) {
+ TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, number);
+ } else {
+ TYPVAL_ENCODE_CONV_NUMBER(tv, -number);
+ }
+ break;
+ }
+ case kMPFloat:
+ if (val_di->di_tv.v_type != VAR_FLOAT) {
+ goto _convert_one_value_regular_dict;
+ }
+ TYPVAL_ENCODE_CONV_FLOAT(tv, val_di->di_tv.vval.v_float);
+ break;
+ case kMPString:
+ case kMPBinary: {
+ const bool is_string = ((MessagePackType)i == kMPString);
+ if (val_di->di_tv.v_type != VAR_LIST) {
+ goto _convert_one_value_regular_dict;
+ }
+ size_t len;
+ char *buf;
+ if (!encode_vim_list_to_buf(val_di->di_tv.vval.v_list, &len,
+ &buf)) {
+ goto _convert_one_value_regular_dict;
+ }
+ if (is_string) {
+ TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len);
+ } else { // -V523
+ TYPVAL_ENCODE_CONV_STRING(tv, buf, len);
+ }
+ xfree(buf);
+ break;
+ }
+ case kMPArray: {
+ if (val_di->di_tv.v_type != VAR_LIST) {
+ goto _convert_one_value_regular_dict;
+ }
+ const int saved_copyID = tv_list_copyid(val_di->di_tv.vval.v_list);
+ _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_di->di_tv.vval.v_list,
+ lv_copyID, copyID,
+ kMPConvList);
+ TYPVAL_ENCODE_CONV_LIST_START(tv, tv_list_len(val_di->di_tv.vval.v_list));
+ assert(saved_copyID != copyID && saved_copyID != copyID - 1);
+ _mp_push(*mpstack, ((MPConvStackVal) {
.tv = tv,
.type = kMPConvList,
.saved_copyID = saved_copyID,
@@ -551,31 +534,31 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
},
},
}));
- break;
- }
- case kMPMap: {
- if (val_di->di_tv.v_type != VAR_LIST) {
- goto _convert_one_value_regular_dict;
- }
- list_T *const val_list = val_di->di_tv.vval.v_list;
- if (val_list == NULL || tv_list_len(val_list) == 0) {
- TYPVAL_ENCODE_CONV_EMPTY_DICT( // -V501
- tv, TYPVAL_ENCODE_NODICT_VAR);
- break;
- }
- TV_LIST_ITER_CONST(val_list, li, {
+ break;
+ }
+ case kMPMap: {
+ if (val_di->di_tv.v_type != VAR_LIST) {
+ goto _convert_one_value_regular_dict;
+ }
+ list_T *const val_list = val_di->di_tv.vval.v_list;
+ if (val_list == NULL || tv_list_len(val_list) == 0) {
+ TYPVAL_ENCODE_CONV_EMPTY_DICT( // -V501
+ tv, TYPVAL_ENCODE_NODICT_VAR);
+ break;
+ }
+ TV_LIST_ITER_CONST(val_list, li, {
if (TV_LIST_ITEM_TV(li)->v_type != VAR_LIST
|| tv_list_len(TV_LIST_ITEM_TV(li)->vval.v_list) != 2) {
goto _convert_one_value_regular_dict;
}
});
- const int saved_copyID = tv_list_copyid(val_di->di_tv.vval.v_list);
- _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_list, lv_copyID, copyID,
- kMPConvPairs);
- TYPVAL_ENCODE_CONV_DICT_START(tv, TYPVAL_ENCODE_NODICT_VAR,
- tv_list_len(val_list));
- assert(saved_copyID != copyID && saved_copyID != copyID - 1);
- _mp_push(*mpstack, ((MPConvStackVal) {
+ const int saved_copyID = tv_list_copyid(val_di->di_tv.vval.v_list);
+ _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_list, lv_copyID, copyID,
+ kMPConvPairs);
+ TYPVAL_ENCODE_CONV_DICT_START(tv, TYPVAL_ENCODE_NODICT_VAR,
+ tv_list_len(val_list));
+ assert(saved_copyID != copyID && saved_copyID != copyID - 1);
+ _mp_push(*mpstack, ((MPConvStackVal) {
.tv = tv,
.type = kMPConvPairs,
.saved_copyID = saved_copyID,
@@ -586,46 +569,45 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
},
},
}));
- break;
- }
- case kMPExt: {
- const list_T *val_list;
- varnumber_T type;
- if (val_di->di_tv.v_type != VAR_LIST
- || tv_list_len((val_list = val_di->di_tv.vval.v_list)) != 2
- || (TV_LIST_ITEM_TV(tv_list_first(val_list))->v_type
- != VAR_NUMBER)
- || ((type
- = TV_LIST_ITEM_TV(tv_list_first(val_list))->vval.v_number)
- > INT8_MAX)
- || type < INT8_MIN
- || (TV_LIST_ITEM_TV(tv_list_last(val_list))->v_type
- != VAR_LIST)) {
- goto _convert_one_value_regular_dict;
- }
- size_t len;
- char *buf;
- if (!(
- encode_vim_list_to_buf(
- TV_LIST_ITEM_TV(tv_list_last(val_list))->vval.v_list, &len,
- &buf))) {
- goto _convert_one_value_regular_dict;
- }
- TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type);
- xfree(buf);
- break;
- }
+ break;
+ }
+ case kMPExt: {
+ const list_T *val_list;
+ varnumber_T type;
+ if (val_di->di_tv.v_type != VAR_LIST
+ || tv_list_len((val_list = val_di->di_tv.vval.v_list)) != 2
+ || (TV_LIST_ITEM_TV(tv_list_first(val_list))->v_type
+ != VAR_NUMBER)
+ || ((type
+ = TV_LIST_ITEM_TV(tv_list_first(val_list))->vval.v_number)
+ > INT8_MAX)
+ || type < INT8_MIN
+ || (TV_LIST_ITEM_TV(tv_list_last(val_list))->v_type
+ != VAR_LIST)) {
+ goto _convert_one_value_regular_dict;
+ }
+ size_t len;
+ char *buf;
+ if (!(
+ encode_vim_list_to_buf(TV_LIST_ITEM_TV(tv_list_last(val_list))->vval.v_list, &len,
+ &buf))) {
+ goto _convert_one_value_regular_dict;
}
+ TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type);
+ xfree(buf);
break;
}
+ }
+ break;
+ }
_convert_one_value_regular_dict: {}
- const int saved_copyID = tv->vval.v_dict->dv_copyID;
- _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_dict, dv_copyID, copyID,
- kMPConvDict);
- TYPVAL_ENCODE_CONV_DICT_START(tv, tv->vval.v_dict,
- tv->vval.v_dict->dv_hashtab.ht_used);
- assert(saved_copyID != copyID);
- _mp_push(*mpstack, ((MPConvStackVal) {
+ const int saved_copyID = tv->vval.v_dict->dv_copyID;
+ _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_dict, dv_copyID, copyID,
+ kMPConvDict);
+ TYPVAL_ENCODE_CONV_DICT_START(tv, tv->vval.v_dict,
+ tv->vval.v_dict->dv_hashtab.ht_used);
+ assert(saved_copyID != copyID);
+ _mp_push(*mpstack, ((MPConvStackVal) {
.tv = tv,
.type = kMPConvDict,
.saved_copyID = saved_copyID,
@@ -638,14 +620,13 @@ _convert_one_value_regular_dict: {}
},
},
}));
- TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, tv->vval.v_dict,
- _mp_last(*mpstack));
- break;
- }
- case VAR_UNKNOWN: {
- internal_error(STR(_TYPVAL_ENCODE_CONVERT_ONE_VALUE) "()");
- return FAIL;
- }
+ TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, tv->vval.v_dict,
+ _mp_last(*mpstack));
+ break;
+ }
+ case VAR_UNKNOWN:
+ internal_error(STR(_TYPVAL_ENCODE_CONVERT_ONE_VALUE) "()");
+ return FAIL;
}
typval_encode_stop_converting_one_item:
return OK;
@@ -654,9 +635,9 @@ typval_encode_stop_converting_one_item:
}
TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE(
- TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME,
- typval_T *const tv, const char *const objname)
- REAL_FATTR_NONNULL_ARG(2, 3) REAL_FATTR_WARN_UNUSED_RESULT;
+ TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME,
+ typval_T *const tv, const char *const objname)
+REAL_FATTR_NONNULL_ARG(2, 3) REAL_FATTR_WARN_UNUSED_RESULT;
/// Convert the whole typval
///
@@ -668,8 +649,8 @@ TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE(
///
/// @return OK in case of success, FAIL in case of failure.
TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE(
- TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME,
- typval_T *const top_tv, const char *const objname)
+ TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, typval_T *const top_tv,
+ const char *const objname)
{
const int copyID = get_copyID();
MPConvStack mpstack;
@@ -687,125 +668,121 @@ typval_encode_stop_converting_one_item:
MPConvStackVal *cur_mpsv = &_mp_last(mpstack);
typval_T *tv = NULL;
switch (cur_mpsv->type) {
- case kMPConvDict: {
- if (!cur_mpsv->data.d.todo) {
- (void)_mp_pop(mpstack);
- cur_mpsv->data.d.dict->dv_copyID = cur_mpsv->saved_copyID;
- TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, *cur_mpsv->data.d.dictp);
- continue;
- } else if (cur_mpsv->data.d.todo
- != cur_mpsv->data.d.dict->dv_hashtab.ht_used) {
- TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(cur_mpsv->tv,
- *cur_mpsv->data.d.dictp);
- }
- while (HASHITEM_EMPTY(cur_mpsv->data.d.hi)) {
- cur_mpsv->data.d.hi++;
- }
- dictitem_T *const di = TV_DICT_HI2DI(cur_mpsv->data.d.hi);
- cur_mpsv->data.d.todo--;
+ case kMPConvDict: {
+ if (!cur_mpsv->data.d.todo) {
+ (void)_mp_pop(mpstack);
+ cur_mpsv->data.d.dict->dv_copyID = cur_mpsv->saved_copyID;
+ TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, *cur_mpsv->data.d.dictp);
+ continue;
+ } else if (cur_mpsv->data.d.todo
+ != cur_mpsv->data.d.dict->dv_hashtab.ht_used) {
+ TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(cur_mpsv->tv,
+ *cur_mpsv->data.d.dictp);
+ }
+ while (HASHITEM_EMPTY(cur_mpsv->data.d.hi)) {
cur_mpsv->data.d.hi++;
- TYPVAL_ENCODE_CONV_STR_STRING(NULL, &di->di_key[0],
- strlen((char *)&di->di_key[0]));
- TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(cur_mpsv->tv,
- *cur_mpsv->data.d.dictp);
- tv = &di->di_tv;
- break;
}
- case kMPConvList: {
- if (cur_mpsv->data.l.li == NULL) {
- (void)_mp_pop(mpstack);
- tv_list_set_copyid(cur_mpsv->data.l.list, cur_mpsv->saved_copyID);
- TYPVAL_ENCODE_CONV_LIST_END(cur_mpsv->tv);
- continue;
- } else if (cur_mpsv->data.l.li
- != tv_list_first(cur_mpsv->data.l.list)) {
- TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(cur_mpsv->tv);
- }
- tv = TV_LIST_ITEM_TV(cur_mpsv->data.l.li);
- cur_mpsv->data.l.li = TV_LIST_ITEM_NEXT(cur_mpsv->data.l.list,
- cur_mpsv->data.l.li);
- break;
+ dictitem_T *const di = TV_DICT_HI2DI(cur_mpsv->data.d.hi);
+ cur_mpsv->data.d.todo--;
+ cur_mpsv->data.d.hi++;
+ TYPVAL_ENCODE_CONV_STR_STRING(NULL, &di->di_key[0],
+ strlen((char *)&di->di_key[0]));
+ TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(cur_mpsv->tv,
+ *cur_mpsv->data.d.dictp);
+ tv = &di->di_tv;
+ break;
+ }
+ case kMPConvList:
+ if (cur_mpsv->data.l.li == NULL) {
+ (void)_mp_pop(mpstack);
+ tv_list_set_copyid(cur_mpsv->data.l.list, cur_mpsv->saved_copyID);
+ TYPVAL_ENCODE_CONV_LIST_END(cur_mpsv->tv);
+ continue;
+ } else if (cur_mpsv->data.l.li
+ != tv_list_first(cur_mpsv->data.l.list)) {
+ TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(cur_mpsv->tv);
}
- case kMPConvPairs: {
- if (cur_mpsv->data.l.li == NULL) {
- (void)_mp_pop(mpstack);
- tv_list_set_copyid(cur_mpsv->data.l.list, cur_mpsv->saved_copyID);
- TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR);
- continue;
- } else if (cur_mpsv->data.l.li
- != tv_list_first(cur_mpsv->data.l.list)) {
- TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(
- cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR);
- }
- const list_T *const kv_pair = (
- TV_LIST_ITEM_TV(cur_mpsv->data.l.li)->vval.v_list);
- TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(
- encode_vim_to__error_ret, *TV_LIST_ITEM_TV(tv_list_first(kv_pair)));
- if (
- _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
- TYPVAL_ENCODE_FIRST_ARG_NAME, &mpstack, cur_mpsv,
- TV_LIST_ITEM_TV(tv_list_first(kv_pair)), copyID, objname)
- == FAIL) {
- goto encode_vim_to__error_ret;
- }
- TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(cur_mpsv->tv,
- TYPVAL_ENCODE_NODICT_VAR);
- tv = TV_LIST_ITEM_TV(tv_list_last(kv_pair));
- cur_mpsv->data.l.li = TV_LIST_ITEM_NEXT(cur_mpsv->data.l.list,
- cur_mpsv->data.l.li);
- break;
+ tv = TV_LIST_ITEM_TV(cur_mpsv->data.l.li);
+ cur_mpsv->data.l.li = TV_LIST_ITEM_NEXT(cur_mpsv->data.l.list,
+ cur_mpsv->data.l.li);
+ break;
+ case kMPConvPairs: {
+ if (cur_mpsv->data.l.li == NULL) {
+ (void)_mp_pop(mpstack);
+ tv_list_set_copyid(cur_mpsv->data.l.list, cur_mpsv->saved_copyID);
+ TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR);
+ continue;
+ } else if (cur_mpsv->data.l.li
+ != tv_list_first(cur_mpsv->data.l.list)) {
+ TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR);
}
- case kMPConvPartial: {
- partial_T *const pt = cur_mpsv->data.p.pt;
- tv = cur_mpsv->tv;
- (void)tv;
- switch (cur_mpsv->data.p.stage) {
- case kMPConvPartialArgs: {
- TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv,
- pt == NULL ? 0 : pt->pt_argc);
- cur_mpsv->data.p.stage = kMPConvPartialSelf;
- if (pt != NULL && pt->pt_argc > 0) {
- TYPVAL_ENCODE_CONV_LIST_START(NULL, pt->pt_argc);
- _mp_push(mpstack, ((MPConvStackVal) {
- .type = kMPConvPartialList,
- .tv = NULL,
- .saved_copyID = copyID - 1,
- .data = {
- .a = {
- .arg = pt->pt_argv,
- .argv = pt->pt_argv,
- .todo = (size_t)pt->pt_argc,
- },
+ const list_T *const kv_pair = (
+ TV_LIST_ITEM_TV(cur_mpsv->data.l.li)->vval.v_list);
+ TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(encode_vim_to__error_ret,
+ *TV_LIST_ITEM_TV(tv_list_first(kv_pair)));
+ if (
+ _TYPVAL_ENCODE_CONVERT_ONE_VALUE(TYPVAL_ENCODE_FIRST_ARG_NAME, &mpstack, cur_mpsv,
+ TV_LIST_ITEM_TV(tv_list_first(kv_pair)), copyID, objname)
+ == FAIL) {
+ goto encode_vim_to__error_ret;
+ }
+ TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(cur_mpsv->tv,
+ TYPVAL_ENCODE_NODICT_VAR);
+ tv = TV_LIST_ITEM_TV(tv_list_last(kv_pair));
+ cur_mpsv->data.l.li = TV_LIST_ITEM_NEXT(cur_mpsv->data.l.list,
+ cur_mpsv->data.l.li);
+ break;
+ }
+ case kMPConvPartial: {
+ partial_T *const pt = cur_mpsv->data.p.pt;
+ tv = cur_mpsv->tv;
+ (void)tv;
+ switch (cur_mpsv->data.p.stage) {
+ case kMPConvPartialArgs:
+ TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv,
+ pt == NULL ? 0 : pt->pt_argc);
+ cur_mpsv->data.p.stage = kMPConvPartialSelf;
+ if (pt != NULL && pt->pt_argc > 0) {
+ TYPVAL_ENCODE_CONV_LIST_START(NULL, pt->pt_argc);
+ _mp_push(mpstack, ((MPConvStackVal) {
+ .type = kMPConvPartialList,
+ .tv = NULL,
+ .saved_copyID = copyID - 1,
+ .data = {
+ .a = {
+ .arg = pt->pt_argv,
+ .argv = pt->pt_argv,
+ .todo = (size_t)pt->pt_argc,
},
- }));
+ },
+ }));
+ }
+ break;
+ case kMPConvPartialSelf: {
+ cur_mpsv->data.p.stage = kMPConvPartialEnd;
+ dict_T *const dict = pt == NULL ? NULL : pt->pt_dict;
+ if (dict != NULL) {
+ TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, dict->dv_hashtab.ht_used);
+ if (dict->dv_hashtab.ht_used == 0) {
+ TYPVAL_ENCODE_CONV_EMPTY_DICT(NULL, pt->pt_dict);
+ continue;
+ }
+ const int saved_copyID = dict->dv_copyID;
+ const int te_csr_ret = _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(TYPVAL_ENCODE_FIRST_ARG_NAME,
+ dict, &dict->dv_copyID,
+ &mpstack, copyID, kMPConvDict,
+ objname);
+ if (te_csr_ret != NOTDONE) {
+ if (te_csr_ret == FAIL) {
+ goto encode_vim_to__error_ret;
+ } else {
+ continue;
}
- break;
}
- case kMPConvPartialSelf: {
- cur_mpsv->data.p.stage = kMPConvPartialEnd;
- dict_T *const dict = pt == NULL ? NULL : pt->pt_dict;
- if (dict != NULL) {
- TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, dict->dv_hashtab.ht_used);
- if (dict->dv_hashtab.ht_used == 0) {
- TYPVAL_ENCODE_CONV_EMPTY_DICT(NULL, pt->pt_dict);
- continue;
- }
- const int saved_copyID = dict->dv_copyID;
- const int te_csr_ret = _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(
- TYPVAL_ENCODE_FIRST_ARG_NAME,
- dict, &dict->dv_copyID, &mpstack, copyID, kMPConvDict,
- objname);
- if (te_csr_ret != NOTDONE) {
- if (te_csr_ret == FAIL) {
- goto encode_vim_to__error_ret;
- } else {
- continue;
- }
- }
- TYPVAL_ENCODE_CONV_DICT_START(NULL, pt->pt_dict,
- dict->dv_hashtab.ht_used);
- assert(saved_copyID != copyID && saved_copyID != copyID - 1);
- _mp_push(mpstack, ((MPConvStackVal) {
+ TYPVAL_ENCODE_CONV_DICT_START(NULL, pt->pt_dict,
+ dict->dv_hashtab.ht_used);
+ assert(saved_copyID != copyID && saved_copyID != copyID - 1);
+ _mp_push(mpstack, ((MPConvStackVal) {
.type = kMPConvDict,
.tv = NULL,
.saved_copyID = saved_copyID,
@@ -818,33 +795,31 @@ typval_encode_stop_converting_one_item:
},
},
}));
- TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(NULL, pt->pt_dict,
- _mp_last(mpstack));
- } else {
- TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1);
- }
- break;
- }
- case kMPConvPartialEnd: {
- TYPVAL_ENCODE_CONV_FUNC_END(tv);
- (void)_mp_pop(mpstack);
- break;
- }
+ TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(NULL, pt->pt_dict,
+ _mp_last(mpstack));
+ } else {
+ TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1);
}
- continue;
+ break;
}
- case kMPConvPartialList: {
- if (!cur_mpsv->data.a.todo) {
- (void)_mp_pop(mpstack);
- TYPVAL_ENCODE_CONV_LIST_END(NULL);
- continue;
- } else if (cur_mpsv->data.a.argv != cur_mpsv->data.a.arg) {
- TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(NULL);
- }
- tv = cur_mpsv->data.a.arg++;
- cur_mpsv->data.a.todo--;
+ case kMPConvPartialEnd:
+ TYPVAL_ENCODE_CONV_FUNC_END(tv);
+ (void)_mp_pop(mpstack);
break;
}
+ continue;
+ }
+ case kMPConvPartialList:
+ if (!cur_mpsv->data.a.todo) {
+ (void)_mp_pop(mpstack);
+ TYPVAL_ENCODE_CONV_LIST_END(NULL);
+ continue;
+ } else if (cur_mpsv->data.a.argv != cur_mpsv->data.a.arg) {
+ TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(NULL);
+ }
+ tv = cur_mpsv->data.a.arg++;
+ cur_mpsv->data.a.todo--;
+ break;
}
assert(tv != NULL);
if (_TYPVAL_ENCODE_CONVERT_ONE_VALUE(TYPVAL_ENCODE_FIRST_ARG_NAME, &mpstack,
diff --git a/src/nvim/eval/typval_encode.h b/src/nvim/eval/typval_encode.h
index 3475f6d8b3..d5cf431870 100644
--- a/src/nvim/eval/typval_encode.h
+++ b/src/nvim/eval/typval_encode.h
@@ -5,14 +5,14 @@
#ifndef NVIM_EVAL_TYPVAL_ENCODE_H
#define NVIM_EVAL_TYPVAL_ENCODE_H
-#include <stddef.h>
+#include <assert.h>
#include <inttypes.h>
+#include <stddef.h>
#include <string.h>
-#include <assert.h>
-#include "nvim/lib/kvec.h"
#include "nvim/eval/typval.h"
#include "nvim/func_attr.h"
+#include "nvim/lib/kvec.h"
/// Type of the stack entry
typedef enum {
@@ -87,7 +87,7 @@ static inline size_t tv_strlen(const typval_T *const tv)
assert(tv->v_type == VAR_STRING);
return (tv->vval.v_string == NULL
? 0
- : strlen((char *) tv->vval.v_string));
+ : strlen((char *)tv->vval.v_string));
}
/// Code for checking whether container references itself
@@ -100,19 +100,19 @@ static inline size_t tv_strlen(const typval_T *const tv)
/// @param conv_type Type of the conversion, @see MPConvStackValType.
#define _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val, copyID_attr, copyID, \
conv_type) \
- do { \
- const int te_csr_ret = _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( \
- TYPVAL_ENCODE_FIRST_ARG_NAME, \
- (val), &(val)->copyID_attr, mpstack, copyID, conv_type, objname); \
- if (te_csr_ret != NOTDONE) { \
- return te_csr_ret; \
- } \
- } while (0)
+ do { \
+ const int te_csr_ret = _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(TYPVAL_ENCODE_FIRST_ARG_NAME, \
+ (val), &(val)->copyID_attr, mpstack, \
+ copyID, conv_type, objname); \
+ if (te_csr_ret != NOTDONE) { \
+ return te_csr_ret; \
+ } \
+ } while (0)
#define _TYPVAL_ENCODE_FUNC_NAME_INNER_2(pref, name, suf) \
- pref##name##suf
+ pref##name##suf
#define _TYPVAL_ENCODE_FUNC_NAME_INNER(pref, name, suf) \
- _TYPVAL_ENCODE_FUNC_NAME_INNER_2(pref, name, suf)
+ _TYPVAL_ENCODE_FUNC_NAME_INNER_2(pref, name, suf)
/// Construct function name, possibly using macros
///
@@ -125,22 +125,22 @@ static inline size_t tv_strlen(const typval_T *const tv)
///
/// @return Concat: pref + #TYPVAL_ENCODE_NAME + suf.
#define _TYPVAL_ENCODE_FUNC_NAME(pref, suf) \
- _TYPVAL_ENCODE_FUNC_NAME_INNER(pref, TYPVAL_ENCODE_NAME, suf)
+ _TYPVAL_ENCODE_FUNC_NAME_INNER(pref, TYPVAL_ENCODE_NAME, suf)
/// Self reference checker function name
#define _TYPVAL_ENCODE_CHECK_SELF_REFERENCE \
- _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _check_self_reference)
+ _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _check_self_reference)
/// Entry point function name
#define _TYPVAL_ENCODE_ENCODE \
- _TYPVAL_ENCODE_FUNC_NAME(encode_vim_to_, )
+ _TYPVAL_ENCODE_FUNC_NAME(encode_vim_to_, )
/// Name of the …convert_one_value function
#define _TYPVAL_ENCODE_CONVERT_ONE_VALUE \
- _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _convert_one_value)
+ _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _convert_one_value)
/// Name of the dummy const dict_T *const variable
#define TYPVAL_ENCODE_NODICT_VAR \
- _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _nodict_var)
+ _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _nodict_var)
#endif // NVIM_EVAL_TYPVAL_ENCODE_H
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index 2137804fdd..f4393a79dc 100644
--- a/src/nvim/eval/userfunc.c
+++ b/src/nvim/eval/userfunc.c
@@ -39,7 +39,7 @@
#define FC_CFUNC 0x800 // C function extension
#ifdef INCLUDE_GENERATED_DECLARATIONS
-#include "eval/userfunc.c.generated.h"
+# include "eval/userfunc.c.generated.h"
#endif
hashtab_T func_hashtab;
@@ -68,11 +68,11 @@ void func_init(void)
static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs, int *varargs,
garray_T *default_args, bool skip)
{
- bool mustend = false;
+ bool mustend = false;
char_u *arg = *argp;
char_u *p = arg;
- int c;
- int i;
+ int c;
+ int i;
if (newargs != NULL) {
ga_init(newargs, (int)sizeof(char_u *), 3);
@@ -203,10 +203,10 @@ static void register_closure(ufunc_T *fp)
/// Get a name for a lambda. Returned in static memory.
-char_u * get_lambda_name(void)
+char_u *get_lambda_name(void)
{
- static char_u name[30];
- static int lambda_no = 0;
+ static char_u name[30];
+ static int lambda_no = 0;
snprintf((char *)name, sizeof(name), "<lambda>%d", ++lambda_no);
return name;
@@ -217,16 +217,16 @@ char_u * get_lambda_name(void)
/// @return OK or FAIL. Returns NOTDONE for dict or {expr}.
int get_lambda_tv(char_u **arg, typval_T *rettv, bool evaluate)
{
- garray_T newargs = GA_EMPTY_INIT_VALUE;
+ garray_T newargs = GA_EMPTY_INIT_VALUE;
garray_T *pnewargs;
ufunc_T *fp = NULL;
partial_T *pt = NULL;
- int varargs;
- int ret;
+ int varargs;
+ int ret;
char_u *start = skipwhite(*arg + 1);
char_u *s, *e;
bool *old_eval_lavars = eval_lavars_used;
- bool eval_lavars = false;
+ bool eval_lavars = false;
// First, check if this is a lambda expression. "->" must exists.
ret = get_function_args(&start, '-', NULL, NULL, NULL, true);
@@ -402,15 +402,15 @@ void emsg_funcname(char *ermsg, const char_u *name)
}
}
-/*
- * Allocate a variable for the result of a function.
- * Return OK or FAIL.
- */
-int get_func_tv(const char_u *name, // name of the function
- int len, // length of "name" or -1 to use strlen()
- typval_T *rettv, char_u **arg, // argument, pointing to the '('
- funcexe_T *funcexe // various values
- )
+/// Allocate a variable for the result of a function.
+///
+/// @param name name of the function
+/// @param len length of "name" or -1 to use strlen()
+/// @param arg argument, pointing to the '('
+/// @param funcexe various values
+///
+/// @return OK or FAIL.
+int get_func_tv(const char_u *name, int len, typval_T *rettv, char_u **arg, funcexe_T *funcexe)
{
char_u *argp;
int ret = OK;
@@ -1436,17 +1436,18 @@ static void argv_add_base(typval_T *const basetv, typval_T **const argvars, int
/// Call a function with its resolved parameters
///
+/// @param funcname name of the function
+/// @param len length of "name" or -1 to use strlen()
+/// @param rettv [out] value goes here
+/// @param argcount_in number of "argvars"
+/// @param argvars_in vars for arguments, must have "argcount" PLUS ONE elements!
+/// @param funcexe more arguments
+///
/// @return FAIL if function cannot be called, else OK (even if an error
/// occurred while executing the function! Set `msg_list` to capture
/// the error, see do_cmdline()).
-int call_func(const char_u *funcname, // name of the function
- int len, // length of "name" or -1 to use strlen()
- typval_T *rettv, // [out] value goes here
- int argcount_in, // number of "argvars"
- typval_T *argvars_in, // vars for arguments, must have "argcount"
- // PLUS ONE elements!
- funcexe_T *funcexe // more arguments
- )
+int call_func(const char_u *funcname, int len, typval_T *rettv, int argcount_in,
+ typval_T *argvars_in, funcexe_T *funcexe)
FUNC_ATTR_NONNULL_ARG(1, 3, 5, 6)
{
int ret = FAIL;
@@ -1690,11 +1691,12 @@ static void list_func_head(ufunc_T *fp, int indent, bool force)
/// TFN_NO_DEREF: do not dereference a Funcref
/// Advances "pp" to just after the function name (if no error).
///
+/// @param skip only find the end, don't evaluate
+/// @param fdp return: info about dictionary used
+/// @param partial return: partial of a FuncRef
+///
/// @return the function name in allocated memory, or NULL for failure.
-char_u *trans_function_name(char_u **pp, bool skip, // only find the end, don't evaluate
- int flags, funcdict_T *fdp, // return: info about dictionary used
- partial_T **partial // return: partial of a FuncRef
- )
+char_u *trans_function_name(char_u **pp, bool skip, int flags, funcdict_T *fdp, partial_T **partial)
FUNC_ATTR_NONNULL_ARG(1)
{
char_u *name = NULL;
@@ -1709,8 +1711,8 @@ char_u *trans_function_name(char_u **pp, bool skip, // only
}
start = *pp;
- /* Check for hard coded <SNR>: already translated function ID (from a user
- * command). */
+ // Check for hard coded <SNR>: already translated function ID (from a user
+ // command).
if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA
&& (*pp)[2] == (int)KE_SNR) {
*pp += 3;
@@ -2032,8 +2034,8 @@ void ex_function(exarg_T *eap)
}
}
- /* An error in a function call during evaluation of an expression in magic
- * braces should not cause the function not to be defined. */
+ // An error in a function call during evaluation of an expression in magic
+ // braces should not cause the function not to be defined.
saved_did_emsg = did_emsg;
did_emsg = FALSE;
@@ -2105,8 +2107,8 @@ void ex_function(exarg_T *eap)
ga_init(&newlines, (int)sizeof(char_u *), 3);
if (!eap->skip) {
- /* Check the name of the function. Unless it's a dictionary function
- * (that we are overwriting). */
+ // Check the name of the function. Unless it's a dictionary function
+ // (that we are overwriting).
if (name != NULL) {
arg = name;
} else {
@@ -2164,8 +2166,8 @@ void ex_function(exarg_T *eap)
}
}
- /* When there is a line break use what follows for the function body.
- * Makes 'exe "func Test()\n...\nendfunc"' work. */
+ // When there is a line break use what follows for the function body.
+ // Makes 'exe "func Test()\n...\nendfunc"' work.
if (*p == '\n') {
line_arg = p + 1;
} else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg) {
@@ -2176,9 +2178,9 @@ void ex_function(exarg_T *eap)
* Read the body of the function, until ":endfunction" is found.
*/
if (KeyTyped) {
- /* Check if the function already exists, don't let the user type the
- * whole function before telling him it doesn't work! For a script we
- * need to skip the body to be able to find what follows. */
+ // Check if the function already exists, don't let the user type the
+ // whole function before telling him it doesn't work! For a script we
+ // need to skip the body to be able to find what follows.
if (!eap->skip && !eap->forceit) {
if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) {
EMSG(_(e_funcdict));
@@ -2305,8 +2307,8 @@ void ex_function(exarg_T *eap)
break;
}
- /* Increase indent inside "if", "while", "for" and "try", decrease
- * at "end". */
+ // Increase indent inside "if", "while", "for" and "try", decrease
+ // at "end".
if (indent > 2 && STRNCMP(p, "end", 3) == 0) {
indent -= 2;
} else if (STRNCMP(p, "if", 2) == 0
@@ -2421,8 +2423,8 @@ void ex_function(exarg_T *eap)
}
}
- /* Don't define the function when skipping commands or when an error was
- * detected. */
+ // Don't define the function when skipping commands or when an error was
+ // detected.
if (eap->skip || did_emsg) {
goto erret;
}
@@ -2640,8 +2642,8 @@ bool function_exists(const char *const name, bool no_deref)
NULL);
nm = skipwhite(nm);
- /* Only accept "funcname", "funcname ", "funcname (..." and
- * "funcname(...", not "funcname!...". */
+ // Only accept "funcname", "funcname ", "funcname (..." and
+ // "funcname(...", not "funcname!...".
if (p != NULL && (*nm == NUL || *nm == '(')) {
n = translated_function_exists(p);
}
@@ -2903,9 +2905,9 @@ void ex_return(exarg_T *eap)
}
}
- /* When skipping or the return gets pending, advance to the next command
- * in this line (!returning). Otherwise, ignore the rest of the line.
- * Following lines will be ignored by get_func_line(). */
+ // When skipping or the return gets pending, advance to the next command
+ // in this line (!returning). Otherwise, ignore the rest of the line.
+ // Following lines will be ignored by get_func_line().
if (returning) {
eap->nextcmd = NULL;
} else if (eap->nextcmd == NULL) { // no argument
@@ -3098,9 +3100,9 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
}
if (reanimate) {
- /* The pending return value could be overwritten by a ":return"
- * without argument in a finally clause; reset the default
- * return value. */
+ // The pending return value could be overwritten by a ":return"
+ // without argument in a finally clause; reset the default
+ // return value.
current_funccal->rettv->v_type = VAR_NUMBER;
current_funccal->rettv->vval.v_number = 0;
}
@@ -3109,9 +3111,9 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
} else {
current_funccal->returned = TRUE;
- /* If the return is carried out now, store the return value. For
- * a return immediately after reanimation, the value is already
- * there. */
+ // If the return is carried out now, store the return value. For
+ // a return immediately after reanimation, the value is already
+ // there.
if (!reanimate && rettv != NULL) {
tv_clear(current_funccal->rettv);
*current_funccal->rettv = *(typval_T *)rettv;
diff --git a/src/nvim/eval/userfunc.h b/src/nvim/eval/userfunc.h
index 3f111343d2..ed86aaad4a 100644
--- a/src/nvim/eval/userfunc.h
+++ b/src/nvim/eval/userfunc.h
@@ -8,7 +8,7 @@
typedef struct {
dict_T *fd_dict; ///< Dictionary used.
char_u *fd_newkey; ///< New key in "dict" in allocated memory.
- dictitem_T *fd_di; ///< Dictionary item used.
+ dictitem_T *fd_di; ///< Dictionary item used.
} funcdict_T;
typedef struct funccal_entry funccal_entry_T;
diff --git a/src/nvim/event/defs.h b/src/nvim/event/defs.h
index fdd4f17d5c..cf079681d0 100644
--- a/src/nvim/event/defs.h
+++ b/src/nvim/event/defs.h
@@ -11,7 +11,7 @@ typedef struct message {
argv_callback handler;
void *argv[EVENT_HANDLER_MAX_ARGC];
} Event;
-typedef void(*event_scheduler)(Event event, void *data);
+typedef void (*event_scheduler)(Event event, void *data);
#define VA_EVENT_INIT(event, h, a) \
do { \
diff --git a/src/nvim/event/loop.h b/src/nvim/event/loop.h
index f5dd23ac8b..acd1d1a334 100644
--- a/src/nvim/event/loop.h
+++ b/src/nvim/event/loop.h
@@ -2,14 +2,13 @@
#define NVIM_EVENT_LOOP_H
#include <stdint.h>
-
#include <uv.h>
+#include "nvim/event/multiqueue.h"
#include "nvim/lib/klist.h"
#include "nvim/os/time.h"
-#include "nvim/event/multiqueue.h"
-typedef void * WatcherPtr;
+typedef void *WatcherPtr;
#define _noop(x)
KLIST_INIT(WatcherPtr, WatcherPtr, _noop)
@@ -65,7 +64,7 @@ typedef struct loop {
break; \
} else if (remaining > 0) { \
uint64_t now = os_hrtime(); \
- remaining -= (int) ((now - before) / 1000000); \
+ remaining -= (int)((now - before) / 1000000); \
before = now; \
if (remaining <= 0) { \
break; \
diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h
index 20c02e4900..2b22cd95dc 100644
--- a/src/nvim/event/process.h
+++ b/src/nvim/event/process.h
@@ -1,10 +1,10 @@
#ifndef NVIM_EVENT_PROCESS_H
#define NVIM_EVENT_PROCESS_H
+#include "nvim/eval/typval.h"
#include "nvim/event/loop.h"
#include "nvim/event/rstream.h"
#include "nvim/event/wstream.h"
-#include "nvim/eval/typval.h"
typedef enum {
kProcessTypeUv,
diff --git a/src/nvim/event/rstream.h b/src/nvim/event/rstream.h
index f30ad79ee5..77418c59a2 100644
--- a/src/nvim/event/rstream.h
+++ b/src/nvim/event/rstream.h
@@ -3,7 +3,6 @@
#include <stdbool.h>
#include <stddef.h>
-
#include <uv.h>
#include "nvim/event/loop.h"
diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c
index 8569b92d56..b34fd73d52 100644
--- a/src/nvim/event/stream.c
+++ b/src/nvim/event/stream.c
@@ -20,7 +20,7 @@
// For compatibility with libuv < 1.19.0 (tested on 1.18.0)
#if UV_VERSION_MINOR < 19
-#define uv_stream_get_write_queue_size(stream) stream->write_queue_size
+# define uv_stream_get_write_queue_size(stream) stream->write_queue_size
#endif
/// Sets the stream associated with `fd` to "blocking" mode.
diff --git a/src/nvim/event/stream.h b/src/nvim/event/stream.h
index a5c33a66a2..02e816b4be 100644
--- a/src/nvim/event/stream.h
+++ b/src/nvim/event/stream.h
@@ -3,7 +3,6 @@
#include <stdbool.h>
#include <stddef.h>
-
#include <uv.h>
#include "nvim/event/loop.h"
@@ -18,7 +17,7 @@ typedef struct stream Stream;
/// @param data User-defined data
/// @param eof If the stream reached EOF.
typedef void (*stream_read_cb)(Stream *stream, RBuffer *buf, size_t count,
- void *data, bool eof);
+ void *data, bool eof);
/// Type of function called when the Stream has information about a write
/// request.
diff --git a/src/nvim/event/wstream.h b/src/nvim/event/wstream.h
index 9008de0d97..d599d29913 100644
--- a/src/nvim/event/wstream.h
+++ b/src/nvim/event/wstream.h
@@ -1,9 +1,8 @@
#ifndef NVIM_EVENT_WSTREAM_H
#define NVIM_EVENT_WSTREAM_H
-#include <stdint.h>
#include <stdbool.h>
-
+#include <stdint.h>
#include <uv.h>
#include "nvim/event/loop.h"
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index f8186c000e..4a23f284cc 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -361,8 +361,8 @@ static int linelen(int *has_tab)
return len;
}
-/* Buffer for two lines used during sorting. They are allocated to
- * contain the longest line being sorted. */
+// Buffer for two lines used during sorting. They are allocated to
+// contain the longest line being sorted.
static char_u *sortbuf1;
static char_u *sortbuf2;
@@ -404,9 +404,9 @@ static int sort_compare(const void *s1, const void *s2)
sorti_T l2 = *(sorti_T *)s2;
int result = 0;
- /* If the user interrupts, there's no way to stop qsort() immediately, but
- * if we return 0 every time, qsort will assume it's done sorting and
- * exit. */
+ // If the user interrupts, there's no way to stop qsort() immediately, but
+ // if we return 0 every time, qsort will assume it's done sorting and
+ // exit.
if (sort_abort) {
return 0;
}
@@ -702,11 +702,11 @@ void ex_sort(exarg_T *eap)
mark_adjust(eap->line2, MAXLNUM, -deleted, 0L, kExtmarkNOOP);
}
- extmark_splice(curbuf, eap->line1-1, 0,
- count, 0, old_count,
- lnum - eap->line2, 0, new_count, kExtmarkUndo);
-
if (change_occurred || deleted != 0) {
+ extmark_splice(curbuf, eap->line1-1, 0,
+ count, 0, old_count,
+ lnum - eap->line2, 0, new_count, kExtmarkUndo);
+
changed_lines(eap->line1, 0, eap->line2 + 1, -deleted, true);
}
@@ -1439,11 +1439,11 @@ static void do_filter(linenr_T line1, linenr_T line2, exarg_T *eap, char_u *cmd,
if (linecount > p_report) {
if (do_in) {
- vim_snprintf((char *)msg_buf, sizeof(msg_buf),
+ vim_snprintf(msg_buf, sizeof(msg_buf),
_("%" PRId64 " lines filtered"), (int64_t)linecount);
- if (msg(msg_buf) && !msg_scroll) {
+ if (msg((char_u *)msg_buf) && !msg_scroll) {
// save message to display it after redraw
- set_keep_msg(msg_buf, 0);
+ set_keep_msg((char_u *)msg_buf, 0);
}
} else {
msgmore((long)linecount);
@@ -1733,8 +1733,8 @@ int rename_buffer(char_u *new_fname)
*/
void ex_file(exarg_T *eap)
{
- /* ":0file" removes the file name. Check for illegal uses ":3file",
- * "0file name", etc. */
+ // ":0file" removes the file name. Check for illegal uses ":3file",
+ // "0file name", etc.
if (eap->addr_count > 0
&& (*eap->arg != NUL
|| eap->line2 > 0
@@ -1800,7 +1800,7 @@ int do_write(exarg_T *eap)
int retval = FAIL;
char_u *free_fname = NULL;
buf_T *alt_buf = NULL;
- int name_was_missing;
+ int name_was_missing;
if (not_writing()) { // check 'write' option
return FAIL;
@@ -1888,11 +1888,11 @@ int do_write(exarg_T *eap)
retval = FAIL;
goto theend;
}
- /* Exchange the file names for the current and the alternate
- * buffer. This makes it look like we are now editing the buffer
- * under the new name. Must be done before buf_write(), because
- * if there is no file name and 'cpo' contains 'F', it will set
- * the file name. */
+ // Exchange the file names for the current and the alternate
+ // buffer. This makes it look like we are now editing the buffer
+ // under the new name. Must be done before buf_write(), because
+ // if there is no file name and 'cpo' contains 'F', it will set
+ // the file name.
fname = alt_buf->b_fname;
alt_buf->b_fname = curbuf->b_fname;
curbuf->b_fname = fname;
@@ -1923,8 +1923,8 @@ int do_write(exarg_T *eap)
do_modelines(0);
}
- /* Autocommands may have changed buffer names, esp. when
- * 'autochdir' is set. */
+ // Autocommands may have changed buffer names, esp. when
+ // 'autochdir' is set.
fname = curbuf->b_sfname;
}
@@ -2003,11 +2003,11 @@ int check_overwrite(exarg_T *eap, buf_T *buf, char_u *fname, char_u *ffname, int
char_u *p;
char_u *swapname;
- /* We only try the first entry in 'directory', without checking if
- * it's writable. If the "." directory is not writable the write
- * will probably fail anyway.
- * Use 'shortname' of the current buffer, since there is no buffer
- * for the written file. */
+ // We only try the first entry in 'directory', without checking if
+ // it's writable. If the "." directory is not writable the write
+ // will probably fail anyway.
+ // Use 'shortname' of the current buffer, since there is no buffer
+ // for the written file.
if (*p_dir == NUL) {
dir = xmalloc(5);
STRCPY(dir, ".");
@@ -2294,8 +2294,8 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new
char_u *new_name = NULL;
bool did_set_swapcommand = false;
buf_T *buf;
- bufref_T bufref;
- bufref_T old_curbuf;
+ bufref_T bufref;
+ bufref_T old_curbuf;
char_u *free_fname = NULL;
int retval = FAIL;
long n;
@@ -2466,8 +2466,8 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new
}
}
- /* May jump to last used line number for a loaded buffer or when asked
- * for explicitly */
+ // May jump to last used line number for a loaded buffer or when asked
+ // for explicitly
if ((oldbuf && newlnum == ECMD_LASTL) || newlnum == ECMD_LAST) {
pos = buflist_findfpos(buf);
newlnum = pos->lnum;
@@ -2577,10 +2577,10 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new
}
}
- /* May get the window options from the last time this buffer
- * was in this window (or another window). If not used
- * before, reset the local window options to the global
- * values. Also restores old folding stuff. */
+ // May get the window options from the last time this buffer
+ // was in this window (or another window). If not used
+ // before, reset the local window options to the global
+ // values. Also restores old folding stuff.
get_winopts(curbuf);
did_get_winopts = true;
}
@@ -2621,10 +2621,10 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new
goto theend;
}
- /* Since we are starting to edit a file, consider the filetype to be
- * unset. Helps for when an autocommand changes files and expects syntax
- * highlighting to work in the other file. */
- did_filetype = FALSE;
+ // Since we are starting to edit a file, consider the filetype to be
+ // unset. Helps for when an autocommand changes files and expects syntax
+ // highlighting to work in the other file.
+ did_filetype = false;
/*
* other_file oldbuf
@@ -2828,8 +2828,8 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new
&& !auto_buf) {
int msg_scroll_save = msg_scroll;
- /* Obey the 'O' flag in 'cpoptions': overwrite any previous file
- * message. */
+ // Obey the 'O' flag in 'cpoptions': overwrite any previous file
+ // message.
if (shortmess(SHM_OVERALL) && !exiting && p_verbose == 0) {
msg_scroll = FALSE;
}
@@ -2953,8 +2953,8 @@ void ex_append(exarg_T *eap)
}
}
if (eap->getline == NULL) {
- /* No getline() function, use the lines that follow. This ends
- * when there is no more. */
+ // No getline() function, use the lines that follow. This ends
+ // when there is no more.
if (eap->nextcmd == NULL || *eap->nextcmd == NUL) {
break;
}
@@ -3078,7 +3078,7 @@ void ex_change(exarg_T *eap)
void ex_z(exarg_T *eap)
{
char_u *x;
- int64_t bigness;
+ int64_t bigness;
char_u *kind;
int minus = 0;
linenr_T start, end, curs, i;
@@ -3750,8 +3750,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle
sub_firstline = vim_strsave(ml_get(sub_firstlnum));
}
- /* Save the line number of the last change for the final
- * cursor position (just like Vi). */
+ // Save the line number of the last change for the final
+ // cursor position (just like Vi).
curwin->w_cursor.lnum = lnum;
do_again = FALSE;
@@ -3778,8 +3778,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle
goto skip;
}
- /* Normally we continue searching for a match just after the
- * previous match. */
+ // Normally we continue searching for a match just after the
+ // previous match.
matchcol = regmatch.endpos[0].col;
prev_matchcol = matchcol;
@@ -3818,8 +3818,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle
do_check_cursorbind();
}
- /* When 'cpoptions' contains "u" don't sync undo when
- * asking for confirmation. */
+ // When 'cpoptions' contains "u" don't sync undo when
+ // asking for confirmation.
if (vim_strchr(p_cpo, CPO_UNDO) != NULL) {
++no_u_sync;
}
@@ -3970,11 +3970,11 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle
}
if (typed == 'n') {
- /* For a multi-line match, put matchcol at the NUL at
- * the end of the line and set nmatch to one, so that
- * we continue looking for a match on the next line.
- * Avoids that ":%s/\nB\@=//gc" and ":%s/\n/,\r/gc"
- * get stuck when pressing 'n'. */
+ // For a multi-line match, put matchcol at the NUL at
+ // the end of the line and set nmatch to one, so that
+ // we continue looking for a match on the next line.
+ // Avoids that ":%s/\nB\@=//gc" and ":%s/\n/,\r/gc"
+ // get stuck when pressing 'n'.
if (nmatch > 1) {
matchcol = (colnr_T)STRLEN(sub_firstline);
skip_match = true;
@@ -3986,8 +3986,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle
}
}
- /* Move the cursor to the start of the match, so that we can
- * use "\=col("."). */
+ // Move the cursor to the start of the match, so that we can
+ // use "\=col(".").
curwin->w_cursor.col = regmatch.startpos[0].col;
// When the match included the "$" of the last line it may
@@ -4178,11 +4178,11 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle
// strings, e.g. :s/$/pat/g or :s/[a-z]* /(&)/g.
// But ":s/\n/#/" is OK.
skip:
- /* We already know that we did the last subst when we are at
- * the end of the line, except that a pattern like
- * "bar\|\nfoo" may match at the NUL. "lnum" can be below
- * "line2" when there is a \zs in the pattern after a line
- * break. */
+ // We already know that we did the last subst when we are at
+ // the end of the line, except that a pattern like
+ // "bar\|\nfoo" may match at the NUL. "lnum" can be below
+ // "line2" when there is a \zs in the pattern after a line
+ // break.
lastone = (skip_match
|| got_int
|| got_quit
@@ -4249,8 +4249,8 @@ skip:
nmatch_tl = 0;
}
- /* When asking, undo is saved each time, must also set
- * changed flag each time. */
+ // When asking, undo is saved each time, must also set
+ // changed flag each time.
if (subflags.do_ask) {
changed_bytes(lnum, 0);
} else {
@@ -4278,9 +4278,9 @@ skip:
* 5. break if there isn't another match in this line
*/
if (nmatch <= 0) {
- /* If the match found didn't start where we were
- * searching, do the next search in the line where we
- * found the match. */
+ // If the match found didn't start where we were
+ // searching, do the next search in the line where we
+ // found the match.
if (nmatch == -1) {
lnum -= regmatch.startpos[0].lnum;
}
@@ -4329,9 +4329,9 @@ skip:
curbuf->deleted_bytes2 = 0;
if (first_line != 0) {
- /* Need to subtract the number of added lines from "last_line" to get
- * the line number before the change (same as adding the number of
- * deleted lines). */
+ // Need to subtract the number of added lines from "last_line" to get
+ // 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);
@@ -4409,7 +4409,7 @@ skip:
pre_src_id = (int)nvim_create_namespace((String)STRING_INIT);
}
if (pre_hl_id == 0) {
- pre_hl_id = syn_check_group((char_u *)S_LEN("Substitute"));
+ pre_hl_id = syn_check_group(S_LEN("Substitute"));
}
curbuf->b_changed = save_b_changed; // preserve 'modified' during preview
preview_buf = show_sub(eap, old_cursor, &preview_lines,
@@ -4451,24 +4451,24 @@ bool do_sub_msg(bool count_only)
*msg_buf = NUL;
}
if (sub_nsubs == 1) {
- vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
+ vim_snprintf_add(msg_buf, sizeof(msg_buf),
"%s", count_only ? _("1 match") : _("1 substitution"));
} else {
- vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
+ vim_snprintf_add(msg_buf, sizeof(msg_buf),
count_only ? _("%" PRId64 " matches")
: _("%" PRId64 " substitutions"),
(int64_t)sub_nsubs);
}
if (sub_nlines == 1) {
- vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
+ vim_snprintf_add(msg_buf, sizeof(msg_buf),
"%s", _(" on 1 line"));
} else {
- vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
+ vim_snprintf_add(msg_buf, sizeof(msg_buf),
_(" on %" PRId64 " lines"), (int64_t)sub_nlines);
}
- if (msg(msg_buf)) {
+ if (msg((char_u *)msg_buf)) {
// save message to display it after redraw
- set_keep_msg(msg_buf, 0);
+ set_keep_msg((char_u *)msg_buf, 0);
}
return true;
}
@@ -4842,9 +4842,9 @@ void ex_help(exarg_T *eap)
}
fclose(helpfd);
- /* Split off help window; put it at far top if no position
- * specified, the current window is vertically split and
- * narrow. */
+ // Split off help window; put it at far top if no position
+ // specified, the current window is vertically split and
+ // narrow.
n = WSP_HELP;
if (cmdmod.split == 0 && curwin->w_width != Columns
&& curwin->w_width < 80) {
@@ -4884,9 +4884,9 @@ void ex_help(exarg_T *eap)
do_tag(tag, DT_HELP, 1, FALSE, TRUE);
- /* Delete the empty buffer if we're not using it. Careful: autocommands
- * may have jumped to another window, check that the buffer is not in a
- * window. */
+ // Delete the empty buffer if we're not using it. Careful: autocommands
+ // may have jumped to another window, check that the buffer is not in a
+ // window.
if (empty_fnum != 0 && curbuf->b_fnum != empty_fnum) {
buf = buflist_findnr(empty_fnum);
if (buf != NULL && buf->b_nwindows == 0) {
@@ -5057,11 +5057,11 @@ int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches, bool
}
if (i < 0) { // no match in table
- /* Replace "\S" with "/\\S", etc. Otherwise every tag is matched.
- * Also replace "\%^" and "\%(", they match every tag too.
- * Also "\zs", "\z1", etc.
- * Also "\@<", "\@=", "\@<=", etc.
- * And also "\_$" and "\_^". */
+ // Replace "\S" with "/\\S", etc. Otherwise every tag is matched.
+ // Also replace "\%^" and "\%(", they match every tag too.
+ // Also "\zs", "\z1", etc.
+ // Also "\@<", "\@=", "\@<=", etc.
+ // And also "\_$" and "\_^".
if (arg[0] == '\\'
&& ((arg[1] != NUL && arg[2] == NUL)
|| (vim_strchr((char_u *)"%_z@", arg[1]) != NULL
@@ -5158,8 +5158,8 @@ int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches, bool
*d++ = '\\';
}
- /* "CTRL-\_" -> "CTRL-\\_" to avoid the special meaning of "\_" in
- * "CTRL-\_CTRL-N" */
+ // "CTRL-\_" -> "CTRL-\\_" to avoid the special meaning of "\_" in
+ // "CTRL-\_CTRL-N"
if (STRNICMP(s, "CTRL-\\_", 7) == 0) {
STRCPY(d, "CTRL-\\\\");
d += 7;
@@ -5213,9 +5213,9 @@ int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches, bool
}
if (find_tags(IObuff, num_matches, matches, flags, MAXCOL, NULL) == OK
&& *num_matches > 0) {
- /* Sort the matches found on the heuristic number that is after the
- * tag name. */
- qsort((void *)*matches, (size_t)*num_matches,
+ // Sort the matches found on the heuristic number that is after the
+ // tag name.
+ qsort((void *)(*matches), (size_t)(*num_matches),
sizeof(char_u *), help_compare);
// Delete more than TAG_MANY to reduce the size of the listing.
while (*num_matches > TAG_MANY) {
@@ -5549,8 +5549,9 @@ static void helptags_one(char_u *dir, const char_u *ext, const char_u *tagfname,
if (add_help_tags
|| path_full_compare((char_u *)"$VIMRUNTIME/doc",
dir, false, true) == kEqualFiles) {
- s = xmalloc(18 + STRLEN(tagfname));
- sprintf((char *)s, "help-tags\t%s\t1\n", tagfname);
+ size_t s_len = 18 + STRLEN(tagfname);
+ s = xmalloc(s_len);
+ snprintf((char *)s, s_len, "help-tags\t%s\t1\n", tagfname);
GA_APPEND(char_u *, &ga, s);
}
@@ -5611,10 +5612,11 @@ static void helptags_one(char_u *dir, const char_u *ext, const char_u *tagfname,
&& (vim_strchr((char_u *)" \t\n\r", s[1]) != NULL
|| s[1] == '\0')) {
*p2 = '\0';
- ++p1;
- s = xmalloc((p2 - p1) + STRLEN(fname) + 2);
+ p1++;
+ size_t s_len= (p2 - p1) + STRLEN(fname) + 2;
+ s = xmalloc(s_len);
GA_APPEND(char_u *, &ga, s);
- sprintf((char *)s, "%s\t%s", p1, fname);
+ snprintf((char *)s, s_len, "%s\t%s", p1, fname);
// find next '*'
p2 = vim_strchr(p2 + 1, '*');
@@ -5798,8 +5800,7 @@ void ex_helptags(exarg_T *eap)
}
if (STRCMP(eap->arg, "ALL") == 0) {
- do_in_path(p_rtp, (char_u *)"doc", DIP_ALL + DIP_DIR,
- helptags_cb, &add_help_tags);
+ do_in_path(p_rtp, "doc", DIP_ALL + DIP_DIR, helptags_cb, &add_help_tags);
} else {
ExpandInit(&xpc);
xpc.xp_context = EXPAND_DIRECTORIES;
diff --git a/src/nvim/ex_cmds.h b/src/nvim/ex_cmds.h
index 1b54b3a898..c34ffa1d3b 100644
--- a/src/nvim/ex_cmds.h
+++ b/src/nvim/ex_cmds.h
@@ -3,11 +3,11 @@
#include <stdbool.h>
-#include "nvim/os/time.h"
-#include "nvim/pos.h"
-#include "nvim/eval/typval.h"
#include "nvim/buffer_defs.h"
+#include "nvim/eval/typval.h"
#include "nvim/ex_cmds_defs.h"
+#include "nvim/os/time.h"
+#include "nvim/pos.h"
// flags for do_ecmd()
#define ECMD_HIDE 0x01 // don't free the current buffer
@@ -18,10 +18,10 @@
#define ECMD_ADDBUF 0x10 // don't edit, just add to buffer list
#define ECMD_ALTBUF 0x20 // like ECMD_ADDBUF and set the alternate file
-/* for lnum argument in do_ecmd() */
-#define ECMD_LASTL (linenr_T)0 /* use last position in loaded file */
-#define ECMD_LAST (linenr_T)-1 /* use last position in all files */
-#define ECMD_ONE (linenr_T)1 /* use first line */
+// for lnum argument in do_ecmd()
+#define ECMD_LASTL (linenr_T)0 // use last position in loaded file
+#define ECMD_LAST (linenr_T)-1 // use last position in all files
+#define ECMD_ONE (linenr_T)1 // use first line
/// Previous :substitute replacement string definition
typedef struct {
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 575c5c9cbd..5d40d7a16a 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -6,79 +6,53 @@
/// Some more functions for command line commands
#include <assert.h>
+#include <fcntl.h>
#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
-#include <fcntl.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
+#include "nvim/vim.h"
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
-#include "nvim/ex_cmds2.h"
+#include "nvim/api/private/defs.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/buffer.h"
#include "nvim/change.h"
#include "nvim/charset.h"
#include "nvim/debugger.h"
#include "nvim/eval/userfunc.h"
#include "nvim/ex_cmds.h"
+#include "nvim/ex_cmds2.h"
#include "nvim/ex_eval.h"
#include "nvim/ex_getln.h"
#include "nvim/fileio.h"
+#include "nvim/garray.h"
+#include "nvim/lua/executor.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
+#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/garray.h"
-#include "nvim/memory.h"
#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/ops.h"
#include "nvim/option.h"
+#include "nvim/os/fs_defs.h"
+#include "nvim/os/shell.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
+#include "nvim/profile.h"
#include "nvim/quickfix.h"
#include "nvim/regexp.h"
#include "nvim/strings.h"
#include "nvim/undo.h"
#include "nvim/version.h"
#include "nvim/window.h"
-#include "nvim/profile.h"
-#include "nvim/os/shell.h"
-#include "nvim/os/fs_defs.h"
-#include "nvim/api/private/helpers.h"
-#include "nvim/api/private/defs.h"
-#include "nvim/lua/executor.h"
-
/// Growarray to store info about already sourced scripts.
-/// Also store the dev/ino, so that we don't have to stat() each
-/// script when going through the list.
-typedef struct scriptitem_S {
- char_u *sn_name;
- bool file_id_valid;
- FileID file_id;
- bool sn_prof_on; ///< true when script is/was profiled
- bool sn_pr_force; ///< forceit: profile functions in this script
- proftime_T sn_pr_child; ///< time set when going into first child
- int sn_pr_nest; ///< nesting for sn_pr_child
- // profiling the script as a whole
- int sn_pr_count; ///< nr of times sourced
- proftime_T sn_pr_total; ///< time spent in script + children
- proftime_T sn_pr_self; ///< time spent in script itself
- proftime_T sn_pr_start; ///< time at script start
- proftime_T sn_pr_children; ///< time in children after script start
- // profiling the script per line
- garray_T sn_prl_ga; ///< things stored for every line
- proftime_T sn_prl_start; ///< start time for current line
- proftime_T sn_prl_children; ///< time spent in children for this line
- proftime_T sn_prl_wait; ///< wait start time for current line
- linenr_T sn_prl_idx; ///< index of line being timed; -1 if none
- int sn_prl_execed; ///< line being timed was executed
-} scriptitem_T;
-
static garray_T script_items = { 0, 0, sizeof(scriptitem_T), 4, NULL };
#define SCRIPT_ITEM(id) (((scriptitem_T *)script_items.ga_data)[(id) - 1])
@@ -109,20 +83,20 @@ struct source_cookie {
vimconv_T conv; ///< type of conversion
};
-# define PRL_ITEM(si, idx) (((sn_prl_T *)(si)->sn_prl_ga.ga_data)[(idx)])
+#define PRL_ITEM(si, idx) (((sn_prl_T *)(si)->sn_prl_ga.ga_data)[(idx)])
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_cmds2.c.generated.h"
#endif
-static char_u *profile_fname = NULL;
+static char_u *profile_fname = NULL;
/// ":profile cmd args"
void ex_profile(exarg_T *eap)
{
static proftime_T pause_time;
- char_u *e;
+ char_u *e;
int len;
e = skiptowhite(eap->arg);
@@ -277,7 +251,7 @@ void set_context_in_profile_cmd(expand_T *xp, const char *arg)
/// Dump the profiling info.
void profile_dump(void)
{
- FILE *fd;
+ FILE *fd;
if (profile_fname != NULL) {
fd = os_fopen((char *)profile_fname, "w");
@@ -317,7 +291,7 @@ static void profile_reset(void)
}
// Reset functions.
- size_t n = func_hashtab.ht_used;
+ size_t n = func_hashtab.ht_used;
hashitem_T *hi = func_hashtab.ht_array;
for (; n > (size_t)0; hi++) {
@@ -362,11 +336,11 @@ static void profile_init(scriptitem_T *si)
}
/// Save time when starting to invoke another script or function.
-void script_prof_save(
- proftime_T *tm // place to store wait time
-)
+///
+/// @param tm place to store wait time
+void script_prof_save(proftime_T *tm)
{
- scriptitem_T *si;
+ scriptitem_T *si;
if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len) {
si = &SCRIPT_ITEM(current_sctx.sc_sid);
@@ -380,7 +354,7 @@ void script_prof_save(
/// Count time spent in children after invoking another script or function.
void script_prof_restore(proftime_T *tm)
{
- scriptitem_T *si;
+ scriptitem_T *si;
if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len) {
si = &SCRIPT_ITEM(current_sctx.sc_sid);
@@ -412,9 +386,9 @@ void prof_inchar_exit(void)
/// Dump the profiling results for all scripts in file "fd".
static void script_dump_profile(FILE *fd)
{
- scriptitem_T *si;
- FILE *sfd;
- sn_prl_T *pp;
+ scriptitem_T *si;
+ FILE *sfd;
+ sn_prl_T *pp;
for (int id = 1; id <= script_items.ga_len; id++) {
si = &SCRIPT_ITEM(id);
@@ -699,7 +673,7 @@ bool check_changed_any(bool hidden, bool unload)
int i;
int bufnum = 0;
size_t bufcount = 0;
- int *bufnrs;
+ int *bufnrs;
// Make a list of all buffers, with the most important ones first.
FOR_ALL_BUFFERS(buf) {
@@ -829,7 +803,7 @@ int check_fname(void)
int buf_write_all(buf_T *buf, int forceit)
{
int retval;
- buf_T *old_curbuf = curbuf;
+ buf_T *old_curbuf = curbuf;
retval = (buf_write(buf, buf->b_ffname, buf->b_fname,
(linenr_T)1, buf->b_ml.ml_line_count, NULL,
@@ -852,7 +826,7 @@ int buf_write_all(buf_T *buf, int forceit)
/// Return a pointer to the start of the next argument.
static char_u *do_one_arg(char_u *str)
{
- char_u *p;
+ char_u *p;
bool inbacktick;
inbacktick = false;
@@ -936,8 +910,8 @@ static int do_arglist(char_u *str, int what, int after, bool will_edit)
{
garray_T new_ga;
int exp_count;
- char_u **exp_files;
- char_u *p;
+ char_u **exp_files;
+ char_u *p;
int match;
int arg_escaped = true;
@@ -1037,9 +1011,8 @@ static bool editing_arg_idx(win_T *win)
|| (win->w_buffer->b_fnum
!= 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))));
+ || !(path_full_compare(alist_name(&WARGLIST(win)[win->w_arg_idx]),
+ win->w_buffer->b_ffname, true, true) & kEqualFiles))));
}
/// Check if window "win" is editing the w_arg_idx file in its argument list.
@@ -1102,7 +1075,7 @@ void ex_args(exarg_T *eap)
xfree(items);
}
} else if (eap->cmdidx == CMD_arglocal) {
- garray_T *gap = &curwin->w_alist->al_ga;
+ garray_T *gap = &curwin->w_alist->al_ga;
// ":argslocal": make a local copy of the global argument list.
ga_grow(gap, GARGCOUNT);
@@ -1158,7 +1131,7 @@ void ex_argument(exarg_T *eap)
void do_argfile(exarg_T *eap, int argn)
{
int other;
- char_u *p;
+ char_u *p;
int old_arg_idx = curwin->w_arg_idx;
if (argn < 0 || argn >= ARGCOUNT) {
@@ -1310,9 +1283,9 @@ void ex_argdelete(exarg_T *eap)
curwin->w_arg_idx = (int)eap->line1;
}
if (ARGCOUNT == 0) {
- curwin->w_arg_idx = 0;
+ curwin->w_arg_idx = 0;
} else if (curwin->w_arg_idx >= ARGCOUNT) {
- curwin->w_arg_idx = ARGCOUNT - 1;
+ curwin->w_arg_idx = ARGCOUNT - 1;
}
}
} else {
@@ -1325,11 +1298,11 @@ void ex_argdelete(exarg_T *eap)
void ex_listdo(exarg_T *eap)
{
int i;
- win_T *wp;
- tabpage_T *tp;
+ win_T *wp;
+ tabpage_T *tp;
int next_fnum = 0;
- char_u *save_ei = NULL;
- char_u *p_shm_save;
+ char_u *save_ei = NULL;
+ char_u *p_shm_save;
if (eap->cmdidx != CMD_windo && eap->cmdidx != CMD_tabdo) {
// Don't do syntax HL autocommands. Skipping the syntax file is a
@@ -1610,9 +1583,9 @@ char_u *get_arglist_name(expand_T *xp FUNC_ATTR_UNUSED, int idx)
/// ":compiler[!] {name}"
void ex_compiler(exarg_T *eap)
{
- char_u *buf;
- char_u *old_cur_comp = NULL;
- char_u *p;
+ char_u *buf;
+ char_u *old_cur_comp = NULL;
+ char_u *p;
if (*eap->arg == NUL) {
// List all compiler scripts.
@@ -1641,10 +1614,10 @@ void ex_compiler(exarg_T *eap)
do_unlet(S_LEN("b:current_compiler"), true);
snprintf((char *)buf, bufsize, "compiler/%s.vim", eap->arg);
- if (source_runtime(buf, DIP_ALL) == FAIL) {
+ if (source_runtime((char *)buf, DIP_ALL) == FAIL) {
// Try lua compiler
snprintf((char *)buf, bufsize, "compiler/%s.lua", eap->arg);
- if (source_runtime(buf, DIP_ALL) == FAIL) {
+ if (source_runtime((char *)buf, DIP_ALL) == FAIL) {
EMSG2(_("E666: compiler not supported: %s"), eap->arg);
}
}
@@ -1703,9 +1676,9 @@ void init_pyxversion(void)
// otherwise return 0.
static int requires_py_version(char_u *filename)
{
- FILE *file;
- int requires_py_version = 0;
- int i, lines;
+ FILE *file;
+ int requires_py_version = 0;
+ int i, lines;
lines = (int)p_mls;
if (lines < 0) {
@@ -1824,7 +1797,7 @@ static void cmd_source(char_u *fname, exarg_T *eap)
|| eap->cstack->cs_idx >= 0);
// ":source" read ex commands
- } else if (do_source(fname, false, DOSO_NONE) == FAIL) {
+ } else if (do_source((char *)fname, false, DOSO_NONE) == FAIL) {
EMSG2(_(e_notopen), fname);
}
}
@@ -1940,9 +1913,30 @@ static char_u *get_str_line(int c, void *cookie, int indent, bool do_concat)
return ga.ga_data;
}
-static int source_using_linegetter(void *cookie,
- LineGetter fgetline,
- const char *traceback_name)
+/// Create a new script item and allocate script-local vars. @see new_script_vars
+///
+/// @param name File name of the script. NULL for anonymous :source.
+/// @param[out] sid_out SID of the new item.
+/// @return pointer to the created script item.
+scriptitem_T *new_script_item(char_u *const name, scid_T *const sid_out)
+{
+ static scid_T last_current_SID = 0;
+ const scid_T sid = ++last_current_SID;
+ if (sid_out != NULL) {
+ *sid_out = sid;
+ }
+ ga_grow(&script_items, (int)(sid - script_items.ga_len));
+ while (script_items.ga_len < sid) {
+ script_items.ga_len++;
+ SCRIPT_ITEM(script_items.ga_len).sn_name = NULL;
+ SCRIPT_ITEM(script_items.ga_len).sn_prof_on = false;
+ }
+ SCRIPT_ITEM(sid).sn_name = name;
+ new_script_vars(sid); // Allocate the local script variables to use for this script.
+ return &SCRIPT_ITEM(sid);
+}
+
+static int source_using_linegetter(void *cookie, LineGetter fgetline, const char *traceback_name)
{
char_u *save_sourcing_name = sourcing_name;
linenr_T save_sourcing_lnum = sourcing_lnum;
@@ -1951,9 +1945,9 @@ static int source_using_linegetter(void *cookie,
sourcing_name = (char_u *)traceback_name;
} else {
snprintf((char *)sourcing_name_buf, sizeof(sourcing_name_buf),
- "%s called at %s:%"PRIdLINENR, traceback_name, save_sourcing_name,
+ "%s called at %s:%" PRIdLINENR, traceback_name, save_sourcing_name,
save_sourcing_lnum);
- sourcing_name = sourcing_name_buf;
+ sourcing_name = sourcing_name_buf; // -V507 reassigned below, before return.
}
sourcing_lnum = 0;
@@ -1987,13 +1981,13 @@ static void cmd_source_buffer(const exarg_T *const eap)
if (ga.ga_len > 400) {
ga_set_growsize(&ga, MAX(ga.ga_len, 8000));
}
- ga_concat(&ga, ml_get(curr_lnum));
+ ga_concat(&ga, (char *)ml_get(curr_lnum));
ga_append(&ga, NL);
}
((char_u *)ga.ga_data)[ga.ga_len - 1] = NUL;
const GetStrLineCookie cookie = {
- .buf = ga.ga_data,
- .offset = 0,
+ .buf = ga.ga_data,
+ .offset = 0,
};
if (curbuf->b_fname
&& path_with_extension((const char *)curbuf->b_fname, "lua")) {
@@ -2012,8 +2006,8 @@ static void cmd_source_buffer(const exarg_T *const eap)
int do_source_str(const char *cmd, const char *traceback_name)
{
GetStrLineCookie cookie = {
- .buf = (char_u *)cmd,
- .offset = 0,
+ .buf = (char_u *)cmd,
+ .offset = 0,
};
return source_using_linegetter((void *)&cookie, get_str_line, traceback_name);
}
@@ -2030,23 +2024,22 @@ int do_source_str(const char *cmd, const char *traceback_name)
/// @param is_vimrc DOSO_ value
///
/// @return FAIL if file could not be opened, OK otherwise
-int do_source(char_u *fname, int check_other, int is_vimrc)
+int do_source(char *fname, int check_other, int is_vimrc)
{
struct source_cookie cookie;
- char_u *save_sourcing_name;
+ char_u *save_sourcing_name;
linenr_T save_sourcing_lnum;
- char_u *p;
- char_u *fname_exp;
- char_u *firstline = NULL;
+ char_u *p;
+ char_u *fname_exp;
+ char_u *firstline = NULL;
int retval = FAIL;
- static scid_T last_current_SID = 0;
static int last_current_SID_seq = 0;
int save_debug_break_level = debug_break_level;
- scriptitem_T *si = NULL;
+ scriptitem_T *si = NULL;
proftime_T wait_start;
bool trigger_source_post = false;
- p = expand_env_save(fname);
+ p = expand_env_save((char_u *)fname);
if (p == NULL) {
return retval;
}
@@ -2115,7 +2108,7 @@ int do_source(char_u *fname, int check_other, int is_vimrc)
verbose_leave();
}
if (is_vimrc == DOSO_VIMRC) {
- vimrc_found(fname_exp, (char_u *)"MYVIMRC");
+ vimrc_found((char *)fname_exp, "MYVIMRC");
}
#ifdef USE_CRNL
@@ -2186,15 +2179,7 @@ int do_source(char_u *fname, int check_other, int is_vimrc)
}
}
if (current_sctx.sc_sid == 0) {
- current_sctx.sc_sid = ++last_current_SID;
- ga_grow(&script_items, (int)(current_sctx.sc_sid - script_items.ga_len));
- while (script_items.ga_len < current_sctx.sc_sid) {
- script_items.ga_len++;
- SCRIPT_ITEM(script_items.ga_len).sn_name = NULL;
- SCRIPT_ITEM(script_items.ga_len).sn_prof_on = false;
- }
- si = &SCRIPT_ITEM(current_sctx.sc_sid);
- si->sn_name = fname_exp;
+ si = new_script_item(fname_exp, &current_sctx.sc_sid);
fname_exp = vim_strsave(si->sn_name); // used for autocmd
if (file_id_ok) {
si->file_id_valid = true;
@@ -2202,9 +2187,6 @@ int do_source(char_u *fname, int check_other, int is_vimrc)
} else {
si->file_id_valid = false;
}
-
- // Allocate the local script variables to use for this script.
- new_script_vars(current_sctx.sc_sid);
}
if (l_do_profiling == PROF_YES) {
@@ -2343,7 +2325,7 @@ void ex_scriptnames(exarg_T *eap)
}
}
-# if defined(BACKSLASH_IN_FILENAME)
+#if defined(BACKSLASH_IN_FILENAME)
/// Fix slashes in the list of script names for 'shellslash'.
void scriptnames_slash_adjust(void)
{
@@ -2354,7 +2336,7 @@ void scriptnames_slash_adjust(void)
}
}
-# endif
+#endif
/// Get a pointer to a script name. Used for ":verbose set".
/// Message appended to "Last set from "
@@ -2363,35 +2345,40 @@ char_u *get_scriptname(LastSet last_set, bool *should_free)
*should_free = false;
switch (last_set.script_ctx.sc_sid) {
- case SID_MODELINE:
- return (char_u *)_("modeline");
- case SID_CMDARG:
- return (char_u *)_("--cmd argument");
- case SID_CARG:
- return (char_u *)_("-c argument");
- case SID_ENV:
- return (char_u *)_("environment variable");
- case SID_ERROR:
- return (char_u *)_("error handler");
- case SID_WINLAYOUT:
- return (char_u *)_("changed window size");
- case SID_LUA:
- return (char_u *)_("Lua");
- case SID_API_CLIENT:
- vim_snprintf((char *)IObuff, IOSIZE,
- _("API client (channel id %" PRIu64 ")"),
- last_set.channel_id);
+ case SID_MODELINE:
+ return (char_u *)_("modeline");
+ case SID_CMDARG:
+ return (char_u *)_("--cmd argument");
+ case SID_CARG:
+ return (char_u *)_("-c argument");
+ case SID_ENV:
+ return (char_u *)_("environment variable");
+ case SID_ERROR:
+ return (char_u *)_("error handler");
+ case SID_WINLAYOUT:
+ return (char_u *)_("changed window size");
+ case SID_LUA:
+ return (char_u *)_("Lua");
+ case SID_API_CLIENT:
+ snprintf((char *)IObuff, IOSIZE, _("API client (channel id %" PRIu64 ")"), last_set.channel_id);
+ return IObuff;
+ case SID_STR:
+ return (char_u *)_("anonymous :source");
+ default: {
+ char_u *const sname = SCRIPT_ITEM(last_set.script_ctx.sc_sid).sn_name;
+ if (sname == NULL) {
+ snprintf((char *)IObuff, IOSIZE, _("anonymous :source (script id %d)"),
+ last_set.script_ctx.sc_sid);
return IObuff;
- case SID_STR:
- return (char_u *)_("anonymous :source");
- default:
- *should_free = true;
- return home_replace_save(NULL,
- SCRIPT_ITEM(last_set.script_ctx.sc_sid).sn_name);
+ }
+
+ *should_free = true;
+ return home_replace_save(NULL, sname);
+ }
}
}
-# if defined(EXITFREE)
+#if defined(EXITFREE)
void free_scriptnames(void)
{
profile_reset();
@@ -2399,11 +2386,11 @@ void free_scriptnames(void)
# define FREE_SCRIPTNAME(item) xfree((item)->sn_name)
GA_DEEP_CLEAR(&script_items, scriptitem_T, FREE_SCRIPTNAME);
}
-# endif
+#endif
linenr_T get_sourced_lnum(LineGetter fgetline, void *cookie)
{
- return fgetline == getsourceline
+ return fgetline == getsourceline
? ((struct source_cookie *)cookie)->sourcing_lnum
: sourcing_lnum;
}
@@ -2462,7 +2449,7 @@ char_u *getsourceline(int c, void *cookie, int indent, bool do_concat)
garray_T ga;
ga_init(&ga, (int)sizeof(char_u), 400);
- ga_concat(&ga, line);
+ ga_concat(&ga, (char *)line);
while (sp->nextline != NULL
&& concat_continued_line(&ga, 400, sp->nextline,
STRLEN(sp->nextline))) {
@@ -2476,7 +2463,7 @@ char_u *getsourceline(int c, void *cookie, int indent, bool do_concat)
}
if (line != NULL && sp->conv.vc_type != CONV_NONE) {
- char_u *s;
+ char_u *s;
// Convert the encoding of the script line.
s = string_convert(&sp->conv, line, NULL);
@@ -2502,7 +2489,7 @@ static char_u *get_one_sourceline(struct source_cookie *sp)
garray_T ga;
int len;
int c;
- char_u *buf;
+ char_u *buf;
#ifdef USE_CRNL
int has_cr; // CR-LF found
#endif
@@ -2605,8 +2592,8 @@ retry:
/// until later and we need to store the time now.
void script_line_start(void)
{
- scriptitem_T *si;
- sn_prl_T *pp;
+ scriptitem_T *si;
+ sn_prl_T *pp;
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) {
return;
@@ -2637,7 +2624,7 @@ void script_line_start(void)
/// Called when actually executing a function line.
void script_line_exec(void)
{
- scriptitem_T *si;
+ scriptitem_T *si;
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) {
return;
@@ -2651,8 +2638,8 @@ void script_line_exec(void)
/// Called when done with a function line.
void script_line_end(void)
{
- scriptitem_T *si;
- sn_prl_T *pp;
+ scriptitem_T *si;
+ sn_prl_T *pp;
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) {
return;
@@ -2677,8 +2664,8 @@ void script_line_end(void)
/// Without the multi-byte feature it's simply ignored.
void ex_scriptencoding(exarg_T *eap)
{
- struct source_cookie *sp;
- char_u *name;
+ struct source_cookie *sp;
+ char_u *name;
if (!getline_equal(eap->getline, eap->cookie, getsourceline)) {
EMSG(_("E167: :scriptencoding used outside of a sourced file"));
@@ -2743,14 +2730,13 @@ void do_finish(exarg_T *eap, int reanimate)
bool source_finished(LineGetter fgetline, void *cookie)
{
return getline_equal(fgetline, cookie, getsourceline)
- && ((struct source_cookie *)getline_cookie(
- fgetline, cookie))->finished;
+ && ((struct source_cookie *)getline_cookie(fgetline, cookie))->finished;
}
/// ":checktime [buffer]"
void ex_checktime(exarg_T *eap)
{
- buf_T *buf;
+ buf_T *buf;
int save_no_check_timestamps = no_check_timestamps;
no_check_timestamps = 0;
@@ -2790,17 +2776,17 @@ char *get_mess_lang(void)
{
char *p;
-# ifdef HAVE_GET_LOCALE_VAL
-# if defined(LC_MESSAGES)
+#ifdef HAVE_GET_LOCALE_VAL
+# if defined(LC_MESSAGES)
p = get_locale_val(LC_MESSAGES);
-# else
+# else
// This is necessary for Win32, where LC_MESSAGES is not defined and $LANG
// may be set to the LCID number. LC_COLLATE is the best guess, LC_TIME
// and LC_MONETARY may be set differently for a Japanese working in the
// US.
p = get_locale_val(LC_COLLATE);
-# endif
-# else
+# endif
+#else
p = os_getenv("LC_ALL");
if (!is_valid_mess_lang(p)) {
p = os_getenv("LC_MESSAGES");
@@ -2808,7 +2794,7 @@ char *get_mess_lang(void)
p = os_getenv("LANG");
}
}
-# endif
+#endif
return is_valid_mess_lang(p) ? p : NULL;
}
@@ -2817,7 +2803,7 @@ char *get_mess_lang(void)
/// Get the language used for messages from the environment.
static char_u *get_mess_env(void)
{
- char_u *p;
+ char_u *p;
p = (char_u *)os_getenv("LC_ALL");
if (p == NULL) {
@@ -2846,37 +2832,37 @@ void set_lang_var(void)
{
const char *loc;
-# ifdef HAVE_GET_LOCALE_VAL
+#ifdef HAVE_GET_LOCALE_VAL
loc = get_locale_val(LC_CTYPE);
-# else
+#else
// setlocale() not supported: use the default value
loc = "C";
-# endif
+#endif
set_vim_var_string(VV_CTYPE, loc, -1);
// When LC_MESSAGES isn't defined use the value from $LC_MESSAGES, fall
// back to LC_CTYPE if it's empty.
-# ifdef HAVE_WORKING_LIBINTL
+#ifdef HAVE_WORKING_LIBINTL
loc = (char *)get_mess_env();
-# elif defined(LC_MESSAGES)
+#elif defined(LC_MESSAGES)
loc = get_locale_val(LC_MESSAGES);
-# else
+#else
// In Windows LC_MESSAGES is not defined fallback to LC_CTYPE
loc = get_locale_val(LC_CTYPE);
-# endif
+#endif
set_vim_var_string(VV_LANG, loc, -1);
-# ifdef HAVE_GET_LOCALE_VAL
+#ifdef HAVE_GET_LOCALE_VAL
loc = get_locale_val(LC_TIME);
-# endif
+#endif
set_vim_var_string(VV_LC_TIME, loc, -1);
-# ifdef HAVE_GET_LOCALE_VAL
+#ifdef HAVE_GET_LOCALE_VAL
loc = get_locale_val(LC_COLLATE);
-# else
+#else
// setlocale() not supported: use the default value
loc = "C";
-# endif
+#endif
set_vim_var_string(VV_COLLATE, loc, -1);
}
@@ -2888,16 +2874,16 @@ void set_lang_var(void)
///
void ex_language(exarg_T *eap)
{
- char *loc;
- char_u *p;
- char_u *name;
+ char *loc;
+ char_u *p;
+ char_u *name;
int what = LC_ALL;
- char *whatstr = "";
-#ifdef LC_MESSAGES
-# define VIM_LC_MESSAGES LC_MESSAGES
-#else
-# define VIM_LC_MESSAGES 6789
-#endif
+ char *whatstr = "";
+# ifdef LC_MESSAGES
+# define VIM_LC_MESSAGES LC_MESSAGES
+# else
+# define VIM_LC_MESSAGES 6789
+# endif
name = eap->arg;
@@ -2926,43 +2912,43 @@ void ex_language(exarg_T *eap)
}
if (*name == NUL) {
-#ifdef HAVE_WORKING_LIBINTL
+# ifdef HAVE_WORKING_LIBINTL
if (what == VIM_LC_MESSAGES) {
p = get_mess_env();
} else {
-#endif
- p = (char_u *)setlocale(what, NULL);
-#ifdef HAVE_WORKING_LIBINTL
- }
-#endif
+# endif
+ p = (char_u *)setlocale(what, NULL);
+# ifdef HAVE_WORKING_LIBINTL
+ }
+# endif
if (p == NULL || *p == NUL) {
p = (char_u *)"Unknown";
}
smsg(_("Current %slanguage: \"%s\""), whatstr, p);
} else {
-#ifndef LC_MESSAGES
+# ifndef LC_MESSAGES
if (what == VIM_LC_MESSAGES) {
loc = "";
} else {
-#endif
- loc = setlocale(what, (char *)name);
-#ifdef LC_NUMERIC
- // Make sure strtod() uses a decimal point, not a comma.
- setlocale(LC_NUMERIC, "C");
-#endif
-#ifndef LC_MESSAGES
- }
-#endif
+# endif
+ loc = setlocale(what, (char *)name);
+# ifdef LC_NUMERIC
+ // Make sure strtod() uses a decimal point, not a comma.
+ setlocale(LC_NUMERIC, "C");
+# endif
+# ifndef LC_MESSAGES
+ }
+# endif
if (loc == NULL) {
EMSG2(_("E197: Cannot set language to \"%s\""), name);
} else {
-#ifdef HAVE_NL_MSG_CAT_CNTR
+# ifdef HAVE_NL_MSG_CAT_CNTR
// Need to do this for GNU gettext, otherwise cached translations
// will be used again.
extern int _nl_msg_cat_cntr;
_nl_msg_cat_cntr++;
-#endif
+# endif
// Reset $LC_ALL, otherwise it would overrule everything.
os_setenv("LC_ALL", "", 1);
@@ -2991,7 +2977,7 @@ void ex_language(exarg_T *eap)
static char_u **locales = NULL; // Array of all available locales
-#ifndef WIN32
+# ifndef WIN32
static bool did_init_locales = false;
/// Return an array of strings for all available locales + NULL for the
@@ -2999,7 +2985,7 @@ static bool did_init_locales = false;
static char_u **find_locales(void)
{
garray_T locales_ga;
- char_u *loc;
+ char_u *loc;
char *saveptr = NULL;
// Find all available locales by running command "locale -a". If this
@@ -3026,20 +3012,20 @@ static char_u **find_locales(void)
((char_u **)locales_ga.ga_data)[locales_ga.ga_len] = NULL;
return (char_u **)locales_ga.ga_data;
}
-#endif
+# endif
/// Lazy initialization of all available locales.
static void init_locales(void)
{
-#ifndef WIN32
+# ifndef WIN32
if (!did_init_locales) {
did_init_locales = true;
locales = find_locales();
}
-#endif
+# endif
}
-# if defined(EXITFREE)
+# if defined(EXITFREE)
void free_locales(void)
{
int i;
@@ -3051,7 +3037,7 @@ void free_locales(void)
}
}
-# endif
+# endif
/// Function given to ExpandGeneric() to obtain the possible arguments of the
/// ":language" command.
@@ -3137,7 +3123,7 @@ static void script_host_do_range(char *name, exarg_T *eap)
/// ":drop"
/// Opens the first argument in a window. When there are two or more arguments
/// the argument list is redefined.
-void ex_drop(exarg_T *eap)
+void ex_drop(exarg_T *eap)
{
bool split = false;
buf_T *buf;
diff --git a/src/nvim/ex_cmds2.h b/src/nvim/ex_cmds2.h
index de4e1429b7..d426ff28f8 100644
--- a/src/nvim/ex_cmds2.h
+++ b/src/nvim/ex_cmds2.h
@@ -16,6 +16,31 @@
#define CCGD_ALLBUF 8 // may write all buffers
#define CCGD_EXCMD 16 // may suggest using !
+/// Also store the dev/ino, so that we don't have to stat() each
+/// script when going through the list.
+typedef struct scriptitem_S {
+ char_u *sn_name;
+ bool file_id_valid;
+ FileID file_id;
+ bool sn_prof_on; ///< true when script is/was profiled
+ bool sn_pr_force; ///< forceit: profile functions in this script
+ proftime_T sn_pr_child; ///< time set when going into first child
+ int sn_pr_nest; ///< nesting for sn_pr_child
+ // profiling the script as a whole
+ int sn_pr_count; ///< nr of times sourced
+ proftime_T sn_pr_total; ///< time spent in script + children
+ proftime_T sn_pr_self; ///< time spent in script itself
+ proftime_T sn_pr_start; ///< time at script start
+ proftime_T sn_pr_children; ///< time in children after script start
+ // profiling the script per line
+ garray_T sn_prl_ga; ///< things stored for every line
+ proftime_T sn_prl_start; ///< start time for current line
+ proftime_T sn_prl_children; ///< time spent in children for this line
+ proftime_T sn_prl_wait; ///< wait start time for current line
+ linenr_T sn_prl_idx; ///< index of line being timed; -1 if none
+ int sn_prl_execed; ///< line being timed was executed
+} scriptitem_T;
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_cmds2.h.generated.h"
#endif
diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h
index d64b14c9c5..171f8ed5cd 100644
--- a/src/nvim/ex_cmds_defs.h
+++ b/src/nvim/ex_cmds_defs.h
@@ -4,8 +4,8 @@
#include <stdbool.h>
#include <stdint.h>
-#include "nvim/pos.h" // for linenr_T
#include "nvim/normal.h"
+#include "nvim/pos.h" // for linenr_T
#include "nvim/regexp_defs.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -83,10 +83,10 @@ typedef enum {
typedef struct exarg exarg_T;
-/* behavior for bad character, "++bad=" argument */
-#define BAD_REPLACE '?' /* replace it with '?' (default) */
-#define BAD_KEEP -1 /* leave it */
-#define BAD_DROP -2 /* erase it */
+// behavior for bad character, "++bad=" argument
+#define BAD_REPLACE '?' // replace it with '?' (default)
+#define BAD_KEEP -1 // leave it
+#define BAD_DROP -2 // erase it
typedef void (*ex_func_T)(exarg_T *eap);
@@ -130,8 +130,8 @@ typedef struct {
eslist_T *cs_emsg_silent_list; // saved values of "emsg_silent"
int cs_lflags; // loop flags: CSL_ flags
} cstack_T;
-# define cs_rettv cs_pend.csp_rv
-# define cs_exception cs_pend.csp_ex
+#define cs_rettv cs_pend.csp_rv
+#define cs_exception cs_pend.csp_ex
// Flags for the cs_lflags item in cstack_T.
enum {
@@ -143,10 +143,10 @@ enum {
/// Arguments used for Ex commands.
struct exarg {
- char_u *arg; ///< argument of the command
- char_u *nextcmd; ///< next command (NULL if none)
- char_u *cmd; ///< the name of the command (except for :make)
- char_u **cmdlinep; ///< pointer to pointer of allocated cmdline
+ char_u *arg; ///< argument of the command
+ char_u *nextcmd; ///< next command (NULL if none)
+ char_u *cmd; ///< the name of the command (except for :make)
+ char_u **cmdlinep; ///< pointer to pointer of allocated cmdline
cmdidx_T cmdidx; ///< the index for the command
uint32_t argt; ///< flags for the command
int skip; ///< don't execute the command, only parse it
@@ -156,7 +156,7 @@ struct exarg {
linenr_T line2; ///< the second line number or count
cmd_addr_T addr_type; ///< type of the count/range
int flags; ///< extra flags after count: EXFLAG_
- char_u *do_ecmd_cmd; ///< +command arg to be used in edited file
+ char_u *do_ecmd_cmd; ///< +command arg to be used in edited file
linenr_T do_ecmd_lnum; ///< the line number in an edited file
int append; ///< TRUE with ":w >>file" command
int usefilter; ///< TRUE with ":w !command" and ":r!command"
@@ -170,7 +170,7 @@ struct exarg {
int useridx; ///< user command index
char_u *errmsg; ///< returned error message
LineGetter getline; ///< Function used to get the next line
- void *cookie; ///< argument for getline()
+ void *cookie; ///< argument for getline()
cstack_T *cstack; ///< condition stack for ":if" etc.
long verbose_save; ///< saved value of p_verbose
int save_msg_silent; ///< saved value of msg_silent
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 34497eb212..4524026e3f 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -99,7 +99,7 @@ static garray_T ucmds = { 0, 0, sizeof(ucmd_T), 4, NULL };
#define USER_CMD_GA(gap, i) (&((ucmd_T *)((gap)->ga_data))[i])
// Whether a command index indicates a user command.
-# define IS_USER_CMDIDX(idx) ((int)(idx) < 0)
+#define IS_USER_CMDIDX(idx) ((int)(idx) < 0)
// Struct for storing a line inside a while/for loop
typedef struct {
@@ -197,8 +197,8 @@ void do_exmode(void)
exmode_active = true;
State = NORMAL;
- /* When using ":global /pat/ visual" and then "Q" we return to continue
- * the :global command. */
+ // When using ":global /pat/ visual" and then "Q" we return to continue
+ // the :global command.
if (global_busy) {
return;
}
@@ -231,8 +231,8 @@ void do_exmode(void)
EMSG(_(e_emptybuf));
} else {
if (ex_pressedreturn) {
- /* go up one line, to overwrite the ":<CR>" line, so the
- * output doesn't contain empty lines. */
+ // go up one line, to overwrite the ":<CR>" line, so the
+ // output doesn't contain empty lines.
msg_row = prev_msg_row;
if (prev_msg_row == Rows - 1) {
msg_row--;
@@ -304,6 +304,7 @@ int do_cmdline_cmd(const char *cmd)
/// DOCMD_KEYTYPED - Don't reset KeyTyped.
/// DOCMD_EXCRESET - Reset the exception environment (used for debugging).
/// DOCMD_KEEPLINE - Store first typed line (for repeating with ".").
+/// DOCMD_PREVIEW - During 'inccommand' preview.
///
/// @param cookie argument for fgetline()
///
@@ -373,8 +374,8 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags)
++ex_nesting_level;
}
- /* Get the function or script name and the address where the next breakpoint
- * line and the debug tick for a function or script are stored. */
+ // Get the function or script name and the address where the next breakpoint
+ // line and the debug tick for a function or script are stored.
if (getline_is_func) {
fname = func_name(real_cookie);
breakpoint = func_breakpoint(real_cookie);
@@ -499,11 +500,11 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags)
}
if (cstack.cs_looplevel > 0) {
- /* Inside a while/for loop we need to store the lines and use them
- * again. Pass a different "fgetline" function to do_one_cmd()
- * below, so that it stores lines in or reads them from
- * "lines_ga". Makes it possible to define a function inside a
- * while/for loop. */
+ // Inside a while/for loop we need to store the lines and use them
+ // again. Pass a different "fgetline" function to do_one_cmd()
+ // below, so that it stores lines in or reads them from
+ // "lines_ga". Makes it possible to define a function inside a
+ // while/for loop.
cmd_getline = get_loop_line;
cmd_cookie = (void *)&cmd_loop_cookie;
cmd_loop_cookie.lines_gap = &lines_ga;
@@ -606,13 +607,13 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags)
recursive--;
// Ignore trailing '|'-separated commands in preview-mode ('inccommand').
- if (State & CMDPREVIEW) {
+ if ((State & CMDPREVIEW) && (flags & DOCMD_PREVIEW)) {
next_cmdline = NULL;
}
if (cmd_cookie == (void *)&cmd_loop_cookie) {
- /* Use "current_line" from "cmd_loop_cookie", it may have been
- * incremented when defining a function. */
+ // Use "current_line" from "cmd_loop_cookie", it may have been
+ // incremented when defining a function.
current_line = cmd_loop_cookie.current_line;
}
@@ -670,8 +671,8 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags)
cstack.cs_lflags |= CSL_HAD_LOOP;
line_breakcheck(); // check if CTRL-C typed
- /* Check for the next breakpoint at or after the ":while"
- * or ":for". */
+ // Check for the next breakpoint at or after the ":while"
+ // or ":for".
if (breakpoint != NULL) {
*breakpoint = dbg_find_breakpoint(getline_equal(fgetline, cookie, getsourceline),
fname,
@@ -723,8 +724,8 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags)
cstack.cs_flags[cstack.cs_idx] |= CSF_ACTIVE | CSF_FINALLY;
}
- /* Update global "trylevel" for recursive calls to do_cmdline() from
- * within this loop. */
+ // Update global "trylevel" for recursive calls to do_cmdline() from
+ // within this loop.
trylevel = initial_trylevel + cstack.cs_trylevel;
// If the outermost try conditional (across function calls and sourced
@@ -805,9 +806,9 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags)
trylevel = initial_trylevel;
}
- /* If a missing ":endtry", ":endwhile", ":endfor", or ":endif" or a memory
- * lack was reported above and the error message is to be converted to an
- * exception, do this now after rewinding the cstack. */
+ // If a missing ":endtry", ":endwhile", ":endfor", or ":endif" or a memory
+ // lack was reported above and the error message is to be converted to an
+ // exception, do this now after rewinding the cstack.
do_errthrow(&cstack, getline_equal(fgetline, cookie, get_func_line)
? (char_u *)"endfunction" : (char_u *)NULL);
@@ -1013,9 +1014,9 @@ int getline_equal(LineGetter fgetline, void *cookie, LineGetter func)
LineGetter gp;
struct loop_cookie *cp;
- /* When "fgetline" is "get_loop_line()" use the "cookie" to find the
- * function that's originally used to obtain the lines. This may be
- * nested several levels. */
+ // When "fgetline" is "get_loop_line()" use the "cookie" to find the
+ // function that's originally used to obtain the lines. This may be
+ // nested several levels.
gp = fgetline;
cp = (struct loop_cookie *)cookie;
while (gp == get_loop_line) {
@@ -1029,14 +1030,14 @@ int getline_equal(LineGetter fgetline, void *cookie, LineGetter func)
/// getline function. Otherwise return "cookie".
///
/// @param cookie argument for fgetline()
-void * getline_cookie(LineGetter fgetline, void *cookie)
+void *getline_cookie(LineGetter fgetline, void *cookie)
{
LineGetter gp;
struct loop_cookie *cp;
- /* When "fgetline" is "get_loop_line()" use the "cookie" to find the
- * cookie that's originally used to obtain the lines. This may be nested
- * several levels. */
+ // When "fgetline" is "get_loop_line()" use the "cookie" to find the
+ // cookie that's originally used to obtain the lines. This may be nested
+ // several levels.
gp = fgetline;
cp = (struct loop_cookie *)cookie;
while (gp == get_loop_line) {
@@ -1249,8 +1250,8 @@ static char_u *skip_colon_white(const char_u *p, bool skipleadingwhite)
/// This function may be called recursively!
///
/// @param cookie argument for fgetline()
-static char_u * do_one_cmd(char_u **cmdlinep, int flags, cstack_T *cstack, LineGetter fgetline,
- void *cookie)
+static char_u *do_one_cmd(char_u **cmdlinep, int flags, cstack_T *cstack, LineGetter fgetline,
+ void *cookie)
{
char_u *p;
linenr_T lnum;
@@ -2624,9 +2625,9 @@ static char_u *find_command(exarg_T *eap, int *full)
}
len = (int)(p - eap->cmd);
if (*eap->cmd == 'd' && (p[-1] == 'l' || p[-1] == 'p')) {
- /* Check for ":dl", ":dell", etc. to ":deletel": that's
- * :delete with the 'l' flag. Same for 'p'. */
- for (i = 0; i < len; ++i) {
+ // Check for ":dl", ":dell", etc. to ":deletel": that's
+ // :delete with the 'l' flag. Same for 'p'.
+ for (i = 0; i < len; i++) {
if (eap->cmd[i] != ((char_u *)"delete")[i]) {
break;
}
@@ -2904,7 +2905,7 @@ int cmd_exists(const char *const name)
/// probably won't change that much -- webb.
///
/// @param buff buffer for command string
-const char * set_one_cmd_context(expand_T *xp, const char *buff)
+const char *set_one_cmd_context(expand_T *xp, const char *buff)
{
size_t len = 0;
exarg_T ea;
@@ -4434,8 +4435,8 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
continue;
}
- /* Wildcards won't be expanded below, the replacement is taken
- * literally. But do expand "~/file", "~user/file" and "$HOME/file". */
+ // Wildcards won't be expanded below, the replacement is taken
+ // literally. But do expand "~/file", "~user/file" and "$HOME/file".
if (vim_strchr(repl, '$') != NULL || vim_strchr(repl, '~') != NULL) {
char_u *l = repl;
@@ -4462,8 +4463,8 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
&& !(eap->argt & EX_NOSPC)) {
char_u *l;
#ifdef BACKSLASH_IN_FILENAME
- /* Don't escape a backslash here, because rem_backslash() doesn't
- * remove it later. */
+ // Don't escape a backslash here, because rem_backslash() doesn't
+ // remove it later.
static char_u *nobslash = (char_u *)" \t\"|";
# define ESCAPE_CHARS nobslash
#else
@@ -5636,7 +5637,7 @@ static void ex_command(exarg_T *eap)
uint32_t argt = 0;
long def = -1;
int flags = 0;
- int compl = EXPAND_NOTHING;
+ int compl = EXPAND_NOTHING;
char_u *compl_arg = NULL;
cmd_addr_T addr_type_arg = ADDR_NONE;
int has_attr = (eap->arg[0] == '-');
@@ -5696,7 +5697,7 @@ void ex_comclear(exarg_T *eap)
uc_clear(&curbuf->b_ucmds);
}
-static void free_ucmd(ucmd_T * cmd) {
+static void free_ucmd(ucmd_T *cmd) {
xfree(cmd->uc_name);
xfree(cmd->uc_rep);
xfree(cmd->uc_compl_arg);
@@ -6948,7 +6949,7 @@ static void ex_goto(exarg_T *eap)
*/
void alist_clear(alist_T *al)
{
-# define FREE_AENTRY_FNAME(arg) xfree(arg->ae_fname)
+#define FREE_AENTRY_FNAME(arg) xfree(arg->ae_fname)
GA_DEEP_CLEAR(&al->al_ga, aentry_T, FREE_AENTRY_FNAME);
}
@@ -7204,8 +7205,8 @@ void ex_splitview(exarg_T *eap)
}
} else if (win_split(eap->addr_count > 0 ? (int)eap->line2 : 0,
*eap->cmd == 'v' ? WSP_VERT : 0) != FAIL) {
- /* Reset 'scrollbind' when editing another file, but keep it when
- * doing ":split" without arguments. */
+ // Reset 'scrollbind' when editing another file, but keep it when
+ // doing ":split" without arguments.
if (*eap->arg != NUL
) {
RESET_BINDING(curwin);
@@ -7401,8 +7402,8 @@ static void ex_find(exarg_T *eap)
fname = find_file_in_path(eap->arg, STRLEN(eap->arg),
FNAME_MESS, TRUE, curbuf->b_ffname);
if (eap->addr_count > 0) {
- /* Repeat finding the file "count" times. This matters when it
- * appears several times in the path. */
+ // Repeat finding the file "count" times. This matters when it
+ // appears several times in the path.
count = eap->line2;
while (fname != NULL && --count > 0) {
xfree(fname);
@@ -7500,16 +7501,16 @@ void do_exedit(exarg_T *eap, win_T *old_curwin)
// After a split we can use an existing buffer.
+ (old_curwin != NULL ? ECMD_OLDBUF : 0)
+ (eap->cmdidx == CMD_badd ? ECMD_ADDBUF : 0)
- + (eap->cmdidx == CMD_balt ? ECMD_ALTBUF : 0)
- , old_curwin == NULL ? curwin : NULL) == FAIL) {
+ + (eap->cmdidx == CMD_balt ? ECMD_ALTBUF : 0),
+ old_curwin == NULL ? curwin : NULL) == FAIL) {
// Editing the file failed. If the window was split, close it.
if (old_curwin != NULL) {
need_hide = (curbufIsChanged() && curbuf->b_nwindows <= 1);
if (!need_hide || buf_hide(curbuf)) {
cleanup_T cs;
- /* Reset the error/interrupt/exception state here so that
- * aborting() returns FALSE when closing a window. */
+ // Reset the error/interrupt/exception state here so that
+ // aborting() returns FALSE when closing a window.
enter_cleanup(&cs);
win_close(curwin, !need_hide && !buf_hide(curbuf));
@@ -7674,8 +7675,8 @@ static void ex_read(exarg_T *eap)
}
} else {
if (empty && exmode_active) {
- /* Delete the empty line that remains. Historically ex does
- * this but vi doesn't. */
+ // Delete the empty line that remains. Historically ex does
+ // this but vi doesn't.
if (eap->line2 == 0) {
lnum = curbuf->b_ml.ml_line_count;
} else {
@@ -7706,6 +7707,21 @@ void free_cd_dir(void)
#endif
+// Get the previous directory for the given chdir scope.
+static char_u *get_prevdir(CdScope scope)
+{
+ switch (scope) {
+ case kCdScopeTabpage:
+ return curtab->tp_prevdir;
+ break;
+ case kCdScopeWindow:
+ return curwin->w_prevdir;
+ break;
+ default:
+ return prev_dir;
+ }
+}
+
/// Deal with the side effects of changing the current directory.
///
/// @param scope Scope of the function call (global, tab or window).
@@ -7715,14 +7731,15 @@ void post_chdir(CdScope scope, bool trigger_dirchanged)
XFREE_CLEAR(curwin->w_localdir);
// Overwrite the tab-local CWD for :cd, :tcd.
- if (scope >= kCdScopeTab) {
+ if (scope >= kCdScopeTabpage) {
XFREE_CLEAR(curtab->tp_localdir);
}
if (scope < kCdScopeGlobal) {
+ char_u *pdir = get_prevdir(scope);
// If still in global directory, set CWD as the global directory.
- if (globaldir == NULL && prev_dir != NULL) {
- globaldir = vim_strsave(prev_dir);
+ if (globaldir == NULL && pdir != NULL) {
+ globaldir = vim_strsave(pdir);
}
}
@@ -7735,7 +7752,7 @@ void post_chdir(CdScope scope, bool trigger_dirchanged)
// We are now in the global directory, no need to remember its name.
XFREE_CLEAR(globaldir);
break;
- case kCdScopeTab:
+ case kCdScopeTabpage:
curtab->tp_localdir = (char_u *)xstrdup(cwd);
break;
case kCdScopeWindow:
@@ -7748,59 +7765,92 @@ void post_chdir(CdScope scope, bool trigger_dirchanged)
shorten_fnames(true);
if (trigger_dirchanged) {
- do_autocmd_dirchanged(cwd, scope, false);
+ do_autocmd_dirchanged(cwd, scope, kCdCauseManual);
}
}
-/// `:cd`, `:tcd`, `:lcd`, `:chdir`, `:tchdir` and `:lchdir`.
-void ex_cd(exarg_T *eap)
+/// Change directory function used by :cd/:tcd/:lcd Ex commands and the chdir() function.
+/// @param new_dir The directory to change to.
+/// @param scope Scope of the function call (global, tab or window).
+/// @return true if the directory is successfully changed.
+bool changedir_func(char_u *new_dir, CdScope scope)
{
- char_u *new_dir;
char_u *tofree;
+ char_u *pdir = NULL;
+ bool retval = false;
- new_dir = eap->arg;
-#if !defined(UNIX)
- // for non-UNIX ":cd" means: print current directory
- if (*new_dir == NUL) {
- ex_pwd(NULL);
- } else
-#endif
- {
- if (allbuf_locked()) {
- return;
- }
+ if (new_dir == NULL || allbuf_locked()) {
+ return false;
+ }
- // ":cd -": Change to previous directory
- if (STRCMP(new_dir, "-") == 0) {
- if (prev_dir == NULL) {
- EMSG(_("E186: No previous directory"));
- return;
- }
- new_dir = prev_dir;
+ // ":cd -": Change to previous directory
+ if (STRCMP(new_dir, "-") == 0) {
+ pdir = get_prevdir(scope);
+ if (pdir == NULL) {
+ EMSG(_("E186: No previous directory"));
+ return false;
}
+ new_dir = pdir;
+ }
- // Save current directory for next ":cd -"
- tofree = prev_dir;
- if (os_dirname(NameBuff, MAXPATHL) == OK) {
- prev_dir = vim_strsave(NameBuff);
- } else {
- prev_dir = NULL;
- }
+ // Free the previous directory
+ tofree = get_prevdir(scope);
+
+ if (os_dirname(NameBuff, MAXPATHL) == OK) {
+ pdir = vim_strsave(NameBuff);
+ } else {
+ pdir = NULL;
+ }
+
+ switch (scope) {
+ case kCdScopeTabpage:
+ curtab->tp_prevdir = pdir;
+ break;
+ case kCdScopeWindow:
+ curwin->w_prevdir = pdir;
+ break;
+ default:
+ prev_dir = pdir;
+ }
#if defined(UNIX)
- // On Unix ":cd" means: go to home directory.
- if (*new_dir == NUL) {
- // Use NameBuff for home directory name.
- expand_env((char_u *)"$HOME", NameBuff, MAXPATHL);
- new_dir = NameBuff;
- }
+ // On Unix ":cd" means: go to home directory.
+ if (*new_dir == NUL) {
+ // Use NameBuff for home directory name.
+ expand_env((char_u *)"$HOME", NameBuff, MAXPATHL);
+ new_dir = NameBuff;
+ }
#endif
- CdScope scope = kCdScopeGlobal; // Depends on command invoked
+ if (vim_chdir(new_dir) == 0) {
+ bool dir_differs = pdir == NULL || pathcmp((char *)pdir, (char *)new_dir, -1) != 0;
+ post_chdir(scope, dir_differs);
+ retval = true;
+ } else {
+ EMSG(_(e_failed));
+ }
+ xfree(tofree);
+
+ return retval;
+}
+
+/// ":cd", ":tcd", ":lcd", ":chdir", "tchdir" and ":lchdir".
+void ex_cd(exarg_T *eap)
+{
+ char_u *new_dir;
+ new_dir = eap->arg;
+#if !defined(UNIX) && !defined(VMS)
+ // for non-UNIX ":cd" means: print current directory
+ if (*new_dir == NUL) {
+ ex_pwd(NULL);
+ } else
+#endif
+ {
+ CdScope scope = kCdScopeGlobal;
switch (eap->cmdidx) {
case CMD_tcd:
case CMD_tchdir:
- scope = kCdScopeTab;
+ scope = kCdScopeTabpage;
break;
case CMD_lcd:
case CMD_lchdir:
@@ -7809,18 +7859,12 @@ void ex_cd(exarg_T *eap)
default:
break;
}
-
- if (vim_chdir(new_dir)) {
- EMSG(_(e_failed));
- } else {
- post_chdir(scope, true);
+ if (changedir_func(new_dir, scope)) {
// Echo the new current directory if the command was typed.
if (KeyTyped || p_verbose >= 5) {
ex_pwd(eap);
}
}
-
- xfree(tofree);
}
}
@@ -7833,7 +7877,17 @@ static void ex_pwd(exarg_T *eap)
#ifdef BACKSLASH_IN_FILENAME
slash_adjust(NameBuff);
#endif
- msg(NameBuff);
+ if (p_verbose > 0) {
+ char *context = "global";
+ if (curwin->w_localdir != NULL) {
+ context = "window";
+ } else if (curtab->tp_localdir != NULL) {
+ context = "tabpage";
+ }
+ smsg("[%s] %s", context, (char *)NameBuff);
+ } else {
+ msg(NameBuff);
+ }
} else {
EMSG(_("E187: Unknown"));
}
@@ -8297,8 +8351,8 @@ static void ex_redir(exarg_T *eap)
}
}
- /* Make sure redirection is not off. Can happen for cmdline completion
- * that indirectly invokes a command to catch its output. */
+ // Make sure redirection is not off. Can happen for cmdline completion
+ // that indirectly invokes a command to catch its output.
if (redir_fd != NULL
|| redir_reg || redir_vname) {
redir_off = false;
@@ -9432,14 +9486,14 @@ static void ex_filetype(exarg_T *eap)
}
if (STRCMP(arg, "on") == 0 || STRCMP(arg, "detect") == 0) {
if (*arg == 'o' || !filetype_detect) {
- source_runtime((char_u *)FILETYPE_FILE, DIP_ALL);
+ source_runtime(FILETYPE_FILE, DIP_ALL);
filetype_detect = kTrue;
if (plugin) {
- source_runtime((char_u *)FTPLUGIN_FILE, DIP_ALL);
+ source_runtime(FTPLUGIN_FILE, DIP_ALL);
filetype_plugin = kTrue;
}
if (indent) {
- source_runtime((char_u *)INDENT_FILE, DIP_ALL);
+ source_runtime(INDENT_FILE, DIP_ALL);
filetype_indent = kTrue;
}
}
@@ -9450,15 +9504,15 @@ static void ex_filetype(exarg_T *eap)
} else if (STRCMP(arg, "off") == 0) {
if (plugin || indent) {
if (plugin) {
- source_runtime((char_u *)FTPLUGOF_FILE, DIP_ALL);
+ source_runtime(FTPLUGOF_FILE, DIP_ALL);
filetype_plugin = kFalse;
}
if (indent) {
- source_runtime((char_u *)INDOFF_FILE, DIP_ALL);
+ source_runtime(INDOFF_FILE, DIP_ALL);
filetype_indent = kFalse;
}
} else {
- source_runtime((char_u *)FTOFF_FILE, DIP_ALL);
+ source_runtime(FTOFF_FILE, DIP_ALL);
filetype_detect = kFalse;
}
} else {
@@ -9470,15 +9524,15 @@ static void ex_filetype(exarg_T *eap)
void filetype_maybe_enable(void)
{
if (filetype_detect == kNone) {
- source_runtime((char_u *)FILETYPE_FILE, true);
+ source_runtime(FILETYPE_FILE, true);
filetype_detect = kTrue;
}
if (filetype_plugin == kNone) {
- source_runtime((char_u *)FTPLUGIN_FILE, true);
+ source_runtime(FTPLUGIN_FILE, true);
filetype_plugin = kTrue;
}
if (filetype_indent == kNone) {
- source_runtime((char_u *)INDENT_FILE, true);
+ source_runtime(INDENT_FILE, true);
filetype_indent = kTrue;
}
}
diff --git a/src/nvim/ex_docmd.h b/src/nvim/ex_docmd.h
index 292e01dd6b..7ec4fad277 100644
--- a/src/nvim/ex_docmd.h
+++ b/src/nvim/ex_docmd.h
@@ -11,8 +11,9 @@
#define DOCMD_KEYTYPED 0x08 // don't reset KeyTyped
#define DOCMD_EXCRESET 0x10 // reset exception environment (for debugging
#define DOCMD_KEEPLINE 0x20 // keep typed line for repeating with "."
+#define DOCMD_PREVIEW 0x40 // during 'inccommand' preview
-/* defines for eval_vars() */
+// defines for eval_vars()
#define VALID_PATH 1
#define VALID_HEAD 2
diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c
index 54776c35e7..09a1350f17 100644
--- a/src/nvim/ex_eval.c
+++ b/src/nvim/ex_eval.c
@@ -7,23 +7,23 @@
///
/// Functions for Ex command line for the +eval feature.
#include <assert.h>
-#include <stdbool.h>
#include <inttypes.h>
#include <limits.h>
+#include <stdbool.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/debugger.h"
-#include "nvim/ex_eval.h"
#include "nvim/charset.h"
+#include "nvim/debugger.h"
#include "nvim/eval.h"
#include "nvim/eval/userfunc.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
-#include "nvim/message.h"
+#include "nvim/ex_eval.h"
#include "nvim/memory.h"
+#include "nvim/message.h"
#include "nvim/regexp.h"
#include "nvim/strings.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_eval.c.generated.h"
@@ -111,8 +111,9 @@ int aborting(void)
*/
void update_force_abort(void)
{
- if (cause_abort)
+ if (cause_abort) {
force_abort = TRUE;
+ }
}
/*
@@ -134,8 +135,8 @@ int should_abort(int retcode)
*/
int aborted_in_try(void)
{
- /* This function is only called after an error. In this case, "force_abort"
- * determines whether searching for finally clauses is necessary. */
+ // This function is only called after an error. In this case, "force_abort"
+ // determines whether searching for finally clauses is necessary.
return force_abort;
}
@@ -248,8 +249,9 @@ bool cause_errthrow(const char_u *mesg, bool severe, bool *ignore)
*/
if (msg_list != NULL) {
plist = msg_list;
- while (*plist != NULL)
+ while (*plist != NULL) {
plist = &(*plist)->next;
+ }
elem = xmalloc(sizeof(struct msglist));
elem->msg = vim_strsave(mesg);
@@ -257,19 +259,20 @@ bool cause_errthrow(const char_u *mesg, bool severe, bool *ignore)
elem->throw_msg = NULL;
*plist = elem;
if (plist == msg_list || severe) {
- char_u *tmsg;
+ char_u *tmsg;
- /* Skip the extra "Vim " prefix for message "E458". */
+ // Skip the extra "Vim " prefix for message "E458".
tmsg = elem->msg;
if (STRNCMP(tmsg, "Vim E", 5) == 0
&& ascii_isdigit(tmsg[5])
&& ascii_isdigit(tmsg[6])
&& ascii_isdigit(tmsg[7])
&& tmsg[8] == ':'
- && tmsg[9] == ' ')
+ && tmsg[9] == ' ') {
(*msg_list)->throw_msg = &tmsg[4];
- else
+ } else {
(*msg_list)->throw_msg = tmsg;
+ }
}
}
return true;
@@ -281,7 +284,7 @@ bool cause_errthrow(const char_u *mesg, bool severe, bool *ignore)
*/
static void free_msglist(struct msglist *l)
{
- struct msglist *messages, *next;
+ struct msglist *messages, *next;
messages = l;
while (messages != NULL) {
@@ -318,18 +321,20 @@ void do_errthrow(cstack_T *cstack, char_u *cmdname)
force_abort = TRUE;
}
- /* If no exception is to be thrown or the conversion should be done after
- * returning to a previous invocation of do_one_cmd(), do nothing. */
- if (msg_list == NULL || *msg_list == NULL)
+ // If no exception is to be thrown or the conversion should be done after
+ // returning to a previous invocation of do_one_cmd(), do nothing.
+ if (msg_list == NULL || *msg_list == NULL) {
return;
+ }
- if (throw_exception(*msg_list, ET_ERROR, cmdname) == FAIL)
+ if (throw_exception(*msg_list, ET_ERROR, cmdname) == FAIL) {
free_msglist(*msg_list);
- else {
- if (cstack != NULL)
+ } else {
+ if (cstack != NULL) {
do_throw(cstack);
- else
+ } else {
need_rethrow = TRUE;
+ }
}
*msg_list = NULL;
}
@@ -357,36 +362,35 @@ int do_intthrow(cstack_T *cstack)
}
} else {
#endif
- // Throw an interrupt exception, so that everything will be aborted
- // (except for executing finally clauses), until the interrupt exception
- // is caught; if still uncaught at the top level, the script processing
- // will be terminated then. - If an interrupt exception is already
- // being thrown, do nothing.
-
- if (current_exception) {
- if (current_exception->type == ET_INTERRUPT) {
- return false;
- }
+ // Throw an interrupt exception, so that everything will be aborted
+ // (except for executing finally clauses), until the interrupt exception
+ // is caught; if still uncaught at the top level, the script processing
+ // will be terminated then. - If an interrupt exception is already
+ // being thrown, do nothing.
- // An interrupt exception replaces any user or error exception.
- discard_current_exception();
- }
- if (throw_exception("Vim:Interrupt", ET_INTERRUPT, NULL) != FAIL) {
- do_throw(cstack);
+ if (current_exception) {
+ if (current_exception->type == ET_INTERRUPT) {
+ return false;
}
-#ifdef THROW_TEST
+
+ // An interrupt exception replaces any user or error exception.
+ discard_current_exception();
+ }
+ if (throw_exception("Vim:Interrupt", ET_INTERRUPT, NULL) != FAIL) {
+ do_throw(cstack);
}
+#ifdef THROW_TEST
+}
#endif
return true;
}
// Get an exception message that is to be stored in current_exception->value.
-char_u *get_exception_string(void *value, except_type_T type, char_u *cmdname,
- int *should_free)
+char_u *get_exception_string(void *value, except_type_T type, char_u *cmdname, int *should_free)
{
- char_u *ret, *mesg;
- char_u *p, *val;
+ char_u *ret, *mesg;
+ char_u *p, *val;
if (type == ET_ERROR) {
*should_free = true;
@@ -434,7 +438,7 @@ char_u *get_exception_string(void *value, except_type_T type, char_u *cmdname,
}
} else {
*should_free = FALSE;
- ret = (char_u *) value;
+ ret = (char_u *)value;
}
return ret;
@@ -447,7 +451,7 @@ char_u *get_exception_string(void *value, except_type_T type, char_u *cmdname,
// error exception.
static int throw_exception(void *value, except_type_T type, char_u *cmdname)
{
- except_T *excp;
+ except_T *excp;
int should_free;
/*
@@ -466,14 +470,16 @@ static int throw_exception(void *value, except_type_T type, char_u *cmdname)
excp = xmalloc(sizeof(except_T));
- if (type == ET_ERROR)
- /* Store the original message and prefix the exception value with
- * "Vim:" or, if a command name is given, "Vim(cmdname):". */
+ if (type == ET_ERROR) {
+ // Store the original message and prefix the exception value with
+ // "Vim:" or, if a command name is given, "Vim(cmdname):".
excp->messages = (struct msglist *)value;
+ }
excp->value = get_exception_string(value, type, cmdname, &should_free);
- if (excp->value == NULL && should_free)
+ if (excp->value == NULL && should_free) {
goto nomem;
+ }
excp->type = type;
excp->throw_name = vim_strsave(sourcing_name == NULL
@@ -483,24 +489,27 @@ static int throw_exception(void *value, except_type_T type, char_u *cmdname)
if (p_verbose >= 13 || debug_break_level > 0) {
int save_msg_silent = msg_silent;
- if (debug_break_level > 0)
- msg_silent = FALSE; /* display messages */
- else
+ if (debug_break_level > 0) {
+ msg_silent = FALSE; // display messages
+ } else {
verbose_enter();
+ }
++no_wait_return;
- if (debug_break_level > 0 || *p_vfile == NUL)
- msg_scroll = TRUE; /* always scroll up, don't overwrite */
-
+ if (debug_break_level > 0 || *p_vfile == NUL) {
+ msg_scroll = TRUE; // always scroll up, don't overwrite
+ }
smsg(_("Exception thrown: %s"), excp->value);
msg_puts("\n"); // don't overwrite this either
- if (debug_break_level > 0 || *p_vfile == NUL)
+ if (debug_break_level > 0 || *p_vfile == NUL) {
cmdline_row = msg_row;
+ }
--no_wait_return;
- if (debug_break_level > 0)
+ if (debug_break_level > 0) {
msg_silent = save_msg_silent;
- else
+ } else {
verbose_leave();
+ }
}
current_exception = excp;
@@ -521,7 +530,7 @@ fail:
*/
static void discard_exception(except_T *excp, bool was_finished)
{
- char_u *saved_IObuff;
+ char_u *saved_IObuff;
if (current_exception == excp) {
current_exception = NULL;
@@ -535,13 +544,15 @@ static void discard_exception(except_T *excp, bool was_finished)
int save_msg_silent = msg_silent;
saved_IObuff = vim_strsave(IObuff);
- if (debug_break_level > 0)
- msg_silent = FALSE; /* display messages */
- else
+ if (debug_break_level > 0) {
+ msg_silent = FALSE; // display messages
+ } else {
verbose_enter();
+ }
++no_wait_return;
- if (debug_break_level > 0 || *p_vfile == NUL)
- msg_scroll = TRUE; /* always scroll up, don't overwrite */
+ if (debug_break_level > 0 || *p_vfile == NUL) {
+ msg_scroll = TRUE; // always scroll up, don't overwrite
+ }
smsg(was_finished ? _("Exception finished: %s")
: _("Exception discarded: %s"),
excp->value);
@@ -558,10 +569,12 @@ static void discard_exception(except_T *excp, bool was_finished)
xstrlcpy((char *)IObuff, (const char *)saved_IObuff, IOSIZE);
xfree(saved_IObuff);
}
- if (excp->type != ET_INTERRUPT)
+ if (excp->type != ET_INTERRUPT) {
xfree(excp->value);
- if (excp->type == ET_ERROR)
+ }
+ if (excp->type == ET_ERROR) {
free_msglist(excp->messages);
+ }
xfree(excp->throw_name);
xfree(excp);
}
@@ -586,7 +599,7 @@ static void catch_exception(except_T *excp)
{
excp->caught = caught_stack;
caught_stack = excp;
- set_vim_var_string(VV_EXCEPTION, (char *) excp->value, -1);
+ set_vim_var_string(VV_EXCEPTION, (char *)excp->value, -1);
if (*excp->throw_name != NUL) {
if (excp->throw_lnum != 0) {
vim_snprintf((char *)IObuff, IOSIZE, _("%s, line %" PRId64),
@@ -594,7 +607,7 @@ static void catch_exception(except_T *excp)
} else {
vim_snprintf((char *)IObuff, IOSIZE, "%s", excp->throw_name);
}
- set_vim_var_string(VV_THROWPOINT, (char *) IObuff, -1);
+ set_vim_var_string(VV_THROWPOINT, (char *)IObuff, -1);
} else {
// throw_name not set on an exception from a command that was typed.
set_vim_var_string(VV_THROWPOINT, NULL, -1);
@@ -603,24 +616,27 @@ static void catch_exception(except_T *excp)
if (p_verbose >= 13 || debug_break_level > 0) {
int save_msg_silent = msg_silent;
- if (debug_break_level > 0)
- msg_silent = FALSE; /* display messages */
- else
+ if (debug_break_level > 0) {
+ msg_silent = FALSE; // display messages
+ } else {
verbose_enter();
+ }
++no_wait_return;
- if (debug_break_level > 0 || *p_vfile == NUL)
- msg_scroll = TRUE; /* always scroll up, don't overwrite */
-
+ if (debug_break_level > 0 || *p_vfile == NUL) {
+ msg_scroll = TRUE; // always scroll up, don't overwrite
+ }
smsg(_("Exception caught: %s"), excp->value);
msg_puts("\n"); // don't overwrite this either
- if (debug_break_level > 0 || *p_vfile == NUL)
+ if (debug_break_level > 0 || *p_vfile == NUL) {
cmdline_row = msg_row;
+ }
--no_wait_return;
- if (debug_break_level > 0)
+ if (debug_break_level > 0) {
msg_silent = save_msg_silent;
- else
+ } else {
verbose_leave();
+ }
}
}
@@ -634,7 +650,7 @@ static void finish_exception(except_T *excp)
}
caught_stack = caught_stack->caught;
if (caught_stack != NULL) {
- set_vim_var_string(VV_EXCEPTION, (char *) caught_stack->value, -1);
+ set_vim_var_string(VV_EXCEPTION, (char *)caught_stack->value, -1);
if (*caught_stack->throw_name != NUL) {
if (caught_stack->throw_lnum != 0) {
vim_snprintf((char *)IObuff, IOSIZE,
@@ -644,7 +660,7 @@ static void finish_exception(except_T *excp)
vim_snprintf((char *)IObuff, IOSIZE, "%s",
caught_stack->throw_name);
}
- set_vim_var_string(VV_THROWPOINT, (char *) IObuff, -1);
+ set_vim_var_string(VV_THROWPOINT, (char *)IObuff, -1);
} else {
// throw_name not set on an exception from a command that was
// typed.
@@ -688,7 +704,7 @@ static void report_pending(int action, int pending, void *value)
case RP_RESUME:
mesg = _("%s resumed");
break;
- /* case RP_DISCARD: */
+ // case RP_DISCARD:
default:
mesg = _("%s discarded");
break;
@@ -708,7 +724,7 @@ static void report_pending(int action, int pending, void *value)
s = ":finish";
break;
case CSTP_RETURN:
- /* ":return" command producing value, allocated */
+ // ":return" command producing value, allocated
s = (char *)get_return_cmd(value);
break;
@@ -718,30 +734,34 @@ static void report_pending(int action, int pending, void *value)
mesg, _("Exception"));
mesg = (char *)concat_str(IObuff, (char_u *)": %s");
s = (char *)((except_T *)value)->value;
- } else if ((pending & CSTP_ERROR) && (pending & CSTP_INTERRUPT))
+ } else if ((pending & CSTP_ERROR) && (pending & CSTP_INTERRUPT)) {
s = _("Error and interrupt");
- else if (pending & CSTP_ERROR)
+ } else if (pending & CSTP_ERROR) {
s = _("Error");
- else /* if (pending & CSTP_INTERRUPT) */
+ } else { // if (pending & CSTP_INTERRUPT)
s = _("Interrupt");
+ }
}
save_msg_silent = msg_silent;
- if (debug_break_level > 0)
- msg_silent = FALSE; /* display messages */
+ if (debug_break_level > 0) {
+ msg_silent = FALSE; // display messages
+ }
++no_wait_return;
- msg_scroll = TRUE; /* always scroll up, don't overwrite */
+ msg_scroll = TRUE; // always scroll up, don't overwrite
smsg(mesg, s);
msg_puts("\n"); // don't overwrite this either
cmdline_row = msg_row;
--no_wait_return;
- if (debug_break_level > 0)
+ if (debug_break_level > 0) {
msg_silent = save_msg_silent;
+ }
- if (pending == CSTP_RETURN)
+ if (pending == CSTP_RETURN) {
xfree(s);
- else if (pending & CSTP_THROW)
+ } else if (pending & CSTP_THROW) {
xfree(mesg);
+ }
}
/*
@@ -751,11 +771,13 @@ static void report_pending(int action, int pending, void *value)
void report_make_pending(int pending, void *value)
{
if (p_verbose >= 14 || debug_break_level > 0) {
- if (debug_break_level <= 0)
+ if (debug_break_level <= 0) {
verbose_enter();
+ }
report_pending(RP_MAKE, pending, value);
- if (debug_break_level <= 0)
+ if (debug_break_level <= 0) {
verbose_leave();
+ }
}
}
@@ -766,11 +788,13 @@ void report_make_pending(int pending, void *value)
void report_resume_pending(int pending, void *value)
{
if (p_verbose >= 14 || debug_break_level > 0) {
- if (debug_break_level <= 0)
+ if (debug_break_level <= 0) {
verbose_enter();
+ }
report_pending(RP_RESUME, pending, value);
- if (debug_break_level <= 0)
+ if (debug_break_level <= 0) {
verbose_leave();
+ }
}
}
@@ -781,11 +805,13 @@ void report_resume_pending(int pending, void *value)
void report_discard_pending(int pending, void *value)
{
if (p_verbose >= 14 || debug_break_level > 0) {
- if (debug_break_level <= 0)
+ if (debug_break_level <= 0) {
verbose_enter();
+ }
report_pending(RP_DISCARD, pending, value);
- if (debug_break_level <= 0)
+ if (debug_break_level <= 0) {
verbose_leave();
+ }
}
}
@@ -808,9 +834,9 @@ void ex_if(exarg_T *eap)
int result;
cstack_T *const cstack = eap->cstack;
- if (cstack->cs_idx == CSTACK_LEN - 1)
+ if (cstack->cs_idx == CSTACK_LEN - 1) {
eap->errmsg = (char_u *)N_("E579: :if nesting too deep");
- else {
+ } else {
++cstack->cs_idx;
cstack->cs_flags[cstack->cs_idx] = 0;
@@ -820,11 +846,13 @@ void ex_if(exarg_T *eap)
result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
if (!skip && !error) {
- if (result)
+ if (result) {
cstack->cs_flags[cstack->cs_idx] = CSF_ACTIVE | CSF_TRUE;
- } else
- /* set TRUE, so this conditional will never get active */
+ }
+ } else {
+ // set TRUE, so this conditional will never get active
cstack->cs_flags[cstack->cs_idx] = CSF_TRUE;
+ }
}
}
@@ -884,13 +912,15 @@ void ex_else(exarg_T *eap)
skip = TRUE;
}
- /* if skipping or the ":if" was TRUE, reset ACTIVE, otherwise set it */
+ // if skipping or the ":if" was TRUE, reset ACTIVE, otherwise set it
if (skip || cstack->cs_flags[cstack->cs_idx] & CSF_TRUE) {
- if (eap->errmsg == NULL)
+ if (eap->errmsg == NULL) {
cstack->cs_flags[cstack->cs_idx] = CSF_TRUE;
- skip = TRUE; /* don't evaluate an ":elseif" */
- } else
+ }
+ skip = TRUE; // don't evaluate an ":elseif"
+ } else {
cstack->cs_flags[cstack->cs_idx] = CSF_ACTIVE;
+ }
/*
* When debugging or a breakpoint was encountered, display the debug prompt
@@ -910,22 +940,25 @@ void ex_else(exarg_T *eap)
if (eap->cmdidx == CMD_elseif) {
bool error;
result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
- /* When throwing error exceptions, we want to throw always the first
- * of several errors in a row. This is what actually happens when
- * a conditional error was detected above and there is another failure
- * when parsing the expression. Since the skip flag is set in this
- * case, the parsing error will be ignored by emsg(). */
+ // When throwing error exceptions, we want to throw always the first
+ // of several errors in a row. This is what actually happens when
+ // a conditional error was detected above and there is another failure
+ // when parsing the expression. Since the skip flag is set in this
+ // case, the parsing error will be ignored by emsg().
if (!skip && !error) {
- if (result)
+ if (result) {
cstack->cs_flags[cstack->cs_idx] = CSF_ACTIVE | CSF_TRUE;
- else
+ } else {
cstack->cs_flags[cstack->cs_idx] = 0;
- } else if (eap->errmsg == NULL)
- /* set TRUE, so this conditional will never get active */
+ }
+ } else if (eap->errmsg == NULL) {
+ // set TRUE, so this conditional will never get active
cstack->cs_flags[cstack->cs_idx] = CSF_TRUE;
- } else
+ }
+ } else {
cstack->cs_flags[cstack->cs_idx] |= CSF_ELSE;
+ }
}
/*
@@ -938,9 +971,9 @@ void ex_while(exarg_T *eap)
int result;
cstack_T *const cstack = eap->cstack;
- if (cstack->cs_idx == CSTACK_LEN - 1)
+ if (cstack->cs_idx == CSTACK_LEN - 1) {
eap->errmsg = (char_u *)N_("E585: :while/:for nesting too deep");
- else {
+ } else {
/*
* The loop flag is set when we have jumped back from the matching
* ":endwhile" or ":endfor". When not set, need to initialise this
@@ -967,21 +1000,22 @@ void ex_while(exarg_T *eap)
* ":for var in list-expr"
*/
if ((cstack->cs_lflags & CSL_HAD_LOOP) != 0) {
- /* Jumping here from a ":continue" or ":endfor": use the
- * previously evaluated list. */
+ // Jumping here from a ":continue" or ":endfor": use the
+ // previously evaluated list.
fi = cstack->cs_forinfo[cstack->cs_idx];
error = FALSE;
} else {
- /* Evaluate the argument and get the info in a structure. */
+ // Evaluate the argument and get the info in a structure.
fi = eval_for_line(eap->arg, &error, &eap->nextcmd, skip);
cstack->cs_forinfo[cstack->cs_idx] = fi;
}
- /* use the element at the start of the list and advance */
- if (!error && fi != NULL && !skip)
+ // use the element at the start of the list and advance
+ if (!error && fi != NULL && !skip) {
result = next_for_item(fi, eap->arg);
- else
+ } else {
result = FALSE;
+ }
if (!result) {
free_for_info(fi);
@@ -999,12 +1033,13 @@ void ex_while(exarg_T *eap)
cstack->cs_lflags ^= CSL_HAD_LOOP;
} else {
cstack->cs_lflags &= ~CSL_HAD_LOOP;
- /* If the ":while" evaluates to FALSE or ":for" is past the end of
- * the list, show the debug prompt at the ":endwhile"/":endfor" as
- * if there was a ":break" in a ":while"/":for" evaluating to
- * TRUE. */
- if (!skip && !error)
+ // If the ":while" evaluates to FALSE or ":for" is past the end of
+ // the list, show the debug prompt at the ":endwhile"/":endfor" as
+ // if there was a ":break" in a ":while"/":for" evaluating to
+ // TRUE.
+ if (!skip && !error) {
cstack->cs_flags[cstack->cs_idx] |= CSF_TRUE;
+ }
}
}
}
@@ -1017,9 +1052,9 @@ void ex_continue(exarg_T *eap)
int idx;
cstack_T *const cstack = eap->cstack;
- if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0)
+ if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0) {
eap->errmsg = (char_u *)N_("E586: :continue without :while or :for");
- else {
+ } else {
/* Try to find the matching ":while". This might stop at a try
* conditional not in its finally clause (which is then to be executed
* next). Therefore, deactivate all conditionals except the ":while"
@@ -1033,7 +1068,7 @@ void ex_continue(exarg_T *eap)
* Set CSL_HAD_CONT, so do_cmdline() will jump back to the
* matching ":while".
*/
- cstack->cs_lflags |= CSL_HAD_CONT; /* let do_cmdline() handle it */
+ cstack->cs_lflags |= CSL_HAD_CONT; // let do_cmdline() handle it
} else {
/* If a try conditional not in its finally clause is reached first,
* make the ":continue" pending for execution at the ":endtry". */
@@ -1073,7 +1108,7 @@ void ex_endwhile(exarg_T *eap)
{
cstack_T *const cstack = eap->cstack;
int idx;
- char_u *err;
+ char_u *err;
int csf;
int fl;
@@ -1085,36 +1120,39 @@ void ex_endwhile(exarg_T *eap)
csf = CSF_FOR;
}
- if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0)
+ if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0) {
eap->errmsg = err;
- else {
+ } else {
fl = cstack->cs_flags[cstack->cs_idx];
if (!(fl & csf)) {
- /* If we are in a ":while" or ":for" but used the wrong endloop
- * command, do not rewind to the next enclosing ":for"/":while". */
- if (fl & CSF_WHILE)
+ // If we are in a ":while" or ":for" but used the wrong endloop
+ // command, do not rewind to the next enclosing ":for"/":while".
+ if (fl & CSF_WHILE) {
eap->errmsg = (char_u *)_("E732: Using :endfor with :while");
- else if (fl & CSF_FOR)
+ } else if (fl & CSF_FOR) {
eap->errmsg = (char_u *)_("E733: Using :endwhile with :for");
+ }
}
if (!(fl & (CSF_WHILE | CSF_FOR))) {
- if (!(fl & CSF_TRY))
+ if (!(fl & CSF_TRY)) {
eap->errmsg = e_endif;
- else if (fl & CSF_FINALLY)
+ } else if (fl & CSF_FINALLY) {
eap->errmsg = e_endtry;
- /* Try to find the matching ":while" and report what's missing. */
+ }
+ // Try to find the matching ":while" and report what's missing.
for (idx = cstack->cs_idx; idx > 0; --idx) {
fl = cstack->cs_flags[idx];
if ((fl & CSF_TRY) && !(fl & CSF_FINALLY)) {
- /* Give up at a try conditional not in its finally clause.
- * Ignore the ":endwhile"/":endfor". */
+ // Give up at a try conditional not in its finally clause.
+ // Ignore the ":endwhile"/":endfor".
eap->errmsg = err;
return;
}
- if (fl & csf)
+ if (fl & csf) {
break;
+ }
}
- /* Cleanup and rewind all contained (and unclosed) conditionals. */
+ // Cleanup and rewind all contained (and unclosed) conditionals.
(void)cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, FALSE);
rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel);
}
@@ -1130,8 +1168,9 @@ void ex_endwhile(exarg_T *eap)
*/
else if (cstack->cs_flags[cstack->cs_idx] & CSF_TRUE
&& !(cstack->cs_flags[cstack->cs_idx] & CSF_ACTIVE)
- && dbg_check_skipped(eap))
+ && dbg_check_skipped(eap)) {
(void)do_intthrow(cstack);
+ }
/*
* Set loop flag, so do_cmdline() will jump back to the matching
@@ -1216,13 +1255,14 @@ void do_throw(cstack_T *cstack)
* the matching catch clause or the finally clause.
*/
if (!(cstack->cs_flags[idx] & CSF_CAUGHT)) {
- if (cstack->cs_flags[idx] & CSF_ACTIVE)
+ if (cstack->cs_flags[idx] & CSF_ACTIVE) {
cstack->cs_flags[idx] |= CSF_THROWN;
- else
- /* THROWN may have already been set for a catchable exception
- * that has been discarded. Ensure it is reset for the new
- * exception. */
+ } else {
+ // THROWN may have already been set for a catchable exception
+ // that has been discarded. Ensure it is reset for the new
+ // exception.
cstack->cs_flags[idx] &= ~CSF_THROWN;
+ }
}
cstack->cs_flags[idx] &= ~CSF_ACTIVE;
cstack->cs_exception[idx] = current_exception;
@@ -1237,9 +1277,9 @@ void ex_try(exarg_T *eap)
int skip;
cstack_T *const cstack = eap->cstack;
- if (cstack->cs_idx == CSTACK_LEN - 1)
+ if (cstack->cs_idx == CSTACK_LEN - 1) {
eap->errmsg = (char_u *)N_("E601: :try nesting too deep");
- else {
+ } else {
++cstack->cs_idx;
++cstack->cs_trylevel;
cstack->cs_flags[cstack->cs_idx] = CSF_TRY;
@@ -1248,9 +1288,9 @@ void ex_try(exarg_T *eap)
skip = CHECK_SKIP;
if (!skip) {
- /* Set ACTIVE and TRUE. TRUE means that the corresponding ":catch"
- * commands should check for a match if an exception is thrown and
- * that the finally clause needs to be executed. */
+ // Set ACTIVE and TRUE. TRUE means that the corresponding ":catch"
+ // commands should check for a match if an exception is thrown and
+ // that the finally clause needs to be executed.
cstack->cs_flags[cstack->cs_idx] |= CSF_ACTIVE | CSF_TRUE;
/*
@@ -1278,7 +1318,6 @@ void ex_try(exarg_T *eap)
emsg_silent = 0;
}
}
-
}
}
@@ -1291,38 +1330,41 @@ void ex_catch(exarg_T *eap)
int give_up = FALSE;
int skip = FALSE;
int caught = FALSE;
- char_u *end;
+ char_u *end;
char_u save_char = 0;
- char_u *save_cpo;
+ char_u *save_cpo;
regmatch_T regmatch;
int prev_got_int;
cstack_T *const cstack = eap->cstack;
- char_u *pat;
+ char_u *pat;
if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0) {
eap->errmsg = (char_u *)N_("E603: :catch without :try");
give_up = TRUE;
} else {
if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) {
- /* Report what's missing if the matching ":try" is not in its
- * finally clause. */
+ // Report what's missing if the matching ":try" is not in its
+ // finally clause.
eap->errmsg = get_end_emsg(cstack);
skip = TRUE;
}
- for (idx = cstack->cs_idx; idx > 0; --idx)
- if (cstack->cs_flags[idx] & CSF_TRY)
+ for (idx = cstack->cs_idx; idx > 0; --idx) {
+ if (cstack->cs_flags[idx] & CSF_TRY) {
break;
+ }
+ }
if (cstack->cs_flags[idx] & CSF_FINALLY) {
/* Give up for a ":catch" after ":finally" and ignore it.
* Just parse. */
eap->errmsg = (char_u *)N_("E604: :catch after :finally");
give_up = TRUE;
- } else
+ } else {
rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
- &cstack->cs_looplevel);
+ &cstack->cs_looplevel);
+ }
}
- if (ends_excmd(*eap->arg)) { /* no argument, catch all errors */
+ if (ends_excmd(*eap->arg)) { // no argument, catch all errors
pat = (char_u *)".*";
end = NULL;
eap->nextcmd = find_nextcmd(eap->arg);
@@ -1390,7 +1432,7 @@ void ex_catch(exarg_T *eap)
prev_got_int = got_int;
got_int = FALSE;
caught = vim_regexec_nl(&regmatch, current_exception->value,
- (colnr_T)0);
+ (colnr_T)0);
got_int |= prev_got_int;
vim_regfree(regmatch.regprog);
}
@@ -1430,8 +1472,9 @@ void ex_catch(exarg_T *eap)
}
}
- if (end != NULL)
+ if (end != NULL) {
eap->nextcmd = find_nextcmd(end);
+ }
}
/*
@@ -1444,28 +1487,31 @@ void ex_finally(exarg_T *eap)
int pending = CSTP_NONE;
cstack_T *const cstack = eap->cstack;
- if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0)
+ if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0) {
eap->errmsg = (char_u *)N_("E606: :finally without :try");
- else {
+ } else {
if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) {
eap->errmsg = get_end_emsg(cstack);
- for (idx = cstack->cs_idx - 1; idx > 0; --idx)
- if (cstack->cs_flags[idx] & CSF_TRY)
+ for (idx = cstack->cs_idx - 1; idx > 0; --idx) {
+ if (cstack->cs_flags[idx] & CSF_TRY) {
break;
- /* Make this error pending, so that the commands in the following
- * finally clause can be executed. This overrules also a pending
- * ":continue", ":break", ":return", or ":finish". */
+ }
+ }
+ // Make this error pending, so that the commands in the following
+ // finally clause can be executed. This overrules also a pending
+ // ":continue", ":break", ":return", or ":finish".
pending = CSTP_ERROR;
- } else
+ } else {
idx = cstack->cs_idx;
+ }
if (cstack->cs_flags[idx] & CSF_FINALLY) {
- /* Give up for a multiple ":finally" and ignore it. */
+ // Give up for a multiple ":finally" and ignore it.
eap->errmsg = (char_u *)N_("E607: multiple :finally");
return;
}
rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
- &cstack->cs_looplevel);
+ &cstack->cs_looplevel);
/*
* Don't do something when the corresponding try block never got active
@@ -1478,14 +1524,14 @@ void ex_finally(exarg_T *eap)
skip = !(cstack->cs_flags[cstack->cs_idx] & CSF_TRUE);
if (!skip) {
- /* When debugging or a breakpoint was encountered, display the
- * debug prompt (if not already done). The user then knows that the
- * finally clause is executed. */
+ // When debugging or a breakpoint was encountered, display the
+ // debug prompt (if not already done). The user then knows that the
+ // finally clause is executed.
if (dbg_check_skipped(eap)) {
- /* Handle a ">quit" debug command as if an interrupt had
- * occurred before the ":finally". That is, discard the
- * original exception and replace it by an interrupt
- * exception. */
+ // Handle a ">quit" debug command as if an interrupt had
+ // occurred before the ":finally". That is, discard the
+ // original exception and replace it by an interrupt
+ // exception.
(void)do_intthrow(cstack);
}
@@ -1517,7 +1563,7 @@ void ex_finally(exarg_T *eap)
if (pending == CSTP_ERROR || did_emsg || got_int || current_exception) {
if (cstack->cs_pending[cstack->cs_idx] == CSTP_RETURN) {
report_discard_pending(CSTP_RETURN,
- cstack->cs_rettv[cstack->cs_idx]);
+ cstack->cs_rettv[cstack->cs_idx]);
discard_pending_return(cstack->cs_rettv[cstack->cs_idx]);
}
if (pending == CSTP_ERROR && !did_emsg) {
@@ -1564,7 +1610,7 @@ void ex_endtry(exarg_T *eap)
int skip;
int rethrow = FALSE;
int pending = CSTP_NONE;
- void *rettv = NULL;
+ void *rettv = NULL;
cstack_T *const cstack = eap->cstack;
if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0) {
@@ -1585,13 +1631,13 @@ void ex_endtry(exarg_T *eap)
if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) {
eap->errmsg = get_end_emsg(cstack);
- /* Find the matching ":try" and report what's missing. */
+ // Find the matching ":try" and report what's missing.
idx = cstack->cs_idx;
do
--idx;
while (idx > 0 && !(cstack->cs_flags[idx] & CSF_TRY));
rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
- &cstack->cs_looplevel);
+ &cstack->cs_looplevel);
skip = TRUE;
/*
@@ -1656,10 +1702,11 @@ void ex_endtry(exarg_T *eap)
if (!skip) {
pending = cstack->cs_pending[idx];
cstack->cs_pending[idx] = CSTP_NONE;
- if (pending == CSTP_RETURN)
+ if (pending == CSTP_RETURN) {
rettv = cstack->cs_rettv[idx];
- else if (pending & CSTP_THROW)
+ } else if (pending & CSTP_THROW) {
current_exception = cstack->cs_exception[idx];
+ }
}
/*
@@ -1679,19 +1726,19 @@ void ex_endtry(exarg_T *eap)
if (!skip) {
report_resume_pending(pending,
- (pending == CSTP_RETURN) ? rettv :
- (pending & CSTP_THROW) ? (void *)current_exception : NULL);
+ (pending == CSTP_RETURN) ? rettv :
+ (pending & CSTP_THROW) ? (void *)current_exception : NULL);
switch (pending) {
case CSTP_NONE:
break;
- /* Reactivate a pending ":continue", ":break", ":return",
- * ":finish" from the try block or a catch clause of this try
- * conditional. This is skipped, if there was an error in an
- * (unskipped) conditional command or an interrupt afterwards
- * or if the finally clause is present and executed a new error,
- * interrupt, throw, ":continue", ":break", ":return", or
- * ":finish". */
+ // Reactivate a pending ":continue", ":break", ":return",
+ // ":finish" from the try block or a catch clause of this try
+ // conditional. This is skipped, if there was an error in an
+ // (unskipped) conditional command or an interrupt afterwards
+ // or if the finally clause is present and executed a new error,
+ // interrupt, throw, ":continue", ":break", ":return", or
+ // ":finish".
case CSTP_CONTINUE:
ex_continue(eap);
break;
@@ -1788,7 +1835,7 @@ void enter_cleanup(cleanup_T *csp)
did_emsg = got_int = need_rethrow = false;
current_exception = NULL;
- /* Report if required by the 'verbose' option or when debugging. */
+ // Report if required by the 'verbose' option or when debugging.
report_make_pending(pending, csp->exception);
} else {
csp->pending = CSTP_NONE;
@@ -1815,13 +1862,14 @@ void leave_cleanup(cleanup_T *csp)
{
int pending = csp->pending;
- if (pending == CSTP_NONE) /* nothing to do */
+ if (pending == CSTP_NONE) { // nothing to do
return;
+ }
- /* If there was an aborting error, an interrupt, or an uncaught exception
- * after the corresponding call to enter_cleanup(), discard what has been
- * made pending by it. Report this to the user if required by the
- * 'verbose' option or when debugging. */
+ // If there was an aborting error, an interrupt, or an uncaught exception
+ // after the corresponding call to enter_cleanup(), discard what has been
+ // made pending by it. Report this to the user if required by the
+ // 'verbose' option or when debugging.
if (aborting() || need_rethrow) {
if (pending & CSTP_THROW) {
// Cancel the pending exception (includes report).
@@ -1830,10 +1878,11 @@ void leave_cleanup(cleanup_T *csp)
report_discard_pending(pending, NULL);
}
- /* If an error was about to be converted to an exception when
- * enter_cleanup() was called, free the message list. */
- if (msg_list != NULL)
+ // If an error was about to be converted to an exception when
+ // enter_cleanup() was called, free the message list.
+ if (msg_list != NULL) {
free_global_msglist();
+ }
}
/*
* If there was no new error, interrupt, or throw between the calls
@@ -1846,9 +1895,9 @@ void leave_cleanup(cleanup_T *csp)
* called, we need to rethrow it. Make it the exception currently
* being thrown.
*/
- if (pending & CSTP_THROW)
+ if (pending & CSTP_THROW) {
current_exception = csp->exception;
-
+ }
/*
* If an error was about to be converted to an exception when
* enter_cleanup() was called, let "cause_abort" take the part of
@@ -1871,8 +1920,7 @@ void leave_cleanup(cleanup_T *csp)
}
// Report if required by the 'verbose' option or when debugging.
- report_resume_pending(
- pending, ((pending & CSTP_THROW) ? (void *)current_exception : NULL));
+ report_resume_pending(pending, ((pending & CSTP_THROW) ? (void *)current_exception : NULL));
}
}
@@ -1920,7 +1968,7 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive)
case CSTP_RETURN:
report_discard_pending(CSTP_RETURN,
- cstack->cs_rettv[idx]);
+ cstack->cs_rettv[idx]);
discard_pending_return(cstack->cs_rettv[idx]);
cstack->cs_pending[idx] = CSTP_NONE;
break;
@@ -1948,32 +1996,36 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive)
*/
if (!(cstack->cs_flags[idx] & CSF_FINALLY)) {
if ((cstack->cs_flags[idx] & CSF_ACTIVE)
- && (cstack->cs_flags[idx] & CSF_CAUGHT))
+ && (cstack->cs_flags[idx] & CSF_CAUGHT)) {
finish_exception((except_T *)cstack->cs_exception[idx]);
- /* Stop at this try conditional - except the try block never
- * got active (because of an inactive surrounding conditional
- * or when the ":try" appeared after an error or interrupt or
- * throw). */
+ }
+ // Stop at this try conditional - except the try block never
+ // got active (because of an inactive surrounding conditional
+ // or when the ":try" appeared after an error or interrupt or
+ // throw).
if (cstack->cs_flags[idx] & CSF_TRUE) {
- if (searched_cond == 0 && !inclusive)
+ if (searched_cond == 0 && !inclusive) {
break;
+ }
stop = TRUE;
}
}
}
- /* Stop on the searched conditional type (even when the surrounding
- * conditional is not active or something has been made pending).
- * If "inclusive" is TRUE and "searched_cond" is CSF_TRY|CSF_SILENT,
- * check first whether "emsg_silent" needs to be restored. */
+ // Stop on the searched conditional type (even when the surrounding
+ // conditional is not active or something has been made pending).
+ // If "inclusive" is TRUE and "searched_cond" is CSF_TRY|CSF_SILENT,
+ // check first whether "emsg_silent" needs to be restored.
if (cstack->cs_flags[idx] & searched_cond) {
- if (!inclusive)
+ if (!inclusive) {
break;
+ }
stop = TRUE;
}
cstack->cs_flags[idx] &= ~CSF_ACTIVE;
- if (stop && searched_cond != (CSF_TRY | CSF_SILENT))
+ if (stop && searched_cond != (CSF_TRY | CSF_SILENT)) {
break;
+ }
/*
* When leaving a try conditional that reset "emsg_silent" on its
@@ -1982,7 +2034,7 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive)
*/
if ((cstack->cs_flags[idx] & CSF_TRY)
&& (cstack->cs_flags[idx] & CSF_SILENT)) {
- eslist_T *elem;
+ eslist_T *elem;
elem = cstack->cs_emsg_silent_list;
cstack->cs_emsg_silent_list = elem->next;
@@ -1990,8 +2042,9 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive)
xfree(elem);
cstack->cs_flags[idx] &= ~CSF_SILENT;
}
- if (stop)
+ if (stop) {
break;
+ }
}
return idx;
}
@@ -2001,10 +2054,12 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive)
*/
static char_u *get_end_emsg(cstack_T *cstack)
{
- if (cstack->cs_flags[cstack->cs_idx] & CSF_WHILE)
+ if (cstack->cs_flags[cstack->cs_idx] & CSF_WHILE) {
return e_endwhile;
- if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR)
+ }
+ if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR) {
return e_endfor;
+ }
return e_endif;
}
@@ -2016,14 +2071,15 @@ static char_u *get_end_emsg(cstack_T *cstack)
* type.
* Also free "for info" structures where needed.
*/
-void rewind_conditionals(cstack_T *cstack, int idx, int cond_type,
- int *cond_level)
+void rewind_conditionals(cstack_T *cstack, int idx, int cond_type, int *cond_level)
{
while (cstack->cs_idx > idx) {
- if (cstack->cs_flags[cstack->cs_idx] & cond_type)
+ if (cstack->cs_flags[cstack->cs_idx] & cond_type) {
--*cond_level;
- if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR)
+ }
+ if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR) {
free_for_info(cstack->cs_forinfo[cstack->cs_idx]);
+ }
--cstack->cs_idx;
}
}
@@ -2043,18 +2099,21 @@ int has_loop_cmd(char_u *p)
{
int len;
- /* skip modifiers, white space and ':' */
+ // skip modifiers, white space and ':'
for (;; ) {
- while (*p == ' ' || *p == '\t' || *p == ':')
+ while (*p == ' ' || *p == '\t' || *p == ':') {
++p;
+ }
len = modifier_len(p);
- if (len == 0)
+ if (len == 0) {
break;
+ }
p += len;
}
if ((p[0] == 'w' && p[1] == 'h')
- || (p[0] == 'f' && p[1] == 'o' && p[2] == 'r'))
+ || (p[0] == 'f' && p[1] == 'o' && p[2] == 'r')) {
return TRUE;
+ }
return FALSE;
}
diff --git a/src/nvim/ex_eval.h b/src/nvim/ex_eval.h
index d8388c9156..d3ba43a469 100644
--- a/src/nvim/ex_eval.h
+++ b/src/nvim/ex_eval.h
@@ -1,22 +1,22 @@
#ifndef NVIM_EX_EVAL_H
#define NVIM_EX_EVAL_H
-#include "nvim/pos.h" // for linenr_T
#include "nvim/ex_cmds_defs.h" // for exarg_T
+#include "nvim/pos.h" // for linenr_T
/* There is no CSF_IF, the lack of CSF_WHILE, CSF_FOR and CSF_TRY means ":if"
* was used. */
-# define CSF_TRUE 0x0001 /* condition was TRUE */
-# define CSF_ACTIVE 0x0002 /* current state is active */
-# define CSF_ELSE 0x0004 /* ":else" has been passed */
-# define CSF_WHILE 0x0008 /* is a ":while" */
-# define CSF_FOR 0x0010 /* is a ":for" */
+#define CSF_TRUE 0x0001 // condition was TRUE
+#define CSF_ACTIVE 0x0002 // current state is active
+#define CSF_ELSE 0x0004 // ":else" has been passed
+#define CSF_WHILE 0x0008 // is a ":while"
+#define CSF_FOR 0x0010 // is a ":for"
-# define CSF_TRY 0x0100 /* is a ":try" */
-# define CSF_FINALLY 0x0200 /* ":finally" has been passed */
-# define CSF_THROWN 0x0400 /* exception thrown to this try conditional */
-# define CSF_CAUGHT 0x0800 /* exception caught by this try conditional */
-# define CSF_SILENT 0x1000 /* "emsg_silent" reset by ":try" */
+#define CSF_TRY 0x0100 // is a ":try"
+#define CSF_FINALLY 0x0200 // ":finally" has been passed
+#define CSF_THROWN 0x0400 // exception thrown to this try conditional
+#define CSF_CAUGHT 0x0800 // exception caught by this try conditional
+#define CSF_SILENT 0x1000 // "emsg_silent" reset by ":try"
/* Note that CSF_ELSE is only used when CSF_TRY and CSF_WHILE are unset
* (an ":if"), and CSF_SILENT is only used when CSF_TRY is set. */
@@ -24,14 +24,14 @@
* What's pending for being reactivated at the ":endtry" of this try
* conditional:
*/
-# define CSTP_NONE 0 /* nothing pending in ":finally" clause */
-# define CSTP_ERROR 1 /* an error is pending */
-# define CSTP_INTERRUPT 2 /* an interrupt is pending */
-# define CSTP_THROW 4 /* a throw is pending */
-# define CSTP_BREAK 8 /* ":break" is pending */
-# define CSTP_CONTINUE 16 /* ":continue" is pending */
-# define CSTP_RETURN 24 /* ":return" is pending */
-# define CSTP_FINISH 32 /* ":finish" is pending */
+#define CSTP_NONE 0 // nothing pending in ":finally" clause
+#define CSTP_ERROR 1 // an error is pending
+#define CSTP_INTERRUPT 2 // an interrupt is pending
+#define CSTP_THROW 4 // a throw is pending
+#define CSTP_BREAK 8 // ":break" is pending
+#define CSTP_CONTINUE 16 // ":continue" is pending
+#define CSTP_RETURN 24 // ":return" is pending
+#define CSTP_FINISH 32 // ":finish" is pending
/*
* A list of error messages that can be converted to an exception. "throw_msg"
@@ -40,9 +40,9 @@
* message in the list. See cause_errthrow() below.
*/
struct msglist {
- char_u *msg; /* original message */
- char_u *throw_msg; /* msg to throw: usually original one */
- struct msglist *next; /* next of several messages in a row */
+ char_u *msg; // original message
+ char_u *throw_msg; // msg to throw: usually original one
+ struct msglist *next; // next of several messages in a row
};
// The exception types.
@@ -60,11 +60,11 @@ typedef enum
typedef struct vim_exception except_T;
struct vim_exception {
except_type_T type; // exception type
- char_u *value; // exception value
- struct msglist *messages; // message(s) causing error exception
- char_u *throw_name; // name of the throw point
+ char_u *value; // exception value
+ struct msglist *messages; // message(s) causing error exception
+ char_u *throw_name; // name of the throw point
linenr_T throw_lnum; // line number of the throw point
- except_T *caught; // next exception on the caught stack
+ except_T *caught; // next exception on the caught stack
};
/*
@@ -74,8 +74,8 @@ struct vim_exception {
*/
typedef struct cleanup_stuff cleanup_T;
struct cleanup_stuff {
- int pending; /* error/interrupt/exception state */
- except_T *exception; /* exception value */
+ int pending; // error/interrupt/exception state
+ except_T *exception; // exception value
};
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index b90773ce83..62a4d48645 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -6,49 +6,56 @@
*/
#include <assert.h>
+#include <inttypes.h>
#include <stdbool.h>
-#include <string.h>
#include <stdlib.h>
-#include <inttypes.h>
+#include <string.h>
-#include "nvim/assert.h"
-#include "nvim/log.h"
-#include "nvim/vim.h"
-#include "nvim/ascii.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/arabic.h"
-#include "nvim/ex_getln.h"
+#include "nvim/ascii.h"
+#include "nvim/assert.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/cursor_shape.h"
#include "nvim/digraph.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/eval/userfunc.h"
+#include "nvim/event/loop.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_eval.h"
+#include "nvim/ex_getln.h"
#include "nvim/fileio.h"
#include "nvim/func_attr.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/highlight.h"
+#include "nvim/highlight_defs.h"
#include "nvim/if_cscope.h"
#include "nvim/indent.h"
+#include "nvim/keymap.h"
+#include "nvim/lib/kvec.h"
+#include "nvim/log.h"
+#include "nvim/lua/executor.h"
#include "nvim/main.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
+#include "nvim/memory.h"
#include "nvim/menu.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/memory.h"
-#include "nvim/cursor_shape.h"
-#include "nvim/keymap.h"
-#include "nvim/garray.h"
-#include "nvim/move.h"
#include "nvim/mouse.h"
+#include "nvim/move.h"
#include "nvim/ops.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/os/time.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/popupmnu.h"
@@ -56,22 +63,15 @@
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/sign.h"
-#include "nvim/strings.h"
#include "nvim/state.h"
+#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/tag.h"
-#include "nvim/window.h"
#include "nvim/ui.h"
-#include "nvim/os/input.h"
-#include "nvim/os/os.h"
-#include "nvim/event/loop.h"
-#include "nvim/os/time.h"
-#include "nvim/lib/kvec.h"
-#include "nvim/api/private/helpers.h"
-#include "nvim/highlight_defs.h"
-#include "nvim/lua/executor.h"
-#include "nvim/viml/parser/parser.h"
+#include "nvim/vim.h"
#include "nvim/viml/parser/expressions.h"
+#include "nvim/viml/parser/parser.h"
+#include "nvim/window.h"
/// Command-line colors: one chunk
///
@@ -110,21 +110,21 @@ typedef enum {
* structure.
*/
struct cmdline_info {
- char_u *cmdbuff; // pointer to command line buffer
+ char_u *cmdbuff; // pointer to command line buffer
int cmdbufflen; // length of cmdbuff
int cmdlen; // number of chars in command line
int cmdpos; // current cursor position
int cmdspos; // cursor column on screen
int cmdfirstc; // ':', '/', '?', '=', '>' or NUL
int cmdindent; // number of spaces before cmdline
- char_u *cmdprompt; // message in front of cmdline
+ char_u *cmdprompt; // message in front of cmdline
int cmdattr; // attributes for prompt
int overstrike; // Typing mode on the command line. Shared by
// getcmdline() and put_on_cmdline().
- expand_T *xpc; // struct being used for expansion, xp_pattern
- // may point into cmdbuff
+ expand_T *xpc; // struct being used for expansion, xp_pattern
+ // may point into cmdbuff
int xp_context; // type of expansion
- char_u *xp_arg; // user-defined expansion arg
+ char_u *xp_arg; // user-defined expansion arg
int input_fn; // when TRUE Invoked for input() function
unsigned prompt_id; ///< Prompt number, used to disable coloring on errors.
Callback highlight_callback; ///< Callback used for coloring user input.
@@ -140,25 +140,25 @@ static unsigned last_prompt_id = 0;
// Struct to store the viewstate during 'incsearch' highlighting.
typedef struct {
- colnr_T vs_curswant;
- colnr_T vs_leftcol;
- linenr_T vs_topline;
- int vs_topfill;
- linenr_T vs_botline;
- int vs_empty_rows;
+ colnr_T vs_curswant;
+ colnr_T vs_leftcol;
+ linenr_T vs_topline;
+ int vs_topfill;
+ linenr_T vs_botline;
+ int vs_empty_rows;
} viewstate_T;
// Struct to store the state of 'incsearch' highlighting.
typedef struct {
- pos_T search_start; // where 'incsearch' starts searching
- pos_T save_cursor;
+ pos_T search_start; // where 'incsearch' starts searching
+ pos_T save_cursor;
viewstate_T init_viewstate;
viewstate_T old_viewstate;
- pos_T match_start;
- pos_T match_end;
- bool did_incsearch;
- bool incsearch_postponed;
- int magic_save;
+ pos_T match_start;
+ pos_T match_end;
+ bool did_incsearch;
+ bool incsearch_postponed;
+ int magic_save;
} incsearch_state_T;
typedef struct command_line_state {
@@ -178,9 +178,9 @@ typedef struct command_line_state {
int did_wild_list; // did wild_list() recently
int wim_index; // index in wim_flags[]
int res;
- int save_msg_scroll;
- int save_State; // remember State when called
- char_u *save_p_icm;
+ int save_msg_scroll;
+ int save_State; // remember State when called
+ char_u *save_p_icm;
int some_key_typed; // one of the keys was typed
// mouse drag and release events are ignored, unless they are
// preceded with a mouse down event
@@ -198,9 +198,9 @@ typedef struct cmdline_info CmdlineInfo;
* TODO: make it local to getcmdline() and pass it around. */
static struct cmdline_info ccline;
-static int cmd_showtail; /* Only show path tail in lists ? */
+static int cmd_showtail; // Only show path tail in lists ?
-static int new_cmdpos; /* position set by set_cmdline_pos() */
+static int new_cmdpos; // position set by set_cmdline_pos()
/// currently displayed block of context
static Array cmdline_block = ARRAY_DICT_INIT;
@@ -210,11 +210,11 @@ static Array cmdline_block = ARRAY_DICT_INIT;
*/
typedef void *(*user_expand_func_T)(const char_u *, int, typval_T *);
-static histentry_T *(history[HIST_COUNT]) = {NULL, NULL, NULL, NULL, NULL};
-static int hisidx[HIST_COUNT] = {-1, -1, -1, -1, -1}; /* lastused entry */
-static int hisnum[HIST_COUNT] = {0, 0, 0, 0, 0};
-/* identifying (unique) number of newest history entry */
-static int hislen = 0; /* actual length of history tables */
+static histentry_T *(history[HIST_COUNT]) = { NULL, NULL, NULL, NULL, NULL };
+static int hisidx[HIST_COUNT] = { -1, -1, -1, -1, -1 }; // lastused entry
+static int hisnum[HIST_COUNT] = { 0, 0, 0, 0, 0 };
+// identifying (unique) number of newest history entry
+static int hislen = 0; // actual length of history tables
/// Flag for command_line_handle_key to ignore <C-c>
///
@@ -230,7 +230,22 @@ static int compl_match_arraysize;
static int compl_startcol;
static int compl_selected;
+/// |:checkhealth| completion items
+///
+/// Regenerates on every new command line prompt, to accomodate changes on the
+/// runtime files.
+typedef struct {
+ garray_T names; // healthcheck names
+ unsigned last_gen; // last_prompt_id where names were generated
+} CheckhealthComp;
+
+/// Cookie used when converting filepath to name
+struct healthchecks_cookie {
+ garray_T *names; // global healthchecks
+ bool is_lua; // true if the current entry is a Lua healthcheck
+};
+static CheckhealthComp healthchecks = { GA_INIT(sizeof(char_u *), 10), 0 };
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_getln.c.generated.h"
@@ -273,11 +288,72 @@ static void init_incsearch_state(incsearch_state_T *s)
save_viewstate(&s->old_viewstate);
}
+/// Completion for |:checkhealth| command.
+///
+/// Given to ExpandGeneric() to obtain all available heathcheck names.
+/// @param[in] idx Index of the healthcheck item.
+/// @param[in] xp Not used.
+static char_u *get_healthcheck_names(expand_T *xp, int idx)
+{
+ // Generate the first time or on new prompt.
+ if (healthchecks.last_gen == 0 || healthchecks.last_gen != last_prompt_id) {
+ ga_clear_strings(&healthchecks.names);
+ char *patterns[3] = { "autoload/health/**.vim", "lua/**/**/health/init.lua", // NOLINT
+ "lua/**/**/health.lua" }; // NOLINT
+ for (int i = 0; i < 3; i++) {
+ struct healthchecks_cookie hcookie = { .names = &healthchecks.names, .is_lua = i != 0 };
+ do_in_runtimepath((char_u *)patterns[i], DIP_ALL, get_healthcheck_cb, &hcookie);
+
+ if (healthchecks.names.ga_len > 0) {
+ ga_remove_duplicate_strings(&healthchecks.names);
+ }
+ }
+ // Tracked to regenerate items on next prompt.
+ healthchecks.last_gen = last_prompt_id;
+ }
+ return idx <
+ (int)healthchecks.names.ga_len ? ((char_u **)(healthchecks.names.ga_data))[idx] : NULL;
+}
+
+/// Transform healthcheck file path into it's name.
+///
+/// Used as a callback for do_in_runtimepath
+/// @param[in] path Expanded path to a possible healthcheck.
+/// @param[out] cookie Array where names will be inserted.
+static void get_healthcheck_cb(char_u *path, void *cookie)
+{
+ if (path != NULL) {
+ struct healthchecks_cookie *hcookie = (struct healthchecks_cookie *)cookie;
+ char *pattern;
+ char *sub = "\\1";
+ char_u *res;
+
+ if (hcookie->is_lua) {
+ // Lua: transform "../lua/vim/lsp/health.lua" into "vim.lsp"
+ pattern = ".*lua[\\/]\\(.\\{-}\\)[\\/]health\\([\\/]init\\)\\?\\.lua$";
+ } else {
+ // Vim: transform "../autoload/health/provider.vim" into "provider"
+ pattern = ".*[\\/]\\([^\\/]*\\)\\.vim$";
+ }
+
+ res = do_string_sub(path, (char_u *)pattern, (char_u *)sub, NULL, (char_u *)"g");
+ if (hcookie->is_lua && res != NULL) {
+ // Replace slashes with dots as represented by the healthcheck plugin.
+ char_u *ares = do_string_sub(res, (char_u *)"[\\/]", (char_u *)".", NULL, (char_u *)"g");
+ xfree(res);
+ res = ares;
+ }
+
+ if (res != NULL) {
+ GA_APPEND(char_u *, hcookie->names, res);
+ }
+ }
+}
+
// Return true when 'incsearch' highlighting is to be done.
// Sets search_first_line and search_last_line to the address range.
-static bool do_incsearch_highlighting(int firstc, int *search_delim,
- incsearch_state_T *s, int *skiplen,
- int *patlen)
+static bool do_incsearch_highlighting(int firstc, int *search_delim, incsearch_state_T *s,
+ int *skiplen, int *patlen)
FUNC_ATTR_NONNULL_ALL
{
char_u *cmd;
@@ -384,7 +460,7 @@ static bool do_incsearch_highlighting(int firstc, int *search_delim,
// Don't do 'hlsearch' highlighting if the pattern matches everything.
if (!use_last_pat) {
char_u c = *end;
- int empty;
+ int empty;
*end = NUL;
empty = empty_pattern(p);
@@ -425,8 +501,7 @@ theend:
}
// May do 'incsearch' highlighting if desired.
-static void may_do_incsearch_highlighting(int firstc, long count,
- incsearch_state_T *s)
+static void may_do_incsearch_highlighting(int firstc, long count, incsearch_state_T *s)
{
pos_T end_pos;
proftime_T tm;
@@ -472,7 +547,7 @@ static void may_do_incsearch_highlighting(int firstc, long count,
// Use the previous pattern for ":s//".
next_char = ccline.cmdbuff[skiplen + patlen];
use_last_pat = patlen == 0 && skiplen > 0
- && ccline.cmdbuff[skiplen - 1] == next_char;
+ && ccline.cmdbuff[skiplen - 1] == next_char;
// If there is no pattern, don't do anything.
if (patlen == 0 && !use_last_pat) {
@@ -624,8 +699,7 @@ static int may_add_char_to_search(int firstc, int *c, incsearch_state_T *s)
return OK;
}
-static void finish_incsearch_highlighting(int gotesc, incsearch_state_T *s,
- bool call_update_screen)
+static void finish_incsearch_highlighting(int gotesc, incsearch_state_T *s, bool call_update_screen)
{
if (s->did_incsearch) {
s->did_incsearch = false;
@@ -872,7 +946,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
&& s->firstc != NUL
&& (s->some_key_typed || s->histype == HIST_SEARCH)) {
add_to_history(s->histype, ccline.cmdbuff, true,
- s->histype == HIST_SEARCH ? s->firstc : NUL);
+ s->histype == HIST_SEARCH ? s->firstc : NUL);
if (s->firstc == ':') {
xfree(new_last_cmdline);
new_last_cmdline = vim_strsave(ccline.cmdbuff);
@@ -973,12 +1047,18 @@ static int command_line_execute(VimState *state, int key)
// typed by the user directly, not when the result of a
// mapping.
switch (s->c) {
- case K_RIGHT: s->c = K_LEFT; break;
- case K_S_RIGHT: s->c = K_S_LEFT; break;
- case K_C_RIGHT: s->c = K_C_LEFT; break;
- case K_LEFT: s->c = K_RIGHT; break;
- case K_S_LEFT: s->c = K_S_RIGHT; break;
- case K_C_LEFT: s->c = K_C_RIGHT; break;
+ case K_RIGHT:
+ s->c = K_LEFT; break;
+ case K_S_RIGHT:
+ s->c = K_S_LEFT; break;
+ case K_C_RIGHT:
+ s->c = K_C_LEFT; break;
+ case K_LEFT:
+ s->c = K_RIGHT; break;
+ case K_S_LEFT:
+ s->c = K_S_RIGHT; break;
+ case K_C_LEFT:
+ s->c = K_C_RIGHT; break;
}
}
}
@@ -1078,7 +1158,7 @@ static int command_line_execute(VimState *state, int key)
redrawcmd();
save_p_ls = -1;
wild_menu_showing = 0;
- // don't redraw statusline if WM_LIST is showing
+ // don't redraw statusline if WM_LIST is showing
} else if (wild_menu_showing != WM_LIST) {
win_redraw_last_status(topframe);
wild_menu_showing = 0; // must be before redraw_statuslines #8385
@@ -1155,7 +1235,7 @@ static int command_line_execute(VimState *state, int key)
s->c = (int)p_wc;
KeyTyped = true; // in case the key was mapped
} else if (STRNCMP(s->xpc.xp_pattern, upseg + 1, 3) == 0
- && s->c == K_DOWN) {
+ && s->c == K_DOWN) {
// If in a direct ancestor, strip off one ../ to go down
int found = false;
@@ -1242,7 +1322,7 @@ static int command_line_execute(VimState *state, int key)
vungetc(s->c);
s->c = Ctrl_BSL;
} else if (s->c == 'e') {
- char_u *p = NULL;
+ char_u *p = NULL;
int len;
// Replace the command line with the result of an expression.
@@ -1318,7 +1398,7 @@ static int command_line_execute(VimState *state, int key)
|| s->c == '\r'
|| s->c == K_KENTER
|| (s->c == ESC
- && (!KeyTyped || vim_strchr(p_cpo, CPO_ESC) != NULL))) {
+ && (!KeyTyped || vim_strchr(p_cpo, CPO_ESC) != NULL))) {
// In Ex mode a backslash escapes a newline.
if (exmode_active
&& s->c != ESC
@@ -1419,7 +1499,7 @@ static int command_line_execute(VimState *state, int key)
}
(void)showmatches(&s->xpc, p_wmnu
- && ((wim_flags[s->wim_index] & WIM_LIST) == 0));
+ && ((wim_flags[s->wim_index] & WIM_LIST) == 0));
redrawcmd();
s->did_wild_list = true;
@@ -1464,7 +1544,7 @@ static int command_line_execute(VimState *state, int key)
}
}
- if (s->c == NUL || s->c == K_ZERO) {
+ if (s->c == NUL || s->c == K_ZERO) {
// NUL is stored as NL
s->c = NL;
}
@@ -1476,8 +1556,7 @@ static int command_line_execute(VimState *state, int key)
// May adjust 'incsearch' highlighting for typing CTRL-G and CTRL-T, go to next
// or previous match.
// Returns FAIL when calling command_line_not_changed.
-static int may_do_command_line_next_incsearch(int firstc, long count,
- incsearch_state_T *s,
+static int may_do_command_line_next_incsearch(int firstc, long count, incsearch_state_T *s,
bool next_match)
FUNC_ATTR_NONNULL_ALL
{
@@ -1500,7 +1579,7 @@ static int may_do_command_line_next_incsearch(int firstc, long count,
ui_busy_start();
ui_flush();
- pos_T t;
+ pos_T t;
char_u *pat;
int search_flags = SEARCH_NOOF;
char_u save;
@@ -1656,7 +1735,7 @@ static int command_line_handle_key(CommandLineState *s)
if (s->c == K_DEL) {
ccline.cmdpos += mb_off_next(ccline.cmdbuff,
- ccline.cmdbuff + ccline.cmdpos);
+ ccline.cmdbuff + ccline.cmdpos);
}
if (ccline.cmdpos > 0) {
@@ -1980,8 +2059,9 @@ static int command_line_handle_key(CommandLineState *s)
return command_line_not_changed(s);
case Ctrl_A: // all matches
- if (nextwild(&s->xpc, WILD_ALL, 0, s->firstc != '@') == FAIL)
+ if (nextwild(&s->xpc, WILD_ALL, 0, s->firstc != '@') == FAIL) {
break;
+ }
return command_line_changed(s);
case Ctrl_L:
@@ -1999,7 +2079,7 @@ static int command_line_handle_key(CommandLineState *s)
case Ctrl_P: // previous match
if (s->xpc.xp_numfiles > 0) {
if (nextwild(&s->xpc, (s->c == Ctrl_P) ? WILD_PREV : WILD_NEXT,
- 0, s->firstc != '@') == FAIL) {
+ 0, s->firstc != '@') == FAIL) {
break;
}
return command_line_not_changed(s);
@@ -2033,7 +2113,7 @@ static int command_line_handle_key(CommandLineState *s)
if (s->hiscnt != s->save_hiscnt) {
// jumped to other entry
- char_u *p;
+ char_u *p;
int len = 0;
int old_firstc;
@@ -2251,7 +2331,7 @@ static int command_line_changed(CommandLineState *s)
State |= CMDPREVIEW;
emsg_silent++; // Block error reporting as the command may be incomplete
msg_silent++; // Block messages, namely ones that prompt
- do_cmdline(ccline.cmdbuff, NULL, NULL, DOCMD_KEEPLINE|DOCMD_NOWAIT);
+ do_cmdline(ccline.cmdbuff, NULL, NULL, DOCMD_KEEPLINE|DOCMD_NOWAIT|DOCMD_PREVIEW);
msg_silent--; // Unblock messages
emsg_silent--; // Unblock error reporting
@@ -2261,7 +2341,6 @@ static int command_line_changed(CommandLineState *s)
update_topline(curwin);
redrawcmdline();
-
} else if (State & CMDPREVIEW) {
State = (State & ~CMDPREVIEW);
close_preview_windows();
@@ -2298,32 +2377,27 @@ static void abandon_cmdline(void)
redraw_cmdline = true;
}
-/*
- * getcmdline() - accept a command line starting with firstc.
- *
- * firstc == ':' get ":" command line.
- * firstc == '/' or '?' get search pattern
- * firstc == '=' get expression
- * firstc == '@' get text for input() function
- * firstc == '>' get text for debug mode
- * firstc == NUL get text for :insert command
- * firstc == -1 like NUL, and break on CTRL-C
- *
- * The line is collected in ccline.cmdbuff, which is reallocated to fit the
- * command line.
- *
- * Careful: getcmdline() can be called recursively!
- *
- * Return pointer to allocated string if there is a commandline, NULL
- * otherwise.
- */
-char_u *
-getcmdline (
- int firstc,
- long count, // only used for incremental search
- int indent, // indent for inside conditionals
- bool do_concat FUNC_ATTR_UNUSED
-)
+/// getcmdline() - accept a command line starting with firstc.
+///
+/// firstc == ':' get ":" command line.
+/// firstc == '/' or '?' get search pattern
+/// firstc == '=' get expression
+/// firstc == '@' get text for input() function
+/// firstc == '>' get text for debug mode
+/// firstc == NUL get text for :insert command
+/// firstc == -1 like NUL, and break on CTRL-C
+///
+/// The line is collected in ccline.cmdbuff, which is reallocated to fit the
+/// command line.
+///
+/// Careful: getcmdline() can be called recursively!
+///
+/// Return pointer to allocated string if there is a commandline, NULL
+/// otherwise.
+///
+/// @param count only used for incremental search
+/// @param indent indent for inside conditionals
+char_u *getcmdline(int firstc, long count, int indent, bool do_concat FUNC_ATTR_UNUSED)
{
// Be prepared for situations where cmdline can be invoked recursively.
// That includes cmd mappings, event handlers, as well as update_screen()
@@ -2348,9 +2422,8 @@ getcmdline (
/// @param[in] highlight_callback Callback used for highlighting user input.
///
/// @return [allocated] Command line or NULL.
-char *getcmdline_prompt(const char firstc, const char *const prompt,
- const int attr, const int xp_context,
- const char *const xp_arg,
+char *getcmdline_prompt(const char firstc, const char *const prompt, const int attr,
+ const int xp_context, const char *const xp_arg,
const Callback highlight_callback)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
{
@@ -2390,8 +2463,9 @@ char *getcmdline_prompt(const char firstc, const char *const prompt,
* another window or buffer. Used when editing the command line etc.
*/
int text_locked(void) {
- if (cmdwin_type != 0)
+ if (cmdwin_type != 0) {
return TRUE;
+ }
return textlock != 0;
}
@@ -2404,7 +2478,7 @@ void text_locked_msg(void)
EMSG(_(get_text_locked_msg()));
}
-char_u * get_text_locked_msg(void) {
+char_u *get_text_locked_msg(void) {
if (cmdwin_type != 0) {
return e_cmdwin;
} else {
@@ -2438,8 +2512,9 @@ int allbuf_locked(void)
static int cmdline_charsize(int idx)
{
- if (cmdline_star > 0) /* showing '*', always 1 position */
+ if (cmdline_star > 0) { // showing '*', always 1 position
return 1;
+ }
return ptr2cells(ccline.cmdbuff + idx);
}
@@ -2459,8 +2534,9 @@ static int cmd_screencol(int bytepos)
int col = cmd_startcol();
if (KeyTyped) {
m = Columns * Rows;
- if (m < 0) /* overflow, Columns or Rows at weird value */
+ if (m < 0) { // overflow, Columns or Rows at weird value
m = MAXCOL;
+ }
} else {
m = MAXCOL;
}
@@ -2492,20 +2568,16 @@ static void correct_screencol(int idx, int cells, int *col)
}
}
-/*
- * Get an Ex command line for the ":" command.
- */
-char_u *
-getexline(
- int c, // normally ':', NUL for ":append"
- void *cookie,
- int indent, // indent for inside conditionals
- bool do_concat
-)
+/// Get an Ex command line for the ":" command.
+///
+/// @param c normally ':', NUL for ":append"
+/// @param indent indent for inside conditionals
+char_u *getexline(int c, void *cookie, int indent, bool do_concat)
{
- /* When executing a register, remove ':' that's in front of each line. */
- if (exec_from_reg && vpeekc() == ':')
+ // When executing a register, remove ':' that's in front of each line.
+ if (exec_from_reg && vpeekc() == ':') {
(void)vgetc();
+ }
return getcmdline(c, 1L, indent, do_concat);
}
@@ -2532,10 +2604,11 @@ static void alloc_cmdbuff(int len)
/*
* give some extra space to avoid having to allocate all the time
*/
- if (len < 80)
+ if (len < 80) {
len = 100;
- else
+ } else {
len += 20;
+ }
ccline.cmdbuff = xmalloc((size_t)len);
ccline.cmdbufflen = len;
@@ -2551,7 +2624,7 @@ static void realloc_cmdbuff(int len)
}
char_u *p = ccline.cmdbuff;
- alloc_cmdbuff(len); /* will get some more */
+ alloc_cmdbuff(len); // will get some more
/* There isn't always a NUL after the command, but it may need to be
* there, thus copy up to the NUL and add a NUL. */
memmove(ccline.cmdbuff, p, (size_t)ccline.cmdlen);
@@ -2564,22 +2637,23 @@ static void realloc_cmdbuff(int len)
&& ccline.xpc->xp_context != EXPAND_UNSUCCESSFUL) {
int i = (int)(ccline.xpc->xp_pattern - p);
- /* If xp_pattern points inside the old cmdbuff it needs to be adjusted
- * to point into the newly allocated memory. */
- if (i >= 0 && i <= ccline.cmdlen)
+ // If xp_pattern points inside the old cmdbuff it needs to be adjusted
+ // to point into the newly allocated memory.
+ if (i >= 0 && i <= ccline.cmdlen) {
ccline.xpc->xp_pattern = ccline.cmdbuff + i;
+ }
}
}
-static char_u *arshape_buf = NULL;
+static char_u *arshape_buf = NULL;
-# if defined(EXITFREE)
+#if defined(EXITFREE)
void free_arshape_buf(void)
{
xfree(arshape_buf);
}
-# endif
+#endif
enum { MAX_CB_ERRORS = 1 };
@@ -2605,8 +2679,7 @@ static void color_expr_cmdline(const CmdlineInfo *const colored_ccline,
ParserHighlight colors;
kvi_init(colors);
ParserState pstate;
- viml_parser_init(
- &pstate, parser_simple_get_line, &plines_p, &colors);
+ viml_parser_init(&pstate, parser_simple_get_line, &plines_p, &colors);
ExprAST east = viml_pexpr_parse(&pstate, kExprFlagsDisallowEOC);
viml_pexpr_free_ast(east);
viml_parser_destroy(&pstate);
@@ -2626,9 +2699,9 @@ static void color_expr_cmdline(const CmdlineInfo *const colored_ccline,
const int id = syn_name2id((const char_u *)chunk.group);
const int attr = (id == 0 ? 0 : syn_id2attr(id));
kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) {
- .start = (int)chunk.start.col,
- .end = (int)chunk.end_col,
- .attr = attr,
+ .start = (int)chunk.start.col,
+ .end = (int)chunk.end_col,
+ .attr = attr,
}));
prev_end = chunk.end_col;
}
@@ -2716,8 +2789,7 @@ static bool color_cmdline(CmdlineInfo *colored_ccline)
color_cb = colored_ccline->highlight_callback;
} else if (colored_ccline->cmdfirstc == ':') {
try_enter(&tstate);
- err_errmsg = N_(
- "E5408: Unable to get g:Nvim_color_cmdline callback: %s");
+ err_errmsg = N_("E5408: Unable to get g:Nvim_color_cmdline callback: %s");
dgc_ret = tv_dict_get_callback(&globvardict, S_LEN("Nvim_color_cmdline"),
&color_cb);
tl_ret = try_leave(&tstate, &err);
@@ -2785,7 +2857,7 @@ static bool color_cmdline(CmdlineInfo *colored_ccline)
}
bool error = false;
const varnumber_T start = (
- tv_get_number_chk(TV_LIST_ITEM_TV(tv_list_first(l)), &error));
+ tv_get_number_chk(TV_LIST_ITEM_TV(tv_list_first(l)), &error));
if (error) {
goto color_cmdline_error;
} else if (!(prev_end <= start && start < colored_ccline->cmdlen)) {
@@ -2805,8 +2877,8 @@ static bool color_cmdline(CmdlineInfo *colored_ccline)
.attr = 0,
}));
}
- const varnumber_T end = tv_get_number_chk(
- TV_LIST_ITEM_TV(TV_LIST_ITEM_NEXT(l, tv_list_first(l))), &error);
+ const varnumber_T end =
+ tv_get_number_chk(TV_LIST_ITEM_TV(TV_LIST_ITEM_NEXT(l, tv_list_first(l))), &error);
if (error) {
goto color_cmdline_error;
} else if (!(start < end && end <= colored_ccline->cmdlen)) {
@@ -2822,8 +2894,7 @@ static bool color_cmdline(CmdlineInfo *colored_ccline)
goto color_cmdline_error;
}
prev_end = end;
- const char *const group = tv_get_string_chk(
- TV_LIST_ITEM_TV(tv_list_last(l)));
+ const char *const group = tv_get_string_chk(TV_LIST_ITEM_TV(tv_list_last(l)));
if (group == NULL) {
goto color_cmdline_error;
}
@@ -3043,7 +3114,7 @@ static void ui_ext_cmdline_show(CmdlineInfo *line)
line->cmdindent,
line->level);
if (line->special_char) {
- ui_call_cmdline_special_char(cchar_to_string((char)(line->special_char)),
+ ui_call_cmdline_special_char(cchar_to_string(line->special_char),
line->special_shift,
line->level);
}
@@ -3141,8 +3212,8 @@ void putcmdline(char c, int shift)
}
msg_no_more = false;
} else if (ccline.redraw_state != kCmdRedrawAll) {
- ui_call_cmdline_special_char(cchar_to_string((char)(c)), shift,
- ccline.level);
+ ui_call_cmdline_special_char(cchar_to_string(c), shift,
+ ccline.level);
}
cursorcmd();
ccline.special_char = c;
@@ -3182,15 +3253,16 @@ void put_on_cmdline(char_u *str, int len, int redraw)
int m;
int c;
- if (len < 0)
+ if (len < 0) {
len = (int)STRLEN(str);
+ }
realloc_cmdbuff(ccline.cmdlen + len + 1);
if (!ccline.overstrike) {
memmove(ccline.cmdbuff + ccline.cmdpos + len,
- ccline.cmdbuff + ccline.cmdpos,
- (size_t)(ccline.cmdlen - ccline.cmdpos));
+ ccline.cmdbuff + ccline.cmdpos,
+ (size_t)(ccline.cmdlen - ccline.cmdpos));
ccline.cmdlen += len;
} else {
// Count nr of characters in the new string.
@@ -3232,11 +3304,12 @@ void put_on_cmdline(char_u *str, int len, int redraw)
if (arabic_combine(utf_ptr2char(ccline.cmdbuff + ccline.cmdpos - i), c)) {
ccline.cmdpos -= i;
len += i;
- } else
+ } else {
i = 0;
+ }
}
if (i != 0) {
- /* Also backup the cursor position. */
+ // Also backup the cursor position.
i = ptr2cells(ccline.cmdbuff + ccline.cmdpos);
ccline.cmdspos -= i;
msg_col -= i;
@@ -3252,9 +3325,10 @@ void put_on_cmdline(char_u *str, int len, int redraw)
i = cmdline_row;
cursorcmd();
draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
- /* Avoid clearing the rest of the line too often. */
- if (cmdline_row != i || ccline.overstrike)
+ // Avoid clearing the rest of the line too often.
+ if (cmdline_row != i || ccline.overstrike) {
msg_clr_eos();
+ }
msg_no_more = FALSE;
}
if (KeyTyped) {
@@ -3348,8 +3422,8 @@ void restore_cmdline_alloc(char_u *p)
/// @returns FAIL for failure, OK otherwise
static bool cmdline_paste(int regname, bool literally, bool remcr)
{
- char_u *arg;
- char_u *p;
+ char_u *arg;
+ char_u *p;
bool allocated;
struct cmdline_info save_ccline;
@@ -3364,8 +3438,9 @@ static bool cmdline_paste(int regname, bool literally, bool remcr)
/* A register containing CTRL-R can cause an endless loop. Allow using
* CTRL-C to break the loop. */
line_breakcheck();
- if (got_int)
+ if (got_int) {
return FAIL;
+ }
/* Need to save and restore ccline. And set "textlock" to avoid nasty
@@ -3377,18 +3452,19 @@ static bool cmdline_paste(int regname, bool literally, bool remcr)
restore_cmdline(&save_ccline);
if (i) {
- /* Got the value of a special register in "arg". */
- if (arg == NULL)
+ // Got the value of a special register in "arg".
+ if (arg == NULL) {
return FAIL;
+ }
- /* When 'incsearch' is set and CTRL-R CTRL-W used: skip the duplicate
- * part of the word. */
+ // When 'incsearch' is set and CTRL-R CTRL-W used: skip the duplicate
+ // part of the word.
p = arg;
if (p_is && regname == Ctrl_W) {
- char_u *w;
+ char_u *w;
int len;
- /* Locate start of last word in the cmd buffer. */
+ // Locate start of last word in the cmd buffer.
for (w = ccline.cmdbuff + ccline.cmdpos; w > ccline.cmdbuff; ) {
len = utf_head_off(ccline.cmdbuff, w - 1) + 1;
if (!vim_iswordc(utf_ptr2char(w - len))) {
@@ -3397,13 +3473,15 @@ static bool cmdline_paste(int regname, bool literally, bool remcr)
w -= len;
}
len = (int)((ccline.cmdbuff + ccline.cmdpos) - w);
- if (p_ic ? STRNICMP(w, arg, len) == 0 : STRNCMP(w, arg, len) == 0)
+ if (p_ic ? STRNICMP(w, arg, len) == 0 : STRNCMP(w, arg, len) == 0) {
p += len;
+ }
}
cmdline_paste_str(p, literally);
- if (allocated)
+ if (allocated) {
xfree(arg);
+ }
return OK;
}
@@ -3420,9 +3498,9 @@ void cmdline_paste_str(char_u *s, int literally)
{
int c, cv;
- if (literally)
+ if (literally) {
put_on_cmdline(s, -1, TRUE);
- else
+ } else {
while (*s != NUL) {
cv = *s;
if (cv == Ctrl_V && s[1]) {
@@ -3436,6 +3514,7 @@ void cmdline_paste_str(char_u *s, int literally)
}
stuffcharReadbuff(c);
}
+ }
}
/// Delete characters on the command line, from "from" to the current position.
@@ -3453,8 +3532,9 @@ static void cmdline_del(int from)
// overwritten.
void redrawcmdline(void)
{
- if (cmd_silent)
+ if (cmd_silent) {
return;
+ }
need_wait_return = false;
compute_cmdrow();
redrawcmd();
@@ -3466,8 +3546,9 @@ static void redrawcmdprompt(void)
{
int i;
- if (cmd_silent)
+ if (cmd_silent) {
return;
+ }
if (ui_has(kUICmdline)) {
ccline.redraw_state = kCmdRedrawAll;
return;
@@ -3494,15 +3575,16 @@ static void redrawcmdprompt(void)
*/
void redrawcmd(void)
{
- if (cmd_silent)
+ if (cmd_silent) {
return;
+ }
if (ui_has(kUICmdline)) {
draw_cmdline(0, ccline.cmdlen);
return;
}
- /* when 'incsearch' is set there may be no command line while redrawing */
+ // when 'incsearch' is set there may be no command line while redrawing
if (ccline.cmdbuff == NULL) {
cmd_cursor_goto(cmdline_row, 0);
msg_clr_eos();
@@ -3514,7 +3596,7 @@ void redrawcmd(void)
msg_start();
redrawcmdprompt();
- /* Don't use more prompt, truncate the cmdline if it doesn't fit. */
+ // Don't use more prompt, truncate the cmdline if it doesn't fit.
msg_no_more = TRUE;
draw_cmdline(0, ccline.cmdlen);
msg_clr_eos();
@@ -3530,7 +3612,7 @@ void redrawcmd(void)
* An emsg() before may have set msg_scroll. This is used in normal mode,
* in cmdline mode we can reset them now.
*/
- msg_scroll = FALSE; /* next message overwrites cmdline */
+ msg_scroll = FALSE; // next message overwrites cmdline
// Typing ':' at the more prompt may set skip_redraw. We don't want this
// in cmdline mode.
@@ -3553,8 +3635,9 @@ void compute_cmdrow(void)
static void cursorcmd(void)
{
- if (cmd_silent)
+ if (cmd_silent) {
return;
+ }
if (ui_has(kUICmdline)) {
if (ccline.redraw_state < kCmdRedrawPos) {
@@ -3642,28 +3725,27 @@ static int sort_func_compare(const void *s1, const void *s2)
char_u *p1 = *(char_u **)s1;
char_u *p2 = *(char_u **)s2;
- if (*p1 != '<' && *p2 == '<') return -1;
- if (*p1 == '<' && *p2 != '<') return 1;
+ if (*p1 != '<' && *p2 == '<') {
+ return -1;
+ }
+ if (*p1 == '<' && *p2 != '<') {
+ return 1;
+ }
return STRCMP(p1, p2);
}
-/*
- * Return FAIL if this is not an appropriate context in which to do
- * completion of anything, return OK if it is (even if there are no matches).
- * For the caller, this means that the character is just passed through like a
- * normal character (instead of being expanded). This allows :s/^I^D etc.
- */
-static int
-nextwild (
- expand_T *xp,
- int type,
- int options, /* extra options for ExpandOne() */
- int escape /* if TRUE, escape the returned matches */
-)
+/// Return FAIL if this is not an appropriate context in which to do
+/// completion of anything, return OK if it is (even if there are no matches).
+/// For the caller, this means that the character is just passed through like a
+/// normal character (instead of being expanded). This allows :s/^I^D etc.
+///
+/// @param options extra options for ExpandOne()
+/// @param escape if TRUE, escape the returned matches
+static int nextwild(expand_T *xp, int type, int options, int escape)
{
int i, j;
- char_u *p1;
- char_u *p2;
+ char_u *p1;
+ char_u *p2;
int difflen;
if (xp->xp_numfiles == -1) {
@@ -3673,10 +3755,10 @@ nextwild (
if (xp->xp_context == EXPAND_UNSUCCESSFUL) {
beep_flush();
- return OK; /* Something illegal on command line */
+ return OK; // Something illegal on command line
}
if (xp->xp_context == EXPAND_NOTHING) {
- /* Caller can use the character as a normal char instead */
+ // Caller can use the character as a normal char instead
return FAIL;
}
@@ -3696,12 +3778,12 @@ nextwild (
// Translate string into pattern and expand it.
p1 = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context);
const int use_options = (
- options
- | WILD_HOME_REPLACE
- | WILD_ADD_SLASH
- | WILD_SILENT
- | (escape ? WILD_ESCAPE : 0)
- | (p_wic ? WILD_ICASE : 0));
+ options
+ | WILD_HOME_REPLACE
+ | WILD_ADD_SLASH
+ | WILD_SILENT
+ | (escape ? WILD_ESCAPE : 0)
+ | (p_wic ? WILD_ICASE : 0));
p2 = ExpandOne(xp, p1, vim_strnsave(&ccline.cmdbuff[i], xp->xp_pattern_len),
use_options, type);
xfree(p1);
@@ -3746,67 +3828,62 @@ nextwild (
/* When expanding a ":map" command and no matches are found, assume that
* the key is supposed to be inserted literally */
- if (xp->xp_context == EXPAND_MAPPINGS && p2 == NULL)
+ if (xp->xp_context == EXPAND_MAPPINGS && p2 == NULL) {
return FAIL;
+ }
- if (xp->xp_numfiles <= 0 && p2 == NULL)
+ if (xp->xp_numfiles <= 0 && p2 == NULL) {
beep_flush();
- else if (xp->xp_numfiles == 1)
- /* free expanded pattern */
+ } else if (xp->xp_numfiles == 1) {
+ // free expanded pattern
(void)ExpandOne(xp, NULL, NULL, 0, WILD_FREE);
+ }
return OK;
}
-/*
- * Do wildcard expansion on the string 'str'.
- * Chars that should not be expanded must be preceded with a backslash.
- * Return a pointer to allocated memory containing the new string.
- * Return NULL for failure.
- *
- * "orig" is the originally expanded string, copied to allocated memory. It
- * should either be kept in orig_save or freed. When "mode" is WILD_NEXT or
- * WILD_PREV "orig" should be NULL.
- *
- * Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode"
- * is WILD_EXPAND_FREE or WILD_ALL.
- *
- * mode = WILD_FREE: just free previously expanded matches
- * mode = WILD_EXPAND_FREE: normal expansion, do not keep matches
- * mode = WILD_EXPAND_KEEP: normal expansion, keep matches
- * mode = WILD_NEXT: use next match in multiple match, wrap to first
- * mode = WILD_PREV: use previous match in multiple match, wrap to first
- * mode = WILD_ALL: return all matches concatenated
- * mode = WILD_LONGEST: return longest matched part
- * mode = WILD_ALL_KEEP: get all matches, keep matches
- *
- * options = WILD_LIST_NOTFOUND: list entries without a match
- * options = WILD_HOME_REPLACE: do home_replace() for buffer names
- * options = WILD_USE_NL: Use '\n' for WILD_ALL
- * options = WILD_NO_BEEP: Don't beep for multiple matches
- * options = WILD_ADD_SLASH: add a slash after directory names
- * options = WILD_KEEP_ALL: don't remove 'wildignore' entries
- * options = WILD_SILENT: don't print warning messages
- * options = WILD_ESCAPE: put backslash before special chars
- * options = WILD_ICASE: ignore case for files
- *
- * The variables xp->xp_context and xp->xp_backslash must have been set!
- */
-char_u *
-ExpandOne (
- expand_T *xp,
- char_u *str,
- char_u *orig, /* allocated copy of original of expanded string */
- int options,
- int mode
-)
+/// Do wildcard expansion on the string 'str'.
+/// Chars that should not be expanded must be preceded with a backslash.
+/// Return a pointer to allocated memory containing the new string.
+/// Return NULL for failure.
+///
+/// "orig" is the originally expanded string, copied to allocated memory. It
+/// should either be kept in orig_save or freed. When "mode" is WILD_NEXT or
+/// WILD_PREV "orig" should be NULL.
+///
+/// Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode"
+/// is WILD_EXPAND_FREE or WILD_ALL.
+///
+/// mode = WILD_FREE: just free previously expanded matches
+/// mode = WILD_EXPAND_FREE: normal expansion, do not keep matches
+/// mode = WILD_EXPAND_KEEP: normal expansion, keep matches
+/// mode = WILD_NEXT: use next match in multiple match, wrap to first
+/// mode = WILD_PREV: use previous match in multiple match, wrap to first
+/// mode = WILD_ALL: return all matches concatenated
+/// mode = WILD_LONGEST: return longest matched part
+/// mode = WILD_ALL_KEEP: get all matches, keep matches
+///
+/// options = WILD_LIST_NOTFOUND: list entries without a match
+/// options = WILD_HOME_REPLACE: do home_replace() for buffer names
+/// options = WILD_USE_NL: Use '\n' for WILD_ALL
+/// options = WILD_NO_BEEP: Don't beep for multiple matches
+/// options = WILD_ADD_SLASH: add a slash after directory names
+/// options = WILD_KEEP_ALL: don't remove 'wildignore' entries
+/// options = WILD_SILENT: don't print warning messages
+/// options = WILD_ESCAPE: put backslash before special chars
+/// options = WILD_ICASE: ignore case for files
+///
+/// The variables xp->xp_context and xp->xp_backslash must have been set!
+///
+/// @param orig allocated copy of original of expanded string
+char_u *ExpandOne(expand_T *xp, char_u *str, char_u *orig, int options, int mode)
{
- char_u *ss = NULL;
+ char_u *ss = NULL;
static int findex;
- static char_u *orig_save = NULL; /* kept value of orig */
+ static char_u *orig_save = NULL; // kept value of orig
int orig_saved = FALSE;
int i;
- int non_suf_match; /* number without matching suffix */
+ int non_suf_match; // number without matching suffix
/*
* first handle the case of using an old match
@@ -3814,27 +3891,31 @@ ExpandOne (
if (mode == WILD_NEXT || mode == WILD_PREV) {
if (xp->xp_numfiles > 0) {
if (mode == WILD_PREV) {
- if (findex == -1)
+ if (findex == -1) {
findex = xp->xp_numfiles;
+ }
--findex;
- } else /* mode == WILD_NEXT */
+ } else { // mode == WILD_NEXT
++findex;
+ }
/*
* When wrapping around, return the original string, set findex to
* -1.
*/
if (findex < 0) {
- if (orig_save == NULL)
+ if (orig_save == NULL) {
findex = xp->xp_numfiles - 1;
- else
+ } else {
findex = -1;
+ }
}
if (findex >= xp->xp_numfiles) {
- if (orig_save == NULL)
+ if (orig_save == NULL) {
findex = 0;
- else
+ } else {
findex = -1;
+ }
}
if (compl_match_array) {
compl_selected = findex;
@@ -3847,8 +3928,9 @@ ExpandOne (
return vim_strsave(orig_save);
}
return vim_strsave(xp->xp_files[findex]);
- } else
+ } else {
return NULL;
+ }
}
if (mode == WILD_CANCEL) {
@@ -3858,7 +3940,7 @@ ExpandOne (
xp->xp_files[findex]);
}
- /* free old names */
+ // free old names
if (xp->xp_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST) {
FreeWild(xp->xp_numfiles, xp->xp_files);
xp->xp_numfiles = -1;
@@ -3866,8 +3948,9 @@ ExpandOne (
}
findex = 0;
- if (mode == WILD_FREE) /* only release file name */
+ if (mode == WILD_FREE) { // only release file name
return NULL;
+ }
if (xp->xp_numfiles == -1 && mode != WILD_APPLY && mode != WILD_CANCEL) {
xfree(orig_save);
@@ -3878,20 +3961,22 @@ ExpandOne (
* Do the expansion.
*/
if (ExpandFromContext(xp, str, &xp->xp_numfiles, &xp->xp_files,
- options) == FAIL) {
+ options) == FAIL) {
#ifdef FNAME_ILLEGAL
/* Illegal file name has been silently skipped. But when there
* are wildcards, the real problem is that there was no match,
* causing the pattern to be added, which has illegal characters.
*/
- if (!(options & WILD_SILENT) && (options & WILD_LIST_NOTFOUND))
+ if (!(options & WILD_SILENT) && (options & WILD_LIST_NOTFOUND)) {
EMSG2(_(e_nomatch2), str);
+ }
#endif
} else if (xp->xp_numfiles == 0) {
- if (!(options & WILD_SILENT))
+ if (!(options & WILD_SILENT)) {
EMSG2(_(e_nomatch2), str);
+ }
} else {
- /* Escape the matches for use on the command line. */
+ // Escape the matches for use on the command line.
ExpandEscape(xp, str, xp->xp_numfiles, xp->xp_files, options);
/*
@@ -3899,10 +3984,11 @@ ExpandOne (
*/
if (mode != WILD_ALL && mode != WILD_ALL_KEEP
&& mode != WILD_LONGEST) {
- if (xp->xp_numfiles)
+ if (xp->xp_numfiles) {
non_suf_match = xp->xp_numfiles;
- else
+ } else {
non_suf_match = 1;
+ }
if ((xp->xp_context == EXPAND_FILES
|| xp->xp_context == EXPAND_DIRECTORIES)
&& xp->xp_numfiles > 1) {
@@ -3912,9 +3998,11 @@ ExpandOne (
* expand_wildcards, only need to check the first two.
*/
non_suf_match = 0;
- for (i = 0; i < 2; ++i)
- if (match_suffix(xp->xp_files[i]))
+ for (i = 0; i < 2; ++i) {
+ if (match_suffix(xp->xp_files[i])) {
++non_suf_match;
+ }
+ }
}
if (non_suf_match != 1) {
/* Can we ever get here unless it's while expanding
@@ -3922,13 +4010,15 @@ ExpandOne (
* together. Don't really want to wait for this message
* (and possibly have to hit return to continue!).
*/
- if (!(options & WILD_SILENT))
+ if (!(options & WILD_SILENT)) {
EMSG(_(e_toomany));
- else if (!(options & WILD_NO_BEEP))
+ } else if (!(options & WILD_NO_BEEP)) {
beep_flush();
+ }
}
- if (!(non_suf_match != 1 && mode == WILD_EXPAND_FREE))
+ if (!(non_suf_match != 1 && mode == WILD_EXPAND_FREE)) {
ss = vim_strsave(xp->xp_files[0]);
+ }
}
}
}
@@ -3970,23 +4060,27 @@ ExpandOne (
// TODO(philix): use xstpcpy instead of strcat in a loop (ExpandOne)
if (mode == WILD_ALL && xp->xp_numfiles > 0) {
size_t len = 0;
- for (i = 0; i < xp->xp_numfiles; ++i)
+ for (i = 0; i < xp->xp_numfiles; ++i) {
len += STRLEN(xp->xp_files[i]) + 1;
+ }
ss = xmalloc(len);
*ss = NUL;
for (i = 0; i < xp->xp_numfiles; ++i) {
STRCAT(ss, xp->xp_files[i]);
- if (i != xp->xp_numfiles - 1)
+ if (i != xp->xp_numfiles - 1) {
STRCAT(ss, (options & WILD_USE_NL) ? "\n" : " ");
+ }
}
}
- if (mode == WILD_EXPAND_FREE || mode == WILD_ALL)
+ if (mode == WILD_EXPAND_FREE || mode == WILD_ALL) {
ExpandCleanup(xp);
+ }
- /* Free "orig" if it wasn't stored in "orig_save". */
- if (!orig_saved)
+ // Free "orig" if it wasn't stored in "orig_save".
+ if (!orig_saved) {
xfree(orig);
+ }
return ss;
}
@@ -4016,13 +4110,14 @@ void ExpandCleanup(expand_T *xp)
void ExpandEscape(expand_T *xp, char_u *str, int numfiles, char_u **files, int options)
{
int i;
- char_u *p;
+ char_u *p;
/*
* May change home directory back to "~"
*/
- if (options & WILD_HOME_REPLACE)
+ if (options & WILD_HOME_REPLACE) {
tilde_replace(str, numfiles, files);
+ }
if (options & WILD_ESCAPE) {
if (xp->xp_context == EXPAND_FILES
@@ -4035,7 +4130,7 @@ void ExpandEscape(expand_T *xp, char_u *str, int numfiles, char_u **files, int o
* and wildmatch characters, except '~'.
*/
for (i = 0; i < numfiles; ++i) {
- /* for ":set path=" we need to escape spaces twice */
+ // for ":set path=" we need to escape spaces twice
if (xp->xp_backslash == XP_BS_THREE) {
p = vim_strsave_escaped(files[i], (char_u *)" ");
xfree(files[i]);
@@ -4057,15 +4152,17 @@ void ExpandEscape(expand_T *xp, char_u *str, int numfiles, char_u **files, int o
/* If 'str' starts with "\~", replace "~" at start of
* files[i] with "\~". */
- if (str[0] == '\\' && str[1] == '~' && files[i][0] == '~')
+ if (str[0] == '\\' && str[1] == '~' && files[i][0] == '~') {
escape_fname(&files[i]);
+ }
}
xp->xp_backslash = XP_BS_NONE;
/* If the first file starts with a '+' escape it. Otherwise it
* could be seen as "+cmd". */
- if (*files[0] == '+')
+ if (*files[0] == '+') {
escape_fname(&files[0]);
+ }
} else if (xp->xp_context == EXPAND_TAGS) {
/*
* Insert a backslash before characters in a tag name that
@@ -4087,12 +4184,11 @@ void ExpandEscape(expand_T *xp, char_u *str, int numfiles, char_u **files, int o
/// if true then it escapes for a shell command.
///
/// @return [allocated] escaped file name.
-char *vim_strsave_fnameescape(const char *const fname,
- const bool shell FUNC_ATTR_UNUSED)
+char *vim_strsave_fnameescape(const char *const fname, const bool shell FUNC_ATTR_UNUSED)
FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
#ifdef BACKSLASH_IN_FILENAME
-#define PATH_ESC_CHARS " \t\n*?[{`%#'\"|!<"
+# define PATH_ESC_CHARS " \t\n*?[{`%#'\"|!<"
char_u buf[sizeof(PATH_ESC_CHARS)];
int j = 0;
@@ -4106,10 +4202,10 @@ char *vim_strsave_fnameescape(const char *const fname,
char *p = (char *)vim_strsave_escaped((const char_u *)fname,
(const char_u *)buf);
#else
-#define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<")
-#define SHELL_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<>();&")
- char *p = (char *)vim_strsave_escaped(
- (const char_u *)fname, (shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS));
+# define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<")
+# define SHELL_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<>();&")
+ char *p =
+ (char *)vim_strsave_escaped((const char_u *)fname, (shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS));
if (shell && csh_like_shell()) {
// For csh and similar shells need to put two backslashes before '!'.
// One is taken by Vim, one by the shell.
@@ -4148,7 +4244,7 @@ static void escape_fname(char_u **pp)
void tilde_replace(char_u *orig_pat, int num_files, char_u **files)
{
int i;
- char_u *p;
+ char_u *p;
if (orig_pat[0] == '~' && vim_ispathsep(orig_pat[1])) {
for (i = 0; i < num_files; ++i) {
@@ -4175,12 +4271,12 @@ static int showmatches(expand_T *xp, int wildmenu)
#define L_SHOWFILE(m) (showtail \
? sm_gettail(files_found[m], false) : files_found[m])
int num_files;
- char_u **files_found;
+ char_u **files_found;
int i, j, k;
int maxlen;
int lines;
int columns;
- char_u *p;
+ char_u *p;
int lastlen;
int attr;
int showtail;
@@ -4188,11 +4284,11 @@ static int showmatches(expand_T *xp, int wildmenu)
if (xp->xp_numfiles == -1) {
set_expand_context(xp);
i = expand_cmdline(xp, ccline.cmdbuff, ccline.cmdpos,
- &num_files, &files_found);
+ &num_files, &files_found);
showtail = expand_showtail(xp);
- if (i != EXPAND_OK)
+ if (i != EXPAND_OK) {
return i;
-
+ }
} else {
num_files = xp->xp_numfiles;
files_found = xp->xp_files;
@@ -4247,10 +4343,12 @@ static int showmatches(expand_T *xp, int wildmenu)
|| xp->xp_context == EXPAND_BUFFERS)) {
home_replace(NULL, files_found[i], NameBuff, MAXPATHL, TRUE);
j = vim_strsize(NameBuff);
- } else
+ } else {
j = vim_strsize(L_SHOWFILE(i));
- if (j > maxlen)
+ }
+ if (j > maxlen) {
maxlen = j;
+ }
}
if (xp->xp_context == EXPAND_TAGS_LISTFILES) {
@@ -4274,7 +4372,7 @@ static int showmatches(expand_T *xp, int wildmenu)
MSG_PUTS_ATTR(_(" kind file\n"), HL_ATTR(HLF_T));
}
- /* list the files line by line */
+ // list the files line by line
for (i = 0; i < lines; ++i) {
lastlen = 999;
for (k = i; k < num_files; k += lines) {
@@ -4287,12 +4385,13 @@ static int showmatches(expand_T *xp, int wildmenu)
msg_puts_long_attr(p + 2, HL_ATTR(HLF_D));
break;
}
- for (j = maxlen - lastlen; --j >= 0; )
+ for (j = maxlen - lastlen; --j >= 0; ) {
msg_putchar(' ');
+ }
if (xp->xp_context == EXPAND_FILES
|| xp->xp_context == EXPAND_SHELLCMD
|| xp->xp_context == EXPAND_BUFFERS) {
- /* highlight directories */
+ // highlight directories
if (xp->xp_numfiles != -1) {
// Expansion was done before and special characters
// were escaped, need to halve backslashes. Also
@@ -4313,7 +4412,7 @@ static int showmatches(expand_T *xp, int wildmenu)
p = L_SHOWFILE(k);
} else {
home_replace(NULL, files_found[k], NameBuff, MAXPATHL,
- TRUE);
+ TRUE);
p = NameBuff;
}
} else {
@@ -4322,11 +4421,11 @@ static int showmatches(expand_T *xp, int wildmenu)
}
lastlen = msg_outtrans_attr(p, j ? attr : 0);
}
- if (msg_col > 0) { /* when not wrapped around */
+ if (msg_col > 0) { // when not wrapped around
msg_clr_eos();
msg_putchar('\n');
}
- ui_flush(); /* show one line at a time */
+ ui_flush(); // show one line at a time
if (got_int) {
got_int = FALSE;
break;
@@ -4337,11 +4436,12 @@ static int showmatches(expand_T *xp, int wildmenu)
* we redraw the command below the lines that we have just listed
* This is a bit tricky, but it saves a lot of screen updating.
*/
- cmdline_row = msg_row; /* will put it back later */
+ cmdline_row = msg_row; // will put it back later
}
- if (xp->xp_numfiles == -1)
+ if (xp->xp_numfiles == -1) {
FreeWild(num_files, files_found);
+ }
return EXPAND_OK;
}
@@ -4352,8 +4452,8 @@ static int showmatches(expand_T *xp, int wildmenu)
*/
char_u *sm_gettail(char_u *s, bool eager)
{
- char_u *p;
- char_u *t = s;
+ char_u *p;
+ char_u *t = s;
int had_sep = FALSE;
for (p = s; *p != NUL; ) {
@@ -4383,26 +4483,29 @@ char_u *sm_gettail(char_u *s, bool eager)
*/
static int expand_showtail(expand_T *xp)
{
- char_u *s;
- char_u *end;
+ char_u *s;
+ char_u *end;
- /* When not completing file names a "/" may mean something different. */
+ // When not completing file names a "/" may mean something different.
if (xp->xp_context != EXPAND_FILES
&& xp->xp_context != EXPAND_SHELLCMD
- && xp->xp_context != EXPAND_DIRECTORIES)
+ && xp->xp_context != EXPAND_DIRECTORIES) {
return FALSE;
+ }
end = path_tail(xp->xp_pattern);
- if (end == xp->xp_pattern) /* there is no path separator */
+ if (end == xp->xp_pattern) { // there is no path separator
return FALSE;
+ }
for (s = xp->xp_pattern; s < end; s++) {
/* Skip escaped wildcards. Only when the backslash is not a path
* separator, on DOS the '*' "path\*\file" must not be skipped. */
- if (rem_backslash(s))
+ if (rem_backslash(s)) {
++s;
- else if (vim_strchr((char_u *)"*?[", *s) != NULL)
+ } else if (vim_strchr((char_u *)"*?[", *s) != NULL) {
return FALSE;
+ }
}
return TRUE;
}
@@ -4418,10 +4521,10 @@ static int expand_showtail(expand_T *xp)
char_u *addstar(char_u *fname, size_t len, int context)
FUNC_ATTR_NONNULL_RET
{
- char_u *retval;
+ char_u *retval;
size_t i, j;
size_t new_len;
- char_u *tail;
+ char_u *tail;
int ends_in_star;
if (context != EXPAND_FILES
@@ -4449,19 +4552,20 @@ char_u *addstar(char_u *fname, size_t len, int context)
} else {
new_len = len + 2; // +2 for '^' at start, NUL at end
for (i = 0; i < len; i++) {
- if (fname[i] == '*' || fname[i] == '~')
+ if (fname[i] == '*' || fname[i] == '~') {
new_len++; /* '*' needs to be replaced by ".*"
'~' needs to be replaced by "\~" */
-
- /* Buffer names are like file names. "." should be literal */
- if (context == EXPAND_BUFFERS && fname[i] == '.')
- new_len++; /* "." becomes "\." */
-
+ }
+ // Buffer names are like file names. "." should be literal
+ if (context == EXPAND_BUFFERS && fname[i] == '.') {
+ new_len++; // "." becomes "\."
+ }
/* Custom expansion takes care of special things, match
* backslashes literally (perhaps also for other types?) */
if ((context == EXPAND_USER_DEFINED
- || context == EXPAND_USER_LIST) && fname[i] == '\\')
- new_len++; /* '\' becomes "\\" */
+ || context == EXPAND_USER_LIST) && fname[i] == '\\') {
+ new_len++; // '\' becomes "\\"
+ }
}
retval = xmalloc(new_len);
{
@@ -4473,22 +4577,30 @@ char_u *addstar(char_u *fname, size_t len, int context)
if (context != EXPAND_USER_DEFINED
&& context != EXPAND_USER_LIST
&& fname[i] == '\\'
- && ++i == len)
+ && ++i == len) {
break;
+ }
switch (fname[i]) {
- case '*': retval[j++] = '.';
+ case '*':
+ retval[j++] = '.';
break;
- case '~': retval[j++] = '\\';
+ case '~':
+ retval[j++] = '\\';
break;
- case '?': retval[j] = '.';
+ case '?':
+ retval[j] = '.';
continue;
- case '.': if (context == EXPAND_BUFFERS)
+ case '.':
+ if (context == EXPAND_BUFFERS) {
retval[j++] = '\\';
+ }
break;
- case '\\': if (context == EXPAND_USER_DEFINED
- || context == EXPAND_USER_LIST)
+ case '\\':
+ if (context == EXPAND_USER_DEFINED
+ || context == EXPAND_USER_LIST) {
retval[j++] = '\\';
+ }
break;
}
retval[j] = fname[i];
@@ -4521,10 +4633,11 @@ char_u *addstar(char_u *fname, size_t len, int context)
if ((*retval != '~' || tail != retval)
&& !ends_in_star
&& vim_strchr(tail, '$') == NULL
- && vim_strchr(retval, '`') == NULL)
+ && vim_strchr(retval, '`') == NULL) {
retval[len++] = '*';
- else if (len > 0 && retval[len - 1] == '$')
+ } else if (len > 0 && retval[len - 1] == '$') {
--len;
+ }
retval[len] = NUL;
}
return retval;
@@ -4534,66 +4647,62 @@ char_u *addstar(char_u *fname, size_t len, int context)
* Must parse the command line so far to work out what context we are in.
* Completion can then be done based on that context.
* This routine sets the variables:
- * xp->xp_pattern The start of the pattern to be expanded within
- * the command line (ends at the cursor).
- * xp->xp_context The type of thing to expand. Will be one of:
+ * xp->xp_pattern The start of the pattern to be expanded within
+ * the command line (ends at the cursor).
+ * xp->xp_context The type of thing to expand. Will be one of:
*
- * EXPAND_UNSUCCESSFUL Used sometimes when there is something illegal on
- * the command line, like an unknown command. Caller
- * should beep.
- * EXPAND_NOTHING Unrecognised context for completion, use char like
- * a normal char, rather than for completion. eg
- * :s/^I/
- * EXPAND_COMMANDS Cursor is still touching the command, so complete
- * it.
- * EXPAND_BUFFERS Complete file names for :buf and :sbuf commands.
- * EXPAND_FILES After command with EX_XFILE set, or after setting
- * with P_EXPAND set. eg :e ^I, :w>>^I
- * EXPAND_DIRECTORIES In some cases this is used instead of the latter
- * when we know only directories are of interest. eg
- * :set dir=^I
- * EXPAND_SHELLCMD After ":!cmd", ":r !cmd" or ":w !cmd".
- * EXPAND_SETTINGS Complete variable names. eg :set d^I
+ * EXPAND_UNSUCCESSFUL Used sometimes when there is something illegal on
+ * the command line, like an unknown command. Caller
+ * should beep.
+ * EXPAND_NOTHING Unrecognised context for completion, use char like
+ * a normal char, rather than for completion. eg
+ * :s/^I/
+ * EXPAND_COMMANDS Cursor is still touching the command, so complete
+ * it.
+ * EXPAND_BUFFERS Complete file names for :buf and :sbuf commands.
+ * EXPAND_FILES After command with EX_XFILE set, or after setting
+ * with P_EXPAND set. eg :e ^I, :w>>^I
+ * EXPAND_DIRECTORIES In some cases this is used instead of the latter
+ * when we know only directories are of interest. eg
+ * :set dir=^I
+ * EXPAND_SHELLCMD After ":!cmd", ":r !cmd" or ":w !cmd".
+ * EXPAND_SETTINGS Complete variable names. eg :set d^I
* EXPAND_BOOL_SETTINGS Complete boolean variables only, eg :set no^I
- * EXPAND_TAGS Complete tags from the files in p_tags. eg :ta a^I
+ * EXPAND_TAGS Complete tags from the files in p_tags. eg :ta a^I
* EXPAND_TAGS_LISTFILES As above, but list filenames on ^D, after :tselect
- * EXPAND_HELP Complete tags from the file 'helpfile'/tags
- * EXPAND_EVENTS Complete event names
- * EXPAND_SYNTAX Complete :syntax command arguments
- * EXPAND_HIGHLIGHT Complete highlight (syntax) group names
- * EXPAND_AUGROUP Complete autocommand group names
- * EXPAND_USER_VARS Complete user defined variable names, eg :unlet a^I
- * EXPAND_MAPPINGS Complete mapping and abbreviation names,
- * eg :unmap a^I , :cunab x^I
- * EXPAND_FUNCTIONS Complete internal or user defined function names,
- * eg :call sub^I
- * EXPAND_USER_FUNC Complete user defined function names, eg :delf F^I
- * EXPAND_EXPRESSION Complete internal or user defined function/variable
- * names in expressions, eg :while s^I
- * EXPAND_ENV_VARS Complete environment variable names
- * EXPAND_USER Complete user names
+ * EXPAND_HELP Complete tags from the file 'helpfile'/tags
+ * EXPAND_EVENTS Complete event names
+ * EXPAND_SYNTAX Complete :syntax command arguments
+ * EXPAND_HIGHLIGHT Complete highlight (syntax) group names
+ * EXPAND_AUGROUP Complete autocommand group names
+ * EXPAND_USER_VARS Complete user defined variable names, eg :unlet a^I
+ * EXPAND_MAPPINGS Complete mapping and abbreviation names,
+ * eg :unmap a^I , :cunab x^I
+ * EXPAND_FUNCTIONS Complete internal or user defined function names,
+ * eg :call sub^I
+ * EXPAND_USER_FUNC Complete user defined function names, eg :delf F^I
+ * EXPAND_EXPRESSION Complete internal or user defined function/variable
+ * names in expressions, eg :while s^I
+ * EXPAND_ENV_VARS Complete environment variable names
+ * EXPAND_USER Complete user names
*/
static void set_expand_context(expand_T *xp)
{
- /* only expansion for ':', '>' and '=' command-lines */
+ // only expansion for ':', '>' and '=' command-lines
if (ccline.cmdfirstc != ':'
&& ccline.cmdfirstc != '>' && ccline.cmdfirstc != '='
- && !ccline.input_fn
- ) {
+ && !ccline.input_fn) {
xp->xp_context = EXPAND_NOTHING;
return;
}
set_cmd_context(xp, ccline.cmdbuff, ccline.cmdlen, ccline.cmdpos, true);
}
-void
-set_cmd_context (
- expand_T *xp,
- char_u *str, // start of command line
- int len, // length of command line (excl. NUL)
- int col, // position of cursor
- int use_ccline // use ccline for info
-)
+/// @param str start of command line
+/// @param len length of command line (excl. NUL)
+/// @param col position of cursor
+/// @param use_ccline use ccline for info
+void set_cmd_context(expand_T *xp, char_u *str, int len, int col, int use_ccline)
{
char_u old_char = NUL;
@@ -4601,8 +4710,9 @@ set_cmd_context (
* Avoid a UMR warning from Purify, only save the character if it has been
* written before.
*/
- if (col < len)
+ if (col < len) {
old_char = str[col];
+ }
str[col] = NUL;
const char *nextcomm = (const char *)str;
@@ -4627,35 +4737,31 @@ set_cmd_context (
str[col] = old_char;
}
-/*
- * Expand the command line "str" from context "xp".
- * "xp" must have been set by set_cmd_context().
- * xp->xp_pattern points into "str", to where the text that is to be expanded
- * starts.
- * Returns EXPAND_UNSUCCESSFUL when there is something illegal before the
- * cursor.
- * Returns EXPAND_NOTHING when there is nothing to expand, might insert the
- * key that triggered expansion literally.
- * Returns EXPAND_OK otherwise.
- */
-int
-expand_cmdline (
- expand_T *xp,
- char_u *str, /* start of command line */
- int col, /* position of cursor */
- int *matchcount, /* return: nr of matches */
- char_u ***matches /* return: array of pointers to matches */
-)
+/// Expand the command line "str" from context "xp".
+/// "xp" must have been set by set_cmd_context().
+/// xp->xp_pattern points into "str", to where the text that is to be expanded
+/// starts.
+/// Returns EXPAND_UNSUCCESSFUL when there is something illegal before the
+/// cursor.
+/// Returns EXPAND_NOTHING when there is nothing to expand, might insert the
+/// key that triggered expansion literally.
+/// Returns EXPAND_OK otherwise.
+///
+/// @param str start of command line
+/// @param col position of cursor
+/// @param matchcount return: nr of matches
+/// @param matches return: array of pointers to matches
+int expand_cmdline(expand_T *xp, char_u *str, int col, int *matchcount, char_u ***matches)
{
- char_u *file_str = NULL;
+ char_u *file_str = NULL;
int options = WILD_ADD_SLASH|WILD_SILENT;
if (xp->xp_context == EXPAND_UNSUCCESSFUL) {
beep_flush();
- return EXPAND_UNSUCCESSFUL; /* Something illegal on command line */
+ return EXPAND_UNSUCCESSFUL; // Something illegal on command line
}
if (xp->xp_context == EXPAND_NOTHING) {
- /* Caller can use the character as a normal char instead */
+ // Caller can use the character as a normal char instead
return EXPAND_NOTHING;
}
@@ -4664,10 +4770,11 @@ expand_cmdline (
xp->xp_pattern_len = (size_t)((str + col) - xp->xp_pattern);
file_str = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context);
- if (p_wic)
+ if (p_wic) {
options += WILD_ICASE;
+ }
- /* find all files that match the description */
+ // find all files that match the description
if (ExpandFromContext(xp, file_str, matchcount, matches, options) == FAIL) {
*matchcount = 0;
*matches = NULL;
@@ -4731,31 +4838,28 @@ static void cleanup_help_tags(int num_file, char_u **file)
typedef char_u *(*ExpandFunc)(expand_T *, int);
-/*
- * Do the expansion based on xp->xp_context and "pat".
- */
-static int
-ExpandFromContext (
- expand_T *xp,
- char_u *pat,
- int *num_file,
- char_u ***file,
- int options // WILD_ flags
-)
+/// Do the expansion based on xp->xp_context and "pat".
+///
+/// @param options WILD_ flags
+static int ExpandFromContext(expand_T *xp, char_u *pat, int *num_file, char_u ***file, int options)
{
regmatch_T regmatch;
int ret;
int flags;
- flags = EW_DIR; /* include directories */
- if (options & WILD_LIST_NOTFOUND)
+ flags = EW_DIR; // include directories
+ if (options & WILD_LIST_NOTFOUND) {
flags |= EW_NOTFOUND;
- if (options & WILD_ADD_SLASH)
+ }
+ if (options & WILD_ADD_SLASH) {
flags |= EW_ADDSLASH;
- if (options & WILD_KEEP_ALL)
+ }
+ if (options & WILD_KEEP_ALL) {
flags |= EW_KEEPALL;
- if (options & WILD_SILENT)
+ }
+ if (options & WILD_SILENT) {
flags |= EW_SILENT;
+ }
if (options & WILD_NOERROR) {
flags |= EW_NOERROR;
}
@@ -4776,32 +4880,38 @@ ExpandFromContext (
if (xp->xp_backslash != XP_BS_NONE) {
free_pat = TRUE;
pat = vim_strsave(pat);
- for (i = 0; pat[i]; ++i)
+ for (i = 0; pat[i]; ++i) {
if (pat[i] == '\\') {
if (xp->xp_backslash == XP_BS_THREE
&& pat[i + 1] == '\\'
&& pat[i + 2] == '\\'
- && pat[i + 3] == ' ')
+ && pat[i + 3] == ' ') {
STRMOVE(pat + i, pat + i + 3);
+ }
if (xp->xp_backslash == XP_BS_ONE
- && pat[i + 1] == ' ')
+ && pat[i + 1] == ' ') {
STRMOVE(pat + i, pat + i + 1);
+ }
}
+ }
}
- if (xp->xp_context == EXPAND_FILES)
+ if (xp->xp_context == EXPAND_FILES) {
flags |= EW_FILE;
- else if (xp->xp_context == EXPAND_FILES_IN_PATH)
+ } else if (xp->xp_context == EXPAND_FILES_IN_PATH) {
flags |= (EW_FILE | EW_PATH);
- else
+ } else {
flags = (flags | EW_DIR) & ~EW_FILE;
- if (options & WILD_ICASE)
+ }
+ if (options & WILD_ICASE) {
flags |= EW_ICASE;
+ }
- /* Expand wildcards, supporting %:h and the like. */
+ // Expand wildcards, supporting %:h and the like.
ret = expand_wildcards_eval(&pat, num_file, file, flags);
- if (free_pat)
+ if (free_pat) {
xfree(pat);
+ }
#ifdef BACKSLASH_IN_FILENAME
if (p_csl[0] != NUL && (options & WILD_IGNORE_COMPLETESLASH) == 0) {
for (int i = 0; i < *num_file; i++) {
@@ -4842,8 +4952,9 @@ ExpandFromContext (
ExpandOldSetting(num_file, file);
return OK;
}
- if (xp->xp_context == EXPAND_BUFFERS)
+ if (xp->xp_context == EXPAND_BUFFERS) {
return ExpandBufnames(pat, num_file, file, options);
+ }
if (xp->xp_context == EXPAND_DIFF_BUFFERS) {
return ExpandBufnames(pat, num_file, file, options | BUF_DIFF_FILTER);
}
@@ -4868,10 +4979,6 @@ ExpandFromContext (
char *directories[] = { "syntax", "indent", "ftplugin", NULL };
return ExpandRTDir(pat, DIP_LUA, num_file, file, directories);
}
- if (xp->xp_context == EXPAND_CHECKHEALTH) {
- char *directories[] = { "autoload/health", NULL };
- return ExpandRTDir(pat, 0, num_file, file, directories);
- }
if (xp->xp_context == EXPAND_USER_LIST) {
return ExpandUserList(xp, num_file, file);
}
@@ -4896,20 +5003,21 @@ ExpandFromContext (
}
regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0);
- if (regmatch.regprog == NULL)
+ if (regmatch.regprog == NULL) {
return FAIL;
+ }
- /* set ignore-case according to p_ic, p_scs and pat */
+ // set ignore-case according to p_ic, p_scs and pat
regmatch.rm_ic = ignorecase(pat);
if (xp->xp_context == EXPAND_SETTINGS
- || xp->xp_context == EXPAND_BOOL_SETTINGS)
+ || xp->xp_context == EXPAND_BOOL_SETTINGS) {
ret = ExpandSettings(xp, &regmatch, num_file, file);
- else if (xp->xp_context == EXPAND_MAPPINGS)
+ } else if (xp->xp_context == EXPAND_MAPPINGS) {
ret = ExpandMappings(&regmatch, num_file, file);
- else if (xp->xp_context == EXPAND_USER_DEFINED)
+ } else if (xp->xp_context == EXPAND_USER_DEFINED) {
ret = ExpandUserDefined(xp, &regmatch, num_file, file);
- else {
+ } else {
static struct expgen {
int context;
ExpandFunc func;
@@ -4947,6 +5055,7 @@ ExpandFromContext (
{ EXPAND_ENV_VARS, get_env_name, true, true },
{ EXPAND_USER, get_users, true, false },
{ EXPAND_ARGLIST, get_arglist_name, true, false },
+ { EXPAND_CHECKHEALTH, get_healthcheck_names, true, false },
};
int i;
@@ -4955,7 +5064,7 @@ ExpandFromContext (
* right function to do the expansion.
*/
ret = FAIL;
- for (i = 0; i < (int)ARRAY_SIZE(tab); ++i)
+ for (i = 0; i < (int)ARRAY_SIZE(tab); ++i) {
if (xp->xp_context == tab[i].context) {
if (tab[i].ic) {
regmatch.rm_ic = TRUE;
@@ -4965,6 +5074,7 @@ ExpandFromContext (
ret = OK;
break;
}
+ }
}
vim_regfree(regmatch.regprog);
@@ -4973,39 +5083,36 @@ ExpandFromContext (
return ret;
}
-/*
- * Expand a list of names.
- *
- * Generic function for command line completion. It calls a function to
- * obtain strings, one by one. The strings are matched against a regexp
- * program. Matching strings are copied into an array, which is returned.
- */
-static void ExpandGeneric(
- expand_T *xp,
- regmatch_T *regmatch,
- int *num_file,
- char_u ***file,
- CompleteListItemGetter func, /* returns a string from the list */
- int escaped
- )
+/// Expand a list of names.
+///
+/// Generic function for command line completion. It calls a function to
+/// obtain strings, one by one. The strings are matched against a regexp
+/// program. Matching strings are copied into an array, which is returned.
+///
+/// @param func returns a string from the list
+static void ExpandGeneric(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file,
+ CompleteListItemGetter func, int escaped)
{
int i;
size_t count = 0;
- char_u *str;
+ char_u *str;
// count the number of matching names
for (i = 0;; ++i) {
str = (*func)(xp, i);
- if (str == NULL) // end of list
+ if (str == NULL) { // end of list
break;
- if (*str == NUL) // skip empty strings
+ }
+ if (*str == NUL) { // skip empty strings
continue;
+ }
if (vim_regexec(regmatch, str, (colnr_T)0)) {
++count;
}
}
- if (count == 0)
+ if (count == 0) {
return;
+ }
assert(count < INT_MAX);
*num_file = (int)count;
*file = (char_u **)xmalloc(count * sizeof(char_u *));
@@ -5037,16 +5144,17 @@ static void ExpandGeneric(
}
}
- /* Sort the results. Keep menu's in the specified order. */
+ // Sort the results. Keep menu's in the specified order.
if (xp->xp_context != EXPAND_MENUNAMES && xp->xp_context != EXPAND_MENUS) {
if (xp->xp_context == EXPAND_EXPRESSION
|| xp->xp_context == EXPAND_FUNCTIONS
- || xp->xp_context == EXPAND_USER_FUNC)
- /* <SNR> functions should be sorted to the end. */
+ || xp->xp_context == EXPAND_USER_FUNC) {
+ // <SNR> functions should be sorted to the end.
qsort((void *)*file, (size_t)*num_file, sizeof(char_u *),
- sort_func_compare);
- else
+ sort_func_compare);
+ } else {
sort_strings(*file, *num_file);
+ }
}
/* Reset the variables used for special highlight names expansion, so that
@@ -5062,26 +5170,27 @@ static void ExpandGeneric(
/// *file will either be set to NULL or point to
/// allocated memory.
/// @param flagsarg is a combination of EW_* flags.
-static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
- int flagsarg)
+static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file, int flagsarg)
FUNC_ATTR_NONNULL_ALL
{
- char_u *pat;
+ char_u *pat;
int i;
- char_u *path = NULL;
+ char_u *path = NULL;
garray_T ga;
char_u *buf = xmalloc(MAXPATHL);
size_t l;
- char_u *s, *e;
+ char_u *s, *e;
int flags = flagsarg;
int ret;
bool did_curdir = false;
// for ":set path=" and ":set tags=" halve backslashes for escaped space
pat = vim_strsave(filepat);
- for (i = 0; pat[i]; ++i)
- if (pat[i] == '\\' && pat[i + 1] == ' ')
+ for (i = 0; pat[i]; ++i) {
+ if (pat[i] == '\\' && pat[i + 1] == ' ') {
STRMOVE(pat + i, pat + i + 1);
+ }
+ }
flags |= EW_FILE | EW_EXEC | EW_SHELLCMD;
@@ -5139,7 +5248,7 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
l = STRLEN(buf);
STRLCPY(buf + l, pat, MAXPATHL - l);
- /* Expand matches in one directory of $PATH. */
+ // Expand matches in one directory of $PATH.
ret = expand_wildcards(1, &buf, num_file, file, flags);
if (ret == OK) {
ga_grow(&ga, *num_file);
@@ -5166,8 +5275,9 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
xfree(*file);
}
}
- if (*e != NUL)
+ if (*e != NUL) {
++e;
+ }
}
*file = ga.ga_data;
*num_file = ga.ga_len;
@@ -5182,8 +5292,8 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
/// Call "user_expand_func()" to invoke a user defined Vim script function and
/// return the result (either a string, a List or NULL).
-static void * call_user_expand_func(user_expand_func_T user_expand_func,
- expand_T *xp, int *num_file, char_u ***file)
+static void *call_user_expand_func(user_expand_func_T user_expand_func, expand_T *xp, int *num_file,
+ char_u ***file)
FUNC_ATTR_NONNULL_ALL
{
char_u keep = 0;
@@ -5192,8 +5302,9 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func,
const sctx_T save_current_sctx = current_sctx;
struct cmdline_info save_ccline;
- if (xp->xp_arg == NULL || xp->xp_arg[0] == '\0' || xp->xp_line == NULL)
+ if (xp->xp_arg == NULL || xp->xp_arg[0] == '\0' || xp->xp_line == NULL) {
return NULL;
+ }
*num_file = 0;
*file = NULL;
@@ -5211,7 +5322,7 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func,
args[1].vval.v_string = xp->xp_line;
args[2].vval.v_number = xp->xp_col;
- /* Save the cmdline, we don't know what the function may do. */
+ // Save the cmdline, we don't know what the function may do.
save_ccline = ccline;
ccline.cmdbuff = NULL;
ccline.cmdprompt = NULL;
@@ -5234,11 +5345,11 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func,
*/
static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file)
{
- char_u *e;
- garray_T ga;
+ char_u *e;
+ garray_T ga;
- char_u *const retstr = call_user_expand_func(
- (user_expand_func_T)call_func_retstr, xp, num_file, file);
+ char_u *const retstr = call_user_expand_func((user_expand_func_T)call_func_retstr, xp, num_file,
+ file);
if (retstr == NULL) {
return FAIL;
@@ -5247,13 +5358,14 @@ static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, int *num_file,
ga_init(&ga, (int)sizeof(char *), 3);
for (char_u *s = retstr; *s != NUL; s = e) {
e = vim_strchr(s, '\n');
- if (e == NULL)
+ if (e == NULL) {
e = s + STRLEN(s);
+ }
const char_u keep = *e;
*e = NUL;
const bool skip = xp->xp_pattern[0]
- && vim_regexec(regmatch, s, (colnr_T)0) == 0;
+ && vim_regexec(regmatch, s, (colnr_T)0) == 0;
*e = keep;
if (!skip) {
GA_APPEND(char_u *, &ga, vim_strnsave(s, (size_t)(e - s)));
@@ -5274,8 +5386,8 @@ static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, int *num_file,
*/
static int ExpandUserList(expand_T *xp, int *num_file, char_u ***file)
{
- list_T *const retlist = call_user_expand_func(
- (user_expand_func_T)call_func_retlist, xp, num_file, file);
+ list_T *const retlist = call_user_expand_func((user_expand_func_T)call_func_retlist, xp, num_file,
+ file);
if (retlist == NULL) {
return FAIL;
}
@@ -5289,8 +5401,7 @@ static int ExpandUserList(expand_T *xp, int *num_file, char_u ***file)
continue; // Skip non-string items and empty strings.
}
- GA_APPEND(char *, &ga, xstrdup(
- (const char *)TV_LIST_ITEM_TV(li)->vval.v_string));
+ GA_APPEND(char *, &ga, xstrdup((const char *)TV_LIST_ITEM_TV(li)->vval.v_string));
});
tv_list_unref(retlist);
@@ -5308,8 +5419,7 @@ static int ExpandUserList(expand_T *xp, int *num_file, char_u ***file)
/// 'packpath'/pack/ * /opt/ * /{dirnames}/{pat}.vim
/// When "flags" has DIP_LUA: search also performed for .lua files
/// "dirnames" is an array with one or more directory names.
-static int ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file,
- char *dirnames[])
+static int ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file, char *dirnames[])
{
*num_file = 0;
*file = NULL;
@@ -5403,8 +5513,9 @@ static int ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file,
}
}
- if (GA_EMPTY(&ga))
+ if (GA_EMPTY(&ga)) {
return FAIL;
+ }
/* Sort and remove duplicates which can happen when specifying multiple
* directories in dirnames. */
@@ -5497,7 +5608,7 @@ void globpath(char_u *path, char_u *file, garray_T *ga, int expand_options)
/*********************************
-* Command line history stuff *
+* Command line history stuff *
*********************************/
/// Translate a history character to the associated type number
@@ -5505,26 +5616,20 @@ static HistoryType hist_char2type(const int c)
FUNC_ATTR_CONST FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (c) {
- case ':': {
- return HIST_CMD;
- }
- case '=': {
- return HIST_EXPR;
- }
- case '@': {
- return HIST_INPUT;
- }
- case '>': {
- return HIST_DEBUG;
- }
- case NUL:
- case '/':
- case '?': {
- return HIST_SEARCH;
- }
- default: {
- return HIST_INVALID;
- }
+ case ':':
+ return HIST_CMD;
+ case '=':
+ return HIST_EXPR;
+ case '@':
+ return HIST_INPUT;
+ case '>':
+ return HIST_DEBUG;
+ case NUL:
+ case '/':
+ case '?':
+ return HIST_SEARCH;
+ default:
+ return HIST_INVALID;
}
// Silence -Wreturn-type
return 0;
@@ -5561,10 +5666,12 @@ static char_u *get_history_arg(expand_T *xp, int idx)
compl[0] = (char_u)short_names[idx];
return compl;
}
- if (idx < short_names_count + history_name_count)
+ if (idx < short_names_count + history_name_count) {
return (char_u *)history_names[idx - short_names_count];
- if (idx == short_names_count + history_name_count)
+ }
+ if (idx == short_names_count + history_name_count) {
return (char_u *)"all";
+ }
return NULL;
}
@@ -5642,49 +5749,48 @@ static inline void clear_hist_entry(histentry_T *hisptr)
memset(hisptr, 0, sizeof(*hisptr));
}
-/*
- * Check if command line 'str' is already in history.
- * If 'move_to_front' is TRUE, matching entry is moved to end of history.
- */
-static int
-in_history (
- int type,
- char_u *str,
- int move_to_front, // Move the entry to the front if it exists
- int sep
-)
+/// Check if command line 'str' is already in history.
+/// If 'move_to_front' is TRUE, matching entry is moved to end of history.
+///
+/// @param move_to_front Move the entry to the front if it exists
+static int in_history(int type, char_u *str, int move_to_front, int sep)
{
int i;
int last_i = -1;
- char_u *p;
+ char_u *p;
- if (hisidx[type] < 0)
+ if (hisidx[type] < 0) {
return FALSE;
+ }
i = hisidx[type];
do {
- if (history[type][i].hisstr == NULL)
+ if (history[type][i].hisstr == NULL) {
return FALSE;
+ }
/* For search history, check that the separator character matches as
* well. */
p = history[type][i].hisstr;
if (STRCMP(str, p) == 0
&& (type != HIST_SEARCH || sep == p[STRLEN(p) + 1])) {
- if (!move_to_front)
+ if (!move_to_front) {
return TRUE;
+ }
last_i = i;
break;
}
- if (--i < 0)
+ if (--i < 0) {
i = hislen - 1;
+ }
} while (i != hisidx[type]);
if (last_i >= 0) {
list_T *const list = history[type][i].additional_elements;
str = history[type][i].hisstr;
while (i != hisidx[type]) {
- if (++i >= hislen)
+ if (++i >= hislen) {
i = 0;
+ }
history[type][last_i] = history[type][i];
last_i = i;
}
@@ -5710,8 +5816,7 @@ in_history (
///
/// @return Any value from HistoryType enum, including HIST_INVALID. May not
/// return HIST_DEFAULT unless return_default is true.
-HistoryType get_histtype(const char *const name, const size_t len,
- const bool return_default)
+HistoryType get_histtype(const char *const name, const size_t len, const bool return_default)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
// No argument: use current history.
@@ -5732,7 +5837,7 @@ HistoryType get_histtype(const char *const name, const size_t len,
return HIST_INVALID;
}
-static int last_maptick = -1; /* last seen maptick */
+static int last_maptick = -1; // last seen maptick
/// Add the given string to the given history. If the string is already in the
/// history then it is moved to the front. "histype" may be one of he HIST_
@@ -5749,8 +5854,9 @@ void add_to_history(int histype, char_u *new_entry, int in_map, int sep)
}
assert(histype != HIST_DEFAULT);
- if (cmdmod.keeppatterns && histype == HIST_SEARCH)
+ if (cmdmod.keeppatterns && histype == HIST_SEARCH) {
return;
+ }
/*
* Searches inside the same mapping overwrite each other, so that only
@@ -5763,14 +5869,16 @@ void add_to_history(int histype, char_u *new_entry, int in_map, int sep)
hisptr = &history[HIST_SEARCH][hisidx[HIST_SEARCH]];
hist_free_entry(hisptr);
--hisnum[histype];
- if (--hisidx[HIST_SEARCH] < 0)
+ if (--hisidx[HIST_SEARCH] < 0) {
hisidx[HIST_SEARCH] = hislen - 1;
+ }
}
last_maptick = -1;
}
if (!in_history(histype, new_entry, true, sep)) {
- if (++hisidx[histype] == hislen)
+ if (++hisidx[histype] == hislen) {
hisidx[histype] = 0;
+ }
hisptr = &history[histype][hisidx[histype]];
hist_free_entry(hisptr);
@@ -5782,8 +5890,9 @@ void add_to_history(int histype, char_u *new_entry, int in_map, int sep)
hisptr->hisstr[len + 1] = (char_u)sep;
hisptr->hisnum = ++hisnum[histype];
- if (histype == HIST_SEARCH && in_map)
+ if (histype == HIST_SEARCH && in_map) {
last_maptick = maptick;
+ }
}
}
@@ -5795,8 +5904,9 @@ void add_to_history(int histype, char_u *new_entry, int in_map, int sep)
int get_history_idx(int histype)
{
if (hislen == 0 || histype < 0 || histype >= HIST_COUNT
- || hisidx[histype] < 0)
+ || hisidx[histype] < 0) {
return -1;
+ }
return history[histype][hisidx[histype]].hisnum;
}
@@ -5831,8 +5941,9 @@ char_u *get_cmdline_str(void)
}
struct cmdline_info *p = get_ccline_ptr();
- if (p == NULL)
+ if (p == NULL) {
return NULL;
+ }
return vim_strnsave(p->cmdbuff, (size_t)p->cmdlen);
}
@@ -5846,8 +5957,9 @@ int get_cmdline_pos(void)
{
struct cmdline_info *p = get_ccline_ptr();
- if (p == NULL)
+ if (p == NULL) {
return -1;
+ }
return p->cmdpos;
}
@@ -5860,15 +5972,17 @@ int set_cmdline_pos(int pos)
{
struct cmdline_info *p = get_ccline_ptr();
- if (p == NULL)
+ if (p == NULL) {
return 1;
+ }
- /* The position is not set directly but after CTRL-\ e or CTRL-R = has
- * changed the command line. */
- if (pos < 0)
+ // The position is not set directly but after CTRL-\ e or CTRL-R = has
+ // changed the command line.
+ if (pos < 0) {
new_cmdpos = 0;
- else
+ } else {
new_cmdpos = pos;
+ }
return 0;
}
@@ -5882,10 +5996,12 @@ int get_cmdline_type(void)
{
struct cmdline_info *p = get_ccline_ptr();
- if (p == NULL)
+ if (p == NULL) {
return NUL;
- if (p->cmdfirstc == NUL)
+ }
+ if (p->cmdfirstc == NUL) {
return (p->input_fn) ? '@' : '-';
+ }
return p->cmdfirstc;
}
@@ -5902,26 +6018,32 @@ static int calc_hist_idx(int histype, int num)
int wrapped = FALSE;
if (hislen == 0 || histype < 0 || histype >= HIST_COUNT
- || (i = hisidx[histype]) < 0 || num == 0)
+ || (i = hisidx[histype]) < 0 || num == 0) {
return -1;
+ }
hist = history[histype];
if (num > 0) {
- while (hist[i].hisnum > num)
+ while (hist[i].hisnum > num) {
if (--i < 0) {
- if (wrapped)
+ if (wrapped) {
break;
+ }
i += hislen;
wrapped = TRUE;
}
- if (hist[i].hisnum == num && hist[i].hisstr != NULL)
+ }
+ if (hist[i].hisnum == num && hist[i].hisstr != NULL) {
return i;
- } else if (-num <= hislen) {
+ }
+ } else if (-num <= hislen) {
i += num + 1;
- if (i < 0)
+ if (i < 0) {
i += hislen;
- if (hist[i].hisstr != NULL)
+ }
+ if (hist[i].hisstr != NULL) {
return i;
+ }
}
return -1;
}
@@ -5933,10 +6055,11 @@ static int calc_hist_idx(int histype, int num)
char_u *get_history_entry(int histype, int idx)
{
idx = calc_hist_idx(histype, idx);
- if (idx >= 0)
+ if (idx >= 0) {
return history[histype][idx].hisstr;
- else
+ } else {
return (char_u *)"";
+ }
}
/// Clear all entries in a history
@@ -5973,7 +6096,7 @@ int del_history_entry(int histype, char_u *str)
bool found = false;
regmatch.regprog = NULL;
- regmatch.rm_ic = FALSE; /* always match case */
+ regmatch.rm_ic = FALSE; // always match case
if (hislen != 0
&& histype >= 0
&& histype < HIST_COUNT
@@ -5984,8 +6107,9 @@ int del_history_entry(int histype, char_u *str)
i = last = idx;
do {
hisptr = &history[histype][i];
- if (hisptr->hisstr == NULL)
+ if (hisptr->hisstr == NULL) {
break;
+ }
if (vim_regexec(&regmatch, hisptr->hisstr, (colnr_T)0)) {
found = true;
hist_free_entry(hisptr);
@@ -5994,14 +6118,17 @@ int del_history_entry(int histype, char_u *str)
history[histype][last] = *hisptr;
clear_hist_entry(hisptr);
}
- if (--last < 0)
+ if (--last < 0) {
last += hislen;
+ }
}
- if (--i < 0)
+ if (--i < 0) {
i += hislen;
+ }
} while (i != idx);
- if (history[histype][idx].hisstr == NULL)
+ if (history[histype][idx].hisstr == NULL) {
hisidx[histype] = -1;
+ }
}
vim_regfree(regmatch.regprog);
return found;
@@ -6016,16 +6143,18 @@ int del_history_idx(int histype, int idx)
int i, j;
i = calc_hist_idx(histype, idx);
- if (i < 0)
+ if (i < 0) {
return FALSE;
+ }
idx = hisidx[histype];
hist_free_entry(&history[histype][i]);
/* When deleting the last added search string in a mapping, reset
* last_maptick, so that the last added search string isn't deleted again.
*/
- if (histype == HIST_SEARCH && maptick == last_maptick && i == idx)
+ if (histype == HIST_SEARCH && maptick == last_maptick && i == idx) {
last_maptick = -1;
+ }
while (i != idx) {
j = (i + 1) % hislen;
@@ -6089,8 +6218,8 @@ void ex_history(exarg_T *eap)
int hisidx2 = -1;
int idx;
int i, j, k;
- char_u *end;
- char_u *arg = eap->arg;
+ char_u *end;
+ char_u *arg = eap->arg;
if (hislen == 0) {
MSG(_("'history' option is zero"));
@@ -6100,8 +6229,9 @@ void ex_history(exarg_T *eap)
if (!(ascii_isdigit(*arg) || *arg == '-' || *arg == ',')) {
end = arg;
while (ASCII_ISALPHA(*end)
- || vim_strchr((char_u *)":=@>/?", *end) != NULL)
+ || vim_strchr((char_u *)":=@>/?", *end) != NULL) {
end++;
+ }
histype1 = get_histtype((const char *)arg, (size_t)(end - arg), false);
if (histype1 == HIST_INVALID) {
if (STRNICMP(arg, "all", end - arg) == 0) {
@@ -6111,8 +6241,9 @@ void ex_history(exarg_T *eap)
EMSG(_(e_trailing));
return;
}
- } else
+ } else {
histype2 = histype1;
+ }
} else {
end = arg;
}
@@ -6130,14 +6261,17 @@ void ex_history(exarg_T *eap)
hist = history[histype1];
j = hisidx1;
k = hisidx2;
- if (j < 0)
+ if (j < 0) {
j = (-j > hislen) ? 0 : hist[(hislen+j+idx+1) % hislen].hisnum;
- if (k < 0)
+ }
+ if (k < 0) {
k = (-k > hislen) ? 0 : hist[(hislen+k+idx+1) % hislen].hisnum;
- if (idx >= 0 && j <= k)
+ }
+ if (idx >= 0 && j <= k) {
for (i = idx + 1; !got_int; ++i) {
- if (i == hislen)
+ if (i == hislen) {
i = 0;
+ }
if (hist[i].hisstr != NULL
&& hist[i].hisnum >= j && hist[i].hisnum <= k) {
msg_putchar('\n');
@@ -6152,9 +6286,11 @@ void ex_history(exarg_T *eap)
msg_outtrans(IObuff);
ui_flush();
}
- if (i == idx)
+ if (i == idx) {
break;
+ }
}
+ }
}
}
@@ -6163,24 +6299,18 @@ int hist_type2char(int type)
FUNC_ATTR_CONST
{
switch (type) {
- case HIST_CMD: {
- return ':';
- }
- case HIST_SEARCH: {
- return '/';
- }
- case HIST_EXPR: {
- return '=';
- }
- case HIST_INPUT: {
- return '@';
- }
- case HIST_DEBUG: {
- return '>';
- }
- default: {
- abort();
- }
+ case HIST_CMD:
+ return ':';
+ case HIST_SEARCH:
+ return '/';
+ case HIST_EXPR:
+ return '=';
+ case HIST_INPUT:
+ return '@';
+ case HIST_DEBUG:
+ return '>';
+ default:
+ abort();
}
return NUL;
}
@@ -6194,10 +6324,10 @@ int hist_type2char(int type)
static int open_cmdwin(void)
{
struct cmdline_info save_ccline;
- bufref_T old_curbuf;
- bufref_T bufref;
- win_T *old_curwin = curwin;
- win_T *wp;
+ bufref_T old_curbuf;
+ bufref_T bufref;
+ win_T *old_curwin = curwin;
+ win_T *wp;
int i;
linenr_T lnum;
garray_T winsizes;
@@ -6207,10 +6337,9 @@ static int open_cmdwin(void)
bool save_exmode = exmode_active;
int save_cmdmsg_rl = cmdmsg_rl;
- /* Can't do this recursively. Can't do it when typing a password. */
+ // Can't do this recursively. Can't do it when typing a password.
if (cmdwin_type != 0
- || cmdline_star > 0
- ) {
+ || cmdline_star > 0) {
beep_flush();
return K_IGNORE;
}
@@ -6272,8 +6401,9 @@ static int open_cmdwin(void)
if (i >= 0) {
lnum = 0;
do {
- if (++i == hislen)
+ if (++i == hislen) {
i = 0;
+ }
if (history[histtype][i].hisstr != NULL) {
ml_append(lnum++, history[histtype][i].hisstr, (colnr_T)0, false);
}
@@ -6341,16 +6471,17 @@ static int open_cmdwin(void)
exmode_active = save_exmode;
- /* Safety check: The old window or buffer was deleted: It's a bug when
- * this happens! */
+ // Safety check: The old window or buffer was deleted: It's a bug when
+ // this happens!
if (!win_valid(old_curwin) || !bufref_valid(&old_curbuf)) {
cmdwin_result = Ctrl_C;
EMSG(_("E199: Active window or buffer deleted"));
} else {
- /* autocmds may abort script processing */
- if (aborting() && cmdwin_result != K_IGNORE)
+ // autocmds may abort script processing
+ if (aborting() && cmdwin_result != K_IGNORE) {
cmdwin_result = Ctrl_C;
- /* Set the new command line from the cmdline buffer. */
+ }
+ // Set the new command line from the cmdline buffer.
xfree(ccline.cmdbuff);
if (cmdwin_result == K_XF1 || cmdwin_result == K_XF2) { // :qa[!] typed
const char *p = (cmdwin_result == K_XF2) ? "qa" : "qa!";
@@ -6367,11 +6498,12 @@ static int open_cmdwin(void)
stuffcharReadbuff(CAR);
}
} else if (cmdwin_result == Ctrl_C) {
- /* :q or :close, don't execute any command
- * and don't modify the cmd window. */
+ // :q or :close, don't execute any command
+ // and don't modify the cmd window.
ccline.cmdbuff = NULL;
- } else
+ } else {
ccline.cmdbuff = vim_strsave(get_cursor_line_ptr());
+ }
if (ccline.cmdbuff == NULL) {
ccline.cmdbuff = vim_strsave((char_u *)"");
ccline.cmdlen = 0;
@@ -6382,8 +6514,9 @@ static int open_cmdwin(void)
ccline.cmdlen = (int)STRLEN(ccline.cmdbuff);
ccline.cmdbufflen = ccline.cmdlen + 1;
ccline.cmdpos = curwin->w_cursor.col;
- if (ccline.cmdpos > ccline.cmdlen)
+ if (ccline.cmdpos > ccline.cmdlen) {
ccline.cmdpos = ccline.cmdlen;
+ }
if (cmdwin_result == K_IGNORE) {
ccline.cmdspos = cmd_screencol(ccline.cmdpos);
redrawcmd();
@@ -6449,13 +6582,12 @@ char *script_get(exarg_T *const eap, size_t *const lenp)
}
const char *const end_pattern = (
- cmd[2] != NUL
+ cmd[2] != NUL
? (const char *)skipwhite((const char_u *)cmd + 2)
: ".");
for (;;) {
- char *const theline = (char *)eap->getline(
- eap->cstack->cs_looplevel > 0 ? -1 :
- NUL, eap->cookie, 0, true);
+ char *const theline = (char *)eap->getline(eap->cstack->cs_looplevel > 0 ? -1 :
+ NUL, eap->cookie, 0, true);
if (theline == NULL || strcmp(end_pattern, theline) == 0) {
xfree(theline);
@@ -6463,7 +6595,7 @@ char *script_get(exarg_T *const eap, size_t *const lenp)
}
if (!eap->skip) {
- ga_concat(&ga, (const char_u *)theline);
+ ga_concat(&ga, theline);
ga_append(&ga, '\n');
}
xfree(theline);
@@ -6497,8 +6629,8 @@ char *script_get(exarg_T *const eap, size_t *const lenp)
///
/// @return Pointer used in next iteration or NULL to indicate that iteration
/// was finished.
-const void *hist_iter(const void *const iter, const uint8_t history_type,
- const bool zero, histentry_T *const hist)
+const void *hist_iter(const void *const iter, const uint8_t history_type, const bool zero,
+ histentry_T *const hist)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(4)
{
*hist = (histentry_T) {
@@ -6509,7 +6641,7 @@ const void *hist_iter(const void *const iter, const uint8_t history_type,
}
histentry_T *const hstart = &(history[history_type][0]);
histentry_T *const hlast = (
- &(history[history_type][hisidx[history_type]]));
+ &(history[history_type][hisidx[history_type]]));
const histentry_T *const hend = &(history[history_type][hislen - 1]);
histentry_T *hiter;
if (iter == NULL) {
@@ -6525,7 +6657,7 @@ const void *hist_iter(const void *const iter, const uint8_t history_type,
} while (hfirst != hlast);
hiter = hfirst;
} else {
- hiter = (histentry_T *) iter;
+ hiter = (histentry_T *)iter;
}
if (hiter == NULL) {
return NULL;
@@ -6538,7 +6670,7 @@ const void *hist_iter(const void *const iter, const uint8_t history_type,
return NULL;
}
hiter++;
- return (const void *) ((hiter > hend) ? hstart : hiter);
+ return (const void *)((hiter > hend) ? hstart : hiter);
}
/// Get array of history items
diff --git a/src/nvim/ex_getln.h b/src/nvim/ex_getln.h
index 3727aa5e62..fe2bf958b5 100644
--- a/src/nvim/ex_getln.h
+++ b/src/nvim/ex_getln.h
@@ -7,7 +7,7 @@
#include "nvim/os/time.h"
#include "nvim/regexp_defs.h"
-/* Values for nextwild() and ExpandOne(). See ExpandOne() for meaning. */
+// Values for nextwild() and ExpandOne(). See ExpandOne() for meaning.
#define WILD_FREE 1
#define WILD_EXPAND_FREE 2
#define WILD_EXPAND_KEEP 3
diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c
index 3038ed3947..0dfd7e1edd 100644
--- a/src/nvim/ex_session.c
+++ b/src/nvim/ex_session.c
@@ -8,13 +8,11 @@
// :mksession
#include <assert.h>
-#include <string.h>
+#include <inttypes.h>
#include <stdbool.h>
#include <stdlib.h>
-#include <inttypes.h>
+#include <string.h>
-#include "nvim/vim.h"
-#include "nvim/globals.h"
#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/cursor.h"
@@ -28,6 +26,7 @@
#include "nvim/fileio.h"
#include "nvim/fold.h"
#include "nvim/getchar.h"
+#include "nvim/globals.h"
#include "nvim/keymap.h"
#include "nvim/misc1.h"
#include "nvim/move.h"
@@ -36,6 +35,7 @@
#include "nvim/os/os.h"
#include "nvim/os/time.h"
#include "nvim/path.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -63,7 +63,7 @@ static int put_view_curpos(FILE *fd, const win_T *wp, char *spaces)
static int ses_winsizes(FILE *fd, int restore_size, win_T *tab_firstwin)
{
int n = 0;
- win_T *wp;
+ win_T *wp;
if (restore_size && (ssop_flags & SSOP_WINSIZE)) {
for (wp = tab_firstwin; wp != NULL; wp = wp->w_next) {
@@ -105,7 +105,7 @@ static int ses_winsizes(FILE *fd, int restore_size, win_T *tab_firstwin)
// Returns FAIL when writing the commands to "fd" fails.
static int ses_win_rec(FILE *fd, frame_T *fr)
{
- frame_T *frc;
+ frame_T *frc;
int count = 0;
if (fr->fr_layout != FR_LEAF) {
@@ -149,7 +149,7 @@ static int ses_win_rec(FILE *fd, frame_T *fr)
// Returns NULL when there none.
static frame_T *ses_skipframe(frame_T *fr)
{
- frame_T *frc;
+ frame_T *frc;
FOR_ALL_FRAMES(frc, fr) {
if (ses_do_frame(frc)) {
@@ -200,11 +200,10 @@ static int ses_do_win(win_T *wp)
/// @param flagp
///
/// @returns FAIL if writing fails.
-static int ses_arglist(FILE *fd, char *cmd, garray_T *gap, int fullname,
- unsigned *flagp)
+static int ses_arglist(FILE *fd, char *cmd, garray_T *gap, int fullname, unsigned *flagp)
{
- char_u *buf = NULL;
- char_u *s;
+ char_u *buf = NULL;
+ char_u *s;
if (fprintf(fd, "%s\n%s\n", cmd, "%argdel") < 0) {
return FAIL;
@@ -297,17 +296,15 @@ static int ses_put_fname(FILE *fd, char_u *name, unsigned *flagp)
return retval;
}
-// Write commands to "fd" to restore the view of a window.
-// Caller must make sure 'scrolloff' is zero.
-static int put_view(
- FILE *fd,
- win_T *wp,
- int add_edit, // add ":edit" command to view
- unsigned *flagp, // vop_flags or ssop_flags
- int current_arg_idx // current argument index of the window, use
-) // -1 if unknown
+/// Write commands to "fd" to restore the view of a window.
+/// Caller must make sure 'scrolloff' is zero.
+///
+/// @param add_edit add ":edit" command to view
+/// @param flagp vop_flags or ssop_flags
+/// @param current_arg_idx current argument index of the window, use -1 if unknown
+static int put_view(FILE *fd, win_T *wp, int add_edit, unsigned *flagp, int current_arg_idx)
{
- win_T *save_curwin;
+ win_T *save_curwin;
int f;
int do_cursor;
int did_next = false;
@@ -348,8 +345,8 @@ static int put_view(
// Load the file.
//
if (wp->w_buffer->b_ffname != NULL
- && (!bt_nofile(wp->w_buffer) || wp->w_buffer->terminal)
- ) {
+ && (!bt_nofile(wp->w_buffer) ||
+ wp->w_buffer->terminal)) {
// Editing a file in this buffer: use ":edit file".
// This may have side effects! (e.g., compressed or network file).
//
@@ -434,8 +431,8 @@ static int put_view(
//
if ((*flagp & SSOP_FOLDS)
&& wp->w_buffer->b_ffname != NULL
- && (bt_normal(wp->w_buffer) || bt_help(wp->w_buffer))
- ) {
+ && (bt_normal(wp->w_buffer) ||
+ bt_help(wp->w_buffer))) {
if (put_folds(fd, wp) == FAIL) {
return FAIL;
}
@@ -453,11 +450,11 @@ static int put_view(
}
} else if (fprintf(fd,
"let s:l = %" PRIdLINENR " - ((%" PRIdLINENR
- " * winheight(0) + %" PRId64 ") / %" PRId64 ")\n",
+ " * winheight(0) + %d) / %d)\n",
wp->w_cursor.lnum,
wp->w_cursor.lnum - wp->w_topline,
- (int64_t)(wp->w_height_inner / 2),
- (int64_t)wp->w_height_inner) < 0) {
+ (wp->w_height_inner / 2),
+ wp->w_height_inner) < 0) {
return FAIL;
}
if (fprintf(fd,
@@ -525,12 +522,12 @@ static int makeopens(FILE *fd, char_u *dirnow)
int only_save_windows = true;
int nr;
int restore_size = true;
- win_T *wp;
- char_u *sname;
- win_T *edited_win = NULL;
+ win_T *wp;
+ char_u *sname;
+ win_T *edited_win = NULL;
int tabnr;
- win_T *tab_firstwin;
- frame_T *tab_topframe;
+ win_T *tab_firstwin;
+ frame_T *tab_topframe;
int cur_arg_idx = 0;
int next_arg_idx = 0;
@@ -658,8 +655,7 @@ static int makeopens(FILE *fd, char_u *dirnow)
if (ses_do_win(wp)
&& wp->w_buffer->b_ffname != NULL
&& !bt_help(wp->w_buffer)
- && !bt_nofile(wp->w_buffer)
- ) {
+ && !bt_nofile(wp->w_buffer)) {
if (need_tabnext && put_line(fd, "tabnext") == FAIL) {
return FAIL;
}
@@ -863,7 +859,7 @@ void ex_loadview(exarg_T *eap)
{
char *fname = get_view_file(*eap->arg);
if (fname != NULL) {
- if (do_source((char_u *)fname, false, DOSO_NONE) == FAIL) {
+ if (do_source(fname, false, DOSO_NONE) == FAIL) {
EMSG2(_(e_notopen), fname);
}
xfree(fname);
@@ -877,12 +873,12 @@ void ex_loadview(exarg_T *eap)
/// - SSOP_SLASH: filenames are written with "/" slash
void ex_mkrc(exarg_T *eap)
{
- FILE *fd;
+ FILE *fd;
int failed = false;
int view_session = false; // :mkview, :mksession
int using_vdir = false; // using 'viewdir'?
char *viewFile = NULL;
- unsigned *flagp;
+ unsigned *flagp;
if (eap->cmdidx == CMD_mksession || eap->cmdidx == CMD_mkview) {
view_session = true;
@@ -967,7 +963,7 @@ void ex_mkrc(exarg_T *eap)
*dirnow = NUL;
}
if (*dirnow != NUL && (ssop_flags & SSOP_SESDIR)) {
- if (vim_chdirfile((char_u *)fname) == OK) {
+ if (vim_chdirfile((char_u *)fname, kCdCauseOther) == OK) {
shorten_fnames(true);
}
} else if (*dirnow != NUL
diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c
index b4f22dbf33..dc73e34111 100644
--- a/src/nvim/extmark.c
+++ b/src/nvim/extmark.c
@@ -29,19 +29,20 @@
// code for redrawing the line with the deleted decoration.
#include <assert.h>
+
#include "nvim/api/vim.h"
-#include "nvim/vim.h"
+#include "nvim/buffer.h"
+#include "nvim/buffer_updates.h"
#include "nvim/charset.h"
-#include "nvim/extmark.h"
#include "nvim/decoration.h"
-#include "nvim/buffer_updates.h"
-#include "nvim/memline.h"
-#include "nvim/pos.h"
+#include "nvim/extmark.h"
#include "nvim/globals.h"
-#include "nvim/map.h"
#include "nvim/lib/kbtree.h"
+#include "nvim/map.h"
+#include "nvim/memline.h"
+#include "nvim/pos.h"
#include "nvim/undo.h"
-#include "nvim/buffer.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "extmark.c.generated.h"
@@ -55,16 +56,16 @@ static ExtmarkNs *buf_ns_ref(buf_T *buf, uint64_t ns_id, bool put) {
/// Create or update an extmark
///
/// must not be used during iteration!
-/// @returns the mark id
-uint64_t extmark_set(buf_T *buf, uint64_t ns_id, uint64_t id,
- int row, colnr_T col, int end_row, colnr_T end_col,
- Decoration *decor, bool right_gravity,
- bool end_right_gravity, ExtmarkOp op)
+/// @returns the internal mark id
+uint64_t extmark_set(buf_T *buf, uint64_t ns_id, uint64_t *idp, int row, colnr_T col, int end_row,
+ colnr_T end_col, Decoration *decor, bool right_gravity, bool end_right_gravity,
+ ExtmarkOp op)
{
ExtmarkNs *ns = buf_ns_ref(buf, ns_id, true);
assert(ns != NULL);
mtpos_t old_pos;
uint64_t mark = 0;
+ uint64_t id = idp ? *idp : 0;
if (id == 0) {
id = ns->free_id++;
@@ -118,7 +119,11 @@ revised:
if (decor) {
decor_redraw(buf, row, end_row > -1 ? end_row : row, decor);
}
- return id;
+
+ if (idp) {
+ *idp = id;
+ }
+ return mark;
}
static bool extmark_setraw(buf_T *buf, uint64_t mark, int row, colnr_T col)
@@ -169,6 +174,10 @@ bool extmark_del(buf_T *buf, uint64_t ns_id, uint64_t id)
decor_free(item.decor);
}
+ if (mark == buf->b_virt_line_mark) {
+ clear_virt_lines(buf, pos.row);
+ }
+
map_del(uint64_t, uint64_t)(ns->map, id);
map_del(uint64_t, ExtmarkItem)(buf->b_extmark_index, mark);
@@ -178,9 +187,7 @@ bool extmark_del(buf_T *buf, uint64_t ns_id, uint64_t id)
// Free extmarks in a ns between lines
// if ns = 0, it means clear all namespaces
-bool extmark_clear(buf_T *buf, uint64_t ns_id,
- int l_row, colnr_T l_col,
- int u_row, colnr_T u_col)
+bool extmark_clear(buf_T *buf, uint64_t ns_id, int l_row, colnr_T l_col, int u_row, colnr_T u_col)
{
if (!map_size(buf->b_extmark_ns)) {
return false;
@@ -229,6 +236,9 @@ bool extmark_clear(buf_T *buf, uint64_t ns_id,
}
uint64_t start_id = mark.id & ~MARKTREE_END_FLAG;
+ if (start_id == buf->b_virt_line_mark) {
+ clear_virt_lines(buf, mark.row);
+ }
ExtmarkItem item = map_get(uint64_t, ExtmarkItem)(buf->b_extmark_index,
start_id);
@@ -281,10 +291,8 @@ bool extmark_clear(buf_T *buf, uint64_t ns_id,
// will be searched to the start, or end
// dir can be set to control the order of the array
// amount = amount of marks to find or -1 for all
-ExtmarkInfoArray extmark_get(buf_T *buf, uint64_t ns_id,
- int l_row, colnr_T l_col,
- int u_row, colnr_T u_col,
- int64_t amount, bool reverse)
+ExtmarkInfoArray extmark_get(buf_T *buf, uint64_t ns_id, int l_row, colnr_T l_col, int u_row,
+ colnr_T u_col, int64_t amount, bool reverse)
{
ExtmarkInfoArray array = KV_INITIAL_VALUE;
MarkTreeIter itr[1];
@@ -394,10 +402,9 @@ void extmark_free_all(buf_T *buf)
// Save info for undo/redo of set marks
-static void u_extmark_set(buf_T *buf, uint64_t mark,
- int row, colnr_T col)
+static void u_extmark_set(buf_T *buf, uint64_t mark, int row, colnr_T col)
{
- u_header_T *uhp = u_force_get_undo_header(buf);
+ u_header_T *uhp = u_force_get_undo_header(buf);
if (!uhp) {
return;
}
@@ -419,11 +426,9 @@ static void u_extmark_set(buf_T *buf, uint64_t mark,
///
/// useful when we cannot simply reverse the operation. This will do nothing on
/// redo, enforces correct position when undo.
-void u_extmark_copy(buf_T *buf,
- int l_row, colnr_T l_col,
- int u_row, colnr_T u_col)
+void u_extmark_copy(buf_T *buf, int l_row, colnr_T l_col, int u_row, colnr_T u_col)
{
- u_header_T *uhp = u_force_get_undo_header(buf);
+ u_header_T *uhp = u_force_get_undo_header(buf);
if (!uhp) {
return;
}
@@ -467,7 +472,6 @@ void extmark_apply_undo(ExtmarkUndoObject undo_info, bool undo)
splice.new_row, splice.new_col, splice.new_byte,
splice.old_row, splice.old_col, splice.old_byte,
kExtmarkNoUndo);
-
} else {
extmark_splice_impl(curbuf,
splice.start_row, splice.start_col, splice.start_byte,
@@ -475,14 +479,14 @@ void extmark_apply_undo(ExtmarkUndoObject undo_info, bool undo)
splice.new_row, splice.new_col, splice.new_byte,
kExtmarkNoUndo);
}
- // kExtmarkSavePos
+ // kExtmarkSavePos
} else if (undo_info.type == kExtmarkSavePos) {
ExtmarkSavePos pos = undo_info.data.savepos;
if (undo) {
if (pos.old_row >= 0) {
extmark_setraw(curbuf, pos.mark, pos.old_row, pos.old_col);
}
- // Redo
+ // Redo
} else {
if (pos.row >= 0) {
extmark_setraw(curbuf, pos.mark, pos.row, pos.col);
@@ -504,15 +508,12 @@ void extmark_apply_undo(ExtmarkUndoObject undo_info, bool undo)
kExtmarkNoUndo);
}
}
+ curbuf->b_virt_line_pos = -1;
}
// Adjust extmark row for inserted/deleted rows (columns stay fixed).
-void extmark_adjust(buf_T *buf,
- linenr_T line1,
- linenr_T line2,
- long amount,
- long amount_after,
+void extmark_adjust(buf_T *buf, linenr_T line1, linenr_T line2, long amount, long amount_after,
ExtmarkOp undo)
{
if (curbuf_splice_pending) {
@@ -537,7 +538,7 @@ void extmark_adjust(buf_T *buf,
}
if (new_row > 0) {
new_byte = ml_find_line_or_offset(buf, line1+new_row, NULL, true)
- - start_byte;
+ - start_byte;
}
extmark_splice_impl(buf,
(int)line1-1, 0, start_byte,
@@ -562,10 +563,8 @@ void extmark_adjust(buf_T *buf,
// the end column of the new region.
// @param new_byte Byte extent of the new region.
// @param undo
-void extmark_splice(buf_T *buf,
- int start_row, colnr_T start_col,
- int old_row, colnr_T old_col, bcount_t old_byte,
- int new_row, colnr_T new_col, bcount_t new_byte,
+void extmark_splice(buf_T *buf, int start_row, colnr_T start_col, int old_row, colnr_T old_col,
+ bcount_t old_byte, int new_row, colnr_T new_col, bcount_t new_byte,
ExtmarkOp undo)
{
long offset = ml_find_line_or_offset(buf, start_row + 1, NULL, true);
@@ -584,13 +583,12 @@ void extmark_splice(buf_T *buf,
undo);
}
-void extmark_splice_impl(buf_T *buf,
- int start_row, colnr_T start_col, bcount_t start_byte,
- int old_row, colnr_T old_col, bcount_t old_byte,
- int new_row, colnr_T new_col, bcount_t new_byte,
- ExtmarkOp undo)
+void extmark_splice_impl(buf_T *buf, int start_row, colnr_T start_col, bcount_t start_byte,
+ int old_row, colnr_T old_col, bcount_t old_byte, int new_row,
+ colnr_T new_col, bcount_t new_byte, ExtmarkOp undo)
{
- curbuf->deleted_bytes2 = 0;
+ buf->deleted_bytes2 = 0;
+ buf->b_virt_line_pos = -1;
buf_updates_send_splice(buf, start_row, start_col, start_byte,
old_row, old_col, old_byte,
new_row, new_col, new_byte);
@@ -612,7 +610,7 @@ void extmark_splice_impl(buf_T *buf,
new_row, new_col);
if (undo == kExtmarkUndo) {
- u_header_T *uhp = u_force_get_undo_header(buf);
+ u_header_T *uhp = u_force_get_undo_header(buf);
if (!uhp) {
return;
}
@@ -621,7 +619,7 @@ void extmark_splice_impl(buf_T *buf,
// TODO(bfredl): this is quite rudimentary. We merge small (within line)
// inserts with each other and small deletes with each other. Add full
// merge algorithm later.
- if (old_row == 0 && new_row == 0 && kv_size(uhp->uh_extmark)) {
+ if (old_row == 0 && new_row == 0 && kv_size(uhp->uh_extmark)) {
ExtmarkUndoObject *item = &kv_A(uhp->uh_extmark,
kv_size(uhp->uh_extmark)-1);
if (item->type == kExtmarkSplice) {
@@ -669,24 +667,20 @@ void extmark_splice_impl(buf_T *buf,
}
}
-void extmark_splice_cols(buf_T *buf,
- int start_row, colnr_T start_col,
- colnr_T old_col, colnr_T new_col,
- ExtmarkOp undo)
+void extmark_splice_cols(buf_T *buf, int start_row, colnr_T start_col, colnr_T old_col,
+ colnr_T new_col, ExtmarkOp undo)
{
extmark_splice(buf, start_row, start_col,
0, old_col, old_col,
0, new_col, new_col, undo);
}
-void extmark_move_region(
- buf_T *buf,
- int start_row, colnr_T start_col, bcount_t start_byte,
- int extent_row, colnr_T extent_col, bcount_t extent_byte,
- int new_row, colnr_T new_col, bcount_t new_byte,
- ExtmarkOp undo)
+void extmark_move_region(buf_T *buf, int start_row, colnr_T start_col, bcount_t start_byte,
+ int extent_row, colnr_T extent_col, bcount_t extent_byte, int new_row,
+ colnr_T new_col, bcount_t new_byte, ExtmarkOp undo)
{
- curbuf->deleted_bytes2 = 0;
+ buf->deleted_bytes2 = 0;
+ buf->b_virt_line_pos = -1;
// TODO(bfredl): this is not synced to the buffer state inside the callback.
// But unless we make the undo implementation smarter, this is not ensured
// anyway.
@@ -704,7 +698,7 @@ void extmark_move_region(
if (undo == kExtmarkUndo) {
- u_header_T *uhp = u_force_get_undo_header(buf);
+ u_header_T *uhp = u_force_get_undo_header(buf);
if (!uhp) {
return;
}
@@ -729,7 +723,7 @@ void extmark_move_region(
uint64_t src2ns(Integer *src_id)
{
if (*src_id == 0) {
- *src_id = (Integer)nvim_create_namespace((String)STRING_INIT);
+ *src_id = nvim_create_namespace((String)STRING_INIT);
}
if (*src_id < 0) {
return UINT64_MAX;
diff --git a/src/nvim/extmark.h b/src/nvim/extmark.h
index 1bc42322a3..aee679a9c7 100644
--- a/src/nvim/extmark.h
+++ b/src/nvim/extmark.h
@@ -1,10 +1,10 @@
#ifndef NVIM_EXTMARK_H
#define NVIM_EXTMARK_H
-#include "nvim/pos.h"
#include "nvim/buffer_defs.h"
#include "nvim/extmark_defs.h"
#include "nvim/marktree.h"
+#include "nvim/pos.h"
EXTERN int extmark_splice_pending INIT(= 0);
diff --git a/src/nvim/extmark_defs.h b/src/nvim/extmark_defs.h
index b5d91382ec..c0a4f4014f 100644
--- a/src/nvim/extmark_defs.h
+++ b/src/nvim/extmark_defs.h
@@ -1,11 +1,21 @@
#ifndef NVIM_EXTMARK_DEFS_H
#define NVIM_EXTMARK_DEFS_H
-#include "nvim/types.h"
#include "nvim/lib/kvec.h"
+#include "nvim/types.h"
typedef struct Decoration Decoration;
+typedef struct {
+ char *text;
+ int hl_id;
+} VirtTextChunk;
+
+typedef kvec_t(VirtTextChunk) VirtText;
+#define VIRTTEXT_EMPTY ((VirtText)KV_INITIAL_VALUE)
+typedef kvec_t(VirtText) VirtLines;
+
+
typedef struct
{
uint64_t ns_id;
diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c
index 8beba38509..fca62353d5 100644
--- a/src/nvim/file_search.c
+++ b/src/nvim/file_search.c
@@ -44,50 +44,51 @@
// functions.
#include <assert.h>
-#include <string.h>
-#include <stdbool.h>
#include <inttypes.h>
#include <limits.h>
+#include <stdbool.h>
+#include <string.h>
-#include "nvim/vim.h"
-#include "nvim/eval.h"
#include "nvim/ascii.h"
-#include "nvim/file_search.h"
#include "nvim/charset.h"
+#include "nvim/eval.h"
+#include "nvim/file_search.h"
#include "nvim/fileio.h"
+#include "nvim/globals.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
#include "nvim/option.h"
+#include "nvim/os/fs_defs.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/strings.h"
#include "nvim/tag.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/os/os.h"
-#include "nvim/os/input.h"
-#include "nvim/os/fs_defs.h"
-static char_u *ff_expand_buffer = NULL; /* used for expanding filenames */
+static char_u *ff_expand_buffer = NULL; // used for expanding filenames
/*
* type for the directory search stack
*/
typedef struct ff_stack {
- struct ff_stack *ffs_prev;
+ struct ff_stack *ffs_prev;
/* the fix part (no wildcards) and the part containing the wildcards
* of the search path
*/
- char_u *ffs_fix_path;
- char_u *ffs_wc_path;
+ char_u *ffs_fix_path;
+ char_u *ffs_wc_path;
/* files/dirs found in the above directory, matched by the first wildcard
* of wc_part
*/
- char_u **ffs_filearray;
+ char_u **ffs_filearray;
int ffs_filearray_size;
- char_u ffs_filearray_cur; /* needed for partly handled dirs */
+ char_u ffs_filearray_cur; // needed for partly handled dirs
/* to store status of partly handled directories
* 0: we work on this directory for the first time
@@ -100,7 +101,7 @@ typedef struct ff_stack {
*/
int ffs_level;
- /* Did we already expand '**' to an empty string? */
+ // Did we already expand '**' to an empty string?
int ffs_star_star_empty;
} ff_stack_T;
@@ -108,19 +109,19 @@ typedef struct ff_stack {
* type for already visited directories or files.
*/
typedef struct ff_visited {
- struct ff_visited *ffv_next;
+ struct ff_visited *ffv_next;
/* Visited directories are different if the wildcard string are
* different. So we have to save it.
*/
- char_u *ffv_wc_path;
+ char_u *ffv_wc_path;
// use FileID for comparison (needed because of links), else use filename.
bool file_id_valid;
FileID file_id;
/* The memory for this struct is allocated according to the length of
* ffv_fname.
*/
- char_u ffv_fname[1]; /* actually longer */
+ char_u ffv_fname[1]; // actually longer
} ff_visited_T;
/*
@@ -138,13 +139,12 @@ typedef struct ff_visited {
* visited lists.
*/
typedef struct ff_visited_list_hdr {
- struct ff_visited_list_hdr *ffvl_next;
-
- /* the filename the attached visited list is for */
- char_u *ffvl_filename;
+ struct ff_visited_list_hdr *ffvl_next;
- ff_visited_T *ffvl_visited_list;
+ // the filename the attached visited list is for
+ char_u *ffvl_filename;
+ ff_visited_T *ffvl_visited_list;
} ff_visited_list_hdr_T;
@@ -156,38 +156,38 @@ typedef struct ff_visited_list_hdr {
/*
* The search context:
- * ffsc_stack_ptr: the stack for the dirs to search
+ * ffsc_stack_ptr: the stack for the dirs to search
* ffsc_visited_list: the currently active visited list
* ffsc_dir_visited_list: the currently active visited list for search dirs
* ffsc_visited_lists_list: the list of all visited lists
* ffsc_dir_visited_lists_list: the list of all visited lists for search dirs
* ffsc_file_to_search: the file to search for
- * ffsc_start_dir: the starting directory, if search path was relative
- * ffsc_fix_path: the fix part of the given path (without wildcards)
- * Needed for upward search.
- * ffsc_wc_path: the part of the given path containing wildcards
- * ffsc_level: how many levels of dirs to search downwards
- * ffsc_stopdirs_v: array of stop directories for upward search
- * ffsc_find_what: FINDFILE_BOTH, FINDFILE_DIR or FINDFILE_FILE
- * ffsc_tagfile: searching for tags file, don't use 'suffixesadd'
+ * ffsc_start_dir: the starting directory, if search path was relative
+ * ffsc_fix_path: the fix part of the given path (without wildcards)
+ * Needed for upward search.
+ * ffsc_wc_path: the part of the given path containing wildcards
+ * ffsc_level: how many levels of dirs to search downwards
+ * ffsc_stopdirs_v: array of stop directories for upward search
+ * ffsc_find_what: FINDFILE_BOTH, FINDFILE_DIR or FINDFILE_FILE
+ * ffsc_tagfile: searching for tags file, don't use 'suffixesadd'
*/
typedef struct ff_search_ctx_T {
- ff_stack_T *ffsc_stack_ptr;
- ff_visited_list_hdr_T *ffsc_visited_list;
- ff_visited_list_hdr_T *ffsc_dir_visited_list;
- ff_visited_list_hdr_T *ffsc_visited_lists_list;
- ff_visited_list_hdr_T *ffsc_dir_visited_lists_list;
- char_u *ffsc_file_to_search;
- char_u *ffsc_start_dir;
- char_u *ffsc_fix_path;
- char_u *ffsc_wc_path;
+ ff_stack_T *ffsc_stack_ptr;
+ ff_visited_list_hdr_T *ffsc_visited_list;
+ ff_visited_list_hdr_T *ffsc_dir_visited_list;
+ ff_visited_list_hdr_T *ffsc_visited_lists_list;
+ ff_visited_list_hdr_T *ffsc_dir_visited_lists_list;
+ char_u *ffsc_file_to_search;
+ char_u *ffsc_start_dir;
+ char_u *ffsc_fix_path;
+ char_u *ffsc_wc_path;
int ffsc_level;
- char_u **ffsc_stopdirs_v;
+ char_u **ffsc_stopdirs_v;
int ffsc_find_what;
int ffsc_tagfile;
} ff_search_ctx_T;
-/* locally needed functions */
+// locally needed functions
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "file_search.c.generated.h"
@@ -195,104 +195,98 @@ typedef struct ff_search_ctx_T {
static char_u e_pathtoolong[] = N_("E854: path too long for completion");
-/*
- * Initialization routine for vim_findfile().
- *
- * Returns the newly allocated search context or NULL if an error occurred.
- *
- * Don't forget to clean up by calling vim_findfile_cleanup() if you are done
- * with the search context.
- *
- * Find the file 'filename' in the directory 'path'.
- * The parameter 'path' may contain wildcards. If so only search 'level'
- * directories deep. The parameter 'level' is the absolute maximum and is
- * not related to restricts given to the '**' wildcard. If 'level' is 100
- * and you use '**200' vim_findfile() will stop after 100 levels.
- *
- * 'filename' cannot contain wildcards! It is used as-is, no backslashes to
- * escape special characters.
- *
- * If 'stopdirs' is not NULL and nothing is found downward, the search is
- * restarted on the next higher directory level. This is repeated until the
- * start-directory of a search is contained in 'stopdirs'. 'stopdirs' has the
- * format ";*<dirname>*\(;<dirname>\)*;\=$".
- *
- * If the 'path' is relative, the starting dir for the search is either VIM's
- * current dir or if the path starts with "./" the current files dir.
- * If the 'path' is absolute, the starting dir is that part of the path before
- * the first wildcard.
- *
- * Upward search is only done on the starting dir.
- *
- * If 'free_visited' is TRUE the list of already visited files/directories is
- * cleared. Set this to FALSE if you just want to search from another
- * directory, but want to be sure that no directory from a previous search is
- * searched again. This is useful if you search for a file at different places.
- * The list of visited files/dirs can also be cleared with the function
- * vim_findfile_free_visited().
- *
- * Set the parameter 'find_what' to FINDFILE_DIR if you want to search for
- * directories only, FINDFILE_FILE for files only, FINDFILE_BOTH for both.
- *
- * A search context returned by a previous call to vim_findfile_init() can be
- * passed in the parameter "search_ctx_arg". This context is reused and
- * reinitialized with the new parameters. The list of already visited
- * directories from this context is only deleted if the parameter
- * "free_visited" is true. Be aware that the passed "search_ctx_arg" is freed
- * if the reinitialization fails.
- *
- * If you don't have a search context from a previous call "search_ctx_arg"
- * must be NULL.
- *
- * This function silently ignores a few errors, vim_findfile() will have
- * limited functionality then.
- */
-void *
-vim_findfile_init (
- char_u *path,
- char_u *filename,
- char_u *stopdirs,
- int level,
- int free_visited,
- int find_what,
- void *search_ctx_arg,
- int tagfile, /* expanding names of tags files */
- char_u *rel_fname /* file name to use for "." */
-)
+/// Initialization routine for vim_findfile().
+///
+/// Returns the newly allocated search context or NULL if an error occurred.
+///
+/// Don't forget to clean up by calling vim_findfile_cleanup() if you are done
+/// with the search context.
+///
+/// Find the file 'filename' in the directory 'path'.
+/// The parameter 'path' may contain wildcards. If so only search 'level'
+/// directories deep. The parameter 'level' is the absolute maximum and is
+/// not related to restricts given to the '**' wildcard. If 'level' is 100
+/// and you use '**200' vim_findfile() will stop after 100 levels.
+///
+/// 'filename' cannot contain wildcards! It is used as-is, no backslashes to
+/// escape special characters.
+///
+/// If 'stopdirs' is not NULL and nothing is found downward, the search is
+/// restarted on the next higher directory level. This is repeated until the
+/// start-directory of a search is contained in 'stopdirs'. 'stopdirs' has the
+/// format ";*<dirname>*\(;<dirname>\)*;\=$".
+///
+/// If the 'path' is relative, the starting dir for the search is either VIM's
+/// current dir or if the path starts with "./" the current files dir.
+/// If the 'path' is absolute, the starting dir is that part of the path before
+/// the first wildcard.
+///
+/// Upward search is only done on the starting dir.
+///
+/// If 'free_visited' is TRUE the list of already visited files/directories is
+/// cleared. Set this to FALSE if you just want to search from another
+/// directory, but want to be sure that no directory from a previous search is
+/// searched again. This is useful if you search for a file at different places.
+/// The list of visited files/dirs can also be cleared with the function
+/// vim_findfile_free_visited().
+///
+/// Set the parameter 'find_what' to FINDFILE_DIR if you want to search for
+/// directories only, FINDFILE_FILE for files only, FINDFILE_BOTH for both.
+///
+/// A search context returned by a previous call to vim_findfile_init() can be
+/// passed in the parameter "search_ctx_arg". This context is reused and
+/// reinitialized with the new parameters. The list of already visited
+/// directories from this context is only deleted if the parameter
+/// "free_visited" is true. Be aware that the passed "search_ctx_arg" is freed
+/// if the reinitialization fails.
+///
+/// If you don't have a search context from a previous call "search_ctx_arg"
+/// must be NULL.
+///
+/// This function silently ignores a few errors, vim_findfile() will have
+/// limited functionality then.
+///
+/// @param tagfile expanding names of tags files
+/// @param rel_fname file name to use for "."
+void *vim_findfile_init(char_u *path, char_u *filename, char_u *stopdirs, int level,
+ int free_visited, int find_what, void *search_ctx_arg, int tagfile,
+ char_u *rel_fname)
{
- char_u *wc_part;
- ff_stack_T *sptr;
- ff_search_ctx_T *search_ctx;
+ char_u *wc_part;
+ ff_stack_T *sptr;
+ ff_search_ctx_T *search_ctx;
/* If a search context is given by the caller, reuse it, else allocate a
* new one.
*/
- if (search_ctx_arg != NULL)
+ if (search_ctx_arg != NULL) {
search_ctx = search_ctx_arg;
- else {
+ } else {
search_ctx = xcalloc(1, sizeof(ff_search_ctx_T));
}
search_ctx->ffsc_find_what = find_what;
search_ctx->ffsc_tagfile = tagfile;
- /* clear the search context, but NOT the visited lists */
+ // clear the search context, but NOT the visited lists
ff_clear(search_ctx);
- /* clear visited list if wanted */
- if (free_visited == TRUE)
+ // clear visited list if wanted
+ if (free_visited == TRUE) {
vim_findfile_free_visited(search_ctx);
- else {
+ } else {
/* Reuse old visited lists. Get the visited list for the given
* filename. If no list for the current filename exists, creates a new
* one. */
search_ctx->ffsc_visited_list = ff_get_visited_list(filename,
- &search_ctx->ffsc_visited_lists_list);
- if (search_ctx->ffsc_visited_list == NULL)
+ &search_ctx->ffsc_visited_lists_list);
+ if (search_ctx->ffsc_visited_list == NULL) {
goto error_return;
+ }
search_ctx->ffsc_dir_visited_list = ff_get_visited_list(filename,
- &search_ctx->ffsc_dir_visited_lists_list);
- if (search_ctx->ffsc_dir_visited_list == NULL)
+ &search_ctx->ffsc_dir_visited_lists_list);
+ if (search_ctx->ffsc_dir_visited_list == NULL) {
goto error_return;
+ }
}
if (ff_expand_buffer == NULL) {
@@ -308,16 +302,18 @@ vim_findfile_init (
size_t len = (size_t)(path_tail(rel_fname) - rel_fname);
if (!vim_isAbsName(rel_fname) && len + 1 < MAXPATHL) {
- /* Make the start dir an absolute path name. */
+ // Make the start dir an absolute path name.
STRLCPY(ff_expand_buffer, rel_fname, len + 1);
search_ctx->ffsc_start_dir = (char_u *)FullName_save((char *)ff_expand_buffer, FALSE);
- } else
+ } else {
search_ctx->ffsc_start_dir = vim_strnsave(rel_fname, len);
- if (*++path != NUL)
+ }
+ if (*++path != NUL) {
++path;
+ }
} else if (*path == NUL || !vim_isAbsName(path)) {
#ifdef BACKSLASH_IN_FILENAME
- /* "c:dir" needs "c:" to be expanded, otherwise use current dir */
+ // "c:dir" needs "c:" to be expanded, otherwise use current dir
if (*path != NUL && path[1] == ':') {
char_u drive[3];
@@ -332,8 +328,9 @@ vim_findfile_init (
path += 2;
} else
#endif
- if (os_dirname(ff_expand_buffer, MAXPATHL) == FAIL)
+ if (os_dirname(ff_expand_buffer, MAXPATHL) == FAIL) {
goto error_return;
+ }
search_ctx->ffsc_start_dir = vim_strsave(ff_expand_buffer);
@@ -342,8 +339,9 @@ vim_findfile_init (
* directory (but not for "//machine/dir"). Only use the drive name. */
if ((*path == '/' || *path == '\\')
&& path[1] != path[0]
- && search_ctx->ffsc_start_dir[1] == ':')
+ && search_ctx->ffsc_start_dir[1] == ':') {
search_ctx->ffsc_start_dir[2] = NUL;
+ }
#endif
}
@@ -357,21 +355,22 @@ vim_findfile_init (
* ff_path_in_stoplist() for details.
*/
if (stopdirs != NULL) {
- char_u *walker = stopdirs;
+ char_u *walker = stopdirs;
- while (*walker == ';')
+ while (*walker == ';') {
walker++;
+ }
size_t dircount = 1;
search_ctx->ffsc_stopdirs_v = xmalloc(sizeof(char_u *));
do {
- char_u *helper;
- void *ptr;
+ char_u *helper;
+ void *ptr;
helper = walker;
ptr = xrealloc(search_ctx->ffsc_stopdirs_v,
- (dircount + 1) * sizeof(char_u *));
+ (dircount + 1) * sizeof(char_u *));
search_ctx->ffsc_stopdirs_v = ptr;
walker = vim_strchr(walker, ';');
if (walker) {
@@ -379,15 +378,15 @@ vim_findfile_init (
search_ctx->ffsc_stopdirs_v[dircount-1] =
vim_strnsave(helper, (size_t)(walker - helper));
walker++;
- } else
+ } else {
/* this might be "", which means ascent till top
* of directory tree.
*/
search_ctx->ffsc_stopdirs_v[dircount-1] =
vim_strsave(helper);
+ }
dircount++;
-
} while (walker != NULL);
search_ctx->ffsc_stopdirs_v[dircount-1] = NULL;
}
@@ -402,9 +401,9 @@ vim_findfile_init (
if (wc_part != NULL) {
int64_t llevel;
int len;
- char *errpt;
+ char *errpt;
- /* save the fix part of the path */
+ // save the fix part of the path
assert(wc_part - path >= 0);
search_ctx->ffsc_fix_path = vim_strnsave(path, (size_t)(wc_part - path));
@@ -428,27 +427,30 @@ vim_findfile_init (
ff_expand_buffer[len++] = *wc_part++;
llevel = strtol((char *)wc_part, &errpt, 10);
- if ((char_u *)errpt != wc_part && llevel > 0 && llevel < 255)
+ if ((char_u *)errpt != wc_part && llevel > 0 && llevel < 255) {
ff_expand_buffer[len++] = (char_u)llevel;
- else if ((char_u *)errpt != wc_part && llevel == 0)
- /* restrict is 0 -> remove already added '**' */
+ } else if ((char_u *)errpt != wc_part && llevel == 0) {
+ // restrict is 0 -> remove already added '**'
len -= 2;
- else
+ } else {
ff_expand_buffer[len++] = FF_MAX_STAR_STAR_EXPAND;
+ }
wc_part = (char_u *)errpt;
if (*wc_part != NUL && !vim_ispathsep(*wc_part)) {
EMSG2(_(
- "E343: Invalid path: '**[number]' must be at the end of the path or be followed by '%s'."),
- PATHSEPSTR);
+ "E343: Invalid path: '**[number]' must be at the end of the path or be followed by '%s'."),
+ PATHSEPSTR);
goto error_return;
}
- } else
+ } else {
ff_expand_buffer[len++] = *wc_part++;
+ }
}
ff_expand_buffer[len] = NUL;
search_ctx->ffsc_wc_path = vim_strsave(ff_expand_buffer);
- } else
+ } else {
search_ctx->ffsc_fix_path = vim_strsave(path);
+ }
if (search_ctx->ffsc_start_dir == NULL) {
/* store the fix part as startdir.
@@ -458,7 +460,7 @@ vim_findfile_init (
search_ctx->ffsc_fix_path[0] = NUL;
}
- /* create an absolute path */
+ // create an absolute path
if (STRLEN(search_ctx->ffsc_start_dir)
+ STRLEN(search_ctx->ffsc_fix_path) + 3 >= MAXPATHL) {
EMSG(_(e_pathtoolong));
@@ -505,8 +507,8 @@ vim_findfile_init (
}
sptr = ff_create_stack_element(ff_expand_buffer,
- search_ctx->ffsc_wc_path,
- level, 0);
+ search_ctx->ffsc_wc_path,
+ level, 0);
ff_push(search_ctx, sptr);
search_ctx->ffsc_file_to_search = vim_strsave(filename);
@@ -527,7 +529,7 @@ error_return:
*/
char_u *vim_findfile_stopdir(char_u *buf)
{
- char_u *r_ptr = buf;
+ char_u *r_ptr = buf;
while (*r_ptr != NUL && *r_ptr != ';') {
if (r_ptr[0] == '\\' && r_ptr[1] == ';') {
@@ -541,8 +543,9 @@ char_u *vim_findfile_stopdir(char_u *buf)
if (*r_ptr == ';') {
*r_ptr = 0;
r_ptr++;
- } else if (*r_ptr == NUL)
+ } else if (*r_ptr == NUL) {
r_ptr = NULL;
+ }
return r_ptr;
}
@@ -551,8 +554,9 @@ char_u *vim_findfile_stopdir(char_u *buf)
*/
void vim_findfile_cleanup(void *ctx)
{
- if (ctx == NULL)
+ if (ctx == NULL) {
return;
+ }
vim_findfile_free_visited(ctx);
ff_clear(ctx);
@@ -573,17 +577,18 @@ void vim_findfile_cleanup(void *ctx)
*/
char_u *vim_findfile(void *search_ctx_arg)
{
- char_u *file_path;
- char_u *rest_of_wildcards;
- char_u *path_end = NULL;
- ff_stack_T *stackp = NULL;
+ char_u *file_path;
+ char_u *rest_of_wildcards;
+ char_u *path_end = NULL;
+ ff_stack_T *stackp = NULL;
size_t len;
- char_u *p;
- char_u *suf;
+ char_u *p;
+ char_u *suf;
ff_search_ctx_T *search_ctx;
- if (search_ctx_arg == NULL)
+ if (search_ctx_arg == NULL) {
return NULL;
+ }
search_ctx = (ff_search_ctx_T *)search_ctx_arg;
@@ -593,24 +598,27 @@ char_u *vim_findfile(void *search_ctx_arg)
*/
file_path = xmalloc(MAXPATHL);
- /* store the end of the start dir -- needed for upward search */
- if (search_ctx->ffsc_start_dir != NULL)
+ // store the end of the start dir -- needed for upward search
+ if (search_ctx->ffsc_start_dir != NULL) {
path_end = &search_ctx->ffsc_start_dir[
- STRLEN(search_ctx->ffsc_start_dir)];
+ STRLEN(search_ctx->ffsc_start_dir)];
+ }
- /* upward search loop */
+ // upward search loop
for (;; ) {
- /* downward search loop */
+ // downward search loop
for (;; ) {
- /* check if user user wants to stop the search*/
+ // check if user user wants to stop the search
os_breakcheck();
- if (got_int)
+ if (got_int) {
break;
+ }
- /* get directory to work on from stack */
+ // get directory to work on from stack
stackp = ff_pop(search_ctx);
- if (stackp == NULL)
+ if (stackp == NULL) {
break;
+ }
/*
* TODO: decide if we leave this test in
@@ -633,10 +641,10 @@ char_u *vim_findfile(void *search_ctx_arg)
*/
if (stackp->ffs_filearray == NULL
&& ff_check_visited(&search_ctx->ffsc_dir_visited_list
- ->ffvl_visited_list,
- stackp->ffs_fix_path
- , stackp->ffs_wc_path
- ) == FAIL) {
+ ->ffvl_visited_list,
+ stackp->ffs_fix_path,
+ stackp->ffs_wc_path
+ ) == FAIL) {
#ifdef FF_VERBOSE
if (p_verbose >= 5) {
verbose_enter_scroll();
@@ -659,7 +667,7 @@ char_u *vim_findfile(void *search_ctx_arg)
}
#endif
- /* check depth */
+ // check depth
if (stackp->ffs_level <= 0) {
ff_free_stack_element(stackp);
continue;
@@ -725,13 +733,14 @@ char_u *vim_findfile(void *search_ctx_arg)
}
if (*p == 0) {
- /* remove '**<numb> from wildcards */
+ // remove '**<numb> from wildcards
STRMOVE(rest_of_wildcards, rest_of_wildcards + 3);
- } else
+ } else {
rest_of_wildcards += 3;
+ }
if (stackp->ffs_star_star_empty == 0) {
- /* if not done before, expand '**' to empty */
+ // if not done before, expand '**' to empty
stackp->ffs_star_star_empty = 1;
dirptrs[1] = stackp->ffs_fix_path;
}
@@ -754,8 +763,9 @@ char_u *vim_findfile(void *search_ctx_arg)
}
file_path[len] = NUL;
- if (vim_ispathsep(*rest_of_wildcards))
+ if (vim_ispathsep(*rest_of_wildcards)) {
rest_of_wildcards++;
+ }
}
/*
@@ -766,23 +776,25 @@ char_u *vim_findfile(void *search_ctx_arg)
stackp->ffs_filearray = xmalloc(sizeof(char *));
stackp->ffs_filearray[0] = vim_strsave(dirptrs[0]);
stackp->ffs_filearray_size = 1;
- } else
+ } else {
/* Add EW_NOTWILD because the expanded path may contain
* wildcard characters that are to be taken literally.
* This is a bit of a hack. */
expand_wildcards((dirptrs[1] == NULL) ? 1 : 2, dirptrs,
- &stackp->ffs_filearray_size,
- &stackp->ffs_filearray,
- EW_DIR|EW_ADDSLASH|EW_SILENT|EW_NOTWILD);
+ &stackp->ffs_filearray_size,
+ &stackp->ffs_filearray,
+ EW_DIR|EW_ADDSLASH|EW_SILENT|EW_NOTWILD);
+ }
stackp->ffs_filearray_cur = 0;
stackp->ffs_stage = 0;
- } else
+ } else {
rest_of_wildcards = &stackp->ffs_wc_path[
- STRLEN(stackp->ffs_wc_path)];
+ STRLEN(stackp->ffs_wc_path)];
+ }
if (stackp->ffs_stage == 0) {
- /* this is the first time we work on this directory */
+ // this is the first time we work on this directory
if (*rest_of_wildcards == NUL) {
/*
* We don't have further wildcards to expand, so we have to
@@ -791,9 +803,9 @@ char_u *vim_findfile(void *search_ctx_arg)
for (int i = stackp->ffs_filearray_cur;
i < stackp->ffs_filearray_size; ++i) {
if (!path_with_url((char *)stackp->ffs_filearray[i])
- && !os_isdir(stackp->ffs_filearray[i]))
- continue; /* not a directory */
-
+ && !os_isdir(stackp->ffs_filearray[i])) {
+ continue; // not a directory
+ }
// prepare the filename to be checked for existence below
if (STRLEN(stackp->ffs_filearray[i]) + 1
+ STRLEN(search_ctx->ffsc_file_to_search) >= MAXPATHL) {
@@ -812,12 +824,13 @@ char_u *vim_findfile(void *search_ctx_arg)
* from 'suffixesadd'.
*/
len = STRLEN(file_path);
- if (search_ctx->ffsc_tagfile)
+ if (search_ctx->ffsc_tagfile) {
suf = (char_u *)"";
- else
+ } else {
suf = curbuf->b_p_sua;
+ }
for (;; ) {
- /* if file exists and we didn't already find it */
+ // if file exists and we didn't already find it
if ((path_with_url((char *)file_path)
|| (os_path_exists(file_path)
&& (search_ctx->ffsc_find_what
@@ -826,19 +839,17 @@ char_u *vim_findfile(void *search_ctx_arg)
== FINDFILE_DIR)
== os_isdir(file_path)))))
#ifndef FF_VERBOSE
- && (ff_check_visited(
- &search_ctx->ffsc_visited_list->ffvl_visited_list,
- file_path
- , (char_u *)""
- ) == OK)
+ && (ff_check_visited(&search_ctx->ffsc_visited_list->ffvl_visited_list,
+ file_path,
+ (char_u *)""
+ ) == OK)
#endif
) {
#ifdef FF_VERBOSE
- if (ff_check_visited(
- &search_ctx->ffsc_visited_list->ffvl_visited_list,
- file_path
- , (char_u *)""
- ) == FAIL) {
+ if (ff_check_visited(&search_ctx->ffsc_visited_list->ffvl_visited_list,
+ file_path,
+ (char_u *)""
+ ) == FAIL) {
if (p_verbose >= 5) {
verbose_enter_scroll();
smsg("Already: %s", file_path);
@@ -849,19 +860,21 @@ char_u *vim_findfile(void *search_ctx_arg)
}
#endif
- /* push dir to examine rest of subdirs later */
+ // push dir to examine rest of subdirs later
assert(i < UCHAR_MAX - 1);
stackp->ffs_filearray_cur = (char_u)(i + 1);
ff_push(search_ctx, stackp);
- if (!path_with_url((char *)file_path))
+ if (!path_with_url((char *)file_path)) {
simplify_filename(file_path);
+ }
if (os_dirname(ff_expand_buffer, MAXPATHL)
== OK) {
p = path_shorten_fname(file_path,
- ff_expand_buffer);
- if (p != NULL)
+ ff_expand_buffer);
+ if (p != NULL) {
STRMOVE(file_path, p);
+ }
}
#ifdef FF_VERBOSE
if (p_verbose >= 5) {
@@ -874,12 +887,13 @@ char_u *vim_findfile(void *search_ctx_arg)
return file_path;
}
- /* Not found or found already, try next suffix. */
- if (*suf == NUL)
+ // Not found or found already, try next suffix.
+ if (*suf == NUL) {
break;
+ }
assert(MAXPATHL >= len);
copy_option_part(&suf, file_path + len,
- MAXPATHL - len, ",");
+ MAXPATHL - len, ",");
}
}
} else {
@@ -889,14 +903,13 @@ char_u *vim_findfile(void *search_ctx_arg)
*/
for (int i = stackp->ffs_filearray_cur;
i < stackp->ffs_filearray_size; ++i) {
- if (!os_isdir(stackp->ffs_filearray[i]))
- continue; /* not a directory */
-
+ if (!os_isdir(stackp->ffs_filearray[i])) {
+ continue; // not a directory
+ }
ff_push(search_ctx,
- ff_create_stack_element(
- stackp->ffs_filearray[i],
- rest_of_wildcards,
- stackp->ffs_level - 1, 0));
+ ff_create_stack_element(stackp->ffs_filearray[i],
+ rest_of_wildcards,
+ stackp->ffs_level - 1, 0));
}
}
stackp->ffs_filearray_cur = 0;
@@ -911,19 +924,20 @@ char_u *vim_findfile(void *search_ctx_arg)
for (int i = stackp->ffs_filearray_cur;
i < stackp->ffs_filearray_size; ++i) {
if (fnamecmp(stackp->ffs_filearray[i],
- stackp->ffs_fix_path) == 0)
- continue; /* don't repush same directory */
- if (!os_isdir(stackp->ffs_filearray[i]))
- continue; /* not a directory */
+ stackp->ffs_fix_path) == 0) {
+ continue; // don't repush same directory
+ }
+ if (!os_isdir(stackp->ffs_filearray[i])) {
+ continue; // not a directory
+ }
ff_push(search_ctx,
- ff_create_stack_element(stackp->ffs_filearray[i],
- stackp->ffs_wc_path, stackp->ffs_level - 1, 1));
+ ff_create_stack_element(stackp->ffs_filearray[i],
+ stackp->ffs_wc_path, stackp->ffs_level - 1, 1));
}
}
- /* we are done with the current directory */
+ // we are done with the current directory
ff_free_stack_element(stackp);
-
}
/* If we reached this, we didn't find anything downwards.
@@ -931,26 +945,30 @@ char_u *vim_findfile(void *search_ctx_arg)
*/
if (search_ctx->ffsc_start_dir
&& search_ctx->ffsc_stopdirs_v != NULL && !got_int) {
- ff_stack_T *sptr;
+ ff_stack_T *sptr;
- /* is the last starting directory in the stop list? */
+ // is the last starting directory in the stop list?
if (ff_path_in_stoplist(search_ctx->ffsc_start_dir,
- (int)(path_end - search_ctx->ffsc_start_dir),
- search_ctx->ffsc_stopdirs_v) == TRUE)
+ (int)(path_end - search_ctx->ffsc_start_dir),
+ search_ctx->ffsc_stopdirs_v) == TRUE) {
break;
+ }
- /* cut of last dir */
+ // cut of last dir
while (path_end > search_ctx->ffsc_start_dir
- && vim_ispathsep(*path_end))
+ && vim_ispathsep(*path_end)) {
path_end--;
+ }
while (path_end > search_ctx->ffsc_start_dir
- && !vim_ispathsep(path_end[-1]))
+ && !vim_ispathsep(path_end[-1])) {
path_end--;
+ }
*path_end = 0;
path_end--;
- if (*search_ctx->ffsc_start_dir == 0)
+ if (*search_ctx->ffsc_start_dir == 0) {
break;
+ }
if (STRLEN(search_ctx->ffsc_start_dir) + 1
+ STRLEN(search_ctx->ffsc_fix_path) >= MAXPATHL) {
@@ -962,12 +980,13 @@ char_u *vim_findfile(void *search_ctx_arg)
}
STRCAT(file_path, search_ctx->ffsc_fix_path);
- /* create a new stack entry */
+ // create a new stack entry
sptr = ff_create_stack_element(file_path,
- search_ctx->ffsc_wc_path, search_ctx->ffsc_level, 0);
+ search_ctx->ffsc_wc_path, search_ctx->ffsc_level, 0);
ff_push(search_ctx, sptr);
- } else
+ } else {
break;
+ }
}
fail:
@@ -983,8 +1002,9 @@ void vim_findfile_free_visited(void *search_ctx_arg)
{
ff_search_ctx_T *search_ctx;
- if (search_ctx_arg == NULL)
+ if (search_ctx_arg == NULL) {
return;
+ }
search_ctx = (ff_search_ctx_T *)search_ctx_arg;
vim_findfile_free_visited_list(&search_ctx->ffsc_visited_lists_list);
@@ -1023,11 +1043,12 @@ static void ff_free_visited_list(ff_visited_T *vl)
* Returns the already visited list for the given filename. If none is found it
* allocates a new one.
*/
-static ff_visited_list_hdr_T *ff_get_visited_list(char_u *filename, ff_visited_list_hdr_T **list_headp)
+static ff_visited_list_hdr_T *ff_get_visited_list(char_u *filename,
+ ff_visited_list_hdr_T **list_headp)
{
- ff_visited_list_hdr_T *retptr = NULL;
+ ff_visited_list_hdr_T *retptr = NULL;
- /* check if a visited list for the given filename exists */
+ // check if a visited list for the given filename exists
if (*list_headp != NULL) {
retptr = *list_headp;
while (retptr != NULL) {
@@ -1115,7 +1136,7 @@ static bool ff_wc_equal(char_u *s1, char_u *s2)
*/
static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u *wc_path)
{
- ff_visited_T *vp;
+ ff_visited_T *vp;
bool url = false;
FileID file_id;
@@ -1131,7 +1152,7 @@ static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u *
}
}
- /* check against list of already visited files */
+ // check against list of already visited files
for (vp = *visited_list; vp != NULL; vp = vp->ffv_next) {
if ((url && fnamecmp(vp->ffv_fname, ff_expand_buffer) == 0)
|| (!url && vp->file_id_valid
@@ -1158,10 +1179,11 @@ static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u *
STRCPY(vp->ffv_fname, ff_expand_buffer);
}
- if (wc_path != NULL)
+ if (wc_path != NULL) {
vp->ffv_wc_path = vim_strsave(wc_path);
- else
+ } else {
vp->ffv_wc_path = NULL;
+ }
vp->ffv_next = *visited_list;
*visited_list = vp;
@@ -1172,7 +1194,8 @@ static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u *
/*
* create stack element from given path pieces
*/
-static ff_stack_T *ff_create_stack_element(char_u *fix_part, char_u *wc_part, int level, int star_star_empty)
+static ff_stack_T *ff_create_stack_element(char_u *fix_part, char_u *wc_part, int level,
+ int star_star_empty)
{
ff_stack_T *new = xmalloc(sizeof(ff_stack_T));
@@ -1184,13 +1207,15 @@ static ff_stack_T *ff_create_stack_element(char_u *fix_part, char_u *wc_part, in
new->ffs_level = level;
new->ffs_star_star_empty = star_star_empty;
- /* the following saves NULL pointer checks in vim_findfile */
- if (fix_part == NULL)
+ // the following saves NULL pointer checks in vim_findfile
+ if (fix_part == NULL) {
fix_part = (char_u *)"";
+ }
new->ffs_fix_path = vim_strsave(fix_part);
- if (wc_part == NULL)
+ if (wc_part == NULL) {
wc_part = (char_u *)"";
+ }
new->ffs_wc_path = vim_strsave(wc_part);
return new;
@@ -1215,11 +1240,12 @@ static void ff_push(ff_search_ctx_T *search_ctx, ff_stack_T *stack_ptr)
*/
static ff_stack_T *ff_pop(ff_search_ctx_T *search_ctx)
{
- ff_stack_T *sptr;
+ ff_stack_T *sptr;
sptr = search_ctx->ffsc_stack_ptr;
- if (search_ctx->ffsc_stack_ptr != NULL)
+ if (search_ctx->ffsc_stack_ptr != NULL) {
search_ctx->ffsc_stack_ptr = search_ctx->ffsc_stack_ptr->ffs_prev;
+ }
return sptr;
}
@@ -1249,11 +1275,12 @@ static void ff_free_stack_element(ff_stack_T *const stack_ptr)
*/
static void ff_clear(ff_search_ctx_T *search_ctx)
{
- ff_stack_T *sptr;
+ ff_stack_T *sptr;
- /* clear up stack */
- while ((sptr = ff_pop(search_ctx)) != NULL)
+ // clear up stack
+ while ((sptr = ff_pop(search_ctx)) != NULL) {
ff_free_stack_element(sptr);
+ }
xfree(search_ctx->ffsc_file_to_search);
xfree(search_ctx->ffsc_start_dir);
@@ -1271,7 +1298,7 @@ static void ff_clear(ff_search_ctx_T *search_ctx)
}
search_ctx->ffsc_stopdirs_v = NULL;
- /* reset everything */
+ // reset everything
search_ctx->ffsc_file_to_search = NULL;
search_ctx->ffsc_start_dir = NULL;
search_ctx->ffsc_fix_path = NULL;
@@ -1287,13 +1314,15 @@ static int ff_path_in_stoplist(char_u *path, int path_len, char_u **stopdirs_v)
{
int i = 0;
- /* eat up trailing path separators, except the first */
- while (path_len > 1 && vim_ispathsep(path[path_len - 1]))
+ // eat up trailing path separators, except the first
+ while (path_len > 1 && vim_ispathsep(path[path_len - 1])) {
path_len--;
+ }
- /* if no path consider it as match */
- if (path_len == 0)
+ // if no path consider it as match
+ if (path_len == 0) {
return TRUE;
+ }
for (i = 0; stopdirs_v[i] != NULL; i++) {
if ((int)STRLEN(stopdirs_v[i]) > path_len) {
@@ -1302,49 +1331,46 @@ static int ff_path_in_stoplist(char_u *path, int path_len, char_u **stopdirs_v)
* '/home/r' would also match '/home/rks'
*/
if (fnamencmp(stopdirs_v[i], path, path_len) == 0
- && vim_ispathsep(stopdirs_v[i][path_len]))
+ && vim_ispathsep(stopdirs_v[i][path_len])) {
return TRUE;
+ }
} else {
- if (fnamecmp(stopdirs_v[i], path) == 0)
+ if (fnamecmp(stopdirs_v[i], path) == 0) {
return TRUE;
+ }
}
}
return FALSE;
}
-/*
- * Find the file name "ptr[len]" in the path. Also finds directory names.
- *
- * On the first call set the parameter 'first' to TRUE to initialize
- * the search. For repeating calls to FALSE.
- *
- * Repeating calls will return other files called 'ptr[len]' from the path.
- *
- * Only on the first call 'ptr' and 'len' are used. For repeating calls they
- * don't need valid values.
- *
- * If nothing found on the first call the option FNAME_MESS will issue the
- * message:
- * 'Can't find file "<file>" in path'
- * On repeating calls:
- * 'No more file "<file>" found in path'
- *
- * options:
- * FNAME_MESS give error message when not found
- *
- * Uses NameBuff[]!
- *
- * Returns an allocated string for the file name. NULL for error.
- *
- */
-char_u *
-find_file_in_path (
- char_u *ptr, /* file name */
- size_t len, /* length of file name */
- int options,
- int first, /* use count'th matching file name */
- char_u *rel_fname /* file name searching relative to */
-)
+/// Find the file name "ptr[len]" in the path. Also finds directory names.
+///
+/// On the first call set the parameter 'first' to TRUE to initialize
+/// the search. For repeating calls to FALSE.
+///
+/// Repeating calls will return other files called 'ptr[len]' from the path.
+///
+/// Only on the first call 'ptr' and 'len' are used. For repeating calls they
+/// don't need valid values.
+///
+/// If nothing found on the first call the option FNAME_MESS will issue the
+/// message:
+/// 'Can't find file "<file>" in path'
+/// On repeating calls:
+/// 'No more file "<file>" found in path'
+///
+/// options:
+/// FNAME_MESS give error message when not found
+///
+/// Uses NameBuff[]!
+///
+/// @param ptr file name
+/// @param len length of file name
+/// @param first use count'th matching file name
+/// @param rel_fname file name searching relative to
+///
+/// @return an allocated string for the file name. NULL for error.
+char_u *find_file_in_path(char_u *ptr, size_t len, int options, int first, char_u *rel_fname)
{
return find_file_in_path_option(ptr, len, options, first,
(*curbuf->b_p_path == NUL
@@ -1353,8 +1379,8 @@ find_file_in_path (
FINDFILE_BOTH, rel_fname, curbuf->b_p_sua);
}
-static char_u *ff_file_to_find = NULL;
-static void *fdip_search_ctx = NULL;
+static char_u *ff_file_to_find = NULL;
+static void *fdip_search_ctx = NULL;
#if defined(EXITFREE)
void free_findfile(void)
@@ -1366,46 +1392,41 @@ void free_findfile(void)
#endif
-/*
- * Find the directory name "ptr[len]" in the path.
- *
- * options:
- * FNAME_MESS give error message when not found
- * FNAME_UNESC unescape backslashes
- *
- * Uses NameBuff[]!
- *
- * Returns an allocated string for the file name. NULL for error.
- */
-char_u *
-find_directory_in_path (
- char_u *ptr, /* file name */
- size_t len, /* length of file name */
- int options,
- char_u *rel_fname /* file name searching relative to */
-)
+/// Find the directory name "ptr[len]" in the path.
+///
+/// options:
+/// FNAME_MESS give error message when not found
+/// FNAME_UNESC unescape backslashes
+///
+/// Uses NameBuff[]!
+///
+/// @param ptr file name
+/// @param len length of file name
+/// @param rel_fname file name searching relative to
+///
+/// @return an allocated string for the file name. NULL for error.
+char_u *find_directory_in_path(char_u *ptr, size_t len, int options, char_u *rel_fname)
{
return find_file_in_path_option(ptr, len, options, TRUE, p_cdpath,
FINDFILE_DIR, rel_fname, (char_u *)"");
}
-char_u *
-find_file_in_path_option (
- char_u *ptr, /* file name */
- size_t len, /* length of file name */
- int options,
- int first, /* use count'th matching file name */
- char_u *path_option, /* p_path or p_cdpath */
- int find_what, /* FINDFILE_FILE, _DIR or _BOTH */
- char_u *rel_fname, /* file name we are looking relative to. */
- char_u *suffixes /* list of suffixes, 'suffixesadd' option */
-)
+/// @param ptr file name
+/// @param len length of file name
+/// @param first use count'th matching file name
+/// @param path_option p_path or p_cdpath
+/// @param find_what FINDFILE_FILE, _DIR or _BOTH
+/// @param rel_fname file name we are looking relative to.
+/// @param suffixes list of suffixes, 'suffixesadd' option
+char_u *find_file_in_path_option(char_u *ptr, size_t len, int options, int first,
+ char_u *path_option, int find_what, char_u *rel_fname,
+ char_u *suffixes)
{
- static char_u *dir;
+ static char_u *dir;
static int did_findfile_init = FALSE;
char_u save_char;
- char_u *file_name = NULL;
- char_u *buf = NULL;
+ char_u *file_name = NULL;
+ char_u *buf = NULL;
int rel_to_curdir;
if (rel_fname != NULL && path_with_url((const char *)rel_fname)) {
@@ -1414,7 +1435,7 @@ find_file_in_path_option (
}
if (first == TRUE) {
- /* copy file name into NameBuff, expanding environment variables */
+ // copy file name into NameBuff, expanding environment variables
save_char = ptr[len];
ptr[len] = NUL;
expand_env_esc(ptr, NameBuff, MAXPATHL, false, true, NULL);
@@ -1485,11 +1506,12 @@ find_file_in_path_option (
&& (find_what == FINDFILE_BOTH
|| ((find_what == FINDFILE_DIR)
== os_isdir(NameBuff))))) {
- file_name = vim_strsave(NameBuff);
- goto theend;
+ file_name = vim_strsave(NameBuff);
+ goto theend;
}
- if (*buf == NUL)
+ if (*buf == NUL) {
break;
+ }
assert(MAXPATHL >= l);
copy_option_part(&buf, NameBuff + l, MAXPATHL - l, ",");
}
@@ -1502,7 +1524,7 @@ find_file_in_path_option (
* Otherwise continue to find the next match.
*/
if (first == TRUE) {
- /* vim_findfile_free_visited can handle a possible NULL pointer */
+ // vim_findfile_free_visited can handle a possible NULL pointer
vim_findfile_free_visited(fdip_search_ctx);
dir = path_option;
did_findfile_init = FALSE;
@@ -1511,12 +1533,13 @@ find_file_in_path_option (
for (;; ) {
if (did_findfile_init) {
file_name = vim_findfile(fdip_search_ctx);
- if (file_name != NULL)
+ if (file_name != NULL) {
break;
+ }
did_findfile_init = FALSE;
} else {
- char_u *r_ptr;
+ char_u *r_ptr;
if (dir == NULL || *dir == NUL) {
/* We searched all paths of the option, now we can
@@ -1528,36 +1551,39 @@ find_file_in_path_option (
buf = xmalloc(MAXPATHL);
- /* copy next path */
+ // copy next path
buf[0] = 0;
copy_option_part(&dir, buf, MAXPATHL, " ,");
- /* get the stopdir string */
+ // get the stopdir string
r_ptr = vim_findfile_stopdir(buf);
fdip_search_ctx = vim_findfile_init(buf, ff_file_to_find,
- r_ptr, 100, FALSE, find_what,
- fdip_search_ctx, FALSE, rel_fname);
- if (fdip_search_ctx != NULL)
+ r_ptr, 100, FALSE, find_what,
+ fdip_search_ctx, FALSE, rel_fname);
+ if (fdip_search_ctx != NULL) {
did_findfile_init = TRUE;
+ }
xfree(buf);
}
}
}
if (file_name == NULL && (options & FNAME_MESS)) {
if (first == TRUE) {
- if (find_what == FINDFILE_DIR)
+ if (find_what == FINDFILE_DIR) {
EMSG2(_("E344: Can't find directory \"%s\" in cdpath"),
- ff_file_to_find);
- else
+ ff_file_to_find);
+ } else {
EMSG2(_("E345: Can't find file \"%s\" in path"),
- ff_file_to_find);
+ ff_file_to_find);
+ }
} else {
- if (find_what == FINDFILE_DIR)
+ if (find_what == FINDFILE_DIR) {
EMSG2(_("E346: No more directory \"%s\" found in cdpath"),
- ff_file_to_find);
- else
+ ff_file_to_find);
+ } else {
EMSG2(_("E347: No more file \"%s\" found in path"),
- ff_file_to_find);
+ ff_file_to_find);
+ }
}
}
@@ -1565,7 +1591,7 @@ theend:
return file_name;
}
-void do_autocmd_dirchanged(char *new_dir, CdScope scope, bool changed_window)
+void do_autocmd_dirchanged(char *new_dir, CdScope scope, CdCause cause)
{
static bool recursive = false;
@@ -1581,29 +1607,44 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope, bool changed_window)
char buf[8];
switch (scope) {
- case kCdScopeGlobal: {
- snprintf(buf, sizeof(buf), "global");
- break;
- }
- case kCdScopeTab: {
- snprintf(buf, sizeof(buf), "tab");
- break;
- }
- case kCdScopeWindow: {
- snprintf(buf, sizeof(buf), "window");
- break;
- }
- case kCdScopeInvalid: {
- // Should never happen.
- abort();
- }
+ case kCdScopeGlobal:
+ snprintf(buf, sizeof(buf), "global");
+ break;
+ case kCdScopeTabpage:
+ snprintf(buf, sizeof(buf), "tabpage");
+ break;
+ case kCdScopeWindow:
+ snprintf(buf, sizeof(buf), "window");
+ break;
+ case kCdScopeInvalid:
+ // Should never happen.
+ abort();
}
+#ifdef BACKSLASH_IN_FILENAME
+ char new_dir_buf[MAXPATHL];
+ STRCPY(new_dir_buf, new_dir);
+ slash_adjust(new_dir_buf);
+ new_dir = new_dir_buf;
+#endif
+
tv_dict_add_str(dict, S_LEN("scope"), buf); // -V614
- tv_dict_add_str(dict, S_LEN("cwd"), new_dir);
- tv_dict_add_bool(dict, S_LEN("changed_window"), changed_window);
+ tv_dict_add_str(dict, S_LEN("cwd"), new_dir);
+ tv_dict_add_bool(dict, S_LEN("changed_window"), cause == kCdCauseWindow);
tv_dict_set_keys_readonly(dict);
+ switch (cause) {
+ case kCdCauseManual:
+ case kCdCauseWindow:
+ break;
+ case kCdCauseAuto:
+ snprintf(buf, sizeof(buf), "auto");
+ break;
+ case kCdCauseOther:
+ // Should never happen.
+ abort();
+ }
+
apply_autocmds(EVENT_DIRCHANGED, (char_u *)buf, (char_u *)new_dir, false,
curbuf);
@@ -1615,7 +1656,7 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope, bool changed_window)
/// Change to a file's directory.
/// Caller must call shorten_fnames()!
/// @return OK or FAIL
-int vim_chdirfile(char_u *fname)
+int vim_chdirfile(char_u *fname, CdCause cause)
{
char dir[MAXPATHL];
@@ -1626,30 +1667,27 @@ int vim_chdirfile(char_u *fname)
NameBuff[0] = NUL;
}
- if (os_chdir(dir) != 0) {
+ if (os_chdir(dir) == 0) {
+ if (cause != kCdCauseOther && pathcmp(dir, (char *)NameBuff, -1) != 0) {
+ do_autocmd_dirchanged(dir, kCdScopeWindow, cause);
+ }
+ } else {
return FAIL;
}
-#ifdef BACKSLASH_IN_FILENAME
- slash_adjust((char_u *)dir);
-#endif
- if (!strequal(dir, (char *)NameBuff)) {
- do_autocmd_dirchanged(dir, kCdScopeWindow, false);
- }
-
return OK;
}
/// Change directory to "new_dir". Search 'cdpath' for relative directory names.
int vim_chdir(char_u *new_dir)
{
- char_u *dir_name = find_directory_in_path(new_dir, STRLEN(new_dir),
- FNAME_MESS, curbuf->b_ffname);
+ char *dir_name = (char *)find_directory_in_path(new_dir, STRLEN(new_dir),
+ FNAME_MESS, curbuf->b_ffname);
if (dir_name == NULL) {
return -1;
}
- int r = os_chdir((char *)dir_name);
+ int r = os_chdir(dir_name);
xfree(dir_name);
return r;
}
diff --git a/src/nvim/file_search.h b/src/nvim/file_search.h
index b128029123..4d4e723922 100644
--- a/src/nvim/file_search.h
+++ b/src/nvim/file_search.h
@@ -1,15 +1,15 @@
#ifndef NVIM_FILE_SEARCH_H
#define NVIM_FILE_SEARCH_H
-#include <stdlib.h> // for size_t
+#include <stdlib.h> // for size_t
-#include "nvim/types.h" // for char_u
-#include "nvim/globals.h" // for CdScope
+#include "nvim/globals.h" // for CdScope
+#include "nvim/types.h" // for char_u
-/* Flags for find_file_*() functions. */
-#define FINDFILE_FILE 0 /* only files */
-#define FINDFILE_DIR 1 /* only directories */
-#define FINDFILE_BOTH 2 /* files and directories */
+// Flags for find_file_*() functions.
+#define FINDFILE_FILE 0 // only files
+#define FINDFILE_DIR 1 // only directories
+#define FINDFILE_BOTH 2 // files and directories
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "file_search.h.generated.h"
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index b7dbda3d99..4a33d74011 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -65,7 +65,7 @@
// For compatibility with libuv < 1.20.0 (tested on 1.18.0)
#ifndef UV_FS_COPYFILE_FICLONE
-#define UV_FS_COPYFILE_FICLONE 0
+# define UV_FS_COPYFILE_FICLONE 0
#endif
#define HAS_BW_FLAGS
@@ -105,9 +105,9 @@ struct bw_info {
int bw_conv_error; // set for conversion error
linenr_T bw_conv_error_lnum; // first line with error or zero
linenr_T bw_start_lnum; // line number at start of buffer
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
iconv_t bw_iconv_fd; // descriptor for iconv() or -1
-# endif
+#endif
};
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -233,11 +233,11 @@ int readfile(char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_ski
char_u *fenc_next = NULL; // next item in 'fencs' or NULL
bool advance_fenc = false;
long real_size = 0;
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
iconv_t iconv_fd = (iconv_t)-1; // descriptor for iconv() or -1
bool did_iconv = false; // true when iconv() failed and trying
// 'charconvert' next
-# endif
+#endif
bool converted = false; // true if conversion done
bool notconverted = false; // true if conversion wanted but it wasn't possible
char_u conv_rest[CONV_RESTLEN];
@@ -269,10 +269,10 @@ int readfile(char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_ski
}
}
- /* Remember the initial values of curbuf, curbuf->b_ffname and
- * curbuf->b_fname to detect whether they are altered as a result of
- * executing nasty autocommands. Also check if "fname" and "sfname"
- * point to one of these values. */
+ // Remember the initial values of curbuf, curbuf->b_ffname and
+ // curbuf->b_fname to detect whether they are altered as a result of
+ // executing nasty autocommands. Also check if "fname" and "sfname"
+ // point to one of these values.
old_curbuf = curbuf;
old_b_ffname = curbuf->b_ffname;
old_b_fname = curbuf->b_fname;
@@ -373,10 +373,10 @@ int readfile(char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_ski
if (perm >= 0 && !S_ISREG(perm) // not a regular file ...
&& !S_ISFIFO(perm) // ... or fifo
&& !S_ISSOCK(perm) // ... or socket
-# ifdef OPEN_CHR_FILES
+#ifdef OPEN_CHR_FILES
&& !(S_ISCHR(perm) && is_dev_fd_file(fname))
// ... or a character special file named /dev/fd/<n>
-# endif
+#endif
) {
if (S_ISDIR(perm)) {
filemess(curbuf, fname, (char_u *)_(msg_is_a_directory), 0);
@@ -429,8 +429,8 @@ int readfile(char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_ski
curbuf->b_orig_mode = 0;
}
- /* Reset the "new file" flag. It will be set again below when the
- * file doesn't exist. */
+ // Reset the "new file" flag. It will be set again below when the
+ // file doesn't exist.
curbuf->b_flags &= ~(BF_NEW | BF_NEW_W);
}
@@ -493,11 +493,11 @@ int readfile(char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_ski
} else {
filemess(curbuf, sfname, (char_u *)(
(fd == UV_EFBIG) ? _("[File too big]") :
-# if defined(UNIX) && defined(EOVERFLOW)
+#if defined(UNIX) && defined(EOVERFLOW)
// libuv only returns -errno in Unix and in Windows open() does not
// set EOVERFLOW
(fd == -EOVERFLOW) ? _("[File too big]") :
-# endif
+#endif
_("[Permission Denied]")), 0);
curbuf->b_p_ro = TRUE; // must use "w!" now
}
@@ -514,8 +514,8 @@ int readfile(char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_ski
}
if (set_options) {
- /* Don't change 'eol' if reading from buffer as it will already be
- * correctly set when reading stdin. */
+ // Don't change 'eol' if reading from buffer as it will already be
+ // correctly set when reading stdin.
if (!read_buffer) {
curbuf->b_p_eol = TRUE;
curbuf->b_start_eol = TRUE;
@@ -768,13 +768,13 @@ retry:
}
}
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
if (iconv_fd != (iconv_t)-1) {
// aborted conversion with iconv(), close the descriptor
iconv_close(iconv_fd);
iconv_fd = (iconv_t)-1;
}
-# endif
+#endif
if (advance_fenc) {
/*
@@ -816,8 +816,8 @@ retry:
fio_flags = 0;
converted = need_conversion(fenc);
if (converted) {
- /* "ucs-bom" means we need to check the first bytes of the file
- * for a BOM. */
+ // "ucs-bom" means we need to check the first bytes of the file
+ // for a BOM.
if (STRCMP(fenc, ENC_UCSBOM) == 0) {
fio_flags = FIO_UCSBOM;
} else {
@@ -833,13 +833,13 @@ retry:
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
// Try using iconv() if we can't convert internally.
if (fio_flags == 0
&& !did_iconv) {
iconv_fd = (iconv_t)my_iconv_open((char_u *)"utf-8", fenc);
}
-# endif
+#endif
/*
* Use the 'charconvert' expression when conversion is required
@@ -847,13 +847,13 @@ retry:
*/
if (fio_flags == 0 && !read_stdin && !read_buffer && *p_ccv != NUL
&& !read_fifo
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
&& iconv_fd == (iconv_t)-1
-# endif
+#endif
) {
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
did_iconv = false;
-# endif
+#endif
/* Skip conversion when it's already done (retry for wrong
* "fileformat"). */
if (tmpname == NULL) {
@@ -872,9 +872,9 @@ retry:
}
} else {
if (fio_flags == 0
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
&& iconv_fd == (iconv_t)-1
-# endif
+#endif
) {
/* Conversion wanted but we can't.
* Try the next conversion in 'fileencodings' */
@@ -949,22 +949,22 @@ retry:
ptr = buffer + linerest;
line_start = buffer;
- /* May need room to translate into.
- * For iconv() we don't really know the required space, use a
- * factor ICONV_MULT.
- * latin1 to utf-8: 1 byte becomes up to 2 bytes
- * utf-16 to utf-8: 2 bytes become up to 3 bytes, 4 bytes
- * become up to 4 bytes, size must be multiple of 2
- * ucs-2 to utf-8: 2 bytes become up to 3 bytes, size must be
- * multiple of 2
- * ucs-4 to utf-8: 4 bytes become up to 6 bytes, size must be
- * multiple of 4 */
+ // May need room to translate into.
+ // For iconv() we don't really know the required space, use a
+ // factor ICONV_MULT.
+ // latin1 to utf-8: 1 byte becomes up to 2 bytes
+ // utf-16 to utf-8: 2 bytes become up to 3 bytes, 4 bytes
+ // become up to 4 bytes, size must be multiple of 2
+ // ucs-2 to utf-8: 2 bytes become up to 3 bytes, size must be
+ // multiple of 2
+ // ucs-4 to utf-8: 4 bytes become up to 6 bytes, size must be
+ // multiple of 4
real_size = (int)size;
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
if (iconv_fd != (iconv_t)-1) {
size = size / ICONV_MULT;
} else {
-# endif
+#endif
if (fio_flags & FIO_LATIN1) {
size = size / 2;
} else if (fio_flags & (FIO_UCS2 | FIO_UTF16)) {
@@ -974,9 +974,9 @@ retry:
} else if (fio_flags == FIO_UCSBOM) {
size = size / ICONV_MULT; // worst case
}
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
}
-# endif
+#endif
if (conv_restlen > 0) {
// Insert unconverted bytes from previous line.
memmove(ptr, conv_rest, conv_restlen); // -V614
@@ -1000,9 +1000,9 @@ retry:
p = ml_get(read_buf_lnum) + read_buf_col;
n = (int)STRLEN(p);
if ((int)tlen + n + 1 > size) {
- /* Filled up to "size", append partial line.
- * Change NL to NUL to reverse the effect done
- * below. */
+ // Filled up to "size", append partial line.
+ // Change NL to NUL to reverse the effect done
+ // below.
n = (int)(size - tlen);
for (ni = 0; ni < n; ++ni) {
if (p[ni] == NL) {
@@ -1026,8 +1026,8 @@ retry:
ptr[tlen++] = NL;
read_buf_col = 0;
if (++read_buf_lnum > from) {
- /* When the last line didn't have an
- * end-of-line don't add it now either. */
+ // When the last line didn't have an
+ // end-of-line don't add it now either.
if (!curbuf->b_p_eol) {
--tlen;
}
@@ -1055,9 +1055,9 @@ retry:
// When we did a conversion report an error.
if (fio_flags != 0
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
|| iconv_fd != (iconv_t)-1
-# endif
+#endif
) {
if (can_retry) {
goto rewind_retry;
@@ -1081,9 +1081,9 @@ retry:
* leave the UTF8 checking code to do it, as it
* works slightly differently. */
if (bad_char_behavior != BAD_KEEP && (fio_flags != 0
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
|| iconv_fd != (iconv_t)-1
-# endif
+#endif
)) {
while (conv_restlen > 0) {
*(--ptr) = bad_char_behavior;
@@ -1091,12 +1091,12 @@ retry:
}
}
fio_flags = 0; // don't convert this
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
if (iconv_fd != (iconv_t)-1) {
iconv_close(iconv_fd);
iconv_fd = (iconv_t)-1;
}
-# endif
+#endif
}
}
}
@@ -1165,7 +1165,7 @@ retry:
break;
}
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
if (iconv_fd != (iconv_t)-1) {
/*
* Attempt conversion of the read bytes to 'encoding' using
@@ -1223,7 +1223,7 @@ retry:
memmove(line_start, buffer, (size_t)linerest);
size = ((char_u *)top - ptr);
}
-# endif
+#endif
if (fio_flags != 0) {
unsigned int u8c;
@@ -1279,8 +1279,8 @@ retry:
}
}
- /* If there is a trailing incomplete sequence move it to
- * conv_rest[]. */
+ // If there is a trailing incomplete sequence move it to
+ // conv_rest[].
if (tail != NULL) {
conv_restlen = (int)((ptr + size) - tail);
memmove(conv_rest, tail, conv_restlen);
@@ -1320,8 +1320,8 @@ retry:
}
}
- /* found second word of double-word, get the first
- * word and compute the resulting character */
+ // found second word of double-word, get the first
+ // word and compute the resulting character
if (fio_flags & FIO_ENDIAN_L) {
u16c = (*--p << 8);
u16c += *--p;
@@ -1369,9 +1369,9 @@ retry:
p -= len;
u8c = utf_ptr2char(p);
if (len == 0) {
- /* Not a valid UTF-8 character, retry with
- * another fenc when possible, otherwise just
- * report the error. */
+ // Not a valid UTF-8 character, retry with
+ // another fenc when possible, otherwise just
+ // report the error.
if (can_retry) {
goto rewind_retry;
}
@@ -1435,18 +1435,18 @@ retry:
}
}
if (l == 1 || l > todo) {
- /* Illegal byte. If we can try another encoding
- * do that, unless at EOF where a truncated
- * file is more likely than a conversion error. */
+ // Illegal byte. If we can try another encoding
+ // do that, unless at EOF where a truncated
+ // file is more likely than a conversion error.
if (can_retry && !incomplete_tail) {
break;
}
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
// When we did a conversion report an error.
if (iconv_fd != (iconv_t)-1 && conv_error == 0) {
conv_error = readfile_linenr(linecnt, ptr, p);
}
-# endif
+#endif
// Remember the first linenr with an illegal byte
if (conv_error == 0 && illegal_byte == 0) {
illegal_byte = readfile_linenr(linecnt, ptr, p);
@@ -1469,17 +1469,17 @@ retry:
// Detected a UTF-8 error.
rewind_retry:
// Retry reading with another conversion.
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
if (*p_ccv != NUL && iconv_fd != (iconv_t)-1) {
// iconv() failed, try 'charconvert'
did_iconv = true;
} else {
-# endif
+#endif
// use next item from 'fileencodings'
advance_fenc = true;
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
}
-# endif
+#endif
file_rewind = true;
goto retry;
}
@@ -1700,11 +1700,11 @@ failed:
if (fenc_alloced) {
xfree(fenc);
}
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
if (iconv_fd != (iconv_t)-1) {
iconv_close(iconv_fd);
}
-# endif
+#endif
if (!read_buffer && !read_stdin) {
close(fd); // errors are ignored
@@ -1909,8 +1909,8 @@ failed:
*/
curbuf->b_no_eol_lnum = read_no_eol_lnum;
- /* When reloading a buffer put the cursor at the first line that is
- * different. */
+ // When reloading a buffer put the cursor at the first line that is
+ // different.
if (flags & READ_KEEP_UNDO) {
u_find_first_changed();
}
@@ -1929,8 +1929,8 @@ failed:
int m = msg_scroll;
int n = msg_scrolled;
- /* Save the fileformat now, otherwise the buffer will be considered
- * modified if the format/encoding was automatically detected. */
+ // Save the fileformat now, otherwise the buffer will be considered
+ // modified if the format/encoding was automatically detected.
if (set_options) {
save_file_ff(curbuf);
}
@@ -2280,9 +2280,9 @@ int buf_write(buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_
write_info.bw_conv_error = FALSE;
write_info.bw_conv_error_lnum = 0;
write_info.bw_restlen = 0;
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
write_info.bw_iconv_fd = (iconv_t)-1;
-# endif
+#endif
/* After writing a file changedtick changes but we don't want to display
* the line. */
@@ -2690,7 +2690,7 @@ int buf_write(buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_
if (fd < 0) { // can't write in directory
backup_copy = TRUE;
} else {
-# ifdef UNIX
+#ifdef UNIX
os_fchown(fd, file_info_old.stat.st_uid, file_info_old.stat.st_gid);
if (!os_fileinfo((char *)IObuff, &file_info)
|| file_info.stat.st_uid != file_info_old.stat.st_uid
@@ -2698,7 +2698,7 @@ int buf_write(buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_
|| (long)file_info.stat.st_mode != perm) {
backup_copy = TRUE;
}
-# endif
+#endif
/* Close the file before removing it, on MS-Windows we
* can't delete an open file. */
close(fd);
@@ -2711,7 +2711,7 @@ int buf_write(buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_
* Break symlinks and/or hardlinks if we've been asked to.
*/
if ((bkc & BKC_BREAKSYMLINK) || (bkc & BKC_BREAKHARDLINK)) {
-# ifdef UNIX
+#ifdef UNIX
bool file_info_link_ok = os_fileinfo_link((char *)fname, &file_info);
// Symlinks.
@@ -2728,7 +2728,7 @@ int buf_write(buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_
|| os_fileinfo_id_equal(&file_info, &file_info_old))) {
backup_copy = FALSE;
}
-# endif
+#endif
}
// make sure we have a valid backup extension to use
@@ -3085,7 +3085,7 @@ nobackup:
if (converted && wb_flags == 0) {
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
// Use iconv() conversion when conversion is needed and it's not done
// internally.
write_info.bw_iconv_fd = (iconv_t)my_iconv_open(fenc, (char_u *)"utf-8");
@@ -3098,7 +3098,7 @@ nobackup:
}
write_info.bw_first = TRUE;
} else
-# endif
+#endif
/*
* When the file needs to be converted with 'charconvert' after
@@ -3114,9 +3114,9 @@ nobackup:
}
}
if (converted && wb_flags == 0
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
&& write_info.bw_iconv_fd == (iconv_t)-1
-# endif
+#endif
&& wfname == fname) {
if (!forceit) {
SET_ERRMSG(_("E213: Cannot convert (add ! to write without conversion)"));
@@ -3154,8 +3154,8 @@ nobackup:
O_WRONLY |
(append ?
(forceit ? (O_APPEND | O_CREAT) : O_APPEND)
- : (O_CREAT | O_TRUNC))
- , perm < 0 ? 0666 : (perm & 0777))) < 0) {
+ : (O_CREAT | O_TRUNC)),
+ perm < 0 ? 0666 : (perm & 0777))) < 0) {
// A forced write will try to create a new file if the old one
// is still readonly. This may also happen when the directory
// is read-only. In that case the mch_remove() will fail.
@@ -3644,12 +3644,12 @@ nofail:
}
xfree(fenc_tofree);
xfree(write_info.bw_conv_buf);
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
if (write_info.bw_iconv_fd != (iconv_t)-1) {
iconv_close(write_info.bw_iconv_fd);
write_info.bw_iconv_fd = (iconv_t)-1;
}
-# endif
+#endif
#ifdef HAVE_ACL
mch_free_acl(acl);
#endif
@@ -4034,7 +4034,7 @@ static int buf_write_bytes(struct bw_info *ip)
}
}
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
if (ip->bw_iconv_fd != (iconv_t)-1) {
const char *from;
size_t fromlen;
@@ -4096,7 +4096,7 @@ static int buf_write_bytes(struct bw_info *ip)
buf = ip->bw_conv_buf;
len = (int)((char_u *)to - ip->bw_conv_buf);
}
-# endif
+#endif
}
if (ip->bw_fd < 0) {
@@ -4684,7 +4684,7 @@ int vim_rename(const char_u *from, const char_u *to)
}
STRCPY(tempname, from);
for (n = 123; n < 99999; n++) {
- char * tail = (char *)path_tail(tempname);
+ char *tail = (char *)path_tail(tempname);
snprintf(tail, (MAXPATHL + 1) - (tail - (char *)tempname - 1), "%d", n);
if (!os_path_exists(tempname)) {
@@ -4804,15 +4804,15 @@ int check_timestamps(int focus)
{
int didit = 0;
- /* Don't check timestamps while system() or another low-level function may
- * cause us to lose and gain focus. */
+ // Don't check timestamps while system() or another low-level function may
+ // cause us to lose and gain focus.
if (no_check_timestamps > 0) {
return FALSE;
}
- /* Avoid doing a check twice. The OK/Reload dialog can cause a focus
- * event and we would keep on checking if the file is steadily growing.
- * Do check again after typing something. */
+ // Avoid doing a check twice. The OK/Reload dialog can cause a focus
+ // event and we would keep on checking if the file is steadily growing.
+ // Do check again after typing something.
if (focus && did_check_timestamps) {
need_check_timestamps = TRUE;
return FALSE;
@@ -5025,8 +5025,8 @@ int buf_check_timestamp(buf_T *buf)
mesg = _("W16: Warning: Mode of file \"%s\" has changed since editing started");
mesg2 = _("See \":help W16\" for more info.");
} else {
- /* Only timestamp changed, store it to avoid a warning
- * in check_mtime() later. */
+ // Only timestamp changed, store it to avoid a warning
+ // in check_mtime() later.
buf->b_mtime_read = buf->b_mtime;
}
}
@@ -5538,8 +5538,8 @@ bool match_file_list(char_u *list, char_u *sfname, char_u *ffname)
/// @param no_bslash Don't use a backward slash as pathsep
///
/// @return NULL on failure.
-char_u * file_pat_to_reg_pat(const char_u *pat, const char_u *pat_end, char *allow_dirs,
- int no_bslash)
+char_u *file_pat_to_reg_pat(const char_u *pat, const char_u *pat_end, char *allow_dirs,
+ int no_bslash)
FUNC_ATTR_NONNULL_ARG(1)
{
const char_u *endp;
@@ -5623,12 +5623,11 @@ char_u * file_pat_to_reg_pat(const char_u *pat, const char_u *pat_end, char *all
}
#ifdef BACKSLASH_IN_FILENAME
if (!no_bslash) {
- /* translate:
- * "\x" to "\\x" e.g., "dir\file"
- * "\*" to "\\.*" e.g., "dir\*.c"
- * "\?" to "\\." e.g., "dir\??.c"
- * "\+" to "\+" e.g., "fileX\+.c"
- */
+ // translate:
+ // "\x" to "\\x" e.g., "dir\file"
+ // "\*" to "\\.*" e.g., "dir\*.c"
+ // "\?" to "\\." e.g., "dir\??.c"
+ // "\+" to "\+" e.g., "fileX\+.c"
if ((vim_isfilec(p[1]) || p[1] == '*' || p[1] == '?')
&& p[1] != '+') {
reg_pat[i++] = '[';
@@ -5642,16 +5641,15 @@ char_u * file_pat_to_reg_pat(const char_u *pat, const char_u *pat_end, char *all
}
}
#endif
- /* Undo escaping from ExpandEscape():
- * foo\?bar -> foo?bar
- * foo\%bar -> foo%bar
- * foo\,bar -> foo,bar
- * foo\ bar -> foo bar
- * Don't unescape \, * and others that are also special in a
- * regexp.
- * An escaped { must be unescaped since we use magic not
- * verymagic. Use "\\\{n,m\}"" to get "\{n,m}".
- */
+ // Undo escaping from ExpandEscape():
+ // foo\?bar -> foo?bar
+ // foo\%bar -> foo%bar
+ // foo\,bar -> foo,bar
+ // foo\ bar -> foo bar
+ // Don't unescape \, * and others that are also special in a
+ // regexp.
+ // An escaped { must be unescaped since we use magic not
+ // verymagic. Use "\\\{n,m\}"" to get "\{n,m}".
if (*++p == '?'
#ifdef BACKSLASH_IN_FILENAME
&& no_bslash
diff --git a/src/nvim/fileio.h b/src/nvim/fileio.h
index 71149bdcc1..9bfec44ef3 100644
--- a/src/nvim/fileio.h
+++ b/src/nvim/fileio.h
@@ -1,9 +1,9 @@
#ifndef NVIM_FILEIO_H
#define NVIM_FILEIO_H
+#include "nvim/autocmd.h"
#include "nvim/buffer_defs.h"
#include "nvim/os/os.h"
-#include "nvim/autocmd.h"
// Values for readfile() flags
#define READ_NEW 0x01 // read a file into a new buffer
diff --git a/src/nvim/fold.c b/src/nvim/fold.c
index 7a017702ee..e141f9bb62 100644
--- a/src/nvim/fold.c
+++ b/src/nvim/fold.c
@@ -224,8 +224,8 @@ bool hasFoldingWin(win_T *const win, const linenr_T lnum, linenr_T *const firstp
break;
}
- /* Fold found, but it's open: Check nested folds. Line number is
- * relative to containing fold. */
+ // Fold found, but it's open: Check nested folds. Line number is
+ // relative to containing fold.
gap = &fp->fd_nested;
lnum_rel -= fp->fd_top;
++level;
@@ -264,8 +264,8 @@ bool hasFoldingWin(win_T *const win, const linenr_T lnum, linenr_T *const firstp
*/
int foldLevel(linenr_T lnum)
{
- /* While updating the folds lines between invalid_top and invalid_bot have
- * an undefined fold level. Otherwise update the folds first. */
+ // While updating the folds lines between invalid_top and invalid_bot have
+ // an undefined fold level. Otherwise update the folds first.
if (invalid_top == (linenr_T)0) {
checkupdate(curwin);
} else if (lnum == prev_lnum && prev_lnum_lvl >= 0) {
@@ -492,9 +492,9 @@ static void newFoldLevelWin(win_T *wp)
checkupdate(wp);
if (wp->w_fold_manual) {
- /* Set all flags for the first level of folds to FD_LEVEL. Following
- * manual open/close will then change the flags to FD_OPEN or
- * FD_CLOSED for those folds that don't use 'foldlevel'. */
+ // Set all flags for the first level of folds to FD_LEVEL. Following
+ // manual open/close will then change the flags to FD_OPEN or
+ // FD_CLOSED for those folds that don't use 'foldlevel'.
fp = (fold_T *)wp->w_folds.ga_data;
for (int i = 0; i < wp->w_folds.ga_len; ++i) {
fp[i].fd_flags = FD_LEVEL;
@@ -904,8 +904,8 @@ int foldMoveTo(const bool updown, const int dir, const long count)
break;
}
- /* When moving up, consider a fold above the cursor; when
- * moving down consider a fold below the cursor. */
+ // When moving up, consider a fold above the cursor; when
+ // moving down consider a fold below the cursor.
if (dir == FORWARD) {
if (fp - (fold_T *)gap->ga_data >= gap->ga_len) {
break;
@@ -1414,7 +1414,7 @@ static void deleteFoldEntry(win_T *const wp, garray_T *const gap, const int idx,
*/
void deleteFoldRecurse(buf_T *bp, garray_T *gap)
{
-# define DELETE_FOLD_NESTED(fd) deleteFoldRecurse(bp, &((fd)->fd_nested))
+#define DELETE_FOLD_NESTED(fd) deleteFoldRecurse(bp, &((fd)->fd_nested))
GA_DEEP_CLEAR(gap, fold_T, DELETE_FOLD_NESTED);
}
@@ -1424,13 +1424,13 @@ void deleteFoldRecurse(buf_T *bp, garray_T *gap)
*/
void foldMarkAdjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long amount_after)
{
- /* If deleting marks from line1 to line2, but not deleting all those
- * lines, set line2 so that only deleted lines have their folds removed. */
+ // If deleting marks from line1 to line2, but not deleting all those
+ // lines, set line2 so that only deleted lines have their folds removed.
if (amount == MAXLNUM && line2 >= line1 && line2 - line1 >= -amount_after) {
line2 = line1 - amount_after - 1;
}
- /* If appending a line in Insert mode, it should be included in the fold
- * just above the line. */
+ // If appending a line in Insert mode, it should be included in the fold
+ // just above the line.
if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM) {
line1--;
}
@@ -1449,8 +1449,8 @@ static void foldMarkAdjustRecurse(win_T *wp, garray_T *gap, linenr_T line1, line
return;
}
- /* In Insert mode an inserted line at the top of a fold is considered part
- * of the fold, otherwise it isn't. */
+ // In Insert mode an inserted line at the top of a fold is considered part
+ // of the fold, otherwise it isn't.
if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM) {
top = line1 + 1;
} else {
@@ -1580,8 +1580,8 @@ static bool check_closed(win_T *const wp, fold_T *const fp, bool *const use_leve
{
bool closed = false;
- /* Check if this fold is closed. If the flag is FD_LEVEL this
- * fold and all folds it contains depend on 'foldlevel'. */
+ // Check if this fold is closed. If the flag is FD_LEVEL this
+ // fold and all folds it contains depend on 'foldlevel'.
if (*use_levelp || fp->fd_flags == FD_LEVEL) {
*use_levelp = true;
if (level >= wp->w_p_fdl) {
@@ -1838,8 +1838,7 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, foldinfo_T foldin
curbuf = wp->w_buffer;
emsg_silent++; // handle exceptions, but don't display errors
- text = eval_to_string_safe(wp->w_p_fdt, NULL,
- was_set_insecurely(wp, (char_u *)"foldtext", OPT_LOCAL));
+ text = eval_to_string_safe(wp->w_p_fdt, NULL, was_set_insecurely(wp, "foldtext", OPT_LOCAL));
emsg_silent--;
if (text == NULL || did_emsg) {
@@ -1875,7 +1874,7 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, foldinfo_T foldin
}
}
if (*p != NUL) {
- p = (char_u *)transstr((const char *)text);
+ p = (char_u *)transstr((const char *)text, true);
xfree(text);
text = p;
}
@@ -2036,8 +2035,8 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
// Init marker variables to speed up foldlevelMarker().
parseMarker(wp);
- /* Need to get the level of the line above top, it is used if there is
- * no marker at the top. */
+ // Need to get the level of the line above top, it is used if there is
+ // no marker at the top.
if (top > 1) {
// Get the fold level at top - 1.
const int level = foldLevelWin(wp, top - 1);
@@ -2047,9 +2046,9 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
fline.lvl = level;
getlevel(&fline);
- /* If a fold started here, we already had the level, if it stops
- * here, we need to use lvl_next. Could also start and end a fold
- * in the same line. */
+ // If a fold started here, we already had the level, if it stops
+ // here, we need to use lvl_next. Could also start and end a fold
+ // in the same line.
if (fline.lvl > level) {
fline.lvl = level - (fline.lvl - fline.lvl_next);
} else {
@@ -2062,8 +2061,8 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
fline.lnum = top;
if (foldmethodIsExpr(wp)) {
getlevel = foldlevelExpr;
- /* start one line back, because a "<1" may indicate the end of a
- * fold in the topline */
+ // start one line back, because a "<1" may indicate the end of a
+ // fold in the topline
if (top > 1) {
--fline.lnum;
}
@@ -2152,9 +2151,9 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
end = fp->fd_top + fp->fd_len - 1;
} else if (getlevel == foldlevelSyntax
&& foldLevelWin(wp, fline.lnum) != fline.lvl) {
- /* For "syntax" method: Compare the foldlevel that the syntax
- * tells us to the foldlevel from the existing folds. If they
- * don't match continue updating folds. */
+ // For "syntax" method: Compare the foldlevel that the syntax
+ // tells us to the foldlevel from the existing folds. If they
+ // don't match continue updating folds.
end = fline.lnum;
} else {
break;
@@ -2186,9 +2185,9 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
changed_window_setting_win(wp);
}
- /* If we updated folds past "bot", need to redraw more lines. Don't do
- * this in other situations, the changed lines will be redrawn anyway and
- * this method can cause the whole window to be updated. */
+ // If we updated folds past "bot", need to redraw more lines. Don't do
+ // this in other situations, the changed lines will be redrawn anyway and
+ // this method can cause the whole window to be updated.
if (end != bot) {
if (wp->w_redraw_top == 0 || wp->w_redraw_top > top) {
wp->w_redraw_top = top;
@@ -2273,10 +2272,10 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level,
// Updating folds can be slow, check for CTRL-C.
line_breakcheck();
- /* Set "lvl" to the level of line "flp->lnum". When flp->start is set
- * and after the first line of the fold, set the level to zero to
- * force the fold to end. Do the same when had_end is set: Previous
- * line was marked as end of a fold. */
+ // Set "lvl" to the level of line "flp->lnum". When flp->start is set
+ // and after the first line of the fold, set the level to zero to
+ // force the fold to end. Do the same when had_end is set: Previous
+ // line was marked as end of a fold.
lvl = flp->lvl;
if (lvl > MAX_LEVEL) {
lvl = MAX_LEVEL;
@@ -2287,12 +2286,11 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level,
}
if (flp->lnum > bot && !finish && fp != NULL) {
- /* For "marker" and "syntax" methods:
- * - If a change caused a nested fold to be removed, we need to
- * delete it and continue at least until where it ended.
- * - If a change caused a nested fold to be created, or this fold
- * to continue below its original end, need to finish this fold.
- */
+ // For "marker" and "syntax" methods:
+ // - If a change caused a nested fold to be removed, we need to
+ // delete it and continue at least until where it ended.
+ // - If a change caused a nested fold to be created, or this fold
+ // to continue below its original end, need to finish this fold.
if (getlevel != foldlevelMarker
&& getlevel != foldlevelExpr
&& getlevel != foldlevelSyntax) {
@@ -2301,9 +2299,9 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level,
i = 0;
fp2 = fp;
if (lvl >= level) {
- /* Compute how deep the folds currently are, if it's deeper
- * than "lvl" then some must be deleted, need to update
- * at least one nested fold. */
+ // Compute how deep the folds currently are, if it's deeper
+ // than "lvl" then some must be deleted, need to update
+ // at least one nested fold.
ll = flp->lnum - fp->fd_top;
while (foldFind(&fp2->fd_nested, ll, &fp2)) {
++i;
@@ -2322,9 +2320,9 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level,
}
}
- /* At the start of the first nested fold and at the end of the current
- * fold: check if existing folds at this level, before the current
- * one, need to be deleted or truncated. */
+ // At the start of the first nested fold and at the end of the current
+ // fold: check if existing folds at this level, before the current
+ // one, need to be deleted or truncated.
if (fp == NULL
&& (lvl != level
|| flp->lnum_save >= bot
@@ -2357,10 +2355,10 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level,
|| (lvl >= level
&& fp->fd_top <= flp->lnum_save))))) {
if (fp->fd_top + fp->fd_len + concat > firstlnum) {
- /* Use existing fold for the new fold. If it starts
- * before where we started looking, extend it. If it
- * starts at another line, update nested folds to keep
- * their position, compensating for the new fd_top. */
+ // Use existing fold for the new fold. If it starts
+ // before where we started looking, extend it. If it
+ // starts at another line, update nested folds to keep
+ // their position, compensating for the new fd_top.
if (fp->fd_top == firstlnum) {
// We have found a fold beginning exactly where we want one.
} else if (fp->fd_top >= startlnum) {
@@ -2504,8 +2502,8 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level,
bot = flp->lnum;
}
- /* Line numbers in the nested fold are relative to the start of
- * this fold. */
+ // Line numbers in the nested fold are relative to the start of
+ // this fold.
flp->lnum = flp->lnum_save - fp->fd_top;
flp->off += fp->fd_top;
i = (int)(fp - (fold_T *)gap->ga_data);
@@ -2548,8 +2546,8 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level,
break;
}
- /* leave flp->lnum_save to lnum of the line that was used to get
- * the level, flp->lnum to the lnum of the next line. */
+ // leave flp->lnum_save to lnum of the line that was used to get
+ // the level, flp->lnum to the lnum of the next line.
flp->lnum_save = flp->lnum;
flp->lnum = ll;
}
@@ -2634,8 +2632,8 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level,
deleteFoldEntry(flp->wp, gap, (int)(fp2 - (fold_T *)gap->ga_data), true);
}
- /* Need to redraw the lines we inspected, which might be further down than
- * was asked for. */
+ // Need to redraw the lines we inspected, which might be further down than
+ // was asked for.
if (bot < flp->lnum - 1) {
bot = flp->lnum - 1;
}
@@ -2948,8 +2946,8 @@ static void foldMerge(win_T *const wp, fold_T *fp1, garray_T *gap, fold_T *fp2)
garray_T *gap1 = &fp1->fd_nested;
garray_T *gap2 = &fp2->fd_nested;
- /* If the last nested fold in fp1 touches the first nested fold in fp2,
- * merge them recursively. */
+ // If the last nested fold in fp1 touches the first nested fold in fp2,
+ // merge them recursively.
if (foldFind(gap1, fp1->fd_len - 1L, &fp3) && foldFind(gap2, 0L, &fp4)) {
foldMerge(wp, fp3, gap2, fp4);
}
@@ -2986,8 +2984,8 @@ static void foldlevelIndent(fline_T *flp)
buf = flp->wp->w_buffer;
s = skipwhite(ml_get_buf(buf, lnum, false));
- /* empty line or lines starting with a character in 'foldignore': level
- * depends on surrounding lines */
+ // empty line or lines starting with a character in 'foldignore': level
+ // depends on surrounding lines
if (*s == NUL || vim_strchr(flp->wp->w_p_fdi, *s) != NULL) {
// first and last line can't be undefined, use level 0
if (lnum == 1 || lnum == buf->b_ml.ml_line_count) {
@@ -3090,8 +3088,8 @@ static void foldlevelExpr(fline_T *flp)
// "-1", "0", "1", ..: set fold level
default:
if (n < 0) {
- /* Use the current level for the next line, so that "a1"
- * will work there. */
+ // Use the current level for the next line, so that "a1"
+ // will work there.
flp->lvl_next = flp->lvl;
} else {
flp->lvl_next = n;
@@ -3100,8 +3098,8 @@ static void foldlevelExpr(fline_T *flp)
break;
}
- /* If the level is unknown for the first or the last line in the file, use
- * level 0. */
+ // If the level is unknown for the first or the last line in the file, use
+ // level 0.
if (flp->lvl < 0) {
if (lnum <= 1) {
flp->lvl = 0;
diff --git a/src/nvim/fold.h b/src/nvim/fold.h
index 37fab4da60..a96ea8a039 100644
--- a/src/nvim/fold.h
+++ b/src/nvim/fold.h
@@ -3,17 +3,17 @@
#include <stdio.h>
-#include "nvim/pos.h"
+#include "nvim/buffer_defs.h"
#include "nvim/garray.h"
+#include "nvim/pos.h"
#include "nvim/types.h"
-#include "nvim/buffer_defs.h"
/*
* Info used to pass info about a fold from the fold-detection code to the
* code that displays the foldcolumn.
*/
typedef struct foldinfo {
- linenr_T fi_lnum; /* line number where fold starts */
+ linenr_T fi_lnum; // line number where fold starts
int fi_level; /* level of the fold; when this is zero the
other fields are invalid */
int fi_low_level; /* lowest fold level that starts in the same
diff --git a/src/nvim/func_attr.h b/src/nvim/func_attr.h
index e0b0610646..afbd87f2be 100644
--- a/src/nvim/func_attr.h
+++ b/src/nvim/func_attr.h
@@ -1,24 +1,24 @@
-// If DEFINE_FUNC_ATTRIBUTES macro is not defined then all function attributes
+// If DEFINE_FUNC_ATTRIBUTES macro is not defined then all function attributes
// are defined as empty values.
//
-// If DO_NOT_DEFINE_EMPTY_ATTRIBUTES then empty macros are not defined. Thus
-// undefined DEFINE_FUNC_ATTRIBUTES and defined DO_NOT_DEFINE_EMPTY_ATTRIBUTES
-// leaves file with untouched FUNC_ATTR_* macros. This variant is used for
+// If DO_NOT_DEFINE_EMPTY_ATTRIBUTES then empty macros are not defined. Thus
+// undefined DEFINE_FUNC_ATTRIBUTES and defined DO_NOT_DEFINE_EMPTY_ATTRIBUTES
+// leaves file with untouched FUNC_ATTR_* macros. This variant is used for
// scripts/gendeclarations.lua.
//
-// Empty macros are used for *.c files. (undefined DEFINE_FUNC_ATTRIBUTES and
+// Empty macros are used for *.c files. (undefined DEFINE_FUNC_ATTRIBUTES and
// undefined DO_NOT_DEFINE_EMPTY_ATTRIBUTES)
//
-// Macros defined as __attribute__((*)) are used by generated header files.
-// (defined DEFINE_FUNC_ATTRIBUTES and undefined
+// Macros defined as __attribute__((*)) are used by generated header files.
+// (defined DEFINE_FUNC_ATTRIBUTES and undefined
// DO_NOT_DEFINE_EMPTY_ATTRIBUTES)
//
-// Defined DEFINE_FUNC_ATTRIBUTES and defined DO_NOT_DEFINE_EMPTY_ATTRIBUTES is
+// Defined DEFINE_FUNC_ATTRIBUTES and defined DO_NOT_DEFINE_EMPTY_ATTRIBUTES is
// not used by anything.
-// FUNC_ATTR_* macros should be in *.c files for declarations generator. If you
-// define a function for which declaration is not generated by
-// gendeclarations.lua (e.g. template hash implementation) then you should use
+// FUNC_ATTR_* macros should be in *.c files for declarations generator. If you
+// define a function for which declaration is not generated by
+// gendeclarations.lua (e.g. template hash implementation) then you should use
// REAL_FATTR_* macros.
// gcc and clang expose their version as follows:
@@ -134,10 +134,10 @@
# if NVIM_HAS_ATTRIBUTE(no_sanitize_undefined)
# define REAL_FATTR_NO_SANITIZE_UNDEFINED \
- __attribute__((no_sanitize_undefined))
+ __attribute__((no_sanitize_undefined))
# elif NVIM_HAS_ATTRIBUTE(no_sanitize)
# define REAL_FATTR_NO_SANITIZE_UNDEFINED \
- __attribute__((no_sanitize("undefined")))
+ __attribute__((no_sanitize("undefined")))
# endif
# endif
diff --git a/src/nvim/garray.c b/src/nvim/garray.c
index 1cfc2b6176..7a3cc4a944 100644
--- a/src/nvim/garray.c
+++ b/src/nvim/garray.c
@@ -5,16 +5,16 @@
///
/// Functions for handling growing arrays.
-#include <string.h>
#include <inttypes.h>
+#include <string.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
+#include "nvim/garray.h"
#include "nvim/log.h"
#include "nvim/memory.h"
#include "nvim/path.h"
-#include "nvim/garray.h"
#include "nvim/strings.h"
+#include "nvim/vim.h"
// #include "nvim/globals.h"
#include "nvim/memline.h"
@@ -143,14 +143,14 @@ void ga_remove_duplicate_strings(garray_T *gap)
/// @param sep
///
/// @returns the concatenated strings
-char_u *ga_concat_strings_sep(const garray_T *gap, const char *sep)
+char *ga_concat_strings_sep(const garray_T *gap, const char *sep)
FUNC_ATTR_NONNULL_RET
{
- const size_t nelem = (size_t) gap->ga_len;
+ const size_t nelem = (size_t)gap->ga_len;
const char **strings = gap->ga_data;
if (nelem == 0) {
- return (char_u *) xstrdup("");
+ return xstrdup("");
}
size_t len = 0;
@@ -169,7 +169,7 @@ char_u *ga_concat_strings_sep(const garray_T *gap, const char *sep)
}
strcpy(s, strings[nelem - 1]);
- return (char_u *) ret;
+ return ret;
}
/// For a growing array that contains a list of strings: concatenate all the
@@ -178,9 +178,9 @@ char_u *ga_concat_strings_sep(const garray_T *gap, const char *sep)
/// @param gap
///
/// @returns the concatenated strings
-char_u* ga_concat_strings(const garray_T *gap) FUNC_ATTR_NONNULL_RET
+char_u *ga_concat_strings(const garray_T *gap) FUNC_ATTR_NONNULL_RET
{
- return ga_concat_strings_sep(gap, ",");
+ return (char_u *)ga_concat_strings_sep(gap, ",");
}
/// Concatenate a string to a growarray which contains characters.
@@ -192,13 +192,13 @@ char_u* ga_concat_strings(const garray_T *gap) FUNC_ATTR_NONNULL_RET
///
/// @param gap
/// @param s
-void ga_concat(garray_T *gap, const char_u *restrict s)
+void ga_concat(garray_T *gap, const char *restrict s)
{
if (s == NULL) {
return;
}
- ga_concat_len(gap, (const char *restrict) s, strlen((char *) s));
+ ga_concat_len(gap, s, STRLEN(s));
}
/// Concatenate a string to a growarray which contains characters
@@ -206,15 +206,14 @@ void ga_concat(garray_T *gap, const char_u *restrict s)
/// @param[out] gap Growarray to modify.
/// @param[in] s String to concatenate.
/// @param[in] len String length.
-void ga_concat_len(garray_T *const gap, const char *restrict s,
- const size_t len)
+void ga_concat_len(garray_T *const gap, const char *restrict s, const size_t len)
FUNC_ATTR_NONNULL_ALL
{
if (len) {
- ga_grow(gap, (int) len);
+ ga_grow(gap, (int)len);
char *data = gap->ga_data;
memcpy(data + gap->ga_len, s, len);
- gap->ga_len += (int) len;
+ gap->ga_len += (int)len;
}
}
diff --git a/src/nvim/garray.h b/src/nvim/garray.h
index e2cbdd4eab..56bd5c9130 100644
--- a/src/nvim/garray.h
+++ b/src/nvim/garray.h
@@ -3,8 +3,8 @@
#include <stddef.h> // for size_t
-#include "nvim/types.h" // for char_u
#include "nvim/log.h"
+#include "nvim/types.h" // for char_u
/// Structure used for growing arrays.
/// This is used to store information that only grows, is deleted all at
@@ -68,6 +68,6 @@ static inline void *ga_append_via_ptr(garray_T *gap, size_t item_size)
/// garray.
///
/// @param gap the garray to be freed
-#define GA_DEEP_CLEAR_PTR(gap) GA_DEEP_CLEAR(gap, void*, FREE_PTR_PTR)
+#define GA_DEEP_CLEAR_PTR(gap) GA_DEEP_CLEAR(gap, void *, FREE_PTR_PTR)
#endif // NVIM_GARRAY_H
diff --git a/src/nvim/generators/c_grammar.lua b/src/nvim/generators/c_grammar.lua
index c9ab0cf709..f35817c466 100644
--- a/src/nvim/generators/c_grammar.lua
+++ b/src/nvim/generators/c_grammar.lua
@@ -16,8 +16,9 @@ local ws = S(' \t') + nl
local fill = ws ^ 0
local c_comment = P('//') * (not_nl ^ 0)
local c_preproc = P('#') * (not_nl ^ 0)
+local dllexport = P('DLLEXPORT') * (ws ^ 1)
local typed_container =
- (P('ArrayOf(') + P('DictionaryOf(')) * ((any - P(')')) ^ 1) * P(')')
+ (P('ArrayOf(') + P('DictionaryOf(') + P('Dict(')) * ((any - P(')')) ^ 1) * P(')')
local c_id = (
typed_container +
(letter * (alpha ^ 0))
@@ -33,6 +34,7 @@ local c_param = Ct(c_param_type * C(c_id))
local c_param_list = c_param * (fill * (P(',') * fill * c_param) ^ 0)
local c_params = Ct(c_void + c_param_list)
local c_proto = Ct(
+ (dllexport ^ -1) *
Cg(c_type, 'return_type') * Cg(c_id, 'name') *
fill * P('(') * fill * Cg(c_params, 'parameters') * fill * P(')') *
Cg(Cc(false), 'fast') *
diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua
index 99d80cdebc..21f8c3855e 100644
--- a/src/nvim/generators/gen_api_dispatch.lua
+++ b/src/nvim/generators/gen_api_dispatch.lua
@@ -33,6 +33,10 @@ local function_names = {}
local c_grammar = require('generators.c_grammar')
+local function startswith(String,Start)
+ return string.sub(String,1,string.len(Start))==Start
+end
+
-- read each input file, parse and append to the api metadata
for i = 6, #arg do
local full_path = arg[i]
@@ -47,7 +51,8 @@ for i = 6, #arg do
local tmp = c_grammar.grammar:match(input:read('*all'))
for j = 1, #tmp do
local fn = tmp[j]
- if not fn.noexport then
+ local public = startswith(fn.name, "nvim_") or fn.deprecated_since
+ if public and not fn.noexport then
functions[#functions + 1] = tmp[j]
function_names[fn.name] = true
if #fn.parameters ~= 0 and fn.parameters[1][2] == 'channel_id' then
@@ -76,10 +81,6 @@ local function shallowcopy(orig)
return copy
end
-local function startswith(String,Start)
- return string.sub(String,1,string.len(Start))==Start
-end
-
-- Export functions under older deprecated names.
-- These will be removed eventually.
local deprecated_aliases = require("api.dispatch_deprecated")
@@ -108,9 +109,10 @@ for _,f in ipairs(shallowcopy(functions)) do
f.lua = f.lua_only or not f.remote_only
f.eval = (not f.lua_only) and (not f.remote_only)
else
+ f.deprecated_since = tonumber(f.deprecated_since)
+ assert(f.deprecated_since == 1)
f.remote = true
f.since = 0
- f.deprecated_since = 1
end
f.method = ismethod
local newname = deprecated_aliases[f.name]
@@ -152,6 +154,8 @@ for _,f in ipairs(functions) do
for i,param in ipairs(f.parameters) do
if param[1] == "DictionaryOf(LuaRef)" then
param = {"Dictionary", param[2]}
+ elseif startswith(param[1], "Dict(") then
+ param = {"Dictionary", param[2]}
end
f_exported.parameters[i] = param
end
@@ -173,7 +177,10 @@ local output = io.open(dispatch_outputf, 'wb')
local function real_type(type)
local rv = type
- if c_grammar.typed_container:match(rv) then
+ local rmatch = string.match(type, "Dict%(([_%w]+)%)")
+ if rmatch then
+ return "KeyDict_"..rmatch
+ elseif c_grammar.typed_container:match(rv) then
if rv:match('Array') then
rv = 'Array'
else
@@ -209,8 +216,9 @@ for i = 1, #functions do
-- Declare/initialize variables that will hold converted arguments
for j = 1, #fn.parameters do
local param = fn.parameters[j]
+ local rt = real_type(param[1])
local converted = 'arg_'..j
- output:write('\n '..param[1]..' '..converted..';')
+ output:write('\n '..rt..' '..converted..';')
end
output:write('\n')
output:write('\n if (args.size != '..#fn.parameters..') {')
@@ -225,7 +233,24 @@ for i = 1, #functions do
param = fn.parameters[j]
converted = 'arg_'..j
local rt = real_type(param[1])
- if rt ~= 'Object' then
+ if rt == 'Object' then
+ output:write('\n '..converted..' = args.items['..(j - 1)..'];\n')
+ elseif rt:match('^KeyDict_') then
+ converted = '&' .. converted
+ output:write('\n if (args.items['..(j - 1)..'].type == kObjectTypeDictionary) {') --luacheck: ignore 631
+ output:write('\n memset('..converted..', 0, sizeof(*'..converted..'));') -- TODO: neeeee
+ output:write('\n if (!api_dict_to_keydict('..converted..', '..rt..'_get_field, args.items['..(j - 1)..'].data.dictionary, error)) {')
+ output:write('\n goto cleanup;')
+ output:write('\n }')
+ output:write('\n } else if (args.items['..(j - 1)..'].type == kObjectTypeArray && args.items['..(j - 1)..'].data.array.size == 0) {') --luacheck: ignore 631
+ output:write('\n memset('..converted..', 0, sizeof(*'..converted..'));')
+
+ output:write('\n } else {')
+ output:write('\n api_set_error(error, kErrorTypeException, \
+ "Wrong type for argument '..j..' when calling '..fn.name..', expecting '..param[1]..'");')
+ output:write('\n goto cleanup;')
+ output:write('\n }\n')
+ else
if rt:match('^Buffer$') or rt:match('^Window$') or rt:match('^Tabpage$') then
-- Buffer, Window, and Tabpage have a specific type, but are stored in integer
output:write('\n if (args.items['..
@@ -257,10 +282,7 @@ for i = 1, #functions do
"Wrong type for argument '..j..' when calling '..fn.name..', expecting '..param[1]..'");')
output:write('\n goto cleanup;')
output:write('\n }\n')
- else
- output:write('\n '..converted..' = args.items['..(j - 1)..'];\n')
end
-
args[#args + 1] = converted
end
@@ -397,7 +419,7 @@ local function process_function(fn)
if not fn.fast then
write_shifted_output(output, string.format([[
- if (!nlua_is_deferred_safe(lstate)) {
+ if (!nlua_is_deferred_safe()) {
return luaL_error(lstate, e_luv_api_disabled, "%s");
}
]], fn.name))
@@ -423,13 +445,24 @@ local function process_function(fn)
if param[1] == "DictionaryOf(LuaRef)" then
extra = "true, "
end
+ local errshift = 0
+ if string.match(param_type, '^KeyDict_') then
+ write_shifted_output(output, string.format([[
+ %s %s = { 0 }; nlua_pop_keydict(lstate, &%s, %s_get_field, %s&err);]], param_type, cparam, cparam, param_type, extra))
+ cparam = '&'..cparam
+ errshift = 1 -- free incomplete dict on error
+ else
+ write_shifted_output(output, string.format([[
+ const %s %s = nlua_pop_%s(lstate, %s&err);]], param[1], cparam, param_type, extra))
+ end
+
write_shifted_output(output, string.format([[
- const %s %s = nlua_pop_%s(lstate, %s&err);
if (ERROR_SET(&err)) {
goto exit_%u;
}
- ]], param[1], cparam, param_type, extra, #fn.parameters - j))
+
+ ]], #fn.parameters - j + errshift))
free_code[#free_code + 1] = ('api_free_%s(%s);'):format(
lc_param_type, cparam)
cparams = cparam .. ', ' .. cparams
@@ -446,7 +479,7 @@ local function process_function(fn)
for i = 1, #free_code do
local rev_i = #free_code - i + 1
local code = free_code[rev_i]
- if i == 1 then
+ if i == 1 and not string.match(real_type(fn.parameters[1][1]), '^KeyDict_') then
free_at_exit_code = free_at_exit_code .. ('\n %s'):format(code)
else
free_at_exit_code = free_at_exit_code .. ('\n exit_%u:\n %s'):format(
diff --git a/src/nvim/generators/gen_declarations.lua b/src/nvim/generators/gen_declarations.lua
index 0782c8115d..c7d5a1a191 100755
--- a/src/nvim/generators/gen_declarations.lua
+++ b/src/nvim/generators/gen_declarations.lua
@@ -60,7 +60,7 @@ local right_word = concat(
)
local word = branch(
concat(
- branch(lit('ArrayOf('), lit('DictionaryOf(')), -- typed container macro
+ branch(lit('ArrayOf('), lit('DictionaryOf('), lit('Dict(')), -- typed container macro
one_or_more(any_character - lit(')')),
lit(')')
),
@@ -216,7 +216,16 @@ local footer = [[
#include "nvim/func_attr.h"
]]
-local non_static = header
+local non_static = header .. [[
+#ifndef DLLEXPORT
+# ifdef WIN32
+# define DLLEXPORT __declspec(dllexport)
+# else
+# define DLLEXPORT
+# endif
+#endif
+]]
+
local static = header
local filepattern = '^#%a* (%d+) "([^"]-)/?([^"/]+)"'
@@ -269,6 +278,7 @@ while init ~= nil do
declaration = declaration:gsub(' $', '')
declaration = declaration:gsub('^ ', '')
declaration = declaration .. ';'
+
if os.getenv('NVIM_GEN_DECLARATIONS_LINE_NUMBERS') == '1' then
declaration = declaration .. (' // %s/%s:%u'):format(
curdir, curfile, declline)
@@ -277,6 +287,7 @@ while init ~= nil do
if declaration:sub(1, 6) == 'static' then
static = static .. declaration
else
+ declaration = 'DLLEXPORT ' .. declaration
non_static = non_static .. declaration
end
declendpos = e
diff --git a/src/nvim/generators/gen_keysets.lua b/src/nvim/generators/gen_keysets.lua
new file mode 100644
index 0000000000..63ef202fe1
--- /dev/null
+++ b/src/nvim/generators/gen_keysets.lua
@@ -0,0 +1,67 @@
+
+local nvimsrcdir = arg[1]
+local shared_file = arg[2]
+local funcs_file = arg[3]
+local defs_file = arg[4]
+
+_G.vim = loadfile(shared_file)()
+
+if nvimsrcdir == '--help' then
+ print([[
+Usage:
+ lua gen_keyset.lua TODOFIXUPDATETHIS
+
+Will generate build/src/nvim/auto/keyset.generated.h with definition of functions
+static const array.
+]])
+ os.exit(0)
+end
+
+
+package.path = nvimsrcdir .. '/?.lua;' .. package.path
+local hashy = require'generators.hashy'
+
+local funcspipe = io.open(funcs_file, 'wb')
+local defspipe = io.open(defs_file, 'wb')
+
+local keysets = require'api.keysets'
+
+for name, keys in pairs(keysets) do
+ local neworder, hashfun = hashy.hashy_hash(name, keys, function (idx)
+ return name.."_table["..idx.."].str"
+ end)
+
+ defspipe:write("typedef struct {\n")
+ for _, key in ipairs(neworder) do
+ defspipe:write(" Object "..key..";\n")
+ end
+ defspipe:write("} KeyDict_"..name..";\n\n")
+
+ defspipe:write("extern KeySetLink "..name.."_table[];\n")
+
+ funcspipe:write("KeySetLink "..name.."_table[] = {\n")
+ for _, key in ipairs(neworder) do
+ funcspipe:write(' {"'..key..'", offsetof(KeyDict_'..name..", "..key..")},\n")
+ end
+ funcspipe:write(' {NULL, 0},\n')
+ funcspipe:write("};\n\n")
+
+ funcspipe:write(hashfun)
+
+ funcspipe:write([[
+Object *KeyDict_]]..name..[[_get_field(void *retval, const char *str, size_t len)
+{
+ int hash = ]]..name..[[_hash(str, len);
+ if (hash == -1) {
+ return NULL;
+ }
+
+ return (Object *)((char *)retval + ]]..name..[[_table[hash].ptr_off);
+}
+
+]])
+ defspipe:write("#define api_free_keydict_"..name.."(x) api_free_keydict(x, "..name.."_table)\n")
+end
+
+funcspipe:close()
+defspipe:close()
diff --git a/src/nvim/generators/hashy.lua b/src/nvim/generators/hashy.lua
new file mode 100644
index 0000000000..fac24c810a
--- /dev/null
+++ b/src/nvim/generators/hashy.lua
@@ -0,0 +1,122 @@
+-- HASHY McHASHFACE
+
+local M = {}
+_G.d = M
+
+
+local function setdefault(table, key)
+ local val = table[key]
+ if val == nil then
+ val = {}
+ table[key] = val
+ end
+ return val
+end
+
+function M.build_pos_hash(strings)
+ local len_buckets = {}
+ local maxlen = 0
+ for _,s in ipairs(strings) do
+ table.insert(setdefault(len_buckets, #s),s)
+ if #s > maxlen then maxlen = #s end
+ end
+
+ local len_pos_buckets = {}
+ local worst_buck_size = 0
+
+ for len = 1,maxlen do
+ local strs = len_buckets[len]
+ if strs then
+ -- the best position so far generates `best_bucket`
+ -- with `minsize` worst case collisions
+ local bestpos, minsize, best_bucket = nil, #strs*2, nil
+ for pos = 1,len do
+ local try_bucket = {}
+ for _,str in ipairs(strs) do
+ local poschar = string.sub(str, pos, pos)
+ table.insert(setdefault(try_bucket, poschar), str)
+ end
+ local maxsize = 1
+ for _,pos_strs in pairs(try_bucket) do
+ maxsize = math.max(maxsize, #pos_strs)
+ end
+ if maxsize < minsize then
+ bestpos = pos
+ minsize = maxsize
+ best_bucket = try_bucket
+ end
+ end
+ len_pos_buckets[len] = {bestpos, best_bucket}
+ worst_buck_size = math.max(worst_buck_size, minsize)
+ end
+ end
+ return len_pos_buckets, maxlen, worst_buck_size
+end
+
+function M.switcher(put, tab, maxlen, worst_buck_size)
+ local neworder = {}
+ put " switch (len) {\n"
+ local bucky = worst_buck_size > 1
+ for len = 1,maxlen do
+ local vals = tab[len]
+ if vals then
+ put(" case "..len..": ")
+ local pos, posbuck = unpack(vals)
+ local keys = vim.tbl_keys(posbuck)
+ if #keys > 1 then
+ table.sort(keys)
+ put("switch (str["..(pos-1).."]) {\n")
+ for _,c in ipairs(keys) do
+ local buck = posbuck[c]
+ local startidx = #neworder
+ vim.list_extend(neworder, buck)
+ local endidx = #neworder
+ put(" case '"..c.."': ")
+ put("low = "..startidx.."; ")
+ if bucky then put("high = "..endidx.."; ") end
+ put "break;\n"
+ end
+ put " default: break;\n"
+ put " }\n "
+ else
+ local startidx = #neworder
+ table.insert(neworder, posbuck[keys[1]][1])
+ local endidx = #neworder
+ put("low = "..startidx.."; ")
+ if bucky then put("high = "..endidx.."; ") end
+ end
+ put " break;\n"
+ end
+ end
+ put " default: break;\n"
+ put " }\n"
+ return neworder
+end
+
+function M.hashy_hash(name, strings, access)
+ local stats = {}
+ local put = function(str) table.insert(stats, str) end
+ local len_pos_buckets, maxlen, worst_buck_size = M.build_pos_hash(strings)
+ put("int "..name.."_hash(const char *str, size_t len)\n{\n")
+ if worst_buck_size > 1 then
+ put(" int low = 0, high = 0;\n")
+ else
+ put(" int low = -1;\n")
+ end
+ local neworder = M.switcher(put, len_pos_buckets, maxlen, worst_buck_size)
+ if worst_buck_size > 1 then
+ error [[ not implemented yet ]] -- TODO(bfredl)
+ else
+ put [[
+ if (low < 0) {
+ return -1;
+ }
+ ]]
+ put("if(memcmp(str, "..access("low")..", len)) {\n return -1;\n }\n")
+ put " return low;\n"
+ put "}\n\n"
+ end
+ return neworder, table.concat(stats)
+end
+
+return M
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index 3bf9d92696..eb836b9005 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -11,22 +11,25 @@
*/
#include <assert.h>
+#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
-#include <inttypes.h>
-#include "nvim/assert.h"
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/getchar.h"
+#include "nvim/assert.h"
#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
+#include "nvim/event/loop.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
+#include "nvim/ex_session.h"
#include "nvim/func_attr.h"
+#include "nvim/garray.h"
+#include "nvim/getchar.h"
+#include "nvim/keymap.h"
#include "nvim/lua/executor.h"
#include "nvim/main.h"
#include "nvim/mbyte.h"
@@ -34,24 +37,21 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/plines.h"
-#include "nvim/keymap.h"
-#include "nvim/garray.h"
#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/ops.h"
#include "nvim/option.h"
+#include "nvim/os/fileio.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/plines.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
-#include "nvim/ex_session.h"
#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
-#include "nvim/event/loop.h"
-#include "nvim/os/input.h"
-#include "nvim/os/os.h"
-#include "nvim/os/fileio.h"
+#include "nvim/vim.h"
/// Index in scriptin
@@ -163,7 +163,7 @@ static size_t last_recorded_len = 0; // number of last recorded chars
*/
void free_buff(buffheader_T *buf)
{
- buffblock_T *p, *np;
+ buffblock_T *p, *np;
for (p = buf->bh_first.b_next; p != NULL; p = np) {
np = p->b_next;
@@ -172,17 +172,15 @@ void free_buff(buffheader_T *buf)
buf->bh_first.b_next = NULL;
}
-/*
- * Return the contents of a buffer as a single string.
- * K_SPECIAL and CSI in the returned string are escaped.
- */
-static char_u *get_buffcont(buffheader_T *buffer,
- int dozero // count == zero is not an error
- )
+/// Return the contents of a buffer as a single string.
+/// K_SPECIAL and CSI in the returned string are escaped.
+///
+/// @param dozero count == zero is not an error
+static char_u *get_buffcont(buffheader_T *buffer, int dozero)
{
size_t count = 0;
- char_u *p = NULL;
- char_u *p2;
+ char_u *p = NULL;
+ char_u *p2;
// compute the total length of the string
for (const buffblock_T *bp = buffer->bh_first.b_next;
@@ -211,7 +209,7 @@ static char_u *get_buffcont(buffheader_T *buffer,
*/
char_u *get_recorded(void)
{
- char_u *p;
+ char_u *p;
size_t len;
p = get_buffcont(&recordbuff, TRUE);
@@ -231,8 +229,9 @@ char_u *get_recorded(void)
* When stopping recording from Insert mode with CTRL-O q, also remove the
* CTRL-O.
*/
- if (len > 0 && restart_edit != 0 && p[len - 1] == Ctrl_O)
+ if (len > 0 && restart_edit != 0 && p[len - 1] == Ctrl_O) {
p[len - 1] = NUL;
+ }
return p;
}
@@ -253,8 +252,7 @@ char_u *get_inserted(void)
/// @param[out] buf Buffer to add to.
/// @param[in] s String to add.
/// @param[in] slen String length or -1 for NUL-terminated string.
-static void add_buff(buffheader_T *const buf, const char *const s,
- ptrdiff_t slen)
+static void add_buff(buffheader_T *const buf, const char *const s, ptrdiff_t slen)
{
if (slen < 0) {
slen = (ptrdiff_t)strlen(s);
@@ -295,7 +293,6 @@ static void add_buff(buffheader_T *const buf, const char *const s,
buf->bh_curr->b_next = p;
buf->bh_curr = p;
}
- return;
}
/*
@@ -354,8 +351,9 @@ static int read_readbuffers(int advance)
int c;
c = read_readbuf(&readbuf1, advance);
- if (c == NUL)
+ if (c == NUL) {
c = read_readbuf(&readbuf2, advance);
+ }
return c;
}
@@ -524,7 +522,7 @@ void restoreRedobuff(save_redo_T *save_redo)
void AppendToRedobuff(const char *s)
{
if (!block_redo) {
- add_buff(&redobuff, (const char *)s, -1L);
+ add_buff(&redobuff, s, -1L);
}
}
@@ -583,8 +581,9 @@ void AppendToRedobuffLit(const char_u *str, int len)
*/
void AppendCharToRedobuff(int c)
{
- if (!block_redo)
+ if (!block_redo) {
add_char_buff(&redobuff, c);
+ }
}
/*
@@ -592,8 +591,9 @@ void AppendCharToRedobuff(int c)
*/
void AppendNumberToRedobuff(long n)
{
- if (!block_redo)
+ if (!block_redo) {
add_num_buff(&redobuff, n);
+ }
}
/*
@@ -865,10 +865,9 @@ void init_default_mappings(void)
// If silent is true, cmd_silent is set when the characters are obtained.
//
// return FAIL for failure, OK otherwise
-int ins_typebuf(char_u *str, int noremap, int offset,
- bool nottyped, bool silent)
+int ins_typebuf(char_u *str, int noremap, int offset, bool nottyped, bool silent)
{
- char_u *s1, *s2;
+ char_u *s1, *s2;
int newlen;
int addlen;
int i;
@@ -877,8 +876,9 @@ int ins_typebuf(char_u *str, int noremap, int offset,
int nrm;
init_typebuf();
- if (++typebuf.tb_change_cnt == 0)
+ if (++typebuf.tb_change_cnt == 0) {
typebuf.tb_change_cnt = 1;
+ }
addlen = (int)STRLEN(str);
@@ -924,12 +924,13 @@ int ins_typebuf(char_u *str, int noremap, int offset,
typebuf.tb_buf = s1;
memmove(s2 + newoff, typebuf.tb_noremap + typebuf.tb_off,
- (size_t)offset);
+ (size_t)offset);
memmove(s2 + newoff + offset + addlen,
- typebuf.tb_noremap + typebuf.tb_off + offset,
- (size_t)(typebuf.tb_len - offset));
- if (typebuf.tb_noremap != noremapbuf_init)
+ typebuf.tb_noremap + typebuf.tb_off + offset,
+ (size_t)(typebuf.tb_len - offset));
+ if (typebuf.tb_noremap != noremapbuf_init) {
xfree(typebuf.tb_noremap);
+ }
typebuf.tb_noremap = s2;
typebuf.tb_off = newoff;
@@ -948,26 +949,29 @@ int ins_typebuf(char_u *str, int noremap, int offset,
/*
* Adjust typebuf.tb_noremap[] for the new characters:
* If noremap == REMAP_NONE or REMAP_SCRIPT: new characters are
- * (sometimes) not remappable
+ * (sometimes) not remappable
* If noremap == REMAP_YES: all the new characters are mappable
* If noremap > 0: "noremap" characters are not remappable, the rest
- * mappable
+ * mappable
*/
- if (noremap == REMAP_SKIP)
+ if (noremap == REMAP_SKIP) {
nrm = 1;
- else if (noremap < 0)
+ } else if (noremap < 0) {
nrm = addlen;
- else
+ } else {
nrm = noremap;
- for (i = 0; i < addlen; ++i)
+ }
+ for (i = 0; i < addlen; ++i) {
typebuf.tb_noremap[typebuf.tb_off + i + offset] =
- (char_u)((--nrm >= 0) ? val : RM_YES);
+ (char_u)((--nrm >= 0) ? val : RM_YES);
+ }
/* tb_maplen and tb_silent only remember the length of mapped and/or
* silent mappings at the start of the buffer, assuming that a mapped
* sequence doesn't result in typed characters. */
- if (nottyped || typebuf.tb_maplen > offset)
+ if (nottyped || typebuf.tb_maplen > offset) {
typebuf.tb_maplen += addlen;
+ }
if (silent || typebuf.tb_silent > offset) {
typebuf.tb_silent += addlen;
cmd_silent = true;
@@ -995,22 +999,32 @@ void ins_char_typebuf(int c)
buf[3] = NUL;
} else {
buf[utf_char2bytes(c, buf)] = NUL;
+ char_u *p = buf;
+ while (*p) {
+ if ((uint8_t)(*p) == CSI || (uint8_t)(*p) == K_SPECIAL) {
+ bool is_csi = (uint8_t)(*p) == CSI;
+ memmove(p + 3, p + 1, STRLEN(p + 1) + 1);
+ *p++ = K_SPECIAL;
+ *p++ = is_csi ? KS_EXTRA : KS_SPECIAL;
+ *p++ = is_csi ? KE_CSI : KE_FILLER;
+ } else {
+ p++;
+ }
+ }
}
(void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent);
}
-/*
- * Return TRUE if the typeahead buffer was changed (while waiting for a
- * character to arrive). Happens when a message was received from a client or
- * from feedkeys().
- * But check in a more generic way to avoid trouble: When "typebuf.tb_buf"
- * changed it was reallocated and the old pointer can no longer be used.
- * Or "typebuf.tb_off" may have been changed and we would overwrite characters
- * that was just added.
- */
-bool typebuf_changed(
- int tb_change_cnt // old value of typebuf.tb_change_cnt
-)
+/// Return TRUE if the typeahead buffer was changed (while waiting for a
+/// character to arrive). Happens when a message was received from a client or
+/// from feedkeys().
+/// But check in a more generic way to avoid trouble: When "typebuf.tb_buf"
+/// changed it was reallocated and the old pointer can no longer be used.
+/// Or "typebuf.tb_off" may have been changed and we would overwrite characters
+/// that was just added.
+///
+/// @param tb_change_cnt old value of typebuf.tb_change_cnt
+bool typebuf_changed(int tb_change_cnt)
{
return tb_change_cnt != 0 && (typebuf.tb_change_cnt != tb_change_cnt
|| typebuf_was_filled
@@ -1051,8 +1065,9 @@ void del_typebuf(int len, int offset)
* Easy case: Just increase typebuf.tb_off.
*/
if (offset == 0 && typebuf.tb_buflen - (typebuf.tb_off + len)
- >= 3 * MAXMAPLEN + 3)
+ >= 3 * MAXMAPLEN + 3) {
typebuf.tb_off += len;
+ }
/*
* Have to move the characters in typebuf.tb_buf[] and typebuf.tb_noremap[]
*/
@@ -1063,9 +1078,9 @@ void del_typebuf(int len, int offset)
*/
if (typebuf.tb_off > MAXMAPLEN) {
memmove(typebuf.tb_buf + MAXMAPLEN,
- typebuf.tb_buf + typebuf.tb_off, (size_t)offset);
+ typebuf.tb_buf + typebuf.tb_off, (size_t)offset);
memmove(typebuf.tb_noremap + MAXMAPLEN,
- typebuf.tb_noremap + typebuf.tb_off, (size_t)offset);
+ typebuf.tb_noremap + typebuf.tb_off, (size_t)offset);
typebuf.tb_off = MAXMAPLEN;
}
// adjust typebuf.tb_buf (include the NUL at the end)
@@ -1075,8 +1090,8 @@ void del_typebuf(int len, int offset)
typebuf.tb_buf + i + len, (size_t)bytes);
// adjust typebuf.tb_noremap[]
memmove(typebuf.tb_noremap + typebuf.tb_off + offset,
- typebuf.tb_noremap + i + len,
- (size_t)(typebuf.tb_len - offset));
+ typebuf.tb_noremap + i + len,
+ (size_t)(typebuf.tb_len - offset));
}
if (typebuf.tb_maplen > offset) { // adjust tb_maplen
@@ -1168,8 +1183,9 @@ static void gotchars(const char_u *chars, size_t len)
void may_sync_undo(void)
{
if ((!(State & (INSERT + CMDLINE)) || arrow_used)
- && scriptin[curscript] == NULL)
+ && scriptin[curscript] == NULL) {
u_sync(false);
+ }
}
/*
@@ -1185,8 +1201,9 @@ void alloc_typebuf(void)
typebuf.tb_maplen = 0;
typebuf.tb_silent = 0;
typebuf.tb_no_abbr_cnt = 0;
- if (++typebuf.tb_change_cnt == 0)
+ if (++typebuf.tb_change_cnt == 0) {
typebuf.tb_change_cnt = 1;
+ }
}
/*
@@ -1264,13 +1281,10 @@ void restore_typeahead(tasave_T *tp)
readbuf2 = tp->save_readbuf2;
}
-/*
- * Open a new script file for the ":source!" command.
- */
-void openscript(
- char_u *name,
- bool directly // when true execute directly
-)
+/// Open a new script file for the ":source!" command.
+///
+/// @param directly when true execute directly
+void openscript(char_u *name, bool directly)
{
if (curscript + 1 == NSCRIPT) {
EMSG(_(e_nesting));
@@ -1351,15 +1365,17 @@ static void closescript(void)
file_free(scriptin[curscript], false);
scriptin[curscript] = NULL;
- if (curscript > 0)
+ if (curscript > 0) {
--curscript;
+ }
}
#if defined(EXITFREE)
void close_all_scripts(void)
{
- while (scriptin[0] != NULL)
+ while (scriptin[0] != NULL) {
closescript();
+ }
}
#endif
@@ -1460,60 +1476,81 @@ int vgetc(void)
continue;
}
c = TO_SPECIAL(c2, c);
-
}
// a keypad or special function key was not mapped, use it like
// its ASCII equivalent
switch (c) {
- case K_KPLUS: c = '+'; break;
- case K_KMINUS: c = '-'; break;
- case K_KDIVIDE: c = '/'; break;
- case K_KMULTIPLY: c = '*'; break;
- case K_KENTER: c = CAR; break;
- case K_KPOINT: c = '.'; break;
- case K_KCOMMA: c = ','; break;
- case K_KEQUAL: c = '='; break;
- case K_K0: c = '0'; break;
- case K_K1: c = '1'; break;
- case K_K2: c = '2'; break;
- case K_K3: c = '3'; break;
- case K_K4: c = '4'; break;
- case K_K5: c = '5'; break;
- case K_K6: c = '6'; break;
- case K_K7: c = '7'; break;
- case K_K8: c = '8'; break;
- case K_K9: c = '9'; break;
-
- case K_XHOME:
- case K_ZHOME:
- if (mod_mask == MOD_MASK_SHIFT) {
- c = K_S_HOME;
- mod_mask = 0;
- } else if (mod_mask == MOD_MASK_CTRL) {
- c = K_C_HOME;
- mod_mask = 0;
- } else {
- c = K_HOME;
- }
- break;
- case K_XEND:
- case K_ZEND:
- if (mod_mask == MOD_MASK_SHIFT) {
- c = K_S_END;
- mod_mask = 0;
- } else if (mod_mask == MOD_MASK_CTRL) {
- c = K_C_END;
- mod_mask = 0;
- } else {
- c = K_END;
- }
- break;
+ case K_KPLUS:
+ c = '+'; break;
+ case K_KMINUS:
+ c = '-'; break;
+ case K_KDIVIDE:
+ c = '/'; break;
+ case K_KMULTIPLY:
+ c = '*'; break;
+ case K_KENTER:
+ c = CAR; break;
+ case K_KPOINT:
+ c = '.'; break;
+ case K_KCOMMA:
+ c = ','; break;
+ case K_KEQUAL:
+ c = '='; break;
+ case K_K0:
+ c = '0'; break;
+ case K_K1:
+ c = '1'; break;
+ case K_K2:
+ c = '2'; break;
+ case K_K3:
+ c = '3'; break;
+ case K_K4:
+ c = '4'; break;
+ case K_K5:
+ c = '5'; break;
+ case K_K6:
+ c = '6'; break;
+ case K_K7:
+ c = '7'; break;
+ case K_K8:
+ c = '8'; break;
+ case K_K9:
+ c = '9'; break;
+
+ case K_XHOME:
+ case K_ZHOME:
+ if (mod_mask == MOD_MASK_SHIFT) {
+ c = K_S_HOME;
+ mod_mask = 0;
+ } else if (mod_mask == MOD_MASK_CTRL) {
+ c = K_C_HOME;
+ mod_mask = 0;
+ } else {
+ c = K_HOME;
+ }
+ break;
+ case K_XEND:
+ case K_ZEND:
+ if (mod_mask == MOD_MASK_SHIFT) {
+ c = K_S_END;
+ mod_mask = 0;
+ } else if (mod_mask == MOD_MASK_CTRL) {
+ c = K_C_END;
+ mod_mask = 0;
+ } else {
+ c = K_END;
+ }
+ break;
- case K_XUP: c = K_UP; break;
- case K_XDOWN: c = K_DOWN; break;
- case K_XLEFT: c = K_LEFT; break;
- case K_XRIGHT: c = K_RIGHT; break;
+ case K_XUP:
+ c = K_UP; break;
+ case K_XDOWN:
+ c = K_DOWN; break;
+ case K_XLEFT:
+ c = K_LEFT; break;
+ case K_XRIGHT:
+ c = K_RIGHT; break;
}
// For a multi-byte character get all the bytes and return the
@@ -1532,7 +1569,7 @@ int vgetc(void)
// a CSI (0x9B),
// of a K_SPECIAL - KS_EXTRA - KE_CSI, which is CSI too.
c = vgetorpeek(true);
- if (vgetorpeek(true) == (int)KE_CSI && c == KS_EXTRA) {
+ if (vgetorpeek(true) == KE_CSI && c == KS_EXTRA) {
buf[i] = CSI;
}
}
@@ -1547,9 +1584,9 @@ int vgetc(void)
if (!no_mapping && KeyTyped
&& (mod_mask == MOD_MASK_ALT || mod_mask == MOD_MASK_META)) {
mod_mask = 0;
- stuffcharReadbuff(c);
- u_sync(false);
- c = ESC;
+ ins_char_typebuf(c);
+ ins_char_typebuf(ESC);
+ continue;
}
break;
@@ -1608,8 +1645,9 @@ int plain_vgetc(void)
*/
int vpeekc(void)
{
- if (old_char != -1)
+ if (old_char != -1) {
return old_char;
+ }
return vgetorpeek(false);
}
@@ -1623,8 +1661,9 @@ int vpeekc_any(void)
int c;
c = vpeekc();
- if (c == NUL && typebuf.tb_len > 0)
+ if (c == NUL && typebuf.tb_len > 0) {
c = ESC;
+ }
return c;
}
@@ -1678,10 +1717,10 @@ static int vgetorpeek(bool advance)
{
int c, c1;
int keylen;
- char_u *s;
- mapblock_T *mp;
- mapblock_T *mp2;
- mapblock_T *mp_match;
+ char_u *s;
+ mapblock_T *mp;
+ mapblock_T *mp2;
+ mapblock_T *mp_match;
int mp_match_len = 0;
bool timedout = false; // waited for more than 1 second
// for mapping to complete
@@ -1700,7 +1739,7 @@ static int vgetorpeek(bool advance)
/*
* This function doesn't work very well when called recursively. This may
* happen though, because of:
- * 1. The call to add_to_showcmd(). char_avail() is then used to check if
+ * 1. The call to add_to_showcmd(). char_avail() is then used to check if
* there is a character available, which calls this function. In that
* case we must return NUL, to indicate no character is available.
* 2. A GUI callback function writes to the screen, causing a
@@ -1709,16 +1748,17 @@ static int vgetorpeek(bool advance)
* thus it should be OK. But don't get a key from the user then.
*/
if (vgetc_busy > 0
- && ex_normal_busy == 0
- )
+ && ex_normal_busy == 0) {
return NUL;
+ }
local_State = get_real_state();
++vgetc_busy;
- if (advance)
+ if (advance) {
KeyStuffed = FALSE;
+ }
init_typebuf();
start_stuff();
@@ -1731,8 +1771,9 @@ static int vgetorpeek(bool advance)
*/
if (typeahead_char != 0) {
c = typeahead_char;
- if (advance)
+ if (advance) {
typeahead_char = 0;
+ }
} else {
c = read_readbuffers(advance);
}
@@ -1802,7 +1843,7 @@ static int vgetorpeek(bool advance)
* - typebuf.tb_buf[typebuf.tb_off] should not be remapped
* - in insert or cmdline mode and 'paste' option set
* - waiting for "hit return to continue" and CR or SPACE
- * typed
+ * typed
* - waiting for a char with --more--
* - in Ctrl-X mode, and we get a valid char for that mode
*/
@@ -1821,8 +1862,8 @@ static int vgetorpeek(bool advance)
&& State != CONFIRM
&& !((ctrl_x_mode_not_default() && vim_is_ctrl_x_key(c1))
|| ((compl_cont_status & CONT_LOCAL)
- && (c1 == Ctrl_N || c1 == Ctrl_P)))
- ) {
+ && (c1 == Ctrl_N ||
+ c1 == Ctrl_P)))) {
if (c1 == K_SPECIAL) {
nolmaplen = 2;
} else {
@@ -1864,14 +1905,16 @@ static int vgetorpeek(bool advance)
// find the match length of this mapping
for (mlen = 1; mlen < typebuf.tb_len; mlen++) {
c2 = typebuf.tb_buf[typebuf.tb_off + mlen];
- if (nomap > 0)
+ if (nomap > 0) {
--nomap;
- else if (c2 == K_SPECIAL)
+ } else if (c2 == K_SPECIAL) {
nomap = 2;
- else
+ } else {
LANGMAP_ADJUST(c2, TRUE);
- if (mp->m_keys[mlen] != c2)
+ }
+ if (mp->m_keys[mlen] != c2) {
break;
+ }
}
/* Don't allow mapping the first byte(s) of a
@@ -1902,17 +1945,21 @@ static int vgetorpeek(bool advance)
&& (mp->m_keys[0] != K_SPECIAL
|| mp->m_keys[1] != KS_EXTRA
|| mp->m_keys[2]
- != (int)KE_SNR))
+ != KE_SNR)) {
continue;
+ }
/*
* If one of the typed keys cannot be
* remapped, skip the entry.
*/
- for (n = mlen; --n >= 0; )
- if (*s++ & (RM_NONE|RM_ABBR))
+ for (n = mlen; --n >= 0; ) {
+ if (*s++ & (RM_NONE|RM_ABBR)) {
break;
- if (n >= 0)
+ }
+ }
+ if (n >= 0) {
continue;
+ }
if (keylen > typebuf.tb_len) {
if (!timedout && !(mp_match != NULL
@@ -2030,10 +2077,11 @@ static int vgetorpeek(bool advance)
*/
if (++mapdepth >= p_mmd) {
EMSG(_("E223: recursive mapping"));
- if (State & CMDLINE)
+ if (State & CMDLINE) {
redrawcmdline();
- else
+ } else {
setcursor();
+ }
flush_buffers(FLUSH_MINIMAL);
mapdepth = 0; // for next one
c = -1;
@@ -2090,9 +2138,9 @@ static int vgetorpeek(bool advance)
* If m_noremap is set, don't remap the whole 'to'
* part.
*/
- if (s == NULL)
+ if (s == NULL) {
i = FAIL;
- else {
+ } else {
int noremap;
// If this is a LANGMAP mapping, then we didn't record the keys
@@ -2101,20 +2149,22 @@ static int vgetorpeek(bool advance)
gotchars(s, STRLEN(s));
}
- if (save_m_noremap != REMAP_YES)
+ if (save_m_noremap != REMAP_YES) {
noremap = save_m_noremap;
- else if (
- STRNCMP(s, save_m_keys != NULL
+ } else if (
+ STRNCMP(s, save_m_keys != NULL
? save_m_keys : mp->m_keys,
- (size_t)keylen)
- != 0)
+ (size_t)keylen)
+ != 0) {
noremap = REMAP_YES;
- else
+ } else {
noremap = REMAP_SKIP;
+ }
i = ins_typebuf(s, noremap,
- 0, TRUE, cmd_silent || save_m_silent);
- if (save_m_expr)
+ 0, TRUE, cmd_silent || save_m_silent);
+ if (save_m_expr) {
xfree(s);
+ }
}
xfree(save_m_keys);
xfree(save_m_str);
@@ -2152,7 +2202,7 @@ static int vgetorpeek(bool advance)
&& (c = inchar(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len,
3, 25L)) == 0) {
colnr_T col = 0, vcol;
- char_u *ptr;
+ char_u *ptr;
if (mode_displayed) {
unshowmode(true);
@@ -2177,7 +2227,7 @@ static int vgetorpeek(bool advance)
if (!ascii_iswhite(ptr[col])) {
curwin->w_wcol = vcol;
}
- vcol += lbr_chartabsize(ptr, ptr + col, (colnr_T)vcol);
+ vcol += lbr_chartabsize(ptr, ptr + col, vcol);
col += utfc_ptr2len(ptr + col);
}
curwin->w_wrow = curwin->w_cline_row
@@ -2299,11 +2349,13 @@ static int vgetorpeek(bool advance)
curwin->w_wcol = new_wcol;
curwin->w_wrow = new_wrow;
push_showcmd();
- if (typebuf.tb_len > SHOWCMD_COLS)
+ if (typebuf.tb_len > SHOWCMD_COLS) {
i = typebuf.tb_len - SHOWCMD_COLS;
- while (i < typebuf.tb_len)
+ }
+ while (i < typebuf.tb_len) {
(void)add_to_showcmd(typebuf.tb_buf[typebuf.tb_off
+ i++]);
+ }
curwin->w_wcol = old_wcol;
curwin->w_wrow = old_wrow;
}
@@ -2346,8 +2398,9 @@ static int vgetorpeek(bool advance)
typebuf.tb_buflen - typebuf.tb_off - typebuf.tb_len - 1,
wait_time);
- if (i != 0)
+ if (i != 0) {
pop_showcmd();
+ }
if (c1 == 1) {
if (State & INSERT) {
edit_unputchar();
@@ -2383,8 +2436,8 @@ static int vgetorpeek(bool advance)
/*
* The "INSERT" message is taken care of here:
- * if we return an ESC to exit insert mode, the message is deleted
- * if we don't return an ESC but deleted the message before, redisplay it
+ * if we return an ESC to exit insert mode, the message is deleted
+ * if we don't return an ESC but deleted the message before, redisplay it
*/
if (advance && p_smd && msg_silent == 0 && (State & INSERT)) {
if (c == ESC && !mode_deleted && !no_mapping && mode_displayed) {
@@ -2418,34 +2471,30 @@ static int vgetorpeek(bool advance)
return c;
}
-/*
- * inchar() - get one character from
- * 1. a scriptfile
- * 2. the keyboard
- *
- * As much characters as we can get (up to 'maxlen') are put in "buf" and
- * NUL terminated (buffer length must be 'maxlen' + 1).
- * Minimum for "maxlen" is 3!!!!
- *
- * "tb_change_cnt" is the value of typebuf.tb_change_cnt if "buf" points into
- * it. When typebuf.tb_change_cnt changes (e.g., when a message is received
- * from a remote client) "buf" can no longer be used. "tb_change_cnt" is 0
- * otherwise.
- *
- * If we got an interrupt all input is read until none is available.
- *
- * If wait_time == 0 there is no waiting for the char.
- * If wait_time == n we wait for n msec for a character to arrive.
- * If wait_time == -1 we wait forever for a character to arrive.
- *
- * Return the number of obtained characters.
- * Return -1 when end of input script reached.
- */
-int inchar(
- char_u *buf,
- int maxlen,
- long wait_time // milli seconds
-)
+/// inchar() - get one character from
+/// 1. a scriptfile
+/// 2. the keyboard
+///
+/// As much characters as we can get (up to 'maxlen') are put in "buf" and
+/// NUL terminated (buffer length must be 'maxlen' + 1).
+/// Minimum for "maxlen" is 3!!!!
+///
+/// "tb_change_cnt" is the value of typebuf.tb_change_cnt if "buf" points into
+/// it. When typebuf.tb_change_cnt changes (e.g., when a message is received
+/// from a remote client) "buf" can no longer be used. "tb_change_cnt" is 0
+/// otherwise.
+///
+/// If we got an interrupt all input is read until none is available.
+///
+/// If wait_time == 0 there is no waiting for the char.
+/// If wait_time == n we wait for n msec for a character to arrive.
+/// If wait_time == -1 we wait forever for a character to arrive.
+///
+/// Return the number of obtained characters.
+/// Return -1 when end of input script reached.
+///
+/// @param wait_time milli seconds
+int inchar(char_u *buf, int maxlen, long wait_time)
{
int len = 0; // Init for GCC.
int retesc = false; // Return ESC with gotint.
@@ -2551,10 +2600,10 @@ int fix_input_buffer(char_u *buf, int len)
// Reading from script, need to process special bytes
int i;
- char_u *p = buf;
+ char_u *p = buf;
// Two characters are special: NUL and K_SPECIAL.
- // Replace NUL by K_SPECIAL KS_ZERO KE_FILLER
+ // Replace NUL by K_SPECIAL KS_ZERO KE_FILLER
// Replace K_SPECIAL by K_SPECIAL KS_SPECIAL KE_FILLER
// Replace CSI by K_SPECIAL KS_EXTRA KE_CSI
for (i = len; --i >= 0; ++p) {
@@ -2595,9 +2644,8 @@ int fix_input_buffer(char_u *buf, int len)
/// @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.
-void set_maparg_lhs_rhs(const char_u *orig_lhs, const size_t orig_lhs_len,
- const char_u *orig_rhs, const size_t orig_rhs_len,
- int cpo_flags, MapArguments *mapargs)
+void set_maparg_lhs_rhs(const char_u *orig_lhs, const size_t orig_lhs_len, const char_u *orig_rhs,
+ const size_t orig_rhs_len, int cpo_flags, MapArguments *mapargs)
{
char_u *lhs_buf = NULL;
char_u *rhs_buf = NULL;
@@ -2612,12 +2660,11 @@ void set_maparg_lhs_rhs(const char_u *orig_lhs, const size_t orig_lhs_len,
char_u *replaced = replace_termcodes(orig_lhs, orig_lhs_len, &lhs_buf,
true, true, true, cpo_flags);
mapargs->lhs_len = STRLEN(replaced);
- xstrlcpy((char *)mapargs->lhs, (char *)replaced, sizeof(mapargs->lhs));
+ STRLCPY(mapargs->lhs, replaced, sizeof(mapargs->lhs));
mapargs->orig_rhs_len = orig_rhs_len;
mapargs->orig_rhs = xcalloc(mapargs->orig_rhs_len + 1, sizeof(char_u));
- xstrlcpy((char *)mapargs->orig_rhs, (char *)orig_rhs,
- mapargs->orig_rhs_len + 1);
+ STRLCPY(mapargs->orig_rhs, orig_rhs, mapargs->orig_rhs_len + 1);
if (STRICMP(orig_rhs, "<nop>") == 0) { // "<Nop>" means nothing
mapargs->rhs = xcalloc(1, sizeof(char_u)); // single null-char
@@ -2629,7 +2676,7 @@ void set_maparg_lhs_rhs(const char_u *orig_lhs, const size_t orig_lhs_len,
mapargs->rhs_len = STRLEN(replaced);
mapargs->rhs_is_noop = false;
mapargs->rhs = xcalloc(mapargs->rhs_len + 1, sizeof(char_u));
- xstrlcpy((char *)mapargs->rhs, (char *)replaced, mapargs->rhs_len + 1);
+ STRLCPY(mapargs->rhs, replaced, mapargs->rhs_len + 1);
}
xfree(lhs_buf);
@@ -2737,7 +2784,7 @@ int str_to_mapargs(const char_u *strargs, bool is_unmap, MapArguments *mapargs)
// (e.g. "<Space>" is longer than ' '), so first copy into a buffer.
size_t orig_lhs_len = (size_t)(lhs_end - to_parse);
char_u *lhs_to_replace = xcalloc(orig_lhs_len + 1, sizeof(char_u));
- xstrlcpy((char *)lhs_to_replace, (char *)to_parse, orig_lhs_len + 1);
+ STRLCPY(lhs_to_replace, to_parse, orig_lhs_len + 1);
size_t orig_rhs_len = STRLEN(rhs_start);
set_maparg_lhs_rhs(lhs_to_replace, orig_lhs_len,
@@ -2764,11 +2811,10 @@ int str_to_mapargs(const char_u *strargs, bool is_unmap, MapArguments *mapargs)
/// @param mode @see do_map
/// @param is_abbrev @see do_map
/// @param buf Target Buffer
-int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
- buf_T *buf)
+int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, buf_T *buf)
{
- mapblock_T *mp, **mpp;
- char_u *p;
+ mapblock_T *mp, **mpp;
+ char_u *p;
int n;
int len = 0; // init for GCC
int did_it = false;
@@ -2777,8 +2823,8 @@ int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
int retval = 0;
int hash;
int new_hash;
- mapblock_T **abbr_table;
- mapblock_T **map_table;
+ mapblock_T **abbr_table;
+ mapblock_T **map_table;
int noremap;
map_table = maphash;
@@ -2813,7 +2859,7 @@ int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
}
char_u *lhs = (char_u *)&args->lhs;
- char_u *rhs = (char_u *)args->rhs;
+ char_u *rhs = args->rhs;
char_u *orig_rhs = args->orig_rhs;
// check arguments and translate function keys
@@ -3148,15 +3194,15 @@ int do_map(int maptype, char_u *arg, int mode, bool is_abbrev)
MapArguments parsed_args;
int result = str_to_mapargs(arg, maptype == 1, &parsed_args);
switch (result) {
- case 0:
- break;
- case 1:
- // invalid arguments
- goto free_and_return;
- default:
- assert(false && "Unknown return code from str_to_mapargs!");
- result = -1;
- goto free_and_return;
+ case 0:
+ break;
+ case 1:
+ // invalid arguments
+ goto free_and_return;
+ default:
+ assert(false && "Unknown return code from str_to_mapargs!");
+ result = -1;
+ goto free_and_return;
} // switch
result = buf_do_map(maptype, &parsed_args, mode, is_abbrev, curbuf);
@@ -3173,7 +3219,7 @@ free_and_return:
*/
static void mapblock_free(mapblock_T **mpp)
{
- mapblock_T *mp;
+ mapblock_T *mp;
mp = *mpp;
xfree(mp->m_keys);
@@ -3199,7 +3245,7 @@ static void validate_maphash(void)
*/
int get_map_mode(char_u **cmdp, bool forceit)
{
- char_u *p;
+ char_u *p;
int modec;
int mode;
@@ -3253,21 +3299,19 @@ void map_clear_mode(char_u *cmdp, char_u *arg, int forceit, int abbr)
mode = get_map_mode(&cmdp, forceit);
map_clear_int(curbuf, mode,
- local,
- abbr);
+ local,
+ abbr);
}
-/*
- * Clear all mappings in "mode".
- */
-void map_clear_int(
- buf_T *buf, // buffer for local mappings
- int mode, // mode in which to delete
- bool local, // true for buffer-local mappings
- bool abbr // true for abbreviations
-)
+/// Clear all mappings in "mode".
+///
+/// @param buf, buffer for local mappings
+/// @param mode mode in which to delete
+/// @param local true for buffer-local mappings
+/// @param abbr true for abbreviations
+void map_clear_int(buf_T *buf, int mode, bool local, bool abbr)
{
- mapblock_T *mp, **mpp;
+ mapblock_T *mp, **mpp;
int hash;
int new_hash;
@@ -3284,10 +3328,11 @@ void map_clear_int(
mpp = &first_abbr;
}
} else {
- if (local)
+ if (local) {
mpp = &buf->b_maphash[hash];
- else
+ } else {
mpp = &maphash[hash];
+ }
}
while (*mpp != NULL) {
mp = *mpp;
@@ -3365,10 +3410,8 @@ char *map_mode_to_chars(int mode)
return (char *)mapmode.ga_data;
}
-static void showmap(
- mapblock_T *mp,
- bool local // true for buffer-local map
-)
+/// @param local true for buffer-local map
+static void showmap(mapblock_T *mp, bool local)
{
size_t len = 1;
@@ -3390,8 +3433,9 @@ static void showmap(
xfree(mapchars);
}
- while (++len <= 3)
+ while (++len <= 3) {
msg_putchar(' ');
+ }
// Display the LHS. Get length of what we write.
len = (size_t)msg_outtrans_special(mp->m_keys, true, 0);
@@ -3408,10 +3452,11 @@ static void showmap(
msg_putchar(' ');
}
- if (local)
+ if (local) {
msg_putchar('@');
- else
+ } else {
msg_putchar(' ');
+ }
/* Use FALSE below if we only want things like <Up> to show up as such on
* the rhs, and not M-x etc, TRUE gets both -- webb */
@@ -3441,8 +3486,7 @@ static void showmap(
/// @param[in] abbr true if checking abbreviations in place of mappings.
///
/// @return true if there is at least one mapping with given parameters.
-bool map_to_exists(const char *const str, const char *const modechars,
- const bool abbr)
+bool map_to_exists(const char *const str, const char *const modechars, const bool abbr)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
{
int mode = 0;
@@ -3487,7 +3531,7 @@ bool map_to_exists(const char *const str, const char *const modechars,
/// @return true if there is at least one mapping with given parameters.
int map_to_exists_mode(const char *const rhs, const int mode, const bool abbr)
{
- mapblock_T *mp;
+ mapblock_T *mp;
int hash;
bool exp_buffer = false;
@@ -3533,29 +3577,25 @@ static int expand_mapmodes = 0;
static bool expand_isabbrev = false;
static bool expand_buffer = false;
-/*
- * Work out what to complete when doing command line completion of mapping
- * or abbreviation names.
- */
-char_u *set_context_in_map_cmd(
- expand_T *xp,
- char_u *cmd,
- char_u *arg,
- bool forceit, // true if '!' given
- bool isabbrev, // true if abbreviation
- bool isunmap, // true if unmap/unabbrev command
- cmdidx_T cmdidx
-)
+/// Work out what to complete when doing command line completion of mapping
+/// or abbreviation names.
+///
+/// @param forceit true if '!' given
+/// @param isabbrev true if abbreviation
+/// @param isunmap true if unmap/unabbrev command
+char_u *set_context_in_map_cmd(expand_T *xp, char_u *cmd, char_u *arg, bool forceit, bool isabbrev,
+ bool isunmap, cmdidx_T cmdidx)
{
- if (forceit && cmdidx != CMD_map && cmdidx != CMD_unmap)
+ if (forceit && cmdidx != CMD_map && cmdidx != CMD_unmap) {
xp->xp_context = EXPAND_NOTHING;
- else {
- if (isunmap)
+ } else {
+ if (isunmap) {
expand_mapmodes = get_map_mode(&cmd, forceit || isabbrev);
- else {
+ } else {
expand_mapmodes = INSERT + CMDLINE;
- if (!isabbrev)
+ if (!isabbrev) {
expand_mapmodes += VISUAL + SELECTMODE + NORMAL + OP_PENDING;
+ }
}
expand_isabbrev = isabbrev;
xp->xp_context = EXPAND_MAPPINGS;
@@ -3603,11 +3643,11 @@ char_u *set_context_in_map_cmd(
// Return OK if matches found, FAIL otherwise.
int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file)
{
- mapblock_T *mp;
+ mapblock_T *mp;
int hash;
int count;
int round;
- char_u *p;
+ char_u *p;
int i;
validate_maphash();
@@ -3642,10 +3682,11 @@ int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file)
}
if (vim_regexec(regmatch, p, (colnr_T)0)) {
- if (round == 1)
+ if (round == 1) {
++count;
- else
+ } else {
(*file)[count++] = vim_strsave(p);
+ }
}
}
@@ -3655,17 +3696,18 @@ int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file)
break; // for (hash)
}
mp = first_abbr;
- } else if (expand_buffer)
+ } else if (expand_buffer) {
mp = curbuf->b_maphash[hash];
- else
+ } else {
mp = maphash[hash];
+ }
for (; mp; mp = mp->m_next) {
if (mp->m_mode & expand_mapmodes) {
p = translate_mapping(mp->m_keys, CPO_TO_CPO_FLAGS);
if (p != NULL && vim_regexec(regmatch, p, (colnr_T)0)) {
- if (round == 1)
+ if (round == 1) {
++count;
- else {
+ } else {
(*file)[count++] = p;
p = NULL;
}
@@ -3685,9 +3727,9 @@ int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file)
} // for (round)
if (count > 1) {
- char_u **ptr1;
- char_u **ptr2;
- char_u **ptr3;
+ char_u **ptr1;
+ char_u **ptr2;
+ char_u **ptr3;
// Sort the matches
sort_strings(*file, count);
@@ -3698,9 +3740,9 @@ int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file)
ptr3 = ptr1 + count;
while (ptr2 < ptr3) {
- if (STRCMP(*ptr1, *ptr2))
+ if (STRCMP(*ptr1, *ptr2)) {
*++ptr1 = *ptr2++;
- else {
+ } else {
xfree(*ptr2++);
count--;
}
@@ -3732,10 +3774,10 @@ bool check_abbr(int c, char_u *ptr, int col, int mincol)
int len;
int scol; // starting column of the abbr.
int j;
- char_u *s;
+ char_u *s;
char_u tb[MB_MAXBYTES + 4];
- mapblock_T *mp;
- mapblock_T *mp2;
+ mapblock_T *mp;
+ mapblock_T *mp2;
int clen = 0; // length in characters
bool is_id = true;
@@ -3779,8 +3821,9 @@ bool check_abbr(int c, char_u *ptr, int col, int mincol)
scol = (int)(p - ptr);
}
- if (scol < mincol)
+ if (scol < mincol) {
scol = mincol;
+ }
if (scol < col) { // there is a word in front of the cursor
ptr += scol;
len = col - scol;
@@ -3858,17 +3901,19 @@ bool check_abbr(int c, char_u *ptr, int col, int mincol)
// insert the last typed char
(void)ins_typebuf(tb, 1, 0, true, mp->m_silent);
}
- if (mp->m_expr)
+ if (mp->m_expr) {
s = eval_map_expr(mp->m_str, c);
- else
+ } else {
s = mp->m_str;
+ }
if (s != NULL) {
// insert the to string
(void)ins_typebuf(s, mp->m_noremap, 0, true, mp->m_silent);
// no abbrev. for these chars
typebuf.tb_no_abbr_cnt += (int)STRLEN(s) + j + 1;
- if (mp->m_expr)
+ if (mp->m_expr) {
xfree(s);
+ }
}
tb[0] = Ctrl_H;
@@ -3883,20 +3928,16 @@ bool check_abbr(int c, char_u *ptr, int col, int mincol)
return false;
}
-/*
- * Evaluate the RHS of a mapping or abbreviations and take care of escaping
- * special characters.
- */
-static char_u *
-eval_map_expr (
- char_u *str,
- int c // NUL or typed character for abbreviation
-)
+/// Evaluate the RHS of a mapping or abbreviations and take care of escaping
+/// special characters.
+///
+/// @param c NUL or typed character for abbreviation
+static char_u *eval_map_expr(char_u *str, int c)
{
- char_u *res;
- char_u *p;
- char_u *expr;
- char_u *save_cmd;
+ char_u *res;
+ char_u *p;
+ char_u *expr;
+ char_u *save_cmd;
pos_T save_cursor;
int save_msg_col;
int save_msg_row;
@@ -3926,8 +3967,9 @@ eval_map_expr (
restore_cmdline_alloc(save_cmd);
xfree(expr);
- if (p == NULL)
+ if (p == NULL) {
return NULL;
+ }
// Escape CSI in the result to be able to use the string as typeahead.
res = vim_strsave_escape_csi(p);
xfree(p);
@@ -3970,7 +4012,7 @@ char_u *vim_strsave_escape_csi(char_u *p)
*/
void vim_unescape_csi(char_u *p)
{
- char_u *s = p, *d = p;
+ char_u *s = p, *d = p;
while (*s != NUL) {
if (s[0] == K_SPECIAL && s[1] == KS_SPECIAL && s[2] == KE_FILLER) {
@@ -3980,26 +4022,23 @@ void vim_unescape_csi(char_u *p)
&& s[1] == KS_EXTRA && s[2] == (int)KE_CSI) {
*d++ = CSI;
s += 3;
- } else
+ } else {
*d++ = *s++;
+ }
}
*d = NUL;
}
-/*
- * Write map commands for the current mappings to an .exrc file.
- * Return FAIL on error, OK otherwise.
- */
-int
-makemap(
- FILE *fd,
- buf_T *buf // buffer for local mappings or NULL
-)
+/// Write map commands for the current mappings to an .exrc file.
+/// Return FAIL on error, OK otherwise.
+///
+/// @param buf buffer for local mappings or NULL
+int makemap(FILE *fd, buf_T *buf)
{
- mapblock_T *mp;
+ mapblock_T *mp;
char_u c1, c2, c3;
- char_u *p;
- char *cmd;
+ char_u *p;
+ char *cmd;
int abbr;
int hash;
bool did_cpo = false;
@@ -4209,13 +4248,14 @@ makemap(
// return FAIL for failure, OK otherwise
int put_escstr(FILE *fd, char_u *strstart, int what)
{
- char_u *str = strstart;
+ char_u *str = strstart;
int c;
// :map xx <Nop>
if (*str == NUL && what == 1) {
- if (fprintf(fd, "<Nop>") < 0)
+ if (fprintf(fd, "<Nop>") < 0) {
return FAIL;
+ }
return OK;
}
@@ -4224,9 +4264,11 @@ int put_escstr(FILE *fd, char_u *strstart, int what)
// K_SPECIAL and CSI bytes.
const char *p = mb_unescape((const char **)&str);
if (p != NULL) {
- while (*p != NUL)
- if (fputc(*p++, fd) < 0)
+ while (*p != NUL) {
+ if (fputc(*p++, fd) < 0) {
return FAIL;
+ }
+ }
--str;
continue;
}
@@ -4261,11 +4303,13 @@ int put_escstr(FILE *fd, char_u *strstart, int what)
*/
if (c == NL) {
if (what == 2) {
- if (fprintf(fd, "\\\026\n") < 0)
+ if (fprintf(fd, "\\\026\n") < 0) {
return FAIL;
+ }
} else {
- if (fprintf(fd, "<NL>") < 0)
+ if (fprintf(fd, "<NL>") < 0) {
return FAIL;
+ }
}
continue;
}
@@ -4282,39 +4326,38 @@ int put_escstr(FILE *fd, char_u *strstart, int what)
* A space in the lhs of a :map needs a CTRL-V.
*/
if (what == 2 && (ascii_iswhite(c) || c == '"' || c == '\\')) {
- if (putc('\\', fd) < 0)
+ if (putc('\\', fd) < 0) {
return FAIL;
+ }
} else if (c < ' ' || c > '~' || c == '|'
|| (what == 0 && c == ' ')
|| (what == 1 && str == strstart && c == ' ')
|| (what != 2 && c == '<')) {
- if (putc(Ctrl_V, fd) < 0)
+ if (putc(Ctrl_V, fd) < 0) {
return FAIL;
+ }
}
- if (putc(c, fd) < 0)
+ if (putc(c, fd) < 0) {
return FAIL;
+ }
}
return OK;
}
-/*
- * Check the string "keys" against the lhs of all mappings.
- * Return pointer to rhs of mapping (mapblock->m_str).
- * NULL when no mapping found.
- */
-char_u *
-check_map (
- char_u *keys,
- int mode,
- int exact, // require exact match
- int ign_mod, // ignore preceding modifier
- int abbr, // do abbreviations
- mapblock_T **mp_ptr, // return: pointer to mapblock or NULL
- int *local_ptr // return: buffer-local mapping or NULL
-)
+/// Check the string "keys" against the lhs of all mappings.
+/// Return pointer to rhs of mapping (mapblock->m_str).
+/// NULL when no mapping found.
+///
+/// @param exact require exact match
+/// @param ign_mod ignore preceding modifier
+/// @param abbr do abbreviations
+/// @param mp_ptr return: pointer to mapblock or NULL
+/// @param local_ptr return: buffer-local mapping or NULL
+char_u *check_map(char_u *keys, int mode, int exact, int ign_mod, int abbr, mapblock_T **mp_ptr,
+ int *local_ptr)
{
int len, minlen;
- mapblock_T *mp;
+ mapblock_T *mp;
validate_maphash();
@@ -4349,10 +4392,12 @@ check_map (
}
minlen = keylen < len ? keylen : len;
if (STRNCMP(s, keys, minlen) == 0) {
- if (mp_ptr != NULL)
+ if (mp_ptr != NULL) {
*mp_ptr = mp;
- if (local_ptr != NULL)
+ }
+ if (local_ptr != NULL) {
*local_ptr = local;
+ }
return mp->m_str;
}
}
@@ -4374,8 +4419,8 @@ check_map (
/// @param nore If true, make a non-recursive mapping.
void add_map(char_u *map, int mode, bool nore)
{
- char_u *s;
- char_u *cpo_save = p_cpo;
+ char_u *s;
+ char_u *cpo_save = p_cpo;
p_cpo = (char_u *)""; // Allow <> notation
// Need to put string in allocated memory, because do_map() will modify it.
@@ -4385,21 +4430,20 @@ void add_map(char_u *map, int mode, bool nore)
p_cpo = cpo_save;
}
-// Translate an internal mapping/abbreviation representation into the
-// corresponding external one recognized by :map/:abbrev commands.
-//
-// This function is called when expanding mappings/abbreviations on the
-// command-line.
-//
-// It uses a growarray to build the translation string since the latter can be
-// wider than the original description. The caller has to free the string
-// afterwards.
-//
-// Returns NULL when there is a problem.
-static char_u * translate_mapping (
- char_u *str,
- int cpo_flags // Value of various flags present in &cpo
-)
+/// Translate an internal mapping/abbreviation representation into the
+/// corresponding external one recognized by :map/:abbrev commands.
+///
+/// This function is called when expanding mappings/abbreviations on the
+/// command-line.
+///
+/// It uses a growarray to build the translation string since the latter can be
+/// wider than the original description. The caller has to free the string
+/// afterwards.
+///
+/// @param cpo_flags Value of various flags present in &cpo
+///
+/// @return NULL when there is a problem.
+static char_u *translate_mapping(char_u *str, int cpo_flags)
{
garray_T ga;
ga_init(&ga, 1, 40);
@@ -4425,7 +4469,7 @@ static char_u * translate_mapping (
str += 2;
}
if (IS_SPECIAL(c) || modifiers) { // special key
- ga_concat(&ga, get_special_key_name(c, modifiers));
+ ga_concat(&ga, (char *)get_special_key_name(c, modifiers));
continue; // for (str)
}
}
@@ -4447,8 +4491,9 @@ static bool typebuf_match_len(const uint8_t *str, int *mlen)
{
int i;
for (i = 0; i < typebuf.tb_len && str[i]; i++) {
- if (str[i] != typebuf.tb_buf[typebuf.tb_off + i])
+ if (str[i] != typebuf.tb_buf[typebuf.tb_off + i]) {
break;
+ }
}
*mlen = i;
return str[i] == NUL; // matched the whole string
@@ -4469,7 +4514,7 @@ mapblock_T *get_maphash(int index, buf_T *buf)
}
/// Get command argument for <Cmd> key
-char_u * getcmdkeycmd(int promptc, void *cookie, int indent, bool do_concat)
+char_u *getcmdkeycmd(int promptc, void *cookie, int indent, bool do_concat)
{
garray_T line_ga;
int c1 = -1, c2;
@@ -4518,7 +4563,7 @@ char_u * getcmdkeycmd(int promptc, void *cookie, int indent, bool do_concat)
aborted = true;
} else if (IS_SPECIAL(c1)) {
if (c1 == K_SNR) {
- ga_concat(&line_ga, (char_u *)"<SNR>");
+ ga_concat(&line_ga, "<SNR>");
} else {
EMSG2(e_cmdmap_key, get_special_key_name(c1, cmod));
aborted = true;
diff --git a/src/nvim/getchar.h b/src/nvim/getchar.h
index f0b52079aa..4e9dd2eab7 100644
--- a/src/nvim/getchar.h
+++ b/src/nvim/getchar.h
@@ -1,10 +1,10 @@
#ifndef NVIM_GETCHAR_H
#define NVIM_GETCHAR_H
-#include "nvim/os/fileio.h"
-#include "nvim/types.h"
#include "nvim/buffer_defs.h"
#include "nvim/ex_cmds_defs.h"
+#include "nvim/os/fileio.h"
+#include "nvim/types.h"
#include "nvim/vim.h"
/// Values for "noremap" argument of ins_typebuf()
@@ -56,6 +56,8 @@ struct map_arguments {
size_t orig_rhs_len;
};
typedef struct map_arguments MapArguments;
+#define MAP_ARGUMENTS_INIT { false, false, false, false, false, false, false, \
+ { 0 }, 0, NULL, 0, false, NULL, 0 }
#define KEYLEN_PART_KEY -1 // keylen value for incomplete key-code
#define KEYLEN_PART_MAP -2 // keylen value for incomplete mapping
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 4d54907a75..d1f6e2dbd9 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -1,23 +1,23 @@
#ifndef NVIM_GLOBALS_H
#define NVIM_GLOBALS_H
-#include <stdbool.h>
#include <inttypes.h>
+#include <stdbool.h>
-#include "nvim/macros.h"
+#include "nvim/event/loop.h"
#include "nvim/ex_eval.h"
#include "nvim/iconv.h"
+#include "nvim/macros.h"
#include "nvim/mbyte.h"
#include "nvim/menu.h"
+#include "nvim/os/os_defs.h"
#include "nvim/syntax_defs.h"
#include "nvim/types.h"
-#include "nvim/event/loop.h"
-#include "nvim/os/os_defs.h"
#define IOSIZE (1024+1) // file I/O and sprintf buffer size
-# define MSG_BUF_LEN 480 // length of buffer for small messages
-# define MSG_BUF_CLEN (MSG_BUF_LEN / 6) // cell length (worst case: utf-8
+#define MSG_BUF_LEN 480 // length of buffer for small messages
+#define MSG_BUF_CLEN (MSG_BUF_LEN / 6) // cell length (worst case: utf-8
// takes 6 bytes for one cell)
#ifdef WIN32
@@ -169,16 +169,16 @@ EXTERN bool compl_busy INIT(= false);
// List of flags for method of completion.
EXTERN int compl_cont_status INIT(= 0);
-# define CONT_ADDING 1 // "normal" or "adding" expansion
-# define CONT_INTRPT (2 + 4) // a ^X interrupted the current expansion
- // it's set only iff N_ADDS is set
-# define CONT_N_ADDS 4 // next ^X<> will add-new or expand-current
-# define CONT_S_IPOS 8 // next ^X<> will set initial_pos?
- // if so, word-wise-expansion will set SOL
-# define CONT_SOL 16 // pattern includes start of line, just for
- // word-wise expansion, not set for ^X^L
-# define CONT_LOCAL 32 // for ctrl_x_mode 0, ^X^P/^X^N do a local
- // expansion, (eg use complete=.)
+#define CONT_ADDING 1 // "normal" or "adding" expansion
+#define CONT_INTRPT (2 + 4) // a ^X interrupted the current expansion
+ // it's set only iff N_ADDS is set
+#define CONT_N_ADDS 4 // next ^X<> will add-new or expand-current
+#define CONT_S_IPOS 8 // next ^X<> will set initial_pos?
+ // if so, word-wise-expansion will set SOL
+#define CONT_SOL 16 // pattern includes start of line, just for
+ // word-wise expansion, not set for ^X^L
+#define CONT_LOCAL 32 // for ctrl_x_mode 0, ^X^P/^X^N do a local
+ // expansion, (eg use complete=.)
EXTERN char_u *edit_submode INIT(= NULL); // msg for CTRL-X submode
EXTERN char_u *edit_submode_pre INIT(= NULL); // prepended to edit_submode
@@ -335,7 +335,7 @@ EXTERN int garbage_collect_at_exit INIT(= false);
#define SID_WINLAYOUT -7 // changing window size
#define SID_LUA -8 // for Lua scripts/chunks
#define SID_API_CLIENT -9 // for API clients
-#define SID_STR -10 // for sourcing a string
+#define SID_STR -10 // for sourcing a string with no script item
// Script CTX being sourced or was sourced to define the current function.
EXTERN sctx_T current_sctx INIT(= { 0 COMMA 0 COMMA 0 });
@@ -363,7 +363,7 @@ EXTERN int t_colors INIT(= 256); // int value of T_CCO
// a match within one line), search_match_endcol the column number of the
// character just after the match in the last line.
EXTERN bool highlight_match INIT(= false); // show search match pos
-EXTERN linenr_T search_match_lines; // lines of of matched string
+EXTERN linenr_T search_match_lines; // lines of matched string
EXTERN colnr_T search_match_endcol; // col nr of match end
EXTERN linenr_T search_first_line INIT(= 0); // for :{FIRST},{last}s/pat
EXTERN linenr_T search_last_line INIT(= MAXLNUM); // for :{first},{LAST}s/pat
@@ -405,7 +405,7 @@ EXTERN int mouse_dragging INIT(= 0); // extending Visual area with
// mouse dragging
// The root of the menu hierarchy.
-EXTERN vimmenu_T *root_menu INIT(= NULL);
+EXTERN vimmenu_T *root_menu INIT(= NULL);
// While defining the system menu, sys_menu is true. This avoids
// overruling of menus that the user already defined.
EXTERN int sys_menu INIT(= false);
@@ -417,48 +417,48 @@ EXTERN int updating_screen INIT(= 0);
// All windows are linked in a list. firstwin points to the first entry,
// lastwin to the last entry (can be the same as firstwin) and curwin to the
// currently active window.
-EXTERN win_T *firstwin; // first window
-EXTERN win_T *lastwin; // last window
-EXTERN win_T *prevwin INIT(= NULL); // previous window
-# define ONE_WINDOW (firstwin == lastwin)
-# define FOR_ALL_FRAMES(frp, first_frame) \
+EXTERN win_T *firstwin; // first window
+EXTERN win_T *lastwin; // last window
+EXTERN win_T *prevwin INIT(= NULL); // previous window
+#define ONE_WINDOW (firstwin == lastwin)
+#define FOR_ALL_FRAMES(frp, first_frame) \
for (frp = first_frame; frp != NULL; frp = frp->fr_next) // NOLINT
// When using this macro "break" only breaks out of the inner loop. Use "goto"
// to break out of the tabpage loop.
-# define FOR_ALL_TAB_WINDOWS(tp, wp) \
+#define FOR_ALL_TAB_WINDOWS(tp, wp) \
FOR_ALL_TABS(tp) \
- FOR_ALL_WINDOWS_IN_TAB(wp, tp)
+ FOR_ALL_WINDOWS_IN_TAB(wp, tp)
// -V:FOR_ALL_WINDOWS_IN_TAB:501
-# define FOR_ALL_WINDOWS_IN_TAB(wp, tp) \
+#define FOR_ALL_WINDOWS_IN_TAB(wp, tp) \
for (win_T *wp = ((tp) == curtab) \
? firstwin : (tp)->tp_firstwin; wp != NULL; wp = wp->w_next)
-EXTERN win_T *curwin; // currently active window
+EXTERN win_T *curwin; // currently active window
-EXTERN win_T *aucmd_win; // window used in aucmd_prepbuf()
+EXTERN win_T *aucmd_win; // window used in aucmd_prepbuf()
EXTERN int aucmd_win_used INIT(= false); // aucmd_win is being used
// The window layout is kept in a tree of frames. topframe points to the top
// of the tree.
-EXTERN frame_T *topframe; // top of the window frame tree
+EXTERN frame_T *topframe; // top of the window frame tree
// Tab pages are alternative topframes. "first_tabpage" points to the first
// one in the list, "curtab" is the current one.
-EXTERN tabpage_T *first_tabpage;
-EXTERN tabpage_T *lastused_tabpage;
-EXTERN tabpage_T *curtab;
+EXTERN tabpage_T *first_tabpage;
+EXTERN tabpage_T *lastused_tabpage;
+EXTERN tabpage_T *curtab;
EXTERN bool redraw_tabline INIT(= false); // need to redraw tabline
// Iterates over all tabs in the tab list
-# define FOR_ALL_TABS(tp) for (tabpage_T *tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+#define FOR_ALL_TABS(tp) for (tabpage_T *tp = first_tabpage; tp != NULL; tp = tp->tp_next)
// All buffers are linked in a list. 'firstbuf' points to the first entry,
// 'lastbuf' to the last entry and 'curbuf' to the currently active buffer.
EXTERN buf_T *firstbuf INIT(= NULL); // first buffer
-EXTERN buf_T *lastbuf INIT(= NULL); // last buffer
-EXTERN buf_T *curbuf INIT(= NULL); // currently active buffer
+EXTERN buf_T *lastbuf INIT(= NULL); // last buffer
+EXTERN buf_T *curbuf INIT(= NULL); // currently active buffer
// Iterates over all buffers in the buffer list.
#define FOR_ALL_BUFFERS(buf) \
@@ -593,16 +593,16 @@ EXTERN int inhibit_delete_count INIT(= 0);
// These flags are set based upon 'fileencoding'.
// The characters are internally stored as UTF-8
// to avoid trouble with NUL bytes.
-# define DBCS_JPN 932 // japan
-# define DBCS_JPNU 9932 // euc-jp
-# define DBCS_KOR 949 // korea
-# define DBCS_KORU 9949 // euc-kr
-# define DBCS_CHS 936 // chinese
-# define DBCS_CHSU 9936 // euc-cn
-# define DBCS_CHT 950 // taiwan
-# define DBCS_CHTU 9950 // euc-tw
-# define DBCS_2BYTE 1 // 2byte-
-# define DBCS_DEBUG -1
+#define DBCS_JPN 932 // japan
+#define DBCS_JPNU 9932 // euc-jp
+#define DBCS_KOR 949 // korea
+#define DBCS_KORU 9949 // euc-kr
+#define DBCS_CHS 936 // chinese
+#define DBCS_CHSU 9936 // euc-cn
+#define DBCS_CHT 950 // taiwan
+#define DBCS_CHTU 9950 // euc-tw
+#define DBCS_2BYTE 1 // 2byte-
+#define DBCS_DEBUG -1
/// Encoding used when 'fencs' is set to "default"
EXTERN char_u *fenc_default INIT(= NULL);
@@ -669,12 +669,12 @@ EXTERN bool swap_exists_did_quit INIT(= false);
EXTERN char_u IObuff[IOSIZE]; ///< Buffer for sprintf, I/O, etc.
EXTERN char_u NameBuff[MAXPATHL]; ///< Buffer for expanding file names
-EXTERN char_u msg_buf[MSG_BUF_LEN]; ///< Small buffer for messages
+EXTERN char msg_buf[MSG_BUF_LEN]; ///< Small buffer for messages
EXTERN char os_buf[ ///< Buffer for the os/ layer
#if MAXPATHL > IOSIZE
-MAXPATHL
+ MAXPATHL
#else
-IOSIZE
+ IOSIZE
#endif
];
@@ -746,7 +746,7 @@ EXTERN bool g_tag_at_cursor INIT(= false); // whether the tag command comes
EXTERN int replace_offset INIT(= 0); // offset for replace_push()
-EXTERN char_u *escape_chars INIT(= (char_u *)" \t\\\"|");
+EXTERN char_u *escape_chars INIT(= (char_u *)" \t\\\"|");
// need backslash in cmd line
EXTERN int keep_help_flag INIT(= false); // doing :ta from help file
@@ -754,7 +754,7 @@ EXTERN int keep_help_flag INIT(= false); // doing :ta from help file
// When a string option is NULL (which only happens in out-of-memory
// situations), it is set to empty_option, to avoid having to check for NULL
// everywhere.
-EXTERN char_u *empty_option INIT(= (char_u *)"");
+EXTERN char_u *empty_option INIT(= (char_u *)"");
EXTERN bool redir_off INIT(= false); // no redirection for a moment
EXTERN FILE *redir_fd INIT(= NULL); // message redirection file
@@ -787,7 +787,7 @@ extern char_u *compiled_sys;
// When a window has a local directory, the absolute path of the global
// current directory is stored here (in allocated memory). If the current
// directory is not a local directory, globaldir is NULL.
-EXTERN char_u *globaldir INIT(= NULL);
+EXTERN char_u *globaldir INIT(= NULL);
// Whether 'keymodel' contains "stopsel" and "startsel".
EXTERN bool km_stopsel INIT(= false);
@@ -810,8 +810,8 @@ EXTERN linenr_T sub_nlines; // total number of lines changed
EXTERN char_u wim_flags[4];
// whether titlestring and iconstring contains statusline syntax
-# define STL_IN_ICON 1
-# define STL_IN_TITLE 2
+#define STL_IN_ICON 1
+#define STL_IN_TITLE 2
EXTERN int stl_syntax INIT(= 0);
// don't use 'hlsearch' temporarily
@@ -846,15 +846,16 @@ EXTERN linenr_T spell_redraw_lnum INIT(= 0);
// The error messages that can be shared are included here.
// Excluded are errors that are only used once and debugging messages.
EXTERN char_u e_abort[] INIT(= N_("E470: Command aborted"));
-EXTERN char_u e_afterinit[] INIT(= N_(
- "E905: Cannot set this option after startup"));
+EXTERN char_u e_afterinit[] INIT(= N_("E905: Cannot set this option after startup"));
EXTERN char_u e_api_spawn_failed[] INIT(= N_("E903: Could not spawn API job"));
EXTERN char_u e_argreq[] INIT(= N_("E471: Argument required"));
EXTERN char_u e_backslash[] INIT(= N_("E10: \\ should be followed by /, ? or &"));
-EXTERN char_u e_cmdwin[] INIT(= N_(
- "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"));
-EXTERN char_u e_curdir[] INIT(= N_(
- "E12: Command not allowed from exrc/vimrc in current dir or tag search"));
+EXTERN char_u e_cmdwin[] INIT(=
+ N_(
+ "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"));
+EXTERN char_u e_curdir[] INIT(=
+ N_(
+ "E12: Command not allowed from exrc/vimrc in current dir or tag search"));
EXTERN char_u e_endif[] INIT(= N_("E171: Missing :endif"));
EXTERN char_u e_endtry[] INIT(= N_("E600: Missing :endtry"));
EXTERN char_u e_endwhile[] INIT(= N_("E170: Missing :endwhile"));
@@ -869,8 +870,7 @@ EXTERN char_u e_interr[] INIT(= N_("Interrupted"));
EXTERN char_u e_invarg[] INIT(= N_("E474: Invalid argument"));
EXTERN char_u e_invarg2[] INIT(= N_("E475: Invalid argument: %s"));
EXTERN char_u e_invargval[] INIT(= N_("E475: Invalid value for argument %s"));
-EXTERN char_u e_invargNval[] INIT(= N_(
- "E475: Invalid value for argument %s: %s"));
+EXTERN char_u e_invargNval[] INIT(= N_("E475: Invalid value for argument %s: %s"));
EXTERN char_u e_duparg2[] INIT(= N_("E983: Duplicate argument: %s"));
EXTERN char_u e_invexpr2[] INIT(= N_("E15: Invalid expression: %s"));
EXTERN char_u e_invrange[] INIT(= N_("E16: Invalid range"));
@@ -880,24 +880,21 @@ EXTERN char_u e_no_spell[] INIT(= N_("E756: Spell checking is not possible"));
EXTERN char_u e_invchan[] INIT(= N_("E900: Invalid channel id"));
EXTERN char_u e_invchanjob[] INIT(= N_("E900: Invalid channel id: not a job"));
EXTERN char_u e_jobtblfull[] INIT(= N_("E901: Job table is full"));
-EXTERN char_u e_jobspawn[] INIT(= N_(
- "E903: Process failed to start: %s: \"%s\""));
+EXTERN char_u e_jobspawn[] INIT(= N_("E903: Process failed to start: %s: \"%s\""));
EXTERN char_u e_channotpty[] INIT(= N_("E904: channel is not a pty"));
-EXTERN char_u e_stdiochan2[] INIT(= N_(
- "E905: Couldn't open stdio channel: %s"));
+EXTERN char_u e_stdiochan2[] INIT(= N_("E905: Couldn't open stdio channel: %s"));
EXTERN char_u e_invstream[] INIT(= N_("E906: invalid stream for channel"));
-EXTERN char_u e_invstreamrpc[] INIT(= N_(
- "E906: invalid stream for rpc channel, use 'rpc'"));
-EXTERN char_u e_streamkey[] INIT(= N_(
- "E5210: dict key '%s' already set for buffered stream in channel %"
- PRIu64));
+EXTERN char_u e_invstreamrpc[] INIT(= N_("E906: invalid stream for rpc channel, use 'rpc'"));
+EXTERN char_u e_streamkey[] INIT(=
+ N_(
+ "E5210: dict key '%s' already set for buffered stream in channel %"
+ PRIu64));
EXTERN char_u e_libcall[] INIT(= N_("E364: Library call failed for \"%s()\""));
EXTERN char e_fsync[] INIT(= N_("E667: Fsync failed: %s"));
EXTERN char_u e_mkdir[] INIT(= N_("E739: Cannot create directory %s: %s"));
EXTERN char_u e_markinval[] INIT(= N_("E19: Mark has invalid line number"));
EXTERN char_u e_marknotset[] INIT(= N_("E20: Mark not set"));
-EXTERN char_u e_modifiable[] INIT(= N_(
- "E21: Cannot make changes, 'modifiable' is off"));
+EXTERN char_u e_modifiable[] INIT(= N_("E21: Cannot make changes, 'modifiable' is off"));
EXTERN char_u e_nesting[] INIT(= N_("E22: Scripts nested too deep"));
EXTERN char_u e_noalt[] INIT(= N_("E23: No alternate file"));
EXTERN char_u e_noabbr[] INIT(= N_("E24: No such abbreviation"));
@@ -909,8 +906,7 @@ EXTERN char_u e_nomap[] INIT(= N_("E31: No such mapping"));
EXTERN char_u e_nomatch[] INIT(= N_("E479: No match"));
EXTERN char_u e_nomatch2[] INIT(= N_("E480: No match: %s"));
EXTERN char_u e_noname[] INIT(= N_("E32: No file name"));
-EXTERN char_u e_nopresub[] INIT(= N_(
- "E33: No previous substitute regular expression"));
+EXTERN char_u e_nopresub[] INIT(= N_("E33: No previous substitute regular expression"));
EXTERN char_u e_noprev[] INIT(= N_("E34: No previous command"));
EXTERN char_u e_noprevre[] INIT(= N_("E35: No previous regular expression"));
EXTERN char_u e_norange[] INIT(= N_("E481: No range allowed"));
@@ -926,36 +922,30 @@ EXTERN char_u e_outofmem[] INIT(= N_("E41: Out of memory!"));
EXTERN char_u e_patnotf[] INIT(= N_("Pattern not found"));
EXTERN char_u e_patnotf2[] INIT(= N_("E486: Pattern not found: %s"));
EXTERN char_u e_positive[] INIT(= N_("E487: Argument must be positive"));
-EXTERN char_u e_prev_dir[] INIT(= N_(
- "E459: Cannot go back to previous directory"));
+EXTERN char_u e_prev_dir[] INIT(= N_("E459: Cannot go back to previous directory"));
EXTERN char_u e_quickfix[] INIT(= N_("E42: No Errors"));
EXTERN char_u e_loclist[] INIT(= N_("E776: No location list"));
EXTERN char_u e_re_damg[] INIT(= N_("E43: Damaged match string"));
EXTERN char_u e_re_corr[] INIT(= N_("E44: Corrupted regexp program"));
-EXTERN char_u e_readonly[] INIT(= N_(
- "E45: 'readonly' option is set (add ! to override)"));
-EXTERN char_u e_readonlyvar[] INIT(= N_(
- "E46: Cannot change read-only variable \"%.*s\""));
+EXTERN char_u e_readonly[] INIT(= N_("E45: 'readonly' option is set (add ! to override)"));
+EXTERN char_u e_readonlyvar[] INIT(= N_("E46: Cannot change read-only variable \"%.*s\""));
EXTERN char_u e_stringreq[] INIT(= N_("E928: String required"));
EXTERN char_u e_dictreq[] INIT(= N_("E715: Dictionary required"));
EXTERN char_u e_blobidx[] INIT(= N_("E979: Blob index out of range: %" PRId64));
EXTERN char_u e_invalblob[] INIT(= N_("E978: Invalid operation for Blob"));
-EXTERN char_u e_toomanyarg[] INIT(= N_(
- "E118: Too many arguments for function: %s"));
-EXTERN char_u e_dictkey[] INIT(= N_(
- "E716: Key not present in Dictionary: \"%s\""));
+EXTERN char_u e_toomanyarg[] INIT(= N_("E118: Too many arguments for function: %s"));
+EXTERN char_u e_dictkey[] INIT(= N_("E716: Key not present in Dictionary: \"%s\""));
EXTERN char_u e_listreq[] INIT(= N_("E714: List required"));
EXTERN char_u e_listblobreq[] INIT(= N_("E897: List or Blob required"));
-EXTERN char_u e_listdictarg[] INIT(= N_(
- "E712: Argument of %s must be a List or Dictionary"));
-EXTERN char_u e_listdictblobarg[] INIT(= N_(
- "E896: Argument of %s must be a List, Dictionary or Blob"));
+EXTERN char_u e_listdictarg[] INIT(= N_("E712: Argument of %s must be a List or Dictionary"));
+EXTERN char_u e_listdictblobarg[] INIT(=
+ N_(
+ "E896: Argument of %s must be a List, Dictionary or Blob"));
EXTERN char_u e_readerrf[] INIT(= N_("E47: Error while reading errorfile"));
EXTERN char_u e_sandbox[] INIT(= N_("E48: Not allowed in sandbox"));
EXTERN char_u e_secure[] INIT(= N_("E523: Not allowed here"));
-EXTERN char_u e_screenmode[] INIT(= N_(
- "E359: Screen mode setting not supported"));
+EXTERN char_u e_screenmode[] INIT(= N_("E359: Screen mode setting not supported"));
EXTERN char_u e_scroll[] INIT(= N_("E49: Invalid scroll size"));
EXTERN char_u e_shellempty[] INIT(= N_("E91: 'shell' option is empty"));
EXTERN char_u e_signdata[] INIT(= N_("E255: Couldn't read in sign data!"));
@@ -969,57 +959,44 @@ EXTERN char_u e_trailing[] INIT(= N_("E488: Trailing characters"));
EXTERN char_u e_trailing2[] INIT(= N_("E488: Trailing characters: %s"));
EXTERN char_u e_umark[] INIT(= N_("E78: Unknown mark"));
EXTERN char_u e_wildexpand[] INIT(= N_("E79: Cannot expand wildcards"));
-EXTERN char_u e_winheight[] INIT(= N_(
- "E591: 'winheight' cannot be smaller than 'winminheight'"));
-EXTERN char_u e_winwidth[] INIT(= N_(
- "E592: 'winwidth' cannot be smaller than 'winminwidth'"));
+EXTERN char_u e_winheight[] INIT(= N_("E591: 'winheight' cannot be smaller than 'winminheight'"));
+EXTERN char_u e_winwidth[] INIT(= N_("E592: 'winwidth' cannot be smaller than 'winminwidth'"));
EXTERN char_u e_write[] INIT(= N_("E80: Error while writing"));
EXTERN char_u e_zerocount[] INIT(= N_("E939: Positive count required"));
-EXTERN char_u e_usingsid[] INIT(= N_(
- "E81: Using <SID> not in a script context"));
+EXTERN char_u e_usingsid[] INIT(= N_("E81: Using <SID> not in a script context"));
EXTERN char_u e_missingparen[] INIT(= N_("E107: Missing parentheses: %s"));
-EXTERN char_u e_maxmempat[] INIT(= N_(
- "E363: pattern uses more memory than 'maxmempattern'"));
+EXTERN char_u e_maxmempat[] INIT(= N_("E363: pattern uses more memory than 'maxmempattern'"));
EXTERN char_u e_emptybuf[] INIT(= N_("E749: empty buffer"));
EXTERN char_u e_nobufnr[] INIT(= N_("E86: Buffer %" PRId64 " does not exist"));
-EXTERN char_u e_invalpat[] INIT(= N_(
- "E682: Invalid search pattern or delimiter"));
+EXTERN char_u e_invalpat[] INIT(= N_("E682: Invalid search pattern or delimiter"));
EXTERN char_u e_bufloaded[] INIT(= N_("E139: File is loaded in another buffer"));
EXTERN char_u e_notset[] INIT(= N_("E764: Option '%s' is not set"));
EXTERN char_u e_invalidreg[] INIT(= N_("E850: Invalid register name"));
-EXTERN char_u e_dirnotf[] INIT(= N_(
- "E919: Directory not found in '%s': \"%s\""));
-EXTERN char_u e_au_recursive[] INIT(= N_(
- "E952: Autocommand caused recursive behavior"));
-EXTERN char_u e_autocmd_close[] INIT(= N_(
- "E813: Cannot close autocmd window"));
+EXTERN char_u e_dirnotf[] INIT(= N_("E919: Directory not found in '%s': \"%s\""));
+EXTERN char_u e_au_recursive[] INIT(= N_("E952: Autocommand caused recursive behavior"));
+EXTERN char_u e_autocmd_close[] INIT(= N_("E813: Cannot close autocmd window"));
EXTERN char_u e_unsupportedoption[] INIT(= N_("E519: Option not supported"));
EXTERN char_u e_fnametoolong[] INIT(= N_("E856: Filename too long"));
EXTERN char_u e_float_as_string[] INIT(= N_("E806: using Float as a String"));
-EXTERN char_u e_autocmd_err[] INIT(=N_(
- "E5500: autocmd has thrown an exception: %s"));
-EXTERN char_u e_cmdmap_err[] INIT(=N_(
- "E5520: <Cmd> mapping must end with <CR>"));
-EXTERN char_u e_cmdmap_repeated[] INIT(=N_(
- "E5521: <Cmd> mapping must end with <CR> before second <Cmd>"));
-EXTERN char_u e_cmdmap_key[] INIT(=N_(
- "E5522: <Cmd> mapping must not include %s key"));
+EXTERN char_u e_autocmd_err[] INIT(=N_("E5500: autocmd has thrown an exception: %s"));
+EXTERN char_u e_cmdmap_err[] INIT(=N_("E5520: <Cmd> mapping must end with <CR>"));
+EXTERN char_u
+e_cmdmap_repeated[] INIT(=N_("E5521: <Cmd> mapping must end with <CR> before second <Cmd>"));
+EXTERN char_u e_cmdmap_key[] INIT(=N_("E5522: <Cmd> mapping must not include %s key"));
-EXTERN char_u e_api_error[] INIT(=N_(
- "E5555: API call: %s"));
+EXTERN char_u e_api_error[] INIT(=N_("E5555: API call: %s"));
-EXTERN char e_luv_api_disabled[] INIT(=N_(
- "E5560: %s must not be called in a lua loop callback"));
+EXTERN char e_luv_api_disabled[] INIT(=N_("E5560: %s must not be called in a lua loop callback"));
EXTERN char_u e_floatonly[] INIT(=N_(
- "E5601: Cannot close window, only floating window would remain"));
-EXTERN char_u e_floatexchange[] INIT(=N_(
- "E5602: Cannot exchange or rotate float"));
+ "E5601: Cannot close window, only floating window would remain"));
+EXTERN char_u e_floatexchange[] INIT(=N_("E5602: Cannot exchange or rotate float"));
-EXTERN char e_cannot_define_autocommands_for_all_events[] INIT(= N_(
- "E1155: Cannot define autocommands for ALL events"));
+EXTERN char e_cannot_define_autocommands_for_all_events[] INIT(=
+ N_(
+ "E1155: Cannot define autocommands for ALL events"));
EXTERN char top_bot_msg[] INIT(= N_("search hit TOP, continuing at BOTTOM"));
EXTERN char bot_top_msg[] INIT(= N_("search hit BOTTOM, continuing at TOP"));
@@ -1057,14 +1034,22 @@ typedef enum {
/// directly, use `MIN_CD_SCOPE` and `MAX_CD_SCOPE` instead.
typedef enum {
kCdScopeInvalid = -1,
- kCdScopeWindow, ///< Affects one window.
- kCdScopeTab, ///< Affects one tab page.
- kCdScopeGlobal, ///< Affects the entire Nvim instance.
+ kCdScopeWindow, ///< Affects one window.
+ kCdScopeTabpage, ///< Affects one tab page.
+ kCdScopeGlobal, ///< Affects the entire Nvim instance.
} CdScope;
#define MIN_CD_SCOPE kCdScopeWindow
#define MAX_CD_SCOPE kCdScopeGlobal
+/// What caused the current directory to change.
+typedef enum {
+ kCdCauseOther = -1,
+ kCdCauseManual, ///< Using `:cd`, `:tcd`, `:lcd` or `chdir()`.
+ kCdCauseWindow, ///< Switching to another window.
+ kCdCauseAuto, ///< On 'autochdir'.
+} CdCause;
+
// Only filled for Win32.
EXTERN char windowsVersion[20] INIT(= { 0 });
diff --git a/src/nvim/grid_defs.h b/src/nvim/grid_defs.h
index dee096214f..bf0a5d63a8 100644
--- a/src/nvim/grid_defs.h
+++ b/src/nvim/grid_defs.h
@@ -48,10 +48,10 @@ typedef struct ScreenGrid ScreenGrid;
struct ScreenGrid {
handle_T handle;
- schar_T *chars;
- sattr_T *attrs;
+ schar_T *chars;
+ sattr_T *attrs;
unsigned *line_offset;
- char_u *line_wraps;
+ char_u *line_wraps;
// last column that was drawn (not cleared with the default background).
// only used when "throttled" is set. Not allocated by grid_alloc!
diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c
index 1b1735c991..0b828777f4 100644
--- a/src/nvim/hardcopy.c
+++ b/src/nvim/hardcopy.c
@@ -6,35 +6,35 @@
*/
#include <assert.h>
-#include <string.h>
#include <inttypes.h>
+#include <string.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
+#include "nvim/vim.h"
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
-#include "nvim/hardcopy.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/eval.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/fileio.h"
+#include "nvim/garray.h"
+#include "nvim/hardcopy.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
-#include "nvim/garray.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
#include "nvim/path.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/ui.h"
#include "nvim/version.h"
-#include "nvim/os/os.h"
-#include "nvim/os/input.h"
/*
* To implement printing on a platform, the following functions must be
@@ -98,20 +98,20 @@
static option_table_T printer_opts[OPT_PRINT_NUM_OPTIONS]
=
{
- {"top", TRUE, 0, NULL, 0, FALSE},
- {"bottom", TRUE, 0, NULL, 0, FALSE},
- {"left", TRUE, 0, NULL, 0, FALSE},
- {"right", TRUE, 0, NULL, 0, FALSE},
- {"header", TRUE, 0, NULL, 0, FALSE},
- {"syntax", FALSE, 0, NULL, 0, FALSE},
- {"number", FALSE, 0, NULL, 0, FALSE},
- {"wrap", FALSE, 0, NULL, 0, FALSE},
- {"duplex", FALSE, 0, NULL, 0, FALSE},
- {"portrait", FALSE, 0, NULL, 0, FALSE},
- {"paper", FALSE, 0, NULL, 0, FALSE},
- {"collate", FALSE, 0, NULL, 0, FALSE},
- {"jobsplit", FALSE, 0, NULL, 0, FALSE},
- {"formfeed", FALSE, 0, NULL, 0, FALSE},
+ { "top", TRUE, 0, NULL, 0, FALSE },
+ { "bottom", TRUE, 0, NULL, 0, FALSE },
+ { "left", TRUE, 0, NULL, 0, FALSE },
+ { "right", TRUE, 0, NULL, 0, FALSE },
+ { "header", TRUE, 0, NULL, 0, FALSE },
+ { "syntax", FALSE, 0, NULL, 0, FALSE },
+ { "number", FALSE, 0, NULL, 0, FALSE },
+ { "wrap", FALSE, 0, NULL, 0, FALSE },
+ { "duplex", FALSE, 0, NULL, 0, FALSE },
+ { "portrait", FALSE, 0, NULL, 0, FALSE },
+ { "paper", FALSE, 0, NULL, 0, FALSE },
+ { "collate", FALSE, 0, NULL, 0, FALSE },
+ { "jobsplit", FALSE, 0, NULL, 0, FALSE },
+ { "formfeed", FALSE, 0, NULL, 0, FALSE },
}
;
@@ -140,22 +140,22 @@ static uint32_t curr_bg;
static uint32_t curr_fg;
static int page_count;
-# define OPT_MBFONT_USECOURIER 0
-# define OPT_MBFONT_ASCII 1
-# define OPT_MBFONT_REGULAR 2
-# define OPT_MBFONT_BOLD 3
-# define OPT_MBFONT_OBLIQUE 4
-# define OPT_MBFONT_BOLDOBLIQUE 5
-# define OPT_MBFONT_NUM_OPTIONS 6
+#define OPT_MBFONT_USECOURIER 0
+#define OPT_MBFONT_ASCII 1
+#define OPT_MBFONT_REGULAR 2
+#define OPT_MBFONT_BOLD 3
+#define OPT_MBFONT_OBLIQUE 4
+#define OPT_MBFONT_BOLDOBLIQUE 5
+#define OPT_MBFONT_NUM_OPTIONS 6
static option_table_T mbfont_opts[OPT_MBFONT_NUM_OPTIONS] =
{
- {"c", FALSE, 0, NULL, 0, FALSE},
- {"a", FALSE, 0, NULL, 0, FALSE},
- {"r", FALSE, 0, NULL, 0, FALSE},
- {"b", FALSE, 0, NULL, 0, FALSE},
- {"i", FALSE, 0, NULL, 0, FALSE},
- {"o", FALSE, 0, NULL, 0, FALSE},
+ { "c", FALSE, 0, NULL, 0, FALSE },
+ { "a", FALSE, 0, NULL, 0, FALSE },
+ { "r", FALSE, 0, NULL, 0, FALSE },
+ { "b", FALSE, 0, NULL, 0, FALSE },
+ { "i", FALSE, 0, NULL, 0, FALSE },
+ { "o", FALSE, 0, NULL, 0, FALSE },
};
/*
@@ -183,31 +183,31 @@ struct prt_ps_font_S {
int uline_width;
int bbox_min_y;
int bbox_max_y;
- char *(ps_fontname[4]);
+ char *(ps_fontname[4]);
};
/* Structures to map user named encoding and mapping to PS equivalents for
* building CID font name */
struct prt_ps_encoding_S {
- char *encoding;
- char *cmap_encoding;
+ char *encoding;
+ char *cmap_encoding;
int needs_charset;
};
struct prt_ps_charset_S {
- char *charset;
- char *cmap_charset;
+ char *charset;
+ char *cmap_charset;
int has_charset;
};
// Collections of encodings and charsets for multi-byte printing
struct prt_ps_mbfont_S {
int num_encodings;
- struct prt_ps_encoding_S *encodings;
+ struct prt_ps_encoding_S *encodings;
int num_charsets;
- struct prt_ps_charset_S *charsets;
- char *ascii_enc;
- char *defcs;
+ struct prt_ps_charset_S *charsets;
+ char *ascii_enc;
+ char *defcs;
};
// Types of PS resource file currently used
@@ -234,14 +234,14 @@ struct prt_ps_resource_S {
};
struct prt_dsc_comment_S {
- char *string;
+ char *string;
int len;
int type;
};
struct prt_dsc_line_S {
int type;
- char_u *string;
+ char_u *string;
int len;
};
@@ -286,15 +286,14 @@ char_u *parse_printmbfont(void)
* Returns an error message for an illegal option, NULL otherwise.
* Only used for the printer at the moment...
*/
-static char_u *parse_list_options(char_u *option_str, option_table_T *table,
- size_t table_size)
+static char_u *parse_list_options(char_u *option_str, option_table_T *table, size_t table_size)
{
option_table_T *old_opts;
- char_u *ret = NULL;
- char_u *stringp;
- char_u *colonp;
- char_u *commap;
- char_u *p;
+ char_u *ret = NULL;
+ char_u *stringp;
+ char_u *colonp;
+ char_u *commap;
+ char_u *p;
size_t idx = 0; // init for GCC
int len;
@@ -317,14 +316,17 @@ static char_u *parse_list_options(char_u *option_str, option_table_T *table,
break;
}
commap = vim_strchr(stringp, ',');
- if (commap == NULL)
+ if (commap == NULL) {
commap = option_str + STRLEN(option_str);
+ }
len = (int)(colonp - stringp);
- for (idx = 0; idx < table_size; ++idx)
- if (STRNICMP(stringp, table[idx].name, len) == 0)
+ for (idx = 0; idx < table_size; ++idx) {
+ if (STRNICMP(stringp, table[idx].name, len) == 0) {
break;
+ }
+ }
if (idx == table_size) {
ret = (char_u *)N_("E551: Illegal component");
@@ -347,8 +349,9 @@ static char_u *parse_list_options(char_u *option_str, option_table_T *table,
table[idx].strlen = (int)(commap - p);
stringp = commap;
- if (*stringp == ',')
+ if (*stringp == ',') {
++stringp;
+ }
}
if (ret != NULL) {
@@ -401,16 +404,18 @@ static void prt_get_attr(int hl_id, prt_text_attr_T *pattr, int modec)
colorindex = atoi(color);
}
- if (colorindex >= 0 && colorindex < t_colors)
+ if (colorindex >= 0 && colorindex < t_colors) {
fg_color = prt_get_term_color(colorindex);
- else
+ } else {
fg_color = PRCOLOR_BLACK;
+ }
}
- if (fg_color == PRCOLOR_WHITE)
+ if (fg_color == PRCOLOR_WHITE) {
fg_color = PRCOLOR_BLACK;
- else if (*p_bg == 'd')
+ } else if (*p_bg == 'd') {
fg_color = darken_rgb(fg_color);
+ }
pattr->fg_color = fg_color;
pattr->bg_color = PRCOLOR_WHITE;
@@ -432,8 +437,7 @@ static void prt_set_bg(uint32_t bg)
}
}
-static void prt_set_font(const TriState bold, const TriState italic,
- const TriState underline)
+static void prt_set_font(const TriState bold, const TriState italic, const TriState underline)
{
if (curr_bold != bold
|| curr_italic != italic
@@ -446,8 +450,8 @@ static void prt_set_font(const TriState bold, const TriState italic,
}
// Print the line number in the left margin.
-static void prt_line_number(prt_settings_T *const psettings,
- const int page_line, const linenr_T lnum)
+static void prt_line_number(prt_settings_T *const psettings, const int page_line,
+ const linenr_T lnum)
{
prt_set_fg(psettings->number.fg_color);
prt_set_bg(psettings->number.bg_color);
@@ -504,18 +508,19 @@ int prt_get_unit(int idx)
int i;
static char *(units[4]) = PRT_UNIT_NAMES;
- if (printer_opts[idx].present)
- for (i = 0; i < 4; ++i)
+ if (printer_opts[idx].present) {
+ for (i = 0; i < 4; ++i) {
if (STRNICMP(printer_opts[idx].string, units[i], 2) == 0) {
u = i;
break;
}
+ }
+ }
return u;
}
// Print the page header.
-static void prt_header(prt_settings_T *const psettings, const int pagenum,
- const linenr_T lnum)
+static void prt_header(prt_settings_T *const psettings, const int pagenum, const linenr_T lnum)
{
int width = psettings->chars_per_line;
@@ -546,10 +551,10 @@ static void prt_header(prt_settings_T *const psettings, const int pagenum,
curwin->w_botline = lnum + 63;
printer_page_num = pagenum;
- use_sandbox = was_set_insecurely(curwin, (char_u *)"printheader", 0);
+ use_sandbox = was_set_insecurely(curwin, "printheader", 0);
build_stl_str_hl(curwin, tbuf, (size_t)width + IOSIZE,
- p_header, use_sandbox,
- ' ', width, NULL, NULL);
+ p_header, use_sandbox,
+ ' ', width, NULL, NULL);
// Reset line numbers
curwin->w_cursor.lnum = tmp_lnum;
@@ -616,17 +621,19 @@ void ex_hardcopy(exarg_T *eap)
settings.has_color = TRUE;
if (*eap->arg == '>') {
- char_u *errormsg = NULL;
+ char_u *errormsg = NULL;
// Expand things like "%.ps".
if (expand_filename(eap, eap->cmdlinep, &errormsg) == FAIL) {
- if (errormsg != NULL)
+ if (errormsg != NULL) {
EMSG(errormsg);
+ }
return;
}
settings.outfile = skipwhite(eap->arg + 1);
- } else if (*eap->arg != NUL)
+ } else if (*eap->arg != NUL) {
settings.arguments = eap->arg;
+ }
/*
* Initialise for printing. Ask the user for settings, unless forceit is
@@ -636,24 +643,22 @@ void ex_hardcopy(exarg_T *eap)
* PS.)
*/
if (mch_print_init(&settings,
- curbuf->b_fname == NULL
- ? (char_u *)buf_spname(curbuf)
- : curbuf->b_sfname == NULL
- ? curbuf->b_fname
- : curbuf->b_sfname,
- eap->forceit) == FAIL)
+ curbuf->b_fname == NULL ? buf_spname(curbuf) : curbuf->b_sfname ==
+ NULL ? curbuf->b_fname : curbuf->b_sfname, eap->forceit) == FAIL) {
return;
+ }
settings.modec = 'c';
- if (!syntax_present(curwin))
+ if (!syntax_present(curwin)) {
settings.do_syntax = FALSE;
- else if (printer_opts[OPT_PRINT_SYNTAX].present
- && TOLOWER_ASC(printer_opts[OPT_PRINT_SYNTAX].string[0]) != 'a')
+ } else if (printer_opts[OPT_PRINT_SYNTAX].present
+ && TOLOWER_ASC(printer_opts[OPT_PRINT_SYNTAX].string[0]) != 'a') {
settings.do_syntax =
(TOLOWER_ASC(printer_opts[OPT_PRINT_SYNTAX].string[0]) == 'y');
- else
+ } else {
settings.do_syntax = settings.has_color;
+ }
// Set up printing attributes for line numbers
settings.number.fg_color = PRCOLOR_BLACK;
@@ -675,8 +680,9 @@ void ex_hardcopy(exarg_T *eap)
/*
* Estimate the total lines to be printed
*/
- for (lnum = eap->line1; lnum <= eap->line2; lnum++)
+ for (lnum = eap->line1; lnum <= eap->line2; lnum++) {
bytes_to_print += STRLEN(skipwhite(ml_get(lnum)));
+ }
if (bytes_to_print == 0) {
MSG(_("No text to be printed"));
goto print_fail_no_begin;
@@ -697,8 +703,9 @@ void ex_hardcopy(exarg_T *eap)
jobsplit = (printer_opts[OPT_PRINT_JOBSPLIT].present
&& TOLOWER_ASC(printer_opts[OPT_PRINT_JOBSPLIT].string[0]) == 'y');
- if (!mch_print_begin(&settings))
+ if (!mch_print_begin(&settings)) {
goto print_fail_no_begin;
+ }
/*
* Loop over collated copies: 1 2 3, 1 2 3, ...
@@ -718,8 +725,9 @@ void ex_hardcopy(exarg_T *eap)
if (jobsplit && collated_copies > 0) {
// Splitting jobs: Stop a previous job and start a new one.
mch_print_end(&settings);
- if (!mch_print_begin(&settings))
+ if (!mch_print_begin(&settings)) {
goto print_fail_no_begin;
+ }
}
/*
@@ -746,34 +754,38 @@ void ex_hardcopy(exarg_T *eap)
// Check for interrupt character every page.
os_breakcheck();
- if (got_int || settings.user_abort)
+ if (got_int || settings.user_abort) {
goto print_fail;
+ }
assert(prtpos.bytes_printed <= SIZE_MAX / 100);
sprintf((char *)IObuff, _("Printing page %d (%zu%%)"),
page_count + 1 + side,
prtpos.bytes_printed * 100 / bytes_to_print);
- if (!mch_print_begin_page(IObuff))
+ if (!mch_print_begin_page(IObuff)) {
goto print_fail;
+ }
- if (settings.n_collated_copies > 1)
+ if (settings.n_collated_copies > 1) {
sprintf((char *)IObuff + STRLEN(IObuff),
- _(" Copy %d of %d"),
- collated_copies + 1,
- settings.n_collated_copies);
+ _(" Copy %d of %d"),
+ collated_copies + 1,
+ settings.n_collated_copies);
+ }
prt_message(IObuff);
/*
* Output header if required
*/
- if (prt_header_height() > 0)
+ if (prt_header_height() > 0) {
prt_header(&settings, page_count + 1 + side,
- prtpos.file_line);
+ prtpos.file_line);
+ }
for (page_line = 0; page_line < settings.lines_per_page;
++page_line) {
prtpos.column = hardcopy_line(&settings,
- page_line, &prtpos);
+ page_line, &prtpos);
if (prtpos.column == 0) {
// finished a file line
prtpos.bytes_printed +=
@@ -803,19 +815,21 @@ void ex_hardcopy(exarg_T *eap)
if (prtpos.file_line > eap->line2 && settings.duplex
&& side == 0
&& uncollated_copies + 1 < settings.n_uncollated_copies) {
- if (!mch_print_blank_page())
+ if (!mch_print_blank_page()) {
goto print_fail;
+ }
}
}
- if (settings.duplex && prtpos.file_line <= eap->line2)
+ if (settings.duplex && prtpos.file_line <= eap->line2) {
++page_count;
+ }
// Remember the position where the next page starts.
page_prtpos = prtpos;
}
vim_snprintf((char *)IObuff, IOSIZE, _("Printed: %s"),
- settings.jobname);
+ settings.jobname);
prt_message(IObuff);
}
@@ -837,7 +851,7 @@ print_fail_no_begin:
static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T *ppos)
{
colnr_T col;
- char_u *line;
+ char_u *line;
int need_break = FALSE;
int outputlen;
int tab_spaces;
@@ -848,8 +862,9 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
if (ppos->column == 0 || ppos->ff) {
print_pos = 0;
tab_spaces = 0;
- if (!ppos->ff && prt_use_number())
+ if (!ppos->ff && prt_use_number()) {
prt_line_number(psettings, page_line, ppos->file_line);
+ }
ppos->ff = FALSE;
} else {
// left over from wrap halfway through a tab
@@ -870,10 +885,11 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
// syntax highlighting stuff.
if (psettings->do_syntax) {
id = syn_get_id(curwin, ppos->file_line, col, 1, NULL, FALSE);
- if (id > 0)
+ if (id > 0) {
id = syn_get_final_id(id);
- else
+ } else {
id = 0;
+ }
// Get the line again, a multi-line regexp may invalidate it.
line = ml_get(ppos->file_line);
@@ -900,8 +916,9 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
need_break = mch_print_text_out((char_u *)" ", 1);
print_pos++;
tab_spaces--;
- if (need_break)
+ if (need_break) {
break;
+ }
}
// Keep the TAB if we didn't finish it.
if (need_break && tab_spaces > 0) {
@@ -930,8 +947,9 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
&& (line[col] == NUL
|| (printer_opts[OPT_PRINT_WRAP].present
&& TOLOWER_ASC(printer_opts[OPT_PRINT_WRAP].string[0])
- == 'n')))
+ == 'n'))) {
return 0;
+ }
return col;
}
@@ -1000,7 +1018,7 @@ static struct prt_ps_font_S prt_ps_courier_font =
600,
-100, 50,
-250, 805,
- {"Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique"}
+ { "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique" }
};
// Generic font metrics for multi-byte fonts
@@ -1009,7 +1027,7 @@ static struct prt_ps_font_S prt_ps_mb_font =
1000,
-100, 50,
-250, 805,
- {NULL, NULL, NULL, NULL}
+ { NULL, NULL, NULL, NULL }
};
// Pointer to current font set being used
@@ -1027,25 +1045,25 @@ static struct prt_ps_font_S *prt_ps_font;
// Japanese encodings and charsets
static struct prt_ps_encoding_S j_encodings[] =
{
- {"iso-2022-jp", NULL, (CS_JIS_C_1978|CS_JIS_X_1983|CS_JIS_X_1990|
- CS_NEC)},
- {"euc-jp", "EUC", (CS_JIS_C_1978|CS_JIS_X_1983|CS_JIS_X_1990)},
- {"sjis", "RKSJ", (CS_JIS_C_1978|CS_JIS_X_1983|CS_MSWINDOWS|
- CS_KANJITALK6|CS_KANJITALK7)},
- {"cp932", "RKSJ", CS_JIS_X_1983},
- {"ucs-2", "UCS2", CS_JIS_X_1990},
- {"utf-8", "UTF8", CS_JIS_X_1990}
+ { "iso-2022-jp", NULL, (CS_JIS_C_1978|CS_JIS_X_1983|CS_JIS_X_1990|
+ CS_NEC) },
+ { "euc-jp", "EUC", (CS_JIS_C_1978|CS_JIS_X_1983|CS_JIS_X_1990) },
+ { "sjis", "RKSJ", (CS_JIS_C_1978|CS_JIS_X_1983|CS_MSWINDOWS|
+ CS_KANJITALK6|CS_KANJITALK7) },
+ { "cp932", "RKSJ", CS_JIS_X_1983 },
+ { "ucs-2", "UCS2", CS_JIS_X_1990 },
+ { "utf-8", "UTF8", CS_JIS_X_1990 }
};
static struct prt_ps_charset_S j_charsets[] =
{
- {"JIS_C_1978", "78", CS_JIS_C_1978},
- {"JIS_X_1983", NULL, CS_JIS_X_1983},
- {"JIS_X_1990", "Hojo", CS_JIS_X_1990},
- {"NEC", "Ext", CS_NEC},
- {"MSWINDOWS", "90ms", CS_MSWINDOWS},
- {"CP932", "90ms", CS_JIS_X_1983},
- {"KANJITALK6", "83pv", CS_KANJITALK6},
- {"KANJITALK7", "90pv", CS_KANJITALK7}
+ { "JIS_C_1978", "78", CS_JIS_C_1978 },
+ { "JIS_X_1983", NULL, CS_JIS_X_1983 },
+ { "JIS_X_1990", "Hojo", CS_JIS_X_1990 },
+ { "NEC", "Ext", CS_NEC },
+ { "MSWINDOWS", "90ms", CS_MSWINDOWS },
+ { "CP932", "90ms", CS_JIS_X_1983 },
+ { "KANJITALK6", "83pv", CS_KANJITALK6 },
+ { "KANJITALK7", "90pv", CS_KANJITALK7 }
};
#define CS_GB_2312_80 (0x01)
@@ -1059,23 +1077,23 @@ static struct prt_ps_charset_S j_charsets[] =
// Simplified Chinese encodings and charsets
static struct prt_ps_encoding_S sc_encodings[] =
{
- {"iso-2022", NULL, (CS_GB_2312_80|CS_GBT_12345_90)},
- {"gb18030", NULL, CS_GBK2K},
- {"euc-cn", "EUC", (CS_GB_2312_80|CS_GBT_12345_90|CS_SC_MAC|
- CS_GBT_90_MAC)},
- {"gbk", "EUC", CS_GBK},
- {"ucs-2", "UCS2", CS_SC_ISO10646},
- {"utf-8", "UTF8", CS_SC_ISO10646}
+ { "iso-2022", NULL, (CS_GB_2312_80|CS_GBT_12345_90) },
+ { "gb18030", NULL, CS_GBK2K },
+ { "euc-cn", "EUC", (CS_GB_2312_80|CS_GBT_12345_90|CS_SC_MAC|
+ CS_GBT_90_MAC) },
+ { "gbk", "EUC", CS_GBK },
+ { "ucs-2", "UCS2", CS_SC_ISO10646 },
+ { "utf-8", "UTF8", CS_SC_ISO10646 }
};
static struct prt_ps_charset_S sc_charsets[] =
{
- {"GB_2312-80", "GB", CS_GB_2312_80},
- {"GBT_12345-90","GBT", CS_GBT_12345_90},
- {"MAC", "GBpc", CS_SC_MAC},
- {"GBT-90_MAC", "GBTpc", CS_GBT_90_MAC},
- {"GBK", "GBK", CS_GBK},
- {"GB18030", "GBK2K", CS_GBK2K},
- {"ISO10646", "UniGB", CS_SC_ISO10646}
+ { "GB_2312-80", "GB", CS_GB_2312_80 },
+ { "GBT_12345-90", "GBT", CS_GBT_12345_90 },
+ { "MAC", "GBpc", CS_SC_MAC },
+ { "GBT-90_MAC", "GBTpc", CS_GBT_90_MAC },
+ { "GBK", "GBK", CS_GBK },
+ { "GB18030", "GBK2K", CS_GBK2K },
+ { "ISO10646", "UniGB", CS_SC_ISO10646 }
};
#define CS_CNS_PLANE_1 (0x01)
@@ -1095,33 +1113,33 @@ static struct prt_ps_charset_S sc_charsets[] =
// Traditional Chinese encodings and charsets
static struct prt_ps_encoding_S tc_encodings[] =
{
- {"iso-2022", NULL, (CS_CNS_PLANE_1|CS_CNS_PLANE_2)},
- {"euc-tw", "EUC", CS_CNS_PLANE_1_2},
- {"big5", "B5", (CS_B5|CS_ETEN|CS_HK_GCCS|CS_HK_SCS|
- CS_HK_SCS_ETEN|CS_MTHKL|CS_MTHKS|CS_DLHKL|
- CS_DLHKS)},
- {"cp950", "B5", CS_B5},
- {"ucs-2", "UCS2", CS_TC_ISO10646},
- {"utf-8", "UTF8", CS_TC_ISO10646},
- {"utf-16", "UTF16", CS_TC_ISO10646},
- {"utf-32", "UTF32", CS_TC_ISO10646}
+ { "iso-2022", NULL, (CS_CNS_PLANE_1|CS_CNS_PLANE_2) },
+ { "euc-tw", "EUC", CS_CNS_PLANE_1_2 },
+ { "big5", "B5", (CS_B5|CS_ETEN|CS_HK_GCCS|CS_HK_SCS|
+ CS_HK_SCS_ETEN|CS_MTHKL|CS_MTHKS|CS_DLHKL|
+ CS_DLHKS) },
+ { "cp950", "B5", CS_B5 },
+ { "ucs-2", "UCS2", CS_TC_ISO10646 },
+ { "utf-8", "UTF8", CS_TC_ISO10646 },
+ { "utf-16", "UTF16", CS_TC_ISO10646 },
+ { "utf-32", "UTF32", CS_TC_ISO10646 }
};
static struct prt_ps_charset_S tc_charsets[] =
{
- {"CNS_1992_1", "CNS1", CS_CNS_PLANE_1},
- {"CNS_1992_2", "CNS2", CS_CNS_PLANE_2},
- {"CNS_1993", "CNS", CS_CNS_PLANE_1_2},
- {"BIG5", NULL, CS_B5},
- {"CP950", NULL, CS_B5},
- {"ETEN", "ETen", CS_ETEN},
- {"HK_GCCS", "HKgccs", CS_HK_GCCS},
- {"SCS", "HKscs", CS_HK_SCS},
- {"SCS_ETEN", "ETHK", CS_HK_SCS_ETEN},
- {"MTHKL", "HKm471", CS_MTHKL},
- {"MTHKS", "HKm314", CS_MTHKS},
- {"DLHKL", "HKdla", CS_DLHKL},
- {"DLHKS", "HKdlb", CS_DLHKS},
- {"ISO10646", "UniCNS", CS_TC_ISO10646}
+ { "CNS_1992_1", "CNS1", CS_CNS_PLANE_1 },
+ { "CNS_1992_2", "CNS2", CS_CNS_PLANE_2 },
+ { "CNS_1993", "CNS", CS_CNS_PLANE_1_2 },
+ { "BIG5", NULL, CS_B5 },
+ { "CP950", NULL, CS_B5 },
+ { "ETEN", "ETen", CS_ETEN },
+ { "HK_GCCS", "HKgccs", CS_HK_GCCS },
+ { "SCS", "HKscs", CS_HK_SCS },
+ { "SCS_ETEN", "ETHK", CS_HK_SCS_ETEN },
+ { "MTHKL", "HKm471", CS_MTHKL },
+ { "MTHKS", "HKm314", CS_MTHKS },
+ { "DLHKL", "HKdla", CS_DLHKL },
+ { "DLHKS", "HKdlb", CS_DLHKS },
+ { "ISO10646", "UniCNS", CS_TC_ISO10646 }
};
#define CS_KR_X_1992 (0x01)
@@ -1132,24 +1150,24 @@ static struct prt_ps_charset_S tc_charsets[] =
// Korean encodings and charsets
static struct prt_ps_encoding_S k_encodings[] =
{
- {"iso-2022-kr", NULL, CS_KR_X_1992},
- {"euc-kr", "EUC", (CS_KR_X_1992|CS_KR_MAC)},
- {"johab", "Johab", CS_KR_X_1992},
- {"cp1361", "Johab", CS_KR_X_1992},
- {"uhc", "UHC", CS_KR_X_1992_MS},
- {"cp949", "UHC", CS_KR_X_1992_MS},
- {"ucs-2", "UCS2", CS_KR_ISO10646},
- {"utf-8", "UTF8", CS_KR_ISO10646}
+ { "iso-2022-kr", NULL, CS_KR_X_1992 },
+ { "euc-kr", "EUC", (CS_KR_X_1992|CS_KR_MAC) },
+ { "johab", "Johab", CS_KR_X_1992 },
+ { "cp1361", "Johab", CS_KR_X_1992 },
+ { "uhc", "UHC", CS_KR_X_1992_MS },
+ { "cp949", "UHC", CS_KR_X_1992_MS },
+ { "ucs-2", "UCS2", CS_KR_ISO10646 },
+ { "utf-8", "UTF8", CS_KR_ISO10646 }
};
static struct prt_ps_charset_S k_charsets[] =
{
- {"KS_X_1992", "KSC", CS_KR_X_1992},
- {"CP1361", "KSC", CS_KR_X_1992},
- {"MAC", "KSCpc", CS_KR_MAC},
- {"MSWINDOWS", "KSCms", CS_KR_X_1992_MS},
- {"CP949", "KSCms", CS_KR_X_1992_MS},
- {"WANSUNG", "KSCms", CS_KR_X_1992_MS},
- {"ISO10646", "UniKS", CS_KR_ISO10646}
+ { "KS_X_1992", "KSC", CS_KR_X_1992 },
+ { "CP1361", "KSC", CS_KR_X_1992 },
+ { "MAC", "KSCpc", CS_KR_MAC },
+ { "MSWINDOWS", "KSCms", CS_KR_X_1992_MS },
+ { "CP949", "KSCms", CS_KR_X_1992_MS },
+ { "WANSUNG", "KSCms", CS_KR_X_1992_MS },
+ { "ISO10646", "UniKS", CS_KR_ISO10646 }
};
static struct prt_ps_mbfont_S prt_ps_mbfonts[] =
@@ -1196,7 +1214,7 @@ static struct prt_ps_mbfont_S prt_ps_mbfonts[] =
*
* VIM Prolog CIDProlog
* 6.2 1.3
- * 7.0 1.4 1.0
+ * 7.0 1.4 1.0
*/
#define PRT_PROLOG_VERSION ((char_u *)"1.4")
#define PRT_CID_PROLOG_VERSION ((char_u *)"1.0")
@@ -1224,11 +1242,11 @@ static struct prt_ps_mbfont_S prt_ps_mbfonts[] =
#define SIZEOF_CSTR(s) (sizeof(s) - 1)
static struct prt_dsc_comment_S prt_dsc_table[] =
{
- {PRT_DSC_TITLE, SIZEOF_CSTR(PRT_DSC_TITLE), PRT_DSC_TITLE_TYPE},
- {PRT_DSC_VERSION, SIZEOF_CSTR(PRT_DSC_VERSION),
- PRT_DSC_VERSION_TYPE},
- {PRT_DSC_ENDCOMMENTS, SIZEOF_CSTR(PRT_DSC_ENDCOMMENTS),
- PRT_DSC_ENDCOMMENTS_TYPE}
+ { PRT_DSC_TITLE, SIZEOF_CSTR(PRT_DSC_TITLE), PRT_DSC_TITLE_TYPE },
+ { PRT_DSC_VERSION, SIZEOF_CSTR(PRT_DSC_VERSION),
+ PRT_DSC_VERSION_TYPE },
+ { PRT_DSC_ENDCOMMENTS, SIZEOF_CSTR(PRT_DSC_ENDCOMMENTS),
+ PRT_DSC_ENDCOMMENTS_TYPE }
};
@@ -1359,14 +1377,15 @@ static void prt_write_boolean(int b)
static void prt_def_font(char *new_name, char *encoding, int height, char *font)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "/_%s /VIM-%s /%s ref\n", new_name, encoding, font);
+ "/_%s /VIM-%s /%s ref\n", new_name, encoding, font);
prt_write_file(prt_line_buffer);
- if (prt_out_mbyte)
+ if (prt_out_mbyte) {
sprintf((char *)prt_line_buffer, "/%s %d %f /_%s sffs\n",
- new_name, height, 500./prt_ps_courier_font.wx, new_name);
- else
+ new_name, height, 500./prt_ps_courier_font.wx, new_name);
+ } else {
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "/%s %d /_%s ffs\n", new_name, height, new_name);
+ "/%s %d /_%s ffs\n", new_name, height, new_name);
+ }
prt_write_file(prt_line_buffer);
}
@@ -1376,10 +1395,10 @@ static void prt_def_font(char *new_name, char *encoding, int height, char *font)
static void prt_def_cidfont(char *new_name, int height, char *cidfont)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "/_%s /%s[/%s] vim_composefont\n", new_name, prt_cmap, cidfont);
+ "/_%s /%s[/%s] vim_composefont\n", new_name, prt_cmap, cidfont);
prt_write_file(prt_line_buffer);
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "/%s %d /_%s ffs\n", new_name, height, new_name);
+ "/%s %d /_%s ffs\n", new_name, height, new_name);
prt_write_file(prt_line_buffer);
}
@@ -1389,7 +1408,7 @@ static void prt_def_cidfont(char *new_name, int height, char *cidfont)
static void prt_dup_cidfont(char *original_name, char *new_name)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "/%s %s d\n", new_name, original_name);
+ "/%s %s d\n", new_name, original_name);
prt_write_file(prt_line_buffer);
}
@@ -1402,10 +1421,12 @@ static void prt_real_bits(double real, int precision, int *pinteger, int *pfract
{
int integer = (int)real;
double fraction = real - integer;
- if (real < integer)
+ if (real < integer) {
fraction = -fraction;
- for (int i = 0; i < precision; i++)
+ }
+ for (int i = 0; i < precision; i++) {
fraction *= 10.0;
+ }
*pinteger = integer;
*pfraction = (int)(fraction + 0.5);
@@ -1447,7 +1468,7 @@ static void prt_write_real(double val, int prec)
static void prt_def_var(char *name, double value, int prec)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "/%s ", name);
+ "/%s ", name);
prt_write_file(prt_line_buffer);
prt_write_real(value, prec);
sprintf((char *)prt_line_buffer, "d\n");
@@ -1500,16 +1521,18 @@ static void prt_flush_buffer(void)
prt_write_string("ul\n");
}
// Draw the text
- if (prt_out_mbyte)
+ if (prt_out_mbyte) {
prt_write_string("<");
- else
+ } else {
prt_write_string("(");
+ }
assert(prt_ps_buffer.ga_len >= 0);
prt_write_file_raw_len(prt_ps_buffer.ga_data, (size_t)prt_ps_buffer.ga_len);
- if (prt_out_mbyte)
+ if (prt_out_mbyte) {
prt_write_string(">");
- else
+ } else {
prt_write_string(")");
+ }
// Add a moveto if need be and use the appropriate show procedure
if (prt_do_moveto) {
prt_write_real(prt_pos_x_moveto, 2);
@@ -1529,15 +1552,16 @@ static void prt_resource_name(char_u *filename, void *cookie)
{
char_u *resource_filename = cookie;
- if (STRLEN(filename) >= MAXPATHL)
+ if (STRLEN(filename) >= MAXPATHL) {
*resource_filename = NUL;
- else
+ } else {
STRCPY(resource_filename, filename);
+ }
}
static int prt_find_resource(char *name, struct prt_ps_resource_S *resource)
{
- char_u *buffer;
+ char_u *buffer;
int retval;
buffer = xmallocz(MAXPATHL);
@@ -1568,15 +1592,17 @@ static int prt_resfile_next_line(void)
// Move to start of next line and then find end of line
idx = prt_resfile.line_end + 1;
while (idx < prt_resfile.len) {
- if (prt_resfile.buffer[idx] != PSLF && prt_resfile.buffer[idx] != PSCR)
+ if (prt_resfile.buffer[idx] != PSLF && prt_resfile.buffer[idx] != PSCR) {
break;
+ }
idx++;
}
prt_resfile.line_start = idx;
while (idx < prt_resfile.len) {
- if (prt_resfile.buffer[idx] == PSLF || prt_resfile.buffer[idx] == PSCR)
+ if (prt_resfile.buffer[idx] == PSLF || prt_resfile.buffer[idx] == PSCR) {
break;
+ }
idx++;
}
prt_resfile.line_end = idx;
@@ -1592,7 +1618,7 @@ static int prt_resfile_strncmp(int offset, const char *string, int len)
return 1;
}
return STRNCMP(&prt_resfile.buffer[prt_resfile.line_start + offset],
- string, len);
+ string, len);
}
static int prt_resfile_skip_nonws(int offset)
@@ -1601,8 +1627,9 @@ static int prt_resfile_skip_nonws(int offset)
idx = prt_resfile.line_start + offset;
while (idx < prt_resfile.line_end) {
- if (isspace(prt_resfile.buffer[idx]))
+ if (isspace(prt_resfile.buffer[idx])) {
return idx - prt_resfile.line_start;
+ }
idx++;
}
return -1;
@@ -1614,8 +1641,9 @@ static int prt_resfile_skip_ws(int offset)
idx = prt_resfile.line_start + offset;
while (idx < prt_resfile.line_end) {
- if (!isspace(prt_resfile.buffer[idx]))
+ if (!isspace(prt_resfile.buffer[idx])) {
return idx - prt_resfile.line_start;
+ }
idx++;
}
return -1;
@@ -1685,10 +1713,10 @@ static bool prt_open_resource(struct prt_ps_resource_S *resource)
// Parse first line to ensure valid resource file
prt_resfile.len = (int)fread((char *)prt_resfile.buffer, sizeof(char_u),
- PRT_FILE_BUFFER_LEN, fd_resource);
+ PRT_FILE_BUFFER_LEN, fd_resource);
if (ferror(fd_resource)) {
EMSG2(_("E457: Can't read PostScript resource file \"%s\""),
- resource->filename);
+ resource->filename);
fclose(fd_resource);
return false;
}
@@ -1702,7 +1730,7 @@ static bool prt_open_resource(struct prt_ps_resource_S *resource)
int offset = 0;
if (prt_resfile_strncmp(offset, PRT_RESOURCE_HEADER,
- (int)STRLEN(PRT_RESOURCE_HEADER)) != 0) {
+ (int)STRLEN(PRT_RESOURCE_HEADER)) != 0) {
EMSG2(_("E618: file \"%s\" is not a PostScript resource file"),
resource->filename);
return false;
@@ -1719,7 +1747,7 @@ static bool prt_open_resource(struct prt_ps_resource_S *resource)
return false;
}
if (prt_resfile_strncmp(offset, PRT_RESOURCE_RESOURCE,
- (int)STRLEN(PRT_RESOURCE_RESOURCE)) != 0) {
+ (int)STRLEN(PRT_RESOURCE_RESOURCE)) != 0) {
EMSG2(_("E619: file \"%s\" is not a supported PostScript resource file"),
resource->filename);
return false;
@@ -1786,8 +1814,7 @@ static bool prt_open_resource(struct prt_ps_resource_S *resource)
return true;
}
-static bool prt_check_resource(const struct prt_ps_resource_S *resource,
- const char_u *version)
+static bool prt_check_resource(const struct prt_ps_resource_S *resource, const char_u *version)
FUNC_ATTR_NONNULL_ALL
{
// Version number m.n should match, the revision number does not matter
@@ -1809,14 +1836,14 @@ static void prt_dsc_start(void)
static void prt_dsc_noarg(char *comment)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "%%%%%s\n", comment);
+ "%%%%%s\n", comment);
prt_write_file(prt_line_buffer);
}
static void prt_dsc_textline(char *comment, char *text)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "%%%%%s: %s\n", comment, text);
+ "%%%%%s: %s\n", comment, text);
prt_write_file(prt_line_buffer);
}
@@ -1824,7 +1851,7 @@ static void prt_dsc_text(char *comment, char *text)
{
// TODO(vim): - should scan 'text' for any chars needing escaping!
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "%%%%%s: (%s)\n", comment, text);
+ "%%%%%s: (%s)\n", comment, text);
prt_write_file(prt_line_buffer);
}
@@ -1835,7 +1862,7 @@ static void prt_dsc_ints(char *comment, int count, int *ints)
int i;
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "%%%%%s:", comment);
+ "%%%%%s:", comment);
prt_write_file(prt_line_buffer);
for (i = 0; i < count; i++) {
@@ -1846,23 +1873,21 @@ static void prt_dsc_ints(char *comment, int count, int *ints)
prt_write_string("\n");
}
-static void prt_dsc_resources(
- const char *comment, // if NULL add to previous
- const char *type,
- const char *string
-)
+/// @param comment if NULL add to previous
+static void prt_dsc_resources(const char *comment, const char *type, const char *string)
FUNC_ATTR_NONNULL_ARG(2, 3)
{
- if (comment != NULL)
+ if (comment != NULL) {
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "%%%%%s: %s", comment, type);
- else
+ "%%%%%s: %s", comment, type);
+ } else {
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "%%%%+ %s", type);
+ "%%%%+ %s", type);
+ }
prt_write_file(prt_line_buffer);
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- " %s\n", string);
+ " %s\n", string);
prt_write_file(prt_line_buffer);
}
@@ -1871,10 +1896,12 @@ static void prt_dsc_font_resource(char *resource, struct prt_ps_font_S *ps_font)
int i;
prt_dsc_resources(resource, "font",
- ps_font->ps_fontname[PRT_PS_FONT_ROMAN]);
- for (i = PRT_PS_FONT_BOLD; i <= PRT_PS_FONT_BOLDOBLIQUE; i++)
- if (ps_font->ps_fontname[i] != NULL)
+ ps_font->ps_fontname[PRT_PS_FONT_ROMAN]);
+ for (i = PRT_PS_FONT_BOLD; i <= PRT_PS_FONT_BOLDOBLIQUE; i++) {
+ if (ps_font->ps_fontname[i] != NULL) {
prt_dsc_resources(NULL, "font", ps_font->ps_fontname[i]);
+ }
+ }
}
static void prt_dsc_requirements(int duplex, int tumble, int collate, int color, int num_copies)
@@ -1882,21 +1909,25 @@ static void prt_dsc_requirements(int duplex, int tumble, int collate, int color,
/* Only output the comment if we need to.
* Note: tumble is ignored if we are not duplexing
*/
- if (!(duplex || collate || color || (num_copies > 1)))
+ if (!(duplex || collate || color || (num_copies > 1))) {
return;
+ }
sprintf((char *)prt_line_buffer, "%%%%Requirements:");
prt_write_file(prt_line_buffer);
if (duplex) {
prt_write_string(" duplex");
- if (tumble)
+ if (tumble) {
prt_write_string("(tumble)");
+ }
}
- if (collate)
+ if (collate) {
prt_write_string(" collate");
- if (color)
+ }
+ if (color) {
prt_write_string(" color");
+ }
if (num_copies > 1) {
prt_write_string(" numcopies(");
// Note: no space wanted so don't use prt_write_int()
@@ -1908,23 +1939,26 @@ static void prt_dsc_requirements(int duplex, int tumble, int collate, int color,
prt_write_string("\n");
}
-static void prt_dsc_docmedia(char *paper_name, double width, double height, double weight, char *colour, char *type)
+static void prt_dsc_docmedia(char *paper_name, double width, double height, double weight,
+ char *colour, char *type)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "%%%%DocumentMedia: %s ", paper_name);
+ "%%%%DocumentMedia: %s ", paper_name);
prt_write_file(prt_line_buffer);
prt_write_real(width, 2);
prt_write_real(height, 2);
prt_write_real(weight, 2);
- if (colour == NULL)
+ if (colour == NULL) {
prt_write_string("()");
- else
+ } else {
prt_write_string(colour);
+ }
prt_write_string(" ");
- if (type == NULL)
+ if (type == NULL) {
prt_write_string("()");
- else
+ } else {
prt_write_string(type);
+ }
prt_write_string("\n");
}
@@ -1938,8 +1972,9 @@ void mch_print_cleanup(void)
* one style).
*/
for (i = PRT_PS_FONT_ROMAN; i <= PRT_PS_FONT_BOLDOBLIQUE; i++) {
- if (prt_ps_mb_font.ps_fontname[i] != NULL)
+ if (prt_ps_mb_font.ps_fontname[i] != NULL) {
xfree(prt_ps_mb_font.ps_fontname[i]);
+ }
prt_ps_mb_font.ps_fontname[i] = NULL;
}
}
@@ -1993,7 +2028,8 @@ static double to_device_units(int idx, double physsize, int def_number)
/*
* Calculate margins for given width and height from printoptions settings.
*/
-static void prt_page_margins(double width, double height, double *left, double *right, double *top, double *bottom)
+static void prt_page_margins(double width, double height, double *left, double *right, double *top,
+ double *bottom)
{
*left = to_device_units(OPT_PRINT_LEFT, width, 10);
*right = width - to_device_units(OPT_PRINT_RIGHT, width, 5);
@@ -2015,11 +2051,13 @@ static int prt_get_cpl(void)
/* If we are outputting multi-byte characters then line numbers will be
* printed with half width characters
*/
- if (prt_out_mbyte)
+ if (prt_out_mbyte) {
prt_number_width /= 2;
+ }
prt_left_margin += prt_number_width;
- } else
+ } else {
prt_number_width = 0.0;
+ }
return (int)((prt_right_margin - prt_left_margin) / prt_char_width);
}
@@ -2044,11 +2082,11 @@ static int prt_get_lpp(void)
* case where the font height can exceed the line height.
*/
prt_bgcol_offset = PRT_PS_FONT_TO_USER(prt_line_height,
- prt_ps_font->bbox_min_y);
+ prt_ps_font->bbox_min_y);
if ((prt_ps_font->bbox_max_y - prt_ps_font->bbox_min_y) < 1000.0) {
prt_bgcol_offset -= PRT_PS_FONT_TO_USER(prt_line_height,
- (1000.0 - (prt_ps_font->bbox_max_y -
- prt_ps_font->bbox_min_y)) / 2);
+ (1000.0 - (prt_ps_font->bbox_max_y -
+ prt_ps_font->bbox_min_y)) / 2);
}
// Get height for topmost line based on background rect offset.
@@ -2063,11 +2101,12 @@ static int prt_get_lpp(void)
return lpp - prt_header_height();
}
-static int prt_match_encoding(char *p_encoding, struct prt_ps_mbfont_S *p_cmap, struct prt_ps_encoding_S **pp_mbenc)
+static int prt_match_encoding(char *p_encoding, struct prt_ps_mbfont_S *p_cmap,
+ struct prt_ps_encoding_S **pp_mbenc)
{
int mbenc;
int enc_len;
- struct prt_ps_encoding_S *p_mbenc;
+ struct prt_ps_encoding_S *p_mbenc;
*pp_mbenc = NULL;
// Look for recognised encoding
@@ -2083,7 +2122,8 @@ static int prt_match_encoding(char *p_encoding, struct prt_ps_mbfont_S *p_cmap,
return FALSE;
}
-static int prt_match_charset(char *p_charset, struct prt_ps_mbfont_S *p_cmap, struct prt_ps_charset_S **pp_mbchar)
+static int prt_match_charset(char *p_charset, struct prt_ps_mbfont_S *p_cmap,
+ struct prt_ps_charset_S **pp_mbchar)
{
int mbchar;
int char_len;
@@ -2108,24 +2148,25 @@ static int prt_match_charset(char *p_charset, struct prt_ps_mbfont_S *p_cmap, st
int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
{
int i;
- char *paper_name;
+ char *paper_name;
int paper_strlen;
int fontsize;
- char_u *p;
+ char_u *p;
int props;
int cmap = 0;
- char_u *p_encoding;
+ char_u *p_encoding;
struct prt_ps_encoding_S *p_mbenc;
struct prt_ps_encoding_S *p_mbenc_first;
- struct prt_ps_charset_S *p_mbchar = NULL;
+ struct prt_ps_charset_S *p_mbchar = NULL;
/*
* Set up font and encoding.
*/
p_encoding = enc_skip(p_penc);
- if (*p_encoding == NUL)
+ if (*p_encoding == NUL) {
p_encoding = enc_skip(p_enc);
+ }
/* Look for a multi-byte font that matches the encoding and character set.
* Only look if multi-byte character set is defined, or using multi-byte
@@ -2136,16 +2177,18 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
if (!(props & ENC_8BIT) && ((*p_pmcs != NUL) || !(props & ENC_UNICODE))) {
p_mbenc_first = NULL;
int effective_cmap = 0;
- for (cmap = 0; cmap < (int)ARRAY_SIZE(prt_ps_mbfonts); cmap++)
+ for (cmap = 0; cmap < (int)ARRAY_SIZE(prt_ps_mbfonts); cmap++) {
if (prt_match_encoding((char *)p_encoding, &prt_ps_mbfonts[cmap],
&p_mbenc)) {
if (p_mbenc_first == NULL) {
p_mbenc_first = p_mbenc;
effective_cmap = cmap;
}
- if (prt_match_charset((char *)p_pmcs, &prt_ps_mbfonts[cmap], &p_mbchar))
+ if (prt_match_charset((char *)p_pmcs, &prt_ps_mbfonts[cmap], &p_mbchar)) {
break;
+ }
}
+ }
// Use first encoding matched if no charset matched
if (p_mbenc_first != NULL && p_mbchar == NULL) {
@@ -2205,7 +2248,6 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
prt_build_cid_fontname(PRT_PS_FONT_BOLD,
mbfont_opts[OPT_MBFONT_BOLD].string,
mbfont_opts[OPT_MBFONT_BOLD].strlen);
-
}
if (mbfont_opts[OPT_MBFONT_OBLIQUE].present) {
prt_build_cid_fontname(PRT_PS_FONT_OBLIQUE,
@@ -2221,8 +2263,8 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
// Check if need to use Courier for ASCII code range, and if so pick up
// the encoding to use
prt_use_courier = (
- mbfont_opts[OPT_MBFONT_USECOURIER].present
- && (TOLOWER_ASC(mbfont_opts[OPT_MBFONT_USECOURIER].string[0]) == 'y'));
+ mbfont_opts[OPT_MBFONT_USECOURIER].present
+ && (TOLOWER_ASC(mbfont_opts[OPT_MBFONT_USECOURIER].string[0]) == 'y'));
if (prt_use_courier) {
// Use national ASCII variant unless ASCII wanted
if (mbfont_opts[OPT_MBFONT_ASCII].present
@@ -2252,13 +2294,16 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
paper_name = "A4";
paper_strlen = 2;
}
- for (i = 0; i < (int)PRT_MEDIASIZE_LEN; ++i)
+ for (i = 0; i < (int)PRT_MEDIASIZE_LEN; ++i) {
if (STRLEN(prt_mediasize[i].name) == (unsigned)paper_strlen
&& STRNICMP(prt_mediasize[i].name, paper_name,
- paper_strlen) == 0)
+ paper_strlen) == 0) {
break;
- if (i == PRT_MEDIASIZE_LEN)
+ }
+ }
+ if (i == PRT_MEDIASIZE_LEN) {
i = 0;
+ }
prt_media = i;
/*
@@ -2280,7 +2325,7 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
// needs to be done before the cpl and lpp are calculated.
double left, right, top, bottom;
prt_page_margins(prt_page_width, prt_page_height, &left, &right, &top,
- &bottom);
+ &bottom);
prt_left_margin = left;
prt_right_margin = right;
prt_top_margin = top;
@@ -2290,9 +2335,11 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
* Set up the font size.
*/
fontsize = PRT_PS_DEFAULT_FONTSIZE;
- for (p = p_pfn; (p = vim_strchr(p, ':')) != NULL; ++p)
- if (p[1] == 'h' && ascii_isdigit(p[2]))
+ for (p = p_pfn; (p = vim_strchr(p, ':')) != NULL; ++p) {
+ if (p[1] == 'h' && ascii_isdigit(p[2])) {
fontsize = atoi((char *)p + 2);
+ }
+ }
prt_font_metrics(fontsize);
/*
@@ -2340,8 +2387,9 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
prt_duplex = FALSE;
psettings->duplex = 0;
} else if (STRNICMP(printer_opts[OPT_PRINT_DUPLEX].string, "short", 5)
- == 0)
+ == 0) {
prt_tumble = TRUE;
+ }
}
// For now user abort not supported
@@ -2369,8 +2417,9 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
}
prt_bufsiz = psettings->chars_per_line;
- if (prt_out_mbyte)
+ if (prt_out_mbyte) {
prt_bufsiz *= 2;
+ }
ga_init(&prt_ps_buffer, (int)sizeof(char), prt_bufsiz);
prt_page_num = 0;
@@ -2389,7 +2438,7 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
static int prt_add_resource(struct prt_ps_resource_S *resource)
{
- FILE* fd_resource;
+ FILE *fd_resource;
char_u resource_buffer[512];
size_t bytes_read;
@@ -2403,7 +2452,7 @@ static int prt_add_resource(struct prt_ps_resource_S *resource)
case PRT_RESOURCE_TYPE_ENCODING:
case PRT_RESOURCE_TYPE_CMAP:
prt_dsc_resources("BeginResource", prt_resource_types[resource->type],
- (char *)resource->title);
+ (char *)resource->title);
break;
default:
return FALSE;
@@ -2413,15 +2462,16 @@ static int prt_add_resource(struct prt_ps_resource_S *resource)
for (;; ) {
bytes_read = fread((char *)resource_buffer, sizeof(char_u),
- sizeof(resource_buffer), fd_resource);
+ sizeof(resource_buffer), fd_resource);
if (ferror(fd_resource)) {
EMSG2(_("E457: Can't read PostScript resource file \"%s\""),
- resource->filename);
+ resource->filename);
fclose(fd_resource);
return FALSE;
}
- if (bytes_read == 0)
+ if (bytes_read == 0) {
break;
+ }
prt_write_file_raw_len(resource_buffer, bytes_read);
if (prt_file_error) {
fclose(fd_resource);
@@ -2447,8 +2497,8 @@ int mch_print_begin(prt_settings_T *psettings)
struct prt_ps_resource_S res_prolog;
struct prt_ps_resource_S res_encoding;
char buffer[256];
- char_u *p_encoding;
- char_u *p;
+ char_u *p_encoding;
+ char_u *p;
struct prt_ps_resource_S res_cidfont;
struct prt_ps_resource_S res_cmap;
int retval = FALSE;
@@ -2468,8 +2518,9 @@ int mch_print_begin(prt_settings_T *psettings)
char *p_time = os_ctime(ctime_buf, sizeof(ctime_buf));
// Note: os_ctime() adds a \n so we have to remove it :-(
p = vim_strchr((char_u *)p_time, '\n');
- if (p != NULL)
+ if (p != NULL) {
*p = NUL;
+ }
prt_dsc_textline("CreationDate", p_time);
prt_dsc_textline("DocumentData", "Clean8Bit");
prt_dsc_textline("Orientation", "Portrait");
@@ -2479,8 +2530,8 @@ int mch_print_begin(prt_settings_T *psettings)
* user coordinate system! We have to recalculate right and bottom
* coordinates based on the font metrics for the bbox to be accurate. */
prt_page_margins(prt_mediasize[prt_media].width,
- prt_mediasize[prt_media].height,
- &left, &right, &top, &bottom);
+ prt_mediasize[prt_media].height,
+ &left, &right, &top, &bottom);
bbox[0] = (int)left;
if (prt_portrait) {
/* In portrait printing the fixed point is the top left corner so we
@@ -2515,9 +2566,10 @@ int mch_print_begin(prt_settings_T *psettings)
}
if (prt_out_mbyte) {
prt_dsc_font_resource((prt_use_courier ? NULL
- : "DocumentNeededResources"), &prt_ps_mb_font);
- if (!prt_custom_cmap)
+ : "DocumentNeededResources"), &prt_ps_mb_font);
+ if (!prt_custom_cmap) {
prt_dsc_resources(NULL, "cmap", prt_cmap);
+ }
}
// Search for external resources VIM supplies
@@ -2525,20 +2577,24 @@ int mch_print_begin(prt_settings_T *psettings)
EMSG(_("E456: Can't find PostScript resource file \"prolog.ps\""));
return FALSE;
}
- if (!prt_open_resource(&res_prolog))
+ if (!prt_open_resource(&res_prolog)) {
return FALSE;
- if (!prt_check_resource(&res_prolog, PRT_PROLOG_VERSION))
+ }
+ if (!prt_check_resource(&res_prolog, PRT_PROLOG_VERSION)) {
return FALSE;
+ }
if (prt_out_mbyte) {
// Look for required version of multi-byte printing procset
if (!prt_find_resource("cidfont", &res_cidfont)) {
EMSG(_("E456: Can't find PostScript resource file \"cidfont.ps\""));
return FALSE;
}
- if (!prt_open_resource(&res_cidfont))
+ if (!prt_open_resource(&res_cidfont)) {
return FALSE;
- if (!prt_check_resource(&res_cidfont, PRT_CID_PROLOG_VERSION))
+ }
+ if (!prt_check_resource(&res_cidfont, PRT_CID_PROLOG_VERSION)) {
return FALSE;
+ }
}
/* Find an encoding to use for printing.
@@ -2562,28 +2618,31 @@ int mch_print_begin(prt_settings_T *psettings)
p_encoding = (char_u *)"latin1";
if (!prt_find_resource((char *)p_encoding, &res_encoding)) {
EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""),
- p_encoding);
+ p_encoding);
return FALSE;
}
}
}
- if (!prt_open_resource(&res_encoding))
+ if (!prt_open_resource(&res_encoding)) {
return FALSE;
+ }
/* For the moment there are no checks on encoding resource files to
* perform */
} else {
p_encoding = enc_skip(p_penc);
- if (*p_encoding == NUL)
+ if (*p_encoding == NUL) {
p_encoding = enc_skip(p_enc);
+ }
if (prt_use_courier) {
// Include ASCII range encoding vector
if (!prt_find_resource(prt_ascii_encoding, &res_encoding)) {
EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""),
- prt_ascii_encoding);
+ prt_ascii_encoding);
return FALSE;
}
- if (!prt_open_resource(&res_encoding))
+ if (!prt_open_resource(&res_encoding)) {
return FALSE;
+ }
/* For the moment there are no checks on encoding resource files to
* perform */
}
@@ -2604,11 +2663,12 @@ int mch_print_begin(prt_settings_T *psettings)
// Find user supplied CMap
if (!prt_find_resource(prt_cmap, &res_cmap)) {
EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""),
- prt_cmap);
+ prt_cmap);
return FALSE;
}
- if (!prt_open_resource(&res_cmap))
+ if (!prt_open_resource(&res_cmap)) {
return FALSE;
+ }
}
// List resources supplied
@@ -2636,8 +2696,8 @@ int mch_print_begin(prt_settings_T *psettings)
prt_dsc_resources(NULL, "encoding", buffer);
}
prt_dsc_requirements(prt_duplex, prt_tumble, prt_collate,
- psettings->do_syntax
- , prt_num_copies);
+ psettings->do_syntax,
+ prt_num_copies);
prt_dsc_noarg("EndComments");
/*
@@ -2651,9 +2711,10 @@ int mch_print_begin(prt_settings_T *psettings)
}
if (prt_out_mbyte) {
prt_dsc_font_resource((prt_use_courier ? NULL : "PageResources"),
- &prt_ps_mb_font);
- if (!prt_custom_cmap)
+ &prt_ps_mb_font);
+ if (!prt_custom_cmap) {
prt_dsc_resources(NULL, "cmap", prt_cmap);
+ }
}
// Paper will be used for all pages
@@ -2680,11 +2741,13 @@ int mch_print_begin(prt_settings_T *psettings)
}
}
- if (!prt_out_mbyte || prt_use_courier)
+ if (!prt_out_mbyte || prt_use_courier) {
/* There will be only one Roman font encoding to be included in the PS
* file. */
- if (!prt_add_resource(&res_encoding))
+ if (!prt_add_resource(&res_encoding)) {
return FALSE;
+ }
+ }
prt_dsc_noarg("EndProlog");
@@ -2710,44 +2773,47 @@ int mch_print_begin(prt_settings_T *psettings)
if (!prt_out_mbyte || prt_use_courier) {
/* When using Courier for ASCII range when printing multi-byte, need to
* pick up ASCII encoding to use with it. */
- if (prt_use_courier)
+ if (prt_use_courier) {
p_encoding = (char_u *)prt_ascii_encoding;
+ }
prt_dsc_resources("IncludeResource", "font",
- prt_ps_courier_font.ps_fontname[PRT_PS_FONT_ROMAN]);
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_ROMAN]);
prt_def_font("F0", (char *)p_encoding, (int)prt_line_height,
- prt_ps_courier_font.ps_fontname[PRT_PS_FONT_ROMAN]);
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_ROMAN]);
prt_dsc_resources("IncludeResource", "font",
- prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLD]);
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLD]);
prt_def_font("F1", (char *)p_encoding, (int)prt_line_height,
- prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLD]);
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLD]);
prt_dsc_resources("IncludeResource", "font",
- prt_ps_courier_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
prt_def_font("F2", (char *)p_encoding, (int)prt_line_height,
- prt_ps_courier_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
prt_dsc_resources("IncludeResource", "font",
- prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
prt_def_font("F3", (char *)p_encoding, (int)prt_line_height,
- prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
}
if (prt_out_mbyte) {
- /* Define the CID fonts to be used in the job. Typically CJKV fonts do
+ /* Define the CID fonts to be used in the job. Typically CJKV fonts do
* not have an italic form being a western style, so where no font is
* defined for these faces VIM falls back to an existing face.
* Note: if using Courier for the ASCII range then the printout will
* have bold/italic/bolditalic regardless of the setting of printmbfont.
*/
prt_dsc_resources("IncludeResource", "font",
- prt_ps_mb_font.ps_fontname[PRT_PS_FONT_ROMAN]);
- if (!prt_custom_cmap)
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_ROMAN]);
+ if (!prt_custom_cmap) {
prt_dsc_resources("IncludeResource", "cmap", prt_cmap);
+ }
prt_def_cidfont("CF0", (int)prt_line_height,
- prt_ps_mb_font.ps_fontname[PRT_PS_FONT_ROMAN]);
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_ROMAN]);
if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD] != NULL) {
prt_dsc_resources("IncludeResource", "font",
- prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD]);
- if (!prt_custom_cmap)
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD]);
+ if (!prt_custom_cmap) {
prt_dsc_resources("IncludeResource", "cmap", prt_cmap);
+ }
prt_def_cidfont("CF1", (int)prt_line_height,
prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD]);
} else {
@@ -2756,9 +2822,10 @@ int mch_print_begin(prt_settings_T *psettings)
}
if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE] != NULL) {
prt_dsc_resources("IncludeResource", "font",
- prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
- if (!prt_custom_cmap)
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
+ if (!prt_custom_cmap) {
prt_dsc_resources("IncludeResource", "cmap", prt_cmap);
+ }
prt_def_cidfont("CF2", (int)prt_line_height,
prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
} else {
@@ -2767,9 +2834,10 @@ int mch_print_begin(prt_settings_T *psettings)
}
if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE] != NULL) {
prt_dsc_resources("IncludeResource", "font",
- prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
- if (!prt_custom_cmap)
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
+ if (!prt_custom_cmap) {
prt_dsc_resources("IncludeResource", "cmap", prt_cmap);
+ }
prt_def_cidfont("CF3", (int)prt_line_height,
prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
} else {
@@ -2780,9 +2848,9 @@ int mch_print_begin(prt_settings_T *psettings)
// Misc constant vars used for underlining and background rects
prt_def_var("UO", PRT_PS_FONT_TO_USER(prt_line_height,
- prt_ps_font->uline_offset), 2);
+ prt_ps_font->uline_offset), 2);
prt_def_var("UW", PRT_PS_FONT_TO_USER(prt_line_height,
- prt_ps_font->uline_width), 2);
+ prt_ps_font->uline_width), 2);
prt_def_var("BO", prt_bgcol_offset, 2);
prt_dsc_noarg("EndSetup");
@@ -2818,7 +2886,7 @@ void mch_print_end(prt_settings_T *psettings)
prt_message((char_u *)_("Sending to printer..."));
// Not printing to a file: use 'printexpr' to print the file.
- if (eval_printexpr((char *) prt_ps_file_name, (char *) psettings->arguments)
+ if (eval_printexpr((char *)prt_ps_file_name, (char *)psettings->arguments)
== FAIL) {
EMSG(_("E365: Failed to print PostScript file"));
} else {
@@ -2853,10 +2921,11 @@ int mch_print_begin_page(char_u *str)
prt_write_string("sv\n0 g\n");
prt_in_ascii = !prt_out_mbyte;
- if (prt_out_mbyte)
+ if (prt_out_mbyte) {
prt_write_string("CF0 sf\n");
- else
+ } else {
prt_write_string("F0 sf\n");
+ }
prt_fgcol = PRCOLOR_BLACK;
prt_bgcol = PRCOLOR_WHITE;
prt_font = PRT_PS_FONT_ROMAN;
@@ -2983,9 +3052,9 @@ int mch_print_text_out(char_u *const textp, size_t len)
b = prt_fgcol & 0xff;
prt_write_real(r / 255.0, 3);
- if (r == g && g == b)
+ if (r == g && g == b) {
prt_write_string("g\n");
- else {
+ } else {
prt_write_real(g / 255.0, 3);
prt_write_real(b / 255.0, 3);
prt_write_string("r\n");
@@ -3003,8 +3072,9 @@ int mch_print_text_out(char_u *const textp, size_t len)
}
prt_need_bgcol = false;
- if (prt_need_underline)
+ if (prt_need_underline) {
prt_do_underline = prt_underline;
+ }
prt_need_underline = false;
prt_attribute_change = false;
@@ -3042,14 +3112,22 @@ int mch_print_text_out(char_u *const textp, size_t len)
*/
ga_append(&prt_ps_buffer, '\\');
switch (ch) {
- case BS: ga_append(&prt_ps_buffer, 'b'); break;
- case TAB: ga_append(&prt_ps_buffer, 't'); break;
- case NL: ga_append(&prt_ps_buffer, 'n'); break;
- case FF: ga_append(&prt_ps_buffer, 'f'); break;
- case CAR: ga_append(&prt_ps_buffer, 'r'); break;
- case '(': ga_append(&prt_ps_buffer, '('); break;
- case ')': ga_append(&prt_ps_buffer, ')'); break;
- case '\\': ga_append(&prt_ps_buffer, '\\'); break;
+ case BS:
+ ga_append(&prt_ps_buffer, 'b'); break;
+ case TAB:
+ ga_append(&prt_ps_buffer, 't'); break;
+ case NL:
+ ga_append(&prt_ps_buffer, 'n'); break;
+ case FF:
+ ga_append(&prt_ps_buffer, 'f'); break;
+ case CAR:
+ ga_append(&prt_ps_buffer, 'r'); break;
+ case '(':
+ ga_append(&prt_ps_buffer, '('); break;
+ case ')':
+ ga_append(&prt_ps_buffer, ')'); break;
+ case '\\':
+ ga_append(&prt_ps_buffer, '\\'); break;
default:
sprintf((char *)ch_buff, "%03o", (unsigned int)ch);
@@ -3058,8 +3136,9 @@ int mch_print_text_out(char_u *const textp, size_t len)
ga_append(&prt_ps_buffer, (char)ch_buff[2]);
break;
}
- } else
+ } else {
ga_append(&prt_ps_buffer, (char)ch);
+ }
}
// Need to free any translated characters
@@ -3071,7 +3150,7 @@ int mch_print_text_out(char_u *const textp, size_t len)
// The downside of fp - use relative error on right margin check
const double next_pos = prt_pos_x + prt_char_width;
const bool need_break = (next_pos > prt_right_margin)
- && ((next_pos - prt_right_margin) > (prt_right_margin * 1e-5));
+ && ((next_pos - prt_right_margin) > (prt_right_margin * 1e-5));
if (need_break) {
prt_flush_buffer();
@@ -3080,15 +3159,16 @@ int mch_print_text_out(char_u *const textp, size_t len)
return need_break;
}
-void mch_print_set_font(const TriState iBold, const TriState iItalic,
- const TriState iUnderline)
+void mch_print_set_font(const TriState iBold, const TriState iItalic, const TriState iUnderline)
{
int font = 0;
- if (iBold)
+ if (iBold) {
font |= 0x01;
- if (iItalic)
+ }
+ if (iItalic) {
font |= 0x02;
+ }
if (font != prt_font) {
prt_font = font;
diff --git a/src/nvim/hardcopy.h b/src/nvim/hardcopy.h
index c6a3321b08..eba769d342 100644
--- a/src/nvim/hardcopy.h
+++ b/src/nvim/hardcopy.h
@@ -4,9 +4,9 @@
#include <stdint.h>
#include <stdlib.h> // for size_t
+#include "nvim/ex_cmds_defs.h" // for exarg_T
#include "nvim/globals.h" // for TriState
#include "nvim/types.h" // for char_u
-#include "nvim/ex_cmds_defs.h" // for exarg_T
/*
* Structure to hold printing color and font attributes.
@@ -34,19 +34,19 @@ typedef struct {
int modec;
int do_syntax;
int user_abort;
- char_u *jobname;
- char_u *outfile;
- char_u *arguments;
+ char_u *jobname;
+ char_u *outfile;
+ char_u *arguments;
} prt_settings_T;
/*
* Generic option table item, only used for printer at the moment.
*/
typedef struct {
- const char *name;
+ const char *name;
int hasnum;
int number;
- char_u *string; /* points into option string */
+ char_u *string; // points into option string
int strlen;
int present;
} option_table_T;
@@ -67,13 +67,13 @@ typedef struct {
#define OPT_PRINT_FORMFEED 13
#define OPT_PRINT_NUM_OPTIONS 14
-/* For prt_get_unit(). */
+// For prt_get_unit().
#define PRT_UNIT_NONE -1
#define PRT_UNIT_PERC 0
#define PRT_UNIT_INCH 1
#define PRT_UNIT_MM 2
#define PRT_UNIT_POINT 3
-#define PRT_UNIT_NAMES {"pc", "in", "mm", "pt"}
+#define PRT_UNIT_NAMES { "pc", "in", "mm", "pt" }
#define PRINT_NUMBER_WIDTH 8
diff --git a/src/nvim/hashtab.c b/src/nvim/hashtab.c
index 526bc284a4..a8e5de839a 100644
--- a/src/nvim/hashtab.c
+++ b/src/nvim/hashtab.c
@@ -22,15 +22,15 @@
/// memory).
#include <assert.h>
+#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
-#include <inttypes.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/hashtab.h"
-#include "nvim/message.h"
#include "nvim/memory.h"
+#include "nvim/message.h"
+#include "nvim/vim.h"
// Magic value for algorithm that walks through the array.
#define PERTURB_SHIFT 5
@@ -102,8 +102,7 @@ hashitem_T *hash_find(const hashtab_T *const ht, const char_u *const key)
///
/// @warning Returned pointer becomes invalid as soon as the hash table
/// is changed in any way.
-hashitem_T *hash_find_len(const hashtab_T *const ht, const char *const key,
- const size_t len)
+hashitem_T *hash_find_len(const hashtab_T *const ht, const char *const key, const size_t len)
{
return hash_lookup(ht, key, len, hash_hash_len(key, len));
}
@@ -119,8 +118,7 @@ hashitem_T *hash_find_len(const hashtab_T *const ht, const char *const key,
/// used for that key.
/// WARNING: Returned pointer becomes invalid as soon as the hash table
/// is changed in any way.
-hashitem_T *hash_lookup(const hashtab_T *const ht,
- const char *const key, const size_t key_len,
+hashitem_T *hash_lookup(const hashtab_T *const ht, const char *const key, const size_t key_len,
const hash_T hash)
{
#ifdef HT_DEBUG
@@ -336,7 +334,7 @@ static void hash_may_resize(hashtab_T *ht, size_t minitems)
bool newarray_is_small = newsize == HT_INIT_SIZE;
bool keep_smallarray = newarray_is_small
- && ht->ht_array == ht->ht_smallarray;
+ && ht->ht_array == ht->ht_smallarray;
// Make sure that oldarray and newarray do not overlap,
// so that copying is possible.
@@ -387,7 +385,7 @@ static void hash_may_resize(hashtab_T *ht, size_t minitems)
}
#define HASH_CYCLE_BODY(hash, p) \
- hash = hash * 101 + *p++
+ hash = hash * 101 + *p++
/// Get the hash number for a key.
///
diff --git a/src/nvim/hashtab.h b/src/nvim/hashtab.h
index c82a6cc121..7740a3e431 100644
--- a/src/nvim/hashtab.h
+++ b/src/nvim/hashtab.h
@@ -77,18 +77,18 @@ typedef struct hashtable_S {
/// @param hi Name of the variable with current hashtab entry.
/// @param code Cycle body.
#define HASHTAB_ITER(ht, hi, code) \
- do { \
- hashtab_T *const hi##ht_ = (ht); \
- size_t hi##todo_ = hi##ht_->ht_used; \
- for (hashitem_T *hi = hi##ht_->ht_array; hi##todo_; hi++) { \
- if (!HASHITEM_EMPTY(hi)) { \
- hi##todo_--; \
- { \
- code \
- } \
+ do { \
+ hashtab_T *const hi##ht_ = (ht); \
+ size_t hi##todo_ = hi##ht_->ht_used; \
+ for (hashitem_T *hi = hi##ht_->ht_array; hi##todo_; hi++) { \
+ if (!HASHITEM_EMPTY(hi)) { \
+ hi##todo_--; \
+ { \
+ code \
} \
} \
- } while (0)
+ } \
+ } while (0)
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "hashtab.h.generated.h"
diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c
index 7341ac9393..737e668e81 100644
--- a/src/nvim/highlight.c
+++ b/src/nvim/highlight.c
@@ -3,9 +3,11 @@
// highlight.c: low level code for UI and syntax highlighting
-#include "nvim/vim.h"
+#include "nvim/api/private/defs.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/highlight.h"
#include "nvim/highlight_defs.h"
+#include "nvim/lua/executor.h"
#include "nvim/map.h"
#include "nvim/message.h"
#include "nvim/option.h"
@@ -13,9 +15,7 @@
#include "nvim/screen.h"
#include "nvim/syntax.h"
#include "nvim/ui.h"
-#include "nvim/api/private/defs.h"
-#include "nvim/api/private/helpers.h"
-#include "nvim/lua/executor.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "highlight.c.generated.h"
@@ -306,7 +306,7 @@ void update_window_hl(win_T *wp, bool invalid)
// syntax group! It needs at least 10 layers of special casing! Noooooo!
//
// haha, theme engine go brrr
- int normality = syn_check_group((const char_u *)S_LEN("Normal"));
+ int normality = syn_check_group(S_LEN("Normal"));
int ns_attr = ns_get_hl(-1, normality, false, false);
if (ns_attr > 0) {
// TODO(bfredl): hantera NormalNC and so on
@@ -361,19 +361,19 @@ void update_window_hl(win_T *wp, bool invalid)
int hl_get_underline(void)
{
return get_attr_entry((HlEntry){
- .attr = (HlAttrs){
- .cterm_ae_attr = (int16_t)HL_UNDERLINE,
- .cterm_fg_color = 0,
- .cterm_bg_color = 0,
- .rgb_ae_attr = (int16_t)HL_UNDERLINE,
- .rgb_fg_color = -1,
- .rgb_bg_color = -1,
- .rgb_sp_color = -1,
- .hl_blend = -1,
- },
- .kind = kHlUI,
- .id1 = 0,
- .id2 = 0,
+ .attr = (HlAttrs){
+ .cterm_ae_attr = (int16_t)HL_UNDERLINE,
+ .cterm_fg_color = 0,
+ .cterm_bg_color = 0,
+ .rgb_ae_attr = (int16_t)HL_UNDERLINE,
+ .rgb_fg_color = -1,
+ .rgb_bg_color = -1,
+ .rgb_sp_color = -1,
+ .hl_blend = -1,
+ },
+ .kind = kHlUI,
+ .id1 = 0,
+ .id2 = 0,
});
}
@@ -648,23 +648,23 @@ static int hl_cterm2rgb_color(int nr)
};
static char_u ansi_table[16][4] = {
// R G B idx
- { 0, 0, 0, 1 } , // black
- { 224, 0, 0, 2 } , // dark red
- { 0, 224, 0, 3 } , // dark green
- { 224, 224, 0, 4 } , // dark yellow / brown
- { 0, 0, 224, 5 } , // dark blue
- { 224, 0, 224, 6 } , // dark magenta
- { 0, 224, 224, 7 } , // dark cyan
- { 224, 224, 224, 8 } , // light grey
-
- { 128, 128, 128, 9 } , // dark grey
- { 255, 64, 64, 10 } , // light red
- { 64, 255, 64, 11 } , // light green
- { 255, 255, 64, 12 } , // yellow
- { 64, 64, 255, 13 } , // light blue
- { 255, 64, 255, 14 } , // light magenta
- { 64, 255, 255, 15 } , // light cyan
- { 255, 255, 255, 16 } , // white
+ { 0, 0, 0, 1 }, // black
+ { 224, 0, 0, 2 }, // dark red
+ { 0, 224, 0, 3 }, // dark green
+ { 224, 224, 0, 4 }, // dark yellow / brown
+ { 0, 0, 224, 5 }, // dark blue
+ { 224, 0, 224, 6 }, // dark magenta
+ { 0, 224, 224, 7 }, // dark cyan
+ { 224, 224, 224, 8 }, // light grey
+
+ { 128, 128, 128, 9 }, // dark grey
+ { 255, 64, 64, 10 }, // light red
+ { 64, 255, 64, 11 }, // light green
+ { 255, 255, 64, 12 }, // yellow
+ { 64, 64, 255, 13 }, // light blue
+ { 255, 64, 255, 14 }, // light magenta
+ { 64, 255, 255, 15 }, // light cyan
+ { 255, 255, 255, 16 }, // white
};
int r = 0;
@@ -790,7 +790,7 @@ Dictionary hlattrs2dict(HlAttrs ae, bool use_rgb)
}
if (ae.hl_blend > -1) {
- PUT(hl, "blend", INTEGER_OBJ(ae.hl_blend));
+ PUT(hl, "blend", INTEGER_OBJ(ae.hl_blend));
}
return hl;
@@ -847,7 +847,7 @@ HlAttrs dict2hlattrs(Dictionary dict, bool use_rgb, int *link_id, Error *err)
err)) {
cterm_mask |= flags[m].flag;
}
- break;
+ break;
}
}
}
@@ -890,7 +890,7 @@ HlAttrs dict2hlattrs(Dictionary dict, bool use_rgb, int *link_id, Error *err)
} else if (link_id && strequal(key, "link")) {
if (val.type == kObjectTypeString) {
String str = val.data.string;
- *link_id = syn_check_group((const char_u *)str.data, (int)str.size);
+ *link_id = syn_check_group(str.data, (int)str.size);
} else if (val.type == kObjectTypeInteger) {
// TODO(bfredl): validate range?
*link_id = (int)val.data.integer;
@@ -915,9 +915,9 @@ HlAttrs dict2hlattrs(Dictionary dict, bool use_rgb, int *link_id, Error *err)
hlattrs.rgb_fg_color = fg;
hlattrs.rgb_sp_color = sp;
hlattrs.cterm_bg_color =
- ctermbg == -1 ? cterm_normal_bg_color : ctermbg + 1;
+ ctermbg == -1 ? cterm_normal_bg_color : ctermbg + 1;
hlattrs.cterm_fg_color =
- ctermfg == -1 ? cterm_normal_fg_color : ctermfg + 1;
+ ctermfg == -1 ? cterm_normal_fg_color : ctermfg + 1;
hlattrs.cterm_ae_attr = cterm_mask;
} else {
hlattrs.cterm_ae_attr = cterm_mask;
@@ -945,34 +945,34 @@ static void hl_inspect_impl(Array *arr, int attr)
HlEntry e = kv_A(attr_entries, attr);
switch (e.kind) {
- case kHlSyntax:
- PUT(item, "kind", STRING_OBJ(cstr_to_string("syntax")));
- PUT(item, "hi_name",
- STRING_OBJ(cstr_to_string((char *)syn_id2name(e.id1))));
- break;
-
- case kHlUI:
- PUT(item, "kind", STRING_OBJ(cstr_to_string("ui")));
- const char *ui_name = (e.id1 == -1) ? "Normal" : hlf_names[e.id1];
- PUT(item, "ui_name", STRING_OBJ(cstr_to_string(ui_name)));
- PUT(item, "hi_name",
- STRING_OBJ(cstr_to_string((char *)syn_id2name(e.id2))));
- break;
-
- case kHlTerminal:
- PUT(item, "kind", STRING_OBJ(cstr_to_string("term")));
- break;
-
- case kHlCombine:
- case kHlBlend:
- case kHlBlendThrough:
- // attribute combination is associative, so flatten to an array
- hl_inspect_impl(arr, e.id1);
- hl_inspect_impl(arr, e.id2);
- return;
-
- case kHlUnknown:
- return;
+ case kHlSyntax:
+ PUT(item, "kind", STRING_OBJ(cstr_to_string("syntax")));
+ PUT(item, "hi_name",
+ STRING_OBJ(cstr_to_string((char *)syn_id2name(e.id1))));
+ break;
+
+ case kHlUI:
+ PUT(item, "kind", STRING_OBJ(cstr_to_string("ui")));
+ const char *ui_name = (e.id1 == -1) ? "Normal" : hlf_names[e.id1];
+ PUT(item, "ui_name", STRING_OBJ(cstr_to_string(ui_name)));
+ PUT(item, "hi_name",
+ STRING_OBJ(cstr_to_string((char *)syn_id2name(e.id2))));
+ break;
+
+ case kHlTerminal:
+ PUT(item, "kind", STRING_OBJ(cstr_to_string("term")));
+ break;
+
+ case kHlCombine:
+ case kHlBlend:
+ case kHlBlendThrough:
+ // attribute combination is associative, so flatten to an array
+ hl_inspect_impl(arr, e.id1);
+ hl_inspect_impl(arr, e.id2);
+ return;
+
+ case kHlUnknown:
+ return;
}
PUT(item, "id", INTEGER_OBJ(attr));
ADD(*arr, DICTIONARY_OBJ(item));
diff --git a/src/nvim/highlight.h b/src/nvim/highlight.h
index a237ddbc34..ae63f83d65 100644
--- a/src/nvim/highlight.h
+++ b/src/nvim/highlight.h
@@ -2,15 +2,16 @@
#define NVIM_HIGHLIGHT_H
#include <stdbool.h>
-#include "nvim/highlight_defs.h"
+
#include "nvim/api/private/defs.h"
+#include "nvim/highlight_defs.h"
#include "nvim/ui.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "highlight.h.generated.h"
#endif
-# define HL_SET_DEFAULT_COLORS(rgb_fg, rgb_bg, rgb_sp) \
+#define HL_SET_DEFAULT_COLORS(rgb_fg, rgb_bg, rgb_sp) \
do { \
bool dark_ = (*p_bg == 'd'); \
rgb_fg = rgb_fg != -1 ? rgb_fg : (dark_ ? 0xFFFFFF : 0x000000); \
diff --git a/src/nvim/highlight_defs.h b/src/nvim/highlight_defs.h
index a0e8bad11f..12f2b62313 100644
--- a/src/nvim/highlight_defs.h
+++ b/src/nvim/highlight_defs.h
@@ -49,62 +49,61 @@ typedef struct attr_entry {
/// Values for index in highlight_attr[].
/// When making changes, also update hlf_names below!
typedef enum {
- HLF_8 = 0 // Meta & special keys listed with ":map", text that is
+ HLF_8 = 0, // Meta & special keys listed with ":map", text that is
// displayed different from what it is
- , HLF_EOB // after the last line in the buffer
- , HLF_TERM // terminal cursor focused
- , HLF_TERMNC // terminal cursor unfocused
- , HLF_AT // @ characters at end of screen, characters that
- // don't really exist in the text
- , HLF_D // directories in CTRL-D listing
- , HLF_E // error messages
- , HLF_I // incremental search
- , HLF_L // last search string
- , HLF_M // "--More--" message
- , HLF_CM // Mode (e.g., "-- INSERT --")
- , HLF_N // line number for ":number" and ":#" commands
- , HLF_LNA // LineNrAbove
- , HLF_LNB // LineNrBelow
- , HLF_CLN // current line number when 'cursorline' is set
- , HLF_R // return to continue message and yes/no questions
- , HLF_S // status lines
- , HLF_SNC // status lines of not-current windows
- , HLF_C // column to separate vertically split windows
- , HLF_T // Titles for output from ":set all", ":autocmd" etc.
- , HLF_V // Visual mode
- , HLF_VNC // Visual mode, autoselecting and not clipboard owner
- , HLF_W // warning messages
- , HLF_WM // Wildmenu highlight
- , HLF_FL // Folded line
- , HLF_FC // Fold column
- , HLF_ADD // Added diff line
- , HLF_CHD // Changed diff line
- , HLF_DED // Deleted diff line
- , HLF_TXD // Text Changed in diff line
- , HLF_SC // Sign column
- , HLF_CONCEAL // Concealed text
- , HLF_SPB // SpellBad
- , HLF_SPC // SpellCap
- , HLF_SPR // SpellRare
- , HLF_SPL // SpellLocal
- , HLF_PNI // popup menu normal item
- , HLF_PSI // popup menu selected item
- , HLF_PSB // popup menu scrollbar
- , HLF_PST // popup menu scrollbar thumb
- , HLF_TP // tabpage line
- , HLF_TPS // tabpage line selected
- , HLF_TPF // tabpage line filler
- , HLF_CUC // 'cursorcolumn'
- , HLF_CUL // 'cursorline'
- , HLF_MC // 'colorcolumn'
- , HLF_QFL // selected quickfix line
- , HLF_0 // Whitespace
- , HLF_INACTIVE // NormalNC: Normal text in non-current windows
- , HLF_MSGSEP // message separator line
- , HLF_NFLOAT // Floating window
- , HLF_MSG // Message area
- , HLF_BORDER // Floating window border
- , HLF_COUNT // MUST be the last one
+ HLF_EOB, // after the last line in the buffer
+ HLF_TERM, // terminal cursor focused
+ HLF_TERMNC, // terminal cursor unfocused
+ HLF_AT, // @ characters at end of screen, characters that don't really exist in the text
+ HLF_D, // directories in CTRL-D listing
+ HLF_E, // error messages
+ HLF_I, // incremental search
+ HLF_L, // last search string
+ HLF_M, // "--More--" message
+ HLF_CM, // Mode (e.g., "-- INSERT --")
+ HLF_N, // line number for ":number" and ":#" commands
+ HLF_LNA, // LineNrAbove
+ HLF_LNB, // LineNrBelow
+ HLF_CLN, // current line number when 'cursorline' is set
+ HLF_R, // return to continue message and yes/no questions
+ HLF_S, // status lines
+ HLF_SNC, // status lines of not-current windows
+ HLF_C, // column to separate vertically split windows
+ HLF_T, // Titles for output from ":set all", ":autocmd" etc.
+ HLF_V, // Visual mode
+ HLF_VNC, // Visual mode, autoselecting and not clipboard owner
+ HLF_W, // warning messages
+ HLF_WM, // Wildmenu highlight
+ HLF_FL, // Folded line
+ HLF_FC, // Fold column
+ HLF_ADD, // Added diff line
+ HLF_CHD, // Changed diff line
+ HLF_DED, // Deleted diff line
+ HLF_TXD, // Text Changed in diff line
+ HLF_SC, // Sign column
+ HLF_CONCEAL, // Concealed text
+ HLF_SPB, // SpellBad
+ HLF_SPC, // SpellCap
+ HLF_SPR, // SpellRare
+ HLF_SPL, // SpellLocal
+ HLF_PNI, // popup menu normal item
+ HLF_PSI, // popup menu selected item
+ HLF_PSB, // popup menu scrollbar
+ HLF_PST, // popup menu scrollbar thumb
+ HLF_TP, // tabpage line
+ HLF_TPS, // tabpage line selected
+ HLF_TPF, // tabpage line filler
+ HLF_CUC, // 'cursorcolumn'
+ HLF_CUL, // 'cursorline'
+ HLF_MC, // 'colorcolumn'
+ HLF_QFL, // selected quickfix line
+ HLF_0, // Whitespace
+ HLF_INACTIVE, // NormalNC: Normal text in non-current windows
+ HLF_MSGSEP, // message separator line
+ HLF_NFLOAT, // Floating window
+ HLF_MSG, // Message area
+ HLF_BORDER, // Floating window border
+ HLF_COUNT // MUST be the last one
} hlf_T;
EXTERN const char *hlf_names[] INIT(= {
diff --git a/src/nvim/iconv.h b/src/nvim/iconv.h
index a7c9ad4040..509f83c415 100644
--- a/src/nvim/iconv.h
+++ b/src/nvim/iconv.h
@@ -4,17 +4,17 @@
#include "auto/config.h"
#ifdef HAVE_ICONV
-# include <errno.h>
-# include <iconv.h>
+# include <errno.h>
+# include <iconv.h>
// define some missing constants if necessary
-# ifndef EILSEQ
-# define EILSEQ 123
-# endif
-# define ICONV_ERRNO errno
-# define ICONV_E2BIG E2BIG
-# define ICONV_EINVAL EINVAL
-# define ICONV_EILSEQ EILSEQ
+# ifndef EILSEQ
+# define EILSEQ 123
+# endif
+# define ICONV_ERRNO errno
+# define ICONV_E2BIG E2BIG
+# define ICONV_EINVAL EINVAL
+# define ICONV_EILSEQ EILSEQ
#endif
#endif // NVIM_ICONV_H
diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c
index 31615e744a..d731e79473 100644
--- a/src/nvim/if_cscope.c
+++ b/src/nvim/if_cscope.c
@@ -9,31 +9,29 @@
* might be a few lines of code that look similar to what Nvi has.
*/
-#include <stdbool.h>
-
#include <assert.h>
#include <errno.h>
-#include <inttypes.h>
#include <fcntl.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <sys/stat.h>
+#include <sys/types.h>
-#include "nvim/buffer.h"
#include "nvim/ascii.h"
-#include "nvim/if_cscope.h"
+#include "nvim/buffer.h"
#include "nvim/charset.h"
+#include "nvim/event/stream.h"
#include "nvim/fileio.h"
-#include "nvim/message.h"
+#include "nvim/if_cscope.h"
#include "nvim/memory.h"
+#include "nvim/message.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
#include "nvim/os/time.h"
#include "nvim/path.h"
#include "nvim/quickfix.h"
#include "nvim/strings.h"
#include "nvim/tag.h"
-#include "nvim/os/os.h"
-#include "nvim/os/input.h"
-#include "nvim/event/stream.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
#if defined(UNIX)
# include <sys/wait.h>
#endif
@@ -43,7 +41,7 @@
# include "if_cscope.c.generated.h"
#endif
-static csinfo_T * csinfo = NULL;
+static csinfo_T *csinfo = NULL;
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()
@@ -90,19 +88,20 @@ char_u *get_cscope_name(expand_T *xp, int idx)
// Complete with sub-commands of ":cscope":
// add, find, help, kill, reset, show
return (char_u *)cs_cmds[idx].name;
- case EXP_SCSCOPE_SUBCMD:
- {
+ 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)
+ 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:
- {
+ case EXP_CSCOPE_FIND: {
const char *query_type[] =
{
"a", "c", "d", "e", "f", "g", "i", "s", "t", NULL
@@ -114,8 +113,7 @@ char_u *get_cscope_name(expand_T *xp, int idx)
// redundant.
return (char_u *)query_type[idx];
}
- case EXP_CSCOPE_KILL:
- {
+ case EXP_CSCOPE_KILL: {
static char connection[5];
// ":cscope kill" accepts connection numbers or partial names of
@@ -124,8 +122,9 @@ char_u *get_cscope_name(expand_T *xp, int idx)
// connections.
size_t i;
for (i = 0, current_idx = 0; i < csinfo_size; i++) {
- if (csinfo[i].fname == NULL)
+ if (csinfo[i].fname == NULL) {
continue;
+ }
if (current_idx++ == idx) {
vim_snprintf(connection, sizeof(connection), "%zu", i);
return (char_u *)connection;
@@ -172,11 +171,9 @@ void set_context_in_cscope_cmd(expand_T *xp, const char *arg, cmdidx_T cmdidx)
/// Find the command, print help if invalid, and then call the corresponding
/// command function.
-static void
-do_cscope_general(
- exarg_T *eap,
- int make_split // whether to split window
-)
+///
+/// @param make_split whether to split window
+static void do_cscope_general(exarg_T *eap, int make_split)
{
cscmd_T *cmdp;
@@ -187,8 +184,7 @@ do_cscope_general(
if (make_split) {
if (!cmdp->cansplit) {
- (void)MSG_PUTS(_(
- "This cscope command does not support splitting the window.\n"));
+ (void)MSG_PUTS(_("This cscope command does not support splitting the window.\n"));
return;
}
postponed_split = -1;
@@ -228,14 +224,16 @@ void ex_cstag(exarg_T *eap)
case 0:
if (cs_check_for_connections()) {
ret = cs_find_common("g", (char *)(eap->arg), eap->forceit, FALSE,
- FALSE, *eap->cmdlinep);
+ FALSE, *eap->cmdlinep);
if (ret == FALSE) {
cs_free_tags();
- if (msg_col)
+ if (msg_col) {
msg_putchar('\n');
+ }
- if (cs_check_for_tags())
+ if (cs_check_for_tags()) {
ret = do_tag(eap->arg, DT_JUMP, 0, eap->forceit, FALSE);
+ }
}
} else if (cs_check_for_tags()) {
ret = do_tag(eap->arg, DT_JUMP, 0, eap->forceit, FALSE);
@@ -245,21 +243,24 @@ void ex_cstag(exarg_T *eap)
if (cs_check_for_tags()) {
ret = do_tag(eap->arg, DT_JUMP, 0, eap->forceit, FALSE);
if (ret == FALSE) {
- if (msg_col)
+ if (msg_col) {
msg_putchar('\n');
+ }
if (cs_check_for_connections()) {
ret = cs_find_common("g", (char *)(eap->arg), eap->forceit,
- FALSE, FALSE, *eap->cmdlinep);
- if (ret == FALSE)
+ FALSE, FALSE, *eap->cmdlinep);
+ if (ret == FALSE) {
cs_free_tags();
+ }
}
}
} else if (cs_check_for_connections()) {
ret = cs_find_common("g", (char *)(eap->arg), eap->forceit, FALSE,
- FALSE, *eap->cmdlinep);
- if (ret == FALSE)
+ FALSE, *eap->cmdlinep);
+ if (ret == FALSE) {
cs_free_tags();
+ }
}
break;
default:
@@ -306,29 +307,29 @@ void cs_print_tags(void)
/*
* "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
*
- * Checks for the existence of a |cscope| connection. If no
- * parameters are specified, then the function returns:
+ * Checks for the existence of a |cscope| connection. If no
+ * parameters are specified, then the function returns:
*
- * 0, if cscope was not available (not compiled in), or if there
- * are no cscope connections; or
- * 1, if there is at least one cscope connection.
+ * 0, if cscope was not available (not compiled in), or if there
+ * are no cscope connections; or
+ * 1, if there is at least one cscope connection.
*
- * If parameters are specified, then the value of {num}
- * determines how existence of a cscope connection is checked:
+ * If parameters are specified, then the value of {num}
+ * determines how existence of a cscope connection is checked:
*
- * {num} Description of existence check
- * ----- ------------------------------
- * 0 Same as no parameters (e.g., "cscope_connection()").
- * 1 Ignore {prepend}, and use partial string matches for
- * {dbpath}.
- * 2 Ignore {prepend}, and use exact string matches for
- * {dbpath}.
- * 3 Use {prepend}, use partial string matches for both
- * {dbpath} and {prepend}.
- * 4 Use {prepend}, use exact string matches for both
- * {dbpath} and {prepend}.
+ * {num} Description of existence check
+ * ----- ------------------------------
+ * 0 Same as no parameters (e.g., "cscope_connection()").
+ * 1 Ignore {prepend}, and use partial string matches for
+ * {dbpath}.
+ * 2 Ignore {prepend}, and use exact string matches for
+ * {dbpath}.
+ * 3 Use {prepend}, use partial string matches for both
+ * {dbpath} and {prepend}.
+ * 4 Use {prepend}, use exact string matches for both
+ * {dbpath} and {prepend}.
*
- * Note: All string comparisons are case sensitive!
+ * Note: All string comparisons are case sensitive!
*/
bool cs_connection(int num, char_u *dbpath, char_u *ppath)
{
@@ -393,8 +394,9 @@ static int cs_add(exarg_T *eap)
cs_usage_msg(Add);
return CSCOPE_FAILURE;
}
- if ((ppath = strtok((char *)NULL, (const char *)" ")) != NULL)
+ if ((ppath = strtok((char *)NULL, (const char *)" ")) != NULL) {
flags = strtok((char *)NULL, (const char *)" ");
+ }
return cs_add_common(fname, ppath, flags);
}
@@ -413,18 +415,16 @@ static void cs_stat_emsg(char *fname)
/// The common routine to add a new cscope connection. Called by
/// cs_add() and cs_reset(). I really don't like to do this, but this
/// routine uses a number of goto statements.
-static int
-cs_add_common(
- char *arg1, // filename - may contain environment variables
- char *arg2, // prepend path - may contain environment variables
- char *flags
-)
+///
+/// @param arg1 filename - may contain environment variables
+/// @param arg2 prepend path - may contain environment variables
+static int cs_add_common(char *arg1, char *arg2, char *flags)
{
- char *fname = NULL;
- char *fname2 = NULL;
- char *ppath = NULL;
+ char *fname = NULL;
+ char *fname2 = NULL;
+ char *ppath = NULL;
size_t usedlen = 0;
- char_u *fbuf = NULL;
+ char_u *fbuf = NULL;
// get the filename (arg1), expand it, and try to stat it
fname = xmalloc(MAXPATHL + 1);
@@ -443,8 +443,9 @@ cs_add_common(
bool file_info_ok = os_fileinfo(fname, &file_info);
if (!file_info_ok) {
staterr:
- if (p_csverbose)
+ if (p_csverbose) {
cs_stat_emsg(fname);
+ }
goto add_err;
}
@@ -465,31 +466,32 @@ staterr:
while (fname[strlen(fname)-1] == '/'
) {
fname[strlen(fname)-1] = '\0';
- if (fname[0] == '\0')
+ if (fname[0] == '\0') {
break;
+ }
}
- if (fname[0] == '\0')
+ if (fname[0] == '\0') {
(void)sprintf(fname2, "/%s", CSCOPE_DBFILE);
- else
+ } else {
(void)sprintf(fname2, "%s/%s", fname, CSCOPE_DBFILE);
+ }
file_info_ok = os_fileinfo(fname2, &file_info);
if (!file_info_ok) {
- if (p_csverbose)
+ if (p_csverbose) {
cs_stat_emsg(fname2);
+ }
goto add_err;
}
i = cs_insert_filelist(fname2, ppath, flags, &file_info);
- }
- else if (S_ISREG(file_info.stat.st_mode) || S_ISLNK(file_info.stat.st_mode))
- {
+ } else if (S_ISREG(file_info.stat.st_mode) || S_ISLNK(file_info.stat.st_mode)) {
i = cs_insert_filelist(fname, ppath, flags, &file_info);
} else {
- if (p_csverbose)
- (void)EMSG2(
- _("E564: %s is not a directory or a valid cscope database"),
- fname);
+ if (p_csverbose) {
+ (void)EMSG2(_("E564: %s is not a directory or a valid cscope database"),
+ fname);
+ }
goto add_err;
}
@@ -538,15 +540,15 @@ static size_t cs_cnt_connections(void)
size_t cnt = 0;
for (size_t i = 0; i < csinfo_size; i++) {
- if (csinfo[i].fname != NULL)
+ if (csinfo[i].fname != NULL) {
cnt++;
+ }
}
return cnt;
}
-static void cs_reading_emsg(
- size_t idx // connection index
-)
+/// @param idx connection index
+static void cs_reading_emsg(size_t idx)
{
EMSGU(_("E262: error reading cscope connection %" PRIu64), idx);
}
@@ -582,7 +584,7 @@ static int cs_cnt_matches(size_t idx)
// Accept "\S*cscope: X lines", also matches "mlcscope".
// Bail out for the "Unable to search" error.
if (strstr((const char *)buf, "Unable to search database") != NULL) {
- break;
+ break;
}
if ((stok = strtok(buf, (const char *)" ")) == NULL) {
continue;
@@ -591,18 +593,21 @@ static int cs_cnt_matches(size_t idx)
continue;
}
- if ((stok = strtok(NULL, (const char *)" ")) == NULL)
+ if ((stok = strtok(NULL, (const char *)" ")) == NULL) {
continue;
+ }
nlines = atoi(stok);
if (nlines < 0) {
nlines = 0;
break;
}
- if ((stok = strtok(NULL, (const char *)" ")) == NULL)
+ if ((stok = strtok(NULL, (const char *)" ")) == NULL) {
continue;
- if (strncmp((const char *)stok, "lines", 5))
+ }
+ if (strncmp((const char *)stok, "lines", 5)) {
continue;
+ }
break;
}
@@ -620,31 +625,40 @@ static char *cs_create_cmd(char *csoption, char *pattern)
char *pat;
switch (csoption[0]) {
- case '0': case 's':
+ case '0':
+ case 's':
search = 0;
break;
- case '1': case 'g':
+ case '1':
+ case 'g':
search = 1;
break;
- case '2': case 'd':
+ case '2':
+ case 'd':
search = 2;
break;
- case '3': case 'c':
+ case '3':
+ case 'c':
search = 3;
break;
- case '4': case 't':
+ case '4':
+ case 't':
search = 4;
break;
- case '6': case 'e':
+ case '6':
+ case 'e':
search = 6;
break;
- case '7': case 'f':
+ case '7':
+ case 'f':
search = 7;
break;
- case '8': case 'i':
+ case '8':
+ case 'i':
search = 8;
break;
- case '9': case 'a':
+ case '9':
+ case 'a':
search = 9;
break;
default:
@@ -656,9 +670,11 @@ static char *cs_create_cmd(char *csoption, char *pattern)
// Skip white space before the patter, except for text and pattern search,
// they may want to use the leading white space.
pat = pattern;
- if (search != 4 && search != 6)
- while (ascii_iswhite(*pat))
+ if (search != 4 && search != 6) {
+ while (ascii_iswhite(*pat)) {
++pat;
+ }
+ }
cmd = xmalloc(strlen(pat) + 2);
@@ -675,7 +691,7 @@ static int cs_create_connection(size_t i)
#ifdef UNIX
int to_cs[2], from_cs[2];
#endif
- char *prog, *cmd, *ppath = NULL;
+ char *prog, *cmd, *ppath = NULL;
#if defined(UNIX)
/*
@@ -686,14 +702,18 @@ static int cs_create_connection(size_t i)
if (pipe(to_cs) < 0 || pipe(from_cs) < 0) {
(void)EMSG(_("E566: Could not create cscope pipes"));
err_closing:
- if (to_cs[0] != -1)
+ if (to_cs[0] != -1) {
(void)close(to_cs[0]);
- if (to_cs[1] != -1)
+ }
+ if (to_cs[1] != -1) {
(void)close(to_cs[1]);
- if (from_cs[0] != -1)
+ }
+ if (from_cs[0] != -1) {
(void)close(from_cs[0]);
- if (from_cs[1] != -1)
+ }
+ if (from_cs[1] != -1) {
(void)close(from_cs[1]);
+ }
return CSCOPE_FAILURE;
}
@@ -759,8 +779,9 @@ err_closing:
len += strlen(ppath);
}
- if (csinfo[i].flags)
+ if (csinfo[i].flags) {
len += strlen(csinfo[i].flags);
+ }
cmd = xmalloc(len);
@@ -779,10 +800,10 @@ err_closing:
(void)strcat(cmd, " ");
(void)strcat(cmd, csinfo[i].flags);
}
-# ifdef UNIX
+#ifdef UNIX
// on Win32 we still need prog
xfree(prog);
-# endif
+#endif
xfree(ppath);
#if defined(UNIX)
@@ -791,12 +812,14 @@ err_closing:
# if defined(HAVE_SETSID)
(void)setsid();
# else
- if (setpgid(0, 0) == -1)
+ if (setpgid(0, 0) == -1) {
PERROR(_("cs_create_connection setpgid failed"));
+ }
# endif
# endif
- if (execl("/bin/sh", "sh", "-c", cmd, (char *)NULL) == -1)
+ if (execl("/bin/sh", "sh", "-c", cmd, (char *)NULL) == -1) {
PERROR(_("cs_create_connection exec failed"));
+ }
exit(127);
// NOTREACHED
@@ -827,7 +850,7 @@ err_closing:
si.hStdError = stdout_wr;
si.hStdInput = stdin_rd;
created = CreateProcess(NULL, cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE,
- NULL, NULL, &si, &pi);
+ NULL, NULL, &si, &pi);
xfree(prog);
xfree(cmd);
@@ -888,9 +911,11 @@ 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 (int i = 0; i < eap_arg_len; ++i)
- if (NUL == eap->arg[i])
+ for (int i = 0; i < eap_arg_len; ++i) {
+ if (NUL == eap->arg[i]) {
eap->arg[i] = ' ';
+ }
+ }
return cs_find_common(opt, pat, eap->forceit, true,
eap->cmdidx == CMD_lcscope, *eap->cmdlinep);
@@ -898,8 +923,8 @@ static int cs_find(exarg_T *eap)
/// Common code for cscope find, shared by cs_find() and ex_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)
{
char *cmd;
int *nummatches;
@@ -966,8 +991,9 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
// create the actual command to send to cscope
cmd = cs_create_cmd(opt, pat);
- if (cmd == NULL)
+ if (cmd == NULL) {
return FALSE;
+ }
nummatches = xmalloc(sizeof(int) * csinfo_size);
@@ -978,8 +1004,9 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
}
totmatches = 0;
for (size_t i = 0; i < csinfo_size; i++) {
- if (csinfo[i].fname == NULL || csinfo[i].to_fp == NULL)
+ if (csinfo[i].fname == NULL || csinfo[i].to_fp == NULL) {
continue;
+ }
// send cmd to cscope
(void)fprintf(csinfo[i].to_fp, "%s\n", cmd);
@@ -987,11 +1014,13 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
nummatches[i] = cs_cnt_matches(i);
- if (nummatches[i] > -1)
+ if (nummatches[i] > -1) {
totmatches += (size_t)nummatches[i];
+ }
- if (nummatches[i] == 0)
+ if (nummatches[i] == 0) {
(void)cs_read_prompt(i);
+ }
}
xfree(cmd);
@@ -1014,10 +1043,10 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
if (qfpos != NULL && *qfpos != '0') {
// Fill error list.
- FILE *f;
- char_u *tmp = vim_tempname();
- qf_info_T *qi = NULL;
- win_T *wp = NULL;
+ FILE *f;
+ char_u *tmp = vim_tempname();
+ qf_info_T *qi = NULL;
+ win_T *wp = NULL;
f = os_fopen((char *)tmp, "w");
if (f == NULL) {
@@ -1039,14 +1068,15 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
}
apply_autocmds(EVENT_QUICKFIXCMDPOST, (char_u *)"cscope",
- curbuf->b_fname, TRUE, curbuf);
- if (use_ll)
+ curbuf->b_fname, TRUE, curbuf);
+ if (use_ll) {
/*
* In the location list window, use the displayed location
* list. Otherwise, use the location list for the window.
*/
qi = (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL)
? wp->w_llist_ref : wp->w_llist;
+ }
qf_jump(qi, 0, 0, forceit);
}
}
@@ -1059,11 +1089,11 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
size_t matched = 0;
// read output
- cs_fill_results((char *)pat, totmatches, nummatches, &matches,
- &contexts, &matched);
+ cs_fill_results(pat, totmatches, nummatches, &matches, &contexts, &matched);
xfree(nummatches);
- if (matches == NULL)
+ if (matches == NULL) {
return FALSE;
+ }
(void)cs_manage_matches(matches, contexts, matched, Store);
@@ -1086,10 +1116,10 @@ static int cs_help(exarg_T *eap)
space_cnt = 0;
}
(void)smsg(_("%-5s: %s%*s (Usage: %s)"),
- cmdp->name,
- help, space_cnt, " ",
- cmdp->usage);
- if (strcmp(cmdp->name, "find") == 0)
+ cmdp->name,
+ help, space_cnt, " ",
+ cmdp->usage);
+ if (strcmp(cmdp->name, "find") == 0) {
MSG_PUTS(_("\n"
" a: Find assignments to this symbol\n"
" c: Find functions calling this function\n"
@@ -1100,6 +1130,7 @@ static int cs_help(exarg_T *eap)
" i: Find files #including this file\n"
" s: Find this C symbol\n"
" t: Find this text string\n"));
+ }
cmdp++;
}
@@ -1121,8 +1152,7 @@ static void clear_csinfo(size_t i)
}
/// Insert a new cscope database filename into the filelist.
-static int cs_insert_filelist(char *fname, char *ppath, char *flags,
- FileInfo *file_info)
+static int cs_insert_filelist(char *fname, char *ppath, char *flags, FileInfo *file_info)
{
size_t i = 0;
bool empty_found = false;
@@ -1130,8 +1160,9 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags,
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)
+ if (p_csverbose) {
(void)EMSG(_("E568: duplicate cscope database not added"));
+ }
return CSCOPE_FAILURE;
}
@@ -1154,8 +1185,9 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags,
csinfo_size *= 2;
csinfo = xrealloc(csinfo, sizeof(csinfo_T)*csinfo_size);
}
- for (size_t j = csinfo_size/2; j < csinfo_size; j++)
+ for (size_t j = csinfo_size/2; j < csinfo_size; j++) {
clear_csinfo(j);
+ }
}
csinfo[i].fname = xmalloc(strlen(fname) + 1);
@@ -1165,14 +1197,16 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags,
if (ppath != NULL) {
csinfo[i].ppath = xmalloc(strlen(ppath) + 1);
(void)strcpy(csinfo[i].ppath, (const char *)ppath);
- } else
+ } else {
csinfo[i].ppath = NULL;
+ }
if (flags != NULL) {
csinfo[i].flags = xmalloc(strlen(flags) + 1);
(void)strcpy(csinfo[i].flags, (const char *)flags);
- } else
+ } else {
csinfo[i].flags = NULL;
+ }
os_fileinfo_id(file_info, &(csinfo[i].file_id));
assert(i <= INT_MAX);
@@ -1181,25 +1215,28 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags,
/// Find cscope command in command table.
-static cscmd_T * cs_lookup_cmd(exarg_T *eap)
+static cscmd_T *cs_lookup_cmd(exarg_T *eap)
{
cscmd_T *cmdp;
char *stok;
size_t len;
- if (eap->arg == NULL)
+ if (eap->arg == NULL) {
return NULL;
+ }
// Store length of eap->arg before it gets modified by strtok().
eap_arg_len = (int)STRLEN(eap->arg);
- if ((stok = strtok((char *)(eap->arg), (const char *)" ")) == NULL)
+ if ((stok = strtok((char *)(eap->arg), (const char *)" ")) == NULL) {
return NULL;
+ }
len = strlen(stok);
for (cmdp = cs_cmds; cmdp->name != NULL; ++cmdp) {
- if (strncmp((const char *)(stok), cmdp->name, len) == 0)
+ if (strncmp((const char *)(stok), cmdp->name, len) == 0) {
return cmdp;
+ }
}
return NULL;
}
@@ -1224,21 +1261,23 @@ static int cs_kill(exarg_T *eap)
|| (strlen(stok) < 3 && stok[0] == '-'
&& ascii_isdigit((int)(stok[1])))) {
num = atoi(stok);
- if (num == -1)
+ if (num == -1) {
killall = true;
- else if (num >= 0) {
+ } else if (num >= 0) {
i = (size_t)num;
} else { // All negative values besides -1 are invalid.
- if (p_csverbose)
+ 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))
+ if (csinfo[i].fname != NULL && strstr(csinfo[i].fname, stok)) {
break;
+ }
}
}
@@ -1250,11 +1289,12 @@ static int cs_kill(exarg_T *eap)
} else {
if (killall) {
for (i = 0; i < csinfo_size; i++) {
- if (csinfo[i].fname)
+ if (csinfo[i].fname) {
cs_kill_execute(i, csinfo[i].fname);
+ }
}
} else {
- cs_kill_execute((size_t)i, stok);
+ cs_kill_execute(i, stok);
}
}
@@ -1263,10 +1303,10 @@ static int cs_kill(exarg_T *eap)
/// Actually kills a specific cscope connection.
-static void cs_kill_execute(
- size_t i, // cscope table index
- char *cname // cscope database name
-)
+///
+/// @param i cscope table index
+/// @param cname cscope database name
+static void cs_kill_execute(size_t i, char *cname)
{
if (p_csverbose) {
msg_clr_eos();
@@ -1293,8 +1333,7 @@ static void cs_kill_execute(
/// Besides, even if this particular case didn't happen, the search pattern
/// 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:
//
@@ -1339,8 +1378,7 @@ static char *cs_make_vim_style_matches(char *fname, char *slno, char *search,
/// Free: frees up everything and resets
///
/// Print: prints the tags
-static char *cs_manage_matches(char **matches, char **contexts,
- size_t 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;
@@ -1352,16 +1390,18 @@ static char *cs_manage_matches(char **matches, char **contexts,
case Store:
assert(matches != NULL);
assert(totmatches > 0);
- if (mp != NULL || cp != NULL)
+ if (mp != NULL || cp != NULL) {
(void)cs_manage_matches(NULL, NULL, 0, Free);
+ }
mp = matches;
cp = contexts;
cnt = totmatches;
next = 0;
break;
case Get:
- if (next >= cnt)
+ if (next >= cnt) {
return NULL;
+ }
p = mp[next];
next++;
@@ -1370,8 +1410,9 @@ static char *cs_manage_matches(char **matches, char **contexts,
if (mp != NULL) {
while (cnt--) {
xfree(mp[cnt]);
- if (cp != NULL)
+ if (cp != NULL) {
xfree(cp[cnt]);
+ }
}
xfree(mp);
xfree(cp);
@@ -1396,8 +1437,8 @@ static char *cs_manage_matches(char **matches, char **contexts,
/// Parse cscope output.
-static char *cs_parse_results(size_t 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;
@@ -1421,8 +1462,9 @@ retry:
// If the line's too long for the buffer, discard it.
if ((p = strchr(buf, '\n')) == NULL) {
- while ((ch = getc(csinfo[cnumber].fr_fp)) != EOF && ch != '\n')
+ while ((ch = getc(csinfo[cnumber].fr_fp)) != EOF && ch != '\n') {
;
+ }
return NULL;
}
*p = '\0';
@@ -1430,14 +1472,18 @@ retry:
/*
* cscope output is in the following format:
*
- * <filename> <context> <line number> <pattern>
+ * <filename> <context> <line number> <pattern>
*/
- if ((name = strtok((char *)buf, (const char *)" ")) == NULL)
+ char *saveptr = NULL;
+ if ((name = os_strtok(buf, (const char *)" ", &saveptr)) == NULL) {
return NULL;
- if ((*context = strtok(NULL, (const char *)" ")) == NULL)
+ }
+ if ((*context = os_strtok(NULL, (const char *)" ", &saveptr)) == NULL) {
return NULL;
- if ((*linenumber = strtok(NULL, (const char *)" ")) == NULL)
+ }
+ if ((*linenumber = os_strtok(NULL, (const char *)" ", &saveptr)) == NULL) {
return NULL;
+ }
*search = *linenumber + strlen(*linenumber) + 1; // +1 to skip \0
// --- nvi ---
@@ -1463,25 +1509,29 @@ static void cs_file_results(FILE *f, int *nummatches_a)
char *buf = xmalloc(CSREAD_BUFSIZE);
for (size_t i = 0; i < csinfo_size; i++) {
- if (nummatches_a[i] < 1)
+ if (nummatches_a[i] < 1) {
continue;
+ }
for (int j = 0; j < nummatches_a[i]; j++) {
if ((fullname = cs_parse_results(i, buf, CSREAD_BUFSIZE, &cntx,
- &slno, &search)) == NULL)
+ &slno, &search)) == NULL) {
continue;
+ }
context = xmalloc(strlen(cntx) + 5);
- if (strcmp(cntx, "<global>")==0)
+ if (strcmp(cntx, "<global>")==0) {
strcpy(context, "<<global>>");
- else
+ } else {
sprintf(context, "<<%s>>", cntx);
+ }
- if (search == NULL)
+ if (search == NULL) {
fprintf(f, "%s\t%s\t%s\n", fullname, slno, context);
- else
+ } else {
fprintf(f, "%s\t%s\t%s %s\n", fullname, slno, context, search);
+ }
xfree(context);
xfree(fullname);
@@ -1495,9 +1545,8 @@ static void cs_file_results(FILE *f, int *nummatches_a)
/// Get parsed cscope output and calls cs_make_vim_style_matches to convert
/// into ctags format.
/// When there are no matches sets "*matches_p" to NULL.
-static void cs_fill_results(char *tagstr, size_t totmatches, int *nummatches_a,
- char ***matches_p, char ***cntxts_p,
- size_t *matched)
+static void cs_fill_results(char *tagstr, size_t totmatches, int *nummatches_a, char ***matches_p,
+ char ***cntxts_p, size_t *matched)
{
char *buf;
char *search, *slno;
@@ -1510,26 +1559,28 @@ static void cs_fill_results(char *tagstr, size_t totmatches, int *nummatches_a,
assert(totmatches > 0);
buf = xmalloc(CSREAD_BUFSIZE);
- matches = xmalloc(sizeof(char *) * (size_t)totmatches);
- cntxts = xmalloc(sizeof(char *) * (size_t)totmatches);
+ matches = xmalloc(sizeof(char *) * totmatches);
+ cntxts = xmalloc(sizeof(char *) * totmatches);
for (size_t i = 0; i < csinfo_size; i++) {
- if (nummatches_a[i] < 1)
+ if (nummatches_a[i] < 1) {
continue;
+ }
for (int j = 0; j < nummatches_a[i]; j++) {
if ((fullname = cs_parse_results(i, buf, CSREAD_BUFSIZE, &cntx,
- &slno, &search)) == NULL)
+ &slno, &search)) == NULL) {
continue;
+ }
matches[totsofar] = cs_make_vim_style_matches(fullname, slno, search,
tagstr);
xfree(fullname);
- if (strcmp(cntx, "<global>") == 0)
+ if (strcmp(cntx, "<global>") == 0) {
cntxts[totsofar] = NULL;
- else {
+ } else {
cntxts[totsofar] = xstrdup(cntx);
}
@@ -1691,9 +1742,9 @@ static void cs_print_tags_priv(char **matches, char **cntxts,
static int cs_read_prompt(size_t i)
{
int ch;
- char *buf = NULL; // buffer for possible error message from cscope
+ char *buf = NULL; // buffer for possible error message from cscope
size_t bufpos = 0;
- char *cs_emsg = _("E609: Cscope error: %s");
+ char *cs_emsg = _("E609: Cscope error: %s");
size_t cs_emsg_len = strlen(cs_emsg);
static char *eprompt = "Press the RETURN key to continue:";
size_t epromptlen = strlen(eprompt);
@@ -1886,10 +1937,12 @@ static void cs_release_csp(size_t i, bool freefnpp)
}
#endif
- if (csinfo[i].fr_fp != NULL)
+ if (csinfo[i].fr_fp != NULL) {
(void)fclose(csinfo[i].fr_fp);
- if (csinfo[i].to_fp != NULL)
+ }
+ if (csinfo[i].to_fp != NULL) {
(void)fclose(csinfo[i].to_fp);
+ }
if (freefnpp) {
xfree(csinfo[i].fname);
@@ -1904,11 +1957,12 @@ static void cs_release_csp(size_t i, bool freefnpp)
/// Calls cs_kill on all cscope connections then reinits.
static int cs_reset(exarg_T *eap)
{
- char **dblist = NULL, **pplist = NULL, **fllist = NULL;
+ char **dblist = NULL, **pplist = NULL, **fllist = NULL;
char buf[25]; // for snprintf " (#%zu)"
- if (csinfo_size == 0)
+ if (csinfo_size == 0) {
return CSCOPE_SUCCESS;
+ }
// malloc our db and ppath list
dblist = xmalloc(csinfo_size * sizeof(char *));
@@ -1919,8 +1973,9 @@ static int cs_reset(exarg_T *eap)
dblist[i] = csinfo[i].fname;
pplist[i] = csinfo[i].ppath;
fllist[i] = csinfo[i].flags;
- if (csinfo[i].fname != NULL)
+ if (csinfo[i].fname != NULL) {
cs_release_csp(i, FALSE);
+ }
}
// rebuild the cscope connection list
@@ -1959,8 +2014,8 @@ static int cs_reset(exarg_T *eap)
/// Contrast this with my development system (Digital Unix), which does.
static char *cs_resolve_file(size_t i, char *name)
{
- char *fullname;
- char_u *csdir = NULL;
+ char *fullname;
+ char_u *csdir = NULL;
/*
* Ppath is freed when we destroy the cscope connection.
@@ -1975,8 +2030,8 @@ static char *cs_resolve_file(size_t i, char *name)
// path in path resolution.
csdir = xmalloc(MAXPATHL);
STRLCPY(csdir, csinfo[i].fname,
- path_tail((char_u *)csinfo[i].fname)
- - (char_u *)csinfo[i].fname + 1);
+ path_tail((char_u *)csinfo[i].fname)
+ - (char_u *)csinfo[i].fname + 1);
len += STRLEN(csdir);
}
@@ -1985,8 +2040,7 @@ static char *cs_resolve_file(size_t i, char *name)
// happens, you are screwed up and need to fix how you're using cscope.
if (csinfo[i].ppath != NULL
&& (strncmp(name, csinfo[i].ppath, strlen(csinfo[i].ppath)) != 0)
- && (name[0] != '/')
- ) {
+ && (name[0] != '/')) {
fullname = xmalloc(len);
(void)sprintf(fullname, "%s/%s", csinfo[i].ppath, name);
} else if (csdir != NULL && csinfo[i].fname != NULL && *csdir != NUL) {
@@ -2005,15 +2059,15 @@ static char *cs_resolve_file(size_t i, char *name)
/// Show all cscope connections.
static int cs_show(exarg_T *eap)
{
- if (cs_cnt_connections() == 0)
+ 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));
+ } else {
+ MSG_PUTS_ATTR(_(" # pid database name prepend path\n"),
+ HL_ATTR(HLF_T));
for (size_t i = 0; i < csinfo_size; i++) {
- if (csinfo[i].fname == NULL)
+ if (csinfo[i].fname == NULL) {
continue;
+ }
if (csinfo[i].ppath != NULL) {
(void)smsg("%2zu %-5" PRId64 " %-34s %-32s", i,
@@ -2033,8 +2087,9 @@ static int cs_show(exarg_T *eap)
/// Only called when VIM exits to quit any cscope sessions.
void cs_end(void)
{
- for (size_t i = 0; i < csinfo_size; i++)
+ for (size_t i = 0; i < csinfo_size; i++) {
cs_release_csp(i, true);
+ }
xfree(csinfo);
csinfo_size = 0;
}
diff --git a/src/nvim/if_cscope.h b/src/nvim/if_cscope.h
index e20462576a..8dbc78943f 100644
--- a/src/nvim/if_cscope.h
+++ b/src/nvim/if_cscope.h
@@ -1,8 +1,8 @@
#ifndef NVIM_IF_CSCOPE_H
#define NVIM_IF_CSCOPE_H
-#include "nvim/types.h" // for char_u and expand_T
-#include "nvim/ex_cmds_defs.h" // for exarg_T
+#include "nvim/ex_cmds_defs.h" // for exarg_T
+#include "nvim/types.h" // for char_u and expand_T
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "if_cscope.h.generated.h"
diff --git a/src/nvim/if_cscope_defs.h b/src/nvim/if_cscope_defs.h
index d2d8b0fb62..182cbc28e1 100644
--- a/src/nvim/if_cscope_defs.h
+++ b/src/nvim/if_cscope_defs.h
@@ -13,9 +13,9 @@
# include <sys/types.h> // pid_t
#endif
-#include "nvim/os/os_defs.h"
-#include "nvim/os/fs_defs.h"
#include "nvim/ex_cmds_defs.h"
+#include "nvim/os/fs_defs.h"
+#include "nvim/os/os_defs.h"
#define CSCOPE_SUCCESS 0
#define CSCOPE_FAILURE -1
@@ -26,30 +26,30 @@
// See ":help cscope-find" for the possible queries.
typedef struct {
- char * name;
+ char *name;
int (*func)(exarg_T *eap);
- char * help;
- char * usage;
+ char *help;
+ char *usage;
int cansplit; // if supports splitting window
} cscmd_T;
typedef struct csi {
- char * fname; // cscope db name
- char * ppath; // path to prepend (the -P option)
- char * flags; // additional cscope flags/options (e.g, -p2)
+ char *fname; // cscope db name
+ char *ppath; // path to prepend (the -P option)
+ char *flags; // additional cscope flags/options (e.g, -p2)
#if defined(UNIX)
pid_t pid; // PID of the connected cscope process
#else
- DWORD pid; // PID of the connected cscope process
- HANDLE hProc; // cscope process handle
- DWORD nVolume; // Volume serial number, instead of st_dev
- DWORD nIndexHigh; // st_ino has no meaning on Windows
- DWORD nIndexLow;
+ DWORD pid; // PID of the connected cscope process
+ HANDLE hProc; // cscope process handle
+ DWORD nVolume; // Volume serial number, instead of st_dev
+ DWORD nIndexHigh; // st_ino has no meaning on Windows
+ DWORD nIndexLow;
#endif
FileID file_id;
- FILE * fr_fp; // from cscope: FILE.
- FILE * to_fp; // to cscope: FILE.
+ FILE *fr_fp; // from cscope: FILE.
+ FILE *to_fp; // to cscope: FILE.
} csinfo_T;
typedef enum { Add, Find, Help, Kill, Reset, Show } csid_e;
diff --git a/src/nvim/indent.c b/src/nvim/indent.c
index 609598b678..f49aff6643 100644
--- a/src/nvim/indent.c
+++ b/src/nvim/indent.c
@@ -7,13 +7,14 @@
#include "nvim/ascii.h"
#include "nvim/assert.h"
+#include "nvim/buffer.h"
#include "nvim/change.h"
-#include "nvim/indent.h"
-#include "nvim/eval.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
-#include "nvim/mark.h"
+#include "nvim/eval.h"
#include "nvim/extmark.h"
+#include "nvim/indent.h"
+#include "nvim/mark.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/misc1.h"
@@ -25,7 +26,6 @@
#include "nvim/search.h"
#include "nvim/strings.h"
#include "nvim/undo.h"
-#include "nvim/buffer.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -444,8 +444,8 @@ int get_breakindent_win(win_T *wp, char_u *line)
int bri = 0;
// window width minus window margin space, i.e. what rests for text
const int eff_wwidth = wp->w_width_inner
- - ((wp->w_p_nu || wp->w_p_rnu)
- && (vim_strchr(p_cpo, CPO_NUMCOL) == NULL)
+ - ((wp->w_p_nu || wp->w_p_rnu)
+ && (vim_strchr(p_cpo, CPO_NUMCOL) == NULL)
? number_width(wp) + 1 : 0);
// used cached indent, unless pointer or 'tabstop' changed
@@ -510,7 +510,7 @@ int get_breakindent_win(win_T *wp, char_u *line)
// the line.
int inindent(int extra)
{
- char_u *ptr;
+ char_u *ptr;
colnr_T col;
for (col = 0, ptr = get_cursor_line_ptr(); ascii_iswhite(*ptr); ++col) {
@@ -533,15 +533,14 @@ int get_expr_indent(void)
colnr_T save_curswant;
int save_set_curswant;
int save_State;
- int use_sandbox = was_set_insecurely(
- curwin, (char_u *)"indentexpr", OPT_LOCAL);
+ int use_sandbox = was_set_insecurely(curwin, "indentexpr", OPT_LOCAL);
// Save and restore cursor position and curswant, in case it was changed
// * via :normal commands.
save_pos = curwin->w_cursor;
save_curswant = curwin->w_curswant;
save_set_curswant = curwin->w_set_curswant;
- set_vim_var_nr(VV_LNUM, (varnumber_T) curwin->w_cursor.lnum);
+ set_vim_var_nr(VV_LNUM, (varnumber_T)curwin->w_cursor.lnum);
if (use_sandbox) {
sandbox++;
@@ -722,11 +721,11 @@ int get_lisp_indent(void)
quotecount = 0;
if (vi_lisp || ((*that != '"') && (*that != '\'')
- && (*that != '#') && ((*that < '0') || (*that > '9')))) {
+ && (*that != '#') && ((*that < '0') || (*that > '9')))) {
while (*that
&& (!ascii_iswhite(*that) || quotecount || parencount)
&& (!((*that == '(' || *that == '[')
- && !quotecount && !parencount && vi_lisp))) {
+ && !quotecount && !parencount && vi_lisp))) {
if (*that == '"') {
quotecount = !quotecount;
}
diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c
index 25c27743f3..3e3e07e9d6 100644
--- a/src/nvim/indent_c.c
+++ b/src/nvim/indent_c.c
@@ -1,6 +1,8 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+// uncrustify:off
+
#include <assert.h>
#include <inttypes.h>
diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c
index c6966ff9fa..b724d82f7c 100644
--- a/src/nvim/keymap.c
+++ b/src/nvim/keymap.c
@@ -5,16 +5,16 @@
#include <inttypes.h>
#include <limits.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/keymap.h"
#include "nvim/charset.h"
-#include "nvim/memory.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
+#include "nvim/keymap.h"
+#include "nvim/memory.h"
#include "nvim/message.h"
-#include "nvim/strings.h"
#include "nvim/mouse.h"
+#include "nvim/strings.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "keymap.c.generated.h"
@@ -51,48 +51,48 @@ static const struct modmasktable {
static char_u modifier_keys_table[] =
{
- /* mod mask with modifier without modifier */
- MOD_MASK_SHIFT, '&', '9', '@', '1', /* begin */
- MOD_MASK_SHIFT, '&', '0', '@', '2', /* cancel */
- MOD_MASK_SHIFT, '*', '1', '@', '4', /* command */
- MOD_MASK_SHIFT, '*', '2', '@', '5', /* copy */
- MOD_MASK_SHIFT, '*', '3', '@', '6', /* create */
- MOD_MASK_SHIFT, '*', '4', 'k', 'D', /* delete char */
- MOD_MASK_SHIFT, '*', '5', 'k', 'L', /* delete line */
- MOD_MASK_SHIFT, '*', '7', '@', '7', /* end */
- MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_END, '@', '7', /* end */
- MOD_MASK_SHIFT, '*', '9', '@', '9', /* exit */
- MOD_MASK_SHIFT, '*', '0', '@', '0', /* find */
- MOD_MASK_SHIFT, '#', '1', '%', '1', /* help */
- MOD_MASK_SHIFT, '#', '2', 'k', 'h', /* home */
- MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_HOME, 'k', 'h', /* home */
- MOD_MASK_SHIFT, '#', '3', 'k', 'I', /* insert */
- MOD_MASK_SHIFT, '#', '4', 'k', 'l', /* left arrow */
- MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_LEFT, 'k', 'l', /* left arrow */
- MOD_MASK_SHIFT, '%', 'a', '%', '3', /* message */
- MOD_MASK_SHIFT, '%', 'b', '%', '4', /* move */
- MOD_MASK_SHIFT, '%', 'c', '%', '5', /* next */
- MOD_MASK_SHIFT, '%', 'd', '%', '7', /* options */
- MOD_MASK_SHIFT, '%', 'e', '%', '8', /* previous */
- MOD_MASK_SHIFT, '%', 'f', '%', '9', /* print */
- MOD_MASK_SHIFT, '%', 'g', '%', '0', /* redo */
- MOD_MASK_SHIFT, '%', 'h', '&', '3', /* replace */
- MOD_MASK_SHIFT, '%', 'i', 'k', 'r', /* right arr. */
- MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_RIGHT, 'k', 'r', /* right arr. */
- MOD_MASK_SHIFT, '%', 'j', '&', '5', /* resume */
- MOD_MASK_SHIFT, '!', '1', '&', '6', /* save */
- MOD_MASK_SHIFT, '!', '2', '&', '7', /* suspend */
- MOD_MASK_SHIFT, '!', '3', '&', '8', /* undo */
- MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_UP, 'k', 'u', /* up arrow */
- MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_DOWN, 'k', 'd', /* down arrow */
-
- /* vt100 F1 */
+ // mod mask with modifier without modifier
+ MOD_MASK_SHIFT, '&', '9', '@', '1', // begin
+ MOD_MASK_SHIFT, '&', '0', '@', '2', // cancel
+ MOD_MASK_SHIFT, '*', '1', '@', '4', // command
+ MOD_MASK_SHIFT, '*', '2', '@', '5', // copy
+ MOD_MASK_SHIFT, '*', '3', '@', '6', // create
+ MOD_MASK_SHIFT, '*', '4', 'k', 'D', // delete char
+ MOD_MASK_SHIFT, '*', '5', 'k', 'L', // delete line
+ MOD_MASK_SHIFT, '*', '7', '@', '7', // end
+ MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_END, '@', '7', // end
+ MOD_MASK_SHIFT, '*', '9', '@', '9', // exit
+ MOD_MASK_SHIFT, '*', '0', '@', '0', // find
+ MOD_MASK_SHIFT, '#', '1', '%', '1', // help
+ MOD_MASK_SHIFT, '#', '2', 'k', 'h', // home
+ MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_HOME, 'k', 'h', // home
+ MOD_MASK_SHIFT, '#', '3', 'k', 'I', // insert
+ MOD_MASK_SHIFT, '#', '4', 'k', 'l', // left arrow
+ MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_LEFT, 'k', 'l', // left arrow
+ MOD_MASK_SHIFT, '%', 'a', '%', '3', // message
+ MOD_MASK_SHIFT, '%', 'b', '%', '4', // move
+ MOD_MASK_SHIFT, '%', 'c', '%', '5', // next
+ MOD_MASK_SHIFT, '%', 'd', '%', '7', // options
+ MOD_MASK_SHIFT, '%', 'e', '%', '8', // previous
+ MOD_MASK_SHIFT, '%', 'f', '%', '9', // print
+ MOD_MASK_SHIFT, '%', 'g', '%', '0', // redo
+ MOD_MASK_SHIFT, '%', 'h', '&', '3', // replace
+ MOD_MASK_SHIFT, '%', 'i', 'k', 'r', // right arr.
+ MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_RIGHT, 'k', 'r', // right arr.
+ MOD_MASK_SHIFT, '%', 'j', '&', '5', // resume
+ MOD_MASK_SHIFT, '!', '1', '&', '6', // save
+ MOD_MASK_SHIFT, '!', '2', '&', '7', // suspend
+ MOD_MASK_SHIFT, '!', '3', '&', '8', // undo
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_UP, 'k', 'u', // up arrow
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_DOWN, 'k', 'd', // down arrow
+
+ // vt100 F1
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF1, KS_EXTRA, (int)KE_XF1,
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF2, KS_EXTRA, (int)KE_XF2,
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF3, KS_EXTRA, (int)KE_XF3,
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF4, KS_EXTRA, (int)KE_XF4,
- MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F1, 'k', '1', /* F1 */
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F1, 'k', '1', // F1
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F2, 'k', '2',
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F3, 'k', '3',
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F4, 'k', '4',
@@ -101,7 +101,7 @@ static char_u modifier_keys_table[] =
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F7, 'k', '7',
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F8, 'k', '8',
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F9, 'k', '9',
- MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F10, 'k', ';', /* F10 */
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F10, 'k', ';', // F10
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F11, 'F', '1',
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F12, 'F', '2',
@@ -133,7 +133,7 @@ static char_u modifier_keys_table[] =
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F36, 'F', 'Q',
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F37, 'F', 'R',
- /* TAB pseudo code*/
+ // TAB pseudo code
MOD_MASK_SHIFT, 'k', 'B', KS_EXTRA, (int)KE_TAB,
NUL
@@ -397,22 +397,38 @@ int handle_x_keys(const int key)
FUNC_ATTR_CONST FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (key) {
- case K_XUP: return K_UP;
- case K_XDOWN: return K_DOWN;
- case K_XLEFT: return K_LEFT;
- case K_XRIGHT: return K_RIGHT;
- case K_XHOME: return K_HOME;
- case K_ZHOME: return K_HOME;
- case K_XEND: return K_END;
- case K_ZEND: return K_END;
- case K_XF1: return K_F1;
- case K_XF2: return K_F2;
- case K_XF3: return K_F3;
- case K_XF4: return K_F4;
- case K_S_XF1: return K_S_F1;
- case K_S_XF2: return K_S_F2;
- case K_S_XF3: return K_S_F3;
- case K_S_XF4: return K_S_F4;
+ case K_XUP:
+ return K_UP;
+ case K_XDOWN:
+ return K_DOWN;
+ case K_XLEFT:
+ return K_LEFT;
+ case K_XRIGHT:
+ return K_RIGHT;
+ case K_XHOME:
+ return K_HOME;
+ case K_ZHOME:
+ return K_HOME;
+ case K_XEND:
+ return K_END;
+ case K_ZEND:
+ return K_END;
+ case K_XF1:
+ return K_F1;
+ case K_XF2:
+ return K_F2;
+ case K_XF3:
+ return K_F3;
+ case K_XF4:
+ return K_F4;
+ case K_S_XF1:
+ return K_S_F1;
+ case K_S_XF2:
+ return K_S_F2;
+ case K_S_XF3:
+ return K_S_F3;
+ case K_S_XF4:
+ return K_S_F4;
}
return key;
}
@@ -427,31 +443,33 @@ char_u *get_special_key_name(int c, int modifiers)
int i, idx;
int table_idx;
- char_u *s;
+ char_u *s;
string[0] = '<';
idx = 1;
- /* Key that stands for a normal character. */
- if (IS_SPECIAL(c) && KEY2TERMCAP0(c) == KS_KEY)
+ // Key that stands for a normal character.
+ if (IS_SPECIAL(c) && KEY2TERMCAP0(c) == KS_KEY) {
c = KEY2TERMCAP1(c);
+ }
/*
* Translate shifted special keys into unshifted keys and set modifier.
* Same for CTRL and ALT modifiers.
*/
if (IS_SPECIAL(c)) {
- for (i = 0; modifier_keys_table[i] != 0; i += MOD_KEYS_ENTRY_SIZE)
- if ( KEY2TERMCAP0(c) == (int)modifier_keys_table[i + 1]
- && (int)KEY2TERMCAP1(c) == (int)modifier_keys_table[i + 2]) {
+ for (i = 0; modifier_keys_table[i] != 0; i += MOD_KEYS_ENTRY_SIZE) {
+ if (KEY2TERMCAP0(c) == (int)modifier_keys_table[i + 1]
+ && (int)KEY2TERMCAP1(c) == (int)modifier_keys_table[i + 2]) {
modifiers |= modifier_keys_table[i];
c = TERMCAP2KEY(modifier_keys_table[i + 3],
- modifier_keys_table[i + 4]);
+ modifier_keys_table[i + 4]);
break;
}
+ }
}
- /* try to find the key in the special key table */
+ // try to find the key in the special key table
table_idx = find_special_key_in_table(c);
/*
@@ -459,14 +477,13 @@ char_u *get_special_key_name(int c, int modifiers)
* extract modifiers.
*/
if (c > 0
- && (*mb_char2len)(c) == 1
- ) {
+ && (*mb_char2len)(c) == 1) {
if (table_idx < 0
&& (!vim_isprintc(c) || (c & 0x7f) == ' ')
&& (c & 0x80)) {
c &= 0x7f;
modifiers |= MOD_MASK_ALT;
- /* try again, to find the un-alted key in the special key table */
+ // try again, to find the un-alted key in the special key table
table_idx = find_special_key_in_table(c);
}
if (table_idx < 0 && !vim_isprintc(c) && c < ' ') {
@@ -475,15 +492,16 @@ char_u *get_special_key_name(int c, int modifiers)
}
}
- /* translate the modifier into a string */
- for (i = 0; mod_mask_table[i].name != 'A'; i++)
+ // translate the modifier into a string
+ for (i = 0; mod_mask_table[i].name != 'A'; i++) {
if ((modifiers & mod_mask_table[i].mod_mask)
== mod_mask_table[i].mod_flag) {
string[idx++] = mod_mask_table[i].name;
string[idx++] = (char_u)'-';
}
+ }
- if (table_idx < 0) { /* unknown special key, may output t_xx */
+ if (table_idx < 0) { // unknown special key, may output t_xx
if (IS_SPECIAL(c)) {
string[idx++] = 't';
string[idx++] = '_';
@@ -497,16 +515,17 @@ char_u *get_special_key_name(int c, int modifiers)
string[idx++] = (char_u)c;
} else {
s = transchar(c);
- while (*s)
+ while (*s) {
string[idx++] = *s++;
+ }
}
}
} else { // use name of special key
size_t len = STRLEN(key_names_table[table_idx].name);
if ((int)len + idx + 2 <= MAX_KEY_NAME_LEN) {
- STRCPY(string + idx, key_names_table[table_idx].name);
- idx += (int)len;
+ STRCPY(string + idx, key_names_table[table_idx].name);
+ idx += (int)len;
}
}
string[idx++] = '>';
@@ -525,9 +544,8 @@ char_u *get_special_key_name(int c, int modifiers)
/// @param[in] in_string Inside a double quoted string
///
/// @return Number of characters added to dst, zero for no match.
-unsigned int trans_special(const char_u **srcp, const size_t src_len,
- char_u *const dst, const bool keycode,
- const bool in_string)
+unsigned int trans_special(const char_u **srcp, const size_t src_len, char_u *const dst,
+ const bool keycode, const bool in_string)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
int modifiers = 0;
@@ -582,9 +600,8 @@ unsigned int special_to_buf(int key, int modifiers, bool keycode, char_u *dst)
/// @param[in] in_string In string, double quote is escaped
///
/// @return Key and modifiers or 0 if there is no match.
-int find_special_key(const char_u **srcp, const size_t src_len, int *const modp,
- const bool keycode, const bool keep_x_key,
- const bool in_string)
+int find_special_key(const char_u **srcp, const size_t src_len, int *const modp, const bool keycode,
+ const bool keep_x_key, const bool in_string)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
const char_u *last_dash;
@@ -641,7 +658,7 @@ int find_special_key(const char_u **srcp, const size_t src_len, int *const modp,
if (bp <= end && *bp == '>') { // found matching '>'
end_of_name = bp + 1;
- /* Which modifiers are given? */
+ // Which modifiers are given?
modifiers = 0x0;
for (bp = src + 1; bp < last_dash; bp++) {
if (*bp != '-') {
@@ -795,13 +812,14 @@ int get_mouse_button(int code, bool *is_click, bool *is_drag)
{
int i;
- for (i = 0; mouse_table[i].pseudo_code; i++)
+ for (i = 0; mouse_table[i].pseudo_code; i++) {
if (code == mouse_table[i].pseudo_code) {
*is_click = mouse_table[i].is_click;
*is_drag = mouse_table[i].is_drag;
return mouse_table[i].button;
}
- return 0; /* Shouldn't get here */
+ }
+ return 0; // Shouldn't get here
}
/// Replace any terminal code strings with the equivalent internal
@@ -829,9 +847,8 @@ int get_mouse_button(int code, bool *is_click, bool *is_drag)
/// @return Pointer to an allocated memory in case of success, "from" in case of
/// failure. In case of success returned pointer is also saved to
/// "bufp".
-char_u *replace_termcodes(const char_u *from, const size_t from_len,
- char_u **bufp, const bool from_part, const bool do_lt,
- const bool special, int cpo_flags)
+char_u *replace_termcodes(const char_u *from, const size_t from_len, char_u **bufp,
+ const bool from_part, const bool do_lt, const bool special, int cpo_flags)
FUNC_ATTR_NONNULL_ALL
{
ssize_t i;
@@ -841,7 +858,7 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len,
const char_u *src;
const char_u *const end = from + from_len - 1;
int do_backslash; // backslash is a special character
- char_u *result; // buffer for resulting string
+ char_u *result; // buffer for resulting string
do_backslash = !(cpo_flags&FLAG_CPO_BSLASH);
@@ -897,7 +914,7 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len,
}
if (special) {
- char_u *p, *s, len;
+ char_u *p, *s, len;
// Replace <Leader> by the value of "mapleader".
// Replace <LocalLeader> by the value of "maplocalleader".
diff --git a/src/nvim/keymap.h b/src/nvim/keymap.h
index 9fc44f6f84..663a7a12ec 100644
--- a/src/nvim/keymap.h
+++ b/src/nvim/keymap.h
@@ -41,31 +41,31 @@
/*
* NUL cannot be in the input string, therefore it is replaced by
- * K_SPECIAL KS_ZERO KE_FILLER
+ * K_SPECIAL KS_ZERO KE_FILLER
*/
#define KS_ZERO 255
/*
* K_SPECIAL cannot be in the input string, therefore it is replaced by
- * K_SPECIAL KS_SPECIAL KE_FILLER
+ * K_SPECIAL KS_SPECIAL KE_FILLER
*/
#define KS_SPECIAL 254
/*
* KS_EXTRA is used for keys that have no termcap name
- * K_SPECIAL KS_EXTRA KE_xxx
+ * K_SPECIAL KS_EXTRA KE_xxx
*/
#define KS_EXTRA 253
/*
* KS_MODIFIER is used when a modifier is given for a (special) key
- * K_SPECIAL KS_MODIFIER bitmask
+ * K_SPECIAL KS_MODIFIER bitmask
*/
#define KS_MODIFIER 252
/*
* These are used for the GUI
- * K_SPECIAL KS_xxx KE_FILLER
+ * K_SPECIAL KS_xxx KE_FILLER
*/
#define KS_MOUSE 251
#define KS_MENU 250
@@ -122,130 +122,130 @@
//
// Entries must be in the range 0x02-0x7f (see comment at K_SPECIAL).
enum key_extra {
- KE_NAME = 3 // name of this terminal entry
-
- , KE_S_UP = 4 // shift-up
- , KE_S_DOWN = 5 // shift-down
-
- , KE_S_F1 = 6 // shifted function keys
- , KE_S_F2 = 7
- , KE_S_F3 = 8
- , KE_S_F4 = 9
- , KE_S_F5 = 10
- , KE_S_F6 = 11
- , KE_S_F7 = 12
- , KE_S_F8 = 13
- , KE_S_F9 = 14
- , KE_S_F10 = 15
-
- , KE_S_F11 = 16
- , KE_S_F12 = 17
- , KE_S_F13 = 18
- , KE_S_F14 = 19
- , KE_S_F15 = 20
- , KE_S_F16 = 21
- , KE_S_F17 = 22
- , KE_S_F18 = 23
- , KE_S_F19 = 24
- , KE_S_F20 = 25
-
- , KE_S_F21 = 26
- , KE_S_F22 = 27
- , KE_S_F23 = 28
- , KE_S_F24 = 29
- , KE_S_F25 = 30
- , KE_S_F26 = 31
- , KE_S_F27 = 32
- , KE_S_F28 = 33
- , KE_S_F29 = 34
- , KE_S_F30 = 35
-
- , KE_S_F31 = 36
- , KE_S_F32 = 37
- , KE_S_F33 = 38
- , KE_S_F34 = 39
- , KE_S_F35 = 40
- , KE_S_F36 = 41
- , KE_S_F37 = 42
-
- , KE_MOUSE = 43 // mouse event start
+ KE_NAME = 3, // name of this terminal entry
+
+ KE_S_UP = 4, // shift-up
+ KE_S_DOWN = 5, // shift-down
+
+ KE_S_F1 = 6, // shifted function keys
+ KE_S_F2 = 7,
+ KE_S_F3 = 8,
+ KE_S_F4 = 9,
+ KE_S_F5 = 10,
+ KE_S_F6 = 11,
+ KE_S_F7 = 12,
+ KE_S_F8 = 13,
+ KE_S_F9 = 14,
+ KE_S_F10 = 15,
+
+ KE_S_F11 = 16,
+ KE_S_F12 = 17,
+ KE_S_F13 = 18,
+ KE_S_F14 = 19,
+ KE_S_F15 = 20,
+ KE_S_F16 = 21,
+ KE_S_F17 = 22,
+ KE_S_F18 = 23,
+ KE_S_F19 = 24,
+ KE_S_F20 = 25,
+
+ KE_S_F21 = 26,
+ KE_S_F22 = 27,
+ KE_S_F23 = 28,
+ KE_S_F24 = 29,
+ KE_S_F25 = 30,
+ KE_S_F26 = 31,
+ KE_S_F27 = 32,
+ KE_S_F28 = 33,
+ KE_S_F29 = 34,
+ KE_S_F30 = 35,
+
+ KE_S_F31 = 36,
+ KE_S_F32 = 37,
+ KE_S_F33 = 38,
+ KE_S_F34 = 39,
+ KE_S_F35 = 40,
+ KE_S_F36 = 41,
+ KE_S_F37 = 42,
+
+ KE_MOUSE = 43, // mouse event start
// Symbols for pseudo keys which are translated from the real key symbols
// above.
- , KE_LEFTMOUSE = 44 // Left mouse button click
- , KE_LEFTDRAG = 45 // Drag with left mouse button down
- , KE_LEFTRELEASE = 46 // Left mouse button release
- , KE_MIDDLEMOUSE = 47 // Middle mouse button click
- , KE_MIDDLEDRAG = 48 // Drag with middle mouse button down
- , KE_MIDDLERELEASE = 49 // Middle mouse button release
- , KE_RIGHTMOUSE = 50 // Right mouse button click
- , KE_RIGHTDRAG = 51 // Drag with right mouse button down
- , KE_RIGHTRELEASE = 52 // Right mouse button release
+ KE_LEFTMOUSE = 44, // Left mouse button click
+ KE_LEFTDRAG = 45, // Drag with left mouse button down
+ KE_LEFTRELEASE = 46, // Left mouse button release
+ KE_MIDDLEMOUSE = 47, // Middle mouse button click
+ KE_MIDDLEDRAG = 48, // Drag with middle mouse button down
+ KE_MIDDLERELEASE = 49, // Middle mouse button release
+ KE_RIGHTMOUSE = 50, // Right mouse button click
+ KE_RIGHTDRAG = 51, // Drag with right mouse button down
+ KE_RIGHTRELEASE = 52, // Right mouse button release
- , KE_IGNORE = 53 // Ignored mouse drag/release
+ KE_IGNORE = 53, // Ignored mouse drag/release
- , KE_TAB = 54 // unshifted TAB key
- , KE_S_TAB_OLD = 55 // shifted TAB key (no longer used)
+ KE_TAB = 54, // unshifted TAB key
+ KE_S_TAB_OLD = 55, // shifted TAB key (no longer used)
// , KE_SNIFF_UNUSED = 56 // obsolete
- , KE_XF1 = 57 // extra vt100 function keys for xterm
- , KE_XF2 = 58
- , KE_XF3 = 59
- , KE_XF4 = 60
- , KE_XEND = 61 // extra (vt100) end key for xterm
- , KE_ZEND = 62 // extra (vt100) end key for xterm
- , KE_XHOME = 63 // extra (vt100) home key for xterm
- , KE_ZHOME = 64 // extra (vt100) home key for xterm
- , KE_XUP = 65 // extra vt100 cursor keys for xterm
- , KE_XDOWN = 66
- , KE_XLEFT = 67
- , KE_XRIGHT = 68
-
- , KE_LEFTMOUSE_NM = 69 // non-mappable Left mouse button click
- , KE_LEFTRELEASE_NM = 70 // non-mappable left mouse button release
-
- , KE_S_XF1 = 71 // vt100 shifted function keys for xterm
- , KE_S_XF2 = 72
- , KE_S_XF3 = 73
- , KE_S_XF4 = 74
+ KE_XF1 = 57, // extra vt100 function keys for xterm
+ KE_XF2 = 58,
+ KE_XF3 = 59,
+ KE_XF4 = 60,
+ KE_XEND = 61, // extra (vt100) end key for xterm
+ KE_ZEND = 62, // extra (vt100) end key for xterm
+ KE_XHOME = 63, // extra (vt100) home key for xterm
+ KE_ZHOME = 64, // extra (vt100) home key for xterm
+ KE_XUP = 65, // extra vt100 cursor keys for xterm
+ KE_XDOWN = 66,
+ KE_XLEFT = 67,
+ KE_XRIGHT = 68,
+
+ KE_LEFTMOUSE_NM = 69, // non-mappable Left mouse button click
+ KE_LEFTRELEASE_NM = 70, // non-mappable left mouse button release
+
+ KE_S_XF1 = 71, // vt100 shifted function keys for xterm
+ KE_S_XF2 = 72,
+ KE_S_XF3 = 73,
+ KE_S_XF4 = 74,
// NOTE: The scroll wheel events are inverted: i.e. UP is the same as
// moving the actual scroll wheel down, LEFT is the same as moving the
// scroll wheel right.
- , KE_MOUSEDOWN = 75 // scroll wheel pseudo-button Down
- , KE_MOUSEUP = 76 // scroll wheel pseudo-button Up
- , KE_MOUSELEFT = 77 // scroll wheel pseudo-button Left
- , KE_MOUSERIGHT = 78 // scroll wheel pseudo-button Right
-
- , KE_KINS = 79 // keypad Insert key
- , KE_KDEL = 80 // keypad Delete key
-
- , KE_CSI = 81 // CSI typed directly
- , KE_SNR = 82 // <SNR>
- , KE_PLUG = 83 // <Plug>
- , KE_CMDWIN = 84 // open command-line window from Command-line Mode
-
- , KE_C_LEFT = 85 // control-left
- , KE_C_RIGHT = 86 // control-right
- , KE_C_HOME = 87 // control-home
- , KE_C_END = 88 // control-end
-
- , KE_X1MOUSE = 89 // X1/X2 mouse-buttons
- , KE_X1DRAG = 90
- , KE_X1RELEASE = 91
- , KE_X2MOUSE = 92
- , KE_X2DRAG = 93
- , KE_X2RELEASE = 94
-
- , KE_DROP = 95 // DnD data is available
+ KE_MOUSEDOWN = 75, // scroll wheel pseudo-button Down
+ KE_MOUSEUP = 76, // scroll wheel pseudo-button Up
+ KE_MOUSELEFT = 77, // scroll wheel pseudo-button Left
+ KE_MOUSERIGHT = 78, // scroll wheel pseudo-button Right
+
+ KE_KINS = 79, // keypad Insert key
+ KE_KDEL = 80, // keypad Delete key
+
+ KE_CSI = 81, // CSI typed directly
+ KE_SNR = 82, // <SNR>
+ KE_PLUG = 83, // <Plug>
+ KE_CMDWIN = 84, // open command-line window from Command-line Mode
+
+ KE_C_LEFT = 85, // control-left
+ KE_C_RIGHT = 86, // control-right
+ KE_C_HOME = 87, // control-home
+ KE_C_END = 88, // control-end
+
+ KE_X1MOUSE = 89, // X1/X2 mouse-buttons
+ KE_X1DRAG = 90,
+ KE_X1RELEASE = 91,
+ KE_X2MOUSE = 92,
+ KE_X2DRAG = 93,
+ KE_X2RELEASE = 94,
+
+ KE_DROP = 95, // DnD data is available
// , KE_CURSORHOLD = 96 // CursorHold event
- , KE_NOP = 97 // no-op: does nothing
+ KE_NOP = 97, // no-op: does nothing
// , KE_FOCUSGAINED = 98 // focus gained
// , KE_FOCUSLOST = 99 // focus lost
- , KE_MOUSEMOVE = 100 // mouse moved with no button down
+ KE_MOUSEMOVE = 100, // mouse moved with no button down
// , KE_CANCEL = 101 // return from vgetc
- , KE_EVENT = 102 // event
- , KE_COMMAND = 104 // <Cmd> special key
+ KE_EVENT = 102, // event
+ KE_COMMAND = 104 // <Cmd> special key
};
/*
diff --git a/src/nvim/lib/kbtree.h b/src/nvim/lib/kbtree.h
index bef37f8ba9..e2a4e9edea 100644
--- a/src/nvim/lib/kbtree.h
+++ b/src/nvim/lib/kbtree.h
@@ -34,386 +34,419 @@
#ifndef NVIM_LIB_KBTREE_H
#define NVIM_LIB_KBTREE_H
+#include <assert.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>
-#include <stdint.h>
-#include <assert.h>
#include "nvim/memory.h"
#define KB_MAX_DEPTH 64
-#define __KB_KEY(type, x) (x->key)
-#define __KB_PTR(btr, x) (x->ptr)
+#define __KB_KEY(type, x) (x->key)
+#define __KB_PTR(btr, x) (x->ptr)
-#define __KB_TREE_T(name,key_t,T) \
- typedef struct kbnode_##name##_s kbnode_##name##_t; \
- struct kbnode_##name##_s { \
- int32_t n; \
- bool is_internal; \
- key_t key[2*T-1]; \
- kbnode_##name##_t *ptr[]; \
- } ; \
+#define __KB_TREE_T(name, key_t, T) \
+ typedef struct kbnode_##name##_s kbnode_##name##_t; \
+ struct kbnode_##name##_s { \
+ int32_t n; \
+ bool is_internal; \
+ key_t key[2*T-1]; \
+ kbnode_##name##_t *ptr[]; \
+ } ; \
\
- typedef struct { \
- kbnode_##name##_t *root; \
- int n_keys, n_nodes; \
- } kbtree_##name##_t; \
+ typedef struct { \
+ kbnode_##name##_t *root; \
+ int n_keys, n_nodes; \
+ } kbtree_##name##_t; \
\
- typedef struct { \
- kbnode_##name##_t *x; \
- int i; \
- } kbpos_##name##_t; \
- typedef struct { \
- kbpos_##name##_t stack[KB_MAX_DEPTH], *p; \
- } kbitr_##name##_t; \
+ typedef struct { \
+ kbnode_##name##_t *x; \
+ int i; \
+ } kbpos_##name##_t; \
+ typedef struct { \
+ kbpos_##name##_t stack[KB_MAX_DEPTH], *p; \
+ } kbitr_##name##_t; \
-#define __kb_destroy(kbnode_t,b) do { \
- int i; \
- unsigned int max = 8; \
- kbnode_t *x, **top, **stack = 0; \
- if (b->root) { \
- top = stack = (kbnode_t**)xcalloc(max, sizeof(kbnode_t*)); \
- *top++ = (b)->root; \
- while (top != stack) { \
- x = *--top; \
- if (x->is_internal == 0) { XFREE_CLEAR(x); continue; } \
- for (i = 0; i <= x->n; ++i) \
- if (__KB_PTR(b, x)[i]) { \
- if (top - stack == (int)max) { \
- max <<= 1; \
- stack = (kbnode_t**)xrealloc(stack, max * sizeof(kbnode_t*)); \
- top = stack + (max>>1); \
- } \
- *top++ = __KB_PTR(b, x)[i]; \
- } \
- XFREE_CLEAR(x); \
- } \
- } \
- XFREE_CLEAR(stack); \
- } while (0)
+#define __kb_destroy(kbnode_t, b) do { \
+ int i; \
+ unsigned int max = 8; \
+ kbnode_t *x, **top, **stack = 0; \
+ if (b->root) { \
+ top = stack = (kbnode_t **)xcalloc(max, sizeof(kbnode_t *)); \
+ *top++ = (b)->root; \
+ while (top != stack) { \
+ x = *--top; \
+ if (x->is_internal == 0) { XFREE_CLEAR(x); continue; } \
+ for (i = 0; i <= x->n; ++i) \
+ if (__KB_PTR(b, x)[i]) { \
+ if (top - stack == (int)max) { \
+ max <<= 1; \
+ stack = (kbnode_t **)xrealloc(stack, max * sizeof(kbnode_t *)); \
+ top = stack + (max>>1); \
+ } \
+ *top++ = __KB_PTR(b, x)[i]; \
+ } \
+ XFREE_CLEAR(x); \
+ } \
+ } \
+ XFREE_CLEAR(stack); \
+} while (0)
-#define __KB_GET_AUX1(name, key_t, kbnode_t, __cmp) \
- static inline int __kb_getp_aux_##name(const kbnode_t * __restrict x, key_t * __restrict k, int *r) \
- { \
- int tr, *rr, begin = 0, end = x->n; \
- if (x->n == 0) return -1; \
- rr = r? r : &tr; \
- while (begin < end) { \
- int mid = (begin + end) >> 1; \
- if (__cmp(__KB_KEY(key_t, x)[mid], *k) < 0) begin = mid + 1; \
- else end = mid; \
- } \
- if (begin == x->n) { *rr = 1; return x->n - 1; } \
- if ((*rr = __cmp(*k, __KB_KEY(key_t, x)[begin])) < 0) --begin; \
- return begin; \
- }
+#define __KB_GET_AUX1(name, key_t, kbnode_t, __cmp) \
+ static inline int __kb_getp_aux_##name(const kbnode_t * __restrict x, key_t * __restrict k, \
+ int *r) \
+ { \
+ int tr, *rr, begin = 0, end = x->n; \
+ if (x->n == 0) return -1; \
+ rr = r? r : &tr; \
+ while (begin < end) { \
+ int mid = (begin + end) >> 1; \
+ if (__cmp(__KB_KEY(key_t, x)[mid], *k) < 0) begin = mid + 1; \
+ else end = mid; \
+ } \
+ if (begin == x->n) { *rr = 1; return x->n - 1; } \
+ if ((*rr = __cmp(*k, __KB_KEY(key_t, x)[begin])) < 0) --begin; \
+ return begin; \
+ }
-#define __KB_GET(name, key_t, kbnode_t) \
- static key_t *kb_getp_##name(kbtree_##name##_t *b, key_t * __restrict k) \
- { \
- if (!b->root) { \
- return 0; \
- } \
- int i, r = 0; \
- kbnode_t *x = b->root; \
- while (x) { \
- i = __kb_getp_aux_##name(x, k, &r); \
- if (i >= 0 && r == 0) return &__KB_KEY(key_t, x)[i]; \
- if (x->is_internal == 0) return 0; \
- x = __KB_PTR(b, x)[i + 1]; \
- } \
- return 0; \
- } \
- static inline key_t *kb_get_##name(kbtree_##name##_t *b, key_t k) \
- { \
- return kb_getp_##name(b, &k); \
- }
+#define __KB_GET(name, key_t, kbnode_t) \
+ static key_t *kb_getp_##name(kbtree_##name##_t *b, key_t * __restrict k) \
+ { \
+ if (!b->root) { \
+ return 0; \
+ } \
+ int i, r = 0; \
+ kbnode_t *x = b->root; \
+ while (x) { \
+ i = __kb_getp_aux_##name(x, k, &r); \
+ if (i >= 0 && r == 0) return &__KB_KEY(key_t, x)[i]; \
+ if (x->is_internal == 0) return 0; \
+ x = __KB_PTR(b, x)[i + 1]; \
+ } \
+ return 0; \
+ } \
+ static inline key_t *kb_get_##name(kbtree_##name##_t *b, key_t k) \
+ { \
+ return kb_getp_##name(b, &k); \
+ }
-#define __KB_INTERVAL(name, key_t, kbnode_t) \
- static inline void kb_intervalp_##name(kbtree_##name##_t *b, key_t * __restrict k, key_t **lower, key_t **upper) \
- { \
- if (!b->root) { \
- return; \
- } \
- int i, r = 0; \
- kbnode_t *x = b->root; \
- *lower = *upper = 0; \
- while (x) { \
- i = __kb_getp_aux_##name(x, k, &r); \
- if (i >= 0 && r == 0) { \
- *lower = *upper = &__KB_KEY(key_t, x)[i]; \
- return; \
- } \
- if (i >= 0) *lower = &__KB_KEY(key_t, x)[i]; \
- if (i < x->n - 1) *upper = &__KB_KEY(key_t, x)[i + 1]; \
- if (x->is_internal == 0) return; \
- x = __KB_PTR(b, x)[i + 1]; \
- } \
- } \
- static inline void kb_interval_##name(kbtree_##name##_t *b, key_t k, key_t **lower, key_t **upper) \
- { \
- kb_intervalp_##name(b, &k, lower, upper); \
- }
+#define __KB_INTERVAL(name, key_t, kbnode_t) \
+ static inline void kb_intervalp_##name(kbtree_##name##_t *b, key_t * __restrict k, key_t **lower, \
+ key_t **upper) \
+ { \
+ if (!b->root) { \
+ return; \
+ } \
+ int i, r = 0; \
+ kbnode_t *x = b->root; \
+ *lower = *upper = 0; \
+ while (x) { \
+ i = __kb_getp_aux_##name(x, k, &r); \
+ if (i >= 0 && r == 0) { \
+ *lower = *upper = &__KB_KEY(key_t, x)[i]; \
+ return; \
+ } \
+ if (i >= 0) *lower = &__KB_KEY(key_t, x)[i]; \
+ if (i < x->n - 1) *upper = &__KB_KEY(key_t, x)[i + 1]; \
+ if (x->is_internal == 0) return; \
+ x = __KB_PTR(b, x)[i + 1]; \
+ } \
+ } \
+ static inline void kb_interval_##name(kbtree_##name##_t *b, key_t k, key_t **lower, key_t **upper) \
+ { \
+ kb_intervalp_##name(b, &k, lower, upper); \
+ }
-#define __KB_PUT(name, key_t, kbnode_t, __cmp, T, ILEN) \
- /* x must be an internal node */ \
- static inline void __kb_split_##name(kbtree_##name##_t *b, kbnode_t *x, int i, kbnode_t *y) \
- { \
- kbnode_t *z; \
- z = (kbnode_t*)xcalloc(1, y->is_internal? ILEN : sizeof(kbnode_##name##_t)); \
- ++b->n_nodes; \
- z->is_internal = y->is_internal; \
- z->n = T - 1; \
- memcpy(__KB_KEY(key_t, z), &__KB_KEY(key_t, y)[T], sizeof(key_t) * (T - 1)); \
- if (y->is_internal) memcpy(__KB_PTR(b, z), &__KB_PTR(b, y)[T], sizeof(void*) * T); \
- y->n = T - 1; \
- memmove(&__KB_PTR(b, x)[i + 2], &__KB_PTR(b, x)[i + 1], sizeof(void*) * (unsigned int)(x->n - i)); \
- __KB_PTR(b, x)[i + 1] = z; \
- memmove(&__KB_KEY(key_t, x)[i + 1], &__KB_KEY(key_t, x)[i], sizeof(key_t) * (unsigned int)(x->n - i)); \
- __KB_KEY(key_t, x)[i] = __KB_KEY(key_t, y)[T - 1]; \
- ++x->n; \
- } \
- static inline key_t *__kb_putp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, key_t * __restrict k) \
- { \
- int i = x->n - 1; \
- key_t *ret; \
- if (x->is_internal == 0) { \
- i = __kb_getp_aux_##name(x, k, 0); \
- if (i != x->n - 1) \
- memmove(&__KB_KEY(key_t, x)[i + 2], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
- ret = &__KB_KEY(key_t, x)[i + 1]; \
- *ret = *k; \
- ++x->n; \
- } else { \
- i = __kb_getp_aux_##name(x, k, 0) + 1; \
- if (__KB_PTR(b, x)[i]->n == 2 * T - 1) { \
- __kb_split_##name(b, x, i, __KB_PTR(b, x)[i]); \
- if (__cmp(*k, __KB_KEY(key_t, x)[i]) > 0) ++i; \
- } \
- ret = __kb_putp_aux_##name(b, __KB_PTR(b, x)[i], k); \
- } \
- return ret; \
- } \
- static inline key_t *kb_putp_##name(kbtree_##name##_t *b, key_t * __restrict k) \
- { \
- if (!b->root) { \
- b->root = (kbnode_t*)xcalloc(1, ILEN); \
- ++b->n_nodes; \
- } \
- kbnode_t *r, *s; \
- ++b->n_keys; \
- r = b->root; \
- if (r->n == 2 * T - 1) { \
- ++b->n_nodes; \
- s = (kbnode_t*)xcalloc(1, ILEN); \
- b->root = s; s->is_internal = 1; s->n = 0; \
- __KB_PTR(b, s)[0] = r; \
- __kb_split_##name(b, s, 0, r); \
- r = s; \
- } \
- return __kb_putp_aux_##name(b, r, k); \
- } \
- static inline void kb_put_##name(kbtree_##name##_t *b, key_t k) \
- { \
- kb_putp_##name(b, &k); \
- }
+#define __KB_PUT(name, key_t, kbnode_t, __cmp, T, ILEN) \
+ /* x must be an internal node */ \
+ static inline void __kb_split_##name(kbtree_##name##_t *b, kbnode_t *x, int i, kbnode_t *y) \
+ { \
+ kbnode_t *z; \
+ z = (kbnode_t *)xcalloc(1, y->is_internal? ILEN : sizeof(kbnode_##name##_t)); \
+ ++b->n_nodes; \
+ z->is_internal = y->is_internal; \
+ z->n = T - 1; \
+ memcpy(__KB_KEY(key_t, z), &__KB_KEY(key_t, y)[T], sizeof(key_t) * (T - 1)); \
+ if (y->is_internal) memcpy(__KB_PTR(b, z), &__KB_PTR(b, y)[T], sizeof(void *) * T); \
+ y->n = T - 1; \
+ memmove(&__KB_PTR(b, x)[i + 2], &__KB_PTR(b, \
+ x)[i + 1], sizeof(void *) * (unsigned int)(x->n - i)); \
+ __KB_PTR(b, x)[i + 1] = z; \
+ memmove(&__KB_KEY(key_t, x)[i + 1], &__KB_KEY(key_t, x)[i], \
+ sizeof(key_t) * (unsigned int)(x->n - i)); \
+ __KB_KEY(key_t, x)[i] = __KB_KEY(key_t, y)[T - 1]; \
+ ++x->n; \
+ } \
+ static inline key_t *__kb_putp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, key_t * __restrict k) \
+ { \
+ int i = x->n - 1; \
+ key_t *ret; \
+ if (x->is_internal == 0) { \
+ i = __kb_getp_aux_##name(x, k, 0); \
+ if (i != x->n - 1) \
+ memmove(&__KB_KEY(key_t, x)[i + 2], &__KB_KEY(key_t, \
+ x)[i + 1], \
+ (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
+ ret = &__KB_KEY(key_t, x)[i + 1]; \
+ *ret = *k; \
+ ++x->n; \
+ } else { \
+ i = __kb_getp_aux_##name(x, k, 0) + 1; \
+ if (__KB_PTR(b, x)[i]->n == 2 * T - 1) { \
+ __kb_split_##name(b, x, i, __KB_PTR(b, x)[i]); \
+ if (__cmp(*k, __KB_KEY(key_t, x)[i]) > 0) ++i; \
+ } \
+ ret = __kb_putp_aux_##name(b, __KB_PTR(b, x)[i], k); \
+ } \
+ return ret; \
+ } \
+ static inline key_t *kb_putp_##name(kbtree_##name##_t *b, key_t * __restrict k) \
+ { \
+ if (!b->root) { \
+ b->root = (kbnode_t *)xcalloc(1, ILEN); \
+ ++b->n_nodes; \
+ } \
+ kbnode_t *r, *s; \
+ ++b->n_keys; \
+ r = b->root; \
+ if (r->n == 2 * T - 1) { \
+ ++b->n_nodes; \
+ s = (kbnode_t *)xcalloc(1, ILEN); \
+ b->root = s; s->is_internal = 1; s->n = 0; \
+ __KB_PTR(b, s)[0] = r; \
+ __kb_split_##name(b, s, 0, r); \
+ r = s; \
+ } \
+ return __kb_putp_aux_##name(b, r, k); \
+ } \
+ static inline void kb_put_##name(kbtree_##name##_t *b, key_t k) \
+ { \
+ kb_putp_##name(b, &k); \
+ }
-#define __KB_DEL(name, key_t, kbnode_t, T) \
- static inline key_t __kb_delp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, key_t * __restrict k, int s) \
- { \
- int yn, zn, i, r = 0; \
- kbnode_t *xp, *y, *z; \
- key_t kp; \
- if (x == 0) return *k; \
- if (s) { /* s can only be 0, 1 or 2 */ \
- r = x->is_internal == 0? 0 : s == 1? 1 : -1; \
- i = s == 1? x->n - 1 : -1; \
- } else i = __kb_getp_aux_##name(x, k, &r); \
- if (x->is_internal == 0) { \
- if (s == 2) ++i; \
- kp = __KB_KEY(key_t, x)[i]; \
- memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
- --x->n; \
- return kp; \
- } \
- if (r == 0) { \
- if ((yn = __KB_PTR(b, x)[i]->n) >= T) { \
- xp = __KB_PTR(b, x)[i]; \
- kp = __KB_KEY(key_t, x)[i]; \
- __KB_KEY(key_t, x)[i] = __kb_delp_aux_##name(b, xp, 0, 1); \
- return kp; \
- } else if ((zn = __KB_PTR(b, x)[i + 1]->n) >= T) { \
- xp = __KB_PTR(b, x)[i + 1]; \
- kp = __KB_KEY(key_t, x)[i]; \
- __KB_KEY(key_t, x)[i] = __kb_delp_aux_##name(b, xp, 0, 2); \
- return kp; \
- } else if (yn == T - 1 && zn == T - 1) { \
- y = __KB_PTR(b, x)[i]; z = __KB_PTR(b, x)[i + 1]; \
- __KB_KEY(key_t, y)[y->n++] = *k; \
- memmove(&__KB_KEY(key_t, y)[y->n], __KB_KEY(key_t, z), (unsigned int)z->n * sizeof(key_t)); \
- if (y->is_internal) memmove(&__KB_PTR(b, y)[y->n], __KB_PTR(b, z), (unsigned int)(z->n + 1) * sizeof(void*)); \
- y->n += z->n; \
- memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
- memmove(&__KB_PTR(b, x)[i + 1], &__KB_PTR(b, x)[i + 2], (unsigned int)(x->n - i - 1) * sizeof(void*)); \
- --x->n; \
- XFREE_CLEAR(z); \
- return __kb_delp_aux_##name(b, y, k, s); \
- } \
- } \
- ++i; \
- if ((xp = __KB_PTR(b, x)[i])->n == T - 1) { \
- if (i > 0 && (y = __KB_PTR(b, x)[i - 1])->n >= T) { \
- memmove(&__KB_KEY(key_t, xp)[1], __KB_KEY(key_t, xp), (unsigned int)xp->n * sizeof(key_t)); \
- if (xp->is_internal) memmove(&__KB_PTR(b, xp)[1], __KB_PTR(b, xp), (unsigned int)(xp->n + 1) * sizeof(void*)); \
- __KB_KEY(key_t, xp)[0] = __KB_KEY(key_t, x)[i - 1]; \
- __KB_KEY(key_t, x)[i - 1] = __KB_KEY(key_t, y)[y->n - 1]; \
- if (xp->is_internal) __KB_PTR(b, xp)[0] = __KB_PTR(b, y)[y->n]; \
- --y->n; ++xp->n; \
- } else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n >= T) { \
- __KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \
- __KB_KEY(key_t, x)[i] = __KB_KEY(key_t, y)[0]; \
- if (xp->is_internal) __KB_PTR(b, xp)[xp->n] = __KB_PTR(b, y)[0]; \
- --y->n; \
- memmove(__KB_KEY(key_t, y), &__KB_KEY(key_t, y)[1], (unsigned int)y->n * sizeof(key_t)); \
- if (y->is_internal) memmove(__KB_PTR(b, y), &__KB_PTR(b, y)[1], (unsigned int)(y->n + 1) * sizeof(void*)); \
- } else if (i > 0 && (y = __KB_PTR(b, x)[i - 1])->n == T - 1) { \
- __KB_KEY(key_t, y)[y->n++] = __KB_KEY(key_t, x)[i - 1]; \
- memmove(&__KB_KEY(key_t, y)[y->n], __KB_KEY(key_t, xp), (unsigned int)xp->n * sizeof(key_t)); \
- if (y->is_internal) memmove(&__KB_PTR(b, y)[y->n], __KB_PTR(b, xp), (unsigned int)(xp->n + 1) * sizeof(void*)); \
- y->n += xp->n; \
- memmove(&__KB_KEY(key_t, x)[i - 1], &__KB_KEY(key_t, x)[i], (unsigned int)(x->n - i) * sizeof(key_t)); \
- memmove(&__KB_PTR(b, x)[i], &__KB_PTR(b, x)[i + 1], (unsigned int)(x->n - i) * sizeof(void*)); \
- --x->n; \
- XFREE_CLEAR(xp); \
- xp = y; \
- } else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n == T - 1) { \
- __KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \
- memmove(&__KB_KEY(key_t, xp)[xp->n], __KB_KEY(key_t, y), (unsigned int)y->n * sizeof(key_t)); \
- if (xp->is_internal) memmove(&__KB_PTR(b, xp)[xp->n], __KB_PTR(b, y), (unsigned int)(y->n + 1) * sizeof(void*)); \
- xp->n += y->n; \
- memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
- memmove(&__KB_PTR(b, x)[i + 1], &__KB_PTR(b, x)[i + 2], (unsigned int)(x->n - i - 1) * sizeof(void*)); \
- --x->n; \
- XFREE_CLEAR(y); \
- } \
- } \
- return __kb_delp_aux_##name(b, xp, k, s); \
- } \
- static inline key_t kb_delp_##name(kbtree_##name##_t *b, key_t * __restrict k) \
- { \
- kbnode_t *x; \
- key_t ret; \
- ret = __kb_delp_aux_##name(b, b->root, k, 0); \
- --b->n_keys; \
- if (b->root->n == 0 && b->root->is_internal) { \
- --b->n_nodes; \
- x = b->root; \
- b->root = __KB_PTR(b, x)[0]; \
- XFREE_CLEAR(x); \
- } \
- return ret; \
- } \
- static inline key_t kb_del_##name(kbtree_##name##_t *b, key_t k) \
- { \
- return kb_delp_##name(b, &k); \
- }
+#define __KB_DEL(name, key_t, kbnode_t, T) \
+ static inline key_t __kb_delp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, key_t * __restrict k, \
+ int s) \
+ { \
+ int yn, zn, i, r = 0; \
+ kbnode_t *xp, *y, *z; \
+ key_t kp; \
+ if (x == 0) return *k; \
+ if (s) { /* s can only be 0, 1 or 2 */ \
+ r = x->is_internal == 0? 0 : s == 1? 1 : -1; \
+ i = s == 1? x->n - 1 : -1; \
+ } else i = __kb_getp_aux_##name(x, k, &r); \
+ if (x->is_internal == 0) { \
+ if (s == 2) ++i; \
+ kp = __KB_KEY(key_t, x)[i]; \
+ memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, \
+ x)[i + 1], \
+ (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
+ --x->n; \
+ return kp; \
+ } \
+ if (r == 0) { \
+ if ((yn = __KB_PTR(b, x)[i]->n) >= T) { \
+ xp = __KB_PTR(b, x)[i]; \
+ kp = __KB_KEY(key_t, x)[i]; \
+ __KB_KEY(key_t, x)[i] = __kb_delp_aux_##name(b, xp, 0, 1); \
+ return kp; \
+ } else if ((zn = __KB_PTR(b, x)[i + 1]->n) >= T) { \
+ xp = __KB_PTR(b, x)[i + 1]; \
+ kp = __KB_KEY(key_t, x)[i]; \
+ __KB_KEY(key_t, x)[i] = __kb_delp_aux_##name(b, xp, 0, 2); \
+ return kp; \
+ } else if (yn == T - 1 && zn == T - 1) { \
+ y = __KB_PTR(b, x)[i]; z = __KB_PTR(b, x)[i + 1]; \
+ __KB_KEY(key_t, y)[y->n++] = *k; \
+ memmove(&__KB_KEY(key_t, y)[y->n], __KB_KEY(key_t, z), (unsigned int)z->n * sizeof(key_t)); \
+ if (y->is_internal) memmove(&__KB_PTR(b, y)[y->n], __KB_PTR(b, \
+ z), \
+ (unsigned int)(z->n + 1) * sizeof(void *)); \
+ y->n += z->n; \
+ memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, \
+ x)[i + 1], \
+ (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
+ memmove(&__KB_PTR(b, x)[i + 1], &__KB_PTR(b, \
+ x)[i + 2], \
+ (unsigned int)(x->n - i - 1) * sizeof(void *)); \
+ --x->n; \
+ XFREE_CLEAR(z); \
+ return __kb_delp_aux_##name(b, y, k, s); \
+ } \
+ } \
+ ++i; \
+ if ((xp = __KB_PTR(b, x)[i])->n == T - 1) { \
+ if (i > 0 && (y = __KB_PTR(b, x)[i - 1])->n >= T) { \
+ memmove(&__KB_KEY(key_t, xp)[1], __KB_KEY(key_t, xp), (unsigned int)xp->n * sizeof(key_t)); \
+ if (xp->is_internal) memmove(&__KB_PTR(b, xp)[1], __KB_PTR(b, \
+ xp), \
+ (unsigned int)(xp->n + 1) * sizeof(void *)); \
+ __KB_KEY(key_t, xp)[0] = __KB_KEY(key_t, x)[i - 1]; \
+ __KB_KEY(key_t, x)[i - 1] = __KB_KEY(key_t, y)[y->n - 1]; \
+ if (xp->is_internal) __KB_PTR(b, xp)[0] = __KB_PTR(b, y)[y->n]; \
+ --y->n; ++xp->n; \
+ } else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n >= T) { \
+ __KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \
+ __KB_KEY(key_t, x)[i] = __KB_KEY(key_t, y)[0]; \
+ if (xp->is_internal) __KB_PTR(b, xp)[xp->n] = __KB_PTR(b, y)[0]; \
+ --y->n; \
+ memmove(__KB_KEY(key_t, y), &__KB_KEY(key_t, y)[1], (unsigned int)y->n * sizeof(key_t)); \
+ if (y->is_internal) memmove(__KB_PTR(b, y), &__KB_PTR(b, \
+ y)[1], \
+ (unsigned int)(y->n + 1) * sizeof(void *)); \
+ } else if (i > 0 && (y = __KB_PTR(b, x)[i - 1])->n == T - 1) { \
+ __KB_KEY(key_t, y)[y->n++] = __KB_KEY(key_t, x)[i - 1]; \
+ memmove(&__KB_KEY(key_t, y)[y->n], __KB_KEY(key_t, xp), \
+ (unsigned int)xp->n * sizeof(key_t)); \
+ if (y->is_internal) memmove(&__KB_PTR(b, y)[y->n], __KB_PTR(b, \
+ xp), \
+ (unsigned int)(xp->n + 1) * sizeof(void *)); \
+ y->n += xp->n; \
+ memmove(&__KB_KEY(key_t, x)[i - 1], &__KB_KEY(key_t, \
+ x)[i], \
+ (unsigned int)(x->n - i) * sizeof(key_t)); \
+ memmove(&__KB_PTR(b, x)[i], &__KB_PTR(b, \
+ x)[i + 1], (unsigned int)(x->n - i) * sizeof(void *)); \
+ --x->n; \
+ XFREE_CLEAR(xp); \
+ xp = y; \
+ } else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n == T - 1) { \
+ __KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \
+ memmove(&__KB_KEY(key_t, xp)[xp->n], __KB_KEY(key_t, y), \
+ (unsigned int)y->n * sizeof(key_t)); \
+ if (xp->is_internal) memmove(&__KB_PTR(b, xp)[xp->n], __KB_PTR(b, y), \
+ (unsigned int)(y->n + 1) * sizeof(void *)); \
+ xp->n += y->n; \
+ memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, \
+ x)[i + 1], \
+ (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
+ memmove(&__KB_PTR(b, x)[i + 1], &__KB_PTR(b, \
+ x)[i + 2], \
+ (unsigned int)(x->n - i - 1) * sizeof(void *)); \
+ --x->n; \
+ XFREE_CLEAR(y); \
+ } \
+ } \
+ return __kb_delp_aux_##name(b, xp, k, s); \
+ } \
+ static inline key_t kb_delp_##name(kbtree_##name##_t *b, key_t * __restrict k) \
+ { \
+ kbnode_t *x; \
+ key_t ret; \
+ ret = __kb_delp_aux_##name(b, b->root, k, 0); \
+ --b->n_keys; \
+ if (b->root->n == 0 && b->root->is_internal) { \
+ --b->n_nodes; \
+ x = b->root; \
+ b->root = __KB_PTR(b, x)[0]; \
+ XFREE_CLEAR(x); \
+ } \
+ return ret; \
+ } \
+ static inline key_t kb_del_##name(kbtree_##name##_t *b, key_t k) \
+ { \
+ return kb_delp_##name(b, &k); \
+ }
#define __KB_ITR(name, key_t, kbnode_t) \
- static inline void kb_itr_first_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \
- { \
- itr->p = NULL; \
- if (b->n_keys == 0) return; \
- itr->p = itr->stack; \
- itr->p->x = b->root; itr->p->i = 0; \
- while (itr->p->x->is_internal && __KB_PTR(b, itr->p->x)[0] != 0) { \
- kbnode_t *x = itr->p->x; \
- ++itr->p; \
- itr->p->x = __KB_PTR(b, x)[0]; itr->p->i = 0; \
- } \
- } \
- static inline int kb_itr_next_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \
- { \
- if (itr->p == NULL) return 0; \
- for (;;) { \
- ++itr->p->i; \
- assert(itr->p->i <= 21); \
- while (itr->p->x && itr->p->i <= itr->p->x->n) { \
- itr->p[1].i = 0; \
- itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[itr->p->i] : 0; \
- ++itr->p; \
- } \
- if (itr->p == itr->stack) { \
- itr->p = NULL; \
- return 0; \
- } \
- --itr->p; \
- if (itr->p->x && itr->p->i < itr->p->x->n) return 1; \
- } \
- } \
- static inline int kb_itr_prev_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \
- { \
- if (itr->p == NULL) return 0; \
- for (;;) { \
- while (itr->p->x && itr->p->i >= 0) { \
- itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[itr->p->i] : 0; \
- itr->p[1].i = itr->p[1].x ? itr->p[1].x->n : -1; \
- ++itr->p; \
- } \
- if (itr->p == itr->stack) { \
- itr->p = NULL; \
- return 0; \
- } \
- --itr->p; \
- --itr->p->i; \
- if (itr->p->x && itr->p->i >= 0) return 1; \
- } \
- } \
- static inline int kb_itr_getp_##name(kbtree_##name##_t *b, key_t * __restrict k, kbitr_##name##_t *itr) \
- { \
- if (b->n_keys == 0) { \
+ static inline void kb_itr_first_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \
+ { \
+ itr->p = NULL; \
+ if (b->n_keys == 0) return; \
+ itr->p = itr->stack; \
+ itr->p->x = b->root; itr->p->i = 0; \
+ while (itr->p->x->is_internal && __KB_PTR(b, itr->p->x)[0] != 0) { \
+ kbnode_t *x = itr->p->x; \
+ ++itr->p; \
+ itr->p->x = __KB_PTR(b, x)[0]; itr->p->i = 0; \
+ } \
+ } \
+ static inline int kb_itr_next_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \
+ { \
+ if (itr->p == NULL) return 0; \
+ for (;;) { \
+ ++itr->p->i; \
+ assert(itr->p->i <= 21); \
+ while (itr->p->x && itr->p->i <= itr->p->x->n) { \
+ itr->p[1].i = 0; \
+ itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[itr->p->i] : 0; \
+ ++itr->p; \
+ } \
+ if (itr->p == itr->stack) { \
+ itr->p = NULL; \
+ return 0; \
+ } \
+ --itr->p; \
+ if (itr->p->x && itr->p->i < itr->p->x->n) return 1; \
+ } \
+ } \
+ static inline int kb_itr_prev_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \
+ { \
+ if (itr->p == NULL) return 0; \
+ for (;;) { \
+ while (itr->p->x && itr->p->i >= 0) { \
+ itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[itr->p->i] : 0; \
+ itr->p[1].i = itr->p[1].x ? itr->p[1].x->n : -1; \
+ ++itr->p; \
+ } \
+ if (itr->p == itr->stack) { \
itr->p = NULL; \
return 0; \
- } \
- int i, r = 0; \
- itr->p = itr->stack; \
- itr->p->x = b->root; \
- while (itr->p->x) { \
- i = __kb_getp_aux_##name(itr->p->x, k, &r); \
- itr->p->i = i; \
- if (i >= 0 && r == 0) return 1; \
- ++itr->p->i; \
- assert(itr->p->i <= 21); \
- itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[i + 1] : 0; \
- ++itr->p; \
- } \
- itr->p->i = 0; \
- return 0; \
- } \
- static inline int kb_itr_get_##name(kbtree_##name##_t *b, key_t k, kbitr_##name##_t *itr) \
- { \
- return kb_itr_getp_##name(b,&k,itr); \
- } \
- static inline void kb_del_itr_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \
- { \
- key_t k = kb_itr_key(itr); \
- kb_delp_##name(b, &k); \
- kb_itr_getp_##name(b, &k, itr); \
- }
+ } \
+ --itr->p; \
+ --itr->p->i; \
+ if (itr->p->x && itr->p->i >= 0) return 1; \
+ } \
+ } \
+ static inline int kb_itr_getp_##name(kbtree_##name##_t *b, key_t * __restrict k, \
+ kbitr_##name##_t *itr) \
+ { \
+ if (b->n_keys == 0) { \
+ itr->p = NULL; \
+ return 0; \
+ } \
+ int i, r = 0; \
+ itr->p = itr->stack; \
+ itr->p->x = b->root; \
+ while (itr->p->x) { \
+ i = __kb_getp_aux_##name(itr->p->x, k, &r); \
+ itr->p->i = i; \
+ if (i >= 0 && r == 0) return 1; \
+ ++itr->p->i; \
+ assert(itr->p->i <= 21); \
+ itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[i + 1] : 0; \
+ ++itr->p; \
+ } \
+ itr->p->i = 0; \
+ return 0; \
+ } \
+ static inline int kb_itr_get_##name(kbtree_##name##_t *b, key_t k, kbitr_##name##_t *itr) \
+ { \
+ return kb_itr_getp_##name(b, &k, itr); \
+ } \
+ static inline void kb_del_itr_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \
+ { \
+ key_t k = kb_itr_key(itr); \
+ kb_delp_##name(b, &k); \
+ kb_itr_getp_##name(b, &k, itr); \
+ }
#define KBTREE_INIT(name, key_t, __cmp, T) \
- KBTREE_INIT_IMPL(name, key_t, kbnode_##name##_t, __cmp, T, (sizeof(kbnode_##name##_t)+(2*T)*sizeof(void *)))
+ KBTREE_INIT_IMPL(name, key_t, kbnode_##name##_t, __cmp, T, \
+ (sizeof(kbnode_##name##_t)+(2*T)*sizeof(void *)))
-#define KBTREE_INIT_IMPL(name, key_t, kbnode_t, __cmp, T, ILEN) \
- __KB_TREE_T(name, key_t, T) \
- __KB_GET_AUX1(name, key_t, kbnode_t, __cmp) \
- __KB_GET(name, key_t, kbnode_t) \
- __KB_INTERVAL(name, key_t, kbnode_t) \
- __KB_PUT(name, key_t, kbnode_t, __cmp, T, ILEN) \
- __KB_DEL(name, key_t, kbnode_t, T) \
- __KB_ITR(name, key_t, kbnode_t)
+#define KBTREE_INIT_IMPL(name, key_t, kbnode_t, __cmp, T, ILEN) \
+ __KB_TREE_T(name, key_t, T) \
+ __KB_GET_AUX1(name, key_t, kbnode_t, __cmp) \
+ __KB_GET(name, key_t, kbnode_t) \
+ __KB_INTERVAL(name, key_t, kbnode_t) \
+ __KB_PUT(name, key_t, kbnode_t, __cmp, T, ILEN) \
+ __KB_DEL(name, key_t, kbnode_t, T) \
+ __KB_ITR(name, key_t, kbnode_t)
#define KB_DEFAULT_SIZE 512
diff --git a/src/nvim/lib/khash.h b/src/nvim/lib/khash.h
index c999511543..dd87415144 100644
--- a/src/nvim/lib/khash.h
+++ b/src/nvim/lib/khash.h
@@ -21,14 +21,14 @@
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-*/
+ */
/*
- Example:
+ Example:
-#include "nvim/khash.h"
-KHASH_MAP_INIT_INT(32, char)
-int main() {
+ #include "nvim/khash.h"
+ KHASH_MAP_INIT_INT(32, char)
+ int main() {
int ret, is_missing;
khiter_t k;
khash_t(32) *h = kh_init(32);
@@ -42,99 +42,98 @@ int main() {
if (kh_exist(h, k)) kh_value(h, k) = 1;
kh_destroy(32, h);
return 0;
-}
-*/
+ }
+ */
/*
- 2013-05-02 (0.2.8):
+ 2013-05-02 (0.2.8):
- * Use quadratic probing. When the capacity is power of 2, stepping function
- i*(i+1)/2 guarantees to traverse each bucket. It is better than double
- hashing on cache performance and is more robust than linear probing.
+ * Use quadratic probing. When the capacity is power of 2, stepping function
+ i*(i+1)/2 guarantees to traverse each bucket. It is better than double
+ hashing on cache performance and is more robust than linear probing.
- In theory, double hashing should be more robust than quadratic probing.
- However, my implementation is probably not for large hash tables, because
- the second hash function is closely tied to the first hash function,
- which reduce the effectiveness of double hashing.
+ In theory, double hashing should be more robust than quadratic probing.
+ However, my implementation is probably not for large hash tables, because
+ the second hash function is closely tied to the first hash function,
+ which reduce the effectiveness of double hashing.
- Reference: http://research.cs.vt.edu/AVresearch/hashing/quadratic.php
+ Reference: http://research.cs.vt.edu/AVresearch/hashing/quadratic.php
- 2011-12-29 (0.2.7):
+ 2011-12-29 (0.2.7):
- * Minor code clean up; no actual effect.
+ * Minor code clean up; no actual effect.
- 2011-09-16 (0.2.6):
+ 2011-09-16 (0.2.6):
- * The capacity is a power of 2. This seems to dramatically improve the
- speed for simple keys. Thank Zilong Tan for the suggestion. Reference:
+ * The capacity is a power of 2. This seems to dramatically improve the
+ speed for simple keys. Thank Zilong Tan for the suggestion. Reference:
- - http://code.google.com/p/ulib/
- - http://nothings.org/computer/judy/
+ - http://code.google.com/p/ulib/
+ - http://nothings.org/computer/judy/
- * Allow to optionally use linear probing which usually has better
- performance for random input. Double hashing is still the default as it
- is more robust to certain non-random input.
+ * Allow to optionally use linear probing which usually has better
+ performance for random input. Double hashing is still the default as it
+ is more robust to certain non-random input.
- * Added Wang's integer hash function (not used by default). This hash
- function is more robust to certain non-random input.
+ * Added Wang's integer hash function (not used by default). This hash
+ function is more robust to certain non-random input.
- 2011-02-14 (0.2.5):
+ 2011-02-14 (0.2.5):
- * Allow to declare global functions.
+ * Allow to declare global functions.
- 2009-09-26 (0.2.4):
+ 2009-09-26 (0.2.4):
- * Improve portability
+ * Improve portability
- 2008-09-19 (0.2.3):
+ 2008-09-19 (0.2.3):
- * Corrected the example
- * Improved interfaces
+ * Corrected the example
+ * Improved interfaces
- 2008-09-11 (0.2.2):
+ 2008-09-11 (0.2.2):
- * Improved speed a little in kh_put()
+ * Improved speed a little in kh_put()
- 2008-09-10 (0.2.1):
+ 2008-09-10 (0.2.1):
- * Added kh_clear()
- * Fixed a compiling error
+ * Added kh_clear()
+ * Fixed a compiling error
- 2008-09-02 (0.2.0):
+ 2008-09-02 (0.2.0):
- * Changed to token concatenation which increases flexibility.
+ * Changed to token concatenation which increases flexibility.
- 2008-08-31 (0.1.2):
+ 2008-08-31 (0.1.2):
- * Fixed a bug in kh_get(), which has not been tested previously.
+ * Fixed a bug in kh_get(), which has not been tested previously.
- 2008-08-31 (0.1.1):
+ 2008-08-31 (0.1.1):
- * Added destructor
-*/
+ * Added destructor
+ */
#ifndef NVIM_LIB_KHASH_H
#define NVIM_LIB_KHASH_H
/*!
- @header
+ @header
- Generic hash table library.
+ Generic hash table library.
*/
#define AC_VERSION_KHASH_H "0.2.8"
-#include <stdlib.h>
-#include <string.h>
#include <limits.h>
#include <stdint.h>
-
-#include "nvim/memory.h"
+#include <stdlib.h>
+#include <string.h>
#include "nvim/func_attr.h"
+#include "nvim/memory.h"
-/* compiler specific configuration */
+// compiler specific configuration
#if UINT_MAX == 0xffffffffu
typedef unsigned int khint32_t;
@@ -149,9 +148,9 @@ typedef unsigned long long khint64_t;
#endif
#ifdef _MSC_VER
-#define kh_inline __inline
+# define kh_inline __inline
#else
-#define kh_inline inline
+# define kh_inline inline
#endif
typedef khint32_t khint_t;
@@ -168,31 +167,32 @@ typedef khint_t khiter_t;
#define __ac_fsize(m) ((m) < 16? 1 : (m)>>4)
#ifndef kroundup32
-#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
+# define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, \
+ ++(x))
#endif
#ifndef kcalloc
-#define kcalloc(N,Z) xcalloc(N,Z)
+# define kcalloc(N, Z) xcalloc(N, Z)
#endif
#ifndef kmalloc
-#define kmalloc(Z) xmalloc(Z)
+# define kmalloc(Z) xmalloc(Z)
#endif
#ifndef krealloc
-#define krealloc(P,Z) xrealloc(P,Z)
+# define krealloc(P, Z) xrealloc(P, Z)
#endif
#ifndef kfree
-#define kfree(P) XFREE_CLEAR(P)
+# define kfree(P) XFREE_CLEAR(P)
#endif
#define __ac_HASH_UPPER 0.77
#define __KHASH_TYPE(name, khkey_t, khval_t) \
- typedef struct { \
- khint_t n_buckets, size, n_occupied, upper_bound; \
- khint32_t *flags; \
- khkey_t *keys; \
- khval_t *vals; \
- } kh_##name##_t;
+ typedef struct { \
+ khint_t n_buckets, size, n_occupied, upper_bound; \
+ khint32_t *flags; \
+ khkey_t *keys; \
+ khval_t *vals; \
+ } kh_##name##_t;
#define __KHASH_PROTOTYPES(name, khkey_t, khval_t) \
extern kh_##name##_t *kh_init_##name(void); \
@@ -207,12 +207,12 @@ typedef khint_t khiter_t;
#define __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, \
__hash_equal) \
SCOPE kh_##name##_t *kh_init_##name(void) \
- REAL_FATTR_UNUSED; \
+ REAL_FATTR_UNUSED; \
SCOPE kh_##name##_t *kh_init_##name(void) { \
- return (kh_##name##_t*)kcalloc(1, sizeof(kh_##name##_t)); \
+ return (kh_##name##_t *)kcalloc(1, sizeof(kh_##name##_t)); \
} \
SCOPE void kh_dealloc_##name(kh_##name##_t *h) \
- REAL_FATTR_UNUSED; \
+ REAL_FATTR_UNUSED; \
SCOPE void kh_dealloc_##name(kh_##name##_t *h) \
{ \
kfree(h->keys); \
@@ -220,7 +220,7 @@ typedef khint_t khiter_t;
kfree(h->vals); \
} \
SCOPE void kh_destroy_##name(kh_##name##_t *h) \
- REAL_FATTR_UNUSED; \
+ REAL_FATTR_UNUSED; \
SCOPE void kh_destroy_##name(kh_##name##_t *h) \
{ \
if (h) { \
@@ -229,7 +229,7 @@ typedef khint_t khiter_t;
} \
} \
SCOPE void kh_clear_##name(kh_##name##_t *h) \
- REAL_FATTR_UNUSED; \
+ REAL_FATTR_UNUSED; \
SCOPE void kh_clear_##name(kh_##name##_t *h) \
{ \
if (h && h->flags) { \
@@ -238,7 +238,7 @@ typedef khint_t khiter_t;
} \
} \
SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \
- REAL_FATTR_UNUSED; \
+ REAL_FATTR_UNUSED; \
SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \
{ \
if (h->n_buckets) { \
@@ -259,10 +259,10 @@ typedef khint_t khiter_t;
} \
} \
SCOPE void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \
- REAL_FATTR_UNUSED; \
+ REAL_FATTR_UNUSED; \
SCOPE void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \
- { /* This function uses 0.25*n_buckets bytes of working space instead of */ \
- /* [sizeof(key_t+val_t)+.25]*n_buckets. */ \
+ { /* This function uses 0.25*n_buckets bytes of working space instead of */ \
+ /* [sizeof(key_t+val_t)+.25]*n_buckets. */ \
khint32_t *new_flags = 0; \
khint_t j = 1; \
{ \
@@ -273,24 +273,23 @@ typedef khint_t khiter_t;
/* requested size is too small */ \
if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) { \
j = 0; \
- } else { /* hash table size to be changed (shrink or expand); rehash */ \
- new_flags = (khint32_t*)kmalloc(__ac_fsize(new_n_buckets) \
- * sizeof(khint32_t)); \
+ } else { /* hash table size to be changed (shrink or expand); rehash */ \
+ new_flags = (khint32_t *)kmalloc(__ac_fsize(new_n_buckets) \
+ * sizeof(khint32_t)); \
memset(new_flags, 0xaa, \
__ac_fsize(new_n_buckets) * sizeof(khint32_t)); \
- if (h->n_buckets < new_n_buckets) { /* expand */ \
- khkey_t *new_keys = (khkey_t*)krealloc( \
- (void *)h->keys, new_n_buckets * sizeof(khkey_t)); \
+ if (h->n_buckets < new_n_buckets) { /* expand */ \
+ khkey_t *new_keys = (khkey_t *)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \
h->keys = new_keys; \
if (kh_is_map) { \
- khval_t *new_vals = (khval_t*)krealloc( \
- (void *)h->vals, new_n_buckets * sizeof(khval_t)); \
+ khval_t *new_vals = \
+ (khval_t *)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \
h->vals = new_vals; \
} \
- } /* otherwise shrink */ \
+ } /* otherwise shrink */ \
} \
} \
- if (j) { /* rehashing is needed */ \
+ if (j) { /* rehashing is needed */ \
for (j = 0; j != h->n_buckets; ++j) { \
if (__ac_iseither(h->flags, j) == 0) { \
khkey_t key = h->keys[j]; \
@@ -324,7 +323,7 @@ typedef khint_t khiter_t;
} \
/* mark it as deleted in the old hash table */ \
__ac_set_isdel_true(h->flags, i); \
- } else { /* write the element and jump out of the loop */ \
+ } else { /* write the element and jump out of the loop */ \
h->keys[i] = key; \
if (kh_is_map) { \
h->vals[i] = val; \
@@ -334,15 +333,15 @@ typedef khint_t khiter_t;
} \
} \
} \
- if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \
- h->keys = (khkey_t*)krealloc((void *)h->keys, \
- new_n_buckets * sizeof(khkey_t)); \
+ if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \
+ h->keys = (khkey_t *)krealloc((void *)h->keys, \
+ new_n_buckets * sizeof(khkey_t)); \
if (kh_is_map) { \
- h->vals = (khval_t*)krealloc((void *)h->vals, \
- new_n_buckets * sizeof(khval_t)); \
+ h->vals = (khval_t *)krealloc((void *)h->vals, \
+ new_n_buckets * sizeof(khval_t)); \
} \
} \
- kfree(h->flags); /* free the working space */ \
+ kfree(h->flags); /* free the working space */ \
h->flags = new_flags; \
h->n_buckets = new_n_buckets; \
h->n_occupied = h->size; \
@@ -350,25 +349,25 @@ typedef khint_t khiter_t;
} \
} \
SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \
- REAL_FATTR_UNUSED; \
+ REAL_FATTR_UNUSED; \
SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \
{ \
khint_t x; \
- if (h->n_occupied >= h->upper_bound) { /* update the hash table */ \
+ if (h->n_occupied >= h->upper_bound) { /* update the hash table */ \
if (h->n_buckets > (h->size << 1)) { \
- kh_resize_##name(h, h->n_buckets - 1); /* clear "deleted" elements */ \
+ kh_resize_##name(h, h->n_buckets - 1); /* clear "deleted" elements */ \
} else { \
- kh_resize_##name(h, h->n_buckets + 1); /* expand the hash table */ \
+ kh_resize_##name(h, h->n_buckets + 1); /* expand the hash table */ \
} \
- } /* TODO: implement automatically shrinking; */ \
- /* resize() already support shrinking */ \
+ } /* TODO: implement automatically shrinking; */ \
+ /* resize() already support shrinking */ \
{ \
khint_t k, i, site, last, mask = h->n_buckets - 1, step = 0; \
x = site = h->n_buckets; \
k = __hash_func(key); \
i = k & mask; \
if (__ac_isempty(h->flags, i)) { \
- x = i; /* for speed up */ \
+ x = i; /* for speed up */ \
} else { \
last = i; \
while (!__ac_isempty(h->flags, i) \
@@ -392,24 +391,24 @@ typedef khint_t khiter_t;
} \
} \
} \
- if (__ac_isempty(h->flags, x)) { /* not present at all */ \
+ if (__ac_isempty(h->flags, x)) { /* not present at all */ \
h->keys[x] = key; \
__ac_set_isboth_false(h->flags, x); \
h->size++; \
h->n_occupied++; \
*ret = 1; \
- } else if (__ac_isdel(h->flags, x)) { /* deleted */ \
+ } else if (__ac_isdel(h->flags, x)) { /* deleted */ \
h->keys[x] = key; \
__ac_set_isboth_false(h->flags, x); \
h->size++; \
*ret = 2; \
} else { \
- *ret = 0; /* Don't touch h->keys[x] if present and not deleted */ \
+ *ret = 0; /* Don't touch h->keys[x] if present and not deleted */ \
} \
return x; \
} \
SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x) \
- REAL_FATTR_UNUSED; \
+ REAL_FATTR_UNUSED; \
SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x) \
{ \
if (x != h->n_buckets && !__ac_iseither(h->flags, x)) { \
@@ -418,240 +417,242 @@ typedef khint_t khiter_t;
} \
}
-#define KHASH_DECLARE(name, khkey_t, khval_t) \
- __KHASH_TYPE(name, khkey_t, khval_t) \
- __KHASH_PROTOTYPES(name, khkey_t, khval_t)
+#define KHASH_DECLARE(name, khkey_t, khval_t) \
+ __KHASH_TYPE(name, khkey_t, khval_t) \
+ __KHASH_PROTOTYPES(name, khkey_t, khval_t)
#define KHASH_INIT2(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
- __KHASH_TYPE(name, khkey_t, khval_t) \
- __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal)
+ __KHASH_TYPE(name, khkey_t, khval_t) \
+ __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal)
#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
- KHASH_INIT2(name, static kh_inline, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal)
+ KHASH_INIT2(name, static kh_inline, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal)
-/* --- BEGIN OF HASH FUNCTIONS --- */
+// --- BEGIN OF HASH FUNCTIONS ---
/*! @function
- @abstract Integer hash function
- @param key The integer [khint32_t]
- @return The hash value [khint_t]
+ @abstract Integer hash function
+ @param key The integer [khint32_t]
+ @return The hash value [khint_t]
*/
#define kh_int_hash_func(key) (khint32_t)(key)
/*! @function
- @abstract Integer comparison function
+ @abstract Integer comparison function
*/
#define kh_int_hash_equal(a, b) ((a) == (b))
/*! @function
- @abstract 64-bit integer hash function
- @param key The integer [khint64_t]
- @return The hash value [khint_t]
+ @abstract 64-bit integer hash function
+ @param key The integer [khint64_t]
+ @return The hash value [khint_t]
*/
#define kh_int64_hash_func(key) (khint32_t)((key)>>33^(key)^(key)<<11)
/*! @function
- @abstract 64-bit integer comparison function
+ @abstract 64-bit integer comparison function
*/
#define kh_int64_hash_equal(a, b) ((a) == (b))
/*! @function
- @abstract const char* hash function
- @param s Pointer to a null terminated string
- @return The hash value
+ @abstract const char* hash function
+ @param s Pointer to a null terminated string
+ @return The hash value
*/
static kh_inline khint_t __ac_X31_hash_string(const char *s)
{
- khint_t h = (khint_t)*s;
- if (h) for (++s ; *s; ++s) h = (h << 5) - h + (uint8_t)*s;
- return h;
+ khint_t h = (khint_t)*s;
+ if (h) {
+ for (++s ; *s; ++s) { h = (h << 5) - h + (uint8_t)*s; }
+ }
+ return h;
}
/*! @function
- @abstract Another interface to const char* hash function
- @param key Pointer to a null terminated string [const char*]
- @return The hash value [khint_t]
+ @abstract Another interface to const char* hash function
+ @param key Pointer to a null terminated string [const char*]
+ @return The hash value [khint_t]
*/
#define kh_str_hash_func(key) __ac_X31_hash_string(key)
/*! @function
- @abstract Const char* comparison function
+ @abstract Const char* comparison function
*/
#define kh_str_hash_equal(a, b) (strcmp(a, b) == 0)
static kh_inline khint_t __ac_Wang_hash(khint_t key)
{
- key += ~(key << 15);
- key ^= (key >> 10);
- key += (key << 3);
- key ^= (key >> 6);
- key += ~(key << 11);
- key ^= (key >> 16);
- return key;
+ key += ~(key << 15);
+ key ^= (key >> 10);
+ key += (key << 3);
+ key ^= (key >> 6);
+ key += ~(key << 11);
+ key ^= (key >> 16);
+ return key;
}
#define kh_int_hash_func2(k) __ac_Wang_hash((khint_t)key)
-/* --- END OF HASH FUNCTIONS --- */
+// --- END OF HASH FUNCTIONS ---
-/* Other convenient macros... */
+// Other convenient macros...
/*!
- @abstract Type of the hash table.
- @param name Name of the hash table [symbol]
+ @abstract Type of the hash table.
+ @param name Name of the hash table [symbol]
*/
#define khash_t(name) kh_##name##_t
/*! @function
- @abstract Initiate a hash table.
- @param name Name of the hash table [symbol]
- @return Pointer to the hash table [khash_t(name)*]
+ @abstract Initiate a hash table.
+ @param name Name of the hash table [symbol]
+ @return Pointer to the hash table [khash_t(name)*]
*/
#define kh_init(name) kh_init_##name()
/*! @function
- @abstract Destroy a hash table.
- @param name Name of the hash table [symbol]
- @param h Pointer to the hash table [khash_t(name)*]
+ @abstract Destroy a hash table.
+ @param name Name of the hash table [symbol]
+ @param h Pointer to the hash table [khash_t(name)*]
*/
#define kh_destroy(name, h) kh_destroy_##name(h)
/*! @function
- @abstract Free memory referenced directly inside a hash table.
- @param name Name of the hash table [symbol]
- @param h Pointer to the hash table [khash_t(name)*]
+ @abstract Free memory referenced directly inside a hash table.
+ @param name Name of the hash table [symbol]
+ @param h Pointer to the hash table [khash_t(name)*]
*/
#define kh_dealloc(name, h) kh_dealloc_##name(h)
/*! @function
- @abstract Reset a hash table without deallocating memory.
- @param name Name of the hash table [symbol]
- @param h Pointer to the hash table [khash_t(name)*]
+ @abstract Reset a hash table without deallocating memory.
+ @param name Name of the hash table [symbol]
+ @param h Pointer to the hash table [khash_t(name)*]
*/
#define kh_clear(name, h) kh_clear_##name(h)
/*! @function
- @abstract Resize a hash table.
- @param name Name of the hash table [symbol]
- @param h Pointer to the hash table [khash_t(name)*]
- @param s New size [khint_t]
+ @abstract Resize a hash table.
+ @param name Name of the hash table [symbol]
+ @param h Pointer to the hash table [khash_t(name)*]
+ @param s New size [khint_t]
*/
#define kh_resize(name, h, s) kh_resize_##name(h, s)
/*! @function
- @abstract Insert a key to the hash table.
- @param name Name of the hash table [symbol]
- @param h Pointer to the hash table [khash_t(name)*]
- @param k Key [type of keys]
- @param r Extra return code: -1 if the operation failed;
+ @abstract Insert a key to the hash table.
+ @param name Name of the hash table [symbol]
+ @param h Pointer to the hash table [khash_t(name)*]
+ @param k Key [type of keys]
+ @param r Extra return code: -1 if the operation failed;
0 if the key is present in the hash table;
1 if the bucket is empty (never used); 2 if the element in
the bucket has been deleted [int*]
- @return Iterator to the inserted element [khint_t]
+ @return Iterator to the inserted element [khint_t]
*/
#define kh_put(name, h, k, r) kh_put_##name(h, k, r)
/*! @function
- @abstract Retrieve a key from the hash table.
- @param name Name of the hash table [symbol]
- @param h Pointer to the hash table [khash_t(name)*]
- @param k Key [type of keys]
- @return Iterator to the found element, or kh_end(h) if the element is absent [khint_t]
+ @abstract Retrieve a key from the hash table.
+ @param name Name of the hash table [symbol]
+ @param h Pointer to the hash table [khash_t(name)*]
+ @param k Key [type of keys]
+ @return Iterator to the found element, or kh_end(h) if the element is absent [khint_t]
*/
#define kh_get(name, h, k) kh_get_##name(h, k)
/*! @function
- @abstract Remove a key from the hash table.
- @param name Name of the hash table [symbol]
- @param h Pointer to the hash table [khash_t(name)*]
- @param k Iterator to the element to be deleted [khint_t]
+ @abstract Remove a key from the hash table.
+ @param name Name of the hash table [symbol]
+ @param h Pointer to the hash table [khash_t(name)*]
+ @param k Iterator to the element to be deleted [khint_t]
*/
#define kh_del(name, h, k) kh_del_##name(h, k)
/*! @function
- @abstract Test whether a bucket contains data.
- @param h Pointer to the hash table [khash_t(name)*]
- @param x Iterator to the bucket [khint_t]
- @return 1 if containing data; 0 otherwise [int]
+ @abstract Test whether a bucket contains data.
+ @param h Pointer to the hash table [khash_t(name)*]
+ @param x Iterator to the bucket [khint_t]
+ @return 1 if containing data; 0 otherwise [int]
*/
#define kh_exist(h, x) (!__ac_iseither((h)->flags, (x)))
/*! @function
- @abstract Get key given an iterator
- @param h Pointer to the hash table [khash_t(name)*]
- @param x Iterator to the bucket [khint_t]
- @return Key [type of keys]
+ @abstract Get key given an iterator
+ @param h Pointer to the hash table [khash_t(name)*]
+ @param x Iterator to the bucket [khint_t]
+ @return Key [type of keys]
*/
#define kh_key(h, x) ((h)->keys[x])
/*! @function
- @abstract Get value given an iterator
- @param h Pointer to the hash table [khash_t(name)*]
- @param x Iterator to the bucket [khint_t]
- @return Value [type of values]
- @discussion For hash sets, calling this results in segfault.
+ @abstract Get value given an iterator
+ @param h Pointer to the hash table [khash_t(name)*]
+ @param x Iterator to the bucket [khint_t]
+ @return Value [type of values]
+ @discussion For hash sets, calling this results in segfault.
*/
#define kh_val(h, x) ((h)->vals[x])
/*! @function
- @abstract Alias of kh_val()
+ @abstract Alias of kh_val()
*/
#define kh_value(h, x) ((h)->vals[x])
/*! @function
- @abstract Get the start iterator
- @param h Pointer to the hash table [khash_t(name)*]
- @return The start iterator [khint_t]
+ @abstract Get the start iterator
+ @param h Pointer to the hash table [khash_t(name)*]
+ @return The start iterator [khint_t]
*/
#define kh_begin(h) (khint_t)(0)
/*! @function
- @abstract Get the end iterator
- @param h Pointer to the hash table [khash_t(name)*]
- @return The end iterator [khint_t]
+ @abstract Get the end iterator
+ @param h Pointer to the hash table [khash_t(name)*]
+ @return The end iterator [khint_t]
*/
#define kh_end(h) ((h)->n_buckets)
/*! @function
- @abstract Get the number of elements in the hash table
- @param h Pointer to the hash table [khash_t(name)*]
- @return Number of elements in the hash table [khint_t]
+ @abstract Get the number of elements in the hash table
+ @param h Pointer to the hash table [khash_t(name)*]
+ @return Number of elements in the hash table [khint_t]
*/
#define kh_size(h) ((h)->size)
/*! @function
- @abstract Get the number of buckets in the hash table
- @param h Pointer to the hash table [khash_t(name)*]
- @return Number of buckets in the hash table [khint_t]
+ @abstract Get the number of buckets in the hash table
+ @param h Pointer to the hash table [khash_t(name)*]
+ @return Number of buckets in the hash table [khint_t]
*/
#define kh_n_buckets(h) ((h)->n_buckets)
/*! @function
- @abstract Iterate over the entries in the hash table
- @param h Pointer to the hash table [khash_t(name)*]
- @param kvar Variable to which key will be assigned
- @param vvar Variable to which value will be assigned
- @param code Block of code to execute
+ @abstract Iterate over the entries in the hash table
+ @param h Pointer to the hash table [khash_t(name)*]
+ @param kvar Variable to which key will be assigned
+ @param vvar Variable to which value will be assigned
+ @param code Block of code to execute
*/
-#define kh_foreach(h, kvar, vvar, code) { khint_t __i; \
- for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \
- if (!kh_exist(h,__i)) continue; \
- (kvar) = kh_key(h,__i); \
- (vvar) = kh_val(h,__i); \
- code; \
- } }
+#define kh_foreach(h, kvar, vvar, code) { khint_t __i; \
+ for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \
+ if (!kh_exist(h, __i)) continue; \
+ (kvar) = kh_key(h, __i); \
+ (vvar) = kh_val(h, __i); \
+ code; \
+ } }
/*! @function
- @abstract Iterate over the values in the hash table
- @param h Pointer to the hash table [khash_t(name)*]
- @param vvar Variable to which value will be assigned
- @param code Block of code to execute
+ @abstract Iterate over the values in the hash table
+ @param h Pointer to the hash table [khash_t(name)*]
+ @param vvar Variable to which value will be assigned
+ @param code Block of code to execute
*/
-#define kh_foreach_value(h, vvar, code) { khint_t __i; \
- for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \
- if (!kh_exist(h,__i)) continue; \
- (vvar) = kh_val(h,__i); \
- code; \
- } }
+#define kh_foreach_value(h, vvar, code) { khint_t __i; \
+ for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \
+ if (!kh_exist(h, __i)) continue; \
+ (vvar) = kh_val(h, __i); \
+ code; \
+ } }
/*! @function
- @abstract Iterate over the keys in the hash table
- @param h Pointer to the hash table [khash_t(name)*]
- @param kvar Variable to which value will be assigned
- @param code Block of code to execute
+ @abstract Iterate over the keys in the hash table
+ @param h Pointer to the hash table [khash_t(name)*]
+ @param kvar Variable to which value will be assigned
+ @param code Block of code to execute
*/
#define kh_foreach_key(h, kvar, code) \
{ \
@@ -665,57 +666,57 @@ static kh_inline khint_t __ac_Wang_hash(khint_t key)
} \
}
-/* More conenient interfaces */
+// More conenient interfaces
/*! @function
- @abstract Instantiate a hash set containing integer keys
- @param name Name of the hash table [symbol]
+ @abstract Instantiate a hash set containing integer keys
+ @param name Name of the hash table [symbol]
*/
-#define KHASH_SET_INIT_INT(name) \
- KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal)
+#define KHASH_SET_INIT_INT(name) \
+ KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal)
/*! @function
- @abstract Instantiate a hash map containing integer keys
- @param name Name of the hash table [symbol]
- @param khval_t Type of values [type]
+ @abstract Instantiate a hash map containing integer keys
+ @param name Name of the hash table [symbol]
+ @param khval_t Type of values [type]
*/
-#define KHASH_MAP_INIT_INT(name, khval_t) \
- KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal)
+#define KHASH_MAP_INIT_INT(name, khval_t) \
+ KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal)
/*! @function
- @abstract Instantiate a hash map containing 64-bit integer keys
- @param name Name of the hash table [symbol]
+ @abstract Instantiate a hash map containing 64-bit integer keys
+ @param name Name of the hash table [symbol]
*/
-#define KHASH_SET_INIT_INT64(name) \
- KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal)
+#define KHASH_SET_INIT_INT64(name) \
+ KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal)
/*! @function
- @abstract Instantiate a hash map containing 64-bit integer keys
- @param name Name of the hash table [symbol]
- @param khval_t Type of values [type]
+ @abstract Instantiate a hash map containing 64-bit integer keys
+ @param name Name of the hash table [symbol]
+ @param khval_t Type of values [type]
*/
-#define KHASH_MAP_INIT_INT64(name, khval_t) \
- KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal)
+#define KHASH_MAP_INIT_INT64(name, khval_t) \
+ KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal)
typedef const char *kh_cstr_t;
/*! @function
- @abstract Instantiate a hash map containing const char* keys
- @param name Name of the hash table [symbol]
+ @abstract Instantiate a hash map containing const char* keys
+ @param name Name of the hash table [symbol]
*/
-#define KHASH_SET_INIT_STR(name) \
- KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal)
+#define KHASH_SET_INIT_STR(name) \
+ KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal)
/*! @function
- @abstract Instantiate a hash map containing const char* keys
- @param name Name of the hash table [symbol]
- @param khval_t Type of values [type]
+ @abstract Instantiate a hash map containing const char* keys
+ @param name Name of the hash table [symbol]
+ @param khval_t Type of values [type]
*/
#define KHASH_MAP_INIT_STR(name, khval_t) \
KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal)
/*! @function
- @abstract Return a literal for an empty hash table.
- @param name Name of the hash table [symbol]
+ @abstract Return a literal for an empty hash table.
+ @param name Name of the hash table [symbol]
*/
#define KHASH_EMPTY_TABLE(name) \
((kh_##name##_t) { \
diff --git a/src/nvim/lib/klist.h b/src/nvim/lib/klist.h
index b80f4be3c2..c8489e298b 100644
--- a/src/nvim/lib/klist.h
+++ b/src/nvim/lib/klist.h
@@ -21,50 +21,50 @@
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-*/
+ */
#ifndef _AC_KLIST_H
#define _AC_KLIST_H
-#include <stdlib.h>
#include <assert.h>
+#include <stdlib.h>
-#include "nvim/memory.h"
#include "nvim/func_attr.h"
+#include "nvim/memory.h"
#define KMEMPOOL_INIT(name, kmptype_t, kmpfree_f) \
- typedef struct { \
- size_t cnt, n, max; \
- kmptype_t **buf; \
- } kmp_##name##_t; \
- static inline kmp_##name##_t *kmp_init_##name(void) { \
- return xcalloc(1, sizeof(kmp_##name##_t)); \
+ typedef struct { \
+ size_t cnt, n, max; \
+ kmptype_t **buf; \
+ } kmp_##name##_t; \
+ static inline kmp_##name##_t *kmp_init_##name(void) { \
+ return xcalloc(1, sizeof(kmp_##name##_t)); \
+ } \
+ static inline void kmp_destroy_##name(kmp_##name##_t *mp) \
+ REAL_FATTR_UNUSED; \
+ static inline void kmp_destroy_##name(kmp_##name##_t *mp) { \
+ size_t k; \
+ for (k = 0; k < mp->n; k++) { \
+ kmpfree_f(mp->buf[k]); XFREE_CLEAR(mp->buf[k]); \
} \
- static inline void kmp_destroy_##name(kmp_##name##_t *mp) \
- REAL_FATTR_UNUSED; \
- static inline void kmp_destroy_##name(kmp_##name##_t *mp) { \
- size_t k; \
- for (k = 0; k < mp->n; k++) { \
- kmpfree_f(mp->buf[k]); XFREE_CLEAR(mp->buf[k]); \
- } \
- XFREE_CLEAR(mp->buf); XFREE_CLEAR(mp); \
+ XFREE_CLEAR(mp->buf); XFREE_CLEAR(mp); \
+ } \
+ static inline kmptype_t *kmp_alloc_##name(kmp_##name##_t *mp) { \
+ mp->cnt++; \
+ if (mp->n == 0) { \
+ return xcalloc(1, sizeof(kmptype_t)); \
} \
- static inline kmptype_t *kmp_alloc_##name(kmp_##name##_t *mp) { \
- mp->cnt++; \
- if (mp->n == 0) { \
- return xcalloc(1, sizeof(kmptype_t)); \
- } \
- return mp->buf[--mp->n]; \
+ return mp->buf[--mp->n]; \
+ } \
+ static inline void kmp_free_##name(kmp_##name##_t *mp, kmptype_t *p) { \
+ mp->cnt--; \
+ if (mp->n == mp->max) { \
+ mp->max = mp->max ? (mp->max << 1) : 16; \
+ mp->buf = xrealloc(mp->buf, sizeof(kmptype_t *) * mp->max); \
} \
- static inline void kmp_free_##name(kmp_##name##_t *mp, kmptype_t *p) { \
- mp->cnt--; \
- if (mp->n == mp->max) { \
- mp->max = mp->max ? (mp->max << 1) : 16; \
- mp->buf = xrealloc(mp->buf, sizeof(kmptype_t *) * mp->max); \
- } \
- mp->buf[mp->n++] = p; \
- }
+ mp->buf[mp->n++] = p; \
+ }
#define kmempool_t(name) kmp_##name##_t
#define kmp_init(name) kmp_init_##name()
@@ -73,55 +73,55 @@
#define kmp_free(name, mp, p) kmp_free_##name(mp, p)
#define KLIST_INIT(name, kltype_t, kmpfree_t) \
- struct __kl1_##name { \
- kltype_t data; \
- struct __kl1_##name *next; \
- }; \
- typedef struct __kl1_##name kl1_##name; \
- KMEMPOOL_INIT(name, kl1_##name, kmpfree_t) \
- typedef struct { \
- kl1_##name *head, *tail; \
- kmp_##name##_t *mp; \
- size_t size; \
- } kl_##name##_t; \
- static inline kl_##name##_t *kl_init_##name(void) { \
- kl_##name##_t *kl = xcalloc(1, sizeof(kl_##name##_t)); \
- kl->mp = kmp_init(name); \
- kl->head = kl->tail = kmp_alloc(name, kl->mp); \
- kl->head->next = 0; \
- return kl; \
- } \
- static inline void kl_destroy_##name(kl_##name##_t *kl) \
- REAL_FATTR_UNUSED; \
- static inline void kl_destroy_##name(kl_##name##_t *kl) { \
- kl1_##name *p; \
- for (p = kl->head; p != kl->tail; p = p->next) { \
- kmp_free(name, kl->mp, p); \
- } \
- kmp_free(name, kl->mp, p); \
- kmp_destroy(name, kl->mp); \
- XFREE_CLEAR(kl); \
+ struct __kl1_##name { \
+ kltype_t data; \
+ struct __kl1_##name *next; \
+ }; \
+ typedef struct __kl1_##name kl1_##name; \
+ KMEMPOOL_INIT(name, kl1_##name, kmpfree_t) \
+ typedef struct { \
+ kl1_##name *head, *tail; \
+ kmp_##name##_t *mp; \
+ size_t size; \
+ } kl_##name##_t; \
+ static inline kl_##name##_t *kl_init_##name(void) { \
+ kl_##name##_t *kl = xcalloc(1, sizeof(kl_##name##_t)); \
+ kl->mp = kmp_init(name); \
+ kl->head = kl->tail = kmp_alloc(name, kl->mp); \
+ kl->head->next = 0; \
+ return kl; \
+ } \
+ static inline void kl_destroy_##name(kl_##name##_t *kl) \
+ REAL_FATTR_UNUSED; \
+ static inline void kl_destroy_##name(kl_##name##_t *kl) { \
+ kl1_##name *p; \
+ for (p = kl->head; p != kl->tail; p = p->next) { \
+ kmp_free(name, kl->mp, p); \
} \
- static inline void kl_push_##name(kl_##name##_t *kl, kltype_t d) { \
- kl1_##name *q, *p = kmp_alloc(name, kl->mp); \
- q = kl->tail; p->next = 0; kl->tail->next = p; kl->tail = p; \
- kl->size++; \
- q->data = d; \
+ kmp_free(name, kl->mp, p); \
+ kmp_destroy(name, kl->mp); \
+ XFREE_CLEAR(kl); \
+ } \
+ static inline void kl_push_##name(kl_##name##_t *kl, kltype_t d) { \
+ kl1_##name *q, *p = kmp_alloc(name, kl->mp); \
+ q = kl->tail; p->next = 0; kl->tail->next = p; kl->tail = p; \
+ kl->size++; \
+ q->data = d; \
+ } \
+ static inline kltype_t kl_shift_at_##name(kl_##name##_t *kl, \
+ kl1_##name **n) { \
+ assert((*n)->next); \
+ kl1_##name *p; \
+ kl->size--; \
+ p = *n; \
+ *n = (*n)->next; \
+ if (p == kl->head) { \
+ kl->head = *n; \
} \
- static inline kltype_t kl_shift_at_##name(kl_##name##_t *kl, \
- kl1_##name **n) { \
- assert((*n)->next); \
- kl1_##name *p; \
- kl->size--; \
- p = *n; \
- *n = (*n)->next; \
- if (p == kl->head) { \
- kl->head = *n; \
- } \
- kltype_t d = p->data; \
- kmp_free(name, kl->mp, p); \
- return d; \
- }
+ kltype_t d = p->data; \
+ kmp_free(name, kl->mp, p); \
+ return d; \
+ }
#define kliter_t(name) kl1_##name
#define klist_t(name) kl_##name##_t
diff --git a/src/nvim/lib/kvec.h b/src/nvim/lib/kvec.h
index 5bd09930a3..eb2d9bbb77 100644
--- a/src/nvim/lib/kvec.h
+++ b/src/nvim/lib/kvec.h
@@ -44,25 +44,25 @@
#include "nvim/os/os_defs.h"
#define kv_roundup32(x) \
- ((--(x)), \
- ((x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16), \
- (++(x)))
+ ((--(x)), \
+ ((x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16), \
+ (++(x)))
#define KV_INITIAL_VALUE { .size = 0, .capacity = 0, .items = NULL }
#define kvec_t(type) \
- struct { \
- size_t size; \
- size_t capacity; \
- type *items; \
- }
+ struct { \
+ size_t size; \
+ size_t capacity; \
+ type *items; \
+ }
#define kv_init(v) ((v).size = (v).capacity = 0, (v).items = 0)
#define kv_destroy(v) \
- do { \
- xfree((v).items); \
- kv_init(v); \
- } while (0)
+ do { \
+ xfree((v).items); \
+ kv_init(v); \
+ } while (0)
#define kv_A(v, i) ((v).items[(i)])
#define kv_pop(v) ((v).items[--(v).size])
#define kv_size(v) ((v).size)
@@ -79,34 +79,34 @@
#define kv_drop(v, n) ((v).size -= (n))
#define kv_resize(v, s) \
- ((v).capacity = (s), \
- (v).items = xrealloc((v).items, sizeof((v).items[0]) * (v).capacity))
+ ((v).capacity = (s), \
+ (v).items = xrealloc((v).items, sizeof((v).items[0]) * (v).capacity))
#define kv_resize_full(v) \
- kv_resize(v, (v).capacity ? (v).capacity << 1 : 8)
+ kv_resize(v, (v).capacity ? (v).capacity << 1 : 8)
#define kv_copy(v1, v0) \
- do { \
- if ((v1).capacity < (v0).size) { \
- kv_resize(v1, (v0).size); \
- } \
- (v1).size = (v0).size; \
- memcpy((v1).items, (v0).items, sizeof((v1).items[0]) * (v0).size); \
- } while (0)
+ do { \
+ if ((v1).capacity < (v0).size) { \
+ kv_resize(v1, (v0).size); \
+ } \
+ (v1).size = (v0).size; \
+ memcpy((v1).items, (v0).items, sizeof((v1).items[0]) * (v0).size); \
+ } while (0)
#define kv_pushp(v) \
- ((((v).size == (v).capacity) ? (kv_resize_full(v), 0) : 0), \
- ((v).items + ((v).size++)))
+ ((((v).size == (v).capacity) ? (kv_resize_full(v), 0) : 0), \
+ ((v).items + ((v).size++)))
#define kv_push(v, x) \
- (*kv_pushp(v) = (x))
+ (*kv_pushp(v) = (x))
#define kv_a(v, i) \
- (*(((v).capacity <= (size_t) (i) \
+ (*(((v).capacity <= (size_t)(i) \
? ((v).capacity = (v).size = (i) + 1, \
kv_roundup32((v).capacity), \
kv_resize((v), (v).capacity), 0UL) \
- : ((v).size <= (size_t) (i) \
+ : ((v).size <= (size_t)(i) \
? (v).size = (i) + 1 \
: 0UL)), \
&(v).items[(i)]))
@@ -120,24 +120,23 @@
/// @param[in] type Type of vector elements.
/// @param[in] init_size Number of the elements in the initial array.
#define kvec_withinit_t(type, INIT_SIZE) \
- struct { \
- size_t size; \
- size_t capacity; \
- type *items; \
- type init_array[INIT_SIZE]; \
- }
+ struct { \
+ size_t size; \
+ size_t capacity; \
+ type *items; \
+ type init_array[INIT_SIZE]; \
+ }
/// Initialize vector with preallocated array
///
/// @param[out] v Vector to initialize.
#define kvi_init(v) \
- ((v).capacity = ARRAY_SIZE((v).init_array), \
- (v).size = 0, \
- (v).items = (v).init_array)
+ ((v).capacity = ARRAY_SIZE((v).init_array), \
+ (v).size = 0, \
+ (v).items = (v).init_array)
/// Move data to a new destination and free source
-static inline void *_memcpy_free(void *const restrict dest,
- void *const restrict src,
+static inline void *_memcpy_free(void *const restrict dest, void *const restrict src,
const size_t size)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_ALWAYS_INLINE
{
@@ -156,15 +155,15 @@ static inline void *_memcpy_free(void *const restrict dest,
/// @param[out] v Vector to resize.
/// @param[in] s New size.
#define kvi_resize(v, s) \
- ((v).capacity = ((s) > ARRAY_SIZE((v).init_array) \
+ ((v).capacity = ((s) > ARRAY_SIZE((v).init_array) \
? (s) \
: ARRAY_SIZE((v).init_array)), \
- (v).items = ((v).capacity == ARRAY_SIZE((v).init_array) \
+ (v).items = ((v).capacity == ARRAY_SIZE((v).init_array) \
? ((v).items == (v).init_array \
? (v).items \
: _memcpy_free((v).init_array, (v).items, \
(v).size * sizeof((v).items[0]))) \
- : ((v).items == (v).init_array \
+ : ((v).items == (v).init_array \
? memcpy(xmalloc((v).capacity * sizeof((v).items[0])), \
(v).items, \
(v).size * sizeof((v).items[0])) \
@@ -175,13 +174,13 @@ static inline void *_memcpy_free(void *const restrict dest,
///
/// @param[out] v Vector to resize.
#define kvi_resize_full(v) \
- /* ARRAY_SIZE((v).init_array) is the minimal capacity of this vector. */ \
- /* Thus when vector is full capacity may not be zero and it is safe */ \
- /* not to bother with checking whether (v).capacity is 0. But now */ \
- /* capacity is not guaranteed to have size that is a power of 2, it is */ \
- /* hard to fix this here and is not very necessary if users will use */ \
- /* 2^x initial array size. */ \
- kvi_resize(v, (v).capacity << 1)
+ /* ARRAY_SIZE((v).init_array) is the minimal capacity of this vector. */ \
+ /* Thus when vector is full capacity may not be zero and it is safe */ \
+ /* not to bother with checking whether (v).capacity is 0. But now */ \
+ /* capacity is not guaranteed to have size that is a power of 2, it is */ \
+ /* hard to fix this here and is not very necessary if users will use */ \
+ /* 2^x initial array size. */ \
+ kvi_resize(v, (v).capacity << 1)
/// Get location where to store new element to a vector with preallocated array
///
@@ -189,24 +188,24 @@ static inline void *_memcpy_free(void *const restrict dest,
///
/// @return Pointer to the place where new value should be stored.
#define kvi_pushp(v) \
- ((((v).size == (v).capacity) ? (kvi_resize_full(v), 0) : 0), \
- ((v).items + ((v).size++)))
+ ((((v).size == (v).capacity) ? (kvi_resize_full(v), 0) : 0), \
+ ((v).items + ((v).size++)))
/// Push value to a vector with preallocated array
///
/// @param[out] v Vector to push to.
/// @param[in] x Value to push.
#define kvi_push(v, x) \
- (*kvi_pushp(v) = (x))
+ (*kvi_pushp(v) = (x))
/// Free array of elements of a vector with preallocated array if needed
///
/// @param[out] v Vector to free.
#define kvi_destroy(v) \
- do { \
- if ((v).items != (v).init_array) { \
- XFREE_CLEAR((v).items); \
- } \
- } while (0)
+ do { \
+ if ((v).items != (v).init_array) { \
+ XFREE_CLEAR((v).items); \
+ } \
+ } while (0)
#endif // NVIM_LIB_KVEC_H
diff --git a/src/nvim/lib/queue.h b/src/nvim/lib/queue.h
index 452998a5a4..871f49c863 100644
--- a/src/nvim/lib/queue.h
+++ b/src/nvim/lib/queue.h
@@ -41,7 +41,7 @@ typedef struct _queue {
while((q) != (h)) { \
QUEUE *next = q->next; \
code \
- (q) = next; \
+ (q) = next; \
}
diff --git a/src/nvim/lib/ringbuf.h b/src/nvim/lib/ringbuf.h
index cb79eaf742..06f7830bd1 100644
--- a/src/nvim/lib/ringbuf.h
+++ b/src/nvim/lib/ringbuf.h
@@ -15,24 +15,29 @@
#ifndef NVIM_LIB_RINGBUF_H
#define NVIM_LIB_RINGBUF_H
-#include <stddef.h>
-#include <string.h>
#include <assert.h>
+#include <stddef.h>
#include <stdint.h>
+#include <string.h>
-#include "nvim/memory.h"
#include "nvim/func_attr.h"
+#include "nvim/memory.h"
#define _RINGBUF_LENGTH(rb) \
- ((rb)->first == NULL ? 0 \
- : ((rb)->next == (rb)->first) ? (size_t) ((rb)->buf_end - (rb)->buf) + 1 \
- : ((rb)->next > (rb)->first) ? (size_t) ((rb)->next - (rb)->first) \
- : (size_t) ((rb)->next - (rb)->buf + (rb)->buf_end - (rb)->first + 1))
+ ((rb)->first == NULL ? 0 \
+ : ((rb)->next == (rb)->first) ? (size_t)((rb)->buf_end - (rb)->buf) + 1 \
+ : ((rb)->next > \
+ (rb)->first) ? (size_t)((rb)->next - \
+ (rb)->first) \
+ : (size_t)((rb)->\
+ next - (rb)->buf + \
+ (rb)->buf_end - \
+ (rb)->first + 1))
#define _RINGBUF_NEXT(rb, var) \
- ((var) == (rb)->buf_end ? (rb)->buf : (var) + 1)
+ ((var) == (rb)->buf_end ? (rb)->buf : (var) + 1)
#define _RINGBUF_PREV(rb, var) \
- ((var) == (rb)->buf ? (rb)->buf_end : (var) - 1)
+ ((var) == (rb)->buf ? (rb)->buf_end : (var) - 1)
/// Iterate over all ringbuf values
///
@@ -40,11 +45,11 @@
/// @param RBType Type of the ring buffer element.
/// @param varname Variable name.
#define RINGBUF_FORALL(rb, RBType, varname) \
- size_t varname##_length_fa_ = _RINGBUF_LENGTH(rb); \
- for (RBType *varname = ((rb)->first == NULL ? (rb)->next : (rb)->first); \
- varname##_length_fa_; \
- (varname = _RINGBUF_NEXT(rb, varname)), \
- varname##_length_fa_--)
+ size_t varname##_length_fa_ = _RINGBUF_LENGTH(rb); \
+ for (RBType *varname = ((rb)->first == NULL ? (rb)->next : (rb)->first); \
+ varname##_length_fa_; \
+ (varname = _RINGBUF_NEXT(rb, varname)), \
+ varname##_length_fa_--)
/// Iterate over all ringbuf values, from end to the beginning
///
@@ -55,11 +60,11 @@
/// @param RBType Type of the ring buffer element.
/// @param varname Variable name.
#define RINGBUF_ITER_BACK(rb, RBType, varname) \
- size_t varname##_length_ib_ = _RINGBUF_LENGTH(rb); \
- for (varname = ((rb)->next == (rb)->buf ? (rb)->buf_end : (rb)->next - 1); \
- varname##_length_ib_; \
- (varname = _RINGBUF_PREV(rb, varname)), \
- varname##_length_ib_--)
+ size_t varname##_length_ib_ = _RINGBUF_LENGTH(rb); \
+ for (varname = ((rb)->next == (rb)->buf ? (rb)->buf_end : (rb)->next - 1); \
+ varname##_length_ib_; \
+ (varname = _RINGBUF_PREV(rb, varname)), \
+ varname##_length_ib_--)
/// Define a ring buffer structure
///
@@ -67,12 +72,12 @@
/// `{TypeName}RingBuffer`.
/// @param RBType Type of the single ring buffer element.
#define RINGBUF_TYPEDEF(TypeName, RBType) \
-typedef struct { \
- RBType *buf; \
- RBType *next; \
- RBType *first; \
- RBType *buf_end; \
-} TypeName##RingBuffer;
+ typedef struct { \
+ RBType *buf; \
+ RBType *next; \
+ RBType *first; \
+ RBType *buf_end; \
+ } TypeName##RingBuffer;
/// Dummy item free macros, for use in RINGBUF_INIT
///
@@ -92,13 +97,13 @@ typedef struct { \
/// @param varname Variable name.
/// @param rbsize Ring buffer size.
#define RINGBUF_STATIC(scope, TypeName, RBType, varname, rbsize) \
-static RBType _##varname##_buf[rbsize]; \
-scope TypeName##RingBuffer varname = { \
- .buf = _##varname##_buf, \
- .next = _##varname##_buf, \
- .first = NULL, \
- .buf_end = _##varname##_buf + rbsize - 1, \
-};
+ static RBType _##varname##_buf[rbsize]; \
+ scope TypeName##RingBuffer varname = { \
+ .buf = _##varname##_buf, \
+ .next = _##varname##_buf, \
+ .first = NULL, \
+ .buf_end = _##varname##_buf + rbsize - 1, \
+ };
/// Initialize a new ring buffer
///
@@ -112,195 +117,191 @@ scope TypeName##RingBuffer varname = { \
///
/// Intended function signature: `void *rbfree(RBType *)`;
#define RINGBUF_INIT(TypeName, funcprefix, RBType, rbfree) \
-static inline TypeName##RingBuffer funcprefix##_rb_new(const size_t size) \
+ static inline TypeName##RingBuffer funcprefix##_rb_new(const size_t size) \
REAL_FATTR_WARN_UNUSED_RESULT; \
-static inline TypeName##RingBuffer funcprefix##_rb_new(const size_t size) \
-{ \
- assert(size != 0); \
- RBType *buf = xmalloc(size * sizeof(RBType)); \
- return (TypeName##RingBuffer) { \
- .buf = buf, \
- .next = buf, \
- .first = NULL, \
- .buf_end = buf + size - 1, \
- }; \
-} \
+ static inline TypeName##RingBuffer funcprefix##_rb_new(const size_t size) \
+ { \
+ assert(size != 0); \
+ RBType *buf = xmalloc(size * sizeof(RBType)); \
+ return (TypeName##RingBuffer) { \
+ .buf = buf, \
+ .next = buf, \
+ .first = NULL, \
+ .buf_end = buf + size - 1, \
+ }; \
+ } \
\
-static inline void funcprefix##_rb_free(TypeName##RingBuffer *const rb) \
+ static inline void funcprefix##_rb_free(TypeName##RingBuffer *const rb) \
REAL_FATTR_UNUSED; \
-static inline void funcprefix##_rb_free(TypeName##RingBuffer *const rb) \
-{ \
- if (rb == NULL) { \
- return; \
- } \
- RINGBUF_FORALL(rb, RBType, rbitem) { \
- rbfree(rbitem); \
+ static inline void funcprefix##_rb_free(TypeName##RingBuffer *const rb) \
+ { \
+ if (rb == NULL) { \
+ return; \
+ } \
+ RINGBUF_FORALL(rb, RBType, rbitem) { \
+ rbfree(rbitem); \
+ } \
+ XFREE_CLEAR(rb->buf); \
} \
- XFREE_CLEAR(rb->buf); \
-} \
\
-static inline void funcprefix##_rb_dealloc(TypeName##RingBuffer *const rb) \
+ static inline void funcprefix##_rb_dealloc(TypeName##RingBuffer *const rb) \
REAL_FATTR_UNUSED; \
-static inline void funcprefix##_rb_dealloc(TypeName##RingBuffer *const rb) \
-{ \
- XFREE_CLEAR(rb->buf); \
-} \
+ static inline void funcprefix##_rb_dealloc(TypeName##RingBuffer *const rb) \
+ { \
+ XFREE_CLEAR(rb->buf); \
+ } \
\
-static inline void funcprefix##_rb_push(TypeName##RingBuffer *const rb, \
- RBType item) \
+ static inline void funcprefix##_rb_push(TypeName##RingBuffer *const rb, \
+ RBType item) \
REAL_FATTR_NONNULL_ARG(1); \
-static inline void funcprefix##_rb_push(TypeName##RingBuffer *const rb, \
- RBType item) \
-{ \
- if (rb->next == rb->first) { \
- rbfree(rb->first); \
- rb->first = _RINGBUF_NEXT(rb, rb->first); \
- } else if (rb->first == NULL) { \
- rb->first = rb->next; \
+ static inline void funcprefix##_rb_push(TypeName##RingBuffer *const rb, \
+ RBType item) \
+ { \
+ if (rb->next == rb->first) { \
+ rbfree(rb->first); \
+ rb->first = _RINGBUF_NEXT(rb, rb->first); \
+ } else if (rb->first == NULL) { \
+ rb->first = rb->next; \
+ } \
+ *rb->next = item; \
+ rb->next = _RINGBUF_NEXT(rb, rb->next); \
} \
- *rb->next = item; \
- rb->next = _RINGBUF_NEXT(rb, rb->next); \
-} \
\
-static inline ptrdiff_t funcprefix##_rb_find_idx( \
- const TypeName##RingBuffer *const rb, const RBType *const item_p) \
+ static inline ptrdiff_t funcprefix##_rb_find_idx(const TypeName##RingBuffer *const rb, \
+ const RBType *const item_p) \
REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE REAL_FATTR_UNUSED; \
-static inline ptrdiff_t funcprefix##_rb_find_idx( \
- const TypeName##RingBuffer *const rb, const RBType *const item_p) \
-{ \
- assert(rb->buf <= item_p); \
- assert(rb->buf_end >= item_p); \
- if (rb->first == NULL) { \
- return -1; \
- } else if (item_p >= rb->first) { \
- return item_p - rb->first; \
- } else { \
- return item_p - rb->buf + rb->buf_end - rb->first + 1; \
+ static inline ptrdiff_t funcprefix##_rb_find_idx(const TypeName##RingBuffer *const rb, \
+ const RBType *const item_p) \
+ { \
+ assert(rb->buf <= item_p); \
+ assert(rb->buf_end >= item_p); \
+ if (rb->first == NULL) { \
+ return -1; \
+ } else if (item_p >= rb->first) { \
+ return item_p - rb->first; \
+ } else { \
+ return item_p - rb->buf + rb->buf_end - rb->first + 1; \
+ } \
} \
-} \
\
-static inline size_t funcprefix##_rb_size( \
- const TypeName##RingBuffer *const rb) \
+ static inline size_t funcprefix##_rb_size(const TypeName##RingBuffer *const rb) \
REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE; \
-static inline size_t funcprefix##_rb_size( \
- const TypeName##RingBuffer *const rb) \
-{ \
- return (size_t) (rb->buf_end - rb->buf) + 1; \
-} \
+ static inline size_t funcprefix##_rb_size(const TypeName##RingBuffer *const rb) \
+ { \
+ return (size_t)(rb->buf_end - rb->buf) + 1; \
+ } \
\
-static inline size_t funcprefix##_rb_length( \
- const TypeName##RingBuffer *const rb) \
+ static inline size_t funcprefix##_rb_length(const TypeName##RingBuffer *const rb) \
REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE; \
-static inline size_t funcprefix##_rb_length( \
- const TypeName##RingBuffer *const rb) \
-{ \
- return _RINGBUF_LENGTH(rb); \
-} \
+ static inline size_t funcprefix##_rb_length(const TypeName##RingBuffer *const rb) \
+ { \
+ return _RINGBUF_LENGTH(rb); \
+ } \
\
-static inline RBType *funcprefix##_rb_idx_p( \
- const TypeName##RingBuffer *const rb, const size_t idx) \
+ static inline RBType *funcprefix##_rb_idx_p(const TypeName##RingBuffer *const rb, \
+ const size_t idx) \
REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE; \
-static inline RBType *funcprefix##_rb_idx_p( \
- const TypeName##RingBuffer *const rb, const size_t idx) \
-{ \
- assert(idx <= funcprefix##_rb_size(rb)); \
- assert(idx <= funcprefix##_rb_length(rb)); \
- if (rb->first + idx > rb->buf_end) { \
- return rb->buf + ((rb->first + idx) - (rb->buf_end + 1)); \
- } else { \
- return rb->first + idx; \
+ static inline RBType *funcprefix##_rb_idx_p(const TypeName##RingBuffer *const rb, \
+ const size_t idx) \
+ { \
+ assert(idx <= funcprefix##_rb_size(rb)); \
+ assert(idx <= funcprefix##_rb_length(rb)); \
+ if (rb->first + idx > rb->buf_end) { \
+ return rb->buf + ((rb->first + idx) - (rb->buf_end + 1)); \
+ } else { \
+ return rb->first + idx; \
+ } \
} \
-} \
\
-static inline RBType funcprefix##_rb_idx(const TypeName##RingBuffer *const rb, \
- const size_t idx) \
+ static inline RBType funcprefix##_rb_idx(const TypeName##RingBuffer *const rb, \
+ const size_t idx) \
REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE REAL_FATTR_UNUSED; \
-static inline RBType funcprefix##_rb_idx(const TypeName##RingBuffer *const rb, \
- const size_t idx) \
-{ \
- return *funcprefix##_rb_idx_p(rb, idx); \
-} \
-\
-static inline void funcprefix##_rb_insert(TypeName##RingBuffer *const rb, \
- const size_t idx, \
- RBType item) \
- REAL_FATTR_NONNULL_ARG(1) REAL_FATTR_UNUSED; \
-static inline void funcprefix##_rb_insert(TypeName##RingBuffer *const rb, \
- const size_t idx, \
- RBType item) \
-{ \
- assert(idx <= funcprefix##_rb_size(rb)); \
- assert(idx <= funcprefix##_rb_length(rb)); \
- const size_t length = funcprefix##_rb_length(rb); \
- if (idx == length) { \
- funcprefix##_rb_push(rb, item); \
- return; \
- } \
- RBType *const insertpos = funcprefix##_rb_idx_p(rb, idx); \
- if (insertpos == rb->next) { \
- funcprefix##_rb_push(rb, item); \
- return; \
- } \
- if (length == funcprefix##_rb_size(rb)) { \
- rbfree(rb->first); \
+ static inline RBType funcprefix##_rb_idx(const TypeName##RingBuffer *const rb, \
+ const size_t idx) \
+ { \
+ return *funcprefix##_rb_idx_p(rb, idx); \
} \
- if (insertpos < rb->next) { \
- memmove(insertpos + 1, insertpos, \
- (size_t) ((uintptr_t) rb->next - (uintptr_t) insertpos)); \
- } else { \
- assert(insertpos > rb->first); \
- assert(rb->next <= rb->first); \
- memmove(rb->buf + 1, rb->buf, \
- (size_t) ((uintptr_t) rb->next - (uintptr_t) rb->buf)); \
- *rb->buf = *rb->buf_end; \
- memmove(insertpos + 1, insertpos, \
- (size_t) ((uintptr_t) (rb->buf_end + 1) - (uintptr_t) insertpos)); \
- } \
- *insertpos = item; \
- if (length == funcprefix##_rb_size(rb)) { \
- rb->first = _RINGBUF_NEXT(rb, rb->first); \
- } \
- rb->next = _RINGBUF_NEXT(rb, rb->next); \
-} \
\
-static inline void funcprefix##_rb_remove(TypeName##RingBuffer *const rb, \
- const size_t idx) \
+ static inline void funcprefix##_rb_insert(TypeName##RingBuffer *const rb, \
+ const size_t idx, \
+ RBType item) \
REAL_FATTR_NONNULL_ARG(1) REAL_FATTR_UNUSED; \
-static inline void funcprefix##_rb_remove(TypeName##RingBuffer *const rb, \
- const size_t idx) \
-{ \
- assert(idx < funcprefix##_rb_size(rb)); \
- assert(idx < funcprefix##_rb_length(rb)); \
- RBType *const rmpos = funcprefix##_rb_idx_p(rb, idx); \
- rbfree(rmpos); \
- if (rmpos == rb->next - 1) { \
- rb->next--; \
- if (rb->first == rb->next) { \
- rb->first = NULL; \
- rb->next = rb->buf; \
+ static inline void funcprefix##_rb_insert(TypeName##RingBuffer *const rb, \
+ const size_t idx, \
+ RBType item) \
+ { \
+ assert(idx <= funcprefix##_rb_size(rb)); \
+ assert(idx <= funcprefix##_rb_length(rb)); \
+ const size_t length = funcprefix##_rb_length(rb); \
+ if (idx == length) { \
+ funcprefix##_rb_push(rb, item); \
+ return; \
+ } \
+ RBType *const insertpos = funcprefix##_rb_idx_p(rb, idx); \
+ if (insertpos == rb->next) { \
+ funcprefix##_rb_push(rb, item); \
+ return; \
+ } \
+ if (length == funcprefix##_rb_size(rb)) { \
+ rbfree(rb->first); \
} \
- } else if (rmpos == rb->first) { \
- rb->first = _RINGBUF_NEXT(rb, rb->first); \
- if (rb->first == rb->next) { \
- rb->first = NULL; \
- rb->next = rb->buf; \
+ if (insertpos < rb->next) { \
+ memmove(insertpos + 1, insertpos, \
+ (size_t)((uintptr_t)rb->next - (uintptr_t)insertpos)); \
+ } else { \
+ assert(insertpos > rb->first); \
+ assert(rb->next <= rb->first); \
+ memmove(rb->buf + 1, rb->buf, \
+ (size_t)((uintptr_t)rb->next - (uintptr_t)rb->buf)); \
+ *rb->buf = *rb->buf_end; \
+ memmove(insertpos + 1, insertpos, \
+ (size_t)((uintptr_t)(rb->buf_end + 1) - (uintptr_t)insertpos)); \
} \
- } else if (rb->first < rb->next || rb->next == rb->buf) { \
- assert(rmpos > rb->first); \
- assert(rmpos <= _RINGBUF_PREV(rb, rb->next)); \
- memmove(rb->first + 1, rb->first, \
- (size_t) ((uintptr_t) rmpos - (uintptr_t) rb->first)); \
- rb->first = _RINGBUF_NEXT(rb, rb->first); \
- } else if (rmpos < rb->next) { \
- memmove(rmpos, rmpos + 1, \
- (size_t) ((uintptr_t) rb->next - (uintptr_t) rmpos)); \
- rb->next = _RINGBUF_PREV(rb, rb->next); \
- } else { \
- assert(rb->first < rb->buf_end); \
- memmove(rb->first + 1, rb->first, \
- (size_t) ((uintptr_t) rmpos - (uintptr_t) rb->first)); \
- rb->first = _RINGBUF_NEXT(rb, rb->first); \
+ *insertpos = item; \
+ if (length == funcprefix##_rb_size(rb)) { \
+ rb->first = _RINGBUF_NEXT(rb, rb->first); \
+ } \
+ rb->next = _RINGBUF_NEXT(rb, rb->next); \
} \
-}
+\
+ static inline void funcprefix##_rb_remove(TypeName##RingBuffer *const rb, \
+ const size_t idx) \
+ REAL_FATTR_NONNULL_ARG(1) REAL_FATTR_UNUSED; \
+ static inline void funcprefix##_rb_remove(TypeName##RingBuffer *const rb, \
+ const size_t idx) \
+ { \
+ assert(idx < funcprefix##_rb_size(rb)); \
+ assert(idx < funcprefix##_rb_length(rb)); \
+ RBType *const rmpos = funcprefix##_rb_idx_p(rb, idx); \
+ rbfree(rmpos); \
+ if (rmpos == rb->next - 1) { \
+ rb->next--; \
+ if (rb->first == rb->next) { \
+ rb->first = NULL; \
+ rb->next = rb->buf; \
+ } \
+ } else if (rmpos == rb->first) { \
+ rb->first = _RINGBUF_NEXT(rb, rb->first); \
+ if (rb->first == rb->next) { \
+ rb->first = NULL; \
+ rb->next = rb->buf; \
+ } \
+ } else if (rb->first < rb->next || rb->next == rb->buf) { \
+ assert(rmpos > rb->first); \
+ assert(rmpos <= _RINGBUF_PREV(rb, rb->next)); \
+ memmove(rb->first + 1, rb->first, \
+ (size_t)((uintptr_t)rmpos - (uintptr_t)rb->first)); \
+ rb->first = _RINGBUF_NEXT(rb, rb->first); \
+ } else if (rmpos < rb->next) { \
+ memmove(rmpos, rmpos + 1, \
+ (size_t)((uintptr_t)rb->next - (uintptr_t)rmpos)); \
+ rb->next = _RINGBUF_PREV(rb, rb->next); \
+ } else { \
+ assert(rb->first < rb->buf_end); \
+ memmove(rb->first + 1, rb->first, \
+ (size_t)((uintptr_t)rmpos - (uintptr_t)rb->first)); \
+ rb->first = _RINGBUF_NEXT(rb, rb->first); \
+ } \
+ }
#endif // NVIM_LIB_RINGBUF_H
diff --git a/src/nvim/log.c b/src/nvim/log.c
index 324382a0f7..5539e3d6c5 100644
--- a/src/nvim/log.c
+++ b/src/nvim/log.c
@@ -17,9 +17,9 @@
#include "auto/config.h"
#include "nvim/log.h"
-#include "nvim/types.h"
#include "nvim/os/os.h"
#include "nvim/os/time.h"
+#include "nvim/types.h"
#define LOG_FILE_ENV "NVIM_LOG_FILE"
@@ -124,8 +124,8 @@ void log_unlock(void)
/// @param line_num Source line number, or -1
/// @param eol Append linefeed "\n"
/// @param fmt printf-style format string
-bool logmsg(int log_level, const char *context, const char *func_name,
- int line_num, bool eol, const char *fmt, ...)
+bool logmsg(int log_level, const char *context, const char *func_name, int line_num, bool eol,
+ const char *fmt, ...)
FUNC_ATTR_UNUSED FUNC_ATTR_PRINTF(6, 7)
{
if (log_level < MIN_LOG_LEVEL) {
@@ -215,8 +215,7 @@ FILE *open_log_file(void)
}
#ifdef HAVE_EXECINFO_BACKTRACE
-void log_callstack_to_file(FILE *log_file, const char *const func_name,
- const int line_num)
+void log_callstack_to_file(FILE *log_file, const char *const func_name, const int line_num)
{
void *trace[100];
int trace_size = backtrace(trace, ARRAY_SIZE(trace));
@@ -268,8 +267,7 @@ end:
#endif
static bool do_log_to_file(FILE *log_file, int log_level, const char *context,
- const char *func_name, int line_num, bool eol,
- const char *fmt, ...)
+ const char *func_name, int line_num, bool eol, const char *fmt, ...)
FUNC_ATTR_PRINTF(7, 8)
{
va_list args;
@@ -281,9 +279,8 @@ static bool do_log_to_file(FILE *log_file, int log_level, const char *context,
return ret;
}
-static bool v_do_log_to_file(FILE *log_file, int log_level,
- const char *context, const char *func_name,
- int line_num, bool eol, const char *fmt,
+static bool v_do_log_to_file(FILE *log_file, int log_level, const char *context,
+ const char *func_name, int line_num, bool eol, const char *fmt,
va_list args)
{
static const char *log_levels[] = {
@@ -317,10 +314,10 @@ static bool v_do_log_to_file(FILE *log_file, int log_level,
? fprintf(log_file, "%s %s.%03d %-5" PRId64 " %s",
log_levels[log_level], date_time, millis, pid,
(context == NULL ? "?:" : context))
- : fprintf(log_file, "%s %s.%03d %-5" PRId64 " %s%s:%d: ",
- log_levels[log_level], date_time, millis, pid,
- (context == NULL ? "" : context),
- func_name, line_num);
+ : fprintf(log_file, "%s %s.%03d %-5" PRId64 " %s%s:%d: ",
+ log_levels[log_level], date_time, millis, pid,
+ (context == NULL ? "" : context),
+ func_name, line_num);
if (rv < 0) {
return false;
}
diff --git a/src/nvim/log.h b/src/nvim/log.h
index 654b682de8..81e39d1cdd 100644
--- a/src/nvim/log.h
+++ b/src/nvim/log.h
@@ -1,8 +1,8 @@
#ifndef NVIM_LOG_H
#define NVIM_LOG_H
-#include <stdio.h>
#include <stdbool.h>
+#include <stdio.h>
#include "auto/config.h"
#include "nvim/macros.h"
@@ -10,10 +10,10 @@
// USDT probes. Example invocation:
// NVIM_PROBE(nvim_foo_bar, 1, string.data);
#if defined(HAVE_SYS_SDT_H)
-#include <sys/sdt.h> // NOLINT
-#define NVIM_PROBE(name, n, ...) STAP_PROBE##n(neovim, name, __VA_ARGS__)
+# include <sys/sdt.h> // NOLINT
+# define NVIM_PROBE(name, n, ...) STAP_PROBE##n(neovim, name, __VA_ARGS__)
#else
-#define NVIM_PROBE(name, n, ...)
+# define NVIM_PROBE(name, n, ...)
#endif
@@ -33,7 +33,7 @@
#define ELOGN(...)
#ifndef MIN_LOG_LEVEL
-# define MIN_LOG_LEVEL INFO_LOG_LEVEL
+# define MIN_LOG_LEVEL INFO_LOG_LEVEL
#endif
#define LOG(level, ...) logmsg((level), NULL, __func__, __LINE__, true, \
diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c
index 07c53299fa..ca3c4f604a 100644
--- a/src/nvim/lua/converter.c
+++ b/src/nvim/lua/converter.c
@@ -755,7 +755,7 @@ void nlua_push_Array(lua_State *lstate, const Array array, bool special)
FUNC_ATTR_NONNULL_ALL \
{ \
lua_pushnumber(lstate, (lua_Number)(item)); \
-}
+ }
GENERATE_INDEX_FUNCTION(Buffer)
GENERATE_INDEX_FUNCTION(Window)
@@ -1126,9 +1126,9 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err)
size_t len;
const char *s = lua_tolstring(lstate, -1, &len);
*cur.obj = STRING_OBJ(((String) {
- .data = xmemdupz(s, len),
- .size = len,
- }));
+ .data = xmemdupz(s, len),
+ .size = len,
+ }));
break;
}
case LUA_TNUMBER: {
@@ -1147,10 +1147,10 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err)
switch (table_props.type) {
case kObjectTypeArray:
*cur.obj = ARRAY_OBJ(((Array) {
- .items = NULL,
- .size = 0,
- .capacity = 0,
- }));
+ .items = NULL,
+ .size = 0,
+ .capacity = 0,
+ }));
if (table_props.maxidx != 0) {
cur.obj->data.array.items =
xcalloc(table_props.maxidx,
@@ -1162,10 +1162,10 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err)
break;
case kObjectTypeDictionary:
*cur.obj = DICTIONARY_OBJ(((Dictionary) {
- .items = NULL,
- .size = 0,
- .capacity = 0,
- }));
+ .items = NULL,
+ .size = 0,
+ .capacity = 0,
+ }));
if (table_props.string_keys_num != 0) {
cur.obj->data.dictionary.items =
xcalloc(table_props.string_keys_num,
@@ -1299,3 +1299,31 @@ void nlua_init_types(lua_State *const lstate)
lua_rawset(lstate, -3);
}
+
+
+void nlua_pop_keydict(lua_State *L, void *retval, field_hash hashy, Error *err)
+{
+ if (!lua_istable(L, -1)) {
+ api_set_error(err, kErrorTypeValidation, "Expected lua table");
+ lua_pop(L, -1);
+ return;
+ }
+
+ lua_pushnil(L); // [dict, nil]
+ while (lua_next(L, -2)) {
+ // [dict, key, value]
+ size_t len;
+ const char *s = lua_tolstring(L, -2, &len);
+ Object *field = hashy(retval, s, len);
+ if (!field) {
+ api_set_error(err, kErrorTypeValidation, "invalid key: %.*s", (int)len, s);
+ lua_pop(L, 3); // []
+ return;
+ }
+
+ *field = nlua_pop_Object(L, true, err);
+ }
+ // [dict]
+ lua_pop(L, 1);
+ // []
+}
diff --git a/src/nvim/lua/converter.h b/src/nvim/lua/converter.h
index 43a7e06019..1c9e60e4b2 100644
--- a/src/nvim/lua/converter.h
+++ b/src/nvim/lua/converter.h
@@ -6,8 +6,8 @@
#include <stdint.h>
#include "nvim/api/private/defs.h"
-#include "nvim/func_attr.h"
#include "nvim/eval.h"
+#include "nvim/func_attr.h"
typedef struct {
LuaRef func_ref;
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 8c7dc90111..59ebafd9c8 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -5,6 +5,7 @@
#include <lua.h>
#include <lualib.h>
+#include "cjson/lua_cjson.h"
#include "luv/luv.h"
#include "mpack/lmpack.h"
#include "nvim/api/private/defs.h"
@@ -531,6 +532,9 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
lua_pushcfunction(lstate, &nlua_xdl_diff);
lua_setfield(lstate, -2, "diff");
+ lua_cjson_new(lstate);
+ lua_setfield(lstate, -2, "json");
+
lua_setglobal(lstate, "vim");
{
@@ -786,7 +790,7 @@ int nlua_call(lua_State *lstate)
Error err = ERROR_INIT;
size_t name_len;
const char_u *name = (const char_u *)luaL_checklstring(lstate, 1, &name_len);
- if (!nlua_is_deferred_safe(lstate)) {
+ if (!nlua_is_deferred_safe()) {
return luaL_error(lstate, e_luv_api_disabled, "vimL function");
}
@@ -842,7 +846,7 @@ free_vim_args:
static int nlua_rpcrequest(lua_State *lstate)
{
- if (!nlua_is_deferred_safe(lstate)) {
+ if (!nlua_is_deferred_safe()) {
return luaL_error(lstate, e_luv_api_disabled, "rpcrequest");
}
return nlua_rpc(lstate, true);
@@ -1312,7 +1316,7 @@ Object nlua_call_ref(LuaRef ref, const char *name, Array args, bool retval, Erro
/// check if the current execution context is safe for calling deferred API
/// methods. Luv callbacks are unsafe as they are called inside the uv loop.
-bool nlua_is_deferred_safe(lua_State *lstate)
+bool nlua_is_deferred_safe(void)
{
return in_fast_callback == 0;
}
diff --git a/src/nvim/lua/executor.h b/src/nvim/lua/executor.h
index ea774ac2e3..a1f66bd02b 100644
--- a/src/nvim/lua/executor.h
+++ b/src/nvim/lua/executor.h
@@ -1,13 +1,13 @@
#ifndef NVIM_LUA_EXECUTOR_H
#define NVIM_LUA_EXECUTOR_H
-#include <lua.h>
#include <lauxlib.h>
+#include <lua.h>
#include "nvim/api/private/defs.h"
-#include "nvim/func_attr.h"
#include "nvim/eval/typval.h"
#include "nvim/ex_cmds_defs.h"
+#include "nvim/func_attr.h"
#include "nvim/lua/converter.h"
// Generated by msgpack-gen.lua
@@ -19,12 +19,12 @@ EXTERN LuaRef nlua_empty_dict_ref INIT(= LUA_NOREF);
EXTERN int nlua_refcount INIT(= 0);
#define set_api_error(s, err) \
- do { \
- Error *err_ = (err); \
- err_->type = kErrorTypeException; \
- err_->set = true; \
- memcpy(&err_->msg[0], s, sizeof(s)); \
- } while (0)
+ do { \
+ Error *err_ = (err); \
+ err_->type = kErrorTypeException; \
+ err_->set = true; \
+ memcpy(&err_->msg[0], s, sizeof(s)); \
+ } while (0)
#define NLUA_CLEAR_REF(x) \
do { \
diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c
index e19274ced9..02bd612149 100644
--- a/src/nvim/lua/treesitter.c
+++ b/src/nvim/lua/treesitter.c
@@ -30,6 +30,7 @@
typedef struct {
TSQueryCursor *cursor;
int predicated_match;
+ int max_match_id;
} TSLua_cursor;
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -260,7 +261,7 @@ int tslua_push_parser(lua_State *L)
return 1;
}
-static TSParser ** parser_check(lua_State *L, uint16_t index)
+static TSParser **parser_check(lua_State *L, uint16_t index)
{
return luaL_checkudata(L, index, TS_META_PARSER);
}
@@ -933,7 +934,7 @@ push:
ts_tree_cursor_current_node(ud),
lua_upvalueindex(2)); // [node]
- const char * field = ts_tree_cursor_current_field_name(ud);
+ const char *field = ts_tree_cursor_current_field_name(ud);
if (field != NULL) {
lua_pushstring(L, ts_tree_cursor_current_field_name(ud));
@@ -1055,6 +1056,8 @@ static int query_next_match(lua_State *L)
static int query_next_capture(lua_State *L)
{
+ // Upvalues are:
+ // [ cursor, node, query, current_match ]
TSLua_cursor *ud = lua_touserdata(L, lua_upvalueindex(1));
TSQueryCursor *cursor = ud->cursor;
@@ -1078,9 +1081,13 @@ static int query_next_capture(lua_State *L)
lua_pushinteger(L, capture.index+1); // [index]
push_node(L, capture.node, lua_upvalueindex(2)); // [index, node]
+ // Now check if we need to run the predicates
uint32_t n_pred;
ts_query_predicates_for_pattern(query, match.pattern_index, &n_pred);
- if (n_pred > 0 && capture_index == 0) {
+
+ if (n_pred > 0 && (ud->max_match_id < (int)match.id)) {
+ ud->max_match_id = match.id;
+
lua_pushvalue(L, lua_upvalueindex(4)); // [index, node, match]
set_match(L, &match, lua_upvalueindex(2));
lua_pushinteger(L, match.pattern_index+1);
@@ -1127,6 +1134,7 @@ static int node_rawquery(lua_State *L)
TSLua_cursor *ud = lua_newuserdata(L, sizeof(*ud)); // [udata]
ud->cursor = cursor;
ud->predicated_match = -1;
+ ud->max_match_id = -1;
lua_getfield(L, LUA_REGISTRYINDEX, TS_META_QUERYCURSOR);
lua_setmetatable(L, -2); // [udata]
diff --git a/src/nvim/lua/treesitter.h b/src/nvim/lua/treesitter.h
index 812166f67b..b69fb9dfae 100644
--- a/src/nvim/lua/treesitter.h
+++ b/src/nvim/lua/treesitter.h
@@ -1,9 +1,9 @@
#ifndef NVIM_LUA_TREESITTER_H
#define NVIM_LUA_TREESITTER_H
+#include <lauxlib.h>
#include <lua.h>
#include <lualib.h>
-#include <lauxlib.h>
#include "tree_sitter/api.h"
diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua
index ba124c41ad..30c7034209 100644
--- a/src/nvim/lua/vim.lua
+++ b/src/nvim/lua/vim.lua
@@ -57,28 +57,29 @@ end
function vim._load_package(name)
local basename = name:gsub('%.', '/')
local paths = {"lua/"..basename..".lua", "lua/"..basename.."/init.lua"}
- for _,path in ipairs(paths) do
- local found = vim.api.nvim_get_runtime_file(path, false)
- if #found > 0 then
- local f, err = loadfile(found[1])
- return f or error(err)
- end
+ local found = vim.api.nvim__get_runtime(paths, false, {is_lua=true})
+ if #found > 0 then
+ local f, err = loadfile(found[1])
+ return f or error(err)
end
+ local so_paths = {}
for _,trail in ipairs(vim._so_trails) do
local path = "lua"..trail:gsub('?', basename) -- so_trails contains a leading slash
- local found = vim.api.nvim_get_runtime_file(path, false)
- if #found > 0 then
- -- Making function name in Lua 5.1 (see src/loadlib.c:mkfuncname) is
- -- a) strip prefix up to and including the first dash, if any
- -- b) replace all dots by underscores
- -- c) prepend "luaopen_"
- -- So "foo-bar.baz" should result in "luaopen_bar_baz"
- local dash = name:find("-", 1, true)
- local modname = dash and name:sub(dash + 1) or name
- local f, err = package.loadlib(found[1], "luaopen_"..modname:gsub("%.", "_"))
- return f or error(err)
- end
+ table.insert(so_paths, path)
+ end
+
+ found = vim.api.nvim__get_runtime(so_paths, false, {is_lua=true})
+ if #found > 0 then
+ -- Making function name in Lua 5.1 (see src/loadlib.c:mkfuncname) is
+ -- a) strip prefix up to and including the first dash, if any
+ -- b) replace all dots by underscores
+ -- c) prepend "luaopen_"
+ -- So "foo-bar.baz" should result in "luaopen_bar_baz"
+ local dash = name:find("-", 1, true)
+ local modname = dash and name:sub(dash + 1) or name
+ local f, err = package.loadlib(found[1], "luaopen_"..modname:gsub("%.", "_"))
+ return f or error(err)
end
return nil
end
@@ -108,6 +109,9 @@ setmetatable(vim, {
elseif key == 'diagnostic' then
t.diagnostic = require('vim.diagnostic')
return t.diagnostic
+ elseif key == 'ui' then
+ t.ui = require('vim.ui')
+ return t.ui
end
end
})
@@ -319,22 +323,25 @@ end
do
local validate = vim.validate
- local function make_dict_accessor(scope)
+ local function make_dict_accessor(scope, handle)
validate {
scope = {scope, 's'};
}
local mt = {}
function mt:__newindex(k, v)
- return vim._setvar(scope, 0, k, v)
+ return vim._setvar(scope, handle or 0, k, v)
end
function mt:__index(k)
- return vim._getvar(scope, 0, k)
+ if handle == nil and type(k) == 'number' then
+ return make_dict_accessor(scope, k)
+ end
+ return vim._getvar(scope, handle or 0, k)
end
return setmetatable({}, mt)
end
- vim.g = make_dict_accessor('g')
- vim.v = make_dict_accessor('v')
+ vim.g = make_dict_accessor('g', false)
+ vim.v = make_dict_accessor('v', false)
vim.b = make_dict_accessor('b')
vim.w = make_dict_accessor('w')
vim.t = make_dict_accessor('t')
@@ -430,6 +437,7 @@ function vim.notify(msg, log_level, _opts)
end
+---@private
function vim.register_keystroke_callback()
error('vim.register_keystroke_callback is deprecated, instead use: vim.on_key')
end
diff --git a/src/nvim/lua/xdiff.c b/src/nvim/lua/xdiff.c
index dc2675a1fe..7eda9b6270 100644
--- a/src/nvim/lua/xdiff.c
+++ b/src/nvim/lua/xdiff.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <errno.h>
#include <lauxlib.h>
#include <lua.h>
@@ -50,8 +53,8 @@ static int write_string(void *priv, mmbuffer_t *mb, int nbuf)
static int hunk_locations_cb(long start_a, long count_a, long start_b, long count_b, void *cb_data)
{
// Mimic extra offsets done by xdiff, see:
- // src/nvim/xdiff/xemit.c:284
- // src/nvim/xdiff/xutils.c:(356,368)
+ // src/xdiff/xemit.c:284
+ // src/xdiff/xutils.c:(356,368)
if (count_a > 0) {
start_a += 1;
}
@@ -59,7 +62,7 @@ static int hunk_locations_cb(long start_a, long count_a, long start_b, long coun
start_b += 1;
}
- lua_State * lstate = (lua_State *)cb_data;
+ lua_State *lstate = (lua_State *)cb_data;
lua_createtable(lstate, 0, 0);
lua_pushinteger(lstate, start_a);
@@ -80,8 +83,8 @@ static int hunk_locations_cb(long start_a, long count_a, long start_b, long coun
static int call_on_hunk_cb(long start_a, long count_a, long start_b, long count_b, void *cb_data)
{
// Mimic extra offsets done by xdiff, see:
- // src/nvim/xdiff/xemit.c:284
- // src/nvim/xdiff/xutils.c:(356,368)
+ // src/xdiff/xemit.c:284
+ // src/xdiff/xutils.c:(356,368)
if (count_a > 0) {
start_a += 1;
}
@@ -90,7 +93,7 @@ static int call_on_hunk_cb(long start_a, long count_a, long start_b, long count_
}
hunkpriv_t *priv = (hunkpriv_t *)cb_data;
- lua_State * lstate = priv->lstate;
+ lua_State *lstate = priv->lstate;
Error *err = priv->err;
const int fidx = lua_gettop(lstate);
lua_pushvalue(lstate, fidx);
@@ -130,7 +133,7 @@ static mmfile_t get_string_arg(lua_State *lstate, int idx)
static bool check_xdiff_opt(ObjectType actType, ObjectType expType, const char *name, Error *err)
{
if (actType != expType) {
- const char * type_str =
+ const char *type_str =
expType == kObjectTypeString ? "string" :
expType == kObjectTypeInteger ? "integer" :
expType == kObjectTypeBoolean ? "boolean" :
@@ -262,8 +265,8 @@ int nlua_xdl_diff(lua_State *lstate)
Error err = ERROR_INIT;
xdemitconf_t cfg;
- xpparam_t params;
- xdemitcb_t ecb;
+ xpparam_t params;
+ xdemitcb_t ecb;
memset(&cfg, 0, sizeof(cfg));
memset(&params, 0, sizeof(params));
diff --git a/src/nvim/lua/xdiff.h b/src/nvim/lua/xdiff.h
index cae7c98e81..b172d2f922 100644
--- a/src/nvim/lua/xdiff.h
+++ b/src/nvim/lua/xdiff.h
@@ -1,9 +1,9 @@
#ifndef NVIM_LUA_XDIFF_H
#define NVIM_LUA_XDIFF_H
+#include <lauxlib.h>
#include <lua.h>
#include <lualib.h>
-#include <lauxlib.h>
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "lua/xdiff.h.generated.h"
diff --git a/src/nvim/macros.h b/src/nvim/macros.h
index e1aa1b7704..50ee91dc36 100644
--- a/src/nvim/macros.h
+++ b/src/nvim/macros.h
@@ -43,15 +43,15 @@
#define TOLOWER_LOC tolower
// toupper() and tolower() for ASCII only and ignore the current locale.
-# define TOUPPER_ASC(c) (((c) < 'a' || (c) > 'z') ? (c) : (c) - ('a' - 'A'))
-# define TOLOWER_ASC(c) (((c) < 'A' || (c) > 'Z') ? (c) : (c) + ('a' - 'A'))
+#define TOUPPER_ASC(c) (((c) < 'a' || (c) > 'z') ? (c) : (c) - ('a' - 'A'))
+#define TOLOWER_ASC(c) (((c) < 'A' || (c) > 'Z') ? (c) : (c) + ('a' - 'A'))
// Like isalpha() but reject non-ASCII characters. Can't be used with a
// special key (negative value).
-# define ASCII_ISLOWER(c) ((unsigned)(c) >= 'a' && (unsigned)(c) <= 'z')
-# define ASCII_ISUPPER(c) ((unsigned)(c) >= 'A' && (unsigned)(c) <= 'Z')
-# define ASCII_ISALPHA(c) (ASCII_ISUPPER(c) || ASCII_ISLOWER(c))
-# define ASCII_ISALNUM(c) (ASCII_ISALPHA(c) || ascii_isdigit(c))
+#define ASCII_ISLOWER(c) ((unsigned)(c) >= 'a' && (unsigned)(c) <= 'z')
+#define ASCII_ISUPPER(c) ((unsigned)(c) >= 'A' && (unsigned)(c) <= 'Z')
+#define ASCII_ISALPHA(c) (ASCII_ISUPPER(c) || ASCII_ISLOWER(c))
+#define ASCII_ISALNUM(c) (ASCII_ISALPHA(c) || ascii_isdigit(c))
// Returns empty string if it is NULL.
#define EMPTY_IF_NULL(x) ((x) ? (x) : (char_u *)"")
@@ -62,7 +62,7 @@
// Don't apply 'langmap' if the character comes from the Stuff buffer or from a
// mapping and the langnoremap option was set.
// The do-while is just to ignore a ';' after the macro.
-# define LANGMAP_ADJUST(c, condition) \
+#define LANGMAP_ADJUST(c, condition) \
do { \
if (*p_langmap \
&& (condition) \
@@ -71,9 +71,9 @@
&& (c) >= 0) \
{ \
if ((c) < 256) \
- c = langmap_mapchar[c]; \
+ c = langmap_mapchar[c]; \
else \
- c = langmap_adjust_mb(c); \
+ c = langmap_adjust_mb(c); \
} \
} while (0)
@@ -90,9 +90,9 @@
# define mch_open_rw(n, f) os_open((n), (f), 0)
#endif
-# define REPLACE_NORMAL(s) (((s) & REPLACE_FLAG) && !((s) & VREPLACE_FLAG))
+#define REPLACE_NORMAL(s) (((s) & REPLACE_FLAG) && !((s) & VREPLACE_FLAG))
-# define UTF_COMPOSINGLIKE(p1, p2) utf_composinglike((p1), (p2))
+#define UTF_COMPOSINGLIKE(p1, p2) utf_composinglike((p1), (p2))
// MB_PTR_ADV(): advance a pointer to the next character, taking care of
// multi-byte characters if needed.
@@ -102,22 +102,22 @@
// PTR2CHAR(): get character from pointer.
// Advance multi-byte pointer, skip over composing chars.
-# define MB_PTR_ADV(p) (p += mb_ptr2len((char_u *)p))
+#define MB_PTR_ADV(p) (p += mb_ptr2len((char_u *)p))
// Advance multi-byte pointer, do not skip over composing chars.
-# define MB_CPTR_ADV(p) (p += utf_ptr2len(p))
+#define MB_CPTR_ADV(p) (p += utf_ptr2len(p))
// Backup multi-byte pointer. Only use with "p" > "s" !
-# define MB_PTR_BACK(s, p) \
- (p -= utf_head_off((char_u *)s, (char_u *)p - 1) + 1)
+#define MB_PTR_BACK(s, p) \
+ (p -= utf_head_off((char_u *)s, (char_u *)p - 1) + 1)
// get length of multi-byte char, not including composing chars
-# define MB_CPTR2LEN(p) utf_ptr2len(p)
+#define MB_CPTR2LEN(p) utf_ptr2len(p)
-# define MB_COPY_CHAR(f, t) mb_copy_char((const char_u **)(&f), &t);
+#define MB_COPY_CHAR(f, t) mb_copy_char((const char_u **)(&f), &t);
-# define MB_CHARLEN(p) mb_charlen(p)
-# define MB_CHAR2LEN(c) mb_char2len(c)
-# define PTR2CHAR(p) utf_ptr2char(p)
+#define MB_CHARLEN(p) mb_charlen(p)
+#define MB_CHAR2LEN(c) mb_char2len(c)
+#define PTR2CHAR(p) utf_ptr2char(p)
-# define RESET_BINDING(wp) \
+#define RESET_BINDING(wp) \
do { \
(wp)->w_p_scb = false; \
(wp)->w_p_crb = false; \
@@ -132,8 +132,8 @@
///
/// -V:ARRAY_SIZE:1063
#define ARRAY_SIZE(arr) \
- ((sizeof(arr)/sizeof((arr)[0])) \
- / ((size_t)(!(sizeof(arr) % sizeof((arr)[0])))))
+ ((sizeof(arr)/sizeof((arr)[0])) \
+ / ((size_t)(!(sizeof(arr) % sizeof((arr)[0])))))
/// Get last array entry
///
@@ -156,7 +156,7 @@
#ifndef __has_attribute
# define NVIM_HAS_ATTRIBUTE(x) 0
#elif defined(__clang__) && __clang__ == 1 \
- && (__clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ <= 5))
+ && (__clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ <= 5))
// Starting in Clang 3.6, __has_attribute was fixed to only report true for
// GNU-style attributes. Prior to that, it reported true if _any_ backend
// supported the attribute.
@@ -166,7 +166,7 @@
#endif
#if NVIM_HAS_ATTRIBUTE(fallthrough) \
- && (!defined(__apple_build_version__) || __apple_build_version__ >= 7000000)
+ && (!defined(__apple_build_version__) || __apple_build_version__ >= 7000000)
# define FALLTHROUGH {} __attribute__((fallthrough))
#else
# define FALLTHROUGH
@@ -204,29 +204,29 @@
///
#if defined(__clang__) && __clang__ == 1
# define PRAGMA_DIAG_PUSH_IGNORE_MISSING_PROTOTYPES \
- _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic push")\
_Pragma("clang diagnostic ignored \"-Wmissing-prototypes\"")
# ifdef HAVE_WIMPLICIT_FALLTHROUGH_FLAG
# define PRAGMA_DIAG_PUSH_IGNORE_IMPLICIT_FALLTHROUGH \
- _Pragma("clang diagnostic push") \
- _Pragma("clang diagnostic ignored \"-Wimplicit-fallthrough\"")
+ _Pragma("clang diagnostic push")\
+ _Pragma("clang diagnostic ignored \"-Wimplicit-fallthrough\"")
# else
# define PRAGMA_DIAG_PUSH_IGNORE_IMPLICIT_FALLTHROUGH \
- _Pragma("clang diagnostic push")
+ _Pragma("clang diagnostic push")
# endif
# define PRAGMA_DIAG_POP \
- _Pragma("clang diagnostic pop")
+ _Pragma("clang diagnostic pop")
#elif defined(__GNUC__)
# define PRAGMA_DIAG_PUSH_IGNORE_MISSING_PROTOTYPES \
- _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic push")\
_Pragma("GCC diagnostic ignored \"-Wmissing-prototypes\"")
# ifdef HAVE_WIMPLICIT_FALLTHROUGH_FLAG
# define PRAGMA_DIAG_PUSH_IGNORE_IMPLICIT_FALLTHROUGH \
- _Pragma("GCC diagnostic push") \
- _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
+ _Pragma("GCC diagnostic push")\
+ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
# else
# define PRAGMA_DIAG_PUSH_IGNORE_IMPLICIT_FALLTHROUGH \
- _Pragma("GCC diagnostic push")
+ _Pragma("GCC diagnostic push")
# endif
# define PRAGMA_DIAG_POP \
_Pragma("GCC diagnostic pop")
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 1507dfac00..00a43c9c79 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -3,25 +3,22 @@
#define EXTERN
#include <assert.h>
+#include <msgpack.h>
+#include <stdbool.h>
#include <stdint.h>
#include <string.h>
-#include <stdbool.h>
-
-#include <msgpack.h>
#include "nvim/ascii.h"
-#include "nvim/channel.h"
-#include "nvim/vim.h"
-#include "nvim/main.h"
#include "nvim/aucmd.h"
#include "nvim/buffer.h"
+#include "nvim/channel.h"
#include "nvim/charset.h"
+#include "nvim/decoration.h"
#include "nvim/diff.h"
#include "nvim/eval.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
-#include "nvim/decoration.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
#include "nvim/getchar.h"
@@ -30,29 +27,36 @@
#include "nvim/iconv.h"
#include "nvim/if_cscope.h"
#include "nvim/lua/executor.h"
+#include "nvim/main.h"
+#include "nvim/vim.h"
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
+#include "nvim/garray.h"
+#include "nvim/log.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
+#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/garray.h"
-#include "nvim/log.h"
-#include "nvim/memory.h"
-#include "nvim/move.h"
#include "nvim/mouse.h"
+#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/ops.h"
#include "nvim/option.h"
-#include "nvim/os_unix.h"
+#include "nvim/os/fileio.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
#include "nvim/os/os_defs.h"
+#include "nvim/os/time.h"
+#include "nvim/os_unix.h"
#include "nvim/path.h"
-#include "nvim/profile.h"
#include "nvim/popupmnu.h"
+#include "nvim/profile.h"
#include "nvim/quickfix.h"
#include "nvim/screen.h"
+#include "nvim/shada.h"
#include "nvim/sign.h"
#include "nvim/state.h"
#include "nvim/strings.h"
@@ -61,24 +65,19 @@
#include "nvim/ui_compositor.h"
#include "nvim/version.h"
#include "nvim/window.h"
-#include "nvim/shada.h"
-#include "nvim/os/input.h"
-#include "nvim/os/os.h"
-#include "nvim/os/time.h"
-#include "nvim/os/fileio.h"
#ifdef WIN32
# include "nvim/os/os_win_console.h"
#endif
+#include "nvim/api/private/defs.h"
+#include "nvim/api/private/dispatch.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/api/ui.h"
#include "nvim/event/loop.h"
-#include "nvim/os/signal.h"
#include "nvim/event/process.h"
+#include "nvim/msgpack_rpc/channel.h"
#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/msgpack_rpc/server.h"
-#include "nvim/msgpack_rpc/channel.h"
-#include "nvim/api/ui.h"
-#include "nvim/api/private/defs.h"
-#include "nvim/api/private/helpers.h"
-#include "nvim/api/private/dispatch.h"
+#include "nvim/os/signal.h"
#ifndef WIN32
# include "nvim/os/pty_process_unix.h"
#endif
@@ -278,9 +277,9 @@ int main(int argc, char **argv)
TIME_MSG("expanding arguments");
- if (params.diff_mode && params.window_count == -1)
- params.window_count = 0; /* open up to 3 windows */
-
+ if (params.diff_mode && params.window_count == -1) {
+ params.window_count = 0; // open up to 3 windows
+ }
// Don't redraw until much later.
RedrawingDisabled++;
@@ -346,7 +345,8 @@ int main(int argc, char **argv)
// Reset 'loadplugins' for "-u NONE" before "--cmd" arguments.
// Allows for setting 'loadplugins' there.
if (params.use_vimrc != NULL && strequal(params.use_vimrc, "NONE")) {
- p_lpl = false;
+ // When using --clean we still want to load plugins
+ p_lpl = params.clean;
}
// Execute --cmd arguments.
@@ -583,18 +583,19 @@ void getout(int exitval)
{
exiting = true;
- /* When running in Ex mode an error causes us to exit with a non-zero exit
- * code. POSIX requires this, although it's not 100% clear from the
- * standard. */
- if (exmode_active)
+ // When running in Ex mode an error causes us to exit with a non-zero exit
+ // code. POSIX requires this, although it's not 100% clear from the
+ // standard.
+ if (exmode_active) {
exitval += ex_exitval;
+ }
set_vim_var_nr(VV_EXITING, exitval);
// Position the cursor on the last screen line, below all the text
ui_cursor_goto(Rows - 1, 0);
- /* Optionally print hashtable efficiency. */
+ // Optionally print hashtable efficiency.
hash_debug_results();
if (v_dying <= 1) {
@@ -605,7 +606,7 @@ void getout(int exitval)
next_tp = tp->tp_next;
FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
if (wp->w_buffer == NULL) {
- /* Autocmd must have close the buffer already, skip. */
+ // Autocmd must have close the buffer already, skip.
continue;
}
@@ -626,7 +627,7 @@ void getout(int exitval)
}
}
- /* Trigger BufUnload for buffers that are loaded */
+ // Trigger BufUnload for buffers that are loaded
FOR_ALL_BUFFERS(buf) {
if (buf->b_ml.ml_mfp != NULL) {
bufref_T bufref;
@@ -674,8 +675,8 @@ void getout(int exitval)
profile_dump();
if (did_emsg
- ) {
- /* give the user a chance to read the (error) message */
+ ) {
+ // give the user a chance to read the (error) message
no_wait_return = FALSE;
wait_return(FALSE);
}
@@ -727,7 +728,7 @@ static void init_locale(void)
setlocale(LC_ALL, "");
# ifdef LC_NUMERIC
- /* Make sure strtod() uses a decimal point, not a comma. */
+ // Make sure strtod() uses a decimal point, not a comma.
setlocale(LC_NUMERIC, "C");
# endif
@@ -749,10 +750,10 @@ static void init_locale(void)
static bool edit_stdin(bool explicit, mparm_T *parmp)
{
bool implicit = !headless_mode
- && !embedded_mode
- && (!exmode_active || parmp->input_neverscript)
- && !parmp->input_isatty
- && scriptin[0] == NULL; // `-s -` was not given.
+ && !embedded_mode
+ && (!exmode_active || parmp->input_neverscript)
+ && !parmp->input_isatty
+ && scriptin[0] == NULL; // `-s -` was not given.
return explicit || implicit;
}
@@ -784,270 +785,242 @@ static void command_line_scan(mparm_T *parmp)
parmp->commands[parmp->n_commands++] = &(argv[0][1]);
}
- // Optional argument.
+ // Optional argument.
} else if (argv[0][0] == '-' && !had_minmin) {
want_argument = false;
c = argv[0][argv_idx++];
switch (c) {
- case NUL: { // "nvim -" read from stdin
- if (exmode_active) {
- // "nvim -e -" silent mode
- silent_mode = true;
- parmp->no_swap_file = true;
- } else {
- if (parmp->edit_type != EDIT_NONE
- && parmp->edit_type != EDIT_FILE
- && parmp->edit_type != EDIT_STDIN) {
- mainerr(err_too_many_args, argv[0]);
- }
- had_stdin_file = true;
- parmp->edit_type = EDIT_STDIN;
+ case NUL: // "nvim -" read from stdin
+ if (exmode_active) {
+ // "nvim -e -" silent mode
+ silent_mode = true;
+ parmp->no_swap_file = true;
+ } else {
+ if (parmp->edit_type != EDIT_NONE
+ && parmp->edit_type != EDIT_FILE
+ && parmp->edit_type != EDIT_STDIN) {
+ mainerr(err_too_many_args, argv[0]);
}
- argv_idx = -1; // skip to next argument
- break;
+ had_stdin_file = true;
+ parmp->edit_type = EDIT_STDIN;
}
- case '-': { // "--" don't take any more option arguments
- // "--help" give help message
- // "--version" give version message
- // "--noplugin[s]" skip plugins
- // "--cmd <cmd>" execute cmd before vimrc
- if (STRICMP(argv[0] + argv_idx, "help") == 0) {
- usage();
- os_exit(0);
- } else if (STRICMP(argv[0] + argv_idx, "version") == 0) {
- version();
- os_exit(0);
- } else if (STRICMP(argv[0] + argv_idx, "api-info") == 0) {
- FileDescriptor fp;
- const int fof_ret = file_open_fd(&fp, STDOUT_FILENO,
- kFileWriteOnly);
- msgpack_packer *p = msgpack_packer_new(&fp, msgpack_file_write);
-
- if (fof_ret != 0) {
- emsgf(_("E5421: Failed to open stdin: %s"), os_strerror(fof_ret));
- }
+ argv_idx = -1; // skip to next argument
+ break;
+ case '-': // "--" don't take any more option arguments
+ // "--help" give help message
+ // "--version" give version message
+ // "--noplugin[s]" skip plugins
+ // "--cmd <cmd>" execute cmd before vimrc
+ if (STRICMP(argv[0] + argv_idx, "help") == 0) {
+ usage();
+ os_exit(0);
+ } else if (STRICMP(argv[0] + argv_idx, "version") == 0) {
+ version();
+ os_exit(0);
+ } else if (STRICMP(argv[0] + argv_idx, "api-info") == 0) {
+ FileDescriptor fp;
+ const int fof_ret = file_open_fd(&fp, STDOUT_FILENO,
+ kFileWriteOnly);
+ msgpack_packer *p = msgpack_packer_new(&fp, msgpack_file_write);
+
+ if (fof_ret != 0) {
+ emsgf(_("E5421: Failed to open stdin: %s"), os_strerror(fof_ret));
+ }
- if (p == NULL) {
- EMSG(_(e_outofmem));
- }
+ if (p == NULL) {
+ EMSG(_(e_outofmem));
+ }
- Object md = DICTIONARY_OBJ(api_metadata());
- msgpack_rpc_from_object(md, p);
+ Object md = DICTIONARY_OBJ(api_metadata());
+ msgpack_rpc_from_object(md, p);
- msgpack_packer_free(p);
- const int ff_ret = file_flush(&fp);
- if (ff_ret < 0) {
- msgpack_file_write_error(ff_ret);
- }
- os_exit(0);
- } else if (STRICMP(argv[0] + argv_idx, "headless") == 0) {
- headless_mode = true;
- } else if (STRICMP(argv[0] + argv_idx, "embed") == 0) {
- embedded_mode = true;
- } else if (STRNICMP(argv[0] + argv_idx, "listen", 6) == 0) {
- want_argument = true;
- argv_idx += 6;
- } else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0) {
- // Do nothing: file args are always literal. #7679
- } else if (STRNICMP(argv[0] + argv_idx, "noplugin", 8) == 0) {
- p_lpl = false;
- } else if (STRNICMP(argv[0] + argv_idx, "cmd", 3) == 0) {
- want_argument = true;
- argv_idx += 3;
- } else if (STRNICMP(argv[0] + argv_idx, "startuptime", 11) == 0) {
- want_argument = true;
- argv_idx += 11;
- } else if (STRNICMP(argv[0] + argv_idx, "clean", 5) == 0) {
- parmp->use_vimrc = "NONE";
- parmp->clean = true;
- set_option_value("shadafile", 0L, "NONE", 0);
- } else {
- if (argv[0][argv_idx])
- mainerr(err_opt_unknown, argv[0]);
- had_minmin = true;
+ msgpack_packer_free(p);
+ const int ff_ret = file_flush(&fp);
+ if (ff_ret < 0) {
+ msgpack_file_write_error(ff_ret);
}
- if (!want_argument) {
- argv_idx = -1; // skip to next argument
+ os_exit(0);
+ } else if (STRICMP(argv[0] + argv_idx, "headless") == 0) {
+ headless_mode = true;
+ } else if (STRICMP(argv[0] + argv_idx, "embed") == 0) {
+ embedded_mode = true;
+ } else if (STRNICMP(argv[0] + argv_idx, "listen", 6) == 0) {
+ want_argument = true;
+ argv_idx += 6;
+ } else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0) {
+ // Do nothing: file args are always literal. #7679
+ } else if (STRNICMP(argv[0] + argv_idx, "noplugin", 8) == 0) {
+ p_lpl = false;
+ } else if (STRNICMP(argv[0] + argv_idx, "cmd", 3) == 0) {
+ want_argument = true;
+ argv_idx += 3;
+ } else if (STRNICMP(argv[0] + argv_idx, "startuptime", 11) == 0) {
+ want_argument = true;
+ argv_idx += 11;
+ } else if (STRNICMP(argv[0] + argv_idx, "clean", 5) == 0) {
+ parmp->use_vimrc = "NONE";
+ parmp->clean = true;
+ set_option_value("shadafile", 0L, "NONE", 0);
+ } else {
+ if (argv[0][argv_idx]) {
+ mainerr(err_opt_unknown, argv[0]);
}
- break;
+ had_minmin = true;
}
- case 'A': { // "-A" start in Arabic mode.
- set_option_value("arabic", 1L, NULL, 0);
- break;
- }
- case 'b': { // "-b" binary mode.
- // Needs to be effective before expanding file names, because
- // for Win32 this makes us edit a shortcut file itself,
- // instead of the file it links to.
- set_options_bin(curbuf->b_p_bin, 1, 0);
- curbuf->b_p_bin = 1; // Binary file I/O.
- break;
+ if (!want_argument) {
+ argv_idx = -1; // skip to next argument
}
+ break;
+ case 'A': // "-A" start in Arabic mode.
+ set_option_value("arabic", 1L, NULL, 0);
+ break;
+ case 'b': // "-b" binary mode.
+ // Needs to be effective before expanding file names, because
+ // for Win32 this makes us edit a shortcut file itself,
+ // instead of the file it links to.
+ set_options_bin(curbuf->b_p_bin, 1, 0);
+ curbuf->b_p_bin = 1; // Binary file I/O.
+ break;
- case 'D': { // "-D" Debugging
- parmp->use_debug_break_level = 9999;
- break;
- }
- case 'd': { // "-d" 'diff'
- parmp->diff_mode = true;
- break;
- }
- case 'e': { // "-e" Ex mode
- exmode_active = true;
- break;
- }
- case 'E': { // "-E" Ex mode
- exmode_active = true;
- parmp->input_neverscript = true;
- break;
- }
- case 'f': { // "-f" GUI: run in foreground.
- break;
- }
- case '?': // "-?" give help message (for MS-Windows)
- case 'h': { // "-h" give help message
- usage();
- os_exit(0);
- }
- case 'H': { // "-H" start in Hebrew mode: rl + hkmap set.
- p_hkmap = true;
- set_option_value("rl", 1L, NULL, 0);
- break;
- }
- case 'l': { // "-l" lisp mode, 'lisp' and 'showmatch' on.
- set_option_value("lisp", 1L, NULL, 0);
- p_sm = true;
- break;
- }
- case 'M': { // "-M" no changes or writing of files
- reset_modifiable();
- FALLTHROUGH;
- }
- case 'm': { // "-m" no writing of files
- p_write = false;
- break;
- }
+ case 'D': // "-D" Debugging
+ parmp->use_debug_break_level = 9999;
+ break;
+ case 'd': // "-d" 'diff'
+ parmp->diff_mode = true;
+ break;
+ case 'e': // "-e" Ex mode
+ exmode_active = true;
+ break;
+ case 'E': // "-E" Ex mode
+ exmode_active = true;
+ parmp->input_neverscript = true;
+ break;
+ case 'f': // "-f" GUI: run in foreground.
+ break;
+ case '?': // "-?" give help message (for MS-Windows)
+ case 'h': // "-h" give help message
+ usage();
+ os_exit(0);
+ case 'H': // "-H" start in Hebrew mode: rl + hkmap set.
+ p_hkmap = true;
+ set_option_value("rl", 1L, NULL, 0);
+ break;
+ case 'l': // "-l" lisp mode, 'lisp' and 'showmatch' on.
+ set_option_value("lisp", 1L, NULL, 0);
+ p_sm = true;
+ break;
+ case 'M': // "-M" no changes or writing of files
+ reset_modifiable();
+ FALLTHROUGH;
+ case 'm': // "-m" no writing of files
+ p_write = false;
+ break;
- case 'N': // "-N" Nocompatible
- case 'X': // "-X" Do not connect to X server
- // No-op
- break;
+ case 'N': // "-N" Nocompatible
+ case 'X': // "-X" Do not connect to X server
+ // No-op
+ break;
- case 'n': { // "-n" no swap file
- parmp->no_swap_file = true;
- break;
- }
- case 'p': { // "-p[N]" open N tab pages
- // default is 0: open window for each file
- parmp->window_count = get_number_arg(argv[0], &argv_idx, 0);
- parmp->window_layout = WIN_TABS;
- break;
- }
- case 'o': { // "-o[N]" open N horizontal split windows
- // default is 0: open window for each file
- parmp->window_count = get_number_arg(argv[0], &argv_idx, 0);
- parmp->window_layout = WIN_HOR;
- break;
- }
- case 'O': { // "-O[N]" open N vertical split windows
- // default is 0: open window for each file
- parmp->window_count = get_number_arg(argv[0], &argv_idx, 0);
- parmp->window_layout = WIN_VER;
- break;
- }
- case 'q': { // "-q" QuickFix mode
- if (parmp->edit_type != EDIT_NONE) {
- mainerr(err_too_many_args, argv[0]);
- }
- parmp->edit_type = EDIT_QF;
- if (argv[0][argv_idx]) { // "-q{errorfile}"
- parmp->use_ef = (char_u *)argv[0] + argv_idx;
- argv_idx = -1;
- } else if (argc > 1) { // "-q {errorfile}"
- want_argument = true;
- }
- break;
- }
- case 'R': { // "-R" readonly mode
- readonlymode = true;
- curbuf->b_p_ro = true;
- p_uc = 10000; // don't update very often
- break;
+ case 'n': // "-n" no swap file
+ parmp->no_swap_file = true;
+ break;
+ case 'p': // "-p[N]" open N tab pages
+ // default is 0: open window for each file
+ parmp->window_count = get_number_arg(argv[0], &argv_idx, 0);
+ parmp->window_layout = WIN_TABS;
+ break;
+ case 'o': // "-o[N]" open N horizontal split windows
+ // default is 0: open window for each file
+ parmp->window_count = get_number_arg(argv[0], &argv_idx, 0);
+ parmp->window_layout = WIN_HOR;
+ break;
+ case 'O': // "-O[N]" open N vertical split windows
+ // default is 0: open window for each file
+ parmp->window_count = get_number_arg(argv[0], &argv_idx, 0);
+ parmp->window_layout = WIN_VER;
+ break;
+ case 'q': // "-q" QuickFix mode
+ if (parmp->edit_type != EDIT_NONE) {
+ mainerr(err_too_many_args, argv[0]);
}
- case 'r': // "-r" recovery mode
- case 'L': { // "-L" recovery mode
- recoverymode = 1;
- break;
+ parmp->edit_type = EDIT_QF;
+ if (argv[0][argv_idx]) { // "-q{errorfile}"
+ parmp->use_ef = (char_u *)argv[0] + argv_idx;
+ argv_idx = -1;
+ } else if (argc > 1) { // "-q {errorfile}"
+ want_argument = true;
}
- case 's': {
- if (exmode_active) { // "-es" silent (batch) Ex-mode
- silent_mode = true;
- parmp->no_swap_file = true;
- } else { // "-s {scriptin}" read from script file
- want_argument = true;
- }
- break;
+ break;
+ case 'R': // "-R" readonly mode
+ readonlymode = true;
+ curbuf->b_p_ro = true;
+ p_uc = 10000; // don't update very often
+ break;
+ case 'r': // "-r" recovery mode
+ case 'L': // "-L" recovery mode
+ recoverymode = 1;
+ break;
+ case 's':
+ if (exmode_active) { // "-es" silent (batch) Ex-mode
+ silent_mode = true;
+ parmp->no_swap_file = true;
+ } else { // "-s {scriptin}" read from script file
+ want_argument = true;
}
- case 't': { // "-t {tag}" or "-t{tag}" jump to tag
- if (parmp->edit_type != EDIT_NONE) {
- mainerr(err_too_many_args, argv[0]);
- }
- parmp->edit_type = EDIT_TAG;
- if (argv[0][argv_idx]) { // "-t{tag}"
- parmp->tagname = (char_u *)argv[0] + argv_idx;
- argv_idx = -1;
- } else { // "-t {tag}"
- want_argument = true;
- }
- break;
+ break;
+ case 't': // "-t {tag}" or "-t{tag}" jump to tag
+ if (parmp->edit_type != EDIT_NONE) {
+ mainerr(err_too_many_args, argv[0]);
}
- case 'v': {
- version();
- os_exit(0);
+ parmp->edit_type = EDIT_TAG;
+ if (argv[0][argv_idx]) { // "-t{tag}"
+ parmp->tagname = (char_u *)argv[0] + argv_idx;
+ argv_idx = -1;
+ } else { // "-t {tag}"
+ want_argument = true;
}
- case 'V': { // "-V{N}" Verbose level
- // default is 10: a little bit verbose
- p_verbose = get_number_arg(argv[0], &argv_idx, 10);
- if (argv[0][argv_idx] != NUL) {
- set_option_value("verbosefile", 0L, argv[0] + argv_idx, 0);
- argv_idx = (int)STRLEN(argv[0]);
- }
- break;
+ break;
+ case 'v':
+ version();
+ os_exit(0);
+ case 'V': // "-V{N}" Verbose level
+ // default is 10: a little bit verbose
+ p_verbose = get_number_arg(argv[0], &argv_idx, 10);
+ if (argv[0][argv_idx] != NUL) {
+ set_option_value("verbosefile", 0L, argv[0] + argv_idx, 0);
+ argv_idx = (int)STRLEN(argv[0]);
}
- case 'w': { // "-w{number}" set window height
- // "-w {scriptout}" write to script
- if (ascii_isdigit(((char_u *)argv[0])[argv_idx])) {
- n = get_number_arg(argv[0], &argv_idx, 10);
- set_option_value("window", n, NULL, 0);
- break;
- }
- want_argument = true;
+ break;
+ case 'w': // "-w{number}" set window height
+ // "-w {scriptout}" write to script
+ if (ascii_isdigit(((char_u *)argv[0])[argv_idx])) {
+ n = get_number_arg(argv[0], &argv_idx, 10);
+ set_option_value("window", n, NULL, 0);
break;
}
+ want_argument = true;
+ break;
- case 'c': { // "-c{command}" or "-c {command}" exec command
- if (argv[0][argv_idx] != NUL) {
- if (parmp->n_commands >= MAX_ARG_CMDS) {
- mainerr(err_extra_cmd, NULL);
- }
- parmp->commands[parmp->n_commands++] = argv[0] + argv_idx;
- argv_idx = -1;
- break;
+ case 'c': // "-c{command}" or "-c {command}" exec command
+ if (argv[0][argv_idx] != NUL) {
+ if (parmp->n_commands >= MAX_ARG_CMDS) {
+ mainerr(err_extra_cmd, NULL);
}
- FALLTHROUGH;
- }
- case 'S': // "-S {file}" execute Vim script
- case 'i': // "-i {shada}" use for ShaDa file
- case 'u': // "-u {vimrc}" vim inits file
- case 'U': // "-U {gvimrc}" gvim inits file
- case 'W': { // "-W {scriptout}" overwrite
- want_argument = true;
+ parmp->commands[parmp->n_commands++] = argv[0] + argv_idx;
+ argv_idx = -1;
break;
}
+ FALLTHROUGH;
+ case 'S': // "-S {file}" execute Vim script
+ case 'i': // "-i {shada}" use for ShaDa file
+ case 'u': // "-u {vimrc}" vim inits file
+ case 'U': // "-U {gvimrc}" gvim inits file
+ case 'W': // "-W {scriptout}" overwrite
+ want_argument = true;
+ break;
- default: {
- mainerr(err_opt_unknown, argv[0]);
- }
+ default:
+ mainerr(err_opt_unknown, argv[0]);
}
// Handle option arguments with argument.
@@ -1065,130 +1038,122 @@ static void command_line_scan(mparm_T *parmp)
argv_idx = -1;
switch (c) {
- case 'c': // "-c {command}" execute command
- case 'S': { // "-S {file}" execute Vim script
- if (parmp->n_commands >= MAX_ARG_CMDS) {
- mainerr(err_extra_cmd, NULL);
- }
- if (c == 'S') {
- char *a;
-
- if (argc < 1) {
- // "-S" without argument: use default session file name.
- a = SESSION_FILE;
- } else if (argv[0][0] == '-') {
- // "-S" followed by another option: use default session file.
- a = SESSION_FILE;
- ++argc;
- --argv;
- } else {
- a = argv[0];
- }
-
- size_t s_size = STRLEN(a) + 9;
- char *s = xmalloc(s_size);
- snprintf(s, s_size, "so %s", a);
- parmp->cmds_tofree[parmp->n_commands] = true;
- parmp->commands[parmp->n_commands++] = s;
+ case 'c': // "-c {command}" execute command
+ case 'S': // "-S {file}" execute Vim script
+ if (parmp->n_commands >= MAX_ARG_CMDS) {
+ mainerr(err_extra_cmd, NULL);
+ }
+ if (c == 'S') {
+ char *a;
+
+ if (argc < 1) {
+ // "-S" without argument: use default session file name.
+ a = SESSION_FILE;
+ } else if (argv[0][0] == '-') {
+ // "-S" followed by another option: use default session file.
+ a = SESSION_FILE;
+ ++argc;
+ --argv;
} else {
- parmp->commands[parmp->n_commands++] = argv[0];
+ a = argv[0];
}
- break;
+
+ size_t s_size = STRLEN(a) + 9;
+ char *s = xmalloc(s_size);
+ snprintf(s, s_size, "so %s", a);
+ parmp->cmds_tofree[parmp->n_commands] = true;
+ parmp->commands[parmp->n_commands++] = s;
+ } else {
+ parmp->commands[parmp->n_commands++] = argv[0];
}
+ break;
- case '-': {
- if (strequal(argv[-1], "--cmd")) {
- // "--cmd {command}" execute command
- if (parmp->n_pre_commands >= MAX_ARG_CMDS) {
- mainerr(err_extra_cmd, NULL);
- }
- parmp->pre_commands[parmp->n_pre_commands++] = argv[0];
- } else if (strequal(argv[-1], "--listen")) {
- // "--listen {address}"
- parmp->listen_addr = argv[0];
+ case '-':
+ if (strequal(argv[-1], "--cmd")) {
+ // "--cmd {command}" execute command
+ if (parmp->n_pre_commands >= MAX_ARG_CMDS) {
+ mainerr(err_extra_cmd, NULL);
}
- // "--startuptime <file>" already handled
- break;
+ parmp->pre_commands[parmp->n_pre_commands++] = argv[0];
+ } else if (strequal(argv[-1], "--listen")) {
+ // "--listen {address}"
+ parmp->listen_addr = argv[0];
}
+ // "--startuptime <file>" already handled
+ break;
- case 'q': { // "-q {errorfile}" QuickFix mode
- parmp->use_ef = (char_u *)argv[0];
- break;
- }
+ case 'q': // "-q {errorfile}" QuickFix mode
+ parmp->use_ef = (char_u *)argv[0];
+ break;
- case 'i': { // "-i {shada}" use for shada
- set_option_value("shadafile", 0L, argv[0], 0);
- break;
- }
+ case 'i': // "-i {shada}" use for shada
+ set_option_value("shadafile", 0L, argv[0], 0);
+ break;
- case 's': { // "-s {scriptin}" read from script file
- if (scriptin[0] != NULL) {
+ case 's': { // "-s {scriptin}" read from script file
+ if (scriptin[0] != NULL) {
scripterror:
- vim_snprintf((char *)IObuff, IOSIZE,
- _("Attempt to open script file again: \"%s %s\"\n"),
- argv[-1], argv[0]);
- mch_errmsg((const char *)IObuff);
- os_exit(2);
- }
- int error;
- if (strequal(argv[0], "-")) {
- const int stdin_dup_fd = os_dup(STDIN_FILENO);
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Attempt to open script file again: \"%s %s\"\n"),
+ argv[-1], argv[0]);
+ mch_errmsg((const char *)IObuff);
+ os_exit(2);
+ }
+ int error;
+ if (strequal(argv[0], "-")) {
+ const int stdin_dup_fd = os_dup(STDIN_FILENO);
#ifdef WIN32
- // Replace the original stdin with the console input handle.
- os_replace_stdin_to_conin();
+ // Replace the original stdin with the console input handle.
+ os_replace_stdin_to_conin();
#endif
- FileDescriptor *const stdin_dup = file_open_fd_new(
- &error, stdin_dup_fd, kFileReadOnly|kFileNonBlocking);
- assert(stdin_dup != NULL);
- scriptin[0] = stdin_dup;
- } else if ((scriptin[0] = file_open_new(
- &error, argv[0], kFileReadOnly|kFileNonBlocking, 0)) == NULL) {
- vim_snprintf((char *)IObuff, IOSIZE,
- _("Cannot open for reading: \"%s\": %s\n"),
- argv[0], os_strerror(error));
- mch_errmsg((const char *)IObuff);
- os_exit(2);
- }
- save_typebuf();
- break;
+ FileDescriptor *const stdin_dup = file_open_fd_new(&error, stdin_dup_fd,
+ kFileReadOnly|kFileNonBlocking);
+ assert(stdin_dup != NULL);
+ scriptin[0] = stdin_dup;
+ } else if ((scriptin[0] =
+ file_open_new(&error, argv[0], kFileReadOnly|kFileNonBlocking,
+ 0)) == NULL) {
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Cannot open for reading: \"%s\": %s\n"),
+ argv[0], os_strerror(error));
+ mch_errmsg((const char *)IObuff);
+ os_exit(2);
}
+ save_typebuf();
+ break;
+ }
- case 't': { // "-t {tag}"
- parmp->tagname = (char_u *)argv[0];
- break;
- }
- case 'u': { // "-u {vimrc}" vim inits file
- parmp->use_vimrc = argv[0];
- break;
- }
- case 'U': { // "-U {gvimrc}" gvim inits file
+ case 't': // "-t {tag}"
+ parmp->tagname = (char_u *)argv[0];
+ break;
+ case 'u': // "-u {vimrc}" vim inits file
+ parmp->use_vimrc = argv[0];
+ break;
+ case 'U': // "-U {gvimrc}" gvim inits file
+ break;
+
+ case 'w': // "-w {nr}" 'window' value
+ // "-w {scriptout}" append to script file
+ if (ascii_isdigit(*((char_u *)argv[0]))) {
+ argv_idx = 0;
+ n = get_number_arg(argv[0], &argv_idx, 10);
+ set_option_value("window", n, NULL, 0);
+ argv_idx = -1;
break;
}
-
- case 'w': { // "-w {nr}" 'window' value
- // "-w {scriptout}" append to script file
- if (ascii_isdigit(*((char_u *)argv[0]))) {
- argv_idx = 0;
- n = get_number_arg(argv[0], &argv_idx, 10);
- set_option_value("window", n, NULL, 0);
- argv_idx = -1;
- break;
- }
- FALLTHROUGH;
+ FALLTHROUGH;
+ case 'W': // "-W {scriptout}" overwrite script file
+ if (scriptout != NULL) {
+ goto scripterror;
}
- case 'W': { // "-W {scriptout}" overwrite script file
- if (scriptout != NULL) {
- goto scripterror;
- }
- if ((scriptout = os_fopen(argv[0], c == 'w' ? APPENDBIN : WRITEBIN))
- == NULL) {
- mch_errmsg(_("Cannot open for script output: \""));
- mch_errmsg(argv[0]);
- mch_errmsg("\"\n");
- os_exit(2);
- }
- break;
+ if ((scriptout = os_fopen(argv[0], c == 'w' ? APPENDBIN : WRITEBIN))
+ == NULL) {
+ mch_errmsg(_("Cannot open for script output: \""));
+ mch_errmsg(argv[0]);
+ mch_errmsg("\"\n");
+ os_exit(2);
}
+ break;
}
}
} else { // File name argument.
@@ -1209,7 +1174,7 @@ scripterror:
if (parmp->diff_mode && os_isdir(p) && GARGCOUNT > 0
&& !os_isdir(alist_name(&GARGLIST[0]))) {
char_u *r = (char_u *)concat_fnames((char *)p,
- (char *)path_tail(alist_name(&GARGLIST[0])), true);
+ (char *)path_tail(alist_name(&GARGLIST[0])), true);
xfree(p);
p = r;
}
@@ -1334,43 +1299,15 @@ static char_u *get_fname(mparm_T *parmp, char_u *cwd)
static void set_window_layout(mparm_T *paramp)
{
if (paramp->diff_mode && paramp->window_layout == 0) {
- if (diffopt_horizontal())
- paramp->window_layout = WIN_HOR; /* use horizontal split */
- else
- paramp->window_layout = WIN_VER; /* use vertical split */
- }
-}
-
-/*
- * Read all the plugin files.
- * Only when compiled with +eval, since most plugins need it.
- */
-static void load_plugins(void)
-{
- if (p_lpl) {
- char_u *rtp_copy = NULL;
- char_u *const plugin_pattern_vim = (char_u *)"plugin/**/*.vim"; // NOLINT
- char_u *const plugin_pattern_lua = (char_u *)"plugin/**/*.lua"; // NOLINT
-
- // don't use source_runtime() yet so we can check for :packloadall below
- source_in_path(p_rtp, plugin_pattern_vim, DIP_ALL | DIP_NOAFTER);
- source_in_path(p_rtp, plugin_pattern_lua, DIP_ALL | DIP_NOAFTER);
- TIME_MSG("loading rtp plugins");
- xfree(rtp_copy);
-
- // Only source "start" packages if not done already with a :packloadall
- // command.
- if (!did_source_packages) {
- load_start_packages();
+ if (diffopt_horizontal()) {
+ paramp->window_layout = WIN_HOR; // use horizontal split
+ } else {
+ paramp->window_layout = WIN_VER; // use vertical split
}
- TIME_MSG("loading packages");
-
- source_runtime(plugin_pattern_vim, DIP_ALL | DIP_AFTER);
- source_runtime(plugin_pattern_lua, DIP_ALL | DIP_AFTER);
- TIME_MSG("loading after plugins");
}
}
+
/*
* "-q errorfile": Load the error file now.
* If the error file can't be read, exit before doing anything else.
@@ -1403,9 +1340,10 @@ static void handle_tag(char_u *tagname)
do_cmdline_cmd((char *)IObuff);
TIME_MSG("jumping to tag");
- /* If the user doesn't want to edit the file then we quit here. */
- if (swap_exists_did_quit)
+ // If the user doesn't want to edit the file then we quit here.
+ if (swap_exists_did_quit) {
getout(1);
+ }
}
}
@@ -1443,26 +1381,31 @@ static void create_windows(mparm_T *parmp)
/*
* Create the number of windows that was requested.
*/
- if (parmp->window_count == -1) /* was not set */
+ if (parmp->window_count == -1) { // was not set
parmp->window_count = 1;
- if (parmp->window_count == 0)
+ }
+ if (parmp->window_count == 0) {
parmp->window_count = GARGCOUNT;
+ }
if (parmp->window_count > 1) {
// Don't change the windows if there was a command in vimrc that
// already split some windows
- if (parmp->window_layout == 0)
+ if (parmp->window_layout == 0) {
parmp->window_layout = WIN_HOR;
+ }
if (parmp->window_layout == WIN_TABS) {
parmp->window_count = make_tabpages(parmp->window_count);
TIME_MSG("making tab pages");
} else if (firstwin->w_next == NULL) {
parmp->window_count = make_windows(parmp->window_count,
- parmp->window_layout == WIN_VER);
+ parmp->window_layout == WIN_VER);
TIME_MSG("making windows");
- } else
+ } else {
parmp->window_count = win_count();
- } else
+ }
+ } else {
parmp->window_count = 1;
+ }
if (recoverymode) { // do recover
msg_scroll = true; // scroll message up
@@ -1482,17 +1425,20 @@ static void create_windows(mparm_T *parmp)
dorewind = TRUE;
while (done++ < 1000) {
if (dorewind) {
- if (parmp->window_layout == WIN_TABS)
+ if (parmp->window_layout == WIN_TABS) {
goto_tabpage(1);
- else
+ } else {
curwin = firstwin;
+ }
} else if (parmp->window_layout == WIN_TABS) {
- if (curtab->tp_next == NULL)
+ if (curtab->tp_next == NULL) {
break;
+ }
goto_tabpage(0);
} else {
- if (curwin->w_next == NULL)
+ if (curwin->w_next == NULL) {
break;
+ }
curwin = curwin->w_next;
}
dorewind = FALSE;
@@ -1506,13 +1452,13 @@ static void create_windows(mparm_T *parmp)
swap_exists_action = SEA_DIALOG;
set_buflisted(TRUE);
- /* create memfile, read file */
+ // create memfile, read file
(void)open_buffer(FALSE, NULL, 0);
if (swap_exists_action == SEA_QUIT) {
if (got_int || only_one_window()) {
- /* abort selected or quit and only one window */
- did_emsg = FALSE; /* avoid hit-enter prompt */
+ // abort selected or quit and only one window
+ did_emsg = FALSE; // avoid hit-enter prompt
getout(1);
}
/* We can't close the window, it would disturb what
@@ -1521,20 +1467,22 @@ static void create_windows(mparm_T *parmp)
setfname(curbuf, NULL, NULL, false);
curwin->w_arg_idx = -1;
swap_exists_action = SEA_NONE;
- } else
+ } else {
handle_swap_exists(NULL);
- dorewind = TRUE; /* start again */
+ }
+ dorewind = TRUE; // start again
}
os_breakcheck();
if (got_int) {
- (void)vgetc(); /* only break the file loading, not the rest */
+ (void)vgetc(); // only break the file loading, not the rest
break;
}
}
- if (parmp->window_layout == WIN_TABS)
+ if (parmp->window_layout == WIN_TABS) {
goto_tabpage(1);
- else
+ } else {
curwin = firstwin;
+ }
curbuf = curwin->w_buffer;
--autocmd_no_enter;
--autocmd_no_leave;
@@ -1545,10 +1493,10 @@ static void create_windows(mparm_T *parmp)
/// windows. make_windows() has already opened the windows.
static void edit_buffers(mparm_T *parmp, char_u *cwd)
{
- int arg_idx; /* index in argument list */
+ int arg_idx; // index in argument list
int i;
bool advance = true;
- win_T *win;
+ win_T *win;
char *p_shm_save = NULL;
/*
@@ -1557,7 +1505,7 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
++autocmd_no_enter;
++autocmd_no_leave;
- /* When w_arg_idx is -1 remove the window (see create_windows()). */
+ // When w_arg_idx is -1 remove the window (see create_windows()).
if (curwin->w_arg_idx == -1) {
win_close(curwin, true);
advance = false;
@@ -1578,8 +1526,9 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
if (advance) {
if (parmp->window_layout == WIN_TABS) {
- if (curtab->tp_next == NULL) /* just checking */
+ if (curtab->tp_next == NULL) { // just checking
break;
+ }
goto_tabpage(0);
// Temporarily reset 'shm' option to not print fileinfo when
// loading the other buffers. This would overwrite the already
@@ -1592,8 +1541,9 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
set_option_value("shm", 0L, buf, 0);
}
} else {
- if (curwin->w_next == NULL) /* just checking */
+ if (curwin->w_next == NULL) { // just checking
break;
+ }
win_enter(curwin->w_next, false);
}
}
@@ -1608,12 +1558,12 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
swap_exists_did_quit = false;
(void)do_ecmd(0, arg_idx < GARGCOUNT
? alist_name(&GARGLIST[arg_idx]) : NULL,
- NULL, NULL, ECMD_LASTL, ECMD_HIDE, curwin);
+ NULL, NULL, ECMD_LASTL, ECMD_HIDE, curwin);
if (swap_exists_did_quit) {
- /* abort or quit selected */
+ // abort or quit selected
if (got_int || only_one_window()) {
- /* abort selected and only one window */
- did_emsg = FALSE; /* avoid hit-enter prompt */
+ // abort selected and only one window
+ did_emsg = FALSE; // avoid hit-enter prompt
getout(1);
}
win_close(curwin, true);
@@ -1626,7 +1576,7 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
}
os_breakcheck();
if (got_int) {
- (void)vgetc(); /* only break the file loading, not the rest */
+ (void)vgetc(); // only break the file loading, not the rest
break;
}
}
@@ -1636,13 +1586,14 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
xfree(p_shm_save);
}
- if (parmp->window_layout == WIN_TABS)
+ if (parmp->window_layout == WIN_TABS) {
goto_tabpage(1);
+ }
--autocmd_no_enter;
- /* make the first window the current window */
+ // make the first window the current window
win = firstwin;
- /* Avoid making a preview window the current window. */
+ // Avoid making a preview window the current window.
while (win->w_p_pvw) {
win = win->w_next;
if (win == NULL) {
@@ -1654,8 +1605,9 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
--autocmd_no_leave;
TIME_MSG("editing files in windows");
- if (parmp->window_count > 1 && parmp->window_layout != WIN_TABS)
- win_equal(curwin, false, 'b'); /* adjust heights */
+ if (parmp->window_count > 1 && parmp->window_layout != WIN_TABS) {
+ win_equal(curwin, false, 'b'); // adjust heights
+ }
}
/*
@@ -1668,7 +1620,7 @@ static void exe_pre_commands(mparm_T *parmp)
int i;
if (cnt > 0) {
- curwin->w_cursor.lnum = 0; /* just in case.. */
+ curwin->w_cursor.lnum = 0; // just in case..
sourcing_name = (char_u *)_("pre-vimrc command line");
current_sctx.sc_sid = SID_CMDARG;
for (i = 0; i < cnt; i++) {
@@ -1693,15 +1645,17 @@ static void exe_commands(mparm_T *parmp)
* with g`" was used.
*/
msg_scroll = TRUE;
- if (parmp->tagname == NULL && curwin->w_cursor.lnum <= 1)
+ if (parmp->tagname == NULL && curwin->w_cursor.lnum <= 1) {
curwin->w_cursor.lnum = 0;
+ }
sourcing_name = (char_u *)"command line";
current_sctx.sc_sid = SID_CARG;
current_sctx.sc_seq = 0;
for (i = 0; i < parmp->n_commands; i++) {
do_cmdline_cmd(parmp->commands[i]);
- if (parmp->cmds_tofree[i])
+ if (parmp->cmds_tofree[i]) {
xfree(parmp->commands[i]);
+ }
}
sourcing_name = NULL;
current_sctx.sc_sid = 0;
@@ -1709,12 +1663,14 @@ static void exe_commands(mparm_T *parmp)
curwin->w_cursor.lnum = 1;
}
- if (!exmode_active)
+ if (!exmode_active) {
msg_scroll = FALSE;
+ }
- /* When started with "-q errorfile" jump to first error again. */
- if (parmp->edit_type == EDIT_QF)
+ // When started with "-q errorfile" jump to first error again.
+ if (parmp->edit_type == EDIT_QF) {
qf_jump(NULL, 0, 0, FALSE);
+ }
TIME_MSG("executing command arguments");
}
@@ -1744,7 +1700,7 @@ static void do_system_initialization(void)
memcpy(vimrc, dir, dir_len);
vimrc[dir_len] = PATHSEP;
memcpy(vimrc + dir_len + 1, path_tail, sizeof(path_tail));
- if (do_source((char_u *)vimrc, false, DOSO_NONE) != FAIL) {
+ if (do_source(vimrc, false, DOSO_NONE) != FAIL) {
xfree(vimrc);
xfree(config_dirs);
return;
@@ -1756,7 +1712,7 @@ static void do_system_initialization(void)
#ifdef SYS_VIMRC_FILE
// Get system wide defaults, if the file name is defined.
- (void)do_source((char_u *)SYS_VIMRC_FILE, false, DOSO_NONE);
+ (void)do_source(SYS_VIMRC_FILE, false, DOSO_NONE);
#endif
}
@@ -1781,24 +1737,24 @@ static bool do_user_initialization(void)
}
char_u *init_lua_path = (char_u *)stdpaths_user_conf_subpath("init.lua");
- if (os_path_exists(init_lua_path)
- && do_source(init_lua_path, true, DOSO_VIMRC)) {
- os_setenv("MYVIMRC", (const char *)init_lua_path, 1);
- char_u *vimrc_path = (char_u *)stdpaths_user_conf_subpath("init.vim");
+ char_u *user_vimrc = (char_u *)stdpaths_user_conf_subpath("init.vim");
- if (os_path_exists(vimrc_path)) {
+ // init.lua
+ if (os_path_exists(init_lua_path)
+ && do_source((char *)init_lua_path, true, DOSO_VIMRC)) {
+ if (os_path_exists(user_vimrc)) {
EMSG3(_("E5422: Conflicting configs: \"%s\" \"%s\""), init_lua_path,
- vimrc_path);
+ user_vimrc);
}
- xfree(vimrc_path);
+ xfree(user_vimrc);
xfree(init_lua_path);
return false;
}
xfree(init_lua_path);
- char_u *user_vimrc = (char_u *)stdpaths_user_conf_subpath("init.vim");
- if (do_source(user_vimrc, true, DOSO_VIMRC) != FAIL) {
+ // init.vim
+ 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,
@@ -1809,6 +1765,7 @@ static bool do_user_initialization(void)
return do_exrc;
}
xfree(user_vimrc);
+
char *const config_dirs = stdpaths_get_xdg_var(kXDGConfigDirs);
if (config_dirs != NULL) {
const void *iter = NULL;
@@ -1825,7 +1782,7 @@ static bool do_user_initialization(void)
memmove(vimrc, dir, dir_len);
vimrc[dir_len] = PATHSEP;
memmove(vimrc + dir_len + 1, path_tail, sizeof(path_tail));
- if (do_source((char_u *) vimrc, true, DOSO_VIMRC) != FAIL) {
+ 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,
@@ -1839,6 +1796,7 @@ static bool do_user_initialization(void)
} while (iter != NULL);
xfree(config_dirs);
}
+
if (execute_env("EXINIT") == OK) {
do_exrc = p_exrc;
return do_exrc;
@@ -1856,7 +1814,7 @@ static void source_startup_scripts(const mparm_T *const parmp)
|| strequal(parmp->use_vimrc, "NORC")) {
// Do nothing.
} else {
- if (do_source((char_u *)parmp->use_vimrc, false, DOSO_NONE) != OK) {
+ if (do_source(parmp->use_vimrc, false, DOSO_NONE) != OK) {
EMSG2(_("E282: Cannot read from \"%s\""), parmp->use_vimrc);
}
}
@@ -1875,9 +1833,9 @@ static void source_startup_scripts(const mparm_T *const parmp)
// If vimrc file is not owned by user, set 'secure' mode.
if (!file_owned(VIMRC_FILE))
#endif
- secure = p_secure;
+ secure = p_secure;
- if (do_source((char_u *)VIMRC_FILE, true, DOSO_VIMRC) == FAIL) {
+ if (do_source(VIMRC_FILE, true, DOSO_VIMRC) == FAIL) {
#if defined(UNIX)
// if ".exrc" is not owned by user set 'secure' mode
if (!file_owned(EXRC_FILE)) {
@@ -1886,7 +1844,7 @@ static void source_startup_scripts(const mparm_T *const parmp)
secure = 0;
}
#endif
- (void)do_source((char_u *)EXRC_FILE, false, DOSO_NONE);
+ (void)do_source(EXRC_FILE, false, DOSO_NONE);
}
}
if (secure == 2) {
@@ -2031,7 +1989,8 @@ static void usage(void)
*/
static void check_swap_exists_action(void)
{
- if (swap_exists_action == SEA_QUIT)
+ if (swap_exists_action == SEA_QUIT) {
getout(1);
+ }
handle_swap_exists(NULL);
}
diff --git a/src/nvim/main.h b/src/nvim/main.h
index d387e6d668..f73af5c288 100644
--- a/src/nvim/main.h
+++ b/src/nvim/main.h
@@ -1,8 +1,8 @@
#ifndef NVIM_MAIN_H
#define NVIM_MAIN_H
-#include "nvim/normal.h"
#include "nvim/event/loop.h"
+#include "nvim/normal.h"
// Maximum number of commands from + or -c arguments.
#define MAX_ARG_CMDS 10
diff --git a/src/nvim/map.c b/src/nvim/map.c
index ccd332192e..20d5570e8c 100644
--- a/src/nvim/map.c
+++ b/src/nvim/map.c
@@ -8,20 +8,18 @@
// khash.h does not make its own copy of the key or value.
//
-#include <stdlib.h>
+#include <lauxlib.h>
+#include <lua.h>
#include <stdbool.h>
+#include <stdlib.h>
#include <string.h>
-#include <lua.h>
-#include <lauxlib.h>
-
+#include "nvim/api/private/dispatch.h"
+#include "nvim/lib/khash.h"
#include "nvim/map.h"
#include "nvim/map_defs.h"
-#include "nvim/vim.h"
#include "nvim/memory.h"
-#include "nvim/api/private/dispatch.h"
-
-#include "nvim/lib/khash.h"
+#include "nvim/vim.h"
#define cstr_t_hash kh_str_hash_func
#define cstr_t_eq kh_str_hash_equal
@@ -38,11 +36,11 @@
#if defined(ARCH_64)
-#define ptr_t_hash(key) uint64_t_hash((uint64_t)key)
-#define ptr_t_eq(a, b) uint64_t_eq((uint64_t)a, (uint64_t)b)
+# define ptr_t_hash(key) uint64_t_hash((uint64_t)key)
+# define ptr_t_eq(a, b) uint64_t_eq((uint64_t)a, (uint64_t)b)
#elif defined(ARCH_32)
-#define ptr_t_hash(key) uint32_t_hash((uint32_t)key)
-#define ptr_t_eq(a, b) uint32_t_eq((uint32_t)a, (uint32_t)b)
+# define ptr_t_hash(key) uint32_t_hash((uint32_t)key)
+# define ptr_t_eq(a, b) uint32_t_eq((uint32_t)a, (uint32_t)b)
#endif
#define INITIALIZER(T, U) T##_##U##_initializer
@@ -52,7 +50,7 @@
#define MAP_IMPL(T, U, ...) \
INITIALIZER_DECLARE(T, U, __VA_ARGS__); \
- __KHASH_IMPL(T##_##U##_map,, T, U, 1, T##_hash, T##_eq) \
+ __KHASH_IMPL(T##_##U##_map, , T, U, 1, T##_hash, T##_eq) \
\
void map_##T##_##U##_destroy(Map(T, U) *map) \
{ \
diff --git a/src/nvim/map.h b/src/nvim/map.h
index d6515878a2..6ed341ac76 100644
--- a/src/nvim/map.h
+++ b/src/nvim/map.h
@@ -3,11 +3,11 @@
#include <stdbool.h>
-#include "nvim/map_defs.h"
-#include "nvim/extmark_defs.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/dispatch.h"
+#include "nvim/extmark_defs.h"
#include "nvim/highlight_defs.h"
+#include "nvim/map_defs.h"
#if defined(__NetBSD__)
# undef uint64_t
@@ -60,7 +60,7 @@ MAP_DECLS(String, handle_T)
MAP_DECLS(ColorKey, ColorItem)
#define MAP_INIT { { 0, 0, 0, 0, NULL, NULL, NULL } }
-#define map_init(k, v, map) do { *(map) = (Map(k, v))MAP_INIT; } while (false)
+#define map_init(k, v, map) do { *(map) = (Map(k, v)) MAP_INIT; } while (false)
#define map_destroy(T, U) map_##T##_##U##_destroy
#define map_get(T, U) map_##T##_##U##_get
diff --git a/src/nvim/map_defs.h b/src/nvim/map_defs.h
index d5a302362f..7b4596ce2e 100644
--- a/src/nvim/map_defs.h
+++ b/src/nvim/map_defs.h
@@ -3,8 +3,8 @@
#include "nvim/lib/khash.h"
-typedef const char * cstr_t;
-typedef void * ptr_t;
+typedef const char *cstr_t;
+typedef void *ptr_t;
#define Map(T, U) Map_##T##_##U
#define PMap(T) Map(T, ptr_t)
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index 0b14089550..ea9acdf31a 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -7,35 +7,35 @@
#include <assert.h>
#include <inttypes.h>
-#include <string.h>
#include <limits.h>
+#include <string.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/mark.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/diff.h"
#include "nvim/eval.h"
#include "nvim/ex_cmds.h"
+#include "nvim/extmark.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
-#include "nvim/extmark.h"
+#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/normal.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/os/time.h"
#include "nvim/path.h"
#include "nvim/quickfix.h"
#include "nvim/search.h"
#include "nvim/sign.h"
#include "nvim/strings.h"
#include "nvim/ui.h"
-#include "nvim/os/os.h"
-#include "nvim/os/time.h"
-#include "nvim/os/input.h"
+#include "nvim/vim.h"
/*
* This file contains routines to maintain and manipulate marks.
@@ -94,17 +94,19 @@ int setmark_pos(int c, pos_T *pos, int fnum)
{
int i;
- /* Check for a special key (may cause islower() to crash). */
- if (c < 0)
+ // Check for a special key (may cause islower() to crash).
+ if (c < 0) {
return FAIL;
+ }
if (c == '\'' || c == '`') {
if (pos == &curwin->w_cursor) {
setpcmark();
- /* keep it even when the cursor doesn't move */
+ // keep it even when the cursor doesn't move
curwin->w_prev_pcmark = curwin->w_pcmark;
- } else
+ } else {
curwin->w_pcmark = *pos;
+ }
return OK;
}
@@ -119,8 +121,8 @@ int setmark_pos(int c, pos_T *pos, int fnum)
return OK;
}
- /* Allow setting '[ and '] for an autocommand that simulates reading a
- * file. */
+ // Allow setting '[ and '] for an autocommand that simulates reading a
+ // file.
if (c == '[') {
buf->b_op_start = *pos;
return OK;
@@ -166,11 +168,12 @@ int setmark_pos(int c, pos_T *pos, int fnum)
*/
void setpcmark(void)
{
- xfmark_T *fm;
+ xfmark_T *fm;
- /* for :global the mark is set only once */
- if (global_busy || listcmd_busy || cmdmod.keepjumps)
+ // for :global the mark is set only once
+ if (global_busy || listcmd_busy || cmdmod.keepjumps) {
return;
+ }
curwin->w_prev_pcmark = curwin->w_pcmark;
curwin->w_pcmark = curwin->w_cursor;
@@ -189,7 +192,7 @@ void setpcmark(void)
}
}
- /* If jumplist is full: remove oldest entry */
+ // If jumplist is full: remove oldest entry
if (++curwin->w_jumplistlen > JUMPLISTSIZE) {
curwin->w_jumplistlen = JUMPLISTSIZE;
free_xfmark(curwin->w_jumplist[0]);
@@ -214,7 +217,7 @@ void checkpcmark(void)
&& (equalpos(curwin->w_pcmark, curwin->w_cursor)
|| curwin->w_pcmark.lnum == 0)) {
curwin->w_pcmark = curwin->w_prev_pcmark;
- curwin->w_prev_pcmark.lnum = 0; /* Show it has been checked */
+ curwin->w_prev_pcmark.lnum = 0; // Show it has been checked
}
}
@@ -223,18 +226,20 @@ void checkpcmark(void)
*/
pos_T *movemark(int count)
{
- pos_T *pos;
- xfmark_T *jmp;
+ pos_T *pos;
+ xfmark_T *jmp;
cleanup_jumplist(curwin, true);
- if (curwin->w_jumplistlen == 0) /* nothing to jump to */
+ if (curwin->w_jumplistlen == 0) { // nothing to jump to
return (pos_T *)NULL;
+ }
for (;; ) {
if (curwin->w_jumplistidx + count < 0
- || curwin->w_jumplistidx + count >= curwin->w_jumplistlen)
+ || curwin->w_jumplistidx + count >= curwin->w_jumplistlen) {
return (pos_T *)NULL;
+ }
/*
* if first CTRL-O or CTRL-I command after a jump, add cursor position
@@ -243,30 +248,34 @@ pos_T *movemark(int count)
*/
if (curwin->w_jumplistidx == curwin->w_jumplistlen) {
setpcmark();
- --curwin->w_jumplistidx; /* skip the new entry */
- if (curwin->w_jumplistidx + count < 0)
+ --curwin->w_jumplistidx; // skip the new entry
+ if (curwin->w_jumplistidx + count < 0) {
return (pos_T *)NULL;
+ }
}
curwin->w_jumplistidx += count;
jmp = curwin->w_jumplist + curwin->w_jumplistidx;
- if (jmp->fmark.fnum == 0)
+ if (jmp->fmark.fnum == 0) {
fname2fnum(jmp);
+ }
if (jmp->fmark.fnum != curbuf->b_fnum) {
- /* jump to other file */
- if (buflist_findnr(jmp->fmark.fnum) == NULL) { /* Skip this one .. */
+ // jump to other file
+ if (buflist_findnr(jmp->fmark.fnum) == NULL) { // Skip this one ..
count += count < 0 ? -1 : 1;
continue;
}
if (buflist_getfile(jmp->fmark.fnum, jmp->fmark.mark.lnum,
- 0, FALSE) == FAIL)
+ 0, FALSE) == FAIL) {
return (pos_T *)NULL;
- /* Set lnum again, autocommands my have changed it */
+ }
+ // Set lnum again, autocommands my have changed it
curwin->w_cursor = jmp->fmark.mark;
pos = (pos_T *)-1;
- } else
+ } else {
pos = &(jmp->fmark.mark);
+ }
return pos;
}
}
@@ -278,20 +287,24 @@ pos_T *movechangelist(int count)
{
int n;
- if (curbuf->b_changelistlen == 0) /* nothing to jump to */
+ if (curbuf->b_changelistlen == 0) { // nothing to jump to
return (pos_T *)NULL;
+ }
n = curwin->w_changelistidx;
if (n + count < 0) {
- if (n == 0)
+ if (n == 0) {
return (pos_T *)NULL;
+ }
n = 0;
} else if (n + count >= curbuf->b_changelistlen) {
- if (n == curbuf->b_changelistlen - 1)
+ if (n == curbuf->b_changelistlen - 1) {
return (pos_T *)NULL;
+ }
n = curbuf->b_changelistlen - 1;
- } else
+ } else {
n += count;
+ }
curwin->w_changelistidx = n;
return &(curbuf->b_changelist[n].mark);
}
@@ -319,16 +332,17 @@ pos_T *getmark(int c, bool changefile)
pos_T *getmark_buf_fnum(buf_T *buf, int c, bool changefile, int *fnum)
{
- pos_T *posp;
- pos_T *startp, *endp;
+ pos_T *posp;
+ pos_T *startp, *endp;
static pos_T pos_copy;
posp = NULL;
- /* Check for special key, can't be a mark name and might cause islower()
- * to crash. */
- if (c < 0)
+ // Check for special key, can't be a mark name and might cause islower()
+ // to crash.
+ if (c < 0) {
return posp;
+ }
if (c > '~') { // check for islower()/isupper()
} else if (c == '\'' || c == '`') { // previous context mark
pos_copy = curwin->w_pcmark; // need to make a copy because
@@ -351,13 +365,13 @@ pos_T *getmark_buf_fnum(buf_T *buf, int c, bool changefile, int *fnum)
pos = curwin->w_cursor;
listcmd_busy = true; // avoid that '' is changed
if (findpar(&oa.inclusive,
- c == '}' ? FORWARD : BACKWARD, 1L, NUL, FALSE)) {
+ c == '}' ? FORWARD : BACKWARD, 1L, NUL, FALSE)) {
pos_copy = curwin->w_cursor;
posp = &pos_copy;
}
curwin->w_cursor = pos;
listcmd_busy = slcb;
- } else if (c == '(' || c == ')') { /* to previous/next sentence */
+ } else if (c == '(' || c == ')') { // to previous/next sentence
pos_T pos;
bool slcb = listcmd_busy;
@@ -369,7 +383,7 @@ pos_T *getmark_buf_fnum(buf_T *buf, int c, bool changefile, int *fnum)
}
curwin->w_cursor = pos;
listcmd_busy = slcb;
- } else if (c == '<' || c == '>') { /* start/end of visual area */
+ } else if (c == '<' || c == '>') { // start/end of visual area
startp = &buf->b_visual.vi_start;
endp = &buf->b_visual.vi_end;
if (((c == '<') == lt(*startp, *endp) || endp->lnum == 0)
@@ -383,86 +397,87 @@ pos_T *getmark_buf_fnum(buf_T *buf, int c, bool changefile, int *fnum)
if (buf->b_visual.vi_mode == 'V') {
pos_copy = *posp;
posp = &pos_copy;
- if (c == '<')
+ if (c == '<') {
pos_copy.col = 0;
- else
+ } else {
pos_copy.col = MAXCOL;
+ }
pos_copy.coladd = 0;
}
- } else if (ASCII_ISLOWER(c)) { /* normal named mark */
+ } else if (ASCII_ISLOWER(c)) { // normal named mark
posp = &(buf->b_namedm[c - 'a'].mark);
- } else if (ASCII_ISUPPER(c) || ascii_isdigit(c)) { /* named file mark */
- if (ascii_isdigit(c))
+ } else if (ASCII_ISUPPER(c) || ascii_isdigit(c)) { // named file mark
+ if (ascii_isdigit(c)) {
c = c - '0' + NMARKS;
- else
+ } else {
c -= 'A';
+ }
posp = &(namedfm[c].fmark.mark);
if (namedfm[c].fmark.fnum == 0) {
fname2fnum(&namedfm[c]);
}
- if (fnum != NULL)
+ if (fnum != NULL) {
*fnum = namedfm[c].fmark.fnum;
- else if (namedfm[c].fmark.fnum != buf->b_fnum) {
- /* mark is in another file */
+ } else if (namedfm[c].fmark.fnum != buf->b_fnum) {
+ // mark is in another file
posp = &pos_copy;
if (namedfm[c].fmark.mark.lnum != 0
&& changefile && namedfm[c].fmark.fnum) {
if (buflist_getfile(namedfm[c].fmark.fnum,
- (linenr_T)1, GETF_SETMARK, FALSE) == OK) {
- /* Set the lnum now, autocommands could have changed it */
+ (linenr_T)1, GETF_SETMARK, FALSE) == OK) {
+ // Set the lnum now, autocommands could have changed it
curwin->w_cursor = namedfm[c].fmark.mark;
return (pos_T *)-1;
}
- pos_copy.lnum = -1; /* can't get file */
- } else
- pos_copy.lnum = 0; /* mark exists, but is not valid in
- current buffer */
+ pos_copy.lnum = -1; // can't get file
+ } else {
+ pos_copy.lnum = 0; // mark exists, but is not valid in current buffer
+ }
}
}
return posp;
}
-/*
- * Search for the next named mark in the current file.
- *
- * Returns pointer to pos_T of the next mark or NULL if no mark is found.
- */
-pos_T *
-getnextmark (
- pos_T *startpos, /* where to start */
- int dir, /* direction for search */
- int begin_line
-)
+/// Search for the next named mark in the current file.
+///
+/// @param startpos where to start
+/// @param dir direction for search
+///
+/// @return pointer to pos_T of the next mark or NULL if no mark is found.
+pos_T *getnextmark(pos_T *startpos, int dir, int begin_line)
{
int i;
- pos_T *result = NULL;
+ pos_T *result = NULL;
pos_T pos;
pos = *startpos;
- /* When searching backward and leaving the cursor on the first non-blank,
- * position must be in a previous line.
- * When searching forward and leaving the cursor on the first non-blank,
- * position must be in a next line. */
- if (dir == BACKWARD && begin_line)
+ // When searching backward and leaving the cursor on the first non-blank,
+ // position must be in a previous line.
+ // When searching forward and leaving the cursor on the first non-blank,
+ // position must be in a next line.
+ if (dir == BACKWARD && begin_line) {
pos.col = 0;
- else if (dir == FORWARD && begin_line)
+ } else if (dir == FORWARD && begin_line) {
pos.col = MAXCOL;
+ }
for (i = 0; i < NMARKS; i++) {
if (curbuf->b_namedm[i].mark.lnum > 0) {
if (dir == FORWARD) {
if ((result == NULL || lt(curbuf->b_namedm[i].mark, *result))
- && lt(pos, curbuf->b_namedm[i].mark))
+ && lt(pos, curbuf->b_namedm[i].mark)) {
result = &curbuf->b_namedm[i].mark;
+ }
} else {
if ((result == NULL || lt(*result, curbuf->b_namedm[i].mark))
- && lt(curbuf->b_namedm[i].mark, pos))
+ && lt(curbuf->b_namedm[i].mark, pos)) {
result = &curbuf->b_namedm[i].mark;
+ }
}
}
}
@@ -494,10 +509,11 @@ static void fname2fnum(xfmark_T *fm)
expand_env((char_u *)"~/", NameBuff, MAXPATHL);
len = (int)STRLEN(NameBuff);
STRLCPY(NameBuff + len, fm->fname + 2, MAXPATHL - len);
- } else
+ } else {
STRLCPY(NameBuff, fm->fname, MAXPATHL);
+ }
- /* Try to shorten the file name. */
+ // Try to shorten the file name.
os_dirname(IObuff, IOSIZE);
p = path_shorten_fname(NameBuff, IObuff);
@@ -513,14 +529,16 @@ static void fname2fnum(xfmark_T *fm)
*/
void fmarks_check_names(buf_T *buf)
{
- char_u *name = buf->b_ffname;
+ char_u *name = buf->b_ffname;
int i;
- if (buf->b_ffname == NULL)
+ if (buf->b_ffname == NULL) {
return;
+ }
- for (i = 0; i < NGLOBALMARKS; ++i)
+ for (i = 0; i < NGLOBALMARKS; ++i) {
fmarks_check_one(&namedfm[i], name, buf);
+ }
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
for (i = 0; i < wp->w_jumplistlen; ++i) {
@@ -550,10 +568,11 @@ int check_mark(pos_T *pos)
return FAIL;
}
if (pos->lnum <= 0) {
- /* lnum is negative if mark is in another file can can't get that
- * file, error message already give then. */
- if (pos->lnum == 0)
+ // lnum is negative if mark is in another file can can't get that
+ // file, error message already give then.
+ if (pos->lnum == 0) {
EMSG(_(e_marknotset));
+ }
return FAIL;
}
if (pos->lnum > curbuf->b_ml.ml_line_count) {
@@ -593,8 +612,9 @@ void clrallmarks(buf_T *const buf)
*/
char_u *fm_getname(fmark_T *fmark, int lead_len)
{
- if (fmark->fnum == curbuf->b_fnum) /* current buffer */
+ if (fmark->fnum == curbuf->b_fnum) { // current buffer
return mark_line(&(fmark->mark), lead_len);
+ }
return buflist_nr2name(fmark->fnum, FALSE, TRUE);
}
@@ -604,11 +624,12 @@ char_u *fm_getname(fmark_T *fmark, int lead_len)
*/
static char_u *mark_line(pos_T *mp, int lead_len)
{
- char_u *s, *p;
+ char_u *s, *p;
int len;
- if (mp->lnum == 0 || mp->lnum > curbuf->b_ml.ml_line_count)
+ if (mp->lnum == 0 || mp->lnum > curbuf->b_ml.ml_line_count) {
return vim_strsave((char_u *)"-invalid-");
+ }
assert(Columns >= 0 && (size_t)Columns <= SIZE_MAX);
// Allow for up to 5 bytes per character.
s = vim_strnsave(skipwhite(ml_get(mp->lnum)), (size_t)Columns * 5);
@@ -617,8 +638,9 @@ static char_u *mark_line(pos_T *mp, int lead_len)
len = 0;
for (p = s; *p != NUL; MB_PTR_ADV(p)) {
len += ptr2cells(p);
- if (len >= Columns - lead_len)
+ if (len >= Columns - lead_len) {
break;
+ }
}
*p = NUL;
return s;
@@ -629,28 +651,32 @@ static char_u *mark_line(pos_T *mp, int lead_len)
*/
void ex_marks(exarg_T *eap)
{
- char_u *arg = eap->arg;
+ char_u *arg = eap->arg;
int i;
- char_u *name;
- pos_T *posp, *startp, *endp;
+ char_u *name;
+ pos_T *posp, *startp, *endp;
- if (arg != NULL && *arg == NUL)
+ if (arg != NULL && *arg == NUL) {
arg = NULL;
+ }
show_one_mark('\'', arg, &curwin->w_pcmark, NULL, true);
- for (i = 0; i < NMARKS; ++i)
+ for (i = 0; i < NMARKS; ++i) {
show_one_mark(i + 'a', arg, &curbuf->b_namedm[i].mark, NULL, true);
+ }
for (i = 0; i < NGLOBALMARKS; ++i) {
- if (namedfm[i].fmark.fnum != 0)
+ if (namedfm[i].fmark.fnum != 0) {
name = fm_getname(&namedfm[i].fmark, 15);
- else
+ } else {
name = namedfm[i].fname;
+ }
if (name != NULL) {
show_one_mark(i >= NMARKS ? i - NMARKS + '0' : i + 'A',
- arg, &namedfm[i].fmark.mark, name,
- namedfm[i].fmark.fnum == curbuf->b_fnum);
- if (namedfm[i].fmark.fnum != 0)
+ arg, &namedfm[i].fmark.mark, name,
+ namedfm[i].fmark.fnum == curbuf->b_fnum);
+ if (namedfm[i].fmark.fnum != 0) {
xfree(name);
+ }
}
}
show_one_mark('"', arg, &curbuf->b_last_cursor.mark, NULL, true);
@@ -673,14 +699,8 @@ void ex_marks(exarg_T *eap)
show_one_mark(-1, arg, NULL, NULL, false);
}
-static void
-show_one_mark(
- int c,
- char_u *arg,
- pos_T *p,
- char_u *name_arg,
- int current // in current file
-)
+/// @param current in current file
+static void show_one_mark(int c, char_u *arg, pos_T *p, char_u *name_arg, int current)
{
static bool did_title = false;
bool mustfree = false;
@@ -731,41 +751,42 @@ show_one_mark(
*/
void ex_delmarks(exarg_T *eap)
{
- char_u *p;
+ char_u *p;
int from, to;
int i;
int lower;
int digit;
int n;
- if (*eap->arg == NUL && eap->forceit)
- /* clear all marks */
+ if (*eap->arg == NUL && eap->forceit) {
+ // clear all marks
clrallmarks(curbuf);
- else if (eap->forceit)
+ } else if (eap->forceit) {
EMSG(_(e_invarg));
- else if (*eap->arg == NUL)
+ } else if (*eap->arg == NUL) {
EMSG(_(e_argreq));
- else {
- /* clear specified marks only */
+ } else {
+ // clear specified marks only
for (p = eap->arg; *p != NUL; ++p) {
lower = ASCII_ISLOWER(*p);
digit = ascii_isdigit(*p);
if (lower || digit || ASCII_ISUPPER(*p)) {
if (p[1] == '-') {
- /* clear range of marks */
+ // clear range of marks
from = *p;
to = p[2];
if (!(lower ? ASCII_ISLOWER(p[2])
- : (digit ? ascii_isdigit(p[2])
- : ASCII_ISUPPER(p[2])))
+ : (digit ? ascii_isdigit(p[2])
+ : ASCII_ISUPPER(p[2])))
|| to < from) {
EMSG2(_(e_invarg2), p);
return;
}
p += 2;
- } else
- /* clear one lower case mark */
+ } else {
+ // clear one lower case mark
from = to = *p;
+ }
for (i = from; i <= to; ++i) {
if (lower) {
@@ -781,19 +802,29 @@ void ex_delmarks(exarg_T *eap)
XFREE_CLEAR(namedfm[n].fname);
}
}
- } else
+ } else {
switch (*p) {
- case '"': CLEAR_FMARK(&curbuf->b_last_cursor); break;
- case '^': CLEAR_FMARK(&curbuf->b_last_insert); break;
- case '.': CLEAR_FMARK(&curbuf->b_last_change); break;
- case '[': curbuf->b_op_start.lnum = 0; break;
- case ']': curbuf->b_op_end.lnum = 0; break;
- case '<': curbuf->b_visual.vi_start.lnum = 0; break;
- case '>': curbuf->b_visual.vi_end.lnum = 0; break;
- case ' ': break;
- default: EMSG2(_(e_invarg2), p);
+ case '"':
+ CLEAR_FMARK(&curbuf->b_last_cursor); break;
+ case '^':
+ CLEAR_FMARK(&curbuf->b_last_insert); break;
+ case '.':
+ CLEAR_FMARK(&curbuf->b_last_change); break;
+ case '[':
+ curbuf->b_op_start.lnum = 0; break;
+ case ']':
+ curbuf->b_op_end.lnum = 0; break;
+ case '<':
+ curbuf->b_visual.vi_start.lnum = 0; break;
+ case '>':
+ curbuf->b_visual.vi_end.lnum = 0; break;
+ case ' ':
+ break;
+ default:
+ EMSG2(_(e_invarg2), p);
return;
}
+ }
}
}
}
@@ -804,7 +835,7 @@ void ex_delmarks(exarg_T *eap)
void ex_jumps(exarg_T *eap)
{
int i;
- char_u *name;
+ char_u *name;
cleanup_jumplist(curwin, true);
// Highlight title
@@ -825,11 +856,11 @@ void ex_jumps(exarg_T *eap)
break;
}
sprintf((char *)IObuff, "%c %2d %5ld %4d ",
- 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);
+ 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_attr(name,
curwin->w_jumplist[i].fmark.fnum == curbuf->b_fnum
@@ -839,8 +870,9 @@ void ex_jumps(exarg_T *eap)
}
ui_flush();
}
- if (curwin->w_jumplistidx == curwin->w_jumplistlen)
+ if (curwin->w_jumplistidx == curwin->w_jumplistlen) {
MSG_PUTS("\n>");
+ }
}
void ex_clearjumps(exarg_T *eap)
@@ -856,7 +888,7 @@ void ex_clearjumps(exarg_T *eap)
void ex_changes(exarg_T *eap)
{
int i;
- char_u *name;
+ char_u *name;
// Highlight title
MSG_PUTS_TITLE(_("\nchange line col text"));
@@ -864,14 +896,15 @@ void ex_changes(exarg_T *eap)
for (i = 0; i < curbuf->b_changelistlen && !got_int; ++i) {
if (curbuf->b_changelist[i].mark.lnum != 0) {
msg_putchar('\n');
- if (got_int)
+ if (got_int) {
break;
+ }
sprintf((char *)IObuff, "%c %3d %5ld %4d ",
- i == curwin->w_changelistidx ? '>' : ' ',
- i > curwin->w_changelistidx ? i - curwin->w_changelistidx
- : curwin->w_changelistidx - i,
- (long)curbuf->b_changelist[i].mark.lnum,
- curbuf->b_changelist[i].mark.col);
+ i == curwin->w_changelistidx ? '>' : ' ',
+ i > curwin->w_changelistidx ? i - curwin->w_changelistidx
+ : curwin->w_changelistidx - i,
+ (long)curbuf->b_changelist[i].mark.lnum,
+ curbuf->b_changelist[i].mark.col);
msg_outtrans(IObuff);
name = mark_line(&curbuf->b_changelist[i].mark, 17);
msg_outtrans_attr(name, HL_ATTR(HLF_D));
@@ -880,8 +913,9 @@ void ex_changes(exarg_T *eap)
}
ui_flush();
}
- if (curwin->w_changelistidx == curbuf->b_changelistlen)
+ if (curwin->w_changelistidx == curbuf->b_changelistlen) {
MSG_PUTS("\n>");
+ }
}
#define one_adjust(add) \
@@ -890,27 +924,27 @@ void ex_changes(exarg_T *eap)
if (*lp >= line1 && *lp <= line2) \
{ \
if (amount == MAXLNUM) \
- *lp = 0; \
+ *lp = 0; \
else \
- *lp += amount; \
+ *lp += amount; \
} \
else if (amount_after && *lp > line2) \
- *lp += amount_after; \
+ *lp += amount_after; \
}
-/* don't delete the line, just put at first deleted line */
+// don't delete the line, just put at first deleted line
#define one_adjust_nodel(add) \
{ \
lp = add; \
if (*lp >= line1 && *lp <= line2) \
{ \
if (amount == MAXLNUM) \
- *lp = line1; \
+ *lp = line1; \
else \
- *lp += amount; \
+ *lp += amount; \
} \
else if (amount_after && *lp > line2) \
- *lp += amount_after; \
+ *lp += amount_after; \
}
/*
@@ -922,13 +956,9 @@ void ex_changes(exarg_T *eap)
* If 'amount_after' is non-zero adjust marks after line2.
* Example: Delete lines 34 and 35: mark_adjust(34, 35, MAXLNUM, -2);
* Example: Insert two lines below 55: mark_adjust(56, MAXLNUM, 2, 0);
- * or: mark_adjust(56, 55, MAXLNUM, 2);
+ * or: mark_adjust(56, 55, MAXLNUM, 2);
*/
-void mark_adjust(linenr_T line1,
- linenr_T line2,
- long amount,
- long amount_after,
- ExtmarkOp op)
+void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after, ExtmarkOp op)
{
mark_adjust_internal(line1, line2, amount, amount_after, true, op);
}
@@ -938,54 +968,56 @@ void mark_adjust(linenr_T line1,
// This is only useful when folds need to be moved in a way different to
// calling foldMarkAdjust() with arguments line1, line2, amount, amount_after,
// for an example of why this may be necessary, see do_move().
-void mark_adjust_nofold(linenr_T line1, linenr_T line2, long amount,
- long amount_after,
+void mark_adjust_nofold(linenr_T line1, linenr_T line2, long amount, long amount_after,
ExtmarkOp op)
{
mark_adjust_internal(line1, line2, amount, amount_after, false, op);
}
-static void mark_adjust_internal(linenr_T line1, linenr_T line2,
- long amount, long amount_after,
- bool adjust_folds,
- ExtmarkOp op)
+static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount, long amount_after,
+ bool adjust_folds, ExtmarkOp op)
{
int i;
int fnum = curbuf->b_fnum;
- linenr_T *lp;
+ linenr_T *lp;
static pos_T initpos = { 1, 0, 0 };
- if (line2 < line1 && amount_after == 0L) /* nothing to do */
+ if (line2 < line1 && amount_after == 0L) { // nothing to do
return;
+ }
if (!cmdmod.lockmarks) {
- /* named marks, lower case and upper case */
+ // named marks, lower case and upper case
for (i = 0; i < NMARKS; i++) {
one_adjust(&(curbuf->b_namedm[i].mark.lnum));
- if (namedfm[i].fmark.fnum == fnum)
+ if (namedfm[i].fmark.fnum == fnum) {
one_adjust_nodel(&(namedfm[i].fmark.mark.lnum));
+ }
}
for (i = NMARKS; i < NGLOBALMARKS; i++) {
- if (namedfm[i].fmark.fnum == fnum)
+ if (namedfm[i].fmark.fnum == fnum) {
one_adjust_nodel(&(namedfm[i].fmark.mark.lnum));
+ }
}
- /* last Insert position */
+ // last Insert position
one_adjust(&(curbuf->b_last_insert.mark.lnum));
- /* last change position */
+ // last change position
one_adjust(&(curbuf->b_last_change.mark.lnum));
- /* last cursor position, if it was set */
- if (!equalpos(curbuf->b_last_cursor.mark, initpos))
+ // last cursor position, if it was set
+ if (!equalpos(curbuf->b_last_cursor.mark, initpos)) {
one_adjust(&(curbuf->b_last_cursor.mark.lnum));
+ }
- /* list of change positions */
- for (i = 0; i < curbuf->b_changelistlen; ++i)
+ // list of change positions
+ for (i = 0; i < curbuf->b_changelistlen; ++i) {
one_adjust_nodel(&(curbuf->b_changelist[i].mark.lnum));
+ }
- /* Visual area */
+ // Visual area
one_adjust_nodel(&(curbuf->b_visual.vi_start.lnum));
one_adjust_nodel(&(curbuf->b_visual.vi_end.lnum));
@@ -1003,29 +1035,31 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2,
}
sign_mark_adjust(line1, line2, amount, amount_after);
- if (op != kExtmarkNOOP) {
- extmark_adjust(curbuf, line1, line2, amount, amount_after, op);
- }
}
- /* previous context mark */
+ if (op != kExtmarkNOOP) {
+ extmark_adjust(curbuf, line1, line2, amount, amount_after, op);
+ }
+
+ // previous context mark
one_adjust(&(curwin->w_pcmark.lnum));
- /* previous pcmark */
+ // previous pcmark
one_adjust(&(curwin->w_prev_pcmark.lnum));
- /* saved cursor for formatting */
- if (saved_cursor.lnum != 0)
+ // saved cursor for formatting
+ if (saved_cursor.lnum != 0) {
one_adjust_nodel(&(saved_cursor.lnum));
+ }
/*
* Adjust items in all windows related to the current buffer.
*/
FOR_ALL_TAB_WINDOWS(tab, win) {
if (!cmdmod.lockmarks) {
- /* Marks in the jumplist. When deleting lines, this may create
- * duplicate marks in the jumplist, they will be removed later. */
- for (i = 0; i < win->w_jumplistlen; ++i) {
+ // Marks in the jumplist. When deleting lines, this may create
+ // duplicate marks in the jumplist, they will be removed later.
+ for (i = 0; i < win->w_jumplistlen; i++) {
if (win->w_jumplist[i].fmark.fnum == fnum) {
one_adjust_nodel(&(win->w_jumplist[i].fmark.mark.lnum));
}
@@ -1034,7 +1068,7 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2,
if (win->w_buffer == curbuf) {
if (!cmdmod.lockmarks) {
- /* marks in the tag stack */
+ // marks in the tag stack
for (i = 0; i < win->w_tagstacklen; i++) {
if (win->w_tagstack[i].fmark.fnum == fnum) {
one_adjust_nodel(&(win->w_tagstack[i].fmark.mark.lnum));
@@ -1042,23 +1076,23 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2,
}
}
- /* the displayed Visual area */
+ // the displayed Visual area
if (win->w_old_cursor_lnum != 0) {
one_adjust_nodel(&(win->w_old_cursor_lnum));
one_adjust_nodel(&(win->w_old_visual_lnum));
}
- /* topline and cursor position for windows with the same buffer
- * other than the current window */
+ // topline and cursor position for windows with the same buffer
+ // other than the current window
if (win != curwin) {
if (win->w_topline >= line1 && win->w_topline <= line2) {
- if (amount == MAXLNUM) { /* topline is deleted */
+ if (amount == MAXLNUM) { // topline is deleted
if (line1 <= 1) {
win->w_topline = 1;
} else {
win->w_topline = line1 - 1;
}
- } else { /* keep topline on the same line */
+ } else { // keep topline on the same line
win->w_topline += amount;
}
win->w_topfill = 0;
@@ -1067,14 +1101,14 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2,
win->w_topfill = 0;
}
if (win->w_cursor.lnum >= line1 && win->w_cursor.lnum <= line2) {
- if (amount == MAXLNUM) { /* line with cursor is deleted */
+ if (amount == MAXLNUM) { // line with cursor is deleted
if (line1 <= 1) {
win->w_cursor.lnum = 1;
} else {
win->w_cursor.lnum = line1 - 1;
}
win->w_cursor.col = 0;
- } else { /* keep cursor on the same line */
+ } else { // keep cursor on the same line
win->w_cursor.lnum += amount;
}
} else if (amount_after && win->w_cursor.lnum > line2) {
@@ -1088,11 +1122,11 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2,
}
}
- /* adjust diffs */
+ // adjust diffs
diff_mark_adjust(line1, line2, amount, amount_after);
}
-/* This code is used often, needs to be fast. */
+// This code is used often, needs to be fast.
#define col_adjust(pp) \
{ \
posp = pp; \
@@ -1115,56 +1149,58 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2,
// position.
// "spaces_removed" is the number of spaces that were removed, matters when the
// cursor is inside them.
-void mark_col_adjust(
- linenr_T lnum, colnr_T mincol, long lnum_amount, long col_amount,
- int spaces_removed)
+void mark_col_adjust(linenr_T lnum, colnr_T mincol, long lnum_amount, long col_amount,
+ int spaces_removed)
{
int i;
int fnum = curbuf->b_fnum;
- pos_T *posp;
-
- if ((col_amount == 0L && lnum_amount == 0L) || cmdmod.lockmarks)
- return; /* nothing to do */
+ pos_T *posp;
- /* named marks, lower case and upper case */
+ if ((col_amount == 0L && lnum_amount == 0L) || cmdmod.lockmarks) {
+ return; // nothing to do
+ }
+ // named marks, lower case and upper case
for (i = 0; i < NMARKS; i++) {
col_adjust(&(curbuf->b_namedm[i].mark));
- if (namedfm[i].fmark.fnum == fnum)
+ if (namedfm[i].fmark.fnum == fnum) {
col_adjust(&(namedfm[i].fmark.mark));
+ }
}
for (i = NMARKS; i < NGLOBALMARKS; i++) {
- if (namedfm[i].fmark.fnum == fnum)
+ if (namedfm[i].fmark.fnum == fnum) {
col_adjust(&(namedfm[i].fmark.mark));
+ }
}
- /* last Insert position */
+ // last Insert position
col_adjust(&(curbuf->b_last_insert.mark));
- /* last change position */
+ // last change position
col_adjust(&(curbuf->b_last_change.mark));
- /* list of change positions */
- for (i = 0; i < curbuf->b_changelistlen; ++i)
+ // list of change positions
+ for (i = 0; i < curbuf->b_changelistlen; ++i) {
col_adjust(&(curbuf->b_changelist[i].mark));
+ }
- /* Visual area */
+ // Visual area
col_adjust(&(curbuf->b_visual.vi_start));
col_adjust(&(curbuf->b_visual.vi_end));
- /* previous context mark */
+ // previous context mark
col_adjust(&(curwin->w_pcmark));
- /* previous pcmark */
+ // previous pcmark
col_adjust(&(curwin->w_prev_pcmark));
- /* saved cursor for formatting */
+ // saved cursor for formatting
col_adjust(&saved_cursor);
/*
* Adjust items in all windows related to the current buffer.
*/
FOR_ALL_WINDOWS_IN_TAB(win, curtab) {
- /* marks in the jumplist */
+ // marks in the jumplist
for (i = 0; i < win->w_jumplistlen; ++i) {
if (win->w_jumplist[i].fmark.fnum == fnum) {
col_adjust(&(win->w_jumplist[i].fmark.mark));
@@ -1172,14 +1208,14 @@ void mark_col_adjust(
}
if (win->w_buffer == curbuf) {
- /* marks in the tag stack */
+ // marks in the tag stack
for (i = 0; i < win->w_tagstacklen; i++) {
if (win->w_tagstack[i].fmark.fnum == fnum) {
col_adjust(&(win->w_tagstack[i].fmark.mark));
}
}
- /* cursor position for other windows with the same buffer */
+ // cursor position for other windows with the same buffer
if (win != curwin) {
col_adjust(&win->w_cursor);
}
@@ -1269,8 +1305,9 @@ void copy_jumplist(win_T *from, win_T *to)
for (i = 0; i < from->w_jumplistlen; ++i) {
to->w_jumplist[i] = from->w_jumplist[i];
- if (from->w_jumplist[i].fname != NULL)
+ if (from->w_jumplist[i].fname != NULL) {
to->w_jumplist[i].fname = vim_strsave(from->w_jumplist[i].fname);
+ }
}
to->w_jumplistlen = from->w_jumplistlen;
to->w_jumplistidx = from->w_jumplistidx;
@@ -1287,18 +1324,17 @@ void copy_jumplist(win_T *from, win_T *to)
///
/// @return Pointer that needs to be passed to next `mark_jumplist_iter` call or
/// NULL if iteration is over.
-const void *mark_jumplist_iter(const void *const iter, const win_T *const win,
- xfmark_T *const fm)
+const void *mark_jumplist_iter(const void *const iter, const win_T *const win, xfmark_T *const fm)
FUNC_ATTR_NONNULL_ARG(2, 3) FUNC_ATTR_WARN_UNUSED_RESULT
{
if (iter == NULL && win->w_jumplistlen == 0) {
- *fm = (xfmark_T) {{{0, 0, 0}, 0, 0, NULL}, NULL};
+ *fm = (xfmark_T) { { { 0, 0, 0 }, 0, 0, NULL }, NULL };
return NULL;
}
const xfmark_T *const iter_mark =
- (iter == NULL
+ (iter == NULL
? &(win->w_jumplist[0])
- : (const xfmark_T *const) iter);
+ : (const xfmark_T *const)iter);
*fm = *iter_mark;
if (iter_mark == &(win->w_jumplist[win->w_jumplistlen - 1])) {
return NULL;
@@ -1318,30 +1354,29 @@ const void *mark_jumplist_iter(const void *const iter, const win_T *const win,
///
/// @return Pointer that needs to be passed to next `mark_global_iter` call or
/// NULL if iteration is over.
-const void *mark_global_iter(const void *const iter, char *const name,
- xfmark_T *const fm)
+const void *mark_global_iter(const void *const iter, char *const name, xfmark_T *const fm)
FUNC_ATTR_NONNULL_ARG(2, 3) FUNC_ATTR_WARN_UNUSED_RESULT
{
*name = NUL;
const xfmark_T *iter_mark = (iter == NULL
? &(namedfm[0])
- : (const xfmark_T *const) iter);
- while ((size_t) (iter_mark - &(namedfm[0])) < ARRAY_SIZE(namedfm)
+ : (const xfmark_T *const)iter);
+ while ((size_t)(iter_mark - &(namedfm[0])) < ARRAY_SIZE(namedfm)
&& !iter_mark->fmark.mark.lnum) {
iter_mark++;
}
- if ((size_t) (iter_mark - &(namedfm[0])) == ARRAY_SIZE(namedfm)
+ if ((size_t)(iter_mark - &(namedfm[0])) == ARRAY_SIZE(namedfm)
|| !iter_mark->fmark.mark.lnum) {
return NULL;
}
- size_t iter_off = (size_t) (iter_mark - &(namedfm[0]));
- *name = (char) (iter_off < NMARKS
- ? 'A' + (char) iter_off
- : '0' + (char) (iter_off - NMARKS));
+ size_t iter_off = (size_t)(iter_mark - &(namedfm[0]));
+ *name = (char)(iter_off < NMARKS
+ ? 'A' + (char)iter_off
+ : '0' + (char)(iter_off - NMARKS));
*fm = *iter_mark;
- while ((size_t) (++iter_mark - &(namedfm[0])) < ARRAY_SIZE(namedfm)) {
+ while ((size_t)(++iter_mark - &(namedfm[0])) < ARRAY_SIZE(namedfm)) {
if (iter_mark->fmark.mark.lnum) {
- return (const void *) iter_mark;
+ return (const void *)iter_mark;
}
}
return NULL;
@@ -1358,34 +1393,27 @@ const void *mark_global_iter(const void *const iter, char *const name,
/// behaviour is undefined.
///
/// @return Pointer to the next mark or NULL.
-static inline const fmark_T *next_buffer_mark(const buf_T *const buf,
- char *const mark_name)
+static inline const fmark_T *next_buffer_mark(const buf_T *const buf, char *const mark_name)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (*mark_name) {
- case NUL: {
- *mark_name = '"';
- return &(buf->b_last_cursor);
- }
- case '"': {
- *mark_name = '^';
- return &(buf->b_last_insert);
- }
- case '^': {
- *mark_name = '.';
- return &(buf->b_last_change);
- }
- case '.': {
- *mark_name = 'a';
- return &(buf->b_namedm[0]);
- }
- case 'z': {
- return NULL;
- }
- default: {
- (*mark_name)++;
- return &(buf->b_namedm[*mark_name - 'a']);
- }
+ case NUL:
+ *mark_name = '"';
+ return &(buf->b_last_cursor);
+ case '"':
+ *mark_name = '^';
+ return &(buf->b_last_insert);
+ case '^':
+ *mark_name = '.';
+ return &(buf->b_last_change);
+ case '.':
+ *mark_name = 'a';
+ return &(buf->b_namedm[0]);
+ case 'z':
+ return NULL;
+ default:
+ (*mark_name)++;
+ return &(buf->b_namedm[*mark_name - 'a']);
}
}
@@ -1401,12 +1429,12 @@ static inline const fmark_T *next_buffer_mark(const buf_T *const buf,
///
/// @return Pointer that needs to be passed to next `mark_buffer_iter` call or
/// NULL if iteration is over.
-const void *mark_buffer_iter(const void *const iter, const buf_T *const buf,
- char *const name, fmark_T *const fm)
+const void *mark_buffer_iter(const void *const iter, const buf_T *const buf, char *const name,
+ fmark_T *const fm)
FUNC_ATTR_NONNULL_ARG(2, 3, 4) FUNC_ATTR_WARN_UNUSED_RESULT
{
*name = NUL;
- char mark_name = (char) (iter == NULL
+ char mark_name = (char)(iter == NULL
? NUL
: (iter == &(buf->b_last_cursor)
? '"'
@@ -1414,8 +1442,8 @@ const void *mark_buffer_iter(const void *const iter, const buf_T *const buf,
? '^'
: (iter == &(buf->b_last_change)
? '.'
- : 'a' + (char) ((const fmark_T *)iter
- - &(buf->b_namedm[0]))))));
+ : 'a' + (char)((const fmark_T *)iter
+ - &(buf->b_namedm[0]))))));
const fmark_T *iter_mark = next_buffer_mark(buf, &mark_name);
while (iter_mark != NULL && iter_mark->mark.lnum == 0) {
iter_mark = next_buffer_mark(buf, &mark_name);
@@ -1423,14 +1451,14 @@ const void *mark_buffer_iter(const void *const iter, const buf_T *const buf,
if (iter_mark == NULL) {
return NULL;
}
- size_t iter_off = (size_t) (iter_mark - &(buf->b_namedm[0]));
+ size_t iter_off = (size_t)(iter_mark - &(buf->b_namedm[0]));
if (mark_name) {
*name = mark_name;
} else {
- *name = (char) ('a' + (char) iter_off);
+ *name = (char)('a' + (char)iter_off);
}
*fm = *iter_mark;
- return (const void *) iter_mark;
+ return (const void *)iter_mark;
}
/// Set global mark
@@ -1467,8 +1495,7 @@ bool mark_set_global(const char name, const xfmark_T fm, const bool update)
/// later then existing one.
///
/// @return true on success, false on failure.
-bool mark_set_local(const char name, buf_T *const buf,
- const fmark_T fm, const bool update)
+bool mark_set_local(const char name, buf_T *const buf, const fmark_T fm, const bool update)
FUNC_ATTR_NONNULL_ALL
{
fmark_T *fm_tgt = NULL;
@@ -1556,8 +1583,7 @@ void mark_mb_adjustpos(buf_T *buf, pos_T *lp)
// Add information about mark 'mname' to list 'l'
-static int add_mark(list_T *l, const char *mname, const pos_T *pos, int bufnr,
- const char *fname)
+static int add_mark(list_T *l, const char *mname, const pos_T *pos, int bufnr, const char *fname)
FUNC_ATTR_NONNULL_ARG(1, 2, 3)
{
if (pos->lnum <= 0) {
@@ -1611,6 +1637,15 @@ void get_buf_local_marks(const buf_T *buf, list_T *l)
add_mark(l, "'>", &buf->b_visual.vi_end, buf->b_fnum, NULL);
}
+/// Get a global mark
+///
+/// @param[in] Name of named mark
+/// @param[out] Global/file mark
+xfmark_T get_global_mark(char name)
+{
+ return namedfm[mark_global_index(name)];
+}
+
/// Get information about global marks ('A' to 'Z' and '0' to '9')
///
/// @param[out] l List to store global marks
diff --git a/src/nvim/mark.h b/src/nvim/mark.h
index b3d9b5d95a..a55f733d9a 100644
--- a/src/nvim/mark.h
+++ b/src/nvim/mark.h
@@ -1,55 +1,55 @@
#ifndef NVIM_MARK_H
#define NVIM_MARK_H
-#include "nvim/macros.h"
#include "nvim/ascii.h"
#include "nvim/buffer_defs.h"
+#include "nvim/ex_cmds_defs.h" // for exarg_T
+#include "nvim/extmark_defs.h"
#include "nvim/func_attr.h"
+#include "nvim/macros.h"
#include "nvim/mark_defs.h"
-#include "nvim/extmark_defs.h"
#include "nvim/memory.h"
-#include "nvim/pos.h"
#include "nvim/os/time.h"
-#include "nvim/ex_cmds_defs.h" // for exarg_T
+#include "nvim/pos.h"
/// Set fmark using given value
#define SET_FMARK(fmarkp_, mark_, fnum_) \
- do { \
- fmark_T *const fmarkp__ = fmarkp_; \
- fmarkp__->mark = mark_; \
- fmarkp__->fnum = fnum_; \
- fmarkp__->timestamp = os_time(); \
- fmarkp__->additional_data = NULL; \
- } while (0)
+ do { \
+ fmark_T *const fmarkp__ = fmarkp_; \
+ fmarkp__->mark = mark_; \
+ fmarkp__->fnum = fnum_; \
+ fmarkp__->timestamp = os_time(); \
+ fmarkp__->additional_data = NULL; \
+ } while (0)
/// Free and set fmark using given value
#define RESET_FMARK(fmarkp_, mark_, fnum_) \
- do { \
- fmark_T *const fmarkp___ = fmarkp_; \
- free_fmark(*fmarkp___); \
- SET_FMARK(fmarkp___, mark_, fnum_); \
- } while (0)
+ do { \
+ fmark_T *const fmarkp___ = fmarkp_; \
+ free_fmark(*fmarkp___); \
+ SET_FMARK(fmarkp___, mark_, fnum_); \
+ } while (0)
/// Clear given fmark
#define CLEAR_FMARK(fmarkp_) \
- RESET_FMARK(fmarkp_, ((pos_T) { 0, 0, 0 }), 0)
+ RESET_FMARK(fmarkp_, ((pos_T) { 0, 0, 0 }), 0)
/// Set given extended mark (regular mark + file name)
#define SET_XFMARK(xfmarkp_, mark_, fnum_, fname_) \
- do { \
- xfmark_T *const xfmarkp__ = xfmarkp_; \
- xfmarkp__->fname = fname_; \
- SET_FMARK(&(xfmarkp__->fmark), mark_, fnum_); \
- } while (0)
+ do { \
+ xfmark_T *const xfmarkp__ = xfmarkp_; \
+ xfmarkp__->fname = fname_; \
+ SET_FMARK(&(xfmarkp__->fmark), mark_, fnum_); \
+ } while (0)
/// Free and set given extended mark (regular mark + file name)
#define RESET_XFMARK(xfmarkp_, mark_, fnum_, fname_) \
- do { \
- xfmark_T *const xfmarkp__ = xfmarkp_; \
- free_xfmark(*xfmarkp__); \
- xfmarkp__->fname = fname_; \
- SET_FMARK(&(xfmarkp__->fmark), mark_, fnum_); \
- } while (0)
+ do { \
+ xfmark_T *const xfmarkp__ = xfmarkp_; \
+ free_xfmark(*xfmarkp__); \
+ xfmarkp__->fname = fname_; \
+ SET_FMARK(&(xfmarkp__->fmark), mark_, fnum_); \
+ } while (0)
/// Convert mark name to the offset
static inline int mark_global_index(const char name)
diff --git a/src/nvim/mark_defs.h b/src/nvim/mark_defs.h
index 2cb489501e..51199a09e0 100644
--- a/src/nvim/mark_defs.h
+++ b/src/nvim/mark_defs.h
@@ -1,9 +1,9 @@
#ifndef NVIM_MARK_DEFS_H
#define NVIM_MARK_DEFS_H
-#include "nvim/pos.h"
-#include "nvim/os/time.h"
#include "nvim/eval/typval.h"
+#include "nvim/os/time.h"
+#include "nvim/pos.h"
/*
* marks: positions in a file
@@ -42,7 +42,7 @@ typedef struct filemark {
/// Structure defining extended mark (mark with file name attached)
typedef struct xfilemark {
fmark_T fmark; ///< Actual mark.
- char_u *fname; ///< File name, used when fnum == 0.
+ char_u *fname; ///< File name, used when fnum == 0.
} xfmark_T;
#endif // NVIM_MARK_DEFS_H
diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c
index a04f250fc3..39c1e36147 100644
--- a/src/nvim/marktree.c
+++ b/src/nvim/marktree.c
@@ -49,9 +49,9 @@
#include <assert.h>
-#include "nvim/marktree.h"
-#include "nvim/lib/kvec.h"
#include "nvim/garray.h"
+#include "nvim/lib/kvec.h"
+#include "nvim/marktree.h"
#define T MT_BRANCH_FACTOR
#define ILEN (sizeof(mtnode_t)+(2 * T) * sizeof(void *))
@@ -137,7 +137,9 @@ static inline int marktree_getp_aux(const mtnode_t *x, mtkey_t k, int *r)
end = mid;
}
}
- if (begin == x->n) { *rr = 1; return x->n - 1; }
+ if (begin == x->n) {
+ *rr = 1; return x->n - 1;
+ }
if ((*rr = key_cmp(k, x->key[begin])) < 0) {
begin--;
}
@@ -232,9 +234,8 @@ uint64_t marktree_put(MarkTree *b, int row, int col, bool right_gravity)
return id;
}
-uint64_t marktree_put_pair(MarkTree *b,
- int start_row, int start_col, bool start_right,
- int end_row, int end_col, bool end_right)
+uint64_t marktree_put_pair(MarkTree *b, int start_row, int start_col, bool start_right, int end_row,
+ int end_col, bool end_right)
{
uint64_t id = (b->next_id+=ID_INCR)|PAIRED;
uint64_t start_id = id|(start_right?RIGHT_GRAVITY:0);
@@ -466,7 +467,7 @@ static mtnode_t *merge_node(MarkTree *b, mtnode_t *p, int i)
unrelative(x->key[x->n].pos, &x->key[x->n+1+k].pos);
}
if (x->level) {
- memmove(&x->ptr[x->n+1], y->ptr, (size_t)(y->n + 1) * sizeof(mtnode_t *));
+ memmove(&x->ptr[x->n+1], y->ptr, ((size_t)y->n + 1) * sizeof(mtnode_t *));
for (int k = 0; k < y->n+1; k++) {
x->ptr[x->n+k+1]->parent = x;
}
@@ -488,7 +489,7 @@ static void pivot_right(MarkTree *b, mtnode_t *p, int i)
mtnode_t *x = p->ptr[i], *y = p->ptr[i+1];
memmove(&y->key[1], y->key, (size_t)y->n * sizeof(mtkey_t));
if (y->level) {
- memmove(&y->ptr[1], y->ptr, (size_t)(y->n + 1) * sizeof(mtnode_t *));
+ memmove(&y->ptr[1], y->ptr, ((size_t)y->n + 1) * sizeof(mtnode_t *));
}
y->key[0] = p->key[i];
refkey(b, y, 0);
@@ -594,8 +595,8 @@ bool marktree_itr_get(MarkTree *b, int row, int col, MarkTreeIter *itr)
itr, false, false, NULL);
}
-bool marktree_itr_get_ext(MarkTree *b, mtpos_t p, MarkTreeIter *itr,
- bool last, bool gravity, mtpos_t *oldbase)
+bool marktree_itr_get_ext(MarkTree *b, mtpos_t p, MarkTreeIter *itr, bool last, bool gravity,
+ mtpos_t *oldbase)
{
mtkey_t k = { .pos = p, .id = gravity ? RIGHT_GRAVITY : 0 };
if (last && !gravity) {
@@ -695,8 +696,7 @@ bool marktree_itr_next(MarkTree *b, MarkTreeIter *itr)
return marktree_itr_next_skip(b, itr, false, NULL);
}
-static bool marktree_itr_next_skip(MarkTree *b, MarkTreeIter *itr, bool skip,
- mtpos_t oldbase[])
+static bool marktree_itr_next_skip(MarkTree *b, MarkTreeIter *itr, bool skip, mtpos_t oldbase[])
{
if (!itr->node) {
return false;
@@ -819,8 +819,8 @@ mtmark_t marktree_itr_current(MarkTreeIter *itr)
mtpos_t pos = marktree_itr_pos(itr);
mtmark_t mark = { .row = pos.row,
.col = pos.col,
- .id = ANTIGRAVITY(keyid),
- .right_gravity = keyid & RIGHT_GRAVITY };
+ .id = ANTIGRAVITY(keyid),
+ .right_gravity = keyid & RIGHT_GRAVITY };
return mark;
}
return (mtmark_t){ -1, -1, 0, false };
@@ -833,14 +833,12 @@ static void swap_id(uint64_t *id1, uint64_t *id2)
*id2 = temp;
}
-bool marktree_splice(MarkTree *b,
- int start_line, int start_col,
- int old_extent_line, int old_extent_col,
- int new_extent_line, int new_extent_col)
+bool marktree_splice(MarkTree *b, int start_line, int start_col, int old_extent_line,
+ int old_extent_col, int new_extent_line, int new_extent_col)
{
mtpos_t start = { start_line, start_col };
- mtpos_t old_extent = { (int)old_extent_line, old_extent_col };
- mtpos_t new_extent = { (int)new_extent_line, new_extent_col };
+ mtpos_t old_extent = { old_extent_line, old_extent_col };
+ mtpos_t new_extent = { new_extent_line, new_extent_col };
bool may_delete = (old_extent.row != 0 || old_extent.col != 0);
bool same_line = old_extent.row == 0 && new_extent.row == 0;
@@ -903,7 +901,7 @@ continue_same_node:
refkey(b, itr->node, itr->i);
refkey(b, enditr->node, enditr->i);
} else {
- past_right = true; // NOLINT
+ past_right = true; // NOLINT
(void)past_right;
break;
}
@@ -994,10 +992,8 @@ past_continue_same_node:
return moved;
}
-void marktree_move_region(MarkTree *b,
- int start_row, colnr_T start_col,
- int extent_row, colnr_T extent_col,
- int new_row, colnr_T new_col)
+void marktree_move_region(MarkTree *b, int start_row, colnr_T start_col, int extent_row,
+ colnr_T extent_col, int new_row, colnr_T new_col)
{
mtpos_t start = { start_row, start_col }, size = { extent_row, extent_col };
mtpos_t end = size;
@@ -1114,8 +1110,7 @@ void marktree_check(MarkTree *b)
}
#ifndef NDEBUG
-static size_t check_node(MarkTree *b, mtnode_t *x,
- mtpos_t *last, bool *last_right)
+static size_t check_node(MarkTree *b, mtnode_t *x, mtpos_t *last, bool *last_right)
{
assert(x->n <= 2 * T - 1);
// TODO(bfredl): too strict if checking "in repair" post-delete tree.
@@ -1173,8 +1168,7 @@ char *mt_inspect_rec(MarkTree *b)
void mt_inspect_node(MarkTree *b, garray_T *ga, mtnode_t *n, mtpos_t off)
{
static char buf[1024];
-#define GA_PUT(x) ga_concat(ga, (char_u *)(x))
- GA_PUT("[");
+ ga_concat(ga, "[");
if (n->level) {
mt_inspect_node(b, ga, n->ptr[0], off);
}
@@ -1182,14 +1176,13 @@ void mt_inspect_node(MarkTree *b, garray_T *ga, mtnode_t *n, mtpos_t off)
mtpos_t p = n->key[i].pos;
unrelative(off, &p);
snprintf((char *)buf, sizeof(buf), "%d/%d", p.row, p.col);
- GA_PUT(buf);
+ ga_concat(ga, buf);
if (n->level) {
mt_inspect_node(b, ga, n->ptr[i+1], p);
} else {
- GA_PUT(",");
+ ga_concat(ga, ",");
}
}
- GA_PUT("]");
-#undef GA_PUT
+ ga_concat(ga, "]");
}
diff --git a/src/nvim/marktree.h b/src/nvim/marktree.h
index 7af23765c3..02f73b8052 100644
--- a/src/nvim/marktree.h
+++ b/src/nvim/marktree.h
@@ -2,9 +2,10 @@
#define NVIM_MARKTREE_H
#include <stdint.h>
-#include "nvim/pos.h"
-#include "nvim/map.h"
+
#include "nvim/garray.h"
+#include "nvim/map.h"
+#include "nvim/pos.h"
#define MT_MAX_DEPTH 20
#define MT_BRANCH_FACTOR 10
diff --git a/src/nvim/math.c b/src/nvim/math.c
index 63309b6f7a..63a29509bd 100644
--- a/src/nvim/math.c
+++ b/src/nvim/math.c
@@ -21,9 +21,12 @@ int xfpclassify(double d)
m = 0xfffffffffffffULL & m;
switch (e) {
- default: return FP_NORMAL;
- case 0x000: return m ? FP_SUBNORMAL : FP_ZERO;
- case 0x7ff: return m ? FP_NAN : FP_INFINITE;
+ default:
+ return FP_NORMAL;
+ case 0x000:
+ return m ? FP_SUBNORMAL : FP_ZERO;
+ case 0x7ff:
+ return m ? FP_NAN : FP_INFINITE;
}
}
int xisinf(double d)
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index fea1ab77a2..62cc3b56ed 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -190,9 +190,9 @@ enc_canon_table[] =
#define IDX_BIG5 29
{ "big5", ENC_DBCS, DBCS_CHT },
- /* MS-DOS and MS-Windows codepages are included here, so that they can be
- * used on Unix too. Most of them are similar to ISO-8859 encodings, but
- * not exactly the same. */
+ // MS-DOS and MS-Windows codepages are included here, so that they can be
+ // used on Unix too. Most of them are similar to ISO-8859 encodings, but
+ // not exactly the same.
#define IDX_CP437 30
{ "cp437", ENC_8BIT, 437 }, // like iso-8859-1
#define IDX_CP737 31
@@ -1066,8 +1066,8 @@ bool utf_printable(int c)
*/
return iswprint(c);
#else
- /* Sorted list of non-overlapping intervals.
- * 0xd800-0xdfff is reserved for UTF-16, actually illegal. */
+ // Sorted list of non-overlapping intervals.
+ // 0xd800-0xdfff is reserved for UTF-16, actually illegal.
static struct interval nonprint[] =
{
{ 0x070f, 0x070f }, { 0x180b, 0x180e }, { 0x200b, 0x200f }, { 0x202a, 0x202e },
@@ -1354,12 +1354,12 @@ static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1, size_t n2
return c1 == 0 ? -1 : 1;
}
- /* Continue with bytewise comparison to produce some result that
- * would make comparison operations involving this function transitive.
- *
- * If only one string had an error, comparison should be made with
- * folded version of the other string. In this case it is enough
- * to fold just one character to determine the result of comparison. */
+ // Continue with bytewise comparison to produce some result that
+ // would make comparison operations involving this function transitive.
+ //
+ // If only one string had an error, comparison should be made with
+ // folded version of the other string. In this case it is enough
+ // to fold just one character to determine the result of comparison.
if (c1 != -1 && c2 == -1) {
n1 = utf_char2bytes(utf_fold(c1), buffer);
@@ -1395,9 +1395,9 @@ static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1, size_t n2
}
#ifdef WIN32
-#ifndef CP_UTF8
-# define CP_UTF8 65001 // magic number from winnls.h
-#endif
+# ifndef CP_UTF8
+# define CP_UTF8 65001 // magic number from winnls.h
+# endif
/// Converts string from UTF-8 to UTF-16.
///
@@ -1637,8 +1637,8 @@ int utf_head_off(const char_u *base, const char_u *p)
while (q > base && (*q & 0xc0) == 0x80) {
--q;
}
- /* Check for illegal sequence. Do allow an illegal byte after where we
- * started. */
+ // Check for illegal sequence. Do allow an illegal byte after where we
+ // started.
len = utf8len_tab[*q];
if (len != (int)(s - q + 1) && len != (int)(p - q + 1)) {
return 0;
@@ -1999,7 +1999,7 @@ void mb_check_adjust_col(void *win_)
/// @param line start of the string
///
/// @return a pointer to the character before "*p", if there is one.
-char_u * mb_prevptr(char_u *line, char_u *p)
+char_u *mb_prevptr(char_u *line, char_u *p)
{
if (p > line) {
MB_PTR_BACK(line, p);
@@ -2099,7 +2099,7 @@ const char *mb_unescape(const char **const pp)
/*
* Skip the Vim specific head of a 'encoding' name.
*/
-char_u * enc_skip(char_u *p)
+char_u *enc_skip(char_u *p)
{
if (STRNCMP(p, "2byte-", 6) == 0) {
return p + 6;
@@ -2202,19 +2202,19 @@ static int enc_alias_search(char_u *name)
* Get the canonicalized encoding of the current locale.
* Returns an allocated string when successful, NULL when not.
*/
-char_u * enc_locale(void)
+char_u *enc_locale(void)
{
int i;
char buf[50];
const char *s;
-# ifdef HAVE_NL_LANGINFO_CODESET
+#ifdef HAVE_NL_LANGINFO_CODESET
if (!(s = nl_langinfo(CODESET)) || *s == NUL)
-# endif
+#endif
{
-# if defined(HAVE_LOCALE_H)
+#if defined(HAVE_LOCALE_H)
if (!(s = setlocale(LC_CTYPE, NULL)) || *s == NUL)
-# endif
+#endif
{
if ((s = os_getenv("LC_ALL"))) {
if ((s = os_getenv("LC_CTYPE"))) {
@@ -2265,7 +2265,7 @@ enc_locale_copy_enc:
return enc_canonize((char_u *)buf);
}
-# if defined(HAVE_ICONV)
+#if defined(HAVE_ICONV)
/*
@@ -2274,10 +2274,10 @@ enc_locale_copy_enc:
* Returns (void *)-1 if failed.
* (should return iconv_t, but that causes problems with prototypes).
*/
-void * my_iconv_open(char_u *to, char_u *from)
+void *my_iconv_open(char_u *to, char_u *from)
{
iconv_t fd;
-#define ICONV_TESTLEN 400
+# define ICONV_TESTLEN 400
char_u tobuf[ICONV_TESTLEN];
char *p;
size_t tolen;
@@ -2335,8 +2335,8 @@ static char_u *iconv_string(const vimconv_T *const vcp, char_u *str, size_t slen
fromlen = slen;
for (;; ) {
if (len == 0 || ICONV_ERRNO == ICONV_E2BIG) {
- /* Allocate enough room for most conversions. When re-allocating
- * increase the buffer size. */
+ // Allocate enough room for most conversions. When re-allocating
+ // increase the buffer size.
len = len + fromlen * 2 + 40;
p = xmalloc(len);
if (done > 0) {
@@ -2395,7 +2395,7 @@ static char_u *iconv_string(const vimconv_T *const vcp, char_u *str, size_t slen
return result;
}
-# endif // HAVE_ICONV
+#endif // HAVE_ICONV
@@ -2425,11 +2425,11 @@ int convert_setup_ext(vimconv_T *vcp, char_u *from, bool from_unicode_is_utf8, c
int to_is_utf8;
// Reset to no conversion.
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
if (vcp->vc_type == CONV_ICONV && vcp->vc_fd != (iconv_t)-1) {
iconv_close(vcp->vc_fd);
}
-# endif
+#endif
*vcp = (vimconv_T)MBYTE_NONE_CONV;
// No conversion when one of the names is empty or they are equal.
@@ -2466,7 +2466,7 @@ int convert_setup_ext(vimconv_T *vcp, char_u *from, bool from_unicode_is_utf8, c
// Internal utf-8 -> latin9 conversion.
vcp->vc_type = CONV_TO_LATIN9;
}
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
else { // NOLINT(readability/braces)
// Use iconv() for conversion.
vcp->vc_fd = (iconv_t)my_iconv_open(to_is_utf8 ? (char_u *)"utf-8" : to,
@@ -2476,7 +2476,7 @@ int convert_setup_ext(vimconv_T *vcp, char_u *from, bool from_unicode_is_utf8, c
vcp->vc_factor = 4; // could be longer too...
}
}
-# endif
+#endif
if (vcp->vc_type == CONV_NONE) {
return FAIL;
}
@@ -2501,8 +2501,8 @@ char_u *string_convert(const vimconv_T *const vcp, char_u *ptr, size_t *lenp)
* an incomplete sequence at the end it is not converted and "*unconvlenp" is
* set to the number of remaining bytes.
*/
-char_u * string_convert_ext(const vimconv_T *const vcp, char_u *ptr, size_t *lenp,
- size_t *unconvlenp)
+char_u *string_convert_ext(const vimconv_T *const vcp, char_u *ptr, size_t *lenp,
+ size_t *unconvlenp)
{
char_u *retval = NULL;
char_u *d;
@@ -2644,11 +2644,11 @@ char_u * string_convert_ext(const vimconv_T *const vcp, char_u *ptr, size_t *len
}
break;
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
case CONV_ICONV: // conversion with vcp->vc_fd
retval = iconv_string(vcp, ptr, len, unconvlenp, lenp);
break;
-# endif
+#endif
}
return retval;
diff --git a/src/nvim/mbyte.h b/src/nvim/mbyte.h
index 536d58be1f..9926f27411 100644
--- a/src/nvim/mbyte.h
+++ b/src/nvim/mbyte.h
@@ -1,12 +1,12 @@
#ifndef NVIM_MBYTE_H
#define NVIM_MBYTE_H
-#include <stdint.h>
#include <stdbool.h>
+#include <stdint.h>
#include <string.h>
-#include "nvim/iconv.h"
#include "nvim/func_attr.h"
+#include "nvim/iconv.h"
#include "nvim/os/os_defs.h" // For indirect
#include "nvim/types.h" // for char_u
@@ -22,21 +22,21 @@
// max length of an unicode char
#define MB_MAXCHAR 6
-/* properties used in enc_canon_table[] (first three mutually exclusive) */
+// properties used in enc_canon_table[] (first three mutually exclusive)
#define ENC_8BIT 0x01
#define ENC_DBCS 0x02
#define ENC_UNICODE 0x04
-#define ENC_ENDIAN_B 0x10 /* Unicode: Big endian */
-#define ENC_ENDIAN_L 0x20 /* Unicode: Little endian */
+#define ENC_ENDIAN_B 0x10 // Unicode: Big endian
+#define ENC_ENDIAN_L 0x20 // Unicode: Little endian
-#define ENC_2BYTE 0x40 /* Unicode: UCS-2 */
-#define ENC_4BYTE 0x80 /* Unicode: UCS-4 */
-#define ENC_2WORD 0x100 /* Unicode: UTF-16 */
+#define ENC_2BYTE 0x40 // Unicode: UCS-2
+#define ENC_4BYTE 0x80 // Unicode: UCS-4
+#define ENC_2WORD 0x100 // Unicode: UTF-16
-#define ENC_LATIN1 0x200 /* Latin1 */
-#define ENC_LATIN9 0x400 /* Latin9 */
-#define ENC_MACROMAN 0x800 /* Mac Roman (not Macro Man! :-) */
+#define ENC_LATIN1 0x200 // Latin1
+#define ENC_LATIN9 0x400 // Latin9
+#define ENC_MACROMAN 0x800 // Mac Roman (not Macro Man! :-)
// TODO(bfredl): eventually we should keep only one of the namings
#define mb_ptr2len utfc_ptr2len
@@ -63,9 +63,9 @@ typedef enum {
typedef struct {
int vc_type; ///< Zero or more ConvFlags.
int vc_factor; ///< Maximal expansion factor.
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
iconv_t vc_fd; ///< Value for CONV_ICONV.
-# endif
+#endif
bool vc_fail; ///< What to do with invalid characters: if true, fail,
///< otherwise use '?'.
} vimconv_T;
diff --git a/src/nvim/memfile.c b/src/nvim/memfile.c
index 7bed644da3..438340e0c4 100644
--- a/src/nvim/memfile.c
+++ b/src/nvim/memfile.c
@@ -39,24 +39,24 @@
/// mf_fullname() make file name full path (use before first :cd)
#include <assert.h>
+#include <fcntl.h>
#include <inttypes.h>
#include <limits.h>
-#include <string.h>
#include <stdbool.h>
-#include <fcntl.h>
+#include <string.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/memfile.h"
+#include "nvim/assert.h"
#include "nvim/fileio.h"
+#include "nvim/memfile.h"
#include "nvim/memline.h"
-#include "nvim/message.h"
#include "nvim/memory.h"
+#include "nvim/message.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
-#include "nvim/assert.h"
-#include "nvim/os/os.h"
-#include "nvim/os/input.h"
+#include "nvim/vim.h"
#define MEMFILE_PAGE_SIZE 4096 /// default page size
@@ -168,7 +168,7 @@ void mf_close(memfile_T *mfp, bool del_file)
return;
}
if (mfp->mf_fd >= 0 && close(mfp->mf_fd) < 0) {
- EMSG(_(e_swapclose));
+ EMSG(_(e_swapclose));
}
if (del_file && mfp->mf_fname != NULL) {
os_remove((char *)mfp->mf_fname);
@@ -282,14 +282,16 @@ bhdr_T *mf_new(memfile_T *mfp, bool negative, unsigned page_count)
bhdr_T *mf_get(memfile_T *mfp, blocknr_T nr, unsigned page_count)
{
// check block number exists
- if (nr >= mfp->mf_blocknr_max || nr <= mfp->mf_blocknr_min)
+ if (nr >= mfp->mf_blocknr_max || nr <= mfp->mf_blocknr_min) {
return NULL;
+ }
// see if it is in the cache
bhdr_T *hp = mf_find_hash(mfp, nr);
if (hp == NULL) { // not in the hash list
- if (nr < 0 || nr >= mfp->mf_infile_count) // can't be in the file
+ if (nr < 0 || nr >= mfp->mf_infile_count) { // can't be in the file
return NULL;
+ }
// could check here if the block is in the free list
@@ -331,8 +333,9 @@ void mf_put(memfile_T *mfp, bhdr_T *hp, bool dirty, bool infile)
mfp->mf_dirty = true;
}
hp->bh_flags = flags;
- if (infile)
+ if (infile) {
mf_trans_add(mfp, hp); // may translate negative in positive nr
+ }
}
/// Signal block as no longer used (may put it in the free list).
@@ -381,32 +384,38 @@ int mf_sync(memfile_T *mfp, int flags)
// fails then we give up.
int status = OK;
bhdr_T *hp;
- for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
+ for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev) {
if (((flags & MFS_ALL) || hp->bh_bnum >= 0)
&& (hp->bh_flags & BH_DIRTY)
&& (status == OK || (hp->bh_bnum >= 0
&& hp->bh_bnum < mfp->mf_infile_count))) {
- if ((flags & MFS_ZERO) && hp->bh_bnum != 0)
+ if ((flags & MFS_ZERO) && hp->bh_bnum != 0) {
continue;
+ }
if (mf_write(mfp, hp) == FAIL) {
- if (status == FAIL) // double error: quit syncing
+ if (status == FAIL) { // double error: quit syncing
break;
+ }
status = FAIL;
}
if (flags & MFS_STOP) { // Stop when char available now.
- if (os_char_avail())
+ if (os_char_avail()) {
break;
+ }
} else {
os_breakcheck();
}
- if (got_int)
+ if (got_int) {
break;
+ }
}
+ }
// If the whole list is flushed, the memfile is not dirty anymore.
// In case of an error, dirty flag is also set, to avoid trying all the time.
- if (hp == NULL || status == FAIL)
+ if (hp == NULL || status == FAIL) {
mfp->mf_dirty = false;
+ }
if (flags & MFS_FLUSH) {
if (os_fsync(mfp->mf_fd)) {
@@ -465,15 +474,17 @@ static void mf_ins_used(memfile_T *mfp, bhdr_T *hp)
/// Remove block from memfile's used list.
static void mf_rem_used(memfile_T *mfp, bhdr_T *hp)
{
- if (hp->bh_next == NULL) // last block in used list
+ if (hp->bh_next == NULL) { // last block in used list
mfp->mf_used_last = hp->bh_prev;
- else
+ } else {
hp->bh_next->bh_prev = hp->bh_prev;
+ }
- if (hp->bh_prev == NULL) // first block in used list
+ if (hp->bh_prev == NULL) { // first block in used list
mfp->mf_used_first = hp->bh_next;
- else
+ } else {
hp->bh_prev->bh_next = hp->bh_next;
+ }
}
/// Release as many blocks as possible.
@@ -554,8 +565,9 @@ static bhdr_T *mf_rem_free(memfile_T *mfp)
/// - Error reading file.
static int mf_read(memfile_T *mfp, bhdr_T *hp)
{
- if (mfp->mf_fd < 0) // there is no file, can't read
+ if (mfp->mf_fd < 0) { // there is no file, can't read
return FAIL;
+ }
unsigned page_size = mfp->mf_page_size;
// TODO(elmart): Check (page_size * hp->bh_bnum) within off_T bounds.
@@ -592,12 +604,15 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp)
unsigned page_count; // number of pages written
unsigned size; // number of bytes written
- if (mfp->mf_fd < 0) // there is no file, can't write
+ if (mfp->mf_fd < 0) { // there is no file, can't write
return FAIL;
+ }
- if (hp->bh_bnum < 0) // must assign file block number
- if (mf_trans_add(mfp, hp) == FAIL)
+ if (hp->bh_bnum < 0) { // must assign file block number
+ if (mf_trans_add(mfp, hp) == FAIL) {
return FAIL;
+ }
+ }
page_size = mfp->mf_page_size;
@@ -620,10 +635,11 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp)
PERROR(_("E296: Seek error in swap file write"));
return FAIL;
}
- if (hp2 == NULL) // freed block, fill with dummy data
+ if (hp2 == NULL) { // freed block, fill with dummy data
page_count = 1;
- else
+ } else {
page_count = hp2->bh_page_count;
+ }
size = page_size * page_count;
void *data = (hp2 == NULL) ? hp->bh_data : hp2->bh_data;
if ((unsigned)write_eintr(mfp->mf_fd, data, size) != size) {
@@ -631,18 +647,22 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp)
/// disk is full. We give the message again only after a successful
/// write or when hitting a key. We keep on trying, in case some
/// space becomes available.
- if (!did_swapwrite_msg)
+ if (!did_swapwrite_msg) {
EMSG(_("E297: Write error in swap file"));
+ }
did_swapwrite_msg = true;
return FAIL;
}
did_swapwrite_msg = false;
- if (hp2 != NULL) // written a non-dummy block
+ if (hp2 != NULL) { // written a non-dummy block
hp2->bh_flags &= ~BH_DIRTY;
- if (nr + (blocknr_T)page_count > mfp->mf_infile_count) // appended to file
+ }
+ if (nr + (blocknr_T)page_count > mfp->mf_infile_count) { // appended to file
mfp->mf_infile_count = nr + page_count;
- if (nr == hp->bh_bnum) // written the desired block
+ }
+ if (nr == hp->bh_bnum) { // written the desired block
break;
+ }
}
return OK;
}
@@ -653,8 +673,9 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp)
/// FAIL On failure.
static int mf_trans_add(memfile_T *mfp, bhdr_T *hp)
{
- if (hp->bh_bnum >= 0) // it's already positive
+ if (hp->bh_bnum >= 0) { // it's already positive
return OK;
+ }
mf_blocknr_trans_item_T *np = xmalloc(sizeof(mf_blocknr_trans_item_T));
@@ -702,8 +723,9 @@ blocknr_T mf_trans_del(memfile_T *mfp, blocknr_T old_nr)
mf_blocknr_trans_item_T *np =
(mf_blocknr_trans_item_T *)mf_hash_find(&mfp->mf_trans, old_nr);
- if (np == NULL) // not found
+ if (np == NULL) { // not found
return old_nr;
+ }
mfp->mf_neg_count--;
blocknr_T new_bnum = np->nt_new_bnum;
@@ -834,8 +856,9 @@ static void mf_hash_free_all(mf_hashtab_T *mht)
static mf_hashitem_T *mf_hash_find(mf_hashtab_T *mht, blocknr_T key)
{
mf_hashitem_T *mhi = mht->mht_buckets[(size_t)key & mht->mht_mask];
- while (mhi != NULL && mhi->mhi_key != key)
+ while (mhi != NULL && mhi->mhi_key != key) {
mhi = mhi->mhi_next;
+ }
return mhi;
}
@@ -845,8 +868,9 @@ static void mf_hash_add_item(mf_hashtab_T *mht, mf_hashitem_T *mhi)
size_t idx = (size_t)mhi->mhi_key & mht->mht_mask;
mhi->mhi_next = mht->mht_buckets[idx];
mhi->mhi_prev = NULL;
- if (mhi->mhi_next != NULL)
+ if (mhi->mhi_next != NULL) {
mhi->mhi_next->mhi_prev = mhi;
+ }
mht->mht_buckets[idx] = mhi;
mht->mht_count++;
@@ -861,14 +885,16 @@ static void mf_hash_add_item(mf_hashtab_T *mht, mf_hashitem_T *mhi)
/// Remove item from hashtable. Item must be non NULL and within hashtable.
static void mf_hash_rem_item(mf_hashtab_T *mht, mf_hashitem_T *mhi)
{
- if (mhi->mhi_prev == NULL)
+ if (mhi->mhi_prev == NULL) {
mht->mht_buckets[(size_t)mhi->mhi_key & mht->mht_mask] =
mhi->mhi_next;
- else
+ } else {
mhi->mhi_prev->mhi_next = mhi->mhi_next;
+ }
- if (mhi->mhi_next != NULL)
+ if (mhi->mhi_next != NULL) {
mhi->mhi_next->mhi_prev = mhi->mhi_prev;
+ }
mht->mht_count--;
@@ -884,8 +910,9 @@ static void mf_hash_grow(mf_hashtab_T *mht)
mf_hashitem_T **buckets = xcalloc(1, size);
int shift = 0;
- while ((mht->mht_mask >> shift) != 0)
+ while ((mht->mht_mask >> shift) != 0) {
shift++;
+ }
for (size_t i = 0; i <= mht->mht_mask; i++) {
/// Traverse the items in the i-th original bucket and move them into
@@ -914,13 +941,16 @@ static void mf_hash_grow(mf_hashtab_T *mht)
}
}
- for (size_t j = 0; j < MHT_GROWTH_FACTOR; j++)
- if (tails[j] != NULL)
+ for (size_t j = 0; j < MHT_GROWTH_FACTOR; j++) {
+ if (tails[j] != NULL) {
tails[j]->mhi_next = NULL;
+ }
+ }
}
- if (mht->mht_buckets != mht->mht_small_buckets)
+ if (mht->mht_buckets != mht->mht_small_buckets) {
xfree(mht->mht_buckets);
+ }
mht->mht_buckets = buckets;
mht->mht_mask = (mht->mht_mask + 1) * MHT_GROWTH_FACTOR - 1;
diff --git a/src/nvim/memfile_defs.h b/src/nvim/memfile_defs.h
index 3eaa7d83e0..537d3e5f65 100644
--- a/src/nvim/memfile_defs.h
+++ b/src/nvim/memfile_defs.h
@@ -1,12 +1,12 @@
#ifndef NVIM_MEMFILE_DEFS_H
#define NVIM_MEMFILE_DEFS_H
-#include <stdint.h>
#include <stdbool.h>
+#include <stdint.h>
#include <stdlib.h>
-#include "nvim/types.h"
#include "nvim/pos.h"
+#include "nvim/types.h"
/// A block number.
///
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index 4ccbb31e2c..29e4a03d51 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -38,29 +38,31 @@
#include <assert.h>
#include <errno.h>
+#include <fcntl.h>
#include <inttypes.h>
-#include <string.h>
#include <stdbool.h>
-#include <fcntl.h>
+#include <string.h>
#include "nvim/ascii.h"
-#include "nvim/vim.h"
-#include "nvim/memline.h"
#include "nvim/buffer.h"
#include "nvim/change.h"
#include "nvim/cursor.h"
#include "nvim/eval.h"
-#include "nvim/getchar.h"
#include "nvim/fileio.h"
#include "nvim/func_attr.h"
+#include "nvim/getchar.h"
#include "nvim/main.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memfile.h"
+#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/os/process.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/screen.h"
@@ -68,44 +70,42 @@
#include "nvim/spell.h"
#include "nvim/strings.h"
#include "nvim/ui.h"
-#include "nvim/version.h"
#include "nvim/undo.h"
+#include "nvim/version.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/os/os.h"
-#include "nvim/os/process.h"
-#include "nvim/os/input.h"
-#ifndef UNIX /* it's in os/unix_defs.h for Unix */
+#ifndef UNIX // it's in os/unix_defs.h for Unix
# include <time.h>
#endif
-typedef struct block0 ZERO_BL; /* contents of the first block */
-typedef struct pointer_block PTR_BL; /* contents of a pointer block */
-typedef struct data_block DATA_BL; /* contents of a data block */
-typedef struct pointer_entry PTR_EN; /* block/line-count pair */
+typedef struct block0 ZERO_BL; // contents of the first block
+typedef struct pointer_block PTR_BL; // contents of a pointer block
+typedef struct data_block DATA_BL; // contents of a data block
+typedef struct pointer_entry PTR_EN; // block/line-count pair
-#define DATA_ID (('d' << 8) + 'a') /* data block id */
-#define PTR_ID (('p' << 8) + 't') /* pointer block id */
-#define BLOCK0_ID0 'b' /* block 0 id 0 */
-#define BLOCK0_ID1 '0' /* block 0 id 1 */
+#define DATA_ID (('d' << 8) + 'a') // data block id
+#define PTR_ID (('p' << 8) + 't') // pointer block id
+#define BLOCK0_ID0 'b' // block 0 id 0
+#define BLOCK0_ID1 '0' // block 0 id 1
/*
* pointer to a block, used in a pointer block
*/
struct pointer_entry {
- blocknr_T pe_bnum; /* block number */
- linenr_T pe_line_count; /* number of lines in this branch */
- linenr_T pe_old_lnum; /* lnum for this block (for recovery) */
- int pe_page_count; /* number of pages in block pe_bnum */
+ blocknr_T pe_bnum; // block number
+ linenr_T pe_line_count; // number of lines in this branch
+ linenr_T pe_old_lnum; // lnum for this block (for recovery)
+ int pe_page_count; // number of pages in block pe_bnum
};
/*
* A pointer block contains a list of branches in the tree.
*/
struct pointer_block {
- uint16_t pb_id; /* ID for pointer block: PTR_ID */
- uint16_t pb_count; /* number of pointers in this block */
- uint16_t pb_count_max; /* maximum value for pb_count */
+ uint16_t pb_id; // ID for pointer block: PTR_ID
+ uint16_t pb_count; // number of pointers in this block
+ uint16_t pb_count_max; // maximum value for pb_count
PTR_EN pb_pointer[1]; /* list of pointers to blocks (actually longer)
* followed by empty space until end of page */
};
@@ -140,12 +140,12 @@ struct data_block {
#define DB_MARKED ((unsigned)1 << ((sizeof(unsigned) * 8) - 1))
#define DB_INDEX_MASK (~DB_MARKED)
-#define INDEX_SIZE (sizeof(unsigned)) /* size of one db_index entry */
-#define HEADER_SIZE (sizeof(DATA_BL) - INDEX_SIZE) /* size of data block header */
+#define INDEX_SIZE (sizeof(unsigned)) // size of one db_index entry
+#define HEADER_SIZE (sizeof(DATA_BL) - INDEX_SIZE) // size of data block header
-#define B0_FNAME_SIZE_ORG 900 /* what it was in older versions */
-#define B0_FNAME_SIZE_NOCRYPT 898 /* 2 bytes used for other things */
-#define B0_FNAME_SIZE_CRYPT 890 /* 10 bytes used for other things */
+#define B0_FNAME_SIZE_ORG 900 // what it was in older versions
+#define B0_FNAME_SIZE_NOCRYPT 898 // 2 bytes used for other things
+#define B0_FNAME_SIZE_CRYPT 890 // 10 bytes used for other things
#define B0_UNAME_SIZE 40
#define B0_HNAME_SIZE 40
/*
@@ -172,18 +172,18 @@ struct data_block {
*/
struct block0 {
char_u b0_id[2]; ///< ID for block 0: BLOCK0_ID0 and BLOCK0_ID1.
- char_u b0_version[10]; /* Vim version string */
- char_u b0_page_size[4]; /* number of bytes per page */
- char_u b0_mtime[4]; /* last modification time of file */
- char_u b0_ino[4]; /* inode of b0_fname */
- char_u b0_pid[4]; /* process id of creator (or 0) */
- char_u b0_uname[B0_UNAME_SIZE]; /* name of user (uid if no name) */
- char_u b0_hname[B0_HNAME_SIZE]; /* host name (if it has a name) */
- char_u b0_fname[B0_FNAME_SIZE_ORG]; /* name of file being edited */
- long b0_magic_long; /* check for byte order of long */
- int b0_magic_int; /* check for byte order of int */
- short b0_magic_short; /* check for byte order of short */
- char_u b0_magic_char; /* check for last char */
+ char_u b0_version[10]; // Vim version string
+ char_u b0_page_size[4]; // number of bytes per page
+ char_u b0_mtime[4]; // last modification time of file
+ char_u b0_ino[4]; // inode of b0_fname
+ char_u b0_pid[4]; // process id of creator (or 0)
+ char_u b0_uname[B0_UNAME_SIZE]; // name of user (uid if no name)
+ char_u b0_hname[B0_HNAME_SIZE]; // host name (if it has a name)
+ char_u b0_fname[B0_FNAME_SIZE_ORG]; // name of file being edited
+ long b0_magic_long; // check for byte order of long
+ int b0_magic_int; // check for byte order of int
+ short b0_magic_short; // check for byte order of short
+ char_u b0_magic_char; // check for last char
};
/*
@@ -200,20 +200,20 @@ struct block0 {
*/
#define b0_flags b0_fname[B0_FNAME_SIZE_ORG - 2]
-/* The lowest two bits contain the fileformat. Zero means it's not set
- * (compatible with Vim 6.x), otherwise it's EOL_UNIX + 1, EOL_DOS + 1 or
- * EOL_MAC + 1. */
+// The lowest two bits contain the fileformat. Zero means it's not set
+// (compatible with Vim 6.x), otherwise it's EOL_UNIX + 1, EOL_DOS + 1 or
+// EOL_MAC + 1.
#define B0_FF_MASK 3
-/* Swap file is in directory of edited file. Used to find the file from
- * different mount points. */
+// Swap file is in directory of edited file. Used to find the file from
+// different mount points.
#define B0_SAME_DIR 4
-/* The 'fileencoding' is at the end of b0_fname[], with a NUL in front of it.
- * When empty there is only the NUL. */
+// The 'fileencoding' is at the end of b0_fname[], with a NUL in front of it.
+// When empty there is only the NUL.
#define B0_HAS_FENC 8
-#define STACK_INCR 5 /* nr of entries added to ml_stack at a time */
+#define STACK_INCR 5 // nr of entries added to ml_stack at a time
/*
* The line number where the first mark may be is remembered.
@@ -226,16 +226,16 @@ static linenr_T lowest_marked = 0;
/*
* arguments for ml_find_line()
*/
-#define ML_DELETE 0x11 /* delete line */
-#define ML_INSERT 0x12 /* insert line */
-#define ML_FIND 0x13 /* just find the line */
-#define ML_FLUSH 0x02 /* flush locked block */
-#define ML_SIMPLE(x) (x & 0x10) /* DEL, INS or FIND */
+#define ML_DELETE 0x11 // delete line
+#define ML_INSERT 0x12 // insert line
+#define ML_FIND 0x13 // just find the line
+#define ML_FLUSH 0x02 // flush locked block
+#define ML_SIMPLE(x) (x & 0x10) // DEL, INS or FIND
-/* argument for ml_upd_block0() */
+// argument for ml_upd_block0()
typedef enum {
- UB_FNAME = 0 /* update timestamp and filename */
- , UB_SAME_DIR /* update the B0_SAME_DIR flag */
+ UB_FNAME = 0, // update timestamp and filename
+ UB_SAME_DIR // update the B0_SAME_DIR flag
} upd_block0_T;
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -249,10 +249,10 @@ typedef enum {
*/
int ml_open(buf_T *buf)
{
- bhdr_T *hp = NULL;
- ZERO_BL *b0p;
- PTR_BL *pp;
- DATA_BL *dp;
+ bhdr_T *hp = NULL;
+ ZERO_BL *b0p;
+ PTR_BL *pp;
+ DATA_BL *dp;
/*
* init fields in memline struct
@@ -307,7 +307,7 @@ int ml_open(buf_T *buf)
b0p->b0_magic_int = (int)B0_MAGIC_INT;
b0p->b0_magic_short = (short)B0_MAGIC_SHORT;
b0p->b0_magic_char = B0_MAGIC_CHAR;
- xstrlcpy(xstpcpy((char *) b0p->b0_version, "VIM "), Version, 6);
+ xstrlcpy(xstpcpy((char *)b0p->b0_version, "VIM "), Version, 6);
long_to_char((long)mfp->mf_page_size, b0p->b0_page_size);
if (!buf->b_spell) {
@@ -329,14 +329,16 @@ int ml_open(buf_T *buf)
* is created.
*/
mf_put(mfp, hp, true, false);
- if (!buf->b_help && !B_SPELL(buf))
+ if (!buf->b_help && !B_SPELL(buf)) {
(void)mf_sync(mfp, 0);
+ }
/*
* Fill in root pointer block and write page 1.
*/
- if ((hp = ml_new_ptr(mfp)) == NULL)
+ if ((hp = ml_new_ptr(mfp)) == NULL) {
goto error;
+ }
if (hp->bh_bnum != 1) {
IEMSG(_("E298: Didn't get block nr 1?"));
goto error;
@@ -346,7 +348,7 @@ int ml_open(buf_T *buf)
pp->pb_pointer[0].pe_bnum = 2;
pp->pb_pointer[0].pe_page_count = 1;
pp->pb_pointer[0].pe_old_lnum = 1;
- pp->pb_pointer[0].pe_line_count = 1; /* line count after insertion */
+ pp->pb_pointer[0].pe_line_count = 1; // line count after insertion
mf_put(mfp, hp, true, false);
/*
@@ -359,10 +361,10 @@ int ml_open(buf_T *buf)
}
dp = hp->bh_data;
- dp->db_index[0] = --dp->db_txt_start; /* at end of block */
+ dp->db_index[0] = --dp->db_txt_start; // at end of block
dp->db_free -= 1 + INDEX_SIZE;
dp->db_line_count = 1;
- *((char_u *)dp + dp->db_txt_start) = NUL; /* empty line */
+ *((char_u *)dp + dp->db_txt_start) = NUL; // empty line
return OK;
@@ -384,18 +386,18 @@ error:
void ml_setname(buf_T *buf)
{
bool success = false;
- memfile_T *mfp;
- char_u *fname;
- char_u *dirp;
+ memfile_T *mfp;
+ char_u *fname;
+ char_u *dirp;
mfp = buf->b_ml.ml_mfp;
- if (mfp->mf_fd < 0) { /* there is no swap file yet */
+ if (mfp->mf_fd < 0) { // there is no swap file yet
/*
* When 'updatecount' is 0 and 'noswapfile' there is no swap file.
* For help files we will make a swap file now.
*/
if (p_uc != 0 && !cmdmod.noswapfile) {
- ml_open_file(buf); /* create a swap file */
+ ml_open_file(buf); // create a swap file
}
return;
}
@@ -406,29 +408,32 @@ void ml_setname(buf_T *buf)
dirp = p_dir;
bool found_existing_dir = false;
for (;; ) {
- if (*dirp == NUL) /* tried all directories, fail */
+ if (*dirp == NUL) { // tried all directories, fail
break;
+ }
fname = (char_u *)findswapname(buf, (char **)&dirp, (char *)mfp->mf_fname,
&found_existing_dir);
- /* alloc's fname */
- if (dirp == NULL) /* out of memory */
+ // alloc's fname
+ if (dirp == NULL) { // out of memory
break;
- if (fname == NULL) /* no file name found for this dir */
+ }
+ if (fname == NULL) { // no file name found for this dir
continue;
+ }
- /* if the file name is the same we don't have to do anything */
+ // if the file name is the same we don't have to do anything
if (fnamecmp(fname, mfp->mf_fname) == 0) {
xfree(fname);
success = true;
break;
}
- /* need to close the swap file before renaming */
+ // need to close the swap file before renaming
if (mfp->mf_fd >= 0) {
close(mfp->mf_fd);
mfp->mf_fd = -1;
}
- /* try to rename the swap file */
+ // try to rename the swap file
if (vim_rename(mfp->mf_fname, fname) == 0) {
success = true;
mf_free_fnames(mfp);
@@ -436,20 +441,21 @@ void ml_setname(buf_T *buf)
ml_upd_block0(buf, UB_SAME_DIR);
break;
}
- xfree(fname); /* this fname didn't work, try another */
+ xfree(fname); // this fname didn't work, try another
}
- if (mfp->mf_fd == -1) { /* need to (re)open the swap file */
+ if (mfp->mf_fd == -1) { // need to (re)open the swap file
mfp->mf_fd = os_open((char *)mfp->mf_fname, O_RDWR, 0);
if (mfp->mf_fd < 0) {
- /* could not (re)open the swap file, what can we do???? */
+ // could not (re)open the swap file, what can we do????
EMSG(_("E301: Oops, lost the swap file!!!"));
return;
}
(void)os_set_cloexec(mfp->mf_fd);
}
- if (!success)
+ if (!success) {
EMSG(_("E302: Could not rename swap file"));
+ }
}
/*
@@ -473,21 +479,22 @@ void ml_open_files(void)
*/
void ml_open_file(buf_T *buf)
{
- memfile_T *mfp;
- char_u *fname;
- char_u *dirp;
+ memfile_T *mfp;
+ char_u *fname;
+ char_u *dirp;
mfp = buf->b_ml.ml_mfp;
if (mfp == NULL || mfp->mf_fd >= 0 || !buf->b_p_swf || cmdmod.noswapfile
|| buf->terminal) {
- return; /* nothing to do */
+ return; // nothing to do
}
- /* For a spell buffer use a temp file name. */
+ // For a spell buffer use a temp file name.
if (buf->b_spell) {
fname = vim_tempname();
- if (fname != NULL)
- (void)mf_open_file(mfp, fname); /* consumes fname! */
+ if (fname != NULL) {
+ (void)mf_open_file(mfp, fname); // consumes fname!
+ }
buf->b_may_swap = false;
return;
}
@@ -498,29 +505,32 @@ void ml_open_file(buf_T *buf)
dirp = p_dir;
bool found_existing_dir = false;
for (;; ) {
- if (*dirp == NUL)
+ if (*dirp == NUL) {
break;
+ }
// There is a small chance that between choosing the swap file name
// and creating it, another Vim creates the file. In that case the
// creation will fail and we will use another directory.
fname = (char_u *)findswapname(buf, (char **)&dirp, NULL,
&found_existing_dir);
- if (dirp == NULL)
- break; /* out of memory */
- if (fname == NULL)
+ if (dirp == NULL) {
+ break; // out of memory
+ }
+ if (fname == NULL) {
continue;
- if (mf_open_file(mfp, fname) == OK) { /* consumes fname! */
+ }
+ if (mf_open_file(mfp, fname) == OK) { // consumes fname!
ml_upd_block0(buf, UB_SAME_DIR);
- /* Flush block zero, so others can read it */
+ // Flush block zero, so others can read it
if (mf_sync(mfp, MFS_ZERO) == OK) {
- /* Mark all blocks that should be in the swapfile as dirty.
- * Needed for when the 'swapfile' option was reset, so that
- * the swap file was deleted, and then on again. */
+ // Mark all blocks that should be in the swapfile as dirty.
+ // Needed for when the 'swapfile' option was reset, so that
+ // the swap file was deleted, and then on again.
mf_set_dirty(mfp);
break;
}
- /* Writing block 0 failed: close the file and try another dir */
+ // Writing block 0 failed: close the file and try another dir
mf_close_file(buf, false);
}
}
@@ -528,13 +538,12 @@ void ml_open_file(buf_T *buf)
if (*p_dir != NUL && mfp->mf_fname == NULL) {
need_wait_return = true; // call wait_return later
no_wait_return++;
- (void)EMSG2(_(
- "E303: Unable to open swap file for \"%s\", recovery impossible"),
- buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname);
+ (void)EMSG2(_("E303: Unable to open swap file for \"%s\", recovery impossible"),
+ buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname);
--no_wait_return;
}
- /* don't try to open a swap file again */
+ // don't try to open a swap file again
buf->b_may_swap = false;
}
@@ -560,17 +569,19 @@ void check_need_swap(bool newfile)
*/
void ml_close(buf_T *buf, int del_file)
{
- if (buf->b_ml.ml_mfp == NULL) /* not open */
+ if (buf->b_ml.ml_mfp == NULL) { // not open
return;
- mf_close(buf->b_ml.ml_mfp, del_file); /* close the .swp file */
- if (buf->b_ml.ml_line_lnum != 0 && (buf->b_ml.ml_flags & ML_LINE_DIRTY))
+ }
+ mf_close(buf->b_ml.ml_mfp, del_file); // close the .swp file
+ if (buf->b_ml.ml_line_lnum != 0 && (buf->b_ml.ml_flags & ML_LINE_DIRTY)) {
xfree(buf->b_ml.ml_line_ptr);
+ }
xfree(buf->b_ml.ml_stack);
XFREE_CLEAR(buf->b_ml.ml_chunksize);
buf->b_ml.ml_mfp = NULL;
- /* Reset the "recovered" flag, give the ATTENTION prompt the next time
- * this buffer is loaded. */
+ // Reset the "recovered" flag, give the ATTENTION prompt the next time
+ // this buffer is loaded.
buf->b_flags &= ~BF_RECOVERED;
}
@@ -585,8 +596,8 @@ void ml_close_all(int del_file)
FOR_ALL_BUFFERS(buf) {
ml_close(buf, del_file && ((buf->b_flags & BF_PRESERVED) == 0));
}
- spell_delete_wordlist(); /* delete the internal wordlist */
- vim_deltempdir(); /* delete created temp directory */
+ spell_delete_wordlist(); // delete the internal wordlist
+ vim_deltempdir(); // delete created temp directory
}
/*
@@ -597,7 +608,7 @@ void ml_close_notmod(void)
{
FOR_ALL_BUFFERS(buf) {
if (!bufIsChanged(buf)) {
- ml_close(buf, TRUE); /* close all not-modified buffers */
+ ml_close(buf, TRUE); // close all not-modified buffers
}
}
}
@@ -633,13 +644,14 @@ static bool ml_check_b0_strings(ZERO_BL *b0p)
*/
static void ml_upd_block0(buf_T *buf, upd_block0_T what)
{
- memfile_T *mfp;
- bhdr_T *hp;
- ZERO_BL *b0p;
+ memfile_T *mfp;
+ bhdr_T *hp;
+ ZERO_BL *b0p;
mfp = buf->b_ml.ml_mfp;
- if (mfp == NULL || (hp = mf_get(mfp, 0, 1)) == NULL)
+ if (mfp == NULL || (hp = mf_get(mfp, 0, 1)) == NULL) {
return;
+ }
b0p = hp->bh_data;
if (ml_check_b0_id(b0p) == FAIL) {
IEMSG(_("E304: ml_upd_block0(): Didn't get block 0??"));
@@ -660,9 +672,9 @@ static void ml_upd_block0(buf_T *buf, upd_block0_T what)
*/
static void set_b0_fname(ZERO_BL *b0p, buf_T *buf)
{
- if (buf->b_ffname == NULL)
+ if (buf->b_ffname == NULL) {
b0p->b0_fname[0] = NUL;
- else {
+ } else {
char uname[B0_UNAME_SIZE];
/*
@@ -673,9 +685,9 @@ static void set_b0_fname(ZERO_BL *b0p, buf_T *buf)
* Then insert the user name to get "~user/".
*/
home_replace(NULL, buf->b_ffname, b0p->b0_fname,
- B0_FNAME_SIZE_CRYPT, TRUE);
+ B0_FNAME_SIZE_CRYPT, TRUE);
if (b0p->b0_fname[0] == '~') {
- /* If there is no user name or it is too long, don't use "~/" */
+ // If there is no user name or it is too long, don't use "~/"
int retval = os_get_user_name(uname, B0_UNAME_SIZE);
size_t ulen = STRLEN(uname);
size_t flen = STRLEN(b0p->b0_fname);
@@ -702,7 +714,7 @@ static void set_b0_fname(ZERO_BL *b0p, buf_T *buf)
}
}
- /* Also add the 'fileencoding' if there is room. */
+ // Also add the 'fileencoding' if there is room.
add_b0_fenc(b0p, curbuf);
}
@@ -714,10 +726,11 @@ static void set_b0_fname(ZERO_BL *b0p, buf_T *buf)
*/
static void set_b0_dir_flag(ZERO_BL *b0p, buf_T *buf)
{
- if (same_directory(buf->b_ml.ml_mfp->mf_fname, buf->b_ffname))
+ if (same_directory(buf->b_ml.ml_mfp->mf_fname, buf->b_ffname)) {
b0p->b0_flags |= B0_SAME_DIR;
- else
+ } else {
b0p->b0_flags &= ~B0_SAME_DIR;
+ }
}
/*
@@ -729,11 +742,11 @@ static void add_b0_fenc(ZERO_BL *b0p, buf_T *buf)
int size = B0_FNAME_SIZE_NOCRYPT;
n = (int)STRLEN(buf->b_p_fenc);
- if ((int)STRLEN(b0p->b0_fname) + n + 1 > size)
+ if ((int)STRLEN(b0p->b0_fname) + n + 1 > size) {
b0p->b0_flags &= ~B0_HAS_FENC;
- else {
+ } else {
memmove((char *)b0p->b0_fname + size - n,
- (char *)buf->b_p_fenc, (size_t)n);
+ (char *)buf->b_p_fenc, (size_t)n);
*(b0p->b0_fname + size - n - 1) = NUL;
b0p->b0_flags |= B0_HAS_FENC;
}
@@ -745,23 +758,23 @@ static void add_b0_fenc(ZERO_BL *b0p, buf_T *buf)
/// swap file.
void ml_recover(bool checkext)
{
- buf_T *buf = NULL;
- memfile_T *mfp = NULL;
- char_u *fname;
- char_u *fname_used = NULL;
- bhdr_T *hp = NULL;
- ZERO_BL *b0p;
+ buf_T *buf = NULL;
+ memfile_T *mfp = NULL;
+ char_u *fname;
+ char_u *fname_used = NULL;
+ bhdr_T *hp = NULL;
+ ZERO_BL *b0p;
int b0_ff;
- char_u *b0_fenc = NULL;
- PTR_BL *pp;
- DATA_BL *dp;
- infoptr_T *ip;
+ char_u *b0_fenc = NULL;
+ PTR_BL *pp;
+ DATA_BL *dp;
+ infoptr_T *ip;
blocknr_T bnum;
int page_count;
int len;
bool directly;
linenr_T lnum;
- char_u *p;
+ char_u *p;
int i;
long error;
bool cannot_open;
@@ -784,8 +797,9 @@ void ml_recover(bool checkext)
// If the file name ends in ".s[a-w][a-z]" we assume this is the swap file.
// Otherwise a search is done to find the swap file(s).
fname = curbuf->b_fname;
- if (fname == NULL) /* When there is no file name */
+ if (fname == NULL) { // When there is no file name
fname = (char_u *)"";
+ }
len = (int)STRLEN(fname);
if (checkext && len >= 4
&& STRNICMP(fname + len - 4, ".s", 2) == 0
@@ -797,32 +811,34 @@ void ml_recover(bool checkext)
} else {
directly = false;
- /* count the number of matching swap files */
+ // count the number of matching swap files
len = recover_names(fname, FALSE, 0, NULL);
- if (len == 0) { /* no swap files found */
+ if (len == 0) { // no swap files found
EMSG2(_("E305: No swap file found for %s"), fname);
goto theend;
}
- if (len == 1) /* one swap file found, use it */
+ if (len == 1) { // one swap file found, use it
i = 1;
- else { /* several swap files found, choose */
- /* list the names of the swap files */
+ } else { // several swap files found, choose
+ // list the names of the swap files
(void)recover_names(fname, TRUE, 0, NULL);
msg_putchar('\n');
MSG_PUTS(_("Enter number of swap file to use (0 to quit): "));
i = get_number(FALSE, NULL);
- if (i < 1 || i > len)
+ if (i < 1 || i > len) {
goto theend;
+ }
}
- /* get the swap file name that will be used */
+ // get the swap file name that will be used
(void)recover_names(fname, FALSE, i, &fname_used);
}
- if (fname_used == NULL)
+ if (fname_used == NULL) {
goto theend; // user chose invalid number.
-
- /* When called from main() still need to initialize storage structure */
- if (called_from_main && ml_open(curbuf) == FAIL)
+ }
+ // When called from main() still need to initialize storage structure
+ if (called_from_main && ml_open(curbuf) == FAIL) {
getout(1);
+ }
/*
* Allocate a buffer structure for the swap file that is used for recovery.
@@ -844,8 +860,8 @@ void ml_recover(bool checkext)
/*
* open the memfile from the old swap file
*/
- p = vim_strsave(fname_used); /* save "fname_used" for the message:
- mf_open() will consume "fname_used"! */
+ p = vim_strsave(fname_used); // save "fname_used" for the message:
+ // mf_open() will consume "fname_used"!
mfp = mf_open(fname_used, O_RDONLY);
fname_used = p;
if (mfp == NULL || mfp->mf_fd < 0) {
@@ -869,9 +885,8 @@ void ml_recover(bool checkext)
msg_start();
MSG_PUTS_ATTR(_("Unable to read block 0 from "), attr | MSG_HIST);
msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
- MSG_PUTS_ATTR(_(
- "\nMaybe no changes were made or Vim did not update the swap file."),
- attr | MSG_HIST);
+ MSG_PUTS_ATTR(_("\nMaybe no changes were made or Vim did not update the swap file."),
+ attr | MSG_HIST);
msg_end();
goto theend;
}
@@ -880,7 +895,7 @@ void ml_recover(bool checkext)
msg_start();
msg_outtrans_attr(mfp->mf_fname, MSG_HIST);
MSG_PUTS_ATTR(_(" cannot be used with this version of Vim.\n"),
- MSG_HIST);
+ MSG_HIST);
MSG_PUTS_ATTR(_("Use Vim version 3.0.\n"), MSG_HIST);
msg_end();
goto theend;
@@ -893,9 +908,9 @@ void ml_recover(bool checkext)
msg_start();
msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
MSG_PUTS_ATTR(_(" cannot be used on this computer.\n"),
- attr | MSG_HIST);
+ attr | MSG_HIST);
MSG_PUTS_ATTR(_("The file was created on "), attr | MSG_HIST);
- /* avoid going past the end of a corrupted hostname */
+ // avoid going past the end of a corrupted hostname
b0p->b0_fname[0] = NUL;
MSG_PUTS_ATTR(b0p->b0_hname, attr | MSG_HIST);
MSG_PUTS_ATTR(_(",\nor the file has been damaged."), attr | MSG_HIST);
@@ -914,9 +929,8 @@ void ml_recover(bool checkext)
if (mfp->mf_page_size < previous_page_size) {
msg_start();
msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
- MSG_PUTS_ATTR(_(
- " has been damaged (page size is smaller than minimum value).\n"),
- attr | MSG_HIST);
+ MSG_PUTS_ATTR(_(" has been damaged (page size is smaller than minimum value).\n"),
+ attr | MSG_HIST);
msg_end();
goto theend;
}
@@ -927,7 +941,7 @@ void ml_recover(bool checkext)
}
mfp->mf_infile_count = mfp->mf_blocknr_max;
- /* need to reallocate the memory used to store the data */
+ // need to reallocate the memory used to store the data
p = xmalloc(mfp->mf_page_size);
memmove(p, hp->bh_data, previous_page_size);
xfree(hp->bh_data);
@@ -948,10 +962,11 @@ void ml_recover(bool checkext)
home_replace(NULL, mfp->mf_fname, NameBuff, MAXPATHL, TRUE);
smsg(_("Using swap file \"%s\""), NameBuff);
- if (buf_spname(curbuf) != NULL)
+ if (buf_spname(curbuf) != NULL) {
STRLCPY(NameBuff, buf_spname(curbuf), MAXPATHL);
- else
+ } else {
home_replace(NULL, curbuf->b_ffname, NameBuff, MAXPATHL, TRUE);
+ }
smsg(_("Original file \"%s\""), NameBuff);
msg_putchar('\n');
@@ -965,13 +980,13 @@ void ml_recover(bool checkext)
&& os_fileinfo((char *)curbuf->b_ffname, &org_file_info)
&& ((os_fileinfo((char *)mfp->mf_fname, &swp_file_info)
&& org_file_info.stat.st_mtim.tv_sec
- > swp_file_info.stat.st_mtim.tv_sec)
+ > swp_file_info.stat.st_mtim.tv_sec)
|| org_file_info.stat.st_mtim.tv_sec != mtime)) {
EMSG(_("E308: Warning: Original file may have been changed"));
}
ui_flush();
- /* Get the 'fileformat' and 'fileencoding' from block zero. */
+ // Get the 'fileformat' and 'fileencoding' from block zero.
b0_ff = (b0p->b0_flags & B0_FF_MASK);
if (b0p->b0_flags & B0_HAS_FENC) {
int fnsize = B0_FNAME_SIZE_NOCRYPT;
@@ -981,7 +996,7 @@ void ml_recover(bool checkext)
b0_fenc = vim_strnsave(p, b0p->b0_fname + fnsize - p);
}
- mf_put(mfp, hp, false, false); /* release block 0 */
+ mf_put(mfp, hp, false, false); // release block 0
hp = NULL;
/*
@@ -996,28 +1011,30 @@ void ml_recover(bool checkext)
* Try reading the original file to obtain the values of 'fileformat',
* 'fileencoding', etc. Ignore errors. The text itself is not used.
*/
- if (curbuf->b_ffname != NULL)
+ if (curbuf->b_ffname != NULL) {
orig_file_status = readfile(curbuf->b_ffname, NULL, (linenr_T)0,
- (linenr_T)0, (linenr_T)MAXLNUM, NULL, READ_NEW);
+ (linenr_T)0, (linenr_T)MAXLNUM, NULL, READ_NEW);
+ }
- /* Use the 'fileformat' and 'fileencoding' as stored in the swap file. */
- if (b0_ff != 0)
+ // Use the 'fileformat' and 'fileencoding' as stored in the swap file.
+ if (b0_ff != 0) {
set_fileformat(b0_ff - 1, OPT_LOCAL);
+ }
if (b0_fenc != NULL) {
set_option_value("fenc", 0L, (char *)b0_fenc, OPT_LOCAL);
xfree(b0_fenc);
}
unchanged(curbuf, true, true);
- bnum = 1; /* start with block 1 */
- page_count = 1; /* which is 1 page */
- lnum = 0; /* append after line 0 in curbuf */
+ bnum = 1; // start with block 1
+ page_count = 1; // which is 1 page
+ lnum = 0; // append after line 0 in curbuf
line_count = 0;
- idx = 0; /* start with first index in block 1 */
+ idx = 0; // start with first index in block 1
error = 0;
buf->b_ml.ml_stack_top = 0;
buf->b_ml.ml_stack = NULL;
- buf->b_ml.ml_stack_size = 0; /* no stack yet */
+ buf->b_ml.ml_stack_size = 0; // no stack yet
if (curbuf->b_ffname == NULL) {
cannot_open = true;
@@ -1027,9 +1044,9 @@ void ml_recover(bool checkext)
serious_error = false;
for (; !got_int; line_breakcheck()) {
- if (hp != NULL)
- mf_put(mfp, hp, false, false); /* release previous block */
-
+ if (hp != NULL) {
+ mf_put(mfp, hp, false, false); // release previous block
+ }
/*
* get block
*/
@@ -1043,11 +1060,12 @@ void ml_recover(bool checkext)
(colnr_T)0, true);
} else { // there is a block
pp = hp->bh_data;
- if (pp->pb_id == PTR_ID) { /* it is a pointer block */
- /* check line count when using pointer block first time */
+ if (pp->pb_id == PTR_ID) { // it is a pointer block
+ // check line count when using pointer block first time
if (idx == 0 && line_count != 0) {
- for (i = 0; i < (int)pp->pb_count; ++i)
+ for (i = 0; i < (int)pp->pb_count; ++i) {
line_count -= pp->pb_pointer[i].pe_line_count;
+ }
if (line_count != 0) {
++error;
ml_append(lnum++, (char_u *)_("???LINE COUNT WRONG"),
@@ -1081,7 +1099,7 @@ void ml_recover(bool checkext)
ml_append(lnum++, (char_u *)_("???LINES MISSING"),
(colnr_T)0, true);
}
- ++idx; /* get same block again for next index */
+ ++idx; // get same block again for next index
continue;
}
@@ -1099,12 +1117,12 @@ void ml_recover(bool checkext)
idx = 0;
continue;
}
- } else { /* not a pointer block */
+ } else { // not a pointer block
dp = hp->bh_data;
- if (dp->db_id != DATA_ID) { /* block id wrong */
+ if (dp->db_id != DATA_ID) { // block id wrong
if (bnum == 1) {
EMSG2(_("E310: Block 1 ID wrong (%s not a .swp file?)"),
- mfp->mf_fname);
+ mfp->mf_fname);
goto theend;
}
++error;
@@ -1117,17 +1135,16 @@ void ml_recover(bool checkext)
// check length of block
// if wrong, use length in pointer block
if (page_count * mfp->mf_page_size != dp->db_txt_end) {
- ml_append(
- lnum++,
- (char_u *)_("??? from here until ???END lines"
- " may be messed up"),
- (colnr_T)0, true);
+ ml_append(lnum++,
+ (char_u *)_("??? from here until ???END lines"
+ " may be messed up"),
+ (colnr_T)0, true);
error++;
has_error = true;
dp->db_txt_end = page_count * mfp->mf_page_size;
}
- /* make sure there is a NUL at the end of the block */
+ // make sure there is a NUL at the end of the block
*((char_u *)dp + dp->db_txt_end - 1) = NUL;
/*
@@ -1135,11 +1152,10 @@ void ml_recover(bool checkext)
* if wrong, use count in data block
*/
if (line_count != dp->db_line_count) {
- ml_append(
- lnum++,
- (char_u *)_("??? from here until ???END lines"
- " may have been inserted/deleted"),
- (colnr_T)0, true);
+ ml_append(lnum++,
+ (char_u *)_("??? from here until ???END lines"
+ " may have been inserted/deleted"),
+ (colnr_T)0, true);
error++;
has_error = true;
}
@@ -1150,8 +1166,9 @@ void ml_recover(bool checkext)
|| txt_start >= (int)dp->db_txt_end) {
p = (char_u *)"???";
++error;
- } else
+ } else {
p = (char_u *)dp + txt_start;
+ }
ml_append(lnum++, p, (colnr_T)0, true);
}
if (has_error) {
@@ -1161,15 +1178,16 @@ void ml_recover(bool checkext)
}
}
- if (buf->b_ml.ml_stack_top == 0) /* finished */
+ if (buf->b_ml.ml_stack_top == 0) { // finished
break;
+ }
/*
* go one block up in the tree
*/
ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]);
bnum = ip->ip_bnum;
- idx = ip->ip_index + 1; /* go to next index */
+ idx = ip->ip_index + 1; // go to next index
page_count = 1;
}
@@ -1181,15 +1199,15 @@ void ml_recover(bool checkext)
* Line ml_line_count + 1 in the dummy empty line.
*/
if (orig_file_status != OK || curbuf->b_ml.ml_line_count != lnum * 2 + 1) {
- /* Recovering an empty file results in two lines and the first line is
- * empty. Don't set the modified flag then. */
+ // Recovering an empty file results in two lines and the first line is
+ // empty. Don't set the modified flag then.
if (!(curbuf->b_ml.ml_line_count == 2 && *ml_get(1) == NUL)) {
changed_internal();
buf_inc_changedtick(curbuf);
}
} else {
for (idx = 1; idx <= lnum; ++idx) {
- /* Need to copy one line, fetching the other one may flush it. */
+ // Need to copy one line, fetching the other one may flush it.
p = vim_strsave(ml_get(idx));
i = STRCMP(p, ml_get(idx + lnum));
xfree(p);
@@ -1206,30 +1224,30 @@ void ml_recover(bool checkext)
* empty buffer. These will now be after the last line in the buffer.
*/
while (curbuf->b_ml.ml_line_count > lnum
- && !(curbuf->b_ml.ml_flags & ML_EMPTY))
+ && !(curbuf->b_ml.ml_flags & ML_EMPTY)) {
ml_delete(curbuf->b_ml.ml_line_count, false);
+ }
curbuf->b_flags |= BF_RECOVERED;
check_cursor();
recoverymode = FALSE;
- if (got_int)
+ if (got_int) {
EMSG(_("E311: Recovery Interrupted"));
- else if (error) {
+ } else if (error) {
++no_wait_return;
MSG(">>>>>>>>>>>>>");
- EMSG(_(
- "E312: Errors detected while recovering; look for lines starting with ???"));
+ EMSG(_( "E312: Errors detected while recovering; look for lines starting with ???"));
--no_wait_return;
MSG(_("See \":help E312\" for more information."));
MSG(">>>>>>>>>>>>>");
} else {
if (curbuf->b_changed) {
MSG(_("Recovery completed. You should check if everything is OK."));
- MSG_PUTS(_(
- "\n(You might want to write out this file under another name\n"));
+ MSG_PUTS(_("\n(You might want to write out this file under another name\n"));
MSG_PUTS(_("and run diff with the original file to check for changes)"));
- } else
+ } else {
MSG(_("Recovery completed. Buffer contents equals file contents."));
+ }
MSG_PUTS(_("\nYou may want to delete the .swp file now.\n\n"));
cmdline_row = msg_row;
}
@@ -1239,68 +1257,65 @@ theend:
xfree(fname_used);
recoverymode = FALSE;
if (mfp != NULL) {
- if (hp != NULL)
+ if (hp != NULL) {
mf_put(mfp, hp, false, false);
- mf_close(mfp, false); /* will also xfree(mfp->mf_fname) */
+ }
+ mf_close(mfp, false); // will also xfree(mfp->mf_fname)
}
if (buf != NULL) { //may be NULL if swap file not found.
xfree(buf->b_ml.ml_stack);
xfree(buf);
}
- if (serious_error && called_from_main)
+ if (serious_error && called_from_main) {
ml_close(curbuf, TRUE);
- else {
+ } else {
apply_autocmds(EVENT_BUFREADPOST, NULL, curbuf->b_fname, FALSE, curbuf);
apply_autocmds(EVENT_BUFWINENTER, NULL, curbuf->b_fname, FALSE, curbuf);
}
- return;
}
-/*
- * Find the names of swap files in current directory and the directory given
- * with the 'directory' option.
- *
- * Used to:
- * - list the swap files for "vim -r"
- * - count the number of swap files when recovering
- * - list the swap files when recovering
- * - find the name of the n'th swap file when recovering
- */
-int
-recover_names (
- char_u *fname, /* base for swap file name */
- int list, /* when TRUE, list the swap file names */
- int nr, /* when non-zero, return nr'th swap file name */
- char_u **fname_out /* result when "nr" > 0 */
-)
+/// Find the names of swap files in current directory and the directory given
+/// with the 'directory' option.
+///
+/// Used to:
+/// - list the swap files for "vim -r"
+/// - count the number of swap files when recovering
+/// - list the swap files when recovering
+/// - find the name of the n'th swap file when recovering
+///
+/// @param fname base for swap file name
+/// @param list when TRUE, list the swap file names
+/// @param nr when non-zero, return nr'th swap file name
+/// @param fname_out result when "nr" > 0
+int recover_names(char_u *fname, int list, int nr, char_u **fname_out)
{
int num_names;
- char_u *(names[6]);
- char_u *tail;
- char_u *p;
+ char_u *(names[6]);
+ char_u *tail;
+ char_u *p;
int num_files;
int file_count = 0;
- char_u **files;
- char_u *dirp;
- char_u *dir_name;
- char_u *fname_res = NULL;
+ char_u **files;
+ char_u *dirp;
+ char_u *dir_name;
+ char_u *fname_res = NULL;
#ifdef HAVE_READLINK
char_u fname_buf[MAXPATHL];
#endif
if (fname != NULL) {
#ifdef HAVE_READLINK
- /* Expand symlink in the file name, because the swap file is created
- * with the actual file instead of with the symlink. */
- if (resolve_symlink(fname, fname_buf) == OK)
+ // Expand symlink in the file name, because the swap file is created
+ // with the actual file instead of with the symlink.
+ if (resolve_symlink(fname, fname_buf) == OK) {
fname_res = fname_buf;
- else
+ } else
#endif
fname_res = fname;
}
if (list) {
- /* use msg() to start the scrolling properly */
+ // use msg() to start the scrolling properly
msg((char_u *)_("Swap files found:"));
msg_putchar('\n');
}
@@ -1315,7 +1330,7 @@ recover_names (
// Advance dirp to next directory name.
(void)copy_option_part(&dirp, dir_name, 31000, ",");
- if (dir_name[0] == '.' && dir_name[1] == NUL) { /* check current dir */
+ if (dir_name[0] == '.' && dir_name[1] == NUL) { // check current dir
if (fname == NULL) {
names[0] = vim_strsave((char_u *)"*.sw?");
/* For Unix names starting with a dot are special. MS-Windows
@@ -1323,9 +1338,10 @@ recover_names (
names[1] = vim_strsave((char_u *)".*.sw?");
names[2] = vim_strsave((char_u *)".sw?");
num_names = 3;
- } else
+ } else {
num_names = recov_file_names(names, fname_res, TRUE);
- } else { /* check directory dir_name */
+ }
+ } else { // check directory dir_name
if (fname == NULL) {
names[0] = (char_u *)concat_fnames((char *)dir_name, "*.sw?", TRUE);
/* For Unix names starting with a dot are special. MS-Windows
@@ -1351,11 +1367,12 @@ recover_names (
}
}
- if (num_names == 0)
+ if (num_names == 0) {
num_files = 0;
- else if (expand_wildcards(num_names, names, &num_files, &files,
- EW_KEEPALL|EW_FILE|EW_SILENT) == FAIL)
+ } else if (expand_wildcards(num_names, names, &num_files, &files,
+ EW_KEEPALL|EW_FILE|EW_SILENT) == FAIL) {
num_files = 0;
+ }
/*
* When no swap file found, wildcard expansion might have failed (e.g.
@@ -1388,27 +1405,29 @@ recover_names (
// down. When the array becomes empty free it here, since
// FreeWild() won't be called below.
xfree(files[i]);
- if (--num_files == 0)
+ if (--num_files == 0) {
xfree(files);
- else
- for (; i < num_files; ++i)
+ } else {
+ for (; i < num_files; ++i) {
files[i] = files[i + 1];
+ }
+ }
}
}
}
if (nr > 0) {
file_count += num_files;
if (nr <= file_count) {
- *fname_out = vim_strsave(
- files[nr - 1 + num_files - file_count]);
- dirp = (char_u *)""; /* stop searching */
+ *fname_out = vim_strsave(files[nr - 1 + num_files - file_count]);
+ dirp = (char_u *)""; // stop searching
}
} else if (list) {
if (dir_name[0] == '.' && dir_name[1] == NUL) {
- if (fname == NULL)
+ if (fname == NULL) {
MSG_PUTS(_(" In current directory:\n"));
- else
+ } else {
MSG_PUTS(_(" Using specified name:\n"));
+ }
} else {
MSG_PUTS(_(" In directory "));
msg_home_replace(dir_name);
@@ -1417,23 +1436,27 @@ recover_names (
if (num_files) {
for (int i = 0; i < num_files; ++i) {
- /* print the swap file name */
+ // print the swap file name
msg_outnum((long)++file_count);
msg_puts(". ");
msg_puts((const char *)path_tail(files[i]));
msg_putchar('\n');
(void)swapfile_info(files[i]);
}
- } else
+ } else {
MSG_PUTS(_(" -- none --\n"));
+ }
ui_flush();
- } else
+ } else {
file_count += num_files;
+ }
- for (int i = 0; i < num_names; ++i)
+ for (int i = 0; i < num_names; ++i) {
xfree(names[i]);
- if (num_files > 0)
+ }
+ if (num_files > 0) {
FreeWild(num_files, files);
+ }
}
xfree(dir_name);
return file_count;
@@ -1544,10 +1567,11 @@ static time_t swapfile_info(char_u *fname)
MSG_PUTS(_(" [garbled strings (not nul terminated)]"));
} else {
MSG_PUTS(_(" file name: "));
- if (b0.b0_fname[0] == NUL)
+ if (b0.b0_fname[0] == NUL) {
MSG_PUTS(_("[No Name]"));
- else
+ } else {
msg_outtrans(b0.b0_fname);
+ }
MSG_PUTS(_("\n modified: "));
MSG_PUTS(b0.b0_dirty ? _("YES") : _("no"));
@@ -1558,10 +1582,11 @@ static time_t swapfile_info(char_u *fname)
}
if (*(b0.b0_hname) != NUL) {
- if (*(b0.b0_uname) != NUL)
+ if (*(b0.b0_uname) != NUL) {
MSG_PUTS(_(" host name: "));
- else
+ } else {
MSG_PUTS(_("\n host name: "));
+ }
msg_outtrans(b0.b0_hname);
}
@@ -1578,11 +1603,13 @@ static time_t swapfile_info(char_u *fname)
MSG_PUTS(_("\n [not usable on this computer]"));
}
}
- } else
+ } else {
MSG_PUTS(_(" [cannot be read]"));
+ }
close(fd);
- } else
+ } else {
MSG_PUTS(_(" [cannot be opened]"));
+ }
msg_putchar('\n');
return x;
@@ -1650,18 +1677,20 @@ static int recov_file_names(char_u **names, char_u *path, int prepend_dot)
// Form the normal swap file name pattern by appending ".sw?".
names[num_names] = (char_u *)concat_fnames((char *)path, ".sw?", FALSE);
- if (num_names >= 1) { /* check if we have the same name twice */
+ if (num_names >= 1) { // check if we have the same name twice
char_u *p = names[num_names - 1];
int i = (int)STRLEN(names[num_names - 1]) - (int)STRLEN(names[num_names]);
- if (i > 0)
- p += i; /* file name has been expanded to full path */
-
- if (STRCMP(p, names[num_names]) != 0)
+ if (i > 0) {
+ p += i; // file name has been expanded to full path
+ }
+ if (STRCMP(p, names[num_names]) != 0) {
++num_names;
- else
+ } else {
xfree(names[num_names]);
- } else
+ }
+ } else {
++num_names;
+ }
return num_names;
}
@@ -1676,11 +1705,11 @@ static int recov_file_names(char_u **names, char_u *path, int prepend_dot)
void ml_sync_all(int check_file, int check_char, bool do_fsync)
{
FOR_ALL_BUFFERS(buf) {
- if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL)
- continue; /* no file */
-
- ml_flush_line(buf); /* flush buffered line */
- /* flush locked block */
+ if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL) {
+ continue; // no file
+ }
+ ml_flush_line(buf); // flush buffered line
+ // flush locked block
(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH);
if (bufIsChanged(buf) && check_file && mf_need_trans(buf->b_ml.ml_mfp)
&& buf->b_ffname != NULL) {
@@ -1719,27 +1748,28 @@ void ml_sync_all(int check_file, int check_char, bool do_fsync)
*/
void ml_preserve(buf_T *buf, int message, bool do_fsync)
{
- bhdr_T *hp;
+ bhdr_T *hp;
linenr_T lnum;
- memfile_T *mfp = buf->b_ml.ml_mfp;
+ memfile_T *mfp = buf->b_ml.ml_mfp;
int status;
int got_int_save = got_int;
if (mfp == NULL || mfp->mf_fname == NULL) {
- if (message)
+ if (message) {
EMSG(_("E313: Cannot preserve, there is no swap file"));
+ }
return;
}
- /* We only want to stop when interrupted here, not when interrupted
- * before. */
- got_int = FALSE;
+ // We only want to stop when interrupted here, not when interrupted
+ // before.
+ got_int = false;
ml_flush_line(buf); // flush buffered line
(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); // flush locked block
status = mf_sync(mfp, MFS_ALL | (do_fsync ? MFS_FLUSH : 0));
- /* stack is invalid after mf_sync(.., MFS_ALL) */
+ // stack is invalid after mf_sync(.., MFS_ALL)
buf->b_ml.ml_stack_top = 0;
/*
@@ -1776,10 +1806,11 @@ theend:
got_int |= got_int_save;
if (message) {
- if (status == OK)
+ if (status == OK) {
MSG(_("File preserved"));
- else
+ } else {
EMSG(_("E314: Preserve failed"));
+ }
}
}
@@ -1787,7 +1818,7 @@ theend:
* NOTE: The pointer returned by the ml_get_*() functions only remains valid
* until the next call!
* line1 = ml_get(1);
- * line2 = ml_get(2); // line1 is now invalid!
+ * line2 = ml_get(2); // line1 is now invalid!
* Make a copy of the line if necessary.
*/
/*
@@ -1810,26 +1841,18 @@ char_u *ml_get_pos(const pos_T *pos)
return ml_get_buf(curbuf, pos->lnum, false) + pos->col;
}
-/*
- * Return a pointer to a line in a specific buffer
- *
- * "will_change": if TRUE mark the buffer dirty (chars in the line will be
- * changed)
- */
-char_u *
-ml_get_buf (
- buf_T *buf,
- linenr_T lnum,
- bool will_change // line will be changed
-)
+/// Return a pointer to a line in a specific buffer
+///
+/// @param will_change true mark the buffer dirty (chars in the line will be changed)
+char_u *ml_get_buf(buf_T *buf, linenr_T lnum, bool will_change)
FUNC_ATTR_NONNULL_ALL
{
- bhdr_T *hp;
- DATA_BL *dp;
- char_u *ptr;
+ bhdr_T *hp;
+ DATA_BL *dp;
+ char_u *ptr;
static int recursive = 0;
- if (lnum > buf->b_ml.ml_line_count) { /* invalid line number */
+ if (lnum > buf->b_ml.ml_line_count) { // invalid line number
if (recursive == 0) {
// Avoid giving this message for a recursive call, may happen when
// the GUI redraws part of the text.
@@ -1841,11 +1864,13 @@ errorret:
STRCPY(IObuff, "???");
return IObuff;
}
- if (lnum <= 0) /* pretend line 0 is line 1 */
+ if (lnum <= 0) { // pretend line 0 is line 1
lnum = 1;
+ }
- if (buf->b_ml.ml_mfp == NULL) /* there are no lines */
+ if (buf->b_ml.ml_mfp == NULL) { // there are no lines
return (char_u *)"";
+ }
/*
* See if it is the same line as requested last time.
@@ -1900,88 +1925,89 @@ int ml_line_alloced(void)
return curbuf->b_ml.ml_flags & ML_LINE_DIRTY;
}
-/*
- * Append a line after lnum (may be 0 to insert a line in front of the file).
- * "line" does not need to be allocated, but can't be another line in a
- * buffer, unlocking may make it invalid.
- *
- * newfile: TRUE when starting to edit a new file, meaning that pe_old_lnum
- * will be set for recovery
- * Check: The caller of this function should probably also call
- * appended_lines().
- *
- * return FAIL for failure, OK otherwise
- */
-int ml_append(
- linenr_T lnum, // append after this line (can be 0)
- char_u *line, // text of the new line
- colnr_T len, // length of new line, including NUL, or 0
- bool newfile // flag, see above
-)
+/// Append a line after lnum (may be 0 to insert a line in front of the file).
+/// "line" does not need to be allocated, but can't be another line in a
+/// buffer, unlocking may make it invalid.
+///
+/// newfile: TRUE when starting to edit a new file, meaning that pe_old_lnum
+/// will be set for recovery
+/// Check: The caller of this function should probably also call
+/// appended_lines().
+///
+/// @param lnum append after this line (can be 0)
+/// @param line text of the new line
+/// @param len length of new line, including NUL, or 0
+/// @param newfile flag, see above
+///
+/// @return FAIL for failure, OK otherwise
+int ml_append(linenr_T lnum, char_u *line, colnr_T len, bool newfile)
{
- /* When starting up, we might still need to create the memfile */
- if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL)
+ // When starting up, we might still need to create the memfile
+ if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL) {
return FAIL;
+ }
- if (curbuf->b_ml.ml_line_lnum != 0)
+ if (curbuf->b_ml.ml_line_lnum != 0) {
ml_flush_line(curbuf);
+ }
return ml_append_int(curbuf, lnum, line, len, newfile, FALSE);
}
-/*
- * Like ml_append() but for an arbitrary buffer. The buffer must already have
- * a memline.
- */
-int ml_append_buf(
- buf_T *buf,
- linenr_T lnum, // append after this line (can be 0)
- char_u *line, // text of the new line
- colnr_T len, // length of new line, including NUL, or 0
- bool newfile // flag, see above
-)
+/// Like ml_append() but for an arbitrary buffer. The buffer must already have
+/// a memline.
+///
+/// @param lnum append after this line (can be 0)
+/// @param line text of the new line
+/// @param len length of new line, including NUL, or 0
+/// @param newfile flag, see above
+int ml_append_buf(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, bool newfile)
FUNC_ATTR_NONNULL_ARG(1)
{
- if (buf->b_ml.ml_mfp == NULL)
+ if (buf->b_ml.ml_mfp == NULL) {
return FAIL;
+ }
- if (buf->b_ml.ml_line_lnum != 0)
+ if (buf->b_ml.ml_line_lnum != 0) {
ml_flush_line(buf);
+ }
return ml_append_int(buf, lnum, line, len, newfile, FALSE);
}
-static int ml_append_int(
- buf_T *buf,
- linenr_T lnum, // append after this line (can be 0)
- char_u *line, // text of the new line
- colnr_T len, // length of line, including NUL, or 0
- bool newfile, // flag, see above
- int mark // mark the new line
-)
+/// @param lnum append after this line (can be 0)
+/// @param line text of the new line
+/// @param len length of line, including NUL, or 0
+/// @param newfile flag, see above
+/// @param mark mark the new line
+static int ml_append_int(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, bool newfile,
+ int mark)
{
int i;
- int line_count; /* number of indexes in current block */
+ int line_count; // number of indexes in current block
int offset;
int from, to;
- int space_needed; /* space needed for new line */
+ int space_needed; // space needed for new line
int page_size;
int page_count;
- int db_idx; /* index for lnum in data block */
- bhdr_T *hp;
- memfile_T *mfp;
- DATA_BL *dp;
- PTR_BL *pp;
- infoptr_T *ip;
-
- /* lnum out of range */
- if (lnum > buf->b_ml.ml_line_count || buf->b_ml.ml_mfp == NULL)
+ int db_idx; // index for lnum in data block
+ bhdr_T *hp;
+ memfile_T *mfp;
+ DATA_BL *dp;
+ PTR_BL *pp;
+ infoptr_T *ip;
+
+ // lnum out of range
+ if (lnum > buf->b_ml.ml_line_count || buf->b_ml.ml_mfp == NULL) {
return FAIL;
+ }
- if (lowest_marked && lowest_marked > lnum)
+ if (lowest_marked && lowest_marked > lnum) {
lowest_marked = lnum + 1;
+ }
- if (len == 0)
- len = (colnr_T)STRLEN(line) + 1; /* space needed for the text */
- space_needed = len + INDEX_SIZE; /* space needed for text + index */
+ if (len == 0) {
+ len = (colnr_T)STRLEN(line) + 1; // space needed for the text
+ }
+ space_needed = len + INDEX_SIZE; // space needed for text + index
mfp = buf->b_ml.ml_mfp;
page_size = mfp->mf_page_size;
@@ -1992,16 +2018,18 @@ static int ml_append_int(
* This also releases any locked block.
*/
if ((hp = ml_find_line(buf, lnum == 0 ? (linenr_T)1 : lnum,
- ML_INSERT)) == NULL)
+ ML_INSERT)) == NULL) {
return FAIL;
+ }
buf->b_ml.ml_flags &= ~ML_EMPTY;
- if (lnum == 0) /* got line one instead, correct db_idx */
- db_idx = -1; /* careful, it is negative! */
- else
+ if (lnum == 0) { // got line one instead, correct db_idx
+ db_idx = -1; // careful, it is negative!
+ } else {
db_idx = lnum - buf->b_ml.ml_locked_low;
- /* get line count before the insertion */
+ }
+ // get line count before the insertion
line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low;
dp = hp->bh_data;
@@ -2022,11 +2050,12 @@ static int ml_append_int(
*/
--(buf->b_ml.ml_locked_lineadd);
--(buf->b_ml.ml_locked_high);
- if ((hp = ml_find_line(buf, lnum + 1, ML_INSERT)) == NULL)
+ if ((hp = ml_find_line(buf, lnum + 1, ML_INSERT)) == NULL) {
return FAIL;
+ }
- db_idx = -1; /* careful, it is negative! */
- /* get line count before the insertion */
+ db_idx = -1; // careful, it is negative!
+ // get line count before the insertion
line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low;
CHECK(buf->b_ml.ml_locked_low != lnum + 1, "locked_low != lnum + 1");
@@ -2035,7 +2064,7 @@ static int ml_append_int(
++buf->b_ml.ml_line_count;
- if ((int)dp->db_free >= space_needed) { /* enough room in data block */
+ if ((int)dp->db_free >= space_needed) { // enough room in data block
/*
* Insert new line in existing data block, or in data block allocated above.
*/
@@ -2047,38 +2076,43 @@ static int ml_append_int(
* move the text of the lines that follow to the front
* adjust the indexes of the lines that follow
*/
- if (line_count > db_idx + 1) { /* if there are following lines */
+ if (line_count > db_idx + 1) { // if there are following lines
/*
* Offset is the start of the previous line.
* This will become the character just after the new line.
*/
- if (db_idx < 0)
+ if (db_idx < 0) {
offset = dp->db_txt_end;
- else
+ } else {
offset = ((dp->db_index[db_idx]) & DB_INDEX_MASK);
+ }
memmove((char *)dp + dp->db_txt_start,
- (char *)dp + dp->db_txt_start + len,
- (size_t)(offset - (dp->db_txt_start + len)));
- for (i = line_count - 1; i > db_idx; --i)
+ (char *)dp + dp->db_txt_start + len,
+ (size_t)(offset - (dp->db_txt_start + len)));
+ for (i = line_count - 1; i > db_idx; --i) {
dp->db_index[i + 1] = dp->db_index[i] - len;
+ }
dp->db_index[db_idx + 1] = offset - len;
- } else /* add line at the end */
+ } else { // add line at the end
dp->db_index[db_idx + 1] = dp->db_txt_start;
+ }
/*
* copy the text into the block
*/
memmove((char *)dp + dp->db_index[db_idx + 1], line, (size_t)len);
- if (mark)
+ if (mark) {
dp->db_index[db_idx + 1] |= DB_MARKED;
+ }
/*
* Mark the block dirty.
*/
buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
- if (!newfile)
+ if (!newfile) {
buf->b_ml.ml_flags |= ML_LOCKED_POS;
- } else { /* not enough space in data block */
+ }
+ } else { // not enough space in data block
/*
* If there is not enough room we have to create a new data block and copy some
* lines into it.
@@ -2090,20 +2124,20 @@ static int ml_append_int(
*/
long line_count_left, line_count_right;
int page_count_left, page_count_right;
- bhdr_T *hp_left;
- bhdr_T *hp_right;
- bhdr_T *hp_new;
+ bhdr_T *hp_left;
+ bhdr_T *hp_right;
+ bhdr_T *hp_new;
int lines_moved;
- int data_moved = 0; /* init to shut up gcc */
- int total_moved = 0; /* init to shut up gcc */
- DATA_BL *dp_right, *dp_left;
+ int data_moved = 0; // init to shut up gcc
+ int total_moved = 0; // init to shut up gcc
+ DATA_BL *dp_right, *dp_left;
int stack_idx;
bool in_left;
int lineadd;
blocknr_T bnum_left, bnum_right;
linenr_T lnum_left, lnum_right;
int pb_idx;
- PTR_BL *pp_new;
+ PTR_BL *pp_new;
/*
* We are going to allocate a new data block. Depending on the
@@ -2113,7 +2147,7 @@ static int ml_append_int(
* also put in the right block. This method is more efficient when
* inserting a lot of lines at one place.
*/
- if (db_idx < 0) { /* left block is new, right block is existing */
+ if (db_idx < 0) { // left block is new, right block is existing
lines_moved = 0;
in_left = true;
// space_needed does not change
@@ -2138,12 +2172,12 @@ static int ml_append_int(
page_count = ((space_needed + HEADER_SIZE) + page_size - 1) / page_size;
hp_new = ml_new_data(mfp, newfile, page_count);
- if (db_idx < 0) { /* left block is new */
+ if (db_idx < 0) { // left block is new
hp_left = hp_new;
hp_right = hp;
line_count_left = 0;
line_count_right = line_count;
- } else { /* right block is new */
+ } else { // right block is new
hp_left = hp;
hp_right = hp_new;
line_count_left = line_count;
@@ -2163,11 +2197,12 @@ static int ml_append_int(
dp_right->db_txt_start -= len;
dp_right->db_free -= len + INDEX_SIZE;
dp_right->db_index[0] = dp_right->db_txt_start;
- if (mark)
+ if (mark) {
dp_right->db_index[0] |= DB_MARKED;
+ }
memmove((char *)dp_right + dp_right->db_txt_start,
- line, (size_t)len);
+ line, (size_t)len);
++line_count_right;
}
/*
@@ -2179,8 +2214,8 @@ static int ml_append_int(
dp_right->db_txt_start -= data_moved;
dp_right->db_free -= total_moved;
memmove((char *)dp_right + dp_right->db_txt_start,
- (char *)dp_left + dp_left->db_txt_start,
- (size_t)data_moved);
+ (char *)dp_left + dp_left->db_txt_start,
+ (size_t)data_moved);
offset = dp_right->db_txt_start - dp_left->db_txt_start;
dp_left->db_txt_start += data_moved;
dp_left->db_free += total_moved;
@@ -2189,8 +2224,9 @@ static int ml_append_int(
* update indexes in the new block
*/
for (to = line_count_right, from = db_idx + 1;
- from < line_count_left; ++from, ++to)
+ from < line_count_left; ++from, ++to) {
dp_right->db_index[to] = dp->db_index[from] + offset;
+ }
line_count_right += lines_moved;
line_count_left -= lines_moved;
}
@@ -2202,22 +2238,24 @@ static int ml_append_int(
dp_left->db_txt_start -= len;
dp_left->db_free -= len + INDEX_SIZE;
dp_left->db_index[line_count_left] = dp_left->db_txt_start;
- if (mark)
+ if (mark) {
dp_left->db_index[line_count_left] |= DB_MARKED;
+ }
memmove((char *)dp_left + dp_left->db_txt_start,
- line, (size_t)len);
+ line, (size_t)len);
++line_count_left;
}
- if (db_idx < 0) { /* left block is new */
+ if (db_idx < 0) { // left block is new
lnum_left = lnum + 1;
lnum_right = 0;
- } else { /* right block is new */
+ } else { // right block is new
lnum_left = 0;
- if (in_left)
+ if (in_left) {
lnum_right = lnum + 2;
- else
+ } else {
lnum_right = lnum + 1;
+ }
}
dp_left->db_line_count = line_count_left;
dp_right->db_line_count = line_count_right;
@@ -2228,10 +2266,12 @@ static int ml_append_int(
* The old one (hp, in ml_locked) gets a positive blocknumber if
* we changed it and we are not editing a new file.
*/
- if (lines_moved || in_left)
+ if (lines_moved || in_left) {
buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
- if (!newfile && db_idx >= 0 && in_left)
+ }
+ if (!newfile && db_idx >= 0 && in_left) {
buf->b_ml.ml_flags |= ML_LOCKED_POS;
+ }
mf_put(mfp, hp_new, true, false);
/*
@@ -2250,9 +2290,10 @@ static int ml_append_int(
--stack_idx) {
ip = &(buf->b_ml.ml_stack[stack_idx]);
pb_idx = ip->ip_index;
- if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
+ if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL) {
return FAIL;
- pp = hp->bh_data; /* must be pointer block */
+ }
+ pp = hp->bh_data; // must be pointer block
if (pp->pb_id != PTR_ID) {
IEMSG(_("E317: pointer block id wrong 3"));
mf_put(mfp, hp, false, false);
@@ -2262,12 +2303,13 @@ static int ml_append_int(
* TODO: If the pointer block is full and we are adding at the end
* try to insert in front of the next block
*/
- /* block not full, add one entry */
+ // block not full, add one entry
if (pp->pb_count < pp->pb_count_max) {
- if (pb_idx + 1 < (int)pp->pb_count)
+ if (pb_idx + 1 < (int)pp->pb_count) {
memmove(&pp->pb_pointer[pb_idx + 2],
- &pp->pb_pointer[pb_idx + 1],
- (size_t)(pp->pb_count - pb_idx - 1) * sizeof(PTR_EN));
+ &pp->pb_pointer[pb_idx + 1],
+ (size_t)(pp->pb_count - pb_idx - 1) * sizeof(PTR_EN));
+ }
++pp->pb_count;
pp->pb_pointer[pb_idx].pe_line_count = line_count_left;
pp->pb_pointer[pb_idx].pe_bnum = bnum_left;
@@ -2276,19 +2318,21 @@ static int ml_append_int(
pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;
- if (lnum_left != 0)
+ if (lnum_left != 0) {
pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left;
- if (lnum_right != 0)
+ }
+ if (lnum_right != 0) {
pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right;
+ }
mf_put(mfp, hp, true, false);
- buf->b_ml.ml_stack_top = stack_idx + 1; /* truncate stack */
+ buf->b_ml.ml_stack_top = stack_idx + 1; // truncate stack
if (lineadd) {
--(buf->b_ml.ml_stack_top);
- /* fix line count for rest of blocks in the stack */
+ // fix line count for rest of blocks in the stack
ml_lineadd(buf, lineadd);
- /* fix stack itself */
+ // fix stack itself
buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
lineadd;
++(buf->b_ml.ml_stack_top);
@@ -2298,21 +2342,23 @@ static int ml_append_int(
* We are finished, break the loop here.
*/
break;
- } else { /* pointer block full */
+ } else { // pointer block full
/*
* split the pointer block
* allocate a new pointer block
* move some of the pointer into the new block
* prepare for updating the parent block
*/
- for (;; ) { /* do this twice when splitting block 1 */
+ for (;; ) { // do this twice when splitting block 1
hp_new = ml_new_ptr(mfp);
- if (hp_new == NULL) /* TODO: try to fix tree */
+ if (hp_new == NULL) { // TODO: try to fix tree
return FAIL;
+ }
pp_new = hp_new->bh_data;
- if (hp->bh_bnum != 1)
+ if (hp->bh_bnum != 1) {
break;
+ }
/*
* if block 1 becomes full the tree is given an extra level
@@ -2326,12 +2372,12 @@ static int ml_append_int(
pp->pb_pointer[0].pe_line_count = buf->b_ml.ml_line_count;
pp->pb_pointer[0].pe_old_lnum = 1;
pp->pb_pointer[0].pe_page_count = 1;
- mf_put(mfp, hp, true, false); /* release block 1 */
- hp = hp_new; /* new block is to be split */
+ mf_put(mfp, hp, true, false); // release block 1
+ hp = hp_new; // new block is to be split
pp = pp_new;
CHECK(stack_idx != 0, _("stack_idx should be 0"));
ip->ip_index = 0;
- ++stack_idx; /* do block 1 again later */
+ ++stack_idx; // do block 1 again later
}
/*
* move the pointers after the current one to the new block
@@ -2340,15 +2386,16 @@ static int ml_append_int(
total_moved = pp->pb_count - pb_idx - 1;
if (total_moved) {
memmove(&pp_new->pb_pointer[0],
- &pp->pb_pointer[pb_idx + 1],
- (size_t)(total_moved) * sizeof(PTR_EN));
+ &pp->pb_pointer[pb_idx + 1],
+ (size_t)(total_moved) * sizeof(PTR_EN));
pp_new->pb_count = total_moved;
pp->pb_count -= total_moved - 1;
pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right;
pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;
- if (lnum_right)
+ if (lnum_right) {
pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right;
+ }
} else {
pp_new->pb_count = 1;
pp_new->pb_pointer[0].pe_bnum = bnum_right;
@@ -2359,8 +2406,9 @@ static int ml_append_int(
pp->pb_pointer[pb_idx].pe_bnum = bnum_left;
pp->pb_pointer[pb_idx].pe_line_count = line_count_left;
pp->pb_pointer[pb_idx].pe_page_count = page_count_left;
- if (lnum_left)
+ if (lnum_left) {
pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left;
+ }
lnum_left = 0;
lnum_right = 0;
@@ -2368,11 +2416,13 @@ static int ml_append_int(
* recompute line counts
*/
line_count_right = 0;
- for (i = 0; i < (int)pp_new->pb_count; ++i)
+ for (i = 0; i < (int)pp_new->pb_count; ++i) {
line_count_right += pp_new->pb_pointer[i].pe_line_count;
+ }
line_count_left = 0;
- for (i = 0; i < (int)pp->pb_count; ++i)
+ for (i = 0; i < (int)pp->pb_count; ++i) {
line_count_left += pp->pb_pointer[i].pe_line_count;
+ }
bnum_left = hp->bh_bnum;
bnum_right = hp_new->bh_bnum;
@@ -2392,7 +2442,7 @@ static int ml_append_int(
}
}
- /* The line was inserted below 'lnum' */
+ // The line was inserted below 'lnum'
ml_updatechunk(buf, lnum + 1, (long)len, ML_CHNK_ADDLINE);
return OK;
}
@@ -2439,8 +2489,9 @@ int ml_replace(linenr_T lnum, char_u *line, bool copy)
// return FAIL for failure, OK otherwise
int ml_replace_buf(buf_T *buf, linenr_T lnum, char_u *line, bool copy)
{
- if (line == NULL) /* just checking... */
+ if (line == NULL) { // just checking...
return FAIL;
+ }
// When starting up, we might still need to create the memfile
if (buf->b_ml.ml_mfp == NULL && open_buffer(false, NULL, 0) == FAIL) {
@@ -2487,12 +2538,12 @@ int ml_delete(linenr_T lnum, bool message)
static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
{
- bhdr_T *hp;
- memfile_T *mfp;
- DATA_BL *dp;
- PTR_BL *pp;
- infoptr_T *ip;
- int count; /* number of entries in block */
+ bhdr_T *hp;
+ memfile_T *mfp;
+ DATA_BL *dp;
+ PTR_BL *pp;
+ infoptr_T *ip;
+ int count; // number of entries in block
int idx;
int stack_idx;
int text_start;
@@ -2500,19 +2551,22 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
long line_size;
int i;
- if (lnum < 1 || lnum > buf->b_ml.ml_line_count)
+ if (lnum < 1 || lnum > buf->b_ml.ml_line_count) {
return FAIL;
+ }
- if (lowest_marked && lowest_marked > lnum)
+ if (lowest_marked && lowest_marked > lnum) {
lowest_marked--;
+ }
/*
* If the file becomes empty the last line is replaced by an empty line.
*/
- if (buf->b_ml.ml_line_count == 1) { /* file becomes empty */
+ if (buf->b_ml.ml_line_count == 1) { // file becomes empty
if (message
- )
+ ) {
set_keep_msg((char_u *)_(no_lines_msg), 0);
+ }
i = ml_replace((linenr_T)1, (char_u *)"", true);
buf->b_ml.ml_flags |= ML_EMPTY;
@@ -2526,14 +2580,16 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
* This also releases any locked block.
*/
mfp = buf->b_ml.ml_mfp;
- if (mfp == NULL)
+ if (mfp == NULL) {
return FAIL;
+ }
- if ((hp = ml_find_line(buf, lnum, ML_DELETE)) == NULL)
+ if ((hp = ml_find_line(buf, lnum, ML_DELETE)) == NULL) {
return FAIL;
+ }
dp = hp->bh_data;
- /* compute line count before the delete */
+ // compute line count before the delete
count = (long)(buf->b_ml.ml_locked_high)
- (long)(buf->b_ml.ml_locked_low) + 2;
idx = lnum - buf->b_ml.ml_locked_low;
@@ -2541,10 +2597,11 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
--buf->b_ml.ml_line_count;
line_start = ((dp->db_index[idx]) & DB_INDEX_MASK);
- if (idx == 0) /* first line in block, text at the end */
+ if (idx == 0) { // first line in block, text at the end
line_size = dp->db_txt_end - line_start;
- else
+ } else {
line_size = ((dp->db_index[idx - 1]) & DB_INDEX_MASK) - line_start;
+ }
// Line should always have an NL char internally (represented as NUL),
// even if 'noeol' is set.
@@ -2560,33 +2617,35 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
* ml_find_line().
*/
if (count == 1) {
- mf_free(mfp, hp); /* free the data block */
+ mf_free(mfp, hp); // free the data block
buf->b_ml.ml_locked = NULL;
for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0;
--stack_idx) {
- buf->b_ml.ml_stack_top = 0; /* stack is invalid when failing */
+ buf->b_ml.ml_stack_top = 0; // stack is invalid when failing
ip = &(buf->b_ml.ml_stack[stack_idx]);
idx = ip->ip_index;
- if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
+ if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL) {
return FAIL;
- pp = hp->bh_data; /* must be pointer block */
+ }
+ pp = hp->bh_data; // must be pointer block
if (pp->pb_id != PTR_ID) {
IEMSG(_("E317: pointer block id wrong 4"));
mf_put(mfp, hp, false, false);
return FAIL;
}
count = --(pp->pb_count);
- if (count == 0) /* the pointer block becomes empty! */
+ if (count == 0) { // the pointer block becomes empty!
mf_free(mfp, hp);
- else {
- if (count != idx) /* move entries after the deleted one */
+ } else {
+ if (count != idx) { // move entries after the deleted one
memmove(&pp->pb_pointer[idx], &pp->pb_pointer[idx + 1],
- (size_t)(count - idx) * sizeof(PTR_EN));
+ (size_t)(count - idx) * sizeof(PTR_EN));
+ }
mf_put(mfp, hp, true, false);
- buf->b_ml.ml_stack_top = stack_idx; /* truncate stack */
- /* fix line count for rest of blocks in the stack */
+ buf->b_ml.ml_stack_top = stack_idx; // truncate stack
+ // fix line count for rest of blocks in the stack
if (buf->b_ml.ml_locked_lineadd != 0) {
ml_lineadd(buf, buf->b_ml.ml_locked_lineadd);
buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
@@ -2604,14 +2663,15 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
*/
text_start = dp->db_txt_start;
memmove((char *)dp + text_start + line_size,
- (char *)dp + text_start, (size_t)(line_start - text_start));
+ (char *)dp + text_start, (size_t)(line_start - text_start));
/*
* delete the index by moving the next indexes backwards
* Adjust the indexes for the text movement.
*/
- for (i = idx; i < count - 1; ++i)
+ for (i = idx; i < count - 1; ++i) {
dp->db_index[i] = dp->db_index[i + 1] + line_size;
+ }
dp->db_free += line_size + INDEX_SIZE;
dp->db_txt_start += line_size;
@@ -2632,24 +2692,25 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
*/
void ml_setmarked(linenr_T lnum)
{
- bhdr_T *hp;
+ bhdr_T *hp;
DATA_BL *dp;
- /* invalid line number */
+ // invalid line number
if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count
- || curbuf->b_ml.ml_mfp == NULL)
- return; /* give error message? */
-
- if (lowest_marked == 0 || lowest_marked > lnum)
+ || curbuf->b_ml.ml_mfp == NULL) {
+ return; // give error message?
+ }
+ if (lowest_marked == 0 || lowest_marked > lnum) {
lowest_marked = lnum;
+ }
/*
* find the data block containing the line
* This also fills the stack with the blocks from the root to the data block
* This also releases any locked block.
*/
- if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
- return; /* give error message? */
-
+ if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL) {
+ return; // give error message?
+ }
dp = hp->bh_data;
dp->db_index[lnum - curbuf->b_ml.ml_locked_low] |= DB_MARKED;
curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
@@ -2660,13 +2721,14 @@ void ml_setmarked(linenr_T lnum)
*/
linenr_T ml_firstmarked(void)
{
- bhdr_T *hp;
- DATA_BL *dp;
+ bhdr_T *hp;
+ DATA_BL *dp;
linenr_T lnum;
int i;
- if (curbuf->b_ml.ml_mfp == NULL)
- return (linenr_T) 0;
+ if (curbuf->b_ml.ml_mfp == NULL) {
+ return (linenr_T)0;
+ }
/*
* The search starts with lowest_marked line. This is the last line where
@@ -2678,22 +2740,23 @@ linenr_T ml_firstmarked(void)
* This also fills the stack with the blocks from the root to the data
* block This also releases any locked block.
*/
- if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
- return (linenr_T)0; /* give error message? */
-
+ if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL) {
+ return (linenr_T)0; // give error message?
+ }
dp = hp->bh_data;
for (i = lnum - curbuf->b_ml.ml_locked_low;
- lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum)
+ lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum) {
if ((dp->db_index[i]) & DB_MARKED) {
(dp->db_index[i]) &= DB_INDEX_MASK;
curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
lowest_marked = lnum + 1;
return lnum;
}
+ }
}
- return (linenr_T) 0;
+ return (linenr_T)0;
}
/*
@@ -2701,13 +2764,14 @@ linenr_T ml_firstmarked(void)
*/
void ml_clearmarked(void)
{
- bhdr_T *hp;
- DATA_BL *dp;
+ bhdr_T *hp;
+ DATA_BL *dp;
linenr_T lnum;
int i;
- if (curbuf->b_ml.ml_mfp == NULL) /* nothing to do */
+ if (curbuf->b_ml.ml_mfp == NULL) { // nothing to do
return;
+ }
/*
* The search starts with line lowest_marked.
@@ -2718,21 +2782,21 @@ void ml_clearmarked(void)
* This also fills the stack with the blocks from the root to the data
* block and releases any locked block.
*/
- if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
- return; /* give error message? */
-
+ if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL) {
+ return; // give error message?
+ }
dp = hp->bh_data;
for (i = lnum - curbuf->b_ml.ml_locked_low;
- lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum)
+ lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum) {
if ((dp->db_index[i]) & DB_MARKED) {
(dp->db_index[i]) &= DB_INDEX_MASK;
curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
}
+ }
}
lowest_marked = 0;
- return;
}
size_t ml_flush_deleted_bytes(buf_T *buf, size_t *codepoints, size_t *codeunits)
@@ -2751,11 +2815,11 @@ size_t ml_flush_deleted_bytes(buf_T *buf, size_t *codepoints, size_t *codeunits)
*/
static void ml_flush_line(buf_T *buf)
{
- bhdr_T *hp;
- DATA_BL *dp;
+ bhdr_T *hp;
+ DATA_BL *dp;
linenr_T lnum;
- char_u *new_line;
- char_u *old_line;
+ char_u *new_line;
+ char_u *old_line;
colnr_T new_len;
int old_len;
int extra;
@@ -2765,13 +2829,14 @@ static void ml_flush_line(buf_T *buf)
int i;
static bool entered = false;
- if (buf->b_ml.ml_line_lnum == 0 || buf->b_ml.ml_mfp == NULL)
- return; /* nothing to do */
-
+ if (buf->b_ml.ml_line_lnum == 0 || buf->b_ml.ml_mfp == NULL) {
+ return; // nothing to do
+ }
if (buf->b_ml.ml_flags & ML_LINE_DIRTY) {
- /* This code doesn't work recursively. */
- if (entered)
+ // This code doesn't work recursively.
+ if (entered) {
return;
+ }
entered = true;
buf->flush_count++;
@@ -2787,39 +2852,41 @@ static void ml_flush_line(buf_T *buf)
idx = lnum - buf->b_ml.ml_locked_low;
start = ((dp->db_index[idx]) & DB_INDEX_MASK);
old_line = (char_u *)dp + start;
- if (idx == 0) /* line is last in block */
+ if (idx == 0) { // line is last in block
old_len = dp->db_txt_end - start;
- else /* text of previous line follows */
+ } else { // text of previous line follows
old_len = (dp->db_index[idx - 1] & DB_INDEX_MASK) - start;
+ }
new_len = (colnr_T)STRLEN(new_line) + 1;
- extra = new_len - old_len; /* negative if lines gets smaller */
+ extra = new_len - old_len; // negative if lines gets smaller
/*
* if new line fits in data block, replace directly
*/
if ((int)dp->db_free >= extra) {
- /* if the length changes and there are following lines */
+ // if the length changes and there are following lines
count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1;
if (extra != 0 && idx < count - 1) {
- /* move text of following lines */
+ // move text of following lines
memmove((char *)dp + dp->db_txt_start - extra,
- (char *)dp + dp->db_txt_start,
- (size_t)(start - dp->db_txt_start));
+ (char *)dp + dp->db_txt_start,
+ (size_t)(start - dp->db_txt_start));
- /* adjust pointers of this and following lines */
- for (i = idx + 1; i < count; ++i)
+ // adjust pointers of this and following lines
+ for (i = idx + 1; i < count; ++i) {
dp->db_index[i] -= extra;
+ }
}
dp->db_index[idx] -= extra;
- /* adjust free space */
+ // adjust free space
dp->db_free -= extra;
dp->db_txt_start -= extra;
- /* copy new line into the data block */
+ // copy new line into the data block
memmove(old_line - extra, new_line, (size_t)new_len);
buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
- /* The else case is already covered by the insert and delete */
+ // The else case is already covered by the insert and delete
ml_updatechunk(buf, lnum, (long)extra, ML_CHNK_UPDLINE);
} else {
// Cannot do it in one data block: Delete and append.
@@ -2876,8 +2943,8 @@ static bhdr_T *ml_new_ptr(memfile_T *mfp)
* lookup line 'lnum' in a memline
*
* action: if ML_DELETE or ML_INSERT the line count is updated while searching
- * if ML_FLUSH only flush a locked block
- * if ML_FIND just find the line
+ * if ML_FLUSH only flush a locked block
+ * if ML_FIND just find the line
*
* If the block was found it is locked and put in ml_locked.
* The stack is updated to lead to the locked block. The ip_high field in
@@ -2889,11 +2956,11 @@ static bhdr_T *ml_new_ptr(memfile_T *mfp)
*/
static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action)
{
- DATA_BL *dp;
- PTR_BL *pp;
- infoptr_T *ip;
- bhdr_T *hp;
- memfile_T *mfp;
+ DATA_BL *dp;
+ PTR_BL *pp;
+ infoptr_T *ip;
+ bhdr_T *hp;
+ memfile_T *mfp;
linenr_T t;
blocknr_T bnum, bnum2;
int dirty;
@@ -2927,58 +2994,63 @@ static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action)
}
mf_put(mfp, buf->b_ml.ml_locked, buf->b_ml.ml_flags & ML_LOCKED_DIRTY,
- buf->b_ml.ml_flags & ML_LOCKED_POS);
+ buf->b_ml.ml_flags & ML_LOCKED_POS);
buf->b_ml.ml_locked = NULL;
/*
* If lines have been added or deleted in the locked block, need to
* update the line count in pointer blocks.
*/
- if (buf->b_ml.ml_locked_lineadd != 0)
+ if (buf->b_ml.ml_locked_lineadd != 0) {
ml_lineadd(buf, buf->b_ml.ml_locked_lineadd);
+ }
}
- if (action == ML_FLUSH) /* nothing else to do */
+ if (action == ML_FLUSH) { // nothing else to do
return NULL;
+ }
- bnum = 1; /* start at the root of the tree */
+ bnum = 1; // start at the root of the tree
page_count = 1;
low = 1;
high = buf->b_ml.ml_line_count;
- if (action == ML_FIND) { /* first try stack entries */
+ if (action == ML_FIND) { // first try stack entries
for (top = buf->b_ml.ml_stack_top - 1; top >= 0; --top) {
ip = &(buf->b_ml.ml_stack[top]);
if (ip->ip_low <= lnum && ip->ip_high >= lnum) {
bnum = ip->ip_bnum;
low = ip->ip_low;
high = ip->ip_high;
- buf->b_ml.ml_stack_top = top; /* truncate stack at prev entry */
+ buf->b_ml.ml_stack_top = top; // truncate stack at prev entry
break;
}
}
- if (top < 0)
- buf->b_ml.ml_stack_top = 0; /* not found, start at the root */
- } else /* ML_DELETE or ML_INSERT */
- buf->b_ml.ml_stack_top = 0; /* start at the root */
-
+ if (top < 0) {
+ buf->b_ml.ml_stack_top = 0; // not found, start at the root
+ }
+ } else { // ML_DELETE or ML_INSERT
+ buf->b_ml.ml_stack_top = 0; // start at the root
+ }
/*
* search downwards in the tree until a data block is found
*/
for (;; ) {
- if ((hp = mf_get(mfp, bnum, page_count)) == NULL)
+ if ((hp = mf_get(mfp, bnum, page_count)) == NULL) {
goto error_noblock;
+ }
/*
* update high for insert/delete
*/
- if (action == ML_INSERT)
+ if (action == ML_INSERT) {
++high;
- else if (action == ML_DELETE)
+ } else if (action == ML_DELETE) {
--high;
+ }
dp = hp->bh_data;
- if (dp->db_id == DATA_ID) { /* data block */
+ if (dp->db_id == DATA_ID) { // data block
buf->b_ml.ml_locked = hp;
buf->b_ml.ml_locked_low = low;
buf->b_ml.ml_locked_high = high;
@@ -2987,7 +3059,7 @@ static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action)
return hp;
}
- pp = (PTR_BL *)(dp); /* must be pointer block */
+ pp = (PTR_BL *)(dp); // must be pointer block
if (pp->pb_id != PTR_ID) {
IEMSG(_("E317: pointer block id wrong"));
goto error_block;
@@ -2998,7 +3070,7 @@ static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action)
ip->ip_bnum = bnum;
ip->ip_low = low;
ip->ip_high = high;
- ip->ip_index = -1; /* index not known yet */
+ ip->ip_index = -1; // index not known yet
dirty = FALSE;
for (idx = 0; idx < (int)pp->pb_count; ++idx) {
@@ -3030,7 +3102,6 @@ static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action)
if (lnum > buf->b_ml.ml_line_count) {
IEMSGN(_("E322: line number out of range: %" PRId64 " past the end"),
lnum - buf->b_ml.ml_line_count);
-
} else {
IEMSGN(_("E323: line count wrong in block %" PRId64), bnum);
}
@@ -3054,10 +3125,11 @@ error_noblock:
* the incremented/decremented line counts, because there won't be a line
* inserted/deleted after all.
*/
- if (action == ML_DELETE)
+ if (action == ML_DELETE) {
ml_lineadd(buf, 1);
- else if (action == ML_INSERT)
+ } else if (action == ML_INSERT) {
ml_lineadd(buf, -1);
+ }
buf->b_ml.ml_stack_top = 0;
return NULL;
}
@@ -3071,9 +3143,9 @@ static int ml_add_stack(buf_T *buf)
{
int top = buf->b_ml.ml_stack_top;
- /* may have to increase the stack size */
+ // may have to increase the stack size
if (top == buf->b_ml.ml_stack_size) {
- CHECK(top > 0, _("Stack size increases")); /* more than 5 levels??? */
+ CHECK(top > 0, _("Stack size increases")); // more than 5 levels???
buf->b_ml.ml_stack_size += STACK_INCR;
size_t new_size = sizeof(infoptr_T) * buf->b_ml.ml_stack_size;
@@ -3097,16 +3169,17 @@ static int ml_add_stack(buf_T *buf)
static void ml_lineadd(buf_T *buf, int count)
{
int idx;
- infoptr_T *ip;
- PTR_BL *pp;
- memfile_T *mfp = buf->b_ml.ml_mfp;
- bhdr_T *hp;
+ infoptr_T *ip;
+ PTR_BL *pp;
+ memfile_T *mfp = buf->b_ml.ml_mfp;
+ bhdr_T *hp;
for (idx = buf->b_ml.ml_stack_top - 1; idx >= 0; --idx) {
ip = &(buf->b_ml.ml_stack[idx]);
- if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
+ if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL) {
break;
- pp = hp->bh_data; /* must be pointer block */
+ }
+ pp = hp->bh_data; // must be pointer block
if (pp->pb_id != PTR_ID) {
mf_put(mfp, hp, false, false);
IEMSG(_("E317: pointer block id wrong 2"));
@@ -3132,14 +3205,15 @@ int resolve_symlink(const char_u *fname, char_u *buf)
int ret;
int depth = 0;
- if (fname == NULL)
+ if (fname == NULL) {
return FAIL;
+ }
- /* Put the result so far in tmp[], starting with the original name. */
+ // Put the result so far in tmp[], starting with the original name.
STRLCPY(tmp, fname, MAXPATHL);
for (;; ) {
- /* Limit symlink depth to 100, catch recursive loops. */
+ // Limit symlink depth to 100, catch recursive loops.
if (++depth == 100) {
EMSG2(_("E773: Symlink loop for \"%s\""), fname);
return FAIL;
@@ -3148,17 +3222,18 @@ int resolve_symlink(const char_u *fname, char_u *buf)
ret = readlink((char *)tmp, (char *)buf, MAXPATHL - 1);
if (ret <= 0) {
if (errno == EINVAL || errno == ENOENT) {
- /* Found non-symlink or not existing file, stop here.
- * When at the first level use the unmodified name, skip the
- * call to vim_FullName(). */
- if (depth == 1)
+ // Found non-symlink or not existing file, stop here.
+ // When at the first level use the unmodified name, skip the
+ // call to vim_FullName().
+ if (depth == 1) {
return FAIL;
+ }
- /* Use the resolved name in tmp[]. */
+ // Use the resolved name in tmp[].
break;
}
- /* There must be some error reading links, use original name. */
+ // There must be some error reading links, use original name.
return FAIL;
}
buf[ret] = NUL;
@@ -3193,8 +3268,8 @@ int resolve_symlink(const char_u *fname, char_u *buf)
*/
char_u *makeswapname(char_u *fname, char_u *ffname, buf_T *buf, char_u *dir_name)
{
- char_u *r, *s;
- char_u *fname_res = fname;
+ char_u *r, *s;
+ char_u *fname_res = fname;
#ifdef HAVE_READLINK
char_u fname_buf[MAXPATHL];
@@ -3221,46 +3296,43 @@ char_u *makeswapname(char_u *fname, char_u *ffname, buf_T *buf, char_u *dir_name
// Prepend a '.' to the swap file name for the current directory.
r = (char_u *)modname((char *)fname_res, ".swp",
- dir_name[0] == '.' && dir_name[1] == NUL);
- if (r == NULL) /* out of memory */
+ dir_name[0] == '.' && dir_name[1] == NUL);
+ if (r == NULL) { // out of memory
return NULL;
+ }
s = get_file_in_dir(r, dir_name);
xfree(r);
return s;
}
-/*
- * Get file name to use for swap file or backup file.
- * Use the name of the edited file "fname" and an entry in the 'dir' or 'bdir'
- * option "dname".
- * - If "dname" is ".", return "fname" (swap file in dir of file).
- * - If "dname" starts with "./", insert "dname" in "fname" (swap file
- * relative to dir of file).
- * - Otherwise, prepend "dname" to the tail of "fname" (swap file in specific
- * dir).
- *
- * The return value is an allocated string and can be NULL.
- */
-char_u *
-get_file_in_dir (
- char_u *fname,
- char_u *dname /* don't use "dirname", it is a global for Alpha */
-)
+/// Get file name to use for swap file or backup file.
+/// Use the name of the edited file "fname" and an entry in the 'dir' or 'bdir'
+/// option "dname".
+/// - If "dname" is ".", return "fname" (swap file in dir of file).
+/// - If "dname" starts with "./", insert "dname" in "fname" (swap file
+/// relative to dir of file).
+/// - Otherwise, prepend "dname" to the tail of "fname" (swap file in specific
+/// dir).
+///
+/// The return value is an allocated string and can be NULL.
+///
+/// @param dname don't use "dirname", it is a global for Alpha
+char_u *get_file_in_dir(char_u *fname, char_u *dname)
{
- char_u *t;
- char_u *tail;
- char_u *retval;
+ char_u *t;
+ char_u *tail;
+ char_u *retval;
int save_char;
tail = path_tail(fname);
- if (dname[0] == '.' && dname[1] == NUL)
+ if (dname[0] == '.' && dname[1] == NUL) {
retval = vim_strsave(fname);
- else if (dname[0] == '.' && vim_ispathsep(dname[1])) {
- if (tail == fname) /* no path before file name */
+ } else if (dname[0] == '.' && vim_ispathsep(dname[1])) {
+ if (tail == fname) { // no path before file name
retval = (char_u *)concat_fnames((char *)dname + 2, (char *)tail, TRUE);
- else {
+ } else {
save_char = *tail;
*tail = NUL;
t = (char_u *)concat_fnames((char *)fname, (char *)dname + 2, TRUE);
@@ -3276,14 +3348,11 @@ get_file_in_dir (
}
-/*
- * Print the ATTENTION message: info about an existing swap file.
- */
-static void
-attention_message (
- buf_T *buf, /* buffer being edited */
- char_u *fname /* swap file name */
-)
+/// Print the ATTENTION message: info about an existing swap file.
+///
+/// @param buf buffer being edited
+/// @param fname swap file name
+static void attention_message(buf_T *buf, char_u *fname)
{
assert(buf->b_fname != NULL);
@@ -3339,7 +3408,7 @@ attention_message (
*/
static int do_swapexists(buf_T *buf, char_u *fname)
{
- set_vim_var_string(VV_SWAPNAME, (char *) fname, -1);
+ set_vim_var_string(VV_SWAPNAME, (char *)fname, -1);
set_vim_var_string(VV_SWAPCHOICE, NULL, -1);
// Trigger SwapExists autocommands with <afile> set to the file being
@@ -3351,12 +3420,18 @@ static int do_swapexists(buf_T *buf, char_u *fname)
set_vim_var_string(VV_SWAPNAME, NULL, -1);
switch (*get_vim_var_str(VV_SWAPCHOICE)) {
- case 'o': return 1;
- case 'e': return 2;
- case 'r': return 3;
- case 'd': return 4;
- case 'q': return 5;
- case 'a': return 6;
+ case 'o':
+ return 1;
+ case 'e':
+ return 2;
+ case 'r':
+ return 3;
+ case 'd':
+ return 4;
+ case 'q':
+ return 5;
+ case 'a':
+ return 6;
}
return 0;
@@ -3385,14 +3460,13 @@ static int do_swapexists(buf_T *buf, char_u *fname)
/// never set to false.
///
/// @return [allocated] Name of the swap file.
-static char *findswapname(buf_T *buf, char **dirp, char *old_fname,
- bool *found_existing_dir)
+static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_existing_dir)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1, 2, 4)
{
char *fname;
size_t n;
char *dir_name;
- char *buf_fname = (char *) buf->b_fname;
+ char *buf_fname = (char *)buf->b_fname;
/*
* Isolate a directory name from *dirp and put it in dir_name.
@@ -3400,7 +3474,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname,
*/
const size_t dir_len = strlen(*dirp) + 1;
dir_name = xmalloc(dir_len);
- (void)copy_option_part((char_u **) dirp, (char_u *) dir_name, dir_len, ",");
+ (void)copy_option_part((char_u **)dirp, (char_u *)dir_name, dir_len, ",");
/*
* we try different names until we find one that does not exist yet
@@ -3459,7 +3533,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname,
// inode too.
expand_env(b0.b0_fname, NameBuff, MAXPATHL);
if (fnamecmp_ino(buf->b_ffname, NameBuff,
- char_to_long(b0.b0_ino))) {
+ char_to_long(b0.b0_ino))) {
differ = TRUE;
}
}
@@ -3468,7 +3542,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname,
// "~user/path/file". Expand it first.
expand_env(b0.b0_fname, NameBuff, MAXPATHL);
if (fnamecmp_ino(buf->b_ffname, NameBuff,
- char_to_long(b0.b0_ino))) {
+ char_to_long(b0.b0_ino))) {
differ = TRUE;
}
}
@@ -3532,12 +3606,10 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname,
choice = do_dialog(VIM_WARNING, (char_u *)_("VIM - ATTENTION"),
(char_u *)name,
process_still_running
- ? (char_u *)_(
- "&Open Read-Only\n&Edit anyway\n&Recover"
- "\n&Quit\n&Abort") :
- (char_u *)_(
- "&Open Read-Only\n&Edit anyway\n&Recover"
- "\n&Delete it\n&Quit\n&Abort"),
+ ? (char_u *)_("&Open Read-Only\n&Edit anyway\n&Recover"
+ "\n&Quit\n&Abort") :
+ (char_u *)_("&Open Read-Only\n&Edit anyway\n&Recover"
+ "\n&Delete it\n&Quit\n&Abort"),
1, NULL, false);
if (process_still_running && choice >= 4) {
@@ -3582,7 +3654,6 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname,
need_wait_return = true;
}
}
-
}
}
}
@@ -3593,19 +3664,19 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname,
* If that still isn't enough decrement the last but one char: ".svz"
* Can happen when editing many "No Name" buffers.
*/
- if (fname[n - 1] == 'a') { /* ".s?a" */
- if (fname[n - 2] == 'a') { /* ".saa": tried enough, give up */
+ if (fname[n - 1] == 'a') { // ".s?a"
+ if (fname[n - 2] == 'a') { // ".saa": tried enough, give up
EMSG(_("E326: Too many swap files found"));
XFREE_CLEAR(fname);
break;
}
- --fname[n - 2]; /* ".svz", ".suz", etc. */
+ --fname[n - 2]; // ".svz", ".suz", etc.
fname[n - 1] = 'z' + 1;
}
- --fname[n - 1]; /* ".swo", ".swn", etc. */
+ --fname[n - 1]; // ".swo", ".swn", etc.
}
- if (os_isdir((char_u *) dir_name)) {
+ if (os_isdir((char_u *)dir_name)) {
*found_existing_dir = true;
} else if (!*found_existing_dir && **dirp == NUL) {
int ret;
@@ -3630,66 +3701,62 @@ static int b0_magic_wrong(ZERO_BL *b0p)
|| b0p->b0_magic_char != B0_MAGIC_CHAR;
}
-/*
- * Compare current file name with file name from swap file.
- * Try to use inode numbers when possible.
- * Return non-zero when files are different.
- *
- * When comparing file names a few things have to be taken into consideration:
- * - When working over a network the full path of a file depends on the host.
- * We check the inode number if possible. It is not 100% reliable though,
- * because the device number cannot be used over a network.
- * - When a file does not exist yet (editing a new file) there is no inode
- * number.
- * - The file name in a swap file may not be valid on the current host. The
- * "~user" form is used whenever possible to avoid this.
- *
- * This is getting complicated, let's make a table:
- *
- * ino_c ino_s fname_c fname_s differ =
- *
- * both files exist -> compare inode numbers:
- * != 0 != 0 X X ino_c != ino_s
- *
- * inode number(s) unknown, file names available -> compare file names
- * == 0 X OK OK fname_c != fname_s
- * X == 0 OK OK fname_c != fname_s
- *
- * current file doesn't exist, file for swap file exist, file name(s) not
- * available -> probably different
- * == 0 != 0 FAIL X TRUE
- * == 0 != 0 X FAIL TRUE
- *
- * current file exists, inode for swap unknown, file name(s) not
- * available -> probably different
- * != 0 == 0 FAIL X TRUE
- * != 0 == 0 X FAIL TRUE
- *
- * current file doesn't exist, inode for swap unknown, one file name not
- * available -> probably different
- * == 0 == 0 FAIL OK TRUE
- * == 0 == 0 OK FAIL TRUE
- *
- * current file doesn't exist, inode for swap unknown, both file names not
- * available -> compare file names
- * == 0 == 0 FAIL FAIL fname_c != fname_s
- *
- * Only the last 32 bits of the inode will be used. This can't be changed
- * without making the block 0 incompatible with 32 bit versions.
- */
-
-static bool fnamecmp_ino(
- char_u *fname_c, // current file name
- char_u *fname_s, // file name from swap file
- long ino_block0
-)
+/// Compare current file name with file name from swap file.
+/// Try to use inode numbers when possible.
+/// Return non-zero when files are different.
+///
+/// When comparing file names a few things have to be taken into consideration:
+/// - When working over a network the full path of a file depends on the host.
+/// We check the inode number if possible. It is not 100% reliable though,
+/// because the device number cannot be used over a network.
+/// - When a file does not exist yet (editing a new file) there is no inode
+/// number.
+/// - The file name in a swap file may not be valid on the current host. The
+/// "~user" form is used whenever possible to avoid this.
+///
+/// This is getting complicated, let's make a table:
+///
+/// ino_c ino_s fname_c fname_s differ =
+///
+/// both files exist -> compare inode numbers:
+/// != 0 != 0 X X ino_c != ino_s
+///
+/// inode number(s) unknown, file names available -> compare file names
+/// == 0 X OK OK fname_c != fname_s
+/// X == 0 OK OK fname_c != fname_s
+///
+/// current file doesn't exist, file for swap file exist, file name(s) not
+/// available -> probably different
+/// == 0 != 0 FAIL X TRUE
+/// == 0 != 0 X FAIL TRUE
+///
+/// current file exists, inode for swap unknown, file name(s) not
+/// available -> probably different
+/// != 0 == 0 FAIL X TRUE
+/// != 0 == 0 X FAIL TRUE
+///
+/// current file doesn't exist, inode for swap unknown, one file name not
+/// available -> probably different
+/// == 0 == 0 FAIL OK TRUE
+/// == 0 == 0 OK FAIL TRUE
+///
+/// current file doesn't exist, inode for swap unknown, both file names not
+/// available -> compare file names
+/// == 0 == 0 FAIL FAIL fname_c != fname_s
+///
+/// Only the last 32 bits of the inode will be used. This can't be changed
+/// without making the block 0 incompatible with 32 bit versions.
+///
+/// @param fname_c current file name
+/// @param fname_s file name from swap file
+static bool fnamecmp_ino(char_u *fname_c, char_u *fname_s, long ino_block0)
{
- uint64_t ino_c = 0; /* ino of current file */
- uint64_t ino_s; /* ino of file from swap file */
- char_u buf_c[MAXPATHL]; /* full path of fname_c */
- char_u buf_s[MAXPATHL]; /* full path of fname_s */
- int retval_c; /* flag: buf_c valid */
- int retval_s; /* flag: buf_s valid */
+ uint64_t ino_c = 0; // ino of current file
+ uint64_t ino_s; // ino of file from swap file
+ char_u buf_c[MAXPATHL]; // full path of fname_c
+ char_u buf_s[MAXPATHL]; // full path of fname_s
+ int retval_c; // flag: buf_c valid
+ int retval_s; // flag: buf_s valid
FileInfo file_info;
if (os_fileinfo((char *)fname_c, &file_info)) {
@@ -3707,8 +3774,9 @@ static bool fnamecmp_ino(
ino_s = (uint64_t)ino_block0;
}
- if (ino_c && ino_s)
+ if (ino_c && ino_s) {
return ino_c != ino_s;
+ }
/*
* One of the inode numbers is unknown, try a forced vim_FullName() and
@@ -3716,8 +3784,9 @@ static bool fnamecmp_ino(
*/
retval_c = vim_FullName((char *)fname_c, (char *)buf_c, MAXPATHL, TRUE);
retval_s = vim_FullName((char *)fname_s, (char *)buf_s, MAXPATHL, TRUE);
- if (retval_c == OK && retval_s == OK)
+ if (retval_c == OK && retval_s == OK) {
return STRCMP(buf_c, buf_s) != 0;
+ }
/*
* Can't compare inodes or file names, guess that the files are different,
@@ -3768,11 +3837,12 @@ static long char_to_long(char_u *s)
*/
void ml_setflags(buf_T *buf)
{
- bhdr_T *hp;
- ZERO_BL *b0p;
+ bhdr_T *hp;
+ ZERO_BL *b0p;
- if (!buf->b_ml.ml_mfp)
+ if (!buf->b_ml.ml_mfp) {
return;
+ }
for (hp = buf->b_ml.ml_mfp->mf_used_last; hp != NULL; hp = hp->bh_prev) {
if (hp->bh_bnum == 0) {
b0p = hp->bh_data;
@@ -3787,19 +3857,19 @@ void ml_setflags(buf_T *buf)
}
}
-#define MLCS_MAXL 800 /* max no of lines in chunk */
-#define MLCS_MINL 400 /* should be half of MLCS_MAXL */
+#define MLCS_MAXL 800 // max no of lines in chunk
+#define MLCS_MINL 400 // should be half of MLCS_MAXL
/*
* Keep information for finding byte offset of a line, updtype may be one of:
* ML_CHNK_ADDLINE: Add len to parent chunk, possibly splitting it
- * Careful: ML_CHNK_ADDLINE may cause ml_find_line() to be called.
+ * Careful: ML_CHNK_ADDLINE may cause ml_find_line() to be called.
* ML_CHNK_DELLINE: Subtract len from parent chunk, possibly deleting it
* ML_CHNK_UPDLINE: Add len to parent chunk, as a signed entity.
*/
static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
{
- static buf_T *ml_upd_lastbuf = NULL;
+ static buf_T *ml_upd_lastbuf = NULL;
static linenr_T ml_upd_lastline;
static linenr_T ml_upd_lastcurline;
static int ml_upd_lastcurix;
@@ -3807,13 +3877,14 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
linenr_T curline = ml_upd_lastcurline;
int curix = ml_upd_lastcurix;
long size;
- chunksize_T *curchnk;
+ chunksize_T *curchnk;
int rest;
- bhdr_T *hp;
- DATA_BL *dp;
+ bhdr_T *hp;
+ DATA_BL *dp;
- if (buf->b_ml.ml_usedchunks == -1 || len == 0)
+ if (buf->b_ml.ml_usedchunks == -1 || len == 0) {
return;
+ }
if (buf->b_ml.ml_chunksize == NULL) {
buf->b_ml.ml_chunksize = xmalloc(sizeof(chunksize_T) * 100);
buf->b_ml.ml_numchunks = 100;
@@ -3841,8 +3912,8 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
|| updtype != ML_CHNK_ADDLINE) {
for (curline = 1, curix = 0;
curix < buf->b_ml.ml_usedchunks - 1
- && line >= curline +
- buf->b_ml.ml_chunksize[curix].mlcs_numlines;
+ && line >= curline +
+ buf->b_ml.ml_chunksize[curix].mlcs_numlines;
curix++) {
curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
}
@@ -3854,31 +3925,31 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
}
curchnk = buf->b_ml.ml_chunksize + curix;
- if (updtype == ML_CHNK_DELLINE)
+ if (updtype == ML_CHNK_DELLINE) {
len = -len;
+ }
curchnk->mlcs_totalsize += len;
if (updtype == ML_CHNK_ADDLINE) {
curchnk->mlcs_numlines++;
- /* May resize here so we don't have to do it in both cases below */
+ // May resize here so we don't have to do it in both cases below
if (buf->b_ml.ml_usedchunks + 1 >= buf->b_ml.ml_numchunks) {
buf->b_ml.ml_numchunks = buf->b_ml.ml_numchunks * 3 / 2;
- buf->b_ml.ml_chunksize = xrealloc(
- buf->b_ml.ml_chunksize,
- sizeof(chunksize_T) * buf->b_ml.ml_numchunks);
+ buf->b_ml.ml_chunksize = xrealloc(buf->b_ml.ml_chunksize,
+ sizeof(chunksize_T) * buf->b_ml.ml_numchunks);
}
if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MAXL) {
- int count; /* number of entries in block */
+ int count; // number of entries in block
int idx;
int text_end;
int linecnt;
memmove(buf->b_ml.ml_chunksize + curix + 1,
- buf->b_ml.ml_chunksize + curix,
- (buf->b_ml.ml_usedchunks - curix) *
- sizeof(chunksize_T));
- /* Compute length of first half of lines in the split chunk */
+ buf->b_ml.ml_chunksize + curix,
+ (buf->b_ml.ml_usedchunks - curix) *
+ sizeof(chunksize_T));
+ // Compute length of first half of lines in the split chunk
size = 0;
linecnt = 0;
while (curline < buf->b_ml.ml_line_count
@@ -3892,11 +3963,12 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
(long)(buf->b_ml.ml_locked_low) + 1;
idx = curline - buf->b_ml.ml_locked_low;
curline = buf->b_ml.ml_locked_high + 1;
- if (idx == 0) /* first line in block, text at the end */
+ if (idx == 0) { // first line in block, text at the end
text_end = dp->db_txt_end;
- else
+ } else {
text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
- /* Compute index of last line to use in this MEMLINE */
+ }
+ // Compute index of last line to use in this MEMLINE
rest = count - idx;
if (linecnt + rest > MLCS_MINL) {
idx += MLCS_MINL - linecnt - 1;
@@ -3912,7 +3984,7 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
buf->b_ml.ml_chunksize[curix].mlcs_totalsize = size;
buf->b_ml.ml_chunksize[curix + 1].mlcs_totalsize -= size;
buf->b_ml.ml_usedchunks++;
- ml_upd_lastbuf = NULL; /* Force recalc of curix & curline */
+ ml_upd_lastbuf = NULL; // Force recalc of curix & curline
return;
} else if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MINL
&& curix == buf->b_ml.ml_usedchunks - 1
@@ -3937,12 +4009,13 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
return;
}
dp = hp->bh_data;
- if (dp->db_line_count == 1)
+ if (dp->db_line_count == 1) {
rest = dp->db_txt_end - dp->db_txt_start;
- else
+ } else {
rest =
((dp->db_index[dp->db_line_count - 2]) & DB_INDEX_MASK)
- dp->db_txt_start;
+ }
curchnk->mlcs_totalsize = rest;
curchnk->mlcs_numlines = 1;
curchnk[-1].mlcs_totalsize -= rest;
@@ -3951,7 +4024,7 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
}
} else if (updtype == ML_CHNK_DELLINE) {
curchnk->mlcs_numlines--;
- ml_upd_lastbuf = NULL; /* Force recalc of curix & curline */
+ ml_upd_lastbuf = NULL; // Force recalc of curix & curline
if (curix < (buf->b_ml.ml_usedchunks - 1)
&& (curchnk->mlcs_numlines + curchnk[1].mlcs_numlines)
<= MLCS_MINL) {
@@ -3960,7 +4033,7 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
} else if (curix == 0 && curchnk->mlcs_numlines <= 0) {
buf->b_ml.ml_usedchunks--;
memmove(buf->b_ml.ml_chunksize, buf->b_ml.ml_chunksize + 1,
- buf->b_ml.ml_usedchunks * sizeof(chunksize_T));
+ buf->b_ml.ml_usedchunks * sizeof(chunksize_T));
return;
} else if (curix == 0 || (curchnk->mlcs_numlines > 10
&& (curchnk->mlcs_numlines +
@@ -3969,15 +4042,15 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
return;
}
- /* Collapse chunks */
+ // Collapse chunks
curchnk[-1].mlcs_numlines += curchnk->mlcs_numlines;
curchnk[-1].mlcs_totalsize += curchnk->mlcs_totalsize;
buf->b_ml.ml_usedchunks--;
if (curix < buf->b_ml.ml_usedchunks) {
memmove(buf->b_ml.ml_chunksize + curix,
- buf->b_ml.ml_chunksize + curix + 1,
- (buf->b_ml.ml_usedchunks - curix) *
- sizeof(chunksize_T));
+ buf->b_ml.ml_chunksize + curix + 1,
+ (buf->b_ml.ml_usedchunks - curix) *
+ sizeof(chunksize_T));
}
return;
}
@@ -4002,9 +4075,9 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
linenr_T curline;
int curix;
long size;
- bhdr_T *hp;
- DATA_BL *dp;
- int count; /* number of entries in block */
+ bhdr_T *hp;
+ DATA_BL *dp;
+ int count; // number of entries in block
int idx;
int start_idx;
int text_end;
@@ -4032,15 +4105,18 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
if (buf->b_ml.ml_usedchunks == -1
|| buf->b_ml.ml_chunksize == NULL
- || lnum < 0)
+ || lnum < 0) {
return -1;
+ }
- if (offp == NULL)
+ if (offp == NULL) {
offset = 0;
- else
+ } else {
offset = *offp;
- if (lnum == 0 && offset <= 0)
- return 1; /* Not a "find offset" and offset 0 _must_ be in line 1 */
+ }
+ if (lnum == 0 && offset <= 0) {
+ return 1; // Not a "find offset" and offset 0 _must_ be in line 1
+ }
/*
* Find the last chunk before the one containing our line. Last chunk is
* special because it will never qualify
@@ -4056,36 +4132,41 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
+ ffdos * buf->b_ml.ml_chunksize[curix].mlcs_numlines))) {
curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
size += buf->b_ml.ml_chunksize[curix].mlcs_totalsize;
- if (offset && ffdos)
+ if (offset && ffdos) {
size += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
+ }
curix++;
}
while ((lnum != 0 && curline < lnum) || (offset != 0 && size < offset)) {
if (curline > buf->b_ml.ml_line_count
- || (hp = ml_find_line(buf, curline, ML_FIND)) == NULL)
+ || (hp = ml_find_line(buf, curline, ML_FIND)) == NULL) {
return -1;
+ }
dp = hp->bh_data;
count = (long)(buf->b_ml.ml_locked_high) -
(long)(buf->b_ml.ml_locked_low) + 1;
start_idx = idx = curline - buf->b_ml.ml_locked_low;
- if (idx == 0) /* first line in block, text at the end */
+ if (idx == 0) { // first line in block, text at the end
text_end = dp->db_txt_end;
- else
+ } else {
text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
- /* Compute index of last line to use in this MEMLINE */
+ }
+ // Compute index of last line to use in this MEMLINE
if (lnum != 0) {
- if (curline + (count - idx) >= lnum)
+ if (curline + (count - idx) >= lnum) {
idx += lnum - curline - 1;
- else
+ } else {
idx = count - 1;
+ }
} else {
extra = 0;
while (offset >= size
+ text_end - (int)((dp->db_index[idx]) & DB_INDEX_MASK)
+ ffdos) {
- if (ffdos)
+ if (ffdos) {
size++;
+ }
if (idx == count - 1) {
extra = 1;
break;
@@ -4096,28 +4177,31 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
len = text_end - ((dp->db_index[idx]) & DB_INDEX_MASK);
size += len;
if (offset != 0 && size >= offset) {
- if (size + ffdos == offset)
+ if (size + ffdos == offset) {
*offp = 0;
- else if (idx == start_idx)
+ } else if (idx == start_idx) {
*offp = offset - size + len;
- else
+ } else {
*offp = offset - size + len
- (text_end - ((dp->db_index[idx - 1]) & DB_INDEX_MASK));
+ }
curline += idx - start_idx + extra;
- if (curline > buf->b_ml.ml_line_count)
- return -1; /* exactly one byte beyond the end */
+ if (curline > buf->b_ml.ml_line_count) {
+ return -1; // exactly one byte beyond the end
+ }
return curline;
}
curline = buf->b_ml.ml_locked_high + 1;
}
if (lnum != 0) {
- /* Count extra CR characters. */
- if (ffdos)
+ // Count extra CR characters.
+ if (ffdos) {
size += lnum - 1;
+ }
- /* Don't count the last line break if 'noeol' and ('bin' or
- * 'nofixeol'). */
+ // Don't count the last line break if 'noeol' and ('bin' or
+ // 'nofixeol').
if ((!buf->b_p_fixeol || buf->b_p_bin) && !buf->b_p_eol
&& lnum > buf->b_ml.ml_line_count) {
size -= ffdos + 1;
diff --git a/src/nvim/memline.h b/src/nvim/memline.h
index a239c6a031..441adf3e87 100644
--- a/src/nvim/memline.h
+++ b/src/nvim/memline.h
@@ -1,9 +1,9 @@
#ifndef NVIM_MEMLINE_H
#define NVIM_MEMLINE_H
+#include "nvim/buffer_defs.h" // for buf_T
+#include "nvim/pos.h" // for pos_T, linenr_T, colnr_T
#include "nvim/types.h"
-#include "nvim/pos.h" // for pos_T, linenr_T, colnr_T
-#include "nvim/buffer_defs.h" // for buf_T
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "memline.h.generated.h"
diff --git a/src/nvim/memline_defs.h b/src/nvim/memline_defs.h
index dc4755f83d..922a2c98d1 100644
--- a/src/nvim/memline_defs.h
+++ b/src/nvim/memline_defs.h
@@ -43,9 +43,9 @@ typedef struct ml_chunksize {
typedef struct memline {
linenr_T ml_line_count; // number of lines in the buffer
- memfile_T *ml_mfp; // pointer to associated memfile
+ memfile_T *ml_mfp; // pointer to associated memfile
- infoptr_T *ml_stack; // stack of pointer blocks (array of IPTRs)
+ infoptr_T *ml_stack; // stack of pointer blocks (array of IPTRs)
int ml_stack_top; // current top of ml_stack
int ml_stack_size; // total number of entries in ml_stack
@@ -56,11 +56,11 @@ typedef struct memline {
int ml_flags;
linenr_T ml_line_lnum; // line number of cached line, 0 if not valid
- char_u *ml_line_ptr; // pointer to cached line
+ char_u *ml_line_ptr; // pointer to cached line
size_t ml_line_offset; // cached byte offset of ml_line_lnum
int ml_line_offset_ff; // fileformat of cached line
- bhdr_T *ml_locked; // block used by last ml_get
+ bhdr_T *ml_locked; // block used by last ml_get
linenr_T ml_locked_low; // first line in ml_locked
linenr_T ml_locked_high; // last line in ml_locked
int ml_locked_lineadd; // number of lines inserted in ml_locked
diff --git a/src/nvim/memory.c b/src/nvim/memory.c
index 7a8fc4da75..5e6c6a8189 100644
--- a/src/nvim/memory.c
+++ b/src/nvim/memory.c
@@ -1,26 +1,26 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
- // Various routines dealing with allocation and deallocation of memory.
+// Various routines dealing with allocation and deallocation of memory.
#include <assert.h>
#include <inttypes.h>
-#include <string.h>
#include <stdbool.h>
+#include <string.h>
-#include "nvim/vim.h"
+#include "nvim/api/vim.h"
#include "nvim/context.h"
+#include "nvim/decoration.h"
#include "nvim/eval.h"
#include "nvim/highlight.h"
+#include "nvim/lua/executor.h"
#include "nvim/memfile.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/ui.h"
#include "nvim/sign.h"
-#include "nvim/api/vim.h"
-#include "nvim/lua/executor.h"
-#include "nvim/decoration.h"
+#include "nvim/ui.h"
+#include "nvim/vim.h"
#ifdef UNIT_TESTING
# define malloc(size) mem_malloc(size)
@@ -47,8 +47,9 @@ void try_to_free_memory(void)
{
static bool trying_to_free = false;
// avoid recursive calls
- if (trying_to_free)
+ if (trying_to_free) {
return;
+ }
trying_to_free = true;
// free any scrollback text
@@ -169,6 +170,8 @@ void *xrealloc(void *ptr, size_t size)
/// xmalloc() wrapper that allocates size + 1 bytes and zeroes the last byte
///
+/// Commonly used to allocate strings, e.g. `char *s = xmallocz(len)`.
+///
/// @see {xmalloc}
/// @param size
/// @return pointer to allocated space. Never NULL
@@ -182,7 +185,7 @@ void *xmallocz(size_t size)
}
void *ret = xmalloc(total_size);
- ((char*)ret)[size] = 0;
+ ((char *)ret)[size] = 0;
return ret;
}
@@ -339,16 +342,16 @@ char *xstpcpy(char *restrict dst, const char *restrict src)
char *xstpncpy(char *restrict dst, const char *restrict src, size_t maxlen)
FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- const char *p = memchr(src, '\0', maxlen);
- if (p) {
- size_t srclen = (size_t)(p - src);
- memcpy(dst, src, srclen);
- memset(dst + srclen, 0, maxlen - srclen);
- return dst + srclen;
- } else {
- memcpy(dst, src, maxlen);
- return dst + maxlen;
- }
+ const char *p = memchr(src, '\0', maxlen);
+ if (p) {
+ size_t srclen = (size_t)(p - src);
+ memcpy(dst, src, srclen);
+ memset(dst + srclen, 0, maxlen - srclen);
+ return dst + srclen;
+ } else {
+ memcpy(dst, src, maxlen);
+ return dst + maxlen;
+ }
}
/// xstrlcpy - Copy a NUL-terminated string into a sized buffer
@@ -447,7 +450,7 @@ void *xmemrchr(const void *src, uint8_t c, size_t len)
{
while (len--) {
if (((uint8_t *)src)[len] == c) {
- return (uint8_t *) src + len;
+ return (uint8_t *)src + len;
}
}
return NULL;
@@ -500,7 +503,7 @@ bool striequal(const char *a, const char *b)
void do_outofmem_msg(size_t size)
{
if (!did_outofmem_msg) {
- /* Don't hide this message */
+ // Don't hide this message
emsg_silent = 0;
/* Must come first to avoid coming back here when printing the error
@@ -523,35 +526,35 @@ void time_to_bytes(time_t time_, uint8_t buf[8])
#if defined(EXITFREE)
-#include "nvim/file_search.h"
-#include "nvim/buffer.h"
-#include "nvim/charset.h"
-#include "nvim/diff.h"
-#include "nvim/edit.h"
-#include "nvim/ex_cmds.h"
-#include "nvim/ex_docmd.h"
-#include "nvim/ex_getln.h"
-#include "nvim/fileio.h"
-#include "nvim/fold.h"
-#include "nvim/getchar.h"
-#include "nvim/mark.h"
-#include "nvim/mbyte.h"
-#include "nvim/memline.h"
-#include "nvim/move.h"
-#include "nvim/option.h"
-#include "nvim/ops.h"
-#include "nvim/os_unix.h"
-#include "nvim/path.h"
-#include "nvim/quickfix.h"
-#include "nvim/regexp.h"
-#include "nvim/screen.h"
-#include "nvim/search.h"
-#include "nvim/spell.h"
-#include "nvim/syntax.h"
-#include "nvim/tag.h"
-#include "nvim/window.h"
-#include "nvim/os/os.h"
-#include "nvim/eval/typval.h"
+# include "nvim/buffer.h"
+# include "nvim/charset.h"
+# include "nvim/diff.h"
+# include "nvim/edit.h"
+# include "nvim/eval/typval.h"
+# include "nvim/ex_cmds.h"
+# include "nvim/ex_docmd.h"
+# include "nvim/ex_getln.h"
+# include "nvim/file_search.h"
+# include "nvim/fileio.h"
+# include "nvim/fold.h"
+# include "nvim/getchar.h"
+# include "nvim/mark.h"
+# include "nvim/mbyte.h"
+# include "nvim/memline.h"
+# include "nvim/move.h"
+# include "nvim/ops.h"
+# include "nvim/option.h"
+# include "nvim/os/os.h"
+# include "nvim/os_unix.h"
+# include "nvim/path.h"
+# include "nvim/quickfix.h"
+# include "nvim/regexp.h"
+# include "nvim/screen.h"
+# include "nvim/search.h"
+# include "nvim/spell.h"
+# include "nvim/syntax.h"
+# include "nvim/tag.h"
+# include "nvim/window.h"
/*
* Free everything that we allocated.
@@ -562,7 +565,7 @@ void time_to_bytes(time_t time_, uint8_t buf[8])
*/
void free_all_mem(void)
{
- buf_T *buf, *nextbuf;
+ buf_T *buf, *nextbuf;
// When we cause a crash here it is caught and Vim tries to exit cleanly.
// Don't try freeing everything again.
@@ -574,10 +577,11 @@ void free_all_mem(void)
// Don't want to trigger autocommands from here on.
block_autocmds();
- /* Close all tabs and windows. Reset 'equalalways' to avoid redraws. */
+ // Close all tabs and windows. Reset 'equalalways' to avoid redraws.
p_ea = false;
- if (first_tabpage->tp_next != NULL)
+ if (first_tabpage->tp_next != NULL) {
do_cmdline_cmd("tabonly!");
+ }
if (!ONE_WINDOW) {
// to keep things simple, don't perform this
@@ -586,17 +590,17 @@ void free_all_mem(void)
do_cmdline_cmd("only!");
}
- /* Free all spell info. */
+ // Free all spell info.
spell_free_all();
- /* Clear user commands (before deleting buffers). */
+ // Clear user commands (before deleting buffers).
ex_comclear(NULL);
- /* Clear menus. */
+ // Clear menus.
do_cmdline_cmd("aunmenu *");
do_cmdline_cmd("menutranslate clear");
- /* Clear mappings, abbreviations, breakpoints. */
+ // Clear mappings, abbreviations, breakpoints.
do_cmdline_cmd("lmapclear");
do_cmdline_cmd("xmapclear");
do_cmdline_cmd("mapclear");
@@ -609,7 +613,7 @@ void free_all_mem(void)
free_titles();
free_findfile();
- /* Obviously named calls. */
+ // Obviously named calls.
free_all_autocmds();
free_all_marks();
alist_clear(&global_alist);
@@ -627,25 +631,25 @@ void free_all_mem(void)
diff_clear(curtab);
clear_sb_text(true); // free any scrollback text
- /* Free some global vars. */
+ // Free some global vars.
xfree(last_cmdline);
xfree(new_last_cmdline);
set_keep_msg(NULL, 0);
- /* Clear cmdline history. */
+ // Clear cmdline history.
p_hi = 0;
init_history();
qf_free_all(NULL);
- /* Free all location lists */
+ // Free all location lists
FOR_ALL_TAB_WINDOWS(tab, win) {
qf_free_all(win);
}
- /* Close all script inputs. */
+ // Close all script inputs.
close_all_scripts();
- /* Destroy all windows. Must come before freeing buffers. */
+ // Destroy all windows. Must come before freeing buffers.
win_free_all();
// Free all option values. Must come after closing windows.
@@ -653,13 +657,13 @@ void free_all_mem(void)
free_arshape_buf();
- /* Clear registers. */
+ // Clear registers.
clear_registers();
ResetRedobuff();
ResetRedobuff();
- /* highlight info */
+ // highlight info
free_highlight();
reset_last_sourcing();
@@ -667,10 +671,12 @@ void free_all_mem(void)
free_tabpage(first_tabpage);
first_tabpage = NULL;
- /* message history */
- for (;; )
- if (delete_first_msg() == FAIL)
+ // message history
+ for (;; ) {
+ if (delete_first_msg() == FAIL) {
break;
+ }
+ }
eval_clear();
api_vim_free_all_mem();
diff --git a/src/nvim/memory.h b/src/nvim/memory.h
index 5b39d002c9..a4be2643d8 100644
--- a/src/nvim/memory.h
+++ b/src/nvim/memory.h
@@ -2,8 +2,8 @@
#define NVIM_MEMORY_H
#include <stdbool.h> // for bool
-#include <stdint.h> // for uint8_t
#include <stddef.h> // for size_t
+#include <stdint.h> // for uint8_t
#include <time.h> // for time_t
/// `malloc()` function signature
diff --git a/src/nvim/menu.c b/src/nvim/menu.c
index 5c07f87bd5..2250002f86 100644
--- a/src/nvim/menu.c
+++ b/src/nvim/menu.c
@@ -10,27 +10,27 @@
#include <inttypes.h>
#include <string.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/menu.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/eval.h"
+#include "nvim/eval/typval.h"
#include "nvim/ex_docmd.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
+#include "nvim/keymap.h"
#include "nvim/memory.h"
+#include "nvim/menu.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/keymap.h"
-#include "nvim/garray.h"
+#include "nvim/screen.h"
#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/ui.h"
-#include "nvim/eval/typval.h"
-#include "nvim/screen.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#define MENUDEPTH 10 /* maximum depth of menus */
+#define MENUDEPTH 10 // maximum depth of menus
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -43,8 +43,7 @@
/// The character for each menu mode
static char_u menu_mode_chars[] = { 'n', 'v', 's', 'o', 'i', 'c', 't' };
-static char_u e_notsubmenu[] = N_(
- "E327: Part of menu-item path is not sub-menu");
+static char_u e_notsubmenu[] = N_("E327: Part of menu-item path is not sub-menu");
static char_u e_othermode[] = N_("E328: Menu only exists in another mode");
static char_u e_nomenu[] = N_("E329: No menu \"%s\"");
@@ -63,18 +62,17 @@ static vimmenu_T **get_root_menu(const char_u *const name)
/// Do the :menu command and relatives.
/// @param eap Ex command arguments
-void
-ex_menu(exarg_T *eap)
+void ex_menu(exarg_T *eap)
{
- char_u *menu_path;
+ char *menu_path;
int modes;
- char_u *map_to; // command mapped to the menu entry
+ char_u *map_to; // command mapped to the menu entry
int noremap;
bool silent = false;
int unmenu;
- char_u *map_buf;
- char_u *arg;
- char_u *p;
+ char_u *map_buf;
+ char_u *arg;
+ char_u *p;
int i;
long pri_tab[MENUDEPTH + 1];
TriState enable = kNone; // kTrue for "menu enable",
@@ -109,8 +107,9 @@ ex_menu(exarg_T *eap)
if (STRNCMP(arg, "icon=", 5) == 0) {
arg += 5;
while (*arg != NUL && *arg != ' ') {
- if (*arg == '\\')
+ if (*arg == '\\') {
STRMOVE(arg, arg + 1);
+ }
MB_PTR_ADV(arg);
}
if (*arg != NUL) {
@@ -139,11 +138,13 @@ ex_menu(exarg_T *eap)
} else if (eap->addr_count && eap->line2 != 0) {
pri_tab[0] = eap->line2;
i = 1;
- } else
+ } else {
i = 0;
- while (i < MENUDEPTH)
+ }
+ while (i < MENUDEPTH) {
pri_tab[i++] = 500;
- pri_tab[MENUDEPTH] = -1; /* mark end of the table */
+ }
+ pri_tab[MENUDEPTH] = -1; // mark end of the table
/*
* Check for "disable" or "enable" argument.
@@ -165,7 +166,7 @@ ex_menu(exarg_T *eap)
}
- menu_path = arg;
+ menu_path = (char *)arg;
if (*menu_path == '.') {
EMSG2(_(e_invarg2), menu_path);
goto theend;
@@ -177,59 +178,62 @@ ex_menu(exarg_T *eap)
* If there is only a menu name, display menus with that name.
*/
if (*map_to == NUL && !unmenu && enable == kNone) {
- show_menus(menu_path, modes);
+ show_menus((char_u *)menu_path, modes);
goto theend;
} else if (*map_to != NUL && (unmenu || enable != kNone)) {
EMSG(_(e_trailing));
goto theend;
}
- vimmenu_T **root_menu_ptr = get_root_menu(menu_path);
+ vimmenu_T **root_menu_ptr = get_root_menu((char_u *)menu_path);
if (enable != kNone) {
// Change sensitivity of the menu.
// For the PopUp menu, remove a menu for each mode separately.
// Careful: menu_enable_recurse() changes menu_path.
if (STRCMP(menu_path, "*") == 0) { // meaning: do all menus
- menu_path = (char_u *)"";
+ menu_path = "";
}
if (menu_is_popup(menu_path)) {
- for (i = 0; i < MENU_INDEX_TIP; ++i)
+ for (i = 0; i < MENU_INDEX_TIP; i++) {
if (modes & (1 << i)) {
p = popup_mode_name(menu_path, i);
menu_enable_recurse(*root_menu_ptr, p, MENU_ALL_MODES, enable);
xfree(p);
}
+ }
}
- menu_enable_recurse(*root_menu_ptr, menu_path, modes, enable);
+ menu_enable_recurse(*root_menu_ptr, (char_u *)menu_path, modes, enable);
} else if (unmenu) {
/*
* Delete menu(s).
*/
- if (STRCMP(menu_path, "*") == 0) /* meaning: remove all menus */
- menu_path = (char_u *)"";
+ if (STRCMP(menu_path, "*") == 0) { // meaning: remove all menus
+ menu_path = "";
+ }
/*
* For the PopUp menu, remove a menu for each mode separately.
*/
if (menu_is_popup(menu_path)) {
- for (i = 0; i < MENU_INDEX_TIP; ++i)
+ for (i = 0; i < MENU_INDEX_TIP; i++) {
if (modes & (1 << i)) {
p = popup_mode_name(menu_path, i);
remove_menu(root_menu_ptr, p, MENU_ALL_MODES, true);
xfree(p);
}
+ }
}
// Careful: remove_menu() changes menu_path
- remove_menu(root_menu_ptr, menu_path, modes, false);
+ remove_menu(root_menu_ptr, (char_u *)menu_path, modes, false);
} else {
/*
* Add menu(s).
* Replace special key codes.
*/
- if (STRICMP(map_to, "<nop>") == 0) { /* "<Nop>" means nothing */
+ if (STRICMP(map_to, "<nop>") == 0) { // "<Nop>" means nothing
map_to = (char_u *)"";
map_buf = NULL;
} else if (modes & MENU_TIP_MODE) {
@@ -241,13 +245,13 @@ ex_menu(exarg_T *eap)
menuarg.modes = modes;
menuarg.noremap[0] = noremap;
menuarg.silent[0] = silent;
- add_menu_path(menu_path, &menuarg, pri_tab, map_to);
+ add_menu_path((char_u *)menu_path, &menuarg, pri_tab, map_to);
/*
* For the PopUp menu, add a menu for each mode separately.
*/
if (menu_is_popup(menu_path)) {
- for (i = 0; i < MENU_INDEX_TIP; ++i)
+ for (i = 0; i < MENU_INDEX_TIP; i++) {
if (modes & (1 << i)) {
p = popup_mode_name(menu_path, i);
// Include all modes, to make ":amenu" work
@@ -255,6 +259,7 @@ ex_menu(exarg_T *eap)
add_menu_path(p, &menuarg, pri_tab, map_to);
xfree(p);
}
+ }
}
xfree(map_buf);
@@ -272,33 +277,28 @@ theend:
/// @param[out] menuarg menu entry
/// @param[] pri_tab priority table
/// @param[in] call_data Right hand side command
-static int
-add_menu_path(
- const char_u *const menu_path,
- vimmenu_T *menuarg,
- const long *const pri_tab,
- const char_u *const call_data
-)
+static int add_menu_path(const char_u *const menu_path, vimmenu_T *menuarg,
+ const long *const pri_tab, const char_u *const call_data)
{
- char_u *path_name;
+ char_u *path_name;
int modes = menuarg->modes;
- vimmenu_T *menu = NULL;
- vimmenu_T *parent;
- vimmenu_T **lower_pri;
- char_u *p;
- char_u *name;
- char_u *dname;
- char_u *next_name;
+ vimmenu_T *menu = NULL;
+ vimmenu_T *parent;
+ vimmenu_T **lower_pri;
+ char_u *p;
+ char_u *name;
+ char_u *dname;
+ char_u *next_name;
char_u c;
char_u d;
int i;
int pri_idx = 0;
int old_modes = 0;
int amenu;
- char_u *en_name;
- char_u *map_to = NULL;
+ char_u *en_name;
+ char_u *map_to = NULL;
- /* Make a copy so we can stuff around with it, since it could be const */
+ // Make a copy so we can stuff around with it, since it could be const
path_name = vim_strsave(menu_path);
vimmenu_T **root_menu_ptr = get_root_menu(menu_path);
vimmenu_T **menup = root_menu_ptr;
@@ -317,12 +317,12 @@ add_menu_path(
}
dname = menu_text(name, NULL, NULL);
if (*dname == NUL) {
- /* Only a mnemonic or accelerator is not valid. */
+ // Only a mnemonic or accelerator is not valid.
EMSG(_("E792: Empty menu name"));
goto erret;
}
- /* See if it's already there */
+ // See if it's already there
lower_pri = menup;
menu = *menup;
while (menu != NULL) {
@@ -343,8 +343,8 @@ add_menu_path(
}
menup = &menu->next;
- /* Count menus, to find where this one needs to be inserted.
- * Ignore menus that are not in the menubar (PopUp and Toolbar) */
+ // Count menus, to find where this one needs to be inserted.
+ // Ignore menus that are not in the menubar (PopUp and Toolbar)
if (parent != NULL || menu_is_menubar(menu->name)) {
if (menu->priority <= pri_tab[pri_idx]) {
lower_pri = menup;
@@ -364,7 +364,7 @@ add_menu_path(
goto erret;
}
- /* Not already there, so lets add it */
+ // Not already there, so lets add it
menu = xcalloc(1, sizeof(vimmenu_T));
menu->modes = modes;
@@ -387,7 +387,6 @@ add_menu_path(
*lower_pri = menu;
old_modes = 0;
-
} else {
old_modes = menu->modes;
@@ -419,16 +418,17 @@ add_menu_path(
*/
amenu = ((modes & (MENU_NORMAL_MODE | MENU_INSERT_MODE)) ==
(MENU_NORMAL_MODE | MENU_INSERT_MODE));
- if (sys_menu)
+ if (sys_menu) {
modes &= ~old_modes;
+ }
if (menu != NULL && modes) {
p = (call_data == NULL) ? NULL : vim_strsave(call_data);
- /* loop over all modes, may add more than one */
+ // loop over all modes, may add more than one
for (i = 0; i < MENU_MODES; ++i) {
if (modes & (1 << i)) {
- /* free any old menu */
+ // free any old menu
free_menu_string(menu, i);
// For "amenu", may insert an extra character.
@@ -462,7 +462,7 @@ add_menu_path(
if (c == Ctrl_C) {
int len = (int)STRLEN(menu->strings[i]);
- /* Append CTRL-\ CTRL-G to obey 'insertmode'. */
+ // Append CTRL-\ CTRL-G to obey 'insertmode'.
menu->strings[i][len] = Ctrl_BSL;
menu->strings[i][len + 1] = Ctrl_G;
menu->strings[i][len + 2] = NUL;
@@ -504,20 +504,17 @@ erret:
* Set the (sub)menu with the given name to enabled or disabled.
* Called recursively.
*/
-static int menu_enable_recurse(vimmenu_T *menu,
- char_u *name,
- int modes,
- int enable)
+static int menu_enable_recurse(vimmenu_T *menu, char_u *name, int modes, int enable)
{
- char_u *p;
-
- if (menu == NULL)
- return OK; /* Got to bottom of hierarchy */
+ char_u *p;
- /* Get name of this element in the menu hierarchy */
+ if (menu == NULL) {
+ return OK; // Got to bottom of hierarchy
+ }
+ // Get name of this element in the menu hierarchy
p = menu_name_skip(name);
- /* Find the menu */
+ // Find the menu
while (menu != NULL) {
if (*name == NUL || *name == '*' || menu_name_equal(name, menu)) {
if (*p != NUL) {
@@ -539,8 +536,9 @@ static int menu_enable_recurse(vimmenu_T *menu,
* modes, so keep looping, otherwise we are just doing the named
* menu item (which has been found) so break here.
*/
- if (*name != NUL && *name != '*')
+ if (*name != NUL && *name != '*') {
break;
+ }
}
menu = menu->next;
}
@@ -553,42 +551,39 @@ static int menu_enable_recurse(vimmenu_T *menu,
return OK;
}
-/*
- * Remove the (sub)menu with the given name from the menu hierarchy
- * Called recursively.
- */
-static int
-remove_menu (
- vimmenu_T **menup,
- char_u *name,
- int modes,
- bool silent /* don't give error messages */
-)
+/// Remove the (sub)menu with the given name from the menu hierarchy
+/// Called recursively.
+///
+/// @param silent don't give error messages
+static int remove_menu(vimmenu_T **menup, char_u *name, int modes, bool silent)
{
- vimmenu_T *menu;
- vimmenu_T *child;
- char_u *p;
-
- if (*menup == NULL)
- return OK; /* Got to bottom of hierarchy */
+ vimmenu_T *menu;
+ vimmenu_T *child;
+ char_u *p;
- /* Get name of this element in the menu hierarchy */
+ if (*menup == NULL) {
+ return OK; // Got to bottom of hierarchy
+ }
+ // Get name of this element in the menu hierarchy
p = menu_name_skip(name);
- /* Find the menu */
+ // Find the menu
while ((menu = *menup) != NULL) {
if (*name == NUL || menu_name_equal(name, menu)) {
if (*p != NUL && menu->children == NULL) {
- if (!silent)
+ if (!silent) {
EMSG(_(e_notsubmenu));
+ }
return FAIL;
}
if ((menu->modes & modes) != 0x0) {
- if (remove_menu(&menu->children, p, modes, silent) == FAIL)
+ if (remove_menu(&menu->children, p, modes, silent) == FAIL) {
return FAIL;
+ }
} else if (*name != NUL) {
- if (!silent)
+ if (!silent) {
EMSG(_(e_othermode));
+ }
return FAIL;
}
@@ -597,39 +592,45 @@ remove_menu (
* modes, so keep looping, otherwise we are just removing the named
* menu item (which has been found) so break here.
*/
- if (*name != NUL)
+ if (*name != NUL) {
break;
+ }
- /* Remove the menu item for the given mode[s]. If the menu item
- * is no longer valid in ANY mode, delete it */
+ // Remove the menu item for the given mode[s]. If the menu item
+ // is no longer valid in ANY mode, delete it
menu->modes &= ~modes;
- if (modes & MENU_TIP_MODE)
+ if (modes & MENU_TIP_MODE) {
free_menu_string(menu, MENU_INDEX_TIP);
- if ((menu->modes & MENU_ALL_MODES) == 0)
+ }
+ if ((menu->modes & MENU_ALL_MODES) == 0) {
free_menu(menup);
- else
+ } else {
menup = &menu->next;
- } else
+ }
+ } else {
menup = &menu->next;
+ }
}
if (*name != NUL) {
if (menu == NULL) {
- if (!silent)
+ if (!silent) {
EMSG2(_(e_nomenu), name);
+ }
return FAIL;
}
- /* Recalculate modes for menu based on the new updated children */
+ // Recalculate modes for menu based on the new updated children
menu->modes &= ~modes;
child = menu->children;
- for (; child != NULL; child = child->next)
+ for (; child != NULL; child = child->next) {
menu->modes |= child->modes;
+ }
if (modes & MENU_TIP_MODE) {
free_menu_string(menu, MENU_INDEX_TIP);
}
if ((menu->modes & MENU_ALL_MODES) == 0) {
- /* The menu item is no longer valid in ANY mode, so delete it */
+ // The menu item is no longer valid in ANY mode, so delete it
*menup = menu;
free_menu(menup);
}
@@ -644,7 +645,7 @@ remove_menu (
static void free_menu(vimmenu_T **menup)
{
int i;
- vimmenu_T *menu;
+ vimmenu_T *menu;
menu = *menup;
@@ -657,10 +658,10 @@ static void free_menu(vimmenu_T **menup)
xfree(menu->en_name);
xfree(menu->en_dname);
xfree(menu->actext);
- for (i = 0; i < MENU_MODES; i++)
+ for (i = 0; i < MENU_MODES; i++) {
free_menu_string(menu, i);
+ }
xfree(menu);
-
}
/*
@@ -671,11 +672,14 @@ static void free_menu_string(vimmenu_T *menu, int idx)
int count = 0;
int i;
- for (i = 0; i < MENU_MODES; i++)
- if (menu->strings[i] == menu->strings[idx])
+ for (i = 0; i < MENU_MODES; i++) {
+ if (menu->strings[i] == menu->strings[idx]) {
count++;
- if (count == 1)
+ }
+ }
+ if (count == 1) {
xfree(menu->strings[idx]);
+ }
menu->strings[idx] = NULL;
}
@@ -793,8 +797,8 @@ static vimmenu_T *find_menu(vimmenu_T *menu, char_u *name, int modes)
if (menu_name_equal(name, menu)) {
// Found menu
if (*p != NUL && menu->children == NULL) {
- EMSG(_(e_notsubmenu));
- return NULL;
+ EMSG(_(e_notsubmenu));
+ return NULL;
} else if ((menu->modes & modes) == 0x0) {
EMSG(_(e_othermode));
return NULL;
@@ -826,8 +830,8 @@ static int show_menus(char_u *const path_name, int modes)
return FAIL;
}
- /* Now we have found the matching menu, and we list the mappings */
- /* Highlight title */
+ // Now we have found the matching menu, and we list the mappings
+ // Highlight title
MSG_PUTS_TITLE(_("\n--- Menus ---"));
show_menus_recursive(menu->parent, modes, 0);
@@ -840,17 +844,20 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
int i;
int bit;
- if (menu != NULL && (menu->modes & modes) == 0x0)
+ if (menu != NULL && (menu->modes & modes) == 0x0) {
return;
+ }
if (menu != NULL) {
msg_putchar('\n');
- if (got_int) /* "q" hit for "--more--" */
+ if (got_int) { // "q" hit for "--more--"
return;
- for (i = 0; i < depth; i++)
+ }
+ for (i = 0; i < depth; i++) {
MSG_PUTS(" ");
+ }
if (menu->priority) {
- msg_outnum((long)menu->priority);
+ msg_outnum(menu->priority);
MSG_PUTS(" ");
}
// Same highlighting as for directories!?
@@ -858,28 +865,33 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
}
if (menu != NULL && menu->children == NULL) {
- for (bit = 0; bit < MENU_MODES; bit++)
+ for (bit = 0; bit < MENU_MODES; bit++) {
if ((menu->modes & modes & (1 << bit)) != 0) {
msg_putchar('\n');
- if (got_int) /* "q" hit for "--more--" */
+ if (got_int) { // "q" hit for "--more--"
return;
- for (i = 0; i < depth + 2; i++)
+ }
+ for (i = 0; i < depth + 2; i++) {
MSG_PUTS(" ");
+ }
msg_putchar(menu_mode_chars[bit]);
- if (menu->noremap[bit] == REMAP_NONE)
+ if (menu->noremap[bit] == REMAP_NONE) {
msg_putchar('*');
- else if (menu->noremap[bit] == REMAP_SCRIPT)
+ } else if (menu->noremap[bit] == REMAP_SCRIPT) {
msg_putchar('&');
- else
+ } else {
msg_putchar(' ');
- if (menu->silent[bit])
+ }
+ if (menu->silent[bit]) {
msg_putchar('s');
- else
+ } else {
msg_putchar(' ');
- if ((menu->modes & menu->enabled & (1 << bit)) == 0)
+ }
+ if ((menu->modes & menu->enabled & (1 << bit)) == 0) {
msg_putchar('-');
- else
+ } else {
msg_putchar(' ');
+ }
MSG_PUTS(" ");
if (*menu->strings[bit] == NUL) {
msg_puts_attr("<Nop>", HL_ATTR(HLF_8));
@@ -887,17 +899,21 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
msg_outtrans_special(menu->strings[bit], false, 0);
}
}
+ }
} else {
if (menu == NULL) {
menu = root_menu;
depth--;
- } else
+ } else {
menu = menu->children;
+ }
- /* recursively show all children. Skip PopUp[nvoci]. */
- for (; menu != NULL && !got_int; menu = menu->next)
- if (!menu_is_hidden(menu->dname))
+ // recursively show all children. Skip PopUp[nvoci].
+ for (; menu != NULL && !got_int; menu = menu->next) {
+ if (!menu_is_hidden(menu->dname)) {
show_menus_recursive(menu, modes, depth + 1);
+ }
+ }
}
}
@@ -905,54 +921,58 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
/*
* Used when expanding menu names.
*/
-static vimmenu_T *expand_menu = NULL;
+static vimmenu_T *expand_menu = NULL;
static int expand_modes = 0x0;
-static int expand_emenu; /* TRUE for ":emenu" command */
+static int expand_emenu; // TRUE for ":emenu" command
/*
* Work out what to complete when doing command line completion of menu names.
*/
-char_u *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char_u *arg,
- bool forceit)
+char_u *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char_u *arg, bool forceit)
FUNC_ATTR_NONNULL_ALL
{
- char_u *after_dot;
- char_u *p;
- char_u *path_name = NULL;
- char_u *name;
+ char_u *after_dot;
+ char_u *p;
+ char_u *path_name = NULL;
+ char_u *name;
int unmenu;
- vimmenu_T *menu;
+ vimmenu_T *menu;
int expand_menus;
xp->xp_context = EXPAND_UNSUCCESSFUL;
- /* Check for priority numbers, enable and disable */
- for (p = arg; *p; ++p)
- if (!ascii_isdigit(*p) && *p != '.')
+ // Check for priority numbers, enable and disable
+ for (p = arg; *p; ++p) {
+ if (!ascii_isdigit(*p) && *p != '.') {
break;
+ }
+ }
if (!ascii_iswhite(*p)) {
if (STRNCMP(arg, "enable", 6) == 0
- && (arg[6] == NUL || ascii_iswhite(arg[6])))
+ && (arg[6] == NUL || ascii_iswhite(arg[6]))) {
p = arg + 6;
- else if (STRNCMP(arg, "disable", 7) == 0
- && (arg[7] == NUL || ascii_iswhite(arg[7])))
+ } else if (STRNCMP(arg, "disable", 7) == 0
+ && (arg[7] == NUL || ascii_iswhite(arg[7]))) {
p = arg + 7;
- else
+ } else {
p = arg;
+ }
}
- while (*p != NUL && ascii_iswhite(*p))
+ while (*p != NUL && ascii_iswhite(*p)) {
++p;
+ }
arg = after_dot = p;
for (; *p && !ascii_iswhite(*p); ++p) {
- if ((*p == '\\' || *p == Ctrl_V) && p[1] != NUL)
+ if ((*p == '\\' || *p == Ctrl_V) && p[1] != NUL) {
p++;
- else if (*p == '.')
+ } else if (*p == '.') {
after_dot = p + 1;
+ }
}
// ":popup" only uses menus, not entries
@@ -966,12 +986,13 @@ char_u *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char_u *arg,
// With :menu though you might want to add a menu with the same name as
// one in another mode, so match menus from other modes too.
expand_modes = get_menu_cmd_modes(cmd, forceit, NULL, &unmenu);
- if (!unmenu)
+ if (!unmenu) {
expand_modes = MENU_ALL_MODES;
+ }
menu = root_menu;
if (after_dot > arg) {
- size_t path_len = (size_t) (after_dot - arg);
+ size_t path_len = (size_t)(after_dot - arg);
path_name = xmalloc(path_len);
STRLCPY(path_name, arg, path_len);
}
@@ -980,7 +1001,7 @@ char_u *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char_u *arg,
p = menu_name_skip(name);
while (menu != NULL) {
if (menu_name_equal(name, menu)) {
- /* Found menu */
+ // Found menu
if ((*p != NUL && menu->children == NULL)
|| ((menu->modes & expand_modes) == 0x0)) {
/*
@@ -995,7 +1016,7 @@ char_u *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char_u *arg,
menu = menu->next;
}
if (menu == NULL) {
- /* No menu found with the name we were looking for */
+ // No menu found with the name we were looking for
xfree(path_name);
return NULL;
}
@@ -1019,35 +1040,38 @@ char_u *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char_u *arg,
*/
char_u *get_menu_name(expand_T *xp, int idx)
{
- static vimmenu_T *menu = NULL;
- char_u *str;
+ static vimmenu_T *menu = NULL;
+ char_u *str;
static int should_advance = FALSE;
- if (idx == 0) { /* first call: start at first item */
+ if (idx == 0) { // first call: start at first item
menu = expand_menu;
should_advance = false;
}
- /* Skip PopUp[nvoci]. */
+ // Skip PopUp[nvoci].
while (menu != NULL && (menu_is_hidden(menu->dname)
|| menu_is_separator(menu->dname)
|| menu->children == NULL)) {
menu = menu->next;
}
- if (menu == NULL) /* at end of linked list */
+ if (menu == NULL) { // at end of linked list
return NULL;
+ }
- if (menu->modes & expand_modes)
- if (should_advance)
+ if (menu->modes & expand_modes) {
+ if (should_advance) {
str = menu->en_dname;
- else {
+ } else {
str = menu->dname;
- if (menu->en_dname == NULL)
+ if (menu->en_dname == NULL) {
should_advance = TRUE;
+ }
}
- else
+ } else {
str = (char_u *)"";
+ }
if (should_advance) {
// Advance to next menu entry.
@@ -1065,18 +1089,18 @@ char_u *get_menu_name(expand_T *xp, int idx)
*/
char_u *get_menu_names(expand_T *xp, int idx)
{
- static vimmenu_T *menu = NULL;
+ static vimmenu_T *menu = NULL;
#define TBUFFER_LEN 256
- static char_u tbuffer[TBUFFER_LEN]; /*hack*/
- char_u *str;
+ static char_u tbuffer[TBUFFER_LEN]; //hack
+ char_u *str;
static bool should_advance = false;
- if (idx == 0) { /* first call: start at first item */
+ if (idx == 0) { // first call: start at first item
menu = expand_menu;
should_advance = false;
}
- /* Skip Browse-style entries, popup menus and separators. */
+ // Skip Browse-style entries, popup menus and separators.
while (menu != NULL
&& (menu_is_hidden(menu->dname)
|| (expand_emenu && menu_is_separator(menu->dname))
@@ -1084,8 +1108,9 @@ char_u *get_menu_names(expand_T *xp, int idx)
menu = menu->next;
}
- if (menu == NULL) /* at end of linked list */
+ if (menu == NULL) { // at end of linked list
return NULL;
+ }
if (menu->modes & expand_modes) {
if (menu->children != NULL) {
@@ -1102,17 +1127,18 @@ char_u *get_menu_names(expand_T *xp, int idx)
STRCAT(tbuffer, "\001");
str = tbuffer;
} else {
- if (should_advance)
+ if (should_advance) {
str = menu->en_dname;
- else {
+ } else {
str = menu->dname;
if (menu->en_dname == NULL) {
should_advance = true;
}
}
}
- } else
+ } else {
str = (char_u *)"";
+ }
if (should_advance) {
// Advance to next menu entry.
@@ -1132,17 +1158,19 @@ char_u *get_menu_names(expand_T *xp, int idx)
/// @return start of the next element
char_u *menu_name_skip(char_u *const name)
{
- char_u *p;
+ char_u *p;
for (p = name; *p && *p != '.'; MB_PTR_ADV(p)) {
if (*p == '\\' || *p == Ctrl_V) {
STRMOVE(p, p + 1);
- if (*p == NUL)
+ if (*p == NUL) {
break;
+ }
}
}
- if (*p)
+ if (*p) {
*p++ = NUL;
+ }
return p;
}
@@ -1154,8 +1182,9 @@ static bool menu_name_equal(const char_u *const name, vimmenu_T *const menu)
{
if (menu->en_name != NULL
&& (menu_namecmp(name, menu->en_name)
- || menu_namecmp(name, menu->en_dname)))
+ || menu_namecmp(name, menu->en_dname))) {
return true;
+ }
return menu_namecmp(name, menu->name) || menu_namecmp(name, menu->dname);
}
@@ -1163,9 +1192,11 @@ static bool menu_namecmp(const char_u *const name, const char_u *const mname)
{
int i;
- for (i = 0; name[i] != NUL && name[i] != TAB; ++i)
- if (name[i] != mname[i])
+ for (i = 0; name[i] != NUL && name[i] != TAB; ++i) {
+ if (name[i] != mname[i]) {
break;
+ }
+ }
return (name[i] == NUL || name[i] == TAB)
&& (mname[i] == NUL || mname[i] == TAB);
}
@@ -1180,45 +1211,39 @@ static bool menu_namecmp(const char_u *const name, const char_u *const mname)
/// to whether the command is a "nore" command.
/// @param[out] unmenu If not NULL, the flag it points to is set according
/// to whether the command is an "unmenu" command.
-int
-get_menu_cmd_modes(
- const char *cmd,
- bool forceit,
- int *noremap,
- int *unmenu
-)
+int get_menu_cmd_modes(const char *cmd, bool forceit, int *noremap, int *unmenu)
{
int modes;
switch (*cmd++) {
- case 'v': /* vmenu, vunmenu, vnoremenu */
+ case 'v': // vmenu, vunmenu, vnoremenu
modes = MENU_VISUAL_MODE | MENU_SELECT_MODE;
break;
- case 'x': /* xmenu, xunmenu, xnoremenu */
+ case 'x': // xmenu, xunmenu, xnoremenu
modes = MENU_VISUAL_MODE;
break;
- case 's': /* smenu, sunmenu, snoremenu */
+ case 's': // smenu, sunmenu, snoremenu
modes = MENU_SELECT_MODE;
break;
- case 'o': /* omenu */
+ case 'o': // omenu
modes = MENU_OP_PENDING_MODE;
break;
- case 'i': /* imenu */
+ case 'i': // imenu
modes = MENU_INSERT_MODE;
break;
case 't':
- modes = MENU_TIP_MODE; /* tmenu */
+ modes = MENU_TIP_MODE; // tmenu
break;
- case 'c': /* cmenu */
+ case 'c': // cmenu
modes = MENU_CMDLINE_MODE;
break;
- case 'a': /* amenu */
+ case 'a': // amenu
modes = MENU_INSERT_MODE | MENU_CMDLINE_MODE | MENU_NORMAL_MODE
| MENU_VISUAL_MODE | MENU_SELECT_MODE
| MENU_OP_PENDING_MODE;
break;
case 'n':
- if (*cmd != 'o') { /* nmenu, not noremenu */
+ if (*cmd != 'o') { // nmenu, not noremenu
modes = MENU_NORMAL_MODE;
break;
}
@@ -1235,10 +1260,12 @@ get_menu_cmd_modes(
}
}
- if (noremap != NULL)
+ if (noremap != NULL) {
*noremap = (*cmd == 'n' ? REMAP_NONE : REMAP_YES);
- if (unmenu != NULL)
+ }
+ if (unmenu != NULL) {
*unmenu = (*cmd == 'u');
+ }
return modes;
}
@@ -1246,12 +1273,12 @@ get_menu_cmd_modes(
* Modify a menu name starting with "PopUp" to include the mode character.
* Returns the name in allocated memory.
*/
-static char_u *popup_mode_name(char_u *name, int idx)
+static char_u *popup_mode_name(char *name, int idx)
{
size_t len = STRLEN(name);
assert(len >= 4);
- char_u *p = vim_strnsave(name, len + 1);
+ char_u *p = vim_strnsave((char_u *)name, len + 1);
memmove(p + 6, p + 5, len - 4);
p[5] = menu_mode_chars[idx];
@@ -1274,27 +1301,31 @@ static char_u *menu_text(const char_u *str, int *mnemonic, char_u **actext)
FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
FUNC_ATTR_NONNULL_ARG(1)
{
- char_u *p;
- char_u *text;
+ char_u *p;
+ char_u *text;
- /* Locate accelerator text, after the first TAB */
+ // Locate accelerator text, after the first TAB
p = vim_strchr(str, TAB);
if (p != NULL) {
- if (actext != NULL)
+ if (actext != NULL) {
*actext = vim_strsave(p + 1);
+ }
assert(p >= str);
text = vim_strnsave(str, (size_t)(p - str));
- } else
+ } else {
text = vim_strsave(str);
+ }
- /* Find mnemonic characters "&a" and reduce "&&" to "&". */
+ // Find mnemonic characters "&a" and reduce "&&" to "&".
for (p = text; p != NULL; ) {
p = vim_strchr(p, '&');
if (p != NULL) {
- if (p[1] == NUL) /* trailing "&" */
+ if (p[1] == NUL) { // trailing "&"
break;
- if (mnemonic != NULL && p[1] != '&')
+ }
+ if (mnemonic != NULL && p[1] != '&') {
*mnemonic = p[1];
+ }
STRMOVE(p, p + 1);
p = p + 1;
}
@@ -1306,14 +1337,14 @@ static char_u *menu_text(const char_u *str, int *mnemonic, char_u **actext)
bool menu_is_menubar(const char_u *const name)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- return !menu_is_popup(name)
+ return !menu_is_popup((char *)name)
&& !menu_is_toolbar(name)
&& !menu_is_winbar(name)
&& *name != MNU_HIDDEN_CHAR;
}
// Return true if "name" is a popup menu name.
-bool menu_is_popup(const char_u *const name)
+bool menu_is_popup(const char *const name)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
return STRNCMP(name, "PopUp", 5) == 0;
@@ -1343,7 +1374,7 @@ int menu_is_separator(char_u *name)
static int menu_is_hidden(char_u *name)
{
return (name[0] == MNU_HIDDEN_CHAR)
- || (menu_is_popup(name) && name[5] != NUL);
+ || (menu_is_popup((char *)name) && name[5] != NUL);
}
// Execute "menu". Use by ":emenu" and the window toolbar.
@@ -1352,25 +1383,25 @@ static void execute_menu(const exarg_T *eap, vimmenu_T *menu)
FUNC_ATTR_NONNULL_ARG(2)
{
int idx = -1;
- char_u *mode;
+ char *mode;
// Use the Insert mode entry when returning to Insert mode.
if (((State & INSERT) || restart_edit) && !current_sctx.sc_sid) {
- mode = (char_u *)"Insert";
+ mode = "Insert";
idx = MENU_INDEX_INSERT;
} else if (State & CMDLINE) {
- mode = (char_u *)"Command";
- idx = MENU_INDEX_CMDLINE;
+ mode = "Command";
+ idx = MENU_INDEX_CMDLINE;
} else if (get_real_state() & VISUAL) {
/* Detect real visual mode -- if we are really in visual mode we
* don't need to do any guesswork to figure out what the selection
* is. Just execute the visual binding for the menu. */
- mode = (char_u *)"Visual";
+ mode = "Visual";
idx = MENU_INDEX_VISUAL;
} else if (eap != NULL && eap->addr_count) {
pos_T tpos;
- mode = (char_u *)"Visual";
+ mode = "Visual";
idx = MENU_INDEX_VISUAL;
/* GEDDES: This is not perfect - but it is a
@@ -1379,13 +1410,13 @@ static void execute_menu(const exarg_T *eap, vimmenu_T *menu)
* select start and end. */
if ((curbuf->b_visual.vi_start.lnum == eap->line1)
&& (curbuf->b_visual.vi_end.lnum) == eap->line2) {
- /* Set it up for visual mode - equivalent to gv. */
+ // Set it up for visual mode - equivalent to gv.
VIsual_mode = curbuf->b_visual.vi_mode;
tpos = curbuf->b_visual.vi_end;
curwin->w_cursor = curbuf->b_visual.vi_start;
curwin->w_curswant = curbuf->b_visual.vi_curswant;
} else {
- /* Set it up for line-wise visual mode */
+ // Set it up for line-wise visual mode
VIsual_mode = 'V';
curwin->w_cursor.lnum = eap->line1;
curwin->w_cursor.col = 1;
@@ -1394,7 +1425,7 @@ static void execute_menu(const exarg_T *eap, vimmenu_T *menu)
tpos.coladd = 0;
}
- /* Activate visual mode */
+ // Activate visual mode
VIsual_active = TRUE;
VIsual_reselect = TRUE;
check_cursor();
@@ -1411,7 +1442,7 @@ static void execute_menu(const exarg_T *eap, vimmenu_T *menu)
}
if (idx == -1 || eap == NULL) {
- mode = (char_u *)"Normal";
+ mode = "Normal";
idx = MENU_INDEX_NORMAL;
}
@@ -1484,15 +1515,15 @@ void ex_emenu(exarg_T *eap)
*/
typedef struct {
- char_u *from; /* English name */
- char_u *from_noamp; /* same, without '&' */
- char_u *to; /* translated name */
+ char_u *from; // English name
+ char_u *from_noamp; // same, without '&'
+ char_u *to; // translated name
} menutrans_T;
static garray_T menutrans_ga = GA_EMPTY_INIT_VALUE;
#define FREE_MENUTRANS(mt) \
- menutrans_T* _mt = (mt); \
+ menutrans_T *_mt = (mt); \
xfree(_mt->from); \
xfree(_mt->from_noamp); \
xfree(_mt->to)
@@ -1504,11 +1535,12 @@ static garray_T menutrans_ga = GA_EMPTY_INIT_VALUE;
*/
void ex_menutranslate(exarg_T *eap)
{
- char_u *arg = eap->arg;
- char_u *from, *from_noamp, *to;
+ char_u *arg = eap->arg;
+ char_u *from, *from_noamp, *to;
- if (menutrans_ga.ga_itemsize == 0)
+ if (menutrans_ga.ga_itemsize == 0) {
ga_init(&menutrans_ga, (int)sizeof(menutrans_T), 5);
+ }
/*
* ":menutrans clear": clear all translations.
@@ -1516,18 +1548,18 @@ void ex_menutranslate(exarg_T *eap)
if (STRNCMP(arg, "clear", 5) == 0 && ends_excmd(*skipwhite(arg + 5))) {
GA_DEEP_CLEAR(&menutrans_ga, menutrans_T, FREE_MENUTRANS);
- /* Delete all "menutrans_" global variables. */
+ // Delete all "menutrans_" global variables.
del_menutrans_vars();
} else {
- /* ":menutrans from to": add translation */
+ // ":menutrans from to": add translation
from = arg;
arg = menu_skip_part(arg);
to = skipwhite(arg);
*arg = NUL;
arg = menu_skip_part(to);
- if (arg == to)
+ if (arg == to) {
EMSG(_(e_invarg));
- else {
+ } else {
from = vim_strsave(from);
from_noamp = menu_text(from, NULL, NULL);
assert(arg >= to);
@@ -1536,7 +1568,7 @@ void ex_menutranslate(exarg_T *eap)
menu_translate_tab_and_shift(to);
menu_unescape_name(from);
menu_unescape_name(to);
- menutrans_T* tp = GA_APPEND_VIA_PTR(menutrans_T, &menutrans_ga);
+ menutrans_T *tp = GA_APPEND_VIA_PTR(menutrans_T, &menutrans_ga);
tp->from = from;
tp->from_noamp = from_noamp;
tp->to = to;
@@ -1550,8 +1582,9 @@ void ex_menutranslate(exarg_T *eap)
static char_u *menu_skip_part(char_u *p)
{
while (*p != NUL && *p != '.' && !ascii_iswhite(*p)) {
- if ((*p == '\\' || *p == Ctrl_V) && p[1] != NUL)
+ if ((*p == '\\' || *p == Ctrl_V) && p[1] != NUL) {
++p;
+ }
++p;
}
return p;
@@ -1563,8 +1596,8 @@ static char_u *menu_skip_part(char_u *p)
*/
static char_u *menutrans_lookup(char_u *name, int len)
{
- menutrans_T *tp = (menutrans_T *)menutrans_ga.ga_data;
- char_u *dname;
+ menutrans_T *tp = (menutrans_T *)menutrans_ga.ga_data;
+ char_u *dname;
for (int i = 0; i < menutrans_ga.ga_len; i++) {
if (STRNICMP(name, tp[i].from, len) == 0 && tp[i].from[len] == NUL) {
@@ -1572,7 +1605,7 @@ static char_u *menutrans_lookup(char_u *name, int len)
}
}
- /* Now try again while ignoring '&' characters. */
+ // Now try again while ignoring '&' characters.
char_u c = name[len];
name[len] = NUL;
dname = menu_text(name, NULL, NULL);
@@ -1593,7 +1626,7 @@ static char_u *menutrans_lookup(char_u *name, int len)
*/
static void menu_unescape_name(char_u *name)
{
- char_u *p;
+ char_u *p;
for (p = name; *p && *p != '.'; MB_PTR_ADV(p)) {
if (*p == '\\') {
@@ -1608,19 +1641,20 @@ static void menu_unescape_name(char_u *name)
*/
static char_u *menu_translate_tab_and_shift(char_u *arg_start)
{
- char_u *arg = arg_start;
+ char_u *arg = arg_start;
while (*arg && !ascii_iswhite(*arg)) {
- if ((*arg == '\\' || *arg == Ctrl_V) && arg[1] != NUL)
+ if ((*arg == '\\' || *arg == Ctrl_V) && arg[1] != NUL) {
arg++;
- else if (STRNICMP(arg, "<TAB>", 5) == 0) {
+ } else if (STRNICMP(arg, "<TAB>", 5) == 0) {
*arg = TAB;
STRMOVE(arg + 1, arg + 5);
}
arg++;
}
- if (*arg != NUL)
+ if (*arg != NUL) {
*arg++ = NUL;
+ }
arg = skipwhite(arg);
return arg;
diff --git a/src/nvim/menu.h b/src/nvim/menu.h
index 642d9aafac..5c65918d79 100644
--- a/src/nvim/menu.h
+++ b/src/nvim/menu.h
@@ -1,10 +1,10 @@
#ifndef NVIM_MENU_H
#define NVIM_MENU_H
-#include <stdbool.h> // for bool
+#include <stdbool.h> // for bool
-#include "nvim/types.h" // for char_u and expand_T
-#include "nvim/ex_cmds_defs.h" // for exarg_T
+#include "nvim/ex_cmds_defs.h" // for exarg_T
+#include "nvim/types.h" // for char_u and expand_T
/// @}
/// note MENU_INDEX_TIP is not a 'real' mode
diff --git a/src/nvim/message.c b/src/nvim/message.c
index f9ed9f3004..279f84f3d4 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -7,42 +7,42 @@
#include <assert.h>
#include <inttypes.h>
-#include <stdbool.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <string.h>
-#include "nvim/vim.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
#include "nvim/assert.h"
-#include "nvim/message.h"
#include "nvim/charset.h"
#include "nvim/eval.h"
-#include "nvim/ex_eval.h"
#include "nvim/ex_docmd.h"
+#include "nvim/ex_eval.h"
#include "nvim/fileio.h"
#include "nvim/func_attr.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
+#include "nvim/highlight.h"
+#include "nvim/keymap.h"
#include "nvim/main.h"
#include "nvim/mbyte.h"
#include "nvim/memory.h"
+#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/keymap.h"
-#include "nvim/garray.h"
+#include "nvim/mouse.h"
+#include "nvim/normal.h"
#include "nvim/ops.h"
#include "nvim/option.h"
-#include "nvim/normal.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/os/time.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
-#include "nvim/highlight.h"
#include "nvim/ui.h"
#include "nvim/ui_compositor.h"
-#include "nvim/mouse.h"
-#include "nvim/os/os.h"
-#include "nvim/os/input.h"
-#include "nvim/os/time.h"
-#include "nvim/api/private/helpers.h"
+#include "nvim/vim.h"
/*
* To be able to scroll back at the "more" and "hit-enter" prompts we need to
@@ -50,24 +50,24 @@
*/
typedef struct msgchunk_S msgchunk_T;
struct msgchunk_S {
- msgchunk_T *sb_next;
- msgchunk_T *sb_prev;
- char sb_eol; /* TRUE when line ends after this text */
- int sb_msg_col; /* column in which text starts */
- int sb_attr; /* text attributes */
- char_u sb_text[1]; /* text to be displayed, actually longer */
+ msgchunk_T *sb_next;
+ msgchunk_T *sb_prev;
+ char sb_eol; // TRUE when line ends after this text
+ int sb_msg_col; // column in which text starts
+ int sb_attr; // text attributes
+ char_u sb_text[1]; // text to be displayed, actually longer
};
-/* Magic chars used in confirm dialog strings */
+// Magic chars used in confirm dialog strings
#define DLG_BUTTON_SEP '\n'
#define DLG_HOTKEY_CHAR '&'
-static int confirm_msg_used = FALSE; /* displaying confirm_msg */
+static int confirm_msg_used = FALSE; // displaying confirm_msg
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "message.c.generated.h"
#endif
-static char_u *confirm_msg = NULL; /* ":confirm" message */
-static char_u *confirm_msg_tail; /* tail of confirm_msg */
+static char_u *confirm_msg = NULL; // ":confirm" message
+static char_u *confirm_msg_tail; // tail of confirm_msg
MessageHistoryEntry *first_msg_hist = NULL;
MessageHistoryEntry *last_msg_hist = NULL;
@@ -79,37 +79,37 @@ static int verbose_did_open = FALSE;
/*
* When writing messages to the screen, there are many different situations.
* A number of variables is used to remember the current state:
- * msg_didany true when messages were written since the last time the
- * user reacted to a prompt.
- * Reset: After hitting a key for the hit-return prompt,
- * hitting <CR> for the command line or input().
- * Set: When any message is written to the screen.
- * msg_didout true when something was written to the current line.
- * Reset: When advancing to the next line, when the current
- * text can be overwritten.
- * Set: When any message is written to the screen.
- * msg_nowait No extra delay for the last drawn message.
- * Used in normal_cmd() before the mode message is drawn.
+ * msg_didany true when messages were written since the last time the
+ * user reacted to a prompt.
+ * Reset: After hitting a key for the hit-return prompt,
+ * hitting <CR> for the command line or input().
+ * Set: When any message is written to the screen.
+ * msg_didout true when something was written to the current line.
+ * Reset: When advancing to the next line, when the current
+ * text can be overwritten.
+ * Set: When any message is written to the screen.
+ * msg_nowait No extra delay for the last drawn message.
+ * Used in normal_cmd() before the mode message is drawn.
* emsg_on_display There was an error message recently. Indicates that there
- * should be a delay before redrawing.
- * msg_scroll The next message should not overwrite the current one.
- * msg_scrolled How many lines the screen has been scrolled (because of
- * messages). Used in update_screen() to scroll the screen
- * back. Incremented each time the screen scrolls a line.
+ * should be a delay before redrawing.
+ * msg_scroll The next message should not overwrite the current one.
+ * msg_scrolled How many lines the screen has been scrolled (because of
+ * messages). Used in update_screen() to scroll the screen
+ * back. Incremented each time the screen scrolls a line.
* msg_scrolled_ign TRUE when msg_scrolled is non-zero and msg_puts_attr()
- * writes something without scrolling should not make
- * need_wait_return to be set. This is a hack to make ":ts"
- * work without an extra prompt.
- * lines_left Number of lines available for messages before the
- * more-prompt is to be given. -1 when not set.
+ * writes something without scrolling should not make
+ * need_wait_return to be set. This is a hack to make ":ts"
+ * work without an extra prompt.
+ * lines_left Number of lines available for messages before the
+ * more-prompt is to be given. -1 when not set.
* need_wait_return true when the hit-return prompt is needed.
- * Reset: After giving the hit-return prompt, when the user
- * has answered some other prompt.
- * Set: When the ruler or typeahead display is overwritten,
- * scrolling the screen for some message.
- * keep_msg Message to be displayed after redrawing the screen, in
- * main_loop().
- * This is an allocated string or NULL when not used.
+ * Reset: After giving the hit-return prompt, when the user
+ * has answered some other prompt.
+ * Set: When the ruler or typeahead display is overwritten,
+ * scrolling the screen for some message.
+ * keep_msg Message to be displayed after redrawing the screen, in
+ * main_loop().
+ * This is an allocated string or NULL when not used.
*/
@@ -231,8 +231,7 @@ int msg_attr(const char *s, const int attr)
}
/// similar to msg_outtrans_attr, but support newlines and tabs.
-void msg_multiline_attr(const char *s, int attr,
- bool check_int, bool *need_clear)
+void msg_multiline_attr(const char *s, int attr, bool check_int, bool *need_clear)
FUNC_ATTR_NONNULL_ALL
{
const char *next_spec = s;
@@ -287,16 +286,17 @@ bool msg_attr_keep(char_u *s, int attr, bool keep, bool multiline)
}
if (attr == 0) {
- set_vim_var_string(VV_STATUSMSG, (char *) s, -1);
+ set_vim_var_string(VV_STATUSMSG, (char *)s, -1);
}
/*
* It is possible that displaying a messages causes a problem (e.g.,
- * when redrawing the window), which causes another message, etc.. To
+ * when redrawing the window), which causes another message, etc.. To
* break this loop, limit the recursiveness to 3 levels.
*/
- if (entered >= 3)
+ if (entered >= 3) {
return TRUE;
+ }
++entered;
/* Add message to history (unless it's a repeated kept message or a
@@ -309,11 +309,12 @@ bool msg_attr_keep(char_u *s, int attr, bool keep, bool multiline)
add_msg_hist((const char *)s, -1, attr, multiline);
}
- /* Truncate the message if needed. */
+ // Truncate the message if needed.
msg_start();
buf = msg_strtrunc(s, FALSE);
- if (buf != NULL)
+ if (buf != NULL) {
s = buf;
+ }
bool need_clear = true;
if (multiline) {
@@ -336,31 +337,28 @@ bool msg_attr_keep(char_u *s, int attr, bool keep, bool multiline)
return retval;
}
-/*
- * Truncate a string such that it can be printed without causing a scroll.
- * Returns an allocated string or NULL when no truncating is done.
- */
-char_u *
-msg_strtrunc (
- char_u *s,
- int force /* always truncate */
-)
+/// Truncate a string such that it can be printed without causing a scroll.
+/// Returns an allocated string or NULL when no truncating is done.
+///
+/// @param force always truncate
+char_u *msg_strtrunc(char_u *s, int force)
{
- char_u *buf = NULL;
+ char_u *buf = NULL;
int len;
int room;
- /* May truncate message to avoid a hit-return prompt */
+ // May truncate message to avoid a hit-return prompt
if ((!msg_scroll && !need_wait_return && shortmess(SHM_TRUNCALL)
&& !exmode_active && msg_silent == 0 && !ui_has(kUIMessages))
|| force) {
len = vim_strsize(s);
- if (msg_scrolled != 0)
- /* Use all the columns. */
+ if (msg_scrolled != 0) {
+ // Use all the columns.
room = (int)(Rows - msg_row) * Columns - 1;
- else
- /* Use up to 'showcmd' column. */
+ } else {
+ // Use up to 'showcmd' column.
room = (int)(Rows - msg_row - 1) * Columns + sc_col - 1;
+ }
if (len > room && room > 0) {
// may have up to 18 bytes per cell (6 per char, up to two
// composing chars)
@@ -390,10 +388,10 @@ void trunc_string(char_u *s, char_u *buf, int room_in, int buflen)
}
half = room / 2;
- /* First part: Start of the string. */
+ // First part: Start of the string.
for (e = 0; len < half && e < buflen; ++e) {
if (s[e] == NUL) {
- /* text fits without truncating! */
+ // text fits without truncating!
buf[e] = NUL;
return;
}
@@ -497,7 +495,7 @@ int smsg_attr_keep(int attr, char *s, ...)
* isn't printed each time when it didn't change.
*/
static int last_sourcing_lnum = 0;
-static char_u *last_sourcing_name = NULL;
+static char_u *last_sourcing_name = NULL;
/*
* Reset the last used sourcing name/lnum. Makes sure it is displayed again
@@ -515,8 +513,9 @@ void reset_last_sourcing(void)
static int other_sourcing_name(void)
{
if (sourcing_name != NULL) {
- if (last_sourcing_name != NULL)
+ if (last_sourcing_name != NULL) {
return STRCMP(sourcing_name, last_sourcing_name) != 0;
+ }
return TRUE;
}
return FALSE;
@@ -577,16 +576,17 @@ void msg_source(int attr)
if (p != NULL) {
msg_attr(p, HL_ATTR(HLF_N));
xfree(p);
- last_sourcing_lnum = sourcing_lnum; /* only once for each line */
+ last_sourcing_lnum = sourcing_lnum; // only once for each line
}
- /* remember the last sourcing name printed, also when it's empty */
+ // remember the last sourcing name printed, also when it's empty
if (sourcing_name == NULL || other_sourcing_name()) {
xfree(last_sourcing_name);
- if (sourcing_name == NULL)
+ if (sourcing_name == NULL) {
last_sourcing_name = NULL;
- else
+ } else {
last_sourcing_name = vim_strsave(sourcing_name);
+ }
}
--no_wait_return;
}
@@ -601,9 +601,9 @@ int emsg_not_now(void)
{
if ((emsg_off > 0 && vim_strchr(p_debug, 'm') == NULL
&& vim_strchr(p_debug, 't') == NULL)
- || emsg_skip > 0
- )
+ || emsg_skip > 0) {
return TRUE;
+ }
return FALSE;
}
@@ -762,7 +762,7 @@ bool emsgf_multiline(const char *const fmt, ...)
va_list ap;
- static char errbuf[MULTILINE_BUFSIZE];
+ static char errbuf[MULTILINE_BUFSIZE];
if (emsg_not_now()) {
return true;
}
@@ -794,9 +794,9 @@ static bool emsgfv(const char *fmt, va_list ap)
/// detected when fuzzing vim.
void iemsg(const char *s)
{
- emsg((char_u *)s);
+ emsg((char_u *)s);
#ifdef ABORT_ON_INTERNAL_ERROR
- abort();
+ abort();
#endif
}
@@ -805,19 +805,19 @@ void iemsg(const char *s)
/// detected when fuzzing vim.
void iemsgf(const char *s, ...)
{
- va_list ap;
- va_start(ap, s);
- (void)emsgfv(s, ap);
- va_end(ap);
+ va_list ap;
+ va_start(ap, s);
+ (void)emsgfv(s, ap);
+ va_end(ap);
#ifdef ABORT_ON_INTERNAL_ERROR
- abort();
+ abort();
#endif
}
/// Give an "Internal error" message.
void internal_error(char *where)
{
- IEMSG2(_(e_intern2), where);
+ IEMSG2(_(e_intern2), where);
}
static void msg_emsgf_event(void **argv)
@@ -858,8 +858,9 @@ char_u *msg_trunc_attr(char_u *s, int force, int attr)
n = msg_attr((const char *)s, attr);
msg_hist_off = false;
- if (n)
+ if (n) {
return s;
+ }
return NULL;
}
@@ -930,18 +931,21 @@ void add_hl_msg_hist(HlMessage hl_msg)
/// @param[in] len Length of s or -1.
static void add_msg_hist(const char *s, int len, int attr, bool multiline)
{
- if (msg_hist_off || msg_silent != 0)
+ if (msg_hist_off || msg_silent != 0) {
return;
+ }
- /* Don't let the message history get too big */
- while (msg_hist_len > MAX_MSG_HIST_LEN)
+ // Don't let the message history get too big
+ while (msg_hist_len > MAX_MSG_HIST_LEN) {
(void)delete_first_msg();
+ }
- /* allocate an entry and add the message at the end of the history */
+ // allocate an entry and add the message at the end of the history
struct msg_hist *p = xmalloc(sizeof(struct msg_hist));
- if (len < 0)
+ if (len < 0) {
len = (int)STRLEN(s);
- /* remove leading and trailing newlines */
+ }
+ // remove leading and trailing newlines
while (len > 0 && *s == '\n') {
++s;
--len;
@@ -972,11 +976,12 @@ int delete_first_msg(void)
{
struct msg_hist *p;
- if (msg_hist_len <= 0)
+ if (msg_hist_len <= 0) {
return FAIL;
+ }
p = first_msg_hist;
first_msg_hist = p->next;
- if (first_msg_hist == NULL) { /* history is becoming empty */
+ if (first_msg_hist == NULL) { // history is becoming empty
assert(msg_hist_len == 1);
last_msg_hist = NULL;
}
@@ -1078,7 +1083,7 @@ void wait_return(int redraw)
int oldState;
int tmpState;
int had_got_int;
- FILE *save_scriptout;
+ FILE *save_scriptout;
if (redraw == true) {
redraw_all_later(NOT_VALID);
@@ -1086,8 +1091,9 @@ void wait_return(int redraw)
/* If using ":silent cmd", don't wait for a return. Also don't set
* need_wait_return to do it later. */
- if (msg_silent != 0)
+ if (msg_silent != 0) {
return;
+ }
/*
* When inside vgetc(), we can't wait for a typed character at all.
@@ -1095,24 +1101,26 @@ void wait_return(int redraw)
* the end. Adjust cmdline_row to avoid the next message overwriting the
* last one.
*/
- if (vgetc_busy > 0)
+ if (vgetc_busy > 0) {
return;
+ }
need_wait_return = true;
if (no_wait_return) {
- if (!exmode_active)
+ if (!exmode_active) {
cmdline_row = msg_row;
+ }
return;
}
redir_off = true; // don't redirect this message
oldState = State;
if (quit_more) {
- c = CAR; /* just pretend CR was hit */
+ c = CAR; // just pretend CR was hit
quit_more = FALSE;
got_int = FALSE;
} else if (exmode_active) {
- MSG_PUTS(" "); /* make sure the cursor is on the right line */
- c = CAR; /* no need for a return in ex mode */
+ MSG_PUTS(" "); // make sure the cursor is on the right line
+ c = CAR; // no need for a return in ex mode
got_int = FALSE;
} else {
// Make sure the hit-return prompt is on screen when 'guioptions' was
@@ -1176,7 +1184,7 @@ void wait_return(int redraw)
0;
}
if (quit_more) {
- c = CAR; /* just pretend CR was hit */
+ c = CAR; // just pretend CR was hit
quit_more = FALSE;
got_int = FALSE;
} else if (c != K_IGNORE) {
@@ -1185,8 +1193,9 @@ void wait_return(int redraw)
}
} else if (msg_scrolled > Rows - 2
&& (c == 'j' || c == 'd' || c == 'f'
- || c == K_DOWN || c == K_PAGEDOWN))
+ || c == K_DOWN || c == K_PAGEDOWN)) {
c = K_IGNORE;
+ }
}
} while ((had_got_int && c == Ctrl_C)
|| c == K_IGNORE
@@ -1201,9 +1210,9 @@ void wait_return(int redraw)
* Avoid that the mouse-up event causes visual mode to start.
*/
if (c == K_LEFTMOUSE || c == K_MIDDLEMOUSE || c == K_RIGHTMOUSE
- || c == K_X1MOUSE || c == K_X2MOUSE)
+ || c == K_X1MOUSE || c == K_X2MOUSE) {
(void)jump_to_mouse(MOUSE_SETPOS, NULL, 0);
- else if (vim_strchr((char_u *)"\r\n ", c) == NULL && c != Ctrl_C) {
+ } else if (vim_strchr((char_u *)"\r\n ", c) == NULL && c != Ctrl_C) {
/* Put the character back in the typeahead buffer. Don't use the
* stuff buffer, because lmaps wouldn't work. */
ins_char_typebuf(c);
@@ -1216,8 +1225,9 @@ void wait_return(int redraw)
// If the user hits ':', '?' or '/' we get a command line from the next
// line.
if (c == ':' || c == '?' || c == '/') {
- if (!exmode_active)
+ if (!exmode_active) {
cmdline_row = msg_row;
+ }
skip_redraw = true; // skip redraw once
do_redraw = false;
msg_ext_keep_after_cmdline = true;
@@ -1240,7 +1250,7 @@ void wait_return(int redraw)
XFREE_CLEAR(keep_msg); // don't redisplay message, it's too long
}
- if (tmpState == SETWSIZE) { /* got resize event while in vgetc() */
+ if (tmpState == SETWSIZE) { // got resize event while in vgetc()
ui_refresh();
} else if (!skip_redraw) {
if (redraw == true || (msg_scrolled != 0 && redraw != -1)) {
@@ -1259,9 +1269,10 @@ static void hit_return_msg(void)
{
int save_p_more = p_more;
- p_more = FALSE; /* don't want see this message when scrolling back */
- if (msg_didout) /* start on a new line */
+ p_more = FALSE; // don't want see this message when scrolling back
+ if (msg_didout) { // start on a new line
msg_putchar('\n');
+ }
msg_ext_set_kind("return_prompt");
if (got_int) {
MSG_PUTS(_("Interrupt: "));
@@ -1280,10 +1291,11 @@ static void hit_return_msg(void)
void set_keep_msg(char_u *s, int attr)
{
xfree(keep_msg);
- if (s != NULL && msg_silent == 0)
+ if (s != NULL && msg_silent == 0) {
keep_msg = vim_strsave(s);
- else
+ } else {
keep_msg = NULL;
+ }
keep_msg_more = false;
keep_msg_attr = attr;
}
@@ -1327,8 +1339,9 @@ void msg_start(void)
did_return = true;
cmdline_row = msg_row;
}
- if (!msg_didany || lines_left < 0)
+ if (!msg_didany || lines_left < 0) {
msg_starthere();
+ }
if (msg_silent == 0) {
msg_didout = false; // no output on current line yet
}
@@ -1396,7 +1409,7 @@ void msg_home_replace_hl(char_u *fname)
static void msg_home_replace_attr(char_u *fname, int attr)
{
- char_u *name;
+ char_u *name;
name = home_replace_save(NULL, fname);
msg_outtrans_attr(name, attr);
@@ -1449,7 +1462,7 @@ int msg_outtrans_len_attr(const char_u *msgstr, int len, int attr)
int mb_l;
int c;
- /* if MSG_HIST flag set, add message to history */
+ // if MSG_HIST flag set, add message to history
if (attr & MSG_HIST) {
add_msg_hist(str, len, attr, false);
attr &= ~MSG_HIST;
@@ -1518,13 +1531,16 @@ void msg_make(char_u *arg)
static char_u *str = (char_u *)"eeffoc", *rs = (char_u *)"Plon#dqg#vxjduB";
arg = skipwhite(arg);
- for (i = 5; *arg && i >= 0; --i)
- if (*arg++ != str[i])
+ for (i = 5; *arg && i >= 0; --i) {
+ if (*arg++ != str[i]) {
break;
+ }
+ }
if (i < 0) {
msg_putchar('\n');
- for (i = 0; rs[i]; ++i)
+ for (i = 0; rs[i]; ++i) {
msg_putchar(rs[i] - 3);
+ }
}
}
@@ -1540,11 +1556,10 @@ void msg_make(char_u *arg)
/// Otherwise characters are not highlighted.
/// This function is used to show mappings, where we want to see how to type
/// the character/string -- webb
-int msg_outtrans_special(
- const char_u *strstart,
- bool from, ///< true for LHS of a mapping
- int maxlen ///< screen columns, 0 for unlimeted
-)
+///
+/// @param from true for LHS of a mapping
+/// @param maxlen screen columns, 0 for unlimited
+int msg_outtrans_special(const char_u *strstart, bool from, int maxlen)
{
if (strstart == NULL) {
return 0; // Do nothing.
@@ -1585,8 +1600,7 @@ int msg_outtrans_special(
/// @param[in] replace_lt Convert `<` into `<lt>`.
///
/// @return [allocated] Converted string.
-char *str2special_save(const char *const str, const bool replace_spaces,
- const bool replace_lt)
+char *str2special_save(const char *const str, const bool replace_spaces, const bool replace_lt)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
FUNC_ATTR_NONNULL_RET
{
@@ -1595,7 +1609,7 @@ char *str2special_save(const char *const str, const bool replace_spaces,
const char *p = str;
while (*p != NUL) {
- ga_concat(&ga, (const char_u *)str2special(&p, replace_spaces, replace_lt));
+ ga_concat(&ga, str2special(&p, replace_spaces, replace_lt));
}
ga_append(&ga, NUL);
return (char *)ga.ga_data;
@@ -1611,8 +1625,7 @@ char *str2special_save(const char *const str, const bool replace_spaces,
/// @return Converted key code, in a static buffer. Buffer is always one and the
/// same, so save converted string somewhere before running str2special
/// for the second time.
-const char *str2special(const char **const sp, const bool replace_spaces,
- const bool replace_lt)
+const char *str2special(const char **const sp, const bool replace_spaces, const bool replace_lt)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET
{
static char buf[7];
@@ -1834,8 +1847,9 @@ void msg_prt_line(char_u *s, int list)
}
}
- if (c == NUL)
+ if (c == NUL) {
break;
+ }
msg_putchar_attr(c, attr);
col++;
@@ -2022,8 +2036,7 @@ static void msg_ext_emit_chunk(void)
* The display part of msg_puts_attr_len().
* May be called recursively to display scroll-back text.
*/
-static void msg_puts_display(const char_u *str, int maxlen, int attr,
- int recurse)
+static void msg_puts_display(const char_u *str, int maxlen, int attr, int recurse)
{
const char_u *s = str;
const char_u *t_s = str; // String from "t_s" to "s" is still todo.
@@ -2076,17 +2089,19 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr,
t_puts(&t_col, t_s, s, attr);
}
- /* When no more prompt and no more room, truncate here */
- if (msg_no_more && lines_left == 0)
+ // When no more prompt and no more room, truncate here
+ if (msg_no_more && lines_left == 0) {
break;
+ }
// Scroll the screen up one line.
bool has_last_char = (*s >= ' ' && !cmdmsg_rl);
msg_scroll_up(!has_last_char);
msg_row = Rows - 2;
- if (msg_col >= Columns) /* can happen after screen resize */
+ if (msg_col >= Columns) { // can happen after screen resize
msg_col = Columns - 1;
+ }
// Display char in last column before showing more-prompt.
if (has_last_char) {
@@ -2127,20 +2142,24 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr,
* If screen is completely filled and 'more' is set then wait
* for a character.
*/
- if (lines_left > 0)
+ if (lines_left > 0) {
--lines_left;
+ }
if (p_more && lines_left == 0 && State != HITRETURN
&& !msg_no_more && !exmode_active) {
- if (do_more_prompt(NUL))
+ if (do_more_prompt(NUL)) {
s = confirm_msg_tail;
- if (quit_more)
+ }
+ if (quit_more) {
return;
+ }
}
/* When we displayed a char in last column need to check if there
* is still more. */
- if (did_last_char)
+ if (did_last_char) {
continue;
+ }
}
wrap = *s == '\n'
@@ -2171,10 +2190,11 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr,
}
} else if (*s == '\r') { // go to column 0
msg_col = 0;
- } else if (*s == '\b') { /* go to previous char */
- if (msg_col)
+ } else if (*s == '\b') { // go to previous char
+ if (msg_col) {
--msg_col;
- } else if (*s == TAB) { /* translate Tab into spaces */
+ }
+ } else if (*s == TAB) { // translate Tab into spaces
do {
msg_screen_putchar(' ', attr);
} while (msg_col & 7);
@@ -2198,9 +2218,10 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr,
msg_screen_putchar(*s, attr);
}
} else {
- /* postpone this character until later */
- if (t_col == 0)
+ // postpone this character until later
+ if (t_col == 0) {
t_s = s;
+ }
t_col += cw;
s += l - 1;
}
@@ -2342,7 +2363,7 @@ void msg_reset_scroll(void)
// non-displayed part of msg_grid is considered invalid.
for (int i = 0; i < MIN(msg_scrollsize(), msg_grid.Rows); i++) {
grid_clear_line(&msg_grid, msg_grid.line_offset[i],
- (int)msg_grid.Columns, false);
+ msg_grid.Columns, false);
}
}
} else {
@@ -2358,7 +2379,7 @@ void msg_reset_scroll(void)
static void inc_msg_scrolled(void)
{
if (*get_vim_var_str(VV_SCROLLSTART) == NUL) {
- char *p = (char *) sourcing_name;
+ char *p = (char *)sourcing_name;
char *tofree = NULL;
// v:scrollstart is empty, set it to the script/function name and line
@@ -2369,7 +2390,7 @@ static void inc_msg_scrolled(void)
size_t len = strlen(p) + 40;
tofree = xmalloc(len);
vim_snprintf(tofree, len, _("%s line %" PRId64),
- p, (int64_t) sourcing_lnum);
+ p, (int64_t)sourcing_lnum);
p = tofree;
}
set_vim_var_string(VV_SCROLLSTART, p, -1);
@@ -2394,15 +2415,13 @@ typedef enum {
static sb_clear_T do_clear_sb_text = SB_CLEAR_NONE;
/// Store part of a printed message for displaying when scrolling back.
-static void store_sb_text(
- char_u **sb_str, // start of string
- char_u *s, // just after string
- int attr,
- int *sb_col,
- int finish // line ends
-)
+///
+/// @param sb_str start of string
+/// @param s just after string
+/// @param finish line ends
+static void store_sb_text(char_u **sb_str, char_u *s, int attr, int *sb_col, int finish)
{
- msgchunk_T *mp;
+ msgchunk_T *mp;
if (do_clear_sb_text == SB_CLEAR_ALL
|| do_clear_sb_text == SB_CLEAR_CMDLINE_DONE) {
@@ -2427,8 +2446,9 @@ static void store_sb_text(
last_msgchunk = mp;
}
mp->sb_next = NULL;
- } else if (finish && last_msgchunk != NULL)
+ } else if (finish && last_msgchunk != NULL) {
last_msgchunk->sb_eol = TRUE;
+ }
*sb_str = s;
*sb_col = 0;
@@ -2460,8 +2480,8 @@ void sb_text_end_cmdline(void)
/// Called when redrawing the screen.
void clear_sb_text(int all)
{
- msgchunk_T *mp;
- msgchunk_T **lastp;
+ msgchunk_T *mp;
+ msgchunk_T **lastp;
if (all) {
lastp = &last_msgchunk;
@@ -2484,7 +2504,7 @@ void clear_sb_text(int all)
*/
void show_sb_text(void)
{
- msgchunk_T *mp;
+ msgchunk_T *mp;
/* Only show something if there is more than one line, otherwise it looks
* weird, typing a command without output results in one line. */
@@ -2504,8 +2524,9 @@ static msgchunk_T *msg_sb_start(msgchunk_T *mps)
{
msgchunk_T *mp = mps;
- while (mp != NULL && mp->sb_prev != NULL && !mp->sb_prev->sb_eol)
+ while (mp != NULL && mp->sb_prev != NULL && !mp->sb_prev->sb_eol) {
mp = mp->sb_prev;
+ }
return mp;
}
@@ -2514,8 +2535,9 @@ static msgchunk_T *msg_sb_start(msgchunk_T *mps)
*/
void msg_sb_eol(void)
{
- if (last_msgchunk != NULL)
+ if (last_msgchunk != NULL) {
last_msgchunk->sb_eol = TRUE;
+ }
}
/*
@@ -2524,18 +2546,20 @@ void msg_sb_eol(void)
*/
static msgchunk_T *disp_sb_line(int row, msgchunk_T *smp)
{
- msgchunk_T *mp = smp;
- char_u *p;
+ msgchunk_T *mp = smp;
+ char_u *p;
for (;; ) {
msg_row = row;
msg_col = mp->sb_msg_col;
p = mp->sb_text;
- if (*p == '\n') /* don't display the line break */
+ if (*p == '\n') { // don't display the line break
++p;
+ }
msg_puts_display(p, -1, mp->sb_attr, TRUE);
- if (mp->sb_eol || mp->sb_next == NULL)
+ if (mp->sb_eol || mp->sb_next == NULL) {
break;
+ }
mp = mp->sb_next;
}
@@ -2633,8 +2657,8 @@ static int do_more_prompt(int typed_char)
int retval = FALSE;
int toscroll;
bool to_redraw = false;
- msgchunk_T *mp_last = NULL;
- msgchunk_T *mp;
+ msgchunk_T *mp_last = NULL;
+ msgchunk_T *mp;
int i;
// If headless mode is enabled and no input is required, this variable
@@ -2651,23 +2675,25 @@ static int do_more_prompt(int typed_char)
entered = true;
if (typed_char == 'G') {
- /* "g<": Find first line on the last page. */
+ // "g<": Find first line on the last page.
mp_last = msg_sb_start(last_msgchunk);
for (i = 0; i < Rows - 2 && mp_last != NULL
- && mp_last->sb_prev != NULL; ++i)
+ && mp_last->sb_prev != NULL; ++i) {
mp_last = msg_sb_start(mp_last->sb_prev);
+ }
}
State = ASKMORE;
setmouse();
- if (typed_char == NUL)
+ if (typed_char == NUL) {
msg_moremsg(FALSE);
+ }
for (;; ) {
/*
* Get a typed character directly from the user.
*/
if (used_typed_char != NUL) {
- c = used_typed_char; /* was typed at hit-enter prompt */
+ c = used_typed_char; // was typed at hit-enter prompt
used_typed_char = NUL;
} else {
c = get_keystroke(resize_events);
@@ -2676,50 +2702,50 @@ static int do_more_prompt(int typed_char)
toscroll = 0;
switch (c) {
- case BS: /* scroll one line back */
+ case BS: // scroll one line back
case K_BS:
case 'k':
case K_UP:
toscroll = -1;
break;
- case CAR: /* one extra line */
+ case CAR: // one extra line
case NL:
case 'j':
case K_DOWN:
toscroll = 1;
break;
- case 'u': /* Up half a page */
+ case 'u': // Up half a page
toscroll = -(Rows / 2);
break;
- case 'd': /* Down half a page */
+ case 'd': // Down half a page
toscroll = Rows / 2;
break;
- case 'b': /* one page back */
+ case 'b': // one page back
case K_PAGEUP:
toscroll = -(Rows - 1);
break;
- case ' ': /* one extra page */
+ case ' ': // one extra page
case 'f':
case K_PAGEDOWN:
case K_LEFTMOUSE:
toscroll = Rows - 1;
break;
- case 'g': /* all the way back to the start */
+ case 'g': // all the way back to the start
toscroll = -999999;
break;
- case 'G': /* all the way to the end */
+ case 'G': // all the way to the end
toscroll = 999999;
lines_left = 999999;
break;
- case ':': /* start new command line */
+ case ':': // start new command line
if (!confirm_msg_used) {
/* Since got_int is set all typeahead will be flushed, but we
* want to keep this ':', remember that in a special way. */
@@ -2733,7 +2759,7 @@ static int do_more_prompt(int typed_char)
case Ctrl_C:
case ESC:
if (confirm_msg_used) {
- /* Jump to the choices of the dialog. */
+ // Jump to the choices of the dialog.
retval = TRUE;
} else {
got_int = TRUE;
@@ -2752,7 +2778,7 @@ static int do_more_prompt(int typed_char)
to_redraw = true;
break;
- default: /* no valid response */
+ default: // no valid response
msg_moremsg(TRUE);
continue;
}
@@ -2771,10 +2797,11 @@ static int do_more_prompt(int typed_char)
mp = NULL;
}
- /* go to start of line at top of the screen */
+ // go to start of line at top of the screen
for (i = 0; i < Rows - 2 && mp != NULL && mp->sb_prev != NULL;
- ++i)
+ ++i) {
mp = msg_sb_start(mp->sb_prev);
+ }
if (mp != NULL && (mp->sb_prev != NULL || to_redraw)) {
// Find line to be displayed at top
@@ -2783,10 +2810,11 @@ static int do_more_prompt(int typed_char)
break;
}
mp = msg_sb_start(mp->sb_prev);
- if (mp_last == NULL)
+ if (mp_last == NULL) {
mp_last = msg_sb_start(last_msgchunk);
- else
+ } else {
mp_last = msg_sb_start(mp_last->sb_prev);
+ }
}
if (toscroll == -1 && !to_redraw) {
@@ -2810,7 +2838,7 @@ static int do_more_prompt(int typed_char)
toscroll = 0;
}
} else {
- /* First display any text that we scrolled back. */
+ // First display any text that we scrolled back.
while (toscroll > 0 && mp_last != NULL) {
if (msg_do_throttle() && !msg_grid.throttled) {
// Tricky: we redraw at one line higher than usual. Therefore
@@ -2836,7 +2864,7 @@ static int do_more_prompt(int typed_char)
continue;
}
- /* display more text, return to caller */
+ // display more text, return to caller
lines_left = toscroll;
}
@@ -2917,7 +2945,7 @@ static void msg_screen_putchar(int c, int attr)
void msg_moremsg(int full)
{
int attr;
- char_u *s = (char_u *)_("-- More --");
+ char_u *s = (char_u *)_("-- More --");
attr = hl_combine_attr(HL_ATTR(HLF_MSG), HL_ATTR(HLF_M));
grid_puts(&msg_grid_adj, s, Rows - 1, 0, attr);
@@ -2935,13 +2963,13 @@ void msg_moremsg(int full)
void repeat_message(void)
{
if (State == ASKMORE) {
- msg_moremsg(TRUE); /* display --more-- message again */
+ msg_moremsg(TRUE); // display --more-- message again
msg_row = Rows - 1;
} else if (State == CONFIRM) {
- display_confirm_msg(); /* display ":confirm" message again */
+ display_confirm_msg(); // display ":confirm" message again
msg_row = Rows - 1;
} else if (State == EXTERNCMD) {
- ui_cursor_goto(msg_row, msg_col); /* put cursor back */
+ ui_cursor_goto(msg_row, msg_col); // put cursor back
} else if (State == HITRETURN || State == SETWSIZE) {
if (msg_row == Rows - 1) {
/* Avoid drawing the "hit-enter" prompt below the previous one,
@@ -2962,8 +2990,9 @@ void repeat_message(void)
*/
void msg_clr_eos(void)
{
- if (msg_silent == 0)
+ if (msg_silent == 0) {
msg_clr_eos_force();
+ }
}
/*
@@ -3129,16 +3158,18 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen)
return;
}
- /* Don't do anything for displaying prompts and the like. */
- if (redir_off)
+ // Don't do anything for displaying prompts and the like.
+ if (redir_off) {
return;
+ }
- /* If 'verbosefile' is set prepare for writing in that file. */
- if (*p_vfile != NUL && verbose_fd == NULL)
+ // If 'verbosefile' is set prepare for writing in that file.
+ if (*p_vfile != NUL && verbose_fd == NULL) {
verbose_open();
+ }
if (redirecting()) {
- /* If the string doesn't start with CR or NL, go to msg_col */
+ // If the string doesn't start with CR or NL, go to msg_col
if (*s != '\n' && *s != '\r') {
while (cur_col < msg_col) {
if (capture_ga) {
@@ -3160,7 +3191,7 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen)
size_t len = maxlen == -1 ? STRLEN(s) : (size_t)maxlen;
if (capture_ga) {
- ga_concat_len(capture_ga, (const char *)str, len);
+ ga_concat_len(capture_ga, str, len);
}
if (redir_reg) {
write_reg_contents(redir_reg, s, len, true);
@@ -3190,8 +3221,9 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen)
s++;
}
- if (msg_silent != 0) /* should update msg_col */
+ if (msg_silent != 0) { // should update msg_col
msg_col = cur_col;
+ }
}
}
@@ -3207,8 +3239,9 @@ int redirecting(void)
*/
void verbose_enter(void)
{
- if (*p_vfile != NUL)
+ if (*p_vfile != NUL) {
++msg_silent;
+ }
}
/*
@@ -3217,9 +3250,11 @@ void verbose_enter(void)
*/
void verbose_leave(void)
{
- if (*p_vfile != NUL)
- if (--msg_silent < 0)
+ if (*p_vfile != NUL) {
+ if (--msg_silent < 0) {
msg_silent = 0;
+ }
+ }
}
/*
@@ -3227,11 +3262,12 @@ void verbose_leave(void)
*/
void verbose_enter_scroll(void)
{
- if (*p_vfile != NUL)
+ if (*p_vfile != NUL) {
++msg_silent;
- else
- /* always scroll up, don't overwrite */
+ } else {
+ // always scroll up, don't overwrite
msg_scroll = TRUE;
+ }
}
/*
@@ -3240,10 +3276,12 @@ void verbose_enter_scroll(void)
void verbose_leave_scroll(void)
{
if (*p_vfile != NUL) {
- if (--msg_silent < 0)
+ if (--msg_silent < 0) {
msg_silent = 0;
- } else
+ }
+ } else {
cmdline_row = msg_row;
+ }
}
/*
@@ -3265,7 +3303,7 @@ void verbose_stop(void)
int verbose_open(void)
{
if (verbose_fd == NULL && !verbose_did_open) {
- /* Only give the error message once. */
+ // Only give the error message once.
verbose_did_open = TRUE;
verbose_fd = os_fopen((char *)p_vfile, "a");
@@ -3324,8 +3362,8 @@ void give_warning2(char_u *const message, char_u *const a1, bool hl)
*/
void msg_advance(int col)
{
- if (msg_silent != 0) { /* nothing to advance to */
- msg_col = col; /* for redirection, may fill it up later */
+ if (msg_silent != 0) { // nothing to advance to
+ msg_col = col; // for redirection, may fill it up later
return;
}
if (ui_has(kUIMessages)) {
@@ -3336,49 +3374,44 @@ void msg_advance(int col)
}
return;
}
- if (col >= Columns) /* not enough room */
+ if (col >= Columns) { // not enough room
col = Columns - 1;
- if (cmdmsg_rl)
- while (msg_col > Columns - col)
+ }
+ if (cmdmsg_rl) {
+ while (msg_col > Columns - col) {
msg_putchar(' ');
- else
- while (msg_col < col)
+ }
+ } else {
+ while (msg_col < col) {
msg_putchar(' ');
+ }
+ }
}
-/*
- * Used for "confirm()" function, and the :confirm command prefix.
- * Versions which haven't got flexible dialogs yet, and console
- * versions, get this generic handler which uses the command line.
- *
- * type = one of:
- * VIM_QUESTION, VIM_INFO, VIM_WARNING, VIM_ERROR or VIM_GENERIC
- * title = title string (can be NULL for default)
- * (neither used in console dialogs at the moment)
- *
- * Format of the "buttons" string:
- * "Button1Name\nButton2Name\nButton3Name"
- * The first button should normally be the default/accept
- * The second button should be the 'Cancel' button
- * Other buttons- use your imagination!
- * A '&' in a button name becomes a shortcut, so each '&' should be before a
- * different letter.
- */
-int
-do_dialog (
- int type,
- char_u *title,
- char_u *message,
- char_u *buttons,
- int dfltbutton,
- char_u *textfield, /* IObuff for inputdialog(), NULL
- otherwise */
- int ex_cmd /* when TRUE pressing : accepts default and starts
- Ex command */
-)
+/// Used for "confirm()" function, and the :confirm command prefix.
+/// Versions which haven't got flexible dialogs yet, and console
+/// versions, get this generic handler which uses the command line.
+///
+/// type = one of:
+/// VIM_QUESTION, VIM_INFO, VIM_WARNING, VIM_ERROR or VIM_GENERIC
+/// title = title string (can be NULL for default)
+/// (neither used in console dialogs at the moment)
+///
+/// Format of the "buttons" string:
+/// "Button1Name\nButton2Name\nButton3Name"
+/// The first button should normally be the default/accept
+/// The second button should be the 'Cancel' button
+/// Other buttons- use your imagination!
+/// A '&' in a button name becomes a shortcut, so each '&' should be before a
+/// different letter.
+///
+/// @param textfiel IObuff for inputdialog(), NULL otherwise
+/// @param ex_cmd when TRUE pressing : accepts default and starts Ex command
+int do_dialog(int type, char_u *title, char_u *message, char_u *buttons, int dfltbutton,
+ char_u *textfield, int ex_cmd)
{
int retval = 0;
- char_u *hotkeys;
+ char_u *hotkeys;
int c;
int i;
@@ -3407,16 +3440,16 @@ do_dialog (
// Get a typed character directly from the user.
c = get_keystroke(NULL);
switch (c) {
- case CAR: /* User accepts default option */
+ case CAR: // User accepts default option
case NL:
retval = dfltbutton;
break;
- case Ctrl_C: /* User aborts/cancels */
+ case Ctrl_C: // User aborts/cancels
case ESC:
retval = 0;
break;
- default: /* Could be a hotkey? */
- if (c < 0) { /* special keys are ignored here */
+ default: // Could be a hotkey?
+ if (c < 0) { // special keys are ignored here
continue;
}
if (c == ':' && ex_cmd) {
@@ -3435,9 +3468,10 @@ do_dialog (
i += utfc_ptr2len(hotkeys + i) - 1;
retval++;
}
- if (hotkeys[i])
+ if (hotkeys[i]) {
break;
- /* No hotkey match, so keep waiting */
+ }
+ // No hotkey match, so keep waiting
continue;
}
break;
@@ -3455,15 +3489,11 @@ do_dialog (
}
-/*
- * Copy one character from "*from" to "*to", taking care of multi-byte
- * characters. Return the length of the character in bytes.
- */
-static int copy_char(
- const char_u *from,
- char_u *to,
- bool lowercase // make character lower case
-)
+/// Copy one character from "*from" to "*to", taking care of multi-byte
+/// characters. Return the length of the character in bytes.
+///
+/// @param lowercase make character lower case
+static int copy_char(const char_u *from, char_u *to, bool lowercase)
FUNC_ATTR_NONNULL_ALL
{
if (lowercase) {
@@ -3490,9 +3520,7 @@ static int copy_char(
/// corresponding button has a hotkey
///
/// @return Pointer to memory allocated for storing hotkeys
-static char_u * console_dialog_alloc(const char_u *message,
- char_u *buttons,
- bool has_hotkey[])
+static char_u *console_dialog_alloc(const char_u *message, char_u *buttons, bool has_hotkey[])
{
int lenhotkey = HOTK_LEN; // count first button
has_hotkey[0] = false;
@@ -3521,9 +3549,9 @@ static char_u * console_dialog_alloc(const char_u *message,
}
len += (int)(STRLEN(message)
- + 2 // for the NL's
- + STRLEN(buttons)
- + 3); // for the ": " and NUL
+ + 2 // for the NL's
+ + STRLEN(buttons)
+ + 3); // for the ": " and NUL
lenhotkey++; // for the NUL
// If no hotkey is specified, first char is used.
@@ -3552,7 +3580,7 @@ static char_u * console_dialog_alloc(const char_u *message,
static char_u *msg_show_console_dialog(char_u *message, char_u *buttons, int dfltbutton)
FUNC_ATTR_NONNULL_RET
{
- bool has_hotkey[HAS_HOTKEY_LEN] = {false};
+ bool has_hotkey[HAS_HOTKEY_LEN] = { false };
char_u *hotk = console_dialog_alloc(message, buttons, has_hotkey);
copy_hotkeys_and_msg(message, buttons, dfltbutton, has_hotkey, hotk);
@@ -3569,9 +3597,8 @@ static char_u *msg_show_console_dialog(char_u *message, char_u *buttons, int dfl
/// @param has_hotkey An element in this array is true if corresponding button
/// has a hotkey
/// @param[out] hotkeys_ptr Pointer to the memory location where hotkeys will be copied
-static void copy_hotkeys_and_msg(const char_u *message, char_u *buttons,
- int default_button_idx, const bool has_hotkey[],
- char_u *hotkeys_ptr)
+static void copy_hotkeys_and_msg(const char_u *message, char_u *buttons, int default_button_idx,
+ const bool has_hotkey[], char_u *hotkeys_ptr)
{
*confirm_msg = '\n';
STRCPY(confirm_msg + 1, message);
@@ -3611,7 +3638,6 @@ static void copy_hotkeys_and_msg(const char_u *message, char_u *buttons,
if (idx < HAS_HOTKEY_LEN - 1 && !has_hotkey[++idx]) {
first_hotkey = true;
}
-
} else if (*r == DLG_HOTKEY_CHAR || first_hotkey) {
if (*r == DLG_HOTKEY_CHAR) {
++r;
@@ -3660,21 +3686,24 @@ void display_confirm_msg(void)
int vim_dialog_yesno(int type, char_u *title, char_u *message, int dflt)
{
if (do_dialog(type,
- title == NULL ? (char_u *)_("Question") : title,
- message,
- (char_u *)_("&Yes\n&No"), dflt, NULL, FALSE) == 1)
+ title == NULL ? (char_u *)_("Question") : title,
+ message,
+ (char_u *)_("&Yes\n&No"), dflt, NULL, FALSE) == 1) {
return VIM_YES;
+ }
return VIM_NO;
}
int vim_dialog_yesnocancel(int type, char_u *title, char_u *message, int dflt)
{
switch (do_dialog(type,
- title == NULL ? (char_u *)_("Question") : title,
- message,
- (char_u *)_("&Yes\n&No\n&Cancel"), dflt, NULL, FALSE)) {
- case 1: return VIM_YES;
- case 2: return VIM_NO;
+ title == NULL ? (char_u *)_("Question") : title,
+ message,
+ (char_u *)_("&Yes\n&No\n&Cancel"), dflt, NULL, FALSE)) {
+ case 1:
+ return VIM_YES;
+ case 2:
+ return VIM_NO;
}
return VIM_CANCEL;
}
@@ -3682,14 +3711,18 @@ int vim_dialog_yesnocancel(int type, char_u *title, char_u *message, int dflt)
int vim_dialog_yesnoallcancel(int type, char_u *title, char_u *message, int dflt)
{
switch (do_dialog(type,
- title == NULL ? (char_u *)"Question" : title,
- message,
- (char_u *)_("&Yes\n&No\nSave &All\n&Discard All\n&Cancel"),
- dflt, NULL, FALSE)) {
- case 1: return VIM_YES;
- case 2: return VIM_NO;
- case 3: return VIM_ALL;
- case 4: return VIM_DISCARDALL;
+ title == NULL ? (char_u *)"Question" : title,
+ message,
+ (char_u *)_("&Yes\n&No\nSave &All\n&Discard All\n&Cancel"),
+ dflt, NULL, FALSE)) {
+ case 1:
+ return VIM_YES;
+ case 2:
+ return VIM_NO;
+ case 3:
+ return VIM_ALL;
+ case 4:
+ return VIM_DISCARDALL;
}
return VIM_CANCEL;
}
diff --git a/src/nvim/message.h b/src/nvim/message.h
index 377c725fa1..6d4d030500 100644
--- a/src/nvim/message.h
+++ b/src/nvim/message.h
@@ -1,15 +1,15 @@
#ifndef NVIM_MESSAGE_H
#define NVIM_MESSAGE_H
-#include <stdbool.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <stddef.h>
-#include "nvim/macros.h"
-#include "nvim/types.h"
-#include "nvim/grid_defs.h"
#include "nvim/api/private/defs.h"
+#include "nvim/grid_defs.h"
#include "nvim/lib/kvec.h"
+#include "nvim/macros.h"
+#include "nvim/types.h"
/*
* Types of dialogs passed to do_dialog().
@@ -19,7 +19,7 @@
#define VIM_WARNING 2
#define VIM_INFO 3
#define VIM_QUESTION 4
-#define VIM_LAST_TYPE 4 /* sentinel value */
+#define VIM_LAST_TYPE 4 // sentinel value
/*
* Return values for functions like vim_dialogyesno()
@@ -42,16 +42,16 @@
#define EMSG(s) emsg((char_u *)(s))
/// Like #EMSG, but for messages with one "%s" inside
-#define EMSG2(s, p) emsgf((const char *) (s), (p))
+#define EMSG2(s, p) emsgf((const char *)(s), (p))
/// Like #EMSG, but for messages with two "%s" inside
-#define EMSG3(s, p, q) emsgf((const char *) (s), (p), (q))
+#define EMSG3(s, p, q) emsgf((const char *)(s), (p), (q))
/// Like #EMSG, but for messages with one "%" PRId64 inside
-#define EMSGN(s, n) emsgf((const char *) (s), (int64_t)(n))
+#define EMSGN(s, n) emsgf((const char *)(s), (int64_t)(n))
/// Like #EMSG, but for messages with one "%" PRIu64 inside
-#define EMSGU(s, n) emsgf((const char *) (s), (uint64_t)(n))
+#define EMSGU(s, n) emsgf((const char *)(s), (uint64_t)(n))
/// Like #EMSG, but for internal messages
#define IEMSG(s) iemsg((const char *)(s))
diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c
index 6d94632687..40db5b7cf3 100644
--- a/src/nvim/misc1.c
+++ b/src/nvim/misc1.c
@@ -7,37 +7,43 @@
#include <assert.h>
#include <inttypes.h>
+#include <limits.h>
#include <stdbool.h>
#include <string.h>
-#include <limits.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/misc1.h"
+#include "nvim/buffer.h"
+#include "nvim/buffer_updates.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/diff.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
+#include "nvim/event/stream.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
#include "nvim/fileio.h"
-#include "nvim/func_attr.h"
#include "nvim/fold.h"
+#include "nvim/func_attr.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
-#include "nvim/buffer_updates.h"
#include "nvim/main.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
-#include "nvim/garray.h"
-#include "nvim/move.h"
+#include "nvim/misc1.h"
#include "nvim/mouse.h"
+#include "nvim/move.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/os/shell.h"
+#include "nvim/os/signal.h"
+#include "nvim/os/time.h"
#include "nvim/os_unix.h"
#include "nvim/quickfix.h"
#include "nvim/regexp.h"
@@ -48,14 +54,8 @@
#include "nvim/tag.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/os/os.h"
-#include "nvim/os/shell.h"
-#include "nvim/os/signal.h"
-#include "nvim/os/input.h"
-#include "nvim/os/time.h"
-#include "nvim/event/stream.h"
-#include "nvim/buffer.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "misc1.c.generated.h"
@@ -73,23 +73,23 @@ static garray_T ga_users = GA_EMPTY_INIT_VALUE;
* If "include_space" is set, include trailing whitespace while calculating the
* length.
*/
-int get_leader_len(char_u *line, char_u **flags,
- bool backward, bool include_space)
+int get_leader_len(char_u *line, char_u **flags, bool backward, bool include_space)
{
int i, j;
int result;
int got_com = FALSE;
int found_one;
- char_u part_buf[COM_MAX_LEN]; /* buffer for one option part */
- char_u *string; /* pointer to comment string */
- char_u *list;
+ char_u part_buf[COM_MAX_LEN]; // buffer for one option part
+ char_u *string; // pointer to comment string
+ char_u *list;
int middle_match_len = 0;
- char_u *prev_list;
- char_u *saved_flags = NULL;
+ char_u *prev_list;
+ char_u *saved_flags = NULL;
result = i = 0;
- while (ascii_iswhite(line[i])) /* leading white space is ignored */
+ while (ascii_iswhite(line[i])) { // leading white space is ignored
++i;
+ }
/*
* Repeat to match several nested comment strings.
@@ -102,51 +102,60 @@ int get_leader_len(char_u *line, char_u **flags,
for (list = curbuf->b_p_com; *list; ) {
/* Get one option part into part_buf[]. Advance "list" to next
* one. Put "string" at start of string. */
- if (!got_com && flags != NULL)
- *flags = list; /* remember where flags started */
+ if (!got_com && flags != NULL) {
+ *flags = list; // remember where flags started
+ }
prev_list = list;
(void)copy_option_part(&list, part_buf, COM_MAX_LEN, ",");
string = vim_strchr(part_buf, ':');
- if (string == NULL) /* missing ':', ignore this part */
+ if (string == NULL) { // missing ':', ignore this part
continue;
- *string++ = NUL; /* isolate flags from string */
+ }
+ *string++ = NUL; // isolate flags from string
/* If we found a middle match previously, use that match when this
* is not a middle or end. */
if (middle_match_len != 0
&& vim_strchr(part_buf, COM_MIDDLE) == NULL
- && vim_strchr(part_buf, COM_END) == NULL)
+ && vim_strchr(part_buf, COM_END) == NULL) {
break;
+ }
/* When we already found a nested comment, only accept further
* nested comments. */
- if (got_com && vim_strchr(part_buf, COM_NEST) == NULL)
+ if (got_com && vim_strchr(part_buf, COM_NEST) == NULL) {
continue;
+ }
- /* When 'O' flag present and using "O" command skip this one. */
- if (backward && vim_strchr(part_buf, COM_NOBACK) != NULL)
+ // When 'O' flag present and using "O" command skip this one.
+ if (backward && vim_strchr(part_buf, COM_NOBACK) != NULL) {
continue;
+ }
/* Line contents and string must match.
* When string starts with white space, must have some white space
* (but the amount does not need to match, there might be a mix of
* TABs and spaces). */
if (ascii_iswhite(string[0])) {
- if (i == 0 || !ascii_iswhite(line[i - 1]))
- continue; /* missing white space */
- while (ascii_iswhite(string[0]))
+ if (i == 0 || !ascii_iswhite(line[i - 1])) {
+ continue; // missing white space
+ }
+ while (ascii_iswhite(string[0])) {
++string;
+ }
}
- for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j)
+ for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j) {
;
- if (string[j] != NUL)
- continue; /* string doesn't match */
-
+ }
+ if (string[j] != NUL) {
+ continue; // string doesn't match
+ }
/* When 'b' flag used, there must be white space or an
* end-of-line after the string in the line. */
if (vim_strchr(part_buf, COM_BLANK) != NULL
- && !ascii_iswhite(line[i + j]) && line[i + j] != NUL)
+ && !ascii_iswhite(line[i + j]) && line[i + j] != NUL) {
continue;
+ }
/* We have found a match, stop searching unless this is a middle
* comment. The middle comment can be a substring of the end
@@ -160,13 +169,15 @@ int get_leader_len(char_u *line, char_u **flags,
}
continue;
}
- if (middle_match_len != 0 && j > middle_match_len)
+ if (middle_match_len != 0 && j > middle_match_len) {
/* Use this match instead of the middle match, since it's a
* longer thus better match. */
middle_match_len = 0;
+ }
- if (middle_match_len == 0)
+ if (middle_match_len == 0) {
i += j;
+ }
found_one = TRUE;
break;
}
@@ -174,29 +185,34 @@ int get_leader_len(char_u *line, char_u **flags,
if (middle_match_len != 0) {
/* Use the previously found middle match after failing to find a
* match with an end. */
- if (!got_com && flags != NULL)
+ if (!got_com && flags != NULL) {
*flags = saved_flags;
+ }
i += middle_match_len;
found_one = TRUE;
}
- /* No match found, stop scanning. */
- if (!found_one)
+ // No match found, stop scanning.
+ if (!found_one) {
break;
+ }
result = i;
- /* Include any trailing white space. */
- while (ascii_iswhite(line[i]))
+ // Include any trailing white space.
+ while (ascii_iswhite(line[i])) {
++i;
+ }
- if (include_space)
+ if (include_space) {
result = i;
+ }
- /* If this comment doesn't nest, stop here. */
+ // If this comment doesn't nest, stop here.
got_com = TRUE;
- if (vim_strchr(part_buf, COM_NEST) == NULL)
+ if (vim_strchr(part_buf, COM_NEST) == NULL) {
break;
+ }
}
return result;
}
@@ -213,12 +229,12 @@ int get_last_leader_offset(char_u *line, char_u **flags)
int result = -1;
int i, j;
int lower_check_bound = 0;
- char_u *string;
- char_u *com_leader;
- char_u *com_flags;
- char_u *list;
+ char_u *string;
+ char_u *com_leader;
+ char_u *com_flags;
+ char_u *list;
int found_one;
- char_u part_buf[COM_MAX_LEN]; /* buffer for one option part */
+ char_u part_buf[COM_MAX_LEN]; // buffer for one option part
/*
* Repeat to match several nested comment strings.
@@ -242,7 +258,7 @@ int get_last_leader_offset(char_u *line, char_u **flags)
* happen. */
continue;
}
- *string++ = NUL; /* Isolate flags from string. */
+ *string++ = NUL; // Isolate flags from string.
com_leader = string;
/*
@@ -252,16 +268,19 @@ int get_last_leader_offset(char_u *line, char_u **flags)
* TABs and spaces).
*/
if (ascii_iswhite(string[0])) {
- if (i == 0 || !ascii_iswhite(line[i - 1]))
+ if (i == 0 || !ascii_iswhite(line[i - 1])) {
continue;
+ }
while (ascii_iswhite(*string)) {
string++;
}
}
- for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j)
+ for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j) {
/* do nothing */;
- if (string[j] != NUL)
+ }
+ if (string[j] != NUL) {
continue;
+ }
/*
* When 'b' flag used, there must be white space or an
@@ -290,23 +309,25 @@ int get_last_leader_offset(char_u *line, char_u **flags)
*/
found_one = TRUE;
- if (flags)
+ if (flags) {
*flags = flags_save;
+ }
com_flags = flags_save;
break;
}
if (found_one) {
- char_u part_buf2[COM_MAX_LEN]; /* buffer for one option part */
+ char_u part_buf2[COM_MAX_LEN]; // buffer for one option part
int len1, len2, off;
result = i;
/*
* If this comment nests, continue searching.
*/
- if (vim_strchr(part_buf, COM_NEST) != NULL)
+ if (vim_strchr(part_buf, COM_NEST) != NULL) {
continue;
+ }
lower_check_bound = i;
@@ -316,31 +337,36 @@ int get_last_leader_offset(char_u *line, char_u **flags)
* the comment leader correctly.
*/
- while (ascii_iswhite(*com_leader))
+ while (ascii_iswhite(*com_leader)) {
++com_leader;
+ }
len1 = (int)STRLEN(com_leader);
for (list = curbuf->b_p_com; *list; ) {
char_u *flags_save = list;
(void)copy_option_part(&list, part_buf2, COM_MAX_LEN, ",");
- if (flags_save == com_flags)
+ if (flags_save == com_flags) {
continue;
+ }
string = vim_strchr(part_buf2, ':');
++string;
- while (ascii_iswhite(*string))
+ while (ascii_iswhite(*string)) {
++string;
+ }
len2 = (int)STRLEN(string);
- if (len2 == 0)
+ if (len2 == 0) {
continue;
+ }
/* Now we have to verify whether string ends with a substring
* beginning the com_leader. */
for (off = (len2 > i ? i : len2); off > 0 && off + len1 > len2; ) {
--off;
if (!STRNCMP(string + off, com_leader, len2 - off)) {
- if (i - off < lower_check_bound)
+ if (i - off < lower_check_bound) {
lower_check_bound = i - off;
+ }
}
}
}
@@ -361,7 +387,7 @@ int gchar_pos(pos_T *pos)
/*
* check_status: called when the status bars for the buffer 'buf'
- * need to be updated
+ * need to be updated
*/
void check_status(buf_T *buf)
{
@@ -459,7 +485,7 @@ int is_mouse_key(int c)
*/
int get_keystroke(MultiQueue *events)
{
- char_u *buf = NULL;
+ char_u *buf = NULL;
int buflen = 150;
int maxlen;
int len = 0;
@@ -493,9 +519,9 @@ int get_keystroke(MultiQueue *events)
n = fix_input_buffer(buf + len, n);
len += n;
waited = 0;
- } else if (len > 0)
- ++waited; /* keep track of the waiting time */
-
+ } else if (len > 0) {
+ ++waited; // keep track of the waiting time
+ }
if (n > 0) { // found a termcode: adjust length
len = n;
}
@@ -503,19 +529,20 @@ int get_keystroke(MultiQueue *events)
continue;
}
- /* Handle modifier and/or special key code. */
+ // Handle modifier and/or special key code.
n = buf[0];
if (n == K_SPECIAL) {
n = TO_SPECIAL(buf[1], buf[2]);
if (buf[1] == KS_MODIFIER
|| n == K_IGNORE
- || (is_mouse_key(n) && n != K_LEFTMOUSE)
- ) {
- if (buf[1] == KS_MODIFIER)
+ || (is_mouse_key(n) && n != K_LEFTMOUSE)) {
+ if (buf[1] == KS_MODIFIER) {
mod_mask = buf[2];
+ }
len -= 3;
- if (len > 0)
+ if (len > 0) {
memmove(buf, buf + 3, (size_t)len);
+ }
continue;
}
break;
@@ -534,27 +561,25 @@ int get_keystroke(MultiQueue *events)
return n;
}
-/*
- * Get a number from the user.
- * When "mouse_used" is not NULL allow using the mouse.
- */
-int
-get_number (
- int colon, /* allow colon to abort */
- int *mouse_used
-)
+/// Get a number from the user.
+/// When "mouse_used" is not NULL allow using the mouse.
+///
+/// @param colon allow colon to abort
+int get_number(int colon, int *mouse_used)
{
int n = 0;
int c;
int typed = 0;
- if (mouse_used != NULL)
+ if (mouse_used != NULL) {
*mouse_used = FALSE;
+ }
/* When not printing messages, the user won't know what to type, return a
* zero (as if CR was hit). */
- if (msg_silent != 0)
+ if (msg_silent != 0) {
return 0;
+ }
no_mapping++;
for (;; ) {
@@ -576,8 +601,9 @@ get_number (
break;
} else if (n == 0 && c == ':' && colon) {
stuffcharReadbuff(':');
- if (!exmode_active)
+ if (!exmode_active) {
cmdline_row = msg_row;
+ }
skip_redraw = true; // skip redraw once
do_redraw = false;
break;
@@ -643,40 +669,45 @@ void msgmore(long n)
{
long pn;
- if (global_busy /* no messages now, wait until global is finished */
- || !messaging()) /* 'lazyredraw' set, don't do messages now */
+ if (global_busy // no messages now, wait until global is finished
+ || !messaging()) { // 'lazyredraw' set, don't do messages now
return;
+ }
/* We don't want to overwrite another important message, but do overwrite
* a previous "more lines" or "fewer lines" message, so that "5dd" and
* then "put" reports the last action. */
- if (keep_msg != NULL && !keep_msg_more)
+ if (keep_msg != NULL && !keep_msg_more) {
return;
+ }
- if (n > 0)
+ if (n > 0) {
pn = n;
- else
+ } else {
pn = -n;
+ }
if (pn > p_report) {
if (pn == 1) {
- if (n > 0)
+ if (n > 0) {
STRLCPY(msg_buf, _("1 more line"), MSG_BUF_LEN);
- else
+ } else {
STRLCPY(msg_buf, _("1 line less"), MSG_BUF_LEN);
+ }
} else {
- if (n > 0)
- vim_snprintf((char *)msg_buf, MSG_BUF_LEN,
- _("%" PRId64 " more lines"), (int64_t)pn);
- else
- vim_snprintf((char *)msg_buf, MSG_BUF_LEN,
- _("%" PRId64 " fewer lines"), (int64_t)pn);
+ if (n > 0) {
+ vim_snprintf(msg_buf, MSG_BUF_LEN,
+ _("%" PRId64 " more lines"), (int64_t)pn);
+ } else {
+ vim_snprintf(msg_buf, MSG_BUF_LEN,
+ _("%" PRId64 " fewer lines"), (int64_t)pn);
+ }
}
if (got_int) {
- xstrlcat((char *)msg_buf, _(" (Interrupted)"), MSG_BUF_LEN);
+ xstrlcat(msg_buf, _(" (Interrupted)"), MSG_BUF_LEN);
}
- if (msg(msg_buf)) {
- set_keep_msg(msg_buf, 0);
+ if (msg((char_u *)msg_buf)) {
+ set_keep_msg((char_u *)msg_buf, 0);
keep_msg_more = true;
}
}
@@ -752,7 +783,7 @@ static void init_users(void)
}
lazy_init_done = TRUE;
-
+
os_get_usernames(&ga_users);
}
@@ -762,8 +793,9 @@ static void init_users(void)
char_u *get_users(expand_T *xp, int idx)
{
init_users();
- if (idx < ga_users.ga_len)
+ if (idx < ga_users.ga_len) {
return ((char_u **)ga_users.ga_data)[idx];
+ }
return NULL;
}
@@ -780,10 +812,12 @@ int match_user(char_u *name)
init_users();
for (int i = 0; i < ga_users.ga_len; i++) {
- if (STRCMP(((char_u **)ga_users.ga_data)[i], name) == 0)
- return 2; /* full match */
- if (STRNCMP(((char_u **)ga_users.ga_data)[i], name, n) == 0)
- result = 1; /* partial match */
+ if (STRCMP(((char_u **)ga_users.ga_data)[i], name) == 0) {
+ return 2; // full match
+ }
+ if (STRNCMP(((char_u **)ga_users.ga_data)[i], name, n) == 0) {
+ result = 1; // partial match
+ }
}
return result;
}
@@ -840,7 +874,7 @@ void preserve_exit(void)
*/
#ifndef BREAKCHECK_SKIP
-# define BREAKCHECK_SKIP 1000
+# define BREAKCHECK_SKIP 1000
#endif
static int breakcheck_count = 0;
@@ -921,8 +955,7 @@ int call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg)
/// @param ret_len length of the stdout
///
/// @return an allocated string, or NULL for error.
-char_u *get_cmd_output(char_u *cmd, char_u *infile, ShellOpts flags,
- size_t *ret_len)
+char_u *get_cmd_output(char_u *cmd, char_u *infile, ShellOpts flags, size_t *ret_len)
{
char_u *buffer = NULL;
@@ -970,12 +1003,14 @@ char_u *get_cmd_output(char_u *cmd, char_u *infile, ShellOpts flags,
EMSG2(_(e_notread), tempname);
XFREE_CLEAR(buffer);
} else if (ret_len == NULL) {
- /* Change NUL into SOH, otherwise the string is truncated. */
- for (i = 0; i < len; ++i)
- if (buffer[i] == NUL)
+ // Change NUL into SOH, otherwise the string is truncated.
+ for (i = 0; i < len; ++i) {
+ if (buffer[i] == NUL) {
buffer[i] = 1;
+ }
+ }
- buffer[len] = NUL; /* make sure the buffer is terminated */
+ buffer[len] = NUL; // make sure the buffer is terminated
} else {
*ret_len = len;
}
@@ -991,10 +1026,12 @@ done:
*/
void FreeWild(int count, char_u **files)
{
- if (count <= 0 || files == NULL)
+ if (count <= 0 || files == NULL) {
return;
- while (count--)
+ }
+ while (count--) {
xfree(files[count]);
+ }
xfree(files);
}
diff --git a/src/nvim/misc1.h b/src/nvim/misc1.h
index f0f66854d8..4ce142c4c5 100644
--- a/src/nvim/misc1.h
+++ b/src/nvim/misc1.h
@@ -1,15 +1,15 @@
#ifndef NVIM_MISC1_H
#define NVIM_MISC1_H
-#include "nvim/vim.h"
#include "nvim/os/shell.h"
+#include "nvim/vim.h"
-/* flags for open_line() */
-#define OPENLINE_DELSPACES 1 /* delete spaces after cursor */
-#define OPENLINE_DO_COM 2 /* format comments */
-#define OPENLINE_KEEPTRAIL 4 /* keep trailing spaces */
-#define OPENLINE_MARKFIX 8 /* fix mark positions */
-#define OPENLINE_COM_LIST 16 /* format comments with list/2nd line indent */
+// flags for open_line()
+#define OPENLINE_DELSPACES 1 // delete spaces after cursor
+#define OPENLINE_DO_COM 2 // format comments
+#define OPENLINE_KEEPTRAIL 4 // keep trailing spaces
+#define OPENLINE_MARKFIX 8 // fix mark positions
+#define OPENLINE_COM_LIST 16 // format comments with list/2nd line indent
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "misc1.h.generated.h"
diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c
index c4fa269851..f02c000e82 100644
--- a/src/nvim/mouse.c
+++ b/src/nvim/mouse.c
@@ -3,26 +3,26 @@
#include <stdbool.h>
-#include "nvim/mouse.h"
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/window.h"
+#include "nvim/buffer_defs.h"
+#include "nvim/charset.h"
+#include "nvim/cursor.h"
+#include "nvim/diff.h"
+#include "nvim/fold.h"
+#include "nvim/memline.h"
+#include "nvim/misc1.h"
+#include "nvim/mouse.h"
+#include "nvim/move.h"
+#include "nvim/os_unix.h"
+#include "nvim/plines.h"
+#include "nvim/screen.h"
#include "nvim/state.h"
#include "nvim/strings.h"
-#include "nvim/screen.h"
#include "nvim/syntax.h"
#include "nvim/ui.h"
#include "nvim/ui_compositor.h"
-#include "nvim/os_unix.h"
-#include "nvim/fold.h"
-#include "nvim/diff.h"
-#include "nvim/move.h"
-#include "nvim/misc1.h"
-#include "nvim/plines.h"
-#include "nvim/cursor.h"
-#include "nvim/buffer_defs.h"
-#include "nvim/memline.h"
-#include "nvim/charset.h"
+#include "nvim/vim.h"
+#include "nvim/window.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "mouse.c.generated.h"
@@ -31,33 +31,34 @@
static linenr_T orig_topline = 0;
static int orig_topfill = 0;
-// Move the cursor to the specified row and column on the screen.
-// Change current window if necessary. Returns an integer with the
-// CURSOR_MOVED bit set if the cursor has moved or unset otherwise.
-//
-// The MOUSE_FOLD_CLOSE bit is set when clicked on the '-' in a fold column.
-// The MOUSE_FOLD_OPEN bit is set when clicked on the '+' in a fold column.
-//
-// If flags has MOUSE_FOCUS, then the current window will not be changed, and
-// if the mouse is outside the window then the text will scroll, or if the
-// mouse was previously on a status line, then the status line may be dragged.
-//
-// If flags has MOUSE_MAY_VIS, then VIsual mode will be started before the
-// cursor is moved unless the cursor was on a status line.
-// This function returns one of IN_UNKNOWN, IN_BUFFER, IN_STATUS_LINE or
-// IN_SEP_LINE depending on where the cursor was clicked.
-//
-// If flags has MOUSE_MAY_STOP_VIS, then Visual mode will be stopped, unless
-// the mouse is on the status line of the same window.
-//
-// If flags has MOUSE_DID_MOVE, nothing is done if the mouse didn't move since
-// the last call.
-//
-// If flags has MOUSE_SETPOS, nothing is done, only the current position is
-// remembered.
-int jump_to_mouse(int flags,
- bool *inclusive, // used for inclusive operator, can be NULL
- int which_button) // MOUSE_LEFT, MOUSE_RIGHT, MOUSE_MIDDLE
+/// Move the cursor to the specified row and column on the screen.
+/// Change current window if necessary. Returns an integer with the
+/// CURSOR_MOVED bit set if the cursor has moved or unset otherwise.
+///
+/// The MOUSE_FOLD_CLOSE bit is set when clicked on the '-' in a fold column.
+/// The MOUSE_FOLD_OPEN bit is set when clicked on the '+' in a fold column.
+///
+/// If flags has MOUSE_FOCUS, then the current window will not be changed, and
+/// if the mouse is outside the window then the text will scroll, or if the
+/// mouse was previously on a status line, then the status line may be dragged.
+///
+/// If flags has MOUSE_MAY_VIS, then VIsual mode will be started before the
+/// cursor is moved unless the cursor was on a status line.
+/// This function returns one of IN_UNKNOWN, IN_BUFFER, IN_STATUS_LINE or
+/// IN_SEP_LINE depending on where the cursor was clicked.
+///
+/// If flags has MOUSE_MAY_STOP_VIS, then Visual mode will be stopped, unless
+/// the mouse is on the status line of the same window.
+///
+/// If flags has MOUSE_DID_MOVE, nothing is done if the mouse didn't move since
+/// the last call.
+///
+/// If flags has MOUSE_SETPOS, nothing is done, only the current position is
+/// remembered.
+///
+/// @param inclusive used for inclusive operator, can be NULL
+/// @param which_button MOUSE_LEFT, MOUSE_RIGHT, MOUSE_MIDDLE
+int jump_to_mouse(int flags, bool *inclusive, int which_button)
{
static int on_status_line = 0; // #lines below bottom of window
static int on_sep_line = 0; // on separator right of window
@@ -66,7 +67,7 @@ int jump_to_mouse(int flags,
static win_T *dragwin = NULL; // window being dragged
static int did_drag = false; // drag was noticed
- win_T *wp, *old_curwin;
+ win_T *wp, *old_curwin;
pos_T old_cursor;
int count;
bool first;
@@ -81,8 +82,9 @@ int jump_to_mouse(int flags,
if (flags & MOUSE_RELEASED) {
// On button release we may change window focus if positioned on a
// status line and no dragging happened.
- if (dragwin != NULL && !did_drag)
+ if (dragwin != NULL && !did_drag) {
flags &= ~(MOUSE_FOCUS | MOUSE_DID_MOVE);
+ }
dragwin = NULL;
did_drag = false;
}
@@ -109,15 +111,16 @@ retnomove:
prev_row = mouse_row;
prev_col = mouse_col;
- if (flags & MOUSE_SETPOS)
+ if (flags & MOUSE_SETPOS) {
goto retnomove; // ugly goto...
-
+ }
old_curwin = curwin;
old_cursor = curwin->w_cursor;
if (!(flags & MOUSE_FOCUS)) {
- if (row < 0 || col < 0) // check if it makes sense
+ if (row < 0 || col < 0) { // check if it makes sense
return IN_UNKNOWN;
+ }
// find the window where the row is in
wp = mouse_find_win(&grid, &row, &col);
@@ -151,10 +154,11 @@ retnomove:
// The rightmost character of the status line might be a vertical
// separator character if there is no connecting window to the right.
if (on_status_line && on_sep_line) {
- if (stl_connected(wp))
+ if (stl_connected(wp)) {
on_sep_line = 0;
- else
+ } else {
on_status_line = 0;
+ }
}
// Before jumping to another buffer, or moving the cursor for a left
@@ -181,28 +185,32 @@ retnomove:
// Only change window focus when not clicking on or dragging the
// status line. Do change focus when releasing the mouse button
// (MOUSE_FOCUS was set above if we dragged first).
- if (dragwin == NULL || (flags & MOUSE_RELEASED))
+ if (dragwin == NULL || (flags & MOUSE_RELEASED)) {
win_enter(wp, true); // can make wp invalid!
+ }
// set topline, to be able to check for double click ourselves
- if (curwin != old_curwin)
+ if (curwin != old_curwin) {
set_mouse_topline(curwin);
+ }
if (on_status_line) { // In (or below) status line
// Don't use start_arrow() if we're in the same window
- if (curwin == old_curwin)
+ if (curwin == old_curwin) {
return IN_STATUS_LINE;
- else
+ } else {
return IN_STATUS_LINE | CURSOR_MOVED;
+ }
}
if (on_sep_line) { // In (or below) status line
// Don't use start_arrow() if we're in the same window
- if (curwin == old_curwin)
+ if (curwin == old_curwin) {
return IN_SEP_LINE;
- else
+ } else {
return IN_SEP_LINE | CURSOR_MOVED;
+ }
}
curwin->w_cursor.lnum = curwin->w_topline;
- } else if (on_status_line && which_button == MOUSE_LEFT) {
+ } else if (on_status_line && which_button == MOUSE_LEFT) {
if (dragwin != NULL) {
// Drag the status line
count = row - dragwin->w_winrow - dragwin->w_height + 1
@@ -211,7 +219,7 @@ retnomove:
did_drag |= count;
}
return IN_STATUS_LINE; // Cursor didn't move
- } else if (on_sep_line && which_button == MOUSE_LEFT) {
+ } else if (on_sep_line && which_button == MOUSE_LEFT) {
if (dragwin != NULL) {
// Drag the separator column
count = col - dragwin->w_wincol - dragwin->w_width + 1
@@ -228,12 +236,17 @@ retnomove:
redraw_curbuf_later(INVERTED); // delete the inversion
}
+ if (grid == 0) {
+ row -= curwin->w_grid_alloc.comp_row+curwin->w_grid.row_offset;
+ col -= curwin->w_grid_alloc.comp_col+curwin->w_grid.col_offset;
+ }
+
// When clicking beyond the end of the window, scroll the screen.
// Scroll by however many rows outside the window we are.
if (row < 0) {
count = 0;
for (first = true; curwin->w_topline > 1; ) {
- if (curwin->w_topfill < diff_check(curwin, curwin->w_topline)) {
+ if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)) {
count++;
} else {
count += plines_win(curwin, curwin->w_topline - 1, true);
@@ -243,8 +256,8 @@ retnomove:
}
first = false;
(void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
- if (curwin->w_topfill < diff_check(curwin, curwin->w_topline)) {
- ++curwin->w_topfill;
+ if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)) {
+ curwin->w_topfill++;
} else {
--curwin->w_topline;
curwin->w_topfill = 0;
@@ -255,7 +268,7 @@ retnomove:
~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
redraw_later(curwin, VALID);
row = 0;
- } else if (row >= curwin->w_height_inner) {
+ } else if (row >= curwin->w_height_inner) {
count = 0;
for (first = true; curwin->w_topline < curbuf->b_ml.ml_line_count; ) {
if (curwin->w_topfill > 0) {
@@ -275,11 +288,10 @@ retnomove:
}
if (curwin->w_topfill > 0) {
- --curwin->w_topfill;
+ curwin->w_topfill--;
} else {
- ++curwin->w_topline;
- curwin->w_topfill =
- diff_check_fill(curwin, curwin->w_topline);
+ curwin->w_topline++;
+ curwin->w_topfill = win_get_fill(curwin, curwin->w_topline);
}
}
check_topfill(curwin, false);
@@ -287,7 +299,7 @@ retnomove:
curwin->w_valid &=
~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
row = curwin->w_height_inner - 1;
- } else if (row == 0) {
+ } else if (row == 0) {
// When dragging the mouse, while the text has been scrolled up as
// far as it goes, moving the mouse in the top line should scroll
// the text down (done later when recomputing w_topline).
@@ -365,12 +377,12 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump)
while (row > 0) {
// Don't include filler lines in "count"
- if (win->w_p_diff
+ if (win_may_fill(win)
&& !hasFoldingWin(win, lnum, NULL, NULL, true, NULL)) {
if (lnum == win->w_topline) {
row -= win->w_topfill;
} else {
- row -= diff_check_fill(win, lnum);
+ row -= win_get_fill(win, lnum);
}
count = plines_win_nofill(win, lnum, true);
} else {
@@ -394,8 +406,9 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump)
if (!retval) {
// Compute the column without wrapping.
off = win_col_off(win) - win_col_off2(win);
- if (col < off)
+ if (col < off) {
col = off;
+ }
col += row * (win->w_width_inner - off);
// add skip column (for long wrapping line)
col += win->w_skipcol;
@@ -431,23 +444,26 @@ win_T *mouse_find_win(int *gridp, int *rowp, int *colp)
}
- frame_T *fp;
+ frame_T *fp;
fp = topframe;
*rowp -= firstwin->w_winrow;
for (;; ) {
- if (fp->fr_layout == FR_LEAF)
+ if (fp->fr_layout == FR_LEAF) {
break;
+ }
if (fp->fr_layout == FR_ROW) {
for (fp = fp->fr_child; fp->fr_next != NULL; fp = fp->fr_next) {
- if (*colp < fp->fr_width)
+ if (*colp < fp->fr_width) {
break;
+ }
*colp -= fp->fr_width;
}
} else { // fr_layout == FR_COL
for (fp = fp->fr_child; fp->fr_next != NULL; fp = fp->fr_next) {
- if (*rowp < fp->fr_height)
+ if (*rowp < fp->fr_height) {
break;
+ }
*rowp -= fp->fr_height;
}
}
@@ -465,7 +481,7 @@ win_T *mouse_find_win(int *gridp, int *rowp, int *colp)
static win_T *mouse_find_grid_win(int *gridp, int *rowp, int *colp)
{
if (*gridp == msg_grid.handle) {
- // rowp += msg_grid_pos; // PVS: dead store #11612
+ *rowp += msg_grid_pos;
*gridp = DEFAULT_GRID_HANDLE;
} else if (*gridp > 1) {
win_T *wp = get_win_by_grid_handle(*gridp);
@@ -574,21 +590,21 @@ static linenr_T find_longest_lnum(void)
bool mouse_scroll_horiz(int dir)
{
if (curwin->w_p_wrap) {
- return false;
+ return false;
}
int step = 6;
if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) {
- step = curwin->w_width_inner;
+ step = curwin->w_width_inner;
}
int leftcol = curwin->w_leftcol + (dir == MSCR_RIGHT ? -step : +step);
if (leftcol < 0) {
- leftcol = 0;
+ leftcol = 0;
}
if (curwin->w_leftcol == leftcol) {
- return false;
+ return false;
}
curwin->w_leftcol = (colnr_T)leftcol;
@@ -597,8 +613,8 @@ bool mouse_scroll_horiz(int dir)
// longest visible line.
if (!virtual_active()
&& (colnr_T)leftcol > scroll_line_len(curwin->w_cursor.lnum)) {
- curwin->w_cursor.lnum = find_longest_lnum();
- curwin->w_cursor.col = 0;
+ curwin->w_cursor.lnum = find_longest_lnum();
+ curwin->w_cursor.col = 0;
}
return leftcol_changed();
@@ -666,8 +682,8 @@ static int mouse_adjust_click(win_T *wp, int row, int col)
vcol = offset;
-#define incr() nudge++; ptr_end += utfc_ptr2len(ptr_end)
-#define decr() nudge--; ptr_end -= utfc_ptr2len(ptr_end)
+#define INCR() nudge++; ptr_end += utfc_ptr2len(ptr_end)
+#define DECR() nudge--; ptr_end -= utfc_ptr2len(ptr_end)
while (ptr < ptr_end && *ptr != NUL) {
cwidth = win_chartabsize(curwin, ptr, vcol);
@@ -676,7 +692,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col)
// A tab will "absorb" any previous adjustments.
cwidth = MIN(cwidth, nudge);
while (cwidth > 0) {
- decr();
+ DECR();
cwidth--;
}
}
@@ -684,20 +700,20 @@ static int mouse_adjust_click(win_T *wp, int row, int col)
matchid = syn_get_concealed_id(wp, lnum, (colnr_T)(ptr - line));
if (matchid != 0) {
if (wp->w_p_cole == 3) {
- incr();
+ INCR();
} else {
if (!(row > 0 && ptr == ptr_row_offset)
&& (wp->w_p_cole == 1 || (wp->w_p_cole == 2
&& (wp->w_p_lcs_chars.conceal != NUL
|| syn_get_sub_char() != NUL)))) {
// At least one placeholder character will be displayed.
- decr();
+ DECR();
}
prev_matchid = matchid;
while (prev_matchid == matchid && *ptr != NUL) {
- incr();
+ INCR();
ptr += utfc_ptr2len(ptr);
matchid = syn_get_concealed_id(wp, lnum, (colnr_T)(ptr - line));
}
diff --git a/src/nvim/mouse.h b/src/nvim/mouse.h
index 6c5bc5dc0e..bf4f9c57e5 100644
--- a/src/nvim/mouse.h
+++ b/src/nvim/mouse.h
@@ -3,8 +3,8 @@
#include <stdbool.h>
-#include "nvim/vim.h"
#include "nvim/buffer_defs.h"
+#include "nvim/vim.h"
// jump_to_mouse() returns one of first four these values, possibly with
// some of the other three added.
diff --git a/src/nvim/move.c b/src/nvim/move.c
index 9fc434923f..64ba02064f 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -18,7 +18,6 @@
#include "nvim/ascii.h"
#include "nvim/buffer.h"
-#include "nvim/move.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/diff.h"
@@ -27,17 +26,18 @@
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/misc1.h"
-#include "nvim/plines.h"
+#include "nvim/move.h"
#include "nvim/option.h"
+#include "nvim/plines.h"
#include "nvim/popupmnu.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/window.h"
typedef struct {
- linenr_T lnum; /* line number */
- int fill; /* filler lines */
- int height; /* height of added line */
+ linenr_T lnum; // line number
+ int fill; // filler lines
+ int height; // height of added line
} lineoff_T;
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -85,7 +85,7 @@ static void comp_botline(win_T *wp)
lnum = last;
}
- /* wp->w_botline is the line that is just below the window */
+ // wp->w_botline is the line that is just below the window
wp->w_botline = lnum;
wp->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
wp->w_viewport_invalid = true;
@@ -197,7 +197,7 @@ void update_topline(win_T *wp)
}
}
// Check if there are more filler lines than allowed.
- if (!check_topline && wp->w_topfill > diff_check_fill(wp, wp->w_topline)) {
+ if (!check_topline && wp->w_topfill > win_get_fill(wp, wp->w_topline)) {
check_topline = true;
}
@@ -274,8 +274,7 @@ void update_topline(win_T *wp)
n += wp->w_filler_rows;
loff.height = 0;
while (loff.lnum < wp->w_botline
- && (loff.lnum + 1 < wp->w_botline || loff.fill == 0)
- ) {
+ && (loff.lnum + 1 < wp->w_botline || loff.fill == 0)) {
n += loff.height;
if (n >= *so_ptr) {
break;
@@ -287,7 +286,7 @@ void update_topline(win_T *wp)
check_botline = false;
}
} else {
- /* sufficient context, no need to scroll */
+ // sufficient context, no need to scroll
check_botline = false;
}
}
@@ -325,8 +324,7 @@ void update_topline(win_T *wp)
* Need to redraw when topline changed.
*/
if (wp->w_topline != old_topline
- || wp->w_topfill != old_topfill
- ) {
+ || wp->w_topfill != old_topfill) {
dollar_vcol = -1;
if (wp->w_skipcol != 0) {
wp->w_skipcol = 0;
@@ -346,7 +344,7 @@ void update_topline(win_T *wp)
/*
* Update win->w_topline to move the cursor onto the screen.
*/
-void update_topline_win(win_T* win)
+void update_topline_win(win_T *win)
{
win_T *save_curwin;
switch_win(&save_curwin, NULL, win, NULL, true);
@@ -374,8 +372,7 @@ static bool check_top_offset(void)
{
long so = get_scrolloff_value(curwin);
if (curwin->w_cursor.lnum < curwin->w_topline + so
- || hasAnyFolding(curwin)
- ) {
+ || hasAnyFolding(curwin)) {
lineoff_T loff;
loff.lnum = curwin->w_cursor.lnum;
loff.fill = 0;
@@ -385,8 +382,8 @@ static bool check_top_offset(void)
topline_back(curwin, &loff);
// Stop when included a line above the window.
if (loff.lnum < curwin->w_topline
- || (loff.lnum == curwin->w_topline && loff.fill > 0)
- ) {
+ || (loff.lnum == curwin->w_topline &&
+ loff.fill > 0)) {
break;
}
n += loff.height;
@@ -420,8 +417,8 @@ void check_cursor_moved(win_T *wp)
wp->w_viewport_invalid = true;
} else if (wp->w_cursor.col != wp->w_valid_cursor.col
|| wp->w_leftcol != wp->w_valid_leftcol
- || wp->w_cursor.coladd != wp->w_valid_cursor.coladd
- ) {
+ || wp->w_cursor.coladd !=
+ wp->w_valid_cursor.coladd) {
wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL);
wp->w_valid_cursor.col = wp->w_cursor.col;
wp->w_valid_leftcol = wp->w_leftcol;
@@ -560,7 +557,7 @@ void validate_cursor(void)
*/
static void curs_rows(win_T *wp)
{
- /* Check if wp->w_lines[].wl_size is invalid */
+ // Check if wp->w_lines[].wl_size is invalid
int all_invalid = (!redrawing()
|| wp->w_lines_valid == 0
|| wp->w_lines[0].wl_lnum > wp->w_topline);
@@ -569,27 +566,28 @@ static void curs_rows(win_T *wp)
for (linenr_T lnum = wp->w_topline; lnum < wp->w_cursor.lnum; ++i) {
bool valid = false;
if (!all_invalid && i < wp->w_lines_valid) {
- if (wp->w_lines[i].wl_lnum < lnum || !wp->w_lines[i].wl_valid)
- continue; /* skip changed or deleted lines */
+ if (wp->w_lines[i].wl_lnum < lnum || !wp->w_lines[i].wl_valid) {
+ continue; // skip changed or deleted lines
+ }
if (wp->w_lines[i].wl_lnum == lnum) {
/* Check for newly inserted lines below this row, in which
* case we need to check for folded lines. */
if (!wp->w_buffer->b_mod_set
|| wp->w_lines[i].wl_lastlnum < wp->w_cursor.lnum
- || wp->w_buffer->b_mod_top
- > wp->w_lines[i].wl_lastlnum + 1)
+ || wp->w_buffer->b_mod_top
+ > wp->w_lines[i].wl_lastlnum + 1) {
valid = true;
+ }
} else if (wp->w_lines[i].wl_lnum > lnum) {
- --i; /* hold at inserted lines */
+ --i; // hold at inserted lines
}
}
- if (valid
- && (lnum != wp->w_topline || !wp->w_p_diff)
- ) {
+ if (valid && (lnum != wp->w_topline || !win_may_fill(wp))) {
lnum = wp->w_lines[i].wl_lastlnum + 1;
- /* Cursor inside folded lines, don't count this row */
- if (lnum > wp->w_cursor.lnum)
+ // Cursor inside folded lines, don't count this row
+ if (lnum > wp->w_cursor.lnum) {
break;
+ }
wp->w_cline_row += wp->w_lines[i].wl_size;
} else {
linenr_T last = lnum;
@@ -613,7 +611,7 @@ static void curs_rows(win_T *wp)
wp->w_cline_height = plines_win_full(wp, wp->w_cursor.lnum, NULL,
&wp->w_cline_folded, true);
} else if (i > wp->w_lines_valid) {
- /* a line that is too long to fit on the last screen line */
+ // a line that is too long to fit on the last screen line
wp->w_cline_height = 0;
wp->w_cline_folded = hasFoldingWin(wp, wp->w_cursor.lnum, NULL,
NULL, true, NULL);
@@ -645,9 +643,9 @@ void validate_virtcol_win(win_T *wp)
getvvcol(wp, &wp->w_cursor, NULL, &(wp->w_virtcol), NULL);
wp->w_valid |= VALID_VIRTCOL;
if (wp->w_p_cuc
- && !pum_visible()
- )
+ && !pum_visible()) {
redraw_later(wp, SOME_VALID);
+ }
}
}
@@ -718,8 +716,9 @@ int curwin_col_off(void)
*/
int win_col_off2(win_T *wp)
{
- if ((wp->w_p_nu || wp->w_p_rnu) && vim_strchr(p_cpo, CPO_NUMCOL) != NULL)
+ if ((wp->w_p_nu || wp->w_p_rnu) && vim_strchr(p_cpo, CPO_NUMCOL) != NULL) {
return number_width(wp) + 1;
+ }
return 0;
}
@@ -732,10 +731,7 @@ int curwin_col_off2(void)
// Also updates curwin->w_wrow and curwin->w_cline_row.
// Also updates curwin->w_leftcol.
// @param may_scroll when true, may scroll horizontally
-void curs_columns(
- win_T *wp,
- int may_scroll
-)
+void curs_columns(win_T *wp, int may_scroll)
{
int n;
int width = 0;
@@ -765,9 +761,10 @@ void curs_columns(
getvvcol(wp, &wp->w_cursor, &startcol, &(wp->w_virtcol), &endcol);
}
- /* remove '$' from change command when cursor moves onto it */
- if (startcol > dollar_vcol)
+ // remove '$' from change command when cursor moves onto it
+ if (startcol > dollar_vcol) {
dollar_vcol = -1;
+ }
int extra = win_col_off(wp);
wp->w_wcol = wp->w_virtcol + extra;
@@ -782,8 +779,7 @@ void curs_columns(
wp->w_wcol = wp->w_width_inner - 1;
wp->w_wrow = wp->w_height_inner - 1;
} else if (wp->w_p_wrap
- && wp->w_width_inner != 0
- ) {
+ && wp->w_width_inner != 0) {
width = textwidth + win_col_off2(wp);
// long line wrapping, adjust wp->w_wrow
@@ -798,13 +794,12 @@ void curs_columns(
// column
char_u *const sbr = get_showbreak_value(wp);
if (*sbr && *get_cursor_pos_ptr() == NUL
- && wp->w_wcol == (int)vim_strsize(sbr)) {
+ && wp->w_wcol == vim_strsize(sbr)) {
wp->w_wcol = 0;
}
}
} else if (may_scroll
- && !wp->w_cline_folded
- ) {
+ && !wp->w_cline_folded) {
// No line wrapping: compute wp->w_leftcol if scrolling is on and line
// is not folded.
// If scrolling is off, wp->w_leftcol is assumed to be 0
@@ -816,7 +811,7 @@ void curs_columns(
assert(siso <= INT_MAX);
int off_left = startcol - wp->w_leftcol - (int)siso;
int off_right =
- endcol - wp->w_leftcol - wp->w_width_inner + (int)siso + 1;
+ endcol - wp->w_leftcol - wp->w_width_inner + (int)siso + 1;
if (off_left < 0 || off_right > 0) {
int diff = (off_left < 0) ? -off_left: off_right;
@@ -836,8 +831,9 @@ void curs_columns(
new_leftcol = wp->w_leftcol + diff;
}
}
- if (new_leftcol < 0)
+ if (new_leftcol < 0) {
new_leftcol = 0;
+ }
if (new_leftcol != (int)wp->w_leftcol) {
wp->w_leftcol = new_leftcol;
win_check_anchored_floats(wp);
@@ -857,7 +853,7 @@ void curs_columns(
if (wp->w_cursor.lnum == wp->w_topline) {
wp->w_wrow += wp->w_topfill;
} else {
- wp->w_wrow += diff_check_fill(wp, wp->w_cursor.lnum);
+ wp->w_wrow += win_get_fill(wp, wp->w_cursor.lnum);
}
prev_skipcol = wp->w_skipcol;
@@ -867,13 +863,12 @@ void curs_columns(
|| ((prev_skipcol > 0
|| wp->w_wrow + so >= wp->w_height_inner)
&& (plines =
- plines_win_nofill(wp, wp->w_cursor.lnum, false)) - 1
+ plines_win_nofill(wp, wp->w_cursor.lnum, false)) - 1
>= wp->w_height_inner))
&& wp->w_height_inner != 0
&& wp->w_cursor.lnum == wp->w_topline
&& width > 0
- && wp->w_width_inner != 0
- ) {
+ && wp->w_width_inner != 0) {
/* Cursor past end of screen. Happens with a single line that does
* not fit on screen. Find a skipcol to show the text around the
* cursor. Avoid scrolling all the time. compute value of "extra":
@@ -972,8 +967,8 @@ void curs_columns(
/// @param[out] scolp start screen column
/// @param[out] ccolp cursor screen column
/// @param[out] ecolp end screen column
-void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp,
- int *ccolp, int *ecolp, bool local)
+void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp, int *ccolp, int *ecolp,
+ bool local)
{
colnr_T scol = 0, ccol = 0, ecol = 0;
int row = 0;
@@ -996,7 +991,7 @@ void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp,
if ((local && existing_row) || visible_row) {
colnr_T off;
colnr_T col;
- int width;
+ int width;
getvcol(wp, pos, &scol, &ccol, &ecol);
@@ -1041,39 +1036,42 @@ bool scrolldown(long line_count, int byfold)
{
int done = 0; // total # of physical lines done
- /* Make sure w_topline is at the first of a sequence of folded lines. */
+ // Make sure w_topline is at the first of a sequence of folded lines.
(void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
- validate_cursor(); /* w_wrow needs to be valid */
+ validate_cursor(); // w_wrow needs to be valid
while (line_count-- > 0) {
- if (curwin->w_topfill < diff_check(curwin, curwin->w_topline)
+ if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)
&& curwin->w_topfill < curwin->w_height_inner - 1) {
curwin->w_topfill++;
done++;
} else {
- if (curwin->w_topline == 1)
+ if (curwin->w_topline == 1) {
break;
+ }
--curwin->w_topline;
curwin->w_topfill = 0;
- /* A sequence of folded lines only counts for one logical line */
+ // A sequence of folded lines only counts for one logical line
linenr_T first;
if (hasFolding(curwin->w_topline, &first, NULL)) {
++done;
- if (!byfold)
+ if (!byfold) {
line_count -= curwin->w_topline - first - 1;
+ }
curwin->w_botline -= curwin->w_topline - first;
curwin->w_topline = first;
} else {
done += plines_win_nofill(curwin, curwin->w_topline, true);
}
}
- --curwin->w_botline; /* approximate w_botline */
+ --curwin->w_botline; // approximate w_botline
invalidate_botline();
}
- curwin->w_wrow += done; /* keep w_wrow updated */
- curwin->w_cline_row += done; /* keep w_cline_row updated */
+ curwin->w_wrow += done; // keep w_wrow updated
+ curwin->w_cline_row += done; // keep w_cline_row updated
- if (curwin->w_cursor.lnum == curwin->w_topline)
+ if (curwin->w_cursor.lnum == curwin->w_topline) {
curwin->w_cline_row = 0;
+ }
check_topfill(curwin, true);
/*
@@ -1082,8 +1080,7 @@ bool scrolldown(long line_count, int byfold)
*/
int wrow = curwin->w_wrow;
if (curwin->w_p_wrap
- && curwin->w_width_inner != 0
- ) {
+ && curwin->w_width_inner != 0) {
validate_virtcol();
validate_cheight();
wrow += curwin->w_cline_height - 1 -
@@ -1094,10 +1091,11 @@ bool scrolldown(long line_count, int byfold)
linenr_T first;
if (hasFolding(curwin->w_cursor.lnum, &first, NULL)) {
--wrow;
- if (first == 1)
+ if (first == 1) {
curwin->w_cursor.lnum = 1;
- else
+ } else {
curwin->w_cursor.lnum = first - 1;
+ }
} else {
wrow -= plines_win(curwin, curwin->w_cursor.lnum--, true);
}
@@ -1106,7 +1104,7 @@ bool scrolldown(long line_count, int byfold)
moved = true;
}
if (moved) {
- /* Move cursor to first line of closed fold. */
+ // Move cursor to first line of closed fold.
foldAdjustCursor();
coladvance(curwin->w_curswant);
}
@@ -1123,39 +1121,44 @@ bool scrollup(long line_count, int byfold)
linenr_T botline = curwin->w_botline;
if ((byfold && hasAnyFolding(curwin))
- || curwin->w_p_diff) {
+ || win_may_fill(curwin)) {
// count each sequence of folded lines as one logical line
linenr_T lnum = curwin->w_topline;
while (line_count--) {
- if (curwin->w_topfill > 0)
+ if (curwin->w_topfill > 0) {
--curwin->w_topfill;
- else {
- if (byfold)
+ } else {
+ if (byfold) {
(void)hasFolding(lnum, NULL, &lnum);
- if (lnum >= curbuf->b_ml.ml_line_count)
+ }
+ if (lnum >= curbuf->b_ml.ml_line_count) {
break;
- ++lnum;
- curwin->w_topfill = diff_check_fill(curwin, lnum);
+ }
+ lnum++;
+ curwin->w_topfill = win_get_fill(curwin, lnum);
}
}
- /* approximate w_botline */
+ // approximate w_botline
curwin->w_botline += lnum - curwin->w_topline;
curwin->w_topline = lnum;
} else {
curwin->w_topline += line_count;
- curwin->w_botline += line_count; /* approximate w_botline */
+ curwin->w_botline += line_count; // approximate w_botline
}
- if (curwin->w_topline > curbuf->b_ml.ml_line_count)
+ if (curwin->w_topline > curbuf->b_ml.ml_line_count) {
curwin->w_topline = curbuf->b_ml.ml_line_count;
- if (curwin->w_botline > curbuf->b_ml.ml_line_count + 1)
+ }
+ if (curwin->w_botline > curbuf->b_ml.ml_line_count + 1) {
curwin->w_botline = curbuf->b_ml.ml_line_count + 1;
+ }
check_topfill(curwin, false);
- if (hasAnyFolding(curwin))
- /* Make sure w_topline is at the first of a sequence of folded lines. */
+ if (hasAnyFolding(curwin)) {
+ // Make sure w_topline is at the first of a sequence of folded lines.
(void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
+ }
curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE);
if (curwin->w_cursor.lnum < curwin->w_topline) {
@@ -1166,19 +1169,15 @@ bool scrollup(long line_count, int byfold)
}
bool moved = topline != curwin->w_topline
- || botline != curwin->w_botline;
+ || botline != curwin->w_botline;
return moved;
}
-/*
- * Don't end up with too many filler lines in the window.
- */
-void
-check_topfill (
- win_T *wp,
- bool down /* when true scroll down when not enough space */
-)
+/// Don't end up with too many filler lines in the window.
+///
+/// @param down when true scroll down when not enough space
+void check_topfill(win_T *wp, bool down)
{
if (wp->w_topfill > 0) {
int n = plines_win_nofill(wp, wp->w_topline, true);
@@ -1207,7 +1206,7 @@ static void max_topfill(void)
if (n >= curwin->w_height_inner) {
curwin->w_topfill = 0;
} else {
- curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline);
+ curwin->w_topfill = win_get_fill(curwin, curwin->w_topline);
if (curwin->w_topfill + n > curwin->w_height_inner) {
curwin->w_topfill = curwin->w_height_inner - n;
}
@@ -1220,15 +1219,14 @@ static void max_topfill(void)
*/
void scrolldown_clamp(void)
{
- int can_fill = (curwin->w_topfill
- < diff_check_fill(curwin, curwin->w_topline));
+ int can_fill = (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline));
if (curwin->w_topline <= 1
- && !can_fill
- )
+ && !can_fill) {
return;
+ }
- validate_cursor(); /* w_wrow needs to be valid */
+ validate_cursor(); // w_wrow needs to be valid
// Compute the row number of the last row of the cursor line
// and make sure it doesn't go off the screen. Make sure the cursor
@@ -1254,7 +1252,7 @@ void scrolldown_clamp(void)
curwin->w_topfill = 0;
}
(void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
- --curwin->w_botline; /* approximate w_botline */
+ --curwin->w_botline; // approximate w_botline
curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE);
}
}
@@ -1266,11 +1264,11 @@ void scrolldown_clamp(void)
void scrollup_clamp(void)
{
if (curwin->w_topline == curbuf->b_ml.ml_line_count
- && curwin->w_topfill == 0
- )
+ && curwin->w_topfill == 0) {
return;
+ }
- validate_cursor(); /* w_wrow needs to be valid */
+ validate_cursor(); // w_wrow needs to be valid
// Compute the row number of the first row of the cursor line
// and make sure it doesn't go off the screen. Make sure the cursor
@@ -1302,7 +1300,7 @@ void scrollup_clamp(void)
*/
static void topline_back(win_T *wp, lineoff_T *lp)
{
- if (lp->fill < diff_check_fill(wp, lp->lnum)) {
+ if (lp->fill < win_get_fill(wp, lp->lnum)) {
// Add a filler line
lp->fill++;
lp->height = 1;
@@ -1328,7 +1326,7 @@ static void topline_back(win_T *wp, lineoff_T *lp)
*/
static void botline_forw(win_T *wp, lineoff_T *lp)
{
- if (lp->fill < diff_check_fill(wp, lp->lnum + 1)) {
+ if (lp->fill < win_get_fill(wp, lp->lnum + 1)) {
// Add a filler line.
lp->fill++;
lp->height = 1;
@@ -1355,8 +1353,8 @@ static void botline_forw(win_T *wp, lineoff_T *lp)
static void botline_topline(lineoff_T *lp)
{
if (lp->fill > 0) {
- ++lp->lnum;
- lp->fill = diff_check_fill(curwin, lp->lnum) - lp->fill + 1;
+ lp->lnum++;
+ lp->fill = win_get_fill(curwin, lp->lnum) - lp->fill + 1;
}
}
@@ -1368,8 +1366,8 @@ static void botline_topline(lineoff_T *lp)
static void topline_botline(lineoff_T *lp)
{
if (lp->fill > 0) {
- lp->fill = diff_check_fill(curwin, lp->lnum) - lp->fill + 1;
- --lp->lnum;
+ lp->fill = win_get_fill(curwin, lp->lnum) - lp->fill + 1;
+ lp->lnum--;
}
}
@@ -1381,15 +1379,16 @@ static void topline_botline(lineoff_T *lp)
void scroll_cursor_top(int min_scroll, int always)
{
int scrolled = 0;
- linenr_T top; /* just above displayed lines */
- linenr_T bot; /* just below displayed lines */
+ linenr_T top; // just above displayed lines
+ linenr_T bot; // just below displayed lines
linenr_T old_topline = curwin->w_topline;
linenr_T old_topfill = curwin->w_topfill;
linenr_T new_topline;
int off = (int)get_scrolloff_value(curwin);
- if (mouse_dragging > 0)
+ if (mouse_dragging > 0) {
off = mouse_dragging - 1;
+ }
/*
* Decrease topline until:
@@ -1416,7 +1415,7 @@ void scroll_cursor_top(int min_scroll, int always)
// "used" already contains the number of filler lines above, don't add it
// again.
// Hide filler lines above cursor line by adding them to "extra".
- int extra = diff_check_fill(curwin, curwin->w_cursor.lnum);
+ int extra = win_get_fill(curwin, curwin->w_cursor.lnum);
/*
* Check if the lines from "top" to "bot" fit in the window. If they do,
@@ -1446,8 +1445,9 @@ void scroll_cursor_top(int min_scroll, int always)
* If scrolling is needed, scroll at least 'sj' lines.
*/
if ((new_topline >= curwin->w_topline || scrolled > min_scroll)
- && extra >= off)
+ && extra >= off) {
break;
+ }
extra += i;
new_topline = top;
@@ -1467,22 +1467,25 @@ void scroll_cursor_top(int min_scroll, int always)
* If "always" is false, only adjust topline to a lower value, higher
* value may happen with wrapping lines
*/
- if (new_topline < curwin->w_topline || always)
+ if (new_topline < curwin->w_topline || always) {
curwin->w_topline = new_topline;
- if (curwin->w_topline > curwin->w_cursor.lnum)
+ }
+ if (curwin->w_topline > curwin->w_cursor.lnum) {
curwin->w_topline = curwin->w_cursor.lnum;
- curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline);
+ }
+ curwin->w_topfill = win_get_fill(curwin, curwin->w_topline);
if (curwin->w_topfill > 0 && extra > off) {
curwin->w_topfill -= extra - off;
- if (curwin->w_topfill < 0)
+ if (curwin->w_topfill < 0) {
curwin->w_topfill = 0;
+ }
}
check_topfill(curwin, false);
if (curwin->w_topline != old_topline
- || curwin->w_topfill != old_topfill
- )
+ || curwin->w_topfill != old_topfill) {
curwin->w_valid &=
~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
+ }
curwin->w_valid |= VALID_TOPLINE;
curwin->w_viewport_invalid = true;
}
@@ -1500,10 +1503,10 @@ void set_empty_rows(win_T *wp, int used)
} else {
wp->w_empty_rows = wp->w_height_inner - used;
if (wp->w_botline <= wp->w_buffer->b_ml.ml_line_count) {
- wp->w_filler_rows = diff_check_fill(wp, wp->w_botline);
- if (wp->w_empty_rows > wp->w_filler_rows)
+ wp->w_filler_rows = win_get_fill(wp, wp->w_botline);
+ if (wp->w_empty_rows > wp->w_filler_rows) {
wp->w_empty_rows -= wp->w_filler_rows;
- else {
+ } else {
wp->w_filler_rows = wp->w_empty_rows;
wp->w_empty_rows = 0;
}
@@ -1526,10 +1529,10 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
lineoff_T boff;
int fill_below_window;
linenr_T old_topline = curwin->w_topline;
- int old_topfill = curwin->w_topfill;
+ int old_topfill = curwin->w_topfill;
linenr_T old_botline = curwin->w_botline;
- int old_valid = curwin->w_valid;
- int old_empty_rows = curwin->w_empty_rows;
+ int old_valid = curwin->w_valid;
+ int old_empty_rows = curwin->w_empty_rows;
linenr_T cln = curwin->w_cursor.lnum; // Cursor Line Number
long so = get_scrolloff_value(curwin);
@@ -1552,9 +1555,9 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
set_empty_rows(curwin, used);
curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
if (curwin->w_topline != old_topline
- || curwin->w_topfill != old_topfill
- )
+ || curwin->w_topfill != old_topfill) {
curwin->w_valid &= ~(VALID_WROW|VALID_CROW);
+ }
} else {
validate_botline(curwin);
}
@@ -1567,8 +1570,9 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
// botline.
if (cln >= curwin->w_botline) {
scrolled = used;
- if (cln == curwin->w_botline)
+ if (cln == curwin->w_botline) {
scrolled -= curwin->w_empty_rows;
+ }
}
/*
@@ -1584,7 +1588,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
}
loff.fill = 0;
boff.fill = 0;
- fill_below_window = diff_check_fill(curwin, curwin->w_botline)
+ fill_below_window = win_get_fill(curwin, curwin->w_botline)
- curwin->w_filler_rows;
while (loff.lnum > 1) {
@@ -1595,8 +1599,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
|| boff.lnum + 1 > curbuf->b_ml.ml_line_count)
&& loff.lnum <= curwin->w_botline
&& (loff.lnum < curwin->w_botline
- || loff.fill >= fill_below_window)
- ) {
+ || loff.fill >= fill_below_window)) {
break;
}
@@ -1612,9 +1615,8 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
}
if (loff.lnum >= curwin->w_botline
&& (loff.lnum > curwin->w_botline
- || loff.fill <= fill_below_window)
- ) {
- /* Count screen lines that are below the window. */
+ || loff.fill <= fill_below_window)) {
+ // Count screen lines that are below the window.
scrolled += loff.height;
if (loff.lnum == curwin->w_botline
&& loff.fill == 0) {
@@ -1634,14 +1636,13 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
extra += boff.height;
if (boff.lnum >= curwin->w_botline
|| (boff.lnum + 1 == curwin->w_botline
- && boff.fill > curwin->w_filler_rows)
- ) {
- /* Count screen lines that are below the window. */
+ && boff.fill > curwin->w_filler_rows)) {
+ // Count screen lines that are below the window.
scrolled += boff.height;
if (boff.lnum == curwin->w_botline
- && boff.fill == 0
- )
+ && boff.fill == 0) {
scrolled -= curwin->w_empty_rows;
+ }
}
}
}
@@ -1651,10 +1652,10 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
// curwin->w_empty_rows is larger, no need to scroll
if (scrolled <= 0) {
line_count = 0;
- // more than a screenfull, don't scroll but redraw
+ // more than a screenfull, don't scroll but redraw
} else if (used > curwin->w_height_inner) {
line_count = used;
- // scroll minimal number of lines
+ // scroll minimal number of lines
} else {
line_count = 0;
boff.fill = curwin->w_topfill;
@@ -1665,8 +1666,9 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
i += boff.height;
++line_count;
}
- if (i < scrolled) /* below curwin->w_botline, don't scroll */
+ if (i < scrolled) { // below curwin->w_botline, don't scroll
line_count = 9999;
+ }
}
/*
@@ -1713,7 +1715,7 @@ void scroll_cursor_halfway(int atend)
boff.fill = 0;
linenr_T topline = loff.lnum;
while (topline > 1) {
- if (below <= above) { /* add a line below the cursor first */
+ if (below <= above) { // add a line below the cursor first
if (boff.lnum < curbuf->b_ml.ml_line_count) {
botline_forw(curwin, &boff);
used += boff.height;
@@ -1722,9 +1724,10 @@ void scroll_cursor_halfway(int atend)
}
below += boff.height;
} else {
- ++below; /* count a "~" line */
- if (atend)
+ ++below; // count a "~" line
+ if (atend) {
++used;
+ }
}
}
@@ -1743,8 +1746,9 @@ void scroll_cursor_halfway(int atend)
topfill = loff.fill;
}
}
- if (!hasFolding(topline, &curwin->w_topline, NULL))
+ if (!hasFolding(topline, &curwin->w_topline, NULL)) {
curwin->w_topline = topline;
+ }
curwin->w_topfill = topfill;
if (old_topline > curwin->w_topline + curwin->w_height_inner) {
curwin->w_botfill = false;
@@ -1793,12 +1797,12 @@ void cursor_correct(void)
* If there are sufficient file-lines above and below the cursor, we can
* return now.
*/
- linenr_T cln = curwin->w_cursor.lnum; /* Cursor Line Number */
+ linenr_T cln = curwin->w_cursor.lnum; // Cursor Line Number
if (cln >= curwin->w_topline + above_wanted
&& cln < curwin->w_botline - below_wanted
- && !hasAnyFolding(curwin)
- )
+ && !hasAnyFolding(curwin)) {
return;
+ }
/*
* Narrow down the area where the cursor can be put by taking lines from
@@ -1808,9 +1812,9 @@ void cursor_correct(void)
*/
linenr_T topline = curwin->w_topline;
linenr_T botline = curwin->w_botline - 1;
- /* count filler lines as context */
- int above = curwin->w_topfill; /* screen lines above topline */
- int below = curwin->w_filler_rows; /* screen lines below botline */
+ // count filler lines as context
+ int above = curwin->w_topfill; // screen lines above topline
+ int below = curwin->w_filler_rows; // screen lines below botline
while ((above < above_wanted || below < below_wanted) && topline < botline) {
if (below < below_wanted && (below <= above || above >= above_wanted)) {
if (hasFolding(botline, &botline, NULL)) {
@@ -1827,17 +1831,18 @@ void cursor_correct(void)
above += plines_win_nofill(curwin, topline, true);
}
- /* Count filler lines below this line as context. */
- if (topline < botline)
- above += diff_check_fill(curwin, topline + 1);
+ // Count filler lines below this line as context.
+ if (topline < botline) {
+ above += win_get_fill(curwin, topline + 1);
+ }
++topline;
}
}
- if (topline == botline || botline == 0)
+ if (topline == botline || botline == 0) {
curwin->w_cursor.lnum = topline;
- else if (topline > botline)
+ } else if (topline > botline) {
curwin->w_cursor.lnum = botline;
- else {
+ } else {
if (cln < topline && curwin->w_topline > 1) {
curwin->w_cursor.lnum = topline;
curwin->w_valid &=
@@ -1867,7 +1872,7 @@ int onepage(Direction dir, long count)
linenr_T old_topline = curwin->w_topline;
long so = get_scrolloff_value(curwin);
- if (curbuf->b_ml.ml_line_count == 1) { /* nothing to do */
+ if (curbuf->b_ml.ml_line_count == 1) { // nothing to do
beep_flush();
return FAIL;
}
@@ -1882,9 +1887,7 @@ int onepage(Direction dir, long count)
? ((curwin->w_topline >= curbuf->b_ml.ml_line_count - so)
&& curwin->w_botline > curbuf->b_ml.ml_line_count)
: (curwin->w_topline == 1
- && curwin->w_topfill ==
- diff_check_fill(curwin, curwin->w_topline)
- )) {
+ && curwin->w_topfill == win_get_fill(curwin, curwin->w_topline))) {
beep_flush();
retval = FAIL;
break;
@@ -1893,16 +1896,18 @@ int onepage(Direction dir, long count)
loff.fill = 0;
if (dir == FORWARD) {
if (ONE_WINDOW && p_window > 0 && p_window < Rows - 1) {
- /* Vi compatible scrolling */
- if (p_window <= 2)
+ // Vi compatible scrolling
+ if (p_window <= 2) {
++curwin->w_topline;
- else
+ } else {
curwin->w_topline += p_window - 2;
- if (curwin->w_topline > curbuf->b_ml.ml_line_count)
+ }
+ if (curwin->w_topline > curbuf->b_ml.ml_line_count) {
curwin->w_topline = curbuf->b_ml.ml_line_count;
+ }
curwin->w_cursor.lnum = curwin->w_topline;
} else if (curwin->w_botline > curbuf->b_ml.ml_line_count) {
- /* at end of file */
+ // at end of file
curwin->w_topline = curbuf->b_ml.ml_line_count;
curwin->w_topfill = 0;
curwin->w_valid &= ~(VALID_WROW|VALID_CROW);
@@ -1910,7 +1915,7 @@ int onepage(Direction dir, long count)
/* For the overlap, start with the line just below the window
* and go upwards. */
loff.lnum = curwin->w_botline;
- loff.fill = diff_check_fill(curwin, loff.lnum)
+ loff.fill = win_get_fill(curwin, loff.lnum)
- curwin->w_filler_rows;
get_scroll_overlap(&loff, -1);
curwin->w_topline = loff.lnum;
@@ -1920,23 +1925,26 @@ int onepage(Direction dir, long count)
curwin->w_valid &= ~(VALID_WCOL|VALID_CHEIGHT|VALID_WROW|
VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
}
- } else { /* dir == BACKWARDS */
+ } else { // dir == BACKWARDS
if (curwin->w_topline == 1) {
- /* Include max number of filler lines */
+ // Include max number of filler lines
max_topfill();
continue;
}
if (ONE_WINDOW && p_window > 0 && p_window < Rows - 1) {
- /* Vi compatible scrolling (sort of) */
- if (p_window <= 2)
+ // Vi compatible scrolling (sort of)
+ if (p_window <= 2) {
--curwin->w_topline;
- else
+ } else {
curwin->w_topline -= p_window - 2;
- if (curwin->w_topline < 1)
+ }
+ if (curwin->w_topline < 1) {
curwin->w_topline = 1;
+ }
curwin->w_cursor.lnum = curwin->w_topline + p_window - 1;
- if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+ if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) {
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ }
continue;
}
@@ -1944,8 +1952,7 @@ int onepage(Direction dir, long count)
* line at the bottom of the window. Make sure this results in
* the same line as before doing CTRL-F. */
loff.lnum = curwin->w_topline - 1;
- loff.fill = diff_check_fill(curwin, loff.lnum + 1)
- - curwin->w_topfill;
+ loff.fill = win_get_fill(curwin, loff.lnum + 1) - curwin->w_topfill;
get_scroll_overlap(&loff, 1);
if (loff.lnum >= curbuf->b_ml.ml_line_count) {
@@ -1967,12 +1974,12 @@ int onepage(Direction dir, long count)
n += loff.height;
}
}
- if (loff.lnum < 1) { /* at begin of file */
+ if (loff.lnum < 1) { // at begin of file
curwin->w_topline = 1;
max_topfill();
curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE);
} else {
- /* Go two lines forward again. */
+ // Go two lines forward again.
topline_botline(&loff);
botline_forw(curwin, &loff);
botline_forw(curwin, &loff);
@@ -1984,14 +1991,13 @@ int onepage(Direction dir, long count)
* very long lines. */
if (loff.lnum >= curwin->w_topline
&& (loff.lnum > curwin->w_topline
- || loff.fill >= curwin->w_topfill)
- ) {
+ || loff.fill >= curwin->w_topfill)) {
/* First try using the maximum number of filler lines. If
* that's not enough, backup one line. */
loff.fill = curwin->w_topfill;
- if (curwin->w_topfill < diff_check_fill(curwin,
- curwin->w_topline))
+ if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)) {
max_topfill();
+ }
if (curwin->w_topfill == loff.fill) {
--curwin->w_topline;
curwin->w_topfill = 0;
@@ -2042,12 +2048,12 @@ int onepage(Direction dir, long count)
* This is symmetric, so that doing both keeps the same lines displayed.
* Three lines are examined:
*
- * before CTRL-F after CTRL-F / before CTRL-B
- * etc. l1
- * l1 last but one line ------------
- * l2 last text line l2 top text line
- * ------------- l3 second text line
- * l3 etc.
+ * before CTRL-F after CTRL-F / before CTRL-B
+ * etc. l1
+ * l1 last but one line ------------
+ * l2 last text line l2 top text line
+ * ------------- l3 second text line
+ * l3 etc.
*/
static void get_scroll_overlap(lineoff_T *lp, int dir)
{
@@ -2059,9 +2065,9 @@ static void get_scroll_overlap(lineoff_T *lp, int dir)
lp->height = plines_win_nofill(curwin, lp->lnum, true);
}
int h1 = lp->height;
- if (h1 > min_height)
- return; /* no overlap */
-
+ if (h1 > min_height) {
+ return; // no overlap
+ }
lineoff_T loff0 = *lp;
if (dir > 0) {
botline_forw(curwin, lp);
@@ -2070,7 +2076,7 @@ static void get_scroll_overlap(lineoff_T *lp, int dir)
}
int h2 = lp->height;
if (h2 == MAXCOL || h2 + h1 > min_height) {
- *lp = loff0; /* no overlap */
+ *lp = loff0; // no overlap
return;
}
@@ -2082,7 +2088,7 @@ static void get_scroll_overlap(lineoff_T *lp, int dir)
}
int h3 = lp->height;
if (h3 == MAXCOL || h3 + h2 > min_height) {
- *lp = loff0; /* no overlap */
+ *lp = loff0; // no overlap
return;
}
@@ -2093,11 +2099,11 @@ static void get_scroll_overlap(lineoff_T *lp, int dir)
topline_back(curwin, lp);
}
int h4 = lp->height;
- if (h4 == MAXCOL || h4 + h3 + h2 > min_height || h3 + h2 + h1 > min_height)
- *lp = loff1; /* 1 line overlap */
- else
- *lp = loff2; /* 2 lines overlap */
- return;
+ if (h4 == MAXCOL || h4 + h3 + h2 > min_height || h3 + h2 + h1 > min_height) {
+ *lp = loff1; // 1 line overlap
+ } else {
+ *lp = loff2; // 2 lines overlap
+ }
}
// Scroll 'scroll' lines up or down.
@@ -2108,11 +2114,11 @@ void halfpage(bool flag, linenr_T Prenum)
if (Prenum) {
curwin->w_p_scr = (Prenum > curwin->w_height_inner) ? curwin->w_height_inner
- : Prenum;
+ : Prenum;
}
assert(curwin->w_p_scr <= INT_MAX);
int n = curwin->w_p_scr <= curwin->w_height_inner ? (int)curwin->w_p_scr
- : curwin->w_height_inner;
+ : curwin->w_height_inner;
update_topline(curwin);
validate_botline(curwin);
@@ -2129,11 +2135,12 @@ void halfpage(bool flag, linenr_T Prenum)
} else {
i = plines_win_nofill(curwin, curwin->w_topline, true);
n -= i;
- if (n < 0 && scrolled > 0)
+ if (n < 0 && scrolled > 0) {
break;
+ }
(void)hasFolding(curwin->w_topline, NULL, &curwin->w_topline);
- ++curwin->w_topline;
- curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline);
+ curwin->w_topline++;
+ curwin->w_topfill = win_get_fill(curwin, curwin->w_topline);
if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
++curwin->w_cursor.lnum;
@@ -2144,13 +2151,11 @@ void halfpage(bool flag, linenr_T Prenum)
curwin->w_valid &= ~(VALID_CROW|VALID_WROW);
scrolled += i;
- /*
- * Correct w_botline for changed w_topline.
- * Won't work when there are filler lines.
- */
- if (curwin->w_p_diff)
+ // Correct w_botline for changed w_topline.
+ // Won't work when there are filler lines.
+ if (win_may_fill(curwin)) {
curwin->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP);
- else {
+ } else {
room += i;
do {
i = plines_win(curwin, curwin->w_botline, true);
@@ -2170,11 +2175,12 @@ void halfpage(bool flag, linenr_T Prenum)
while (--n >= 0
&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
(void)hasFolding(curwin->w_cursor.lnum, NULL,
- &curwin->w_cursor.lnum);
+ &curwin->w_cursor.lnum);
++curwin->w_cursor.lnum;
}
- } else
+ } else {
curwin->w_cursor.lnum += n;
+ }
check_cursor_lnum();
}
} else {
@@ -2182,15 +2188,16 @@ void halfpage(bool flag, linenr_T Prenum)
* scroll the text down
*/
while (n > 0 && curwin->w_topline > 1) {
- if (curwin->w_topfill < diff_check_fill(curwin, curwin->w_topline)) {
+ if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)) {
i = 1;
n--;
curwin->w_topfill++;
} else {
i = plines_win_nofill(curwin, curwin->w_topline - 1, true);
n -= i;
- if (n < 0 && scrolled > 0)
+ if (n < 0 && scrolled > 0) {
break;
+ }
--curwin->w_topline;
(void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
curwin->w_topfill = 0;
@@ -2206,19 +2213,20 @@ void halfpage(bool flag, linenr_T Prenum)
// When hit top of the file: move cursor up.
if (n > 0) {
- if (curwin->w_cursor.lnum <= (linenr_T)n)
+ if (curwin->w_cursor.lnum <= (linenr_T)n) {
curwin->w_cursor.lnum = 1;
- else if (hasAnyFolding(curwin)) {
+ } else if (hasAnyFolding(curwin)) {
while (--n >= 0 && curwin->w_cursor.lnum > 1) {
--curwin->w_cursor.lnum;
(void)hasFolding(curwin->w_cursor.lnum,
- &curwin->w_cursor.lnum, NULL);
+ &curwin->w_cursor.lnum, NULL);
}
- } else
+ } else {
curwin->w_cursor.lnum -= n;
+ }
}
}
- /* Move cursor to first line of closed fold. */
+ // Move cursor to first line of closed fold.
foldAdjustCursor();
check_topfill(curwin, !flag);
cursor_correct();
@@ -2245,7 +2253,7 @@ void do_check_cursorbind(void)
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
curwin = wp;
curbuf = curwin->w_buffer;
- /* skip original window and windows with 'noscrollbind' */
+ // skip original window and windows with 'noscrollbind'
if (curwin != old_curwin && curwin->w_p_crb) {
if (curwin->w_p_diff) {
curwin->w_cursor.lnum =
diff --git a/src/nvim/move.h b/src/nvim/move.h
index 3670dc9086..dd944e39ee 100644
--- a/src/nvim/move.h
+++ b/src/nvim/move.h
@@ -2,6 +2,7 @@
#define NVIM_MOVE_H
#include <stdbool.h>
+
#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
index 813f21407c..a1a1f0f8c0 100644
--- a/src/nvim/msgpack_rpc/channel.c
+++ b/src/nvim/msgpack_rpc/channel.c
@@ -33,8 +33,8 @@
#include "nvim/vim.h"
#if MIN_LOG_LEVEL > DEBUG_LOG_LEVEL
-#define log_client_msg(...)
-#define log_server_msg(...)
+# define log_client_msg(...)
+# define log_server_msg(...)
#endif
static PMap(cstr_t) event_strings = MAP_INIT;
@@ -699,14 +699,14 @@ const char *rpc_client_name(Channel *chan)
}
#if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL
-#define REQ "[request] "
-#define RES "[response] "
-#define NOT "[notify] "
-#define ERR "[error] "
+# define REQ "[request] "
+# define RES "[response] "
+# define NOT "[notify] "
+# define ERR "[error] "
// Cannot define array with negative offsets, so this one is needed to be added
// to MSGPACK_UNPACK_\* values.
-#define MUR_OFF 2
+# define MUR_OFF 2
static const char *const msgpack_error_messages[] = {
[MSGPACK_UNPACK_EXTRA_BYTES + MUR_OFF] = "extra bytes found",
diff --git a/src/nvim/msgpack_rpc/channel.h b/src/nvim/msgpack_rpc/channel.h
index 90e1c7d48b..eb0de47437 100644
--- a/src/nvim/msgpack_rpc/channel.h
+++ b/src/nvim/msgpack_rpc/channel.h
@@ -5,10 +5,10 @@
#include <uv.h>
#include "nvim/api/private/defs.h"
-#include "nvim/event/socket.h"
+#include "nvim/channel.h"
#include "nvim/event/process.h"
+#include "nvim/event/socket.h"
#include "nvim/vim.h"
-#include "nvim/channel.h"
#define METHOD_MAXLEN 512
diff --git a/src/nvim/msgpack_rpc/channel_defs.h b/src/nvim/msgpack_rpc/channel_defs.h
index de328af1ce..6647779db9 100644
--- a/src/nvim/msgpack_rpc/channel_defs.h
+++ b/src/nvim/msgpack_rpc/channel_defs.h
@@ -1,13 +1,13 @@
#ifndef NVIM_MSGPACK_RPC_CHANNEL_DEFS_H
#define NVIM_MSGPACK_RPC_CHANNEL_DEFS_H
+#include <msgpack.h>
#include <stdbool.h>
#include <uv.h>
-#include <msgpack.h>
#include "nvim/api/private/defs.h"
-#include "nvim/event/socket.h"
#include "nvim/event/process.h"
+#include "nvim/event/socket.h"
#include "nvim/vim.h"
typedef struct Channel Channel;
diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c
index 0bc58fffba..f805858904 100644
--- a/src/nvim/msgpack_rpc/helpers.c
+++ b/src/nvim/msgpack_rpc/helpers.c
@@ -15,50 +15,13 @@
#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "keysets.generated.h"
# include "msgpack_rpc/helpers.c.generated.h"
#endif
static msgpack_zone zone;
static msgpack_sbuffer sbuffer;
-#define HANDLE_TYPE_CONVERSION_IMPL(t, lt) \
- static bool msgpack_rpc_to_##lt(const msgpack_object *const obj, \
- Integer *const arg) \
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT \
- { \
- if (obj->type != MSGPACK_OBJECT_EXT \
- || obj->via.ext.type + EXT_OBJECT_TYPE_SHIFT != kObjectType##t) { \
- return false; \
- } \
- \
- msgpack_object data; \
- msgpack_unpack_return ret = msgpack_unpack(obj->via.ext.ptr, \
- obj->via.ext.size, \
- NULL, \
- &zone, \
- &data); \
- \
- if (ret != MSGPACK_UNPACK_SUCCESS) { \
- return false; \
- } \
- \
- *arg = (handle_T)data.via.i64; \
- return true; \
- } \
- \
- static void msgpack_rpc_from_##lt(Integer o, msgpack_packer *res) \
-/* uncrustify:indent-off */ \
- FUNC_ATTR_NONNULL_ARG(2) \
-/* uncrustify:indent-on */ \
- { \
- msgpack_packer pac; \
- msgpack_packer_init(&pac, &sbuffer, msgpack_sbuffer_write); \
- msgpack_pack_int64(&pac, (handle_T)o); \
- msgpack_pack_ext(res, sbuffer.size, \
- kObjectType##t - EXT_OBJECT_TYPE_SHIFT); \
- msgpack_pack_ext_body(res, sbuffer.data, sbuffer.size); \
- msgpack_sbuffer_clear(&sbuffer); \
- }
void msgpack_rpc_helpers_init(void)
{
@@ -66,10 +29,6 @@ void msgpack_rpc_helpers_init(void)
msgpack_sbuffer_init(&sbuffer);
}
-HANDLE_TYPE_CONVERSION_IMPL(Buffer, buffer)
-HANDLE_TYPE_CONVERSION_IMPL(Window, window)
-HANDLE_TYPE_CONVERSION_IMPL(Tabpage, tabpage)
-
typedef struct {
const msgpack_object *mobj;
Object *aobj;
@@ -90,11 +49,11 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
kvec_withinit_t(MPToAPIObjectStackItem, 2) stack = KV_INITIAL_VALUE;
kvi_init(stack);
kvi_push(stack, ((MPToAPIObjectStackItem) {
- .mobj = obj,
- .aobj = arg,
- .container = false,
- .idx = 0,
- }));
+ .mobj = obj,
+ .aobj = arg,
+ .container = false,
+ .idx = 0,
+ }));
while (ret && kv_size(stack)) {
MPToAPIObjectStackItem cur = kv_last(stack);
if (!cur.container) {
@@ -154,19 +113,19 @@ case type: { \
cur.idx++;
kv_last(stack) = cur;
kvi_push(stack, ((MPToAPIObjectStackItem) {
- .mobj = &cur.mobj->via.array.ptr[idx],
- .aobj = &cur.aobj->data.array.items[idx],
- .container = false,
- }));
+ .mobj = &cur.mobj->via.array.ptr[idx],
+ .aobj = &cur.aobj->data.array.items[idx],
+ .container = false,
+ }));
}
} else {
*cur.aobj = ARRAY_OBJ(((Array) {
- .size = size,
- .capacity = size,
- .items = (size > 0
+ .size = size,
+ .capacity = size,
+ .items = (size > 0
? xcalloc(size, sizeof(*cur.aobj->data.array.items))
: NULL),
- }));
+ }));
cur.container = true;
kv_last(stack) = cur;
}
@@ -207,48 +166,38 @@ case type: { \
}
if (ret) {
kvi_push(stack, ((MPToAPIObjectStackItem) {
- .mobj = &cur.mobj->via.map.ptr[idx].val,
- .aobj = &cur.aobj->data.dictionary.items[idx].value,
- .container = false,
- }));
+ .mobj = &cur.mobj->via.map.ptr[idx].val,
+ .aobj = &cur.aobj->data.dictionary.items[idx].value,
+ .container = false,
+ }));
}
}
} else {
*cur.aobj = DICTIONARY_OBJ(((Dictionary) {
- .size = size,
- .capacity = size,
- .items = (size > 0
+ .size = size,
+ .capacity = size,
+ .items = (size > 0
? xcalloc(size, sizeof(*cur.aobj->data.dictionary.items))
: NULL),
- }));
+ }));
cur.container = true;
kv_last(stack) = cur;
}
break;
}
case MSGPACK_OBJECT_EXT:
- switch ((ObjectType)(cur.mobj->via.ext.type + EXT_OBJECT_TYPE_SHIFT)) {
- case kObjectTypeBuffer:
- cur.aobj->type = kObjectTypeBuffer;
- ret = msgpack_rpc_to_buffer(cur.mobj, &cur.aobj->data.integer);
- break;
- case kObjectTypeWindow:
- cur.aobj->type = kObjectTypeWindow;
- ret = msgpack_rpc_to_window(cur.mobj, &cur.aobj->data.integer);
- break;
- case kObjectTypeTabpage:
- cur.aobj->type = kObjectTypeTabpage;
- ret = msgpack_rpc_to_tabpage(cur.mobj, &cur.aobj->data.integer);
- break;
- case kObjectTypeNil:
- case kObjectTypeBoolean:
- case kObjectTypeInteger:
- case kObjectTypeFloat:
- case kObjectTypeString:
- case kObjectTypeArray:
- case kObjectTypeDictionary:
- case kObjectTypeLuaRef:
- break;
+ if (0 <= cur.mobj->via.ext.type && cur.mobj->via.ext.type <= EXT_OBJECT_TYPE_MAX) {
+ cur.aobj->type = (ObjectType)(cur.mobj->via.ext.type + EXT_OBJECT_TYPE_SHIFT);
+ msgpack_object data;
+ msgpack_unpack_return status = msgpack_unpack(cur.mobj->via.ext.ptr, cur.mobj->via.ext.size,
+ NULL, &zone, &data);
+
+ if (status != MSGPACK_UNPACK_SUCCESS || data.type != MSGPACK_OBJECT_POSITIVE_INTEGER) {
+ ret = false;
+ break;
+ }
+ cur.aobj->data.integer = (handle_T)data.via.i64;
+ ret = true;
}
break;
#undef STR_CASE
@@ -350,6 +299,17 @@ void msgpack_rpc_from_string(const String result, msgpack_packer *res)
}
}
+static void msgpack_rpc_from_handle(ObjectType type, Integer o, msgpack_packer *res)
+ FUNC_ATTR_NONNULL_ARG(3)
+{
+ msgpack_packer pac;
+ msgpack_packer_init(&pac, &sbuffer, msgpack_sbuffer_write);
+ msgpack_pack_int64(&pac, (handle_T)o);
+ msgpack_pack_ext(res, sbuffer.size, (int8_t)(type - EXT_OBJECT_TYPE_SHIFT));
+ msgpack_pack_ext_body(res, sbuffer.data, sbuffer.size);
+ msgpack_sbuffer_clear(&sbuffer);
+}
+
typedef struct {
const Object *aobj;
bool container;
@@ -394,13 +354,9 @@ void msgpack_rpc_from_object(const Object result, msgpack_packer *const res)
msgpack_rpc_from_string(cur.aobj->data.string, res);
break;
case kObjectTypeBuffer:
- msgpack_rpc_from_buffer(cur.aobj->data.integer, res);
- break;
case kObjectTypeWindow:
- msgpack_rpc_from_window(cur.aobj->data.integer, res);
- break;
case kObjectTypeTabpage:
- msgpack_rpc_from_tabpage(cur.aobj->data.integer, res);
+ msgpack_rpc_from_handle(cur.aobj->type, cur.aobj->data.integer, res);
break;
case kObjectTypeArray: {
const size_t size = cur.aobj->data.array.size;
@@ -412,9 +368,9 @@ void msgpack_rpc_from_object(const Object result, msgpack_packer *const res)
cur.idx++;
kv_last(stack) = cur;
kvi_push(stack, ((APIToMPObjectStackItem) {
- .aobj = &cur.aobj->data.array.items[idx],
- .container = false,
- }));
+ .aobj = &cur.aobj->data.array.items[idx],
+ .container = false,
+ }));
}
} else {
msgpack_pack_array(res, size);
@@ -435,9 +391,9 @@ void msgpack_rpc_from_object(const Object result, msgpack_packer *const res)
msgpack_rpc_from_string(cur.aobj->data.dictionary.items[idx].key,
res);
kvi_push(stack, ((APIToMPObjectStackItem) {
- .aobj = &cur.aobj->data.dictionary.items[idx].value,
- .container = false,
- }));
+ .aobj = &cur.aobj->data.dictionary.items[idx].value,
+ .container = false,
+ }));
}
} else {
msgpack_pack_map(res, size);
diff --git a/src/nvim/msgpack_rpc/helpers.h b/src/nvim/msgpack_rpc/helpers.h
index 0e4cd1be6d..e5fd92374d 100644
--- a/src/nvim/msgpack_rpc/helpers.h
+++ b/src/nvim/msgpack_rpc/helpers.h
@@ -1,13 +1,12 @@
#ifndef NVIM_MSGPACK_RPC_HELPERS_H
#define NVIM_MSGPACK_RPC_HELPERS_H
-#include <stdint.h>
-#include <stdbool.h>
-
#include <msgpack.h>
+#include <stdbool.h>
+#include <stdint.h>
-#include "nvim/event/wstream.h"
#include "nvim/api/private/defs.h"
+#include "nvim/event/wstream.h"
/// Value by which objects represented as EXT type are shifted
///
@@ -15,6 +14,7 @@
/// buffer/window/tabpage block inside ObjectType enum. This block yet cannot be
/// split or reordered.
#define EXT_OBJECT_TYPE_SHIFT kObjectTypeBuffer
+#define EXT_OBJECT_TYPE_MAX (kObjectTypeTabpage - EXT_OBJECT_TYPE_SHIFT)
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "msgpack_rpc/helpers.h.generated.h"
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index b8a62a8fea..686071e25a 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -349,8 +349,8 @@ static const struct nv_cmd {
// Sorted index of commands in nv_cmds[].
static short nv_cmd_idx[NV_CMDS_SIZE];
-/* The highest index for which
- * nv_cmds[idx].cmd_char == nv_cmd_idx[nv_cmds[idx].cmd_char] */
+// The highest index for which
+// nv_cmds[idx].cmd_char == nv_cmd_idx[nv_cmds[idx].cmd_char]
static int nv_max_linear;
/*
@@ -2167,6 +2167,7 @@ static void op_function(const oparg_T *oap)
FUNC_ATTR_NONNULL_ALL
{
const TriState save_virtual_op = virtual_op;
+ const bool save_finish_op = finish_op;
if (*p_opfunc == NUL) {
EMSG(_("E774: 'operatorfunc' is empty"));
@@ -2193,9 +2194,13 @@ static void op_function(const oparg_T *oap)
// function.
virtual_op = kNone;
+ // Reset finish_op so that mode() returns the right value.
+ finish_op = false;
+
(void)call_func_retnr(p_opfunc, 1, argv);
virtual_op = save_virtual_op;
+ finish_op = save_finish_op;
}
}
@@ -3372,7 +3377,7 @@ static void may_clear_cmdline(void)
}
// Routines for displaying a partly typed command
-# define SHOWCMD_BUFLEN SHOWCMD_COLS + 1 + 30
+#define SHOWCMD_BUFLEN SHOWCMD_COLS + 1 + 30
static char_u showcmd_buf[SHOWCMD_BUFLEN];
static char_u old_showcmd_buf[SHOWCMD_BUFLEN]; // For push_showcmd()
static bool showcmd_is_clear = true;
@@ -3623,8 +3628,8 @@ void do_check_scrollbind(bool check)
static colnr_T old_leftcol = 0;
if (check && curwin->w_p_scb) {
- /* If a ":syncbind" command was just used, don't scroll, only reset
- * the values. */
+ // If a ":syncbind" command was just used, don't scroll, only reset
+ // the values.
if (did_syncbind) {
did_syncbind = false;
} else if (curwin == old_curwin) {
@@ -4264,8 +4269,8 @@ void scroll_redraw(int up, long count)
break;
}
}
- /* Mark w_topline as valid, otherwise the screen jumps back at the
- * end of the file. */
+ // Mark w_topline as valid, otherwise the screen jumps back at the
+ // end of the file.
check_cursor_moved(curwin);
curwin->w_valid |= VALID_TOPLINE;
}
@@ -4712,9 +4717,9 @@ dozet:
if (ptr == NULL) {
pos_T pos = curwin->w_cursor;
- /* Find bad word under the cursor. When 'spell' is
- * off this fails and find_ident_under_cursor() is
- * used below. */
+ // Find bad word under the cursor. When 'spell' is
+ // off this fails and find_ident_under_cursor() is
+ // used below.
emsg_off++;
len = spell_move_to(curwin, FORWARD, true, true, NULL);
emsg_off--;
@@ -4833,10 +4838,8 @@ static void nv_colon(cmdarg_T *cap)
&& (cap->oap->start.lnum > curbuf->b_ml.ml_line_count
|| cap->oap->start.col >
(colnr_T)STRLEN(ml_get(cap->oap->start.lnum))
- || did_emsg
- )) {
- /* The start of the operator has become invalid by the Ex command.
- */
+ || did_emsg)) {
+ // The start of the operator has become invalid by the Ex command.
clearopbeep(cap->oap);
}
}
@@ -5261,16 +5264,15 @@ static void nv_scroll(cmdarg_T *cap)
} else {
if (cap->cmdchar == 'M') {
// Don't count filler lines above the window.
- used -= diff_check_fill(curwin, curwin->w_topline)
+ used -= win_get_fill(curwin, curwin->w_topline)
- curwin->w_topfill;
validate_botline(curwin); // make sure w_empty_rows is valid
half = (curwin->w_height_inner - curwin->w_empty_rows + 1) / 2;
for (n = 0; curwin->w_topline + n < curbuf->b_ml.ml_line_count; n++) {
// Count half he number of filler lines to be "below this
// line" and half to be "above the next line".
- if (n > 0 && used + diff_check_fill(curwin, curwin->w_topline
- + n) / 2 >= half) {
- --n;
+ if (n > 0 && used + win_get_fill(curwin, curwin->w_topline + n) / 2 >= half) {
+ n--;
break;
}
used += plines_win(curwin, curwin->w_topline + n, true);
@@ -5668,8 +5670,8 @@ static int normal_search(cmdarg_T *cap, int dir, char_u *pat, int opt, int *wrap
}
}
- /* "/$" will put the cursor after the end of the line, may need to
- * correct that here */
+ // "/$" will put the cursor after the end of the line, may need to
+ // correct that here
check_cursor();
return i;
}
@@ -5849,16 +5851,15 @@ static void nv_brackets(cmdarg_T *cap)
}
c = gchar_cursor();
if (c == '{' || c == '}') {
- /* Must have found end/start of class: use it.
- * Or found the place to be at. */
+ // Must have found end/start of class: use it.
+ // Or found the place to be at.
if ((c == findc && norm) || (n == 1 && !norm)) {
new_pos = curwin->w_cursor;
pos = &new_pos;
n = 0;
- }
- /* if no match found at all, we started outside of the
- * class and we're inside now. Just go on. */
- else if (new_pos.lnum == 0) {
+ } else if (new_pos.lnum == 0) {
+ // if no match found at all, we started outside of the
+ // class and we're inside now. Just go on.
new_pos = curwin->w_cursor;
pos = &new_pos;
}
@@ -6307,8 +6308,8 @@ static void v_swap_corners(int cmdchar)
curwin->w_cursor.lnum = old_cursor.lnum;
curwin->w_curswant = right;
- /* 'selection "exclusive" and cursor at right-bottom corner: move it
- * right one column */
+ // 'selection "exclusive" and cursor at right-bottom corner: move it
+ // right one column
if (old_cursor.lnum >= VIsual.lnum && *p_sel == 'e') {
++curwin->w_curswant;
}
@@ -6480,8 +6481,8 @@ static void v_visop(cmdarg_T *cap)
{
static char_u trans[] = "YyDdCcxdXdAAIIrr";
- /* Uppercase means linewise, except in block mode, then "D" deletes till
- * the end of the line, and "C" replaces till EOL */
+ // Uppercase means linewise, except in block mode, then "D" deletes till
+ // the end of the line, and "C" replaces till EOL
if (isupper(cap->cmdchar)) {
if (VIsual_mode != Ctrl_V) {
VIsual_mode_orig = VIsual_mode;
@@ -6913,8 +6914,8 @@ static void nv_g_cmd(cmdarg_T *cap)
VIsual_active = true;
VIsual_reselect = true;
- /* Set Visual to the start and w_cursor to the end of the Visual
- * area. Make sure they are on an existing character. */
+ // Set Visual to the start and w_cursor to the end of the Visual
+ // area. Make sure they are on an existing character.
check_cursor();
VIsual = curwin->w_cursor;
curwin->w_cursor = tpos;
@@ -6957,10 +6958,9 @@ static void nv_g_cmd(cmdarg_T *cap)
nv_visual(cap);
break;
- /* "gn", "gN" visually select next/previous search match
- * "gn" selects next match
- * "gN" selects previous match
- */
+ // "gn", "gN" visually select next/previous search match
+ // "gn" selects next match
+ // "gN" selects previous match
case 'N':
case 'n':
if (!current_search(cap->count1, cap->nchar == 'n')) {
@@ -7034,9 +7034,9 @@ static void nv_g_cmd(cmdarg_T *cap)
} else {
i = curwin->w_leftcol;
}
- /* Go to the middle of the screen line. When 'number' or
- * 'relativenumber' is on and lines are wrapping the middle can be more
- * to the left. */
+ // Go to the middle of the screen line. When 'number' or
+ // 'relativenumber' is on and lines are wrapping the middle can be more
+ // to the left.
if (cap->nchar == 'm') {
i += (curwin->w_width_inner - curwin_col_off()
+ ((curwin->w_p_wrap && i > 0)
@@ -7684,11 +7684,10 @@ static void nv_wordcmd(cmdarg_T *cap)
*/
static void adjust_cursor(oparg_T *oap)
{
- /* The cursor cannot remain on the NUL when:
- * - the column is > 0
- * - not in Visual mode or 'selection' is "o"
- * - 'virtualedit' is not "all" and not "onemore".
- */
+ // The cursor cannot remain on the NUL when:
+ // - the column is > 0
+ // - not in Visual mode or 'selection' is "o"
+ // - 'virtualedit' is not "all" and not "onemore".
if (curwin->w_cursor.col > 0 && gchar_cursor() == NUL
&& (!VIsual_active || *p_sel == 'o')
&& !virtual_active() &&
@@ -7957,8 +7956,8 @@ static void nv_edit(cmdarg_T *cap)
if (curwin->w_cursor.coladd && cap->cmdchar != 'A') {
int save_State = State;
- /* Pretend Insert mode here to allow the cursor on the
- * character past the end of the line */
+ // Pretend Insert mode here to allow the cursor on the
+ // character past the end of the line
State = INSERT;
coladvance(getviscol());
State = save_State;
@@ -7975,9 +7974,9 @@ static void invoke_edit(cmdarg_T *cap, int repl, int cmd, int startln)
{
int restart_edit_save = 0;
- /* Complicated: When the user types "a<C-O>a" we don't want to do Insert
- * mode recursively. But when doing "a<C-O>." or "a<C-O>rx" we do allow
- * it. */
+ // Complicated: When the user types "a<C-O>a" we don't want to do Insert
+ // mode recursively. But when doing "a<C-O>." or "a<C-O>rx" we do allow
+ // it.
if (repl || !stuff_empty()) {
restart_edit_save = restart_edit;
} else {
@@ -8261,8 +8260,8 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent)
&& curwin->w_cursor.col < curbuf->b_op_start.col)
|| (VIsual_mode == 'V'
&& curwin->w_cursor.lnum < curbuf->b_op_start.lnum)) {
- /* cursor is at the end of the line or end of file, put
- * forward. */
+ // cursor is at the end of the line or end of file, put
+ // forward.
dir = FORWARD;
}
// May have been reset in do_put().
@@ -8276,8 +8275,8 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent)
xfree(savereg);
}
- /* What to reselect with "gv"? Selecting the just put text seems to
- * be the most useful, since the original text was removed. */
+ // What to reselect with "gv"? Selecting the just put text seems to
+ // be the most useful, since the original text was removed.
if (was_visual) {
curbuf->b_visual.vi_start = curbuf->b_op_start;
curbuf->b_visual.vi_end = curbuf->b_op_end;
diff --git a/src/nvim/normal.h b/src/nvim/normal.h
index 8e15e909d4..fbcc6da75b 100644
--- a/src/nvim/normal.h
+++ b/src/nvim/normal.h
@@ -2,13 +2,14 @@
#define NVIM_NORMAL_H
#include <stdbool.h>
-#include "nvim/pos.h"
+
#include "nvim/buffer_defs.h" // for win_T
+#include "nvim/pos.h"
-/* Values for find_ident_under_cursor() */
-#define FIND_IDENT 1 /* find identifier (word) */
-#define FIND_STRING 2 /* find any string (WORD) */
-#define FIND_EVAL 4 /* include "->", "[]" and "." */
+// Values for find_ident_under_cursor()
+#define FIND_IDENT 1 // find identifier (word)
+#define FIND_STRING 2 // find any string (WORD)
+#define FIND_EVAL 4 // include "->", "[]" and "."
/// Motion types, used for operators and for yank/delete registers.
///
@@ -56,24 +57,24 @@ typedef struct oparg_S {
* Arguments for Normal mode commands.
*/
typedef struct cmdarg_S {
- oparg_T *oap; /* Operator arguments */
- int prechar; /* prefix character (optional, always 'g') */
- int cmdchar; /* command character */
- int nchar; /* next command character (optional) */
- int ncharC1; /* first composing character (optional) */
- int ncharC2; /* second composing character (optional) */
- int extra_char; /* yet another character (optional) */
- long opcount; /* count before an operator */
- long count0; /* count before command, default 0 */
- long count1; /* count before command, default 1 */
- int arg; /* extra argument from nv_cmds[] */
- int retval; /* return: CA_* values */
- char_u *searchbuf; /* return: pointer to search pattern or NULL */
+ oparg_T *oap; // Operator arguments
+ int prechar; // prefix character (optional, always 'g')
+ int cmdchar; // command character
+ int nchar; // next command character (optional)
+ int ncharC1; // first composing character (optional)
+ int ncharC2; // second composing character (optional)
+ int extra_char; // yet another character (optional)
+ long opcount; // count before an operator
+ long count0; // count before command, default 0
+ long count1; // count before command, default 1
+ int arg; // extra argument from nv_cmds[]
+ int retval; // return: CA_* values
+ char_u *searchbuf; // return: pointer to search pattern or NULL
} cmdarg_T;
-/* values for retval: */
-#define CA_COMMAND_BUSY 1 /* skip restarting edit() once */
-#define CA_NO_ADJ_OP_END 2 /* don't adjust operator end */
+// values for retval:
+#define CA_COMMAND_BUSY 1 // skip restarting edit() once
+#define CA_NO_ADJ_OP_END 2 // don't adjust operator end
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 12fb8439f1..3a8f7c42a5 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -376,7 +376,7 @@ static void shift_block(oparg_T *oap, int amount)
*/
total += bd.pre_whitesp; // all virtual WS up to & incl a split TAB
colnr_T ws_vcol = bd.start_vcol - bd.pre_whitesp;
- char_u * old_textstart = bd.textstart;
+ char_u *old_textstart = bd.textstart;
if (bd.startspaces) {
if (utfc_ptr2len(bd.textstart) == 1) {
bd.textstart++;
@@ -435,9 +435,9 @@ static void shift_block(oparg_T *oap, int amount)
* non-whitespace character.
*/
- /* If "bd.startspaces" is set, "bd.textstart" points to the character,
- * the part of which is displayed at the block's beginning. Let's start
- * searching from the next character. */
+ // If "bd.startspaces" is set, "bd.textstart" points to the character,
+ // the part of which is displayed at the block's beginning. Let's start
+ // searching from the next character.
if (bd.startspaces) {
MB_PTR_ADV(non_white);
}
@@ -614,8 +614,8 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def
skipped, offset-startcol, kExtmarkUndo);
if (lnum == oap->end.lnum) {
- /* Set "']" mark to the end of the block instead of the end of
- * the insert in the first line. */
+ // Set "']" mark to the end of the block instead of the end of
+ // the insert in the first line.
curbuf->b_op_end.lnum = oap->end.lnum;
curbuf->b_op_end.col = offset;
}
@@ -804,12 +804,6 @@ bool valid_yank_reg(int regname, bool writing)
return false;
}
-typedef enum {
- YREG_PASTE,
- YREG_YANK,
- YREG_PUT,
-} yreg_mode_t;
-
/// Return yankreg_T to use, according to the value of `regname`.
/// Cannot handle the '_' (black hole) register.
/// Must only be called with a valid register name!
@@ -1852,8 +1846,8 @@ int op_replace(oparg_T *oap, int c)
numc -= (oap->end_vcol - bd.end_vcol) + 1;
}
- /* A double-wide character can be replaced only up to half the
- * times. */
+ // A double-wide character can be replaced only up to half the
+ // times.
if ((*mb_char2cells)(c) > 1) {
if ((numc & 1) && !bd.is_short) {
++bd.endspaces;
@@ -1944,8 +1938,8 @@ int op_replace(oparg_T *oap, int c)
n = gchar_cursor();
if (n != NUL) {
if ((*mb_char2len)(c) > 1 || (*mb_char2len)(n) > 1) {
- /* This is slow, but it handles replacing a single-byte
- * with a multi-byte and the other way around. */
+ // This is slow, but it handles replacing a single-byte
+ // with a multi-byte and the other way around.
if (curwin->w_cursor.lnum == oap->end.lnum) {
oap->end.col += (*mb_char2len)(c) - (*mb_char2len)(n);
}
@@ -1955,8 +1949,8 @@ int op_replace(oparg_T *oap, int c)
int end_vcol = 0;
if (curwin->w_cursor.lnum == oap->end.lnum) {
- /* oap->end has to be recalculated when
- * the tab breaks */
+ // oap->end has to be recalculated when
+ // the tab breaks
end_vcol = getviscol2(oap->end.col,
oap->end.coladd);
}
@@ -1975,9 +1969,9 @@ int op_replace(oparg_T *oap, int c)
virtcols -= oap->start.coladd;
}
- /* oap->end has been trimmed so it's effectively inclusive;
- * as a result an extra +1 must be counted so we don't
- * trample the NUL byte. */
+ // oap->end has been trimmed so it's effectively inclusive;
+ // as a result an extra +1 must be counted so we don't
+ // trample the NUL byte.
coladvance_force(getviscol2(oap->end.col, oap->end.coladd) + 1);
curwin->w_cursor.col -= (virtcols + 1);
for (; virtcols >= 0; virtcols--) {
@@ -2234,8 +2228,8 @@ void op_insert(oparg_T *oap, long count1)
++curwin->w_cursor.col;
}
if (bd.is_short && !bd.is_MAX) {
- /* First line was too short, make it longer and adjust the
- * values in "bd". */
+ // First line was too short, make it longer and adjust the
+ // values in "bd".
if (u_save_cursor() == FAIL) {
return;
}
@@ -2392,8 +2386,8 @@ int op_change(oparg_T *oap)
}
}
- /* First delete the text in the region. In an empty buffer only need to
- * save for undo */
+ // First delete the text in the region. In an empty buffer only need to
+ // save for undo
if (curbuf->b_ml.ml_flags & ML_EMPTY) {
if (u_save_cursor() == FAIL) {
return FALSE;
@@ -2823,17 +2817,17 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg)
tv_list_append_string(list, (const char *)reg->y_array[i], -1);
}
tv_list_set_lock(list, VAR_FIXED);
- tv_dict_add_list(dict, S_LEN("regcontents"), list);
+ (void)tv_dict_add_list(dict, S_LEN("regcontents"), list);
// Register type.
char buf[NUMBUFLEN+2];
format_reg_type(reg->y_type, reg->y_width, buf, ARRAY_SIZE(buf));
- tv_dict_add_str(dict, S_LEN("regtype"), buf);
+ (void)tv_dict_add_str(dict, S_LEN("regtype"), buf);
// Name of requested register, or empty string for unnamed operation.
buf[0] = (char)oap->regname;
buf[1] = NUL;
- tv_dict_add_str(dict, S_LEN("regname"), buf);
+ (void)tv_dict_add_str(dict, S_LEN("regname"), buf);
// Motion type: inclusive or exclusive.
tv_dict_add_bool(dict, S_LEN("inclusive"),
@@ -2842,11 +2836,11 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg)
// Kind of operation: yank, delete, change).
buf[0] = (char)get_op_char(oap->op_type);
buf[1] = NUL;
- tv_dict_add_str(dict, S_LEN("operator"), buf);
+ (void)tv_dict_add_str(dict, S_LEN("operator"), buf);
// Selection type: visual or not.
- tv_dict_add_bool(dict, S_LEN("visual"),
- oap->is_VIsual ? kBoolVarTrue : kBoolVarFalse);
+ (void)tv_dict_add_bool(dict, S_LEN("visual"),
+ oap->is_VIsual ? kBoolVarTrue : kBoolVarFalse);
tv_dict_set_keys_readonly(dict);
textlock++;
@@ -3650,6 +3644,12 @@ int get_register_name(int num)
}
}
+/// @return the index of the register "" points to.
+int get_unname_register(void)
+{
+ return y_previous == NULL ? -1 : (int)(y_previous - &y_regs[0]);
+}
+
/*
* ":dis" and ":registers": Display the contents of the yank registers.
*/
@@ -3872,10 +3872,9 @@ char_u *skip_comment(char_u *line, bool process, bool include_space, bool *is_co
++comment_flags;
}
- /* If we found a colon, it means that we are not processing a line
- * starting with a closing part of a three-part comment. That's good,
- * because we don't want to remove those as this would be annoying.
- */
+ // If we found a colon, it means that we are not processing a line
+ // starting with a closing part of a three-part comment. That's good,
+ // because we don't want to remove those as this would be annoying.
if (*comment_flags == ':' || *comment_flags == NUL) {
line += lead_len;
}
@@ -4054,8 +4053,8 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions
curwin->w_buffer->b_op_end.col = sumsize;
}
- /* Only report the change in the first line here, del_lines() will report
- * the deleted line. */
+ // Only report the change in the first line here, del_lines() will report
+ // the deleted line.
changed_lines(curwin->w_cursor.lnum, currsize,
curwin->w_cursor.lnum + 1, 0L, true);
@@ -4172,8 +4171,8 @@ void op_format(oparg_T *oap, int keep_cursor)
{
long old_line_count = curbuf->b_ml.ml_line_count;
- /* Place the cursor where the "gq" or "gw" command was given, so that "u"
- * can put it back there. */
+ // Place the cursor where the "gq" or "gw" command was given, so that "u"
+ // can put it back there.
curwin->w_cursor = oap->cursor_start;
if (u_save((linenr_T)(oap->start.lnum - 1),
@@ -4190,8 +4189,8 @@ void op_format(oparg_T *oap, int keep_cursor)
// Set '[ mark at the start of the formatted area
curbuf->b_op_start = oap->start;
- /* For "gw" remember the cursor position and put it back below (adjusted
- * for joined and split lines). */
+ // For "gw" remember the cursor position and put it back below (adjusted
+ // for joined and split lines).
if (keep_cursor) {
saved_cursor = oap->cursor_start;
}
@@ -4221,8 +4220,8 @@ void op_format(oparg_T *oap, int keep_cursor)
if (oap->is_VIsual) {
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_old_cursor_lnum != 0) {
- /* When lines have been inserted or deleted, adjust the end of
- * the Visual area to be redrawn. */
+ // When lines have been inserted or deleted, adjust the end of
+ // the Visual area to be redrawn.
if (wp->w_old_cursor_lnum > wp->w_old_visual_lnum) {
wp->w_old_cursor_lnum += old_line_count;
} else {
@@ -4244,16 +4243,16 @@ void op_formatexpr(oparg_T *oap)
}
if (fex_format(oap->start.lnum, oap->line_count, NUL) != 0) {
- /* As documented: when 'formatexpr' returns non-zero fall back to
- * internal formatting. */
- op_format(oap, FALSE);
+ // As documented: when 'formatexpr' returns non-zero fall back to
+ // internal formatting.
+ op_format(oap, false);
}
}
/// @param c character to be inserted
int fex_format(linenr_T lnum, long count, int c)
{
- int use_sandbox = was_set_insecurely(curwin, (char_u *)"formatexpr", OPT_LOCAL);
+ int use_sandbox = was_set_insecurely(curwin, "formatexpr", OPT_LOCAL);
int r;
char_u *fex;
@@ -4325,8 +4324,8 @@ void format_lines(linenr_T line_count, int avoid_fex)
} else {
is_not_par = true;
}
- next_is_not_par = fmt_check_par(curwin->w_cursor.lnum
- , &next_leader_len, &next_leader_flags, do_comments
+ next_is_not_par = fmt_check_par(curwin->w_cursor.lnum,
+ &next_leader_len, &next_leader_flags, do_comments
);
is_end_par = (is_not_par || next_is_not_par);
if (!is_end_par && do_trail_white) {
@@ -4354,8 +4353,8 @@ void format_lines(linenr_T line_count, int avoid_fex)
next_leader_len = 0;
next_leader_flags = NULL;
} else {
- next_is_not_par = fmt_check_par(curwin->w_cursor.lnum + 1
- , &next_leader_len, &next_leader_flags, do_comments
+ next_is_not_par = fmt_check_par(curwin->w_cursor.lnum + 1,
+ &next_leader_len, &next_leader_flags, do_comments
);
if (do_number_indent) {
next_is_start_par =
@@ -4424,8 +4423,8 @@ void format_lines(linenr_T line_count, int avoid_fex)
*/
if (is_end_par || force_format) {
if (need_set_indent) {
- /* replace indent in first line with minimal number of
- * tabs and spaces, according to current options */
+ // replace indent in first line with minimal number of
+ // tabs and spaces, according to current options
(void)set_indent(get_indent(), SIN_CHANGED);
}
@@ -4451,8 +4450,8 @@ void format_lines(linenr_T line_count, int avoid_fex)
// at end of par.: need to set indent of next par.
need_set_indent = is_end_par;
if (is_end_par) {
- /* When called with a negative line count, break at the
- * end of the paragraph. */
+ // When called with a negative line count, break at the
+ // end of the paragraph.
if (line_count < 0) {
break;
}
@@ -4674,9 +4673,9 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool
} else {
bdp->startspaces = oap->end_vcol - oap->start_vcol + 1;
if (is_del && oap->op_type != OP_LSHIFT) {
- /* just putting the sum of those two into
- * bdp->startspaces doesn't work for Visual replace,
- * so we have to split the tab in two */
+ // just putting the sum of those two into
+ // bdp->startspaces doesn't work for Visual replace,
+ // so we have to split the tab in two
bdp->startspaces = bdp->start_char_vcols
- (bdp->start_vcol - oap->start_vcol);
bdp->endspaces = bdp->end_vcol - oap->end_vcol - 1;
@@ -4817,7 +4816,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd)
if (change_cnt == 1) {
MSG(_("1 line changed"));
} else {
- smsg((char *)_("%" PRId64 " lines changed"), (int64_t)change_cnt);
+ smsg(_("%" PRId64 " lines changed"), (int64_t)change_cnt);
}
}
}
@@ -5560,6 +5559,11 @@ static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type, const char_u *str
}
}
+ // Without any lines make the register empty.
+ if (y_ptr->y_size + newlines == 0) {
+ XFREE_CLEAR(y_ptr->y_array);
+ return;
+ }
// Grow the register array to hold the pointers to the new lines.
char_u **pp = xrealloc(y_ptr->y_array,
@@ -6051,7 +6055,7 @@ bool prepare_yankreg_from_object(yankreg_T *reg, String regtype, size_t lines)
void finish_yankreg_from_object(yankreg_T *reg, bool clipboard_adjust)
{
- if (reg->y_size > 0 && strlen((char *)reg->y_array[reg->y_size-1]) == 0) {
+ if (reg->y_size > 0 && STRLEN(reg->y_array[reg->y_size-1]) == 0) {
// a known-to-be charwise yank might have a final linebreak
// but otherwise there is no line after the final newline
if (reg->y_type != kMTCharWise) {
@@ -6116,7 +6120,7 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet)
goto err;
}
char_u *regtype = TV_LIST_ITEM_TV(tv_list_last(res))->vval.v_string;
- if (regtype == NULL || strlen((char *)regtype) > 1) {
+ if (regtype == NULL || STRLEN(regtype) > 1) {
goto err;
}
switch (regtype[0]) {
@@ -6159,7 +6163,7 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet)
reg->y_array[tv_idx++] = (char_u *)xstrdupnul((const char *)TV_LIST_ITEM_TV(li)->vval.v_string);
});
- if (reg->y_size > 0 && strlen((char *)reg->y_array[reg->y_size-1]) == 0) {
+ if (reg->y_size > 0 && STRLEN(reg->y_array[reg->y_size-1]) == 0) {
// a known-to-be charwise yank might have a final linebreak
// but otherwise there is no line after the final newline
if (reg->y_type != kMTCharWise) {
diff --git a/src/nvim/ops.h b/src/nvim/ops.h
index 112ffbeaba..11049b72c0 100644
--- a/src/nvim/ops.h
+++ b/src/nvim/ops.h
@@ -3,14 +3,14 @@
#include <stdbool.h>
-#include "nvim/macros.h"
#include "nvim/ascii.h"
-#include "nvim/types.h"
-#include "nvim/extmark.h"
#include "nvim/eval/typval.h"
+#include "nvim/ex_cmds_defs.h" // for exarg_T
+#include "nvim/extmark.h"
+#include "nvim/macros.h"
+#include "nvim/normal.h" // for MotionType and oparg_T
#include "nvim/os/time.h"
-#include "nvim/normal.h" // for MotionType and oparg_T
-#include "nvim/ex_cmds_defs.h" // for exarg_T
+#include "nvim/types.h"
typedef int (*Indenter)(void);
@@ -90,6 +90,13 @@ typedef struct yankreg {
dict_T *additional_data; ///< Additional data from ShaDa file.
} yankreg_T;
+/// Modes for get_yank_register()
+typedef enum {
+ YREG_PASTE,
+ YREG_YANK,
+ YREG_PUT,
+} yreg_mode_t;
+
/// Convert register name into register index
///
/// @param[in] regname Register name.
diff --git a/src/nvim/option.c b/src/nvim/option.c
index d3056aaa83..fb888ffd0f 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -22,50 +22,50 @@
#define IN_OPTION_C
#include <assert.h>
#include <inttypes.h>
+#include <limits.h>
#include <stdbool.h>
-#include <string.h>
#include <stdlib.h>
-#include <limits.h>
+#include <string.h>
-#include "nvim/vim.h"
-#include "nvim/macros.h"
#include "nvim/ascii.h"
-#include "nvim/edit.h"
-#include "nvim/option.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/cursor_shape.h"
#include "nvim/diff.h"
#include "nvim/digraph.h"
+#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
+#include "nvim/ex_session.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/hardcopy.h"
#include "nvim/highlight.h"
#include "nvim/indent_c.h"
+#include "nvim/keymap.h"
+#include "nvim/macros.h"
#include "nvim/mbyte.h"
#include "nvim/memfile.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/runtime.h"
-#include "nvim/keymap.h"
-#include "nvim/garray.h"
-#include "nvim/cursor_shape.h"
-#include "nvim/move.h"
#include "nvim/mouse.h"
+#include "nvim/move.h"
#include "nvim/normal.h"
+#include "nvim/option.h"
+#include "nvim/os/os.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/popupmnu.h"
#include "nvim/regexp.h"
-#include "nvim/ex_session.h"
+#include "nvim/runtime.h"
#include "nvim/screen.h"
#include "nvim/spell.h"
#include "nvim/spellfile.h"
@@ -74,13 +74,13 @@
#include "nvim/ui.h"
#include "nvim/ui_compositor.h"
#include "nvim/undo.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/os/os.h"
#ifdef WIN32
# include "nvim/os/pty_conpty_win.h"
#endif
-#include "nvim/lua/executor.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/lua/executor.h"
#include "nvim/os/input.h"
#include "nvim/os/lang.h"
#include "nvim/quickfix.h"
@@ -124,64 +124,64 @@ static char *p_ttytype = NULL;
static int p_ai;
static int p_bin;
static int p_bomb;
-static char_u *p_bh;
-static char_u *p_bt;
+static char_u *p_bh;
+static char_u *p_bt;
static int p_bl;
static long p_channel;
static int p_ci;
static int p_cin;
-static char_u *p_cink;
-static char_u *p_cino;
-static char_u *p_cinw;
-static char_u *p_com;
-static char_u *p_cms;
-static char_u *p_cpt;
-static char_u *p_cfu;
-static char_u *p_ofu;
-static char_u *p_tfu;
+static char_u *p_cink;
+static char_u *p_cino;
+static char_u *p_cinw;
+static char_u *p_com;
+static char_u *p_cms;
+static char_u *p_cpt;
+static char_u *p_cfu;
+static char_u *p_ofu;
+static char_u *p_tfu;
static int p_eol;
static int p_fixeol;
static int p_et;
-static char_u *p_fenc;
-static char_u *p_ff;
-static char_u *p_fo;
-static char_u *p_flp;
-static char_u *p_ft;
+static char_u *p_fenc;
+static char_u *p_ff;
+static char_u *p_fo;
+static char_u *p_flp;
+static char_u *p_ft;
static long p_iminsert;
static long p_imsearch;
-static char_u *p_inex;
-static char_u *p_inde;
-static char_u *p_indk;
-static char_u *p_fex;
+static char_u *p_inex;
+static char_u *p_inde;
+static char_u *p_indk;
+static char_u *p_fex;
static int p_inf;
-static char_u *p_isk;
+static char_u *p_isk;
static int p_lisp;
static int p_ml;
static int p_ma;
static int p_mod;
-static char_u *p_mps;
-static char_u *p_nf;
+static char_u *p_mps;
+static char_u *p_nf;
static int p_pi;
-static char_u *p_qe;
+static char_u *p_qe;
static int p_ro;
static int p_si;
static long p_sts;
-static char_u *p_sua;
+static char_u *p_sua;
static long p_sw;
static int p_swf;
static long p_smc;
-static char_u *p_syn;
-static char_u *p_spc;
-static char_u *p_spf;
-static char_u *p_spl;
-static char_u *p_spo;
+static char_u *p_syn;
+static char_u *p_spc;
+static char_u *p_spf;
+static char_u *p_spl;
+static char_u *p_spo;
static long p_ts;
static long p_tw;
static int p_udf;
static long p_wm;
static char_u *p_vsts;
static char_u *p_vts;
-static char_u *p_keymap;
+static char_u *p_keymap;
// Saved values for when 'bin' is set.
static int p_et_nobin;
@@ -198,15 +198,15 @@ static long p_wm_nopaste;
static char_u *p_vsts_nopaste;
typedef struct vimoption {
- char *fullname; // full option name
- char *shortname; // permissible abbreviation
+ char *fullname; // full option name
+ char *shortname; // permissible abbreviation
uint32_t flags; // see below
- char_u *var; // global option: pointer to variable;
- // window-local option: VAR_WIN;
- // buffer-local option: global value
+ char_u *var; // global option: pointer to variable;
+ // window-local option: VAR_WIN;
+ // buffer-local option: global value
idopt_T indir; // global option: PV_NONE;
// local option: indirect option index
- char_u *def_val; // default values for variable (neovim!!)
+ char_u *def_val; // default values for variable (neovim!!)
LastSet last_set; // script in which the option was last set
} vimoption_T;
@@ -314,12 +314,15 @@ static char *(p_csl_values[]) = { "slash", "backslash", NULL };
#endif
static char *(p_icm_values[]) = { "nosplit", "split", NULL };
static char *(p_scl_values[]) = { "yes", "no", "auto", "auto:1", "auto:2",
- "auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8", "auto:9",
- "yes:1", "yes:2", "yes:3", "yes:4", "yes:5", "yes:6", "yes:7", "yes:8",
- "yes:9", "number", NULL };
+ "auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8",
+ "auto:9",
+ "yes:1", "yes:2", "yes:3", "yes:4", "yes:5", "yes:6",
+ "yes:7", "yes:8",
+ "yes:9", "number", NULL };
static char *(p_fdc_values[]) = { "auto", "auto:1", "auto:2",
- "auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8", "auto:9",
- "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL };
+ "auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8",
+ "auto:9",
+ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL };
/// All possible flags for 'shm'.
static char_u SHM_ALL[] = {
@@ -371,11 +374,11 @@ void set_init_1(bool clean_arg)
* temp files.
*/
{
-# ifdef UNIX
- static char *(names[4]) = {"", "TMPDIR", "TEMP", "TMP"};
-# else
- static char *(names[3]) = {"TMPDIR", "TEMP", "TMP"};
-# endif
+#ifdef UNIX
+ static char *(names[4]) = { "", "TMPDIR", "TEMP", "TMP" };
+#else
+ static char *(names[3]) = { "TMPDIR", "TEMP", "TMP" };
+#endif
garray_T ga;
opt_idx = findoption("backupskip");
@@ -383,16 +386,16 @@ void set_init_1(bool clean_arg)
for (size_t n = 0; n < ARRAY_SIZE(names); n++) {
bool mustfree = true;
char *p;
-# ifdef UNIX
+#ifdef UNIX
if (*names[n] == NUL) {
-# ifdef __APPLE__
+# ifdef __APPLE__
p = "/private/tmp";
-# else
+# else
p = "/tmp";
-# endif
+# endif
mustfree = false;
} else
-# endif
+#endif
{
p = vim_getenv(names[n]);
}
@@ -426,8 +429,8 @@ void set_init_1(bool clean_arg)
}
{
- char_u *cdpath;
- char_u *buf;
+ char_u *cdpath;
+ char_u *buf;
int i;
int j;
@@ -470,13 +473,13 @@ void set_init_1(bool clean_arg)
set_string_default("printexpr",
#ifdef UNIX
"system(['lpr'] "
- "+ (empty(&printdevice)?[]:['-P', &printdevice]) "
- "+ [v:fname_in])"
+ "+ (empty(&printdevice)?[]:['-P', &printdevice]) "
+ "+ [v:fname_in])"
". delete(v:fname_in)"
"+ v:shell_error",
#elif defined(MSWIN)
"system(['copy', v:fname_in, "
- "empty(&printdevice)?'LPT1':&printdevice])"
+ "empty(&printdevice)?'LPT1':&printdevice])"
". delete(v:fname_in)",
#else
"",
@@ -550,7 +553,7 @@ void set_init_1(bool clean_arg)
&& options[opt_idx].var != NULL) {
p = _(*(char **)options[opt_idx].var);
} else {
- p = (char *) option_expand(opt_idx, NULL);
+ p = (char *)option_expand(opt_idx, NULL);
}
if (p != NULL) {
p = xstrdup(p);
@@ -584,8 +587,8 @@ void set_init_1(bool clean_arg)
// in 'fileencodings'
char_u *p = enc_locale();
if (p == NULL) {
- // use utf-8 as 'default' if locale encoding can't be detected.
- p = (char_u *)xmemdupz(S_LEN("utf-8"));
+ // use utf-8 as 'default' if locale encoding can't be detected.
+ p = (char_u *)xmemdupz(S_LEN("utf-8"));
}
fenc_default = p;
@@ -605,15 +608,15 @@ void set_init_1(bool clean_arg)
/// @param opt_flags OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL
static void set_option_default(int opt_idx, int opt_flags)
{
- char_u *varp; // pointer to variable for current option
+ char_u *varp; // pointer to variable for current option
int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
varp = get_varp_scope(&(options[opt_idx]), both ? OPT_LOCAL : opt_flags);
uint32_t flags = options[opt_idx].flags;
if (varp != NULL) { // skip hidden option, nothing to do for it
if (flags & P_STRING) {
- /* Use set_string_option_direct() for local options to handle
- * freeing and allocating the value. */
+ // Use set_string_option_direct() for local options to handle
+ // 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);
@@ -624,7 +627,7 @@ static void set_option_default(int opt_idx, int opt_flags)
*(char_u **)varp = options[opt_idx].def_val;
options[opt_idx].flags &= ~P_ALLOCED;
}
- } else if (flags & P_NUM) {
+ } else if (flags & P_NUM) {
if (options[opt_idx].indir == PV_SCROLL) {
win_comp_scroll(curwin);
} else {
@@ -667,10 +670,9 @@ static void set_option_default(int opt_idx, int opt_flags)
}
/// Set all options (except terminal options) to their default value.
-static void
-set_options_default(
- int opt_flags // OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL
-)
+///
+/// @param opt_flags OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL
+static void set_options_default(int opt_flags)
{
for (int i = 0; options[i].fullname; i++) {
if (!(options[i].flags & P_NODEFAULT)) {
@@ -710,8 +712,7 @@ static void set_string_default(const char *name, char *val, bool allocated)
// For an option value that contains comma separated items, find "newval" in
// "origval". Return NULL if not found.
-static char_u *find_dup_item(char_u *origval, const char_u *newval,
- uint32_t flags)
+static char_u *find_dup_item(char_u *origval, const char_u *newval, uint32_t flags)
FUNC_ATTR_NONNULL_ARG(2)
{
int bs = 0;
@@ -827,9 +828,8 @@ void set_init_3(void)
// Default for p_sp is "| tee", for p_srr is ">".
// For known shells it is changed here to include stderr.
//
- if ( fnamecmp(p, "csh") == 0
- || fnamecmp(p, "tcsh") == 0
- ) {
+ if (fnamecmp(p, "csh") == 0
+ || fnamecmp(p, "tcsh") == 0) {
if (do_sp) {
p_sp = (char_u *)"|& tee";
options[idx_sp].def_val = p_sp;
@@ -847,8 +847,7 @@ void set_init_3(void)
|| fnamecmp(p, "bash") == 0
|| fnamecmp(p, "fish") == 0
|| fnamecmp(p, "ash") == 0
- || fnamecmp(p, "dash") == 0
- ) {
+ || fnamecmp(p, "dash") == 0) {
// Always use POSIX shell style redirection if we reach this
if (do_sp) {
p_sp = (char_u *)"2>&1| tee";
@@ -933,28 +932,27 @@ void set_title_defaults(void)
}
}
-// Parse 'arg' for option settings.
-//
-// 'arg' may be IObuff, but only when no errors can be present and option
-// does not need to be expanded with option_expand().
-// "opt_flags":
-// 0 for ":set"
-// OPT_GLOBAL for ":setglobal"
-// OPT_LOCAL for ":setlocal" and a modeline
-// OPT_MODELINE for a modeline
-// OPT_WINONLY to only set window-local options
-// OPT_NOWIN to skip setting window-local options
-//
-// returns FAIL if an error is detected, OK otherwise
-int do_set(
- char_u *arg, // option string (may be written to!)
- int opt_flags
-)
+/// Parse 'arg' for option settings.
+///
+/// 'arg' may be IObuff, but only when no errors can be present and option
+/// does not need to be expanded with option_expand().
+/// "opt_flags":
+/// 0 for ":set"
+/// OPT_GLOBAL for ":setglobal"
+/// OPT_LOCAL for ":setlocal" and a modeline
+/// OPT_MODELINE for a modeline
+/// OPT_WINONLY to only set window-local options
+/// OPT_NOWIN to skip setting window-local options
+///
+/// @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 opt_idx;
- char_u *errmsg;
+ char_u *errmsg;
char_u errbuf[80];
- char_u *startarg;
+ char_u *startarg;
int prefix; // 1: nothing, 0: "no", 2: "inv" in front of name
char_u nextchar; // next non-white char after option name
int afterchar; // character just after option name
@@ -963,7 +961,7 @@ int do_set(
varnumber_T value;
int key;
uint32_t flags; // flags for current option
- char_u *varp = NULL; // pointer to variable for current option
+ char_u *varp = NULL; // pointer to variable for current option
int did_show = false; // already showed one value
int adding; // "opt+=arg"
int prepending; // "opt^=arg"
@@ -1096,11 +1094,12 @@ int do_set(
flags = P_STRING;
}
- /* Skip all options that are not window-local (used when showing
- * an already loaded buffer in a window). */
+ // Skip all options that are not window-local (used when showing
+ // an already loaded buffer in a window).
if ((opt_flags & OPT_WINONLY)
- && (opt_idx < 0 || options[opt_idx].var != VAR_WIN))
+ && (opt_idx < 0 || options[opt_idx].var != VAR_WIN)) {
goto skip;
+ }
// Skip all options that are window-local (used for :vimgrep).
if ((opt_flags & OPT_NOWIN) && opt_idx >= 0
@@ -1115,8 +1114,7 @@ int do_set(
goto skip;
}
if ((flags & P_MLE) && !p_mle) {
- errmsg = (char_u *)N_(
- "E992: Not allowed in a modeline when 'modelineexpr' is off");
+ errmsg = (char_u *)N_("E992: Not allowed in a modeline when 'modelineexpr' is off");
goto skip;
}
// In diff mode some options are overruled. This avoids that
@@ -1177,10 +1175,10 @@ int do_set(
option_last_set_msg(options[opt_idx].last_set);
} else if ((int)options[opt_idx].indir & PV_WIN) {
option_last_set_msg(curwin->w_p_script_ctx[
- (int)options[opt_idx].indir & PV_MASK]);
+ (int)options[opt_idx].indir & PV_MASK]);
} else if ((int)options[opt_idx].indir & PV_BUF) {
option_last_set_msg(curbuf->b_p_script_ctx[
- (int)options[opt_idx].indir & PV_MASK]);
+ (int)options[opt_idx].indir & PV_MASK]);
}
}
} else {
@@ -1188,8 +1186,9 @@ int do_set(
goto skip;
}
if (nextchar != '?'
- && nextchar != NUL && !ascii_iswhite(afterchar))
+ && nextchar != NUL && !ascii_iswhite(afterchar)) {
errmsg = e_trailing;
+ }
} else {
int value_is_replaced = !prepending && !adding && !removing;
int value_checked = false;
@@ -1260,8 +1259,7 @@ int do_set(
if ((long *)varp == &curbuf->b_p_ul && opt_flags == OPT_LOCAL) {
value = NO_LOCAL_UNDOLEVEL;
} else {
- value = *(long *)get_varp_scope(
- &(options[opt_idx]), OPT_GLOBAL);
+ value = *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL);
}
} else if (((long *)varp == &p_wc
|| (long *)varp == &p_wcm)
@@ -1299,11 +1297,11 @@ int do_set(
errbuf, sizeof(errbuf),
opt_flags);
} else if (opt_idx >= 0) { // String.
- char_u *save_arg = NULL;
- char_u *s = NULL;
- char_u *oldval = NULL; // previous value if *varp
- char_u *newval;
- char_u *origval = NULL;
+ char_u *save_arg = NULL;
+ char_u *s = NULL;
+ char_u *oldval = NULL; // previous value if *varp
+ char_u *newval;
+ char_u *origval = NULL;
char *saved_origval = NULL;
char *saved_newval = NULL;
unsigned newlen;
@@ -1314,8 +1312,9 @@ int do_set(
* with a local value the local value will be
* reset, use the global value here. */
if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
- && ((int)options[opt_idx].indir & PV_BOTH))
+ && ((int)options[opt_idx].indir & PV_BOTH)) {
varp = options[opt_idx].var;
+ }
/* The old value is kept until we are sure that the
* new value is valid. */
@@ -1349,8 +1348,7 @@ int do_set(
newval = (char_u *)xstrdup((char *)newval);
}
} else if (nextchar == '<') { // set to global val
- newval = vim_strsave(*(char_u **)get_varp_scope(
- &(options[opt_idx]), OPT_GLOBAL));
+ newval = vim_strsave(*(char_u **)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL));
new_value_alloced = true;
} else {
arg++; // jump to after the '=' or ':'
@@ -1378,16 +1376,13 @@ int do_set(
*(char_u **)varp = empty_option;
break;
case 1:
- *(char_u **)varp = vim_strsave(
- (char_u *)"indent,eol");
+ *(char_u **)varp = vim_strsave((char_u *)"indent,eol");
break;
case 2:
- *(char_u **)varp = vim_strsave(
- (char_u *)"indent,eol,start");
+ *(char_u **)varp = vim_strsave((char_u *)"indent,eol,start");
break;
case 3:
- *(char_u **)varp = vim_strsave(
- (char_u *)"indent,eol,nostop");
+ *(char_u **)varp = vim_strsave((char_u *)"indent,eol,nostop");
break;
}
xfree(oldval);
@@ -1427,9 +1422,9 @@ int do_set(
* Remove '>' before 'dir' and 'bdir', for
* backwards compatibility with version 3.0
*/
- else if ( *arg == '>'
- && (varp == (char_u *)&p_dir
- || varp == (char_u *)&p_bdir)) {
+ else if (*arg == '>'
+ && (varp == (char_u *)&p_dir
+ || varp == (char_u *)&p_bdir)) {
arg++;
}
@@ -1464,8 +1459,9 @@ int do_set(
|| (s == newval
&& arg[2] != '\\')))
#endif
- )
+ ) {
arg++; // remove backslash
+ }
i = utfc_ptr2len(arg);
if (i > 1) {
// copy multibyte char
@@ -1518,8 +1514,8 @@ int do_set(
}
}
- /* concatenate the two strings; add a ',' if
- * needed */
+ // concatenate the two strings; add a ',' if
+ // needed
if (adding || prepending) {
comma = ((flags & P_COMMA) && *origval != NUL
&& *newval != NUL);
@@ -1533,7 +1529,7 @@ int do_set(
i--;
}
memmove(newval + i + comma, newval,
- STRLEN(newval) + 1);
+ STRLEN(newval) + 1);
memmove(newval, origval, (size_t)i);
} else {
i = (int)STRLEN(newval);
@@ -1544,8 +1540,8 @@ int do_set(
}
}
- /* Remove newval[] from origval[]. (Note: "i" has
- * been set above and is used here). */
+ // Remove newval[] from origval[]. (Note: "i" has
+ // been set above and is used here).
if (removing) {
STRCPY(newval, origval);
if (*s) {
@@ -1650,7 +1646,6 @@ int do_set(
if (errmsg != NULL) {
goto skip;
}
-
} else {
// key code option(FIXME(tarruda): Show a warning or something
// similar)
@@ -1719,15 +1714,13 @@ theend:
return OK;
}
-// Call this when an option has been given a new value through a user command.
-// Sets the P_WAS_SET flag and takes care of the P_INSECURE flag.
-static void did_set_option(
- int opt_idx,
- int opt_flags, // possibly with OPT_MODELINE
- int new_value, // value was replaced completely
- int value_checked // value was checked to be safe, no need to
- // set P_INSECURE
-)
+/// Call this when an option has been given a new value through a user command.
+/// Sets the P_WAS_SET flag and takes care of the P_INSECURE flag.
+///
+/// @param opt_flags possibly with OPT_MODELINE
+/// @param new_value value was replaced completely
+/// @param value_checked value was checked to be safe, no need to set P_INSECURE
+static void did_set_option(int opt_idx, int opt_flags, int new_value, int value_checked)
{
options[opt_idx].flags |= P_WAS_SET;
@@ -1796,12 +1789,10 @@ static void did_set_title(void)
}
}
-// set_options_bin - called when 'bin' changes value.
-void set_options_bin(
- int oldval,
- int newval,
- int opt_flags // OPT_LOCAL and/or OPT_GLOBAL
-)
+/// set_options_bin - called when 'bin' changes value.
+///
+/// @param opt_flags OPT_LOCAL and/or OPT_GLOBAL
+void set_options_bin(int oldval, int newval, int opt_flags)
{
/*
* The option values that are changed when 'bin' changes are
@@ -1859,7 +1850,7 @@ void set_options_bin(
/// number, return -1.
int get_shada_parameter(int type)
{
- char_u *p;
+ char_u *p;
p = find_shada_parameter(type);
if (p != NULL && ascii_isdigit(*p)) {
@@ -1873,7 +1864,7 @@ int get_shada_parameter(int type)
/// Return NULL if the parameter is not specified in the string.
char_u *find_shada_parameter(int type)
{
- char_u *p;
+ char_u *p;
for (p = p_shada; *p; p++) {
if (*p == type) {
@@ -2081,9 +2072,9 @@ static void check_string_option(char_u **pp)
/// Return true when option "opt" was set from a modeline or in secure mode.
/// Return false when it wasn't.
/// Return -1 for an unknown option.
-int was_set_insecurely(win_T *const wp, char_u *opt, int opt_flags)
+int was_set_insecurely(win_T *const wp, char *opt, int opt_flags)
{
- int idx = findoption((const char *)opt);
+ int idx = findoption(opt);
if (idx >= 0) {
uint32_t *flagp = insecure_flag(wp, idx, opt_flags);
@@ -2102,12 +2093,18 @@ static uint32_t *insecure_flag(win_T *const wp, int opt_idx, int opt_flags)
if (opt_flags & OPT_LOCAL) {
assert(wp != NULL);
switch ((int)options[opt_idx].indir) {
- case PV_STL: return &wp->w_p_stl_flags;
- case PV_FDE: return &wp->w_p_fde_flags;
- case PV_FDT: return &wp->w_p_fdt_flags;
- case PV_INDE: return &wp->w_buffer->b_p_inde_flags;
- case PV_FEX: return &wp->w_buffer->b_p_fex_flags;
- case PV_INEX: return &wp->w_buffer->b_p_inex_flags;
+ case PV_STL:
+ return &wp->w_p_stl_flags;
+ case PV_FDE:
+ return &wp->w_p_fde_flags;
+ case PV_FDT:
+ return &wp->w_p_fdt_flags;
+ case PV_INDE:
+ return &wp->w_buffer->b_p_inde_flags;
+ case PV_FEX:
+ return &wp->w_buffer->b_p_fex_flags;
+ case PV_INEX:
+ return &wp->w_buffer->b_p_inex_flags;
}
}
@@ -2125,23 +2122,19 @@ static void redraw_titles(void)
static int shada_idx = -1;
-// Set a string option to a new value (without checking the effect).
-// The string is copied into allocated memory.
-// if ("opt_idx" == -1) "name" is used, otherwise "opt_idx" is used.
-// When "set_sid" is zero set the scriptID to current_sctx.sc_sid. When
-// "set_sid" is SID_NONE don't set the scriptID. Otherwise set the scriptID to
-// "set_sid".
-void
-set_string_option_direct(
- const char *name,
- int opt_idx,
- const char_u *val,
- int opt_flags, // OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL
- int set_sid
-)
-{
- char_u *s;
- char_u **varp;
+/// Set a string option to a new value (without checking the effect).
+/// The string is copied into allocated memory.
+/// if ("opt_idx" == -1) "name" is used, otherwise "opt_idx" is used.
+/// When "set_sid" is zero set the scriptID to current_sctx.sc_sid. When
+/// "set_sid" is SID_NONE don't set the scriptID. Otherwise set the scriptID to
+/// "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,
+ int set_sid)
+{
+ char_u *s;
+ char_u **varp;
int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
int idx = opt_idx;
@@ -2158,7 +2151,7 @@ set_string_option_direct(
return;
}
- assert((void *) options[idx].var != (void *) &p_shada);
+ assert((void *)options[idx].var != (void *)&p_shada);
s = vim_strsave(val);
{
@@ -2198,13 +2191,12 @@ set_string_option_direct(
}
/// Set global value for string option when it's a local option.
-static void
-set_string_option_global(
- int opt_idx, // option index
- char_u **varp // pointer to option variable
-)
+///
+/// @param opt_idx option index
+/// @param varp pointer to option variable
+static void set_string_option_global(int opt_idx, char_u **varp)
{
- char_u **p, *s;
+ char_u **p, *s;
// the global value is always allocated
if (options[opt_idx].var == VAR_WIN) {
@@ -2227,8 +2219,7 @@ set_string_option_global(
/// #OPT_GLOBAL.
///
/// @return NULL on success, error message on error.
-static char *set_string_option(const int opt_idx, const char *const value,
- const int opt_flags)
+static char *set_string_option(const int opt_idx, const char *const value, const int opt_flags)
FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_WARN_UNUSED_RESULT
{
if (options[opt_idx].var == NULL) { // don't set hidden option
@@ -2236,12 +2227,11 @@ static char *set_string_option(const int opt_idx, const char *const value,
}
char *const s = xstrdup(value);
- char **const varp = (char **)get_varp_scope(
- &(options[opt_idx]),
- ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
+ char **const varp = (char **)get_varp_scope(&(options[opt_idx]),
+ ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
? (((int)options[opt_idx].indir & PV_BOTH)
? OPT_GLOBAL : OPT_LOCAL)
- : opt_flags));
+ : opt_flags));
char *const oldval = *varp;
*varp = s;
@@ -2249,9 +2239,9 @@ static char *set_string_option(const int opt_idx, const char *const value,
char *const saved_newval = xstrdup(s);
int value_checked = false;
- char *const r = (char *)did_set_string_option(
- opt_idx, (char_u **)varp, (int)true, (char_u *)oldval,
- NULL, 0, opt_flags, &value_checked);
+ char *const r = (char *)did_set_string_option(opt_idx, (char_u **)varp, (int)true,
+ (char_u *)oldval,
+ NULL, 0, opt_flags, &value_checked);
if (r == NULL) {
did_set_option(opt_idx, opt_flags, true, value_checked);
}
@@ -2315,23 +2305,23 @@ static bool valid_spellfile(const char_u *val)
/// Handle string options that need some action to perform when changed.
/// Returns NULL for success, or an error message for an error.
-static char_u *
-did_set_string_option(
- int opt_idx, // index in options[] table
- char_u **varp, // pointer to the option variable
- bool new_value_alloced, // new value was allocated
- char_u *oldval, // previous value of the option
- char_u *errbuf, // buffer for errors, or NULL
- size_t errbuflen, // length of errors buffer
- int opt_flags, // OPT_LOCAL and/or OPT_GLOBAL
- int *value_checked // value was checked to be safe, no
- // need to set P_INSECURE
-)
-{
- char_u *errmsg = NULL;
- char_u *s, *p;
+///
+/// @param opt_idx index in options[] table
+/// @param varp pointer to the option variable
+/// @param new_value_alloced new value was allocated
+/// @param oldval previous value of the option
+/// @param errbuf buffer for errors, or NULL
+/// @param errbuflen length of errors buffer
+/// @param opt_flags OPT_LOCAL and/or OPT_GLOBAL
+/// @param value_checked value was checked to be safe, no need to set P_INSECURE
+static char_u *did_set_string_option(int opt_idx, char_u **varp, bool new_value_alloced,
+ char_u *oldval, char_u *errbuf, size_t errbuflen,
+ int opt_flags, int *value_checked)
+{
+ char_u *errmsg = NULL;
+ char_u *s, *p;
int did_chartab = false;
- char_u **gvarp;
+ char_u **gvarp;
bool free_oldval = (options[opt_idx].flags & P_ALLOCED);
bool value_changed = false;
@@ -2345,7 +2335,7 @@ did_set_string_option(
errmsg = e_secure;
} else if (((options[opt_idx].flags & P_NFNAME)
&& vim_strpbrk(*varp, (char_u *)(secure ? "/\\*?[|;&<>\r\n"
- : "/\\*?[<>\r\n")) != NULL)
+ : "/\\*?[<>\r\n")) != NULL)
|| ((options[opt_idx].flags & P_NDNAME)
&& vim_strpbrk(*varp, (char_u *)"*?[|;&<>\r\n") != NULL)) {
// Check for a "normal" directory or file name in some options. Disallow a
@@ -2353,7 +2343,7 @@ did_set_string_option(
// are often illegal in a file name. Be more permissive if "secure" is off.
errmsg = e_invarg;
} else if (gvarp == &p_bkc) { // 'backupcopy'
- char_u *bkc = p_bkc;
+ char_u *bkc = p_bkc;
unsigned int *flags = &bkc_flags;
if (opt_flags & OPT_LOCAL) {
@@ -2407,6 +2397,8 @@ did_set_string_option(
os_setenv("VIMRUNTIME", "", 1);
didset_vimruntime = false;
}
+ } else if (varp == &p_rtp || varp == &p_pp) { // 'runtimepath' 'packpath'
+ runtime_search_path_invalidate();
} else if (varp == &curwin->w_p_culopt
|| gvarp == &curwin->w_allbuf_opt.wo_culopt) { // 'cursorlineopt'
if (**varp == NUL || fill_culopt_flags(*varp, curwin) != OK) {
@@ -2493,13 +2485,14 @@ ambw_end:
check_string_option(&p_bg);
init_highlight(false, false);
}
- } else
+ } else {
errmsg = e_invarg;
+ }
} else if (varp == &p_wim) { // 'wildmode'
if (check_opt_wim() == FAIL) {
errmsg = e_invarg;
}
- // 'wildoptions'
+ // 'wildoptions'
} else if (varp == &p_wop) {
if (opt_strings_flags(p_wop, p_wop_values, &wop_flags, true) != OK) {
errmsg = e_invarg;
@@ -2513,7 +2506,7 @@ ambw_end:
if (check_ei() == FAIL) {
errmsg = e_invarg;
}
- // 'encoding', 'fileencoding' and 'makeencoding'
+ // 'encoding', 'fileencoding' and 'makeencoding'
} else if (varp == &p_enc || gvarp == &p_fenc || gvarp == &p_menc) {
if (gvarp == &p_fenc) {
if (!MODIFIABLE(curbuf) && opt_flags != OPT_GLOBAL) {
@@ -2684,7 +2677,7 @@ ambw_end:
if (*p_vfile != NUL && verbose_open() == FAIL) {
errmsg = e_invarg;
}
- // 'shada'
+ // 'shada'
} else if (varp == &p_shada) {
// TODO(ZyX-I): Remove this code in the future, alongside with &viminfo
// option.
@@ -2692,7 +2685,7 @@ ambw_end:
? (shada_idx == -1
? ((shada_idx = findoption("shada")))
: shada_idx)
- : opt_idx);
+ : opt_idx);
// Update free_oldval now that we have the opt_idx for 'shada', otherwise
// there would be a disconnect between the check for P_ALLOCED at the start
// of the function and the set of P_ALLOCED at the end of the function.
@@ -2721,8 +2714,9 @@ ambw_end:
_("E526: Missing number after <%s>"),
transchar_byte(*(s - 1)));
errmsg = errbuf;
- } else
+ } else {
errmsg = (char_u *)"";
+ }
break;
}
}
@@ -2743,8 +2737,7 @@ ambw_end:
} else if (gvarp == &p_sbr) { // 'showbreak'
for (s = *varp; *s; ) {
if (ptr2cells(s) != 1) {
- errmsg = (char_u *)N_(
- "E595: 'showbreak' contains unprintable or wide character");
+ errmsg = (char_u *)N_("E595: 'showbreak' contains unprintable or wide character");
}
MB_PTR_ADV(s);
}
@@ -2769,7 +2762,6 @@ ambw_end:
stl_syntax &= ~flagval;
}
did_set_title();
-
} else if (varp == &p_sel) { // 'selection'
if (*p_sel == NUL
|| check_opt_strings(p_sel, p_sel_values, false) != OK) {
@@ -2888,8 +2880,9 @@ ambw_end:
} else if (gvarp == &p_cpt) {
// check if it is a valid value for 'complete' -- Acevedo
for (s = *varp; *s; ) {
- while (*s == ',' || *s == ' ')
+ while (*s == ',' || *s == ' ') {
s++;
+ }
if (!*s) {
break;
}
@@ -2912,8 +2905,9 @@ ambw_end:
_("E535: Illegal character after <%c>"),
*--s);
errmsg = errbuf;
- } else
+ } else {
errmsg = (char_u *)"";
+ }
break;
}
}
@@ -3024,8 +3018,7 @@ ambw_end:
}
} else if (gvarp == &p_cms) { // 'commentstring'
if (**varp != NUL && strstr((char *)(*varp), "%s") == NULL) {
- errmsg = (char_u *)N_(
- "E537: 'commentstring' must be empty or contain %s");
+ errmsg = (char_u *)N_("E537: 'commentstring' must be empty or contain %s");
}
} else if (varp == &p_fdo) { // 'foldopen'
if (opt_strings_flags(p_fdo, p_fdo_values, &fdo_flags, true) != OK) {
@@ -3068,11 +3061,11 @@ ambw_end:
} else if (gvarp == &p_cino) { // 'cinoptions'
// TODO(vim): recognize errors
parse_cino(curbuf);
- // inccommand
+ // inccommand
} else if (varp == &p_icm) {
- if (check_opt_strings(p_icm, p_icm_values, false) != OK) {
- errmsg = e_invarg;
- }
+ if (check_opt_strings(p_icm, p_icm_values, false) != OK) {
+ errmsg = e_invarg;
+ }
} else if (gvarp == &p_ft) {
if (!valid_filetype(*varp)) {
errmsg = e_invarg;
@@ -3274,7 +3267,7 @@ ambw_end:
}
if (varp == &(curwin->w_s->b_p_spl)) {
char_u fname[200];
- char_u *q = curwin->w_s->b_p_spl;
+ char_u *q = curwin->w_s->b_p_spl;
// Skip the first name if it is "cjk".
if (STRNCMP(q, "cjk,", 4) == 0) {
@@ -3295,7 +3288,7 @@ ambw_end:
if (p > q) {
vim_snprintf((char *)fname, sizeof(fname), "spell/%.*s.vim",
(int)(p - q), q);
- source_runtime(fname, DIP_ALL);
+ source_runtime((char *)fname, DIP_ALL);
}
}
}
@@ -3305,8 +3298,9 @@ ambw_end:
}
if (curwin->w_curswant != MAXCOL
- && (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0)
+ && (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0) {
curwin->w_set_curswant = true;
+ }
check_redraw(options[opt_idx].flags);
@@ -3334,8 +3328,7 @@ int check_signcolumn(char_u *val)
&& !STRNCMP(val, "auto:", 5)
&& ascii_isdigit(val[5])
&& val[6] == '-'
- && ascii_isdigit(val[7])
- ) {
+ && ascii_isdigit(val[7])) {
int min = val[5] - '0';
int max = val[7] - '0';
if (min < 1 || max < 2 || min > 8 || max > 9 || min >= max) {
@@ -3352,7 +3345,7 @@ int check_signcolumn(char_u *val)
/// @return error message, NULL if it's OK.
char_u *check_colorcolumn(win_T *wp)
{
- char_u *s;
+ char_u *s;
int col;
unsigned int count = 0;
int color_cols[256];
@@ -3446,9 +3439,9 @@ static char_u *set_chars_option(win_T *wp, char_u **varp, bool set)
int multispace_len = 0; // Length of lcs-multispace string
struct chars_tab {
- int *cp; ///< char value
- char *name; ///< char id
- int def; ///< default value
+ int *cp; ///< char value
+ char *name; ///< char id
+ int def; ///< default value
};
struct chars_tab *tab;
@@ -3517,7 +3510,7 @@ static char_u *set_chars_option(win_T *wp, char_u **varp, bool set)
xfree(wp->w_p_lcs_chars.multispace);
}
if (multispace_len > 0) {
- wp->w_p_lcs_chars.multispace = xmalloc((size_t)(multispace_len + 1) * sizeof(int));
+ wp->w_p_lcs_chars.multispace = xmalloc(((size_t)multispace_len + 1) * sizeof(int));
wp->w_p_lcs_chars.multispace[multispace_len] = NUL;
} else {
wp->w_p_lcs_chars.multispace = NULL;
@@ -3658,8 +3651,9 @@ char_u *check_stl_option(char_u *s)
}
if (*s == '.') {
s++;
- while (*s && ascii_isdigit(*s))
+ while (*s && ascii_isdigit(*s)) {
s++;
+ }
}
if (*s == '(') {
groupdepth++;
@@ -3687,7 +3681,7 @@ char_u *check_stl_option(char_u *s)
static char_u *did_set_spell_option(bool is_spellfile)
{
- char_u *errmsg = NULL;
+ char_u *errmsg = NULL;
if (is_spellfile) {
int l = (int)STRLEN(curwin->w_s->b_p_spf);
@@ -3714,8 +3708,8 @@ static char_u *did_set_spell_option(bool is_spellfile)
static char_u *compile_cap_prog(synblock_T *synblock)
FUNC_ATTR_NONNULL_ALL
{
- regprog_T *rp = synblock->b_cap_prog;
- char_u *re;
+ regprog_T *rp = synblock->b_cap_prog;
+ char_u *re;
if (synblock->b_p_spc == NULL || *synblock->b_p_spc == NUL) {
synblock->b_cap_prog = NULL;
@@ -3751,7 +3745,7 @@ static bool parse_winhl_opt(win_T *wp)
char *hi = colon+1;
char *commap = xstrchrnul(hi, ',');
int len = (int)(commap-hi);
- int hl_id = len ? syn_check_group((char_u *)hi, len) : -1;
+ int hl_id = len ? syn_check_group(hi, len) : -1;
if (strncmp("Normal", p, nlen) == 0) {
w_hl_id_normal = hl_id;
@@ -3814,8 +3808,7 @@ static void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx)
/// @param[in] opt_flags OPT_LOCAL and/or OPT_GLOBAL.
///
/// @return NULL on success, error message on error.
-static char *set_bool_option(const int opt_idx, char_u *const varp,
- const int value,
+static char *set_bool_option(const int opt_idx, char_u *const varp, const int value,
const int opt_flags)
{
int old_value = *(int *)varp;
@@ -3840,7 +3833,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
if ((int *)varp == &p_force_on && p_force_on == false) {
p_force_on = true;
return (char *)e_unsupportedoption;
- // Ensure that options set to p_force_off cannot be enabled.
+ // Ensure that options set to p_force_off cannot be enabled.
} else if ((int *)varp == &p_force_off && p_force_off == true) {
p_force_off = false;
return (char *)e_unsupportedoption;
@@ -3853,7 +3846,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
} else if ((int *)varp == &curwin->w_p_cul && !value && old_value) {
// 'cursorline'
reset_cursorline();
- // 'undofile'
+ // 'undofile'
} else if ((int *)varp == &curbuf->b_p_udf || (int *)varp == &p_udf) {
// Only take action when the option was set. When reset we do not
// delete the undo file, the option may be set again without making
@@ -3906,7 +3899,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
// when 'buflisted' changes, trigger autocommands
apply_autocmds(curbuf->b_p_bl ? EVENT_BUFADD : EVENT_BUFDELETE,
NULL, NULL, true, curbuf);
- } else if ((int *)varp == (int *)&curbuf->b_p_swf) {
+ } else if ((int *)varp == &curbuf->b_p_swf) {
// when 'swf' is set, create swapfile, when reset remove swapfile
if (curbuf->b_p_swf && p_uc) {
ml_open_file(curbuf); // create the swap file
@@ -3917,7 +3910,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
}
} else if ((int *)varp == &p_terse) {
// when 'terse' is set change 'shortmess'
- char_u *p;
+ char_u *p;
p = vim_strchr(p_shm, SHM_SEARCH);
@@ -3954,8 +3947,8 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
// when 'hlsearch' is set or reset: reset no_hlsearch
set_no_hlsearch(false);
} else if ((int *)varp == &curwin->w_p_scb) {
- // when 'scrollbind' is set: snapshot the current position to avoid a jump
- // at the end of normal_cmd()
+ // when 'scrollbind' is set: snapshot the current position to avoid a jump
+ // at the end of normal_cmd()
if (curwin->w_p_scb) {
do_check_scrollbind(false);
curwin->w_scbind_pos = curwin->w_topline;
@@ -4025,7 +4018,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
}
} else if ((int *)varp == &curwin->w_p_spell) { // 'spell'
if (curwin->w_p_spell) {
- char_u *errmsg = did_set_spelllang(curwin);
+ char_u *errmsg = did_set_spelllang(curwin);
if (errmsg != NULL) {
EMSG(_(errmsg));
}
@@ -4051,11 +4044,10 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
}
}
- /* Arabic requires a utf-8 encoding, inform the user if its not
- * set. */
+ // Arabic requires a utf-8 encoding, inform the user if its not
+ // set.
if (STRCMP(p_enc, "utf-8") != 0) {
- static char *w_arabic = N_(
- "W17: Arabic requires UTF-8, do ':set encoding=utf-8'");
+ static char *w_arabic = N_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'");
msg_source(HL_ATTR(HLF_W));
msg_attr(_(w_arabic), HL_ATTR(HLF_W));
@@ -4078,12 +4070,12 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
changed_window_setting();
}
- /* 'arabicshape' isn't reset, it is a global option and
- * another window may still need it "on". */
+ // 'arabicshape' isn't reset, it is a global option and
+ // another window may still need it "on".
}
- /* 'delcombine' isn't reset, it is a global option and another
- * window may still want it "on". */
+ // 'delcombine' isn't reset, it is a global option and another
+ // window may still want it "on".
// Revert to the default keymap
curbuf->b_p_iminsert = B_IMODE_NONE;
@@ -4115,7 +4107,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
set_vim_var_string(VV_OPTION_OLD, buf_old, -1);
set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
apply_autocmds(EVENT_OPTIONSET,
- (char_u *) options[opt_idx].fullname,
+ (char_u *)options[opt_idx].fullname,
NULL, false, NULL);
reset_v_option_vars();
}
@@ -4145,13 +4137,13 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
/// @param[in] opt_flags OPT_LOCAL, OPT_GLOBAL or OPT_MODELINE.
///
/// @return NULL on success, error message on error.
-static char *set_num_option(int opt_idx, char_u *varp, long value,
- char_u *errbuf, size_t errbuflen, int opt_flags)
+static char *set_num_option(int opt_idx, char_u *varp, long value, char_u *errbuf, size_t errbuflen,
+ int opt_flags)
{
- char_u *errmsg = NULL;
+ char_u *errmsg = NULL;
long old_value = *(long *)varp;
long old_Rows = Rows; // remember old Rows
- long *pp = (long *)varp;
+ long *pp = (long *)varp;
// Disallow changing some options from secure mode.
if ((secure || sandbox != 0)
@@ -4161,7 +4153,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
// Many number options assume their value is in the signed int range.
if (value < INT_MIN || value > INT_MAX) {
- return (char *)e_invarg;
+ return (char *)e_invarg;
}
// Options that need some validation.
@@ -4425,7 +4417,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
if (p_lines < min_rows() && full_screen) {
if (errbuf != NULL) {
vim_snprintf((char *)errbuf, errbuflen,
- _("E593: Need at least %d lines"), min_rows());
+ _("E593: Need at least %d lines"), min_rows());
errmsg = errbuf;
}
p_lines = min_rows();
@@ -4433,7 +4425,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
if (p_columns < MIN_COLUMNS && full_screen) {
if (errbuf != NULL) {
vim_snprintf((char *)errbuf, errbuflen,
- _("E594: Need at least %d columns"), MIN_COLUMNS);
+ _("E594: Need at least %d columns"), MIN_COLUMNS);
errmsg = errbuf;
}
p_columns = MIN_COLUMNS;
@@ -4478,7 +4470,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
}
win_comp_scroll(curwin);
} else if (curwin->w_p_scr <= 0) {
- // If 'scroll' became invalid because of a side effect silently adjust it.
+ // If 'scroll' became invalid because of a side effect silently adjust it.
curwin->w_p_scr = 1;
} else { // curwin->w_p_scr > curwin->w_height
curwin->w_p_scr = curwin->w_height;
@@ -4514,7 +4506,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
set_vim_var_string(VV_OPTION_OLD, buf_old, -1);
set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
apply_autocmds(EVENT_OPTIONSET,
- (char_u *) options[opt_idx].fullname,
+ (char_u *)options[opt_idx].fullname,
NULL, false, NULL);
reset_v_option_vars();
}
@@ -4534,8 +4526,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
return (char *)errmsg;
}
-static void trigger_optionsset_string(int opt_idx, int opt_flags,
- char *oldval, char *newval)
+static void trigger_optionsset_string(int opt_idx, int opt_flags, char *oldval, char *newval)
{
// Don't do this recursively.
if (oldval != NULL
@@ -4658,8 +4649,8 @@ bool is_tty_option(const char *name)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
return (name[0] == 't' && name[1] == '_')
- || strequal(name, "term")
- || strequal(name, "ttytype");
+ || strequal(name, "term")
+ || strequal(name, "ttytype");
}
#define TCO_BUFFER_SIZE 8
@@ -4738,18 +4729,15 @@ static int findoption(const char *const arg)
/// Gets the value for an option.
///
+/// @param stringval NULL when only checking existence
+///
/// @returns:
/// Number or Toggle option: 1, *numval gets value.
/// String option: 0, *stringval gets allocated string.
/// Hidden Number or Toggle option: -1.
/// hidden String option: -2.
/// unknown option: -3.
-int get_option_value(
- const char *name,
- long *numval,
- char_u **stringval, ///< NULL when only checking existence
- int opt_flags
-)
+int get_option_value(const char *name, long *numval, char_u **stringval, int opt_flags)
{
if (get_tty_option(name, (char **)stringval)) {
return 0;
@@ -4783,7 +4771,7 @@ int get_option_value(
if ((int *)varp == &curbuf->b_changed) {
*numval = curbufIsChanged();
} else {
- *numval = (long) *(int *)varp; // NOLINT(whitespace/cast)
+ *numval = (long)*(int *)varp; // NOLINT(whitespace/cast)
}
}
return 1;
@@ -4805,11 +4793,7 @@ int get_option_value(
// see SOPT_* in option_defs.h for other flags
//
// Possible opt_type values: see SREQ_* in option_defs.h
-int get_option_value_strict(char *name,
- int64_t *numval,
- char **stringval,
- int opt_type,
- void *from)
+int get_option_value_strict(char *name, int64_t *numval, char **stringval, int opt_type, void *from)
{
if (get_tty_option(name, stringval)) {
return SOPT_STRING | SOPT_GLOBAL;
@@ -4925,8 +4909,8 @@ int get_option_value_strict(char *name,
/// @param[in] opt_flags Flags: OPT_LOCAL, OPT_GLOBAL, or 0 (both).
///
/// @return NULL on success, error message on error.
-char *set_option_value(const char *const name, const long number,
- const char *const string, const int opt_flags)
+char *set_option_value(const char *const name, const long number, const char *const string,
+ const int opt_flags)
FUNC_ATTR_NONNULL_ARG(1)
{
if (is_tty_option(name)) {
@@ -4934,7 +4918,7 @@ char *set_option_value(const char *const name, const long number,
}
int opt_idx;
- char_u *varp;
+ char_u *varp;
opt_idx = findoption(name);
if (opt_idx < 0) {
@@ -4994,7 +4978,7 @@ int find_key_option_len(const char_u *arg_arg, size_t len, bool has_lt)
// add_termcap_entry().
if (len >= 4 && arg[0] == 't' && arg[1] == '_') {
key = TERMCAP2KEY(arg[2], arg[3]);
- } else if (has_lt) {
+ } else if (has_lt) {
arg--; // put arg at the '<'
modifiers = 0;
key = find_special_key(&arg, len + 1, &modifiers, true, true, false);
@@ -5012,15 +4996,13 @@ static int find_key_option(const char_u *arg, bool has_lt)
/// if 'all' == 0: show changed options
/// if 'all' == 1: show all normal options
-static void
-showoptions(
- int all,
- int opt_flags // OPT_LOCAL and/or OPT_GLOBAL
-)
+///
+/// @param opt_flags OPT_LOCAL and/or OPT_GLOBAL
+static void showoptions(int all, int opt_flags)
{
- vimoption_T *p;
+ vimoption_T *p;
int col;
- char_u *varp;
+ char_u *varp;
int item_count;
int run;
int row, rows;
@@ -5155,13 +5137,11 @@ void ui_refresh_options(void)
/// showoneopt: show the value of one option
/// must not be called with a hidden option!
-static void
-showoneopt(
- vimoption_T *p,
- int opt_flags // OPT_LOCAL or OPT_GLOBAL
-)
+///
+/// @param opt_flags OPT_LOCAL or OPT_GLOBAL
+static void showoneopt(vimoption_T *p, int opt_flags)
{
- char_u *varp;
+ char_u *varp;
int save_silent = silent_mode;
silent_mode = false;
@@ -5212,11 +5192,11 @@ showoneopt(
/// Return FAIL on error, OK otherwise.
int makeset(FILE *fd, int opt_flags, int local_only)
{
- vimoption_T *p;
- char_u *varp; // currently used value
- char_u *varp_fresh; // local value
- char_u *varp_local = NULL; // fresh value
- char *cmd;
+ vimoption_T *p;
+ char_u *varp; // currently used value
+ char_u *varp_fresh; // local value
+ char_u *varp_local = NULL; // fresh value
+ char *cmd;
int round;
int pri;
@@ -5238,8 +5218,8 @@ int makeset(FILE *fd, int opt_flags, int local_only)
continue;
}
- /* Do not store options like 'bufhidden' and 'syntax' in a vimrc
- * file, they are always buffer-specific. */
+ // Do not store options like 'bufhidden' and 'syntax' in a vimrc
+ // file, they are always buffer-specific.
if ((opt_flags & OPT_GLOBAL) && (p->flags & P_NOGLOB)) {
continue;
}
@@ -5340,29 +5320,28 @@ int makefoldset(FILE *fd)
|| put_setnum(fd, "setlocal", "fdl", &curwin->w_p_fdl) == FAIL
|| put_setnum(fd, "setlocal", "fml", &curwin->w_p_fml) == FAIL
|| put_setnum(fd, "setlocal", "fdn", &curwin->w_p_fdn) == FAIL
- || put_setbool(fd, "setlocal", "fen", curwin->w_p_fen) == FAIL
- ) {
+ || put_setbool(fd, "setlocal", "fen",
+ curwin->w_p_fen) == FAIL) {
return FAIL;
}
return OK;
}
-static int put_setstring(FILE *fd, char *cmd, char *name,
- char_u **valuep, uint64_t flags)
+static int put_setstring(FILE *fd, char *cmd, char *name, char_u **valuep, uint64_t flags)
{
- char_u *s;
- char_u *buf = NULL;
- char_u *part = NULL;
- char_u *p;
+ char_u *s;
+ char_u *buf = NULL;
+ char_u *part = NULL;
+ char_u *p;
if (fprintf(fd, "%s %s=", cmd, name) < 0) {
return FAIL;
}
if (*valuep != NULL) {
- /* Output 'pastetoggle' as key names. For other
- * options some characters have to be escaped with
- * CTRL-V or backslash */
+ // Output 'pastetoggle' as key names. For other
+ // options some characters have to be escaped with
+ // CTRL-V or backslash
if (valuep == &p_pt) {
s = *valuep;
while (*s != NUL) {
@@ -5380,7 +5359,7 @@ static int put_setstring(FILE *fd, char *cmd, char *name,
home_replace(NULL, *valuep, buf, size, false);
// If the option value is longer than MAXPATHL, we need to append
- // search comma separated part of the option separately, so that it
+ // each comma separated part of the option separately, so that it
// can be expanded when read back.
if (size >= MAXPATHL && (flags & P_COMMA) != 0
&& vim_strchr(*valuep, ',') != NULL) {
@@ -5392,15 +5371,15 @@ static int put_setstring(FILE *fd, char *cmd, char *name,
}
p = buf;
while (*p != NUL) {
- // for each comma separated option part, append value to
- // the option, :set rtp+=value
- if (fprintf(fd, "%s %s+=", cmd, name) < 0) {
- goto fail;
- }
- (void)copy_option_part(&p, part, size, ",");
- if (put_escstr(fd, part, 2) == FAIL || put_eol(fd) == FAIL) {
- goto fail;
- }
+ // for each comma separated option part, append value to
+ // the option, :set rtp+=value
+ if (fprintf(fd, "%s %s+=", cmd, name) < 0) {
+ goto fail;
+ }
+ (void)copy_option_part(&p, part, size, ",");
+ if (put_escstr(fd, part, 2) == FAIL || put_eol(fd) == FAIL) {
+ goto fail;
+ }
}
xfree(buf);
xfree(part);
@@ -5516,124 +5495,149 @@ void unset_global_local_option(char *name, void *from)
switch ((int)p->indir)
{
- // global option with local value: use local value if it's been set
+ // global option with local value: use local value if it's been set
+ case PV_EP:
+ clear_string_option(&buf->b_p_ep);
+ break;
+ case PV_KP:
+ clear_string_option(&buf->b_p_kp);
+ break;
+ case PV_PATH:
+ clear_string_option(&buf->b_p_path);
+ break;
+ case PV_AR:
+ buf->b_p_ar = -1;
+ break;
+ case PV_BKC:
+ clear_string_option(&buf->b_p_bkc);
+ buf->b_bkc_flags = 0;
+ break;
+ case PV_TAGS:
+ clear_string_option(&buf->b_p_tags);
+ break;
+ case PV_TC:
+ clear_string_option(&buf->b_p_tc);
+ buf->b_tc_flags = 0;
+ break;
+ case PV_SISO:
+ curwin->w_p_siso = -1;
+ break;
+ case PV_SO:
+ curwin->w_p_so = -1;
+ break;
+ case PV_DEF:
+ clear_string_option(&buf->b_p_def);
+ break;
+ case PV_INC:
+ clear_string_option(&buf->b_p_inc);
+ break;
+ case PV_DICT:
+ clear_string_option(&buf->b_p_dict);
+ break;
+ case PV_TSR:
+ clear_string_option(&buf->b_p_tsr);
+ break;
+ case PV_FP:
+ clear_string_option(&buf->b_p_fp);
+ break;
+ case PV_EFM:
+ clear_string_option(&buf->b_p_efm);
+ break;
+ case PV_GP:
+ clear_string_option(&buf->b_p_gp);
+ break;
+ case PV_MP:
+ clear_string_option(&buf->b_p_mp);
+ break;
+ case PV_SBR:
+ clear_string_option(&((win_T *)from)->w_p_sbr);
+ break;
+ case PV_STL:
+ clear_string_option(&((win_T *)from)->w_p_stl);
+ break;
+ case PV_UL:
+ buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
+ break;
+ case PV_LW:
+ clear_string_option(&buf->b_p_lw);
+ break;
+ case PV_MENC:
+ clear_string_option(&buf->b_p_menc);
+ break;
+ case PV_LCS:
+ clear_string_option(&((win_T *)from)->w_p_lcs);
+ set_chars_option((win_T *)from, &((win_T *)from)->w_p_lcs, true);
+ redraw_later((win_T *)from, NOT_VALID);
+ break;
+ case PV_FCS:
+ clear_string_option(&((win_T *)from)->w_p_fcs);
+ set_chars_option((win_T *)from, &((win_T *)from)->w_p_fcs, true);
+ redraw_later((win_T *)from, NOT_VALID);
+ break;
+ }
+}
+
+/// Get pointer to option variable, depending on local or global scope.
+static char_u *get_varp_scope(vimoption_T *p, int opt_flags)
+{
+ if ((opt_flags & OPT_GLOBAL) && p->indir != PV_NONE) {
+ if (p->var == VAR_WIN) {
+ return (char_u *)GLOBAL_WO(get_varp(p));
+ }
+ return p->var;
+ }
+ if ((opt_flags & OPT_LOCAL) && ((int)p->indir & PV_BOTH)) {
+ switch ((int)p->indir) {
+ case PV_FP:
+ return (char_u *)&(curbuf->b_p_fp);
+ case PV_EFM:
+ return (char_u *)&(curbuf->b_p_efm);
+ case PV_GP:
+ return (char_u *)&(curbuf->b_p_gp);
+ case PV_MP:
+ return (char_u *)&(curbuf->b_p_mp);
case PV_EP:
- clear_string_option(&buf->b_p_ep);
- break;
+ return (char_u *)&(curbuf->b_p_ep);
case PV_KP:
- clear_string_option(&buf->b_p_kp);
- break;
+ return (char_u *)&(curbuf->b_p_kp);
case PV_PATH:
- clear_string_option(&buf->b_p_path);
- break;
+ return (char_u *)&(curbuf->b_p_path);
case PV_AR:
- buf->b_p_ar = -1;
- break;
- case PV_BKC:
- clear_string_option(&buf->b_p_bkc);
- buf->b_bkc_flags = 0;
- break;
+ return (char_u *)&(curbuf->b_p_ar);
case PV_TAGS:
- clear_string_option(&buf->b_p_tags);
- break;
+ return (char_u *)&(curbuf->b_p_tags);
case PV_TC:
- clear_string_option(&buf->b_p_tc);
- buf->b_tc_flags = 0;
- break;
+ return (char_u *)&(curbuf->b_p_tc);
case PV_SISO:
- curwin->w_p_siso = -1;
- break;
+ return (char_u *)&(curwin->w_p_siso);
case PV_SO:
- curwin->w_p_so = -1;
- break;
+ return (char_u *)&(curwin->w_p_so);
case PV_DEF:
- clear_string_option(&buf->b_p_def);
- break;
+ return (char_u *)&(curbuf->b_p_def);
case PV_INC:
- clear_string_option(&buf->b_p_inc);
- break;
+ return (char_u *)&(curbuf->b_p_inc);
case PV_DICT:
- clear_string_option(&buf->b_p_dict);
- break;
+ return (char_u *)&(curbuf->b_p_dict);
case PV_TSR:
- clear_string_option(&buf->b_p_tsr);
- break;
- case PV_FP:
- clear_string_option(&buf->b_p_fp);
- break;
- case PV_EFM:
- clear_string_option(&buf->b_p_efm);
- break;
- case PV_GP:
- clear_string_option(&buf->b_p_gp);
- break;
- case PV_MP:
- clear_string_option(&buf->b_p_mp);
- break;
+ return (char_u *)&(curbuf->b_p_tsr);
+ case PV_TFU:
+ return (char_u *)&(curbuf->b_p_tfu);
case PV_SBR:
- clear_string_option(&((win_T *)from)->w_p_sbr);
- break;
+ return (char_u *)&(curwin->w_p_sbr);
case PV_STL:
- clear_string_option(&((win_T *)from)->w_p_stl);
- break;
+ return (char_u *)&(curwin->w_p_stl);
case PV_UL:
- buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
- break;
+ return (char_u *)&(curbuf->b_p_ul);
case PV_LW:
- clear_string_option(&buf->b_p_lw);
- break;
+ return (char_u *)&(curbuf->b_p_lw);
+ case PV_BKC:
+ return (char_u *)&(curbuf->b_p_bkc);
case PV_MENC:
- clear_string_option(&buf->b_p_menc);
- break;
- case PV_LCS:
- clear_string_option(&((win_T *)from)->w_p_lcs);
- set_chars_option((win_T *)from, &((win_T *)from)->w_p_lcs, true);
- redraw_later((win_T *)from, NOT_VALID);
- break;
+ return (char_u *)&(curbuf->b_p_menc);
case PV_FCS:
- clear_string_option(&((win_T *)from)->w_p_fcs);
- set_chars_option((win_T *)from, &((win_T *)from)->w_p_fcs, true);
- redraw_later((win_T *)from, NOT_VALID);
- break;
- }
-}
-
-/// Get pointer to option variable, depending on local or global scope.
-static char_u *get_varp_scope(vimoption_T *p, int opt_flags)
-{
- if ((opt_flags & OPT_GLOBAL) && p->indir != PV_NONE) {
- if (p->var == VAR_WIN) {
- return (char_u *)GLOBAL_WO(get_varp(p));
- }
- return p->var;
- }
- if ((opt_flags & OPT_LOCAL) && ((int)p->indir & PV_BOTH)) {
- switch ((int)p->indir) {
- case PV_FP: return (char_u *)&(curbuf->b_p_fp);
- case PV_EFM: return (char_u *)&(curbuf->b_p_efm);
- case PV_GP: return (char_u *)&(curbuf->b_p_gp);
- case PV_MP: return (char_u *)&(curbuf->b_p_mp);
- case PV_EP: return (char_u *)&(curbuf->b_p_ep);
- case PV_KP: return (char_u *)&(curbuf->b_p_kp);
- case PV_PATH: return (char_u *)&(curbuf->b_p_path);
- case PV_AR: return (char_u *)&(curbuf->b_p_ar);
- case PV_TAGS: return (char_u *)&(curbuf->b_p_tags);
- case PV_TC: return (char_u *)&(curbuf->b_p_tc);
- case PV_SISO: return (char_u *)&(curwin->w_p_siso);
- case PV_SO: return (char_u *)&(curwin->w_p_so);
- case PV_DEF: return (char_u *)&(curbuf->b_p_def);
- case PV_INC: return (char_u *)&(curbuf->b_p_inc);
- case PV_DICT: return (char_u *)&(curbuf->b_p_dict);
- case PV_TSR: return (char_u *)&(curbuf->b_p_tsr);
- case PV_TFU: return (char_u *)&(curbuf->b_p_tfu);
- case PV_SBR: return (char_u *)&(curwin->w_p_sbr);
- case PV_STL: return (char_u *)&(curwin->w_p_stl);
- case PV_UL: return (char_u *)&(curbuf->b_p_ul);
- case PV_LW: return (char_u *)&(curbuf->b_p_lw);
- case PV_BKC: return (char_u *)&(curbuf->b_p_bkc);
- case PV_MENC: return (char_u *)&(curbuf->b_p_menc);
- case PV_FCS: return (char_u *)&(curwin->w_p_fcs);
- case PV_LCS: return (char_u *)&(curwin->w_p_lcs);
+ return (char_u *)&(curwin->w_p_fcs);
+ case PV_LCS:
+ return (char_u *)&(curwin->w_p_lcs);
}
return NULL; // "cannot happen"
}
@@ -5649,163 +5653,290 @@ static char_u *get_varp(vimoption_T *p)
}
switch ((int)p->indir) {
- case PV_NONE: return p->var;
+ case PV_NONE:
+ return p->var;
// global option with local value: use local value if it's been set
- case PV_EP: return *curbuf->b_p_ep != NUL
+ case PV_EP:
+ return *curbuf->b_p_ep != NUL
? (char_u *)&curbuf->b_p_ep : p->var;
- case PV_KP: return *curbuf->b_p_kp != NUL
+ case PV_KP:
+ return *curbuf->b_p_kp != NUL
? (char_u *)&curbuf->b_p_kp : p->var;
- case PV_PATH: return *curbuf->b_p_path != NUL
+ case PV_PATH:
+ return *curbuf->b_p_path != NUL
? (char_u *)&(curbuf->b_p_path) : p->var;
- case PV_AR: return curbuf->b_p_ar >= 0
+ case PV_AR:
+ return curbuf->b_p_ar >= 0
? (char_u *)&(curbuf->b_p_ar) : p->var;
- case PV_TAGS: return *curbuf->b_p_tags != NUL
+ case PV_TAGS:
+ return *curbuf->b_p_tags != NUL
? (char_u *)&(curbuf->b_p_tags) : p->var;
- case PV_TC: return *curbuf->b_p_tc != NUL
+ case PV_TC:
+ return *curbuf->b_p_tc != NUL
? (char_u *)&(curbuf->b_p_tc) : p->var;
- case PV_SISO: return curwin->w_p_siso >= 0
+ case PV_SISO:
+ return curwin->w_p_siso >= 0
? (char_u *)&(curwin->w_p_siso) : p->var;
- case PV_SO: return curwin->w_p_so >= 0
+ case PV_SO:
+ return curwin->w_p_so >= 0
? (char_u *)&(curwin->w_p_so) : p->var;
- case PV_BKC: return *curbuf->b_p_bkc != NUL
+ case PV_BKC:
+ return *curbuf->b_p_bkc != NUL
? (char_u *)&(curbuf->b_p_bkc) : p->var;
- case PV_DEF: return *curbuf->b_p_def != NUL
+ case PV_DEF:
+ return *curbuf->b_p_def != NUL
? (char_u *)&(curbuf->b_p_def) : p->var;
- case PV_INC: return *curbuf->b_p_inc != NUL
+ case PV_INC:
+ return *curbuf->b_p_inc != NUL
? (char_u *)&(curbuf->b_p_inc) : p->var;
- case PV_DICT: return *curbuf->b_p_dict != NUL
+ case PV_DICT:
+ return *curbuf->b_p_dict != NUL
? (char_u *)&(curbuf->b_p_dict) : p->var;
- case PV_TSR: return *curbuf->b_p_tsr != NUL
+ case PV_TSR:
+ return *curbuf->b_p_tsr != NUL
? (char_u *)&(curbuf->b_p_tsr) : p->var;
- case PV_FP: return *curbuf->b_p_fp != NUL
+ case PV_FP:
+ return *curbuf->b_p_fp != NUL
? (char_u *)&(curbuf->b_p_fp) : p->var;
- case PV_EFM: return *curbuf->b_p_efm != NUL
+ case PV_EFM:
+ return *curbuf->b_p_efm != NUL
? (char_u *)&(curbuf->b_p_efm) : p->var;
- case PV_GP: return *curbuf->b_p_gp != NUL
+ case PV_GP:
+ return *curbuf->b_p_gp != NUL
? (char_u *)&(curbuf->b_p_gp) : p->var;
- case PV_MP: return *curbuf->b_p_mp != NUL
+ case PV_MP:
+ return *curbuf->b_p_mp != NUL
? (char_u *)&(curbuf->b_p_mp) : p->var;
- case PV_SBR: return *curwin->w_p_sbr != NUL
+ case PV_SBR:
+ return *curwin->w_p_sbr != NUL
? (char_u *)&(curwin->w_p_sbr) : p->var;
- case PV_STL: return *curwin->w_p_stl != NUL
+ case PV_STL:
+ return *curwin->w_p_stl != NUL
? (char_u *)&(curwin->w_p_stl) : p->var;
- case PV_UL: return curbuf->b_p_ul != NO_LOCAL_UNDOLEVEL
+ case PV_UL:
+ return curbuf->b_p_ul != NO_LOCAL_UNDOLEVEL
? (char_u *)&(curbuf->b_p_ul) : p->var;
- case PV_LW: return *curbuf->b_p_lw != NUL
+ case PV_LW:
+ return *curbuf->b_p_lw != NUL
? (char_u *)&(curbuf->b_p_lw) : p->var;
- case PV_MENC: return *curbuf->b_p_menc != NUL
+ case PV_MENC:
+ return *curbuf->b_p_menc != NUL
? (char_u *)&(curbuf->b_p_menc) : p->var;
- case PV_FCS: return *curwin->w_p_fcs != NUL
+ case PV_FCS:
+ return *curwin->w_p_fcs != NUL
? (char_u *)&(curwin->w_p_fcs) : p->var;
- case PV_LCS: return *curwin->w_p_lcs != NUL
+ case PV_LCS:
+ return *curwin->w_p_lcs != NUL
? (char_u *)&(curwin->w_p_lcs) : p->var;
- case PV_ARAB: return (char_u *)&(curwin->w_p_arab);
- case PV_LIST: return (char_u *)&(curwin->w_p_list);
- case PV_SPELL: return (char_u *)&(curwin->w_p_spell);
- case PV_CUC: return (char_u *)&(curwin->w_p_cuc);
- case PV_CUL: return (char_u *)&(curwin->w_p_cul);
- case PV_CULOPT: return (char_u *)&(curwin->w_p_culopt);
- case PV_CC: return (char_u *)&(curwin->w_p_cc);
- case PV_DIFF: return (char_u *)&(curwin->w_p_diff);
- case PV_FDC: return (char_u *)&(curwin->w_p_fdc);
- case PV_FEN: return (char_u *)&(curwin->w_p_fen);
- case PV_FDI: return (char_u *)&(curwin->w_p_fdi);
- case PV_FDL: return (char_u *)&(curwin->w_p_fdl);
- case PV_FDM: return (char_u *)&(curwin->w_p_fdm);
- case PV_FML: return (char_u *)&(curwin->w_p_fml);
- case PV_FDN: return (char_u *)&(curwin->w_p_fdn);
- case PV_FDE: return (char_u *)&(curwin->w_p_fde);
- case PV_FDT: return (char_u *)&(curwin->w_p_fdt);
- case PV_FMR: return (char_u *)&(curwin->w_p_fmr);
- case PV_NU: return (char_u *)&(curwin->w_p_nu);
- case PV_RNU: return (char_u *)&(curwin->w_p_rnu);
- case PV_NUW: return (char_u *)&(curwin->w_p_nuw);
- case PV_WFH: return (char_u *)&(curwin->w_p_wfh);
- case PV_WFW: return (char_u *)&(curwin->w_p_wfw);
- case PV_PVW: return (char_u *)&(curwin->w_p_pvw);
- case PV_RL: return (char_u *)&(curwin->w_p_rl);
- case PV_RLC: return (char_u *)&(curwin->w_p_rlc);
- case PV_SCROLL: return (char_u *)&(curwin->w_p_scr);
- case PV_WRAP: return (char_u *)&(curwin->w_p_wrap);
- case PV_LBR: return (char_u *)&(curwin->w_p_lbr);
- case PV_BRI: return (char_u *)&(curwin->w_p_bri);
- case PV_BRIOPT: return (char_u *)&(curwin->w_p_briopt);
- case PV_SCBIND: return (char_u *)&(curwin->w_p_scb);
- case PV_CRBIND: return (char_u *)&(curwin->w_p_crb);
- case PV_COCU: return (char_u *)&(curwin->w_p_cocu);
- case PV_COLE: return (char_u *)&(curwin->w_p_cole);
-
- case PV_AI: return (char_u *)&(curbuf->b_p_ai);
- case PV_BIN: return (char_u *)&(curbuf->b_p_bin);
- case PV_BOMB: return (char_u *)&(curbuf->b_p_bomb);
- case PV_BH: return (char_u *)&(curbuf->b_p_bh);
- case PV_BT: return (char_u *)&(curbuf->b_p_bt);
- case PV_BL: return (char_u *)&(curbuf->b_p_bl);
- case PV_CHANNEL:return (char_u *)&(curbuf->b_p_channel);
- case PV_CI: return (char_u *)&(curbuf->b_p_ci);
- case PV_CIN: return (char_u *)&(curbuf->b_p_cin);
- case PV_CINK: return (char_u *)&(curbuf->b_p_cink);
- case PV_CINO: return (char_u *)&(curbuf->b_p_cino);
- case PV_CINW: return (char_u *)&(curbuf->b_p_cinw);
- case PV_COM: return (char_u *)&(curbuf->b_p_com);
- case PV_CMS: return (char_u *)&(curbuf->b_p_cms);
- case PV_CPT: return (char_u *)&(curbuf->b_p_cpt);
-# ifdef BACKSLASH_IN_FILENAME
- case PV_CSL: return (char_u *)&(curbuf->b_p_csl);
-# endif
- case PV_CFU: return (char_u *)&(curbuf->b_p_cfu);
- case PV_OFU: return (char_u *)&(curbuf->b_p_ofu);
- case PV_EOL: return (char_u *)&(curbuf->b_p_eol);
- case PV_FIXEOL: return (char_u *)&(curbuf->b_p_fixeol);
- case PV_ET: return (char_u *)&(curbuf->b_p_et);
- case PV_FENC: return (char_u *)&(curbuf->b_p_fenc);
- case PV_FF: return (char_u *)&(curbuf->b_p_ff);
- case PV_FT: return (char_u *)&(curbuf->b_p_ft);
- case PV_FO: return (char_u *)&(curbuf->b_p_fo);
- case PV_FLP: return (char_u *)&(curbuf->b_p_flp);
- case PV_IMI: return (char_u *)&(curbuf->b_p_iminsert);
- case PV_IMS: return (char_u *)&(curbuf->b_p_imsearch);
- case PV_INF: return (char_u *)&(curbuf->b_p_inf);
- case PV_ISK: return (char_u *)&(curbuf->b_p_isk);
- case PV_INEX: return (char_u *)&(curbuf->b_p_inex);
- case PV_INDE: return (char_u *)&(curbuf->b_p_inde);
- case PV_INDK: return (char_u *)&(curbuf->b_p_indk);
- case PV_FEX: return (char_u *)&(curbuf->b_p_fex);
- case PV_LISP: return (char_u *)&(curbuf->b_p_lisp);
- case PV_ML: return (char_u *)&(curbuf->b_p_ml);
- case PV_MPS: return (char_u *)&(curbuf->b_p_mps);
- case PV_MA: return (char_u *)&(curbuf->b_p_ma);
- case PV_MOD: return (char_u *)&(curbuf->b_changed);
- case PV_NF: return (char_u *)&(curbuf->b_p_nf);
- case PV_PI: return (char_u *)&(curbuf->b_p_pi);
- case PV_QE: return (char_u *)&(curbuf->b_p_qe);
- case PV_RO: return (char_u *)&(curbuf->b_p_ro);
- case PV_SCBK: return (char_u *)&(curbuf->b_p_scbk);
- case PV_SI: return (char_u *)&(curbuf->b_p_si);
- case PV_STS: return (char_u *)&(curbuf->b_p_sts);
- case PV_SUA: return (char_u *)&(curbuf->b_p_sua);
- case PV_SWF: return (char_u *)&(curbuf->b_p_swf);
- case PV_SMC: return (char_u *)&(curbuf->b_p_smc);
- case PV_SYN: return (char_u *)&(curbuf->b_p_syn);
- case PV_SPC: return (char_u *)&(curwin->w_s->b_p_spc);
- case PV_SPF: return (char_u *)&(curwin->w_s->b_p_spf);
- case PV_SPL: return (char_u *)&(curwin->w_s->b_p_spl);
- case PV_SPO: return (char_u *)&(curwin->w_s->b_p_spo);
- case PV_SW: return (char_u *)&(curbuf->b_p_sw);
- case PV_TFU: return (char_u *)&(curbuf->b_p_tfu);
- case PV_TS: return (char_u *)&(curbuf->b_p_ts);
- case PV_TW: return (char_u *)&(curbuf->b_p_tw);
- case PV_UDF: return (char_u *)&(curbuf->b_p_udf);
- case PV_WM: return (char_u *)&(curbuf->b_p_wm);
- case PV_VSTS: return (char_u *)&(curbuf->b_p_vsts);
- case PV_VTS: return (char_u *)&(curbuf->b_p_vts);
- case PV_KMAP: return (char_u *)&(curbuf->b_p_keymap);
- case PV_SCL: return (char_u *)&(curwin->w_p_scl);
- case PV_WINHL: return (char_u *)&(curwin->w_p_winhl);
- case PV_WINBL: return (char_u *)&(curwin->w_p_winbl);
- default: IEMSG(_("E356: get_varp ERROR"));
+ case PV_ARAB:
+ return (char_u *)&(curwin->w_p_arab);
+ case PV_LIST:
+ return (char_u *)&(curwin->w_p_list);
+ case PV_SPELL:
+ return (char_u *)&(curwin->w_p_spell);
+ case PV_CUC:
+ return (char_u *)&(curwin->w_p_cuc);
+ case PV_CUL:
+ return (char_u *)&(curwin->w_p_cul);
+ case PV_CULOPT:
+ return (char_u *)&(curwin->w_p_culopt);
+ case PV_CC:
+ return (char_u *)&(curwin->w_p_cc);
+ case PV_DIFF:
+ return (char_u *)&(curwin->w_p_diff);
+ case PV_FDC:
+ return (char_u *)&(curwin->w_p_fdc);
+ case PV_FEN:
+ return (char_u *)&(curwin->w_p_fen);
+ case PV_FDI:
+ return (char_u *)&(curwin->w_p_fdi);
+ case PV_FDL:
+ return (char_u *)&(curwin->w_p_fdl);
+ case PV_FDM:
+ return (char_u *)&(curwin->w_p_fdm);
+ case PV_FML:
+ return (char_u *)&(curwin->w_p_fml);
+ case PV_FDN:
+ return (char_u *)&(curwin->w_p_fdn);
+ case PV_FDE:
+ return (char_u *)&(curwin->w_p_fde);
+ case PV_FDT:
+ return (char_u *)&(curwin->w_p_fdt);
+ case PV_FMR:
+ return (char_u *)&(curwin->w_p_fmr);
+ case PV_NU:
+ return (char_u *)&(curwin->w_p_nu);
+ case PV_RNU:
+ return (char_u *)&(curwin->w_p_rnu);
+ case PV_NUW:
+ return (char_u *)&(curwin->w_p_nuw);
+ case PV_WFH:
+ return (char_u *)&(curwin->w_p_wfh);
+ case PV_WFW:
+ return (char_u *)&(curwin->w_p_wfw);
+ case PV_PVW:
+ return (char_u *)&(curwin->w_p_pvw);
+ case PV_RL:
+ return (char_u *)&(curwin->w_p_rl);
+ case PV_RLC:
+ return (char_u *)&(curwin->w_p_rlc);
+ case PV_SCROLL:
+ return (char_u *)&(curwin->w_p_scr);
+ case PV_WRAP:
+ return (char_u *)&(curwin->w_p_wrap);
+ case PV_LBR:
+ return (char_u *)&(curwin->w_p_lbr);
+ case PV_BRI:
+ return (char_u *)&(curwin->w_p_bri);
+ case PV_BRIOPT:
+ return (char_u *)&(curwin->w_p_briopt);
+ case PV_SCBIND:
+ return (char_u *)&(curwin->w_p_scb);
+ case PV_CRBIND:
+ return (char_u *)&(curwin->w_p_crb);
+ case PV_COCU:
+ return (char_u *)&(curwin->w_p_cocu);
+ case PV_COLE:
+ return (char_u *)&(curwin->w_p_cole);
+
+ case PV_AI:
+ return (char_u *)&(curbuf->b_p_ai);
+ case PV_BIN:
+ return (char_u *)&(curbuf->b_p_bin);
+ case PV_BOMB:
+ return (char_u *)&(curbuf->b_p_bomb);
+ case PV_BH:
+ return (char_u *)&(curbuf->b_p_bh);
+ case PV_BT:
+ return (char_u *)&(curbuf->b_p_bt);
+ case PV_BL:
+ return (char_u *)&(curbuf->b_p_bl);
+ case PV_CHANNEL:
+ return (char_u *)&(curbuf->b_p_channel);
+ case PV_CI:
+ return (char_u *)&(curbuf->b_p_ci);
+ case PV_CIN:
+ return (char_u *)&(curbuf->b_p_cin);
+ case PV_CINK:
+ return (char_u *)&(curbuf->b_p_cink);
+ case PV_CINO:
+ return (char_u *)&(curbuf->b_p_cino);
+ case PV_CINW:
+ return (char_u *)&(curbuf->b_p_cinw);
+ case PV_COM:
+ return (char_u *)&(curbuf->b_p_com);
+ case PV_CMS:
+ return (char_u *)&(curbuf->b_p_cms);
+ case PV_CPT:
+ return (char_u *)&(curbuf->b_p_cpt);
+#ifdef BACKSLASH_IN_FILENAME
+ case PV_CSL:
+ return (char_u *)&(curbuf->b_p_csl);
+#endif
+ case PV_CFU:
+ return (char_u *)&(curbuf->b_p_cfu);
+ case PV_OFU:
+ return (char_u *)&(curbuf->b_p_ofu);
+ case PV_EOL:
+ return (char_u *)&(curbuf->b_p_eol);
+ case PV_FIXEOL:
+ return (char_u *)&(curbuf->b_p_fixeol);
+ case PV_ET:
+ return (char_u *)&(curbuf->b_p_et);
+ case PV_FENC:
+ return (char_u *)&(curbuf->b_p_fenc);
+ case PV_FF:
+ return (char_u *)&(curbuf->b_p_ff);
+ case PV_FT:
+ return (char_u *)&(curbuf->b_p_ft);
+ case PV_FO:
+ return (char_u *)&(curbuf->b_p_fo);
+ case PV_FLP:
+ return (char_u *)&(curbuf->b_p_flp);
+ case PV_IMI:
+ return (char_u *)&(curbuf->b_p_iminsert);
+ case PV_IMS:
+ return (char_u *)&(curbuf->b_p_imsearch);
+ case PV_INF:
+ return (char_u *)&(curbuf->b_p_inf);
+ case PV_ISK:
+ return (char_u *)&(curbuf->b_p_isk);
+ case PV_INEX:
+ return (char_u *)&(curbuf->b_p_inex);
+ case PV_INDE:
+ return (char_u *)&(curbuf->b_p_inde);
+ case PV_INDK:
+ return (char_u *)&(curbuf->b_p_indk);
+ case PV_FEX:
+ return (char_u *)&(curbuf->b_p_fex);
+ case PV_LISP:
+ return (char_u *)&(curbuf->b_p_lisp);
+ case PV_ML:
+ return (char_u *)&(curbuf->b_p_ml);
+ case PV_MPS:
+ return (char_u *)&(curbuf->b_p_mps);
+ case PV_MA:
+ return (char_u *)&(curbuf->b_p_ma);
+ case PV_MOD:
+ return (char_u *)&(curbuf->b_changed);
+ case PV_NF:
+ return (char_u *)&(curbuf->b_p_nf);
+ case PV_PI:
+ return (char_u *)&(curbuf->b_p_pi);
+ case PV_QE:
+ return (char_u *)&(curbuf->b_p_qe);
+ case PV_RO:
+ return (char_u *)&(curbuf->b_p_ro);
+ case PV_SCBK:
+ return (char_u *)&(curbuf->b_p_scbk);
+ case PV_SI:
+ return (char_u *)&(curbuf->b_p_si);
+ case PV_STS:
+ return (char_u *)&(curbuf->b_p_sts);
+ case PV_SUA:
+ return (char_u *)&(curbuf->b_p_sua);
+ case PV_SWF:
+ return (char_u *)&(curbuf->b_p_swf);
+ case PV_SMC:
+ return (char_u *)&(curbuf->b_p_smc);
+ case PV_SYN:
+ return (char_u *)&(curbuf->b_p_syn);
+ case PV_SPC:
+ return (char_u *)&(curwin->w_s->b_p_spc);
+ case PV_SPF:
+ return (char_u *)&(curwin->w_s->b_p_spf);
+ case PV_SPL:
+ return (char_u *)&(curwin->w_s->b_p_spl);
+ case PV_SPO:
+ return (char_u *)&(curwin->w_s->b_p_spo);
+ case PV_SW:
+ return (char_u *)&(curbuf->b_p_sw);
+ case PV_TFU:
+ return (char_u *)&(curbuf->b_p_tfu);
+ case PV_TS:
+ return (char_u *)&(curbuf->b_p_ts);
+ case PV_TW:
+ return (char_u *)&(curbuf->b_p_tw);
+ case PV_UDF:
+ return (char_u *)&(curbuf->b_p_udf);
+ case PV_WM:
+ return (char_u *)&(curbuf->b_p_wm);
+ case PV_VSTS:
+ return (char_u *)&(curbuf->b_p_vsts);
+ case PV_VTS:
+ return (char_u *)&(curbuf->b_p_vts);
+ case PV_KMAP:
+ return (char_u *)&(curbuf->b_p_keymap);
+ case PV_SCL:
+ return (char_u *)&(curwin->w_p_scl);
+ case PV_WINHL:
+ return (char_u *)&(curwin->w_p_winhl);
+ case PV_WINBL:
+ return (char_u *)&(curwin->w_p_winbl);
+ default:
+ IEMSG(_("E356: get_varp ERROR"));
}
// always return a valid pointer to avoid a crash!
return (char_u *)&(curbuf->b_p_wm);
@@ -5963,7 +6094,7 @@ void didset_window_options(win_T *wp)
void buf_copy_options(buf_T *buf, int flags)
{
int should_copy = true;
- char_u *save_p_isk = NULL; // init for GCC
+ char_u *save_p_isk = NULL; // init for GCC
int dont_do_help;
int did_isk = false;
@@ -6008,22 +6139,18 @@ void buf_copy_options(buf_T *buf, int flags)
buf->b_p_ro = false; // don't copy readonly
buf->b_p_fenc = vim_strsave(p_fenc);
switch (*p_ffs) {
- case 'm': {
- buf->b_p_ff = vim_strsave((char_u *)FF_MAC);
- break;
- }
- case 'd': {
- buf->b_p_ff = vim_strsave((char_u *)FF_DOS);
- break;
- }
- case 'u': {
- buf->b_p_ff = vim_strsave((char_u *)FF_UNIX);
- break;
- }
- default: {
- buf->b_p_ff = vim_strsave(p_ff);
- break;
- }
+ case 'm':
+ buf->b_p_ff = vim_strsave((char_u *)FF_MAC);
+ break;
+ case 'd':
+ buf->b_p_ff = vim_strsave((char_u *)FF_DOS);
+ break;
+ case 'u':
+ buf->b_p_ff = vim_strsave((char_u *)FF_UNIX);
+ break;
+ default:
+ buf->b_p_ff = vim_strsave(p_ff);
+ break;
}
buf->b_p_bh = empty_option;
buf->b_p_bt = empty_option;
@@ -6052,9 +6179,9 @@ void buf_copy_options(buf_T *buf, int flags)
buf->b_p_inf = p_inf;
buf->b_p_swf = cmdmod.noswapfile ? false : p_swf;
buf->b_p_cpt = vim_strsave(p_cpt);
-# ifdef BACKSLASH_IN_FILENAME
+#ifdef BACKSLASH_IN_FILENAME
buf->b_p_csl = vim_strsave(p_csl);
-# endif
+#endif
buf->b_p_cfu = vim_strsave(p_cfu);
buf->b_p_ofu = vim_strsave(p_ofu);
buf->b_p_tfu = vim_strsave(p_tfu);
@@ -6204,21 +6331,17 @@ void set_imsearch_global(void)
}
static int expand_option_idx = -1;
-static char_u expand_option_name[5] = {'t', '_', NUL, NUL, NUL};
+static char_u expand_option_name[5] = { 't', '_', NUL, NUL, NUL };
static int expand_option_flags = 0;
-void
-set_context_in_set_cmd(
- expand_T *xp,
- char_u *arg,
- int opt_flags // OPT_GLOBAL and/or OPT_LOCAL
-)
+/// @param opt_flags OPT_GLOBAL and/or OPT_LOCAL
+void set_context_in_set_cmd(expand_T *xp, char_u *arg, int opt_flags)
{
char_u nextchar;
uint32_t flags = 0; // init for GCC
int opt_idx = 0; // init for GCC
- char_u *p;
- char_u *s;
+ char_u *p;
+ char_u *s;
int is_term_option = false;
int key;
@@ -6342,15 +6465,14 @@ set_context_in_set_cmd(
|| p == (char_u *)&p_pp
|| p == (char_u *)&p_rtp
|| p == (char_u *)&p_cdpath
- || p == (char_u *)&p_vdir
- ) {
+ || p == (char_u *)&p_vdir) {
xp->xp_context = EXPAND_DIRECTORIES;
if (p == (char_u *)&p_path
- || p == (char_u *)&p_cdpath
- )
+ || p == (char_u *)&p_cdpath) {
xp->xp_backslash = XP_BS_THREE;
- else
+ } else {
xp->xp_backslash = XP_BS_ONE;
+ }
} else if (p == (char_u *)&p_ft) {
xp->xp_context = EXPAND_FILETYPE;
} else {
@@ -6387,8 +6509,6 @@ set_context_in_set_cmd(
break;
}
}
-
- return;
}
int ExpandSettings(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file)
@@ -6396,7 +6516,7 @@ int ExpandSettings(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***
int num_normal = 0; // Nr of matching non-term-code settings
int match;
int count = 0;
- char_u *str;
+ char_u *str;
int loop;
static char *(names[]) = { "all" };
int ic = regmatch->rm_ic; // remember the ignore-case flag
@@ -6440,8 +6560,9 @@ int ExpandSettings(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***
if (match) {
if (loop == 0) {
num_normal++;
- } else
+ } else {
(*file)[count++] = vim_strsave(str);
+ }
}
}
@@ -6484,8 +6605,8 @@ void ExpandOldSetting(int *num_file, char_u ***file)
char_u *buf = vim_strsave_escaped(var, escape_chars);
#ifdef BACKSLASH_IN_FILENAME
- /* For MS-Windows et al. we don't double backslashes at the start and
- * before a file name character. */
+ // For MS-Windows et al. we don't double backslashes at the start and
+ // before a file name character.
for (var = buf; *var != NUL; MB_PTR_ADV(var)) {
if (var[0] == '\\' && var[1] == '\\'
&& expand_option_idx >= 0
@@ -6503,13 +6624,11 @@ void ExpandOldSetting(int *num_file, char_u ***file)
/// Get the value for the numeric or string option///opp in a nice format into
/// NameBuff[]. Must not be called with a hidden option!
-static void
-option_value2string(
- vimoption_T *opp,
- int opt_flags // OPT_GLOBAL and/or OPT_LOCAL
-)
+///
+/// @param opt_flags OPT_GLOBAL and/or OPT_LOCAL
+static void option_value2string(vimoption_T *opp, int opt_flags)
{
- char_u *varp;
+ char_u *varp;
varp = get_varp_scope(opp, opt_flags);
@@ -6532,7 +6651,7 @@ option_value2string(
NameBuff[0] = NUL;
} else if (opp->flags & P_EXPAND) {
home_replace(NULL, varp, NameBuff, MAXPATHL, false);
- // Translate 'pastetoggle' into special key names.
+ // Translate 'pastetoggle' into special key names.
} else if ((char_u **)opp->var == &p_pt) {
str2specialbuf((const char *)p_pt, (char *)NameBuff, MAXPATHL);
} else {
@@ -6645,8 +6764,8 @@ static void langmap_init(void)
/// changed at any time!
static void langmap_set(void)
{
- char_u *p;
- char_u *p2;
+ char_u *p;
+ char_u *p2;
int from, to;
ga_clear(&langmap_mapga); // clear the previous map first
@@ -6692,7 +6811,7 @@ static void langmap_set(void)
}
if (to == NUL) {
EMSG2(_("E357: 'langmap': Matching character missing for %s"),
- transchar(from));
+ transchar(from));
return;
}
@@ -6711,9 +6830,8 @@ static void langmap_set(void)
p = p2;
if (p[0] != NUL) {
if (p[0] != ',') {
- EMSG2(_(
- "E358: 'langmap': Extra characters after semicolon: %s"),
- p);
+ EMSG2(_("E358: 'langmap': Extra characters after semicolon: %s"),
+ p);
return;
}
p++;
@@ -6888,15 +7006,15 @@ static void paste_option_changed(void)
///
/// Set the values for options that didn't get set yet to the defaults.
/// When "fname" is not NULL, use it to set $"envname" when it wasn't set yet.
-void vimrc_found(char_u *fname, char_u *envname)
+void vimrc_found(char *fname, char *envname)
{
if (fname != NULL && envname != NULL) {
- char *p = vim_getenv((char *)envname);
+ char *p = vim_getenv(envname);
if (p == NULL) {
// Set $MYVIMRC to the first vimrc file found.
- p = FullName_save((char *)fname, false);
+ p = FullName_save(fname, false);
if (p != NULL) {
- os_setenv((char *)envname, p, 1);
+ os_setenv(envname, p, 1);
xfree(p);
}
} else {
@@ -6938,7 +7056,7 @@ void reset_option_was_set(const char *name)
/// fill_breakat_flags() -- called when 'breakat' changes value.
static void fill_breakat_flags(void)
{
- char_u *p;
+ char_u *p;
int i;
for (i = 0; i < 256; i++) {
@@ -6997,13 +7115,10 @@ static int fill_culopt_flags(char_u *val, win_T *wp)
/// Check an option that can be a range of string values.
///
-/// Return OK for correct value, FAIL otherwise.
-/// Empty is always OK.
-static int check_opt_strings(
- char_u *val,
- char **values,
- int list // when true: accept a list of values
-)
+/// @param list when true: accept a list of values
+///
+/// @return OK for correct value, FAIL otherwise. Empty is always OK.
+static int check_opt_strings(char_u *val, char **values, int list)
{
return opt_strings_flags(val, values, NULL, list);
}
@@ -7011,14 +7126,12 @@ static int check_opt_strings(
/// Handle an option that can be a range of string values.
/// Set a flag in "*flagp" for each string present.
///
-/// Return OK for correct value, FAIL otherwise.
-/// Empty is always OK.
-static int opt_strings_flags(
- char_u *val, // new value
- char **values, // array of valid string values
- unsigned *flagp,
- bool list // when true: accept a list of values
-)
+/// @param val new value
+/// @param values array of valid string values
+/// @param list when true: accept a list of values
+///
+/// @return OK for correct value, FAIL otherwise. Empty is always OK.
+static int opt_strings_flags(char_u *val, char **values, unsigned *flagp, bool list)
{
unsigned int new_flags = 0;
@@ -7049,7 +7162,7 @@ static int opt_strings_flags(
static int check_opt_wim(void)
{
char_u new_wim_flags[4];
- char_u *p;
+ char_u *p;
int i;
int idx = 0;
@@ -7106,10 +7219,14 @@ bool can_bs(int what)
return false;
}
switch (*p_bs) {
- case '3': return true;
- case '2': return what != BS_NOSTOP;
- case '1': return what != BS_START;
- case '0': return false;
+ case '3':
+ return true;
+ case '2':
+ return what != BS_NOSTOP;
+ case '1':
+ return what != BS_START;
+ case '0':
+ return false;
}
return vim_strchr(p_bs, what) != NULL;
}
@@ -7306,11 +7423,7 @@ colnr_T tabstop_start(colnr_T col, long ts, long *vts)
// Find the number of tabs and spaces necessary to get from one column
// to another.
-void tabstop_fromto(colnr_T start_col,
- colnr_T end_col,
- long ts_arg,
- long *vts,
- int *ntabs,
+void tabstop_fromto(colnr_T start_col, colnr_T end_col, long ts_arg, long *vts, int *ntabs,
int *nspcs)
{
int spaces = end_col - start_col;
@@ -7486,18 +7599,13 @@ static bool briopt_check(win_T *wp)
while (*p != NUL)
{
if (STRNCMP(p, "shift:", 6) == 0
- && ((p[6] == '-' && ascii_isdigit(p[7])) || ascii_isdigit(p[6])))
- {
+ && ((p[6] == '-' && ascii_isdigit(p[7])) || ascii_isdigit(p[6]))) {
p += 6;
bri_shift = getdigits_int(&p, true, 0);
- }
- else if (STRNCMP(p, "min:", 4) == 0 && ascii_isdigit(p[4]))
- {
+ } else if (STRNCMP(p, "min:", 4) == 0 && ascii_isdigit(p[4])) {
p += 4;
bri_min = getdigits_int(&p, true, 0);
- }
- else if (STRNCMP(p, "sbr", 3) == 0)
- {
+ } else if (STRNCMP(p, "sbr", 3) == 0) {
p += 3;
bri_sbr = true;
} else if (STRNCMP(p, "list:", 5) == 0) {
@@ -7590,8 +7698,10 @@ int get_fileformat_force(const buf_T *buf, const exarg_T *eap)
int default_fileformat(void)
{
switch (*p_ffs) {
- case 'm': return EOL_MAC;
- case 'd': return EOL_DOS;
+ case 'm':
+ return EOL_MAC;
+ case 'd':
+ return EOL_DOS;
}
return EOL_UNIX;
}
@@ -7607,15 +7717,15 @@ void set_fileformat(int eol_style, int opt_flags)
char *p = NULL;
switch (eol_style) {
- case EOL_UNIX:
- p = FF_UNIX;
- break;
- case EOL_MAC:
- p = FF_MAC;
- break;
- case EOL_DOS:
- p = FF_DOS;
- break;
+ case EOL_UNIX:
+ p = FF_UNIX;
+ break;
+ case EOL_MAC:
+ p = FF_MAC;
+ break;
+ case EOL_DOS:
+ p = FF_DOS;
+ break;
}
// p is NULL if "eol_style" is EOL_UNKNOWN.
@@ -7653,11 +7763,10 @@ char_u *skip_to_option_part(const char_u *p)
/// @param[in] sep_chars chars that separate the option parts
///
/// @return length of `*option`
-size_t copy_option_part(char_u **option, char_u *buf, size_t maxlen,
- char *sep_chars)
+size_t copy_option_part(char_u **option, char_u *buf, size_t maxlen, char *sep_chars)
{
size_t len = 0;
- char_u *p = *option;
+ char_u *p = *option;
// skip '.' at start of option part, for 'suffixes'
if (*p == '.') {
@@ -7820,52 +7929,52 @@ Dictionary get_all_vimoptions(void)
static Dictionary vimoption2dict(vimoption_T *opt)
{
- Dictionary dict = ARRAY_DICT_INIT;
+ Dictionary dict = ARRAY_DICT_INIT;
- PUT(dict, "name", CSTR_TO_OBJ(opt->fullname));
- PUT(dict, "shortname", CSTR_TO_OBJ(opt->shortname));
+ PUT(dict, "name", CSTR_TO_OBJ(opt->fullname));
+ PUT(dict, "shortname", CSTR_TO_OBJ(opt->shortname));
- const char *scope;
- if (opt->indir & PV_BUF) {
- scope = "buf";
- } else if (opt->indir & PV_WIN) {
- scope = "win";
- } else {
- scope = "global";
- }
-
- PUT(dict, "scope", CSTR_TO_OBJ(scope));
-
- // welcome to the jungle
- PUT(dict, "global_local", BOOL(opt->indir & PV_BOTH));
- PUT(dict, "commalist", BOOL(opt->flags & P_COMMA));
- PUT(dict, "flaglist", BOOL(opt->flags & P_FLAGLIST));
-
- PUT(dict, "was_set", BOOL(opt->flags & P_WAS_SET));
-
- PUT(dict, "last_set_sid", INTEGER_OBJ(opt->last_set.script_ctx.sc_sid));
- PUT(dict, "last_set_linenr", INTEGER_OBJ(opt->last_set.script_ctx.sc_lnum));
- PUT(dict, "last_set_chan", INTEGER_OBJ((int64_t)opt->last_set.channel_id));
-
- const char *type;
- Object def;
- // TODO(bfredl): do you even nocp?
- char_u *def_val = opt->def_val;
- if (opt->flags & P_STRING) {
- type = "string";
- def = CSTR_TO_OBJ(def_val ? (char *)def_val : "");
- } else if (opt->flags & P_NUM) {
- type = "number";
- def = INTEGER_OBJ((Integer)(intptr_t)def_val);
- } else if (opt->flags & P_BOOL) {
- type = "boolean";
- def = BOOL((intptr_t)def_val);
- } else {
- type = ""; def = NIL;
- }
- PUT(dict, "type", CSTR_TO_OBJ(type));
- PUT(dict, "default", def);
- PUT(dict, "allows_duplicates", BOOL(!(opt->flags & P_NODUP)));
+ const char *scope;
+ if (opt->indir & PV_BUF) {
+ scope = "buf";
+ } else if (opt->indir & PV_WIN) {
+ scope = "win";
+ } else {
+ scope = "global";
+ }
+
+ PUT(dict, "scope", CSTR_TO_OBJ(scope));
+
+ // welcome to the jungle
+ PUT(dict, "global_local", BOOL(opt->indir & PV_BOTH));
+ PUT(dict, "commalist", BOOL(opt->flags & P_COMMA));
+ PUT(dict, "flaglist", BOOL(opt->flags & P_FLAGLIST));
+
+ PUT(dict, "was_set", BOOL(opt->flags & P_WAS_SET));
+
+ PUT(dict, "last_set_sid", INTEGER_OBJ(opt->last_set.script_ctx.sc_sid));
+ PUT(dict, "last_set_linenr", INTEGER_OBJ(opt->last_set.script_ctx.sc_lnum));
+ PUT(dict, "last_set_chan", INTEGER_OBJ((int64_t)opt->last_set.channel_id));
+
+ const char *type;
+ Object def;
+ // TODO(bfredl): do you even nocp?
+ char_u *def_val = opt->def_val;
+ if (opt->flags & P_STRING) {
+ type = "string";
+ def = CSTR_TO_OBJ(def_val ? (char *)def_val : "");
+ } else if (opt->flags & P_NUM) {
+ type = "number";
+ def = INTEGER_OBJ((Integer)(intptr_t)def_val);
+ } else if (opt->flags & P_BOOL) {
+ type = "boolean";
+ def = BOOL((intptr_t)def_val);
+ } else {
+ type = ""; def = NIL;
+ }
+ PUT(dict, "type", CSTR_TO_OBJ(type));
+ PUT(dict, "default", def);
+ PUT(dict, "allows_duplicates", BOOL(!(opt->flags & P_NODUP)));
- return dict;
+ return dict;
}
diff --git a/src/nvim/option.h b/src/nvim/option.h
index c6ee03e052..452494172f 100644
--- a/src/nvim/option.h
+++ b/src/nvim/option.h
@@ -3,10 +3,10 @@
#include "nvim/ex_cmds_defs.h" // for exarg_T
-/* flags for buf_copy_options() */
-#define BCO_ENTER 1 /* going to enter the buffer */
-#define BCO_ALWAYS 2 /* always copy the options */
-#define BCO_NOHELP 4 /* don't touch the help related options */
+// flags for buf_copy_options()
+#define BCO_ENTER 1 // going to enter the buffer
+#define BCO_ALWAYS 2 // always copy the options
+#define BCO_NOHELP 4 // don't touch the help related options
/// Flags for option-setting functions
///
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index e588d3f373..441d29cd9f 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -1,9 +1,9 @@
#ifndef NVIM_OPTION_DEFS_H
#define NVIM_OPTION_DEFS_H
-#include "nvim/types.h"
-#include "nvim/macros.h" // For EXTERN
#include "eval/typval.h" // For scid_T
+#include "nvim/macros.h" // For EXTERN
+#include "nvim/types.h"
// option_defs.h: definition of global variables for settable options
@@ -25,9 +25,11 @@
// The "%f|%l| %m" one is used for when the contents of the quickfix window is
// written to a file.
#ifdef WIN32
-# define DFLT_EFM "%f(%l) \\=: %t%*\\D%n: %m,%*[^\"]\"%f\"%*\\D%l: %m,%f(%l) \\=: %m,%*[^ ] %f %l: %m,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,%f|%l| %m"
+# define DFLT_EFM \
+ "%f(%l) \\=: %t%*\\D%n: %m,%*[^\"]\"%f\"%*\\D%l: %m,%f(%l) \\=: %m,%*[^ ] %f %l: %m,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,%f|%l| %m"
#else
-# define DFLT_EFM "%*[^\"]\"%f\"%*\\D%l: %m,\"%f\"%*\\D%l: %m,%-G%f:%l: (Each undeclared identifier is reported only once,%-G%f:%l: for each function it appears in.),%-GIn file included from %f:%l:%c:,%-GIn file included from %f:%l:%c\\,,%-GIn file included from %f:%l:%c,%-GIn file included from %f:%l,%-G%*[ ]from %f:%l:%c,%-G%*[ ]from %f:%l:,%-G%*[ ]from %f:%l\\,,%-G%*[ ]from %f:%l,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,\"%f\"\\, line %l%*\\D%c%*[^ ] %m,%D%*\\a[%*\\d]: Entering directory %*[`']%f',%X%*\\a[%*\\d]: Leaving directory %*[`']%f',%D%*\\a: Entering directory %*[`']%f',%X%*\\a: Leaving directory %*[`']%f',%DMaking %*\\a in %f,%f|%l| %m"
+# define DFLT_EFM \
+ "%*[^\"]\"%f\"%*\\D%l: %m,\"%f\"%*\\D%l: %m,%-G%f:%l: (Each undeclared identifier is reported only once,%-G%f:%l: for each function it appears in.),%-GIn file included from %f:%l:%c:,%-GIn file included from %f:%l:%c\\,,%-GIn file included from %f:%l:%c,%-GIn file included from %f:%l,%-G%*[ ]from %f:%l:%c,%-G%*[ ]from %f:%l:,%-G%*[ ]from %f:%l\\,,%-G%*[ ]from %f:%l,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,\"%f\"\\, line %l%*\\D%c%*[^ ] %m,%D%*\\a[%*\\d]: Entering directory %*[`']%f',%X%*\\a[%*\\d]: Leaving directory %*[`']%f',%D%*\\a: Entering directory %*[`']%f',%X%*\\a: Leaving directory %*[`']%f',%DMaking %*\\a in %f,%f|%l| %m"
#endif
#define DFLT_GREPFORMAT "%f:%l:%m,%f:%l%m,%f %l%m"
@@ -42,17 +44,17 @@
# define DFLT_FFS_VIM "dos,unix"
# define DFLT_FFS_VI "dos,unix" // also autodetect in compatible mode
#else
-# define DFLT_FF "unix"
-# define DFLT_FFS_VIM "unix,dos"
-# define DFLT_FFS_VI ""
+# define DFLT_FF "unix"
+# define DFLT_FFS_VIM "unix,dos"
+# define DFLT_FFS_VI ""
#endif
// Possible values for 'encoding'
-# define ENC_UCSBOM "ucs-bom" // check for BOM at start of file
+#define ENC_UCSBOM "ucs-bom" // check for BOM at start of file
// default value for 'encoding'
-# define ENC_DFLT "utf-8"
+#define ENC_DFLT "utf-8"
// end-of-line style
#define EOL_UNKNOWN -1 // not defined yet
@@ -179,9 +181,9 @@ enum {
};
/// Represented by 'a' flag.
#define SHM_ALL_ABBREVIATIONS ((char_u[]) { \
- SHM_RO, SHM_MOD, SHM_FILE, SHM_LAST, SHM_TEXT, SHM_LINES, SHM_NEW, SHM_WRI, \
- 0, \
-})
+ SHM_RO, SHM_MOD, SHM_FILE, SHM_LAST, SHM_TEXT, SHM_LINES, SHM_NEW, SHM_WRI, \
+ 0, \
+ })
// characters for p_go:
#define GO_ASEL 'a' // autoselect
@@ -264,16 +266,16 @@ enum {
};
/// C string containing all 'statusline' option flags
#define STL_ALL ((char_u[]) { \
- STL_FILEPATH, STL_FULLPATH, STL_FILENAME, STL_COLUMN, STL_VIRTCOL, \
- STL_VIRTCOL_ALT, STL_LINE, STL_NUMLINES, STL_BUFNO, STL_KEYMAP, STL_OFFSET, \
- STL_OFFSET_X, STL_BYTEVAL, STL_BYTEVAL_X, STL_ROFLAG, STL_ROFLAG_ALT, \
- STL_HELPFLAG, STL_HELPFLAG_ALT, STL_FILETYPE, STL_FILETYPE_ALT, \
- STL_PREVIEWFLAG, STL_PREVIEWFLAG_ALT, STL_MODIFIED, STL_MODIFIED_ALT, \
- STL_QUICKFIX, STL_PERCENTAGE, STL_ALTPERCENT, STL_ARGLISTSTAT, STL_PAGENUM, \
- STL_VIM_EXPR, STL_SEPARATE, STL_TRUNCMARK, STL_USER_HL, STL_HIGHLIGHT, \
- STL_TABPAGENR, STL_TABCLOSENR, STL_CLICK_FUNC, \
- 0, \
-})
+ STL_FILEPATH, STL_FULLPATH, STL_FILENAME, STL_COLUMN, STL_VIRTCOL, \
+ STL_VIRTCOL_ALT, STL_LINE, STL_NUMLINES, STL_BUFNO, STL_KEYMAP, STL_OFFSET, \
+ STL_OFFSET_X, STL_BYTEVAL, STL_BYTEVAL_X, STL_ROFLAG, STL_ROFLAG_ALT, \
+ STL_HELPFLAG, STL_HELPFLAG_ALT, STL_FILETYPE, STL_FILETYPE_ALT, \
+ STL_PREVIEWFLAG, STL_PREVIEWFLAG_ALT, STL_MODIFIED, STL_MODIFIED_ALT, \
+ STL_QUICKFIX, STL_PERCENTAGE, STL_ALTPERCENT, STL_ARGLISTSTAT, STL_PAGENUM, \
+ STL_VIM_EXPR, STL_SEPARATE, STL_TRUNCMARK, STL_USER_HL, STL_HIGHLIGHT, \
+ STL_TABPAGENR, STL_TABCLOSENR, STL_CLICK_FUNC, \
+ 0, \
+ })
// flags used for parsed 'wildmode'
#define WIM_FULL 0x01
@@ -305,36 +307,36 @@ enum {
EXTERN long p_aleph; // 'aleph'
EXTERN int p_acd; // 'autochdir'
-EXTERN char_u *p_ambw; // 'ambiwidth'
+EXTERN char_u *p_ambw; // 'ambiwidth'
EXTERN int p_ar; // 'autoread'
EXTERN int p_aw; // 'autowrite'
EXTERN int p_awa; // 'autowriteall'
-EXTERN char_u *p_bs; // 'backspace'
-EXTERN char_u *p_bg; // 'background'
+EXTERN char_u *p_bs; // 'backspace'
+EXTERN char_u *p_bg; // 'background'
EXTERN int p_bk; // 'backup'
-EXTERN char_u *p_bkc; // 'backupcopy'
+EXTERN char_u *p_bkc; // 'backupcopy'
EXTERN unsigned int bkc_flags; ///< flags from 'backupcopy'
#ifdef IN_OPTION_C
static char *(p_bkc_values[]) =
-{"yes", "auto", "no", "breaksymlink", "breakhardlink", NULL};
+{ "yes", "auto", "no", "breaksymlink", "breakhardlink", NULL };
#endif
-# define BKC_YES 0x001
-# define BKC_AUTO 0x002
-# define BKC_NO 0x004
-# define BKC_BREAKSYMLINK 0x008
-# define BKC_BREAKHARDLINK 0x010
+#define BKC_YES 0x001
+#define BKC_AUTO 0x002
+#define BKC_NO 0x004
+#define BKC_BREAKSYMLINK 0x008
+#define BKC_BREAKHARDLINK 0x010
EXTERN char_u *p_bdir; // 'backupdir'
EXTERN char_u *p_bex; // 'backupext'
EXTERN char_u *p_bo; // 'belloff'
EXTERN char breakat_flags[256]; // which characters are in 'breakat'
EXTERN unsigned bo_flags;
-# ifdef IN_OPTION_C
-static char *(p_bo_values[]) = {"all", "backspace", "cursor", "complete",
- "copy", "ctrlg", "error", "esc", "ex",
- "hangul", "insertmode", "lang", "mess",
- "showmatch", "operator", "register", "shell",
- "spell", "wildmode", NULL};
-# endif
+#ifdef IN_OPTION_C
+static char *(p_bo_values[]) = { "all", "backspace", "cursor", "complete",
+ "copy", "ctrlg", "error", "esc", "ex",
+ "hangul", "insertmode", "lang", "mess",
+ "showmatch", "operator", "register", "shell",
+ "spell", "wildmode", NULL };
+#endif
// values for the 'belloff' option
#define BO_ALL 0x0001
@@ -357,61 +359,61 @@ static char *(p_bo_values[]) = {"all", "backspace", "cursor", "complete",
#define BO_SPELL 0x20000
#define BO_WILD 0x40000
-EXTERN char_u *p_bsk; // 'backupskip'
-EXTERN char_u *p_breakat; // 'breakat'
-EXTERN char_u *p_cmp; // 'casemap'
+EXTERN char_u *p_bsk; // 'backupskip'
+EXTERN char_u *p_breakat; // 'breakat'
+EXTERN char_u *p_cmp; // 'casemap'
EXTERN unsigned cmp_flags;
-# ifdef IN_OPTION_C
-static char *(p_cmp_values[]) = {"internal", "keepascii", NULL};
-# endif
-# define CMP_INTERNAL 0x001
-# define CMP_KEEPASCII 0x002
-EXTERN char_u *p_enc; // 'encoding'
+#ifdef IN_OPTION_C
+static char *(p_cmp_values[]) = { "internal", "keepascii", NULL };
+#endif
+#define CMP_INTERNAL 0x001
+#define CMP_KEEPASCII 0x002
+EXTERN char_u *p_enc; // 'encoding'
EXTERN int p_deco; // 'delcombine'
-EXTERN char_u *p_ccv; // 'charconvert'
-EXTERN char_u *p_cedit; // 'cedit'
-EXTERN char_u *p_cb; // 'clipboard'
+EXTERN char_u *p_ccv; // 'charconvert'
+EXTERN char_u *p_cedit; // 'cedit'
+EXTERN char_u *p_cb; // 'clipboard'
EXTERN unsigned cb_flags;
#ifdef IN_OPTION_C
-static char *(p_cb_values[]) = {"unnamed", "unnamedplus", NULL};
+static char *(p_cb_values[]) = { "unnamed", "unnamedplus", NULL };
#endif
-# define CB_UNNAMED 0x001
-# define CB_UNNAMEDPLUS 0x002
-# define CB_UNNAMEDMASK (CB_UNNAMED | CB_UNNAMEDPLUS)
+#define CB_UNNAMED 0x001
+#define CB_UNNAMEDPLUS 0x002
+#define CB_UNNAMEDMASK (CB_UNNAMED | CB_UNNAMEDPLUS)
EXTERN long p_cwh; // 'cmdwinheight'
EXTERN long p_ch; // 'cmdheight'
EXTERN long p_columns; // 'columns'
EXTERN int p_confirm; // 'confirm'
-EXTERN char_u *p_cot; // 'completeopt'
-# ifdef BACKSLASH_IN_FILENAME
-EXTERN char_u *p_csl; // 'completeslash'
-# endif
+EXTERN char_u *p_cot; // 'completeopt'
+#ifdef BACKSLASH_IN_FILENAME
+EXTERN char_u *p_csl; // 'completeslash'
+#endif
EXTERN long p_pb; // 'pumblend'
EXTERN long p_ph; // 'pumheight'
EXTERN long p_pw; // 'pumwidth'
-EXTERN char_u *p_cpo; // 'cpoptions'
-EXTERN char_u *p_csprg; // 'cscopeprg'
+EXTERN char_u *p_cpo; // 'cpoptions'
+EXTERN char_u *p_csprg; // 'cscopeprg'
EXTERN int p_csre; // 'cscoperelative'
-EXTERN char_u *p_csqf; // 'cscopequickfix'
-# define CSQF_CMDS "sgdctefia"
-# define CSQF_FLAGS "+-0"
+EXTERN char_u *p_csqf; // 'cscopequickfix'
+#define CSQF_CMDS "sgdctefia"
+#define CSQF_FLAGS "+-0"
EXTERN int p_cst; // 'cscopetag'
EXTERN long p_csto; // 'cscopetagorder'
EXTERN long p_cspc; // 'cscopepathcomp'
EXTERN int p_csverbose; // 'cscopeverbose'
-EXTERN char_u *p_debug; // 'debug'
-EXTERN char_u *p_def; // 'define'
-EXTERN char_u *p_inc;
-EXTERN char_u *p_dip; // 'diffopt'
-EXTERN char_u *p_dex; // 'diffexpr'
-EXTERN char_u *p_dict; // 'dictionary'
+EXTERN char_u *p_debug; // 'debug'
+EXTERN char_u *p_def; // 'define'
+EXTERN char_u *p_inc;
+EXTERN char_u *p_dip; // 'diffopt'
+EXTERN char_u *p_dex; // 'diffexpr'
+EXTERN char_u *p_dict; // 'dictionary'
EXTERN int p_dg; // 'digraph'
-EXTERN char_u *p_dir; // 'directory'
-EXTERN char_u *p_dy; // 'display'
+EXTERN char_u *p_dir; // 'directory'
+EXTERN char_u *p_dy; // 'display'
EXTERN unsigned dy_flags;
#ifdef IN_OPTION_C
static char *(p_dy_values[]) = { "lastline", "truncate", "uhex", "msgsep",
- NULL };
+ NULL };
#endif
#define DY_LASTLINE 0x001
#define DY_TRUNCATE 0x002
@@ -420,72 +422,72 @@ static char *(p_dy_values[]) = { "lastline", "truncate", "uhex", "msgsep",
#define DY_MSGSEP 0x008
EXTERN int p_ed; // 'edcompatible'
EXTERN int p_emoji; // 'emoji'
-EXTERN char_u *p_ead; // 'eadirection'
+EXTERN char_u *p_ead; // 'eadirection'
EXTERN int p_ea; // 'equalalways'
-EXTERN char_u *p_ep; // 'equalprg'
+EXTERN char_u *p_ep; // 'equalprg'
EXTERN int p_eb; // 'errorbells'
-EXTERN char_u *p_ef; // 'errorfile'
-EXTERN char_u *p_efm; // 'errorformat'
-EXTERN char_u *p_gefm; // 'grepformat'
-EXTERN char_u *p_gp; // 'grepprg'
-EXTERN char_u *p_ei; // 'eventignore'
+EXTERN char_u *p_ef; // 'errorfile'
+EXTERN char_u *p_efm; // 'errorformat'
+EXTERN char_u *p_gefm; // 'grepformat'
+EXTERN char_u *p_gp; // 'grepprg'
+EXTERN char_u *p_ei; // 'eventignore'
EXTERN int p_exrc; // 'exrc'
-EXTERN char_u *p_fencs; // 'fileencodings'
-EXTERN char_u *p_ffs; // 'fileformats'
+EXTERN char_u *p_fencs; // 'fileencodings'
+EXTERN char_u *p_ffs; // 'fileformats'
EXTERN int p_fic; // 'fileignorecase'
-EXTERN char_u *p_fcl; // 'foldclose'
+EXTERN char_u *p_fcl; // 'foldclose'
EXTERN long p_fdls; // 'foldlevelstart'
-EXTERN char_u *p_fdo; // 'foldopen'
+EXTERN char_u *p_fdo; // 'foldopen'
EXTERN unsigned fdo_flags;
-# ifdef IN_OPTION_C
-static char *(p_fdo_values[]) = {"all", "block", "hor", "mark", "percent",
- "quickfix", "search", "tag", "insert",
- "undo", "jump", NULL};
-# endif
-# define FDO_ALL 0x001
-# define FDO_BLOCK 0x002
-# define FDO_HOR 0x004
-# define FDO_MARK 0x008
-# define FDO_PERCENT 0x010
-# define FDO_QUICKFIX 0x020
-# define FDO_SEARCH 0x040
-# define FDO_TAG 0x080
-# define FDO_INSERT 0x100
-# define FDO_UNDO 0x200
-# define FDO_JUMP 0x400
-EXTERN char_u *p_fp; // 'formatprg'
+#ifdef IN_OPTION_C
+static char *(p_fdo_values[]) = { "all", "block", "hor", "mark", "percent",
+ "quickfix", "search", "tag", "insert",
+ "undo", "jump", NULL };
+#endif
+#define FDO_ALL 0x001
+#define FDO_BLOCK 0x002
+#define FDO_HOR 0x004
+#define FDO_MARK 0x008
+#define FDO_PERCENT 0x010
+#define FDO_QUICKFIX 0x020
+#define FDO_SEARCH 0x040
+#define FDO_TAG 0x080
+#define FDO_INSERT 0x100
+#define FDO_UNDO 0x200
+#define FDO_JUMP 0x400
+EXTERN char_u *p_fp; // 'formatprg'
EXTERN int p_fs; // 'fsync'
EXTERN int p_gd; // 'gdefault'
-EXTERN char_u *p_pdev; // 'printdevice'
-EXTERN char_u *p_penc; // 'printencoding'
-EXTERN char_u *p_pexpr; // 'printexpr'
-EXTERN char_u *p_pmfn; // 'printmbfont'
-EXTERN char_u *p_pmcs; // 'printmbcharset'
-EXTERN char_u *p_pfn; // 'printfont'
-EXTERN char_u *p_popt; // 'printoptions'
-EXTERN char_u *p_header; // 'printheader'
-EXTERN char_u *p_guicursor; // 'guicursor'
-EXTERN char_u *p_guifont; // 'guifont'
-EXTERN char_u *p_guifontwide; // 'guifontwide'
-EXTERN char_u *p_hf; // 'helpfile'
+EXTERN char_u *p_pdev; // 'printdevice'
+EXTERN char_u *p_penc; // 'printencoding'
+EXTERN char_u *p_pexpr; // 'printexpr'
+EXTERN char_u *p_pmfn; // 'printmbfont'
+EXTERN char_u *p_pmcs; // 'printmbcharset'
+EXTERN char_u *p_pfn; // 'printfont'
+EXTERN char_u *p_popt; // 'printoptions'
+EXTERN char_u *p_header; // 'printheader'
+EXTERN char_u *p_guicursor; // 'guicursor'
+EXTERN char_u *p_guifont; // 'guifont'
+EXTERN char_u *p_guifontwide; // 'guifontwide'
+EXTERN char_u *p_hf; // 'helpfile'
EXTERN long p_hh; // 'helpheight'
-EXTERN char_u *p_hlg; // 'helplang'
+EXTERN char_u *p_hlg; // 'helplang'
EXTERN int p_hid; // 'hidden'
-EXTERN char_u *p_hl; // 'highlight'
+EXTERN char_u *p_hl; // 'highlight'
EXTERN int p_hls; // 'hlsearch'
EXTERN long p_hi; // 'history'
EXTERN int p_hkmap; // 'hkmap'
EXTERN int p_hkmapp; // 'hkmapp'
EXTERN int p_arshape; // 'arabicshape'
EXTERN int p_icon; // 'icon'
-EXTERN char_u *p_iconstring; // 'iconstring'
+EXTERN char_u *p_iconstring; // 'iconstring'
EXTERN int p_ic; // 'ignorecase'
EXTERN int p_is; // 'incsearch'
-EXTERN char_u *p_icm; // 'inccommand'
+EXTERN char_u *p_icm; // 'inccommand'
EXTERN int p_im; // 'insertmode'
-EXTERN char_u *p_isf; // 'isfname'
-EXTERN char_u *p_isi; // 'isident'
-EXTERN char_u *p_isp; // 'isprint'
+EXTERN char_u *p_isf; // 'isfname'
+EXTERN char_u *p_isi; // 'isident'
+EXTERN char_u *p_isp; // 'isprint'
EXTERN int p_js; // 'joinspaces'
EXTERN char_u *p_jop; // 'jumpooptions'
EXTERN unsigned jop_flags;
@@ -493,26 +495,26 @@ EXTERN unsigned jop_flags;
static char *(p_jop_values[]) = { "stack", NULL };
#endif
#define JOP_STACK 0x01
-EXTERN char_u *p_kp; // 'keywordprg'
-EXTERN char_u *p_km; // 'keymodel'
-EXTERN char_u *p_langmap; // 'langmap'
+EXTERN char_u *p_kp; // 'keywordprg'
+EXTERN char_u *p_km; // 'keymodel'
+EXTERN char_u *p_langmap; // 'langmap'
EXTERN int p_lnr; // 'langnoremap'
EXTERN int p_lrm; // 'langremap'
-EXTERN char_u *p_lm; // 'langmenu'
-EXTERN long p_lines; // 'lines'
-EXTERN long p_linespace; // 'linespace'
-EXTERN char_u *p_lispwords; // 'lispwords'
+EXTERN char_u *p_lm; // 'langmenu'
+EXTERN long p_lines; // 'lines'
+EXTERN long p_linespace; // 'linespace'
+EXTERN char_u *p_lispwords; // 'lispwords'
EXTERN long p_ls; // 'laststatus'
EXTERN long p_stal; // 'showtabline'
-EXTERN char_u *p_lcs; // 'listchars'
+EXTERN char_u *p_lcs; // 'listchars'
EXTERN int p_lz; // 'lazyredraw'
EXTERN int p_lpl; // 'loadplugins'
EXTERN int p_magic; // 'magic'
-EXTERN char_u *p_menc; // 'makeencoding'
-EXTERN char_u *p_mef; // 'makeef'
-EXTERN char_u *p_mp; // 'makeprg'
-EXTERN char_u *p_cc; // 'colorcolumn'
+EXTERN char_u *p_menc; // 'makeencoding'
+EXTERN char_u *p_mef; // 'makeef'
+EXTERN char_u *p_mp; // 'makeprg'
+EXTERN char_u *p_cc; // 'colorcolumn'
EXTERN int p_cc_cols[256]; // array for 'colorcolumn' columns
EXTERN long p_mat; // 'matchtime'
EXTERN long p_mco; // 'maxcombine'
@@ -520,26 +522,26 @@ EXTERN long p_mfd; // 'maxfuncdepth'
EXTERN long p_mmd; // 'maxmapdepth'
EXTERN long p_mmp; // 'maxmempattern'
EXTERN long p_mis; // 'menuitems'
-EXTERN char_u *p_msm; // 'mkspellmem'
+EXTERN char_u *p_msm; // 'mkspellmem'
EXTERN long p_mle; // 'modelineexpr'
EXTERN long p_mls; // 'modelines'
-EXTERN char_u *p_mouse; // 'mouse'
-EXTERN char_u *p_mousem; // 'mousemodel'
+EXTERN char_u *p_mouse; // 'mouse'
+EXTERN char_u *p_mousem; // 'mousemodel'
EXTERN long p_mousef; // 'mousefocus'
EXTERN long p_mouset; // 'mousetime'
EXTERN int p_more; // 'more'
-EXTERN char_u *p_opfunc; // 'operatorfunc'
-EXTERN char_u *p_para; // 'paragraphs'
+EXTERN char_u *p_opfunc; // 'operatorfunc'
+EXTERN char_u *p_para; // 'paragraphs'
EXTERN int p_paste; // 'paste'
-EXTERN char_u *p_pt; // 'pastetoggle'
-EXTERN char_u *p_pex; // 'patchexpr'
-EXTERN char_u *p_pm; // 'patchmode'
-EXTERN char_u *p_path; // 'path'
-EXTERN char_u *p_cdpath; // 'cdpath'
+EXTERN char_u *p_pt; // 'pastetoggle'
+EXTERN char_u *p_pex; // 'patchexpr'
+EXTERN char_u *p_pm; // 'patchmode'
+EXTERN char_u *p_path; // 'path'
+EXTERN char_u *p_cdpath; // 'cdpath'
EXTERN long p_pyx; // 'pyxversion'
EXTERN char_u *p_rdb; // 'redrawdebug'
EXTERN unsigned rdb_flags;
-# ifdef IN_OPTION_C
+#ifdef IN_OPTION_C
static char *(p_rdb_values[]) = {
"compositor",
"nothrottle",
@@ -547,11 +549,11 @@ static char *(p_rdb_values[]) = {
"nodelta",
NULL
};
-# endif
-# define RDB_COMPOSITOR 0x001
-# define RDB_NOTHROTTLE 0x002
-# define RDB_INVALID 0x004
-# define RDB_NODELTA 0x008
+#endif
+#define RDB_COMPOSITOR 0x001
+#define RDB_NOTHROTTLE 0x002
+#define RDB_INVALID 0x004
+#define RDB_NODELTA 0x008
EXTERN long p_rdt; // 'redrawtime'
EXTERN int p_remap; // 'remap'
@@ -561,21 +563,21 @@ EXTERN long p_pvh; // 'previewheight'
EXTERN int p_ari; // 'allowrevins'
EXTERN int p_ri; // 'revins'
EXTERN int p_ru; // 'ruler'
-EXTERN char_u *p_ruf; // 'rulerformat'
-EXTERN char_u *p_pp; // 'packpath'
-EXTERN char_u *p_qftf; // 'quickfixtextfunc'
-EXTERN char_u *p_rtp; // 'runtimepath'
+EXTERN char_u *p_ruf; // 'rulerformat'
+EXTERN char_u *p_pp; // 'packpath'
+EXTERN char_u *p_qftf; // 'quickfixtextfunc'
+EXTERN char_u *p_rtp; // 'runtimepath'
EXTERN long p_scbk; // 'scrollback'
EXTERN long p_sj; // 'scrolljump'
EXTERN long p_so; // 'scrolloff'
-EXTERN char_u *p_sbo; // 'scrollopt'
-EXTERN char_u *p_sections; // 'sections'
+EXTERN char_u *p_sbo; // 'scrollopt'
+EXTERN char_u *p_sections; // 'sections'
EXTERN int p_secure; // 'secure'
-EXTERN char_u *p_sel; // 'selection'
-EXTERN char_u *p_slm; // 'selectmode'
-EXTERN char_u *p_ssop; // 'sessionoptions'
+EXTERN char_u *p_sel; // 'selection'
+EXTERN char_u *p_slm; // 'selectmode'
+EXTERN char_u *p_ssop; // 'sessionoptions'
EXTERN unsigned ssop_flags;
-# ifdef IN_OPTION_C
+#ifdef IN_OPTION_C
// Also used for 'viewoptions'! Keep in sync with SSOP_ flags.
static char *(p_ssop_values[]) = {
"buffers", "winpos", "resize", "winsize",
@@ -583,41 +585,41 @@ static char *(p_ssop_values[]) = {
"sesdir", "curdir", "folds", "cursor", "tabpages", "terminal", "skiprtp",
NULL
};
-# endif
-# define SSOP_BUFFERS 0x001
-# define SSOP_WINPOS 0x002
-# define SSOP_RESIZE 0x004
-# define SSOP_WINSIZE 0x008
-# define SSOP_LOCALOPTIONS 0x010
-# define SSOP_OPTIONS 0x020
-# define SSOP_HELP 0x040
-# define SSOP_BLANK 0x080
-# define SSOP_GLOBALS 0x100
-# define SSOP_SLASH 0x200 // Deprecated, always set.
-# define SSOP_UNIX 0x400 // Deprecated, always set.
-# define SSOP_SESDIR 0x800
-# define SSOP_CURDIR 0x1000
-# define SSOP_FOLDS 0x2000
-# define SSOP_CURSOR 0x4000
-# define SSOP_TABPAGES 0x8000
-# define SSOP_TERMINAL 0x10000
-# define SSOP_SKIP_RTP 0x20000
-
-EXTERN char_u *p_sh; // 'shell'
-EXTERN char_u *p_shcf; // 'shellcmdflag'
-EXTERN char_u *p_sp; // 'shellpipe'
-EXTERN char_u *p_shq; // 'shellquote'
-EXTERN char_u *p_sxq; // 'shellxquote'
-EXTERN char_u *p_sxe; // 'shellxescape'
-EXTERN char_u *p_srr; // 'shellredir'
+#endif
+#define SSOP_BUFFERS 0x001
+#define SSOP_WINPOS 0x002
+#define SSOP_RESIZE 0x004
+#define SSOP_WINSIZE 0x008
+#define SSOP_LOCALOPTIONS 0x010
+#define SSOP_OPTIONS 0x020
+#define SSOP_HELP 0x040
+#define SSOP_BLANK 0x080
+#define SSOP_GLOBALS 0x100
+#define SSOP_SLASH 0x200 // Deprecated, always set.
+#define SSOP_UNIX 0x400 // Deprecated, always set.
+#define SSOP_SESDIR 0x800
+#define SSOP_CURDIR 0x1000
+#define SSOP_FOLDS 0x2000
+#define SSOP_CURSOR 0x4000
+#define SSOP_TABPAGES 0x8000
+#define SSOP_TERMINAL 0x10000
+#define SSOP_SKIP_RTP 0x20000
+
+EXTERN char_u *p_sh; // 'shell'
+EXTERN char_u *p_shcf; // 'shellcmdflag'
+EXTERN char_u *p_sp; // 'shellpipe'
+EXTERN char_u *p_shq; // 'shellquote'
+EXTERN char_u *p_sxq; // 'shellxquote'
+EXTERN char_u *p_sxe; // 'shellxescape'
+EXTERN char_u *p_srr; // 'shellredir'
EXTERN int p_stmp; // 'shelltemp'
#ifdef BACKSLASH_IN_FILENAME
EXTERN int p_ssl; // 'shellslash'
#endif
-EXTERN char_u *p_stl; // 'statusline'
+EXTERN char_u *p_stl; // 'statusline'
EXTERN int p_sr; // 'shiftround'
-EXTERN char_u *p_shm; // 'shortmess'
-EXTERN char_u *p_sbr; // 'showbreak'
+EXTERN char_u *p_shm; // 'shortmess'
+EXTERN char_u *p_sbr; // 'showbreak'
EXTERN int p_sc; // 'showcmd'
EXTERN int p_sft; // 'showfulltag'
EXTERN int p_sm; // 'showmatch'
@@ -628,29 +630,29 @@ EXTERN int p_scs; // 'smartcase'
EXTERN int p_sta; // 'smarttab'
EXTERN int p_sb; // 'splitbelow'
EXTERN long p_tpm; // 'tabpagemax'
-EXTERN char_u *p_tal; // 'tabline'
-EXTERN char_u *p_tpf; // 'termpastefilter'
+EXTERN char_u *p_tal; // 'tabline'
+EXTERN char_u *p_tpf; // 'termpastefilter'
EXTERN unsigned int tpf_flags; ///< flags from 'termpastefilter'
#ifdef IN_OPTION_C
static char *(p_tpf_values[]) =
- { "BS", "HT", "FF", "ESC", "DEL", "C0", "C1", NULL };
+{ "BS", "HT", "FF", "ESC", "DEL", "C0", "C1", NULL };
#endif
-# define TPF_BS 0x001
-# define TPF_HT 0x002
-# define TPF_FF 0x004
-# define TPF_ESC 0x008
-# define TPF_DEL 0x010
-# define TPF_C0 0x020
-# define TPF_C1 0x040
-EXTERN char_u *p_sps; // 'spellsuggest'
+#define TPF_BS 0x001
+#define TPF_HT 0x002
+#define TPF_FF 0x004
+#define TPF_ESC 0x008
+#define TPF_DEL 0x010
+#define TPF_C0 0x020
+#define TPF_C1 0x040
+EXTERN char_u *p_sps; // 'spellsuggest'
EXTERN int p_spr; // 'splitright'
EXTERN int p_sol; // 'startofline'
-EXTERN char_u *p_su; // 'suffixes'
-EXTERN char_u *p_swb; // 'switchbuf'
+EXTERN char_u *p_su; // 'suffixes'
+EXTERN char_u *p_swb; // 'switchbuf'
EXTERN unsigned swb_flags;
#ifdef IN_OPTION_C
static char *(p_swb_values[]) =
- { "useopen", "usetab", "split", "newtab", "vsplit", "uselast", NULL };
+{ "useopen", "usetab", "split", "newtab", "vsplit", "uselast", NULL };
#endif
#define SWB_USEOPEN 0x001
#define SWB_USETAB 0x002
@@ -663,7 +665,7 @@ EXTERN char_u *p_tc; ///< 'tagcase'
EXTERN unsigned tc_flags; ///< flags from 'tagcase'
#ifdef IN_OPTION_C
static char *(p_tc_values[]) =
- { "followic", "ignore", "match", "followscs", "smart", NULL };
+{ "followic", "ignore", "match", "followscs", "smart", NULL };
#endif
#define TC_FOLLOWIC 0x01
#define TC_IGNORE 0x02
@@ -701,35 +703,35 @@ EXTERN unsigned vop_flags; ///< uses SSOP_ flags
EXTERN int p_vb; ///< 'visualbell'
EXTERN char_u *p_ve; ///< 'virtualedit'
EXTERN unsigned ve_flags;
-# ifdef IN_OPTION_C
-static char *(p_ve_values[]) = {"block", "insert", "all", "onemore", NULL};
-# endif
-# define VE_BLOCK 5 // includes "all"
-# define VE_INSERT 6 // includes "all"
-# define VE_ALL 4
-# define VE_ONEMORE 8
+#ifdef IN_OPTION_C
+static char *(p_ve_values[]) = { "block", "insert", "all", "onemore", NULL };
+#endif
+#define VE_BLOCK 5 // includes "all"
+#define VE_INSERT 6 // includes "all"
+#define VE_ALL 4
+#define VE_ONEMORE 8
EXTERN long p_verbose; // 'verbose'
#ifdef IN_OPTION_C
char_u *p_vfile = (char_u *)""; // used before options are initialized
#else
-extern char_u *p_vfile; // 'verbosefile'
+extern char_u *p_vfile; // 'verbosefile'
#endif
EXTERN int p_warn; // 'warn'
-EXTERN char_u *p_wop; // 'wildoptions'
+EXTERN char_u *p_wop; // 'wildoptions'
EXTERN unsigned wop_flags;
-# ifdef IN_OPTION_C
+#ifdef IN_OPTION_C
static char *(p_wop_values[]) = { "tagfile", "pum", NULL };
#endif
#define WOP_TAGFILE 0x01
#define WOP_PUM 0x02
EXTERN long p_window; // 'window'
-EXTERN char_u *p_wak; // 'winaltkeys'
-EXTERN char_u *p_wig; // 'wildignore'
-EXTERN char_u *p_ww; // 'whichwrap'
+EXTERN char_u *p_wak; // 'winaltkeys'
+EXTERN char_u *p_wig; // 'wildignore'
+EXTERN char_u *p_ww; // 'whichwrap'
EXTERN long p_wc; // 'wildchar'
EXTERN long p_wcm; // 'wildcharm'
EXTERN int p_wic; // 'wildignorecase'
-EXTERN char_u *p_wim; // 'wildmode'
+EXTERN char_u *p_wim; // 'wildmode'
EXTERN int p_wmnu; // 'wildmenu'
EXTERN long p_wh; // 'winheight'
EXTERN long p_wmh; // 'winminheight'
@@ -750,91 +752,91 @@ EXTERN int p_force_off; ///< options that cannot be turned on.
// b_p_scriptID[].
//
enum {
- BV_AI = 0
- , BV_AR
- , BV_BH
- , BV_BKC
- , BV_BT
- , BV_EFM
- , BV_GP
- , BV_MP
- , BV_BIN
- , BV_BL
- , BV_BOMB
- , BV_CHANNEL
- , BV_CI
- , BV_CIN
- , BV_CINK
- , BV_CINO
- , BV_CINW
- , BV_CM
- , BV_CMS
- , BV_COM
- , BV_CPT
- , BV_DICT
- , BV_TSR
- , BV_CSL
- , BV_CFU
- , BV_DEF
- , BV_INC
- , BV_EOL
- , BV_FIXEOL
- , BV_EP
- , BV_ET
- , BV_FENC
- , BV_FP
- , BV_BEXPR
- , BV_FEX
- , BV_FF
- , BV_FLP
- , BV_FO
- , BV_FT
- , BV_IMI
- , BV_IMS
- , BV_INDE
- , BV_INDK
- , BV_INEX
- , BV_INF
- , BV_ISK
- , BV_KMAP
- , BV_KP
- , BV_LISP
- , BV_LW
- , BV_MENC
- , BV_MA
- , BV_ML
- , BV_MOD
- , BV_MPS
- , BV_NF
- , BV_OFU
- , BV_PATH
- , BV_PI
- , BV_QE
- , BV_RO
- , BV_SCBK
- , BV_SI
- , BV_SMC
- , BV_SYN
- , BV_SPC
- , BV_SPF
- , BV_SPL
- , BV_SPO
- , BV_STS
- , BV_SUA
- , BV_SW
- , BV_SWF
- , BV_TFU
- , BV_TAGS
- , BV_TC
- , BV_TS
- , BV_TW
- , BV_TX
- , BV_UDF
- , BV_UL
- , BV_WM
- , BV_VSTS
- , BV_VTS
- , BV_COUNT // must be the last one
+ BV_AI = 0,
+ BV_AR,
+ BV_BH,
+ BV_BKC,
+ BV_BT,
+ BV_EFM,
+ BV_GP,
+ BV_MP,
+ BV_BIN,
+ BV_BL,
+ BV_BOMB,
+ BV_CHANNEL,
+ BV_CI,
+ BV_CIN,
+ BV_CINK,
+ BV_CINO,
+ BV_CINW,
+ BV_CM,
+ BV_CMS,
+ BV_COM,
+ BV_CPT,
+ BV_DICT,
+ BV_TSR,
+ BV_CSL,
+ BV_CFU,
+ BV_DEF,
+ BV_INC,
+ BV_EOL,
+ BV_FIXEOL,
+ BV_EP,
+ BV_ET,
+ BV_FENC,
+ BV_FP,
+ BV_BEXPR,
+ BV_FEX,
+ BV_FF,
+ BV_FLP,
+ BV_FO,
+ BV_FT,
+ BV_IMI,
+ BV_IMS,
+ BV_INDE,
+ BV_INDK,
+ BV_INEX,
+ BV_INF,
+ BV_ISK,
+ BV_KMAP,
+ BV_KP,
+ BV_LISP,
+ BV_LW,
+ BV_MENC,
+ BV_MA,
+ BV_ML,
+ BV_MOD,
+ BV_MPS,
+ BV_NF,
+ BV_OFU,
+ BV_PATH,
+ BV_PI,
+ BV_QE,
+ BV_RO,
+ BV_SCBK,
+ BV_SI,
+ BV_SMC,
+ BV_SYN,
+ BV_SPC,
+ BV_SPF,
+ BV_SPL,
+ BV_SPO,
+ BV_STS,
+ BV_SUA,
+ BV_SW,
+ BV_SWF,
+ BV_TFU,
+ BV_TAGS,
+ BV_TC,
+ BV_TS,
+ BV_TW,
+ BV_TX,
+ BV_UDF,
+ BV_UL,
+ BV_WM,
+ BV_VSTS,
+ BV_VTS,
+ BV_COUNT // must be the last one
};
/*
@@ -843,51 +845,51 @@ enum {
* window structure.
*/
enum {
- WV_LIST = 0
- , WV_ARAB
- , WV_COCU
- , WV_COLE
- , WV_CRBIND
- , WV_BRI
- , WV_BRIOPT
- , WV_DIFF
- , WV_FDC
- , WV_FEN
- , WV_FDI
- , WV_FDL
- , WV_FDM
- , WV_FML
- , WV_FDN
- , WV_FDE
- , WV_FDT
- , WV_FMR
- , WV_LBR
- , WV_NU
- , WV_RNU
- , WV_NUW
- , WV_PVW
- , WV_RL
- , WV_RLC
- , WV_SCBIND
- , WV_SCROLL
- , WV_SISO
- , WV_SO
- , WV_SPELL
- , WV_CUC
- , WV_CUL
- , WV_CULOPT
- , WV_CC
- , WV_SBR
- , WV_STL
- , WV_WFH
- , WV_WFW
- , WV_WRAP
- , WV_SCL
- , WV_WINHL
- , WV_FCS
- , WV_LCS
- , WV_WINBL
- , WV_COUNT // must be the last one
+ WV_LIST = 0,
+ WV_ARAB,
+ WV_COCU,
+ WV_COLE,
+ WV_CRBIND,
+ WV_BRI,
+ WV_BRIOPT,
+ WV_DIFF,
+ WV_FDC,
+ WV_FEN,
+ WV_FDI,
+ WV_FDL,
+ WV_FDM,
+ WV_FML,
+ WV_FDN,
+ WV_FDE,
+ WV_FDT,
+ WV_FMR,
+ WV_LBR,
+ WV_NU,
+ WV_RNU,
+ WV_NUW,
+ WV_PVW,
+ WV_RL,
+ WV_RLC,
+ WV_SCBIND,
+ WV_SCROLL,
+ WV_SISO,
+ WV_SO,
+ WV_SPELL,
+ WV_CUC,
+ WV_CUL,
+ WV_CULOPT,
+ WV_CC,
+ WV_SBR,
+ WV_STL,
+ WV_WFH,
+ WV_WFW,
+ WV_WRAP,
+ WV_SCL,
+ WV_WINHL,
+ WV_FCS,
+ WV_LCS,
+ WV_WINBL,
+ WV_COUNT // must be the last one
};
// Value for b_p_ul indicating the global value must be used.
diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c
index 0fc3f35ffc..0f363ecfc3 100644
--- a/src/nvim/os/env.c
+++ b/src/nvim/os/env.c
@@ -22,15 +22,15 @@
#include "nvim/vim.h"
#ifdef WIN32
-#include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8
+# include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8
#endif
#ifdef HAVE__NSGETENVIRON
-#include <crt_externs.h>
+# include <crt_externs.h>
#endif
#ifdef HAVE_SYS_UTSNAME_H
-#include <sys/utsname.h>
+# include <sys/utsname.h>
#endif
// Because `uv_os_getenv` requires allocating, we must manage a map to maintain
@@ -1146,7 +1146,7 @@ size_t home_replace(const buf_T *const buf, const char_u *src, char_u *const dst
/// Like home_replace, store the replaced string in allocated memory.
/// @param buf When not NULL, check for help files
/// @param src Input file name
-char_u * home_replace_save(buf_T *buf, char_u *src) FUNC_ATTR_NONNULL_RET
+char_u *home_replace_save(buf_T *buf, char_u *src) FUNC_ATTR_NONNULL_RET
{
size_t len = 3; // space for "~/" and trailing NUL
if (src != NULL) { // just in case
@@ -1161,7 +1161,7 @@ char_u * home_replace_save(buf_T *buf, char_u *src) FUNC_ATTR_NONNULL_RET
/// Function given to ExpandGeneric() to obtain an environment variable name.
char_u *get_env_name(expand_T *xp, int idx)
{
-# define ENVNAMELEN 100
+#define ENVNAMELEN 100
// this static buffer is needed to avoid a memory leak in ExpandGeneric
static char_u name[ENVNAMELEN];
assert(idx >= 0);
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index d50d68c99e..9675cfbb0f 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -29,7 +29,7 @@
#include "nvim/strings.h"
#ifdef WIN32
-#include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8
+# include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8
#endif
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -134,7 +134,7 @@ bool os_isdir(const char_u *name)
bool os_isdir_executable(const char *name)
FUNC_ATTR_NONNULL_ALL
{
- int32_t mode = os_getperm((const char *)name);
+ int32_t mode = os_getperm(name);
if (mode < 0) {
return false;
}
@@ -1226,12 +1226,12 @@ char *os_resolve_shortcut(const char *fname)
goto shortcut_errorw;
}
-# if 0 // This makes Vim wait a long time if the target does not exist.
+# if 0 // This makes Vim wait a long time if the target does not exist.
hr = pslw->lpVtbl->Resolve(pslw, NULL, SLR_NO_UI);
if (hr != S_OK) {
goto shortcut_errorw;
}
-# endif
+# endif
// Get the path to the link target.
ZeroMemory(wsz, MAX_PATH * sizeof(wchar_t));
@@ -1262,7 +1262,7 @@ shortcut_end:
return rfname;
}
-#define is_path_sep(c) ((c) == L'\\' || (c) == L'/')
+# define is_path_sep(c) ((c) == L'\\' || (c) == L'/')
/// Returns true if the path contains a reparse point (junction or symbolic
/// link). Otherwise false in returned.
bool os_is_reparse_point_include(const char *path)
diff --git a/src/nvim/os/input.h b/src/nvim/os/input.h
index d571965408..7026781407 100644
--- a/src/nvim/os/input.h
+++ b/src/nvim/os/input.h
@@ -1,8 +1,8 @@
#ifndef NVIM_OS_INPUT_H
#define NVIM_OS_INPUT_H
-#include <stdint.h>
#include <stdbool.h>
+#include <stdint.h>
#include "nvim/api/private/defs.h"
#include "nvim/event/multiqueue.h"
diff --git a/src/nvim/os/os.h b/src/nvim/os/os.h
index 3e89e5a94a..bff2936f8e 100644
--- a/src/nvim/os/os.h
+++ b/src/nvim/os/os.h
@@ -9,11 +9,11 @@
#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "os/env.h.generated.h"
# include "os/fs.h.generated.h"
# include "os/mem.h.generated.h"
-# include "os/env.h.generated.h"
-# include "os/users.h.generated.h"
# include "os/stdpaths.h.generated.h"
+# include "os/users.h.generated.h"
#endif
#endif // NVIM_OS_OS_H
diff --git a/src/nvim/os/os_defs.h b/src/nvim/os/os_defs.h
index 1b7859b0d3..8049b3b80e 100644
--- a/src/nvim/os/os_defs.h
+++ b/src/nvim/os/os_defs.h
@@ -16,7 +16,7 @@
#define BASENAMELEN (NAME_MAX - 5)
// Use the system path length if it makes sense.
-# define DEFAULT_MAXPATHL 4096
+#define DEFAULT_MAXPATHL 4096
#if defined(PATH_MAX) && (PATH_MAX > DEFAULT_MAXPATHL)
# define MAXPATHL PATH_MAX
#else
diff --git a/src/nvim/os/os_win_console.c b/src/nvim/os/os_win_console.c
index 2c9cb699fc..18e2e02b81 100644
--- a/src/nvim/os/os_win_console.c
+++ b/src/nvim/os/os_win_console.c
@@ -46,29 +46,3 @@ void os_replace_stdout_and_stderr_to_conout(void)
const int conerr_fd = _open_osfhandle((intptr_t)conout_handle, 0);
assert(conerr_fd == STDERR_FILENO);
}
-
-void os_set_vtp(bool enable)
-{
- static TriState is_legacy = kNone;
- if (is_legacy == kNone) {
- uv_tty_vtermstate_t state;
- uv_tty_get_vterm_state(&state);
- is_legacy = (state == UV_TTY_UNSUPPORTED) ? kTrue : kFalse;
- }
- if (!is_legacy && !os_has_vti()) {
- uv_tty_set_vterm_state(enable ? UV_TTY_SUPPORTED : UV_TTY_UNSUPPORTED);
- }
-}
-
-static bool os_has_vti(void)
-{
- static TriState has_vti = kNone;
- if (has_vti == kNone) {
- HANDLE handle = (HANDLE)_get_osfhandle(input_global_fd());
- DWORD dwMode;
- if (handle != INVALID_HANDLE_VALUE && GetConsoleMode(handle, &dwMode)) {
- has_vti = !!(dwMode & ENABLE_VIRTUAL_TERMINAL_INPUT) ? kTrue : kFalse;
- }
- }
- return has_vti == kTrue;
-}
diff --git a/src/nvim/os/process.h b/src/nvim/os/process.h
index 1722d56bd3..faa4762cf1 100644
--- a/src/nvim/os/process.h
+++ b/src/nvim/os/process.h
@@ -2,6 +2,7 @@
#define NVIM_OS_PROCESS_H
#include <stddef.h>
+
#include "nvim/api/private/defs.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c
index d94de2e397..24ecf5c24f 100644
--- a/src/nvim/os/pty_process_unix.c
+++ b/src/nvim/os/pty_process_unix.c
@@ -157,7 +157,7 @@ static void init_child(PtyProcess *ptyproc)
FUNC_ATTR_NONNULL_ALL
{
#if defined(HAVE__NSGETENVIRON)
-#define environ (*_NSGetEnviron())
+# define environ (*_NSGetEnviron())
#else
extern char **environ;
#endif
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index f0d446b4c5..2bff65b241 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.c
@@ -873,10 +873,10 @@ static void system_data_cb(Stream *stream, RBuffer *buf, size_t count, void *dat
/// Returns the previous decision if size=0.
static bool out_data_decide_throttle(size_t size)
{
- static uint64_t started = 0; // Start time of the current throttle.
- static size_t received = 0; // Bytes observed since last throttle.
- static size_t visit = 0; // "Pulse" count of the current throttle.
- static char pulse_msg[] = { ' ', ' ', ' ', '\0' };
+ static uint64_t started = 0; // Start time of the current throttle.
+ static size_t received = 0; // Bytes observed since last throttle.
+ static size_t visit = 0; // "Pulse" count of the current throttle.
+ static char pulse_msg[] = { ' ', ' ', ' ', '\0' };
if (!size) {
bool previous_decision = (visit > 0);
@@ -933,8 +933,8 @@ static bool out_data_decide_throttle(size_t size)
static void out_data_ring(char *output, size_t size)
{
#define MAX_CHUNK_SIZE (OUT_DATA_THRESHOLD / 2)
- static char last_skipped[MAX_CHUNK_SIZE]; // Saved output.
- static size_t last_skipped_len = 0;
+ static char last_skipped[MAX_CHUNK_SIZE]; // Saved output.
+ static size_t last_skipped_len = 0;
assert(output != NULL || (size == 0 || size == SIZE_MAX));
diff --git a/src/nvim/os/signal.c b/src/nvim/os/signal.c
index 65b1845d01..0d125ec964 100644
--- a/src/nvim/os/signal.c
+++ b/src/nvim/os/signal.c
@@ -119,7 +119,7 @@ void signal_accept_deadly(void)
rejecting_deadly = false;
}
-static char * signal_name(int signum)
+static char *signal_name(int signum)
{
switch (signum) {
#ifdef SIGPWR
diff --git a/src/nvim/os/time.h b/src/nvim/os/time.h
index ad4886446a..1b6c667dbb 100644
--- a/src/nvim/os/time.h
+++ b/src/nvim/os/time.h
@@ -1,8 +1,8 @@
#ifndef NVIM_OS_TIME_H
#define NVIM_OS_TIME_H
-#include <stdint.h>
#include <stdbool.h>
+#include <stdint.h>
#include <time.h>
typedef uint64_t Timestamp;
diff --git a/src/nvim/os/tty.c b/src/nvim/os/tty.c
index c80ef99084..126b1b0044 100644
--- a/src/nvim/os/tty.c
+++ b/src/nvim/os/tty.c
@@ -23,15 +23,6 @@
/// @param out_fd stdout file descriptor
void os_tty_guess_term(const char **term, int out_fd)
{
- bool winpty = (os_getenv("NVIM") != NULL);
-
- if (winpty) {
- // Force TERM=win32con when running in winpty.
- *term = "win32con";
- uv_tty_set_vterm_state(UV_TTY_UNSUPPORTED);
- return;
- }
-
bool conemu_ansi = strequal(os_getenv("ConEmuANSI"), "ON");
bool vtp = false;
diff --git a/src/nvim/os/unix_defs.h b/src/nvim/os/unix_defs.h
index 60a2dfa882..4ed3b51694 100644
--- a/src/nvim/os/unix_defs.h
+++ b/src/nvim/os/unix_defs.h
@@ -1,8 +1,8 @@
#ifndef NVIM_OS_UNIX_DEFS_H
#define NVIM_OS_UNIX_DEFS_H
-#include <unistd.h>
#include <sys/param.h>
+#include <unistd.h>
// POSIX.1-2008 says that NAME_MAX should be in here
#include <limits.h>
diff --git a/src/nvim/os/users.c b/src/nvim/os/users.c
index 2687c66f24..fd7ead68da 100644
--- a/src/nvim/os/users.c
+++ b/src/nvim/os/users.c
@@ -43,7 +43,7 @@ int os_get_usernames(garray_T *users)
}
ga_init(users, sizeof(char *), 20);
-# if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H)
+#if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H)
{
struct passwd *pw;
@@ -53,7 +53,7 @@ int os_get_usernames(garray_T *users)
}
endpwent();
}
-# elif defined(WIN32)
+#elif defined(WIN32)
{
DWORD nusers = 0, ntotal = 0, i;
PUSER_INFO_0 uinfo;
@@ -73,8 +73,8 @@ int os_get_usernames(garray_T *users)
NetApiBufferFree(uinfo);
}
}
-# endif
-# if defined(HAVE_GETPWNAM)
+#endif
+#if defined(HAVE_GETPWNAM)
{
const char *user_env = os_getenv("USER");
@@ -104,7 +104,7 @@ int os_get_usernames(garray_T *users)
}
}
}
-# endif
+#endif
return OK;
}
diff --git a/src/nvim/os/win_defs.h b/src/nvim/os/win_defs.h
index 66d72de08d..efef77be7b 100644
--- a/src/nvim/os/win_defs.h
+++ b/src/nvim/os/win_defs.h
@@ -7,11 +7,14 @@
// winsock2.h must be first to avoid incompatibilities
// with winsock.h (included by windows.h)
+
+// uncrustify:off
#include <winsock2.h>
-#include <windows.h>
-#include <sys/stat.h>
+// uncrustify:on
#include <io.h>
#include <stdio.h>
+#include <sys/stat.h>
+#include <windows.h>
// Windows does not have S_IFLNK but libuv defines it
// and sets the flag for us when calling uv_fs_stat.
diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c
index 44274e8f1d..9396a5896a 100644
--- a/src/nvim/os_unix.c
+++ b/src/nvim/os_unix.c
@@ -7,14 +7,13 @@
#include <stdbool.h>
#include <string.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/os_unix.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/eval.h"
#include "nvim/ex_cmds.h"
#include "nvim/fileio.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/main.h"
#include "nvim/mbyte.h"
@@ -23,19 +22,20 @@
#include "nvim/message.h"
#include "nvim/misc1.h"
#include "nvim/mouse.h"
-#include "nvim/garray.h"
+#include "nvim/msgpack_rpc/helpers.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/os/shell.h"
+#include "nvim/os/signal.h"
+#include "nvim/os/time.h"
+#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
-#include "nvim/ui.h"
#include "nvim/types.h"
-#include "nvim/os/os.h"
-#include "nvim/os/time.h"
-#include "nvim/os/input.h"
-#include "nvim/os/shell.h"
-#include "nvim/os/signal.h"
-#include "nvim/msgpack_rpc/helpers.h"
+#include "nvim/ui.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os_unix.c.generated.h"
@@ -61,13 +61,15 @@ vim_acl_T mch_get_acl(const char_u *fname)
// Set the ACL of file "fname" to "acl" (unless it's NULL).
void mch_set_acl(const char_u *fname, vim_acl_T aclent)
{
- if (aclent == NULL)
+ if (aclent == NULL) {
return;
+ }
}
void mch_free_acl(vim_acl_T aclent)
{
- if (aclent == NULL)
+ if (aclent == NULL) {
return;
+ }
}
#endif
diff --git a/src/nvim/os_unix.h b/src/nvim/os_unix.h
index d627b16ec0..aae05f7fcc 100644
--- a/src/nvim/os_unix.h
+++ b/src/nvim/os_unix.h
@@ -1,8 +1,8 @@
#ifndef NVIM_OS_UNIX_H
#define NVIM_OS_UNIX_H
-#include "nvim/types.h" // for vim_acl_T
#include "nvim/os/shell.h"
+#include "nvim/types.h" // for vim_acl_T
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os_unix.h.generated.h"
diff --git a/src/nvim/path.c b/src/nvim/path.c
index 5d14eba0a5..5b1793b111 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.c
@@ -6,15 +6,13 @@
#include <stdbool.h>
#include <stdlib.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/path.h"
#include "nvim/charset.h"
#include "nvim/eval.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
-#include "nvim/fileio.h"
#include "nvim/file_search.h"
+#include "nvim/fileio.h"
#include "nvim/garray.h"
#include "nvim/memfile.h"
#include "nvim/memline.h"
@@ -22,20 +20,22 @@
#include "nvim/message.h"
#include "nvim/misc1.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
#include "nvim/os/os.h"
#include "nvim/os/shell.h"
#include "nvim/os_unix.h"
+#include "nvim/path.h"
#include "nvim/quickfix.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/tag.h"
#include "nvim/types.h"
-#include "nvim/os/input.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#define URL_SLASH 1 /* path_is_url() has found "://" */
-#define URL_BACKSLASH 2 /* path_is_url() has found ":\\" */
+#define URL_SLASH 1 // path_is_url() has found "://"
+#define URL_BACKSLASH 2 // path_is_url() has found ":\\"
#ifdef gen_expand_wildcards
# undef gen_expand_wildcards
@@ -53,8 +53,8 @@
/// @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, const bool expandenv)
+FileComparison path_full_compare(char_u *const s1, char_u *const s2, const bool checkname,
+ const bool expandenv)
{
assert(s1 && s2);
char_u exp1[MAXPATHL];
@@ -63,9 +63,9 @@ FileComparison path_full_compare(char_u *const s1, char_u *const s2,
FileID file_id_1, file_id_2;
if (expandenv) {
- expand_env(s1, exp1, MAXPATHL);
+ expand_env(s1, exp1, MAXPATHL);
} else {
- xstrlcpy((char *)exp1, (const char *)s1, MAXPATHL);
+ xstrlcpy((char *)exp1, (const char *)s1, MAXPATHL);
}
bool id_ok_1 = os_fileid((char *)exp1, &file_id_1);
bool id_ok_2 = os_fileid((char *)s2, &file_id_2);
@@ -146,7 +146,7 @@ char_u *path_tail_with_sep(char_u *fname)
const char_u *invocation_path_tail(const char_u *invocation, size_t *len)
FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ARG(1)
{
- const char_u *tail = get_past_head((char_u *) invocation);
+ const char_u *tail = get_past_head((char_u *)invocation);
const char_u *p = tail;
while (*p != NUL && *p != ' ') {
bool was_sep = vim_ispathsep_nocolon(*p);
@@ -266,7 +266,7 @@ int vim_ispathlistsep(int c)
#ifdef UNIX
return c == ':';
#else
- return c == ';'; /* might not be right for every system... */
+ return c == ';'; // might not be right for every system...
#endif
}
@@ -280,11 +280,12 @@ char_u *shorten_dir(char_u *str)
char_u *d = str;
bool skip = false;
for (char_u *s = str;; ++s) {
- if (s >= tail) { /* copy the whole tail */
+ if (s >= tail) { // copy the whole tail
*d++ = *s;
- if (*s == NUL)
+ if (*s == NUL) {
break;
- } else if (vim_ispathsep(*s)) { /* copy '/' and next char */
+ }
+ } else if (vim_ispathsep(*s)) { // copy '/' and next char
*d++ = *s;
skip = false;
} else if (!skip) {
@@ -348,8 +349,7 @@ int path_fnamecmp(const char *fname1, const char *fname2)
/// @param[in] len Compare at most len bytes.
///
/// @return 0 if they are equal, non-zero otherwise.
-int path_fnamencmp(const char *const fname1, const char *const fname2,
- size_t len)
+int path_fnamencmp(const char *const fname1, const char *const fname2, size_t len)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
#ifdef BACKSLASH_IN_FILENAME
@@ -389,9 +389,8 @@ int path_fnamencmp(const char *const fname1, const char *const fname2,
/// add a path separator before fname2.
///
/// @return fname1
-static inline char *do_concat_fnames(char *fname1, const size_t len1,
- const char *fname2, const size_t len2,
- const bool sep)
+static inline char *do_concat_fnames(char *fname1, const size_t len1, const char *fname2,
+ const size_t len2, const bool sep)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
{
if (sep && *fname1 && !after_pathsep(fname1, fname1 + len1)) {
@@ -548,7 +547,7 @@ bool path_has_exp_wildcard(const char_u *p)
#else
const char *wildcards = "*?["; // Windows.
#endif
- if (vim_strchr((char_u *) wildcards, *p) != NULL) {
+ if (vim_strchr((char_u *)wildcards, *p) != NULL) {
return true;
}
}
@@ -590,8 +589,8 @@ static const char *scandir_next_with_dots(Directory *dir)
/// Implementation of path_expand().
///
/// Chars before `path + wildoff` do not get expanded.
-static size_t do_path_expand(garray_T *gap, const char_u *path,
- size_t wildoff, int flags, bool didstar)
+static size_t do_path_expand(garray_T *gap, const char_u *path, size_t wildoff, int flags,
+ bool didstar)
FUNC_ATTR_NONNULL_ALL
{
int start_len = gap->ga_len;
@@ -599,11 +598,12 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
bool starstar = false;
static int stardepth = 0; // depth for "**" expansion
- /* Expanding "**" may take a long time, check for CTRL-C. */
+ // Expanding "**" may take a long time, check for CTRL-C.
if (stardepth > 0) {
os_breakcheck();
- if (got_int)
+ if (got_int) {
return 0;
+ }
}
// Make room for file name. When doing encoding conversion the actual
@@ -633,7 +633,7 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
|| (!p_fic && (flags & EW_ICASE)
&& isalpha(PTR2CHAR(path_end)))
#endif
- )) {
+ )) {
e = p;
}
len = (size_t)(utfc_ptr2len(path_end));
@@ -644,20 +644,23 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
e = p;
*e = NUL;
- /* Now we have one wildcard component between "s" and "e". */
+ // Now we have one wildcard component between "s" and "e".
/* Remove backslashes between "wildoff" and the start of the wildcard
* component. */
- for (p = buf + wildoff; p < s; ++p)
+ for (p = buf + wildoff; p < s; ++p) {
if (rem_backslash(p)) {
STRMOVE(p, p + 1);
--e;
--s;
}
+ }
- /* Check for "**" between "s" and "e". */
- for (p = s; p < e; ++p)
- if (p[0] == '*' && p[1] == '*')
+ // Check for "**" between "s" and "e".
+ for (p = s; p < e; ++p) {
+ if (p[0] == '*' && p[1] == '*') {
starstar = true;
+ }
+ }
// convert the file pattern to a regexp pattern
int starts_with_dot = *s == '.';
@@ -675,11 +678,13 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
#else
regmatch.rm_ic = true; // Always ignore case on Windows.
#endif
- if (flags & (EW_NOERROR | EW_NOTWILD))
+ if (flags & (EW_NOERROR | EW_NOTWILD)) {
++emsg_silent;
+ }
regmatch.regprog = vim_regcomp(pat, RE_MAGIC);
- if (flags & (EW_NOERROR | EW_NOTWILD))
+ if (flags & (EW_NOERROR | EW_NOTWILD)) {
--emsg_silent;
+ }
xfree(pat);
if (regmatch.regprog == NULL && (flags & EW_NOTWILD) == 0) {
@@ -727,9 +732,9 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
}
STRCPY(buf + len, path_end);
- if (path_has_exp_wildcard(path_end)) { /* handle more wildcards */
- /* need to expand another component of the path */
- /* remove backslashes for the remaining components only */
+ if (path_has_exp_wildcard(path_end)) { // handle more wildcards
+ // need to expand another component of the path
+ // remove backslashes for the remaining components only
(void)do_path_expand(gap, buf, len + 1, flags, false);
} else {
FileInfo file_info;
@@ -741,7 +746,7 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
}
// add existing file or symbolic link
if ((flags & EW_ALLLINKS) ? os_fileinfo_link((char *)buf, &file_info)
- : os_path_exists(buf)) {
+ : os_path_exists(buf)) {
addfile(gap, buf, flags);
}
}
@@ -767,14 +772,16 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
*/
static int find_previous_pathsep(char_u *path, char_u **psep)
{
- /* skip the current separator */
- if (*psep > path && vim_ispathsep(**psep))
+ // skip the current separator
+ if (*psep > path && vim_ispathsep(**psep)) {
--*psep;
+ }
- /* find the previous separator */
+ // find the previous separator
while (*psep > path) {
- if (vim_ispathsep(**psep))
+ if (vim_ispathsep(**psep)) {
return OK;
+ }
MB_PTR_BACK(path, *psep);
}
@@ -828,8 +835,9 @@ static void expand_path_option(char_u *curdir, garray_T *gap)
/* Relative to current buffer:
* "/path/file" + "." -> "/path/"
* "/path/file" + "./subdir" -> "/path/subdir" */
- if (curbuf->b_ffname == NULL)
+ if (curbuf->b_ffname == NULL) {
continue;
+ }
char_u *p = path_tail(curbuf->b_ffname);
size_t len = (size_t)(p - curbuf->b_ffname);
if (len + STRLEN(buf) >= MAXPATHL) {
@@ -870,13 +878,13 @@ static void expand_path_option(char_u *curdir, garray_T *gap)
*
* path: /foo/bar/baz
* fname: /foo/bar/baz/quux.txt
- * returns: ^this
+ * returns: ^this
*/
static char_u *get_path_cutoff(char_u *fname, garray_T *gap)
{
int maxlen = 0;
- char_u **path_part = (char_u **)gap->ga_data;
- char_u *cutoff = NULL;
+ char_u **path_part = (char_u **)gap->ga_data;
+ char_u *cutoff = NULL;
for (int i = 0; i < gap->ga_len; i++) {
int j = 0;
@@ -932,14 +940,16 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
STRCAT(file_pattern, pattern);
char_u *pat = file_pat_to_reg_pat(file_pattern, NULL, NULL, true);
xfree(file_pattern);
- if (pat == NULL)
+ if (pat == NULL) {
return;
+ }
- regmatch.rm_ic = TRUE; /* always ignore case */
+ regmatch.rm_ic = TRUE; // always ignore case
regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
xfree(pat);
- if (regmatch.regprog == NULL)
+ if (regmatch.regprog == NULL) {
return;
+ }
char_u *curdir = xmalloc(MAXPATHL);
os_dirname(curdir, MAXPATHL);
@@ -951,16 +961,17 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
char_u *path = fnames[i];
int is_in_curdir;
char_u *dir_end = (char_u *)gettail_dir((const char *)path);
- char_u *pathsep_p;
- char_u *path_cutoff;
+ char_u *pathsep_p;
+ char_u *path_cutoff;
len = STRLEN(path);
is_in_curdir = fnamencmp(curdir, path, dir_end - path) == 0
&& curdir[dir_end - path] == NUL;
- if (is_in_curdir)
+ if (is_in_curdir) {
in_curdir[i] = vim_strsave(path);
+ }
- /* Shorten the filename while maintaining its uniqueness */
+ // Shorten the filename while maintaining its uniqueness
path_cutoff = get_path_cutoff(path, &path_ga);
// Don't assume all files can be reached without path when search
@@ -1010,19 +1021,21 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
os_breakcheck();
}
- /* Shorten filenames in /in/current/directory/{filename} */
+ // Shorten filenames in /in/current/directory/{filename}
for (int i = 0; i < gap->ga_len && !got_int; i++) {
char_u *rel_path;
char_u *path = in_curdir[i];
- if (path == NULL)
+ if (path == NULL) {
continue;
+ }
/* If the {filename} is not unique, change it to ./{filename}.
* Else reduce it to {filename} */
short_name = path_shorten_fname(path, curdir);
- if (short_name == NULL)
+ if (short_name == NULL) {
short_name = path;
+ }
if (is_unique(short_name, gap, i)) {
STRCPY(fnames[i], short_name);
continue;
@@ -1040,14 +1053,16 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
}
xfree(curdir);
- for (int i = 0; i < gap->ga_len; i++)
+ for (int i = 0; i < gap->ga_len; i++) {
xfree(in_curdir[i]);
+ }
xfree(in_curdir);
ga_clear_strings(&path_ga);
vim_regfree(regmatch.regprog);
- if (sort_again)
+ if (sort_again) {
ga_remove_duplicate_strings(gap);
+ }
}
/// Find end of the directory name
@@ -1072,8 +1087,9 @@ const char *gettail_dir(const char *const fname)
look_for_sep = false;
}
} else {
- if (!look_for_sep)
+ if (!look_for_sep) {
dir_end = next_dir_end;
+ }
look_for_sep = true;
}
MB_PTR_ADV(p);
@@ -1082,16 +1098,12 @@ const char *gettail_dir(const char *const fname)
}
-/*
- * Calls globpath() with 'path' values for the given pattern and stores the
- * result in "gap".
- * Returns the total number of matches.
- */
-static int expand_in_path(
- garray_T *const gap,
- char_u *const pattern,
- const int flags // EW_* flags
-)
+/// Calls globpath() with 'path' values for the given pattern and stores the
+/// result in "gap".
+/// Returns the total number of matches.
+///
+/// @param flags EW_* flags
+static int expand_in_path(garray_T *const gap, char_u *const pattern, const int flags)
{
garray_T path_ga;
@@ -1131,7 +1143,7 @@ static bool has_env_var(char_u *p)
for (; *p; MB_PTR_ADV(p)) {
if (*p == '\\' && p[1] != NUL) {
p++;
- } else if (vim_strchr((char_u *) "$" , *p) != NULL) {
+ } else if (vim_strchr((char_u *)"$", *p) != NULL) {
return true;
}
}
@@ -1186,8 +1198,7 @@ static bool has_special_wildchar(char_u *p)
/// If FAIL is returned, *num_file and *file are either
/// unchanged or *num_file is set to 0 and *file is set
/// to NULL or points to "".
-int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
- char_u ***file, int flags)
+int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file, char_u ***file, int flags)
{
garray_T ga;
char_u *p;
@@ -1203,9 +1214,9 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
*/
if (recursive)
#ifdef SPECIAL_WILDCHAR
- return os_expand_wildcards(num_pat, pat, num_file, file, flags);
+ { return os_expand_wildcards(num_pat, pat, num_file, file, flags); }
#else
- return FAIL;
+ { return FAIL; }
#endif
#ifdef SPECIAL_WILDCHAR
@@ -1247,8 +1258,9 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
// First expand environment variables, "~/" and "~user/".
if ((has_env_var(p) && !(flags & EW_NOTENV)) || *p == '~') {
p = expand_env_save_opt(p, true);
- if (p == NULL)
+ if (p == NULL) {
p = pat[i];
+ }
#ifdef UNIX
/*
* On Unix, if expand_env() can't expand an environment
@@ -1278,8 +1290,8 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
&& !path_is_absolute(p)
&& !(p[0] == '.'
&& (vim_ispathsep(p[1])
- || (p[1] == '.' && vim_ispathsep(p[2]))))
- ) {
+ || (p[1] == '.' &&
+ vim_ispathsep(p[2]))))) {
/* :find completion where 'path' is used.
* Recursiveness is OK here. */
recursive = false;
@@ -1295,7 +1307,7 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
}
if (add_pat == -1 || (add_pat == 0 && (flags & EW_NOTFOUND))) {
- char_u *t = backslash_halve_save(p);
+ char_u *t = backslash_halve_save(p);
/* When EW_NOTFOUND is used, always add files and dirs. Makes
* "vim c:/" work. */
@@ -1310,10 +1322,12 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
}
}
- if (did_expand_in_path && !GA_EMPTY(&ga) && (flags & EW_PATH))
+ if (did_expand_in_path && !GA_EMPTY(&ga) && (flags & EW_PATH)) {
uniquefy_paths(&ga, p);
- if (p != pat[i])
+ }
+ if (p != pat[i]) {
xfree(p);
+ }
}
*num_file = ga.ga_len;
@@ -1333,14 +1347,12 @@ static int vim_backtick(char_u *p)
return *p == '`' && *(p + 1) != NUL && *(p + STRLEN(p) - 1) == '`';
}
-// Expand an item in `backticks` by executing it as a command.
-// Currently only works when pat[] starts and ends with a `.
-// Returns number of file names found, -1 if an error is encountered.
-static int expand_backtick(
- garray_T *gap,
- char_u *pat,
- int flags /* EW_* flags */
-)
+/// Expand an item in `backticks` by executing it as a command.
+/// Currently only works when pat[] starts and ends with a `.
+/// Returns number of file names found, -1 if an error is encountered.
+///
+/// @param flags EW_* flags
+static int expand_backtick(garray_T *gap, char_u *pat, int flags)
{
char_u *p;
char_u *buffer;
@@ -1361,11 +1373,12 @@ static int expand_backtick(
cmd = buffer;
while (*cmd != NUL) {
- cmd = skipwhite(cmd); /* skip over white space */
+ cmd = skipwhite(cmd); // skip over white space
p = cmd;
- while (*p != NUL && *p != '\r' && *p != '\n') /* skip over entry */
+ while (*p != NUL && *p != '\r' && *p != '\n') { // skip over entry
++p;
- /* add an entry if it is not empty */
+ }
+ // add an entry if it is not empty
if (p > cmd) {
char_u i = *p;
*p = NUL;
@@ -1374,8 +1387,9 @@ static int expand_backtick(
++cnt;
}
cmd = p;
- while (*cmd != NUL && (*cmd == '\r' || *cmd == '\n'))
+ while (*cmd != NUL && (*cmd == '\r' || *cmd == '\n')) {
++cmd;
+ }
}
xfree(buffer);
@@ -1414,18 +1428,16 @@ void slash_adjust(char_u *p)
}
#endif
-// Add a file to a file list. Accepted flags:
-// EW_DIR add directories
-// EW_FILE add files
-// EW_EXEC add executable files
-// EW_NOTFOUND add even when it doesn't exist
-// EW_ADDSLASH add slash after directory name
-// EW_ALLLINKS add symlink also when the referred file does not exist
-void addfile(
- garray_T *gap,
- char_u *f, /* filename */
- int flags
-)
+/// Add a file to a file list. Accepted flags:
+/// EW_DIR add directories
+/// EW_FILE add files
+/// EW_EXEC add executable files
+/// EW_NOTFOUND add even when it doesn't exist
+/// EW_ADDSLASH add slash after directory name
+/// EW_ALLLINKS add symlink also when the referred file does not exist
+///
+/// @param f filename
+void addfile(garray_T *gap, char_u *f, int flags)
{
bool isdir;
FileInfo file_info;
@@ -1439,14 +1451,16 @@ void addfile(
}
#ifdef FNAME_ILLEGAL
- /* if the file/dir contains illegal characters, don't add it */
- if (vim_strpbrk(f, (char_u *)FNAME_ILLEGAL) != NULL)
+ // if the file/dir contains illegal characters, don't add it
+ if (vim_strpbrk(f, (char_u *)FNAME_ILLEGAL) != NULL) {
return;
+ }
#endif
isdir = os_isdir(f);
- if ((isdir && !(flags & EW_DIR)) || (!isdir && !(flags & EW_FILE)))
+ if ((isdir && !(flags & EW_DIR)) || (!isdir && !(flags & EW_FILE))) {
return;
+ }
// If the file isn't executable, may not add it. Do accept directories.
// When invoked from expand_shellcmd() do not use $PATH.
@@ -1464,8 +1478,9 @@ void addfile(
/*
* Append a slash or backslash after directory names if none is present.
*/
- if (isdir && (flags & EW_ADDSLASH))
+ if (isdir && (flags & EW_ADDSLASH)) {
add_pathsep((char *)p);
+ }
GA_APPEND(char_u *, gap, p);
}
@@ -1478,14 +1493,15 @@ void addfile(
void simplify_filename(char_u *filename)
{
int components = 0;
- char_u *p, *tail, *start;
+ char_u *p, *tail, *start;
bool stripping_disabled = false;
bool relative = true;
p = filename;
#ifdef BACKSLASH_IN_FILENAME
- if (p[1] == ':') /* skip "x:" */
+ if (p[1] == ':') { // skip "x:"
p += 2;
+ }
#endif
if (vim_ispathsep(*p)) {
@@ -1494,17 +1510,18 @@ void simplify_filename(char_u *filename)
++p;
while (vim_ispathsep(*p));
}
- start = p; /* remember start after "c:/" or "/" or "///" */
+ start = p; // remember start after "c:/" or "/" or "///"
do {
/* At this point "p" is pointing to the char following a single "/"
* or "p" is at the "start" of the (absolute or relative) path name. */
- if (vim_ispathsep(*p))
- STRMOVE(p, p + 1); /* remove duplicate "/" */
- else if (p[0] == '.' && (vim_ispathsep(p[1]) || p[1] == NUL)) {
- if (p == start && relative)
- p += 1 + (p[1] != NUL); /* keep single "." or leading "./" */
- else {
+ if (vim_ispathsep(*p)) {
+ STRMOVE(p, p + 1); // remove duplicate "/"
+ } else if (p[0] == '.' &&
+ (vim_ispathsep(p[1]) || p[1] == NUL)) {
+ if (p == start && relative) {
+ p += 1 + (p[1] != NUL); // keep single "." or leading "./"
+ } else {
/* Strip "./" or ".///". If we are at the end of the file name
* and there is no trailing path separator, either strip "/." if
* we are after "start", or strip "." if we are at the beginning
@@ -1527,11 +1544,11 @@ void simplify_filename(char_u *filename)
MB_PTR_ADV(tail);
}
- if (components > 0) { /* strip one preceding component */
+ if (components > 0) { // strip one preceding component
bool do_strip = false;
char_u saved_char;
- /* Don't strip for an erroneous file name. */
+ // Don't strip for an erroneous file name.
if (!stripping_disabled) {
/* If the preceding component does not exist in the file
* system, we strip it. On Unix, we don't accept a symbolic
@@ -1613,21 +1630,22 @@ void simplify_filename(char_u *filename)
*p++ = '.';
*p = NUL;
} else {
- if (p > start && tail[-1] == '.')
+ if (p > start && tail[-1] == '.') {
--p;
- STRMOVE(p, tail); /* strip previous component */
+ }
+ STRMOVE(p, tail); // strip previous component
}
--components;
}
- } else if (p == start && !relative) /* leading "/.." or "/../" */
- STRMOVE(p, tail); /* strip ".." or "../" */
- else {
- if (p == start + 2 && p[-2] == '.') { /* leading "./../" */
- STRMOVE(p - 2, p); /* strip leading "./" */
+ } else if (p == start && !relative) { // leading "/.." or "/../"
+ STRMOVE(p, tail); // strip ".." or "../"
+ } else {
+ if (p == start + 2 && p[-2] == '.') { // leading "./../"
+ STRMOVE(p - 2, p); // strip leading "./"
tail -= 2;
}
- p = tail; /* skip to char after ".." or "../" */
+ p = tail; // skip to char after ".." or "../"
}
} else {
components++; // Simple path component.
@@ -1639,31 +1657,23 @@ void simplify_filename(char_u *filename)
static char *eval_includeexpr(const char *const ptr, const size_t len)
{
set_vim_var_string(VV_FNAME, ptr, (ptrdiff_t)len);
- char *res = (char *)eval_to_string_safe(
- curbuf->b_p_inex, NULL,
- was_set_insecurely(curwin, (char_u *)"includeexpr", OPT_LOCAL));
+ char *res = (char *)eval_to_string_safe(curbuf->b_p_inex, NULL,
+ was_set_insecurely(curwin, "includeexpr", OPT_LOCAL));
set_vim_var_string(VV_FNAME, NULL, 0);
return res;
}
-/*
- * Return the name of the file ptr[len] in 'path'.
- * Otherwise like file_name_at_cursor().
- */
-char_u *
-find_file_name_in_path (
- char_u *ptr,
- size_t len,
- int options,
- long count,
- char_u *rel_fname /* file we are searching relative to */
-)
+/// Return the name of the file ptr[len] in 'path'.
+/// Otherwise like file_name_at_cursor().
+///
+/// @param rel_fname file we are searching relative to
+char_u *find_file_name_in_path(char_u *ptr, size_t len, int options, long count, char_u *rel_fname)
{
char_u *file_name;
char_u *tofree = NULL;
if ((options & FNAME_INCL) && *curbuf->b_p_inex != NUL) {
- tofree = (char_u *) eval_includeexpr((char *) ptr, len);
+ tofree = (char_u *)eval_includeexpr((char *)ptr, len);
if (tofree != NULL) {
ptr = tofree;
len = STRLEN(ptr);
@@ -1680,7 +1690,7 @@ find_file_name_in_path (
*/
if (file_name == NULL
&& !(options & FNAME_INCL) && *curbuf->b_p_inex != NUL) {
- tofree = (char_u *) eval_includeexpr((char *) ptr, len);
+ tofree = (char_u *)eval_includeexpr((char *)ptr, len);
if (tofree != NULL) {
ptr = tofree;
len = STRLEN(ptr);
@@ -1701,8 +1711,9 @@ find_file_name_in_path (
xfree(file_name);
file_name = find_file_in_path(ptr, len, options, FALSE, rel_fname);
}
- } else
+ } else {
file_name = vim_strnsave(ptr, len);
+ }
xfree(tofree);
@@ -1714,10 +1725,11 @@ find_file_name_in_path (
// URL_BACKSLASH.
int path_is_url(const char *p)
{
- if (strncmp(p, "://", 3) == 0)
+ if (strncmp(p, "://", 3) == 0) {
return URL_SLASH;
- else if (strncmp(p, ":\\\\", 3) == 0)
+ } else if (strncmp(p, ":\\\\", 3) == 0) {
return URL_BACKSLASH;
+ }
return 0;
}
@@ -1735,7 +1747,9 @@ int path_with_url(const char *fname)
bool path_with_extension(const char *path, const char *extension)
{
const char *last_dot = strrchr(path, '.');
- if (!last_dot) { return false; }
+ if (!last_dot) {
+ return false;
+ }
return strcmp(last_dot + 1, extension) == 0;
}
@@ -1809,8 +1823,9 @@ char *fix_fname(const char *fname)
# ifdef BACKSLASH_IN_FILENAME
|| strstr(fname, "\\\\") != NULL
# endif
- )
+ ) {
return FullName_save(fname, false);
+ }
fname = xstrdup(fname);
@@ -1845,7 +1860,7 @@ void path_fix_case(char_u *name)
tail = name;
} else {
*slash = NUL;
- ok = os_scandir(&dir, (char *) name);
+ ok = os_scandir(&dir, (char *)name);
*slash = '/';
tail = slash + 1;
}
@@ -1855,7 +1870,7 @@ void path_fix_case(char_u *name)
}
char_u *entry;
- while ((entry = (char_u *) os_scandir_next(&dir))) {
+ while ((entry = (char_u *)os_scandir_next(&dir))) {
// Only accept names that differ in case and are the same byte
// length. TODO: accept different length name.
if (STRICMP(tail, entry) == 0 && STRLEN(tail) == STRLEN(entry)) {
@@ -1895,12 +1910,13 @@ int after_pathsep(const char *b, const char *p)
bool same_directory(char_u *f1, char_u *f2)
{
char_u ffname[MAXPATHL];
- char_u *t1;
- char_u *t2;
+ char_u *t1;
+ char_u *t2;
- /* safety check */
- if (f1 == NULL || f2 == NULL)
+ // safety check
+ if (f1 == NULL || f2 == NULL) {
return false;
+ }
(void)vim_FullName((char *)f1, (char *)ffname, MAXPATHL, FALSE);
t1 = path_tail_with_sep(ffname);
@@ -1918,22 +1934,23 @@ int pathcmp(const char *p, const char *q, int maxlen)
{
int i, j;
int c1, c2;
- const char *s = NULL;
+ const char *s = NULL;
for (i = 0, j = 0; maxlen < 0 || (i < maxlen && j < maxlen);) {
c1 = PTR2CHAR((char_u *)p + i);
c2 = PTR2CHAR((char_u *)q + j);
- /* End of "p": check if "q" also ends or just has a slash. */
+ // End of "p": check if "q" also ends or just has a slash.
if (c1 == NUL) {
- if (c2 == NUL) /* full match */
+ if (c2 == NUL) { // full match
return 0;
+ }
s = q;
i = j;
break;
}
- /* End of "q": check if "p" just has a slash. */
+ // End of "q": check if "p" just has a slash.
if (c2 == NUL) {
s = p;
break;
@@ -1941,15 +1958,17 @@ int pathcmp(const char *p, const char *q, int maxlen)
if ((p_fic ? mb_toupper(c1) != mb_toupper(c2) : c1 != c2)
#ifdef BACKSLASH_IN_FILENAME
- /* consider '/' and '\\' to be equal */
+ // consider '/' and '\\' to be equal
&& !((c1 == '/' && c2 == '\\')
|| (c1 == '\\' && c2 == '/'))
#endif
) {
- if (vim_ispathsep(c1))
+ if (vim_ispathsep(c1)) {
return -1;
- if (vim_ispathsep(c2))
+ }
+ if (vim_ispathsep(c2)) {
return 1;
+ }
return p_fic ? mb_toupper(c1) - mb_toupper(c2)
: c1 - c2; // no match
}
@@ -2018,7 +2037,7 @@ char_u *path_shorten_fname(char_u *full_path, char_u *dir_name)
}
assert(dir_name != NULL);
- size_t len = strlen((char *)dir_name);
+ size_t len = STRLEN(dir_name);
// If dir_name is a path head, full_path can always be made relative.
if (len == (size_t)path_head_length() && is_path_head(dir_name)) {
@@ -2057,26 +2076,27 @@ char_u *path_shorten_fname(char_u *full_path, char_u *dir_name)
/// If FAIL is returned, *num_file and *file are either
/// unchanged or *num_file is set to 0 and *file is set
/// to NULL or points to "".
-int expand_wildcards_eval(char_u **pat, int *num_file, char_u ***file,
- int flags)
+int expand_wildcards_eval(char_u **pat, int *num_file, char_u ***file, int flags)
{
int ret = FAIL;
- char_u *eval_pat = NULL;
- char_u *exp_pat = *pat;
- char_u *ignored_msg;
+ char_u *eval_pat = NULL;
+ char_u *exp_pat = *pat;
+ char_u *ignored_msg;
size_t usedlen;
if (*exp_pat == '%' || *exp_pat == '#' || *exp_pat == '<') {
++emsg_off;
eval_pat = eval_vars(exp_pat, exp_pat, &usedlen,
- NULL, &ignored_msg, NULL);
+ NULL, &ignored_msg, NULL);
--emsg_off;
- if (eval_pat != NULL)
+ if (eval_pat != NULL) {
exp_pat = concat_str(eval_pat, exp_pat + usedlen);
+ }
}
- if (exp_pat != NULL)
+ if (exp_pat != NULL) {
ret = expand_wildcards(1, &exp_pat, num_file, file, flags);
+ }
if (eval_pat != NULL) {
xfree(exp_pat);
@@ -2100,25 +2120,25 @@ int expand_wildcards_eval(char_u **pat, int *num_file, char_u ***file,
/// If FAIL is returned, *num_file and *file are either
/// unchanged or *num_file is set to 0 and *file is set to
/// NULL or points to "".
-int expand_wildcards(int num_pat, char_u **pat, int *num_files, char_u ***files,
- int flags)
+int expand_wildcards(int num_pat, char_u **pat, int *num_files, char_u ***files, int flags)
{
int retval;
int i, j;
- char_u *p;
- int non_suf_match; /* number without matching suffix */
+ char_u *p;
+ int non_suf_match; // number without matching suffix
retval = gen_expand_wildcards(num_pat, pat, num_files, files, flags);
- /* When keeping all matches, return here */
- if ((flags & EW_KEEPALL) || retval == FAIL)
+ // When keeping all matches, return here
+ if ((flags & EW_KEEPALL) || retval == FAIL) {
return retval;
+ }
/*
* Remove names that match 'wildignore'.
*/
if (*p_wig) {
- char_u *ffname;
+ char_u *ffname;
// check all files in (*files)[]
assert(*num_files == 0 || *files != NULL);
@@ -2183,7 +2203,7 @@ int match_suffix(char_u *fname)
if (setsuflen == 0) {
char_u *tail = path_tail(fname);
- /* empty entry: match name without a '.' */
+ // empty entry: match name without a '.'
if (vim_strchr(tail, '.') == NULL) {
setsuflen = 1;
break;
@@ -2209,13 +2229,13 @@ int path_full_dir_name(char *directory, char *buffer, size_t len)
int retval = OK;
if (STRLEN(directory) == 0) {
- return os_dirname((char_u *) buffer, len);
+ return os_dirname((char_u *)buffer, len);
}
char old_dir[MAXPATHL];
// Get current directory name.
- if (os_dirname((char_u *) old_dir, MAXPATHL) == FAIL) {
+ if (os_dirname((char_u *)old_dir, MAXPATHL) == FAIL) {
return FAIL;
}
@@ -2229,7 +2249,7 @@ int path_full_dir_name(char *directory, char *buffer, size_t len)
retval = FAIL;
}
- if (retval == FAIL || os_dirname((char_u *) buffer, len) == FAIL) {
+ if (retval == FAIL || os_dirname((char_u *)buffer, len) == FAIL) {
// Do not return immediately since we are in the wrong directory.
retval = FAIL;
}
@@ -2283,14 +2303,13 @@ int append_path(char *path, const char *to_append, size_t max_len)
/// @param force also expand when "fname" is already absolute.
///
/// @return FAIL for failure, OK for success.
-static int path_to_absolute(const char_u *fname, char_u *buf, size_t len,
- int force)
+static int path_to_absolute(const char_u *fname, char_u *buf, size_t len, int force)
{
char_u *p;
*buf = NUL;
char *relative_directory = xmalloc(len);
- char *end_of_path = (char *) fname;
+ char *end_of_path = (char *)fname;
// expand it if forced or not an absolute path
if (force || !path_is_absolute(fname)) {
@@ -2311,13 +2330,13 @@ static int path_to_absolute(const char_u *fname, char_u *buf, size_t len,
memcpy(relative_directory, fname, (size_t)(p - fname));
relative_directory[p-fname] = NUL;
}
- end_of_path = (char *) (p + 1);
+ end_of_path = (char *)(p + 1);
} else {
relative_directory[0] = NUL;
- end_of_path = (char *) fname;
+ end_of_path = (char *)fname;
}
- if (FAIL == path_full_dir_name(relative_directory, (char *) buf, len)) {
+ if (FAIL == path_full_dir_name(relative_directory, (char *)buf, len)) {
xfree(relative_directory);
return FAIL;
}
diff --git a/src/nvim/path.h b/src/nvim/path.h
index 15abd19646..5d81e68caa 100644
--- a/src/nvim/path.h
+++ b/src/nvim/path.h
@@ -2,22 +2,22 @@
#define NVIM_PATH_H
#include "nvim/func_attr.h"
-#include "nvim/types.h"
#include "nvim/garray.h"
+#include "nvim/types.h"
-/* Flags for expand_wildcards() */
-#define EW_DIR 0x01 /* include directory names */
-#define EW_FILE 0x02 /* include file names */
-#define EW_NOTFOUND 0x04 /* include not found names */
-#define EW_ADDSLASH 0x08 /* append slash to directory name */
-#define EW_KEEPALL 0x10 /* keep all matches */
-#define EW_SILENT 0x20 /* don't print "1 returned" from shell */
-#define EW_EXEC 0x40 /* executable files */
-#define EW_PATH 0x80 /* search in 'path' too */
-#define EW_ICASE 0x100 /* ignore case */
-#define EW_NOERROR 0x200 /* no error for bad regexp */
-#define EW_NOTWILD 0x400 /* add match with literal name if exists */
-#define EW_KEEPDOLLAR 0x800 /* do not escape $, $var is expanded */
+// Flags for expand_wildcards()
+#define EW_DIR 0x01 // include directory names
+#define EW_FILE 0x02 // include file names
+#define EW_NOTFOUND 0x04 // include not found names
+#define EW_ADDSLASH 0x08 // append slash to directory name
+#define EW_KEEPALL 0x10 // keep all matches
+#define EW_SILENT 0x20 // don't print "1 returned" from shell
+#define EW_EXEC 0x40 // executable files
+#define EW_PATH 0x80 // search in 'path' too
+#define EW_ICASE 0x100 // ignore case
+#define EW_NOERROR 0x200 // no error for bad regexp
+#define EW_NOTWILD 0x400 // add match with literal name if exists
+#define EW_KEEPDOLLAR 0x800 // do not escape $, $var is expanded
/* Note: mostly EW_NOTFOUND and EW_SILENT are mutually exclusive: EW_NOTFOUND
* is used when executing commands and EW_SILENT for interactive expanding. */
#define EW_ALLLINKS 0x1000 // also links not pointing to existing file
diff --git a/src/nvim/plines.c b/src/nvim/plines.c
index a656686a95..5b0418ed92 100644
--- a/src/nvim/plines.c
+++ b/src/nvim/plines.c
@@ -5,18 +5,18 @@
#include <assert.h>
#include <inttypes.h>
+#include <limits.h>
#include <stdbool.h>
#include <string.h>
-#include <limits.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/plines.h"
+#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/decoration.h"
#include "nvim/diff.h"
-#include "nvim/func_attr.h"
#include "nvim/fold.h"
+#include "nvim/func_attr.h"
#include "nvim/indent.h"
#include "nvim/main.h"
#include "nvim/mbyte.h"
@@ -24,10 +24,11 @@
#include "nvim/memory.h"
#include "nvim/move.h"
#include "nvim/option.h"
+#include "nvim/plines.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/buffer.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "plines.c.generated.h"
@@ -41,7 +42,34 @@ int plines_win(win_T *wp, linenr_T lnum, bool winheight)
{
// Check for filler lines above this buffer line. When folded the result
// is one line anyway.
- return plines_win_nofill(wp, lnum, winheight) + diff_check_fill(wp, lnum);
+ return plines_win_nofill(wp, lnum, winheight) + win_get_fill(wp, lnum);
+}
+
+
+/// Return the number of filler lines above "lnum".
+///
+/// @param wp
+/// @param lnum
+///
+/// @return Number of filler lines above lnum
+int win_get_fill(win_T *wp, linenr_T lnum)
+{
+ int virt_lines = decor_virtual_lines(wp, lnum);
+
+ // be quick when there are no filler lines
+ if (diffopt_filler()) {
+ int n = diff_check(wp, lnum);
+
+ if (n > 0) {
+ return virt_lines+n;
+ }
+ }
+ return virt_lines;
+}
+
+bool win_may_fill(win_T *wp)
+{
+ return (wp->w_p_diff && diffopt_filler()) || wp->w_buffer->b_virt_line_mark;
}
/// @param winheight when true limit to window height
@@ -71,7 +99,7 @@ int plines_win_nofill(win_T *wp, linenr_T lnum, bool winheight)
/// "wp". Does not care about folding, 'wrap' or 'diff'.
int plines_win_nofold(win_T *wp, linenr_T lnum)
{
- char_u *s;
+ char_u *s;
unsigned int col;
int width;
@@ -107,7 +135,7 @@ int plines_win_col(win_T *wp, linenr_T lnum, long column)
{
// Check for filler lines above this buffer line. When folded the result
// is one line anyway.
- int lines = diff_check_fill(wp, lnum);
+ int lines = win_get_fill(wp, lnum);
if (!wp->w_p_wrap) {
return lines + 1;
@@ -159,8 +187,8 @@ int plines_win_col(win_T *wp, linenr_T lnum, long column)
/// @param[in] cache whether to use the window's cache for folds
///
/// @return the total number of screen lines
-int plines_win_full(win_T *wp, linenr_T lnum, linenr_T *const nextp,
- bool *const foldedp, const bool cache)
+int plines_win_full(win_T *wp, linenr_T lnum, linenr_T *const nextp, bool *const foldedp,
+ const bool cache)
{
bool folded = hasFoldingWin(wp, lnum, NULL, nextp, cache, NULL);
if (foldedp) {
@@ -302,8 +330,7 @@ int lbr_chartabsize_adv(char_u *line, char_u **s, colnr_T col)
/// @param headp
///
/// @return The number of characters taken up on the screen.
-int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s,
- colnr_T col, int *headp)
+int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *headp)
{
colnr_T col2;
colnr_T col_adj = 0; // col + screen size of tab
@@ -326,7 +353,7 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s,
int size = win_chartabsize(wp, s, col);
int c = *s;
if (*s == TAB) {
- col_adj = size - 1;
+ col_adj = size - 1;
}
// If 'linebreak' set check at a blank before a non-blank if the line
@@ -343,8 +370,8 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s,
colmax = (colnr_T)(wp->w_width_inner - numberextra - col_adj);
if (col >= colmax) {
- colmax += col_adj;
- n = colmax + win_col_off2(wp);
+ colmax += col_adj;
+ n = colmax + win_col_off2(wp);
if (n > 0) {
colmax += (((col - colmax) / n) + 1) * n - col_adj;
diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c
index 1705ea0c12..606c03f838 100644
--- a/src/nvim/popupmnu.c
+++ b/src/nvim/popupmnu.c
@@ -9,27 +9,27 @@
#include <inttypes.h>
#include <stdbool.h>
-#include "nvim/buffer.h"
-#include "nvim/vim.h"
#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
-#include "nvim/eval/typval.h"
-#include "nvim/popupmnu.h"
+#include "nvim/buffer.h"
#include "nvim/charset.h"
+#include "nvim/edit.h"
+#include "nvim/eval/typval.h"
#include "nvim/ex_cmds.h"
#include "nvim/memline.h"
+#include "nvim/memory.h"
#include "nvim/move.h"
#include "nvim/option.h"
+#include "nvim/popupmnu.h"
#include "nvim/screen.h"
-#include "nvim/ui_compositor.h"
#include "nvim/search.h"
#include "nvim/strings.h"
-#include "nvim/memory.h"
-#include "nvim/window.h"
-#include "nvim/edit.h"
#include "nvim/ui.h"
+#include "nvim/ui_compositor.h"
+#include "nvim/vim.h"
+#include "nvim/window.h"
-static pumitem_T *pum_array = NULL; // items of displayed pum
+static pumitem_T *pum_array = NULL; // items of displayed pum
static int pum_size; // nr of items in "pum_array"
static int pum_selected; // index of selected item or -1
static int pum_first = 0; // index of top item
@@ -98,8 +98,7 @@ static void pum_compute_size(void)
/// if false, a new item is selected, but the array
/// is the same
/// @param cmd_startcol only for cmdline mode: column of completed match
-void pum_display(pumitem_T *array, int size, int selected, bool array_changed,
- int cmd_startcol)
+void pum_display(pumitem_T *array, int size, int selected, bool array_changed, int cmd_startcol)
{
int context_lines;
int above_row;
@@ -234,7 +233,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed,
context_lines = 3;
} else {
context_lines = curwin->w_cline_row
- + curwin->w_cline_height - curwin->w_wrow;
+ + curwin->w_cline_height - curwin->w_wrow;
}
pum_row = pum_win_row + context_lines;
@@ -488,17 +487,17 @@ void pum_redraw(void)
s = NULL;
switch (round) {
- case 1:
- p = pum_array[idx].pum_text;
- break;
+ case 1:
+ p = pum_array[idx].pum_text;
+ break;
- case 2:
- p = pum_array[idx].pum_kind;
- break;
+ case 2:
+ p = pum_array[idx].pum_kind;
+ break;
- case 3:
- p = pum_array[idx].pum_extra;
- break;
+ case 3:
+ p = pum_array[idx].pum_extra;
+ break;
}
if (p != NULL) {
@@ -515,7 +514,7 @@ void pum_redraw(void)
char_u saved = *p;
*p = NUL;
- st = (char_u *)transstr((const char *)s);
+ st = (char_u *)transstr((const char *)s, true);
*p = saved;
if (pum_rl) {
diff --git a/src/nvim/popupmnu.h b/src/nvim/popupmnu.h
index 7956e50a93..7d3f4c6f51 100644
--- a/src/nvim/popupmnu.h
+++ b/src/nvim/popupmnu.h
@@ -1,10 +1,10 @@
#ifndef NVIM_POPUPMNU_H
#define NVIM_POPUPMNU_H
-#include "nvim/vim.h"
-#include "nvim/macros.h"
#include "nvim/grid_defs.h"
+#include "nvim/macros.h"
#include "nvim/types.h"
+#include "nvim/vim.h"
/// Used for popup menu items.
typedef struct {
diff --git a/src/nvim/pos.h b/src/nvim/pos.h
index b7c4b6ef92..2fbd049aa0 100644
--- a/src/nvim/pos.h
+++ b/src/nvim/pos.h
@@ -26,8 +26,8 @@ enum { MINCOL = 1 };
* position in file or buffer
*/
typedef struct {
- linenr_T lnum; /* line number */
- colnr_T col; /* column number */
+ linenr_T lnum; // line number
+ colnr_T col; // column number
colnr_T coladd;
} pos_T;
@@ -36,8 +36,8 @@ typedef struct {
* Same, but without coladd.
*/
typedef struct {
- linenr_T lnum; /* line number */
- colnr_T col; /* column number */
+ linenr_T lnum; // line number
+ colnr_T col; // column number
} lpos_T;
#endif // NVIM_POS_H
diff --git a/src/nvim/profile.c b/src/nvim/profile.c
index f9b0bb0a2b..fe7bd2e912 100644
--- a/src/nvim/profile.c
+++ b/src/nvim/profile.c
@@ -1,17 +1,16 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-#include <stdio.h>
-#include <math.h>
#include <assert.h>
+#include <math.h>
+#include <stdio.h>
#include "nvim/assert.h"
-#include "nvim/profile.h"
-#include "nvim/os/time.h"
#include "nvim/func_attr.h"
-#include "nvim/os/os_defs.h"
-
#include "nvim/globals.h" // for the global `time_fd` (startuptime)
+#include "nvim/os/os_defs.h"
+#include "nvim/os/time.h"
+#include "nvim/profile.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "profile.c.generated.h"
@@ -97,7 +96,7 @@ proftime_T profile_divide(proftime_T tm, int count) FUNC_ATTR_CONST
return profile_zero();
}
- return (proftime_T) round((double) tm / (double) count);
+ return (proftime_T)round((double)tm / (double)count);
}
/// Adds time `tm2` to `tm1`.
diff --git a/src/nvim/profile.h b/src/nvim/profile.h
index 7b378577ce..17c35c5eb7 100644
--- a/src/nvim/profile.h
+++ b/src/nvim/profile.h
@@ -7,8 +7,8 @@
typedef uint64_t proftime_T;
#define TIME_MSG(s) do { \
- if (time_fd != NULL) time_msg(s, NULL); \
- } while (0)
+ if (time_fd != NULL) time_msg(s, NULL); \
+} while (0)
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "profile.h.generated.h"
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index e1ee5dc28f..a8d4996340 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -8,9 +8,8 @@
#include <stdbool.h>
#include <string.h>
-#include "nvim/vim.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
-#include "nvim/quickfix.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
@@ -26,29 +25,30 @@
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
+#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/memory.h"
#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
+#include "nvim/quickfix.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/ui.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/os/os.h"
-#include "nvim/os/input.h"
-#include "nvim/api/private/helpers.h"
struct dir_stack_T {
- struct dir_stack_T *next;
- char_u *dirname;
+ struct dir_stack_T *next;
+ char_u *dirname;
};
// For each error the next struct is allocated and linked in a list.
@@ -67,7 +67,7 @@ struct qfline_S {
char_u *qf_pattern; ///< search pattern for the error
char_u *qf_text; ///< description of the error
char_u qf_viscol; ///< set to TRUE if qf_col and qf_end_col is
- // screen column
+ // screen column
char_u qf_cleared; ///< set to TRUE if line has been deleted
char_u qf_type; ///< type of the error (mostly 'E'); 1 for :helpgrep
char_u qf_valid; ///< valid error message detected
@@ -83,7 +83,7 @@ typedef enum
QFLT_QUICKFIX, ///< Quickfix list - global list
QFLT_LOCATION, ///< Location list - per window list
QFLT_INTERNAL ///< Internal - Temporary list used by
- // getqflist()/getloclist()
+ // getqflist()/getloclist()
} qfltype_T;
/// Quickfix/Location list definition
@@ -93,17 +93,17 @@ typedef enum
/// information and entries can be added later using setqflist()/setloclist().
typedef struct qf_list_S {
unsigned qf_id; ///< Unique identifier for this list
- qfltype_T qfl_type;
- qfline_T *qf_start; ///< pointer to the first error
- qfline_T *qf_last; ///< pointer to the last error
- qfline_T *qf_ptr; ///< pointer to the current error
+ qfltype_T qfl_type;
+ qfline_T *qf_start; ///< pointer to the first error
+ qfline_T *qf_last; ///< pointer to the last error
+ qfline_T *qf_ptr; ///< pointer to the current error
int qf_count; ///< number of errors (0 means empty list)
int qf_index; ///< current index in the error list
int qf_nonevalid; ///< TRUE if not a single valid entry found
- char_u *qf_title; ///< title derived from the command that created
- ///< the error list or set by setqflist
- typval_T *qf_ctx; ///< context set by setqflist/setloclist
- Callback qftf_cb; ///< 'quickfixtextfunc' callback function
+ char_u *qf_title; ///< title derived from the command that created
+ ///< the error list or set by setqflist
+ typval_T *qf_ctx; ///< context set by setqflist/setloclist
+ Callback qftf_cb; ///< 'quickfixtextfunc' callback function
struct dir_stack_T *qf_dir_stack;
char_u *qf_directory;
@@ -137,8 +137,8 @@ static unsigned last_qf_id = 0; // Last Used quickfix list id
// Structure used to hold the info of one part of 'errorformat'
typedef struct efm_S efm_T;
struct efm_S {
- regprog_T *prog; // pre-formatted part of 'errorformat'
- efm_T *next; // pointer to next (NULL if last)
+ regprog_T *prog; // pre-formatted part of 'errorformat'
+ efm_T *next; // pointer to next (NULL if last)
char_u addr[FMT_PATTERNS]; // indices of used % patterns
char_u prefix; // prefix of this format line:
// 'D' enter directory
@@ -183,12 +183,12 @@ typedef struct {
size_t linelen;
char_u *growbuf;
size_t growbufsiz;
- FILE *fd;
- typval_T *tv;
- char_u *p_str;
- list_T *p_list;
+ FILE *fd;
+ typval_T *tv;
+ char_u *p_str;
+ list_T *p_list;
listitem_T *p_li;
- buf_T *buf;
+ buf_T *buf;
linenr_T buflnum;
linenr_T lnumlast;
vimconv_T vc;
@@ -201,13 +201,13 @@ typedef struct {
size_t errmsglen;
long lnum;
long end_lnum;
- int col;
+ int col;
int end_col;
bool use_viscol;
char_u *pattern;
- int enr;
+ int enr;
char_u type;
- bool valid;
+ bool valid;
} qffields_T;
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -236,7 +236,7 @@ static char_u *e_no_more_items = (char_u *)N_("E553: No more items");
// Macro to loop through all the items in a quickfix list
// Quickfix item index starts from 1, so i below starts at 1
#define FOR_ALL_QFL_ITEMS(qfl, qfp, i) \
- for (i = 1, qfp = qfl->qf_start; /* NOLINT(readability/braces) */ \
+ for (i = 1, qfp = qfl->qf_start; /* NOLINT(readability/braces) */ \
!got_int && i <= qfl->qf_count && qfp != NULL; \
i++, qfp = qfp->qf_next)
@@ -244,7 +244,7 @@ static char_u *e_no_more_items = (char_u *)N_("E553: No more items");
// Looking up a buffer can be slow if there are many. Remember the last one
// to make this a lot faster if there are multiple matches in the same file.
static char_u *qf_last_bufname = NULL;
-static bufref_T qf_last_bufref = { NULL, 0, 0 };
+static bufref_T qf_last_bufref = { NULL, 0, 0 };
static char *e_current_quickfix_list_was_changed =
N_("E925: Current quickfix list was changed");
@@ -258,9 +258,7 @@ static qf_delq_T *qf_delq_head = NULL;
/// Process the next line from a file/buffer/list/string and add it
/// to the quickfix list 'qfl'.
-static int qf_init_process_nextline(qf_list_T *qfl,
- efm_T *fmt_first,
- qfstate_T *state,
+static int qf_init_process_nextline(qf_list_T *qfl, efm_T *fmt_first, qfstate_T *state,
qffields_T *fields)
{
int status;
@@ -308,11 +306,10 @@ static int qf_init_process_nextline(qf_list_T *qfl,
/// @params enc If non-NULL, encoding used to parse errors
///
/// @returns -1 for error, number of errors for success.
-int qf_init(win_T *wp, const char_u *restrict efile,
- char_u *restrict errorformat, int newlist,
+int qf_init(win_T *wp, const char_u *restrict efile, char_u *restrict errorformat, int newlist,
const char_u *restrict qf_title, char_u *restrict enc)
{
- qf_info_T *qi = &ql_info;
+ qf_info_T *qi = &ql_info;
if (wp != NULL) {
qi = ll_get_or_alloc_list(wp);
@@ -338,7 +335,7 @@ static struct fmtpattern
{ 't', "." },
{ 'm', ".\\+" },
{ 'r', ".*" },
- { 'p', "[- .]*" }, // NOLINT(whitespace/tab)
+ { 'p', "[- .]*"}, // NOLINT(whitespace/tab)
{ 'v', "\\d\\+" },
{ 's', ".\\+" },
{ 'o', ".\\+" }
@@ -348,14 +345,8 @@ static struct fmtpattern
/// See fmt_pat definition above for the list of supported patterns. The
/// pattern specifier is supplied in "efmpat". The converted pattern is stored
/// in "regpat". Returns a pointer to the location after the pattern.
-static char_u * efmpat_to_regpat(
- const char_u *efmpat,
- char_u *regpat,
- efm_T *efminfo,
- int idx,
- int round,
- char_u *errmsg,
- size_t errmsglen)
+static char_u *efmpat_to_regpat(const char_u *efmpat, char_u *regpat, efm_T *efminfo, int idx,
+ int round, char_u *errmsg, size_t errmsglen)
FUNC_ATTR_NONNULL_ALL
{
if (efminfo->addr[idx]) {
@@ -374,7 +365,7 @@ static char_u * efmpat_to_regpat(
EMSG(errmsg);
return NULL;
}
- efminfo->addr[idx] = (char_u)++round;
+ efminfo->addr[idx] = (char_u)++ round;
*regpat++ = '\\';
*regpat++ = '(';
#ifdef BACKSLASH_IN_FILENAME
@@ -415,13 +406,8 @@ static char_u * efmpat_to_regpat(
/// Convert a scanf like format in 'errorformat' to a regular expression.
/// Returns a pointer to the location after the pattern.
-static char_u * scanf_fmt_to_regpat(
- const char_u **pefmp,
- const char_u *efm,
- int len,
- char_u *regpat,
- char_u *errmsg,
- size_t errmsglen)
+static char_u *scanf_fmt_to_regpat(const char_u **pefmp, const char_u *efm, int len, char_u *regpat,
+ char_u *errmsg, size_t errmsglen)
FUNC_ATTR_NONNULL_ALL
{
const char_u *efmp = *pefmp;
@@ -459,8 +445,8 @@ static char_u * scanf_fmt_to_regpat(
}
/// Analyze/parse an errorformat prefix.
-static const char_u *efm_analyze_prefix(const char_u *efmp, efm_T *efminfo,
- char_u *errmsg, size_t errmsglen)
+static const char_u *efm_analyze_prefix(const char_u *efmp, efm_T *efminfo, char_u *errmsg,
+ size_t errmsglen)
FUNC_ATTR_NONNULL_ALL
{
if (vim_strchr((char_u *)"+-", *efmp) != NULL) {
@@ -480,8 +466,8 @@ static const char_u *efm_analyze_prefix(const char_u *efmp, efm_T *efminfo,
// Converts a 'errorformat' string to regular expression pattern
-static int efm_to_regpat(const char_u *efm, int len, efm_T *fmt_ptr,
- char_u *regpat, char_u *errmsg, size_t errmsglen)
+static int efm_to_regpat(const char_u *efm, int len, efm_T *fmt_ptr, char_u *regpat, char_u *errmsg,
+ size_t errmsglen)
FUNC_ATTR_NONNULL_ALL
{
// Build regexp pattern from current 'errorformat' option
@@ -598,7 +584,7 @@ static int efm_option_part_len(char_u *efm)
/// Parse the 'errorformat' option. Multiple parts in the 'errorformat' option
/// are parsed and converted to regular expressions. Returns information about
/// the parsed 'errorformat' option.
-static efm_T * parse_efm_option(char_u *efm)
+static efm_T *parse_efm_option(char_u *efm)
{
efm_T *fmt_ptr = NULL;
efm_T *fmt_first = NULL;
@@ -769,7 +755,7 @@ retry:
errno = 0;
if (fgets((char *)IObuff, IOSIZE, state->fd) == NULL) {
if (errno == EINTR) {
- goto retry;
+ goto retry;
}
return QF_END_OF_INPUT;
}
@@ -915,7 +901,7 @@ static bool qf_list_has_valid_entries(qf_list_T *qfl)
}
/// Return a pointer to a list in the specified quickfix stack
-static qf_list_T * qf_get_list(qf_info_T *qi, int idx)
+static qf_list_T *qf_get_list(qf_info_T *qi, int idx)
FUNC_ATTR_NONNULL_ALL
{
return &qi->qf_lists[idx];
@@ -923,11 +909,11 @@ static qf_list_T * qf_get_list(qf_info_T *qi, int idx)
/// Parse a line and get the quickfix fields.
/// Return the QF_ status.
-static int qf_parse_line(qf_list_T *qfl, char_u *linebuf,
- size_t linelen, efm_T *fmt_first, qffields_T *fields)
+static int qf_parse_line(qf_list_T *qfl, char_u *linebuf, size_t linelen, efm_T *fmt_first,
+ qffields_T *fields)
{
efm_T *fmt_ptr;
- int idx = 0;
+ int idx = 0;
char_u *tail = NULL;
int status;
@@ -1030,14 +1016,8 @@ static void qf_free_fields(qffields_T *pfields)
// Setup the state information used for parsing lines and populating a
// quickfix list.
-static int qf_setup_state(
- qfstate_T *pstate,
- char_u *restrict enc,
- const char_u *restrict efile,
- typval_T *tv,
- buf_T *buf,
- linenr_T lnumfirst,
- linenr_T lnumlast)
+static int qf_setup_state(qfstate_T *pstate, char_u *restrict enc, const char_u *restrict efile,
+ typval_T *tv, buf_T *buf, linenr_T lnumfirst, linenr_T lnumlast)
FUNC_ATTR_NONNULL_ARG(1)
{
pstate->vc.vc_type = CONV_NONE;
@@ -1080,38 +1060,32 @@ static void qf_cleanup_state(qfstate_T *pstate)
}
}
-// Read the errorfile "efile" into memory, line by line, building the error
-// list.
-// Alternative: when "efile" is NULL read errors from buffer "buf".
-// Alternative: when "tv" is not NULL get errors from the string or list.
-// Always use 'errorformat' from "buf" if there is a local value.
-// Then "lnumfirst" and "lnumlast" specify the range of lines to use.
-// Set the title of the list to "qf_title".
-// Return -1 for error, number of errors for success.
-static int
-qf_init_ext(
- qf_info_T *qi,
- int qf_idx,
- const char_u *restrict efile,
- buf_T *buf,
- typval_T *tv,
- char_u *restrict errorformat,
- bool newlist, // true: start a new error list
- linenr_T lnumfirst, // first line number to use
- linenr_T lnumlast, // last line number to use
- const char_u *restrict qf_title,
- char_u *restrict enc
-)
+/// Read the errorfile "efile" into memory, line by line, building the error
+/// list.
+/// Alternative: when "efile" is NULL read errors from buffer "buf".
+/// Alternative: when "tv" is not NULL get errors from the string or list.
+/// Always use 'errorformat' from "buf" if there is a local value.
+/// Then "lnumfirst" and "lnumlast" specify the range of lines to use.
+/// Set the title of the list to "qf_title".
+///
+/// @param newlist true: start a new error list
+/// @param lnumfirst first line number to use
+/// @param lnumlast last line number to use
+///
+/// @return -1 for error, number of errors for success.
+static int qf_init_ext(qf_info_T *qi, int qf_idx, const char_u *restrict efile, buf_T *buf,
+ typval_T *tv, char_u *restrict errorformat, bool newlist, linenr_T lnumfirst,
+ linenr_T lnumlast, const char_u *restrict qf_title, char_u *restrict enc)
FUNC_ATTR_NONNULL_ARG(1)
{
qf_list_T *qfl;
qfstate_T state = { 0 };
qffields_T fields = { 0 };
- qfline_T *old_last = NULL;
+ qfline_T *old_last = NULL;
bool adding = false;
- static efm_T *fmt_first = NULL;
- char_u *efm;
- static char_u *last_efm = NULL;
+ static efm_T *fmt_first = NULL;
+ char_u *efm;
+ static char_u *last_efm = NULL;
int retval = -1; // default: return error flag
int status;
@@ -1237,7 +1211,7 @@ static void qf_store_title(qf_list_T *qfl, const char_u *title)
/// that created the quickfix list with the ":" prefix.
/// Create a quickfix list title string by prepending ":" to a user command.
/// Returns a pointer to a static buffer with the title.
-static char_u * qf_cmdtitle(char_u *cmd)
+static char_u *qf_cmdtitle(char_u *cmd)
{
static char_u qftitle_str[IOSIZE];
@@ -1247,7 +1221,7 @@ static char_u * qf_cmdtitle(char_u *cmd)
}
/// Return a pointer to the current list in the specified quickfix stack
-static qf_list_T * qf_get_curlist(qf_info_T *qi)
+static qf_list_T *qf_get_curlist(qf_info_T *qi)
FUNC_ATTR_NONNULL_ALL
{
return qf_get_list(qi, qi->qf_curlist);
@@ -1263,7 +1237,7 @@ static void qf_new_list(qf_info_T *qi, const char_u *qf_title)
// If the current entry is not the last entry, delete entries beyond
// the current entry. This makes it possible to browse in a tree-like
- // way with ":grep'.
+ // way with ":grep".
while (qi->qf_listcount > qi->qf_curlist + 1) {
qf_free(&qi->qf_lists[--qi->qf_listcount]);
}
@@ -1276,8 +1250,9 @@ static void qf_new_list(qf_info_T *qi, const char_u *qf_title)
qi->qf_lists[i - 1] = qi->qf_lists[i];
}
qi->qf_curlist = LISTCOUNT - 1;
- } else
+ } else {
qi->qf_curlist = qi->qf_listcount++;
+ }
qfl = qf_get_curlist(qi);
memset(qfl, 0, sizeof(qf_list_T));
qf_store_title(qfl, qf_title);
@@ -1287,10 +1262,7 @@ static void qf_new_list(qf_info_T *qi, const char_u *qf_title)
/// Parse the match for filename ('%f') pattern in regmatch.
/// Return the matched value in "fields->namebuf".
-static int qf_parse_fmt_f(regmatch_T *rmp,
- int midx,
- qffields_T *fields,
- int prefix)
+static int qf_parse_fmt_f(regmatch_T *rmp, int midx, qffields_T *fields, int prefix)
{
char_u c;
@@ -1360,9 +1332,7 @@ static int qf_parse_fmt_t(regmatch_T *rmp, int midx, qffields_T *fields)
/// Parse the match for '%+' format pattern. The whole matching line is included
/// in the error string. Return the matched line in "fields->errmsg".
-static void qf_parse_fmt_plus(const char_u *linebuf,
- size_t linelen,
- qffields_T *fields)
+static void qf_parse_fmt_plus(const char_u *linebuf, size_t linelen, qffields_T *fields)
FUNC_ATTR_NONNULL_ALL
{
if (linelen >= fields->errmsglen) {
@@ -1499,9 +1469,8 @@ static int (*qf_parse_fmt[FMT_PATTERNS])(regmatch_T *, int, qffields_T *) = {
/// fmt_ptr contains the 'efm' format specifiers/prefixes that have a match.
/// Returns QF_OK if all the matches are successfully parsed. On failure,
/// returns QF_FAIL or QF_NOMEM.
-static int qf_parse_match(char_u *linebuf, size_t linelen, efm_T *fmt_ptr,
- regmatch_T *regmatch, qffields_T *fields,
- int qf_multiline, int qf_multiscan, char_u **tail)
+static int qf_parse_match(char_u *linebuf, size_t linelen, efm_T *fmt_ptr, regmatch_T *regmatch,
+ qffields_T *fields, int qf_multiline, int qf_multiscan, char_u **tail)
{
char_u idx = fmt_ptr->prefix;
int i;
@@ -1549,9 +1518,8 @@ static int qf_parse_match(char_u *linebuf, size_t linelen, efm_T *fmt_ptr,
/// 'fmt_ptr->prog' and return the matching values in 'fields'.
/// Returns QF_OK if the efm format matches completely and the fields are
/// successfully copied. Otherwise returns QF_FAIL or QF_NOMEM.
-static int qf_parse_get_fields(char_u *linebuf, size_t linelen, efm_T *fmt_ptr,
- qffields_T *fields, int qf_multiline,
- int qf_multiscan, char_u **tail)
+static int qf_parse_get_fields(char_u *linebuf, size_t linelen, efm_T *fmt_ptr, qffields_T *fields,
+ int qf_multiline, int qf_multiscan, char_u **tail)
{
regmatch_T regmatch;
int status = QF_FAIL;
@@ -1611,8 +1579,7 @@ static int qf_parse_dir_pfx(int idx, qffields_T *fields, qf_list_T *qfl)
}
/// Parse global file name error format prefixes (%O, %P and %Q).
-static int qf_parse_file_pfx(int idx, qffields_T *fields, qf_list_T *qfl,
- char_u *tail)
+static int qf_parse_file_pfx(int idx, qffields_T *fields, qf_list_T *qfl, char_u *tail)
{
fields->valid = false;
if (*fields->namebuf == NUL || os_path_exists(fields->namebuf)) {
@@ -1635,8 +1602,7 @@ static int qf_parse_file_pfx(int idx, qffields_T *fields, qf_list_T *qfl,
/// Parse a non-error line (a line which doesn't match any of the error
/// format in 'efm').
-static int qf_parse_line_nomatch(char_u *linebuf, size_t linelen,
- qffields_T *fields)
+static int qf_parse_line_nomatch(char_u *linebuf, size_t linelen, qffields_T *fields)
{
fields->namebuf[0] = NUL; // no match found, remove file name
fields->lnum = 0; // don't jump to this line
@@ -1662,8 +1628,8 @@ static int qf_parse_multiline_pfx(int idx, qf_list_T *qfl, qffields_T *fields)
return QF_FAIL;
}
if (*fields->errmsg) {
- size_t textlen = strlen((char *)qfprev->qf_text);
- size_t errlen = strlen((char *)fields->errmsg);
+ size_t textlen = STRLEN(qfprev->qf_text);
+ size_t errlen = STRLEN(fields->errmsg);
qfprev->qf_text = xrealloc(qfprev->qf_text, textlen + errlen + 2);
qfprev->qf_text[textlen] = '\n';
STRCPY(qfprev->qf_text + textlen + 1, fields->errmsg);
@@ -1714,11 +1680,12 @@ static void locstack_queue_delreq(qf_info_T *qi)
static void ll_free_all(qf_info_T **pqi)
{
int i;
- qf_info_T *qi;
+ qf_info_T *qi;
qi = *pqi;
- if (qi == NULL)
+ if (qi == NULL) {
return;
+ }
*pqi = NULL; // Remove reference to this list
qi->qf_refcount--;
@@ -1741,7 +1708,7 @@ static void ll_free_all(qf_info_T **pqi)
void qf_free_all(win_T *wp)
{
int i;
- qf_info_T *qi = &ql_info;
+ qf_info_T *qi = &ql_info;
if (wp != NULL) {
// location list
@@ -1761,7 +1728,7 @@ void qf_free_all(win_T *wp)
/// Must always call decr_quickfix_busy() exactly once after this.
static void incr_quickfix_busy(void)
{
- quickfix_busy++;
+ quickfix_busy++;
}
/// Safe to free location list stacks. Process any delayed delete requests.
@@ -1818,11 +1785,9 @@ void check_quickfix_busy(void)
/// @param valid valid entry
///
/// @returns QF_OK or QF_FAIL.
-static int qf_add_entry(qf_list_T *qfl, char_u *dir, char_u *fname,
- char_u *module, int bufnum, char_u *mesg,
- long lnum, long end_lnum, int col, int end_col,
- char_u vis_col, char_u *pattern, int nr,
- char_u type, char_u valid)
+static int qf_add_entry(qf_list_T *qfl, char_u *dir, char_u *fname, char_u *module, int bufnum,
+ char_u *mesg, long lnum, long end_lnum, int col, int end_col,
+ char_u vis_col, char_u *pattern, int nr, char_u type, char_u valid)
{
qfline_T *qfp = xmalloc(sizeof(qfline_T));
qfline_T **lastp; // pointer to qf_last or NULL
@@ -1858,7 +1823,7 @@ static int qf_add_entry(qf_list_T *qfl, char_u *dir, char_u *fname,
if (type != 1 && !vim_isprintc(type)) { // only printable chars allowed
type = 0;
}
- qfp->qf_type = (char_u)type;
+ qfp->qf_type = type;
qfp->qf_valid = valid;
lastp = &qfl->qf_last;
@@ -1921,7 +1886,7 @@ static qf_info_T *ll_get_or_alloc_list(win_T *wp)
/// For a location list command, returns the stack for the current window. If
/// the location list is not found, then returns NULL and prints an error
/// message if 'print_emsg' is TRUE.
-static qf_info_T * qf_cmd_get_stack(exarg_T *eap, int print_emsg)
+static qf_info_T *qf_cmd_get_stack(exarg_T *eap, int print_emsg)
{
qf_info_T *qi = &ql_info;
@@ -2140,10 +2105,9 @@ static int qf_get_fnum(qf_list_T *qfl, char_u *directory, char_u *fname )
// Push dirbuf onto the directory stack and return pointer to actual dir or
// NULL on error.
-static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr,
- bool is_file_stack)
+static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr, bool is_file_stack)
{
- struct dir_stack_T *ds_ptr;
+ struct dir_stack_T *ds_ptr;
// allocate new stack element and hook it in
struct dir_stack_T *ds_new = xmalloc(sizeof(struct dir_stack_T));
@@ -2165,9 +2129,10 @@ static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr,
while (ds_new) {
xfree((*stackptr)->dirname);
(*stackptr)->dirname = (char_u *)concat_fnames((char *)ds_new->dirname,
- (char *)dirbuf, TRUE);
- if (os_isdir((*stackptr)->dirname))
+ (char *)dirbuf, TRUE);
+ if (os_isdir((*stackptr)->dirname)) {
break;
+ }
ds_new = ds_new->next;
}
@@ -2187,9 +2152,9 @@ static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr,
}
}
- if ((*stackptr)->dirname != NULL)
+ if ((*stackptr)->dirname != NULL) {
return (*stackptr)->dirname;
- else {
+ } else {
ds_ptr = *stackptr;
*stackptr = (*stackptr)->next;
xfree(ds_ptr);
@@ -2202,7 +2167,7 @@ static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr,
// stack is empty
static char_u *qf_pop_dir(struct dir_stack_T **stackptr)
{
- struct dir_stack_T *ds_ptr;
+ struct dir_stack_T *ds_ptr;
// TODO(vim): Should we check if dirbuf is the directory on top of the stack?
// What to do if it isn't?
@@ -2222,7 +2187,7 @@ static char_u *qf_pop_dir(struct dir_stack_T **stackptr)
// clean up directory stack
static void qf_clean_dir_stack(struct dir_stack_T **stackptr)
{
- struct dir_stack_T *ds_ptr;
+ struct dir_stack_T *ds_ptr;
while ((ds_ptr = *stackptr) != NULL) {
*stackptr = (*stackptr)->next;
@@ -2251,9 +2216,9 @@ static void qf_clean_dir_stack(struct dir_stack_T **stackptr)
/// qf_guess_filepath will return NULL.
static char_u *qf_guess_filepath(qf_list_T *qfl, char_u *filename)
{
- struct dir_stack_T *ds_ptr;
- struct dir_stack_T *ds_tmp;
- char_u *fullname;
+ struct dir_stack_T *ds_ptr;
+ struct dir_stack_T *ds_tmp;
+ char_u *fullname;
// no dirs on the stack - there's nothing we can do
if (qfl->qf_dir_stack == NULL) {
@@ -2332,8 +2297,7 @@ static bool is_qf_entry_present(qf_list_T *qfl, qfline_T *qf_ptr)
/// Get the next valid entry in the current quickfix/location list. The search
/// starts from the current entry. Returns NULL on failure.
-static qfline_T *get_next_valid_entry(qf_list_T *qfl, qfline_T *qf_ptr,
- int *qf_index, int dir)
+static qfline_T *get_next_valid_entry(qf_list_T *qfl, qfline_T *qf_ptr, int *qf_index, int dir)
{
int idx = *qf_index;
int old_qf_fnum = qf_ptr->qf_fnum;
@@ -2353,8 +2317,7 @@ static qfline_T *get_next_valid_entry(qf_list_T *qfl, qfline_T *qf_ptr,
/// Get the previous valid entry in the current quickfix/location list. The
/// search starts from the current entry. Returns NULL on failure.
-static qfline_T *get_prev_valid_entry(qf_list_T *qfl, qfline_T *qf_ptr,
- int *qf_index, int dir)
+static qfline_T *get_prev_valid_entry(qf_list_T *qfl, qfline_T *qf_ptr, int *qf_index, int dir)
{
int idx = *qf_index;
int old_qf_fnum = qf_ptr->qf_fnum;
@@ -2376,8 +2339,7 @@ static qfline_T *get_prev_valid_entry(qf_list_T *qfl, qfline_T *qf_ptr,
/// the quickfix list.
/// dir == FORWARD or FORWARD_FILE: next valid entry
/// dir == BACKWARD or BACKWARD_FILE: previous valid entry
-static qfline_T *get_nth_valid_entry(qf_list_T *qfl, int errornr,
- int dir, int *new_qfidx)
+static qfline_T *get_nth_valid_entry(qf_list_T *qfl, int errornr, int dir, int *new_qfidx)
{
qfline_T *qf_ptr = qfl->qf_ptr;
int qf_idx = qfl->qf_index;
@@ -2442,20 +2404,19 @@ static qfline_T *get_nth_entry(qf_list_T *qfl, int errornr, int *new_qfidx)
/// specifies the direction (FORWARD/BACKWARD/FORWARD_FILE/BACKWARD_FILE).
/// Returns a pointer to the entry and the index of the new entry is stored in
/// 'new_qfidx'.
-static qfline_T * qf_get_entry(qf_list_T *qfl, int errornr,
- int dir, int *new_qfidx)
+static qfline_T *qf_get_entry(qf_list_T *qfl, int errornr, int dir, int *new_qfidx)
{
- qfline_T *qf_ptr = qfl->qf_ptr;
- int qfidx = qfl->qf_index;
+ qfline_T *qf_ptr = qfl->qf_ptr;
+ int qfidx = qfl->qf_index;
- if (dir != 0) { // next/prev valid entry
- qf_ptr = get_nth_valid_entry(qfl, errornr, dir, &qfidx);
- } else if (errornr != 0) { // go to specified number
- qf_ptr = get_nth_entry(qfl, errornr, &qfidx);
- }
+ if (dir != 0) { // next/prev valid entry
+ qf_ptr = get_nth_valid_entry(qfl, errornr, dir, &qfidx);
+ } else if (errornr != 0) { // go to specified number
+ qf_ptr = get_nth_entry(qfl, errornr, &qfidx);
+ }
- *new_qfidx = qfidx;
- return qf_ptr;
+ *new_qfidx = qfidx;
+ return qf_ptr;
}
// Find a window displaying a Vim help file.
@@ -2596,8 +2557,7 @@ static int qf_open_new_file_win(qf_info_T *ll_ref)
// to the window just above the location list window. This is used for opening
// a file from a location window and not from a quickfix window. If some usable
// window is previously found, then it is supplied in 'use_win'.
-static void qf_goto_win_with_ll_file(win_T *use_win, int qf_fnum,
- qf_info_T *ll_ref)
+static void qf_goto_win_with_ll_file(win_T *use_win, int qf_fnum, qf_info_T *ll_ref)
{
win_T *win = use_win;
@@ -2684,8 +2644,7 @@ static void qf_goto_win_with_qfl_file(int qf_fnum)
// window, jump to it. Otherwise open a new window to display the file. If
// 'newwin' is true, then always open a new window. This is called from either
// a quickfix or a location list window.
-static int qf_jump_to_usable_window(int qf_fnum, bool newwin,
- int *opened_window)
+static int qf_jump_to_usable_window(int qf_fnum, bool newwin, int *opened_window)
{
win_T *usable_wp = NULL;
bool usable_win = false;
@@ -2735,8 +2694,8 @@ static int qf_jump_to_usable_window(int qf_fnum, bool newwin,
}
/// Edit the selected file or help file.
-static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit,
- win_T *oldwin, int *opened_window)
+static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, win_T *oldwin,
+ int *opened_window)
{
qf_list_T *qfl = qf_get_curlist(qi);
long old_changetick = qfl->qf_changedtick;
@@ -2789,8 +2748,7 @@ static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit,
/// Go to the error line in the current file using either line/column number or
/// a search pattern.
-static void qf_jump_goto_line(linenr_T qf_lnum, int qf_col, char_u qf_viscol,
- char_u *qf_pattern)
+static void qf_jump_goto_line(linenr_T qf_lnum, int qf_col, char_u qf_viscol, char_u *qf_pattern)
{
linenr_T i;
@@ -2826,8 +2784,8 @@ static void qf_jump_goto_line(linenr_T qf_lnum, int qf_col, char_u qf_viscol,
}
/// Display quickfix list index and size message
-static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr,
- buf_T *old_curbuf, linenr_T old_lnum)
+static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, buf_T *old_curbuf,
+ linenr_T old_lnum)
{
// Update the screen before showing the message, unless the screen
// scrolled up.
@@ -2862,15 +2820,14 @@ static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr,
/// Returns OK if successfully jumped or opened a window. Returns FAIL if not
/// able to jump/open a window. Returns NOTDONE if a file is not associated
/// with the entry.
-static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, bool newwin,
- int *opened_window)
+static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, bool newwin, int *opened_window)
{
qf_list_T *qfl = qf_get_curlist(qi);
long old_changetick = qfl->qf_changedtick;
int old_qf_curlist = qi->qf_curlist;
qfltype_T qfl_type = qfl->qfl_type;
- // For ":helpgrep" find a help window or open one.
+ // For ":helpgrep" find a help window or open one.
if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0)) {
if (jump_to_help_window(qi, newwin, opened_window) == FAIL) {
return FAIL;
@@ -2921,9 +2878,8 @@ static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, bool newwin,
/// Returns OK on success and FAIL on failing to open the file/buffer. Returns
/// NOTDONE if the quickfix/location list is freed by an autocmd when opening
/// the file.
-static int qf_jump_to_buffer(qf_info_T *qi, int qf_index, qfline_T *qf_ptr,
- int forceit, win_T *oldwin, int *opened_window,
- int openfold, int print_message)
+static int qf_jump_to_buffer(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, int forceit,
+ win_T *oldwin, int *opened_window, int openfold, int print_message)
{
buf_T *old_curbuf;
linenr_T old_lnum;
@@ -2975,8 +2931,7 @@ void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit)
// else if "errornr" is zero, redisplay the same line
// If 'forceit' is true, then can discard changes to the current buffer.
// If 'newwin' is true, then open the file in a new window.
-static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit,
- bool newwin)
+static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, bool newwin)
{
qf_list_T *qfl;
qfline_T *qf_ptr;
@@ -2991,8 +2946,9 @@ static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit,
const bool old_KeyTyped = KeyTyped; // getting file may reset it
int retval = OK;
- if (qi == NULL)
+ if (qi == NULL) {
qi = &ql_info;
+ }
if (qf_stack_empty(qi) || qf_list_empty(qf_get_curlist(qi))) {
EMSG(_(e_quickfix));
@@ -3042,8 +2998,8 @@ static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit,
win_close(curwin, true); // Close opened window
}
if (qf_ptr != NULL && qf_ptr->qf_fnum != 0) {
- // Couldn't open file, so put index back where it was. This could
- // happen if the file was readonly and we changed something.
+ // Couldn't open file, so put index back where it was. This could
+ // happen if the file was readonly and we changed something.
failed:
qf_ptr = old_qf_ptr;
qf_index = old_qf_index;
@@ -3158,9 +3114,9 @@ void qf_list(exarg_T *eap)
int i;
int idx1 = 1;
int idx2 = -1;
- char_u *arg = eap->arg;
- int all = eap->forceit; // if not :cl!, only show
- // recognised errors
+ char_u *arg = eap->arg;
+ int all = eap->forceit; // if not :cl!, only show
+ // recognised errors
qf_info_T *qi;
if ((qi = qf_cmd_get_stack(eap, true)) == NULL) {
@@ -3203,15 +3159,15 @@ void qf_list(exarg_T *eap)
// that this depends on syntax items defined in the qf.vim syntax file
qfFileAttr = syn_name2attr((char_u *)"qfFileName");
if (qfFileAttr == 0) {
- qfFileAttr = HL_ATTR(HLF_D);
+ qfFileAttr = HL_ATTR(HLF_D);
}
qfSepAttr = syn_name2attr((char_u *)"qfSeparator");
if (qfSepAttr == 0) {
- qfSepAttr = HL_ATTR(HLF_D);
+ qfSepAttr = HL_ATTR(HLF_D);
}
qfLineAttr = syn_name2attr((char_u *)"qfLineNr");
if (qfLineAttr == 0) {
- qfLineAttr = HL_ATTR(HLF_N);
+ qfLineAttr = HL_ATTR(HLF_N);
}
if (qfl->qf_nonevalid) {
@@ -3227,8 +3183,7 @@ void qf_list(exarg_T *eap)
// Remove newlines and leading whitespace from an error message.
// Put the result in "buf[bufsize]".
-static void qf_fmt_text(const char_u *restrict text, char_u *restrict buf,
- int bufsize)
+static void qf_fmt_text(const char_u *restrict text, char_u *restrict buf, int bufsize)
FUNC_ATTR_NONNULL_ALL
{
int i;
@@ -3237,11 +3192,14 @@ static void qf_fmt_text(const char_u *restrict text, char_u *restrict buf,
for (i = 0; *p != NUL && i < bufsize - 1; ++i) {
if (*p == '\n') {
buf[i] = ' ';
- while (*++p != NUL)
- if (!ascii_iswhite(*p) && *p != '\n')
+ while (*++p != NUL) {
+ if (!ascii_iswhite(*p) && *p != '\n') {
break;
- } else
+ }
+ }
+ } else {
buf[i] = *p++;
+ }
}
buf[i] = NUL;
}
@@ -3290,8 +3248,8 @@ static void qf_msg(qf_info_T *qi, int which, char *lead)
size_t len = STRLEN(buf);
if (len < 34) {
- memset(buf + len, ' ', 34 - len);
- buf[34] = NUL;
+ memset(buf + len, ' ', 34 - len);
+ buf[34] = NUL;
}
xstrlcat((char *)buf, title, IOSIZE);
}
@@ -3374,8 +3332,8 @@ void qf_history(exarg_T *eap)
/// associated with the list like context and title are not freed.
static void qf_free_items(qf_list_T *qfl)
{
- qfline_T *qfp;
- qfline_T *qfpnext;
+ qfline_T *qfp;
+ qfline_T *qfpnext;
bool stop = false;
while (qfl->qf_count && qfl->qf_start != NULL) {
@@ -3430,13 +3388,12 @@ static void qf_free(qf_list_T *qfl)
}
// qf_mark_adjust: adjust marks
-bool qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, long amount,
- long amount_after)
+bool qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long amount_after)
{
int i;
- qfline_T *qfp;
+ qfline_T *qfp;
int idx;
- qf_info_T *qi = &ql_info;
+ qf_info_T *qi = &ql_info;
bool found_one = false;
int buf_has_flag = wp == NULL ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
@@ -3457,12 +3414,14 @@ bool qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, long amount,
if (qfp->qf_fnum == curbuf->b_fnum) {
found_one = true;
if (qfp->qf_lnum >= line1 && qfp->qf_lnum <= line2) {
- if (amount == MAXLNUM)
+ if (amount == MAXLNUM) {
qfp->qf_cleared = TRUE;
- else
+ } else {
qfp->qf_lnum += amount;
- } else if (amount_after && qfp->qf_lnum > line2)
+ }
+ } else if (amount_after && qfp->qf_lnum > line2) {
qfp->qf_lnum += amount_after;
+ }
}
}
}
@@ -3490,7 +3449,7 @@ static char_u *qf_types(int c, int nr)
{
static char_u buf[20];
static char_u cc[3];
- char_u *p;
+ char_u *p;
if (c == 'W' || c == 'w') {
p = (char_u *)" warning";
@@ -3509,8 +3468,9 @@ static char_u *qf_types(int c, int nr)
p = cc;
}
- if (nr <= 0)
+ if (nr <= 0) {
return p;
+ }
sprintf((char *)buf, "%s %3d", (char *)p, nr);
return buf;
@@ -3520,7 +3480,7 @@ static char_u *qf_types(int c, int nr)
// When "split" is true: Open the entry/result under the cursor in a new window.
void qf_view_result(bool split)
{
- qf_info_T *qi = &ql_info;
+ qf_info_T *qi = &ql_info;
if (!bt_quickfix(curbuf)) {
return;
@@ -3549,9 +3509,9 @@ void qf_view_result(bool split)
// close it if not.
void ex_cwindow(exarg_T *eap)
{
- qf_info_T *qi;
- qf_list_T *qfl;
- win_T *win;
+ qf_info_T *qi;
+ qf_list_T *qfl;
+ win_T *win;
if ((qi = qf_cmd_get_stack(eap, true)) == NULL) {
return;
@@ -3596,8 +3556,7 @@ void ex_cclose(exarg_T *eap)
// Goto a quickfix or location list window (if present).
// Returns OK if the window is found, FAIL otherwise.
-static int qf_goto_cwindow(const qf_info_T *qi, bool resize, int sz,
- bool vertsplit)
+static int qf_goto_cwindow(const qf_info_T *qi, bool resize, int sz, bool vertsplit)
{
win_T *const win = qf_find_win(qi);
if (win == NULL) {
@@ -3725,8 +3684,8 @@ static void qf_set_title_var(qf_list_T *qfl)
/// ":lopen": open a window that shows the location list.
void ex_copen(exarg_T *eap)
{
- qf_info_T *qi;
- qf_list_T *qfl;
+ qf_info_T *qi;
+ qf_list_T *qfl;
int height;
int status = FAIL;
int lnum;
@@ -3812,7 +3771,7 @@ void ex_cbottom(exarg_T *eap)
// window).
linenr_T qf_current_entry(win_T *wp)
{
- qf_info_T *qi = &ql_info;
+ qf_info_T *qi = &ql_info;
if (IS_LL_WINDOW(wp)) {
// In the location list window, use the referenced location list
@@ -3822,14 +3781,13 @@ linenr_T qf_current_entry(win_T *wp)
return qf_get_curlist(qi)->qf_index;
}
-// Update the cursor position in the quickfix window to the current error.
-// Return TRUE if there is a quickfix window.
-static int qf_win_pos_update(
- qf_info_T *qi,
- int old_qf_index // previous qf_index or zero
-)
+/// Update the cursor position in the quickfix window to the current error.
+/// Return TRUE if there is a quickfix window.
+///
+/// @param old_qf_index previous qf_index or zero
+static int qf_win_pos_update(qf_info_T *qi, int old_qf_index)
{
- win_T *win;
+ win_T *win;
int qf_index = qf_get_curlist(qi)->qf_index;
// Put the cursor on the current error in the quickfix window, so that
@@ -3954,8 +3912,8 @@ static void qf_update_win_titlevar(qf_info_T *qi)
// Find the quickfix buffer. If it exists, update the contents.
static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last)
{
- buf_T *buf;
- win_T *win;
+ buf_T *buf;
+ win_T *win;
aco_save_T aco;
// Check if a buffer for the quickfix list exists. Update it.
@@ -4002,9 +3960,8 @@ static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last)
}
// Add an error line to the quickfix buffer.
-static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum,
- const qfline_T *qfp, char_u *dirname,
- char_u *qftf_str, bool first_bufline)
+static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, const qfline_T *qfp,
+ char_u *dirname, char_u *qftf_str, bool first_bufline)
FUNC_ATTR_NONNULL_ARG(1, 2, 4, 5)
{
int len;
@@ -4076,10 +4033,7 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum,
// Call the 'quickfixtextfunc' function to get the list of lines to display in
// the quickfix window for the entries 'start_idx' to 'end_idx'.
-static list_T *call_qftf_func(qf_list_T *qfl,
- int qf_winid,
- long start_idx,
- long end_idx)
+static list_T *call_qftf_func(qf_list_T *qfl, int qf_winid, long start_idx, long end_idx)
{
Callback *cb = &qftf_cb;
list_T *qftf_list = NULL;
@@ -4126,12 +4080,11 @@ static list_T *call_qftf_func(qf_list_T *qfl,
/// If "old_last" is not NULL append the items after this one.
/// When "old_last" is NULL then "buf" must equal "curbuf"! Because ml_delete()
/// is used and autocommands will be triggered.
-static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last,
- int qf_winid)
+static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int qf_winid)
FUNC_ATTR_NONNULL_ARG(2)
{
linenr_T lnum;
- qfline_T *qfp;
+ qfline_T *qfp;
const bool old_KeyTyped = KeyTyped;
list_T *qftf_list = NULL;
listitem_T *qftf_li = NULL;
@@ -4150,11 +4103,11 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last,
// Check if there is anything to display
if (qfl != NULL) {
- char_u dirname[MAXPATHL];
- int prev_bufnr = -1;
- bool invalid_val = false;
+ char_u dirname[MAXPATHL];
+ int prev_bufnr = -1;
+ bool invalid_val = false;
- *dirname = NUL;
+ *dirname = NUL;
// Add one line for each error
if (old_last == NULL) {
@@ -4235,7 +4188,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last,
static void qf_list_changed(qf_list_T *qfl)
{
- qfl->qf_changedtick++;
+ qfl->qf_changedtick++;
}
/// Return the quickfix/location list number with the given identifier.
@@ -4291,7 +4244,7 @@ int grep_internal(cmdidx_T cmdidx)
|| cmdidx == CMD_grepadd
|| cmdidx == CMD_lgrepadd)
&& STRCMP("internal",
- *curbuf->b_p_gp == NUL ? p_gp : curbuf->b_p_gp) == 0;
+ *curbuf->b_p_gp == NUL ? p_gp : curbuf->b_p_gp) == 0;
}
// Return the make/grep autocmd name.
@@ -4299,20 +4252,20 @@ static char_u *make_get_auname(cmdidx_T cmdidx)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (cmdidx) {
- case CMD_make:
- return (char_u *)"make";
- case CMD_lmake:
- return (char_u *)"lmake";
- case CMD_grep:
- return (char_u *)"grep";
- case CMD_lgrep:
- return (char_u *)"lgrep";
- case CMD_grepadd:
- return (char_u *)"grepadd";
- case CMD_lgrepadd:
- return (char_u *)"lgrepadd";
- default:
- return NULL;
+ case CMD_make:
+ return (char_u *)"make";
+ case CMD_lmake:
+ return (char_u *)"lmake";
+ case CMD_grep:
+ return (char_u *)"grep";
+ case CMD_lgrep:
+ return (char_u *)"lgrep";
+ case CMD_grepadd:
+ return (char_u *)"grepadd";
+ case CMD_lgrepadd:
+ return (char_u *)"lgrepadd";
+ default:
+ return NULL;
}
}
@@ -4349,9 +4302,9 @@ static char *make_get_fullcmd(const char_u *makecmd, const char_u *fname)
// Used for ":make", ":lmake", ":grep", ":lgrep", ":grepadd", and ":lgrepadd"
void ex_make(exarg_T *eap)
{
- char_u *fname;
- win_T *wp = NULL;
- qf_info_T *qi = &ql_info;
+ char_u *fname;
+ win_T *wp = NULL;
+ qf_info_T *qi = &ql_info;
int res;
char_u *enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc;
@@ -4375,8 +4328,9 @@ void ex_make(exarg_T *eap)
autowrite_all();
fname = get_mef_name();
- if (fname == NULL)
+ if (fname == NULL) {
return;
+ }
os_remove((char *)fname); // in case it's not unique
char *const cmd = make_get_fullcmd(eap->arg, fname);
@@ -4422,24 +4376,28 @@ cleanup:
// Returns NULL for error.
static char_u *get_mef_name(void)
{
- char_u *p;
- char_u *name;
+ char_u *p;
+ char_u *name;
static int start = -1;
static int off = 0;
if (*p_mef == NUL) {
name = vim_tempname();
- if (name == NULL)
+ if (name == NULL) {
EMSG(_(e_notmp));
+ }
return name;
}
- for (p = p_mef; *p; ++p)
- if (p[0] == '#' && p[1] == '#')
+ for (p = p_mef; *p; ++p) {
+ if (p[0] == '#' && p[1] == '#') {
break;
+ }
+ }
- if (*p == NUL)
+ if (*p == NUL) {
return vim_strsave(p_mef);
+ }
// Keep trying until the name doesn't exist yet.
for (;; ) {
@@ -4613,7 +4571,7 @@ static size_t qf_get_nth_valid_entry(qf_list_T *qfl, size_t n, int fdo)
/// ":cdo", ":ldo", ":cfdo" and ":lfdo".
void ex_cc(exarg_T *eap)
{
- qf_info_T *qi;
+ qf_info_T *qi;
if ((qi = qf_cmd_get_stack(eap, true)) == NULL) {
return;
@@ -4624,19 +4582,19 @@ void ex_cc(exarg_T *eap)
errornr = (int)eap->line2;
} else {
switch (eap->cmdidx) {
- case CMD_cc:
- case CMD_ll:
- errornr = 0;
- break;
- case CMD_crewind:
- case CMD_lrewind:
- case CMD_cfirst:
- case CMD_lfirst:
- errornr = 1;
- break;
- default:
- errornr = 32767;
- break;
+ case CMD_cc:
+ case CMD_ll:
+ errornr = 0;
+ break;
+ case CMD_crewind:
+ case CMD_lrewind:
+ case CMD_cfirst:
+ case CMD_lfirst:
+ errornr = 1;
+ break;
+ default:
+ errornr = 32767;
+ break;
}
}
@@ -4651,9 +4609,8 @@ void ex_cc(exarg_T *eap)
} else {
n = 1;
}
- size_t valid_entry = qf_get_nth_valid_entry(
- qf_get_curlist(qi), n,
- eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo);
+ size_t valid_entry = qf_get_nth_valid_entry(qf_get_curlist(qi), n,
+ eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo);
assert(valid_entry <= INT_MAX);
errornr = (int)valid_entry;
}
@@ -4666,7 +4623,7 @@ void ex_cc(exarg_T *eap)
/// ":cdo", ":ldo", ":cfdo" and ":lfdo".
void ex_cnext(exarg_T *eap)
{
- qf_info_T *qi;
+ qf_info_T *qi;
if ((qi = qf_cmd_get_stack(eap, true)) == NULL) {
return;
@@ -4684,31 +4641,31 @@ void ex_cnext(exarg_T *eap)
// Depending on the command jump to either next or previous entry/file.
Direction dir;
switch (eap->cmdidx) {
- case CMD_cprevious:
- case CMD_lprevious:
- case CMD_cNext:
- case CMD_lNext:
- dir = BACKWARD;
- break;
- case CMD_cnfile:
- case CMD_lnfile:
- case CMD_cfdo:
- case CMD_lfdo:
- dir = FORWARD_FILE;
- break;
- case CMD_cpfile:
- case CMD_lpfile:
- case CMD_cNfile:
- case CMD_lNfile:
- dir = BACKWARD_FILE;
- break;
- case CMD_cnext:
- case CMD_lnext:
- case CMD_cdo:
- case CMD_ldo:
- default:
- dir = FORWARD;
- break;
+ case CMD_cprevious:
+ case CMD_lprevious:
+ case CMD_cNext:
+ case CMD_lNext:
+ dir = BACKWARD;
+ break;
+ case CMD_cnfile:
+ case CMD_lnfile:
+ case CMD_cfdo:
+ case CMD_lfdo:
+ dir = FORWARD_FILE;
+ break;
+ case CMD_cpfile:
+ case CMD_lpfile:
+ case CMD_cNfile:
+ case CMD_lNfile:
+ dir = BACKWARD_FILE;
+ break;
+ case CMD_cnext:
+ case CMD_lnext:
+ case CMD_cdo:
+ case CMD_ldo:
+ default:
+ dir = FORWARD;
+ break;
}
qf_jump(qi, dir, errornr, eap->forceit);
@@ -4717,9 +4674,7 @@ void ex_cnext(exarg_T *eap)
/// Find the first entry in the quickfix list 'qfl' from buffer 'bnr'.
/// The index of the entry is stored in 'errornr'.
/// Returns NULL if an entry is not found.
-static qfline_T *qf_find_first_entry_in_buf(qf_list_T *qfl,
- int bnr,
- int *errornr)
+static qfline_T *qf_find_first_entry_in_buf(qf_list_T *qfl, int bnr, int *errornr)
{
qfline_T *qfp = NULL;
int idx = 0;
@@ -4738,7 +4693,7 @@ static qfline_T *qf_find_first_entry_in_buf(qf_list_T *qfl,
/// Find the first quickfix entry on the same line as 'entry'. Updates 'errornr'
/// with the error number for the first entry. Assumes the entries are sorted in
/// the quickfix list by line number.
-static qfline_T * qf_find_first_entry_on_line(qfline_T *entry, int *errornr)
+static qfline_T *qf_find_first_entry_on_line(qfline_T *entry, int *errornr)
{
while (!got_int
&& entry->qf_prev != NULL
@@ -4754,7 +4709,7 @@ static qfline_T * qf_find_first_entry_on_line(qfline_T *entry, int *errornr)
/// Find the last quickfix entry on the same line as 'entry'. Updates 'errornr'
/// with the error number for the last entry. Assumes the entries are sorted in
/// the quickfix list by line number.
-static qfline_T * qf_find_last_entry_on_line(qfline_T *entry, int *errornr)
+static qfline_T *qf_find_last_entry_on_line(qfline_T *entry, int *errornr)
{
while (!got_int
&& entry->qf_next != NULL
@@ -4770,57 +4725,53 @@ static qfline_T * qf_find_last_entry_on_line(qfline_T *entry, int *errornr)
// Returns true if the specified quickfix entry is
// after the given line (linewise is true)
// or after the line and column.
-static bool qf_entry_after_pos(const qfline_T *qfp, const pos_T *pos,
- bool linewise)
+static bool qf_entry_after_pos(const qfline_T *qfp, const pos_T *pos, bool linewise)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (linewise) {
return qfp->qf_lnum > pos->lnum;
}
return qfp->qf_lnum > pos->lnum
- || (qfp->qf_lnum == pos->lnum && qfp->qf_col > pos->col);
+ || (qfp->qf_lnum == pos->lnum && qfp->qf_col > pos->col);
}
// Returns true if the specified quickfix entry is
// before the given line (linewise is true)
// or before the line and column.
-static bool qf_entry_before_pos(const qfline_T *qfp, const pos_T *pos,
- bool linewise)
+static bool qf_entry_before_pos(const qfline_T *qfp, const pos_T *pos, bool linewise)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (linewise) {
return qfp->qf_lnum < pos->lnum;
}
return qfp->qf_lnum < pos->lnum
- || (qfp->qf_lnum == pos->lnum && qfp->qf_col < pos->col);
+ || (qfp->qf_lnum == pos->lnum && qfp->qf_col < pos->col);
}
// Returns true if the specified quickfix entry is
// on or after the given line (linewise is true)
// or on or after the line and column.
-static bool qf_entry_on_or_after_pos(const qfline_T *qfp, const pos_T *pos,
- bool linewise)
+static bool qf_entry_on_or_after_pos(const qfline_T *qfp, const pos_T *pos, bool linewise)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (linewise) {
return qfp->qf_lnum >= pos->lnum;
}
return qfp->qf_lnum > pos->lnum
- || (qfp->qf_lnum == pos->lnum && qfp->qf_col >= pos->col);
+ || (qfp->qf_lnum == pos->lnum && qfp->qf_col >= pos->col);
}
// Returns true if the specified quickfix entry is
// on or before the given line (linewise is true)
// or on or before the line and column.
-static bool qf_entry_on_or_before_pos(const qfline_T *qfp, const pos_T *pos,
- bool linewise)
+static bool qf_entry_on_or_before_pos(const qfline_T *qfp, const pos_T *pos, bool linewise)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (linewise) {
return qfp->qf_lnum <= pos->lnum;
}
return qfp->qf_lnum < pos->lnum
- || (qfp->qf_lnum == pos->lnum && qfp->qf_col <= pos->col);
+ || (qfp->qf_lnum == pos->lnum && qfp->qf_col <= pos->col);
}
/// Find the first quickfix entry after position 'pos' in buffer 'bnr'.
@@ -4830,13 +4781,8 @@ static bool qf_entry_on_or_before_pos(const qfline_T *qfp, const pos_T *pos,
/// 'qfp' points to the very first entry in the buffer and 'errornr' is the
/// index of the very first entry in the quickfix list.
/// Returns NULL if an entry is not found after 'pos'.
-static qfline_T *qf_find_entry_after_pos(
- int bnr,
- const pos_T *pos,
- bool linewise,
- qfline_T *qfp,
- int *errornr
-)
+static qfline_T *qf_find_entry_after_pos(int bnr, const pos_T *pos, bool linewise, qfline_T *qfp,
+ int *errornr)
FUNC_ATTR_NONNULL_ALL
{
if (qf_entry_after_pos(qfp, pos, linewise)) {
@@ -4871,13 +4817,8 @@ static qfline_T *qf_find_entry_after_pos(
/// 'qfp' points to the very first entry in the buffer and 'errornr' is the
/// index of the very first entry in the quickfix list.
/// Returns NULL if an entry is not found before 'pos'.
-static qfline_T *qf_find_entry_before_pos(
- int bnr,
- const pos_T *pos,
- bool linewise,
- qfline_T *qfp,
- int *errornr
-)
+static qfline_T *qf_find_entry_before_pos(int bnr, const pos_T *pos, bool linewise, qfline_T *qfp,
+ int *errornr)
FUNC_ATTR_NONNULL_ALL
{
// Find the entry just before the position 'pos'
@@ -4902,14 +4843,8 @@ static qfline_T *qf_find_entry_before_pos(
/// Find a quickfix entry in 'qfl' closest to position 'pos' in buffer 'bnr' in
/// the direction 'dir'.
-static qfline_T *qf_find_closest_entry(
- qf_list_T *qfl,
- int bnr,
- const pos_T *pos,
- Direction dir,
- bool linewise,
- int *errornr
-)
+static qfline_T *qf_find_closest_entry(qf_list_T *qfl, int bnr, const pos_T *pos, Direction dir,
+ bool linewise, int *errornr)
FUNC_ATTR_NONNULL_ALL
{
qfline_T *qfp;
@@ -4934,8 +4869,7 @@ static qfline_T *qf_find_closest_entry(
/// Get the nth quickfix entry below the specified entry. Searches forward in
/// the list. If linewise is true, then treat multiple entries on a single line
/// as one.
-static void qf_get_nth_below_entry(qfline_T *entry, linenr_T n,
- bool linewise, int *errornr)
+static void qf_get_nth_below_entry(qfline_T *entry, linenr_T n, bool linewise, int *errornr)
FUNC_ATTR_NONNULL_ALL
{
while (n-- > 0 && !got_int) {
@@ -4966,8 +4900,7 @@ static void qf_get_nth_below_entry(qfline_T *entry, linenr_T n,
/// Get the nth quickfix entry above the specified entry. Searches backwards in
/// the list. If linewise is TRUE, then treat multiple entries on a single line
/// as one.
-static void qf_get_nth_above_entry(qfline_T *entry, linenr_T n,
- bool linewise, int *errornr)
+static void qf_get_nth_above_entry(qfline_T *entry, linenr_T n, bool linewise, int *errornr)
FUNC_ATTR_NONNULL_ALL
{
while (n-- > 0 && !got_int) {
@@ -4988,14 +4921,8 @@ static void qf_get_nth_above_entry(qfline_T *entry, linenr_T n,
/// Find the n'th quickfix entry adjacent to position 'pos' in buffer 'bnr' in
/// the specified direction. Returns the error number in the quickfix list or 0
/// if an entry is not found.
-static int qf_find_nth_adj_entry(
- qf_list_T *qfl,
- int bnr,
- pos_T *pos,
- linenr_T n,
- Direction dir,
- bool linewise
-)
+static int qf_find_nth_adj_entry(qf_list_T *qfl, int bnr, pos_T *pos, linenr_T n, Direction dir,
+ bool linewise)
FUNC_ATTR_NONNULL_ALL
{
int errornr;
@@ -5072,16 +4999,15 @@ void ex_cbelow(exarg_T *eap)
// A quickfix entry column number is 1 based whereas cursor column
// number is 0 based. Adjust the column number.
pos.col++;
- const int errornr = qf_find_nth_adj_entry(
- qfl,
- curbuf->b_fnum,
- &pos,
- eap->addr_count > 0 ? eap->line2 : 0,
- dir,
- eap->cmdidx == CMD_cbelow
- || eap->cmdidx == CMD_lbelow
- || eap->cmdidx == CMD_cabove
- || eap->cmdidx == CMD_labove);
+ const int errornr = qf_find_nth_adj_entry(qfl,
+ curbuf->b_fnum,
+ &pos,
+ eap->addr_count > 0 ? eap->line2 : 0,
+ dir,
+ eap->cmdidx == CMD_cbelow
+ || eap->cmdidx == CMD_lbelow
+ || eap->cmdidx == CMD_cabove
+ || eap->cmdidx == CMD_labove);
if (errornr > 0) {
qf_jump(qi, 0, errornr, false);
@@ -5092,16 +5018,23 @@ void ex_cbelow(exarg_T *eap)
/// Return the autocmd name for the :cfile Ex commands
-static char_u * cfile_get_auname(cmdidx_T cmdidx)
+static char_u *cfile_get_auname(cmdidx_T cmdidx)
{
switch (cmdidx) {
- case CMD_cfile: return (char_u *)"cfile";
- case CMD_cgetfile: return (char_u *)"cgetfile";
- case CMD_caddfile: return (char_u *)"caddfile";
- case CMD_lfile: return (char_u *)"lfile";
- case CMD_lgetfile: return (char_u *)"lgetfile";
- case CMD_laddfile: return (char_u *)"laddfile";
- default: return NULL;
+ case CMD_cfile:
+ return (char_u *)"cfile";
+ case CMD_cgetfile:
+ return (char_u *)"cgetfile";
+ case CMD_caddfile:
+ return (char_u *)"caddfile";
+ case CMD_lfile:
+ return (char_u *)"lfile";
+ case CMD_lgetfile:
+ return (char_u *)"lgetfile";
+ case CMD_laddfile:
+ return (char_u *)"laddfile";
+ default:
+ return NULL;
}
}
@@ -5110,9 +5043,9 @@ static char_u * cfile_get_auname(cmdidx_T cmdidx)
// ":lfile"/":lgetfile"/":laddfile" commands.
void ex_cfile(exarg_T *eap)
{
- win_T *wp = NULL;
- qf_info_T *qi = &ql_info;
- char_u *au_name = NULL;
+ win_T *wp = NULL;
+ qf_info_T *qi = &ql_info;
+ char_u *au_name = NULL;
au_name = cfile_get_auname(eap->cmdidx);
if (au_name != NULL
@@ -5173,15 +5106,24 @@ void ex_cfile(exarg_T *eap)
static char_u *vgr_get_auname(cmdidx_T cmdidx)
{
switch (cmdidx) {
- case CMD_vimgrep: return (char_u *)"vimgrep";
- case CMD_lvimgrep: return (char_u *)"lvimgrep";
- case CMD_vimgrepadd: return (char_u *)"vimgrepadd";
- case CMD_lvimgrepadd: return (char_u *)"lvimgrepadd";
- case CMD_grep: return (char_u *)"grep";
- case CMD_lgrep: return (char_u *)"lgrep";
- case CMD_grepadd: return (char_u *)"grepadd";
- case CMD_lgrepadd: return (char_u *)"lgrepadd";
- default: return NULL;
+ case CMD_vimgrep:
+ return (char_u *)"vimgrep";
+ case CMD_lvimgrep:
+ return (char_u *)"lvimgrep";
+ case CMD_vimgrepadd:
+ return (char_u *)"vimgrepadd";
+ case CMD_lvimgrepadd:
+ return (char_u *)"lvimgrepadd";
+ case CMD_grep:
+ return (char_u *)"grep";
+ case CMD_lgrep:
+ return (char_u *)"lgrep";
+ case CMD_grepadd:
+ return (char_u *)"grepadd";
+ case CMD_lgrepadd:
+ return (char_u *)"lgrepadd";
+ default:
+ return NULL;
}
}
@@ -5226,8 +5168,7 @@ static void vgr_display_fname(char_u *fname)
}
/// Load a dummy buffer to search for a pattern using vimgrep.
-static buf_T *vgr_load_dummy_buf(char_u *fname, char_u *dirname_start,
- char_u *dirname_now)
+static buf_T *vgr_load_dummy_buf(char_u *fname, char_u *dirname_start, char_u *dirname_now)
{
// Don't do Filetype autocommands to avoid loading syntax and
// indent scripts, a great speed improvement.
@@ -5249,8 +5190,7 @@ static buf_T *vgr_load_dummy_buf(char_u *fname, char_u *dirname_start,
/// Check whether a quickfix/location list is valid. Autocmds may remove or
/// change a quickfix list when vimgrep is running. If the list is not found,
/// create a new list.
-static bool vgr_qflist_valid(win_T *wp, qf_info_T *qi, unsigned qfid,
- char_u *title)
+static bool vgr_qflist_valid(win_T *wp, qf_info_T *qi, unsigned qfid, char_u *title)
{
// Verify that the quickfix/location list was not freed by an autocmd
if (!qflist_valid(wp, qfid)) {
@@ -5274,9 +5214,8 @@ static bool vgr_qflist_valid(win_T *wp, qf_info_T *qi, unsigned qfid,
/// Search for a pattern in all the lines in a buffer and add the matching lines
/// to a quickfix list.
-static bool vgr_match_buflines(qf_list_T *qfl, char_u *fname, buf_T *buf,
- regmmatch_T *regmatch, long *tomatch,
- int duplicate_name, int flags)
+static bool vgr_match_buflines(qf_list_T *qfl, char_u *fname, buf_T *buf, regmmatch_T *regmatch,
+ long *tomatch, int duplicate_name, int flags)
FUNC_ATTR_NONNULL_ARG(1, 3, 4, 5)
{
bool found_match = false;
@@ -5373,27 +5312,27 @@ void ex_vimgrep(exarg_T *eap)
{
regmmatch_T regmatch;
int fcount;
- char_u **fnames;
- char_u *fname;
- char_u *s;
- char_u *p;
+ char_u **fnames;
+ char_u *fname;
+ char_u *s;
+ char_u *p;
int fi;
- qf_list_T *qfl;
+ qf_list_T *qfl;
win_T *wp = NULL;
- buf_T *buf;
+ buf_T *buf;
int duplicate_name = FALSE;
int using_dummy;
int redraw_for_dummy = FALSE;
int found_match;
- buf_T *first_match_buf = NULL;
+ buf_T *first_match_buf = NULL;
time_t seconds = 0;
aco_save_T aco;
int flags = 0;
long tomatch;
- char_u *dirname_start = NULL;
- char_u *dirname_now = NULL;
- char_u *target_dir = NULL;
- char_u *au_name = NULL;
+ char_u *dirname_start = NULL;
+ char_u *dirname_now = NULL;
+ char_u *target_dir = NULL;
+ char_u *au_name = NULL;
au_name = vgr_get_auname(eap->cmdidx);
if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
@@ -5405,10 +5344,11 @@ void ex_vimgrep(exarg_T *eap)
qf_info_T *qi = qf_cmd_get_or_alloc_stack(eap, &wp);
- if (eap->addr_count > 0)
+ if (eap->addr_count > 0) {
tomatch = eap->line2;
- else
+ } else {
tomatch = MAXLNUM;
+ }
// Get the search pattern: either white-separated or enclosed in //
regmatch.regprog = NULL;
@@ -5492,8 +5432,9 @@ void ex_vimgrep(exarg_T *eap)
save_qfid = qf_get_curlist(qi)->qf_id;
if (buf == NULL) {
- if (!got_int)
+ if (!got_int) {
smsg(_("Cannot open file \"%s\""), fname);
+ }
} else {
// Try for a match in all lines of the buffer.
// For ":1vimgrep" look for first match only.
@@ -5502,8 +5443,9 @@ void ex_vimgrep(exarg_T *eap)
duplicate_name, flags);
if (using_dummy) {
- if (found_match && first_match_buf == NULL)
+ if (found_match && first_match_buf == NULL) {
first_match_buf = buf;
+ }
if (duplicate_name) {
// Never keep a dummy buffer if there is another buffer
// with the same name.
@@ -5585,8 +5527,9 @@ void ex_vimgrep(exarg_T *eap)
vgr_jump_to_match(qi, eap->forceit, &redraw_for_dummy, first_match_buf,
target_dir);
}
- } else
+ } else {
EMSG2(_(e_nomatch2), s);
+ }
decr_quickfix_busy();
@@ -5624,24 +5567,22 @@ static void restore_start_dir(char_u *dirname_start)
xfree(dirname_now);
}
-// Load file "fname" into a dummy buffer and return the buffer pointer,
-// placing the directory resulting from the buffer load into the
-// "resulting_dir" pointer. "resulting_dir" must be allocated by the caller
-// prior to calling this function. Restores directory to "dirname_start" prior
-// to returning, if autocmds or the 'autochdir' option have changed it.
-//
-// If creating the dummy buffer does not fail, must call unload_dummy_buffer()
-// or wipe_dummy_buffer() later!
-//
-// Returns NULL if it fails.
-static buf_T *
-load_dummy_buffer (
- char_u *fname,
- char_u *dirname_start, // in: old directory
- char_u *resulting_dir // out: new directory
-)
-{
- buf_T *newbuf;
+/// Load file "fname" into a dummy buffer and return the buffer pointer,
+/// placing the directory resulting from the buffer load into the
+/// "resulting_dir" pointer. "resulting_dir" must be allocated by the caller
+/// prior to calling this function. Restores directory to "dirname_start" prior
+/// to returning, if autocmds or the 'autochdir' option have changed it.
+///
+/// If creating the dummy buffer does not fail, must call unload_dummy_buffer()
+/// or wipe_dummy_buffer() later!
+///
+/// @param dirname_start in: old directory
+/// @param resulting_dir out: new directory
+///
+/// @return NULL if it fails.
+static buf_T *load_dummy_buffer(char_u *fname, char_u *dirname_start, char_u *resulting_dir)
+{
+ buf_T *newbuf;
bufref_T newbufref;
bufref_T newbuf_to_wipe;
int failed = true;
@@ -5807,17 +5748,14 @@ static int get_qfline_items(qfline_T *qfp, list_T *list)
|| (tv_dict_add_nr(dict, S_LEN("vcol"), (varnumber_T)qfp->qf_viscol)
== FAIL)
|| (tv_dict_add_nr(dict, S_LEN("nr"), (varnumber_T)qfp->qf_nr) == FAIL)
- || (tv_dict_add_str(
- dict, S_LEN("module"),
- (qfp->qf_module == NULL ? "" : (const char *)qfp->qf_module))
+ || (tv_dict_add_str(dict, S_LEN("module"),
+ (qfp->qf_module == NULL ? "" : (const char *)qfp->qf_module))
== FAIL)
- || (tv_dict_add_str(
- dict, S_LEN("pattern"),
- (qfp->qf_pattern == NULL ? "" : (const char *)qfp->qf_pattern))
+ || (tv_dict_add_str(dict, S_LEN("pattern"),
+ (qfp->qf_pattern == NULL ? "" : (const char *)qfp->qf_pattern))
== FAIL)
- || (tv_dict_add_str(
- dict, S_LEN("text"),
- (qfp->qf_text == NULL ? "" : (const char *)qfp->qf_text))
+ || (tv_dict_add_str(dict, S_LEN("text"),
+ (qfp->qf_text == NULL ? "" : (const char *)qfp->qf_text))
== FAIL)
|| (tv_dict_add_str(dict, S_LEN("type"), (const char *)buf) == FAIL)
|| (tv_dict_add_nr(dict, S_LEN("valid"), (varnumber_T)qfp->qf_valid)
@@ -5834,12 +5772,11 @@ static int get_qfline_items(qfline_T *qfp, list_T *list)
/// If qf_idx is -1, use the current list. Otherwise, use the specified list.
/// If eidx is not 0, then return only the specified entry. Otherwise return
/// all the entries.
-int get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, int eidx,
- list_T *list)
+int get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, int eidx, list_T *list)
{
qf_info_T *qi = qi_arg;
qf_list_T *qfl;
- qfline_T *qfp;
+ qfline_T *qfp;
int i;
if (qi == NULL) {
@@ -5875,7 +5812,7 @@ int get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, int eidx,
return get_qfline_items(qfp, list);
}
} else if (get_qfline_items(qfp, list) == FAIL) {
- return FAIL;
+ return FAIL;
}
}
@@ -6051,10 +5988,7 @@ static int qf_getprop_qfidx(qf_info_T *qi, dict_T *what)
}
/// Return default values for quickfix list properties in retdict.
-static int qf_getprop_defaults(qf_info_T *qi,
- int flags,
- int locstack,
- dict_T *retdict)
+static int qf_getprop_defaults(qf_info_T *qi, int flags, int locstack, dict_T *retdict)
{
int status = OK;
@@ -6099,15 +6033,14 @@ static int qf_getprop_defaults(qf_info_T *qi,
/// Return the quickfix list title as 'title' in retdict
static int qf_getprop_title(qf_list_T *qfl, dict_T *retdict)
{
- return tv_dict_add_str(retdict, S_LEN("title"),
- (const char *)qfl->qf_title);
+ return tv_dict_add_str(retdict, S_LEN("title"),
+ (const char *)qfl->qf_title);
}
// Returns the identifier of the window used to display files from a location
// list. If there is no associated window, then returns 0. Useful only when
// called from a location list window.
-static int qf_getprop_filewinid(const win_T *wp, const qf_info_T *qi,
- dict_T *retdict)
+static int qf_getprop_filewinid(const win_T *wp, const qf_info_T *qi, dict_T *retdict)
FUNC_ATTR_NONNULL_ARG(3)
{
handle_T winid = 0;
@@ -6124,8 +6057,7 @@ static int qf_getprop_filewinid(const win_T *wp, const qf_info_T *qi,
/// Return the quickfix list items/entries as 'items' in retdict.
/// If eidx is not 0, then return the item at the specified index.
-static int qf_getprop_items(qf_info_T *qi, int qf_idx, int eidx,
- dict_T *retdict)
+static int qf_getprop_items(qf_info_T *qi, int qf_idx, int eidx, dict_T *retdict)
{
list_T *l = tv_list_alloc(kListLenMayKnow);
get_errorlist(qi, NULL, qf_idx, eidx, l);
@@ -6284,11 +6216,8 @@ static int qf_setprop_qftf(qf_list_T *qfl, dictitem_T *di)
/// Add a new quickfix entry to list at 'qf_idx' in the stack 'qi' from the
/// items in the dict 'd'. If it is a valid error entry, then set 'valid_entry'
/// to true.
-static int qf_add_entry_from_dict(
- qf_list_T *qfl,
- const dict_T *d,
- bool first_entry,
- bool *valid_entry)
+static int qf_add_entry_from_dict(qf_list_T *qfl, const dict_T *d, bool first_entry,
+ bool *valid_entry)
FUNC_ATTR_NONNULL_ALL
{
static bool did_bufnr_emsg;
@@ -6364,8 +6293,7 @@ static int qf_add_entry_from_dict(
/// Add list of entries to quickfix/location list. Each list entry is
/// a dictionary with item information.
-static int qf_add_entries(qf_info_T *qi, int qf_idx, list_T *list,
- char_u *title, int action)
+static int qf_add_entries(qf_info_T *qi, int qf_idx, list_T *list, char_u *title, int action)
{
qf_list_T *qfl = qf_get_list(qi, qf_idx);
qfline_T *old_last = NULL;
@@ -6428,11 +6356,7 @@ static int qf_add_entries(qf_info_T *qi, int qf_idx, list_T *list,
}
/// Get the quickfix list index from 'nr' or 'id'
-static int qf_setprop_get_qfidx(
- const qf_info_T *qi,
- const dict_T *what,
- int action,
- bool *newlist)
+static int qf_setprop_get_qfidx(const qf_info_T *qi, const dict_T *what, int action, bool *newlist)
FUNC_ATTR_NONNULL_ALL
{
dictitem_T *di;
@@ -6483,8 +6407,7 @@ static int qf_setprop_get_qfidx(
}
// Set the quickfix list title.
-static int qf_setprop_title(qf_info_T *qi, int qf_idx, const dict_T *what,
- const dictitem_T *di)
+static int qf_setprop_title(qf_info_T *qi, int qf_idx, const dict_T *what, const dictitem_T *di)
FUNC_ATTR_NONNULL_ALL
{
qf_list_T *qfl = qf_get_list(qi, qf_idx);
@@ -6502,8 +6425,7 @@ static int qf_setprop_title(qf_info_T *qi, int qf_idx, const dict_T *what,
}
// Set quickfix list items/entries.
-static int qf_setprop_items(qf_info_T *qi, int qf_idx, dictitem_T *di,
- int action)
+static int qf_setprop_items(qf_info_T *qi, int qf_idx, dictitem_T *di, int action)
FUNC_ATTR_NONNULL_ALL
{
if (di->di_tv.v_type != VAR_LIST) {
@@ -6520,17 +6442,13 @@ static int qf_setprop_items(qf_info_T *qi, int qf_idx, dictitem_T *di,
}
// Set quickfix list items/entries from a list of lines.
-static int qf_setprop_items_from_lines(
- qf_info_T *qi,
- int qf_idx,
- const dict_T *what,
- dictitem_T *di,
- int action)
+static int qf_setprop_items_from_lines(qf_info_T *qi, int qf_idx, const dict_T *what,
+ dictitem_T *di, int action)
FUNC_ATTR_NONNULL_ALL
{
char_u *errorformat = p_efm;
dictitem_T *efm_di;
- int retval = FAIL;
+ int retval = FAIL;
// Use the user supplied errorformat settings (if present)
if ((efm_di = tv_dict_find(what, S_LEN("efm"))) != NULL) {
@@ -6570,11 +6488,10 @@ static int qf_setprop_context(qf_list_T *qfl, dictitem_T *di)
}
// Set the current index in the specified quickfix list
-static int qf_setprop_curidx(qf_info_T *qi, qf_list_T *qfl,
- const dictitem_T *di)
+static int qf_setprop_curidx(qf_info_T *qi, qf_list_T *qfl, const dictitem_T *di)
FUNC_ATTR_NONNULL_ALL
{
- int newidx;
+ int newidx;
// If the specified index is '$', then use the last entry
if (di->di_tv.v_type == VAR_STRING
@@ -6615,13 +6532,12 @@ static int qf_setprop_curidx(qf_info_T *qi, qf_list_T *qfl,
/// Set quickfix/location list properties (title, items, context).
/// Also used to add items from parsing a list of lines.
/// Used by the setqflist() and setloclist() Vim script functions.
-static int qf_set_properties(qf_info_T *qi, const dict_T *what, int action,
- char_u *title)
+static int qf_set_properties(qf_info_T *qi, const dict_T *what, int action, char_u *title)
FUNC_ATTR_NONNULL_ALL
{
qf_list_T *qfl;
dictitem_T *di;
- int retval = FAIL;
+ int retval = FAIL;
bool newlist = action == ' ' || qf_stack_empty(qi);
int qf_idx = qf_setprop_get_qfidx(qi, what, action, &newlist);
if (qf_idx == INVALID_QFIDX) { // List not found
@@ -6727,8 +6643,7 @@ static void qf_free_stack(win_T *wp, qf_info_T *qi)
// of dictionaries. "title" will be copied to w:quickfix_title
// "action" is 'a' for add, 'r' for replace. Otherwise create a new list.
// When "what" is not NULL then only set some properties.
-int set_errorlist(win_T *wp, list_T *list, int action, char_u *title,
- dict_T *what)
+int set_errorlist(win_T *wp, list_T *list, int action, char_u *title, dict_T *what)
{
qf_info_T *qi = &ql_info;
int retval = OK;
@@ -6813,32 +6728,37 @@ bool set_ref_in_quickfix(int copyID)
}
/// Return the autocmd name for the :cbuffer Ex commands
-static char_u * cbuffer_get_auname(cmdidx_T cmdidx)
+static char_u *cbuffer_get_auname(cmdidx_T cmdidx)
{
switch (cmdidx) {
- case CMD_cbuffer: return (char_u *)"cbuffer";
- case CMD_cgetbuffer: return (char_u *)"cgetbuffer";
- case CMD_caddbuffer: return (char_u *)"caddbuffer";
- case CMD_lbuffer: return (char_u *)"lbuffer";
- case CMD_lgetbuffer: return (char_u *)"lgetbuffer";
- case CMD_laddbuffer: return (char_u *)"laddbuffer";
- default: return NULL;
+ case CMD_cbuffer:
+ return (char_u *)"cbuffer";
+ case CMD_cgetbuffer:
+ return (char_u *)"cgetbuffer";
+ case CMD_caddbuffer:
+ return (char_u *)"caddbuffer";
+ case CMD_lbuffer:
+ return (char_u *)"lbuffer";
+ case CMD_lgetbuffer:
+ return (char_u *)"lgetbuffer";
+ case CMD_laddbuffer:
+ return (char_u *)"laddbuffer";
+ default:
+ return NULL;
}
}
/// Process and validate the arguments passed to the :cbuffer, :caddbuffer,
/// :cgetbuffer, :lbuffer, :laddbuffer, :lgetbuffer Ex commands.
-static int cbuffer_process_args(exarg_T *eap,
- buf_T **bufp,
- linenr_T *line1,
- linenr_T *line2)
+static int cbuffer_process_args(exarg_T *eap, buf_T **bufp, linenr_T *line1, linenr_T *line2)
{
buf_T *buf = NULL;
- if (*eap->arg == NUL)
+ if (*eap->arg == NUL) {
buf = curbuf;
- else if (*skipwhite(skipdigits(eap->arg)) == NUL)
+ } else if (*skipwhite(skipdigits(eap->arg)) == NUL) {
buf = buflist_findnr(atoi((char *)eap->arg));
+ }
if (buf == NULL) {
EMSG(_(e_invarg));
@@ -6944,16 +6864,23 @@ void ex_cbuffer(exarg_T *eap)
}
/// Return the autocmd name for the :cexpr Ex commands.
-static char_u * cexpr_get_auname(cmdidx_T cmdidx)
+static char_u *cexpr_get_auname(cmdidx_T cmdidx)
{
switch (cmdidx) {
- case CMD_cexpr: return (char_u *)"cexpr";
- case CMD_cgetexpr: return (char_u *)"cgetexpr";
- case CMD_caddexpr: return (char_u *)"caddexpr";
- case CMD_lexpr: return (char_u *)"lexpr";
- case CMD_lgetexpr: return (char_u *)"lgetexpr";
- case CMD_laddexpr: return (char_u *)"laddexpr";
- default: return NULL;
+ case CMD_cexpr:
+ return (char_u *)"cexpr";
+ case CMD_cgetexpr:
+ return (char_u *)"cgetexpr";
+ case CMD_caddexpr:
+ return (char_u *)"caddexpr";
+ case CMD_lexpr:
+ return (char_u *)"lexpr";
+ case CMD_lgetexpr:
+ return (char_u *)"lgetexpr";
+ case CMD_laddexpr:
+ return (char_u *)"laddexpr";
+ default:
+ return NULL;
}
}
@@ -7047,10 +6974,7 @@ static qf_info_T *hgr_get_ll(bool *new_ll)
}
// Search for a pattern in a help file.
-static void hgr_search_file(
- qf_list_T *qfl,
- char_u *fname,
- regmatch_T *p_regmatch)
+static void hgr_search_file(qf_list_T *qfl, char_u *fname, regmatch_T *p_regmatch)
FUNC_ATTR_NONNULL_ARG(1, 3)
{
FILE *const fd = os_fopen((char *)fname, "r");
@@ -7105,11 +7029,8 @@ static void hgr_search_file(
// Search for a pattern in all the help files in the doc directory under
// the given directory.
-static void hgr_search_files_in_dir(
- qf_list_T *qfl,
- char_u *dirname,
- regmatch_T *p_regmatch,
- const char_u *lang)
+static void hgr_search_files_in_dir(qf_list_T *qfl, char_u *dirname, regmatch_T *p_regmatch,
+ const char_u *lang)
FUNC_ATTR_NONNULL_ARG(1, 2, 3)
{
int fcount;
@@ -7141,8 +7062,7 @@ static void hgr_search_files_in_dir(
// and add the matches to a quickfix list.
// 'lang' is the language specifier. If supplied, then only matches in the
// specified language are found.
-static void hgr_search_in_rtp(qf_list_T *qfl, regmatch_T *p_regmatch,
- const char_u *lang)
+static void hgr_search_in_rtp(qf_list_T *qfl, regmatch_T *p_regmatch, const char_u *lang)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
// Go through all directories in 'runtimepath'
@@ -7162,9 +7082,12 @@ void ex_helpgrep(exarg_T *eap)
char_u *au_name = NULL;
switch (eap->cmdidx) {
- case CMD_helpgrep: au_name = (char_u *)"helpgrep"; break;
- case CMD_lhelpgrep: au_name = (char_u *)"lhelpgrep"; break;
- default: break;
+ case CMD_helpgrep:
+ au_name = (char_u *)"helpgrep"; break;
+ case CMD_lhelpgrep:
+ au_name = (char_u *)"lhelpgrep"; break;
+ default:
+ break;
}
if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
curbuf->b_fname, true, curbuf)) {
diff --git a/src/nvim/quickfix.h b/src/nvim/quickfix.h
index fdeb8d1a2f..f5178e332a 100644
--- a/src/nvim/quickfix.h
+++ b/src/nvim/quickfix.h
@@ -1,10 +1,10 @@
#ifndef NVIM_QUICKFIX_H
#define NVIM_QUICKFIX_H
-#include "nvim/types.h"
#include "nvim/ex_cmds_defs.h"
+#include "nvim/types.h"
-/* flags for skip_vimgrep_pat() */
+// flags for skip_vimgrep_pat()
#define VGR_GLOBAL 1
#define VGR_NOJUMP 2
diff --git a/src/nvim/rbuffer.c b/src/nvim/rbuffer.c
index df9394fbb2..4ac50095b3 100644
--- a/src/nvim/rbuffer.c
+++ b/src/nvim/rbuffer.c
@@ -6,8 +6,8 @@
#include <string.h>
#include "nvim/memory.h"
-#include "nvim/vim.h"
#include "nvim/rbuffer.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "rbuffer.c.generated.h"
@@ -144,7 +144,7 @@ void rbuffer_consumed(RBuffer *buf, size_t count)
buf->read_ptr += count;
if (buf->read_ptr >= buf->end_ptr) {
- buf->read_ptr -= rbuffer_capacity(buf);
+ buf->read_ptr -= rbuffer_capacity(buf);
}
bool was_full = buf->size == rbuffer_capacity(buf);
diff --git a/src/nvim/rbuffer.h b/src/nvim/rbuffer.h
index a8dfcac580..cc690050ab 100644
--- a/src/nvim/rbuffer.h
+++ b/src/nvim/rbuffer.h
@@ -38,17 +38,17 @@
// create infinite loops
#define RBUFFER_UNTIL_EMPTY(buf, rptr, rcnt) \
for (size_t rcnt = 0, _r = 1; _r; _r = 0) /* NOLINT(readability/braces) */ \
- for ( /* NOLINT(readability/braces) */ \
- char *rptr = rbuffer_read_ptr(buf, &rcnt); \
- buf->size; \
- rptr = rbuffer_read_ptr(buf, &rcnt))
+ for ( /* NOLINT(readability/braces) */ \
+ char *rptr = rbuffer_read_ptr(buf, &rcnt); \
+ buf->size; \
+ rptr = rbuffer_read_ptr(buf, &rcnt))
#define RBUFFER_UNTIL_FULL(buf, wptr, wcnt) \
for (size_t wcnt = 0, _r = 1; _r; _r = 0) /* NOLINT(readability/braces) */ \
- for ( /* NOLINT(readability/braces) */ \
- char *wptr = rbuffer_write_ptr(buf, &wcnt); \
- rbuffer_space(buf); \
- wptr = rbuffer_write_ptr(buf, &wcnt))
+ for ( /* NOLINT(readability/braces) */ \
+ char *wptr = rbuffer_write_ptr(buf, &wcnt); \
+ rbuffer_space(buf); \
+ wptr = rbuffer_write_ptr(buf, &wcnt))
// Iteration
@@ -56,23 +56,23 @@
for (size_t i = 0; /* NOLINT(readability/braces) */ \
i < buf->size; \
i = buf->size) \
- for (char c = 0; /* NOLINT(readability/braces) */ \
- i < buf->size ? ((int)(c = *rbuffer_get(buf, i))) || 1 : 0; \
- i++)
+ for (char c = 0; /* NOLINT(readability/braces) */ \
+ i < buf->size ? ((int)(c = *rbuffer_get(buf, i))) || 1 : 0; \
+ i++)
#define RBUFFER_EACH_REVERSE(buf, c, i) \
for (size_t i = buf->size; /* NOLINT(readability/braces) */ \
i != SIZE_MAX; \
i = SIZE_MAX) \
- for (char c = 0; /* NOLINT(readability/braces) */ \
- i-- > 0 ? ((int)(c = *rbuffer_get(buf, i))) || 1 : 0; \
- )
+ for (char c = 0; /* NOLINT(readability/braces) */ \
+ i-- > 0 ? ((int)(c = *rbuffer_get(buf, i))) || 1 : 0; \
+ )
typedef struct rbuffer RBuffer;
/// Type of function invoked during certain events:
/// - When the RBuffer switches to the full state
/// - When the RBuffer switches to the non-full state
-typedef void(*rbuffer_callback)(RBuffer *buf, void *data);
+typedef void (*rbuffer_callback)(RBuffer *buf, void *data);
struct rbuffer {
rbuffer_callback full_cb, nonfull_cb;
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index 98a46cf781..24dc86e034 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.c
@@ -1,6 +1,8 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+// uncrustify:off
+
/*
* Handling of regular expressions: vim_regcomp(), vim_regexec(), vim_regsub()
*
@@ -3003,8 +3005,8 @@ static void ungetchr(void)
at_start = prev_at_start;
prev_at_start = false;
- /* Backup regparse, so that it's at the same position as before the
- * getchr(). */
+ // Backup regparse, so that it's at the same position as before the
+ // getchr().
regparse -= prevchr_len;
}
@@ -6412,8 +6414,8 @@ static int cstrncmp(char_u *s1, char_u *s2, int *n)
int c1, c2, c11, c12;
int junk;
- /* we have to handle the strcmp ourselves, since it is necessary to
- * deal with the composing characters by ignoring them: */
+ // we have to handle the strcmp ourselves, since it is necessary to
+ // deal with the composing characters by ignoring them:
str1 = s1;
str2 = s2;
c1 = c2 = 0;
@@ -7184,8 +7186,8 @@ static regengine_T nfa_regengine =
(char_u *)""
};
-/* Which regexp engine to use? Needed for vim_regcomp().
- * Must match with 'regexpengine'. */
+// Which regexp engine to use? Needed for vim_regcomp().
+// Must match with 'regexpengine'.
static int regexp_engine = 0;
#ifdef REGEXP_DEBUG
diff --git a/src/nvim/regexp.h b/src/nvim/regexp.h
index 74ed34188c..9527afed58 100644
--- a/src/nvim/regexp.h
+++ b/src/nvim/regexp.h
@@ -1,9 +1,9 @@
#ifndef NVIM_REGEXP_H
#define NVIM_REGEXP_H
-#include "nvim/types.h"
#include "nvim/buffer_defs.h"
#include "nvim/regexp_defs.h"
+#include "nvim/types.h"
// Second argument for vim_regcomp().
#define RE_MAGIC 1 ///< 'magic' option
diff --git a/src/nvim/regexp_defs.h b/src/nvim/regexp_defs.h
index a729a91555..1d112bd64a 100644
--- a/src/nvim/regexp_defs.h
+++ b/src/nvim/regexp_defs.h
@@ -15,8 +15,8 @@
#include <stdbool.h>
#include "nvim/pos.h"
-#include "nvim/types.h"
#include "nvim/profile.h"
+#include "nvim/types.h"
/*
* The number of sub-matches is limited to 10.
@@ -53,7 +53,7 @@ typedef struct reg_extmatch reg_extmatch_T;
/// always 0.
/// When there is no match, the line number is -1.
typedef struct {
- regprog_T *regprog;
+ regprog_T *regprog;
lpos_T startpos[NSUBEXP];
lpos_T endpos[NSUBEXP];
int rmm_ic;
@@ -90,7 +90,7 @@ typedef struct {
int regstart;
char_u reganch;
- char_u *regmust;
+ char_u *regmust;
int regmlen;
char_u reghasz;
char_u program[1]; // actually longer..
@@ -101,8 +101,8 @@ typedef struct {
typedef struct nfa_state nfa_state_T;
struct nfa_state {
int c;
- nfa_state_T *out;
- nfa_state_T *out1;
+ nfa_state_T *out;
+ nfa_state_T *out1;
int id;
int lastlist[2]; // 0: normal, 1: recursive
int val;
@@ -119,16 +119,16 @@ typedef struct {
unsigned re_flags;
bool re_in_use;
- nfa_state_T *start; // points into state[]
+ nfa_state_T *start; // points into state[]
int reganch; // pattern starts with ^
int regstart; // char at start of pattern
- char_u *match_text; // plain text to match with
+ char_u *match_text; // plain text to match with
int has_zend; // pattern contains \ze
int has_backref; // pattern contains \1 .. \9
int reghasz;
- char_u *pattern;
+ char_u *pattern;
int nsubexp; // number of ()
int nstate;
nfa_state_T state[1]; // actually longer..
@@ -140,10 +140,10 @@ typedef struct {
* When there is no match, the pointer is NULL.
*/
typedef struct {
- regprog_T *regprog;
- char_u *startp[NSUBEXP];
- char_u *endp[NSUBEXP];
- bool rm_ic;
+ regprog_T *regprog;
+ char_u *startp[NSUBEXP];
+ char_u *endp[NSUBEXP];
+ bool rm_ic;
} regmatch_T;
/*
@@ -153,16 +153,16 @@ typedef struct {
*/
struct reg_extmatch {
int16_t refcnt;
- char_u *matches[NSUBEXP];
+ char_u *matches[NSUBEXP];
};
struct regengine {
- regprog_T *(*regcomp)(char_u *, int);
+ regprog_T *(*regcomp)(char_u *, int);
void (*regfree)(regprog_T *);
int (*regexec_nl)(regmatch_T *, char_u *, colnr_T, bool);
long (*regexec_multi)(regmmatch_T *, win_T *, buf_T *, linenr_T, colnr_T,
proftime_T *, int *);
- char_u *expr;
+ char_u *expr;
};
#endif // NVIM_REGEXP_DEFS_H
diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c
index 039f9b4675..c8b7190b4a 100644
--- a/src/nvim/regexp_nfa.c
+++ b/src/nvim/regexp_nfa.c
@@ -1,6 +1,8 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+// uncrustify:off
+
/*
* NFA regular expression implementation.
*
@@ -372,8 +374,8 @@ nfa_regcomp_start (
/* A reasonable estimation for maximum size */
nstate_max = (STRLEN(expr) + 1) * 25;
- /* Some items blow up in size, such as [A-z]. Add more space for that.
- * When it is still not enough realloc_post_list() will be used. */
+ // Some items blow up in size, such as [A-z]. Add more space for that.
+ // When it is still not enough realloc_post_list() will be used.
nstate_max += 1000;
/* Size for postfix representation of expr. */
@@ -1424,8 +1426,8 @@ static int nfa_regatom(void)
}
break;
- /* Catch \%^ and \%$ regardless of where they appear in the
- * pattern -- regardless of whether or not it makes sense. */
+ // Catch \%^ and \%$ regardless of where they appear in the
+ // pattern -- regardless of whether or not it makes sense.
case '^':
EMIT(NFA_BOF);
break;
@@ -1466,13 +1468,13 @@ static int nfa_regatom(void)
EMIT(NFA_OPT_CHARS);
EMIT(n);
- /* Emit as "\%(\%[abc]\)" to be able to handle
- * "\%[abc]*" which would cause the empty string to be
- * matched an unlimited number of times. NFA_NOPEN is
- * added only once at a position, while NFA_SPLIT is
- * added multiple times. This is more efficient than
- * not allowing NFA_SPLIT multiple times, it is used
- * a lot. */
+ // Emit as "\%(\%[abc]\)" to be able to handle
+ // "\%[abc]*" which would cause the empty string to be
+ // matched an unlimited number of times. NFA_NOPEN is
+ // added only once at a position, while NFA_SPLIT is
+ // added multiple times. This is more efficient than
+ // not allowing NFA_SPLIT multiple times, it is used
+ // a lot.
EMIT(NFA_NOPEN);
break;
}
@@ -1882,8 +1884,8 @@ static int nfa_regpiece(void)
int my_post_start;
int quest;
- /* Save the current parse state, so that we can use it if <atom>{m,n} is
- * next. */
+ // Save the current parse state, so that we can use it if <atom>{m,n} is
+ // next.
save_parse_state(&old_state);
/* store current pos in the postfix form, for \{m,n} involving 0s */
@@ -1967,12 +1969,11 @@ static int nfa_regpiece(void)
break;
case Magic('{'):
- /* a{2,5} will expand to 'aaa?a?a?'
- * a{-1,3} will expand to 'aa??a??', where ?? is the nongreedy
- * version of '?'
- * \v(ab){2,3} will expand to '(ab)(ab)(ab)?', where all the
- * parenthesis have the same id
- */
+ // a{2,5} will expand to 'aaa?a?a?'
+ // a{-1,3} will expand to 'aa??a??', where ?? is the nongreedy
+ // version of '?'
+ // \v(ab){2,3} will expand to '(ab)(ab)(ab)?', where all the
+ // parenthesis have the same id
greedy = true;
c2 = peekchr();
@@ -1983,8 +1984,8 @@ static int nfa_regpiece(void)
if (!read_limits(&minval, &maxval))
EMSG_RET_FAIL(_("E870: (NFA regexp) Error reading repetition limits"));
- /* <atom>{0,inf}, <atom>{0,} and <atom>{} are equivalent to
- * <atom>* */
+ // <atom>{0,inf}, <atom>{0,} and <atom>{} are equivalent to
+ // <atom>*
if (minval == 0 && maxval == MAX_LIMIT) {
if (greedy)
/* \{}, \{0,} */
@@ -3327,10 +3328,10 @@ static nfa_state_T *post2nfa(int *postfix, int *end, int nfa_calc_size)
break;
}
- /* Allow "NFA_MOPEN" as a valid postfix representation for
- * the empty regexp "". In this case, the NFA will be
- * NFA_MOPEN -> NFA_MCLOSE. Note that this also allows
- * empty groups of parenthesis, and empty mbyte chars */
+ // Allow "NFA_MOPEN" as a valid postfix representation for
+ // the empty regexp "". In this case, the NFA will be
+ // NFA_MOPEN -> NFA_MCLOSE. Note that this also allows
+ // empty groups of parenthesis, and empty mbyte chars
if (stackp == stack) {
s = alloc_state(mopen, NULL, NULL);
if (s == NULL)
@@ -3343,8 +3344,8 @@ static nfa_state_T *post2nfa(int *postfix, int *end, int nfa_calc_size)
break;
}
- /* At least one node was emitted before NFA_MOPEN, so
- * at least one node will be between NFA_MOPEN and NFA_MCLOSE */
+ // At least one node was emitted before NFA_MOPEN, so
+ // at least one node will be between NFA_MOPEN and NFA_MCLOSE
e = POP();
s = alloc_state(mopen, e.start, NULL); /* `(' */
if (s == NULL)
@@ -3501,14 +3502,14 @@ static void nfa_postprocess(nfa_regprog_T *prog)
int ch_invisible = failure_chance(prog->state[i].out, 0);
int ch_follows = failure_chance(prog->state[i].out1->out, 0);
- /* Postpone when the invisible match is expensive or has a
- * lower chance of failing. */
+ // Postpone when the invisible match is expensive or has a
+ // lower chance of failing.
if (c == NFA_START_INVISIBLE_BEFORE
|| c == NFA_START_INVISIBLE_BEFORE_NEG) {
- /* "before" matches are very expensive when
- * unbounded, always prefer what follows then,
- * unless what follows will always match.
- * Otherwise strongly prefer what follows. */
+ // "before" matches are very expensive when
+ // unbounded, always prefer what follows then,
+ // unless what follows will always match.
+ // Otherwise strongly prefer what follows.
if (prog->state[i].val <= 0 && ch_follows > 0) {
directly = false;
} else {
@@ -3527,9 +3528,9 @@ static void nfa_postprocess(nfa_regprog_T *prog)
}
}
-/****************************************************************
-* NFA execution code.
-****************************************************************/
+/////////////////////////////////////////////////////////////////
+// NFA execution code.
+/////////////////////////////////////////////////////////////////
/* Values for done in nfa_pim_T. */
#define NFA_PIM_UNUSED 0 /* pim not used */
@@ -4195,8 +4196,8 @@ skip_add:
save_ptr = NULL;
memset(&save_multipos, 0, sizeof(save_multipos));
- /* Set the position (with "off" added) in the subexpression. Save
- * and restore it when it was in use. Otherwise fill any gap. */
+ // Set the position (with "off" added) in the subexpression. Save
+ // and restore it when it was in use. Otherwise fill any gap.
if (REG_MULTI) {
if (subidx < sub->in_use) {
save_multipos = sub->list.multi[subidx];
@@ -4295,8 +4296,8 @@ skip_add:
sub = &subs->norm;
}
- /* We don't fill in gaps here, there must have been an MOPEN that
- * has done that. */
+ // We don't fill in gaps here, there must have been an MOPEN that
+ // has done that.
save_in_use = sub->in_use;
if (sub->in_use <= subidx)
sub->in_use = subidx + 1;
diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c
index d4191cff6b..5ade6244f9 100644
--- a/src/nvim/runtime.c
+++ b/src/nvim/runtime.c
@@ -5,21 +5,26 @@
///
/// Management of runtime files (including packages)
-#include "nvim/vim.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
#include "nvim/charset.h"
#include "nvim/eval.h"
-#include "nvim/option.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds2.h"
+#include "nvim/lua/executor.h"
#include "nvim/misc1.h"
+#include "nvim/option.h"
#include "nvim/os/os.h"
#include "nvim/runtime.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "runtime.c.generated.h"
#endif
+static bool runtime_search_path_valid = false;
+static int *runtime_search_path_ref = NULL;
+static RuntimeSearchPath runtime_search_path;
/// ":runtime [what] {name}"
void ex_runtime(exarg_T *eap)
@@ -43,13 +48,13 @@ void ex_runtime(exarg_T *eap)
arg = skipwhite(arg + len);
}
- source_runtime(arg, flags);
+ source_runtime((char *)arg, flags);
}
static void source_callback(char_u *fname, void *cookie)
{
- (void)do_source(fname, false, DOSO_NONE);
+ (void)do_source((char *)fname, false, DOSO_NONE);
}
/// Find the file "name" in all directories in "path" and invoke
@@ -60,12 +65,11 @@ static void source_callback(char_u *fname, void *cookie)
/// When "flags" has DIP_ERR: give an error message if there is no match.
///
/// return FAIL when no file could be sourced, OK otherwise.
-int do_in_path(char_u *path, char_u *name, int flags,
- DoInRuntimepathCB callback, void *cookie)
+int do_in_path(char_u *path, char *name, int flags, DoInRuntimepathCB callback, void *cookie)
{
- char_u *tail;
+ char_u *tail;
int num_files;
- char_u **files;
+ char_u **files;
int i;
bool did_one = false;
@@ -76,8 +80,7 @@ int do_in_path(char_u *path, char_u *name, int flags,
{
if (p_verbose > 10 && name != NULL) {
verbose_enter();
- smsg(_("Searching for \"%s\" in \"%s\""),
- (char *)name, (char *)path);
+ smsg(_("Searching for \"%s\" in \"%s\""), name, (char *)path);
verbose_leave();
}
@@ -90,8 +93,7 @@ int do_in_path(char_u *path, char_u *name, int flags,
// Skip after or non-after directories.
if (flags & (DIP_NOAFTER | DIP_AFTER)) {
- bool is_after = buflen >= 5
- && STRCMP(buf + buflen - 5, "after") == 0;
+ bool is_after = path_is_after(buf, buflen);
if ((is_after && (flags & DIP_NOAFTER))
|| (!is_after && (flags & DIP_AFTER))) {
@@ -107,7 +109,7 @@ int do_in_path(char_u *path, char_u *name, int flags,
tail = buf + STRLEN(buf);
// Loop over all patterns in "name"
- char_u *np = name;
+ char_u *np = (char_u *)name;
while (*np != NUL && ((flags & DIP_ALL) || !did_one)) {
// Append the pattern from "name" to buf[].
assert(MAXPATHL >= (tail - buf));
@@ -156,6 +158,188 @@ int do_in_path(char_u *path, char_u *name, int flags,
return did_one ? OK : FAIL;
}
+RuntimeSearchPath runtime_search_path_get_cached(int *ref)
+ FUNC_ATTR_NONNULL_ALL
+{
+ runtime_search_path_validate();
+
+ *ref = 0;
+ if (runtime_search_path_ref == NULL) {
+ // cached path was unreferenced. keep a ref to
+ // prevent runtime_search_path() to freeing it too early
+ (*ref)++;
+ runtime_search_path_ref = ref;
+ }
+ return runtime_search_path;
+}
+
+void runtime_search_path_unref(RuntimeSearchPath path, int *ref)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (*ref) {
+ if (runtime_search_path_ref == ref) {
+ runtime_search_path_ref = NULL;
+ } else {
+ runtime_search_path_free(path);
+ }
+ }
+}
+
+
+/// Find the file "name" in all directories in "path" and invoke
+/// "callback(fname, cookie)".
+/// "name" can contain wildcards.
+/// When "flags" has DIP_ALL: source all files, otherwise only the first one.
+/// When "flags" has DIP_DIR: find directories instead of files.
+/// When "flags" has DIP_ERR: give an error message if there is no match.
+///
+/// return FAIL when no file could be sourced, OK otherwise.
+int do_in_cached_path(char_u *name, int flags, DoInRuntimepathCB callback, void *cookie)
+{
+ char_u *tail;
+ int num_files;
+ char_u **files;
+ int i;
+ bool did_one = false;
+
+ char_u buf[MAXPATHL];
+
+ if (p_verbose > 10 && name != NULL) {
+ verbose_enter();
+ smsg(_("Searching for \"%s\" in runtime path"), (char *)name);
+ verbose_leave();
+ }
+
+ int ref;
+ RuntimeSearchPath path = runtime_search_path_get_cached(&ref);
+
+ // Loop over all entries in cached path
+ for (size_t j = 0; j < kv_size(path); j++) {
+ SearchPathItem item = kv_A(path, j);
+ size_t buflen = strlen(item.path);
+
+ // Skip after or non-after directories.
+ if (flags & (DIP_NOAFTER | DIP_AFTER)) {
+ if ((item.after && (flags & DIP_NOAFTER))
+ || (!item.after && (flags & DIP_AFTER))) {
+ continue;
+ }
+ }
+
+ if (name == NULL) {
+ (*callback)((char_u *)item.path, cookie);
+ } else if (buflen + STRLEN(name) + 2 < MAXPATHL) {
+ STRCPY(buf, item.path);
+ add_pathsep((char *)buf);
+ tail = buf + STRLEN(buf);
+
+ // Loop over all patterns in "name"
+ char_u *np = name;
+ while (*np != NUL && ((flags & DIP_ALL) || !did_one)) {
+ // Append the pattern from "name" to buf[].
+ assert(MAXPATHL >= (tail - buf));
+ copy_option_part(&np, tail, (size_t)(MAXPATHL - (tail - buf)),
+ "\t ");
+
+ if (p_verbose > 10) {
+ verbose_enter();
+ smsg(_("Searching for \"%s\""), buf);
+ verbose_leave();
+ }
+
+ int ew_flags = ((flags & DIP_DIR) ? EW_DIR : EW_FILE)
+ | (flags & DIP_DIRFILE) ? (EW_DIR|EW_FILE) : 0;
+
+ // Expand wildcards, invoke the callback for each match.
+ char_u *(pat[]) = { buf };
+ if (gen_expand_wildcards(1, pat, &num_files, &files, ew_flags) == OK) {
+ for (i = 0; i < num_files; i++) {
+ (*callback)(files[i], cookie);
+ did_one = true;
+ if (!(flags & DIP_ALL)) {
+ break;
+ }
+ }
+ FreeWild(num_files, files);
+ }
+ }
+ }
+ }
+
+ if (!did_one && name != NULL) {
+ if (flags & DIP_ERR) {
+ EMSG3(_(e_dirnotf), "runtime path", name);
+ } else if (p_verbose > 0) {
+ verbose_enter();
+ smsg(_("not found in runtime path: \"%s\""), name);
+ verbose_leave();
+ }
+ }
+
+ runtime_search_path_unref(path, &ref);
+
+ return did_one ? OK : FAIL;
+}
+
+Array runtime_inspect(void)
+{
+ RuntimeSearchPath path = runtime_search_path;
+ Array rv = ARRAY_DICT_INIT;
+
+ for (size_t i = 0; i < kv_size(path); i++) {
+ SearchPathItem *item = &kv_A(path, i);
+ Array entry = ARRAY_DICT_INIT;
+ ADD(entry, STRING_OBJ(cstr_to_string(item->path)));
+ ADD(entry, BOOLEAN_OBJ(item->after));
+ if (item->has_lua != kNone) {
+ ADD(entry, BOOLEAN_OBJ(item->has_lua == kTrue));
+ }
+ ADD(rv, ARRAY_OBJ(entry));
+ }
+ return rv;
+}
+
+ArrayOf(String) runtime_get_named(bool lua, Array pat, bool all)
+{
+ int ref;
+ RuntimeSearchPath path = runtime_search_path_get_cached(&ref);
+ ArrayOf(String) rv = ARRAY_DICT_INIT;
+ static char buf[MAXPATHL];
+
+ for (size_t i = 0; i < kv_size(path); i++) {
+ SearchPathItem *item = &kv_A(path, i);
+ if (lua) {
+ if (item->has_lua == kNone) {
+ size_t size = (size_t)snprintf(buf, sizeof buf, "%s/lua/", item->path);
+ item->has_lua = (size < sizeof buf && os_isdir((char_u *)buf)) ? kTrue : kFalse;
+ }
+ if (item->has_lua == kFalse) {
+ continue;
+ }
+ }
+
+ for (size_t j = 0; j < pat.size; j++) {
+ Object pat_item = pat.items[j];
+ if (pat_item.type == kObjectTypeString) {
+ size_t size = (size_t)snprintf(buf, sizeof buf, "%s/%s",
+ item->path, pat_item.data.string.data);
+ if (size < sizeof buf) {
+ if (os_file_is_readable(buf)) {
+ ADD(rv, STRING_OBJ(cstr_to_string(buf)));
+ if (!all) {
+ goto done;
+ }
+ }
+ }
+ }
+ }
+ }
+
+done:
+ runtime_search_path_unref(path, &ref);
+ return rv;
+}
+
/// Find "name" in "path". When found, invoke the callback function for
/// it: callback(fname, "cookie")
/// When "flags" has DIP_ALL repeat for all matches, otherwise only the first
@@ -164,29 +348,22 @@ int do_in_path(char_u *path, char_u *name, int flags,
/// If "name" is NULL calls callback for each entry in "path". Cookie is
/// passed by reference in this case, setting it to NULL indicates that callback
/// has done its job.
-int do_in_path_and_pp(char_u *path, char_u *name, int flags,
- DoInRuntimepathCB callback, void *cookie)
+int do_in_path_and_pp(char_u *path, char_u *name, int flags, DoInRuntimepathCB callback,
+ void *cookie)
{
int done = FAIL;
- if (!(flags & (DIP_NOAFTER | DIP_AFTER))) {
- done = do_in_path_and_pp(path, name, flags | DIP_NOAFTER, callback, cookie);
- if (done == OK && !(flags & DIP_ALL)) {
- return done;
- }
- flags |= DIP_AFTER;
- }
if ((flags & DIP_NORTP) == 0) {
- done |= do_in_path(path, (name && !*name) ? NULL : name, flags, callback, cookie);
+ done |= do_in_path(path, (char *)((name && !*name) ? NULL : name), flags, callback, cookie);
}
if ((done == FAIL || (flags & DIP_ALL)) && (flags & DIP_START)) {
char *start_dir = "pack/*/start/*/%s%s"; // NOLINT
size_t len = STRLEN(start_dir) + STRLEN(name) + 6;
- char_u *s = xmallocz(len); // TODO(bfredl): get rid of random allocations
+ char *s = xmallocz(len); // TODO(bfredl): get rid of random allocations
char *suffix = (flags & DIP_AFTER) ? "after/" : "";
- vim_snprintf((char *)s, len, start_dir, suffix, name);
+ vim_snprintf(s, len, start_dir, suffix, name);
done |= do_in_path(p_pp, s, flags & ~DIP_AFTER, callback, cookie);
xfree(s);
@@ -196,7 +373,7 @@ int do_in_path_and_pp(char_u *path, char_u *name, int flags,
len = STRLEN(start_dir) + STRLEN(name) + 6;
s = xmallocz(len);
- vim_snprintf((char *)s, len, start_dir, suffix, name);
+ vim_snprintf(s, len, start_dir, suffix, name);
done |= do_in_path(p_pp, s, flags & ~DIP_AFTER, callback, cookie);
xfree(s);
@@ -206,9 +383,9 @@ int do_in_path_and_pp(char_u *path, char_u *name, int flags,
if ((done == FAIL || (flags & DIP_ALL)) && (flags & DIP_OPT)) {
char *opt_dir = "pack/*/opt/*/%s"; // NOLINT
size_t len = STRLEN(opt_dir) + STRLEN(name);
- char_u *s = xmallocz(len);
+ char *s = xmallocz(len);
- vim_snprintf((char *)s, len, opt_dir, name);
+ vim_snprintf(s, len, opt_dir, name);
done |= do_in_path(p_pp, s, flags, callback, cookie);
xfree(s);
@@ -218,7 +395,7 @@ int do_in_path_and_pp(char_u *path, char_u *name, int flags,
len = STRLEN(opt_dir) + STRLEN(name);
s = xmallocz(len);
- vim_snprintf((char *)s, len, opt_dir, name);
+ vim_snprintf(s, len, opt_dir, name);
done |= do_in_path(p_pp, s, flags, callback, cookie);
xfree(s);
@@ -228,10 +405,189 @@ int do_in_path_and_pp(char_u *path, char_u *name, int flags,
return done;
}
+static void push_path(RuntimeSearchPath *search_path, Map(String, handle_T) *rtp_used, char *entry,
+ bool after)
+{
+ handle_T h = map_get(String, handle_T)(rtp_used, cstr_as_string(entry));
+ if (h == 0) {
+ char *allocated = xstrdup(entry);
+ map_put(String, handle_T)(rtp_used, cstr_as_string(allocated), 1);
+ kv_push(*search_path, ((SearchPathItem){ allocated, after, kNone }));
+ }
+}
+
+static void expand_rtp_entry(RuntimeSearchPath *search_path, Map(String, handle_T) *rtp_used,
+ char *entry, bool after)
+{
+ if (map_get(String, handle_T)(rtp_used, cstr_as_string(entry))) {
+ return;
+ }
+
+ if (!*entry) {
+ push_path(search_path, rtp_used, entry, after);
+ }
+
+ int num_files;
+ char_u **files;
+ char_u *(pat[]) = { (char_u *)entry };
+ if (gen_expand_wildcards(1, pat, &num_files, &files, EW_DIR) == OK) {
+ for (int i = 0; i < num_files; i++) {
+ push_path(search_path, rtp_used, (char *)files[i], after);
+ }
+ FreeWild(num_files, files);
+ }
+}
+
+static void expand_pack_entry(RuntimeSearchPath *search_path, Map(String, handle_T) *rtp_used,
+ CharVec *after_path, char_u *pack_entry)
+{
+ static char buf[MAXPATHL];
+ char *(start_pat[]) = { "/pack/*/start/*", "/start/*" }; // NOLINT
+ for (int i = 0; i < 2; i++) {
+ if (STRLEN(pack_entry) + STRLEN(start_pat[i]) + 1 > MAXPATHL) {
+ continue;
+ }
+ STRLCPY(buf, pack_entry, MAXPATHL);
+ xstrlcat(buf, start_pat[i], sizeof buf);
+ expand_rtp_entry(search_path, rtp_used, buf, false);
+ size_t after_size = STRLEN(buf)+7;
+ char *after = xmallocz(after_size);
+ xstrlcpy(after, buf, after_size);
+ xstrlcat(after, "/after", after_size);
+ kv_push(*after_path, after);
+ }
+}
+
+static bool path_is_after(char_u *buf, size_t buflen)
+{
+ // NOTE: we only consider dirs exactly matching "after" to be an AFTER dir.
+ // vim8 considers all dirs like "foo/bar_after", "Xafter" etc, as an
+ // "after" dir in SOME codepaths not not in ALL codepaths.
+ return buflen >= 5
+ && (!(buflen >= 6) || vim_ispathsep(buf[buflen-6]))
+ && STRCMP(buf + buflen - 5, "after") == 0;
+}
+
+RuntimeSearchPath runtime_search_path_build(void)
+{
+ kvec_t(String) pack_entries = KV_INITIAL_VALUE;
+ // TODO(bfredl): these should just be sets, when Set(String) is do merge to
+ // master.
+ Map(String, handle_T) pack_used = MAP_INIT;
+ Map(String, handle_T) rtp_used = MAP_INIT;
+ RuntimeSearchPath search_path = KV_INITIAL_VALUE;
+ CharVec after_path = KV_INITIAL_VALUE;
+
+ static char_u buf[MAXPATHL];
+ for (char *entry = (char *)p_pp; *entry != NUL; ) {
+ char *cur_entry = entry;
+ copy_option_part((char_u **)&entry, buf, MAXPATHL, ",");
+
+ String the_entry = { .data = cur_entry, .size = STRLEN(buf) };
+
+ kv_push(pack_entries, the_entry);
+ map_put(String, handle_T)(&pack_used, the_entry, 0);
+ }
+
+
+ char *rtp_entry;
+ for (rtp_entry = (char *)p_rtp; *rtp_entry != NUL; ) {
+ char *cur_entry = rtp_entry;
+ copy_option_part((char_u **)&rtp_entry, buf, MAXPATHL, ",");
+ size_t buflen = STRLEN(buf);
+
+ if (path_is_after(buf, buflen)) {
+ rtp_entry = cur_entry;
+ break;
+ }
+
+ // fact: &rtp entries can contain wild chars
+ expand_rtp_entry(&search_path, &rtp_used, (char *)buf, false);
+
+ handle_T *h = map_ref(String, handle_T)(&pack_used, cstr_as_string((char *)buf), false);
+ if (h) {
+ (*h)++;
+ expand_pack_entry(&search_path, &rtp_used, &after_path, buf);
+ }
+ }
+
+ for (size_t i = 0; i < kv_size(pack_entries); i++) {
+ handle_T h = map_get(String, handle_T)(&pack_used, kv_A(pack_entries, i));
+ if (h == 0) {
+ expand_pack_entry(&search_path, &rtp_used, &after_path, (char_u *)kv_A(pack_entries, i).data);
+ }
+ }
+
+ // "after" packages
+ for (size_t i = 0; i < kv_size(after_path); i++) {
+ expand_rtp_entry(&search_path, &rtp_used, kv_A(after_path, i), true);
+ xfree(kv_A(after_path, i));
+ }
+
+ // "after" dirs in rtp
+ for (; *rtp_entry != NUL;) {
+ copy_option_part((char_u **)&rtp_entry, buf, MAXPATHL, ",");
+ expand_rtp_entry(&search_path, &rtp_used, (char *)buf, path_is_after(buf, STRLEN(buf)));
+ }
+
+ // strings are not owned
+ kv_destroy(pack_entries);
+ kv_destroy(after_path);
+ map_destroy(String, handle_T)(&pack_used);
+ map_destroy(String, handle_T)(&rtp_used);
+
+ return search_path;
+}
+
+void runtime_search_path_invalidate(void)
+{
+ runtime_search_path_valid = false;
+}
+
+void runtime_search_path_free(RuntimeSearchPath path)
+{
+ for (size_t j = 0; j < kv_size(path); j++) {
+ SearchPathItem item = kv_A(path, j);
+ xfree(item.path);
+ }
+ kv_destroy(path);
+}
+
+void runtime_search_path_validate(void)
+{
+ if (!nlua_is_deferred_safe()) {
+ // Cannot rebuild search path in an async context. As a plugin will invoke
+ // itself asynchronously from sync code in the same plugin, the sought
+ // after lua/autoload module will most likely already be in the cached path.
+ // Thus prefer using the stale cache over erroring out in this situation.
+ return;
+ }
+ if (!runtime_search_path_valid) {
+ if (!runtime_search_path_ref) {
+ runtime_search_path_free(runtime_search_path);
+ }
+ runtime_search_path = runtime_search_path_build();
+ runtime_search_path_valid = true;
+ runtime_search_path_ref = NULL; // initially unowned
+ }
+}
+
+
+
/// Just like do_in_path_and_pp(), using 'runtimepath' for "path".
int do_in_runtimepath(char_u *name, int flags, DoInRuntimepathCB callback, void *cookie)
{
- return do_in_path_and_pp(p_rtp, name, flags | DIP_START, callback, cookie);
+ int success = FAIL;
+ if (!(flags & DIP_NORTP)) {
+ success |= do_in_cached_path((name && !*name) ? NULL : name, flags, callback, cookie);
+ flags = (flags & ~DIP_START) | DIP_NORTP;
+ }
+ // TODO(bfredl): we could integrate disabled OPT dirs into the cached path
+ // which would effectivize ":packadd myoptpack" as well
+ if ((flags & (DIP_START|DIP_OPT)) && (success == FAIL || (flags & DIP_ALL))) {
+ success |= do_in_path_and_pp(p_rtp, name, flags, callback, cookie);
+ }
+ return success;
}
/// Source the file "name" from all directories in 'runtimepath'.
@@ -239,10 +595,9 @@ int do_in_runtimepath(char_u *name, int flags, DoInRuntimepathCB callback, void
/// When "flags" has DIP_ALL: source all files, otherwise only the first one.
///
/// return FAIL when no file could be sourced, OK otherwise.
-int source_runtime(char_u *name, int flags)
+int source_runtime(char *name, int flags)
{
- flags |= (flags & DIP_NORTP) ? 0 : DIP_START;
- return source_in_path(p_rtp, name, flags);
+ return do_in_runtimepath((char_u *)name, flags, source_callback, NULL);
}
/// Just like source_runtime(), but use "path" instead of 'runtimepath'.
@@ -260,14 +615,17 @@ static void source_all_matches(char_u *pat)
if (gen_expand_wildcards(1, &pat, &num_files, &files, EW_FILE) == OK) {
for (int i = 0; i < num_files; i++) {
- (void)do_source(files[i], false, DOSO_NONE);
+ (void)do_source((char *)files[i], false, DOSO_NONE);
}
FreeWild(num_files, files);
}
}
/// Add the package directory to 'runtimepath'
-static int add_pack_dir_to_rtp(char_u *fname)
+///
+/// @param fname the package path
+/// @param is_pack whether the added dir is a "pack/*/start/*/" style package
+static int add_pack_dir_to_rtp(char_u *fname, bool is_pack)
{
char_u *p4, *p3, *p2, *p1, *p;
char_u *buf = NULL;
@@ -345,7 +703,7 @@ static int add_pack_dir_to_rtp(char_u *fname)
// check if rtp/pack/name/start/name/after exists
afterdir = concat_fnames((char *)fname, "after", true);
size_t afterlen = 0;
- if (os_isdir((char_u *)afterdir)) {
+ if (is_pack ? pack_has_entries((char_u *)afterdir) : os_isdir((char_u *)afterdir)) {
afterlen = strlen(afterdir) + 1; // add one for comma
}
@@ -466,7 +824,7 @@ static void add_pack_plugin(bool opt, char_u *fname, void *cookie)
xfree(buf);
if (!found) {
// directory is not yet in 'runtimepath', add it
- if (add_pack_dir_to_rtp(fname) == FAIL) {
+ if (add_pack_dir_to_rtp(fname, false) == FAIL) {
return;
}
}
@@ -487,13 +845,48 @@ static void add_opt_pack_plugin(char_u *fname, void *cookie)
add_pack_plugin(true, fname, cookie);
}
+
+/// Add all packages in the "start" directory to 'runtimepath'.
+void add_pack_start_dirs(void)
+{
+ do_in_path(p_pp, NULL, DIP_ALL + DIP_DIR, add_pack_start_dir, NULL);
+}
+
+static bool pack_has_entries(char_u *buf)
+{
+ int num_files;
+ char_u **files;
+ char_u *(pat[]) = { buf };
+ if (gen_expand_wildcards(1, pat, &num_files, &files, EW_DIR) == OK) {
+ FreeWild(num_files, files);
+ }
+ return num_files > 0;
+}
+
+static void add_pack_start_dir(char_u *fname, void *cookie)
+{
+ static char_u buf[MAXPATHL];
+ char *(start_pat[]) = { "/start/*", "/pack/*/start/*" }; // NOLINT
+ for (int i = 0; i < 2; i++) {
+ if (STRLEN(fname) + STRLEN(start_pat[i]) + 1 > MAXPATHL) {
+ continue;
+ }
+ STRLCPY(buf, fname, MAXPATHL);
+ xstrlcat((char *)buf, start_pat[i], sizeof buf);
+ if (pack_has_entries(buf)) {
+ add_pack_dir_to_rtp(buf, true);
+ }
+ }
+}
+
+
/// Load plugins from all packages in the "start" directory.
void load_start_packages(void)
{
did_source_packages = true;
- do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT
+ do_in_path(p_pp, "pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT
add_start_pack_plugin, &APP_LOAD);
- do_in_path(p_pp, (char_u *)"start/*", DIP_ALL + DIP_DIR, // NOLINT
+ do_in_path(p_pp, "start/*", DIP_ALL + DIP_DIR, // NOLINT
add_start_pack_plugin, &APP_LOAD);
}
@@ -505,10 +898,43 @@ void ex_packloadall(exarg_T *eap)
// First do a round to add all directories to 'runtimepath', then load
// the plugins. This allows for plugins to use an autoload directory
// of another plugin.
+ add_pack_start_dirs();
load_start_packages();
}
}
+/// Read all the plugin files at startup
+void load_plugins(void)
+{
+ if (p_lpl) {
+ char_u *rtp_copy = p_rtp;
+ char_u *const plugin_pattern_vim = (char_u *)"plugin/**/*.vim"; // NOLINT
+ char_u *const plugin_pattern_lua = (char_u *)"plugin/**/*.lua"; // NOLINT
+
+ if (!did_source_packages) {
+ rtp_copy = vim_strsave(p_rtp);
+ add_pack_start_dirs();
+ }
+
+ // don't use source_runtime() yet so we can check for :packloadall below
+ source_in_path(rtp_copy, plugin_pattern_vim, DIP_ALL | DIP_NOAFTER);
+ source_in_path(rtp_copy, plugin_pattern_lua, DIP_ALL | DIP_NOAFTER);
+ TIME_MSG("loading rtp plugins");
+
+ // Only source "start" packages if not done already with a :packloadall
+ // command.
+ if (!did_source_packages) {
+ xfree(rtp_copy);
+ load_start_packages();
+ }
+ TIME_MSG("loading packages");
+
+ source_runtime((char *)plugin_pattern_vim, DIP_ALL | DIP_AFTER);
+ source_runtime((char *)plugin_pattern_lua, DIP_ALL | DIP_AFTER);
+ TIME_MSG("loading after plugins");
+ }
+}
+
/// ":packadd[!] {name}"
void ex_packadd(exarg_T *eap)
{
@@ -527,9 +953,7 @@ void ex_packadd(exarg_T *eap)
vim_snprintf(pat, len, plugpat, round == 1 ? "start" : "opt", eap->arg);
// The first round don't give a "not found" error, in the second round
// only when nothing was found in the first round.
- res = do_in_path(p_pp, (char_u *)pat,
- DIP_ALL + DIP_DIR
- + (round == 2 && res == FAIL ? DIP_ERR : 0),
+ res = do_in_path(p_pp, pat, DIP_ALL + DIP_DIR + (round == 2 && res == FAIL ? DIP_ERR : 0),
round == 1 ? add_start_pack_plugin : add_opt_pack_plugin,
eap->forceit ? &APP_ADD_DIR : &APP_BOTH);
xfree(pat);
@@ -564,8 +988,7 @@ static char *strcpy_comma_escaped(char *dest, const char *src, const size_t len)
/// (common_suf is present after each new item, single_suf is present
/// after half of the new items) and with commas after each item, commas
/// inside the values are escaped.
-static inline size_t compute_double_env_sep_len(const char *const val,
- const size_t common_suf_len,
+static inline size_t compute_double_env_sep_len(const char *const val, const size_t common_suf_len,
const size_t single_suf_len)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
{
@@ -608,9 +1031,8 @@ static inline size_t compute_double_env_sep_len(const char *const val,
/// Otherwise in reverse.
///
/// @return (dest + appended_characters_length)
-static inline char *add_env_sep_dirs(char *dest, const char *const val,
- const char *const suf1, const size_t len1,
- const char *const suf2, const size_t len2,
+static inline char *add_env_sep_dirs(char *dest, const char *const val, const char *const suf1,
+ const size_t len1, const char *const suf2, const size_t len2,
const bool forward)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ARG(1)
{
@@ -669,9 +1091,8 @@ static inline char *add_env_sep_dirs(char *dest, const char *const val,
/// Otherwise in reverse.
///
/// @return (dest + appended_characters_length)
-static inline char *add_dir(char *dest, const char *const dir,
- const size_t dir_len, const XDGVarType type,
- const char *const suf1, const size_t len1,
+static inline char *add_dir(char *dest, const char *const dir, const size_t dir_len,
+ const XDGVarType type, const char *const suf1, const size_t len1,
const char *const suf2, const size_t len2)
FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT
{
diff --git a/src/nvim/runtime.h b/src/nvim/runtime.h
index b40c2b670e..4337a0b3cd 100644
--- a/src/nvim/runtime.h
+++ b/src/nvim/runtime.h
@@ -7,10 +7,31 @@
typedef void (*DoInRuntimepathCB)(char_u *, void *);
+typedef struct {
+ char *path;
+ bool after;
+ TriState has_lua;
+} SearchPathItem;
+
+typedef kvec_t(SearchPathItem) RuntimeSearchPath;
+typedef kvec_t(char *) CharVec;
+
// last argument for do_source()
#define DOSO_NONE 0
#define DOSO_VIMRC 1 // loading vimrc file
+// Used for flags in do_in_path()
+#define DIP_ALL 0x01 // all matches, not just the first one
+#define DIP_DIR 0x02 // find directories instead of files
+#define DIP_ERR 0x04 // give an error message when none found
+#define DIP_START 0x08 // also use "start" directory in 'packpath'
+#define DIP_OPT 0x10 // also use "opt" directory in 'packpath'
+#define DIP_NORTP 0x20 // do not use 'runtimepath'
+#define DIP_NOAFTER 0x40 // skip "after" directories
+#define DIP_AFTER 0x80 // only use "after" directories
+#define DIP_LUA 0x100 // also use ".lua" files
+#define DIP_DIRFILE 0x200 // find both files and directories
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "runtime.h.generated.h"
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 79e960fe8b..32eb28e761 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -166,7 +166,7 @@ static bool resizing = false;
#endif
#define SEARCH_HL_PRIORITY 0
-static char * provider_err = NULL;
+static char *provider_err = NULL;
static bool provider_invoke(NS ns_id, const char *name, LuaRef ref, Array args, bool default_true)
{
@@ -1003,8 +1003,7 @@ static void win_update(win_T *wp, Providers *providers)
i = plines_m_win(wp, wp->w_topline, wp->w_lines[0].wl_lnum - 1);
// insert extra lines for previously invisible filler lines
if (wp->w_lines[0].wl_lnum != wp->w_topline) {
- i += diff_check_fill(wp, wp->w_lines[0].wl_lnum)
- - wp->w_old_topfill;
+ i += win_get_fill(wp, wp->w_lines[0].wl_lnum) - wp->w_old_topfill;
}
if (i != 0 && i < wp->w_grid.Rows - 2) { // less than a screen off
// Try to insert the correct number of lines.
@@ -1067,7 +1066,7 @@ static void win_update(win_T *wp, Providers *providers)
if (wp->w_lines[0].wl_lnum == wp->w_topline) {
row += wp->w_old_topfill;
} else {
- row += diff_check_fill(wp, wp->w_topline);
+ row += win_get_fill(wp, wp->w_topline);
}
// ... but don't delete new filler lines.
row -= wp->w_topfill;
@@ -1101,12 +1100,12 @@ static void win_update(win_T *wp, Providers *providers)
break;
}
}
- /* Correct the first entry for filler lines at the top
- * when it won't get updated below. */
- if (wp->w_p_diff && bot_start > 0) {
- wp->w_lines[0].wl_size =
- plines_win_nofill(wp, wp->w_topline, true)
- + wp->w_topfill;
+
+ // Correct the first entry for filler lines at the top
+ // when it won't get updated below.
+ if (win_may_fill(wp) && bot_start > 0) {
+ wp->w_lines[0].wl_size = (plines_win_nofill(wp, wp->w_topline, true)
+ + wp->w_topfill);
}
}
}
@@ -1564,7 +1563,7 @@ static void win_update(win_T *wp, Providers *providers)
&& lnum > wp->w_topline
&& !(dy_flags & (DY_LASTLINE | DY_TRUNCATE))
&& srow + wp->w_lines[idx].wl_size > wp->w_grid.Rows
- && diff_check_fill(wp, lnum) == 0) {
+ && win_get_fill(wp, lnum) == 0) {
// This line is not going to fit. Don't draw anything here,
// will draw "@ " lines below.
row = wp->w_grid.Rows + 1;
@@ -1664,7 +1663,7 @@ static void win_update(win_T *wp, Providers *providers)
* Don't overwrite it, it can be edited.
*/
wp->w_botline = lnum + 1;
- } else if (diff_check_fill(wp, lnum) >= wp->w_grid.Rows - srow) {
+ } else if (win_get_fill(wp, lnum) >= wp->w_grid.Rows - srow) {
// Window ends in filler lines.
wp->w_botline = lnum;
wp->w_filler_rows = wp->w_grid.Rows - srow;
@@ -1691,7 +1690,7 @@ static void win_update(win_T *wp, Providers *providers)
} else {
if (eof) { // we hit the end of the file
wp->w_botline = buf->b_ml.ml_line_count + 1;
- j = diff_check_fill(wp, wp->w_botline);
+ j = win_get_fill(wp, wp->w_botline);
if (j > 0 && !wp->w_botfill) {
// Display filler text below last line. win_line() will check
// for ml_line_count+1 and only draw filler lines
@@ -1866,7 +1865,7 @@ static int compute_foldcolumn(win_T *wp, int col)
/// Put a single char from an UTF-8 buffer into a line buffer.
///
/// Handles composing chars and arabic shaping state.
-static int line_putchar(LineState *s, schar_T *dest, int maxcells, bool rl)
+static int line_putchar(buf_T *buf, LineState *s, schar_T *dest, int maxcells, bool rl, int vcol)
{
const char_u *p = (char_u *)s->p;
int cells = utf_ptr2cells(p);
@@ -1876,7 +1875,13 @@ static int line_putchar(LineState *s, schar_T *dest, int maxcells, bool rl)
return -1;
}
u8c = utfc_ptr2char(p, u8cc);
- if (*p < 0x80 && u8cc[0] == 0) {
+ if (*p == TAB) {
+ cells = MIN(tabstop_padding(vcol, buf->b_p_ts, buf->b_p_vts_array), maxcells);
+ for (int c = 0; c < cells; c++) {
+ schar_from_ascii(dest[c], ' ');
+ }
+ goto done;
+ } else if (*p < 0x80 && u8cc[0] == 0) {
schar_from_ascii(dest[0], *p);
s->prev_c = u8c;
} else {
@@ -1909,6 +1914,7 @@ static int line_putchar(LineState *s, schar_T *dest, int maxcells, bool rl)
if (cells > 1) {
dest[1][0] = 0;
}
+done:
s->p += c_len;
return cells;
}
@@ -2055,7 +2061,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
bool draw_color_col = false; // highlight colorcolumn
int *color_cols = NULL; // pointer to according columns array
bool has_spell = false; // this buffer has spell checking
-# define SPWORDLEN 150
+#define SPWORDLEN 150
char_u nextline[SPWORDLEN * 2]; // text with start of the next line
int nextlinecol = 0; // column where nextline[] starts
int nextline_idx = 0; /* index in nextline[] where next line
@@ -2118,12 +2124,12 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
// draw_state: items that are drawn in sequence:
#define WL_START 0 // nothing done yet
-# define WL_CMDLINE WL_START + 1 // cmdline window column
-# define WL_FOLD WL_CMDLINE + 1 // 'foldcolumn'
-# define WL_SIGN WL_FOLD + 1 // column for signs
+#define WL_CMDLINE WL_START + 1 // cmdline window column
+#define WL_FOLD WL_CMDLINE + 1 // 'foldcolumn'
+#define WL_SIGN WL_FOLD + 1 // column for signs
#define WL_NR WL_SIGN + 1 // line number
-# define WL_BRI WL_NR + 1 // 'breakindent'
-# define WL_SBR WL_BRI + 1 // 'showbreak' or 'diff'
+#define WL_BRI WL_NR + 1 // 'breakindent'
+#define WL_SBR WL_BRI + 1 // 'showbreak' or 'diff'
#define WL_LINE WL_SBR + 1 // text in the line
int draw_state = WL_START; // what to draw next
@@ -2138,8 +2144,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
int did_wcol = false;
int match_conc = 0; ///< cchar for match functions
int old_boguscols = 0;
-# define VCOL_HLC (vcol - vcol_off)
-# define FIX_FOR_BOGUSCOLS \
+#define VCOL_HLC (vcol - vcol_off)
+#define FIX_FOR_BOGUSCOLS \
{ \
n_extra += vcol_off; \
vcol -= vcol_off; \
@@ -2202,7 +2208,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
if (provider_err) {
Decoration err_decor = DECORATION_INIT;
- int hl_err = syn_check_group((char_u *)S_LEN("ErrorMsg"));
+ int hl_err = syn_check_group(S_LEN("ErrorMsg"));
kv_push(err_decor.virt_text,
((VirtTextChunk){ .text = provider_err,
.hl_id = hl_err }));
@@ -2366,8 +2372,11 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
filler_lines = 0;
area_highlighting = true;
}
+ int virtual_lines = decor_virtual_lines(wp, lnum);
+ filler_lines += virtual_lines;
if (lnum == wp->w_topline) {
filler_lines = wp->w_topfill;
+ virtual_lines = MIN(virtual_lines, filler_lines);
}
filler_todo = filler_lines;
@@ -2409,7 +2418,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
// If this line has a sign with line highlighting set line_attr.
// TODO(bfredl, vigoux): this should not take priority over decoration!
- sign_attrs_T * sattr = sign_get_attr(SIGN_LINEHL, sattrs, 0, 1);
+ sign_attrs_T *sattr = sign_get_attr(SIGN_LINEHL, sattrs, 0, 1);
if (sattr != NULL) {
line_attr = sattr->sat_linehl;
}
@@ -2895,7 +2904,18 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
if (draw_state == WL_SBR - 1 && n_extra == 0) {
draw_state = WL_SBR;
- if (filler_todo > 0) {
+ if (filler_todo > filler_lines - virtual_lines) {
+ // TODO(bfredl): check this doesn't inhibit TUI-style
+ // clear-to-end-of-line.
+ c_extra = ' ';
+ c_final = NUL;
+ if (wp->w_p_rl) {
+ n_extra = col + 1;
+ } else {
+ n_extra = grid->Columns - col;
+ }
+ char_attr = 0;
+ } else if (filler_todo > 0) {
// draw "deleted" diff line(s)
if (char2cells(wp->w_p_fcs_chars.diff) > 1) {
c_extra = '-';
@@ -3667,8 +3687,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
n_extra = tab_len;
} else {
char_u *p;
- int i;
- int saved_nextra = n_extra;
+ int i;
+ int saved_nextra = n_extra;
if (vcol_off > 0) {
// there are characters to conceal
@@ -4402,7 +4422,19 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
&& !wp->w_p_rl; // Not right-to-left.
int draw_col = col - boguscols;
- draw_virt_text(buf, win_col_offset, &draw_col, grid->Columns);
+ if (filler_todo > 0) {
+ int index = filler_todo - (filler_lines - virtual_lines);
+ if (index > 0) {
+ int fpos = kv_size(buf->b_virt_lines) - index;
+ assert(fpos >= 0);
+ int offset = buf->b_virt_line_leftcol ? 0 : win_col_offset;
+ draw_virt_text_item(buf, offset, kv_A(buf->b_virt_lines, fpos),
+ kHlModeReplace, grid->Columns, offset);
+ }
+ } else {
+ draw_virt_text(buf, win_col_offset, &draw_col, grid->Columns);
+ }
+
grid_put_linebuf(grid, row, 0, draw_col, grid->Columns, wp->w_p_rl,
wp, wp->w_hl_attr_normal, wrap);
if (wrap) {
@@ -4485,67 +4517,80 @@ void draw_virt_text(buf_T *buf, int col_off, int *end_col, int max_col)
bool do_eol = state->eol_col > -1;
for (size_t i = 0; i < kv_size(state->active); i++) {
DecorRange *item = &kv_A(state->active, i);
- if (item->start_row == state->row && kv_size(item->decor.virt_text)) {
- if (item->win_col == -1) {
- if (item->decor.virt_text_pos == kVTRightAlign) {
- right_pos -= item->decor.virt_text_width;
- item->win_col = right_pos;
- } else if (item->decor.virt_text_pos == kVTEndOfLine && do_eol) {
- item->win_col = state->eol_col;
- state->eol_col += item->decor.virt_text_width;
- } else if (item->decor.virt_text_pos == kVTWinCol) {
- item->win_col = MAX(item->decor.col+col_off, 0);
- }
- }
- if (item->win_col < 0) {
- continue;
- }
- VirtText vt = item->decor.virt_text;
- HlMode hl_mode = item->decor.hl_mode;
- LineState s = LINE_STATE("");
- int virt_attr = 0;
- int col = item->win_col;
- size_t virt_pos = 0;
- item->win_col = -2; // deactivate
-
- while (col < max_col) {
- if (!*s.p) {
- if (virt_pos >= kv_size(vt)) {
- break;
- }
- virt_attr = 0;
- do {
- s.p = kv_A(vt, virt_pos).text;
- int hl_id = kv_A(vt, virt_pos).hl_id;
- virt_attr = hl_combine_attr(virt_attr,
- hl_id > 0 ? syn_id2attr(hl_id) : 0);
- virt_pos++;
- } while (!s.p && virt_pos < kv_size(vt));
- if (!s.p) {
- break;
- }
- }
- int attr;
- bool through = false;
- if (hl_mode == kHlModeCombine) {
- attr = hl_combine_attr(linebuf_attr[col], virt_attr);
- } else if (hl_mode == kHlModeBlend) {
- through = (*s.p == ' ');
- attr = hl_blend_attrs(linebuf_attr[col], virt_attr, &through);
- } else {
- attr = virt_attr;
- }
- schar_T dummy[2];
- int cells = line_putchar(&s, through ? dummy : &linebuf_char[col],
- max_col-col, false);
- linebuf_attr[col++] = attr;
- if (cells > 1) {
- linebuf_attr[col++] = attr;
- }
+ if (!(item->start_row == state->row && kv_size(item->decor.virt_text))) {
+ continue;
+ }
+ if (item->win_col == -1) {
+ if (item->decor.virt_text_pos == kVTRightAlign) {
+ right_pos -= item->decor.virt_text_width;
+ item->win_col = right_pos;
+ } else if (item->decor.virt_text_pos == kVTEndOfLine && do_eol) {
+ item->win_col = state->eol_col;
+ } else if (item->decor.virt_text_pos == kVTWinCol) {
+ item->win_col = MAX(item->decor.col+col_off, 0);
+ }
+ }
+ if (item->win_col < 0) {
+ continue;
+ }
+
+ int col = draw_virt_text_item(buf, item->win_col, item->decor.virt_text,
+ item->decor.hl_mode, max_col, item->win_col-col_off);
+ item->win_col = -2; // deactivate
+ if (item->decor.virt_text_pos == kVTEndOfLine && do_eol) {
+ state->eol_col = col+1;
+ }
+
+ *end_col = MAX(*end_col, col);
+ }
+}
+
+static int draw_virt_text_item(buf_T *buf, int col, VirtText vt, HlMode hl_mode, int max_col,
+ int vcol)
+{
+ LineState s = LINE_STATE("");
+ int virt_attr = 0;
+ size_t virt_pos = 0;
+
+ while (col < max_col) {
+ if (!*s.p) {
+ if (virt_pos >= kv_size(vt)) {
+ break;
+ }
+ virt_attr = 0;
+ do {
+ s.p = kv_A(vt, virt_pos).text;
+ int hl_id = kv_A(vt, virt_pos).hl_id;
+ virt_attr = hl_combine_attr(virt_attr,
+ hl_id > 0 ? syn_id2attr(hl_id) : 0);
+ virt_pos++;
+ } while (!s.p && virt_pos < kv_size(vt));
+ if (!s.p) {
+ break;
}
- *end_col = MAX(*end_col, col);
}
+ int attr;
+ bool through = false;
+ if (hl_mode == kHlModeCombine) {
+ attr = hl_combine_attr(linebuf_attr[col], virt_attr);
+ } else if (hl_mode == kHlModeBlend) {
+ through = (*s.p == ' ');
+ attr = hl_blend_attrs(linebuf_attr[col], virt_attr, &through);
+ } else {
+ attr = virt_attr;
+ }
+ schar_T dummy[2];
+ int cells = line_putchar(buf, &s, through ? dummy : &linebuf_char[col],
+ max_col-col, false, vcol);
+ // if we failed to emit a char, we still need to advance
+ cells = MAX(cells, 1);
+
+ for (int c = 0; c < cells; c++) {
+ linebuf_attr[col++] = attr;
+ }
+ vcol += cells;
}
+ return col;
}
/// Determine if dedicated window grid should be used or the default_grid
@@ -5119,8 +5164,8 @@ void win_redr_status_matches(expand_T *xp, int num_matches, char_u **matches, in
if (row >= 0) {
if (wild_menu_showing == 0 || wild_menu_showing == WM_LIST) {
if (msg_scrolled > 0) {
- /* Put the wildmenu just above the command line. If there is
- * no room, scroll the screen one line up. */
+ // Put the wildmenu just above the command line. If there is
+ // no room, scroll the screen one line up.
if (cmdline_row == Rows - 1) {
msg_scroll_up(false);
msg_scrolled++;
@@ -5420,7 +5465,7 @@ static void win_redr_custom(win_T *wp, bool draw_ruler)
fillchar = ' ';
attr = HL_ATTR(HLF_TPF);
maxwidth = Columns;
- use_sandbox = was_set_insecurely(wp, (char_u *)"tabline", 0);
+ use_sandbox = was_set_insecurely(wp, "tabline", 0);
} else {
row = W_ENDROW(wp);
fillchar = fillchar_status(&attr, wp);
@@ -5455,15 +5500,14 @@ static void win_redr_custom(win_T *wp, bool draw_ruler)
attr = HL_ATTR(HLF_MSG);
}
- use_sandbox = was_set_insecurely(wp, (char_u *)"rulerformat", 0);
+ use_sandbox = was_set_insecurely(wp, "rulerformat", 0);
} else {
if (*wp->w_p_stl != NUL) {
stl = wp->w_p_stl;
} else {
stl = p_stl;
}
- use_sandbox = was_set_insecurely(wp, (char_u *)"statusline",
- *wp->w_p_stl == NUL ? 0 : OPT_LOCAL);
+ use_sandbox = was_set_insecurely(wp, "statusline", *wp->w_p_stl == NUL ? 0 : OPT_LOCAL);
}
col += wp->w_wincol;
@@ -5489,7 +5533,7 @@ static void win_redr_custom(win_T *wp, bool draw_ruler)
ewp->w_p_crb = p_crb_save;
// Make all characters printable.
- p = (char_u *)transstr((const char *)buf);
+ p = (char_u *)transstr((const char *)buf, true);
len = STRLCPY(buf, p, sizeof(buf));
len = (size_t)len < sizeof(buf) ? len : (int)sizeof(buf) - 1;
xfree(p);
@@ -6987,8 +7031,8 @@ int showmode(void)
if (VIsual_active) {
char *p;
- /* Don't concatenate separate words to avoid translation
- * problems. */
+ // Don't concatenate separate words to avoid translation
+ // problems.
switch ((VIsual_select ? 4 : 0)
+ (VIsual_mode == Ctrl_V) * 2
+ (VIsual_mode == 'V')) {
@@ -7335,7 +7379,7 @@ void get_trans_bufname(buf_T *buf)
/*
* Get the character to use in a status line. Get its attributes in "*attr".
*/
-static int fillchar_status(int *attr, win_T *wp)
+int fillchar_status(int *attr, win_T *wp)
{
int fill;
bool is_curwin = (wp == curwin);
diff --git a/src/nvim/screen.h b/src/nvim/screen.h
index 5f339b9ae2..d704a6eb8a 100644
--- a/src/nvim/screen.h
+++ b/src/nvim/screen.h
@@ -3,10 +3,10 @@
#include <stdbool.h>
-#include "nvim/types.h"
#include "nvim/buffer_defs.h"
#include "nvim/grid_defs.h"
#include "nvim/pos.h"
+#include "nvim/types.h"
/*
* flags for update_screen()
@@ -14,12 +14,12 @@
*/
#define VALID 10 /* buffer not changed, or changes marked
with b_mod_* */
-#define INVERTED 20 /* redisplay inverted part that changed */
-#define INVERTED_ALL 25 /* redisplay whole inverted part */
-#define REDRAW_TOP 30 /* display first w_upd_rows screen lines */
-#define SOME_VALID 35 /* like NOT_VALID but may scroll */
-#define NOT_VALID 40 /* buffer needs complete redraw */
-#define CLEAR 50 /* screen messed up, clear it */
+#define INVERTED 20 // redisplay inverted part that changed
+#define INVERTED_ALL 25 // redisplay whole inverted part
+#define REDRAW_TOP 30 // display first w_upd_rows screen lines
+#define SOME_VALID 35 // like NOT_VALID but may scroll
+#define NOT_VALID 40 // buffer needs complete redraw
+#define CLEAR 50 // screen messed up, clear it
/// By default, all widows are draw on a single rectangular grid, represented by
/// this ScreenGrid instance. In multigrid mode each window will have its own
diff --git a/src/nvim/search.c b/src/nvim/search.c
index 4be2402f1d..1b54d12042 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -839,14 +839,14 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
}
}
- /* With the SEARCH_END option move to the last character
- * of the match. Don't do it for an empty match, end
- * should be same as start then. */
+ // With the SEARCH_END option move to the last character
+ // of the match. Don't do it for an empty match, end
+ // should be same as start then.
if ((options & SEARCH_END) && !(options & SEARCH_NOOF)
&& !(matchpos.lnum == endpos.lnum
&& matchpos.col == endpos.col)) {
- /* For a match in the first column, set the position
- * on the NUL in the previous line. */
+ // For a match in the first column, set the position
+ // on the NUL in the previous line.
pos->lnum = lnum + endpos.lnum;
pos->col = endpos.col;
if (endpos.col == 0) {
@@ -1046,8 +1046,8 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
char_u *strcopy = NULL;
char_u *ps;
char_u *msgbuf = NULL;
- size_t len;
- bool has_offset = false;
+ size_t len;
+ bool has_offset = false;
/*
* A line offset is not remembered, this is vi compatible.
@@ -1182,8 +1182,8 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
if ((options & SEARCH_ECHO) && messaging() && !msg_silent
&& (!cmd_silent || !shortmess(SHM_SEARCHCOUNT))) {
char_u *trunc;
- char_u off_buf[40];
- size_t off_len = 0;
+ char_u off_buf[40];
+ size_t off_len = 0;
// Compute msg_row early.
msg_start();
@@ -1498,8 +1498,8 @@ int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char_u *pat)
p = skipwhite(ptr);
pos->col = (colnr_T)(p - ptr);
- /* when adding lines the matching line may be empty but it is not
- * ignored because we are interested in the next line -- Acevedo */
+ // when adding lines the matching line may be empty but it is not
+ // ignored because we are interested in the next line -- Acevedo
if ((compl_cont_status & CONT_ADDING)
&& !(compl_cont_status & CONT_SOL)) {
if (mb_strcmp_ic((bool)p_ic, (const char *)p, (const char *)pat) == 0) {
@@ -1566,9 +1566,9 @@ int searchc(cmdarg_T *cap, int t_cmd)
c = *lastc;
// For multi-byte re-use last lastc_bytes[] and lastc_bytelen.
- /* Force a move of at least one char, so ";" and "," will move the
- * cursor, even if the cursor is right in front of char we are looking
- * at. */
+ // Force a move of at least one char, so ";" and "," will move the
+ // cursor, even if the cursor is right in front of char we are looking
+ // at.
if (vim_strchr(p_cpo, CPO_SCOLON) == NULL && count == 1 && t_cmd) {
stop = false;
}
@@ -2084,10 +2084,10 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
if (linep[pos.col - 1] == 'R'
&& linep[pos.col] == '"'
&& vim_strchr(linep + pos.col + 1, '(') != NULL) {
- /* Possible start of raw string. Now that we have the
- * delimiter we can check if it ends before where we
- * started searching, or before the previously found
- * raw string start. */
+ // Possible start of raw string. Now that we have the
+ // delimiter we can check if it ends before where we
+ // started searching, or before the previously found
+ // raw string start.
if (!find_rawstring_end(linep, &pos,
count > 0 ? &match_pos : &curwin->w_cursor)) {
count++;
@@ -2208,8 +2208,8 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
break;
case '"':
- /* a quote that is preceded with an odd number of backslashes is
- * ignored */
+ // a quote that is preceded with an odd number of backslashes is
+ // ignored
if (do_quotes) {
int col;
@@ -2282,8 +2282,8 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
bslcnt++;
}
}
- /* Only accept a match when 'M' is in 'cpo' or when escaping
- * is what we expect. */
+ // Only accept a match when 'M' is in 'cpo' or when escaping
+ // is what we expect.
if (cpo_bsl || (bslcnt & 1) == match_escaped) {
if (c == initc) {
count++;
@@ -2459,7 +2459,7 @@ int findsent(Direction dir, long count)
{
pos_T pos, tpos;
int c;
- int (*func)(pos_T *);
+ int (*func)(pos_T *);
bool noskip = false; // do not skip blanks
pos = curwin->w_cursor;
@@ -3505,8 +3505,8 @@ int current_block(oparg_T *oap, long count, int include, int what, int other)
// Include the character under the cursor.
oap->inclusive = true;
} else {
- /* End is before the start (no text in between <>, [], etc.): don't
- * operate on any text. */
+ // End is before the start (no text in between <>, [], etc.): don't
+ // operate on any text.
curwin->w_cursor = start_pos;
}
}
@@ -4044,8 +4044,8 @@ bool current_quote(oparg_T *oap, long count, bool include, int quotechar)
}
if (!vis_empty) {
- /* Check if the existing selection exactly spans the text inside
- * quotes. */
+ // Check if the existing selection exactly spans the text inside
+ // quotes.
if (vis_bef_curs) {
inside_quotes = VIsual.col > 0
&& line[VIsual.col - 1] == quotechar
@@ -4072,11 +4072,11 @@ bool current_quote(oparg_T *oap, long count, bool include, int quotechar)
}
if (!vis_empty && line[col_start] == quotechar) {
- /* Already selecting something and on a quote character. Find the
- * next quoted string. */
+ // Already selecting something and on a quote character. Find the
+ // next quoted string.
if (vis_bef_curs) {
- /* Assume we are on a closing quote: move to after the next
- * opening quote. */
+ // Assume we are on a closing quote: move to after the next
+ // opening quote.
col_start = find_next_quote(line, col_start + 1, quotechar, NULL);
if (col_start < 0) {
goto abort_search;
@@ -4474,7 +4474,7 @@ static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool sh
update_search_stat(dirc, pos, cursor_pos, &stat, recompute, maxcount,
timeout);
if (stat.cur > 0) {
- char t[SEARCH_STAT_BUF_LEN];
+ char t[SEARCH_STAT_BUF_LEN];
if (curwin->w_p_rl && *curwin->w_p_rlc == 's') {
if (stat.incomplete == 1) {
@@ -4534,19 +4534,19 @@ static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool sh
static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchstat_T *stat,
bool recompute, int maxcount, long timeout)
{
- int save_ws = p_ws;
- bool wraparound = false;
- pos_T p = (*pos);
- static pos_T lastpos = { 0, 0, 0 };
- static int cur = 0;
- static int cnt = 0;
- static bool exact_match = false;
- static int incomplete = 0;
- static int last_maxcount = SEARCH_STAT_DEF_MAX_COUNT;
- static int chgtick = 0;
+ int save_ws = p_ws;
+ bool wraparound = false;
+ pos_T p = (*pos);
+ static pos_T lastpos = { 0, 0, 0 };
+ static int cur = 0;
+ static int cnt = 0;
+ static bool exact_match = false;
+ static int incomplete = 0;
+ static int last_maxcount = SEARCH_STAT_DEF_MAX_COUNT;
+ static int chgtick = 0;
static char_u *lastpat = NULL;
static buf_T *lbuf = NULL;
- proftime_T start;
+ proftime_T start;
memset(stat, 0, sizeof(searchstat_T));
@@ -4636,12 +4636,12 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchst
// "searchcount()" function
void f_searchcount(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- pos_T pos = curwin->w_cursor;
+ pos_T pos = curwin->w_cursor;
char_u *pattern = NULL;
- int maxcount = SEARCH_STAT_DEF_MAX_COUNT;
- long timeout = SEARCH_STAT_DEF_TIMEOUT;
- bool recompute = true;
- searchstat_T stat;
+ int maxcount = SEARCH_STAT_DEF_MAX_COUNT;
+ long timeout = SEARCH_STAT_DEF_TIMEOUT;
+ bool recompute = true;
+ searchstat_T stat;
tv_dict_alloc_ret(rettv);
@@ -4800,8 +4800,8 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo
file_line = xmalloc(LSIZE);
if (type != CHECK_PATH && type != FIND_DEFINE
- /* when CONT_SOL is set compare "ptr" with the beginning of the line
- * is faster than quote_meta/regcomp/regexec "ptr" -- Acevedo */
+ // when CONT_SOL is set compare "ptr" with the beginning of the line
+ // is faster than quote_meta/regcomp/regexec "ptr" -- Acevedo
&& !(compl_cont_status & CONT_SOL)) {
pat = xmalloc(len + 5);
assert(len <= INT_MAX);
@@ -4946,10 +4946,9 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo
// Nothing found, use the rest of the line.
p = incl_regmatch.endp[0];
i = (int)STRLEN(p);
- }
- /* Avoid checking before the start of the line, can
- * happen if \zs appears in the regexp. */
- else if (p > line) {
+ } else if (p > line) {
+ // Avoid checking before the start of the line, can
+ // happen if \zs appears in the regexp.
if (p[-1] == '"' || p[-1] == '<') {
--p;
++i;
@@ -5129,9 +5128,9 @@ search_line:
// IOSIZE > compl_length, so the STRNCPY works
STRNCPY(IObuff, aux, i);
- /* Get the next line: when "depth" < 0 from the current
- * buffer, otherwise from the included file. Jump to
- * exit_matched when past the last line. */
+ // Get the next line: when "depth" < 0 from the current
+ // buffer, otherwise from the included file. Jump to
+ // exit_matched when past the last line.
if (depth < 0) {
if (lnum >= end_lnum) {
goto exit_matched;
@@ -5142,9 +5141,9 @@ search_line:
goto exit_matched;
}
- /* we read a line, set "already" to check this "line" later
- * if depth >= 0 we'll increase files[depth].lnum far
- * bellow -- Acevedo */
+ // we read a line, set "already" to check this "line" later
+ // if depth >= 0 we'll increase files[depth].lnum far
+ // bellow -- Acevedo
already = aux = p = skipwhite(line);
p = find_word_start(p);
p = find_word_end(p);
@@ -5195,8 +5194,8 @@ search_line:
if (did_show) {
msg_putchar('\n'); // cursor below last one
}
- if (!got_int) { /* don't display if 'q' typed
- at "--more--" message */
+ if (!got_int) { // don't display if 'q' typed
+ // at "--more--" message
msg_home_replace_hl(curr_fname);
}
prev_fname = curr_fname;
@@ -5209,10 +5208,10 @@ search_line:
match_count++);
}
- /* Set matched flag for this file and all the ones that
- * include it */
- for (i = 0; i <= depth; ++i) {
- files[i].matched = TRUE;
+ // Set matched flag for this file and all the ones that
+ // include it
+ for (i = 0; i <= depth; i++) {
+ files[i].matched = true;
}
} else if (--count <= 0) {
found = true;
diff --git a/src/nvim/search.h b/src/nvim/search.h
index 0dbaf79c37..85bcda84a4 100644
--- a/src/nvim/search.h
+++ b/src/nvim/search.h
@@ -4,14 +4,14 @@
#include <stdbool.h>
#include <stdint.h>
-#include "nvim/vim.h"
#include "nvim/buffer_defs.h"
#include "nvim/eval/funcs.h"
#include "nvim/eval/typval.h"
#include "nvim/normal.h"
#include "nvim/os/time.h"
+#include "nvim/vim.h"
-/* Values for the find_pattern_in_path() function args 'type' and 'action': */
+// Values for the find_pattern_in_path() function args 'type' and 'action':
#define FIND_ANY 1
#define FIND_DEFINE 2
#define CHECK_PATH 3
@@ -37,18 +37,18 @@
#define SEARCH_PEEK 0x800 ///< peek for typed char, cancel search
#define SEARCH_COL 0x1000 ///< start at specified column instead of zero
-/* Values for flags argument for findmatchlimit() */
-#define FM_BACKWARD 0x01 /* search backwards */
-#define FM_FORWARD 0x02 /* search forwards */
-#define FM_BLOCKSTOP 0x04 /* stop at start/end of block */
-#define FM_SKIPCOMM 0x08 /* skip comments */
+// Values for flags argument for findmatchlimit()
+#define FM_BACKWARD 0x01 // search backwards
+#define FM_FORWARD 0x02 // search forwards
+#define FM_BLOCKSTOP 0x04 // stop at start/end of block
+#define FM_SKIPCOMM 0x08 // skip comments
-/* Values for sub_cmd and which_pat argument for search_regcomp() */
-/* Also used for which_pat argument for searchit() */
-#define RE_SEARCH 0 /* save/use pat in/from search_pattern */
-#define RE_SUBST 1 /* save/use pat in/from subst_pattern */
-#define RE_BOTH 2 /* save pat in both patterns */
-#define RE_LAST 2 /* use last used pattern if "pat" is NULL */
+// Values for sub_cmd and which_pat argument for search_regcomp()
+// Also used for which_pat argument for searchit()
+#define RE_SEARCH 0 // save/use pat in/from search_pattern
+#define RE_SUBST 1 // save/use pat in/from subst_pattern
+#define RE_BOTH 2 // save pat in both patterns
+#define RE_LAST 2 // use last used pattern if "pat" is NULL
// Values for searchcount()
#define SEARCH_STAT_DEF_TIMEOUT 40L
@@ -78,21 +78,21 @@ typedef struct spat {
/// Optional extra arguments for searchit().
typedef struct {
- linenr_T sa_stop_lnum; ///< stop after this line number when != 0
- proftime_T *sa_tm; ///< timeout limit or NULL
- int sa_timed_out; ///< set when timed out
- int sa_wrapped; ///< search wrapped around
+ linenr_T sa_stop_lnum; ///< stop after this line number when != 0
+ proftime_T *sa_tm; ///< timeout limit or NULL
+ int sa_timed_out; ///< set when timed out
+ int sa_wrapped; ///< search wrapped around
} searchit_arg_T;
typedef struct searchstat
{
- int cur; // current position of found words
- int cnt; // total count of found words
- bool exact_match; // true if matched exactly on specified position
- int incomplete; // 0: search was fully completed
- // 1: recomputing was timed out
- // 2: max count exceeded
- int last_maxcount; // the max count of the last search
+ int cur; // current position of found words
+ int cnt; // total count of found words
+ bool exact_match; // true if matched exactly on specified position
+ int incomplete; // 0: search was fully completed
+ // 1: recomputing was timed out
+ // 2: max count exceeded
+ int last_maxcount; // the max count of the last search
} searchstat_T;
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/sha256.c b/src/nvim/sha256.c
index a2378cc202..9d6a2f2c41 100644
--- a/src/nvim/sha256.c
+++ b/src/nvim/sha256.c
@@ -51,8 +51,7 @@ void sha256_start(context_sha256_T *ctx)
ctx->state[7] = 0x5BE0CD19;
}
-static void sha256_process(context_sha256_T *ctx,
- const char_u data[SHA256_BUFFER_SIZE])
+static void sha256_process(context_sha256_T *ctx, const char_u data[SHA256_BUFFER_SIZE])
{
uint32_t temp1, temp2, W[SHA256_BUFFER_SIZE];
uint32_t A, B, C, D, E, F, G, H;
@@ -88,7 +87,7 @@ static void sha256_process(context_sha256_T *ctx,
#define R(t) \
(W[t] = S1(W[t - 2]) + W[t - 7] + \
- S0(W[t - 15]) + W[t - 16])
+ S0(W[t - 15]) + W[t - 16])
#define P(a, b, c, d, e, f, g, h, x, K) { \
temp1 = h + S3(e) + F1(e, f, g) + K + x; \
@@ -188,7 +187,7 @@ void sha256_update(context_sha256_T *ctx, const char_u *input, size_t length)
uint32_t left = ctx->total[0] & (SHA256_BUFFER_SIZE-1); // left < buf size
- ctx->total[0] += (uint32_t) length;
+ ctx->total[0] += (uint32_t)length;
ctx->total[0] &= 0xFFFFFFFF;
if (ctx->total[0] < length) {
@@ -262,8 +261,8 @@ void sha256_finish(context_sha256_T *ctx, char_u digest[SHA256_SUM_SIZE])
///
/// @returns hex digest of "buf[buf_len]" in a static array.
/// if "salt" is not NULL also do "salt[salt_len]".
-const char *sha256_bytes(const uint8_t *restrict buf, size_t buf_len,
- const uint8_t *restrict salt, size_t salt_len)
+const char *sha256_bytes(const uint8_t *restrict buf, size_t buf_len, const uint8_t *restrict salt,
+ size_t salt_len)
{
char_u sha256sum[SHA256_SUM_SIZE];
static char hexit[SHA256_BUFFER_SIZE + 1]; // buf size + NULL
diff --git a/src/nvim/sha256.h b/src/nvim/sha256.h
index deb881a288..b52d300de6 100644
--- a/src/nvim/sha256.h
+++ b/src/nvim/sha256.h
@@ -1,8 +1,8 @@
#ifndef NVIM_SHA256_H
#define NVIM_SHA256_H
-#include <stdint.h> // for uint32_t
#include <stddef.h>
+#include <stdint.h> // for uint32_t
#include "nvim/types.h" // for char_u
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index 7d277fe5c8..10f93913ad 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -1,51 +1,50 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdbool.h>
-#include <string.h>
-#include <inttypes.h>
-#include <errno.h>
#include <assert.h>
-
+#include <errno.h>
+#include <inttypes.h>
#include <msgpack.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
#include <uv.h>
-#include "nvim/os/os.h"
-#include "nvim/os/time.h"
-#include "nvim/vim.h"
-#include "nvim/pos.h"
-#include "nvim/ascii.h"
-#include "nvim/shada.h"
-#include "nvim/message.h"
-#include "nvim/globals.h"
-#include "nvim/memory.h"
-#include "nvim/mark.h"
-#include "nvim/macros.h"
-#include "nvim/ops.h"
-#include "nvim/garray.h"
-#include "nvim/option.h"
-#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/buffer_defs.h"
+#include "nvim/eval/decode.h"
+#include "nvim/eval/encode.h"
+#include "nvim/eval/typval.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
-#include "nvim/search.h"
-#include "nvim/regexp.h"
-#include "nvim/eval/typval.h"
-#include "nvim/version.h"
-#include "nvim/path.h"
#include "nvim/fileio.h"
-#include "nvim/os/fileio.h"
-#include "nvim/strings.h"
-#include "nvim/quickfix.h"
-#include "nvim/eval/encode.h"
-#include "nvim/eval/decode.h"
+#include "nvim/garray.h"
+#include "nvim/globals.h"
#include "nvim/lib/khash.h"
#include "nvim/lib/kvec.h"
+#include "nvim/macros.h"
+#include "nvim/mark.h"
+#include "nvim/memory.h"
+#include "nvim/message.h"
+#include "nvim/msgpack_rpc/helpers.h"
+#include "nvim/ops.h"
+#include "nvim/option.h"
+#include "nvim/os/fileio.h"
+#include "nvim/os/os.h"
+#include "nvim/os/time.h"
+#include "nvim/path.h"
+#include "nvim/pos.h"
+#include "nvim/quickfix.h"
+#include "nvim/regexp.h"
+#include "nvim/search.h"
+#include "nvim/shada.h"
+#include "nvim/strings.h"
+#include "nvim/version.h"
+#include "nvim/vim.h"
#ifdef HAVE_BE64TOH
# define _BSD_SOURCE 1
@@ -66,26 +65,6 @@ KHASH_SET_INIT_INT64(bufset)
KHASH_MAP_INIT_STR(fnamebufs, buf_T *)
KHASH_SET_INIT_STR(strset)
-#define copy_option_part(src, dest, ...) \
- ((char *) copy_option_part((char_u **) src, (char_u *) dest, __VA_ARGS__))
-#define find_shada_parameter(...) \
- ((const char *) find_shada_parameter(__VA_ARGS__))
-#define home_replace_save(a, b) \
- ((char *)home_replace_save(a, (char_u *)b))
-#define home_replace(a, b, c, d, e) \
- home_replace(a, (char_u *)b, (char_u *)c, d, e)
-#define vim_rename(a, b) \
- (vim_rename((char_u *)a, (char_u *)b))
-#define mb_strnicmp(a, b, c) \
- (mb_strnicmp((char_u *)a, (char_u *)b, c))
-#define path_try_shorten_fname(b) \
- ((char *)path_try_shorten_fname((char_u *)b))
-#define buflist_new(ffname, sfname, ...) \
- (buflist_new((char_u *)ffname, (char_u *)sfname, __VA_ARGS__))
-#define os_isdir(f) (os_isdir((char_u *) f))
-#define regtilde(s, m) ((char *) regtilde((char_u *) s, m))
-#define path_tail_with_sep(f) ((char *) path_tail_with_sep((char_u *)f))
-
#define SEARCH_KEY_MAGIC "sm"
#define SEARCH_KEY_SMARTCASE "sc"
#define SEARCH_KEY_HAS_LINE_OFFSET "sl"
@@ -172,7 +151,7 @@ typedef enum {
kSDItemBufferList = 9, ///< Buffer list.
kSDItemLocalMark = 10, ///< Buffer-local mark.
kSDItemChange = 11, ///< Item from buffer change list.
-#define SHADA_LAST_ENTRY ((uint64_t) kSDItemChange)
+#define SHADA_LAST_ENTRY ((uint64_t)kSDItemChange)
} ShadaEntryType;
/// Possible results when reading ShaDa file
@@ -202,11 +181,11 @@ enum SRNIFlags {
kSDReadHeader = (1 << kSDItemHeader), ///< Determines whether header should
///< be read (it is usually ignored).
kSDReadUndisableableData = (
- (1 << kSDItemSearchPattern)
- | (1 << kSDItemSubString)
- | (1 << kSDItemJump)), ///< Data reading which cannot be disabled by
- ///< &shada or other options except for disabling
- ///< reading ShaDa as a whole.
+ (1 << kSDItemSearchPattern)
+ | (1 << kSDItemSubString)
+ | (1 << kSDItemJump)), ///< Data reading which cannot be disabled by
+ ///< &shada or other options except for disabling
+ ///< reading ShaDa as a whole.
kSDReadRegisters = (1 << kSDItemRegister), ///< Determines whether registers
///< should be read (may only be
///< disabled when writing, but
@@ -434,13 +413,13 @@ typedef struct sd_write_def {
#endif
#define DEF_SDE(name, attr, ...) \
- [kSDItem##name] = { \
- .timestamp = 0, \
- .type = kSDItem##name, \
- .data = { \
- .attr = { __VA_ARGS__ } \
- } \
- }
+ [kSDItem##name] = { \
+ .timestamp = 0, \
+ .type = kSDItem##name, \
+ .data = { \
+ .attr = { __VA_ARGS__ } \
+ } \
+ }
#define DEFAULT_POS { 1, 0, 0 }
static const pos_T default_pos = DEFAULT_POS;
static const ShadaEntry sd_default_values[] = {
@@ -475,9 +454,9 @@ static const ShadaEntry sd_default_values[] = {
DEF_SDE(Variable, global_var,
.name = NULL,
.value = {
- .v_type = VAR_UNKNOWN,
- .vval = { .v_string = NULL }
- },
+ .v_type = VAR_UNKNOWN,
+ .vval = { .v_string = NULL }
+ },
.additional_elements = NULL),
DEF_SDE(GlobalMark, filemark,
.name = '"',
@@ -533,17 +512,16 @@ static inline void hmll_init(HMLList *const hmll, const size_t size)
///
/// @return `for` cycle header (use `HMLL_FORALL(hmll, cur_entry) {body}`).
#define HMLL_FORALL(hmll, cur_entry, code) \
- for (HMLListEntry *cur_entry = (hmll)->first; cur_entry != NULL; \
- cur_entry = cur_entry->next) { \
- code \
- } \
+ for (HMLListEntry *cur_entry = (hmll)->first; cur_entry != NULL; \
+ cur_entry = cur_entry->next) { \
+ code \
+ } \
/// Remove entry from the linked list
///
/// @param hmll List to remove from.
/// @param hmll_entry Entry to remove.
-static inline void hmll_remove(HMLList *const hmll,
- HMLListEntry *const hmll_entry)
+static inline void hmll_remove(HMLList *const hmll, HMLListEntry *const hmll_entry)
FUNC_ATTR_NONNULL_ALL
{
if (hmll_entry == hmll->last_free_entry - 1) {
@@ -580,9 +558,7 @@ static inline void hmll_remove(HMLList *const hmll,
/// to insert at the first entry.
/// @param[in] data Data to insert.
/// @param[in] can_free_entry True if data can be freed.
-static inline void hmll_insert(HMLList *const hmll,
- HMLListEntry *hmll_entry,
- const ShadaEntry data,
+static inline void hmll_insert(HMLList *const hmll, HMLListEntry *hmll_entry, const ShadaEntry data,
const bool can_free_entry)
FUNC_ATTR_NONNULL_ARG(1)
{
@@ -595,11 +571,11 @@ static inline void hmll_insert(HMLList *const hmll,
}
HMLListEntry *target_entry;
if (hmll->free_entry == NULL) {
- assert((size_t) (hmll->last_free_entry - hmll->entries)
+ assert((size_t)(hmll->last_free_entry - hmll->entries)
== hmll->num_entries);
target_entry = hmll->last_free_entry++;
} else {
- assert((size_t) (hmll->last_free_entry - hmll->entries) - 1
+ assert((size_t)(hmll->last_free_entry - hmll->entries) - 1
== hmll->num_entries);
target_entry = hmll->free_entry;
hmll->free_entry = NULL;
@@ -628,20 +604,6 @@ static inline void hmll_insert(HMLList *const hmll,
}
}
-/// Iterate over HMLList in backward direction
-///
-/// @param hmll Pointer to the list.
-/// @param cur_entry Name of the variable to iterate over, must be already
-/// defined.
-/// @param code Code to execute on each iteration.
-///
-/// @return `for` cycle header (use `HMLL_FORALL(hmll, cur_entry) {body}`).
-#define HMLL_ITER_BACK(hmll, cur_entry, code) \
- for (cur_entry = (hmll)->last; cur_entry != NULL; \
- cur_entry = cur_entry->prev) { \
- code \
- }
-
/// Free linked list
///
/// @param[in] hmll List to free.
@@ -655,8 +617,7 @@ static inline void hmll_dealloc(HMLList *const hmll)
/// Wrapper for reading from file descriptors
///
/// @return -1 or number of bytes read.
-static ptrdiff_t read_file(ShaDaReadDef *const sd_reader, void *const dest,
- const size_t size)
+static ptrdiff_t read_file(ShaDaReadDef *const sd_reader, void *const dest, const size_t size)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
const ptrdiff_t ret = file_read(sd_reader->cookie, dest, size);
@@ -678,14 +639,13 @@ static int read_char(ShaDaReadDef *const sd_reader)
if (read_bytes != 1) {
return EOF;
}
- return (int) ret;
+ return (int)ret;
}
/// Wrapper for writing to file descriptors
///
/// @return -1 or number of bytes written.
-static ptrdiff_t write_file(ShaDaWriteDef *const sd_writer,
- const void *const dest,
+static ptrdiff_t write_file(ShaDaWriteDef *const sd_writer, const void *const dest,
const size_t size)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -720,8 +680,7 @@ static void close_sd_writer(ShaDaWriteDef *const sd_writer)
///
/// @return FAIL in case of failure, OK in case of success. May set
/// sd_reader->eof or sd_reader->error.
-static int sd_reader_skip_read(ShaDaReadDef *const sd_reader,
- const size_t offset)
+static int sd_reader_skip_read(ShaDaReadDef *const sd_reader, const size_t offset)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
const ptrdiff_t skip_bytes = file_skip(sd_reader->cookie, offset);
@@ -749,8 +708,7 @@ static int sd_reader_skip_read(ShaDaReadDef *const sd_reader,
///
/// @return kSDReadStatusReadError, kSDReadStatusNotShaDa or
/// kSDReadStatusSuccess.
-static ShaDaReadResult sd_reader_skip(ShaDaReadDef *const sd_reader,
- const size_t offset)
+static ShaDaReadResult sd_reader_skip(ShaDaReadDef *const sd_reader, const size_t offset)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
if (sd_reader->skip(sd_reader, offset) != OK) {
@@ -762,7 +720,7 @@ static ShaDaReadResult sd_reader_skip(ShaDaReadDef *const sd_reader,
emsgf(_(RCERR "Error while reading ShaDa file: "
"last entry specified that it occupies %" PRIu64 " bytes, "
"but file ended earlier"),
- (uint64_t) offset);
+ (uint64_t)offset);
return kSDReadStatusNotShaDa;
}
abort();
@@ -776,8 +734,7 @@ static ShaDaReadResult sd_reader_skip(ShaDaReadDef *const sd_reader,
/// @param[out] sd_reader Location where reader structure will be saved.
///
/// @return libuv error in case of error, 0 otherwise.
-static int open_shada_file_for_reading(const char *const fname,
- ShaDaReadDef *sd_reader)
+static int open_shada_file_for_reading(const char *const fname, ShaDaReadDef *sd_reader)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
int error;
@@ -819,7 +776,7 @@ static void close_file(void *cookie)
static inline bool in_bufset(const khash_t(bufset) *const set, const buf_T *buf)
FUNC_ATTR_PURE
{
- return kh_get(bufset, set, (uintptr_t) buf) != kh_end(set);
+ return kh_get(bufset, set, (uintptr_t)buf) != kh_end(set);
}
/// Check whether string is in the given set
@@ -837,7 +794,7 @@ static inline bool in_strset(const khash_t(strset) *const set, char *str)
/// Msgpack callback for writing to ShaDaWriteDef*
static int msgpack_sd_writer_write(void *data, const char *buf, size_t len)
{
- ShaDaWriteDef *const sd_writer = (ShaDaWriteDef *) data;
+ ShaDaWriteDef *const sd_writer = (ShaDaWriteDef *)data;
ptrdiff_t written_bytes = sd_writer->write(sd_writer, buf, len);
if (written_bytes == -1) {
emsgf(_(SERR "System error while writing ShaDa file: %s"),
@@ -910,10 +867,8 @@ static int shada_read_file(const char *const file, const int flags)
/// @param[out] hist Location where iteration results should be saved.
///
/// @return Next iteration state.
-static const void *shada_hist_iter(const void *const iter,
- const uint8_t history_type,
- const bool zero,
- ShadaEntry *const hist)
+static const void *shada_hist_iter(const void *const iter, const uint8_t history_type,
+ const bool zero, ShadaEntry *const hist)
FUNC_ATTR_NONNULL_ARG(4) FUNC_ATTR_WARN_UNUSED_RESULT
{
histentry_T hist_he;
@@ -927,9 +882,9 @@ static const void *shada_hist_iter(const void *const iter,
.data = {
.history_item = {
.histtype = history_type,
- .string = (char *) hist_he.hisstr,
- .sep = (char) (history_type == HIST_SEARCH
- ? (char) hist_he.hisstr[STRLEN(hist_he.hisstr) + 1]
+ .string = (char *)hist_he.hisstr,
+ .sep = (char)(history_type == HIST_SEARCH
+ ? (char)hist_he.hisstr[STRLEN(hist_he.hisstr) + 1]
: 0),
.additional_elements = hist_he.additional_elements,
}
@@ -954,8 +909,8 @@ static const void *shada_hist_iter(const void *const iter,
/// be used. Must be true only if inserting
/// entry from current Neovim history.
/// @param[in] can_free_entry True if entry can be freed.
-static void hms_insert(HistoryMergerState *const hms_p, const ShadaEntry entry,
- const bool do_iter, const bool can_free_entry)
+static void hms_insert(HistoryMergerState *const hms_p, const ShadaEntry entry, const bool do_iter,
+ const bool can_free_entry)
FUNC_ATTR_NONNULL_ALL
{
if (do_iter) {
@@ -992,11 +947,12 @@ static void hms_insert(HistoryMergerState *const hms_p, const ShadaEntry entry,
}
}
HMLListEntry *insert_after;
- HMLL_ITER_BACK(hmll, insert_after, {
+ // Iterate over HMLList in backward direction
+ for (insert_after = hmll->last; insert_after != NULL; insert_after = insert_after->prev) {
if (insert_after->data.timestamp <= entry.timestamp) {
break;
}
- })
+ }
hmll_insert(hmll, insert_after, entry, can_free_entry);
}
@@ -1008,11 +964,8 @@ static void hms_insert(HistoryMergerState *const hms_p, const ShadaEntry entry,
/// @param[in] do_merge Prepare structure for merging elements.
/// @param[in] reading If true, then merger is reading history for use
/// in Neovim.
-static inline void hms_init(HistoryMergerState *const hms_p,
- const uint8_t history_type,
- const size_t num_elements,
- const bool do_merge,
- const bool reading)
+static inline void hms_init(HistoryMergerState *const hms_p, const uint8_t history_type,
+ const size_t num_elements, const bool do_merge, const bool reading)
FUNC_ATTR_NONNULL_ALL
{
hmll_init(&hms_p->hmll, num_elements);
@@ -1027,8 +980,7 @@ static inline void hms_init(HistoryMergerState *const hms_p,
///
/// @param[in,out] hms_p Merger structure into which history should be
/// inserted.
-static inline void hms_insert_whole_neovim_history(
- HistoryMergerState *const hms_p)
+static inline void hms_insert_whole_neovim_history(HistoryMergerState *const hms_p)
FUNC_ATTR_NONNULL_ALL
{
while (hms_p->last_hist_entry.type != kSDItemMissing) {
@@ -1048,21 +1000,20 @@ static inline void hms_insert_whole_neovim_history(
/// @param[out] new_hisidx New last history entry index.
/// @param[out] new_hisnum Amount of history items in merger structure.
static inline void hms_to_he_array(const HistoryMergerState *const hms_p,
- histentry_T *const hist_array,
- int *const new_hisidx,
+ histentry_T *const hist_array, int *const new_hisidx,
int *const new_hisnum)
FUNC_ATTR_NONNULL_ALL
{
histentry_T *hist = hist_array;
HMLL_FORALL(&hms_p->hmll, cur_entry, {
hist->timestamp = cur_entry->data.timestamp;
- hist->hisnum = (int) (hist - hist_array) + 1;
- hist->hisstr = (char_u *) cur_entry->data.data.history_item.string;
+ hist->hisnum = (int)(hist - hist_array) + 1;
+ hist->hisstr = (char_u *)cur_entry->data.data.history_item.string;
hist->additional_elements =
- cur_entry->data.data.history_item.additional_elements;
+ cur_entry->data.data.history_item.additional_elements;
hist++;
})
- *new_hisnum = (int) (hist - hist_array);
+ *new_hisnum = (int)(hist - hist_array);
*new_hisidx = *new_hisnum - 1;
}
@@ -1083,7 +1034,7 @@ static inline void hms_dealloc(HistoryMergerState *const hms_p)
///
/// @return for cycle header. Use `HMS_ITER(hms_p, cur_entry) {body}`.
#define HMS_ITER(hms_p, cur_entry, code) \
- HMLL_FORALL(&((hms_p)->hmll), cur_entry, code)
+ HMLL_FORALL(&((hms_p)->hmll), cur_entry, code)
/// Find buffer for given buffer name (cached)
///
@@ -1091,8 +1042,7 @@ static inline void hms_dealloc(HistoryMergerState *const hms_p)
/// @param[in] fname File name to find.
///
/// @return Pointer to the buffer or NULL.
-static buf_T *find_buffer(khash_t(fnamebufs) *const fname_bufs,
- const char *const fname)
+static buf_T *find_buffer(khash_t(fnamebufs) *const fname_bufs, const char *const fname)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
int kh_ret;
@@ -1123,7 +1073,7 @@ static inline bool marks_equal(const pos_T a, const pos_T b)
entry, fname_cond, free_func, fin_func, \
idxadj_func, afterfree_func) \
do { \
- const int jl_len = (int) jumps_size; \
+ const int jl_len = (int)jumps_size; \
int i; \
for (i = jl_len; i > 0; i--) { \
const jumps_type jl_entry = jumps[i - 1]; \
@@ -1140,17 +1090,17 @@ static inline bool marks_equal(const pos_T a, const pos_T b)
free_func(jumps[0]); \
i--; \
if (i > 0) { \
- memmove(&jumps[0], &jumps[1], sizeof(jumps[1]) * (size_t) i); \
+ memmove(&jumps[0], &jumps[1], sizeof(jumps[1]) * (size_t)i); \
} \
} else if (i != jl_len) { \
memmove(&jumps[i + 1], &jumps[i], \
- sizeof(jumps[0]) * (size_t) (jl_len - i)); \
+ sizeof(jumps[0]) * (size_t)(jl_len - i)); \
} \
} else if (i == 0) { \
if (jl_len == JUMPLISTSIZE) { \
i = -1; \
} else if (jl_len > 0) { \
- memmove(&jumps[1], &jumps[0], sizeof(jumps[0]) * (size_t) jl_len); \
+ memmove(&jumps[1], &jumps[0], sizeof(jumps[0]) * (size_t)jl_len); \
} \
} \
if (i != -1) { \
@@ -1177,8 +1127,8 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
const bool get_old_files = (flags & (kShaDaGetOldfiles | kShaDaForceit)
&& (force || tv_list_len(oldfiles_list) == 0));
const bool want_marks = flags & kShaDaWantMarks;
- const unsigned srni_flags = (unsigned) (
- (flags & kShaDaWantInfo
+ const unsigned srni_flags = (unsigned)(
+ (flags & kShaDaWantInfo
? (kSDReadUndisableableData
| kSDReadRegisters
| kSDReadGlobalMarks
@@ -1190,11 +1140,11 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
&& ARGCOUNT == 0
? kSDReadBufferList
: 0))
- : 0)
- | (want_marks && get_shada_parameter('\'') > 0
+ : 0)
+ | (want_marks && get_shada_parameter('\'') > 0
? kSDReadLocalMarks | kSDReadChanges
: 0)
- | (get_old_files
+ | (get_old_files
? kSDReadLocalMarks
: 0));
if (srni_flags == 0) {
@@ -1204,7 +1154,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
HistoryMergerState hms[HIST_COUNT];
if (srni_flags & kSDReadHistory) {
for (uint8_t i = 0; i < HIST_COUNT; i++) {
- hms_init(&hms[i], i, (size_t) p_hi, true, true);
+ hms_init(&hms[i], i, (size_t)p_hi, true, true);
}
}
ShadaEntry cur_entry;
@@ -1219,253 +1169,239 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
while ((srni_ret = shada_read_next_item(sd_reader, &cur_entry, srni_flags, 0))
!= kSDReadStatusFinished) {
switch (srni_ret) {
- case kSDReadStatusSuccess: {
- break;
- }
- case kSDReadStatusFinished: {
- // Should be handled by the while condition.
- abort();
- }
- case kSDReadStatusNotShaDa:
- case kSDReadStatusReadError: {
- goto shada_read_main_cycle_end;
- }
- case kSDReadStatusMalformed: {
- continue;
- }
+ case kSDReadStatusSuccess:
+ break;
+ case kSDReadStatusFinished:
+ // Should be handled by the while condition.
+ abort();
+ case kSDReadStatusNotShaDa:
+ case kSDReadStatusReadError:
+ goto shada_read_main_cycle_end;
+ case kSDReadStatusMalformed:
+ continue;
}
switch (cur_entry.type) {
- case kSDItemMissing: {
- abort();
- }
- case kSDItemUnknown: {
- break;
- }
- case kSDItemHeader: {
- shada_free_shada_entry(&cur_entry);
- break;
- }
- case kSDItemSearchPattern: {
- if (!force) {
- SearchPattern pat;
- (cur_entry.data.search_pattern.is_substitute_pattern
+ case kSDItemMissing:
+ abort();
+ case kSDItemUnknown:
+ break;
+ case kSDItemHeader:
+ shada_free_shada_entry(&cur_entry);
+ break;
+ case kSDItemSearchPattern:
+ if (!force) {
+ SearchPattern pat;
+ (cur_entry.data.search_pattern.is_substitute_pattern
? &get_substitute_pattern
: &get_search_pattern)(&pat);
- if (pat.pat != NULL && pat.timestamp >= cur_entry.timestamp) {
- shada_free_shada_entry(&cur_entry);
- break;
- }
+ if (pat.pat != NULL && pat.timestamp >= cur_entry.timestamp) {
+ shada_free_shada_entry(&cur_entry);
+ break;
}
- (cur_entry.data.search_pattern.is_substitute_pattern
+ }
+ (cur_entry.data.search_pattern.is_substitute_pattern
? &set_substitute_pattern
: &set_search_pattern)((SearchPattern) {
- .magic = cur_entry.data.search_pattern.magic,
- .no_scs = !cur_entry.data.search_pattern.smartcase,
- .off = {
- .dir = cur_entry.data.search_pattern.search_backward ? '?' : '/',
- .line = cur_entry.data.search_pattern.has_line_offset,
- .end = cur_entry.data.search_pattern.place_cursor_at_end,
- .off = cur_entry.data.search_pattern.offset,
- },
- .pat = (char_u *) cur_entry.data.search_pattern.pat,
- .additional_data = cur_entry.data.search_pattern.additional_data,
- .timestamp = cur_entry.timestamp,
- });
- if (cur_entry.data.search_pattern.is_last_used) {
- set_last_used_pattern(
- cur_entry.data.search_pattern.is_substitute_pattern);
- set_no_hlsearch(!cur_entry.data.search_pattern.highlighted);
- }
- // Do not free shada entry: its allocated memory was saved above.
- break;
- }
- case kSDItemSubString: {
- if (!force) {
- SubReplacementString sub;
- sub_get_replacement(&sub);
- if (sub.sub != NULL && sub.timestamp >= cur_entry.timestamp) {
- shada_free_shada_entry(&cur_entry);
- break;
- }
- }
- sub_set_replacement((SubReplacementString) {
- .sub = cur_entry.data.sub_string.sub,
- .timestamp = cur_entry.timestamp,
- .additional_elements = cur_entry.data.sub_string.additional_elements,
- });
- // Without using regtilde and without / &cpo flag previous substitute
- // string is close to useless: you can only use it with :& or :~ and
- // that’s all because s//~ is not available until the first call to
- // regtilde. Vim was not calling this for some reason.
- (void) regtilde(cur_entry.data.sub_string.sub, p_magic);
- // Do not free shada entry: its allocated memory was saved above.
- break;
+ .magic = cur_entry.data.search_pattern.magic,
+ .no_scs = !cur_entry.data.search_pattern.smartcase,
+ .off = {
+ .dir = cur_entry.data.search_pattern.search_backward ? '?' : '/',
+ .line = cur_entry.data.search_pattern.has_line_offset,
+ .end = cur_entry.data.search_pattern.place_cursor_at_end,
+ .off = cur_entry.data.search_pattern.offset,
+ },
+ .pat = (char_u *)cur_entry.data.search_pattern.pat,
+ .additional_data = cur_entry.data.search_pattern.additional_data,
+ .timestamp = cur_entry.timestamp,
+ });
+ if (cur_entry.data.search_pattern.is_last_used) {
+ set_last_used_pattern(cur_entry.data.search_pattern.is_substitute_pattern);
+ set_no_hlsearch(!cur_entry.data.search_pattern.highlighted);
}
- case kSDItemHistoryEntry: {
- if (cur_entry.data.history_item.histtype >= HIST_COUNT) {
+ // Do not free shada entry: its allocated memory was saved above.
+ break;
+ case kSDItemSubString:
+ if (!force) {
+ SubReplacementString sub;
+ sub_get_replacement(&sub);
+ if (sub.sub != NULL && sub.timestamp >= cur_entry.timestamp) {
shada_free_shada_entry(&cur_entry);
break;
}
- hms_insert(hms + cur_entry.data.history_item.histtype, cur_entry, true,
- true);
- // Do not free shada entry: its allocated memory was saved above.
+ }
+ sub_set_replacement((SubReplacementString) {
+ .sub = cur_entry.data.sub_string.sub,
+ .timestamp = cur_entry.timestamp,
+ .additional_elements = cur_entry.data.sub_string.additional_elements,
+ });
+ // Without using regtilde and without / &cpo flag previous substitute
+ // string is close to useless: you can only use it with :& or :~ and
+ // that’s all because s//~ is not available until the first call to
+ // regtilde. Vim was not calling this for some reason.
+ (void)(char *)regtilde((char_u *)cur_entry.data.sub_string.sub, p_magic);
+ // Do not free shada entry: its allocated memory was saved above.
+ break;
+ case kSDItemHistoryEntry:
+ if (cur_entry.data.history_item.histtype >= HIST_COUNT) {
+ shada_free_shada_entry(&cur_entry);
+ break;
+ }
+ hms_insert(hms + cur_entry.data.history_item.histtype, cur_entry, true,
+ true);
+ // Do not free shada entry: its allocated memory was saved above.
+ break;
+ case kSDItemRegister:
+ if (cur_entry.data.reg.type != kMTCharWise
+ && cur_entry.data.reg.type != kMTLineWise
+ && cur_entry.data.reg.type != kMTBlockWise) {
+ shada_free_shada_entry(&cur_entry);
break;
}
- case kSDItemRegister: {
- if (cur_entry.data.reg.type != kMTCharWise
- && cur_entry.data.reg.type != kMTLineWise
- && cur_entry.data.reg.type != kMTBlockWise) {
+ if (!force) {
+ const yankreg_T *const reg = op_reg_get(cur_entry.data.reg.name);
+ if (reg == NULL || reg->timestamp >= cur_entry.timestamp) {
shada_free_shada_entry(&cur_entry);
break;
}
- if (!force) {
- const yankreg_T *const reg = op_reg_get(cur_entry.data.reg.name);
- if (reg == NULL || reg->timestamp >= cur_entry.timestamp) {
- shada_free_shada_entry(&cur_entry);
- break;
- }
- }
- if (!op_reg_set(cur_entry.data.reg.name, (yankreg_T) {
- .y_array = (char_u **)cur_entry.data.reg.contents,
- .y_size = cur_entry.data.reg.contents_size,
- .y_type = cur_entry.data.reg.type,
- .y_width = (colnr_T) cur_entry.data.reg.width,
- .timestamp = cur_entry.timestamp,
- .additional_data = cur_entry.data.reg.additional_data,
- }, cur_entry.data.reg.is_unnamed)) {
- shada_free_shada_entry(&cur_entry);
- }
- // Do not free shada entry: its allocated memory was saved above.
- break;
}
- case kSDItemVariable: {
- var_set_global(cur_entry.data.global_var.name,
- cur_entry.data.global_var.value);
- cur_entry.data.global_var.value.v_type = VAR_UNKNOWN;
+ if (!op_reg_set(cur_entry.data.reg.name, (yankreg_T) {
+ .y_array = (char_u **)cur_entry.data.reg.contents,
+ .y_size = cur_entry.data.reg.contents_size,
+ .y_type = cur_entry.data.reg.type,
+ .y_width = (colnr_T)cur_entry.data.reg.width,
+ .timestamp = cur_entry.timestamp,
+ .additional_data = cur_entry.data.reg.additional_data,
+ }, cur_entry.data.reg.is_unnamed)) {
shada_free_shada_entry(&cur_entry);
- break;
}
- case kSDItemJump:
- case kSDItemGlobalMark: {
- buf_T *buf = find_buffer(&fname_bufs, cur_entry.data.filemark.fname);
- if (buf != NULL) {
- XFREE_CLEAR(cur_entry.data.filemark.fname);
- }
- xfmark_T fm = (xfmark_T) {
- .fname = (char_u *) (buf == NULL
+ // Do not free shada entry: its allocated memory was saved above.
+ break;
+ case kSDItemVariable:
+ var_set_global(cur_entry.data.global_var.name,
+ cur_entry.data.global_var.value);
+ cur_entry.data.global_var.value.v_type = VAR_UNKNOWN;
+ shada_free_shada_entry(&cur_entry);
+ break;
+ case kSDItemJump:
+ case kSDItemGlobalMark: {
+ buf_T *buf = find_buffer(&fname_bufs, cur_entry.data.filemark.fname);
+ if (buf != NULL) {
+ XFREE_CLEAR(cur_entry.data.filemark.fname);
+ }
+ xfmark_T fm = (xfmark_T) {
+ .fname = (char_u *)(buf == NULL
? cur_entry.data.filemark.fname
: NULL),
- .fmark = {
- .mark = cur_entry.data.filemark.mark,
- .fnum = (buf == NULL ? 0 : buf->b_fnum),
- .timestamp = cur_entry.timestamp,
- .additional_data = cur_entry.data.filemark.additional_data,
- },
- };
- if (cur_entry.type == kSDItemGlobalMark) {
- if (!mark_set_global(cur_entry.data.filemark.name, fm, !force)) {
- shada_free_shada_entry(&cur_entry);
- break;
- }
- } else {
+ .fmark = {
+ .mark = cur_entry.data.filemark.mark,
+ .fnum = (buf == NULL ? 0 : buf->b_fnum),
+ .timestamp = cur_entry.timestamp,
+ .additional_data = cur_entry.data.filemark.additional_data,
+ },
+ };
+ if (cur_entry.type == kSDItemGlobalMark) {
+ if (!mark_set_global(cur_entry.data.filemark.name, fm, !force)) {
+ shada_free_shada_entry(&cur_entry);
+ break;
+ }
+ } else {
#define SDE_TO_XFMARK(entry) fm
#define ADJUST_IDX(i) \
- if (curwin->w_jumplistidx >= i \
- && curwin->w_jumplistidx + 1 <= curwin->w_jumplistlen) { \
- curwin->w_jumplistidx++; \
- }
+ if (curwin->w_jumplistidx >= i \
+ && curwin->w_jumplistidx + 1 <= curwin->w_jumplistlen) { \
+ curwin->w_jumplistidx++; \
+ }
#define DUMMY_AFTERFREE(entry)
- MERGE_JUMPS(curwin->w_jumplistlen, curwin->w_jumplist, xfmark_T,
- fmark.timestamp, fmark.mark, cur_entry,
- (buf == NULL
+ MERGE_JUMPS(curwin->w_jumplistlen, curwin->w_jumplist, xfmark_T,
+ fmark.timestamp, fmark.mark, cur_entry,
+ (buf == NULL
? (jl_entry.fname != NULL
&& STRCMP(fm.fname, jl_entry.fname) == 0)
: fm.fmark.fnum == jl_entry.fmark.fnum),
- free_xfmark, SDE_TO_XFMARK, ADJUST_IDX, DUMMY_AFTERFREE);
+ free_xfmark, SDE_TO_XFMARK, ADJUST_IDX, DUMMY_AFTERFREE);
#undef SDE_TO_XFMARK
#undef ADJUST_IDX
#undef DUMMY_AFTERFREE
- }
- // Do not free shada entry: its allocated memory was saved above.
- break;
}
- case kSDItemBufferList: {
- for (size_t i = 0; i < cur_entry.data.buffer_list.size; i++) {
- char *const sfname = path_try_shorten_fname(
- cur_entry.data.buffer_list.buffers[i].fname);
- buf_T *const buf = buflist_new(
- cur_entry.data.buffer_list.buffers[i].fname, sfname, 0,
- BLN_LISTED);
- if (buf != NULL) {
- RESET_FMARK(&buf->b_last_cursor,
- cur_entry.data.buffer_list.buffers[i].pos, 0);
- buflist_setfpos(buf, curwin, buf->b_last_cursor.mark.lnum,
- buf->b_last_cursor.mark.col, false);
- buf->additional_data =
- cur_entry.data.buffer_list.buffers[i].additional_data;
- cur_entry.data.buffer_list.buffers[i].additional_data = NULL;
- }
+ // Do not free shada entry: its allocated memory was saved above.
+ break;
+ }
+ case kSDItemBufferList:
+ for (size_t i = 0; i < cur_entry.data.buffer_list.size; i++) {
+ char *const sfname =
+ (char *)path_try_shorten_fname((char_u *)cur_entry.data.buffer_list.buffers[i].fname);
+ buf_T *const buf =
+ buflist_new((char_u *)cur_entry.data.buffer_list.buffers[i].fname, (char_u *)sfname, 0,
+ BLN_LISTED);
+ if (buf != NULL) {
+ RESET_FMARK(&buf->b_last_cursor,
+ cur_entry.data.buffer_list.buffers[i].pos, 0);
+ buflist_setfpos(buf, curwin, buf->b_last_cursor.mark.lnum,
+ buf->b_last_cursor.mark.col, false);
+ buf->additional_data =
+ cur_entry.data.buffer_list.buffers[i].additional_data;
+ cur_entry.data.buffer_list.buffers[i].additional_data = NULL;
}
- shada_free_shada_entry(&cur_entry);
- break;
}
- case kSDItemChange:
- case kSDItemLocalMark: {
- if (get_old_files && !in_strset(&oldfiles_set,
- cur_entry.data.filemark.fname)) {
- char *fname = cur_entry.data.filemark.fname;
- if (want_marks) {
- // Do not bother with allocating memory for the string if already
- // allocated string from cur_entry can be used. It cannot be used if
- // want_marks is set because this way it may be used for a mark.
- fname = xstrdup(fname);
- }
- int kh_ret;
- (void)kh_put(strset, &oldfiles_set, fname, &kh_ret);
- tv_list_append_allocated_string(oldfiles_list, fname);
- if (!want_marks) {
- // Avoid free because this string was already used.
- cur_entry.data.filemark.fname = NULL;
- }
+ shada_free_shada_entry(&cur_entry);
+ break;
+ case kSDItemChange:
+ case kSDItemLocalMark: {
+ if (get_old_files && !in_strset(&oldfiles_set,
+ cur_entry.data.filemark.fname)) {
+ char *fname = cur_entry.data.filemark.fname;
+ if (want_marks) {
+ // Do not bother with allocating memory for the string if already
+ // allocated string from cur_entry can be used. It cannot be used if
+ // want_marks is set because this way it may be used for a mark.
+ fname = xstrdup(fname);
}
+ int kh_ret;
+ (void)kh_put(strset, &oldfiles_set, fname, &kh_ret);
+ tv_list_append_allocated_string(oldfiles_list, fname);
if (!want_marks) {
- shada_free_shada_entry(&cur_entry);
- break;
+ // Avoid free because this string was already used.
+ cur_entry.data.filemark.fname = NULL;
}
- buf_T *buf = find_buffer(&fname_bufs, cur_entry.data.filemark.fname);
- if (buf == NULL) {
+ }
+ if (!want_marks) {
+ shada_free_shada_entry(&cur_entry);
+ break;
+ }
+ buf_T *buf = find_buffer(&fname_bufs, cur_entry.data.filemark.fname);
+ if (buf == NULL) {
+ shada_free_shada_entry(&cur_entry);
+ break;
+ }
+ const fmark_T fm = (fmark_T) {
+ .mark = cur_entry.data.filemark.mark,
+ .fnum = 0,
+ .timestamp = cur_entry.timestamp,
+ .additional_data = cur_entry.data.filemark.additional_data,
+ };
+ if (cur_entry.type == kSDItemLocalMark) {
+ if (!mark_set_local(cur_entry.data.filemark.name, buf, fm, !force)) {
shada_free_shada_entry(&cur_entry);
break;
}
- const fmark_T fm = (fmark_T) {
- .mark = cur_entry.data.filemark.mark,
- .fnum = 0,
- .timestamp = cur_entry.timestamp,
- .additional_data = cur_entry.data.filemark.additional_data,
- };
- if (cur_entry.type == kSDItemLocalMark) {
- if (!mark_set_local(cur_entry.data.filemark.name, buf, fm, !force)) {
- shada_free_shada_entry(&cur_entry);
- break;
- }
- } else {
- int kh_ret;
- (void) kh_put(bufset, &cl_bufs, (uintptr_t) buf, &kh_ret);
+ } else {
+ int kh_ret;
+ (void)kh_put(bufset, &cl_bufs, (uintptr_t)buf, &kh_ret);
#define SDE_TO_FMARK(entry) fm
#define AFTERFREE(entry) (entry).data.filemark.fname = NULL
#define DUMMY_IDX_ADJ(i)
- MERGE_JUMPS(buf->b_changelistlen, buf->b_changelist, fmark_T,
- timestamp, mark, cur_entry, true,
- free_fmark, SDE_TO_FMARK, DUMMY_IDX_ADJ, AFTERFREE);
+ MERGE_JUMPS(buf->b_changelistlen, buf->b_changelist, fmark_T,
+ timestamp, mark, cur_entry, true,
+ free_fmark, SDE_TO_FMARK, DUMMY_IDX_ADJ, AFTERFREE);
#undef SDE_TO_FMARK
#undef AFTERFREE
#undef DUMMY_IDX_ADJ
- }
- // Do not free shada entry: except for fname, its allocated memory (i.e.
- // additional_data attribute contents if non-NULL) was saved above.
- xfree(cur_entry.data.filemark.fname);
- break;
}
+ // Do not free shada entry: except for fname, its allocated memory (i.e.
+ // additional_data attribute contents if non-NULL) was saved above.
+ xfree(cur_entry.data.filemark.fname);
+ break;
+ }
}
}
shada_read_main_cycle_end:
@@ -1490,7 +1426,7 @@ shada_read_main_cycle_end:
}
if (cl_bufs.n_occupied) {
FOR_ALL_TAB_WINDOWS(tp, wp) {
- (void) tp;
+ (void)tp;
if (in_bufset(&cl_bufs, wp->w_buffer)) {
wp->w_changelistidx = wp->w_buffer->b_changelistlen;
}
@@ -1499,7 +1435,7 @@ shada_read_main_cycle_end:
kh_dealloc(bufset, &cl_bufs);
const char *key;
kh_foreach_key(&fname_bufs, key, {
- xfree((void *) key);
+ xfree((void *)key);
})
kh_dealloc(fnamebufs, &fname_bufs);
kh_dealloc(strset, &oldfiles_set);
@@ -1535,7 +1471,7 @@ static char *shada_filename(const char *file)
if (p_shadafile != NULL && *p_shadafile != NUL) {
file = p_shadafile;
} else {
- if ((file = find_shada_parameter('n')) == NULL || *file == NUL) {
+ if ((file = (char *)find_shada_parameter('n')) == NULL || *file == NUL) {
file = shada_get_default_file();
}
// XXX It used to be one level lower, so that whatever is in
@@ -1544,33 +1480,25 @@ static char *shada_filename(const char *file)
// If shell is not performing them then they should be done in main.c
// where arguments are parsed, *not here*.
expand_env((char_u *)file, &(NameBuff[0]), MAXPATHL);
- file = (const char *) &(NameBuff[0]);
+ file = (const char *)&(NameBuff[0]);
}
}
return xstrdup(file);
}
#define PACK_STATIC_STR(s) \
- do { \
- msgpack_pack_str(spacker, sizeof(s) - 1); \
- msgpack_pack_str_body(spacker, s, sizeof(s) - 1); \
- } while (0)
-#define PACK_STRING(s) \
- do { \
- const String s_ = (s); \
- msgpack_pack_str(spacker, s_.size); \
- if (s_.size) { \
- msgpack_pack_str_body(spacker, s_.data, s_.size); \
- } \
- } while (0)
+ do { \
+ msgpack_pack_str(spacker, sizeof(s) - 1); \
+ msgpack_pack_str_body(spacker, s, sizeof(s) - 1); \
+ } while (0)
#define PACK_BIN(s) \
- do { \
- const String s_ = (s); \
- msgpack_pack_bin(spacker, s_.size); \
- if (s_.size > 0) { \
- msgpack_pack_bin_body(spacker, s_.data, s_.size); \
- } \
- } while (0)
+ do { \
+ const String s_ = (s); \
+ msgpack_pack_bin(spacker, s_.size); \
+ if (s_.size > 0) { \
+ msgpack_pack_bin_body(spacker, s_.data, s_.size); \
+ } \
+ } while (0)
/// Write single ShaDa entry
///
@@ -1580,8 +1508,7 @@ static char *shada_filename(const char *file)
/// restrictions.
///
/// @return kSDWriteSuccessfull, kSDWriteFailed or kSDWriteIgnError.
-static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
- ShadaEntry entry,
+static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer, ShadaEntry entry,
const size_t max_kbyte)
FUNC_ATTR_NONNULL_ALL
{
@@ -1625,244 +1552,243 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
#define CHECK_DEFAULT(entry, attr) \
(sd_default_values[entry.type].data.attr == entry.data.attr)
#define ONE_IF_NOT_DEFAULT(entry, attr) \
- ((size_t) (!CHECK_DEFAULT(entry, attr)))
+ ((size_t)(!CHECK_DEFAULT(entry, attr)))
switch (entry.type) {
- case kSDItemMissing: {
- abort();
- }
- case kSDItemUnknown: {
- if (spacker->callback(spacker->data, entry.data.unknown_item.contents,
- (unsigned) entry.data.unknown_item.size) == -1) {
- goto shada_pack_entry_error;
- }
- break;
+ case kSDItemMissing:
+ abort();
+ case kSDItemUnknown:
+ if (spacker->callback(spacker->data, entry.data.unknown_item.contents,
+ (unsigned)entry.data.unknown_item.size) == -1) {
+ goto shada_pack_entry_error;
}
- case kSDItemHistoryEntry: {
- const bool is_hist_search =
- entry.data.history_item.histtype == HIST_SEARCH;
- const size_t arr_size = 2 + (size_t)is_hist_search + (size_t)(
- tv_list_len(entry.data.history_item.additional_elements));
- msgpack_pack_array(spacker, arr_size);
- msgpack_pack_uint8(spacker, entry.data.history_item.histtype);
- PACK_BIN(cstr_as_string(entry.data.history_item.string));
- if (is_hist_search) {
- msgpack_pack_uint8(spacker, (uint8_t)entry.data.history_item.sep);
- }
- DUMP_ADDITIONAL_ELEMENTS(entry.data.history_item.additional_elements,
- "history entry item");
- break;
+ break;
+ case kSDItemHistoryEntry: {
+ const bool is_hist_search =
+ entry.data.history_item.histtype == HIST_SEARCH;
+ const size_t arr_size = 2 + (size_t)is_hist_search + (size_t)(
+ tv_list_len(entry.data.
+ history_item.
+ additional_elements));
+ msgpack_pack_array(spacker, arr_size);
+ msgpack_pack_uint8(spacker, entry.data.history_item.histtype);
+ PACK_BIN(cstr_as_string(entry.data.history_item.string));
+ if (is_hist_search) {
+ msgpack_pack_uint8(spacker, (uint8_t)entry.data.history_item.sep);
}
- case kSDItemVariable: {
- if (entry.data.global_var.value.v_type == VAR_TYPE_BLOB) {
- // Strings and Blobs both pack as msgpack BINs; differentiate them by
- // storing an additional VAR_TYPE_BLOB element alongside Blobs
- list_T *const list = tv_list_alloc(1);
- tv_list_append_number(list, VAR_TYPE_BLOB);
- entry.data.global_var.additional_elements = list;
- }
- const size_t arr_size = 2 + (size_t)(
- tv_list_len(entry.data.global_var.additional_elements));
- msgpack_pack_array(spacker, arr_size);
- const String varname = cstr_as_string(entry.data.global_var.name);
- PACK_BIN(varname);
- char vardesc[256] = "variable g:";
- memcpy(&vardesc[sizeof("variable g:") - 1], varname.data,
- varname.size + 1);
- if (encode_vim_to_msgpack(spacker, &entry.data.global_var.value, vardesc)
- == FAIL) {
- ret = kSDWriteIgnError;
- EMSG2(_(WERR "Failed to write variable %s"),
- entry.data.global_var.name);
- goto shada_pack_entry_error;
- }
- DUMP_ADDITIONAL_ELEMENTS(entry.data.global_var.additional_elements,
- "variable item");
- break;
+ DUMP_ADDITIONAL_ELEMENTS(entry.data.history_item.additional_elements,
+ "history entry item");
+ break;
+ }
+ case kSDItemVariable: {
+ if (entry.data.global_var.value.v_type == VAR_TYPE_BLOB) {
+ // Strings and Blobs both pack as msgpack BINs; differentiate them by
+ // storing an additional VAR_TYPE_BLOB element alongside Blobs
+ list_T *const list = tv_list_alloc(1);
+ tv_list_append_number(list, VAR_TYPE_BLOB);
+ entry.data.global_var.additional_elements = list;
}
- case kSDItemSubString: {
- const size_t arr_size = 1 + (size_t)(
- tv_list_len(entry.data.sub_string.additional_elements));
- msgpack_pack_array(spacker, arr_size);
- PACK_BIN(cstr_as_string(entry.data.sub_string.sub));
- DUMP_ADDITIONAL_ELEMENTS(entry.data.sub_string.additional_elements,
- "sub string item");
- break;
+ const size_t arr_size = 2 + (size_t)(
+ tv_list_len(entry.data.global_var.additional_elements));
+ msgpack_pack_array(spacker, arr_size);
+ const String varname = cstr_as_string(entry.data.global_var.name);
+ PACK_BIN(varname);
+ char vardesc[256] = "variable g:";
+ memcpy(&vardesc[sizeof("variable g:") - 1], varname.data,
+ varname.size + 1);
+ if (encode_vim_to_msgpack(spacker, &entry.data.global_var.value, vardesc)
+ == FAIL) {
+ ret = kSDWriteIgnError;
+ EMSG2(_(WERR "Failed to write variable %s"),
+ entry.data.global_var.name);
+ goto shada_pack_entry_error;
}
- case kSDItemSearchPattern: {
- const size_t map_size = (size_t) (
- 1 // Search pattern is always present
- + ONE_IF_NOT_DEFAULT(entry, search_pattern.magic)
- + ONE_IF_NOT_DEFAULT(entry, search_pattern.is_last_used)
- + ONE_IF_NOT_DEFAULT(entry, search_pattern.smartcase)
- + ONE_IF_NOT_DEFAULT(entry, search_pattern.has_line_offset)
- + ONE_IF_NOT_DEFAULT(entry, search_pattern.place_cursor_at_end)
- + ONE_IF_NOT_DEFAULT(entry, search_pattern.is_substitute_pattern)
- + ONE_IF_NOT_DEFAULT(entry, search_pattern.highlighted)
- + ONE_IF_NOT_DEFAULT(entry, search_pattern.offset)
- + ONE_IF_NOT_DEFAULT(entry, search_pattern.search_backward)
- // finally, additional data:
- + (size_t) (
- entry.data.search_pattern.additional_data
+ DUMP_ADDITIONAL_ELEMENTS(entry.data.global_var.additional_elements,
+ "variable item");
+ break;
+ }
+ case kSDItemSubString: {
+ const size_t arr_size = 1 + (size_t)(
+ tv_list_len(entry.data.sub_string.additional_elements));
+ msgpack_pack_array(spacker, arr_size);
+ PACK_BIN(cstr_as_string(entry.data.sub_string.sub));
+ DUMP_ADDITIONAL_ELEMENTS(entry.data.sub_string.additional_elements,
+ "sub string item");
+ break;
+ }
+ case kSDItemSearchPattern: {
+ const size_t map_size = (size_t)(
+ 1 // Search pattern is always present
+ + ONE_IF_NOT_DEFAULT(entry, search_pattern.magic)
+ + ONE_IF_NOT_DEFAULT(entry, search_pattern.is_last_used)
+ + ONE_IF_NOT_DEFAULT(entry, search_pattern.smartcase)
+ + ONE_IF_NOT_DEFAULT(entry, search_pattern.has_line_offset)
+ + ONE_IF_NOT_DEFAULT(entry, search_pattern.place_cursor_at_end)
+ + ONE_IF_NOT_DEFAULT(entry,
+ search_pattern.is_substitute_pattern)
+ + ONE_IF_NOT_DEFAULT(entry, search_pattern.highlighted)
+ + ONE_IF_NOT_DEFAULT(entry, search_pattern.offset)
+ + ONE_IF_NOT_DEFAULT(entry, search_pattern.search_backward)
+ // finally, additional data:
+ + (size_t)(
+ entry.data.search_pattern.additional_data
? entry.data.search_pattern.additional_data->dv_hashtab.ht_used
: 0));
- msgpack_pack_map(spacker, map_size);
- PACK_STATIC_STR(SEARCH_KEY_PAT);
- PACK_BIN(cstr_as_string(entry.data.search_pattern.pat));
+ msgpack_pack_map(spacker, map_size);
+ PACK_STATIC_STR(SEARCH_KEY_PAT);
+ PACK_BIN(cstr_as_string(entry.data.search_pattern.pat));
#define PACK_BOOL(entry, name, attr) \
- do { \
- if (!CHECK_DEFAULT(entry, search_pattern.attr)) { \
- PACK_STATIC_STR(name); \
- if (sd_default_values[entry.type].data.search_pattern.attr) { \
- msgpack_pack_false(spacker); \
- } else { \
- msgpack_pack_true(spacker); \
- } \
- } \
- } while (0)
- PACK_BOOL(entry, SEARCH_KEY_MAGIC, magic);
- PACK_BOOL(entry, SEARCH_KEY_IS_LAST_USED, is_last_used);
- PACK_BOOL(entry, SEARCH_KEY_SMARTCASE, smartcase);
- PACK_BOOL(entry, SEARCH_KEY_HAS_LINE_OFFSET, has_line_offset);
- PACK_BOOL(entry, SEARCH_KEY_PLACE_CURSOR_AT_END, place_cursor_at_end);
- PACK_BOOL(entry, SEARCH_KEY_IS_SUBSTITUTE_PATTERN, is_substitute_pattern);
- PACK_BOOL(entry, SEARCH_KEY_HIGHLIGHTED, highlighted);
- PACK_BOOL(entry, SEARCH_KEY_BACKWARD, search_backward);
- if (!CHECK_DEFAULT(entry, search_pattern.offset)) {
- PACK_STATIC_STR(SEARCH_KEY_OFFSET);
- msgpack_pack_int64(spacker, entry.data.search_pattern.offset);
- }
-#undef PACK_BOOL
- DUMP_ADDITIONAL_DATA(entry.data.search_pattern.additional_data,
- "search pattern item");
- break;
+ do { \
+ if (!CHECK_DEFAULT(entry, search_pattern.attr)) { \
+ PACK_STATIC_STR(name); \
+ if (sd_default_values[entry.type].data.search_pattern.attr) { \
+ msgpack_pack_false(spacker); \
+ } else { \
+ msgpack_pack_true(spacker); \
+ } \
+ } \
+ } while (0)
+ PACK_BOOL(entry, SEARCH_KEY_MAGIC, magic);
+ PACK_BOOL(entry, SEARCH_KEY_IS_LAST_USED, is_last_used);
+ PACK_BOOL(entry, SEARCH_KEY_SMARTCASE, smartcase);
+ PACK_BOOL(entry, SEARCH_KEY_HAS_LINE_OFFSET, has_line_offset);
+ PACK_BOOL(entry, SEARCH_KEY_PLACE_CURSOR_AT_END, place_cursor_at_end);
+ PACK_BOOL(entry, SEARCH_KEY_IS_SUBSTITUTE_PATTERN, is_substitute_pattern);
+ PACK_BOOL(entry, SEARCH_KEY_HIGHLIGHTED, highlighted);
+ PACK_BOOL(entry, SEARCH_KEY_BACKWARD, search_backward);
+ if (!CHECK_DEFAULT(entry, search_pattern.offset)) {
+ PACK_STATIC_STR(SEARCH_KEY_OFFSET);
+ msgpack_pack_int64(spacker, entry.data.search_pattern.offset);
}
- case kSDItemChange:
- case kSDItemGlobalMark:
- case kSDItemLocalMark:
- case kSDItemJump: {
- const size_t map_size = (size_t) (
- 1 // File name
- + ONE_IF_NOT_DEFAULT(entry, filemark.mark.lnum)
- + ONE_IF_NOT_DEFAULT(entry, filemark.mark.col)
- + ONE_IF_NOT_DEFAULT(entry, filemark.name)
- // Additional entries, if any:
- + (size_t) (
- entry.data.filemark.additional_data == NULL
+#undef PACK_BOOL
+ DUMP_ADDITIONAL_DATA(entry.data.search_pattern.additional_data,
+ "search pattern item");
+ break;
+ }
+ case kSDItemChange:
+ case kSDItemGlobalMark:
+ case kSDItemLocalMark:
+ case kSDItemJump: {
+ const size_t map_size = (size_t)(
+ 1 // File name
+ + ONE_IF_NOT_DEFAULT(entry, filemark.mark.lnum)
+ + ONE_IF_NOT_DEFAULT(entry, filemark.mark.col)
+ + ONE_IF_NOT_DEFAULT(entry, filemark.name)
+ // Additional entries, if any:
+ + (size_t)(
+ entry.data.filemark.additional_data == NULL
? 0
: entry.data.filemark.additional_data->dv_hashtab.ht_used));
- msgpack_pack_map(spacker, map_size);
- PACK_STATIC_STR(KEY_FILE);
- PACK_BIN(cstr_as_string(entry.data.filemark.fname));
- if (!CHECK_DEFAULT(entry, filemark.mark.lnum)) {
- PACK_STATIC_STR(KEY_LNUM);
- msgpack_pack_long(spacker, entry.data.filemark.mark.lnum);
- }
- if (!CHECK_DEFAULT(entry, filemark.mark.col)) {
- PACK_STATIC_STR(KEY_COL);
- msgpack_pack_long(spacker, entry.data.filemark.mark.col);
- }
- assert(entry.type == kSDItemJump || entry.type == kSDItemChange
+ msgpack_pack_map(spacker, map_size);
+ PACK_STATIC_STR(KEY_FILE);
+ PACK_BIN(cstr_as_string(entry.data.filemark.fname));
+ if (!CHECK_DEFAULT(entry, filemark.mark.lnum)) {
+ PACK_STATIC_STR(KEY_LNUM);
+ msgpack_pack_long(spacker, entry.data.filemark.mark.lnum);
+ }
+ if (!CHECK_DEFAULT(entry, filemark.mark.col)) {
+ PACK_STATIC_STR(KEY_COL);
+ msgpack_pack_long(spacker, entry.data.filemark.mark.col);
+ }
+ assert(entry.type == kSDItemJump || entry.type == kSDItemChange
? CHECK_DEFAULT(entry, filemark.name)
: true);
- if (!CHECK_DEFAULT(entry, filemark.name)) {
- PACK_STATIC_STR(KEY_NAME_CHAR);
- msgpack_pack_uint8(spacker, (uint8_t) entry.data.filemark.name);
- }
- DUMP_ADDITIONAL_DATA(entry.data.filemark.additional_data,
- "mark (change, jump, global or local) item");
- break;
+ if (!CHECK_DEFAULT(entry, filemark.name)) {
+ PACK_STATIC_STR(KEY_NAME_CHAR);
+ msgpack_pack_uint8(spacker, (uint8_t)entry.data.filemark.name);
}
- case kSDItemRegister: {
- const size_t map_size = (size_t) (
- 2 // Register contents and name
- + ONE_IF_NOT_DEFAULT(entry, reg.type)
- + ONE_IF_NOT_DEFAULT(entry, reg.width)
- + ONE_IF_NOT_DEFAULT(entry, reg.is_unnamed)
- // Additional entries, if any:
- + (size_t) (entry.data.reg.additional_data == NULL
+ DUMP_ADDITIONAL_DATA(entry.data.filemark.additional_data,
+ "mark (change, jump, global or local) item");
+ break;
+ }
+ case kSDItemRegister: {
+ const size_t map_size = (size_t)(
+ 2 // Register contents and name
+ + ONE_IF_NOT_DEFAULT(entry, reg.type)
+ + ONE_IF_NOT_DEFAULT(entry, reg.width)
+ + ONE_IF_NOT_DEFAULT(entry, reg.is_unnamed)
+ // Additional entries, if any:
+ + (size_t)(entry.data.reg.additional_data == NULL
? 0
: entry.data.reg.additional_data->dv_hashtab.ht_used));
- msgpack_pack_map(spacker, map_size);
- PACK_STATIC_STR(REG_KEY_CONTENTS);
- msgpack_pack_array(spacker, entry.data.reg.contents_size);
- for (size_t i = 0; i < entry.data.reg.contents_size; i++) {
- PACK_BIN(cstr_as_string(entry.data.reg.contents[i]));
- }
- PACK_STATIC_STR(KEY_NAME_CHAR);
- msgpack_pack_char(spacker, entry.data.reg.name);
- if (!CHECK_DEFAULT(entry, reg.type)) {
- PACK_STATIC_STR(REG_KEY_TYPE);
- msgpack_pack_uint8(spacker, (uint8_t)entry.data.reg.type);
- }
- if (!CHECK_DEFAULT(entry, reg.width)) {
- PACK_STATIC_STR(REG_KEY_WIDTH);
- msgpack_pack_uint64(spacker, (uint64_t) entry.data.reg.width);
- }
- if (!CHECK_DEFAULT(entry, reg.is_unnamed)) {
- PACK_STATIC_STR(REG_KEY_UNNAMED);
- if (entry.data.reg.is_unnamed) {
- msgpack_pack_true(spacker);
- } else {
- msgpack_pack_false(spacker);
- }
+ msgpack_pack_map(spacker, map_size);
+ PACK_STATIC_STR(REG_KEY_CONTENTS);
+ msgpack_pack_array(spacker, entry.data.reg.contents_size);
+ for (size_t i = 0; i < entry.data.reg.contents_size; i++) {
+ PACK_BIN(cstr_as_string(entry.data.reg.contents[i]));
+ }
+ PACK_STATIC_STR(KEY_NAME_CHAR);
+ msgpack_pack_char(spacker, entry.data.reg.name);
+ if (!CHECK_DEFAULT(entry, reg.type)) {
+ PACK_STATIC_STR(REG_KEY_TYPE);
+ msgpack_pack_uint8(spacker, (uint8_t)entry.data.reg.type);
+ }
+ if (!CHECK_DEFAULT(entry, reg.width)) {
+ PACK_STATIC_STR(REG_KEY_WIDTH);
+ msgpack_pack_uint64(spacker, (uint64_t)entry.data.reg.width);
+ }
+ if (!CHECK_DEFAULT(entry, reg.is_unnamed)) {
+ PACK_STATIC_STR(REG_KEY_UNNAMED);
+ if (entry.data.reg.is_unnamed) {
+ msgpack_pack_true(spacker);
+ } else {
+ msgpack_pack_false(spacker);
}
- DUMP_ADDITIONAL_DATA(entry.data.reg.additional_data, "register item");
- break;
}
- case kSDItemBufferList: {
- msgpack_pack_array(spacker, entry.data.buffer_list.size);
- for (size_t i = 0; i < entry.data.buffer_list.size; i++) {
- const size_t map_size = (size_t) (
- 1 // Buffer name
- + (size_t) (entry.data.buffer_list.buffers[i].pos.lnum
- != default_pos.lnum)
- + (size_t) (entry.data.buffer_list.buffers[i].pos.col
- != default_pos.col)
- // Additional entries, if any:
- + (size_t) (
- entry.data.buffer_list.buffers[i].additional_data == NULL
+ DUMP_ADDITIONAL_DATA(entry.data.reg.additional_data, "register item");
+ break;
+ }
+ case kSDItemBufferList:
+ msgpack_pack_array(spacker, entry.data.buffer_list.size);
+ for (size_t i = 0; i < entry.data.buffer_list.size; i++) {
+ const size_t map_size = (size_t)(
+ 1 // Buffer name
+ + (size_t)(entry.data.buffer_list.buffers[i].pos.lnum
+ != default_pos.lnum)
+ + (size_t)(entry.data.buffer_list.buffers[i].pos.col
+ != default_pos.col)
+ // Additional entries, if any:
+ + (size_t)(
+ entry.data.buffer_list.buffers[i].additional_data
+ == NULL
? 0
: (entry.data.buffer_list.buffers[i].additional_data
->dv_hashtab.ht_used)));
- msgpack_pack_map(spacker, map_size);
- PACK_STATIC_STR(KEY_FILE);
- PACK_BIN(cstr_as_string(entry.data.buffer_list.buffers[i].fname));
- if (entry.data.buffer_list.buffers[i].pos.lnum != 1) {
- PACK_STATIC_STR(KEY_LNUM);
- msgpack_pack_uint64(
- spacker, (uint64_t) entry.data.buffer_list.buffers[i].pos.lnum);
- }
- if (entry.data.buffer_list.buffers[i].pos.col != 0) {
- PACK_STATIC_STR(KEY_COL);
- msgpack_pack_uint64(
- spacker, (uint64_t) entry.data.buffer_list.buffers[i].pos.col);
- }
- DUMP_ADDITIONAL_DATA(entry.data.buffer_list.buffers[i].additional_data,
- "buffer list subitem");
+ msgpack_pack_map(spacker, map_size);
+ PACK_STATIC_STR(KEY_FILE);
+ PACK_BIN(cstr_as_string(entry.data.buffer_list.buffers[i].fname));
+ if (entry.data.buffer_list.buffers[i].pos.lnum != 1) {
+ PACK_STATIC_STR(KEY_LNUM);
+ msgpack_pack_uint64(spacker, (uint64_t)entry.data.buffer_list.buffers[i].pos.lnum);
}
- break;
+ if (entry.data.buffer_list.buffers[i].pos.col != 0) {
+ PACK_STATIC_STR(KEY_COL);
+ msgpack_pack_uint64(spacker, (uint64_t)entry.data.buffer_list.buffers[i].pos.col);
+ }
+ DUMP_ADDITIONAL_DATA(entry.data.buffer_list.buffers[i].additional_data,
+ "buffer list subitem");
}
- case kSDItemHeader: {
- msgpack_pack_map(spacker, entry.data.header.size);
- for (size_t i = 0; i < entry.data.header.size; i++) {
- PACK_STRING(entry.data.header.items[i].key);
- const Object obj = entry.data.header.items[i].value;
- switch (obj.type) {
- case kObjectTypeString: {
- PACK_BIN(obj.data.string);
- break;
- }
- case kObjectTypeInteger: {
- msgpack_pack_int64(spacker, (int64_t) obj.data.integer);
- break;
- }
- default: {
- abort();
- }
- }
+ break;
+ case kSDItemHeader:
+ msgpack_pack_map(spacker, entry.data.header.size);
+ for (size_t i = 0; i < entry.data.header.size; i++) {
+ const String s = entry.data.header.items[i].key;
+ msgpack_pack_str(spacker, s.size);
+ if (s.size) {
+ msgpack_pack_str_body(spacker, s.data, s.size);
+ }
+ const Object obj = entry.data.header.items[i].value;
+ switch (obj.type) {
+ case kObjectTypeString:
+ PACK_BIN(obj.data.string);
+ break;
+ case kObjectTypeInteger:
+ msgpack_pack_int64(spacker, (int64_t)obj.data.integer);
+ break;
+ default:
+ abort();
}
- break;
}
+ break;
}
#undef CHECK_DEFAULT
#undef ONE_IF_NOT_DEFAULT
@@ -1872,17 +1798,17 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
goto shada_pack_entry_error;
}
} else {
- if (msgpack_pack_uint64(packer, (uint64_t) entry.type) == -1) {
+ if (msgpack_pack_uint64(packer, (uint64_t)entry.type) == -1) {
goto shada_pack_entry_error;
}
}
- if (msgpack_pack_uint64(packer, (uint64_t) entry.timestamp) == -1) {
+ if (msgpack_pack_uint64(packer, (uint64_t)entry.timestamp) == -1) {
goto shada_pack_entry_error;
}
if (sbuf.size > 0) {
- if ((msgpack_pack_uint64(packer, (uint64_t) sbuf.size) == -1)
+ if ((msgpack_pack_uint64(packer, (uint64_t)sbuf.size) == -1)
|| (packer->callback(packer->data, sbuf.data,
- (unsigned) sbuf.size) == -1)) {
+ (unsigned)sbuf.size) == -1)) {
goto shada_pack_entry_error;
}
}
@@ -1895,7 +1821,6 @@ shada_pack_entry_error:
msgpack_sbuffer_destroy(&sbuf);
return ret;
}
-#undef PACK_STRING
/// Write single ShaDa entry and free it afterwards
///
@@ -1905,9 +1830,9 @@ shada_pack_entry_error:
/// @param[in] entry Entry written.
/// @param[in] max_kbyte Maximum size of an item in KiB. Zero means no
/// restrictions.
-static inline ShaDaWriteResult shada_pack_pfreed_entry(
- msgpack_packer *const packer, PossiblyFreedShadaEntry entry,
- const size_t max_kbyte)
+static inline ShaDaWriteResult shada_pack_pfreed_entry(msgpack_packer *const packer,
+ PossiblyFreedShadaEntry entry,
+ const size_t max_kbyte)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
{
ShaDaWriteResult ret = kSDWriteSuccessfull;
@@ -1945,9 +1870,10 @@ static int compare_file_marks(const void *a, const void *b)
///
/// @return kSDReadStatusNotShaDa, kSDReadStatusReadError or
/// kSDReadStatusSuccess.
-static inline ShaDaReadResult shada_parse_msgpack(
- ShaDaReadDef *const sd_reader, const size_t length,
- msgpack_unpacked *ret_unpacked, char **const ret_buf)
+static inline ShaDaReadResult shada_parse_msgpack(ShaDaReadDef *const sd_reader,
+ const size_t length,
+ msgpack_unpacked *ret_unpacked,
+ char **const ret_buf)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1)
{
const uintmax_t initial_fpos = sd_reader->fpos;
@@ -1964,47 +1890,42 @@ shada_parse_msgpack_read_next: {}
msgpack_unpacked unpacked;
msgpack_unpacked_init(&unpacked);
const msgpack_unpack_return result =
- msgpack_unpack_next(&unpacked, buf, length, &off);
+ msgpack_unpack_next(&unpacked, buf, length, &off);
ShaDaReadResult ret = kSDReadStatusSuccess;
switch (result) {
- case MSGPACK_UNPACK_SUCCESS: {
- if (off < length) {
- goto shada_parse_msgpack_extra_bytes;
- }
- break;
+ case MSGPACK_UNPACK_SUCCESS:
+ if (off < length) {
+ goto shada_parse_msgpack_extra_bytes;
}
- case MSGPACK_UNPACK_PARSE_ERROR: {
- emsgf(_(RCERR "Failed to parse ShaDa file due to a msgpack parser error "
- "at position %" PRIu64),
- (uint64_t) initial_fpos);
- ret = kSDReadStatusNotShaDa;
- break;
+ break;
+ case MSGPACK_UNPACK_PARSE_ERROR:
+ emsgf(_(RCERR "Failed to parse ShaDa file due to a msgpack parser error "
+ "at position %" PRIu64),
+ (uint64_t)initial_fpos);
+ ret = kSDReadStatusNotShaDa;
+ break;
+ case MSGPACK_UNPACK_NOMEM_ERROR:
+ if (!did_try_to_free) {
+ did_try_to_free = true;
+ try_to_free_memory();
+ goto shada_parse_msgpack_read_next;
}
- case MSGPACK_UNPACK_NOMEM_ERROR: {
- if (!did_try_to_free) {
- did_try_to_free = true;
- try_to_free_memory();
- goto shada_parse_msgpack_read_next;
- }
- EMSG(_(e_outofmem));
- ret = kSDReadStatusReadError;
- break;
- }
- case MSGPACK_UNPACK_CONTINUE: {
- emsgf(_(RCERR "Failed to parse ShaDa file: incomplete msgpack string "
- "at position %" PRIu64),
- (uint64_t) initial_fpos);
- ret = kSDReadStatusNotShaDa;
- break;
- }
- case MSGPACK_UNPACK_EXTRA_BYTES: {
+ EMSG(_(e_outofmem));
+ ret = kSDReadStatusReadError;
+ break;
+ case MSGPACK_UNPACK_CONTINUE:
+ emsgf(_(RCERR "Failed to parse ShaDa file: incomplete msgpack string "
+ "at position %" PRIu64),
+ (uint64_t)initial_fpos);
+ ret = kSDReadStatusNotShaDa;
+ break;
+ case MSGPACK_UNPACK_EXTRA_BYTES:
shada_parse_msgpack_extra_bytes:
- emsgf(_(RCERR "Failed to parse ShaDa file: extra bytes in msgpack string "
- "at position %" PRIu64),
- (uint64_t) initial_fpos);
- ret = kSDReadStatusNotShaDa;
- break;
- }
+ emsgf(_(RCERR "Failed to parse ShaDa file: extra bytes in msgpack string "
+ "at position %" PRIu64),
+ (uint64_t)initial_fpos);
+ ret = kSDReadStatusNotShaDa;
+ break;
}
if (ret_buf != NULL && ret == kSDReadStatusSuccess) {
if (ret_unpacked == NULL) {
@@ -2034,81 +1955,67 @@ static const char *shada_format_entry(const ShadaEntry entry)
vim_snprintf(S_LEN(ret), "%s", "[ ] ts=%" PRIu64 " ");
// ^ Space for `can_free_entry`
switch (entry.type) {
- case kSDItemMissing: {
- vim_snprintf_add(S_LEN(ret), "Missing");
- break;
- }
- case kSDItemHeader: {
- vim_snprintf_add(S_LEN(ret), "Header { TODO }");
- break;
- }
- case kSDItemBufferList: {
- vim_snprintf_add(S_LEN(ret), "BufferList { TODO }");
- break;
- }
- case kSDItemUnknown: {
- vim_snprintf_add(S_LEN(ret), "Unknown { TODO }");
- break;
- }
- case kSDItemSearchPattern: {
- vim_snprintf_add(S_LEN(ret), "SearchPattern { TODO }");
- break;
- }
- case kSDItemSubString: {
- vim_snprintf_add(S_LEN(ret), "SubString { TODO }");
- break;
- }
- case kSDItemHistoryEntry: {
- vim_snprintf_add(S_LEN(ret), "HistoryEntry { TODO }");
- break;
- }
- case kSDItemRegister: {
- vim_snprintf_add(S_LEN(ret), "Register { TODO }");
- break;
- }
- case kSDItemVariable: {
- vim_snprintf_add(S_LEN(ret), "Variable { TODO }");
- break;
- }
+ case kSDItemMissing:
+ vim_snprintf_add(S_LEN(ret), "Missing");
+ break;
+ case kSDItemHeader:
+ vim_snprintf_add(S_LEN(ret), "Header { TODO }");
+ break;
+ case kSDItemBufferList:
+ vim_snprintf_add(S_LEN(ret), "BufferList { TODO }");
+ break;
+ case kSDItemUnknown:
+ vim_snprintf_add(S_LEN(ret), "Unknown { TODO }");
+ break;
+ case kSDItemSearchPattern:
+ vim_snprintf_add(S_LEN(ret), "SearchPattern { TODO }");
+ break;
+ case kSDItemSubString:
+ vim_snprintf_add(S_LEN(ret), "SubString { TODO }");
+ break;
+ case kSDItemHistoryEntry:
+ vim_snprintf_add(S_LEN(ret), "HistoryEntry { TODO }");
+ break;
+ case kSDItemRegister:
+ vim_snprintf_add(S_LEN(ret), "Register { TODO }");
+ break;
+ case kSDItemVariable:
+ vim_snprintf_add(S_LEN(ret), "Variable { TODO }");
+ break;
#define FORMAT_MARK_ENTRY(entry_name, name_fmt, name_fmt_arg) \
- do { \
- typval_T ad_tv = { \
- .v_type = VAR_DICT, \
- .vval.v_dict = entry.data.filemark.additional_data \
- }; \
- size_t ad_len; \
- char *const ad = encode_tv2string(&ad_tv, &ad_len); \
- vim_snprintf_add( \
- S_LEN(ret), \
- entry_name " {" name_fmt " file=[%zu]\"%.512s\", " \
- "pos={l=%" PRIdLINENR ",c=%" PRIdCOLNR ",a=%" PRIdCOLNR "}, " \
- "ad={%p:[%zu]%.64s} }", \
- name_fmt_arg, \
- strlen(entry.data.filemark.fname), \
- entry.data.filemark.fname, \
- entry.data.filemark.mark.lnum, \
- entry.data.filemark.mark.col, \
- entry.data.filemark.mark.coladd, \
- (void *)entry.data.filemark.additional_data, \
- ad_len, \
- ad); \
- } while (0)
- case kSDItemGlobalMark: {
- FORMAT_MARK_ENTRY("GlobalMark", " name='%c',", entry.data.filemark.name);
- break;
- }
- case kSDItemChange: {
- FORMAT_MARK_ENTRY("Change", "%s", "");
- break;
- }
- case kSDItemLocalMark: {
- FORMAT_MARK_ENTRY("LocalMark", " name='%c',", entry.data.filemark.name);
- break;
- }
- case kSDItemJump: {
- FORMAT_MARK_ENTRY("Jump", "%s", "");
- break;
- }
+ do { \
+ typval_T ad_tv = { \
+ .v_type = VAR_DICT, \
+ .vval.v_dict = entry.data.filemark.additional_data \
+ }; \
+ size_t ad_len; \
+ char *const ad = encode_tv2string(&ad_tv, &ad_len); \
+ vim_snprintf_add(S_LEN(ret), \
+ entry_name " {" name_fmt " file=[%zu]\"%.512s\", " \
+ "pos={l=%" PRIdLINENR ",c=%" PRIdCOLNR ",a=%" PRIdCOLNR "}, " \
+ "ad={%p:[%zu]%.64s} }", \
+ name_fmt_arg, \
+ strlen(entry.data.filemark.fname), \
+ entry.data.filemark.fname, \
+ entry.data.filemark.mark.lnum, \
+ entry.data.filemark.mark.col, \
+ entry.data.filemark.mark.coladd, \
+ (void *)entry.data.filemark.additional_data, \
+ ad_len, \
+ ad); \
+ } while (0)
+ case kSDItemGlobalMark:
+ FORMAT_MARK_ENTRY("GlobalMark", " name='%c',", entry.data.filemark.name);
+ break;
+ case kSDItemChange:
+ FORMAT_MARK_ENTRY("Change", "%s", "");
+ break;
+ case kSDItemLocalMark:
+ FORMAT_MARK_ENTRY("LocalMark", " name='%c',", entry.data.filemark.name);
+ break;
+ case kSDItemJump:
+ FORMAT_MARK_ENTRY("Jump", "%s", "");
+ break;
#undef FORMAT_MARK_ENTRY
}
return ret;
@@ -2119,8 +2026,7 @@ static const char *shada_format_entry(const ShadaEntry entry)
/// @param[in] entry ShaDa entry to format.
///
/// @return string representing ShaDa entry in a static buffer.
-static const char *shada_format_pfreed_entry(
- const PossiblyFreedShadaEntry pfs_entry)
+static const char *shada_format_pfreed_entry(const PossiblyFreedShadaEntry pfs_entry)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_UNUSED FUNC_ATTR_NONNULL_RET
{
char *ret = (char *)shada_format_entry(pfs_entry.data);
@@ -2136,10 +2042,11 @@ static const char *shada_format_pfreed_entry(
/// @param[in,out] ret_wms Location where results are saved.
/// @param[out] packer MessagePack packer for entries which are not
/// merged.
-static inline ShaDaWriteResult shada_read_when_writing(
- ShaDaReadDef *const sd_reader, const unsigned srni_flags,
- const size_t max_kbyte, WriteMergerState *const wms,
- msgpack_packer *const packer)
+static inline ShaDaWriteResult shada_read_when_writing(ShaDaReadDef *const sd_reader,
+ const unsigned srni_flags,
+ const size_t max_kbyte,
+ WriteMergerState *const wms,
+ msgpack_packer *const packer)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
ShaDaWriteResult ret = kSDWriteSuccessfull;
@@ -2149,217 +2056,202 @@ static inline ShaDaWriteResult shada_read_when_writing(
max_kbyte))
!= kSDReadStatusFinished) {
switch (srni_ret) {
- case kSDReadStatusSuccess: {
- break;
- }
- case kSDReadStatusFinished: {
- // Should be handled by the while condition.
- abort();
- }
- case kSDReadStatusNotShaDa: {
- ret = kSDWriteReadNotShada;
- FALLTHROUGH;
- }
- case kSDReadStatusReadError: {
- return ret;
- }
- case kSDReadStatusMalformed: {
- continue;
- }
+ case kSDReadStatusSuccess:
+ break;
+ case kSDReadStatusFinished:
+ // Should be handled by the while condition.
+ abort();
+ case kSDReadStatusNotShaDa:
+ ret = kSDWriteReadNotShada;
+ FALLTHROUGH;
+ case kSDReadStatusReadError:
+ return ret;
+ case kSDReadStatusMalformed:
+ continue;
}
#define COMPARE_WITH_ENTRY(wms_entry_, entry) \
- do { \
- PossiblyFreedShadaEntry *const wms_entry = (wms_entry_); \
- if (wms_entry->data.type != kSDItemMissing) { \
- if (wms_entry->data.timestamp >= (entry).timestamp) { \
- shada_free_shada_entry(&(entry)); \
- break; \
- } \
- if (wms_entry->can_free_entry) { \
- shada_free_shada_entry(&wms_entry->data); \
- } \
+ do { \
+ PossiblyFreedShadaEntry *const wms_entry = (wms_entry_); \
+ if (wms_entry->data.type != kSDItemMissing) { \
+ if (wms_entry->data.timestamp >= (entry).timestamp) { \
+ shada_free_shada_entry(&(entry)); \
+ break; \
+ } \
+ if (wms_entry->can_free_entry) { \
+ shada_free_shada_entry(&wms_entry->data); \
} \
- *wms_entry = pfs_entry; \
- } while (0)
+ } \
+ *wms_entry = pfs_entry; \
+ } while (0)
const PossiblyFreedShadaEntry pfs_entry = {
.can_free_entry = true,
.data = entry,
};
switch (entry.type) {
- case kSDItemMissing: {
+ case kSDItemMissing:
+ break;
+ case kSDItemHeader:
+ case kSDItemBufferList:
+ abort();
+ case kSDItemUnknown:
+ ret = shada_pack_entry(packer, entry, 0);
+ shada_free_shada_entry(&entry);
+ break;
+ case kSDItemSearchPattern:
+ COMPARE_WITH_ENTRY((entry.data.search_pattern.is_substitute_pattern
+ ? &wms->sub_search_pattern
+ : &wms->search_pattern), entry);
+ break;
+ case kSDItemSubString:
+ COMPARE_WITH_ENTRY(&wms->replacement, entry);
+ break;
+ case kSDItemHistoryEntry:
+ if (entry.data.history_item.histtype >= HIST_COUNT) {
+ ret = shada_pack_entry(packer, entry, 0);
+ shada_free_shada_entry(&entry);
break;
}
- case kSDItemHeader:
- case kSDItemBufferList: {
- abort();
+ if (wms->hms[entry.data.history_item.histtype].hmll.size != 0) {
+ hms_insert(&wms->hms[entry.data.history_item.histtype], entry, true,
+ true);
+ } else {
+ shada_free_shada_entry(&entry);
}
- case kSDItemUnknown: {
+ break;
+ case kSDItemRegister: {
+ const int idx = op_reg_index(entry.data.reg.name);
+ if (idx < 0) {
ret = shada_pack_entry(packer, entry, 0);
shada_free_shada_entry(&entry);
break;
}
- case kSDItemSearchPattern: {
- COMPARE_WITH_ENTRY((entry.data.search_pattern.is_substitute_pattern
- ? &wms->sub_search_pattern
- : &wms->search_pattern), entry);
- break;
- }
- case kSDItemSubString: {
- COMPARE_WITH_ENTRY(&wms->replacement, entry);
- break;
+ COMPARE_WITH_ENTRY(&wms->registers[idx], entry);
+ break;
+ }
+ case kSDItemVariable:
+ if (!in_strset(&wms->dumped_variables, entry.data.global_var.name)) {
+ ret = shada_pack_entry(packer, entry, 0);
}
- case kSDItemHistoryEntry: {
- if (entry.data.history_item.histtype >= HIST_COUNT) {
- ret = shada_pack_entry(packer, entry, 0);
- shada_free_shada_entry(&entry);
- break;
+ shada_free_shada_entry(&entry);
+ break;
+ case kSDItemGlobalMark:
+ if (ascii_isdigit(entry.data.filemark.name)) {
+ bool processed_mark = false;
+ // Completely ignore numbered mark names, make a list sorted by
+ // timestamp.
+ for (size_t i = ARRAY_SIZE(wms->numbered_marks); i > 0; i--) {
+ ShadaEntry wms_entry = wms->numbered_marks[i - 1].data;
+ if (wms_entry.type != kSDItemGlobalMark) {
+ continue;
+ }
+ // Ignore duplicates.
+ if (wms_entry.timestamp == entry.timestamp
+ && (wms_entry.data.filemark.additional_data == NULL
+ && entry.data.filemark.additional_data == NULL)
+ && marks_equal(wms_entry.data.filemark.mark,
+ entry.data.filemark.mark)
+ && strcmp(wms_entry.data.filemark.fname,
+ entry.data.filemark.fname) == 0) {
+ shada_free_shada_entry(&entry);
+ processed_mark = true;
+ break;
+ }
+ if (wms_entry.timestamp >= entry.timestamp) {
+ processed_mark = true;
+ if (i < ARRAY_SIZE(wms->numbered_marks)) {
+ replace_numbered_mark(wms, i, pfs_entry);
+ } else {
+ shada_free_shada_entry(&entry);
+ }
+ break;
+ }
}
- if (wms->hms[entry.data.history_item.histtype].hmll.size != 0) {
- hms_insert(&wms->hms[entry.data.history_item.histtype], entry, true,
- true);
- } else {
- shada_free_shada_entry(&entry);
+ if (!processed_mark) {
+ replace_numbered_mark(wms, 0, pfs_entry);
}
- break;
- }
- case kSDItemRegister: {
- const int idx = op_reg_index(entry.data.reg.name);
+ } else {
+ const int idx = mark_global_index(entry.data.filemark.name);
if (idx < 0) {
ret = shada_pack_entry(packer, entry, 0);
shada_free_shada_entry(&entry);
break;
}
- COMPARE_WITH_ENTRY(&wms->registers[idx], entry);
- break;
+ COMPARE_WITH_ENTRY(&wms->global_marks[idx], entry);
}
- case kSDItemVariable: {
- if (!in_strset(&wms->dumped_variables, entry.data.global_var.name)) {
- ret = shada_pack_entry(packer, entry, 0);
- }
+ break;
+ case kSDItemChange:
+ case kSDItemLocalMark: {
+ if (shada_removable(entry.data.filemark.fname)) {
shada_free_shada_entry(&entry);
break;
}
- case kSDItemGlobalMark: {
- if (ascii_isdigit(entry.data.filemark.name)) {
- bool processed_mark = false;
- // Completely ignore numbered mark names, make a list sorted by
- // timestamp.
- for (size_t i = ARRAY_SIZE(wms->numbered_marks); i > 0; i--) {
- ShadaEntry wms_entry = wms->numbered_marks[i - 1].data;
- if (wms_entry.type != kSDItemGlobalMark) {
- continue;
- }
- // Ignore duplicates.
- if (wms_entry.timestamp == entry.timestamp
- && (wms_entry.data.filemark.additional_data == NULL
- && entry.data.filemark.additional_data == NULL)
- && marks_equal(wms_entry.data.filemark.mark,
- entry.data.filemark.mark)
- && strcmp(wms_entry.data.filemark.fname,
- entry.data.filemark.fname) == 0) {
+ const char *const fname = (const char *)entry.data.filemark.fname;
+ khiter_t k;
+ int kh_ret;
+ k = kh_put(file_marks, &wms->file_marks, fname, &kh_ret);
+ FileMarks *const filemarks = &kh_val(&wms->file_marks, k);
+ if (kh_ret > 0) {
+ memset(filemarks, 0, sizeof(*filemarks));
+ }
+ if (entry.timestamp > filemarks->greatest_timestamp) {
+ filemarks->greatest_timestamp = entry.timestamp;
+ }
+ if (entry.type == kSDItemLocalMark) {
+ const int idx = mark_local_index(entry.data.filemark.name);
+ if (idx < 0) {
+ filemarks->additional_marks = xrealloc(filemarks->additional_marks,
+ (++filemarks->additional_marks_size
+ * sizeof(filemarks->additional_marks[0])));
+ filemarks->additional_marks[filemarks->additional_marks_size - 1] =
+ entry;
+ } else {
+ PossiblyFreedShadaEntry *const wms_entry = &filemarks->marks[idx];
+ if (wms_entry->data.type != kSDItemMissing) {
+ if (wms_entry->data.timestamp >= entry.timestamp) {
shada_free_shada_entry(&entry);
- processed_mark = true;
break;
}
- if (wms_entry.timestamp >= entry.timestamp) {
- processed_mark = true;
- if (i < ARRAY_SIZE(wms->numbered_marks)) {
- replace_numbered_mark(wms, i, pfs_entry);
- } else {
- shada_free_shada_entry(&entry);
+ if (wms_entry->can_free_entry) {
+ if (kh_key(&wms->file_marks, k)
+ == wms_entry->data.data.filemark.fname) {
+ kh_key(&wms->file_marks, k) = entry.data.filemark.fname;
}
- break;
+ shada_free_shada_entry(&wms_entry->data);
}
}
- if (!processed_mark) {
- replace_numbered_mark(wms, 0, pfs_entry);
- }
- } else {
- const int idx = mark_global_index(entry.data.filemark.name);
- if (idx < 0) {
- ret = shada_pack_entry(packer, entry, 0);
- shada_free_shada_entry(&entry);
- break;
- }
- COMPARE_WITH_ENTRY(&wms->global_marks[idx], entry);
- }
- break;
- }
- case kSDItemChange:
- case kSDItemLocalMark: {
- if (shada_removable(entry.data.filemark.fname)) {
- shada_free_shada_entry(&entry);
- break;
+ *wms_entry = pfs_entry;
}
- const char *const fname = (const char *) entry.data.filemark.fname;
- khiter_t k;
- int kh_ret;
- k = kh_put(file_marks, &wms->file_marks, fname, &kh_ret);
- FileMarks *const filemarks = &kh_val(&wms->file_marks, k);
- if (kh_ret > 0) {
- memset(filemarks, 0, sizeof(*filemarks));
- }
- if (entry.timestamp > filemarks->greatest_timestamp) {
- filemarks->greatest_timestamp = entry.timestamp;
- }
- if (entry.type == kSDItemLocalMark) {
- const int idx = mark_local_index(entry.data.filemark.name);
- if (idx < 0) {
- filemarks->additional_marks = xrealloc(
- filemarks->additional_marks,
- (++filemarks->additional_marks_size
- * sizeof(filemarks->additional_marks[0])));
- filemarks->additional_marks[filemarks->additional_marks_size - 1] =
- entry;
- } else {
- PossiblyFreedShadaEntry *const wms_entry = &filemarks->marks[idx];
- if (wms_entry->data.type != kSDItemMissing) {
- if (wms_entry->data.timestamp >= entry.timestamp) {
- shada_free_shada_entry(&entry);
- break;
- }
- if (wms_entry->can_free_entry) {
- if (kh_key(&wms->file_marks, k)
- == wms_entry->data.data.filemark.fname) {
- kh_key(&wms->file_marks, k) = entry.data.filemark.fname;
- }
- shada_free_shada_entry(&wms_entry->data);
- }
- }
- *wms_entry = pfs_entry;
- }
- } else {
+ } else {
#define FREE_POSSIBLY_FREED_SHADA_ENTRY(entry) \
- do { \
- if (entry.can_free_entry) { \
- shada_free_shada_entry(&entry.data); \
- } \
- } while (0)
+ do { \
+ if (entry.can_free_entry) { \
+ shada_free_shada_entry(&entry.data); \
+ } \
+ } while (0)
#define SDE_TO_PFSDE(entry) \
- ((PossiblyFreedShadaEntry) { .can_free_entry = true, .data = entry })
+ ((PossiblyFreedShadaEntry) { .can_free_entry = true, .data = entry })
#define AFTERFREE_DUMMY(entry)
#define DUMMY_IDX_ADJ(i)
- MERGE_JUMPS(filemarks->changes_size, filemarks->changes,
- PossiblyFreedShadaEntry, data.timestamp,
- data.data.filemark.mark, entry, true,
- FREE_POSSIBLY_FREED_SHADA_ENTRY, SDE_TO_PFSDE,
- DUMMY_IDX_ADJ, AFTERFREE_DUMMY);
- }
- break;
- }
- case kSDItemJump: {
- MERGE_JUMPS(wms->jumps_size, wms->jumps, PossiblyFreedShadaEntry,
- data.timestamp, data.data.filemark.mark, entry,
- strcmp(jl_entry.data.data.filemark.fname,
- entry.data.filemark.fname) == 0,
+ MERGE_JUMPS(filemarks->changes_size, filemarks->changes,
+ PossiblyFreedShadaEntry, data.timestamp,
+ data.data.filemark.mark, entry, true,
FREE_POSSIBLY_FREED_SHADA_ENTRY, SDE_TO_PFSDE,
DUMMY_IDX_ADJ, AFTERFREE_DUMMY);
+ }
+ break;
+ }
+ case kSDItemJump:
+ MERGE_JUMPS(wms->jumps_size, wms->jumps, PossiblyFreedShadaEntry,
+ data.timestamp, data.data.filemark.mark, entry,
+ strcmp(jl_entry.data.data.filemark.fname,
+ entry.data.filemark.fname) == 0,
+ FREE_POSSIBLY_FREED_SHADA_ENTRY, SDE_TO_PFSDE,
+ DUMMY_IDX_ADJ, AFTERFREE_DUMMY);
#undef FREE_POSSIBLY_FREED_SHADA_ENTRY
#undef SDE_TO_PFSDE
#undef DUMMY_IDX_ADJ
#undef AFTERFREE_DUMMY
- break;
- }
+ break;
}
}
#undef COMPARE_WITH_ENTRY
@@ -2372,8 +2264,7 @@ static inline ShaDaWriteResult shada_read_when_writing(
/// @param[in] removable_bufs Cache of buffers ignored due to their location.
///
/// @return true or false.
-static inline bool ignore_buf(const buf_T *const buf,
- khash_t(bufset) *const removable_bufs)
+static inline bool ignore_buf(const buf_T *const buf, khash_t(bufset) *const removable_bufs)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE
{
return (buf->b_ffname == NULL || !buf->b_p_bl || bt_quickfix(buf) \
@@ -2385,8 +2276,7 @@ static inline bool ignore_buf(const buf_T *const buf,
/// @param[in] removable_bufs Buffers which are ignored
///
/// @return ShadaEntry List of buffers to save, kSDItemBufferList entry.
-static inline ShadaEntry shada_get_buflist(
- khash_t(bufset) *const removable_bufs)
+static inline ShadaEntry shada_get_buflist(khash_t(bufset) *const removable_bufs)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE
{
int max_bufs = get_shada_parameter('%');
@@ -2400,14 +2290,14 @@ static inline ShadaEntry shada_get_buflist(
ShadaEntry buflist_entry = (ShadaEntry) {
.type = kSDItemBufferList,
- .timestamp = os_time(),
- .data = {
- .buffer_list = {
- .size = buf_count,
- .buffers = xmalloc(buf_count
- * sizeof(*buflist_entry.data.buffer_list.buffers)),
- },
+ .timestamp = os_time(),
+ .data = {
+ .buffer_list = {
+ .size = buf_count,
+ .buffers = xmalloc(buf_count
+ * sizeof(*buflist_entry.data.buffer_list.buffers)),
},
+ },
};
size_t i = 0;
FOR_ALL_BUFFERS(buf) {
@@ -2419,8 +2309,8 @@ static inline ShadaEntry shada_get_buflist(
}
buflist_entry.data.buffer_list.buffers[i] = (struct buffer_list_buffer) {
.pos = buf->b_last_cursor.mark,
- .fname = (char *)buf->b_ffname,
- .additional_data = buf->additional_data,
+ .fname = (char *)buf->b_ffname,
+ .additional_data = buf->additional_data,
};
i++;
}
@@ -2442,8 +2332,7 @@ static inline ShadaEntry shada_get_buflist(
/// saved.
static inline void add_search_pattern(PossiblyFreedShadaEntry *const ret_pse,
const SearchPatternGetter get_pattern,
- const bool is_substitute_pattern,
- const bool search_last_used,
+ const bool is_substitute_pattern, const bool search_last_used,
const bool search_highlighted)
FUNC_ATTR_ALWAYS_INLINE
{
@@ -2464,7 +2353,7 @@ static inline void add_search_pattern(PossiblyFreedShadaEntry *const ret_pse,
? defaults.data.search_pattern.has_line_offset
: pat.off.line),
.place_cursor_at_end = (
- is_substitute_pattern
+ is_substitute_pattern
? defaults.data.search_pattern.place_cursor_at_end
: pat.off.end),
.offset = (is_substitute_pattern
@@ -2488,8 +2377,7 @@ static inline void add_search_pattern(PossiblyFreedShadaEntry *const ret_pse,
///
/// @param[in] wms The WriteMergerState used when writing.
/// @param[in] max_reg_lines The maximum number of register lines.
-static inline void shada_initialize_registers(WriteMergerState *const wms,
- int max_reg_lines)
+static inline void shada_initialize_registers(WriteMergerState *const wms, int max_reg_lines)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
{
const void *reg_iter = NULL;
@@ -2513,7 +2401,7 @@ static inline void shada_initialize_registers(WriteMergerState *const wms,
.data = {
.reg = {
.contents = (char **)reg.y_array,
- .contents_size = (size_t)reg.y_size,
+ .contents_size = reg.y_size,
.type = reg.y_type,
.width = (size_t)(reg.y_type == kMTBlockWise ? reg.y_width : 0),
.additional_data = reg.additional_data,
@@ -2534,8 +2422,7 @@ static inline void shada_initialize_registers(WriteMergerState *const wms,
/// @param[out] wms Merger state to adjust.
/// @param[in] idx Index at which new mark should be placed.
/// @param[in] entry New mark.
-static inline void replace_numbered_mark(WriteMergerState *const wms,
- const size_t idx,
+static inline void replace_numbered_mark(WriteMergerState *const wms, const size_t idx,
const PossiblyFreedShadaEntry entry)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
{
@@ -2573,8 +2460,7 @@ static inline void find_removable_bufs(khash_t(bufset) *removable_bufs)
/// @param[in] sd_reader Structure containing file reader definition. If it is
/// not NULL then contents of this file will be merged
/// with current Neovim runtime.
-static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
- ShaDaReadDef *const sd_reader)
+static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef *const sd_reader)
FUNC_ATTR_NONNULL_ARG(1)
{
ShaDaWriteResult ret = kSDWriteSuccessfull;
@@ -2595,8 +2481,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
}
const bool dump_registers = (max_reg_lines != 0);
khash_t(bufset) removable_bufs = KHASH_EMPTY_TABLE(bufset);
- const size_t max_kbyte = (size_t) max_kbyte_i;
- const size_t num_marked_files = (size_t) get_shada_parameter('\'');
+ const size_t max_kbyte = (size_t)max_kbyte_i;
+ const size_t num_marked_files = (size_t)get_shada_parameter('\'');
const bool dump_global_marks = get_shada_parameter('f') != 0;
bool dump_history = false;
@@ -2609,20 +2495,21 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
if (num_saved > 0) {
dump_history = true;
dump_one_history[i] = true;
- hms_init(&wms->hms[i], i, (size_t) num_saved, sd_reader != NULL, false);
+ hms_init(&wms->hms[i], i, (size_t)num_saved, sd_reader != NULL, false);
} else {
dump_one_history[i] = false;
}
}
- const unsigned srni_flags = (unsigned) (
- kSDReadUndisableableData
- | kSDReadUnknown
- | (dump_history ? kSDReadHistory : 0)
- | (dump_registers ? kSDReadRegisters : 0)
- | (dump_global_vars ? kSDReadVariables : 0)
- | (dump_global_marks ? kSDReadGlobalMarks : 0)
- | (num_marked_files ? kSDReadLocalMarks | kSDReadChanges : 0));
+ const unsigned srni_flags = (unsigned)(
+ kSDReadUndisableableData
+ | kSDReadUnknown
+ | (dump_history ? kSDReadHistory : 0)
+ | (dump_registers ? kSDReadRegisters : 0)
+ | (dump_global_vars ? kSDReadVariables : 0)
+ | (dump_global_marks ? kSDReadGlobalMarks : 0)
+ | (num_marked_files ? kSDReadLocalMarks |
+ kSDReadChanges : 0));
msgpack_packer *const packer = msgpack_packer_new(sd_writer,
&msgpack_sd_writer_write);
@@ -2652,11 +2539,11 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
{ STATIC_CSTR_AS_STRING("version"),
STRING_OBJ(cstr_as_string(longVersion)) },
{ STATIC_CSTR_AS_STRING("max_kbyte"),
- INTEGER_OBJ((Integer) max_kbyte) },
+ INTEGER_OBJ((Integer)max_kbyte) },
{ STATIC_CSTR_AS_STRING("pid"),
- INTEGER_OBJ((Integer) os_get_pid()) },
+ INTEGER_OBJ((Integer)os_get_pid()) },
{ STATIC_CSTR_AS_STRING("encoding"),
- STRING_OBJ(cstr_as_string((char *) p_enc)) },
+ STRING_OBJ(cstr_as_string((char *)p_enc)) },
}),
}
}
@@ -2688,34 +2575,32 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
break;
}
switch (vartv.v_type) {
- case VAR_FUNC:
- case VAR_PARTIAL:
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ tv_clear(&vartv);
+ continue;
+ case VAR_DICT: {
+ dict_T *di = vartv.vval.v_dict;
+ int copyID = get_copyID();
+ if (!set_ref_in_ht(&di->dv_hashtab, copyID, NULL)
+ && copyID == di->dv_copyID) {
tv_clear(&vartv);
continue;
- case VAR_DICT:
- {
- dict_T *di = vartv.vval.v_dict;
- int copyID = get_copyID();
- if (!set_ref_in_ht(&di->dv_hashtab, copyID, NULL)
- && copyID == di->dv_copyID) {
- tv_clear(&vartv);
- continue;
- }
- break;
- }
- case VAR_LIST:
- {
- list_T *l = vartv.vval.v_list;
- int copyID = get_copyID();
- if (!set_ref_in_list(l, copyID, NULL)
- && copyID == l->lv_copyID) {
- tv_clear(&vartv);
- continue;
- }
- break;
- }
- default:
- break;
+ }
+ break;
+ }
+ case VAR_LIST: {
+ list_T *l = vartv.vval.v_list;
+ int copyID = get_copyID();
+ if (!set_ref_in_list(l, copyID, NULL)
+ && copyID == l->lv_copyID) {
+ tv_clear(&vartv);
+ continue;
+ }
+ break;
+ }
+ default:
+ break;
}
typval_T tgttv;
tv_copy(&vartv, &tgttv);
@@ -2725,7 +2610,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
.timestamp = cur_timestamp,
.data = {
.global_var = {
- .name = (char *) name,
+ .name = (char *)name,
.value = tgttv,
.additional_elements = NULL,
}
@@ -2740,7 +2625,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
tv_clear(&tgttv);
if (spe_ret == kSDWriteSuccessfull) {
int kh_ret;
- (void) kh_put(strset, &wms->dumped_variables, name, &kh_ret);
+ (void)kh_put(strset, &wms->dumped_variables, name, &kh_ret);
}
} while (var_iter != NULL);
}
@@ -2773,7 +2658,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
.timestamp = sub.timestamp,
.data = {
.sub_string = {
- .sub = (char *) sub.sub,
+ .sub = sub.sub,
.additional_elements = sub.additional_elements,
}
}
@@ -2795,17 +2680,17 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
const char *fname;
if (fm.fmark.fnum == 0) {
assert(fm.fname != NULL);
- if (shada_removable((const char *) fm.fname)) {
+ if (shada_removable((const char *)fm.fname)) {
continue;
}
- fname = (const char *) fm.fname;
+ fname = (const char *)fm.fname;
} else {
const buf_T *const buf = buflist_findnr(fm.fmark.fnum);
if (buf == NULL || buf->b_ffname == NULL
|| in_bufset(&removable_bufs, buf)) {
continue;
}
- fname = (const char *) buf->b_ffname;
+ fname = (const char *)buf->b_ffname;
}
const PossiblyFreedShadaEntry pf_entry = {
.can_free_entry = false,
@@ -2842,7 +2727,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
continue;
}
const void *local_marks_iter = NULL;
- const char *const fname = (const char *) buf->b_ffname;
+ const char *const fname = (const char *)buf->b_ffname;
khiter_t k;
int kh_ret;
k = kh_put(file_marks, &wms->file_marks, fname, &kh_ret);
@@ -2866,7 +2751,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
.filemark = {
.mark = fm.mark,
.name = name,
- .fname = (char *) fname,
+ .fname = (char *)fname,
.additional_data = fm.additional_data,
}
}
@@ -2886,7 +2771,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
.data = {
.filemark = {
.mark = fm.mark,
- .fname = (char *) fname,
+ .fname = (char *)fname,
.additional_data = fm.additional_data,
}
}
@@ -2896,13 +2781,13 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
filemarks->greatest_timestamp = fm.timestamp;
}
}
- filemarks->changes_size = (size_t) buf->b_changelistlen;
+ filemarks->changes_size = (size_t)buf->b_changelistlen;
}
}
if (sd_reader != NULL) {
- const ShaDaWriteResult srww_ret = shada_read_when_writing(
- sd_reader, srni_flags, max_kbyte, wms, packer);
+ const ShaDaWriteResult srww_ret = shada_read_when_writing(sd_reader, srni_flags, max_kbyte, wms,
+ packer);
if (srww_ret != kSDWriteSuccessfull) {
ret = srww_ret;
}
@@ -2968,7 +2853,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
const size_t file_markss_size = kh_size(&wms->file_marks);
FileMarks **const all_file_markss =
- xmalloc(file_markss_size * sizeof(*all_file_markss));
+ xmalloc(file_markss_size * sizeof(*all_file_markss));
FileMarks **cur_file_marks = all_file_markss;
for (khint_t i = kh_begin(&wms->file_marks); i != kh_end(&wms->file_marks);
i++) {
@@ -2976,7 +2861,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
*cur_file_marks++ = &kh_val(&wms->file_marks, i);
}
}
- qsort((void *) all_file_markss, file_markss_size, sizeof(*all_file_markss),
+ qsort((void *)all_file_markss, file_markss_size, sizeof(*all_file_markss),
&compare_file_marks);
const size_t file_markss_to_dump = MIN(num_marked_files, file_markss_size);
for (size_t i = 0; i < file_markss_to_dump; i++) {
@@ -3007,11 +2892,10 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
if (dump_one_history[i]) {
hms_insert_whole_neovim_history(&wms->hms[i]);
HMS_ITER(&wms->hms[i], cur_entry, {
- if (shada_pack_pfreed_entry(
- packer, (PossiblyFreedShadaEntry) {
- .data = cur_entry->data,
- .can_free_entry = cur_entry->can_free_entry,
- }, max_kbyte) == kSDWriteFailed) {
+ if (shada_pack_pfreed_entry(packer, (PossiblyFreedShadaEntry) {
+ .data = cur_entry->data,
+ .can_free_entry = cur_entry->can_free_entry,
+ }, max_kbyte) == kSDWriteFailed) {
ret = kSDWriteFailed;
break;
}
@@ -3037,7 +2921,6 @@ shada_write_exit:
return ret;
}
-#undef IGNORE_BUF
#undef PACK_STATIC_STR
/// Write ShaDa file to a given location
@@ -3082,7 +2965,7 @@ int shada_write_file(const char *const file, bool nomerge)
}
// Save permissions from the original file, with modifications:
- int perm = (int) os_getperm(fname);
+ int perm = (int)os_getperm(fname);
perm = (perm >= 0) ? ((perm & 0777) | 0600) : 0600;
// ^3 ^1 ^2 ^2,3
// 1: Strip SUID bit if any.
@@ -3090,8 +2973,7 @@ int shada_write_file(const char *const file, bool nomerge)
// 3: If somebody happened to delete the file after it was opened for
// reading use u=rw permissions.
shada_write_file_open: {}
- sd_writer.cookie = file_open_new(
- &error, tempname, kFileCreateOnly|kFileNoSymlink, perm);
+ sd_writer.cookie = file_open_new(&error, tempname, kFileCreateOnly|kFileNoSymlink, perm);
if (sd_writer.cookie == NULL) {
if (error == UV_EEXIST || error == UV_ELOOP) {
// File already exists, try another name
@@ -3118,11 +3000,11 @@ shada_write_file_open: {}
}
if (nomerge) {
shada_write_file_nomerge: {}
- char *const tail = path_tail_with_sep(fname);
+ char *const tail = (char *)path_tail_with_sep((char_u *)fname);
if (tail != fname) {
const char tail_save = *tail;
*tail = NUL;
- if (!os_isdir(fname)) {
+ if (!os_isdir((char_u *)fname)) {
int ret;
char *failed_dir;
if ((ret = os_mkdir_recurse(fname, 0700, &failed_dir)) != 0) {
@@ -3173,7 +3055,7 @@ shada_write_file_nomerge: {}
// overwrite a user’s viminfo file after a "su root", with a
// viminfo file that the user can't read.
FileInfo old_info;
- if (os_fileinfo((char *)fname, &old_info)) {
+ if (os_fileinfo(fname, &old_info)) {
if (getuid() == ROOT_UID) {
if (old_info.stat.st_uid != ROOT_UID
|| old_info.stat.st_gid != getgid()) {
@@ -3197,7 +3079,7 @@ shada_write_file_nomerge: {}
}
}
#endif
- if (vim_rename(tempname, fname) == -1) {
+ if (vim_rename((char_u *)tempname, (char_u *)fname) == -1) {
EMSG3(_(RNERR "Can't rename ShaDa file from %s to %s!"),
tempname, fname);
} else {
@@ -3244,8 +3126,7 @@ int shada_read_marks(void)
/// @param[in] missing_ok If true, do not error out when file is missing.
///
/// @return OK in case of success, FAIL otherwise.
-int shada_read_everything(const char *const fname, const bool forceit,
- const bool missing_ok)
+int shada_read_everything(const char *const fname, const bool forceit, const bool missing_ok)
{
return shada_read_file(fname,
kShaDaWantInfo|kShaDaWantMarks|kShaDaGetOldfiles
@@ -3259,81 +3140,71 @@ static void shada_free_shada_entry(ShadaEntry *const entry)
return;
}
switch (entry->type) {
- case kSDItemMissing: {
- break;
+ case kSDItemMissing:
+ break;
+ case kSDItemUnknown:
+ xfree(entry->data.unknown_item.contents);
+ break;
+ case kSDItemHeader:
+ api_free_dictionary(entry->data.header);
+ break;
+ case kSDItemChange:
+ case kSDItemJump:
+ case kSDItemGlobalMark:
+ case kSDItemLocalMark:
+ tv_dict_unref(entry->data.filemark.additional_data);
+ xfree(entry->data.filemark.fname);
+ break;
+ case kSDItemSearchPattern:
+ tv_dict_unref(entry->data.search_pattern.additional_data);
+ xfree(entry->data.search_pattern.pat);
+ break;
+ case kSDItemRegister:
+ tv_dict_unref(entry->data.reg.additional_data);
+ for (size_t i = 0; i < entry->data.reg.contents_size; i++) {
+ xfree(entry->data.reg.contents[i]);
}
- case kSDItemUnknown: {
- xfree(entry->data.unknown_item.contents);
- break;
- }
- case kSDItemHeader: {
- api_free_dictionary(entry->data.header);
- break;
- }
- case kSDItemChange:
- case kSDItemJump:
- case kSDItemGlobalMark:
- case kSDItemLocalMark: {
- tv_dict_unref(entry->data.filemark.additional_data);
- xfree(entry->data.filemark.fname);
- break;
- }
- case kSDItemSearchPattern: {
- tv_dict_unref(entry->data.search_pattern.additional_data);
- xfree(entry->data.search_pattern.pat);
- break;
- }
- case kSDItemRegister: {
- tv_dict_unref(entry->data.reg.additional_data);
- for (size_t i = 0; i < entry->data.reg.contents_size; i++) {
- xfree(entry->data.reg.contents[i]);
- }
- xfree(entry->data.reg.contents);
- break;
- }
- case kSDItemHistoryEntry: {
- tv_list_unref(entry->data.history_item.additional_elements);
- xfree(entry->data.history_item.string);
- break;
- }
- case kSDItemVariable: {
- tv_list_unref(entry->data.global_var.additional_elements);
- xfree(entry->data.global_var.name);
- tv_clear(&entry->data.global_var.value);
- break;
- }
- case kSDItemSubString: {
- tv_list_unref(entry->data.sub_string.additional_elements);
- xfree(entry->data.sub_string.sub);
- break;
- }
- case kSDItemBufferList: {
- for (size_t i = 0; i < entry->data.buffer_list.size; i++) {
- xfree(entry->data.buffer_list.buffers[i].fname);
- tv_dict_unref(entry->data.buffer_list.buffers[i].additional_data);
- }
- xfree(entry->data.buffer_list.buffers);
- break;
+ xfree(entry->data.reg.contents);
+ break;
+ case kSDItemHistoryEntry:
+ tv_list_unref(entry->data.history_item.additional_elements);
+ xfree(entry->data.history_item.string);
+ break;
+ case kSDItemVariable:
+ tv_list_unref(entry->data.global_var.additional_elements);
+ xfree(entry->data.global_var.name);
+ tv_clear(&entry->data.global_var.value);
+ break;
+ case kSDItemSubString:
+ tv_list_unref(entry->data.sub_string.additional_elements);
+ xfree(entry->data.sub_string.sub);
+ break;
+ case kSDItemBufferList:
+ for (size_t i = 0; i < entry->data.buffer_list.size; i++) {
+ xfree(entry->data.buffer_list.buffers[i].fname);
+ tv_dict_unref(entry->data.buffer_list.buffers[i].additional_data);
}
+ xfree(entry->data.buffer_list.buffers);
+ break;
}
}
#ifndef HAVE_BE64TOH
static inline uint64_t be64toh(uint64_t big_endian_64_bits)
{
-#ifdef ORDER_BIG_ENDIAN
+# ifdef ORDER_BIG_ENDIAN
return big_endian_64_bits;
-#else
+# else
// It may appear that when !defined(ORDER_BIG_ENDIAN) actual order is big
// endian. This variant is suboptimal, but it works regardless of actual
// order.
- uint8_t *buf = (uint8_t *) &big_endian_64_bits;
+ uint8_t *buf = (uint8_t *)&big_endian_64_bits;
uint64_t ret = 0;
for (size_t i = 8; i; i--) {
- ret |= ((uint64_t) buf[i - 1]) << ((8 - i) * 8);
+ ret |= ((uint64_t)buf[i - 1]) << ((8 - i) * 8);
}
return ret;
-#endif
+# endif
}
#endif
@@ -3346,8 +3217,7 @@ static inline uint64_t be64toh(uint64_t big_endian_64_bits)
/// @return kSDReadStatusSuccess if everything was OK, kSDReadStatusNotShaDa if
/// there were not enough bytes to read or kSDReadStatusReadError if
/// there was some error while reading.
-static ShaDaReadResult fread_len(ShaDaReadDef *const sd_reader,
- char *const buffer,
+static ShaDaReadResult fread_len(ShaDaReadDef *const sd_reader, char *const buffer,
const size_t length)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -3385,8 +3255,7 @@ static ShaDaReadResult fread_len(ShaDaReadDef *const sd_reader,
/// @return kSDReadStatusSuccess if reading was successful,
/// kSDReadStatusNotShaDa if there were not enough bytes to read or
/// kSDReadStatusReadError if reading failed for whatever reason.
-static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader,
- const int first_char,
+static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader, const int first_char,
uint64_t *const result)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -3401,42 +3270,37 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader,
emsgf(_(RCERR "Error while reading ShaDa file: "
"expected positive integer at position %" PRIu64
", but got nothing"),
- (uint64_t) fpos);
+ (uint64_t)fpos);
return kSDReadStatusNotShaDa;
}
}
if (~first_char & 0x80) {
// Positive fixnum
- *result = (uint64_t) ((uint8_t) first_char);
+ *result = (uint64_t)((uint8_t)first_char);
} else {
size_t length = 0;
switch (first_char) {
- case 0xCC: { // uint8
- length = 1;
- break;
- }
- case 0xCD: { // uint16
- length = 2;
- break;
- }
- case 0xCE: { // uint32
- length = 4;
- break;
- }
- case 0xCF: { // uint64
- length = 8;
- break;
- }
- default: {
- emsgf(_(RCERR "Error while reading ShaDa file: "
- "expected positive integer at position %" PRIu64),
- (uint64_t) fpos);
- return kSDReadStatusNotShaDa;
- }
+ case 0xCC: // uint8
+ length = 1;
+ break;
+ case 0xCD: // uint16
+ length = 2;
+ break;
+ case 0xCE: // uint32
+ length = 4;
+ break;
+ case 0xCF: // uint64
+ length = 8;
+ break;
+ default:
+ emsgf(_(RCERR "Error while reading ShaDa file: "
+ "expected positive integer at position %" PRIu64),
+ (uint64_t)fpos);
+ return kSDReadStatusNotShaDa;
}
uint64_t buf = 0;
- char *buf_u8 = (char *) &buf;
+ char *buf_u8 = (char *)&buf;
ShaDaReadResult fl_ret;
if ((fl_ret = fread_len(sd_reader, &(buf_u8[sizeof(buf)-length]), length))
!= kSDReadStatusSuccess) {
@@ -3448,24 +3312,24 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader,
}
#define READERR(entry_name, error_desc) \
- RERR "Error while reading ShaDa file: " \
- entry_name " entry at position %" PRIu64 " " \
- error_desc
+ RERR "Error while reading ShaDa file: " \
+ entry_name " entry at position %" PRIu64 " " \
+ error_desc
#define CHECK_KEY(key, expected) ( \
- key.via.str.size == sizeof(expected) - 1 \
- && STRNCMP(key.via.str.ptr, expected, sizeof(expected) - 1) == 0)
+ key.via.str.size == sizeof(expected) - 1 \
+ && STRNCMP(key.via.str.ptr, expected, sizeof(expected) - 1) == 0)
#define CLEAR_GA_AND_ERROR_OUT(ga) \
- do { \
- ga_clear(&ga); \
- goto shada_read_next_item_error; \
- } while (0)
+ do { \
+ ga_clear(&ga); \
+ goto shada_read_next_item_error; \
+ } while (0)
#define ID(s) s
#define BINDUP(b) xmemdupz(b.ptr, b.size)
-#define TOINT(s) ((int) (s))
-#define TOLONG(s) ((long) (s))
-#define TOCHAR(s) ((char) (s))
-#define TOU8(s) ((uint8_t) (s))
-#define TOSIZE(s) ((size_t) (s))
+#define TOINT(s) ((int)(s))
+#define TOLONG(s) ((long)(s))
+#define TOCHAR(s) ((char)(s))
+#define TOU8(s) ((uint8_t)(s))
+#define TOSIZE(s) ((size_t)(s))
#define CHECKED_ENTRY(condition, error_desc, entry_name, obj, tgt, attr, \
proc) \
do { \
@@ -3486,18 +3350,16 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader,
}
#define CHECKED_KEY(un, entry_name, name, error_desc, tgt, condition, attr, \
proc) \
- else if (CHECK_KEY( /* NOLINT(readability/braces) */ \
- un.data.via.map.ptr[i].key, name)) { \
- CHECKED_ENTRY( \
- condition, "has " name " key value " error_desc, \
- entry_name, un.data.via.map.ptr[i].val, \
- tgt, attr, proc); \
+ else if (CHECK_KEY( /* NOLINT(readability/braces) */ \
+ un.data.via.map.ptr[i].key, name)) { \
+ CHECKED_ENTRY(condition, "has " name " key value " error_desc, \
+ entry_name, un.data.via.map.ptr[i].val, \
+ tgt, attr, proc); \
}
#define TYPED_KEY(un, entry_name, name, type_name, tgt, objtype, attr, proc) \
- CHECKED_KEY( \
- un, entry_name, name, "which is not " type_name, tgt, \
- un.data.via.map.ptr[i].val.type == MSGPACK_OBJECT_##objtype, \
- attr, proc)
+ CHECKED_KEY(un, entry_name, name, "which is not " type_name, tgt, \
+ un.data.via.map.ptr[i].val.type == MSGPACK_OBJECT_##objtype, \
+ attr, proc)
#define BOOLEAN_KEY(un, entry_name, name, tgt) \
TYPED_KEY(un, entry_name, name, "a boolean", tgt, BOOLEAN, boolean, ID)
#define STRING_KEY(un, entry_name, name, tgt) \
@@ -3506,19 +3368,18 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader,
TYPED_KEY(un, entry_name, name, "a binary", tgt, BIN, bin, \
BIN_CONVERTED)
#define INT_KEY(un, entry_name, name, tgt, proc) \
- CHECKED_KEY( \
- un, entry_name, name, "which is not an integer", tgt, \
- ((un.data.via.map.ptr[i].val.type \
- == MSGPACK_OBJECT_POSITIVE_INTEGER) \
- || (un.data.via.map.ptr[i].val.type \
- == MSGPACK_OBJECT_NEGATIVE_INTEGER)), \
- i64, proc)
+ CHECKED_KEY(un, entry_name, name, "which is not an integer", tgt, \
+ ((un.data.via.map.ptr[i].val.type \
+ == MSGPACK_OBJECT_POSITIVE_INTEGER) \
+ || (un.data.via.map.ptr[i].val.type \
+ == MSGPACK_OBJECT_NEGATIVE_INTEGER)), \
+ i64, proc)
#define INTEGER_KEY(un, entry_name, name, tgt) \
INT_KEY(un, entry_name, name, tgt, TOINT)
#define LONG_KEY(un, entry_name, name, tgt) \
INT_KEY(un, entry_name, name, tgt, TOLONG)
#define ADDITIONAL_KEY(un) \
- else { /* NOLINT(readability/braces) */ \
+ else { /* NOLINT(readability/braces) */ \
ga_grow(&ad_ga, 1); \
memcpy(((char *)ad_ga.ga_data) + ((size_t)ad_ga.ga_len \
* sizeof(*un.data.via.map.ptr)), \
@@ -3526,57 +3387,56 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader,
sizeof(*un.data.via.map.ptr)); \
ad_ga.ga_len++; \
}
-#define CONVERTED(str, len) (xmemdupz((str), (len)))
-#define BIN_CONVERTED(b) CONVERTED(b.ptr, b.size)
+#define BIN_CONVERTED(b) (xmemdupz((b.ptr), (b.size)))
#define SET_ADDITIONAL_DATA(tgt, name) \
- do { \
- if (ad_ga.ga_len) { \
- msgpack_object obj = { \
- .type = MSGPACK_OBJECT_MAP, \
- .via = { \
- .map = { \
- .size = (uint32_t) ad_ga.ga_len, \
- .ptr = ad_ga.ga_data, \
- } \
- } \
- }; \
- typval_T adtv; \
- if (msgpack_to_vim(obj, &adtv) == FAIL \
- || adtv.v_type != VAR_DICT) { \
- emsgf(_(READERR(name, \
- "cannot be converted to a VimL dictionary")), \
- initial_fpos); \
- ga_clear(&ad_ga); \
- tv_clear(&adtv); \
- goto shada_read_next_item_error; \
+ do { \
+ if (ad_ga.ga_len) { \
+ msgpack_object obj = { \
+ .type = MSGPACK_OBJECT_MAP, \
+ .via = { \
+ .map = { \
+ .size = (uint32_t)ad_ga.ga_len, \
+ .ptr = ad_ga.ga_data, \
} \
- tgt = adtv.vval.v_dict; \
} \
+ }; \
+ typval_T adtv; \
+ if (msgpack_to_vim(obj, &adtv) == FAIL \
+ || adtv.v_type != VAR_DICT) { \
+ emsgf(_(READERR(name, \
+ "cannot be converted to a VimL dictionary")), \
+ initial_fpos); \
ga_clear(&ad_ga); \
- } while (0)
+ tv_clear(&adtv); \
+ goto shada_read_next_item_error; \
+ } \
+ tgt = adtv.vval.v_dict; \
+ } \
+ ga_clear(&ad_ga); \
+ } while (0)
#define SET_ADDITIONAL_ELEMENTS(src, src_maxsize, tgt, name) \
- do { \
- if ((src).size > (size_t) (src_maxsize)) { \
- msgpack_object obj = { \
- .type = MSGPACK_OBJECT_ARRAY, \
- .via = { \
- .array = { \
- .size = ((src).size - (uint32_t) (src_maxsize)), \
- .ptr = (src).ptr + (src_maxsize), \
- } \
- } \
- }; \
- typval_T aetv; \
- if (msgpack_to_vim(obj, &aetv) == FAIL) { \
- emsgf(_(READERR(name, "cannot be converted to a VimL list")), \
- initial_fpos); \
- tv_clear(&aetv); \
- goto shada_read_next_item_error; \
+ do { \
+ if ((src).size > (size_t)(src_maxsize)) { \
+ msgpack_object obj = { \
+ .type = MSGPACK_OBJECT_ARRAY, \
+ .via = { \
+ .array = { \
+ .size = ((src).size - (uint32_t)(src_maxsize)), \
+ .ptr = (src).ptr + (src_maxsize), \
} \
- assert(aetv.v_type == VAR_LIST); \
- (tgt) = aetv.vval.v_list; \
} \
- } while (0)
+ }; \
+ typval_T aetv; \
+ if (msgpack_to_vim(obj, &aetv) == FAIL) { \
+ emsgf(_(READERR(name, "cannot be converted to a VimL list")), \
+ initial_fpos); \
+ tv_clear(&aetv); \
+ goto shada_read_next_item_error; \
+ } \
+ assert(aetv.v_type == VAR_LIST); \
+ (tgt) = aetv.vval.v_list; \
+ } \
+ } while (0)
/// Iterate over shada file contents
///
@@ -3588,10 +3448,8 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader,
/// greater then given.
///
/// @return Any value from ShaDaReadResult enum.
-static ShaDaReadResult shada_read_next_item(ShaDaReadDef *const sd_reader,
- ShadaEntry *const entry,
- const unsigned flags,
- const size_t max_kbyte)
+static ShaDaReadResult shada_read_next_item(ShaDaReadDef *const sd_reader, ShadaEntry *const entry,
+ const unsigned flags, const size_t max_kbyte)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
ShaDaReadResult ret = kSDReadStatusMalformed;
@@ -3607,11 +3465,11 @@ shada_read_next_item_start:
// First: manually unpack type, timestamp and length.
// This is needed to avoid both seeking and having to maintain a buffer.
- uint64_t type_u64 = (uint64_t) kSDItemMissing;
+ uint64_t type_u64 = (uint64_t)kSDItemMissing;
uint64_t timestamp_u64;
uint64_t length_u64;
- const uint64_t initial_fpos = (uint64_t) sd_reader->fpos;
+ const uint64_t initial_fpos = (uint64_t)sd_reader->fpos;
const int first_char = read_char(sd_reader);
if (first_char == EOF && sd_reader->eof) {
return kSDReadStatusFinished;
@@ -3654,7 +3512,7 @@ shada_read_next_item_start:
if ((type_u64 > SHADA_LAST_ENTRY
? !(flags & kSDReadUnknown)
- : !((unsigned) (1 << type_u64) & flags))
+ : !((unsigned)(1 << type_u64) & flags))
|| (max_kbyte && length > max_kbyte * 1024)) {
// First entry is unknown or equal to "\n" (10)? Most likely this means that
// current file is not a ShaDa file because first item should normally be
@@ -3682,16 +3540,16 @@ shada_read_next_item_start:
entry->data.unknown_item.size = length;
entry->data.unknown_item.type = type_u64;
if (initial_fpos == 0) {
- const ShaDaReadResult spm_ret = shada_parse_msgpack(
- sd_reader, length, NULL, &entry->data.unknown_item.contents);
+ const ShaDaReadResult spm_ret = shada_parse_msgpack(sd_reader, length, NULL,
+ &entry->data.unknown_item.contents);
if (spm_ret != kSDReadStatusSuccess) {
entry->type = kSDItemMissing;
}
return spm_ret;
} else {
entry->data.unknown_item.contents = xmalloc(length);
- const ShaDaReadResult fl_ret = fread_len(
- sd_reader, entry->data.unknown_item.contents, length);
+ const ShaDaReadResult fl_ret =
+ fread_len(sd_reader, entry->data.unknown_item.contents, length);
if (fl_ret != kSDReadStatusSuccess) {
shada_free_shada_entry(entry);
entry->type = kSDItemMissing;
@@ -3711,373 +3569,367 @@ shada_read_next_item_start:
}
ret = kSDReadStatusMalformed;
entry->data = sd_default_values[type_u64].data;
- switch ((ShadaEntryType) type_u64) {
- case kSDItemHeader: {
- if (!msgpack_rpc_to_dictionary(&(unpacked.data), &(entry->data.header))) {
- emsgf(_(READERR("header", "is not a dictionary")), initial_fpos);
- goto shada_read_next_item_error;
- }
- break;
+ switch ((ShadaEntryType)type_u64) {
+ case kSDItemHeader:
+ if (!msgpack_rpc_to_dictionary(&(unpacked.data), &(entry->data.header))) {
+ emsgf(_(READERR("header", "is not a dictionary")), initial_fpos);
+ goto shada_read_next_item_error;
}
- case kSDItemSearchPattern: {
- if (unpacked.data.type != MSGPACK_OBJECT_MAP) {
- emsgf(_(READERR("search pattern", "is not a dictionary")),
- initial_fpos);
- goto shada_read_next_item_error;
- }
- garray_T ad_ga;
- ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1);
- for (size_t i = 0; i < unpacked.data.via.map.size; i++) {
- CHECK_KEY_IS_STR(unpacked, "search pattern")
- BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_MAGIC,
- entry->data.search_pattern.magic)
- BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_SMARTCASE,
- entry->data.search_pattern.smartcase)
- BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_HAS_LINE_OFFSET,
- entry->data.search_pattern.has_line_offset)
- BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_PLACE_CURSOR_AT_END,
- entry->data.search_pattern.place_cursor_at_end)
- BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_IS_LAST_USED,
- entry->data.search_pattern.is_last_used)
- BOOLEAN_KEY(unpacked, "search pattern",
- SEARCH_KEY_IS_SUBSTITUTE_PATTERN,
- entry->data.search_pattern.is_substitute_pattern)
- BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_HIGHLIGHTED,
- entry->data.search_pattern.highlighted)
- BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_BACKWARD,
- entry->data.search_pattern.search_backward)
- INTEGER_KEY(unpacked, "search pattern", SEARCH_KEY_OFFSET,
- entry->data.search_pattern.offset)
- CONVERTED_STRING_KEY(unpacked, "search pattern", SEARCH_KEY_PAT,
- entry->data.search_pattern.pat)
- ADDITIONAL_KEY(unpacked)
- }
- if (entry->data.search_pattern.pat == NULL) {
- emsgf(_(READERR("search pattern", "has no pattern")), initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
- }
- SET_ADDITIONAL_DATA(entry->data.search_pattern.additional_data,
- "search pattern");
- break;
+ break;
+ case kSDItemSearchPattern: {
+ if (unpacked.data.type != MSGPACK_OBJECT_MAP) {
+ emsgf(_(READERR("search pattern", "is not a dictionary")),
+ initial_fpos);
+ goto shada_read_next_item_error;
}
- case kSDItemChange:
- case kSDItemJump:
- case kSDItemGlobalMark:
- case kSDItemLocalMark: {
- if (unpacked.data.type != MSGPACK_OBJECT_MAP) {
- emsgf(_(READERR("mark", "is not a dictionary")), initial_fpos);
- goto shada_read_next_item_error;
- }
- garray_T ad_ga;
- ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1);
- for (size_t i = 0; i < unpacked.data.via.map.size; i++) {
- CHECK_KEY_IS_STR(unpacked, "mark")
- if (CHECK_KEY(unpacked.data.via.map.ptr[i].key, KEY_NAME_CHAR)) {
- if (type_u64 == kSDItemJump || type_u64 == kSDItemChange) {
- emsgf(_(READERR("mark", "has n key which is only valid for "
- "local and global mark entries")), initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
- }
- CHECKED_ENTRY(
- (unpacked.data.via.map.ptr[i].val.type
- == MSGPACK_OBJECT_POSITIVE_INTEGER),
- "has n key value which is not an unsigned integer",
- "mark", unpacked.data.via.map.ptr[i].val,
- entry->data.filemark.name, u64, TOCHAR);
+ garray_T ad_ga;
+ ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1);
+ for (size_t i = 0; i < unpacked.data.via.map.size; i++) {
+ CHECK_KEY_IS_STR(unpacked, "search pattern")
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_MAGIC,
+ entry->data.search_pattern.magic)
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_SMARTCASE,
+ entry->data.search_pattern.smartcase)
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_HAS_LINE_OFFSET,
+ entry->data.search_pattern.has_line_offset)
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_PLACE_CURSOR_AT_END,
+ entry->data.search_pattern.place_cursor_at_end)
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_IS_LAST_USED,
+ entry->data.search_pattern.is_last_used)
+ BOOLEAN_KEY(unpacked, "search pattern",
+ SEARCH_KEY_IS_SUBSTITUTE_PATTERN,
+ entry->data.search_pattern.is_substitute_pattern)
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_HIGHLIGHTED,
+ entry->data.search_pattern.highlighted)
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_BACKWARD,
+ entry->data.search_pattern.search_backward)
+ INTEGER_KEY(unpacked, "search pattern", SEARCH_KEY_OFFSET,
+ entry->data.search_pattern.offset)
+ CONVERTED_STRING_KEY(unpacked, "search pattern", SEARCH_KEY_PAT,
+ entry->data.search_pattern.pat)
+ ADDITIONAL_KEY(unpacked)
+ }
+ if (entry->data.search_pattern.pat == NULL) {
+ emsgf(_(READERR("search pattern", "has no pattern")), initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ }
+ SET_ADDITIONAL_DATA(entry->data.search_pattern.additional_data,
+ "search pattern");
+ break;
+ }
+ case kSDItemChange:
+ case kSDItemJump:
+ case kSDItemGlobalMark:
+ case kSDItemLocalMark: {
+ if (unpacked.data.type != MSGPACK_OBJECT_MAP) {
+ emsgf(_(READERR("mark", "is not a dictionary")), initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ garray_T ad_ga;
+ ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1);
+ for (size_t i = 0; i < unpacked.data.via.map.size; i++) {
+ CHECK_KEY_IS_STR(unpacked, "mark")
+ if (CHECK_KEY(unpacked.data.via.map.ptr[i].key, KEY_NAME_CHAR)) {
+ if (type_u64 == kSDItemJump || type_u64 == kSDItemChange) {
+ emsgf(_(READERR("mark", "has n key which is only valid for "
+ "local and global mark entries")), initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
}
- LONG_KEY(unpacked, "mark", KEY_LNUM, entry->data.filemark.mark.lnum)
- INTEGER_KEY(unpacked, "mark", KEY_COL, entry->data.filemark.mark.col)
- STRING_KEY(unpacked, "mark", KEY_FILE, entry->data.filemark.fname)
- ADDITIONAL_KEY(unpacked)
- }
- if (entry->data.filemark.fname == NULL) {
- emsgf(_(READERR("mark", "is missing file name")), initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
- }
- if (entry->data.filemark.mark.lnum <= 0) {
- emsgf(_(READERR("mark", "has invalid line number")), initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ CHECKED_ENTRY((unpacked.data.via.map.ptr[i].val.type
+ == MSGPACK_OBJECT_POSITIVE_INTEGER),
+ "has n key value which is not an unsigned integer",
+ "mark", unpacked.data.via.map.ptr[i].val,
+ entry->data.filemark.name, u64, TOCHAR);
}
- if (entry->data.filemark.mark.col < 0) {
- emsgf(_(READERR("mark", "has invalid column number")), initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
- }
- SET_ADDITIONAL_DATA(entry->data.filemark.additional_data, "mark");
- break;
+ LONG_KEY(unpacked, "mark", KEY_LNUM, entry->data.filemark.mark.lnum)
+ INTEGER_KEY(unpacked, "mark", KEY_COL, entry->data.filemark.mark.col)
+ STRING_KEY(unpacked, "mark", KEY_FILE, entry->data.filemark.fname)
+ ADDITIONAL_KEY(unpacked)
}
- case kSDItemRegister: {
- if (unpacked.data.type != MSGPACK_OBJECT_MAP) {
- emsgf(_(READERR("register", "is not a dictionary")), initial_fpos);
- goto shada_read_next_item_error;
- }
- garray_T ad_ga;
- ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1);
- for (size_t i = 0; i < unpacked.data.via.map.size; i++) {
- CHECK_KEY_IS_STR(unpacked, "register")
- if (CHECK_KEY(unpacked.data.via.map.ptr[i].key,
- REG_KEY_CONTENTS)) {
- if (unpacked.data.via.map.ptr[i].val.type != MSGPACK_OBJECT_ARRAY) {
- emsgf(_(READERR("register",
- "has " REG_KEY_CONTENTS
- " key with non-array value")),
- initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
- }
- if (unpacked.data.via.map.ptr[i].val.via.array.size == 0) {
- emsgf(_(READERR("register",
- "has " REG_KEY_CONTENTS " key with empty array")),
- initial_fpos);
+ if (entry->data.filemark.fname == NULL) {
+ emsgf(_(READERR("mark", "is missing file name")), initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ }
+ if (entry->data.filemark.mark.lnum <= 0) {
+ emsgf(_(READERR("mark", "has invalid line number")), initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ }
+ if (entry->data.filemark.mark.col < 0) {
+ emsgf(_(READERR("mark", "has invalid column number")), initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ }
+ SET_ADDITIONAL_DATA(entry->data.filemark.additional_data, "mark");
+ break;
+ }
+ case kSDItemRegister: {
+ if (unpacked.data.type != MSGPACK_OBJECT_MAP) {
+ emsgf(_(READERR("register", "is not a dictionary")), initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ garray_T ad_ga;
+ ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1);
+ for (size_t i = 0; i < unpacked.data.via.map.size; i++) {
+ CHECK_KEY_IS_STR(unpacked, "register")
+ if (CHECK_KEY(unpacked.data.via.map.ptr[i].key,
+ REG_KEY_CONTENTS)) {
+ if (unpacked.data.via.map.ptr[i].val.type != MSGPACK_OBJECT_ARRAY) {
+ emsgf(_(READERR("register",
+ "has " REG_KEY_CONTENTS
+ " key with non-array value")),
+ initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ }
+ if (unpacked.data.via.map.ptr[i].val.via.array.size == 0) {
+ emsgf(_(READERR("register",
+ "has " REG_KEY_CONTENTS " key with empty array")),
+ initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ }
+ const msgpack_object_array arr =
+ unpacked.data.via.map.ptr[i].val.via.array;
+ for (size_t j = 0; j < arr.size; j++) {
+ if (arr.ptr[j].type != MSGPACK_OBJECT_BIN) {
+ emsgf(_(READERR("register", "has " REG_KEY_CONTENTS " array "
+ "with non-binary value")), initial_fpos);
CLEAR_GA_AND_ERROR_OUT(ad_ga);
}
- const msgpack_object_array arr =
- unpacked.data.via.map.ptr[i].val.via.array;
- for (size_t j = 0; j < arr.size; j++) {
- if (arr.ptr[j].type != MSGPACK_OBJECT_BIN) {
- emsgf(_(READERR("register", "has " REG_KEY_CONTENTS " array "
- "with non-binary value")), initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
- }
- }
- entry->data.reg.contents_size = arr.size;
- entry->data.reg.contents = xmalloc(arr.size * sizeof(char *));
- for (size_t j = 0; j < arr.size; j++) {
- entry->data.reg.contents[j] = BIN_CONVERTED(arr.ptr[j].via.bin);
- }
}
- BOOLEAN_KEY(unpacked, "register", REG_KEY_UNNAMED,
- entry->data.reg.is_unnamed)
- TYPED_KEY(unpacked, "register", REG_KEY_TYPE, "an unsigned integer",
- entry->data.reg.type, POSITIVE_INTEGER, u64, TOU8)
- TYPED_KEY(unpacked, "register", KEY_NAME_CHAR, "an unsigned integer",
- entry->data.reg.name, POSITIVE_INTEGER, u64, TOCHAR)
- TYPED_KEY(unpacked, "register", REG_KEY_WIDTH, "an unsigned integer",
- entry->data.reg.width, POSITIVE_INTEGER, u64, TOSIZE)
- ADDITIONAL_KEY(unpacked)
- }
- if (entry->data.reg.contents == NULL) {
- emsgf(_(READERR("register", "has missing " REG_KEY_CONTENTS " array")),
- initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ entry->data.reg.contents_size = arr.size;
+ entry->data.reg.contents = xmalloc(arr.size * sizeof(char *));
+ for (size_t j = 0; j < arr.size; j++) {
+ entry->data.reg.contents[j] = BIN_CONVERTED(arr.ptr[j].via.bin);
+ }
}
- SET_ADDITIONAL_DATA(entry->data.reg.additional_data, "register");
- break;
+ BOOLEAN_KEY(unpacked, "register", REG_KEY_UNNAMED,
+ entry->data.reg.is_unnamed)
+ TYPED_KEY(unpacked, "register", REG_KEY_TYPE, "an unsigned integer",
+ entry->data.reg.type, POSITIVE_INTEGER, u64, TOU8)
+ TYPED_KEY(unpacked, "register", KEY_NAME_CHAR, "an unsigned integer",
+ entry->data.reg.name, POSITIVE_INTEGER, u64, TOCHAR)
+ TYPED_KEY(unpacked, "register", REG_KEY_WIDTH, "an unsigned integer",
+ entry->data.reg.width, POSITIVE_INTEGER, u64, TOSIZE)
+ ADDITIONAL_KEY(unpacked)
}
- case kSDItemHistoryEntry: {
- if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) {
- emsgf(_(READERR("history", "is not an array")), initial_fpos);
- goto shada_read_next_item_error;
- }
- if (unpacked.data.via.array.size < 2) {
- emsgf(_(READERR("history", "does not have enough elements")),
- initial_fpos);
+ if (entry->data.reg.contents == NULL) {
+ emsgf(_(READERR("register", "has missing " REG_KEY_CONTENTS " array")),
+ initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ }
+ SET_ADDITIONAL_DATA(entry->data.reg.additional_data, "register");
+ break;
+ }
+ case kSDItemHistoryEntry: {
+ if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) {
+ emsgf(_(READERR("history", "is not an array")), initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ if (unpacked.data.via.array.size < 2) {
+ emsgf(_(READERR("history", "does not have enough elements")),
+ initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ if (unpacked.data.via.array.ptr[0].type
+ != MSGPACK_OBJECT_POSITIVE_INTEGER) {
+ emsgf(_(READERR("history", "has wrong history type type")),
+ initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ if (unpacked.data.via.array.ptr[1].type
+ != MSGPACK_OBJECT_BIN) {
+ emsgf(_(READERR("history", "has wrong history string type")),
+ initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ if (memchr(unpacked.data.via.array.ptr[1].via.bin.ptr, 0,
+ unpacked.data.via.array.ptr[1].via.bin.size) != NULL) {
+ emsgf(_(READERR("history", "contains string with zero byte inside")),
+ initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ entry->data.history_item.histtype =
+ (uint8_t)unpacked.data.via.array.ptr[0].via.u64;
+ const bool is_hist_search =
+ entry->data.history_item.histtype == HIST_SEARCH;
+ if (is_hist_search) {
+ if (unpacked.data.via.array.size < 3) {
+ emsgf(_(READERR("search history",
+ "does not have separator character")), initial_fpos);
goto shada_read_next_item_error;
}
- if (unpacked.data.via.array.ptr[0].type
+ if (unpacked.data.via.array.ptr[2].type
!= MSGPACK_OBJECT_POSITIVE_INTEGER) {
- emsgf(_(READERR("history", "has wrong history type type")),
- initial_fpos);
- goto shada_read_next_item_error;
- }
- if (unpacked.data.via.array.ptr[1].type
- != MSGPACK_OBJECT_BIN) {
- emsgf(_(READERR("history", "has wrong history string type")),
- initial_fpos);
+ emsgf(_(READERR("search history",
+ "has wrong history separator type")), initial_fpos);
goto shada_read_next_item_error;
}
- if (memchr(unpacked.data.via.array.ptr[1].via.bin.ptr, 0,
- unpacked.data.via.array.ptr[1].via.bin.size) != NULL) {
- emsgf(_(READERR("history", "contains string with zero byte inside")),
- initial_fpos);
- goto shada_read_next_item_error;
- }
- entry->data.history_item.histtype =
- (uint8_t) unpacked.data.via.array.ptr[0].via.u64;
- const bool is_hist_search =
- entry->data.history_item.histtype == HIST_SEARCH;
- if (is_hist_search) {
- if (unpacked.data.via.array.size < 3) {
- emsgf(_(READERR("search history",
- "does not have separator character")), initial_fpos);
- goto shada_read_next_item_error;
- }
- if (unpacked.data.via.array.ptr[2].type
- != MSGPACK_OBJECT_POSITIVE_INTEGER) {
- emsgf(_(READERR("search history",
- "has wrong history separator type")), initial_fpos);
+ entry->data.history_item.sep =
+ (char)unpacked.data.via.array.ptr[2].via.u64;
+ }
+ size_t strsize;
+ strsize = (
+ unpacked.data.via.array.ptr[1].via.bin.size
+ + 1 // Zero byte
+ + 1); // Separator character
+ entry->data.history_item.string = xmalloc(strsize);
+ memcpy(entry->data.history_item.string,
+ unpacked.data.via.array.ptr[1].via.bin.ptr,
+ unpacked.data.via.array.ptr[1].via.bin.size);
+ entry->data.history_item.string[strsize - 2] = 0;
+ entry->data.history_item.string[strsize - 1] =
+ entry->data.history_item.sep;
+ SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, (2 + is_hist_search),
+ entry->data.history_item.additional_elements,
+ "history");
+ break;
+ }
+ case kSDItemVariable: {
+ if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) {
+ emsgf(_(READERR("variable", "is not an array")), initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ if (unpacked.data.via.array.size < 2) {
+ emsgf(_(READERR("variable", "does not have enough elements")),
+ initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ if (unpacked.data.via.array.ptr[0].type != MSGPACK_OBJECT_BIN) {
+ emsgf(_(READERR("variable", "has wrong variable name type")),
+ initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ entry->data.global_var.name =
+ xmemdupz(unpacked.data.via.array.ptr[0].via.bin.ptr,
+ unpacked.data.via.array.ptr[0].via.bin.size);
+ SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 2,
+ entry->data.global_var.additional_elements,
+ "variable");
+ bool is_blob = false;
+ // A msgpack BIN could be a String or Blob; an additional VAR_TYPE_BLOB
+ // element is stored with Blobs which can be used to differentiate them
+ if (unpacked.data.via.array.ptr[1].type == MSGPACK_OBJECT_BIN) {
+ const listitem_T *type_item
+ = tv_list_first(entry->data.global_var.additional_elements);
+ if (type_item != NULL) {
+ const typval_T *type_tv = TV_LIST_ITEM_TV(type_item);
+ if (type_tv->v_type != VAR_NUMBER
+ || type_tv->vval.v_number != VAR_TYPE_BLOB) {
+ emsgf(_(READERR("variable", "has wrong variable type")),
+ initial_fpos);
goto shada_read_next_item_error;
}
- entry->data.history_item.sep =
- (char) unpacked.data.via.array.ptr[2].via.u64;
+ is_blob = true;
}
- size_t strsize;
- strsize = (
- unpacked.data.via.array.ptr[1].via.bin.size
- + 1 // Zero byte
- + 1); // Separator character
- entry->data.history_item.string = xmalloc(strsize);
- memcpy(entry->data.history_item.string,
- unpacked.data.via.array.ptr[1].via.bin.ptr,
- unpacked.data.via.array.ptr[1].via.bin.size);
- entry->data.history_item.string[strsize - 2] = 0;
- entry->data.history_item.string[strsize - 1] =
- entry->data.history_item.sep;
- SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, (2 + is_hist_search),
- entry->data.history_item.additional_elements,
- "history");
- break;
}
- case kSDItemVariable: {
- if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) {
- emsgf(_(READERR("variable", "is not an array")), initial_fpos);
- goto shada_read_next_item_error;
- }
- if (unpacked.data.via.array.size < 2) {
- emsgf(_(READERR("variable", "does not have enough elements")),
- initial_fpos);
- goto shada_read_next_item_error;
- }
- if (unpacked.data.via.array.ptr[0].type != MSGPACK_OBJECT_BIN) {
- emsgf(_(READERR("variable", "has wrong variable name type")),
- initial_fpos);
- goto shada_read_next_item_error;
- }
- entry->data.global_var.name =
- xmemdupz(unpacked.data.via.array.ptr[0].via.bin.ptr,
- unpacked.data.via.array.ptr[0].via.bin.size);
- SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 2,
- entry->data.global_var.additional_elements,
- "variable");
- bool is_blob = false;
- // A msgpack BIN could be a String or Blob; an additional VAR_TYPE_BLOB
- // element is stored with Blobs which can be used to differentiate them
- if (unpacked.data.via.array.ptr[1].type == MSGPACK_OBJECT_BIN) {
- const listitem_T *type_item
- = tv_list_first(entry->data.global_var.additional_elements);
- if (type_item != NULL) {
- const typval_T *type_tv = TV_LIST_ITEM_TV(type_item);
- if (type_tv->v_type != VAR_NUMBER
- || type_tv->vval.v_number != VAR_TYPE_BLOB) {
- emsgf(_(READERR("variable", "has wrong variable type")),
- initial_fpos);
- goto shada_read_next_item_error;
- }
- is_blob = true;
- }
- }
- if (is_blob) {
- const msgpack_object_bin *const bin
- = &unpacked.data.via.array.ptr[1].via.bin;
- blob_T *const blob = tv_blob_alloc();
- ga_concat_len(&blob->bv_ga, bin->ptr, (size_t)bin->size);
- tv_blob_set_ret(&entry->data.global_var.value, blob);
- } else if (msgpack_to_vim(unpacked.data.via.array.ptr[1],
- &(entry->data.global_var.value)) == FAIL) {
- emsgf(_(READERR("variable", "has value that cannot "
- "be converted to the VimL value")), initial_fpos);
- goto shada_read_next_item_error;
- }
- break;
+ if (is_blob) {
+ const msgpack_object_bin *const bin
+ = &unpacked.data.via.array.ptr[1].via.bin;
+ blob_T *const blob = tv_blob_alloc();
+ ga_concat_len(&blob->bv_ga, bin->ptr, (size_t)bin->size);
+ tv_blob_set_ret(&entry->data.global_var.value, blob);
+ } else if (msgpack_to_vim(unpacked.data.via.array.ptr[1],
+ &(entry->data.global_var.value)) == FAIL) {
+ emsgf(_(READERR("variable", "has value that cannot "
+ "be converted to the VimL value")), initial_fpos);
+ goto shada_read_next_item_error;
}
- case kSDItemSubString: {
- if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) {
- emsgf(_(READERR("sub string", "is not an array")), initial_fpos);
- goto shada_read_next_item_error;
- }
- if (unpacked.data.via.array.size < 1) {
- emsgf(_(READERR("sub string", "does not have enough elements")),
- initial_fpos);
- goto shada_read_next_item_error;
- }
- if (unpacked.data.via.array.ptr[0].type != MSGPACK_OBJECT_BIN) {
- emsgf(_(READERR("sub string", "has wrong sub string type")),
- initial_fpos);
- goto shada_read_next_item_error;
- }
- entry->data.sub_string.sub =
- BIN_CONVERTED(unpacked.data.via.array.ptr[0].via.bin);
- SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 1,
- entry->data.sub_string.additional_elements,
- "sub string");
+ break;
+ }
+ case kSDItemSubString:
+ if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) {
+ emsgf(_(READERR("sub string", "is not an array")), initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ if (unpacked.data.via.array.size < 1) {
+ emsgf(_(READERR("sub string", "does not have enough elements")),
+ initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ if (unpacked.data.via.array.ptr[0].type != MSGPACK_OBJECT_BIN) {
+ emsgf(_(READERR("sub string", "has wrong sub string type")),
+ initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ entry->data.sub_string.sub =
+ BIN_CONVERTED(unpacked.data.via.array.ptr[0].via.bin);
+ SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 1,
+ entry->data.sub_string.additional_elements,
+ "sub string");
+ break;
+ case kSDItemBufferList:
+ if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) {
+ emsgf(_(READERR("buffer list", "is not an array")), initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ if (unpacked.data.via.array.size == 0) {
break;
}
- case kSDItemBufferList: {
- if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) {
- emsgf(_(READERR("buffer list", "is not an array")), initial_fpos);
- goto shada_read_next_item_error;
- }
- if (unpacked.data.via.array.size == 0) {
- break;
- }
- entry->data.buffer_list.buffers =
- xcalloc(unpacked.data.via.array.size,
- sizeof(*entry->data.buffer_list.buffers));
- for (size_t i = 0; i < unpacked.data.via.array.size; i++) {
- entry->data.buffer_list.size++;
- msgpack_unpacked unpacked_2 = (msgpack_unpacked) {
- .data = unpacked.data.via.array.ptr[i],
- };
+ entry->data.buffer_list.buffers =
+ xcalloc(unpacked.data.via.array.size,
+ sizeof(*entry->data.buffer_list.buffers));
+ for (size_t i = 0; i < unpacked.data.via.array.size; i++) {
+ entry->data.buffer_list.size++;
+ msgpack_unpacked unpacked_2 = (msgpack_unpacked) {
+ .data = unpacked.data.via.array.ptr[i],
+ };
+ {
+ if (unpacked_2.data.type != MSGPACK_OBJECT_MAP) {
+ emsgf(_(RERR "Error while reading ShaDa file: "
+ "buffer list at position %" PRIu64 " "
+ "contains entry that is not a dictionary"),
+ initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ entry->data.buffer_list.buffers[i].pos = default_pos;
+ garray_T ad_ga;
+ ga_init(&ad_ga, sizeof(*(unpacked_2.data.via.map.ptr)), 1);
{
- if (unpacked_2.data.type != MSGPACK_OBJECT_MAP) {
- emsgf(_(RERR "Error while reading ShaDa file: "
- "buffer list at position %" PRIu64 " "
- "contains entry that is not a dictionary"),
- initial_fpos);
- goto shada_read_next_item_error;
- }
- entry->data.buffer_list.buffers[i].pos = default_pos;
- garray_T ad_ga;
- ga_init(&ad_ga, sizeof(*(unpacked_2.data.via.map.ptr)), 1);
+ // XXX: Temporarily reassign `i` because the macros depend on it.
+ const size_t j = i;
{
- // XXX: Temporarily reassign `i` because the macros depend on it.
- const size_t j = i;
- {
- for (i = 0; i < unpacked_2.data.via.map.size; i++) { // -V535
- CHECK_KEY_IS_STR(unpacked_2, "buffer list entry")
- LONG_KEY(unpacked_2, "buffer list entry", KEY_LNUM,
- entry->data.buffer_list.buffers[j].pos.lnum)
- INTEGER_KEY(unpacked_2, "buffer list entry", KEY_COL,
- entry->data.buffer_list.buffers[j].pos.col)
- STRING_KEY(unpacked_2, "buffer list entry", KEY_FILE,
- entry->data.buffer_list.buffers[j].fname)
- ADDITIONAL_KEY(unpacked_2)
- }
+ for (i = 0; i < unpacked_2.data.via.map.size; i++) { // -V535
+ CHECK_KEY_IS_STR(unpacked_2, "buffer list entry")
+ LONG_KEY(unpacked_2, "buffer list entry", KEY_LNUM,
+ entry->data.buffer_list.buffers[j].pos.lnum)
+ INTEGER_KEY(unpacked_2, "buffer list entry", KEY_COL,
+ entry->data.buffer_list.buffers[j].pos.col)
+ STRING_KEY(unpacked_2, "buffer list entry", KEY_FILE,
+ entry->data.buffer_list.buffers[j].fname)
+ ADDITIONAL_KEY(unpacked_2)
}
- i = j; // XXX: Restore `i`.
}
- if (entry->data.buffer_list.buffers[i].pos.lnum <= 0) {
- emsgf(_(RERR "Error while reading ShaDa file: "
- "buffer list at position %" PRIu64 " "
- "contains entry with invalid line number"),
- initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
- }
- if (entry->data.buffer_list.buffers[i].pos.col < 0) {
- emsgf(_(RERR "Error while reading ShaDa file: "
- "buffer list at position %" PRIu64 " "
- "contains entry with invalid column number"),
- initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
- }
- if (entry->data.buffer_list.buffers[i].fname == NULL) {
- emsgf(_(RERR "Error while reading ShaDa file: "
- "buffer list at position %" PRIu64 " "
- "contains entry that does not have a file name"),
- initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
- }
- SET_ADDITIONAL_DATA(
- entry->data.buffer_list.buffers[i].additional_data,
- "buffer list entry");
+ i = j; // XXX: Restore `i`.
+ }
+ if (entry->data.buffer_list.buffers[i].pos.lnum <= 0) {
+ emsgf(_(RERR "Error while reading ShaDa file: "
+ "buffer list at position %" PRIu64 " "
+ "contains entry with invalid line number"),
+ initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ }
+ if (entry->data.buffer_list.buffers[i].pos.col < 0) {
+ emsgf(_(RERR "Error while reading ShaDa file: "
+ "buffer list at position %" PRIu64 " "
+ "contains entry with invalid column number"),
+ initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
}
+ if (entry->data.buffer_list.buffers[i].fname == NULL) {
+ emsgf(_(RERR "Error while reading ShaDa file: "
+ "buffer list at position %" PRIu64 " "
+ "contains entry that does not have a file name"),
+ initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ }
+ SET_ADDITIONAL_DATA(entry->data.buffer_list.buffers[i].additional_data,
+ "buffer list entry");
}
- break;
- }
- case kSDItemMissing:
- case kSDItemUnknown: {
- abort();
}
+ break;
+ case kSDItemMissing:
+ case kSDItemUnknown:
+ abort();
}
- entry->type = (ShadaEntryType) type_u64;
+ entry->type = (ShadaEntryType)type_u64;
ret = kSDReadStatusSuccess;
shada_read_next_item_end:
if (buf != NULL) {
@@ -4086,13 +3938,12 @@ shada_read_next_item_end:
}
return ret;
shada_read_next_item_error:
- entry->type = (ShadaEntryType) type_u64;
+ entry->type = (ShadaEntryType)type_u64;
shada_free_shada_entry(entry);
entry->type = kSDItemMissing;
goto shada_read_next_item_end;
}
#undef BIN_CONVERTED
-#undef CONVERTED
#undef CHECK_KEY
#undef BOOLEAN_KEY
#undef CONVERTED_STRING_KEY
@@ -4121,17 +3972,17 @@ shada_read_next_item_error:
static bool shada_removable(const char *name)
FUNC_ATTR_WARN_UNUSED_RESULT
{
- char *p;
+ char *p;
char part[MAXPATHL + 1];
bool retval = false;
- char *new_name = home_replace_save(NULL, name);
- for (p = (char *) p_shada; *p; ) {
- (void) copy_option_part(&p, part, ARRAY_SIZE(part), ", ");
+ char *new_name = (char *)home_replace_save(NULL, (char_u *)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, part + 1, NameBuff, MAXPATHL, true);
+ home_replace(NULL, (char_u *)(part + 1), (char_u *)NameBuff, MAXPATHL, true);
size_t n = STRLEN(NameBuff);
- if (mb_strnicmp(NameBuff, new_name, n) == 0) {
+ if (mb_strnicmp((char_u *)NameBuff, (char_u *)new_name, n) == 0) {
retval = true;
break;
}
@@ -4148,8 +3999,8 @@ static bool shada_removable(const char *name)
/// location.
///
/// @return number of jumplist entries
-static inline size_t shada_init_jumps(
- PossiblyFreedShadaEntry *jumps, khash_t(bufset) *const removable_bufs)
+static inline size_t shada_init_jumps(PossiblyFreedShadaEntry *jumps,
+ khash_t(bufset) *const removable_bufs)
{
if (!curwin->w_jumplistlen) {
return 0;
@@ -4176,9 +4027,9 @@ static inline size_t shada_init_jumps(
: fm.fmark.fnum != 0) {
continue;
}
- const char *const fname = (char *) (fm.fmark.fnum == 0
+ const char *const fname = (char *)(fm.fmark.fnum == 0
? (fm.fname == NULL ? NULL : fm.fname)
- : buf ? buf->b_ffname : NULL);
+ : buf ? buf->b_ffname : NULL);
if (fname == NULL) {
continue;
}
@@ -4191,7 +4042,7 @@ static inline size_t shada_init_jumps(
.filemark = {
.name = NUL,
.mark = fm.fmark.mark,
- .fname = (char *) fname,
+ .fname = (char *)fname,
.additional_data = fm.fmark.additional_data,
}
}
@@ -4272,9 +4123,8 @@ void shada_encode_gvars(msgpack_sbuffer *const sbuf)
do {
typval_T vartv;
const char *name = NULL;
- var_iter = var_shada_iter(
- var_iter, &name, &vartv,
- VAR_FLAVOUR_DEFAULT | VAR_FLAVOUR_SESSION | VAR_FLAVOUR_SHADA);
+ var_iter = var_shada_iter(var_iter, &name, &vartv,
+ VAR_FLAVOUR_DEFAULT | VAR_FLAVOUR_SESSION | VAR_FLAVOUR_SHADA);
if (name == NULL) {
break;
}
@@ -4304,8 +4154,7 @@ void shada_encode_gvars(msgpack_sbuffer *const sbuf)
/// Wrapper for reading from msgpack_sbuffer.
///
/// @return number of bytes read.
-static ptrdiff_t read_sbuf(ShaDaReadDef *const sd_reader, void *const dest,
- const size_t size)
+static ptrdiff_t read_sbuf(ShaDaReadDef *const sd_reader, void *const dest, const size_t size)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
msgpack_sbuffer *sbuf = (msgpack_sbuffer *)sd_reader->cookie;
@@ -4327,8 +4176,7 @@ static ptrdiff_t read_sbuf(ShaDaReadDef *const sd_reader, void *const dest,
///
/// @return FAIL in case of failure, OK in case of success. May set
/// sd_reader->eof.
-static int sd_sbuf_reader_skip_read(ShaDaReadDef *const sd_reader,
- const size_t offset)
+static int sd_sbuf_reader_skip_read(ShaDaReadDef *const sd_reader, const size_t offset)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
msgpack_sbuffer *sbuf = (msgpack_sbuffer *)sd_reader->cookie;
@@ -4346,8 +4194,7 @@ static int sd_sbuf_reader_skip_read(ShaDaReadDef *const sd_reader,
///
/// @param[in] sbuf msgpack_sbuffer to read from.
/// @param[out] sd_reader Location where reader structure will be saved.
-static void open_shada_sbuf_for_reading(const msgpack_sbuffer *const sbuf,
- ShaDaReadDef *sd_reader)
+static void open_shada_sbuf_for_reading(const msgpack_sbuffer *const sbuf, ShaDaReadDef *sd_reader)
FUNC_ATTR_NONNULL_ALL
{
*sd_reader = (ShaDaReadDef) {
diff --git a/src/nvim/sign.c b/src/nvim/sign.c
index c6f59b42b8..1b100161bf 100644
--- a/src/nvim/sign.c
+++ b/src/nvim/sign.c
@@ -6,33 +6,33 @@
//
-#include "nvim/vim.h"
-#include "nvim/sign.h"
#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
-#include "nvim/ex_docmd.h"
#include "nvim/edit.h"
+#include "nvim/ex_docmd.h"
#include "nvim/fold.h"
#include "nvim/move.h"
+#include "nvim/option.h"
#include "nvim/screen.h"
+#include "nvim/sign.h"
#include "nvim/syntax.h"
-#include "nvim/option.h"
+#include "nvim/vim.h"
/// Struct to hold the sign properties.
typedef struct sign sign_T;
struct sign
{
- sign_T *sn_next; // next sign in list
- int sn_typenr; // type number of sign
- char_u *sn_name; // name of sign
- char_u *sn_icon; // name of pixmap
- char_u *sn_text; // text used instead of pixmap
- int sn_line_hl; // highlight ID for line
- int sn_text_hl; // highlight ID for text
- int sn_num_hl; // highlight ID for line number
+ sign_T *sn_next; // next sign in list
+ int sn_typenr; // type number of sign
+ char_u *sn_name; // name of sign
+ char_u *sn_icon; // name of pixmap
+ char_u *sn_text; // text used instead of pixmap
+ int sn_line_hl; // highlight ID for line
+ int sn_text_hl; // highlight ID for text
+ int sn_num_hl; // highlight ID for line number
};
static sign_T *first_sign = NULL;
@@ -42,19 +42,19 @@ static void sign_list_defined(sign_T *sp);
static void sign_undefine(sign_T *sp, sign_T *sp_prev);
static char *cmds[] = {
- "define",
+ "define",
#define SIGNCMD_DEFINE 0
- "undefine",
+ "undefine",
#define SIGNCMD_UNDEFINE 1
- "list",
+ "list",
#define SIGNCMD_LIST 2
- "place",
+ "place",
#define SIGNCMD_PLACE 3
- "unplace",
+ "unplace",
#define SIGNCMD_UNPLACE 4
- "jump",
+ "jump",
#define SIGNCMD_JUMP 5
- NULL
+ NULL
#define SIGNCMD_LAST 6
};
@@ -65,17 +65,17 @@ static int next_sign_id = 1; // next sign id in the global group
/// Initialize data needed for managing signs
void init_signs(void)
{
- hash_init(&sg_table); // sign group hash table
+ hash_init(&sg_table); // sign group hash table
}
/// A new sign in group 'groupname' is added. If the group is not present,
/// create it. Otherwise reference the group.
///
-static signgroup_T * sign_group_ref(const char_u *groupname)
+static signgroup_T *sign_group_ref(const char_u *groupname)
{
- hash_T hash;
- hashitem_T *hi;
- signgroup_T *group;
+ hash_T hash;
+ hashitem_T *hi;
+ signgroup_T *group;
hash = hash_hash(groupname);
hi = hash_lookup(&sg_table, (char *)groupname, STRLEN(groupname), hash);
@@ -100,7 +100,7 @@ static signgroup_T * sign_group_ref(const char_u *groupname)
/// removed, then remove the group.
static void sign_group_unref(char_u *groupname)
{
- hashitem_T *hi;
+ hashitem_T *hi;
signgroup_T *group;
hi = hash_find(&sg_table, groupname);
@@ -120,10 +120,10 @@ static void sign_group_unref(char_u *groupname)
/// or in a named group. If 'group' is '*', then the sign is part of the group.
bool sign_in_group(sign_entry_T *sign, const char_u *group)
{
- return ((group != NULL && STRCMP(group, "*") == 0)
- || (group == NULL && sign->se_group == NULL)
- || (group != NULL && sign->se_group != NULL
- && STRCMP(group, sign->se_group->sg_name) == 0));
+ return ((group != NULL && STRCMP(group, "*") == 0)
+ || (group == NULL && sign->se_group == NULL)
+ || (group != NULL && sign->se_group != NULL
+ && STRCMP(group, sign->se_group->sg_name) == 0));
}
/// Get the next free sign identifier in the specified group
@@ -166,17 +166,19 @@ int sign_group_get_next_signid(buf_T *buf, const char_u *groupname)
/// Insert a new sign into the signlist for buffer 'buf' between the 'prev' and
/// 'next' signs.
-static void insert_sign(
- buf_T *buf, // buffer to store sign in
- sign_entry_T *prev, // previous sign entry
- sign_entry_T *next, // next sign entry
- int id, // sign ID
- const char_u *group, // sign group; NULL for global group
- int prio, // sign priority
- linenr_T lnum, // line number which gets the mark
- int typenr, // typenr of sign we are adding
- bool has_text_or_icon // sign has text or icon
-)
+///
+/// @param buf buffer to store sign in
+/// @param prev previous sign entry
+/// @param next next sign entry
+/// @param id sign ID
+/// @param group sign group; NULL for global group
+/// @param prio sign priority
+/// @param lnum line number which gets the mark
+/// @param typenr typenr of sign we are adding
+/// @param has_text_or_icon sign has text or icon
+static void insert_sign(buf_T *buf, sign_entry_T *prev, sign_entry_T *next, int id,
+ const char_u *group, int prio, linenr_T lnum, int typenr,
+ bool has_text_or_icon)
{
sign_entry_T *newsign = xmalloc(sizeof(sign_entry_T));
newsign->se_id = id;
@@ -212,18 +214,19 @@ static void insert_sign(
}
/// Insert a new sign sorted by line number and sign priority.
-static void insert_sign_by_lnum_prio(
- buf_T *buf, // buffer to store sign in
- sign_entry_T *prev, // previous sign entry
- int id, // sign ID
- const char_u *group, // sign group; NULL for global group
- int prio, // sign priority
- linenr_T lnum, // line number which gets the mark
- int typenr, // typenr of sign we are adding
- bool has_text_or_icon // sign has text or icon
-)
+///
+/// @param buf buffer to store sign in
+/// @param prev previous sign entry
+/// @param id sign ID
+/// @param group sign group; NULL for global group
+/// @param prio sign priority
+/// @param lnum line number which gets the mark
+/// @param typenr typenr of sign we are adding
+/// @param has_text_or_icon sign has text or icon
+static void insert_sign_by_lnum_prio(buf_T *buf, sign_entry_T *prev, int id, const char_u *group,
+ int prio, linenr_T lnum, int typenr, bool has_text_or_icon)
{
- sign_entry_T *sign;
+ sign_entry_T *sign;
// keep signs sorted by lnum, priority and id: insert new sign at
// the proper position in the list for this lnum.
@@ -242,9 +245,9 @@ static void insert_sign_by_lnum_prio(
}
/// Get the name of a sign by its typenr.
-char_u * sign_typenr2name(int typenr)
+char_u *sign_typenr2name(int typenr)
{
- sign_T *sp;
+ sign_T *sp;
for (sp = first_sign; sp != NULL; sp = sp->sn_next) {
if (sp->sn_typenr == typenr) {
@@ -255,9 +258,9 @@ char_u * sign_typenr2name(int typenr)
}
/// Return information about a sign in a Dict
-dict_T * sign_get_info(sign_entry_T *sign)
+dict_T *sign_get_info(sign_entry_T *sign)
{
- dict_T *d = tv_dict_alloc();
+ dict_T *d = tv_dict_alloc();
tv_dict_add_nr(d, S_LEN("id"), sign->se_id);
tv_dict_add_str(d, S_LEN("group"), ((sign->se_group == NULL)
? (char *)""
@@ -345,15 +348,16 @@ static void sign_sort_by_prio_on_line(buf_T *buf, sign_entry_T *sign)
/// Add the sign into the signlist. Find the right spot to do it though.
-void buf_addsign(
- buf_T *buf, // buffer to store sign in
- int id, // sign ID
- const char_u *groupname, // sign group
- int prio, // sign priority
- linenr_T lnum, // line number which gets the mark
- int typenr, // typenr of sign we are adding
- bool has_text_or_icon // sign has text or icon
-)
+///
+/// @param buf buffer to store sign in
+/// @param id sign ID
+/// @param groupname sign group
+/// @param prio sign priority
+/// @param lnum line number which gets the mark
+/// @param typenr typenr of sign we are adding
+/// @param has_text_or_icon sign has text or icon
+void buf_addsign(buf_T *buf, int id, const char_u *groupname, int prio, linenr_T lnum, int typenr,
+ bool has_text_or_icon)
{
sign_entry_T *sign; // a sign in the signlist
sign_entry_T *prev; // the previous sign
@@ -368,53 +372,51 @@ void buf_addsign(
sign_sort_by_prio_on_line(buf, sign);
return;
} else if (lnum < sign->se_lnum) {
- insert_sign_by_lnum_prio(
- buf,
- prev,
- id,
- groupname,
- prio,
- lnum,
- typenr,
- has_text_or_icon);
+ insert_sign_by_lnum_prio(buf,
+ prev,
+ id,
+ groupname,
+ prio,
+ lnum,
+ typenr,
+ has_text_or_icon);
return;
}
prev = sign;
}
- insert_sign_by_lnum_prio(
- buf,
- prev,
- id,
- groupname,
- prio,
- lnum,
- typenr,
- has_text_or_icon);
+ insert_sign_by_lnum_prio(buf,
+ prev,
+ id,
+ groupname,
+ prio,
+ lnum,
+ typenr,
+ has_text_or_icon);
}
-// For an existing, placed sign "markId" change the type to "typenr".
-// Returns the line number of the sign, or zero if the sign is not found.
-linenr_T buf_change_sign_type(
- buf_T *buf, // buffer to store sign in
- int markId, // sign ID
- const char_u *group, // sign group
- int typenr, // typenr of sign we are adding
- int prio // sign priority
-)
+/// For an existing, placed sign "markId" change the type to "typenr".
+/// Returns the line number of the sign, or zero if the sign is not found.
+///
+/// @param buf buffer to store sign in
+/// @param markId sign ID
+/// @param group sign group
+/// @param typenr typenr of sign we are adding
+/// @param prio sign priority
+linenr_T buf_change_sign_type(buf_T *buf, int markId, const char_u *group, int typenr, int prio)
{
- sign_entry_T *sign; // a sign in the signlist
+ sign_entry_T *sign; // a sign in the signlist
- FOR_ALL_SIGNS_IN_BUF(buf, sign) {
- if (sign->se_id == markId && sign_in_group(sign, group)) {
- sign->se_typenr = typenr;
- sign->se_priority = prio;
- sign_sort_by_prio_on_line(buf, sign);
- return sign->se_lnum;
- }
+ FOR_ALL_SIGNS_IN_BUF(buf, sign) {
+ if (sign->se_id == markId && sign_in_group(sign, group)) {
+ sign->se_typenr = typenr;
+ sign->se_priority = prio;
+ sign_sort_by_prio_on_line(buf, sign);
+ return sign->se_lnum;
}
+ }
- return (linenr_T)0;
+ return (linenr_T)0;
}
/// Return the sign attrs which has the attribute specified by 'type'. Returns
@@ -426,44 +428,43 @@ linenr_T buf_change_sign_type(
/// @param max_signs the number of signs, with priority for the ones
/// with the highest Ids.
/// @return Attrs of the matching sign, or NULL
-sign_attrs_T * sign_get_attr(SignType type, sign_attrs_T sattrs[],
- int idx, int max_signs)
+sign_attrs_T *sign_get_attr(SignType type, sign_attrs_T sattrs[], int idx, int max_signs)
{
- sign_attrs_T *matches[SIGN_SHOW_MAX];
- int nr_matches = 0;
-
- for (int i = 0; i < SIGN_SHOW_MAX; i++) {
- if ( (type == SIGN_TEXT && sattrs[i].sat_text != NULL)
- || (type == SIGN_LINEHL && sattrs[i].sat_linehl != 0)
- || (type == SIGN_NUMHL && sattrs[i].sat_numhl != 0)) {
- matches[nr_matches] = &sattrs[i];
- nr_matches++;
- // attr list is sorted with most important (priority, id), thus we
- // may stop as soon as we have max_signs matches
- if (nr_matches >= max_signs) {
- break;
- }
- }
+ sign_attrs_T *matches[SIGN_SHOW_MAX];
+ int nr_matches = 0;
+
+ for (int i = 0; i < SIGN_SHOW_MAX; i++) {
+ if ( (type == SIGN_TEXT && sattrs[i].sat_text != NULL)
+ || (type == SIGN_LINEHL && sattrs[i].sat_linehl != 0)
+ || (type == SIGN_NUMHL && sattrs[i].sat_numhl != 0)) {
+ matches[nr_matches] = &sattrs[i];
+ nr_matches++;
+ // attr list is sorted with most important (priority, id), thus we
+ // may stop as soon as we have max_signs matches
+ if (nr_matches >= max_signs) {
+ break;
+ }
}
+ }
- if (nr_matches > idx) {
- return matches[nr_matches - idx - 1];
- }
+ if (nr_matches > idx) {
+ return matches[nr_matches - idx - 1];
+ }
- return NULL;
+ return NULL;
}
/// Lookup a sign by typenr. Returns NULL if sign is not found.
-static sign_T * find_sign_by_typenr(int typenr)
+static sign_T *find_sign_by_typenr(int typenr)
{
- sign_T *sp;
+ sign_T *sp;
- for (sp = first_sign; sp != NULL; sp = sp->sn_next) {
- if (sp->sn_typenr == typenr) {
- return sp;
- }
+ for (sp = first_sign; sp != NULL; sp = sp->sn_next) {
+ if (sp->sn_typenr == typenr) {
+ return sp;
}
- return NULL;
+ }
+ return NULL;
}
/// Return the attributes of all the signs placed on line 'lnum' in buffer
@@ -474,44 +475,44 @@ static sign_T * find_sign_by_typenr(int typenr)
/// @return Number of signs of which attrs were found
int buf_get_signattrs(buf_T *buf, linenr_T lnum, sign_attrs_T sattrs[])
{
- sign_entry_T *sign;
- sign_T *sp;
+ sign_entry_T *sign;
+ sign_T *sp;
- int nr_matches = 0;
+ int nr_matches = 0;
- FOR_ALL_SIGNS_IN_BUF(buf, sign) {
- if (sign->se_lnum > lnum) {
- // Signs are sorted by line number in the buffer. No need to check
- // for signs after the specified line number 'lnum'.
- break;
- }
+ FOR_ALL_SIGNS_IN_BUF(buf, sign) {
+ if (sign->se_lnum > lnum) {
+ // Signs are sorted by line number in the buffer. No need to check
+ // for signs after the specified line number 'lnum'.
+ break;
+ }
- if (sign->se_lnum == lnum) {
- sign_attrs_T sattr;
- memset(&sattr, 0, sizeof(sattr));
- sattr.sat_typenr = sign->se_typenr;
- sp = find_sign_by_typenr(sign->se_typenr);
- if (sp != NULL) {
- sattr.sat_text = sp->sn_text;
- if (sattr.sat_text != NULL && sp->sn_text_hl != 0) {
- sattr.sat_texthl = syn_id2attr(sp->sn_text_hl);
- }
- if (sp->sn_line_hl != 0) {
- sattr.sat_linehl = syn_id2attr(sp->sn_line_hl);
- }
- if (sp->sn_num_hl != 0) {
- sattr.sat_numhl = syn_id2attr(sp->sn_num_hl);
- }
- }
-
- sattrs[nr_matches] = sattr;
- nr_matches++;
- if (nr_matches == SIGN_SHOW_MAX) {
- break;
- }
+ if (sign->se_lnum == lnum) {
+ sign_attrs_T sattr;
+ memset(&sattr, 0, sizeof(sattr));
+ sattr.sat_typenr = sign->se_typenr;
+ sp = find_sign_by_typenr(sign->se_typenr);
+ if (sp != NULL) {
+ sattr.sat_text = sp->sn_text;
+ if (sattr.sat_text != NULL && sp->sn_text_hl != 0) {
+ sattr.sat_texthl = syn_id2attr(sp->sn_text_hl);
+ }
+ if (sp->sn_line_hl != 0) {
+ sattr.sat_linehl = syn_id2attr(sp->sn_line_hl);
+ }
+ if (sp->sn_num_hl != 0) {
+ sattr.sat_numhl = syn_id2attr(sp->sn_num_hl);
}
+ }
+
+ sattrs[nr_matches] = sattr;
+ nr_matches++;
+ if (nr_matches == SIGN_SHOW_MAX) {
+ break;
+ }
}
- return nr_matches;
+ }
+ return nr_matches;
}
/// Delete sign 'id' in group 'group' from buffer 'buf'.
@@ -520,14 +521,15 @@ int buf_get_signattrs(buf_T *buf, linenr_T lnum, sign_attrs_T sattrs[])
/// If 'group' is '*', then delete the sign in all the groups. If 'group' is
/// NULL, then delete the sign in the global group. Otherwise delete the sign in
/// the specified group.
-/// Returns the line number of the deleted sign. If multiple signs are deleted,
+///
+/// @param buf buffer sign is stored in
+/// @param atlnum sign at this line, 0 - at any line
+/// @param id sign id
+/// @param group sign group
+///
+/// @return the line number of the deleted sign. If multiple signs are deleted,
/// then returns the line number of the last sign deleted.
-linenr_T buf_delsign(
- buf_T *buf, // buffer sign is stored in
- linenr_T atlnum, // sign at this line, 0 - at any line
- int id, // sign id
- char_u *group // sign group
-)
+linenr_T buf_delsign(buf_T *buf, linenr_T atlnum, int id, char_u *group)
{
sign_entry_T **lastp; // pointer to pointer to current sign
sign_entry_T *sign; // a sign in a b_signlist
@@ -580,30 +582,30 @@ linenr_T buf_delsign(
/// Find the line number of the sign with the requested id in group 'group'. If
/// the sign does not exist, return 0 as the line number. This will still let
/// the correct file get loaded.
-int buf_findsign(
- buf_T *buf, // buffer to store sign in
- int id, // sign ID
- char_u *group // sign group
-)
+///
+/// @param buf buffer to store sign in
+/// @param id sign ID
+/// @param group sign group
+int buf_findsign(buf_T *buf, int id, char_u *group)
{
- sign_entry_T *sign; // a sign in the signlist
+ sign_entry_T *sign; // a sign in the signlist
- FOR_ALL_SIGNS_IN_BUF(buf, sign) {
- if (sign->se_id == id && sign_in_group(sign, group)) {
- return (int)sign->se_lnum;
- }
+ FOR_ALL_SIGNS_IN_BUF(buf, sign) {
+ if (sign->se_id == id && sign_in_group(sign, group)) {
+ return (int)sign->se_lnum;
}
+ }
- return 0;
+ return 0;
}
/// Return the sign at line 'lnum' in buffer 'buf'. Returns NULL if a sign is
/// not found at the line. If 'groupname' is NULL, searches in the global group.
-static sign_entry_T * buf_getsign_at_line(
- buf_T *buf, // buffer whose sign we are searching for
- linenr_T lnum, // line number of sign
- char_u *groupname // sign group name
-)
+///
+/// @param buf buffer whose sign we are searching for
+/// @param lnum line number of sign
+/// @param groupname sign group name
+static sign_entry_T *buf_getsign_at_line(buf_T *buf, linenr_T lnum, char_u *groupname)
{
sign_entry_T *sign; // a sign in the signlist
@@ -623,61 +625,61 @@ static sign_entry_T * buf_getsign_at_line(
}
/// Return the identifier of the sign at line number 'lnum' in buffer 'buf'.
-int buf_findsign_id(
- buf_T *buf, // buffer whose sign we are searching for
- linenr_T lnum, // line number of sign
- char_u *groupname // sign group name
-)
+///
+/// @param buf buffer whose sign we are searching for
+/// @param lnum line number of sign
+/// @param groupname sign group name
+int buf_findsign_id(buf_T *buf, linenr_T lnum, char_u *groupname)
{
- sign_entry_T *sign; // a sign in the signlist
+ sign_entry_T *sign; // a sign in the signlist
- sign = buf_getsign_at_line(buf, lnum, groupname);
- if (sign != NULL) {
- return sign->se_id;
- }
+ sign = buf_getsign_at_line(buf, lnum, groupname);
+ if (sign != NULL) {
+ return sign->se_id;
+ }
- return 0;
+ return 0;
}
/// Delete signs in buffer "buf".
void buf_delete_signs(buf_T *buf, char_u *group)
{
- sign_entry_T *sign;
- sign_entry_T **lastp; // pointer to pointer to current sign
- sign_entry_T *next;
+ sign_entry_T *sign;
+ sign_entry_T **lastp; // pointer to pointer to current sign
+ sign_entry_T *next;
- // When deleting the last sign need to redraw the windows to remove the
- // sign column. Not when curwin is NULL (this means we're exiting).
- if (buf->b_signlist != NULL && curwin != NULL) {
- changed_line_abv_curs();
- }
+ // When deleting the last sign need to redraw the windows to remove the
+ // sign column. Not when curwin is NULL (this means we're exiting).
+ if (buf->b_signlist != NULL && curwin != NULL) {
+ changed_line_abv_curs();
+ }
- lastp = &buf->b_signlist;
- for (sign = buf->b_signlist; sign != NULL; sign = next) {
- next = sign->se_next;
- if (sign_in_group(sign, group)) {
- *lastp = next;
- if (next != NULL) {
- next->se_prev = sign->se_prev;
- }
- if (sign->se_group != NULL) {
- sign_group_unref(sign->se_group->sg_name);
- }
- xfree(sign);
- } else {
- lastp = &sign->se_next;
+ lastp = &buf->b_signlist;
+ for (sign = buf->b_signlist; sign != NULL; sign = next) {
+ next = sign->se_next;
+ if (sign_in_group(sign, group)) {
+ *lastp = next;
+ if (next != NULL) {
+ next->se_prev = sign->se_prev;
+ }
+ if (sign->se_group != NULL) {
+ sign_group_unref(sign->se_group->sg_name);
}
+ xfree(sign);
+ } else {
+ lastp = &sign->se_next;
}
- buf->b_signcols_valid = false;
+ }
+ buf->b_signcols_valid = false;
}
/// List placed signs for "rbuf". If "rbuf" is NULL do it for all buffers.
void sign_list_placed(buf_T *rbuf, char_u *sign_group)
{
buf_T *buf;
- sign_entry_T *sign;
- char lbuf[MSG_BUF_LEN];
- char group[MSG_BUF_LEN];
+ sign_entry_T *sign;
+ char lbuf[MSG_BUF_LEN];
+ char group[MSG_BUF_LEN];
MSG_PUTS_TITLE(_("\n--- Signs ---"));
msg_putchar('\n');
@@ -720,12 +722,7 @@ void sign_list_placed(buf_T *rbuf, char_u *sign_group)
}
/// Adjust a placed sign for inserted/deleted lines.
-void sign_mark_adjust(
- linenr_T line1,
- linenr_T line2,
- long amount,
- long amount_after
-)
+void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after)
{
sign_entry_T *sign; // a sign in a b_signlist
sign_entry_T *next; // the next sign in a b_signlist
@@ -769,26 +766,26 @@ void sign_mark_adjust(
/// Find index of a ":sign" subcmd from its name.
/// "*end_cmd" must be writable.
-static int sign_cmd_idx(
- char_u *begin_cmd, // begin of sign subcmd
- char_u *end_cmd // just after sign subcmd
-)
+///
+/// @param begin_cmd begin of sign subcmd
+/// @param end_cmd just after sign subcmd
+static int sign_cmd_idx(char_u *begin_cmd, char_u *end_cmd)
{
- int idx;
- char_u save = *end_cmd;
+ int idx;
+ char_u save = *end_cmd;
- *end_cmd = (char_u)NUL;
- for (idx = 0; ; idx++) {
- if (cmds[idx] == NULL || STRCMP(begin_cmd, cmds[idx]) == 0) {
- break;
- }
+ *end_cmd = (char_u)NUL;
+ for (idx = 0; ; idx++) {
+ if (cmds[idx] == NULL || STRCMP(begin_cmd, cmds[idx]) == 0) {
+ break;
}
- *end_cmd = save;
- return idx;
+ }
+ *end_cmd = save;
+ return idx;
}
/// Find a sign by name. Also returns pointer to the previous sign.
-static sign_T * sign_find(const char_u *name, sign_T **sp_prev)
+static sign_T *sign_find(const char_u *name, sign_T **sp_prev)
{
sign_T *sp;
@@ -808,10 +805,10 @@ static sign_T * sign_find(const char_u *name, sign_T **sp_prev)
}
/// Allocate a new sign
-static sign_T * alloc_new_sign(char_u *name)
+static sign_T *alloc_new_sign(char_u *name)
{
- sign_T *sp;
- sign_T *lp;
+ sign_T *sp;
+ sign_T *lp;
int start = next_sign_typenr;
// Allocate a new sign.
@@ -858,8 +855,8 @@ static void sign_define_init_icon(sign_T *sp, char_u *icon)
/// Initialize the text for a new sign
static int sign_define_init_text(sign_T *sp, char_u *text)
{
- char_u *s;
- char_u *endp;
+ char_u *s;
+ char_u *endp;
int cells;
size_t len;
@@ -904,17 +901,11 @@ static int sign_define_init_text(sign_T *sp, char_u *text)
}
/// Define a new sign or update an existing sign
-int sign_define_by_name(
- char_u *name,
- char_u *icon,
- char_u *linehl,
- char_u *text,
- char_u *texthl,
- char_u *numhl
-)
+int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl,
+ char *numhl)
{
- sign_T *sp_prev;
- sign_T *sp;
+ sign_T *sp_prev;
+ sign_T *sp;
sp = sign_find(name, &sp_prev);
if (sp == NULL) {
@@ -949,11 +940,11 @@ int sign_define_by_name(
}
if (linehl != NULL) {
- sp->sn_line_hl = syn_check_group(linehl, (int)STRLEN(linehl));
+ sp->sn_line_hl = syn_check_group((char *)linehl, (int)STRLEN(linehl));
}
if (texthl != NULL) {
- sp->sn_text_hl = syn_check_group(texthl, (int)STRLEN(texthl));
+ sp->sn_text_hl = syn_check_group((char *)texthl, (int)STRLEN(texthl));
}
if (numhl != NULL) {
@@ -966,8 +957,8 @@ int sign_define_by_name(
/// Free the sign specified by 'name'.
int sign_undefine_by_name(const char_u *name)
{
- sign_T *sp_prev;
- sign_T *sp;
+ sign_T *sp_prev;
+ sign_T *sp;
sp = sign_find(name, &sp_prev);
if (sp == NULL) {
@@ -982,18 +973,18 @@ int sign_undefine_by_name(const char_u *name)
static void may_force_numberwidth_recompute(buf_T *buf, int unplace)
{
FOR_ALL_TAB_WINDOWS(tp, wp)
- if (wp->w_buffer == buf
- && (wp->w_p_nu || wp->w_p_rnu)
- && (unplace || wp->w_nrwidth_width < 2)
- && (*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u')) {
- wp->w_nrwidth_line_count = 0;
- }
+ if (wp->w_buffer == buf
+ && (wp->w_p_nu || wp->w_p_rnu)
+ && (unplace || wp->w_nrwidth_width < 2)
+ && (*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u')) {
+ wp->w_nrwidth_line_count = 0;
+ }
}
/// List the signs matching 'name'
static void sign_list_by_name(char_u *name)
{
- sign_T *sp;
+ sign_T *sp;
sp = sign_find(name, NULL);
if (sp != NULL) {
@@ -1005,14 +996,8 @@ static void sign_list_by_name(char_u *name)
/// Place a sign at the specified file location or update a sign.
-int sign_place(
- int *sign_id,
- const char_u *sign_group,
- const char_u *sign_name,
- buf_T *buf,
- linenr_T lnum,
- int prio
-)
+int sign_place(int *sign_id, const char_u *sign_group, const char_u *sign_name, buf_T *buf,
+ linenr_T lnum, int prio)
{
sign_T *sp;
@@ -1038,14 +1023,13 @@ int sign_place(
// ":sign place {id} line={lnum} name={name} file={fname}":
// place a sign
bool has_text_or_icon = sp->sn_text != NULL || sp->sn_icon != NULL;
- buf_addsign(
- buf,
- *sign_id,
- sign_group,
- prio,
- lnum,
- sp->sn_typenr,
- has_text_or_icon);
+ buf_addsign(buf,
+ *sign_id,
+ sign_group,
+ prio,
+ lnum,
+ sp->sn_typenr,
+ has_text_or_icon);
} else {
// ":sign place {id} file={fname}": change sign type and/or priority
lnum = buf_change_sign_type(buf, *sign_id, sign_group, sp->sn_typenr, prio);
@@ -1075,7 +1059,7 @@ int sign_unplace(int sign_id, char_u *sign_group, buf_T *buf, linenr_T atlnum)
redraw_buf_later(buf, NOT_VALID);
buf_delete_signs(buf, sign_group);
} else {
- linenr_T lnum;
+ linenr_T lnum;
// Delete only the specified signs
lnum = buf_delsign(buf, atlnum, sign_id, sign_group);
@@ -1098,7 +1082,7 @@ int sign_unplace(int sign_id, char_u *sign_group, buf_T *buf, linenr_T atlnum)
/// Unplace the sign at the current cursor line.
static void sign_unplace_at_cursor(char_u *groupname)
{
- int id = -1;
+ int id = -1;
id = buf_findsign_id(curwin->w_buffer, curwin->w_cursor.lnum, groupname);
if (id > 0) {
@@ -1144,13 +1128,13 @@ linenr_T sign_jump(int sign_id, char_u *sign_group, buf_T *buf)
/// ":sign define {name} ..." command
static void sign_define_cmd(char_u *sign_name, char_u *cmdline)
{
- char_u *arg;
- char_u *p = cmdline;
- char_u *icon = NULL;
- char_u *text = NULL;
- char_u *linehl = NULL;
- char_u *texthl = NULL;
- char_u *numhl = NULL;
+ char_u *arg;
+ char_u *p = cmdline;
+ char_u *icon = NULL;
+ char_u *text = NULL;
+ char_u *linehl = NULL;
+ char_u *texthl = NULL;
+ char_u *numhl = NULL;
int failed = false;
// set values for a defined sign.
@@ -1183,7 +1167,7 @@ static void sign_define_cmd(char_u *sign_name, char_u *cmdline)
}
if (!failed) {
- sign_define_by_name(sign_name, icon, linehl, text, texthl, numhl);
+ sign_define_by_name(sign_name, icon, linehl, text, texthl, (char *)numhl);
}
xfree(icon);
@@ -1194,14 +1178,8 @@ static void sign_define_cmd(char_u *sign_name, char_u *cmdline)
}
/// ":sign place" command
-static void sign_place_cmd(
- buf_T *buf,
- linenr_T lnum,
- char_u *sign_name,
- int id,
- char_u *group,
- int prio
-)
+static void sign_place_cmd(buf_T *buf, linenr_T lnum, char_u *sign_name, int id, char_u *group,
+ int prio)
{
if (id <= 0) {
// List signs placed in a file/buffer
@@ -1233,62 +1211,56 @@ static void sign_place_cmd(
}
/// ":sign unplace" command
-static void sign_unplace_cmd(
- buf_T *buf,
- linenr_T lnum,
- char_u *sign_name,
- int id,
- char_u *group
-)
+static void sign_unplace_cmd(buf_T *buf, linenr_T lnum, char_u *sign_name, int id, char_u *group)
{
- if (lnum >= 0 || sign_name != NULL || (group != NULL && *group == '\0')) {
- EMSG(_(e_invarg));
- return;
- }
+ if (lnum >= 0 || sign_name != NULL || (group != NULL && *group == '\0')) {
+ EMSG(_(e_invarg));
+ return;
+ }
- if (id == -2) {
- if (buf != NULL) {
- // :sign unplace * file={fname}
- // :sign unplace * group={group} file={fname}
- // :sign unplace * group=* file={fname}
- // :sign unplace * buffer={nr}
- // :sign unplace * group={group} buffer={nr}
- // :sign unplace * group=* buffer={nr}
- sign_unplace(0, group, buf, 0);
- } else {
- // :sign unplace *
- // :sign unplace * group={group}
- // :sign unplace * group=*
- FOR_ALL_BUFFERS(cbuf) {
- if (cbuf->b_signlist != NULL) {
- buf_delete_signs(cbuf, group);
- }
+ if (id == -2) {
+ if (buf != NULL) {
+ // :sign unplace * file={fname}
+ // :sign unplace * group={group} file={fname}
+ // :sign unplace * group=* file={fname}
+ // :sign unplace * buffer={nr}
+ // :sign unplace * group={group} buffer={nr}
+ // :sign unplace * group=* buffer={nr}
+ sign_unplace(0, group, buf, 0);
+ } else {
+ // :sign unplace *
+ // :sign unplace * group={group}
+ // :sign unplace * group=*
+ FOR_ALL_BUFFERS(cbuf) {
+ if (cbuf->b_signlist != NULL) {
+ buf_delete_signs(cbuf, group);
}
}
+ }
+ } else {
+ if (buf != NULL) {
+ // :sign unplace {id} file={fname}
+ // :sign unplace {id} group={group} file={fname}
+ // :sign unplace {id} group=* file={fname}
+ // :sign unplace {id} buffer={nr}
+ // :sign unplace {id} group={group} buffer={nr}
+ // :sign unplace {id} group=* buffer={nr}
+ sign_unplace(id, group, buf, 0);
} else {
- if (buf != NULL) {
- // :sign unplace {id} file={fname}
- // :sign unplace {id} group={group} file={fname}
- // :sign unplace {id} group=* file={fname}
- // :sign unplace {id} buffer={nr}
- // :sign unplace {id} group={group} buffer={nr}
- // :sign unplace {id} group=* buffer={nr}
- sign_unplace(id, group, buf, 0);
+ if (id == -1) {
+ // :sign unplace group={group}
+ // :sign unplace group=*
+ sign_unplace_at_cursor(group);
} else {
- if (id == -1) {
- // :sign unplace group={group}
- // :sign unplace group=*
- sign_unplace_at_cursor(group);
- } else {
- // :sign unplace {id}
- // :sign unplace {id} group={group}
- // :sign unplace {id} group=*
- FOR_ALL_BUFFERS(cbuf) {
- sign_unplace(id, group, cbuf, 0);
- }
+ // :sign unplace {id}
+ // :sign unplace {id} group={group}
+ // :sign unplace {id} group=*
+ FOR_ALL_BUFFERS(cbuf) {
+ sign_unplace(id, group, cbuf, 0);
}
}
}
+ }
}
/// Jump to a placed sign commands:
@@ -1296,13 +1268,7 @@ static void sign_unplace_cmd(
/// :sign jump {id} buffer={nr}
/// :sign jump {id} group={group} file={fname}
/// :sign jump {id} group={group} buffer={nr}
-static void sign_jump_cmd(
- buf_T *buf,
- linenr_T lnum,
- char_u *sign_name,
- int id,
- char_u *group
-)
+static void sign_jump_cmd(buf_T *buf, linenr_T lnum, char_u *sign_name, int id, char_u *group)
{
if (sign_name == NULL && group == NULL && id == -1) {
EMSG(_(e_argreq));
@@ -1324,21 +1290,13 @@ static void sign_jump_cmd(
/// ":sign jump" commands.
/// The supported arguments are: line={lnum} name={name} group={group}
/// priority={prio} and file={fname} or buffer={nr}.
-static int parse_sign_cmd_args(
- int cmd,
- char_u *arg,
- char_u **sign_name,
- int *signid,
- char_u **group,
- int *prio,
- buf_T **buf,
- linenr_T *lnum
-)
+static int parse_sign_cmd_args(int cmd, char_u *arg, char_u **sign_name, int *signid,
+ char_u **group, int *prio, buf_T **buf, linenr_T *lnum)
{
- char_u *arg1;
- char_u *name;
- char_u *filename = NULL;
- int lnum_arg = false;
+ char_u *arg1;
+ char_u *name;
+ char_u *filename = NULL;
+ int lnum_arg = false;
// first arg could be placed sign id
arg1 = arg;
@@ -1448,7 +1406,7 @@ void ex_sign(exarg_T *eap)
} else if (*arg == NUL) {
EMSG(_("E156: Missing sign name"));
} else {
- char_u *name;
+ char_u *name;
// Isolate the sign name. If it's a number skip leading zeroes,
// so that "099" and "99" are the same sign. But keep "0".
@@ -1574,12 +1532,8 @@ list_T *get_buffer_signs(buf_T *buf)
}
/// Return information about all the signs placed in a buffer
-static void sign_get_placed_in_buf(
- buf_T *buf,
- linenr_T lnum,
- int sign_id,
- const char_u *sign_group,
- list_T *retlist)
+static void sign_get_placed_in_buf(buf_T *buf, linenr_T lnum, int sign_id, const char_u *sign_group,
+ list_T *retlist)
{
dict_T *d;
list_T *l;
@@ -1609,13 +1563,8 @@ static void sign_get_placed_in_buf(
/// Get a list of signs placed in buffer 'buf'. If 'num' is non-zero, return the
/// sign placed at the line number. If 'lnum' is zero, return all the signs
/// placed in 'buf'. If 'buf' is NULL, return signs placed in all the buffers.
-void sign_get_placed(
- buf_T *buf,
- linenr_T lnum,
- int sign_id,
- const char_u *sign_group,
- list_T *retlist
-)
+void sign_get_placed(buf_T *buf, linenr_T lnum, int sign_id, const char_u *sign_group,
+ list_T *retlist)
{
if (buf != NULL) {
sign_get_placed_in_buf(buf, lnum, sign_id, sign_group, retlist);
@@ -1697,13 +1646,13 @@ void free_signs(void)
static enum
{
- EXP_SUBCMD, // expand :sign sub-commands
- EXP_DEFINE, // expand :sign define {name} args
- EXP_PLACE, // expand :sign place {id} args
- EXP_LIST, // expand :sign place args
- EXP_UNPLACE, // expand :sign unplace"
- EXP_SIGN_NAMES, // expand with name of placed signs
- EXP_SIGN_GROUPS, // expand with name of placed sign groups
+ EXP_SUBCMD, // expand :sign sub-commands
+ EXP_DEFINE, // expand :sign define {name} args
+ EXP_PLACE, // expand :sign place {id} args
+ EXP_LIST, // expand :sign place args
+ EXP_UNPLACE, // expand :sign unplace"
+ EXP_SIGN_NAMES, // expand with name of placed signs
+ EXP_SIGN_GROUPS, // expand with name of placed sign groups
} expand_what;
// Return the n'th sign name (used for command line completion)
@@ -1740,45 +1689,45 @@ static char_u *get_nth_sign_group_name(int idx)
/// Function given to ExpandGeneric() to obtain the sign command
/// expansion.
-char_u * get_sign_name(expand_T *xp, int idx)
+char_u *get_sign_name(expand_T *xp, int idx)
{
switch (expand_what) {
- case EXP_SUBCMD:
- return (char_u *)cmds[idx];
- case EXP_DEFINE: {
- char *define_arg[] = { "icon=", "linehl=", "text=", "texthl=", "numhl=",
- NULL };
- return (char_u *)define_arg[idx];
- }
- case EXP_PLACE: {
- char *place_arg[] = { "line=", "name=", "group=", "priority=", "file=",
- "buffer=", NULL };
- return (char_u *)place_arg[idx];
- }
- case EXP_LIST: {
- char *list_arg[] = { "group=", "file=", "buffer=", NULL };
- return (char_u *)list_arg[idx];
- }
- case EXP_UNPLACE: {
- char *unplace_arg[] = { "group=", "file=", "buffer=", NULL };
- return (char_u *)unplace_arg[idx];
- }
- case EXP_SIGN_NAMES:
- return get_nth_sign_name(idx);
- case EXP_SIGN_GROUPS:
- return get_nth_sign_group_name(idx);
- default:
- return NULL;
+ case EXP_SUBCMD:
+ return (char_u *)cmds[idx];
+ case EXP_DEFINE: {
+ char *define_arg[] = { "icon=", "linehl=", "text=", "texthl=", "numhl=",
+ NULL };
+ return (char_u *)define_arg[idx];
+ }
+ case EXP_PLACE: {
+ char *place_arg[] = { "line=", "name=", "group=", "priority=", "file=",
+ "buffer=", NULL };
+ return (char_u *)place_arg[idx];
+ }
+ case EXP_LIST: {
+ char *list_arg[] = { "group=", "file=", "buffer=", NULL };
+ return (char_u *)list_arg[idx];
+ }
+ case EXP_UNPLACE: {
+ char *unplace_arg[] = { "group=", "file=", "buffer=", NULL };
+ return (char_u *)unplace_arg[idx];
+ }
+ case EXP_SIGN_NAMES:
+ return get_nth_sign_name(idx);
+ case EXP_SIGN_GROUPS:
+ return get_nth_sign_group_name(idx);
+ default:
+ return NULL;
}
}
/// Handle command line completion for :sign command.
void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
{
- char_u *end_subcmd;
- char_u *last;
- int cmd_idx;
- char_u *begin_subcmd_args;
+ char_u *end_subcmd;
+ char_u *last;
+ int cmd_idx;
+ char_u *begin_subcmd_args;
// Default: expand subcommands.
xp->xp_context = EXPAND_SIGN;
@@ -1822,70 +1771,70 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
// Expand last argument name (before equal sign).
xp->xp_pattern = last;
switch (cmd_idx) {
- case SIGNCMD_DEFINE:
- expand_what = EXP_DEFINE;
- break;
- case SIGNCMD_PLACE:
- // List placed signs
- if (ascii_isdigit(*begin_subcmd_args)) {
- // :sign place {id} {args}...
- expand_what = EXP_PLACE;
- } else {
- // :sign place {args}...
- expand_what = EXP_LIST;
- }
- break;
- case SIGNCMD_LIST:
- case SIGNCMD_UNDEFINE:
- // :sign list <CTRL-D>
- // :sign undefine <CTRL-D>
- expand_what = EXP_SIGN_NAMES;
- break;
- case SIGNCMD_JUMP:
- case SIGNCMD_UNPLACE:
- expand_what = EXP_UNPLACE;
- break;
- default:
- xp->xp_context = EXPAND_NOTHING;
+ case SIGNCMD_DEFINE:
+ expand_what = EXP_DEFINE;
+ break;
+ case SIGNCMD_PLACE:
+ // List placed signs
+ if (ascii_isdigit(*begin_subcmd_args)) {
+ // :sign place {id} {args}...
+ expand_what = EXP_PLACE;
+ } else {
+ // :sign place {args}...
+ expand_what = EXP_LIST;
+ }
+ break;
+ case SIGNCMD_LIST:
+ case SIGNCMD_UNDEFINE:
+ // :sign list <CTRL-D>
+ // :sign undefine <CTRL-D>
+ expand_what = EXP_SIGN_NAMES;
+ break;
+ case SIGNCMD_JUMP:
+ case SIGNCMD_UNPLACE:
+ expand_what = EXP_UNPLACE;
+ break;
+ default:
+ xp->xp_context = EXPAND_NOTHING;
}
} else {
- // Expand last argument value (after equal sign).
+ // Expand last argument value (after equal sign).
xp->xp_pattern = p + 1;
switch (cmd_idx) {
- case SIGNCMD_DEFINE:
- if (STRNCMP(last, "texthl", 6) == 0
- || STRNCMP(last, "linehl", 6) == 0
- || STRNCMP(last, "numhl", 5) == 0) {
- xp->xp_context = EXPAND_HIGHLIGHT;
- } else if (STRNCMP(last, "icon", 4) == 0) {
- xp->xp_context = EXPAND_FILES;
- } else {
- xp->xp_context = EXPAND_NOTHING;
- }
- break;
- case SIGNCMD_PLACE:
- if (STRNCMP(last, "name", 4) == 0) {
- expand_what = EXP_SIGN_NAMES;
- } else if (STRNCMP(last, "group", 5) == 0) {
- expand_what = EXP_SIGN_GROUPS;
- } else if (STRNCMP(last, "file", 4) == 0) {
- xp->xp_context = EXPAND_BUFFERS;
- } else {
- xp->xp_context = EXPAND_NOTHING;
- }
- break;
- case SIGNCMD_UNPLACE:
- case SIGNCMD_JUMP:
- if (STRNCMP(last, "group", 5) == 0) {
- expand_what = EXP_SIGN_GROUPS;
- } else if (STRNCMP(last, "file", 4) == 0) {
- xp->xp_context = EXPAND_BUFFERS;
- } else {
- xp->xp_context = EXPAND_NOTHING;
- }
- break;
- default:
+ case SIGNCMD_DEFINE:
+ if (STRNCMP(last, "texthl", 6) == 0
+ || STRNCMP(last, "linehl", 6) == 0
+ || STRNCMP(last, "numhl", 5) == 0) {
+ xp->xp_context = EXPAND_HIGHLIGHT;
+ } else if (STRNCMP(last, "icon", 4) == 0) {
+ xp->xp_context = EXPAND_FILES;
+ } else {
xp->xp_context = EXPAND_NOTHING;
+ }
+ break;
+ case SIGNCMD_PLACE:
+ if (STRNCMP(last, "name", 4) == 0) {
+ expand_what = EXP_SIGN_NAMES;
+ } else if (STRNCMP(last, "group", 5) == 0) {
+ expand_what = EXP_SIGN_GROUPS;
+ } else if (STRNCMP(last, "file", 4) == 0) {
+ xp->xp_context = EXPAND_BUFFERS;
+ } else {
+ xp->xp_context = EXPAND_NOTHING;
+ }
+ break;
+ case SIGNCMD_UNPLACE:
+ case SIGNCMD_JUMP:
+ if (STRNCMP(last, "group", 5) == 0) {
+ expand_what = EXP_SIGN_GROUPS;
+ } else if (STRNCMP(last, "file", 4) == 0) {
+ xp->xp_context = EXPAND_BUFFERS;
+ } else {
+ xp->xp_context = EXPAND_NOTHING;
+ }
+ break;
+ default:
+ xp->xp_context = EXPAND_NOTHING;
}
}
}
@@ -1914,15 +1863,15 @@ int sign_define_from_dict(const char *name_arg, dict_T *dict)
goto cleanup;
}
if (dict != NULL) {
- icon = tv_dict_get_string(dict, "icon" , true);
+ icon = tv_dict_get_string(dict, "icon", true);
linehl = tv_dict_get_string(dict, "linehl", true);
- text = tv_dict_get_string(dict, "text" , true);
+ text = tv_dict_get_string(dict, "text", true);
texthl = tv_dict_get_string(dict, "texthl", true);
- numhl = tv_dict_get_string(dict, "numhl" , true);
+ numhl = tv_dict_get_string(dict, "numhl", true);
}
if (sign_define_by_name((char_u *)name, (char_u *)icon, (char_u *)linehl,
- (char_u *)text, (char_u *)texthl, (char_u *)numhl)
+ (char_u *)text, (char_u *)texthl, numhl)
== OK) {
retval = 0;
}
@@ -1942,27 +1891,23 @@ cleanup:
/// values in 'retlist'.
void sign_define_multiple(list_T *l, list_T *retlist)
{
- int retval;
+ int retval;
- TV_LIST_ITER_CONST(l, li, {
- retval = -1;
- if (TV_LIST_ITEM_TV(li)->v_type == VAR_DICT) {
- retval = sign_define_from_dict(NULL, TV_LIST_ITEM_TV(li)->vval.v_dict);
- } else {
- EMSG(_(e_dictreq));
- }
- tv_list_append_number(retlist, retval);
- });
+ TV_LIST_ITER_CONST(l, li, {
+ retval = -1;
+ if (TV_LIST_ITEM_TV(li)->v_type == VAR_DICT) {
+ retval = sign_define_from_dict(NULL, TV_LIST_ITEM_TV(li)->vval.v_dict);
+ } else {
+ EMSG(_(e_dictreq));
+ }
+ tv_list_append_number(retlist, retval);
+ });
}
/// Place a new sign using the values specified in dict 'dict'. Returns the sign
/// identifier if successfully placed, otherwise returns 0.
-int sign_place_from_dict(
- typval_T *id_tv,
- typval_T *group_tv,
- typval_T *name_tv,
- typval_T *buf_tv,
- dict_T *dict)
+int sign_place_from_dict(typval_T *id_tv, typval_T *group_tv, typval_T *name_tv, typval_T *buf_tv,
+ dict_T *dict)
{
int sign_id = 0;
char_u *group = NULL;
diff --git a/src/nvim/sign.h b/src/nvim/sign.h
index e3a5a27c74..9044c2d0bb 100644
--- a/src/nvim/sign.h
+++ b/src/nvim/sign.h
@@ -2,6 +2,7 @@
#define NVIM_SIGN_H
#include <stdbool.h>
+
#include "nvim/buffer_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/sign_defs.h"
diff --git a/src/nvim/sign_defs.h b/src/nvim/sign_defs.h
index 721b2db25b..f3ec2c45f6 100644
--- a/src/nvim/sign_defs.h
+++ b/src/nvim/sign_defs.h
@@ -2,6 +2,7 @@
#define NVIM_SIGN_DEFS_H
#include <stdbool.h>
+
#include "nvim/pos.h"
#include "nvim/types.h"
@@ -10,9 +11,9 @@
// Sign group
typedef struct signgroup_S
{
- uint16_t sg_refcount; // number of signs in this group
- int sg_next_sign_id; // next sign id for this group
- char_u sg_name[1]; // sign group name
+ uint16_t sg_refcount; // number of signs in this group
+ int sg_next_sign_id; // next sign id for this group
+ char_u sg_name[1]; // sign group name
} signgroup_T;
// Macros to get the sign group structure from the group name
@@ -22,23 +23,23 @@ typedef struct signgroup_S
typedef struct sign_entry sign_entry_T;
struct sign_entry {
- int se_id; // unique identifier for each placed sign
- int se_typenr; // typenr of sign
- int se_priority; // priority for highlighting
- bool se_has_text_or_icon; // has text or icon
- linenr_T se_lnum; // line number which has this sign
- signgroup_T *se_group; // sign group
- sign_entry_T *se_next; // next entry in a list of signs
- sign_entry_T *se_prev; // previous entry -- for easy reordering
+ int se_id; // unique identifier for each placed sign
+ int se_typenr; // typenr of sign
+ int se_priority; // priority for highlighting
+ bool se_has_text_or_icon; // has text or icon
+ linenr_T se_lnum; // line number which has this sign
+ signgroup_T *se_group; // sign group
+ sign_entry_T *se_next; // next entry in a list of signs
+ sign_entry_T *se_prev; // previous entry -- for easy reordering
};
/// Sign attributes. Used by the screen refresh routines.
typedef struct sign_attrs_S {
- int sat_typenr;
- char_u *sat_text;
- int sat_texthl;
- int sat_linehl;
- int sat_numhl;
+ int sat_typenr;
+ char_u *sat_text;
+ int sat_texthl;
+ int sat_linehl;
+ int sat_numhl;
} sign_attrs_T;
#define SIGN_SHOW_MAX 9
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 610a359141..9ed421c8a0 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -72,15 +72,14 @@
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
-#include <string.h>
#include <stdlib.h>
+#include <string.h>
#include <wctype.h>
-/* for offsetof() */
+// for offsetof()
#include <stddef.h>
#include "nvim/ascii.h"
-#include "nvim/spell.h"
#include "nvim/buffer.h"
#include "nvim/change.h"
#include "nvim/charset.h"
@@ -92,6 +91,7 @@
#include "nvim/ex_docmd.h"
#include "nvim/fileio.h"
#include "nvim/func_attr.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/hashtab.h"
#include "nvim/mark.h"
@@ -100,21 +100,21 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/garray.h"
#include "nvim/normal.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/search.h"
+#include "nvim/spell.h"
#include "nvim/spellfile.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
-#include "nvim/undo.h"
#include "nvim/ui.h"
-#include "nvim/os/os.h"
-#include "nvim/os/input.h"
+#include "nvim/undo.h"
// only used for su_badflags
#define WF_MIXCAP 0x20 // mix of upper and lower case: macaRONI
@@ -151,26 +151,26 @@ typedef struct suginfo_S {
int su_maxscore; // maximum score for adding to su_ga
int su_sfmaxscore; // idem, for when doing soundfold words
garray_T su_sga; // like su_ga, sound-folded scoring
- char_u *su_badptr; // start of bad word in line
+ char_u *su_badptr; // start of bad word in line
int su_badlen; // length of detected bad word in line
int su_badflags; // caps flags for bad word
char_u su_badword[MAXWLEN]; // bad word truncated at su_badlen
char_u su_fbadword[MAXWLEN]; // su_badword case-folded
char_u su_sal_badword[MAXWLEN]; // su_badword soundfolded
hashtab_T su_banned; // table with banned words
- slang_T *su_sallang; // default language for sound folding
+ slang_T *su_sallang; // default language for sound folding
} suginfo_T;
// One word suggestion. Used in "si_ga".
typedef struct {
- char_u *st_word; // suggested word, allocated string
+ char_u *st_word; // suggested word, allocated string
int st_wordlen; // STRLEN(st_word)
int st_orglen; // length of replaced text
int st_score; // lower is better
int st_altscore; // used when st_score compares equal
bool st_salscore; // st_score is for soundalike
bool st_had_bonus; // bonus already included in score
- slang_T *st_slang; // language used for sound folding
+ slang_T *st_slang; // language used for sound folding
} suggest_T;
#define SUG(ga, i) (((suggest_T *)(ga).ga_data)[i])
@@ -235,14 +235,14 @@ typedef struct {
// Structure to store info for word matching.
typedef struct matchinf_S {
- langp_T *mi_lp; // info for language and region
+ langp_T *mi_lp; // info for language and region
// pointers to original text to be checked
- char_u *mi_word; // start of word being checked
- char_u *mi_end; // end of matching word so far
- char_u *mi_fend; // next char to be added to mi_fword
- char_u *mi_cend; // char after what was used for
- // mi_capflags
+ char_u *mi_word; // start of word being checked
+ char_u *mi_end; // end of matching word so far
+ char_u *mi_fend; // next char to be added to mi_fword
+ char_u *mi_cend; // char after what was used for
+ // mi_capflags
// case-folded text
char_u mi_fword[MAXWLEN + 1]; // mi_word case-folded
@@ -265,11 +265,11 @@ typedef struct matchinf_S {
// others
int mi_result; // result so far: SP_BAD, SP_OK, etc.
int mi_capflags; // WF_ONECAP WF_ALLCAP WF_KEEPCAP
- win_T *mi_win; // buffer being checked
+ win_T *mi_win; // buffer being checked
// for NOBREAK
int mi_result2; // "mi_resul" without following word
- char_u *mi_end2; // "mi_end" without following word
+ char_u *mi_end2; // "mi_end" without following word
} matchinf_T;
// Structure used for the cookie argument of do_in_runtimepath().
@@ -334,26 +334,24 @@ char *e_format = N_("E759: Format error in spell file");
static char_u *repl_from = NULL;
static char_u *repl_to = NULL;
-// Main spell-checking function.
-// "ptr" points to a character that could be the start of a word.
-// "*attrp" is set to the highlight index for a badly spelled word. For a
-// non-word or when it's OK it remains unchanged.
-// This must only be called when 'spelllang' is not empty.
-//
-// "capcol" is used to check for a Capitalised word after the end of a
-// sentence. If it's zero then perform the check. Return the column where to
-// check next, or -1 when no sentence end was found. If it's NULL then don't
-// worry.
-//
-// Returns the length of the word in bytes, also when it's OK, so that the
-// caller can skip over the word.
-size_t spell_check(
- win_T *wp, // current window
- char_u *ptr,
- hlf_T *attrp,
- int *capcol, // column to check for Capital
- bool docount // count good words
-)
+/// Main spell-checking function.
+/// "ptr" points to a character that could be the start of a word.
+/// "*attrp" is set to the highlight index for a badly spelled word. For a
+/// non-word or when it's OK it remains unchanged.
+/// This must only be called when 'spelllang' is not empty.
+///
+/// "capcol" is used to check for a Capitalised word after the end of a
+/// sentence. If it's zero then perform the check. Return the column where to
+/// check next, or -1 when no sentence end was found. If it's NULL then don't
+/// worry.
+///
+/// @param wp current window
+/// @param capcol column to check for Capital
+/// @param docount count good words
+///
+/// @return the length of the word in bytes, also when it's OK, so that the
+/// caller can skip over the word.
+size_t spell_check(win_T *wp, char_u *ptr, hlf_T *attrp, int *capcol, bool docount)
{
matchinf_T mi; // Most things are put in "mi" so that it can
// be passed to functions quickly.
@@ -383,7 +381,7 @@ size_t spell_check(
// julifeest".
if (*ptr >= '0' && *ptr <= '9') {
if (*ptr == '0' && (ptr[1] == 'b' || ptr[1] == 'B')) {
- mi.mi_end = (char_u*) skipbin((char*) ptr + 2);
+ mi.mi_end = (char_u *)skipbin((char *)ptr + 2);
} else if (*ptr == '0' && (ptr[1] == 'x' || ptr[1] == 'X')) {
mi.mi_end = skiphex(ptr + 2);
} else {
@@ -486,7 +484,7 @@ size_t spell_check(
// Count the word in the first language where it's found to be OK.
if (count_word && mi.mi_result == SP_OK) {
count_common_word(mi.mi_lp->lp_slang, ptr,
- (int)(mi.mi_end - ptr), 1);
+ (int)(mi.mi_end - ptr), 1);
count_word = false;
}
}
@@ -499,8 +497,8 @@ size_t spell_check(
return nrlen;
}
} else if (!spell_iswordp_nmw(ptr, wp)) {
- // When we are at a non-word character there is no error, just
- // skip over the character (try looking for a word after it).
+ // When we are at a non-word character there is no error, just
+ // skip over the character (try looking for a word after it).
if (capcol != NULL && wp->w_s->b_cap_prog != NULL) {
regmatch_T regmatch;
@@ -521,7 +519,7 @@ size_t spell_check(
MB_PTR_ADV(mi.mi_end);
} else if (mi.mi_result == SP_BAD
&& LANGP_ENTRY(wp->w_s->b_langp, 0)->lp_slang->sl_nobreak) {
- char_u *p, *fp;
+ char_u *p, *fp;
int save_result = mi.mi_result;
// First language in 'spelllang' is NOBREAK. Find first position
@@ -576,10 +574,10 @@ static void find_word(matchinf_T *mip, int mode)
{
int wlen = 0;
int flen;
- char_u *ptr;
- slang_T *slang = mip->mi_lp->lp_slang;
- char_u *byts;
- idx_T *idxs;
+ char_u *ptr;
+ slang_T *slang = mip->mi_lp->lp_slang;
+ char_u *byts;
+ idx_T *idxs;
if (mode == FIND_KEEPWORD || mode == FIND_KEEPCOMPOUND) {
// Check for word with matching case in keep-case tree.
@@ -588,9 +586,10 @@ static void find_word(matchinf_T *mip, int mode)
byts = slang->sl_kbyts;
idxs = slang->sl_kidxs;
- if (mode == FIND_KEEPCOMPOUND)
+ if (mode == FIND_KEEPCOMPOUND) {
// Skip over the previously found word(s).
wlen += mip->mi_compoff;
+ }
} else {
// Check for case-folded in case-folded tree.
ptr = mip->mi_fword;
@@ -607,12 +606,11 @@ static void find_word(matchinf_T *mip, int mode)
wlen = mip->mi_compoff;
flen -= mip->mi_compoff;
}
-
}
- if (byts == NULL)
+ if (byts == NULL) {
return; // array is empty
-
+ }
idx_T arridx = 0;
int endlen[MAXWLEN]; // length at possible word endings
idx_T endidx[MAXWLEN]; // possible word endings
@@ -625,8 +623,9 @@ static void find_word(matchinf_T *mip, int mode)
// - we reach the end of the tree,
// - or we reach the end of the line.
for (;; ) {
- if (flen <= 0 && *mip->mi_fend != NUL)
+ if (flen <= 0 && *mip->mi_fend != NUL) {
flen = fold_more(mip);
+ }
len = byts[arridx++];
@@ -648,35 +647,39 @@ static void find_word(matchinf_T *mip, int mode)
++arridx;
--len;
}
- if (len == 0)
+ if (len == 0) {
break; // no children, word must end here
+ }
}
// Stop looking at end of the line.
- if (ptr[wlen] == NUL)
+ if (ptr[wlen] == NUL) {
break;
+ }
// Perform a binary search in the list of accepted bytes.
c = ptr[wlen];
- if (c == TAB) // <Tab> is handled like <Space>
+ if (c == TAB) { // <Tab> is handled like <Space>
c = ' ';
+ }
idx_T lo = arridx;
idx_T hi = arridx + len - 1;
while (lo < hi) {
idx_T m = (lo + hi) / 2;
- if (byts[m] > c)
+ if (byts[m] > c) {
hi = m - 1;
- else if (byts[m] < c)
+ } else if (byts[m] < c) {
lo = m + 1;
- else {
+ } else {
lo = hi = m;
break;
}
}
// Stop if there is no matching byte.
- if (hi < lo || byts[lo] != c)
+ if (hi < lo || byts[lo] != c) {
break;
+ }
// Continue at the child (if there is one).
arridx = idxs[lo];
@@ -687,10 +690,12 @@ static void find_word(matchinf_T *mip, int mode)
// checked word.
if (c == ' ') {
for (;; ) {
- if (flen <= 0 && *mip->mi_fend != NUL)
+ if (flen <= 0 && *mip->mi_fend != NUL) {
flen = fold_more(mip);
- if (ptr[wlen] != ' ' && ptr[wlen] != TAB)
+ }
+ if (ptr[wlen] != ' ' && ptr[wlen] != TAB) {
break;
+ }
++wlen;
--flen;
}
@@ -711,11 +716,13 @@ static void find_word(matchinf_T *mip, int mode)
continue; // not at first byte of character
}
if (spell_iswordp(ptr + wlen, mip->mi_win)) {
- if (slang->sl_compprog == NULL && !slang->sl_nobreak)
+ if (slang->sl_compprog == NULL && !slang->sl_nobreak) {
continue; // next char is a word character
+ }
word_ends = false;
- } else
+ } else {
word_ends = true;
+ }
// The prefix flag is before compound flags. Once a valid prefix flag
// has been found we try compound flags.
bool prefix_found = false;
@@ -754,23 +761,26 @@ static void find_word(matchinf_T *mip, int mode)
}
if (mip->mi_capflags == WF_KEEPCAP
- || !spell_valid_case(mip->mi_capflags, flags))
+ || !spell_valid_case(mip->mi_capflags, flags)) {
continue;
+ }
}
// When mode is FIND_PREFIX the word must support the prefix:
// check the prefix ID and the condition. Do that for the list at
// mip->mi_prefarridx that find_prefix() filled.
else if (mode == FIND_PREFIX && !prefix_found) {
c = valid_word_prefix(mip->mi_prefcnt, mip->mi_prefarridx,
- flags,
- mip->mi_word + mip->mi_cprefixlen, slang,
- false);
- if (c == 0)
+ flags,
+ mip->mi_word + mip->mi_cprefixlen, slang,
+ false);
+ if (c == 0) {
continue;
+ }
// Use the WF_RARE flag for a rare prefix.
- if (c & WF_RAREPFX)
+ if (c & WF_RAREPFX) {
flags |= WF_RARE;
+ }
prefix_found = true;
}
@@ -790,8 +800,9 @@ static void find_word(matchinf_T *mip, int mode)
// that's too short... Myspell compatibility requires this
// anyway.
if (((unsigned)flags >> 24) == 0
- || wlen - mip->mi_compoff < slang->sl_compminlen)
+ || wlen - mip->mi_compoff < slang->sl_compminlen) {
continue;
+ }
// For multi-byte chars check character length against
// COMPOUNDMIN.
if (slang->sl_compminlen > 0
@@ -804,27 +815,32 @@ static void find_word(matchinf_T *mip, int mode)
// maximum for syllables is specified.
if (!word_ends && mip->mi_complen + mip->mi_compextra + 2
> slang->sl_compmax
- && slang->sl_compsylmax == MAXWLEN)
+ && slang->sl_compsylmax == MAXWLEN) {
continue;
+ }
// Don't allow compounding on a side where an affix was added,
// unless COMPOUNDPERMITFLAG was used.
- if (mip->mi_complen > 0 && (flags & WF_NOCOMPBEF))
+ if (mip->mi_complen > 0 && (flags & WF_NOCOMPBEF)) {
continue;
- if (!word_ends && (flags & WF_NOCOMPAFT))
+ }
+ if (!word_ends && (flags & WF_NOCOMPAFT)) {
continue;
+ }
// Quickly check if compounding is possible with this flag.
if (!byte_in_str(mip->mi_complen == 0
? slang->sl_compstartflags
: slang->sl_compallflags,
- ((unsigned)flags >> 24)))
+ ((unsigned)flags >> 24))) {
continue;
+ }
// If there is a match with a CHECKCOMPOUNDPATTERN rule
// discard the compound word.
- if (match_checkcompoundpattern(ptr, wlen, &slang->sl_comppat))
+ if (match_checkcompoundpattern(ptr, wlen, &slang->sl_comppat)) {
continue;
+ }
if (mode == FIND_COMPOUND) {
int capflags;
@@ -842,8 +858,9 @@ static void find_word(matchinf_T *mip, int mode)
}
capflags = captype(p, mip->mi_word + wlen);
if (capflags == WF_KEEPCAP || (capflags == WF_ALLCAP
- && (flags & WF_FIXCAP) != 0))
+ && (flags & WF_FIXCAP) != 0)) {
continue;
+ }
if (capflags != WF_ALLCAP) {
// When the character before the word is a word
@@ -876,23 +893,26 @@ static void find_word(matchinf_T *mip, int mode)
STRLCPY(fword, ptr, endlen[endidxcnt] + 1);
}
}
- if (!can_compound(slang, fword, mip->mi_compflags))
+ if (!can_compound(slang, fword, mip->mi_compflags)) {
continue;
+ }
} else if (slang->sl_comprules != NULL
- && !match_compoundrule(slang, mip->mi_compflags))
+ && !match_compoundrule(slang, mip->mi_compflags)) {
// The compound flags collected so far do not match any
// COMPOUNDRULE, discard the compounded word.
continue;
+ }
}
// Check NEEDCOMPOUND: can't use word without compounding.
- else if (flags & WF_NEEDCOMP)
+ else if (flags & WF_NEEDCOMP) {
continue;
+ }
int nobreak_result = SP_OK;
if (!word_ends) {
int save_result = mip->mi_result;
- char_u *save_end = mip->mi_end;
+ char_u *save_end = mip->mi_end;
langp_T *save_lp = mip->mi_lp;
// Check that a valid word follows. If there is one and we
@@ -900,8 +920,9 @@ static void find_word(matchinf_T *mip, int mode)
// always finished here. For NOBREAK we only check that a
// valid word follows.
// Recursive!
- if (slang->sl_nobreak)
+ if (slang->sl_nobreak) {
mip->mi_result = SP_BAD;
+ }
// Find following word in case-folded tree.
mip->mi_compoff = endlen[endidxcnt];
@@ -922,8 +943,9 @@ static void find_word(matchinf_T *mip, int mode)
c = mip->mi_compoff;
#endif
++mip->mi_complen;
- if (flags & WF_COMPROOT)
+ if (flags & WF_COMPROOT) {
++mip->mi_compextra;
+ }
// For NOBREAK we need to try all NOBREAK languages, at least
// to find the ".add" file(s).
@@ -931,8 +953,9 @@ static void find_word(matchinf_T *mip, int mode)
if (slang->sl_nobreak) {
mip->mi_lp = LANGP_ENTRY(mip->mi_win->w_s->b_langp, lpi);
if (mip->mi_lp->lp_slang->sl_fidxs == NULL
- || !mip->mi_lp->lp_slang->sl_nobreak)
+ || !mip->mi_lp->lp_slang->sl_nobreak) {
continue;
+ }
}
find_word(mip, FIND_COMPOUND);
@@ -956,12 +979,14 @@ static void find_word(matchinf_T *mip, int mode)
#endif
}
- if (!slang->sl_nobreak)
+ if (!slang->sl_nobreak) {
break;
+ }
}
--mip->mi_complen;
- if (flags & WF_COMPROOT)
+ if (flags & WF_COMPROOT) {
--mip->mi_compextra;
+ }
mip->mi_lp = save_lp;
if (slang->sl_nobreak) {
@@ -969,25 +994,28 @@ static void find_word(matchinf_T *mip, int mode)
mip->mi_result = save_result;
mip->mi_end = save_end;
} else {
- if (mip->mi_result == SP_OK)
+ if (mip->mi_result == SP_OK) {
break;
+ }
continue;
}
}
int res = SP_BAD;
- if (flags & WF_BANNED)
+ if (flags & WF_BANNED) {
res = SP_BANNED;
- else if (flags & WF_REGION) {
+ } else if (flags & WF_REGION) {
// Check region.
- if ((mip->mi_lp->lp_region & (flags >> 16)) != 0)
+ if ((mip->mi_lp->lp_region & (flags >> 16)) != 0) {
res = SP_OK;
- else
+ } else {
res = SP_LOCAL;
- } else if (flags & WF_RARE)
+ }
+ } else if (flags & WF_RARE) {
res = SP_RARE;
- else
+ } else {
res = SP_OK;
+ }
// Always use the longest match and the best result. For NOBREAK
// we separately keep the longest match without a following good
@@ -997,36 +1025,37 @@ static void find_word(matchinf_T *mip, int mode)
mip->mi_result2 = res;
mip->mi_end2 = mip->mi_word + wlen;
} else if (mip->mi_result2 == res
- && mip->mi_end2 < mip->mi_word + wlen)
+ && mip->mi_end2 < mip->mi_word + wlen) {
mip->mi_end2 = mip->mi_word + wlen;
+ }
} else if (mip->mi_result > res) {
mip->mi_result = res;
mip->mi_end = mip->mi_word + wlen;
- } else if (mip->mi_result == res && mip->mi_end < mip->mi_word + wlen)
+ } else if (mip->mi_result == res && mip->mi_end < mip->mi_word + wlen) {
mip->mi_end = mip->mi_word + wlen;
+ }
- if (mip->mi_result == SP_OK)
+ if (mip->mi_result == SP_OK) {
break;
+ }
}
- if (mip->mi_result == SP_OK)
+ if (mip->mi_result == SP_OK) {
break;
+ }
}
}
-// Returns true if there is a match between the word ptr[wlen] and
-// CHECKCOMPOUNDPATTERN rules, assuming that we will concatenate with another
-// word.
-// A match means that the first part of CHECKCOMPOUNDPATTERN matches at the
-// end of ptr[wlen] and the second part matches after it.
-static bool
-match_checkcompoundpattern (
- char_u *ptr,
- int wlen,
- garray_T *gap // &sl_comppat
-)
+/// Returns true if there is a match between the word ptr[wlen] and
+/// CHECKCOMPOUNDPATTERN rules, assuming that we will concatenate with another
+/// word.
+/// A match means that the first part of CHECKCOMPOUNDPATTERN matches at the
+/// end of ptr[wlen] and the second part matches after it.
+///
+/// @param gap &sl_comppat
+static bool match_checkcompoundpattern(char_u *ptr, int wlen, garray_T *gap)
{
- char_u *p;
+ char_u *p;
int len;
for (int i = 0; i + 1 < gap->ga_len; i += 2) {
@@ -1036,8 +1065,9 @@ match_checkcompoundpattern (
// check if first part matches at end of previous word.
p = ((char_u **)gap->ga_data)[i];
len = (int)STRLEN(p);
- if (len <= wlen && STRNCMP(ptr + wlen - len, p, len) == 0)
+ if (len <= wlen && STRNCMP(ptr + wlen - len, p, len) == 0) {
return true;
+ }
}
}
return false;
@@ -1045,8 +1075,7 @@ match_checkcompoundpattern (
// Returns true if "flags" is a valid sequence of compound flags and "word"
// does not have too many syllables.
-static bool can_compound(slang_T *slang, const char_u *word,
- const char_u *flags)
+static bool can_compound(slang_T *slang, const char_u *word, const char_u *flags)
FUNC_ATTR_NONNULL_ALL
{
char_u uflags[MAXWLEN * 2] = { 0 };
@@ -1069,8 +1098,9 @@ static bool can_compound(slang_T *slang, const char_u *word,
// are too many syllables AND the number of compound words is above
// COMPOUNDWORDMAX then compounding is not allowed.
if (slang->sl_compsylmax < MAXWLEN
- && count_syllables(slang, word) > slang->sl_compsylmax)
+ && count_syllables(slang, word) > slang->sl_compsylmax) {
return (int)STRLEN(flags) < slang->sl_compmax;
+ }
return true;
}
@@ -1082,8 +1112,9 @@ static bool can_be_compound(trystate_T *sp, slang_T *slang, char_u *compflags, i
// If the flag doesn't appear in sl_compstartflags or sl_compallflags
// then it can't possibly compound.
if (!byte_in_str(sp->ts_complen == sp->ts_compsplit
- ? slang->sl_compstartflags : slang->sl_compallflags, flag))
+ ? slang->sl_compstartflags : slang->sl_compallflags, flag)) {
return false;
+ }
// If there are no wildcards, we can check if the flags collected so far
// possibly can form a match with COMPOUNDRULE patterns. This only
@@ -1105,7 +1136,7 @@ static bool can_be_compound(trystate_T *sp, slang_T *slang, char_u *compflags, i
// Caller must check that slang->sl_comprules is not NULL.
static bool match_compoundrule(slang_T *slang, char_u *compflags)
{
- char_u *p;
+ char_u *p;
int i;
int c;
@@ -1115,30 +1146,37 @@ static bool match_compoundrule(slang_T *slang, char_u *compflags)
// them against the current rule entry
for (i = 0;; ++i) {
c = compflags[i];
- if (c == NUL)
+ if (c == NUL) {
// found a rule that matches for the flags we have so far
return true;
- if (*p == '/' || *p == NUL)
+ }
+ if (*p == '/' || *p == NUL) {
break; // end of rule, it's too short
+ }
if (*p == '[') {
bool match = false;
// compare against all the flags in []
++p;
- while (*p != ']' && *p != NUL)
- if (*p++ == c)
+ while (*p != ']' && *p != NUL) {
+ if (*p++ == c) {
match = true;
- if (!match)
+ }
+ }
+ if (!match) {
break; // none matches
- } else if (*p != c)
+ }
+ } else if (*p != c) {
break; // flag of word doesn't match flag in pattern
+ }
++p;
}
// Skip to the next "/", where the next pattern starts.
p = vim_strchr(p, '/');
- if (p == NULL)
+ if (p == NULL) {
break;
+ }
}
// Checked all the rules and none of them match the flags, so there
@@ -1146,18 +1184,15 @@ static bool match_compoundrule(slang_T *slang, char_u *compflags)
return false;
}
-// Return non-zero if the prefix indicated by "arridx" matches with the prefix
-// ID in "flags" for the word "word".
-// The WF_RAREPFX flag is included in the return value for a rare prefix.
-static int
-valid_word_prefix (
- int totprefcnt, // nr of prefix IDs
- int arridx, // idx in sl_pidxs[]
- int flags,
- char_u *word,
- slang_T *slang,
- bool cond_req // only use prefixes with a condition
-)
+/// Return non-zero if the prefix indicated by "arridx" matches with the prefix
+/// ID in "flags" for the word "word".
+/// The WF_RAREPFX flag is included in the return value for a rare prefix.
+///
+/// @param totprefcnt nr of prefix IDs
+/// @param arridx idx in sl_pidxs[]
+/// @param cond_req only use prefixes with a condition
+static int valid_word_prefix(int totprefcnt, int arridx, int flags, char_u *word, slang_T *slang,
+ bool cond_req)
{
int prefcnt;
int pidx;
@@ -1168,13 +1203,15 @@ valid_word_prefix (
pidx = slang->sl_pidxs[arridx + prefcnt];
// Check the prefix ID.
- if (prefid != (pidx & 0xff))
+ if (prefid != (pidx & 0xff)) {
continue;
+ }
// Check if the prefix doesn't combine and the word already has a
// suffix.
- if ((flags & WF_HAS_AFF) && (pidx & WF_PFX_NC))
+ if ((flags & WF_HAS_AFF) && (pidx & WF_PFX_NC)) {
continue;
+ }
// Check the condition, if there is one. The condition index is
// stored in the two bytes above the prefix ID byte.
@@ -1183,8 +1220,9 @@ valid_word_prefix (
if (!vim_regexec_prog(rp, false, word, 0)) {
continue;
}
- } else if (cond_req)
+ } else if (cond_req) {
continue;
+ }
// It's a match! Return the WF_ flags.
return pidx;
@@ -1206,16 +1244,16 @@ static void find_prefix(matchinf_T *mip, int mode)
int wlen = 0;
int flen;
int c;
- char_u *ptr;
+ char_u *ptr;
idx_T lo, hi, m;
- slang_T *slang = mip->mi_lp->lp_slang;
- char_u *byts;
- idx_T *idxs;
+ slang_T *slang = mip->mi_lp->lp_slang;
+ char_u *byts;
+ idx_T *idxs;
byts = slang->sl_pbyts;
- if (byts == NULL)
+ if (byts == NULL) {
return; // array is empty
-
+ }
// We use the case-folded word here, since prefixes are always
// case-folded.
ptr = mip->mi_fword;
@@ -1232,8 +1270,9 @@ static void find_prefix(matchinf_T *mip, int mode)
// - we reach the end of the tree,
// - or we reach the end of the line.
for (;; ) {
- if (flen == 0 && *mip->mi_fend != NUL)
+ if (flen == 0 && *mip->mi_fend != NUL) {
flen = fold_more(mip);
+ }
len = byts[arridx++];
@@ -1254,9 +1293,10 @@ static void find_prefix(matchinf_T *mip, int mode)
// Find the word that comes after the prefix.
mip->mi_prefixlen = wlen;
- if (mode == FIND_COMPOUND)
+ if (mode == FIND_COMPOUND) {
// Skip over the previously found word(s).
mip->mi_prefixlen += mip->mi_compoff;
+ }
// Case-folded length may differ from original length.
mip->mi_cprefixlen = nofold_len(mip->mi_fword, mip->mi_prefixlen,
@@ -1264,13 +1304,15 @@ static void find_prefix(matchinf_T *mip, int mode)
find_word(mip, FIND_PREFIX);
- if (len == 0)
+ if (len == 0) {
break; // no children, word must end here
+ }
}
// Stop looking at end of the line.
- if (ptr[wlen] == NUL)
+ if (ptr[wlen] == NUL) {
break;
+ }
// Perform a binary search in the list of accepted bytes.
c = ptr[wlen];
@@ -1278,19 +1320,20 @@ static void find_prefix(matchinf_T *mip, int mode)
hi = arridx + len - 1;
while (lo < hi) {
m = (lo + hi) / 2;
- if (byts[m] > c)
+ if (byts[m] > c) {
hi = m - 1;
- else if (byts[m] < c)
+ } else if (byts[m] < c) {
lo = m + 1;
- else {
+ } else {
lo = hi = m;
break;
}
}
// Stop if there is no matching byte.
- if (hi < lo || byts[lo] != c)
+ if (hi < lo || byts[lo] != c) {
break;
+ }
// Continue at the child (if there is one).
arridx = idxs[lo];
@@ -1305,7 +1348,7 @@ static void find_prefix(matchinf_T *mip, int mode)
static int fold_more(matchinf_T *mip)
{
int flen;
- char_u *p;
+ char_u *p;
p = mip->mi_fend;
do {
@@ -1349,42 +1392,40 @@ static bool no_spell_checking(win_T *wp)
return false;
}
-// Moves to the next spell error.
-// "curline" is false for "[s", "]s", "[S" and "]S".
-// "curline" is true to find word under/after cursor in the same line.
-// For Insert mode completion "dir" is BACKWARD and "curline" is true: move
-// to after badly spelled word before the cursor.
-// Return 0 if not found, length of the badly spelled word otherwise.
-size_t
-spell_move_to (
- win_T *wp,
- int dir, // FORWARD or BACKWARD
- bool allwords, // true for "[s"/"]s", false for "[S"/"]S"
- bool curline,
- hlf_T *attrp // return: attributes of bad word or NULL
- // (only when "dir" is FORWARD)
-)
+/// Moves to the next spell error.
+/// "curline" is false for "[s", "]s", "[S" and "]S".
+/// "curline" is true to find word under/after cursor in the same line.
+/// For Insert mode completion "dir" is BACKWARD and "curline" is true: move
+/// to after badly spelled word before the cursor.
+///
+/// @param dir FORWARD or BACKWARD
+/// @param allwords true for "[s"/"]s", false for "[S"/"]S"
+/// @param attrp return: attributes of bad word or NULL (only when "dir" is FORWARD)
+///
+/// @return 0 if not found, length of the badly spelled word otherwise.
+size_t spell_move_to(win_T *wp, int dir, bool allwords, bool curline, hlf_T *attrp)
{
linenr_T lnum;
pos_T found_pos;
size_t found_len = 0;
- char_u *line;
- char_u *p;
- char_u *endp;
+ char_u *line;
+ char_u *p;
+ char_u *endp;
hlf_T attr = HLF_COUNT;
size_t len;
int has_syntax = syntax_present(wp);
int col;
bool can_spell;
- char_u *buf = NULL;
+ char_u *buf = NULL;
size_t buflen = 0;
int skip = 0;
int capcol = -1;
bool found_one = false;
bool wrapped = false;
- if (no_spell_checking(wp))
+ if (no_spell_checking(wp)) {
return 0;
+ }
// Start looking for bad word at the start of the line, because we can't
// start halfway through a word, we don't know where it starts or ends.
@@ -1410,8 +1451,9 @@ spell_move_to (
assert(buf && buflen >= len + MAXWLEN + 2);
// In first line check first word for Capital.
- if (lnum == 1)
+ if (lnum == 1) {
capcol = 0;
+ }
// For checking first word with a capital skip white space.
if (capcol == 0) {
@@ -1431,10 +1473,11 @@ spell_move_to (
// Copy the line into "buf" and append the start of the next line if
// possible.
STRCPY(buf, line);
- if (lnum < wp->w_buffer->b_ml.ml_line_count)
+ if (lnum < wp->w_buffer->b_ml.ml_line_count) {
spell_cat_line(buf + STRLEN(buf),
ml_get_buf(wp->w_buffer, lnum + 1, false),
MAXWLEN);
+ }
p = buf + skip;
endp = buf + len;
while (p < endp) {
@@ -1443,8 +1486,9 @@ spell_move_to (
if (dir == BACKWARD
&& lnum == wp->w_cursor.lnum
&& !wrapped
- && (colnr_T)(p - buf) >= wp->w_cursor.col)
+ && (colnr_T)(p - buf) >= wp->w_cursor.col) {
break;
+ }
// start of word
attr = HLF_COUNT;
@@ -1464,11 +1508,13 @@ spell_move_to (
if (has_syntax) {
col = (int)(p - buf);
(void)syn_get_id(wp, lnum, (colnr_T)col,
- FALSE, &can_spell, FALSE);
- if (!can_spell)
+ FALSE, &can_spell, FALSE);
+ if (!can_spell) {
attr = HLF_COUNT;
- } else
+ }
+ } else {
can_spell = true;
+ }
if (can_spell) {
found_one = true;
@@ -1479,8 +1525,9 @@ spell_move_to (
// No need to search further.
wp->w_cursor = found_pos;
xfree(buf);
- if (attrp != NULL)
+ if (attrp != NULL) {
*attrp = attr;
+ }
return len;
} else if (curline) {
// Insert mode completion: put cursor after
@@ -1490,8 +1537,9 @@ spell_move_to (
}
found_len = len;
}
- } else
+ } else {
found_one = true;
+ }
}
}
@@ -1529,22 +1577,24 @@ spell_move_to (
// starting line again and accept the last match.
lnum = wp->w_buffer->b_ml.ml_line_count;
wrapped = true;
- if (!shortmess(SHM_SEARCH))
+ if (!shortmess(SHM_SEARCH)) {
give_warning((char_u *)_(top_bot_msg), true);
+ }
}
capcol = -1;
} else {
- if (lnum < wp->w_buffer->b_ml.ml_line_count)
+ if (lnum < wp->w_buffer->b_ml.ml_line_count) {
++lnum;
- else if (!p_ws)
+ } else if (!p_ws) {
break; // at first line and 'nowrapscan'
- else {
+ } else {
// Wrap around to the start of the buffer. May search the
// starting line again and accept the first match.
lnum = 1;
wrapped = true;
- if (!shortmess(SHM_SEARCH))
+ if (!shortmess(SHM_SEARCH)) {
give_warning((char_u *)_(bot_top_msg), true);
+ }
}
// If we are back at the starting line and there is no match then
@@ -1555,17 +1605,19 @@ spell_move_to (
// Skip the characters at the start of the next line that were
// included in a match crossing line boundaries.
- if (attr == HLF_COUNT)
+ if (attr == HLF_COUNT) {
skip = (int)(p - endp);
- else
+ } else {
skip = 0;
+ }
// Capcol skips over the inserted space.
--capcol;
// But after empty line check first word in next line
- if (*skipwhite(line) == NUL)
+ if (*skipwhite(line) == NUL) {
capcol = 0;
+ }
}
line_breakcheck();
@@ -1581,12 +1633,13 @@ spell_move_to (
// to skip those bytes if the word was OK.
void spell_cat_line(char_u *buf, char_u *line, int maxlen)
{
- char_u *p;
+ char_u *p;
int n;
p = skipwhite(line);
- while (vim_strchr((char_u *)"*#/\"\t", *p) != NULL)
+ while (vim_strchr((char_u *)"*#/\"\t", *p) != NULL) {
p = skipwhite(p + 1);
+ }
if (*p != NUL) {
// Only worth concatenating if there is something else than spaces to
@@ -1630,8 +1683,9 @@ static void spell_load_lang(char_u *lang)
if (r == FAIL && *sl.sl_lang != NUL && round == 1
&& apply_autocmds(EVENT_SPELLFILEMISSING, lang,
- curbuf->b_fname, FALSE, curbuf))
+ curbuf->b_fname, FALSE, curbuf)) {
continue;
+ }
break;
}
break;
@@ -1647,9 +1701,8 @@ static void spell_load_lang(char_u *lang)
lang);
do_cmdline_cmd(autocmd_buf);
} else {
- smsg(
- _("Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""),
- lang, spell_enc(), lang);
+ smsg(_("Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""),
+ lang, spell_enc(), lang);
}
} else if (sl.sl_slang != NULL) {
// At least one file was loaded, now load ALL the additions.
@@ -1662,9 +1715,9 @@ static void spell_load_lang(char_u *lang)
// use "latin1" for "latin9". And limit to 60 characters (just in case).
char_u *spell_enc(void)
{
-
- if (STRLEN(p_enc) < 60 && STRCMP(p_enc, "iso-8859-15") != 0)
+ if (STRLEN(p_enc) < 60 && STRCMP(p_enc, "iso-8859-15") != 0) {
return p_enc;
+ }
return (char_u *)"latin1";
}
@@ -1673,7 +1726,7 @@ char_u *spell_enc(void)
static void int_wordlist_spl(char_u *fname)
{
vim_snprintf((char *)fname, MAXPATHL, SPL_FNAME_TMPL,
- int_wordlist, spell_enc());
+ int_wordlist, spell_enc());
}
// Allocate a new slang_T for language "lang". "lang" can be NULL.
@@ -1683,8 +1736,9 @@ slang_T *slang_alloc(char_u *lang)
{
slang_T *lp = xcalloc(1, sizeof(slang_T));
- if (lang != NULL)
+ if (lang != NULL) {
lp->sl_name = vim_strsave(lang);
+ }
ga_init(&lp->sl_rep, sizeof(fromto_T), 10);
ga_init(&lp->sl_repsal, sizeof(fromto_T), 10);
lp->sl_compmax = MAXWLEN;
@@ -1722,7 +1776,7 @@ static void free_fromto(fromto_T *ftp) {
// Clear an slang_T so that the file can be reloaded.
void slang_clear(slang_T *lp)
{
- garray_T *gap;
+ garray_T *gap;
XFREE_CLEAR(lp->sl_fbyts);
XFREE_CLEAR(lp->sl_kbyts);
@@ -1792,17 +1846,18 @@ void slang_clear_sug(slang_T *lp)
// Invoked through do_in_runtimepath().
static void spell_load_cb(char_u *fname, void *cookie)
{
- spelload_T *slp = (spelload_T *)cookie;
- slang_T *slang;
+ spelload_T *slp = (spelload_T *)cookie;
+ slang_T *slang;
slang = spell_load_file(fname, slp->sl_lang, NULL, false);
if (slang != NULL) {
// When a previously loaded file has NOBREAK also use it for the
// ".add" files.
- if (slp->sl_nobreak && slang->sl_add)
+ if (slp->sl_nobreak && slang->sl_add) {
slang->sl_nobreak = true;
- else if (slang->sl_nobreak)
+ } else if (slang->sl_nobreak) {
slp->sl_nobreak = true;
+ }
slp->sl_slang = slang;
}
@@ -1818,10 +1873,10 @@ static void spell_load_cb(char_u *fname, void *cookie)
void count_common_word(slang_T *lp, char_u *word, int len, int count)
{
hash_T hash;
- hashitem_T *hi;
+ hashitem_T *hi;
wordcount_T *wc;
char_u buf[MAXWLEN];
- char_u *p;
+ char_u *p;
if (len == -1) {
p = word;
@@ -1842,21 +1897,18 @@ void count_common_word(slang_T *lp, char_u *word, int len, int count)
hash_add_item(&lp->sl_wordcount, hi, wc->wc_word, hash);
} else {
wc = HI2WC(hi);
- if ((wc->wc_count += count) < (unsigned)count) // check for overflow
+ if ((wc->wc_count += count) < (unsigned)count) { // check for overflow
wc->wc_count = MAXWORDCOUNT;
+ }
}
}
-// Adjust the score of common words.
-static int
-score_wordcount_adj (
- slang_T *slang,
- int score,
- char_u *word,
- bool split // word was split, less bonus
-)
+/// Adjust the score of common words.
+///
+/// @param split word was split, less bonus
+static int score_wordcount_adj(slang_T *slang, int score, char_u *word, bool split)
{
- hashitem_T *hi;
+ hashitem_T *hi;
wordcount_T *wc;
int bonus;
int newscore;
@@ -1864,18 +1916,21 @@ score_wordcount_adj (
hi = hash_find(&slang->sl_wordcount, word);
if (!HASHITEM_EMPTY(hi)) {
wc = HI2WC(hi);
- if (wc->wc_count < SCORE_THRES2)
+ if (wc->wc_count < SCORE_THRES2) {
bonus = SCORE_COMMON1;
- else if (wc->wc_count < SCORE_THRES3)
+ } else if (wc->wc_count < SCORE_THRES3) {
bonus = SCORE_COMMON2;
- else
+ } else {
bonus = SCORE_COMMON3;
- if (split)
+ }
+ if (split) {
newscore = score - bonus / 2;
- else
+ } else {
newscore = score - bonus;
- if (newscore < 0)
+ }
+ if (newscore < 0) {
return 0;
+ }
return newscore;
}
return score;
@@ -1885,11 +1940,13 @@ score_wordcount_adj (
// Like strchr() but independent of locale.
bool byte_in_str(char_u *str, int n)
{
- char_u *p;
+ char_u *p;
- for (p = str; *p != NUL; ++p)
- if (*p == n)
+ for (p = str; *p != NUL; ++p) {
+ if (*p == n) {
return true;
+ }
+ }
return false;
}
@@ -1897,24 +1954,27 @@ bool byte_in_str(char_u *str, int n)
// in "slang->sl_syl_items".
int init_syl_tab(slang_T *slang)
{
- char_u *p;
- char_u *s;
+ char_u *p;
+ char_u *s;
int l;
ga_init(&slang->sl_syl_items, sizeof(syl_item_T), 4);
p = vim_strchr(slang->sl_syllable, '/');
while (p != NULL) {
*p++ = NUL;
- if (*p == NUL) // trailing slash
+ if (*p == NUL) { // trailing slash
break;
+ }
s = p;
p = vim_strchr(p, '/');
- if (p == NULL)
+ if (p == NULL) {
l = (int)STRLEN(s);
- else
+ } else {
l = (int)(p - s);
- if (l >= SY_MAXLEN)
+ }
+ if (l >= SY_MAXLEN) {
return SP_FORMERROR;
+ }
syl_item_T *syl = GA_APPEND_VIA_PTR(syl_item_T, &slang->sl_syl_items);
STRLCPY(syl->sy_chars, s, l + 1);
@@ -1932,11 +1992,12 @@ static int count_syllables(slang_T *slang, const char_u *word)
int cnt = 0;
bool skip = false;
int len;
- syl_item_T *syl;
+ syl_item_T *syl;
int c;
- if (slang->sl_syllable == NULL)
+ if (slang->sl_syllable == NULL) {
return 0;
+ }
for (const char_u *p = word; *p != NUL; p += len) {
// When running into a space reset counter.
@@ -1951,8 +2012,9 @@ static int count_syllables(slang_T *slang, const char_u *word)
for (int i = 0; i < slang->sl_syl_items.ga_len; ++i) {
syl = ((syl_item_T *)slang->sl_syl_items.ga_data) + i;
if (syl->sy_len > len
- && STRNCMP(p, syl->sy_chars, syl->sy_len) == 0)
+ && STRNCMP(p, syl->sy_chars, syl->sy_len) == 0) {
len = syl->sy_len;
+ }
}
if (len != 0) { // found a match, count syllable
++cnt;
@@ -1961,9 +2023,9 @@ static int count_syllables(slang_T *slang, const char_u *word)
// No recognized syllable item, at least a syllable char then?
c = utf_ptr2char(p);
len = (*mb_ptr2len)(p);
- if (vim_strchr(slang->sl_syllable, c) == NULL)
+ if (vim_strchr(slang->sl_syllable, c) == NULL) {
skip = false; // No, search for next syllable
- else if (!skip) {
+ } else if (!skip) {
++cnt; // Yes, count it
skip = true; // don't count following syllable chars
}
@@ -1977,26 +2039,26 @@ static int count_syllables(slang_T *slang, const char_u *word)
char_u *did_set_spelllang(win_T *wp)
{
garray_T ga;
- char_u *splp;
- char_u *region;
+ char_u *splp;
+ char_u *region;
char_u region_cp[3];
bool filename;
int region_mask;
- slang_T *slang;
+ slang_T *slang;
int c;
char_u lang[MAXWLEN + 1];
char_u spf_name[MAXPATHL];
int len;
- char_u *p;
+ char_u *p;
int round;
- char_u *spf;
- char_u *use_region = NULL;
+ char_u *spf;
+ char_u *use_region = NULL;
bool dont_use_region = false;
bool nobreak = false;
- langp_T *lp, *lp2;
+ langp_T *lp, *lp2;
static bool recursive = false;
- char_u *ret_msg = NULL;
- char_u *spl_copy;
+ char_u *ret_msg = NULL;
+ char_u *spl_copy;
bufref_T bufref;
set_bufref(&bufref, wp->w_buffer);
@@ -2004,8 +2066,9 @@ char_u *did_set_spelllang(win_T *wp)
// We don't want to do this recursively. May happen when a language is
// not available and the SpellFileMissing autocommand opens a new buffer
// in which 'spell' is set.
- if (recursive)
+ if (recursive) {
return NULL;
+ }
recursive = true;
ga_init(&ga, sizeof(langp_T), 2);
@@ -2046,8 +2109,9 @@ char_u *did_set_spelllang(win_T *wp)
STRLCPY(region_cp, p + 1, 3);
memmove(p, p + 3, len - (p - lang) - 2);
region = region_cp;
- } else
+ } else {
dont_use_region = true;
+ }
// Check if we loaded this language before.
for (slang = first_lang; slang != NULL; slang = slang->sl_next) {
@@ -2061,28 +2125,32 @@ char_u *did_set_spelllang(win_T *wp)
if (len > 3 && lang[len - 3] == '_') {
region = lang + len - 2;
lang[len - 3] = NUL;
- } else
+ } else {
dont_use_region = true;
+ }
// Check if we loaded this language before.
- for (slang = first_lang; slang != NULL; slang = slang->sl_next)
- if (STRICMP(lang, slang->sl_name) == 0)
+ for (slang = first_lang; slang != NULL; slang = slang->sl_next) {
+ if (STRICMP(lang, slang->sl_name) == 0) {
break;
+ }
+ }
}
if (region != NULL) {
// If the region differs from what was used before then don't
// use it for 'spellfile'.
- if (use_region != NULL && STRCMP(region, use_region) != 0)
+ if (use_region != NULL && STRCMP(region, use_region) != 0) {
dont_use_region = true;
+ }
use_region = region;
}
// If not found try loading the language now.
if (slang == NULL) {
- if (filename)
+ if (filename) {
(void)spell_load_file(lang, lang, NULL, false);
- else {
+ } else {
spell_load_lang(lang);
// SpellFileMissing autocommands may do anything, including
// destroying the buffer we are using...
@@ -2105,16 +2173,19 @@ char_u *did_set_spelllang(win_T *wp)
c = find_region(slang->sl_regions, region);
if (c == REGION_ALL) {
if (slang->sl_add) {
- if (*slang->sl_regions != NUL)
+ if (*slang->sl_regions != NUL) {
// This addition file is for other regions.
region_mask = 0;
- } else
+ }
+ } else {
// This is probably an error. Give a warning and
// accept the words anyway.
smsg(_("Warning: region %s not supported"),
region);
- } else
+ }
+ } else {
region_mask = 1 << c;
+ }
}
if (region_mask != 0) {
@@ -2123,8 +2194,9 @@ char_u *did_set_spelllang(win_T *wp)
p_->lp_region = region_mask;
use_midword(slang, wp);
- if (slang->sl_nobreak)
+ if (slang->sl_nobreak) {
nobreak = true;
+ }
}
}
}
@@ -2138,8 +2210,9 @@ char_u *did_set_spelllang(win_T *wp)
for (round = 0; round == 0 || *spf != NUL; ++round) {
if (round == 0) {
// Internal wordlist, if there is one.
- if (int_wordlist == NULL)
+ if (int_wordlist == NULL) {
continue;
+ }
int_wordlist_spl(spf_name);
} else {
// One entry in 'spellfile'.
@@ -2154,8 +2227,9 @@ char_u *did_set_spelllang(win_T *wp)
break;
}
}
- if (c < ga.ga_len)
+ if (c < ga.ga_len) {
continue;
+ }
}
// Check if it was loaded already.
@@ -2169,31 +2243,34 @@ char_u *did_set_spelllang(win_T *wp)
// Not loaded, try loading it now. The language name includes the
// region name, the region is ignored otherwise. for int_wordlist
// use an arbitrary name.
- if (round == 0)
+ if (round == 0) {
STRCPY(lang, "internal wordlist");
- else {
+ } else {
STRLCPY(lang, path_tail(spf_name), MAXWLEN + 1);
p = vim_strchr(lang, '.');
- if (p != NULL)
+ if (p != NULL) {
*p = NUL; // truncate at ".encoding.add"
+ }
}
slang = spell_load_file(spf_name, lang, NULL, true);
// If one of the languages has NOBREAK we assume the addition
// files also have this.
- if (slang != NULL && nobreak)
+ if (slang != NULL && nobreak) {
slang->sl_nobreak = true;
+ }
}
if (slang != NULL) {
region_mask = REGION_ALL;
if (use_region != NULL && !dont_use_region) {
// find region in sl_regions
c = find_region(slang->sl_regions, use_region);
- if (c != REGION_ALL)
+ if (c != REGION_ALL) {
region_mask = 1 << c;
- else if (*slang->sl_regions != NUL)
+ } else if (*slang->sl_regions != NUL) {
// This spell file is for other regions.
region_mask = 0;
+ }
}
if (region_mask != 0) {
@@ -2219,36 +2296,38 @@ char_u *did_set_spelllang(win_T *wp)
lp = LANGP_ENTRY(ga, i);
// sound folding
- if (!GA_EMPTY(&lp->lp_slang->sl_sal))
+ if (!GA_EMPTY(&lp->lp_slang->sl_sal)) {
// language does sound folding itself
lp->lp_sallang = lp->lp_slang;
- else
+ } else {
// find first similar language that does sound folding
for (int j = 0; j < ga.ga_len; ++j) {
lp2 = LANGP_ENTRY(ga, j);
if (!GA_EMPTY(&lp2->lp_slang->sl_sal)
&& STRNCMP(lp->lp_slang->sl_name,
- lp2->lp_slang->sl_name, 2) == 0) {
+ lp2->lp_slang->sl_name, 2) == 0) {
lp->lp_sallang = lp2->lp_slang;
break;
}
}
+ }
// REP items
- if (!GA_EMPTY(&lp->lp_slang->sl_rep))
+ if (!GA_EMPTY(&lp->lp_slang->sl_rep)) {
// language has REP items itself
lp->lp_replang = lp->lp_slang;
- else
+ } else {
// find first similar language that has REP items
for (int j = 0; j < ga.ga_len; ++j) {
lp2 = LANGP_ENTRY(ga, j);
if (!GA_EMPTY(&lp2->lp_slang->sl_rep)
&& STRNCMP(lp->lp_slang->sl_name,
- lp2->lp_slang->sl_name, 2) == 0) {
+ lp2->lp_slang->sl_name, 2) == 0) {
lp->lp_replang = lp2->lp_slang;
break;
}
}
+ }
}
theend:
@@ -2302,10 +2381,12 @@ static int find_region(char_u *rp, char_u *region)
int i;
for (i = 0;; i += 2) {
- if (rp[i] == NUL)
+ if (rp[i] == NUL) {
return REGION_ALL;
- if (rp[i] == region[0] && rp[i + 1] == region[1])
+ }
+ if (rp[i] == region[0] && rp[i + 1] == region[1]) {
break;
+ }
}
return i / 2;
}
@@ -2323,7 +2404,7 @@ static int find_region(char_u *rp, char_u *region)
int captype(char_u *word, char_u *end)
FUNC_ATTR_NONNULL_ARG(1)
{
- char_u *p;
+ char_u *p;
int firstcap;
bool allcap;
bool past_second = false; // past second word char
@@ -2356,10 +2437,12 @@ int captype(char_u *word, char_u *end)
}
}
- if (allcap)
+ if (allcap) {
return WF_ALLCAP;
- if (firstcap)
+ }
+ if (firstcap) {
return WF_ONECAP;
+ }
return 0;
}
@@ -2373,7 +2456,7 @@ static int badword_captype(char_u *word, char_u *end)
int c;
int l, u;
bool first;
- char_u *p;
+ char_u *p;
if (flags & WF_KEEPCAP) {
// Count the number of UPPER and lower case letters.
@@ -2383,23 +2466,27 @@ static int badword_captype(char_u *word, char_u *end)
c = PTR2CHAR(p);
if (SPELL_ISUPPER(c)) {
++u;
- if (p == word)
+ if (p == word) {
first = true;
- } else
+ }
+ } else {
++l;
+ }
}
// If there are more UPPER than lower case letters suggest an
// ALLCAP word. Otherwise, if the first letter is UPPER then
// suggest ONECAP. Exception: "ALl" most likely should be "All",
// require three upper case letters.
- if (u > l && u > 2)
+ if (u > l && u > 2) {
flags |= WF_ALLCAP;
- else if (first)
+ } else if (first) {
flags |= WF_ONECAP;
+ }
- if (u >= 2 && l >= 2) // maCARONI maCAroni
+ if (u >= 2 && l >= 2) { // maCARONI maCAroni
flags |= WF_MIXCAP;
+ }
}
return flags;
}
@@ -2407,7 +2494,7 @@ static int badword_captype(char_u *word, char_u *end)
// Delete the internal wordlist and its .spl file.
void spell_delete_wordlist(void)
{
- char_u fname[MAXPATHL] = {0};
+ char_u fname[MAXPATHL] = { 0 };
if (int_wordlist != NULL) {
os_remove((char *)int_wordlist);
@@ -2420,7 +2507,7 @@ void spell_delete_wordlist(void)
// Free all languages.
void spell_free_all(void)
{
- slang_T *slang;
+ slang_T *slang;
// Go through all buffers and handle 'spelllang'. <VN>
FOR_ALL_BUFFERS(buf) {
@@ -2475,10 +2562,10 @@ static int bytes2offset(char_u **pp)
c = *p++;
if ((c & 0x80) == 0x00) { // 1 byte
nr = c - 1;
- } else if ((c & 0xc0) == 0x80) { // 2 bytes
+ } else if ((c & 0xc0) == 0x80) { // 2 bytes
nr = (c & 0x3f) - 1;
nr = nr * 255 + (*p++ - 1);
- } else if ((c & 0xe0) == 0xc0) { // 3 bytes
+ } else if ((c & 0xe0) == 0xc0) { // 3 bytes
nr = (c & 0x1f) - 1;
nr = nr * 255 + (*p++ - 1);
nr = nr * 255 + (*p++ - 1);
@@ -2537,8 +2624,9 @@ void clear_spell_chartab(spelltab_T *sp)
// We include digits. A word shouldn't start with a digit, but handling
// that is done separately.
- for (i = '0'; i <= '9'; ++i)
+ for (i = '0'; i <= '9'; ++i) {
sp->st_isw[i] = true;
+ }
for (i = 'A'; i <= 'Z'; ++i) {
sp->st_isw[i] = true;
sp->st_isu[i] = true;
@@ -2627,9 +2715,10 @@ bool spell_iswordp_nmw(const char_u *p, win_T *wp)
static bool spell_mb_isword_class(int cl, const win_T *wp)
FUNC_ATTR_PURE FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
- if (wp->w_s->b_cjk)
+ if (wp->w_s->b_cjk) {
// East Asian characters are not considered word characters.
return cl == 2 || cl == 0x2800;
+ }
return cl >= 2 && cl != 0x2070 && cl != 0x2080 && cl != 3;
}
@@ -2641,11 +2730,12 @@ static bool spell_iswordp_w(const int *p, const win_T *wp)
const int *s;
if (*p < 256 ? wp->w_s->b_spell_ismw[*p]
- : (wp->w_s->b_spell_ismw_mb != NULL
- && vim_strchr(wp->w_s->b_spell_ismw_mb, *p) != NULL))
+ : (wp->w_s->b_spell_ismw_mb != NULL
+ && vim_strchr(wp->w_s->b_spell_ismw_mb, *p) != NULL)) {
s = p + 1;
- else
+ } else {
s = p;
+ }
if (*s > 255) {
return spell_mb_isword_class(utf_class(*s), wp);
@@ -2657,8 +2747,7 @@ static bool spell_iswordp_w(const int *p, const win_T *wp)
// Uses the character definitions from the .spl file.
// When using a multi-byte 'encoding' the length may change!
// Returns FAIL when something wrong.
-int spell_casefold(const win_T *wp, char_u *str, int len, char_u *buf,
- int buflen)
+int spell_casefold(const win_T *wp, char_u *str, int len, char_u *buf, int buflen)
FUNC_ATTR_NONNULL_ALL
{
if (len >= buflen) {
@@ -2708,8 +2797,8 @@ static int sps_limit = 9999; // max nr of suggestions given
// Sets "sps_flags" and "sps_limit".
int spell_check_sps(void)
{
- char_u *p;
- char_u *s;
+ char_u *p;
+ char_u *s;
char_u buf[MAXPATHL];
int f;
@@ -2742,12 +2831,14 @@ int spell_check_sps(void)
sps_limit = 9999;
return FAIL;
}
- if (f != 0)
+ if (f != 0) {
sps_flags = f;
+ }
}
- if (sps_flags == 0)
+ if (sps_flags == 0) {
sps_flags = SPS_BEST;
+ }
return OK;
}
@@ -2758,13 +2849,13 @@ int spell_check_sps(void)
// When "count" is non-zero use that suggestion.
void spell_suggest(int count)
{
- char_u *line;
+ char_u *line;
pos_T prev_cursor = curwin->w_cursor;
char_u wcopy[MAXWLEN + 2];
- char_u *p;
+ char_u *p;
int c;
suginfo_T sug;
- suggest_T *stp;
+ suggest_T *stp;
int mouse_used;
int need_cap;
int limit;
@@ -2833,36 +2924,39 @@ void spell_suggest(int count)
// Get the list of suggestions. Limit to 'lines' - 2 or the number in
// 'spellsuggest', whatever is smaller.
- if (sps_limit > (int)Rows - 2)
- limit = (int)Rows - 2;
- else
+ if (sps_limit > Rows - 2) {
+ limit = Rows - 2;
+ } else {
limit = sps_limit;
+ }
spell_find_suggest(line + curwin->w_cursor.col, badlen, &sug, limit,
- true, need_cap, true);
+ true, need_cap, true);
- if (GA_EMPTY(&sug.su_ga))
+ if (GA_EMPTY(&sug.su_ga)) {
MSG(_("Sorry, no suggestions"));
- else if (count > 0) {
- if (count > sug.su_ga.ga_len)
+ } else if (count > 0) {
+ if (count > sug.su_ga.ga_len) {
smsg(_("Sorry, only %" PRId64 " suggestions"),
(int64_t)sug.su_ga.ga_len);
+ }
} else {
// When 'rightleft' is set the list is drawn right-left.
cmdmsg_rl = curwin->w_p_rl;
- if (cmdmsg_rl)
+ if (cmdmsg_rl) {
msg_col = Columns - 1;
+ }
// List the suggestions.
msg_start();
msg_row = Rows - 1; // for when 'cmdheight' > 1
lines_left = Rows; // avoid more prompt
vim_snprintf((char *)IObuff, IOSIZE, _("Change \"%.*s\" to:"),
- sug.su_badlen, sug.su_badptr);
+ sug.su_badlen, sug.su_badptr);
if (cmdmsg_rl && STRNCMP(IObuff, "Change", 6) == 0) {
// And now the rabbit from the high hat: Avoid showing the
// untranslated message rightleft.
vim_snprintf((char *)IObuff, IOSIZE, ":ot \"%.*s\" egnahC",
- sug.su_badlen, sug.su_badptr);
+ sug.su_badlen, sug.su_badptr);
}
msg_puts((const char *)IObuff);
msg_clr_eos();
@@ -2875,10 +2969,11 @@ void spell_suggest(int count)
// The suggested word may replace only part of the bad word, add
// the not replaced part.
STRLCPY(wcopy, stp->st_word, MAXWLEN + 1);
- if (sug.su_badlen > stp->st_orglen)
+ if (sug.su_badlen > stp->st_orglen) {
STRLCPY(wcopy + stp->st_wordlen,
- sug.su_badptr + stp->st_orglen,
- sug.su_badlen - stp->st_orglen + 1);
+ sug.su_badptr + stp->st_orglen,
+ sug.su_badlen - stp->st_orglen + 1);
+ }
vim_snprintf((char *)IObuff, IOSIZE, "%2d", i + 1);
if (cmdmsg_rl) {
rl_mirror(IObuff);
@@ -2897,16 +2992,18 @@ void spell_suggest(int count)
if (p_verbose > 0) {
// Add the score.
- if (sps_flags & (SPS_DOUBLE | SPS_BEST))
+ if (sps_flags & (SPS_DOUBLE | SPS_BEST)) {
vim_snprintf((char *)IObuff, IOSIZE, " (%s%d - %d)",
- stp->st_salscore ? "s " : "",
- stp->st_score, stp->st_altscore);
- else
+ stp->st_salscore ? "s " : "",
+ stp->st_score, stp->st_altscore);
+ } else {
vim_snprintf((char *)IObuff, IOSIZE, " (%d)",
- stp->st_score);
- if (cmdmsg_rl)
+ stp->st_score);
+ }
+ if (cmdmsg_rl) {
// Mirror the numbers, but keep the leading space.
rl_mirror(IObuff + 1);
+ }
msg_advance(30);
msg_puts((const char *)IObuff);
}
@@ -2941,8 +3038,8 @@ void spell_suggest(int count)
// repl_to.
repl_from = vim_strnsave(sug.su_badptr, sug.su_badlen);
vim_snprintf((char *)IObuff, IOSIZE, "%s%.*s", stp->st_word,
- sug.su_badlen - stp->st_orglen,
- sug.su_badptr + stp->st_orglen);
+ sug.su_badlen - stp->st_orglen,
+ sug.su_badptr + stp->st_orglen);
repl_to = vim_strsave(IObuff);
} else {
// Replacing su_badlen or more, use the whole word.
@@ -2961,7 +3058,7 @@ void spell_suggest(int count)
ResetRedobuff();
AppendToRedobuff("ciw");
AppendToRedobuffLit(p + c,
- stp->st_wordlen + sug.su_badlen - stp->st_orglen);
+ stp->st_wordlen + sug.su_badlen - stp->st_orglen);
AppendCharToRedobuff(ESC);
// "p" may be freed here
@@ -2969,8 +3066,9 @@ void spell_suggest(int count)
curwin->w_cursor.col = c;
changed_bytes(curwin->w_cursor.lnum, c);
- } else
+ } else {
curwin->w_cursor = prev_cursor;
+ }
spell_find_cleanup(&sug);
xfree(line);
@@ -2982,27 +3080,28 @@ void spell_suggest(int count)
static bool check_need_cap(linenr_T lnum, colnr_T col)
{
bool need_cap = false;
- char_u *line;
- char_u *line_copy = NULL;
- char_u *p;
+ char_u *line;
+ char_u *line_copy = NULL;
+ char_u *p;
colnr_T endcol;
regmatch_T regmatch;
- if (curwin->w_s->b_cap_prog == NULL)
+ if (curwin->w_s->b_cap_prog == NULL) {
return false;
+ }
line = get_cursor_line_ptr();
endcol = 0;
if (getwhitecols(line) >= (int)col) {
// At start of line, check if previous line is empty or sentence
// ends there.
- if (lnum == 1)
+ if (lnum == 1) {
need_cap = true;
- else {
+ } else {
line = ml_get(lnum - 1);
- if (*skipwhite(line) == NUL)
+ if (*skipwhite(line) == NUL) {
need_cap = true;
- else {
+ } else {
// Append a space in place of the line break.
line_copy = concat_str(line, (char_u *)" ");
line = line_copy;
@@ -3042,10 +3141,10 @@ static bool check_need_cap(linenr_T lnum, colnr_T col)
void ex_spellrepall(exarg_T *eap)
{
pos_T pos = curwin->w_cursor;
- char_u *frompat;
+ char_u *frompat;
int addlen;
- char_u *line;
- char_u *p;
+ char_u *line;
+ char_u *p;
bool save_ws = p_ws;
linenr_T prev_lnum = 0;
@@ -3072,7 +3171,7 @@ void ex_spellrepall(exarg_T *eap)
// when changing "etc" to "etc.".
line = get_cursor_line_ptr();
if (addlen <= 0 || STRNCMP(line + curwin->w_cursor.col,
- repl_to, STRLEN(repl_to)) != 0) {
+ repl_to, STRLEN(repl_to)) != 0) {
p = xmalloc(STRLEN(line) + addlen + 1);
memmove(p, line, curwin->w_cursor.col);
STRCPY(p + curwin->w_cursor.col, repl_to);
@@ -3093,26 +3192,23 @@ void ex_spellrepall(exarg_T *eap)
curwin->w_cursor = pos;
xfree(frompat);
- if (sub_nsubs == 0)
+ if (sub_nsubs == 0) {
EMSG2(_("E753: Not found: %s"), repl_from);
- else
+ } else {
do_sub_msg(false);
+ }
}
-// Find spell suggestions for "word". Return them in the growarray "*gap" as
-// a list of allocated strings.
-void
-spell_suggest_list (
- garray_T *gap,
- char_u *word,
- int maxcount, // maximum nr of suggestions
- bool need_cap, // 'spellcapcheck' matched
- bool interactive
-)
+/// Find spell suggestions for "word". Return them in the growarray "*gap" as
+/// a list of allocated strings.
+///
+/// @param maxcount maximum nr of suggestions
+/// @param need_cap 'spellcapcheck' matched
+void spell_suggest_list(garray_T *gap, char_u *word, int maxcount, bool need_cap, bool interactive)
{
suginfo_T sug;
- suggest_T *stp;
- char_u *wcopy;
+ suggest_T *stp;
+ char_u *wcopy;
spell_find_suggest(word, 0, &sug, maxcount, false, need_cap, interactive);
@@ -3134,44 +3230,41 @@ spell_suggest_list (
spell_find_cleanup(&sug);
}
-// Find spell suggestions for the word at the start of "badptr".
-// Return the suggestions in "su->su_ga".
-// The maximum number of suggestions is "maxcount".
-// Note: does use info for the current window.
-// This is based on the mechanisms of Aspell, but completely reimplemented.
-static void
-spell_find_suggest (
- char_u *badptr,
- int badlen, // length of bad word or 0 if unknown
- suginfo_T *su,
- int maxcount,
- bool banbadword, // don't include badword in suggestions
- bool need_cap, // word should start with capital
- bool interactive
-)
+/// Find spell suggestions for the word at the start of "badptr".
+/// Return the suggestions in "su->su_ga".
+/// The maximum number of suggestions is "maxcount".
+/// Note: does use info for the current window.
+/// This is based on the mechanisms of Aspell, but completely reimplemented.
+///
+/// @param badlen length of bad word or 0 if unknown
+/// @param banbadword don't include badword in suggestions
+/// @param need_cap word should start with capital
+static void spell_find_suggest(char_u *badptr, int badlen, suginfo_T *su, int maxcount,
+ bool banbadword, bool need_cap, bool interactive)
{
hlf_T attr = HLF_COUNT;
char_u buf[MAXPATHL];
- char_u *p;
+ char_u *p;
bool do_combine = false;
- char_u *sps_copy;
+ char_u *sps_copy;
static bool expr_busy = false;
int c;
- langp_T *lp;
+ langp_T *lp;
bool did_intern = false;
// Set the info in "*su".
memset(su, 0, sizeof(suginfo_T));
ga_init(&su->su_ga, (int)sizeof(suggest_T), 10);
ga_init(&su->su_sga, (int)sizeof(suggest_T), 10);
- if (*badptr == NUL)
+ if (*badptr == NUL) {
return;
+ }
hash_init(&su->su_banned);
su->su_badptr = badptr;
- if (badlen != 0)
+ if (badlen != 0) {
su->su_badlen = badlen;
- else {
+ } else {
size_t tmplen = spell_check(curwin, su->su_badptr, &attr, NULL, false);
assert(tmplen <= INT_MAX);
su->su_badlen = (int)tmplen;
@@ -3179,8 +3272,9 @@ spell_find_suggest (
su->su_maxcount = maxcount;
su->su_maxscore = SCORE_MAXINIT;
- if (su->su_badlen >= MAXWLEN)
+ if (su->su_badlen >= MAXWLEN) {
su->su_badlen = MAXWLEN - 1; // just in case
+ }
STRLCPY(su->su_badword, su->su_badptr, su->su_badlen + 1);
(void)spell_casefold(curwin, su->su_badptr, su->su_badlen, su->su_fbadword,
MAXWLEN);
@@ -3192,9 +3286,10 @@ spell_find_suggest (
// get caps flags for bad word
su->su_badflags = badword_captype(su->su_badptr,
- su->su_badptr + su->su_badlen);
- if (need_cap)
+ su->su_badptr + su->su_badlen);
+ if (need_cap) {
su->su_badflags |= WF_ONECAP;
+ }
// Find the default language for sound folding. We simply use the first
// one in 'spelllang' that supports sound folding. That's good for when
@@ -3210,9 +3305,10 @@ spell_find_suggest (
// Soundfold the bad word with the default sound folding, so that we don't
// have to do this many times.
- if (su->su_sallang != NULL)
+ if (su->su_sallang != NULL) {
spell_soundfold(su->su_sallang, su->su_fbadword, true,
- su->su_sal_badword);
+ su->su_sal_badword);
+ }
// If the word is not capitalised and spell_check() doesn't consider the
// word to be bad then it might need to be capitalised. Add a suggestion
@@ -3221,12 +3317,13 @@ spell_find_suggest (
if (!SPELL_ISUPPER(c) && attr == HLF_COUNT) {
make_case_word(su->su_badword, buf, WF_ONECAP);
add_suggestion(su, &su->su_ga, buf, su->su_badlen, SCORE_ICASE,
- 0, true, su->su_sallang, false);
+ 0, true, su->su_sallang, false);
}
// Ban the bad word itself. It may appear in another region.
- if (banbadword)
+ if (banbadword) {
add_banned(su, su->su_badword);
+ }
// Make a copy of 'spellsuggest', because the expression may change it.
sps_copy = vim_strsave(p_sps);
@@ -3258,10 +3355,11 @@ spell_find_suggest (
xfree(sps_copy);
- if (do_combine)
+ if (do_combine) {
// Combine the two list of suggestions. This must be done last,
// because sorting changes the order again.
score_combine(su);
+ }
}
// Find suggestions by evaluating expression "expr".
@@ -3297,9 +3395,9 @@ static void spell_suggest_expr(suginfo_T *su, char_u *expr)
// Find suggestions in file "fname". Used for "file:" in 'spellsuggest'.
static void spell_suggest_file(suginfo_T *su, char_u *fname)
{
- FILE *fd;
+ FILE *fd;
char_u line[MAXWLEN * 2];
- char_u *p;
+ char_u *p;
int len;
char_u cword[MAXWLEN];
@@ -3315,13 +3413,15 @@ static void spell_suggest_file(suginfo_T *su, char_u *fname)
line_breakcheck();
p = vim_strchr(line, '/');
- if (p == NULL)
+ if (p == NULL) {
continue; // No Tab found, just skip the line.
+ }
*p++ = NUL;
if (STRICMP(su->su_badword, line) == 0) {
// Match! Isolate the good word, until CR or NL.
- for (len = 0; p[len] >= ' '; ++len)
+ for (len = 0; p[len] >= ' '; ++len) {
;
+ }
p[len] = NUL;
// If the suggestion doesn't have specific case duplicate the case
@@ -3332,7 +3432,7 @@ static void spell_suggest_file(suginfo_T *su, char_u *fname)
}
add_suggestion(su, &su->su_ga, p, su->su_badlen,
- SCORE_FILE, 0, true, su->su_sallang, false);
+ SCORE_FILE, 0, true, su->su_sallang, false);
}
}
@@ -3360,15 +3460,17 @@ static void spell_suggest_intern(suginfo_T *su, bool interactive)
suggest_try_change(su);
// For the resulting top-scorers compute the sound-a-like score.
- if (sps_flags & SPS_DOUBLE)
+ if (sps_flags & SPS_DOUBLE) {
score_comp_sal(su);
+ }
// 3. Try finding sound-a-like words.
if ((sps_flags & SPS_FAST) == 0) {
- if (sps_flags & SPS_BEST)
+ if (sps_flags & SPS_BEST) {
// Adjust the word score for the suggestions found so far for how
// they sounds like.
rescore_suggestions(su);
+ }
// While going through the soundfold tree "su_maxscore" is the score
// for the soundfold word, limits the changes that are being tried,
@@ -3407,9 +3509,10 @@ static void spell_suggest_intern(suginfo_T *su, bool interactive)
}
if ((sps_flags & SPS_DOUBLE) == 0 && su->su_ga.ga_len != 0) {
- if (sps_flags & SPS_BEST)
+ if (sps_flags & SPS_BEST) {
// Adjust the word score for how it sounds like.
rescore_suggestions(su);
+ }
// Remove bogus suggestions, sort and truncate at "maxcount".
check_suggestions(su, &su->su_ga);
@@ -3420,7 +3523,7 @@ static void spell_suggest_intern(suginfo_T *su, bool interactive)
// Free the info put in "*su" by spell_find_suggest().
static void spell_find_cleanup(suginfo_T *su)
{
-# define FREE_SUG_WORD(sug) xfree(sug->st_word)
+#define FREE_SUG_WORD(sug) xfree(sug->st_word)
// Free the suggestions.
GA_DEEP_CLEAR(&su->su_ga, suggest_T, FREE_SUG_WORD);
GA_DEEP_CLEAR(&su->su_sga, suggest_T, FREE_SUG_WORD);
@@ -3459,11 +3562,13 @@ static void allcap_copy(char_u *word, char_u *wcopy)
if (c == 0xdf) {
c = 'S';
- if (d - wcopy >= MAXWLEN - 1)
+ if (d - wcopy >= MAXWLEN - 1) {
break;
+ }
*d++ = c;
- } else
+ } else {
c = SPELL_TOUPPER(c);
+ }
if (d - wcopy >= MAXWLEN - MB_MAXBYTES) {
break;
@@ -3476,7 +3581,7 @@ static void allcap_copy(char_u *word, char_u *wcopy)
// Try finding suggestions by recognizing specific situations.
static void suggest_try_special(suginfo_T *su)
{
- char_u *p;
+ char_u *p;
size_t len;
int c;
char_u word[MAXWLEN];
@@ -3496,7 +3601,7 @@ static void suggest_try_special(suginfo_T *su)
// Give a soundalike score of 0, compute the score as if deleting one
// character.
add_suggestion(su, &su->su_ga, word, su->su_badlen,
- RESCORE(SCORE_REP, 0), 0, true, su->su_sallang, false);
+ RESCORE(SCORE_REP, 0), 0, true, su->su_sallang, false);
}
}
@@ -3509,8 +3614,7 @@ proftime_T total;
proftime_T times[STATE_FINAL + 1];
long counts[STATE_FINAL + 1];
- static void
-prof_init(void)
+static void prof_init(void)
{
for (int i = 0; i <= STATE_FINAL; i++) {
profile_zero(&times[i]);
@@ -3521,8 +3625,7 @@ prof_init(void)
}
// call before changing state
- static void
-prof_store(state_T state)
+static void prof_store(state_T state)
{
profile_end(&current);
profile_add(&times[state], &current);
@@ -3531,8 +3634,7 @@ prof_store(state_T state)
}
# define PROF_STORE(state) prof_store(state);
- static void
-prof_report(char *name)
+static void prof_report(char *name)
{
FILE *fd = fopen("suggestprof", "a");
@@ -3554,8 +3656,8 @@ static void suggest_try_change(suginfo_T *su)
{
char_u fword[MAXWLEN]; // copy of the bad word, case-folded
int n;
- char_u *p;
- langp_T *lp;
+ char_u *p;
+ langp_T *lp;
// We make a copy of the case-folded bad word, so that we can modify it
// to find matches (esp. REP items). Append some more text, changing
@@ -3570,8 +3672,9 @@ static void suggest_try_change(suginfo_T *su)
// If reloading a spell file fails it's still in the list but
// everything has been cleared.
- if (lp->lp_slang->sl_fbyts == NULL)
+ if (lp->lp_slang->sl_fbyts == NULL) {
continue;
+ }
// Try it for this language. Will add possible suggestions.
//
@@ -3623,28 +3726,28 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
char_u tword[MAXWLEN]; // good word collected so far
trystate_T stack[MAXWLEN];
char_u preword[MAXWLEN * 3] = { 0 }; // word found with proper case;
- // concatenation of prefix compound
- // words and split word. NUL terminated
- // when going deeper but not when coming
- // back.
+ // concatenation of prefix compound
+ // words and split word. NUL terminated
+ // when going deeper but not when coming
+ // back.
char_u compflags[MAXWLEN]; // compound flags, one for each word
- trystate_T *sp;
+ trystate_T *sp;
int newscore;
int score;
- char_u *byts, *fbyts, *pbyts;
- idx_T *idxs, *fidxs, *pidxs;
+ char_u *byts, *fbyts, *pbyts;
+ idx_T *idxs, *fidxs, *pidxs;
int depth;
int c, c2, c3;
int n = 0;
int flags;
- garray_T *gap;
+ garray_T *gap;
idx_T arridx;
int len;
- char_u *p;
- fromto_T *ftp;
+ char_u *p;
+ fromto_T *ftp;
int fl = 0, tl;
int repextra = 0; // extra bytes in fword[] from REP item
- slang_T *slang = lp->lp_slang;
+ slang_T *slang = lp->lp_slang;
int fword_ends;
bool goodword_ends;
#ifdef DEBUG_TRIEWALK
@@ -3709,8 +3812,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
if (sp->ts_prefixdepth == PFD_PREFIXTREE) {
// Skip over the NUL bytes, we use them later.
- for (n = 0; n < len && byts[arridx + n] == 0; ++n)
+ for (n = 0; n < len && byts[arridx + n] == 0; ++n) {
;
+ }
sp->ts_curi += n;
// Always past NUL bytes now.
@@ -3727,7 +3831,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
n = nofold_len(fword, sp->ts_fidx, su->su_badptr);
flags = badword_captype(su->su_badptr, su->su_badptr + n);
su->su_badflags = badword_captype(su->su_badptr + n,
- su->su_badptr + su->su_badlen);
+ su->su_badptr + su->su_badlen);
#ifdef DEBUG_TRIEWALK
sprintf(changename[depth], "prefix");
#endif
@@ -3743,7 +3847,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// and make find_keepcap_word() works.
tword[sp->ts_twordlen] = NUL;
make_case_word(tword + sp->ts_splitoff,
- preword + sp->ts_prewordlen, flags);
+ preword + sp->ts_prewordlen, flags);
sp->ts_prewordlen = (char_u)STRLEN(preword);
sp->ts_splitoff = sp->ts_twordlen;
}
@@ -3764,8 +3868,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
flags = (int)idxs[arridx];
// Skip words with the NOSUGGEST flag.
- if (flags & WF_NOSUGGEST)
+ if (flags & WF_NOSUGGEST) {
break;
+ }
fword_ends = (fword[sp->ts_fidx] == NUL
|| (soundfold
@@ -3782,17 +3887,20 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// none this must be the first try without a prefix.
n = stack[sp->ts_prefixdepth].ts_arridx;
len = pbyts[n++];
- for (c = 0; c < len && pbyts[n + c] == 0; ++c)
+ for (c = 0; c < len && pbyts[n + c] == 0; ++c) {
;
+ }
if (c > 0) {
c = valid_word_prefix(c, n, flags,
- tword + sp->ts_splitoff, slang, false);
- if (c == 0)
+ tword + sp->ts_splitoff, slang, false);
+ if (c == 0) {
break;
+ }
// Use the WF_RARE flag for a rare prefix.
- if (c & WF_RAREPFX)
+ if (c & WF_RAREPFX) {
flags |= WF_RARE;
+ }
// Tricky: when checking for both prefix and compounding
// we run into the prefix flag first.
@@ -3805,10 +3913,11 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// Check NEEDCOMPOUND: can't use word without compounding. Do try
// appending another compound word below.
if (sp->ts_complen == sp->ts_compsplit && fword_ends
- && (flags & WF_NEEDCOMP))
+ && (flags & WF_NEEDCOMP)) {
goodword_ends = false;
- else
+ } else {
goodword_ends = true;
+ }
p = NULL;
compound_ok = true;
@@ -3821,18 +3930,19 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
if (sp->ts_fidx - sp->ts_splitfidx
== sp->ts_twordlen - sp->ts_splitoff
&& STRNCMP(fword + sp->ts_splitfidx,
- tword + sp->ts_splitoff,
- sp->ts_fidx - sp->ts_splitfidx) == 0) {
+ tword + sp->ts_splitoff,
+ sp->ts_fidx - sp->ts_splitfidx) == 0) {
preword[sp->ts_prewordlen] = NUL;
newscore = score_wordcount_adj(slang, sp->ts_score,
- preword + sp->ts_prewordlen,
- sp->ts_prewordlen > 0);
+ preword + sp->ts_prewordlen,
+ sp->ts_prewordlen > 0);
// Add the suggestion if the score isn't too bad.
- if (newscore <= su->su_maxscore)
+ if (newscore <= su->su_maxscore) {
add_suggestion(su, &su->su_ga, preword,
- sp->ts_splitfidx - repextra,
- newscore, 0, false,
- lp->lp_sallang, false);
+ sp->ts_splitfidx - repextra,
+ newscore, 0, false,
+ lp->lp_sallang, false);
+ }
break;
}
} else {
@@ -3856,23 +3966,26 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
compflags[sp->ts_complen] = ((unsigned)flags >> 24);
compflags[sp->ts_complen + 1] = NUL;
STRLCPY(preword + sp->ts_prewordlen,
- tword + sp->ts_splitoff,
- sp->ts_twordlen - sp->ts_splitoff + 1);
+ tword + sp->ts_splitoff,
+ sp->ts_twordlen - sp->ts_splitoff + 1);
// Verify CHECKCOMPOUNDPATTERN rules.
if (match_checkcompoundpattern(preword, sp->ts_prewordlen,
- &slang->sl_comppat))
+ &slang->sl_comppat)) {
compound_ok = false;
+ }
if (compound_ok) {
p = preword;
- while (*skiptowhite(p) != NUL)
+ while (*skiptowhite(p) != NUL) {
p = skipwhite(skiptowhite(p));
+ }
if (fword_ends && !can_compound(slang, p,
- compflags + sp->ts_compsplit))
+ compflags + sp->ts_compsplit)) {
// Compound is not allowed. But it may still be
// possible if we add another (short) word.
compound_ok = false;
+ }
}
// Get pointer to last char of previous word.
@@ -3884,29 +3997,31 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// Form the word with proper case in preword.
// If there is a word from a previous split, append.
// For the soundfold tree don't change the case, simply append.
- if (soundfold)
+ if (soundfold) {
STRCPY(preword + sp->ts_prewordlen, tword + sp->ts_splitoff);
- else if (flags & WF_KEEPCAP)
+ } else if (flags & WF_KEEPCAP) {
// Must find the word in the keep-case tree.
find_keepcap_word(slang, tword + sp->ts_splitoff,
- preword + sp->ts_prewordlen);
- else {
+ preword + sp->ts_prewordlen);
+ } else {
// Include badflags: If the badword is onecap or allcap
// use that for the goodword too. But if the badword is
// allcap and it's only one char long use onecap.
c = su->su_badflags;
if ((c & WF_ALLCAP)
- && su->su_badlen == (*mb_ptr2len)(su->su_badptr)
- )
+ && su->su_badlen ==
+ (*mb_ptr2len)(su->su_badptr)) {
c = WF_ONECAP;
+ }
c |= flags;
// When appending a compound word after a word character don't
// use Onecap.
- if (p != NULL && spell_iswordp_nmw(p, curwin))
+ if (p != NULL && spell_iswordp_nmw(p, curwin)) {
c &= ~WF_ONECAP;
+ }
make_case_word(tword + sp->ts_splitoff,
- preword + sp->ts_prewordlen, c);
+ preword + sp->ts_prewordlen, c);
}
if (!soundfold) {
@@ -3919,8 +4034,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
if ((sp->ts_complen == sp->ts_compsplit
&& WAS_BANNED(su, preword + sp->ts_prewordlen))
|| WAS_BANNED(su, preword)) {
- if (slang->sl_compprog == NULL)
+ if (slang->sl_compprog == NULL) {
break;
+ }
// the word so far was banned but we may try compounding
goodword_ends = false;
}
@@ -3929,14 +4045,17 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
newscore = 0;
if (!soundfold) { // soundfold words don't have flags
if ((flags & WF_REGION)
- && (((unsigned)flags >> 16) & lp->lp_region) == 0)
+ && (((unsigned)flags >> 16) & lp->lp_region) == 0) {
newscore += SCORE_REGION;
- if (flags & WF_RARE)
+ }
+ if (flags & WF_RARE) {
newscore += SCORE_RARE;
+ }
if (!spell_valid_case(su->su_badflags,
- captype(preword + sp->ts_prewordlen, NULL)))
+ captype(preword + sp->ts_prewordlen, NULL))) {
newscore += SCORE_ICASE;
+ }
}
// TODO: how about splitting in the soundfold tree?
@@ -3951,15 +4070,16 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// print the stack of changes that brought us here
smsg("------ %s -------", fword);
- for (j = 0; j < depth; ++j)
+ for (j = 0; j < depth; ++j) {
smsg("%s", changename[j]);
+ }
}
#endif
if (soundfold) {
// For soundfolded words we need to find the original
// words, the edit distance and then add them.
add_sound_suggest(su, preword, sp->ts_score, lp);
- } else if (sp->ts_fidx > 0) {
+ } else if (sp->ts_fidx > 0) {
// Give a penalty when changing non-word char to word
// char, e.g., "thes," -> "these".
p = fword + sp->ts_fidx;
@@ -3974,15 +4094,15 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// Give a bonus to words seen before.
score = score_wordcount_adj(slang,
- sp->ts_score + newscore,
- preword + sp->ts_prewordlen,
- sp->ts_prewordlen > 0);
+ sp->ts_score + newscore,
+ preword + sp->ts_prewordlen,
+ sp->ts_prewordlen > 0);
// Add the suggestion if the score isn't too bad.
if (score <= su->su_maxscore) {
add_suggestion(su, &su->su_ga, preword,
- sp->ts_fidx - repextra,
- score, 0, false, lp->lp_sallang, false);
+ sp->ts_fidx - repextra,
+ score, 0, false, lp->lp_sallang, false);
if (su->su_badflags & WF_MIXCAP) {
// We really don't know if the word should be
@@ -3990,13 +4110,13 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
c = captype(preword, NULL);
if (c == 0 || c == WF_ALLCAP) {
make_case_word(tword + sp->ts_splitoff,
- preword + sp->ts_prewordlen,
- c == 0 ? WF_ALLCAP : 0);
+ preword + sp->ts_prewordlen,
+ c == 0 ? WF_ALLCAP : 0);
add_suggestion(su, &su->su_ga, preword,
- sp->ts_fidx - repextra,
- score + SCORE_ICASE, 0, false,
- lp->lp_sallang, false);
+ sp->ts_fidx - repextra,
+ score + SCORE_ICASE, 0, false,
+ lp->lp_sallang, false);
}
}
}
@@ -4006,8 +4126,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// Try word split and/or compounding.
if ((sp->ts_fidx >= sp->ts_fidxtry || fword_ends)
// Don't split in the middle of a character
- && (sp->ts_tcharlen == 0)
- ) {
+ && (sp->ts_tcharlen == 0)) {
bool try_compound;
int try_split;
@@ -4045,7 +4164,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
|| sp->ts_complen + 1 - sp->ts_compsplit
< slang->sl_compmax)
&& (can_be_compound(sp, slang,
- compflags, ((unsigned)flags >> 24)))) {
+ compflags, ((unsigned)flags >> 24)))) {
try_compound = true;
compflags[sp->ts_complen] = ((unsigned)flags >> 24);
compflags[sp->ts_complen + 1] = NUL;
@@ -4076,35 +4195,40 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// is only one word it must not have the NEEDCOMPOUND
// flag.
if (sp->ts_complen == sp->ts_compsplit
- && (flags & WF_NEEDCOMP))
+ && (flags & WF_NEEDCOMP)) {
break;
+ }
p = preword;
- while (*skiptowhite(p) != NUL)
+ while (*skiptowhite(p) != NUL) {
p = skipwhite(skiptowhite(p));
+ }
if (sp->ts_complen > sp->ts_compsplit
&& !can_compound(slang, p,
- compflags + sp->ts_compsplit))
+ compflags + sp->ts_compsplit)) {
break;
+ }
- if (slang->sl_nosplitsugs)
+ if (slang->sl_nosplitsugs) {
newscore += SCORE_SPLIT_NO;
- else
+ } else {
newscore += SCORE_SPLIT;
+ }
// Give a bonus to words seen before.
newscore = score_wordcount_adj(slang, newscore,
- preword + sp->ts_prewordlen, true);
+ preword + sp->ts_prewordlen, true);
}
if (TRY_DEEPER(su, stack, depth, newscore)) {
go_deeper(stack, depth, newscore);
#ifdef DEBUG_TRIEWALK
- if (!try_compound && !fword_ends)
+ if (!try_compound && !fword_ends) {
sprintf(changename[depth], "%.*s-%s: split",
- sp->ts_twordlen, tword, fword + sp->ts_fidx);
- else
+ sp->ts_twordlen, tword, fword + sp->ts_fidx);
+ } else {
sprintf(changename[depth], "%.*s-%s: compound",
- sp->ts_twordlen, tword, fword + sp->ts_fidx);
+ sp->ts_twordlen, tword, fword + sp->ts_fidx);
+ }
#endif
// Save things to be restored at STATE_SPLITUNDO.
sp->ts_save_badflags = su->su_badflags;
@@ -4115,8 +4239,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
sp = &stack[depth];
// Append a space to preword when splitting.
- if (!try_compound && !fword_ends)
+ if (!try_compound && !fword_ends) {
STRCAT(preword, " ");
+ }
sp->ts_prewordlen = (char_u)STRLEN(preword);
sp->ts_splitoff = sp->ts_twordlen;
sp->ts_splitfidx = sp->ts_fidx;
@@ -4127,8 +4252,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// character when the word ends. But only when the
// good word can end.
if (((!try_compound && !spell_iswordp_nmw(fword
- + sp->ts_fidx,
- curwin))
+ + sp->ts_fidx,
+ curwin))
|| fword_ends)
&& fword[sp->ts_fidx] != NUL
&& goodword_ends) {
@@ -4138,28 +4263,30 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
if (fword_ends) {
// Copy the skipped character to preword.
memmove(preword + sp->ts_prewordlen,
- fword + sp->ts_fidx, l);
+ fword + sp->ts_fidx, l);
sp->ts_prewordlen += l;
preword[sp->ts_prewordlen] = NUL;
- } else
+ } else {
sp->ts_score -= SCORE_SPLIT - SCORE_SUBST;
+ }
sp->ts_fidx += l;
}
// When compounding include compound flag in
// compflags[] (already set above). When splitting we
// may start compounding over again.
- if (try_compound)
+ if (try_compound) {
++sp->ts_complen;
- else
+ } else {
sp->ts_compsplit = sp->ts_complen;
+ }
sp->ts_prefixdepth = PFD_NOPREFIX;
// set su->su_badflags to the caps type at this
// position
n = nofold_len(fword, sp->ts_fidx, su->su_badptr);
su->su_badflags = badword_captype(su->su_badptr + n,
- su->su_badptr + su->su_badlen);
+ su->su_badptr + su->su_badlen);
// Restart at top of the tree.
sp->ts_arridx = 0;
@@ -4194,8 +4321,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// Past the NUL bytes in the node.
su->su_badflags = sp->ts_save_badflags;
if (fword[sp->ts_fidx] == NUL
- && sp->ts_tcharlen == 0
- ) {
+ && sp->ts_tcharlen == 0) {
// The badword ends, can't use STATE_PLAIN.
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_DEL;
@@ -4228,11 +4354,12 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// just deleted this byte, accepting it is always cheaper than
// delete + substitute.
if (c == fword[sp->ts_fidx]
- || (sp->ts_tcharlen > 0 && sp->ts_isdiff != DIFF_NONE)
- )
+ || (sp->ts_tcharlen > 0 &&
+ sp->ts_isdiff != DIFF_NONE)) {
newscore = 0;
- else
+ } else {
newscore = SCORE_SUBST;
+ }
if ((newscore == 0
|| (sp->ts_fidx >= sp->ts_fidxtry
&& ((sp->ts_flags & TSF_DIDDEL) == 0
@@ -4240,14 +4367,15 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
&& TRY_DEEPER(su, stack, depth, newscore)) {
go_deeper(stack, depth, newscore);
#ifdef DEBUG_TRIEWALK
- if (newscore > 0)
+ if (newscore > 0) {
sprintf(changename[depth], "%.*s-%s: subst %c to %c",
- sp->ts_twordlen, tword, fword + sp->ts_fidx,
- fword[sp->ts_fidx], c);
- else
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ fword[sp->ts_fidx], c);
+ } else {
sprintf(changename[depth], "%.*s-%s: accept %c",
- sp->ts_twordlen, tword, fword + sp->ts_fidx,
- fword[sp->ts_fidx]);
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ fword[sp->ts_fidx]);
+ }
#endif
++depth;
sp = &stack[depth];
@@ -4289,12 +4417,11 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
+ sp->ts_fcharstart))) {
sp->ts_score -= SCORE_SUBST - SCORE_SUBCOMP;
} else if (
- !soundfold
- && slang->sl_has_map
- && similar_chars(
- slang,
- utf_ptr2char(tword + sp->ts_twordlen - sp->ts_tcharlen),
- utf_ptr2char(fword + sp->ts_fcharstart))) {
+ !soundfold
+ && slang->sl_has_map
+ && similar_chars(slang,
+ utf_ptr2char(tword + sp->ts_twordlen - sp->ts_tcharlen),
+ utf_ptr2char(fword + sp->ts_fcharstart))) {
// For a similar character adjust score from
// SCORE_SUBST to SCORE_SIMILAR.
sp->ts_score -= SCORE_SUBST - SCORE_SIMILAR;
@@ -4339,19 +4466,20 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_INS_PREP;
sp->ts_curi = 1;
- if (soundfold && sp->ts_fidx == 0 && fword[sp->ts_fidx] == '*')
+ if (soundfold && sp->ts_fidx == 0 && fword[sp->ts_fidx] == '*') {
// Deleting a vowel at the start of a word counts less, see
// soundalike_score().
newscore = 2 * SCORE_DEL / 3;
- else
+ } else {
newscore = SCORE_DEL;
+ }
if (fword[sp->ts_fidx] != NUL
&& TRY_DEEPER(su, stack, depth, newscore)) {
go_deeper(stack, depth, newscore);
#ifdef DEBUG_TRIEWALK
sprintf(changename[depth], "%.*s-%s: delete %c",
- sp->ts_twordlen, tword, fword + sp->ts_fidx,
- fword[sp->ts_fidx]);
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ fword[sp->ts_fidx]);
#endif
++depth;
@@ -4421,19 +4549,20 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// accepting that byte is always better.
n += sp->ts_curi++;
c = byts[n];
- if (soundfold && sp->ts_twordlen == 0 && c == '*')
+ if (soundfold && sp->ts_twordlen == 0 && c == '*') {
// Inserting a vowel at the start of a word counts less,
// see soundalike_score().
newscore = 2 * SCORE_INS / 3;
- else
+ } else {
newscore = SCORE_INS;
+ }
if (c != fword[sp->ts_fidx]
&& TRY_DEEPER(su, stack, depth, newscore)) {
go_deeper(stack, depth, newscore);
#ifdef DEBUG_TRIEWALK
sprintf(changename[depth], "%.*s-%s: insert %c",
- sp->ts_twordlen, tword, fword + sp->ts_fidx,
- c);
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ c);
#endif
++depth;
sp = &stack[depth];
@@ -4454,8 +4583,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// soundfold words (illogical but does give a better
// score).
if (sp->ts_twordlen >= 2
- && tword[sp->ts_twordlen - 2] == c)
+ && tword[sp->ts_twordlen - 2] == c) {
sp->ts_score -= SCORE_INS - SCORE_INSDUP;
+ }
}
}
break;
@@ -4566,8 +4696,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
go_deeper(stack, depth, SCORE_SWAP3);
#ifdef DEBUG_TRIEWALK
sprintf(changename[depth], "%.*s-%s: swap3 %c and %c",
- sp->ts_twordlen, tword, fword + sp->ts_fidx,
- c, c3);
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ c, c3);
#endif
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_UNSWAP3;
@@ -4611,8 +4741,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
#ifdef DEBUG_TRIEWALK
p = fword + sp->ts_fidx;
sprintf(changename[depth], "%.*s-%s: rotate left %c%c%c",
- sp->ts_twordlen, tword, fword + sp->ts_fidx,
- p[0], p[1], p[2]);
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ p[0], p[1], p[2]);
#endif
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_UNROT3L;
@@ -4648,8 +4778,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
#ifdef DEBUG_TRIEWALK
p = fword + sp->ts_fidx;
sprintf(changename[depth], "%.*s-%s: rotate right %c%c%c",
- sp->ts_twordlen, tword, fword + sp->ts_fidx,
- p[0], p[1], p[2]);
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ p[0], p[1], p[2]);
#endif
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_UNROT3R;
@@ -4696,10 +4826,11 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// Use the first byte to quickly find the first entry that may
// match. If the index is -1 there is none.
- if (soundfold)
+ if (soundfold) {
sp->ts_curi = slang->sl_repsal_first[fword[sp->ts_fidx]];
- else
+ } else {
sp->ts_curi = lp->lp_replang->sl_rep_first[fword[sp->ts_fidx]];
+ }
if (sp->ts_curi < 0) {
PROF_STORE(sp->ts_state)
@@ -4717,10 +4848,11 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// valid.
p = fword + sp->ts_fidx;
- if (soundfold)
+ if (soundfold) {
gap = &slang->sl_repsal;
- else
+ } else {
gap = &lp->lp_replang->sl_rep;
+ }
while (sp->ts_curi < gap->ga_len) {
ftp = (fromto_T *)gap->ga_data + sp->ts_curi++;
if (*ftp->ft_from != *p) {
@@ -4733,8 +4865,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
go_deeper(stack, depth, SCORE_REP);
#ifdef DEBUG_TRIEWALK
sprintf(changename[depth], "%.*s-%s: replace %s with %s",
- sp->ts_twordlen, tword, fword + sp->ts_fidx,
- ftp->ft_from, ftp->ft_to);
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ ftp->ft_from, ftp->ft_to);
#endif
// Need to undo this afterwards.
PROF_STORE(sp->ts_state)
@@ -4755,19 +4887,21 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
}
}
- if (sp->ts_curi >= gap->ga_len && sp->ts_state == STATE_REP)
+ if (sp->ts_curi >= gap->ga_len && sp->ts_state == STATE_REP) {
// No (more) matches.
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_FINAL;
+ }
break;
case STATE_REP_UNDO:
// Undo a REP replacement and continue with the next one.
- if (soundfold)
+ if (soundfold) {
gap = &slang->sl_repsal;
- else
+ } else {
gap = &lp->lp_replang->sl_rep;
+ }
ftp = (fromto_T *)gap->ga_data + sp->ts_curi - 1;
fl = (int)STRLEN(ftp->ft_from);
tl = (int)STRLEN(ftp->ft_to);
@@ -4815,7 +4949,7 @@ static void go_deeper(trystate_T *stack, int depth, int score_add)
// fword[flen] and return the byte length of that many chars in "word".
static int nofold_len(char_u *fword, int flen, char_u *word)
{
- char_u *p;
+ char_u *p;
int i = 0;
for (p = fword; p < fword + flen; MB_PTR_ADV(p)) {
@@ -4849,9 +4983,9 @@ static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword)
int len;
int c;
idx_T lo, hi, m;
- char_u *p;
- char_u *byts = slang->sl_kbyts; // array with bytes of the words
- idx_T *idxs = slang->sl_kidxs; // array with indexes
+ char_u *p;
+ char_u *byts = slang->sl_kbyts; // array with bytes of the words
+ idx_T *idxs = slang->sl_kidxs; // array with indexes
if (byts == NULL) {
// array is empty: "cannot happen"
@@ -4882,7 +5016,7 @@ static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword)
// kword is getting too long, continue one level up
--depth;
- } else if (++round[depth] > 2) {
+ } else if (++round[depth] > 2) {
// tried both fold-case and upper-case character, continue one
// level up
--depth;
@@ -4907,19 +5041,20 @@ static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword)
hi = tryidx + len - 1;
while (lo < hi) {
m = (lo + hi) / 2;
- if (byts[m] > c)
+ if (byts[m] > c) {
hi = m - 1;
- else if (byts[m] < c)
+ } else if (byts[m] < c) {
lo = m + 1;
- else {
+ } else {
lo = hi = m;
break;
}
}
// Stop if there is no matching byte.
- if (hi < lo || byts[lo] != c)
+ if (hi < lo || byts[lo] != c) {
break;
+ }
// Continue at the child (if there is one).
tryidx = idxs[lo];
@@ -4930,11 +5065,11 @@ static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword)
// level deeper.
if (round[depth] == 1) {
STRNCPY(kword + kwordlen[depth], fword + fwordidx[depth],
- flen);
+ flen);
kwordlen[depth + 1] = kwordlen[depth] + flen;
} else {
STRNCPY(kword + kwordlen[depth], uword + uwordidx[depth],
- ulen);
+ ulen);
kwordlen[depth + 1] = kwordlen[depth] + ulen;
}
fwordidx[depth + 1] = fwordidx[depth] + flen;
@@ -4955,11 +5090,11 @@ static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword)
// su->su_sga.
static void score_comp_sal(suginfo_T *su)
{
- langp_T *lp;
+ langp_T *lp;
char_u badsound[MAXWLEN];
int i;
- suggest_T *stp;
- suggest_T *sstp;
+ suggest_T *stp;
+ suggest_T *sstp;
int score;
ga_grow(&su->su_sga, su->su_ga.ga_len);
@@ -4998,13 +5133,13 @@ static void score_comp_sal(suginfo_T *su)
static void score_combine(suginfo_T *su)
{
garray_T ga;
- garray_T *gap;
- langp_T *lp;
- suggest_T *stp;
- char_u *p;
+ garray_T *gap;
+ langp_T *lp;
+ suggest_T *stp;
+ char_u *p;
char_u badsound[MAXWLEN];
int round;
- slang_T *slang = NULL;
+ slang_T *slang = NULL;
// Add the alternate score to su_ga.
for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) {
@@ -5017,11 +5152,12 @@ static void score_combine(suginfo_T *su)
for (int i = 0; i < su->su_ga.ga_len; ++i) {
stp = &SUG(su->su_ga, i);
stp->st_altscore = stp_sal_score(stp, su, slang, badsound);
- if (stp->st_altscore == SCORE_MAXMAX)
+ if (stp->st_altscore == SCORE_MAXMAX) {
stp->st_score = (stp->st_score * 3 + SCORE_BIG) / 4;
- else
+ } else {
stp->st_score = (stp->st_score * 3
+ stp->st_altscore) / 4;
+ }
stp->st_salscore = false;
}
break;
@@ -5030,7 +5166,7 @@ static void score_combine(suginfo_T *su)
if (slang == NULL) { // Using "double" without sound folding.
(void)cleanup_suggestions(&su->su_ga, su->su_maxscore,
- su->su_maxcount);
+ su->su_maxcount);
return;
}
@@ -5038,11 +5174,12 @@ static void score_combine(suginfo_T *su)
for (int i = 0; i < su->su_sga.ga_len; ++i) {
stp = &SUG(su->su_sga, i);
stp->st_altscore = spell_edit_score(slang,
- su->su_badword, stp->st_word);
- if (stp->st_score == SCORE_MAXMAX)
+ su->su_badword, stp->st_word);
+ if (stp->st_score == SCORE_MAXMAX) {
stp->st_score = (SCORE_BIG * 7 + stp->st_altscore) / 8;
- else
+ } else {
stp->st_score = (stp->st_score * 7 + stp->st_altscore) / 8;
+ }
stp->st_salscore = true;
}
@@ -5066,13 +5203,16 @@ static void score_combine(suginfo_T *su)
// Don't add a word if it's already there.
p = SUG(*gap, i).st_word;
int j;
- for (j = 0; j < ga.ga_len; ++j)
- if (STRCMP(stp[j].st_word, p) == 0)
+ for (j = 0; j < ga.ga_len; ++j) {
+ if (STRCMP(stp[j].st_word, p) == 0) {
break;
- if (j == ga.ga_len)
+ }
+ }
+ if (j == ga.ga_len) {
stp[ga.ga_len++] = SUG(*gap, i);
- else
+ } else {
xfree(p);
+ }
}
}
}
@@ -5091,19 +5231,15 @@ static void score_combine(suginfo_T *su)
su->su_ga = ga;
}
-// For the goodword in "stp" compute the soundalike score compared to the
-// badword.
-static int
-stp_sal_score (
- suggest_T *stp,
- suginfo_T *su,
- slang_T *slang,
- char_u *badsound // sound-folded badword
-)
+/// For the goodword in "stp" compute the soundalike score compared to the
+/// badword.
+///
+/// @param badsound sound-folded badword
+static int stp_sal_score(suggest_T *stp, suginfo_T *su, slang_T *slang, char_u *badsound)
{
- char_u *p;
- char_u *pbad;
- char_u *pgood;
+ char_u *p;
+ char_u *pbad;
+ char_u *pgood;
char_u badsound2[MAXWLEN];
char_u fword[MAXWLEN];
char_u goodsound[MAXWLEN];
@@ -5111,9 +5247,9 @@ stp_sal_score (
int lendiff;
lendiff = su->su_badlen - stp->st_orglen;
- if (lendiff >= 0)
+ if (lendiff >= 0) {
pbad = badsound;
- else {
+ } else {
// soundfold the bad word with more characters following
(void)spell_casefold(curwin, su->su_badptr, stp->st_orglen, fword, MAXWLEN);
@@ -5122,9 +5258,11 @@ stp_sal_score (
// removing the space. Don't do it when the good word also contains a
// space.
if (ascii_iswhite(su->su_badptr[su->su_badlen])
- && *skiptowhite(stp->st_word) == NUL)
- for (p = fword; *(p = skiptowhite(p)) != NUL; )
+ && *skiptowhite(stp->st_word) == NUL) {
+ for (p = fword; *(p = skiptowhite(p)) != NUL; ) {
STRMOVE(p, p + 1);
+ }
+ }
spell_soundfold(slang, fword, true, badsound2);
pbad = badsound2;
@@ -5135,10 +5273,11 @@ stp_sal_score (
// what replaces the bad word.
STRCPY(goodword, stp->st_word);
STRLCPY(goodword + stp->st_wordlen,
- su->su_badptr + su->su_badlen - lendiff, lendiff + 1);
+ su->su_badptr + su->su_badlen - lendiff, lendiff + 1);
pgood = goodword;
- } else
+ } else {
pgood = stp->st_word;
+ }
// Sound-fold the word and compute the score for the difference.
spell_soundfold(slang, pgood, false, goodsound);
@@ -5153,17 +5292,18 @@ static sftword_T dumsft;
// Prepare for calling suggest_try_soundalike().
static void suggest_try_soundalike_prep(void)
{
- langp_T *lp;
- slang_T *slang;
+ langp_T *lp;
+ slang_T *slang;
// Do this for all languages that support sound folding and for which a
// .sug file has been loaded.
for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) {
lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
slang = lp->lp_slang;
- if (!GA_EMPTY(&slang->sl_sal) && slang->sl_sbyts != NULL)
+ if (!GA_EMPTY(&slang->sl_sal) && slang->sl_sbyts != NULL) {
// prepare the hashtable used by add_sound_suggest()
hash_init(&slang->sl_sounddone);
+ }
}
}
@@ -5172,8 +5312,8 @@ static void suggest_try_soundalike_prep(void)
static void suggest_try_soundalike(suginfo_T *su)
{
char_u salword[MAXWLEN];
- langp_T *lp;
- slang_T *slang;
+ langp_T *lp;
+ slang_T *slang;
// Do this for all languages that support sound folding and for which a
// .sug file has been loaded.
@@ -5201,10 +5341,10 @@ static void suggest_try_soundalike(suginfo_T *su)
// Finish up after calling suggest_try_soundalike().
static void suggest_try_soundalike_finish(void)
{
- langp_T *lp;
- slang_T *slang;
+ langp_T *lp;
+ slang_T *slang;
int todo;
- hashitem_T *hi;
+ hashitem_T *hi;
// Do this for all languages that support sound folding and for which a
// .sug file has been loaded.
@@ -5214,11 +5354,12 @@ static void suggest_try_soundalike_finish(void)
if (!GA_EMPTY(&slang->sl_sal) && slang->sl_sbyts != NULL) {
// Free the info about handled words.
todo = (int)slang->sl_sounddone.ht_used;
- for (hi = slang->sl_sounddone.ht_array; todo > 0; ++hi)
+ for (hi = slang->sl_sounddone.ht_array; todo > 0; ++hi) {
if (!HASHITEM_EMPTY(hi)) {
xfree(HI2SFT(hi));
--todo;
}
+ }
// Clear the hashtable, it may also be used by another region.
hash_clear(&slang->sl_sounddone);
@@ -5227,32 +5368,28 @@ static void suggest_try_soundalike_finish(void)
}
}
-// A match with a soundfolded word is found. Add the good word(s) that
-// produce this soundfolded word.
-static void
-add_sound_suggest (
- suginfo_T *su,
- char_u *goodword,
- int score, // soundfold score
- langp_T *lp
-)
+/// A match with a soundfolded word is found. Add the good word(s) that
+/// produce this soundfolded word.
+///
+/// @param score soundfold score
+static void add_sound_suggest(suginfo_T *su, char_u *goodword, int score, langp_T *lp)
{
- slang_T *slang = lp->lp_slang; // language for sound folding
+ slang_T *slang = lp->lp_slang; // language for sound folding
int sfwordnr;
- char_u *nrline;
+ char_u *nrline;
int orgnr;
char_u theword[MAXWLEN];
int i;
int wlen;
- char_u *byts;
- idx_T *idxs;
+ char_u *byts;
+ idx_T *idxs;
int n;
int wordcount;
int wc;
int goodscore;
hash_T hash;
- hashitem_T *hi;
- sftword_T *sft;
+ hashitem_T *hi;
+ sftword_T *sft;
int bc, gc;
int limit;
@@ -5271,8 +5408,9 @@ add_sound_suggest (
hash_add_item(&slang->sl_sounddone, hi, sft->sft_word, hash);
} else {
sft = HI2SFT(hi);
- if (score >= sft->sft_score)
+ if (score >= sft->sft_score) {
return;
+ }
sft->sft_score = score;
}
@@ -5299,25 +5437,28 @@ add_sound_suggest (
wordcount = 0;
for (wlen = 0; wlen < MAXWLEN - 3; ++wlen) {
i = 1;
- if (wordcount == orgnr && byts[n + 1] == NUL)
+ if (wordcount == orgnr && byts[n + 1] == NUL) {
break; // found end of word
-
- if (byts[n + 1] == NUL)
+ }
+ if (byts[n + 1] == NUL) {
++wordcount;
+ }
// skip over the NUL bytes
- for (; byts[n + i] == NUL; ++i)
+ for (; byts[n + i] == NUL; ++i) {
if (i > byts[n]) { // safety check
STRCPY(theword + wlen, "BAD");
wlen += 3;
goto badword;
}
+ }
// One of the siblings must have the word.
for (; i < byts[n]; ++i) {
wc = idxs[idxs[n + i]]; // nr of words under this byte
- if (wordcount + wc > orgnr)
+ if (wordcount + wc > orgnr) {
break;
+ }
wordcount += wc;
}
@@ -5330,12 +5471,13 @@ badword:
// Go over the possible flags and regions.
for (; i <= byts[n] && byts[n + i] == NUL; ++i) {
char_u cword[MAXWLEN];
- char_u *p;
+ char_u *p;
int flags = (int)idxs[n + i];
// Skip words with the NOSUGGEST flag
- if (flags & WF_NOSUGGEST)
+ if (flags & WF_NOSUGGEST) {
continue;
+ }
if (flags & WF_KEEPCAP) {
// Must find the word in the keep-case tree.
@@ -5347,23 +5489,26 @@ badword:
// Need to fix case according to "flags".
make_case_word(theword, cword, flags);
p = cword;
- } else
+ } else {
p = theword;
+ }
}
// Add the suggestion.
if (sps_flags & SPS_DOUBLE) {
// Add the suggestion if the score isn't too bad.
- if (score <= su->su_maxscore)
+ if (score <= su->su_maxscore) {
add_suggestion(su, &su->su_sga, p, su->su_badlen,
- score, 0, false, slang, false);
+ score, 0, false, slang, false);
+ }
} else {
// Add a penalty for words in another region.
if ((flags & WF_REGION)
- && (((unsigned)flags >> 16) & lp->lp_region) == 0)
+ && (((unsigned)flags >> 16) & lp->lp_region) == 0) {
goodscore = SCORE_REGION;
- else
+ } else {
goodscore = 0;
+ }
// Add a small penalty for changing the first letter from
// lower to upper case. Helps for "tath" -> "Kath", which is
@@ -5373,8 +5518,9 @@ badword:
if (SPELL_ISUPPER(gc)) {
bc = PTR2CHAR(su->su_badword);
if (!SPELL_ISUPPER(bc)
- && SPELL_TOFOLD(bc) != SPELL_TOFOLD(gc))
+ && SPELL_TOFOLD(bc) != SPELL_TOFOLD(gc)) {
goodscore += SCORE_ICASE / 2;
+ }
}
// Compute the score for the good word. This only does letter
@@ -5385,11 +5531,12 @@ badword:
// If the limit is very high then the iterative method is
// inefficient, using an array is quicker.
limit = MAXSCORE(su->su_sfmaxscore - goodscore, score);
- if (limit > SCORE_LIMITMAX)
+ if (limit > SCORE_LIMITMAX) {
goodscore += spell_edit_score(slang, su->su_badword, p);
- else
+ } else {
goodscore += spell_edit_score_limit(slang, su->su_badword,
- p, limit);
+ p, limit);
+ }
// When going over the limit don't bother to do the rest.
if (goodscore < SCORE_MAXMAX) {
@@ -5398,9 +5545,10 @@ badword:
// Add the suggestion if the score isn't too bad.
goodscore = RESCORE(goodscore, score);
- if (goodscore <= su->su_sfmaxscore)
+ if (goodscore <= su->su_sfmaxscore) {
add_suggestion(su, &su->su_ga, p, su->su_badlen,
- goodscore, score, true, slang, true);
+ goodscore, score, true, slang, true);
+ }
}
}
}
@@ -5414,9 +5562,9 @@ static int soundfold_find(slang_T *slang, char_u *word)
int len;
int wlen = 0;
int c;
- char_u *ptr = word;
- char_u *byts;
- idx_T *idxs;
+ char_u *ptr = word;
+ char_u *byts;
+ idx_T *idxs;
int wordnr = 0;
byts = slang->sl_sbyts;
@@ -5430,35 +5578,41 @@ static int soundfold_find(slang_T *slang, char_u *word)
// If the word ends we found the word. If not skip the NUL bytes.
c = ptr[wlen];
if (byts[arridx] == NUL) {
- if (c == NUL)
+ if (c == NUL) {
break;
+ }
// Skip over the zeros, there can be several.
while (len > 0 && byts[arridx] == NUL) {
++arridx;
--len;
}
- if (len == 0)
+ if (len == 0) {
return -1; // no children, word should have ended here
+ }
++wordnr;
}
// If the word ends we didn't find it.
- if (c == NUL)
+ if (c == NUL) {
return -1;
+ }
// Perform a binary search in the list of accepted bytes.
- if (c == TAB) // <Tab> is handled like <Space>
+ if (c == TAB) { // <Tab> is handled like <Space>
c = ' ';
+ }
while (byts[arridx] < c) {
// The word count is in the first idxs[] entry of the child.
wordnr += idxs[idxs[arridx]];
++arridx;
- if (--len == 0) // end of the bytes, didn't find it
+ if (--len == 0) { // end of the bytes, didn't find it
return -1;
+ }
}
- if (byts[arridx] != c) // didn't find the byte
+ if (byts[arridx] != c) { // didn't find the byte
return -1;
+ }
// Continue at the child (if there is one).
arridx = idxs[arridx];
@@ -5466,9 +5620,11 @@ static int soundfold_find(slang_T *slang, char_u *word)
// One space in the good word may stand for several spaces in the
// checked word.
- if (c == ' ')
- while (ptr[wlen] == ' ' || ptr[wlen] == TAB)
+ if (c == ' ') {
+ while (ptr[wlen] == ' ' || ptr[wlen] == TAB) {
++wlen;
+ }
+ }
}
return wordnr;
@@ -5477,15 +5633,16 @@ static int soundfold_find(slang_T *slang, char_u *word)
// Copy "fword" to "cword", fixing case according to "flags".
static void make_case_word(char_u *fword, char_u *cword, int flags)
{
- if (flags & WF_ALLCAP)
+ if (flags & WF_ALLCAP) {
// Make it all upper-case
allcap_copy(fword, cword);
- else if (flags & WF_ONECAP)
+ } else if (flags & WF_ONECAP) {
// Make the first letter upper-case
onecap_copy(fword, cword, true);
- else
+ } else {
// Use goodword as-is.
STRCPY(cword, fword);
+ }
}
// Returns true if "c1" and "c2" are similar characters according to the MAP
@@ -5494,7 +5651,7 @@ static bool similar_chars(slang_T *slang, int c1, int c2)
{
int m1, m2;
char_u buf[MB_MAXBYTES + 1];
- hashitem_T *hi;
+ hashitem_T *hi;
if (c1 >= 256) {
buf[utf_char2bytes(c1, buf)] = 0;
@@ -5526,25 +5683,20 @@ static bool similar_chars(slang_T *slang, int c1, int c2)
return m1 == m2;
}
-// Adds a suggestion to the list of suggestions.
-// For a suggestion that is already in the list the lowest score is remembered.
-static void
-add_suggestion (
- suginfo_T *su,
- garray_T *gap, // either su_ga or su_sga
- const char_u *goodword,
- int badlenarg, // len of bad word replaced with "goodword"
- int score,
- int altscore,
- bool had_bonus, // value for st_had_bonus
- slang_T *slang, // language for sound folding
- bool maxsf // su_maxscore applies to soundfold score,
- // su_sfmaxscore to the total score.
-)
+/// Adds a suggestion to the list of suggestions.
+/// For a suggestion that is already in the list the lowest score is remembered.
+///
+/// @param gap either su_ga or su_sga
+/// @param badlenarg len of bad word replaced with "goodword"
+/// @param had_bonus value for st_had_bonus
+/// @param slang language for sound folding
+/// @param maxsf su_maxscore applies to soundfold score, su_sfmaxscore to the total score.
+static void add_suggestion(suginfo_T *su, garray_T *gap, const char_u *goodword, int badlenarg,
+ int score, int altscore, bool had_bonus, slang_T *slang, bool maxsf)
{
int goodlen; // len of goodword changed
int badlen; // len of bad word changed
- suggest_T *stp;
+ suggest_T *stp;
suggest_T new_sug;
// Minimize "badlen" for consistency. Avoids that changing "the the" to
@@ -5554,8 +5706,9 @@ add_suggestion (
for (;; ) {
goodlen = (int)(pgood - goodword);
badlen = (int)(pbad - su->su_badptr);
- if (goodlen <= 0 || badlen <= 0)
+ if (goodlen <= 0 || badlen <= 0) {
break;
+ }
MB_PTR_BACK(goodword, pgood);
MB_PTR_BACK(su->su_badptr, pbad);
if (utf_ptr2char(pgood) != utf_ptr2char(pbad)) {
@@ -5563,10 +5716,11 @@ add_suggestion (
}
}
- if (badlen == 0 && goodlen == 0)
+ if (badlen == 0 && goodlen == 0) {
// goodword doesn't change anything; may happen for "the the" changing
// the first "the" to itself.
return;
+ }
int i;
if (GA_EMPTY(gap)) {
@@ -5581,8 +5735,9 @@ add_suggestion (
&& stp->st_orglen == badlen
&& STRNCMP(stp->st_word, goodword, goodlen) == 0) {
// Found it. Remember the word with the lowest score.
- if (stp->st_slang == NULL)
+ if (stp->st_slang == NULL) {
stp->st_slang = slang;
+ }
new_sug.st_score = score;
new_sug.st_altscore = altscore;
@@ -5595,9 +5750,9 @@ add_suggestion (
// suggest_try_change() doesn't compute the soundalike
// word to keep it fast, while some special methods set
// the soundalike score to zero.
- if (had_bonus)
+ if (had_bonus) {
rescore_one(su, stp);
- else {
+ } else {
new_sug.st_word = stp->st_word;
new_sug.st_wordlen = stp->st_wordlen;
new_sug.st_slang = stp->st_slang;
@@ -5630,25 +5785,24 @@ add_suggestion (
// If we have too many suggestions now, sort the list and keep
// the best suggestions.
if (gap->ga_len > SUG_MAX_COUNT(su)) {
- if (maxsf)
+ if (maxsf) {
su->su_sfmaxscore = cleanup_suggestions(gap,
- su->su_sfmaxscore, SUG_CLEAN_COUNT(su));
- else
+ su->su_sfmaxscore, SUG_CLEAN_COUNT(su));
+ } else {
su->su_maxscore = cleanup_suggestions(gap,
- su->su_maxscore, SUG_CLEAN_COUNT(su));
+ su->su_maxscore, SUG_CLEAN_COUNT(su));
+ }
}
}
}
-// Suggestions may in fact be flagged as errors. Esp. for banned words and
-// for split words, such as "the the". Remove these from the list here.
-static void
-check_suggestions (
- suginfo_T *su,
- garray_T *gap // either su_ga or su_sga
-)
+/// Suggestions may in fact be flagged as errors. Esp. for banned words and
+/// for split words, such as "the the". Remove these from the list here.
+///
+/// @param gap either su_ga or su_sga
+static void check_suggestions(suginfo_T *su, garray_T *gap)
{
- suggest_T *stp;
+ suggest_T *stp;
char_u longword[MAXWLEN + 1];
int len;
hlf_T attr;
@@ -5662,16 +5816,17 @@ check_suggestions (
STRLCPY(longword, stp[i].st_word, MAXWLEN + 1);
len = stp[i].st_wordlen;
STRLCPY(longword + len, su->su_badptr + stp[i].st_orglen,
- MAXWLEN - len + 1);
+ MAXWLEN - len + 1);
attr = HLF_COUNT;
(void)spell_check(curwin, longword, &attr, NULL, false);
if (attr != HLF_COUNT) {
// Remove this entry.
xfree(stp[i].st_word);
--gap->ga_len;
- if (i < gap->ga_len)
+ if (i < gap->ga_len) {
memmove(stp + i, stp + i + 1,
- sizeof(suggest_T) * (gap->ga_len - i));
+ sizeof(suggest_T) * (gap->ga_len - i));
+ }
}
}
}
@@ -5680,9 +5835,9 @@ check_suggestions (
// Add a word to be banned.
static void add_banned(suginfo_T *su, char_u *word)
{
- char_u *s;
+ char_u *s;
hash_T hash;
- hashitem_T *hi;
+ hashitem_T *hi;
hash = hash_hash(word);
const size_t word_len = STRLEN(word);
@@ -5707,23 +5862,24 @@ static void rescore_suggestions(suginfo_T *su)
// Recompute the score for one suggestion if sound-folding is possible.
static void rescore_one(suginfo_T *su, suggest_T *stp)
{
- slang_T *slang = stp->st_slang;
+ slang_T *slang = stp->st_slang;
char_u sal_badword[MAXWLEN];
- char_u *p;
+ char_u *p;
// Only rescore suggestions that have no sal score yet and do have a
// language.
if (slang != NULL && !GA_EMPTY(&slang->sl_sal) && !stp->st_had_bonus) {
- if (slang == su->su_sallang)
+ if (slang == su->su_sallang) {
p = su->su_sal_badword;
- else {
+ } else {
spell_soundfold(slang, su->su_fbadword, true, sal_badword);
p = sal_badword;
}
stp->st_altscore = stp_sal_score(stp, su, slang, p);
- if (stp->st_altscore == SCORE_MAXMAX)
+ if (stp->st_altscore == SCORE_MAXMAX) {
stp->st_altscore = SCORE_BIG;
+ }
stp->st_score = RESCORE(stp->st_score, stp->st_altscore);
stp->st_had_bonus = true;
}
@@ -5734,28 +5890,27 @@ static void rescore_one(suginfo_T *su, suggest_T *stp)
// First on "st_score", then "st_altscore" then alphabetically.
static int sug_compare(const void *s1, const void *s2)
{
- suggest_T *p1 = (suggest_T *)s1;
- suggest_T *p2 = (suggest_T *)s2;
+ suggest_T *p1 = (suggest_T *)s1;
+ suggest_T *p2 = (suggest_T *)s2;
int n = p1->st_score - p2->st_score;
if (n == 0) {
n = p1->st_altscore - p2->st_altscore;
- if (n == 0)
+ if (n == 0) {
n = STRICMP(p1->st_word, p2->st_word);
+ }
}
return n;
}
-// Cleanup the suggestions:
-// - Sort on score.
-// - Remove words that won't be displayed.
-// Returns the maximum score in the list or "maxscore" unmodified.
-static int
-cleanup_suggestions (
- garray_T *gap,
- int maxscore,
- int keep // nr of suggestions to keep
-)
+/// Cleanup the suggestions:
+/// - Sort on score.
+/// - Remove words that won't be displayed.
+///
+/// @param keep nr of suggestions to keep
+///
+/// @return the maximum score in the list or "maxscore" unmodified.
+static int cleanup_suggestions(garray_T *gap, int maxscore, int keep)
FUNC_ATTR_NONNULL_ALL
{
if (gap->ga_len > 0) {
@@ -5823,12 +5978,12 @@ char *eval_soundfold(const char *const word)
void spell_soundfold(slang_T *slang, char_u *inword, bool folded, char_u *res)
{
char_u fword[MAXWLEN];
- char_u *word;
+ char_u *word;
- if (slang->sl_sofo)
+ if (slang->sl_sofo) {
// SOFOFROM and SOFOTO used
spell_soundfold_sofo(slang, inword, res);
- else {
+ } else {
// SAL items used. Requires the word to be case-folded.
if (folded) {
word = inword;
@@ -5892,12 +6047,12 @@ static void spell_soundfold_sofo(slang_T *slang, char_u *inword, char_u *res)
// Multi-byte version of spell_soundfold().
static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
{
- salitem_T *smp = (salitem_T *)slang->sl_sal.ga_data;
+ salitem_T *smp = (salitem_T *)slang->sl_sal.ga_data;
int word[MAXWLEN] = { 0 };
int wres[MAXWLEN] = { 0 };
int l;
- int *ws;
- int *pf;
+ int *ws;
+ int *pf;
int i, j, z;
int reslen;
int n, k = 0;
@@ -5918,7 +6073,7 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
wordlen = 0;
for (const char_u *s = inword; *s != NUL; ) {
const char_u *t = s;
- c = mb_cptr2char_adv((const char_u **)&s);
+ c = mb_cptr2char_adv(&s);
if (slang->sl_rem_accents) {
if (utf_class(c) == 0) {
if (did_white) {
@@ -5954,27 +6109,34 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
&& ws[0] != NUL; ++n) {
// Quickly skip entries that don't match the word. Most
// entries are less then three chars, optimize for that.
- if (c != ws[0])
+ if (c != ws[0]) {
continue;
+ }
k = smp[n].sm_leadlen;
if (k > 1) {
- if (word[i + 1] != ws[1])
+ if (word[i + 1] != ws[1]) {
continue;
+ }
if (k > 2) {
- for (j = 2; j < k; ++j)
- if (word[i + j] != ws[j])
+ for (j = 2; j < k; ++j) {
+ if (word[i + j] != ws[j]) {
break;
- if (j < k)
+ }
+ }
+ if (j < k) {
continue;
+ }
}
}
if ((pf = smp[n].sm_oneof_w) != NULL) {
// Check for match with one of the chars in "sm_oneof".
- while (*pf != NUL && *pf != word[i + k])
+ while (*pf != NUL && *pf != word[i + k]) {
++pf;
- if (*pf == NUL)
+ }
+ if (*pf == NUL) {
continue;
+ }
++k;
}
char_u *s = smp[n].sm_rules;
@@ -5986,15 +6148,17 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
k--;
s++;
}
- if (*s == '<')
+ if (*s == '<') {
s++;
+ }
if (ascii_isdigit(*s)) {
// determine priority
pri = *s - '0';
s++;
}
- if (*s == '^' && *(s + 1) == '^')
+ if (*s == '^' && *(s + 1) == '^') {
s++;
+ }
if (*s == NUL
|| (*s == '^'
@@ -6017,19 +6181,24 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
for (; ((ws = smp[n0].sm_lead_w)[0] & 0xff)
== (c0 & 0xff); ++n0) {
// Quickly skip entries that don't match the word.
- if (c0 != ws[0])
+ if (c0 != ws[0]) {
continue;
+ }
k0 = smp[n0].sm_leadlen;
if (k0 > 1) {
- if (word[i + k] != ws[1])
+ if (word[i + k] != ws[1]) {
continue;
+ }
if (k0 > 2) {
pf = word + i + k + 1;
- for (j = 2; j < k0; ++j)
- if (*pf++ != ws[j])
+ for (j = 2; j < k0; ++j) {
+ if (*pf++ != ws[j]) {
break;
- if (j < k0)
+ }
+ }
+ if (j < k0) {
continue;
+ }
}
}
k0 += k - 1;
@@ -6037,10 +6206,12 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
if ((pf = smp[n0].sm_oneof_w) != NULL) {
// Check for match with one of the chars in
// "sm_oneof".
- while (*pf != NUL && *pf != word[i + k0])
+ while (*pf != NUL && *pf != word[i + k0]) {
++pf;
- if (*pf == NUL)
+ }
+ if (*pf == NUL) {
continue;
+ }
++k0;
}
@@ -6051,8 +6222,9 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
// "if (k0 == k)"
s++;
}
- if (*s == '<')
+ if (*s == '<') {
s++;
+ }
if (ascii_isdigit(*s)) {
p0 = *s - '0';
s++;
@@ -6062,22 +6234,25 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
// *s == '^' cuts
|| (*s == '$'
&& !spell_iswordp_w(word + i + k0,
- curwin))) {
- if (k0 == k)
+ curwin))) {
+ if (k0 == k) {
// this is just a piece of the string
continue;
+ }
- if (p0 < pri)
+ if (p0 < pri) {
// priority too low
continue;
+ }
// rule fits; stop search
break;
}
}
if (p0 >= pri && (smp[n0].sm_lead_w[0] & 0xff)
- == (c0 & 0xff))
+ == (c0 & 0xff)) {
continue;
+ }
}
// replace string
@@ -6088,20 +6263,23 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
// rule with '<' is used
if (reslen > 0 && ws != NULL && *ws != NUL
&& (wres[reslen - 1] == c
- || wres[reslen - 1] == *ws))
+ || wres[reslen - 1] == *ws)) {
reslen--;
+ }
z0 = 1;
z = 1;
k0 = 0;
- if (ws != NULL)
+ if (ws != NULL) {
while (*ws != NUL && word[i + k0] != NUL) {
word[i + k0] = *ws;
k0++;
ws++;
}
- if (k > k0)
+ }
+ if (k > k0) {
memmove(word + i + k0, word + i + k,
- sizeof(int) * (wordlen - (i + k) + 1));
+ sizeof(int) * (wordlen - (i + k) + 1));
+ }
// new "actual letter"
c = word[i];
@@ -6109,23 +6287,27 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
// no '<' rule used
i += k - 1;
z = 0;
- if (ws != NULL)
+ if (ws != NULL) {
while (*ws != NUL && ws[1] != NUL
&& reslen < MAXWLEN) {
- if (reslen == 0 || wres[reslen - 1] != *ws)
+ if (reslen == 0 || wres[reslen - 1] != *ws) {
wres[reslen++] = *ws;
+ }
ws++;
}
+ }
// new "actual letter"
- if (ws == NULL)
+ if (ws == NULL) {
c = NUL;
- else
+ } else {
c = *ws;
+ }
if (strstr((char *)s, "^^") != NULL) {
- if (c != NUL)
+ if (c != NUL) {
wres[reslen++] = c;
+ }
memmove(word, word + i + 1,
- sizeof(int) * (wordlen - (i + 1) + 1));
+ sizeof(int) * (wordlen - (i + 1) + 1));
i = 0;
z0 = 1;
}
@@ -6133,7 +6315,7 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
break;
}
}
- } else if (ascii_iswhite(c)) {
+ } else if (ascii_iswhite(c)) {
c = ' ';
k = 1;
}
@@ -6141,9 +6323,10 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
if (z0 == 0) {
if (k && !p0 && reslen < MAXWLEN && c != NUL
&& (!slang->sl_collapse || reslen == 0
- || wres[reslen - 1] != c))
+ || wres[reslen - 1] != c)) {
// condense only double letters
wres[reslen++] = c;
+ }
i++;
z = 0;
@@ -6162,35 +6345,36 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
res[l] = NUL;
}
-// Compute a score for two sound-a-like words.
-// This permits up to two inserts/deletes/swaps/etc. to keep things fast.
-// Instead of a generic loop we write out the code. That keeps it fast by
-// avoiding checks that will not be possible.
-static int
-soundalike_score (
- char_u *goodstart, // sound-folded good word
- char_u *badstart // sound-folded bad word
-)
+/// Compute a score for two sound-a-like words.
+/// This permits up to two inserts/deletes/swaps/etc. to keep things fast.
+/// Instead of a generic loop we write out the code. That keeps it fast by
+/// avoiding checks that will not be possible.
+///
+/// @param goodstart sound-folded good word
+/// @param badstart sound-folded bad word
+static int soundalike_score(char_u *goodstart, char_u *badstart)
{
- char_u *goodsound = goodstart;
- char_u *badsound = badstart;
+ char_u *goodsound = goodstart;
+ char_u *badsound = badstart;
int goodlen;
int badlen;
int n;
- char_u *pl, *ps;
- char_u *pl2, *ps2;
+ char_u *pl, *ps;
+ char_u *pl2, *ps2;
int score = 0;
// Adding/inserting "*" at the start (word starts with vowel) shouldn't be
// counted so much, vowels in the middle of the word aren't counted at all.
if ((*badsound == '*' || *goodsound == '*') && *badsound != *goodsound) {
if ((badsound[0] == NUL && goodsound[1] == NUL)
- || (goodsound[0] == NUL && badsound[1] == NUL))
+ || (goodsound[0] == NUL && badsound[1] == NUL)) {
// changing word with vowel to word without a sound
return SCORE_DEL;
- if (badsound[0] == NUL || goodsound[0] == NUL)
+ }
+ if (badsound[0] == NUL || goodsound[0] == NUL) {
// more than two changes
return SCORE_MAXMAX;
+ }
if (badsound[1] == goodsound[1]
|| (badsound[1] != NUL
@@ -6199,10 +6383,11 @@ soundalike_score (
// handle like a substitute
} else {
score = 2 * SCORE_DEL / 3;
- if (*badsound == '*')
+ if (*badsound == '*') {
++badsound;
- else
+ } else {
++goodsound;
+ }
}
}
@@ -6212,8 +6397,9 @@ soundalike_score (
// Return quickly if the lengths are too different to be fixed by two
// changes.
n = goodlen - badlen;
- if (n < -2 || n > 2)
+ if (n < -2 || n > 2) {
return SCORE_MAXMAX;
+ }
if (n > 0) {
pl = goodsound; // goodsound is longest
@@ -6239,8 +6425,9 @@ soundalike_score (
++ps;
}
// strings must be equal after second delete
- if (STRCMP(pl + 1, ps) == 0)
+ if (STRCMP(pl + 1, ps) == 0) {
return score + SCORE_DEL * 2;
+ }
// Failed to compare.
break;
@@ -6253,20 +6440,23 @@ soundalike_score (
pl2 = pl + 1;
ps2 = ps;
while (*pl2 == *ps2) {
- if (*pl2 == NUL) // reached the end
+ if (*pl2 == NUL) { // reached the end
return score + SCORE_DEL;
+ }
++pl2;
++ps2;
}
// 2: delete then swap, then rest must be equal
if (pl2[0] == ps2[1] && pl2[1] == ps2[0]
- && STRCMP(pl2 + 2, ps2 + 2) == 0)
+ && STRCMP(pl2 + 2, ps2 + 2) == 0) {
return score + SCORE_DEL + SCORE_SWAP;
+ }
// 3: delete then substitute, then the rest must be equal
- if (STRCMP(pl2 + 1, ps2 + 1) == 0)
+ if (STRCMP(pl2 + 1, ps2 + 1) == 0) {
return score + SCORE_DEL + SCORE_SUBST;
+ }
// 4: first swap then delete
if (pl[0] == ps[1] && pl[1] == ps[0]) {
@@ -6277,8 +6467,9 @@ soundalike_score (
++ps2;
}
// delete a char and then strings must be equal
- if (STRCMP(pl2 + 1, ps2) == 0)
+ if (STRCMP(pl2 + 1, ps2) == 0) {
return score + SCORE_SWAP + SCORE_DEL;
+ }
}
// 5: first substitute then delete
@@ -6289,8 +6480,9 @@ soundalike_score (
++ps2;
}
// delete a char and then strings must be equal
- if (STRCMP(pl2 + 1, ps2) == 0)
+ if (STRCMP(pl2 + 1, ps2) == 0) {
return score + SCORE_SUBST + SCORE_DEL;
+ }
// Failed to compare.
break;
@@ -6299,47 +6491,54 @@ soundalike_score (
// Lengths are equal, thus changes must result in same length: An
// insert is only possible in combination with a delete.
// 1: check if for identical strings
- if (*pl == NUL)
+ if (*pl == NUL) {
return score;
+ }
// 2: swap
if (pl[0] == ps[1] && pl[1] == ps[0]) {
pl2 = pl + 2; // swap, skip two chars
ps2 = ps + 2;
while (*pl2 == *ps2) {
- if (*pl2 == NUL) // reached the end
+ if (*pl2 == NUL) { // reached the end
return score + SCORE_SWAP;
+ }
++pl2;
++ps2;
}
// 3: swap and swap again
if (pl2[0] == ps2[1] && pl2[1] == ps2[0]
- && STRCMP(pl2 + 2, ps2 + 2) == 0)
+ && STRCMP(pl2 + 2, ps2 + 2) == 0) {
return score + SCORE_SWAP + SCORE_SWAP;
+ }
// 4: swap and substitute
- if (STRCMP(pl2 + 1, ps2 + 1) == 0)
+ if (STRCMP(pl2 + 1, ps2 + 1) == 0) {
return score + SCORE_SWAP + SCORE_SUBST;
+ }
}
// 5: substitute
pl2 = pl + 1;
ps2 = ps + 1;
while (*pl2 == *ps2) {
- if (*pl2 == NUL) // reached the end
+ if (*pl2 == NUL) { // reached the end
return score + SCORE_SUBST;
+ }
++pl2;
++ps2;
}
// 6: substitute and swap
if (pl2[0] == ps2[1] && pl2[1] == ps2[0]
- && STRCMP(pl2 + 2, ps2 + 2) == 0)
+ && STRCMP(pl2 + 2, ps2 + 2) == 0) {
return score + SCORE_SUBST + SCORE_SWAP;
+ }
// 7: substitute and substitute
- if (STRCMP(pl2 + 1, ps2 + 1) == 0)
+ if (STRCMP(pl2 + 1, ps2 + 1) == 0) {
return score + SCORE_SUBST + SCORE_SUBST;
+ }
// 8: insert then delete
pl2 = pl;
@@ -6348,8 +6547,9 @@ soundalike_score (
++pl2;
++ps2;
}
- if (STRCMP(pl2 + 1, ps2) == 0)
+ if (STRCMP(pl2 + 1, ps2) == 0) {
return score + SCORE_INS + SCORE_DEL;
+ }
// 9: delete then insert
pl2 = pl + 1;
@@ -6358,8 +6558,9 @@ soundalike_score (
++pl2;
++ps2;
}
- if (STRCMP(pl2, ps2 + 1) == 0)
+ if (STRCMP(pl2, ps2 + 1) == 0) {
return score + SCORE_INS + SCORE_DEL;
+ }
// Failed to compare.
break;
@@ -6408,8 +6609,9 @@ static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword)
cnt = xmalloc(sizeof(int) * (badlen + 1) * (goodlen + 1));
CNT(0, 0) = 0;
- for (j = 1; j <= goodlen; ++j)
+ for (j = 1; j <= goodlen; ++j) {
CNT(0, j) = CNT(0, j - 1) + SCORE_INS;
+ }
for (i = 1; i <= badlen; ++i) {
CNT(i, 0) = CNT(i - 1, 0) + SCORE_DEL;
@@ -6420,16 +6622,17 @@ static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword)
CNT(i, j) = CNT(i - 1, j - 1);
} else {
// Use a better score when there is only a case difference.
- if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc))
+ if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc)) {
CNT(i, j) = SCORE_ICASE + CNT(i - 1, j - 1);
- else {
+ } else {
// For a similar character use SCORE_SIMILAR.
if (slang != NULL
&& slang->sl_has_map
- && similar_chars(slang, gc, bc))
+ && similar_chars(slang, gc, bc)) {
CNT(i, j) = SCORE_SIMILAR + CNT(i - 1, j - 1);
- else
+ } else {
CNT(i, j) = SCORE_SUBST + CNT(i - 1, j - 1);
+ }
}
if (i > 1 && j > 1) {
@@ -6437,16 +6640,19 @@ static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword)
pgc = wgoodword[j - 2];
if (bc == pgc && pbc == gc) {
t = SCORE_SWAP + CNT(i - 2, j - 2);
- if (t < CNT(i, j))
+ if (t < CNT(i, j)) {
CNT(i, j) = t;
+ }
}
}
t = SCORE_DEL + CNT(i - 1, j);
- if (t < CNT(i, j))
+ if (t < CNT(i, j)) {
CNT(i, j) = t;
+ }
t = SCORE_INS + CNT(i, j - 1);
- if (t < CNT(i, j))
+ if (t < CNT(i, j)) {
CNT(i, j) = t;
+ }
}
}
}
@@ -6515,11 +6721,13 @@ static int spell_edit_score_limit_w(slang_T *slang, char_u *badword, char_u *goo
bc = wbadword[bi];
gc = wgoodword[gi];
- if (bc != gc) // stop at a char that's different
+ if (bc != gc) { // stop at a char that's different
break;
+ }
if (bc == NUL) { // both words end
- if (score < minscore)
+ if (score < minscore) {
minscore = score;
+ }
goto pop; // do next alternative
}
++bi;
@@ -6528,14 +6736,16 @@ static int spell_edit_score_limit_w(slang_T *slang, char_u *badword, char_u *goo
if (gc == NUL) { // goodword ends, delete badword chars
do {
- if ((score += SCORE_DEL) >= minscore)
+ if ((score += SCORE_DEL) >= minscore) {
goto pop; // do next alternative
+ }
} while (wbadword[++bi] != NUL);
minscore = score;
- } else if (bc == NUL) { // badword ends, insert badword chars
+ } else if (bc == NUL) { // badword ends, insert badword chars
do {
- if ((score += SCORE_INS) >= minscore)
+ if ((score += SCORE_INS) >= minscore) {
goto pop; // do next alternative
+ }
} while (wgoodword[++gi] != NUL);
minscore = score;
} else { // both words continue
@@ -6586,16 +6796,17 @@ static int spell_edit_score_limit_w(slang_T *slang, char_u *badword, char_u *goo
// Substitute one character for another which is the same
// thing as deleting a character from both goodword and badword.
// Use a better score when there is only a case difference.
- if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc))
+ if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc)) {
score += SCORE_ICASE;
- else {
+ } else {
// For a similar character use SCORE_SIMILAR.
if (slang != NULL
&& slang->sl_has_map
- && similar_chars(slang, gc, bc))
+ && similar_chars(slang, gc, bc)) {
score += SCORE_SIMILAR;
- else
+ } else {
score += SCORE_SUBST;
+ }
}
if (score < minscore) {
@@ -6607,8 +6818,9 @@ static int spell_edit_score_limit_w(slang_T *slang, char_u *badword, char_u *goo
}
pop:
// Get here to try the next alternative, pop it from the stack.
- if (stackidx == 0) // stack is empty, finished
+ if (stackidx == 0) { // stack is empty, finished
break;
+ }
// pop an item from the stack
--stackidx;
@@ -6620,8 +6832,9 @@ pop:
// When the score goes over "limit" it may actually be much higher.
// Return a very large number to avoid going below the limit when giving a
// bonus.
- if (minscore > limit)
+ if (minscore > limit) {
return SCORE_MAXMAX;
+ }
return minscore;
}
@@ -6656,7 +6869,7 @@ void ex_spellinfo(exarg_T *eap)
// ":spelldump"
void ex_spelldump(exarg_T *eap)
{
- char_u *spl;
+ char_u *spl;
long dummy;
if (no_spell_checking(curwin)) {
@@ -6685,50 +6898,49 @@ void ex_spelldump(exarg_T *eap)
redraw_later(curwin, NOT_VALID);
}
-// Go through all possible words and:
-// 1. When "pat" is NULL: dump a list of all words in the current buffer.
-// "ic" and "dir" are not used.
-// 2. When "pat" is not NULL: add matching words to insert mode completion.
-void
-spell_dump_compl (
- char_u *pat, // leading part of the word
- int ic, // ignore case
- Direction *dir, // direction for adding matches
- int dumpflags_arg // DUMPFLAG_*
-)
+/// Go through all possible words and:
+/// 1. When "pat" is NULL: dump a list of all words in the current buffer.
+/// "ic" and "dir" are not used.
+/// 2. When "pat" is not NULL: add matching words to insert mode completion.
+///
+/// @param pat leading part of the word
+/// @param ic ignore case
+/// @param dir direction for adding matches
+/// @param dumpflags_arg DUMPFLAG_*
+void spell_dump_compl(char_u *pat, int ic, Direction *dir, int dumpflags_arg)
{
- langp_T *lp;
- slang_T *slang;
+ langp_T *lp;
+ slang_T *slang;
idx_T arridx[MAXWLEN];
int curi[MAXWLEN];
char_u word[MAXWLEN];
int c;
- char_u *byts;
- idx_T *idxs;
+ char_u *byts;
+ idx_T *idxs;
linenr_T lnum = 0;
int round;
int depth;
int n;
int flags;
- char_u *region_names = NULL; // region names being used
+ char_u *region_names = NULL; // region names being used
bool do_region = true; // dump region names and numbers
- char_u *p;
+ char_u *p;
int dumpflags = dumpflags_arg;
int patlen;
// When ignoring case or when the pattern starts with capital pass this on
// to dump_word().
if (pat != NULL) {
- if (ic)
+ if (ic) {
dumpflags |= DUMPFLAG_ICASE;
- else {
+ } else {
n = captype(pat, NULL);
- if (n == WF_ONECAP)
+ if (n == WF_ONECAP) {
dumpflags |= DUMPFLAG_ONECAP;
- else if (n == WF_ALLCAP
- && (int)STRLEN(pat) > mb_ptr2len(pat)
- )
+ } else if (n == WF_ALLCAP
+ && (int)STRLEN(pat) > mb_ptr2len(pat)) {
dumpflags |= DUMPFLAG_ALLCAP;
+ }
}
}
@@ -6738,9 +6950,9 @@ spell_dump_compl (
lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
p = lp->lp_slang->sl_regions;
if (p[0] != 0) {
- if (region_names == NULL) // first language with regions
+ if (region_names == NULL) { // first language with regions
region_names = p;
- else if (STRCMP(region_names, p) != 0) {
+ } else if (STRCMP(region_names, p) != 0) {
do_region = false; // region names are different
break;
}
@@ -6752,15 +6964,17 @@ spell_dump_compl (
vim_snprintf((char *)IObuff, IOSIZE, "/regions=%s", region_names);
ml_append(lnum++, IObuff, (colnr_T)0, false);
}
- } else
+ } else {
do_region = false;
+ }
// Loop over all files loaded for the entries in 'spelllang'.
for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) {
lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
slang = lp->lp_slang;
- if (slang->sl_fbyts == NULL) // reloading failed
+ if (slang->sl_fbyts == NULL) { // reloading failed
continue;
+ }
if (pat == NULL) {
vim_snprintf((char *)IObuff, IOSIZE, "# file: %s", slang->sl_fname);
@@ -6769,10 +6983,11 @@ spell_dump_compl (
// When matching with a pattern and there are no prefixes only use
// parts of the tree that match "pat".
- if (pat != NULL && slang->sl_pbyts == NULL)
+ if (pat != NULL && slang->sl_pbyts == NULL) {
patlen = (int)STRLEN(pat);
- else
+ } else {
patlen = -1;
+ }
// round 1: case-folded tree
// round 2: keep-case tree
@@ -6786,9 +7001,9 @@ spell_dump_compl (
byts = slang->sl_kbyts;
idxs = slang->sl_kidxs;
}
- if (byts == NULL)
+ if (byts == NULL) {
continue; // array is empty
-
+ }
depth = 0;
arridx[0] = 0;
curi[0] = 1;
@@ -6817,23 +7032,26 @@ spell_dump_compl (
|| (((unsigned)flags >> 16)
& lp->lp_region) != 0)) {
word[depth] = NUL;
- if (!do_region)
+ if (!do_region) {
flags &= ~WF_REGION;
+ }
// Dump the basic word if there is no prefix or
// when it's the first one.
c = (unsigned)flags >> 24;
if (c == 0 || curi[depth] == 2) {
dump_word(slang, word, pat, dir,
- dumpflags, flags, lnum);
- if (pat == NULL)
+ dumpflags, flags, lnum);
+ if (pat == NULL) {
++lnum;
+ }
}
// Apply the prefix, if there is one.
- if (c != 0)
+ if (c != 0) {
lnum = dump_prefixes(slang, word, pat, dir,
- dumpflags, flags, lnum);
+ dumpflags, flags, lnum);
+ }
}
} else {
// Normal char, go one level deeper.
@@ -6849,8 +7067,9 @@ spell_dump_compl (
// ignore case...
assert(depth >= 0);
if (depth <= patlen
- && mb_strnicmp(word, pat, (size_t)depth) != 0)
+ && mb_strnicmp(word, pat, (size_t)depth) != 0) {
--depth;
+ }
}
}
}
@@ -6860,22 +7079,23 @@ spell_dump_compl (
// Dumps one word: apply case modifications and append a line to the buffer.
// When "lnum" is zero add insert mode completion.
-static void dump_word(slang_T *slang, char_u *word, char_u *pat,
- Direction *dir, int dumpflags, int wordflags,
- linenr_T lnum)
+static void dump_word(slang_T *slang, char_u *word, char_u *pat, Direction *dir, int dumpflags,
+ int wordflags, linenr_T lnum)
{
bool keepcap = false;
- char_u *p;
- char_u *tw;
+ char_u *p;
+ char_u *tw;
char_u cword[MAXWLEN];
char_u badword[MAXWLEN + 10];
int i;
int flags = wordflags;
- if (dumpflags & DUMPFLAG_ONECAP)
+ if (dumpflags & DUMPFLAG_ONECAP) {
flags |= WF_ONECAP;
- if (dumpflags & DUMPFLAG_ALLCAP)
+ }
+ if (dumpflags & DUMPFLAG_ALLCAP) {
flags |= WF_ALLCAP;
+ }
if ((dumpflags & DUMPFLAG_KEEPCASE) == 0 && (flags & WF_CAPMASK) != 0) {
// Need to fix case according to "flags".
@@ -6885,8 +7105,9 @@ static void dump_word(slang_T *slang, char_u *word, char_u *pat,
p = word;
if ((dumpflags & DUMPFLAG_KEEPCASE)
&& ((captype(word, NULL) & WF_KEEPCAP) == 0
- || (flags & WF_FIXCAP) != 0))
+ || (flags & WF_FIXCAP) != 0)) {
keepcap = true;
+ }
}
tw = p;
@@ -6917,13 +7138,13 @@ static void dump_word(slang_T *slang, char_u *word, char_u *pat,
}
if (dumpflags & DUMPFLAG_COUNT) {
- hashitem_T *hi;
+ hashitem_T *hi;
// Include the word count for ":spelldump!".
hi = hash_find(&slang->sl_wordcount, tw);
if (!HASHITEM_EMPTY(hi)) {
vim_snprintf((char *)IObuff, IOSIZE, "%s\t%d",
- tw, HI2WC(hi)->wc_count);
+ tw, HI2WC(hi)->wc_count);
p = IObuff;
}
}
@@ -6939,20 +7160,16 @@ static void dump_word(slang_T *slang, char_u *word, char_u *pat,
}
}
-// For ":spelldump": Find matching prefixes for "word". Prepend each to
-// "word" and append a line to the buffer.
-// When "lnum" is zero add insert mode completion.
-// Return the updated line number.
-static linenr_T
-dump_prefixes (
- slang_T *slang,
- char_u *word, // case-folded word
- char_u *pat,
- Direction *dir,
- int dumpflags,
- int flags, // flags with prefix ID
- linenr_T startlnum
-)
+/// For ":spelldump": Find matching prefixes for "word". Prepend each to
+/// "word" and append a line to the buffer.
+/// When "lnum" is zero add insert mode completion.
+///
+/// @param word case-folded word
+/// @param flags flags with prefix ID
+///
+/// @return the updated line number.
+static linenr_T dump_prefixes(slang_T *slang, char_u *word, char_u *pat, Direction *dir,
+ int dumpflags, int flags, linenr_T startlnum)
{
idx_T arridx[MAXWLEN];
int curi[MAXWLEN];
@@ -6960,8 +7177,8 @@ dump_prefixes (
char_u word_up[MAXWLEN];
bool has_word_up = false;
int c;
- char_u *byts;
- idx_T *idxs;
+ char_u *byts;
+ idx_T *idxs;
linenr_T lnum = startlnum;
int depth;
int n;
@@ -6998,19 +7215,22 @@ dump_prefixes (
c = byts[n];
if (c == 0) {
// End of prefix, find out how many IDs there are.
- for (i = 1; i < len; ++i)
- if (byts[n + i] != 0)
+ for (i = 1; i < len; ++i) {
+ if (byts[n + i] != 0) {
break;
+ }
+ }
curi[depth] += i - 1;
c = valid_word_prefix(i, n, flags, word, slang, false);
if (c != 0) {
STRLCPY(prefix + depth, word, MAXWLEN - depth);
dump_word(slang, prefix, pat, dir, dumpflags,
- (c & WF_RAREPFX) ? (flags | WF_RARE)
- : flags, lnum);
- if (lnum != 0)
+ (c & WF_RAREPFX) ? (flags | WF_RARE)
+ : flags, lnum);
+ if (lnum != 0) {
++lnum;
+ }
}
// Check for prefix that matches the word when the
@@ -7018,14 +7238,15 @@ dump_prefixes (
// a condition.
if (has_word_up) {
c = valid_word_prefix(i, n, flags, word_up, slang,
- true);
+ true);
if (c != 0) {
STRLCPY(prefix + depth, word_up, MAXWLEN - depth);
dump_word(slang, prefix, pat, dir, dumpflags,
- (c & WF_RAREPFX) ? (flags | WF_RARE)
- : flags, lnum);
- if (lnum != 0)
+ (c & WF_RAREPFX) ? (flags | WF_RARE)
+ : flags, lnum);
+ if (lnum != 0) {
++lnum;
+ }
}
}
} else {
@@ -7045,7 +7266,7 @@ dump_prefixes (
// Uses the spell-checking word characters.
char_u *spell_to_word_end(char_u *start, win_T *win)
{
- char_u *p = start;
+ char_u *p = start;
while (*p != NUL && spell_iswordp(p, win)) {
MB_PTR_ADV(p);
@@ -7060,8 +7281,8 @@ char_u *spell_to_word_end(char_u *start, win_T *win)
// Returns the column number of the word.
int spell_word_start(int startcol)
{
- char_u *line;
- char_u *p;
+ char_u *line;
+ char_u *p;
int col = 0;
if (no_spell_checking(curwin)) {
diff --git a/src/nvim/spell.h b/src/nvim/spell.h
index e93c82b91d..f941f0e5e7 100644
--- a/src/nvim/spell.h
+++ b/src/nvim/spell.h
@@ -3,9 +3,9 @@
#include <stdbool.h>
-#include "nvim/spell_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/globals.h"
+#include "nvim/spell_defs.h"
#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/spell_defs.h b/src/nvim/spell_defs.h
index f07f5673f9..78aa6bf199 100644
--- a/src/nvim/spell_defs.h
+++ b/src/nvim/spell_defs.h
@@ -20,9 +20,9 @@
// is 8 bytes we could use something smaller, but what?
typedef int idx_T;
-# define SPL_FNAME_TMPL "%s.%s.spl"
-# define SPL_FNAME_ADD ".add."
-# define SPL_FNAME_ASCII ".ascii."
+#define SPL_FNAME_TMPL "%s.%s.spl"
+#define SPL_FNAME_ADD ".add."
+#define SPL_FNAME_ASCII ".ascii."
// Flags used for a word. Only the lowest byte can be used, the region byte
// comes above it.
@@ -71,22 +71,22 @@ typedef int idx_T;
// si_repsal, sl_rep, and si_sal. Not for sl_sal!
// One replacement: from "ft_from" to "ft_to".
typedef struct fromto_S {
- char_u *ft_from;
- char_u *ft_to;
+ char_u *ft_from;
+ char_u *ft_to;
} fromto_T;
// Info from "SAL" entries in ".aff" file used in sl_sal.
// The info is split for quick processing by spell_soundfold().
// Note that "sm_oneof" and "sm_rules" point into sm_lead.
typedef struct salitem_S {
- char_u *sm_lead; // leading letters
+ char_u *sm_lead; // leading letters
int sm_leadlen; // length of "sm_lead"
- char_u *sm_oneof; // letters from () or NULL
- char_u *sm_rules; // rules like ^, $, priority
- char_u *sm_to; // replacement.
- int *sm_lead_w; // wide character copy of "sm_lead"
- int *sm_oneof_w; // wide character copy of "sm_oneof"
- int *sm_to_w; // wide character copy of "sm_to"
+ char_u *sm_oneof; // letters from () or NULL
+ char_u *sm_rules; // rules like ^, $, priority
+ char_u *sm_to; // replacement.
+ int *sm_lead_w; // wide character copy of "sm_lead"
+ int *sm_oneof_w; // wide character copy of "sm_oneof"
+ int *sm_to_w; // wide character copy of "sm_to"
} salitem_T;
typedef int salfirst_T;
@@ -113,25 +113,25 @@ typedef int salfirst_T;
typedef struct slang_S slang_T;
struct slang_S {
- slang_T *sl_next; // next language
- char_u *sl_name; // language name "en", "en.rare", "nl", etc.
- char_u *sl_fname; // name of .spl file
+ slang_T *sl_next; // next language
+ char_u *sl_name; // language name "en", "en.rare", "nl", etc.
+ char_u *sl_fname; // name of .spl file
bool sl_add; // true if it's a .add file.
- char_u *sl_fbyts; // case-folded word bytes
- long sl_fbyts_len; // length of sl_fbyts
- idx_T *sl_fidxs; // case-folded word indexes
- char_u *sl_kbyts; // keep-case word bytes
- idx_T *sl_kidxs; // keep-case word indexes
- char_u *sl_pbyts; // prefix tree word bytes
- idx_T *sl_pidxs; // prefix tree word indexes
+ char_u *sl_fbyts; // case-folded word bytes
+ long sl_fbyts_len; // length of sl_fbyts
+ idx_T *sl_fidxs; // case-folded word indexes
+ char_u *sl_kbyts; // keep-case word bytes
+ idx_T *sl_kidxs; // keep-case word indexes
+ char_u *sl_pbyts; // prefix tree word bytes
+ idx_T *sl_pidxs; // prefix tree word indexes
- char_u *sl_info; // infotext string or NULL
+ char_u *sl_info; // infotext string or NULL
char_u sl_regions[MAXREGIONS * 2 + 1];
- // table with up to 8 region names plus NUL
+ // table with up to 8 region names plus NUL
- char_u *sl_midword; // MIDWORD string or NULL
+ char_u *sl_midword; // MIDWORD string or NULL
hashtab_T sl_wordcount; // hashtable with word count, wordcount_T
@@ -140,17 +140,17 @@ struct slang_S {
int sl_compsylmax; // COMPOUNDSYLMAX (default: MAXWLEN)
int sl_compoptions; // COMP_* flags
garray_T sl_comppat; // CHECKCOMPOUNDPATTERN items
- regprog_T *sl_compprog; // COMPOUNDRULE turned into a regexp progrm
- // (NULL when no compounding)
- char_u *sl_comprules; // all COMPOUNDRULE concatenated (or NULL)
- char_u *sl_compstartflags; // flags for first compound word
- char_u *sl_compallflags; // all flags for compound words
+ regprog_T *sl_compprog; // COMPOUNDRULE turned into a regexp progrm
+ // (NULL when no compounding)
+ char_u *sl_comprules; // all COMPOUNDRULE concatenated (or NULL)
+ char_u *sl_compstartflags; // flags for first compound word
+ char_u *sl_compallflags; // all flags for compound words
bool sl_nobreak; // When true: no spaces between words
- char_u *sl_syllable; // SYLLABLE repeatable chars or NULL
+ char_u *sl_syllable; // SYLLABLE repeatable chars or NULL
garray_T sl_syl_items; // syllable items
int sl_prefixcnt; // number of items in "sl_prefprog"
- regprog_T **sl_prefprog; // table with regprogs for prefixes
+ regprog_T **sl_prefprog; // table with regprogs for prefixes
garray_T sl_rep; // list of fromto_T entries from REP lines
int16_t sl_rep_first[256]; // indexes where byte first appears, -1 if
@@ -171,9 +171,9 @@ struct slang_S {
// Info from the .sug file. Loaded on demand.
time_t sl_sugtime; // timestamp for .sug file
- char_u *sl_sbyts; // soundfolded word bytes
- idx_T *sl_sidxs; // soundfolded word indexes
- buf_T *sl_sugbuf; // buffer with word number table
+ char_u *sl_sbyts; // soundfolded word bytes
+ idx_T *sl_sidxs; // soundfolded word indexes
+ buf_T *sl_sugbuf; // buffer with word number table
bool sl_sugloaded; // true when .sug file was loaded or failed to
// load
@@ -186,9 +186,9 @@ struct slang_S {
// Structure used in "b_langp", filled from 'spelllang'.
typedef struct langp_S {
- slang_T *lp_slang; // info for this language
- slang_T *lp_sallang; // language used for sound folding or NULL
- slang_T *lp_replang; // language used for REP items or NULL
+ slang_T *lp_slang; // info for this language
+ slang_T *lp_sallang; // language used for sound folding or NULL
+ slang_T *lp_replang; // language used for REP items or NULL
int lp_region; // bitmask for region or REGION_ALL
} langp_T;
@@ -268,7 +268,7 @@ typedef struct trystate_S {
#define SPELL_TOFOLD(c) ((c) >= 128 ? utf_fold(c) : (int)spelltab.st_fold[c])
#define SPELL_TOUPPER(c) ((c) >= 128 ? mb_toupper(c) \
- : (int)spelltab.st_upper[c])
+ : (int)spelltab.st_upper[c])
#define SPELL_ISUPPER(c) ((c) >= 128 ? mb_isupper(c) : spelltab.st_isu[c])
diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c
index 843ecec1b1..e3a6236ae4 100644
--- a/src/nvim/spellfile.c
+++ b/src/nvim/spellfile.c
@@ -226,19 +226,17 @@
// stored as an offset to the previous number in as
// few bytes as possible, see offset2bytes())
-#include <stdio.h>
#include <stdint.h>
+#include <stdio.h>
#include <wctype.h>
-#include "nvim/vim.h"
-#include "nvim/spell_defs.h"
#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/ex_cmds2.h"
#include "nvim/fileio.h"
-#include "nvim/memory.h"
#include "nvim/memline.h"
+#include "nvim/memory.h"
#include "nvim/misc1.h"
#include "nvim/option.h"
#include "nvim/os/os.h"
@@ -246,9 +244,11 @@
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/spell.h"
+#include "nvim/spell_defs.h"
#include "nvim/spellfile.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
+#include "nvim/vim.h"
#ifndef UNIX // it's in os/unix_defs.h for Unix
# include <time.h> // for time_t
@@ -310,7 +310,7 @@ static char *msg_compressing = N_("Compressing word tree...");
// and .dic file.
// Main structure to store the contents of a ".aff" file.
typedef struct afffile_S {
- char_u *af_enc; // "SET", normalized, alloc'ed string or NULL
+ char_u *af_enc; // "SET", normalized, alloc'ed string or NULL
int af_flagtype; // AFT_CHAR, AFT_LONG, AFT_NUM or AFT_CAPLONG
unsigned af_rare; // RARE ID for rare word
unsigned af_keepcase; // KEEPCASE ID for keep-case word
@@ -338,17 +338,17 @@ typedef struct afffile_S {
typedef struct affentry_S affentry_T;
// Affix entry from ".aff" file. Used for prefixes and suffixes.
struct affentry_S {
- affentry_T *ae_next; // next affix with same name/number
- char_u *ae_chop; // text to chop off basic word (can be NULL)
- char_u *ae_add; // text to add to basic word (can be NULL)
- char_u *ae_flags; // flags on the affix (can be NULL)
- char_u *ae_cond; // condition (NULL for ".")
- regprog_T *ae_prog; // regexp program for ae_cond or NULL
+ affentry_T *ae_next; // next affix with same name/number
+ char_u *ae_chop; // text to chop off basic word (can be NULL)
+ char_u *ae_add; // text to add to basic word (can be NULL)
+ char_u *ae_flags; // flags on the affix (can be NULL)
+ char_u *ae_cond; // condition (NULL for ".")
+ regprog_T *ae_prog; // regexp program for ae_cond or NULL
char ae_compforbid; // COMPOUNDFORBIDFLAG found
char ae_comppermit; // COMPOUNDPERMITFLAG found
};
-# define AH_KEY_LEN 17 // 2 x 8 bytes + NUL
+#define AH_KEY_LEN 17 // 2 x 8 bytes + NUL
// Affix header from ".aff" file. Used for af_pref and af_suff.
typedef struct affheader_S {
@@ -357,7 +357,7 @@ typedef struct affheader_S {
int ah_newID; // prefix ID after renumbering; 0 if not used
int ah_combine; // suffix may combine with prefix
int ah_follows; // another affix block should be following
- affentry_T *ah_first; // first affix entry
+ affentry_T *ah_first; // first affix entry
} affheader_T;
#define HI2AH(hi) ((affheader_T *)(hi)->hi_key)
@@ -381,7 +381,7 @@ typedef struct compitem_S {
typedef struct sblock_S sblock_T;
struct sblock_S {
int sb_used; // nr of bytes already in use
- sblock_T *sb_next; // next block in list
+ sblock_T *sb_next; // next block in list
char_u sb_data[1]; // data, actually longer
};
@@ -397,9 +397,9 @@ struct wordnode_S {
wordnode_T *next; // next node with same hash key
wordnode_T *wnode; // parent node that will write this node
} wn_u2;
- wordnode_T *wn_child; // child (next byte in word)
- wordnode_T *wn_sibling; // next sibling (alternate byte in word,
- // always sorted)
+ wordnode_T *wn_child; // child (next byte in word)
+ wordnode_T *wn_sibling; // next sibling (alternate byte in word,
+ // always sorted)
int wn_refs; // Nr. of references to this node. Only
// relevant for first node in a list of
// siblings, in following siblings it is
@@ -425,29 +425,29 @@ struct wordnode_S {
// Info used while reading the spell files.
typedef struct spellinfo_S {
- wordnode_T *si_foldroot; // tree with case-folded words
+ wordnode_T *si_foldroot; // tree with case-folded words
long si_foldwcount; // nr of words in si_foldroot
- wordnode_T *si_keeproot; // tree with keep-case words
+ wordnode_T *si_keeproot; // tree with keep-case words
long si_keepwcount; // nr of words in si_keeproot
- wordnode_T *si_prefroot; // tree with postponed prefixes
+ wordnode_T *si_prefroot; // tree with postponed prefixes
long si_sugtree; // creating the soundfolding trie
- sblock_T *si_blocks; // memory blocks used
+ sblock_T *si_blocks; // memory blocks used
long si_blocks_cnt; // memory blocks allocated
int si_did_emsg; // TRUE when ran out of memory
long si_compress_cnt; // words to add before lowering
// compression limit
- wordnode_T *si_first_free; // List of nodes that have been freed during
- // compression, linked by "wn_child" field.
+ wordnode_T *si_first_free; // List of nodes that have been freed during
+ // compression, linked by "wn_child" field.
long si_free_count; // number of nodes in si_first_free
#ifdef SPELL_PRINTTREE
int si_wordnode_nr; // sequence nr for nodes
#endif
- buf_T *si_spellbuf; // buffer used to store soundfold word table
+ buf_T *si_spellbuf; // buffer used to store soundfold word table
int si_ascii; // handling only ASCII words
int si_add; // addition file
@@ -457,18 +457,18 @@ typedef struct spellinfo_S {
int si_memtot; // runtime memory used
int si_verbose; // verbose messages
int si_msg_count; // number of words added since last message
- char_u *si_info; // info text chars or NULL
+ char_u *si_info; // info text chars or NULL
int si_region_count; // number of regions supported (1 when there
// are no regions)
char_u si_region_name[MAXREGIONS * 2 + 1];
- // region names; used only if
- // si_region_count > 1)
+ // region names; used only if
+ // si_region_count > 1)
garray_T si_rep; // list of fromto_T entries from REP lines
garray_T si_repsal; // list of fromto_T entries from REPSAL lines
garray_T si_sal; // list of fromto_T entries from SAL lines
- char_u *si_sofofr; // SOFOFROM text
- char_u *si_sofoto; // SOFOTO text
+ char_u *si_sofofr; // SOFOFROM text
+ char_u *si_sofoto; // SOFOTO text
int si_nosugfile; // NOSUGFILE item found
int si_nosplitsugs; // NOSPLITSUGS item found
int si_nocompoundsugs; // NOCOMPOUNDSUGS item found
@@ -478,16 +478,16 @@ typedef struct spellinfo_S {
time_t si_sugtime; // timestamp for .sug file
int si_rem_accents; // soundsalike: remove accents
garray_T si_map; // MAP info concatenated
- char_u *si_midword; // MIDWORD chars or NULL
+ char_u *si_midword; // MIDWORD chars or NULL
int si_compmax; // max nr of words for compounding
int si_compminlen; // minimal length for compounding
int si_compsylmax; // max nr of syllables for compounding
int si_compoptions; // COMP_ flags
garray_T si_comppat; // CHECKCOMPOUNDPATTERN items, each stored as
// a string
- char_u *si_compflags; // flags used for compounding
+ char_u *si_compflags; // flags used for compounding
char_u si_nobreak; // NOBREAK
- char_u *si_syllable; // syllable string
+ char_u *si_syllable; // syllable string
garray_T si_prefcond; // table with conditions for postponed
// prefixes, each stored as a string
int si_newprefID; // current value for ah_newID
@@ -508,16 +508,16 @@ typedef struct spellinfo_S {
/// @return Allows to proceed if everything is OK, returns SP_TRUNCERROR if
/// there are not enough bytes, returns SP_OTHERERROR if reading failed.
#define SPELL_READ_BYTES(buf, n, fd, exit_code) \
- do { \
- const size_t n__SPRB = (n); \
- FILE *const fd__SPRB = (fd); \
- char *const buf__SPRB = (buf); \
- const size_t read_bytes__SPRB = fread(buf__SPRB, 1, n__SPRB, fd__SPRB); \
- if (read_bytes__SPRB != n__SPRB) { \
- exit_code; \
- return feof(fd__SPRB) ? SP_TRUNCERROR : SP_OTHERERROR; \
- } \
- } while (0)
+ do { \
+ const size_t n__SPRB = (n); \
+ FILE *const fd__SPRB = (fd); \
+ char *const buf__SPRB = (buf); \
+ const size_t read_bytes__SPRB = fread(buf__SPRB, 1, n__SPRB, fd__SPRB); \
+ if (read_bytes__SPRB != n__SPRB) { \
+ exit_code; \
+ return feof(fd__SPRB) ? SP_TRUNCERROR : SP_OTHERERROR; \
+ } \
+ } while (0)
/// Like #SPELL_READ_BYTES, but also error out if NUL byte was read
///
@@ -525,16 +525,16 @@ typedef struct spellinfo_S {
/// there are not enough bytes, returns SP_OTHERERROR if reading failed,
/// returns SP_FORMERROR if read out a NUL byte.
#define SPELL_READ_NONNUL_BYTES(buf, n, fd, exit_code) \
- do { \
- const size_t n__SPRNB = (n); \
- FILE *const fd__SPRNB = (fd); \
- char *const buf__SPRNB = (buf); \
- SPELL_READ_BYTES(buf__SPRNB, n__SPRNB, fd__SPRNB, exit_code); \
- if (memchr(buf__SPRNB, NUL, (size_t)n__SPRNB)) { \
- exit_code; \
- return SP_FORMERROR; \
- } \
- } while (0)
+ do { \
+ const size_t n__SPRNB = (n); \
+ FILE *const fd__SPRNB = (fd); \
+ char *const buf__SPRNB = (buf); \
+ SPELL_READ_BYTES(buf__SPRNB, n__SPRNB, fd__SPRNB, exit_code); \
+ if (memchr(buf__SPRNB, NUL, (size_t)n__SPRNB)) { \
+ exit_code; \
+ return SP_FORMERROR; \
+ } \
+ } while (0)
/// Check that spell file starts with a magic string
///
@@ -556,40 +556,36 @@ static inline int spell_check_magic_string(FILE *const fd)
return 0;
}
-// Load one spell file and store the info into a slang_T.
-//
-// This is invoked in three ways:
-// - From spell_load_cb() to load a spell file for the first time. "lang" is
-// the language name, "old_lp" is NULL. Will allocate an slang_T.
-// - To reload a spell file that was changed. "lang" is NULL and "old_lp"
-// points to the existing slang_T.
-// - Just after writing a .spl file; it's read back to produce the .sug file.
-// "old_lp" is NULL and "lang" is NULL. Will allocate an slang_T.
-//
-// Returns the slang_T the spell file was loaded into. NULL for error.
-slang_T *
-spell_load_file (
- char_u *fname,
- char_u *lang,
- slang_T *old_lp,
- bool silent // no error if file doesn't exist
-)
+/// Load one spell file and store the info into a slang_T.
+///
+/// This is invoked in three ways:
+/// - From spell_load_cb() to load a spell file for the first time. "lang" is
+/// the language name, "old_lp" is NULL. Will allocate an slang_T.
+/// - To reload a spell file that was changed. "lang" is NULL and "old_lp"
+/// points to the existing slang_T.
+/// - Just after writing a .spl file; it's read back to produce the .sug file.
+/// "old_lp" is NULL and "lang" is NULL. Will allocate an slang_T.
+///
+/// @param silent no error if file doesn't exist
+///
+/// @return the slang_T the spell file was loaded into. NULL for error.
+slang_T *spell_load_file(char_u *fname, char_u *lang, slang_T *old_lp, bool silent)
{
- FILE *fd;
- char_u *p;
+ FILE *fd;
+ char_u *p;
int n;
int len;
- char_u *save_sourcing_name = sourcing_name;
+ char_u *save_sourcing_name = sourcing_name;
linenr_T save_sourcing_lnum = sourcing_lnum;
- slang_T *lp = NULL;
+ slang_T *lp = NULL;
int c = 0;
int res;
fd = os_fopen((char *)fname, "r");
if (fd == NULL) {
- if (!silent)
+ if (!silent) {
EMSG2(_(e_notopen), fname);
- else if (p_verbose > 2) {
+ } else if (p_verbose > 2) {
verbose_enter();
smsg((char *)e_notopen, fname);
verbose_leave();
@@ -610,8 +606,9 @@ spell_load_file (
// Check for .add.spl.
lp->sl_add = strstr((char *)path_tail(fname), SPL_FNAME_ADD) != NULL;
- } else
+ } else {
lp = old_lp;
+ }
// Set sourcing_name, so that error messages mention the file name.
sourcing_name = fname;
@@ -620,19 +617,16 @@ spell_load_file (
// <HEADER>: <fileID>
const int scms_ret = spell_check_magic_string(fd);
switch (scms_ret) {
- case SP_FORMERROR:
- case SP_TRUNCERROR: {
- emsgf("%s", _("E757: This does not look like a spell file"));
- goto endFAIL;
- }
- case SP_OTHERERROR: {
- emsgf(_("E5042: Failed to read spell file %s: %s"),
- fname, strerror(ferror(fd)));
- goto endFAIL;
- }
- case 0: {
- break;
- }
+ case SP_FORMERROR:
+ case SP_TRUNCERROR:
+ emsgf("%s", _("E757: This does not look like a spell file"));
+ goto endFAIL;
+ case SP_OTHERERROR:
+ emsgf(_("E5042: Failed to read spell file %s: %s"),
+ fname, strerror(ferror(fd)));
+ goto endFAIL;
+ case 0:
+ break;
}
c = getc(fd); // <versionnr>
if (c < VIMSPELLVERSION) {
@@ -648,19 +642,22 @@ spell_load_file (
// <section>: <sectionID> <sectionflags> <sectionlen> (section contents)
for (;; ) {
n = getc(fd); // <sectionID> or <sectionend>
- if (n == SN_END)
+ if (n == SN_END) {
break;
+ }
c = getc(fd); // <sectionflags>
len = get4c(fd); // <sectionlen>
- if (len < 0)
+ if (len < 0) {
goto truncerr;
+ }
res = 0;
switch (n) {
case SN_INFO:
lp->sl_info = READ_STRING(fd, len); // <infotext>
- if (lp->sl_info == NULL)
+ if (lp->sl_info == NULL) {
goto endFAIL;
+ }
break;
case SN_REGION:
@@ -673,8 +670,9 @@ spell_load_file (
case SN_MIDWORD:
lp->sl_midword = READ_STRING(fd, len); // <midword>
- if (lp->sl_midword == NULL)
+ if (lp->sl_midword == NULL) {
goto endFAIL;
+ }
break;
case SN_PREFCOND:
@@ -699,8 +697,9 @@ spell_load_file (
case SN_MAP:
p = READ_STRING(fd, len); // <mapstr>
- if (p == NULL)
+ if (p == NULL) {
goto endFAIL;
+ }
set_map_str(lp, p);
xfree(p);
break;
@@ -731,10 +730,12 @@ spell_load_file (
case SN_SYLLABLE:
lp->sl_syllable = READ_STRING(fd, len); // <syllable>
- if (lp->sl_syllable == NULL)
+ if (lp->sl_syllable == NULL) {
goto endFAIL;
- if (init_syl_tab(lp) == FAIL)
+ }
+ if (init_syl_tab(lp) == FAIL) {
goto endFAIL;
+ }
break;
default:
@@ -744,9 +745,11 @@ spell_load_file (
EMSG(_("E770: Unsupported section in spell file"));
goto endFAIL;
}
- while (--len >= 0)
- if (getc(fd) < 0)
+ while (--len >= 0) {
+ if (getc(fd) < 0) {
goto truncerr;
+ }
+ }
break;
}
someerror:
@@ -759,8 +762,9 @@ truncerr:
EMSG(_(e_spell_trunc));
goto endFAIL;
}
- if (res == SP_OTHERERROR)
+ if (res == SP_OTHERERROR) {
goto endFAIL;
+ }
}
// <LWORDTREE>
@@ -792,16 +796,19 @@ truncerr:
goto endOK;
endFAIL:
- if (lang != NULL)
+ if (lang != NULL) {
// truncating the name signals the error to spell_load_lang()
*lang = NUL;
- if (lp != NULL && old_lp == NULL)
+ }
+ if (lp != NULL && old_lp == NULL) {
slang_free(lp);
+ }
lp = NULL;
endOK:
- if (fd != NULL)
+ if (fd != NULL) {
fclose(fd);
+ }
sourcing_name = save_sourcing_name;
sourcing_lnum = save_sourcing_lnum;
@@ -827,8 +834,9 @@ static void tree_count_words(char_u *byts, idx_T *idxs)
if (curi[depth] > byts[arridx[depth]]) {
// Done all bytes at this node, go up one level.
idxs[arridx[depth]] = wordcount[depth];
- if (depth > 0)
+ if (depth > 0) {
wordcount[depth - 1] += wordcount[depth];
+ }
--depth;
fast_breakcheck();
@@ -862,10 +870,10 @@ static void tree_count_words(char_u *byts, idx_T *idxs)
// Load the .sug files for languages that have one and weren't loaded yet.
void suggest_load_files(void)
{
- langp_T *lp;
- slang_T *slang;
- char_u *dotp;
- FILE *fd;
+ langp_T *lp;
+ slang_T *slang;
+ char_u *dotp;
+ FILE *fd;
char_u buf[MAXWLEN];
int i;
time_t timestamp;
@@ -895,21 +903,22 @@ void suggest_load_files(void)
}
// <SUGHEADER>: <fileID> <versionnr> <timestamp>
- for (i = 0; i < VIMSUGMAGICL; ++i)
+ for (i = 0; i < VIMSUGMAGICL; ++i) {
buf[i] = getc(fd); // <fileID>
+ }
if (STRNCMP(buf, VIMSUGMAGIC, VIMSUGMAGICL) != 0) {
EMSG2(_("E778: This does not look like a .sug file: %s"),
- slang->sl_fname);
+ slang->sl_fname);
goto nextone;
}
c = getc(fd); // <versionnr>
if (c < VIMSUGVERSION) {
EMSG2(_("E779: Old .sug file, needs to be updated: %s"),
- slang->sl_fname);
+ slang->sl_fname);
goto nextone;
- } else if (c > VIMSUGVERSION) {
+ } else if (c > VIMSUGVERSION) {
EMSG2(_("E780: .sug file is for newer version of Vim: %s"),
- slang->sl_fname);
+ slang->sl_fname);
goto nextone;
}
@@ -918,7 +927,7 @@ void suggest_load_files(void)
timestamp = get8ctime(fd); // <timestamp>
if (timestamp != slang->sl_sugtime) {
EMSG2(_("E781: .sug file doesn't match .spl file: %s"),
- slang->sl_fname);
+ slang->sl_fname);
goto nextone;
}
@@ -928,7 +937,7 @@ void suggest_load_files(void)
false, 0) != 0) {
someerror:
EMSG2(_("E782: error while reading .sug file: %s"),
- slang->sl_fname);
+ slang->sl_fname);
slang_clear_sug(slang);
goto nextone;
}
@@ -942,8 +951,9 @@ someerror:
// <sugwcount>
wcount = get4c(fd);
- if (wcount < 0)
+ if (wcount < 0) {
goto someerror;
+ }
// Read all the wordnr lists into the buffer, one NUL terminated
// list per line.
@@ -956,8 +966,9 @@ someerror:
goto someerror;
}
GA_APPEND(char_u, &ga, c);
- if (c == NUL)
+ if (c == NUL) {
break;
+ }
}
if (ml_append_buf(slang->sl_sugbuf, (linenr_T)wordnr,
ga.ga_data, ga.ga_len, true) == FAIL) {
@@ -972,8 +983,9 @@ someerror:
tree_count_words(slang->sl_sbyts, slang->sl_sidxs);
nextone:
- if (fd != NULL)
+ if (fd != NULL) {
fclose(fd);
+ }
STRCPY(dotp, ".spl");
}
}
@@ -988,7 +1000,7 @@ nextone:
static char_u *read_cnt_string(FILE *fd, int cnt_bytes, int *cntp)
{
int cnt = 0;
- char_u *str;
+ char_u *str;
// read the length bytes, MSB first
for (int i = 0; i < cnt_bytes; i++) {
@@ -1001,12 +1013,13 @@ static char_u *read_cnt_string(FILE *fd, int cnt_bytes, int *cntp)
cnt = (cnt << 8) + (unsigned)c;
}
*cntp = cnt;
- if (cnt == 0)
+ if (cnt == 0) {
return NULL; // nothing to read, return NULL
-
+ }
str = READ_STRING(fd, cnt);
- if (str == NULL)
+ if (str == NULL) {
*cntp = SP_OTHERERROR;
+ }
return str;
}
@@ -1027,14 +1040,15 @@ static int read_region_section(FILE *fd, slang_T *lp, int len)
// Return SP_*ERROR flags.
static int read_charflags_section(FILE *fd)
{
- char_u *flags;
- char_u *fol;
+ char_u *flags;
+ char_u *fol;
int flagslen, follen;
// <charflagslen> <charflags>
flags = read_cnt_string(fd, 1, &flagslen);
- if (flagslen < 0)
+ if (flagslen < 0) {
return flagslen;
+ }
// <folcharslen> <folchars>
fol = read_cnt_string(fd, 2, &follen);
@@ -1044,15 +1058,17 @@ static int read_charflags_section(FILE *fd)
}
// Set the word-char flags and fill SPELL_ISUPPER() table.
- if (flags != NULL && fol != NULL)
+ if (flags != NULL && fol != NULL) {
set_spell_charflags(flags, flagslen, fol);
+ }
xfree(flags);
xfree(fol);
// When <charflagslen> is zero then <fcharlen> must also be zero.
- if ((flags == NULL) != (fol == NULL))
+ if ((flags == NULL) != (fol == NULL)) {
return SP_FORMERROR;
+ }
return 0;
}
@@ -1094,11 +1110,12 @@ static int read_prefcond_section(FILE *fd, slang_T *lp)
static int read_rep_section(FILE *fd, garray_T *gap, int16_t *first)
{
int cnt;
- fromto_T *ftp;
+ fromto_T *ftp;
cnt = get2c(fd); // <repcount>
- if (cnt < 0)
+ if (cnt < 0) {
return SP_TRUNCERROR;
+ }
ga_grow(gap, cnt);
@@ -1107,15 +1124,18 @@ static int read_rep_section(FILE *fd, garray_T *gap, int16_t *first)
int c;
ftp = &((fromto_T *)gap->ga_data)[gap->ga_len];
ftp->ft_from = read_cnt_string(fd, 1, &c);
- if (c < 0)
+ if (c < 0) {
return c;
- if (c == 0)
+ }
+ if (c == 0) {
return SP_FORMERROR;
+ }
ftp->ft_to = read_cnt_string(fd, 1, &c);
if (c <= 0) {
xfree(ftp->ft_from);
- if (c < 0)
+ if (c < 0) {
return c;
+ }
return SP_FORMERROR;
}
}
@@ -1126,8 +1146,9 @@ static int read_rep_section(FILE *fd, garray_T *gap, int16_t *first)
}
for (int i = 0; i < gap->ga_len; ++i) {
ftp = &((fromto_T *)gap->ga_data)[i];
- if (first[*ftp->ft_from] == -1)
+ if (first[*ftp->ft_from] == -1) {
first[*ftp->ft_from] = i;
+ }
}
return 0;
}
@@ -1137,10 +1158,10 @@ static int read_rep_section(FILE *fd, garray_T *gap, int16_t *first)
static int read_sal_section(FILE *fd, slang_T *slang)
{
int cnt;
- garray_T *gap;
- salitem_T *smp;
+ garray_T *gap;
+ salitem_T *smp;
int ccnt;
- char_u *p;
+ char_u *p;
slang->sl_sofo = false;
@@ -1156,8 +1177,9 @@ static int read_sal_section(FILE *fd, slang_T *slang)
}
cnt = get2c(fd); // <salcount>
- if (cnt < 0)
+ if (cnt < 0) {
return SP_TRUNCERROR;
+ }
gap = &slang->sl_sal;
ga_init(gap, sizeof(salitem_T), 10);
@@ -1169,8 +1191,9 @@ static int read_sal_section(FILE *fd, slang_T *slang)
smp = &((salitem_T *)gap->ga_data)[gap->ga_len];
ccnt = getc(fd); // <salfromlen>
- if (ccnt < 0)
+ if (ccnt < 0) {
return SP_TRUNCERROR;
+ }
p = xmalloc(ccnt + 2);
smp->sm_lead = p;
@@ -1178,8 +1201,9 @@ static int read_sal_section(FILE *fd, slang_T *slang)
int i = 0;
for (; i < ccnt; ++i) {
c = getc(fd); // <salfrom>
- if (vim_strchr((char_u *)"0123456789(-<^$", c) != NULL)
+ if (vim_strchr((char_u *)"0123456789(-<^$", c) != NULL) {
break;
+ }
*p++ = c;
}
smp->sm_leadlen = (int)(p - smp->sm_lead);
@@ -1190,15 +1214,18 @@ static int read_sal_section(FILE *fd, slang_T *slang)
smp->sm_oneof = p;
for (++i; i < ccnt; ++i) {
c = getc(fd); // <salfrom>
- if (c == ')')
+ if (c == ')') {
break;
+ }
*p++ = c;
}
*p++ = NUL;
- if (++i < ccnt)
+ if (++i < ccnt) {
c = getc(fd);
- } else
+ }
+ } else {
smp->sm_oneof = NULL;
+ }
// Any following chars go in sm_rules.
smp->sm_rules = p;
@@ -1209,7 +1236,8 @@ static int read_sal_section(FILE *fd, slang_T *slang)
i++;
if (i < ccnt) {
SPELL_READ_NONNUL_BYTES( // <salfrom>
- (char *)p, (size_t)(ccnt - i), fd, xfree(smp->sm_lead));
+ (char *)p, (size_t)(ccnt - i), fd,
+ xfree(smp->sm_lead));
p += (ccnt - i);
}
*p++ = NUL;
@@ -1272,13 +1300,16 @@ static int read_words_section(FILE *fd, slang_T *lp, int len)
// Read one word at a time.
for (i = 0;; ++i) {
c = getc(fd);
- if (c == EOF)
+ if (c == EOF) {
return SP_TRUNCERROR;
+ }
word[i] = c;
- if (word[i] == NUL)
+ if (word[i] == NUL) {
break;
- if (i == MAXWLEN - 1)
+ }
+ if (i == MAXWLEN - 1) {
return SP_FORMERROR;
+ }
}
// Init the count to 10.
@@ -1293,15 +1324,16 @@ static int read_words_section(FILE *fd, slang_T *lp, int len)
static int read_sofo_section(FILE *fd, slang_T *slang)
{
int cnt;
- char_u *from, *to;
+ char_u *from, *to;
int res;
slang->sl_sofo = true;
// <sofofromlen> <sofofrom>
from = read_cnt_string(fd, 2, &cnt);
- if (cnt < 0)
+ if (cnt < 0) {
return cnt;
+ }
// <sofotolen> <sofoto>
to = read_cnt_string(fd, 2, &cnt);
@@ -1311,12 +1343,13 @@ static int read_sofo_section(FILE *fd, slang_T *slang)
}
// Store the info in slang->sl_sal and/or slang->sl_sal_first.
- if (from != NULL && to != NULL)
+ if (from != NULL && to != NULL) {
res = set_sofo(slang, from, to);
- else if (from != NULL || to != NULL)
+ } else if (from != NULL || to != NULL) {
res = SP_FORMERROR; // only one of two strings is an error
- else
+ } else {
res = 0;
+ }
xfree(from);
xfree(to);
@@ -1331,39 +1364,42 @@ static int read_compound(FILE *fd, slang_T *slang, int len)
int todo = len;
int c;
int atstart;
- char_u *pat;
- char_u *pp;
- char_u *cp;
- char_u *ap;
- char_u *crp;
+ char_u *pat;
+ char_u *pp;
+ char_u *cp;
+ char_u *ap;
+ char_u *crp;
int cnt;
- garray_T *gap;
+ garray_T *gap;
- if (todo < 2)
+ if (todo < 2) {
return SP_FORMERROR; // need at least two bytes
-
+ }
--todo;
c = getc(fd); // <compmax>
- if (c < 2)
+ if (c < 2) {
c = MAXWLEN;
+ }
slang->sl_compmax = c;
--todo;
c = getc(fd); // <compminlen>
- if (c < 1)
+ if (c < 1) {
c = 0;
+ }
slang->sl_compminlen = c;
--todo;
c = getc(fd); // <compsylmax>
- if (c < 1)
+ if (c < 1) {
c = MAXWLEN;
+ }
slang->sl_compsylmax = c;
c = getc(fd); // <compoptions>
- if (c != 0)
+ if (c != 0) {
ungetc(c, fd); // be backwards compatible with Vim 7.0b
- else {
+ } else {
--todo;
c = getc(fd); // only use the lower byte for now
--todo;
@@ -1381,13 +1417,15 @@ static int read_compound(FILE *fd, slang_T *slang, int len)
((char_u **)(gap->ga_data))[gap->ga_len++] =
read_cnt_string(fd, 1, &cnt);
// <comppatlen> <comppattext>
- if (cnt < 0)
+ if (cnt < 0) {
return cnt;
+ }
todo -= cnt + 1;
}
}
- if (todo < 0)
+ if (todo < 0) {
return SP_FORMERROR;
+ }
// Turn the COMPOUNDRULE items into a regexp pattern:
// "a[bc]/a*b+" -> "^\(a[bc]\|a*b\+\)$".
@@ -1436,17 +1474,18 @@ static int read_compound(FILE *fd, slang_T *slang, int len)
if (atstart != 0) {
// At start of item: copy flags to "sl_compstartflags". For a
// [abc] item set "atstart" to 2 and copy up to the ']'.
- if (c == '[')
+ if (c == '[') {
atstart = 2;
- else if (c == ']')
+ } else if (c == ']') {
atstart = 0;
- else {
+ } else {
if (!byte_in_str(slang->sl_compstartflags, c)) {
*cp++ = c;
*cp = NUL;
}
- if (atstart == 1)
+ if (atstart == 1) {
atstart = 0;
+ }
}
}
@@ -1455,8 +1494,9 @@ static int read_compound(FILE *fd, slang_T *slang, int len)
if (c == '?' || c == '+' || c == '*') {
XFREE_CLEAR(slang->sl_comprules);
crp = NULL;
- } else
+ } else {
*crp++ = c;
+ }
}
if (c == '/') { // slash separates two items
@@ -1476,13 +1516,15 @@ static int read_compound(FILE *fd, slang_T *slang, int len)
*pp++ = '$';
*pp = NUL;
- if (crp != NULL)
+ if (crp != NULL) {
*crp = NUL;
+ }
slang->sl_compprog = vim_regcomp(pat, RE_MAGIC + RE_STRING + RE_STRICT);
xfree(pat);
- if (slang->sl_compprog == NULL)
+ if (slang->sl_compprog == NULL) {
return SP_FORMERROR;
+ }
return 0;
}
@@ -1491,8 +1533,8 @@ static int read_compound(FILE *fd, slang_T *slang, int len)
// Returns SP_*ERROR flags when there is something wrong.
static int set_sofo(slang_T *lp, char_u *from, char_u *to)
{
- char_u *s;
- char_u *p;
+ char_u *s;
+ char_u *p;
// Use "sl_sal" as an array with 256 pointers to a list of wide
// characters. The index is the low byte of the character.
@@ -1554,10 +1596,10 @@ static int set_sofo(slang_T *lp, char_u *from, char_u *to)
// Fill the first-index table for "lp".
static void set_sal_first(slang_T *lp)
{
- salfirst_T *sfirst;
- salitem_T *smp;
+ salfirst_T *sfirst;
+ salitem_T *smp;
int c;
- garray_T *gap = &lp->sl_sal;
+ garray_T *gap = &lp->sl_sal;
sfirst = lp->sl_sal_first;
for (int i = 0; i < 256; ++i) {
@@ -1613,24 +1655,21 @@ static int *mb_str2wide(char_u *s)
return res;
}
-// Reads a tree from the .spl or .sug file.
-// Allocates the memory and stores pointers in "bytsp" and "idxsp".
-// This is skipped when the tree has zero length.
-// Returns zero when OK, SP_ value for an error.
-static int
-spell_read_tree (
- FILE *fd,
- char_u **bytsp,
- long *bytsp_len,
- idx_T **idxsp,
- bool prefixtree, // true for the prefix tree
- int prefixcnt // when "prefixtree" is true: prefix count
-)
+/// Reads a tree from the .spl or .sug file.
+/// Allocates the memory and stores pointers in "bytsp" and "idxsp".
+/// This is skipped when the tree has zero length.
+///
+/// @param prefixtree true for the prefix tree
+/// @param prefixcnt when "prefixtree" is true: prefix count
+///
+/// @return zero when OK, SP_ value for an error.
+static int spell_read_tree(FILE *fd, char_u **bytsp, long *bytsp_len, idx_T **idxsp,
+ bool prefixtree, int prefixcnt)
FUNC_ATTR_NONNULL_ARG(1, 2, 4)
{
int idx;
- char_u *bp;
- idx_T *ip;
+ char_u *bp;
+ idx_T *ip;
// The tree size was computed when writing the file, so that we can
// allocate it as one long block. <nodecount>
@@ -1656,30 +1695,28 @@ spell_read_tree (
// Recursively read the tree and store it in the array.
idx = read_tree_node(fd, bp, ip, len, 0, prefixtree, prefixcnt);
- if (idx < 0)
+ if (idx < 0) {
return idx;
+ }
}
return 0;
}
-// Read one row of siblings from the spell file and store it in the byte array
-// "byts" and index array "idxs". Recursively read the children.
-//
-// NOTE: The code here must match put_node()!
-//
-// Returns the index (>= 0) following the siblings.
-// Returns SP_TRUNCERROR if the file is shorter than expected.
-// Returns SP_FORMERROR if there is a format error.
-static idx_T
-read_tree_node (
- FILE *fd,
- char_u *byts,
- idx_T *idxs,
- int maxidx, // size of arrays
- idx_T startidx, // current index in "byts" and "idxs"
- bool prefixtree, // true for reading PREFIXTREE
- int maxprefcondnr // maximum for <prefcondnr>
-)
+/// Read one row of siblings from the spell file and store it in the byte array
+/// "byts" and index array "idxs". Recursively read the children.
+///
+/// NOTE: The code here must match put_node()!
+///
+/// Returns the index (>= 0) following the siblings.
+/// Returns SP_TRUNCERROR if the file is shorter than expected.
+/// Returns SP_FORMERROR if there is a format error.
+///
+/// @param maxidx size of arrays
+/// @param startidx current index in "byts" and "idxs"
+/// @param prefixtree true for reading PREFIXTREE
+/// @param maxprefcondnr maximum for <prefcondnr>
+static idx_T read_tree_node(FILE *fd, char_u *byts, idx_T *idxs, int maxidx, idx_T startidx,
+ bool prefixtree, int maxprefcondnr)
{
int len;
int i;
@@ -1690,18 +1727,21 @@ read_tree_node (
#define SHARED_MASK 0x8000000
len = getc(fd); // <siblingcount>
- if (len <= 0)
+ if (len <= 0) {
return SP_TRUNCERROR;
+ }
- if (startidx + len >= maxidx)
+ if (startidx + len >= maxidx) {
return SP_FORMERROR;
+ }
byts[idx++] = len;
// Read the byte values, flag/region bytes and shared indexes.
for (i = 1; i <= len; ++i) {
c = getc(fd); // <byte>
- if (c < 0)
+ if (c < 0) {
return SP_TRUNCERROR;
+ }
if (c <= BY_SPECIAL) {
if (c == BY_NOFLAGS && !prefixtree) {
// No flags, all regions.
@@ -1712,16 +1752,18 @@ read_tree_node (
// condition nr. In idxs[] store the prefix ID in the low
// byte, the condition index shifted up 8 bits, the flags
// shifted up 24 bits.
- if (c == BY_FLAGS)
+ if (c == BY_FLAGS) {
c = getc(fd) << 24; // <pflags>
- else
+ } else {
c = 0;
+ }
c |= getc(fd); // <affixID>
n = get2c(fd); // <prefcondnr>
- if (n >= maxprefcondnr)
+ if (n >= maxprefcondnr) {
return SP_FORMERROR;
+ }
c |= (n << 8);
} else { // c must be BY_FLAGS or BY_FLAGS2
// Read flags and optional region and prefix ID. In
@@ -1729,21 +1771,25 @@ read_tree_node (
// that and prefix ID above the region.
c2 = c;
c = getc(fd); // <flags>
- if (c2 == BY_FLAGS2)
+ if (c2 == BY_FLAGS2) {
c = (getc(fd) << 8) + c; // <flags2>
- if (c & WF_REGION)
+ }
+ if (c & WF_REGION) {
c = (getc(fd) << 16) + c; // <region>
- if (c & WF_AFX)
+ }
+ if (c & WF_AFX) {
c = (getc(fd) << 24) + c; // <affixID>
+ }
}
idxs[idx] = c;
c = 0;
- } else { // c == BY_INDEX
+ } else { // c == BY_INDEX
// <nodeidx>
n = get3c(fd);
- if (n < 0 || n >= maxidx)
+ if (n < 0 || n >= maxidx) {
return SP_FORMERROR;
+ }
idxs[idx] = n + SHARED_MASK;
c = getc(fd); // <xbyte>
}
@@ -1754,38 +1800,39 @@ read_tree_node (
// Recursively read the children for non-shared siblings.
// Skip the end-of-word ones (zero byte value) and the shared ones (and
// remove SHARED_MASK)
- for (i = 1; i <= len; ++i)
+ for (i = 1; i <= len; ++i) {
if (byts[startidx + i] != 0) {
- if (idxs[startidx + i] & SHARED_MASK)
+ if (idxs[startidx + i] & SHARED_MASK) {
idxs[startidx + i] &= ~SHARED_MASK;
- else {
+ } else {
idxs[startidx + i] = idx;
idx = read_tree_node(fd, byts, idxs, maxidx, idx,
- prefixtree, maxprefcondnr);
- if (idx < 0)
+ prefixtree, maxprefcondnr);
+ if (idx < 0) {
break;
+ }
}
}
+ }
return idx;
}
-// Reload the spell file "fname" if it's loaded.
-static void
-spell_reload_one (
- char_u *fname,
- bool added_word // invoked through "zg"
-)
+/// Reload the spell file "fname" if it's loaded.
+///
+/// @param added_word invoked through "zg"
+static void spell_reload_one(char_u *fname, bool added_word)
{
- slang_T *slang;
+ slang_T *slang;
bool didit = false;
for (slang = first_lang; slang != NULL; slang = slang->sl_next) {
if (path_full_compare(fname, slang->sl_fname, false, true) == kEqualFiles) {
slang_clear(slang);
- if (spell_load_file(fname, NULL, slang, false) == NULL)
+ if (spell_load_file(fname, NULL, slang, false) == NULL) {
// reloading failed, clear the language
slang_clear(slang);
+ }
redraw_all_later(SOME_VALID);
didit = true;
}
@@ -1793,8 +1840,9 @@ spell_reload_one (
// When "zg" was used and the file wasn't loaded yet, should redo
// 'spelllang' to load it now.
- if (added_word && !didit)
+ if (added_word && !didit) {
did_set_spelllang(curwin);
+ }
}
// Functions for ":mkspell".
@@ -1820,13 +1868,14 @@ static long compress_added = 500000; // word count
// Sets "sps_flags".
int spell_check_msm(void)
{
- char_u *p = p_msm;
+ char_u *p = p_msm;
long start = 0;
long incr = 0;
long added = 0;
- if (!ascii_isdigit(*p))
+ if (!ascii_isdigit(*p)) {
return FAIL;
+ }
// block count = (value * 1024) / SBLOCKSIZE (but avoid overflow)
start = (getdigits_long(&p, true, 0) * 10) / (SBLOCKSIZE / 102);
if (*p != ',') {
@@ -1864,11 +1913,12 @@ int spell_check_msm(void)
// readable format, so that we can see what happens when adding a word and/or
// compressing the tree.
// Based on code from Olaf Seibert.
-#define PRINTLINESIZE 1000
-#define PRINTWIDTH 6
+# define PRINTLINESIZE 1000
+# define PRINTWIDTH 6
-#define PRINTSOME(l, depth, fmt, a1, a2) vim_snprintf(l + depth * PRINTWIDTH, \
- PRINTLINESIZE - PRINTWIDTH * depth, fmt, a1, a2)
+# define PRINTSOME(l, depth, fmt, a1, a2) vim_snprintf(l + depth * PRINTWIDTH, \
+ PRINTLINESIZE - PRINTWIDTH * depth, fmt, a1, \
+ a2)
static char line1[PRINTLINESIZE];
static char line2[PRINTLINESIZE];
@@ -1876,7 +1926,7 @@ static char line3[PRINTLINESIZE];
static void spell_clear_flags(wordnode_T *node)
{
- wordnode_T *np;
+ wordnode_T *np;
for (np = node; np != NULL; np = np->wn_sibling) {
np->wn_u1.index = FALSE;
@@ -1898,20 +1948,23 @@ static void spell_print_node(wordnode_T *node, int depth)
node->wn_u1.index = TRUE;
if (node->wn_byte != NUL) {
- if (node->wn_child != NULL)
+ if (node->wn_child != NULL) {
PRINTSOME(line1, depth, " %c -> ", node->wn_byte, 0);
- else
+ } else {
// Cannot happen?
PRINTSOME(line1, depth, " %c ???", node->wn_byte, 0);
- } else
+ }
+ } else {
PRINTSOME(line1, depth, " $ ", 0, 0);
+ }
PRINTSOME(line2, depth, "%d/%d ", node->wn_nr, node->wn_refs);
- if (node->wn_sibling != NULL)
+ if (node->wn_sibling != NULL) {
PRINTSOME(line3, depth, " | ", 0, 0);
- else
+ } else {
PRINTSOME(line3, depth, " ", 0, 0);
+ }
if (node->wn_byte == NUL) {
msg((char_u *)line1);
@@ -1920,8 +1973,9 @@ static void spell_print_node(wordnode_T *node, int depth)
}
// do the children
- if (node->wn_byte != NUL && node->wn_child != NULL)
+ if (node->wn_byte != NUL && node->wn_child != NULL) {
spell_print_node(node->wn_child, depth + 1);
+ }
// do the siblings
if (node->wn_sibling != NULL) {
@@ -1951,39 +2005,39 @@ static void spell_print_tree(wordnode_T *root)
// Returns an afffile_T, NULL for complete failure.
static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
{
- FILE *fd;
+ FILE *fd;
char_u rline[MAXLINELEN];
- char_u *line;
- char_u *pc = NULL;
+ char_u *line;
+ char_u *pc = NULL;
#define MAXITEMCNT 30
- char_u *(items[MAXITEMCNT]);
+ char_u *(items[MAXITEMCNT]);
int itemcnt;
- char_u *p;
+ char_u *p;
int lnum = 0;
affheader_T *cur_aff = NULL;
bool did_postpone_prefix = false;
int aff_todo = 0;
- hashtab_T *tp;
- char_u *low = NULL;
- char_u *fol = NULL;
- char_u *upp = NULL;
+ hashtab_T *tp;
+ char_u *low = NULL;
+ char_u *fol = NULL;
+ char_u *upp = NULL;
int do_rep;
int do_repsal;
int do_sal;
int do_mapline;
bool found_map = false;
- hashitem_T *hi;
+ hashitem_T *hi;
int l;
int compminlen = 0; // COMPOUNDMIN value
int compsylmax = 0; // COMPOUNDSYLMAX value
int compoptions = 0; // COMP_ flags
int compmax = 0; // COMPOUNDWORDMAX value
- char_u *compflags = NULL; // COMPOUNDFLAG and COMPOUNDRULE
- // concatenated
- char_u *midword = NULL; // MIDWORD value
- char_u *syllable = NULL; // SYLLABLE value
- char_u *sofofrom = NULL; // SOFOFROM value
- char_u *sofoto = NULL; // SOFOTO value
+ char_u *compflags = NULL; // COMPOUNDFLAG and COMPOUNDRULE
+ // concatenated
+ char_u *midword = NULL; // MIDWORD value
+ char_u *syllable = NULL; // SYLLABLE value
+ char_u *sofofrom = NULL; // SOFOFROM value
+ char_u *sofoto = NULL; // SOFOTO value
// Open the file.
fd = os_fopen((char *)fname, "r");
@@ -2019,8 +2073,9 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
++lnum;
// Skip comment lines.
- if (*rline == '#')
+ if (*rline == '#') {
continue;
+ }
// Convert from "SET" to 'encoding' when needed.
xfree(pc);
@@ -2041,22 +2096,29 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
// item.
itemcnt = 0;
for (p = line;; ) {
- while (*p != NUL && *p <= ' ') // skip white space and CR/NL
+ while (*p != NUL && *p <= ' ') { // skip white space and CR/NL
++p;
- if (*p == NUL)
+ }
+ if (*p == NUL) {
break;
- if (itemcnt == MAXITEMCNT) // too many items
+ }
+ if (itemcnt == MAXITEMCNT) { // too many items
break;
+ }
items[itemcnt++] = p;
// A few items have arbitrary text argument, don't split them.
- if (itemcnt == 2 && spell_info_item(items[0]))
- while (*p >= ' ' || *p == TAB) // skip until CR/NL
+ if (itemcnt == 2 && spell_info_item(items[0])) {
+ while (*p >= ' ' || *p == TAB) { // skip until CR/NL
++p;
- else
- while (*p > ' ') // skip until white space or CR/NL
+ }
+ } else {
+ while (*p > ' ') { // skip until white space or CR/NL
++p;
- if (*p == NUL)
+ }
+ }
+ if (*p == NUL) {
break;
+ }
*p++ = NUL;
}
@@ -2067,21 +2129,23 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
aff->af_enc = enc_canonize(items[1]);
if (!spin->si_ascii
&& convert_setup(&spin->si_conv, aff->af_enc,
- p_enc) == FAIL)
+ p_enc) == FAIL) {
smsg(_("Conversion in %s not supported: from %s to %s"),
fname, aff->af_enc, p_enc);
+ }
spin->si_conv.vc_fail = true;
} else if (is_aff_rule(items, itemcnt, "FLAG", 2)
&& aff->af_flagtype == AFT_CHAR) {
- if (STRCMP(items[1], "long") == 0)
+ if (STRCMP(items[1], "long") == 0) {
aff->af_flagtype = AFT_LONG;
- else if (STRCMP(items[1], "num") == 0)
+ } else if (STRCMP(items[1], "num") == 0) {
aff->af_flagtype = AFT_NUM;
- else if (STRCMP(items[1], "caplong") == 0)
+ } else if (STRCMP(items[1], "caplong") == 0) {
aff->af_flagtype = AFT_CAPLONG;
- else
+ } else {
smsg(_("Invalid value for FLAG in %s line %d: %s"),
fname, lnum, items[1]);
+ }
if (aff->af_rare != 0
|| aff->af_keepcase != 0
|| aff->af_bad != 0
@@ -2092,10 +2156,11 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
|| aff->af_nosuggest != 0
|| compflags != NULL
|| aff->af_suff.ht_used > 0
- || aff->af_pref.ht_used > 0)
+ || aff->af_pref.ht_used > 0) {
smsg(_("FLAG after using flags in %s line %d: %s"),
fname, lnum, items[1]);
- } else if (spell_info_item(items[0]) && itemcnt > 1) {
+ }
+ } else if (spell_info_item(items[0]) && itemcnt > 1) {
p = getroom(spin,
(spin->si_info == NULL ? 0 : STRLEN(spin->si_info))
+ STRLEN(items[0])
@@ -2111,7 +2176,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
} else if (is_aff_rule(items, itemcnt, "MIDWORD", 2)
&& midword == NULL) {
midword = getroom_save(spin, items[1]);
- } else if (is_aff_rule(items, itemcnt, "TRY", 2)) {
+ } else if (is_aff_rule(items, itemcnt, "TRY", 2)) {
// ignored, we look in the tree for what chars may appear
}
// TODO: remove "RAR" later
@@ -2119,54 +2184,56 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
|| is_aff_rule(items, itemcnt, "RARE", 2))
&& aff->af_rare == 0) {
aff->af_rare = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
+ fname, lnum);
}
// TODO: remove "KEP" later
else if ((is_aff_rule(items, itemcnt, "KEP", 2)
|| is_aff_rule(items, itemcnt, "KEEPCASE", 2))
&& aff->af_keepcase == 0) {
aff->af_keepcase = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
+ fname, lnum);
} else if ((is_aff_rule(items, itemcnt, "BAD", 2)
|| is_aff_rule(items, itemcnt, "FORBIDDENWORD", 2))
&& aff->af_bad == 0) {
aff->af_bad = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
+ fname, lnum);
} else if (is_aff_rule(items, itemcnt, "NEEDAFFIX", 2)
&& aff->af_needaffix == 0) {
aff->af_needaffix = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
+ fname, lnum);
} else if (is_aff_rule(items, itemcnt, "CIRCUMFIX", 2)
&& aff->af_circumfix == 0) {
aff->af_circumfix = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
+ fname, lnum);
} else if (is_aff_rule(items, itemcnt, "NOSUGGEST", 2)
&& aff->af_nosuggest == 0) {
aff->af_nosuggest = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
+ fname, lnum);
} else if ((is_aff_rule(items, itemcnt, "NEEDCOMPOUND", 2)
|| is_aff_rule(items, itemcnt, "ONLYINCOMPOUND", 2))
&& aff->af_needcomp == 0) {
aff->af_needcomp = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
+ fname, lnum);
} else if (is_aff_rule(items, itemcnt, "COMPOUNDROOT", 2)
&& aff->af_comproot == 0) {
aff->af_comproot = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
+ fname, lnum);
} else if (is_aff_rule(items, itemcnt, "COMPOUNDFORBIDFLAG", 2)
&& aff->af_compforbid == 0) {
aff->af_compforbid = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- if (aff->af_pref.ht_used > 0)
+ fname, lnum);
+ if (aff->af_pref.ht_used > 0) {
smsg(_("Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line %d"),
fname, lnum);
+ }
} else if (is_aff_rule(items, itemcnt, "COMPOUNDPERMITFLAG", 2)
&& aff->af_comppermit == 0) {
aff->af_comppermit = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- if (aff->af_pref.ht_used > 0)
+ fname, lnum);
+ if (aff->af_pref.ht_used > 0) {
smsg(_("Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line %d"),
fname, lnum);
+ }
} else if (is_aff_rule(items, itemcnt, "COMPOUNDFLAG", 2)
&& compflags == NULL) {
// Turn flag "c" into COMPOUNDRULE compatible string "c+",
@@ -2175,20 +2242,22 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
STRCPY(p, items[1]);
STRCAT(p, "+");
compflags = p;
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULES", 2)) {
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULES", 2)) {
// We don't use the count, but do check that it's a number and
// not COMPOUNDRULE mistyped.
- if (atoi((char *)items[1]) == 0)
+ if (atoi((char *)items[1]) == 0) {
smsg(_("Wrong COMPOUNDRULES value in %s line %d: %s"),
fname, lnum, items[1]);
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULE", 2)) {
+ }
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULE", 2)) {
// Don't use the first rule if it is a number.
if (compflags != NULL || *skipdigits(items[1]) != NUL) {
// Concatenate this string to previously defined ones,
// using a slash to separate them.
l = (int)STRLEN(items[1]) + 1;
- if (compflags != NULL)
+ if (compflags != NULL) {
l += (int)STRLEN(compflags) + 1;
+ }
p = getroom(spin, l, false);
if (compflags != NULL) {
STRCPY(p, compflags);
@@ -2200,43 +2269,49 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
} else if (is_aff_rule(items, itemcnt, "COMPOUNDWORDMAX", 2)
&& compmax == 0) {
compmax = atoi((char *)items[1]);
- if (compmax == 0)
+ if (compmax == 0) {
smsg(_("Wrong COMPOUNDWORDMAX value in %s line %d: %s"),
fname, lnum, items[1]);
+ }
} else if (is_aff_rule(items, itemcnt, "COMPOUNDMIN", 2)
&& compminlen == 0) {
compminlen = atoi((char *)items[1]);
- if (compminlen == 0)
+ if (compminlen == 0) {
smsg(_("Wrong COMPOUNDMIN value in %s line %d: %s"),
fname, lnum, items[1]);
+ }
} else if (is_aff_rule(items, itemcnt, "COMPOUNDSYLMAX", 2)
&& compsylmax == 0) {
compsylmax = atoi((char *)items[1]);
- if (compsylmax == 0)
+ if (compsylmax == 0) {
smsg(_("Wrong COMPOUNDSYLMAX value in %s line %d: %s"),
fname, lnum, items[1]);
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDDUP", 1)) {
+ }
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDDUP", 1)) {
compoptions |= COMP_CHECKDUP;
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDREP", 1)) {
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDREP", 1)) {
compoptions |= COMP_CHECKREP;
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDCASE", 1)) {
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDCASE", 1)) {
compoptions |= COMP_CHECKCASE;
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDTRIPLE", 1)) {
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDTRIPLE", 1)) {
compoptions |= COMP_CHECKTRIPLE;
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 2)) {
- if (atoi((char *)items[1]) == 0)
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 2)) {
+ if (atoi((char *)items[1]) == 0) {
smsg(_("Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"),
fname, lnum, items[1]);
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 3)) {
- garray_T *gap = &spin->si_comppat;
+ }
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 3)) {
+ garray_T *gap = &spin->si_comppat;
int i;
// Only add the couple if it isn't already there.
- for (i = 0; i < gap->ga_len - 1; i += 2)
+ for (i = 0; i < gap->ga_len - 1; i += 2) {
if (STRCMP(((char_u **)(gap->ga_data))[i], items[1]) == 0
&& STRCMP(((char_u **)(gap->ga_data))[i + 1],
- items[2]) == 0)
+ items[2]) == 0) {
break;
+ }
+ }
if (i >= gap->ga_len) {
ga_grow(gap, 2);
((char_u **)(gap->ga_data))[gap->ga_len++]
@@ -2247,15 +2322,15 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
} else if (is_aff_rule(items, itemcnt, "SYLLABLE", 2)
&& syllable == NULL) {
syllable = getroom_save(spin, items[1]);
- } else if (is_aff_rule(items, itemcnt, "NOBREAK", 1)) {
+ } else if (is_aff_rule(items, itemcnt, "NOBREAK", 1)) {
spin->si_nobreak = true;
- } else if (is_aff_rule(items, itemcnt, "NOSPLITSUGS", 1)) {
+ } else if (is_aff_rule(items, itemcnt, "NOSPLITSUGS", 1)) {
spin->si_nosplitsugs = true;
} else if (is_aff_rule(items, itemcnt, "NOCOMPOUNDSUGS", 1)) {
spin->si_nocompoundsugs = true;
- } else if (is_aff_rule(items, itemcnt, "NOSUGFILE", 1)) {
+ } else if (is_aff_rule(items, itemcnt, "NOSUGFILE", 1)) {
spin->si_nosugfile = true;
- } else if (is_aff_rule(items, itemcnt, "PFXPOSTPONE", 1)) {
+ } else if (is_aff_rule(items, itemcnt, "PFXPOSTPONE", 1)) {
aff->af_pfxpostpone = true;
} else if (is_aff_rule(items, itemcnt, "IGNOREEXTRA", 1)) {
aff->af_ignoreextra = true;
@@ -2266,10 +2341,11 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
int lasti = 4;
char_u key[AH_KEY_LEN];
- if (*items[0] == 'P')
+ if (*items[0] == 'P') {
tp = &aff->af_pref;
- else
+ } else {
tp = &aff->af_suff;
+ }
// Myspell allows the same affix name to be used multiple
// times. The affix files that do this have an undocumented
@@ -2279,12 +2355,14 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
hi = hash_find(tp, key);
if (!HASHITEM_EMPTY(hi)) {
cur_aff = HI2AH(hi);
- if (cur_aff->ah_combine != (*items[2] == 'Y'))
+ if (cur_aff->ah_combine != (*items[2] == 'Y')) {
smsg(_("Different combining flag in continued affix block in %s line %d: %s"),
fname, lnum, items[1]);
- if (!cur_aff->ah_follows)
+ }
+ if (!cur_aff->ah_follows) {
smsg(_("Duplicate affix in %s line %d: %s"),
fname, lnum, items[1]);
+ }
} else {
// New affix letter.
cur_aff = getroom(spin, sizeof(*cur_aff), true);
@@ -2317,20 +2395,23 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
if (itemcnt > lasti && STRCMP(items[lasti], "S") == 0) {
++lasti;
cur_aff->ah_follows = true;
- } else
+ } else {
cur_aff->ah_follows = false;
+ }
// Myspell allows extra text after the item, but that might
// mean mistakes go unnoticed. Require a comment-starter,
// unless IGNOREEXTRA is used. Hunspell uses a "-" item.
if (itemcnt > lasti
&& !aff->af_ignoreextra
- && *items[lasti] != '#')
+ && *items[lasti] != '#') {
smsg(_(e_afftrailing), fname, lnum, items[lasti]);
+ }
- if (STRCMP(items[2], "Y") != 0 && STRCMP(items[2], "N") != 0)
+ if (STRCMP(items[2], "Y") != 0 && STRCMP(items[2], "N") != 0) {
smsg(_("Expected Y or N in %s line %d: %s"),
- fname, lnum, items[2]);
+ fname, lnum, items[2]);
+ }
if (*items[0] == 'P' && aff->af_pfxpostpone) {
if (cur_aff->ah_newID == 0) {
@@ -2343,9 +2424,10 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
// postponed. We know that only after handling all
// the items.
did_postpone_prefix = false;
- } else
+ } else {
// Did use the ID in a previous block.
did_postpone_prefix = true;
+ }
}
aff_todo = atoi((char *)items[3]);
@@ -2354,7 +2436,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
&& aff_todo > 0
&& STRCMP(cur_aff->ah_key, items[1]) == 0
&& itemcnt >= 5) {
- affentry_T *aff_entry;
+ affentry_T *aff_entry;
bool upper = false;
int lasti = 5;
@@ -2363,15 +2445,17 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
// Hunspell uses a "-" item.
if (itemcnt > lasti && *items[lasti] != '#'
&& (STRCMP(items[lasti], "-") != 0
- || itemcnt != lasti + 1))
+ || itemcnt != lasti + 1)) {
smsg(_(e_afftrailing), fname, lnum, items[lasti]);
+ }
// New item for an affix letter.
aff_todo--;
aff_entry = getroom(spin, sizeof(*aff_entry), true);
- if (STRCMP(items[2], "0") != 0)
+ if (STRCMP(items[2], "0") != 0) {
aff_entry->ae_chop = getroom_save(spin, items[2]);
+ }
if (STRCMP(items[3], "0") != 0) {
aff_entry->ae_add = getroom_save(spin, items[3]);
@@ -2394,15 +2478,17 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
char_u buf[MAXLINELEN];
aff_entry->ae_cond = getroom_save(spin, items[4]);
- if (*items[0] == 'P')
+ if (*items[0] == 'P') {
sprintf((char *)buf, "^%s", items[4]);
- else
+ } else {
sprintf((char *)buf, "%s$", items[4]);
+ }
aff_entry->ae_prog = vim_regcomp(buf,
- RE_MAGIC + RE_STRING + RE_STRICT);
- if (aff_entry->ae_prog == NULL)
+ RE_MAGIC + RE_STRING + RE_STRICT);
+ if (aff_entry->ae_prog == NULL) {
smsg(_("Broken condition in %s line %d: %s"),
fname, lnum, items[4]);
+ }
}
// For postponed prefixes we need an entry in si_prefcond
@@ -2418,9 +2504,8 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
// be empty or start with the same letter.
if (aff_entry->ae_chop != NULL
&& aff_entry->ae_add != NULL
- && aff_entry->ae_chop[(*mb_ptr2len)(
- aff_entry->ae_chop)] == NUL
- ) {
+ && aff_entry->ae_chop[(*mb_ptr2len)(aff_entry->ae_chop)] ==
+ NUL) {
int c, c_up;
c = PTR2CHAR(aff_entry->ae_chop);
@@ -2445,10 +2530,9 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
aff_entry->ae_cond = getroom_save(spin, buf);
if (aff_entry->ae_cond != NULL) {
sprintf((char *)buf, "^%s",
- aff_entry->ae_cond);
+ aff_entry->ae_cond);
vim_regfree(aff_entry->ae_prog);
- aff_entry->ae_prog = vim_regcomp(
- buf, RE_MAGIC + RE_STRING);
+ aff_entry->ae_prog = vim_regcomp(buf, RE_MAGIC + RE_STRING);
}
}
}
@@ -2457,43 +2541,49 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
if (aff_entry->ae_chop == NULL) {
int idx;
- char_u **pp;
+ char_u **pp;
int n;
// Find a previously used condition.
for (idx = spin->si_prefcond.ga_len - 1; idx >= 0;
--idx) {
p = ((char_u **)spin->si_prefcond.ga_data)[idx];
- if (str_equal(p, aff_entry->ae_cond))
+ if (str_equal(p, aff_entry->ae_cond)) {
break;
+ }
}
if (idx < 0) {
// Not found, add a new condition.
idx = spin->si_prefcond.ga_len;
pp = GA_APPEND_VIA_PTR(char_u *, &spin->si_prefcond);
*pp = (aff_entry->ae_cond == NULL) ?
- NULL : getroom_save(spin, aff_entry->ae_cond);
+ NULL : getroom_save(spin, aff_entry->ae_cond);
}
// Add the prefix to the prefix tree.
- if (aff_entry->ae_add == NULL)
+ if (aff_entry->ae_add == NULL) {
p = (char_u *)"";
- else
+ } else {
p = aff_entry->ae_add;
+ }
// PFX_FLAGS is a negative number, so that
// tree_add_word() knows this is the prefix tree.
n = PFX_FLAGS;
- if (!cur_aff->ah_combine)
+ if (!cur_aff->ah_combine) {
n |= WFP_NC;
- if (upper)
+ }
+ if (upper) {
n |= WFP_UP;
- if (aff_entry->ae_comppermit)
+ }
+ if (aff_entry->ae_comppermit) {
n |= WFP_COMPPERMIT;
- if (aff_entry->ae_compforbid)
+ }
+ if (aff_entry->ae_compforbid) {
n |= WFP_COMPFORBID;
+ }
tree_add_word(spin, p, spin->si_prefroot, n,
- idx, cur_aff->ah_newID);
+ idx, cur_aff->ah_newID);
did_postpone_prefix = true;
}
@@ -2504,26 +2594,28 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
}
}
}
- } else if (is_aff_rule(items, itemcnt, "FOL", 2) && fol == NULL) {
+ } else if (is_aff_rule(items, itemcnt, "FOL", 2) && fol == NULL) {
fol = vim_strsave(items[1]);
- } else if (is_aff_rule(items, itemcnt, "LOW", 2) && low == NULL) {
+ } else if (is_aff_rule(items, itemcnt, "LOW", 2) && low == NULL) {
low = vim_strsave(items[1]);
- } else if (is_aff_rule(items, itemcnt, "UPP", 2) && upp == NULL) {
+ } else if (is_aff_rule(items, itemcnt, "UPP", 2) && upp == NULL) {
upp = vim_strsave(items[1]);
} else if (is_aff_rule(items, itemcnt, "REP", 2)
|| is_aff_rule(items, itemcnt, "REPSAL", 2)) {
- /* Ignore REP/REPSAL count */;
- if (!isdigit(*items[1]))
+ // Ignore REP/REPSAL count
+ if (!isdigit(*items[1])) {
smsg(_("Expected REP(SAL) count in %s line %d"),
fname, lnum);
+ }
} else if ((STRCMP(items[0], "REP") == 0
|| STRCMP(items[0], "REPSAL") == 0)
&& itemcnt >= 3) {
// REP/REPSAL item
// Myspell ignores extra arguments, we require it starts with
// # to detect mistakes.
- if (itemcnt > 3 && items[3][0] != '#')
+ if (itemcnt > 3 && items[3][0] != '#') {
smsg(_(e_afftrailing), fname, lnum, items[3]);
+ }
if (items[0][3] == 'S' ? do_repsal : do_rep) {
// Replace underscore with space (can't include a space
// directly).
@@ -2541,15 +2633,16 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
? &spin->si_repsal
: &spin->si_rep, items[1], items[2]);
}
- } else if (is_aff_rule(items, itemcnt, "MAP", 2)) {
+ } else if (is_aff_rule(items, itemcnt, "MAP", 2)) {
// MAP item or count
if (!found_map) {
// First line contains the count.
found_map = true;
- if (!isdigit(*items[1]))
+ if (!isdigit(*items[1])) {
smsg(_("Expected MAP count in %s line %d"),
fname, lnum);
- } else if (do_mapline) {
+ }
+ } else if (do_mapline) {
int c;
// Check that every character appears only once.
@@ -2566,7 +2659,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
// We simply concatenate all the MAP strings, separated by
// slashes.
- ga_concat(&spin->si_map, items[1]);
+ ga_concat(&spin->si_map, (char *)items[1]);
ga_append(&spin->si_map, '/');
}
}
@@ -2575,17 +2668,18 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
if (do_sal) {
// SAL item (sounds-a-like)
// Either one of the known keys or a from-to pair.
- if (STRCMP(items[1], "followup") == 0)
+ if (STRCMP(items[1], "followup") == 0) {
spin->si_followup = sal_to_bool(items[2]);
- else if (STRCMP(items[1], "collapse_result") == 0)
+ } else if (STRCMP(items[1], "collapse_result") == 0) {
spin->si_collapse = sal_to_bool(items[2]);
- else if (STRCMP(items[1], "remove_accents") == 0)
+ } else if (STRCMP(items[1], "remove_accents") == 0) {
spin->si_rem_accents = sal_to_bool(items[2]);
- else
+ } else {
// when "to" is "_" it means empty
add_fromto(spin, &spin->si_sal, items[1],
- STRCMP(items[2], "_") == 0 ? (char_u *)""
- : items[2]);
+ STRCMP(items[2], "_") == 0 ? (char_u *)""
+ : items[2]);
+ }
}
} else if (is_aff_rule(items, itemcnt, "SOFOFROM", 2)
&& sofofrom == NULL) {
@@ -2593,19 +2687,20 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
} else if (is_aff_rule(items, itemcnt, "SOFOTO", 2)
&& sofoto == NULL) {
sofoto = getroom_save(spin, items[1]);
- } else if (STRCMP(items[0], "COMMON") == 0) {
+ } else if (STRCMP(items[0], "COMMON") == 0) {
int i;
for (i = 1; i < itemcnt; ++i) {
if (HASHITEM_EMPTY(hash_find(&spin->si_commonwords,
- items[i]))) {
+ items[i]))) {
p = vim_strsave(items[i]);
hash_add(&spin->si_commonwords, p);
}
}
- } else
+ } else {
smsg(_("Unrecognized or duplicate item in %s line %d: %s"),
fname, lnum, items[0]);
+ }
}
}
@@ -2646,17 +2741,19 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
spin->si_compoptions |= compoptions;
}
- if (compflags != NULL)
+ if (compflags != NULL) {
process_compflags(spin, aff, compflags);
+ }
// Check that we didn't use too many renumbered flags.
if (spin->si_newcompID < spin->si_newprefID) {
- if (spin->si_newcompID == 127 || spin->si_newcompID == 255)
+ if (spin->si_newcompID == 127 || spin->si_newcompID == 255) {
MSG(_("Too many postponed prefixes"));
- else if (spin->si_newprefID == 0 || spin->si_newprefID == 127)
+ } else if (spin->si_newprefID == 0 || spin->si_newprefID == 127) {
MSG(_("Too many compound flags"));
- else
+ } else {
MSG(_("Too many postponed prefixes and/or compound flags"));
+ }
}
if (syllable != NULL) {
@@ -2665,12 +2762,12 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
}
if (sofofrom != NULL || sofoto != NULL) {
- if (sofofrom == NULL || sofoto == NULL)
+ if (sofofrom == NULL || sofoto == NULL) {
smsg(_("Missing SOFO%s line in %s"),
sofofrom == NULL ? "FROM" : "TO", fname);
- else if (!GA_EMPTY(&spin->si_sal))
+ } else if (!GA_EMPTY(&spin->si_sal)) {
smsg(_("Both SAL and SOFO lines in %s"), fname);
- else {
+ } else {
aff_check_string(spin->si_sofofr, sofofrom, "SOFOFROM");
aff_check_string(spin->si_sofoto, sofoto, "SOFOTO");
spin->si_sofofr = sofofrom;
@@ -2701,8 +2798,8 @@ static bool is_aff_rule(char_u **items, int itemcnt, char *rulename, int mincoun
// ae_flags to ae_comppermit and ae_compforbid.
static void aff_process_flags(afffile_T *affile, affentry_T *entry)
{
- char_u *p;
- char_u *prevp;
+ char_u *p;
+ char_u *prevp;
unsigned flag;
if (entry->ae_flags != NULL
@@ -2713,16 +2810,19 @@ static void aff_process_flags(afffile_T *affile, affentry_T *entry)
if (flag == affile->af_comppermit || flag == affile->af_compforbid) {
STRMOVE(prevp, p);
p = prevp;
- if (flag == affile->af_comppermit)
+ if (flag == affile->af_comppermit) {
entry->ae_comppermit = true;
- else
+ } else {
entry->ae_compforbid = true;
+ }
}
- if (affile->af_flagtype == AFT_NUM && *p == ',')
+ if (affile->af_flagtype == AFT_NUM && *p == ',') {
++p;
+ }
}
- if (*entry->ae_flags == NUL)
+ if (*entry->ae_flags == NUL) {
entry->ae_flags = NULL; // nothing left
+ }
}
}
@@ -2742,16 +2842,17 @@ static bool spell_info_item(char_u *s)
static unsigned affitem2flag(int flagtype, char_u *item, char_u *fname, int lnum)
{
unsigned res;
- char_u *p = item;
+ char_u *p = item;
res = get_affitem(flagtype, &p);
if (res == 0) {
- if (flagtype == AFT_NUM)
+ if (flagtype == AFT_NUM) {
smsg(_("Flag is not a number in %s line %d: %s"),
fname, lnum, item);
- else
+ } else {
smsg(_("Illegal flag in %s line %d: %s"),
fname, lnum, item);
+ }
}
if (*p != NUL) {
smsg(_(e_affname), fname, lnum, item);
@@ -2781,8 +2882,9 @@ static unsigned get_affitem(int flagtype, char_u **pp)
res = mb_ptr2char_adv((const char_u **)pp);
if (flagtype == AFT_LONG || (flagtype == AFT_CAPLONG
&& res >= 'A' && res <= 'Z')) {
- if (**pp == NUL)
+ if (**pp == NUL) {
return 0;
+ }
res = mb_ptr2char_adv((const char_u **)pp) + (res << 16);
}
}
@@ -2795,22 +2897,23 @@ static unsigned get_affitem(int flagtype, char_u **pp)
// they fit in one byte.
static void process_compflags(spellinfo_T *spin, afffile_T *aff, char_u *compflags)
{
- char_u *p;
- char_u *prevp;
+ char_u *p;
+ char_u *prevp;
unsigned flag;
- compitem_T *ci;
+ compitem_T *ci;
int id;
int len;
- char_u *tp;
+ char_u *tp;
char_u key[AH_KEY_LEN];
- hashitem_T *hi;
+ hashitem_T *hi;
// Make room for the old and the new compflags, concatenated with a / in
// between. Processing it makes it shorter, but we don't know by how
// much, thus allocate the maximum.
len = (int)STRLEN(compflags) + 1;
- if (spin->si_compflags != NULL)
+ if (spin->si_compflags != NULL) {
len += (int)STRLEN(spin->si_compflags) + 1;
+ }
p = getroom(spin, len, false);
if (spin->si_compflags != NULL) {
STRCPY(p, spin->si_compflags);
@@ -2820,10 +2923,10 @@ static void process_compflags(spellinfo_T *spin, afffile_T *aff, char_u *compfla
tp = p + STRLEN(p);
for (p = compflags; *p != NUL; ) {
- if (vim_strchr((char_u *)"/?*+[]", *p) != NULL)
+ if (vim_strchr((char_u *)"/?*+[]", *p) != NULL) {
// Copy non-flag characters directly.
*tp++ = *p++;
- else {
+ } else {
// First get the flag number, also checks validity.
prevp = p;
flag = get_affitem(aff->af_flagtype, &p);
@@ -2849,8 +2952,9 @@ static void process_compflags(spellinfo_T *spin, afffile_T *aff, char_u *compfla
}
*tp++ = id;
}
- if (aff->af_flagtype == AFT_NUM && *p == ',')
+ if (aff->af_flagtype == AFT_NUM && *p == ',') {
++p;
+ }
}
}
@@ -2872,7 +2976,7 @@ static void check_renumber(spellinfo_T *spin)
// Returns true if flag "flag" appears in affix list "afflist".
static bool flag_in_afflist(int flagtype, char_u *afflist, unsigned flag)
{
- char_u *p;
+ char_u *p;
unsigned n;
switch (flagtype) {
@@ -2916,25 +3020,28 @@ static bool flag_in_afflist(int flagtype, char_u *afflist, unsigned flag)
// Give a warning when "spinval" and "affval" numbers are set and not the same.
static void aff_check_number(int spinval, int affval, char *name)
{
- if (spinval != 0 && spinval != affval)
+ if (spinval != 0 && spinval != affval) {
smsg(_("%s value differs from what is used in another .aff file"),
name);
+ }
}
// Give a warning when "spinval" and "affval" strings are set and not the same.
static void aff_check_string(char_u *spinval, char_u *affval, char *name)
{
- if (spinval != NULL && STRCMP(spinval, affval) != 0)
+ if (spinval != NULL && STRCMP(spinval, affval) != 0) {
smsg(_("%s value differs from what is used in another .aff file"),
name);
+ }
}
// Returns true if strings "s1" and "s2" are equal. Also consider both being
// NULL as equal.
static bool str_equal(char_u *s1, char_u *s2)
{
- if (s1 == NULL || s2 == NULL)
+ if (s1 == NULL || s2 == NULL) {
return s1 == s2;
+ }
return STRCMP(s1, s2) == 0;
}
@@ -2960,11 +3067,11 @@ static bool sal_to_bool(char_u *s)
// Free the structure filled by spell_read_aff().
static void spell_free_aff(afffile_T *aff)
{
- hashtab_T *ht;
- hashitem_T *hi;
+ hashtab_T *ht;
+ hashitem_T *hi;
int todo;
affheader_T *ah;
- affentry_T *ae;
+ affentry_T *ae;
xfree(aff->af_enc);
@@ -2975,12 +3082,14 @@ static void spell_free_aff(afffile_T *aff)
if (!HASHITEM_EMPTY(hi)) {
--todo;
ah = HI2AH(hi);
- for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next)
+ for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next) {
vim_regfree(ae->ae_prog);
+ }
}
}
- if (ht == &aff->af_suff)
+ if (ht == &aff->af_suff) {
break;
+ }
}
hash_clear(&aff->af_pref);
@@ -2994,18 +3103,18 @@ static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile)
{
hashtab_T ht;
char_u line[MAXLINELEN];
- char_u *p;
- char_u *afflist;
+ char_u *p;
+ char_u *afflist;
char_u store_afflist[MAXWLEN];
int pfxlen;
bool need_affix;
- char_u *dw;
- char_u *pc;
- char_u *w;
+ char_u *dw;
+ char_u *pc;
+ char_u *w;
int l;
hash_T hash;
- hashitem_T *hi;
- FILE *fd;
+ hashitem_T *hi;
+ FILE *fd;
int lnum = 1;
int non_ascii = 0;
int retval = OK;
@@ -3042,16 +3151,18 @@ static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile)
while (!vim_fgets(line, MAXLINELEN, fd) && !got_int) {
line_breakcheck();
++lnum;
- if (line[0] == '#' || line[0] == '/')
+ if (line[0] == '#' || line[0] == '/') {
continue; // comment line
-
+ }
// Remove CR, LF and white space from the end. White space halfway through
// the word is kept to allow multi-word terms like "et al.".
l = (int)STRLEN(line);
- while (l > 0 && line[l - 1] <= ' ')
+ while (l > 0 && line[l - 1] <= ' ') {
--l;
- if (l == 0)
+ }
+ if (l == 0) {
continue; // empty line
+ }
line[l] = NUL;
// Convert from "SET" to 'encoding' when needed.
@@ -3117,15 +3228,17 @@ static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile)
hash = hash_hash(dw);
hi = hash_lookup(&ht, (const char *)dw, STRLEN(dw), hash);
if (!HASHITEM_EMPTY(hi)) {
- if (p_verbose > 0)
+ if (p_verbose > 0) {
smsg(_("Duplicate word in %s line %d: %s"),
fname, lnum, dw);
- else if (duplicate == 0)
+ } else if (duplicate == 0) {
smsg(_("First duplicate word in %s line %d: %s"),
fname, lnum, dw);
+ }
++duplicate;
- } else
+ } else {
hash_add_item(&ht, hi, dw, hash);
+ }
flags = 0;
store_afflist[0] = NUL;
@@ -3135,48 +3248,57 @@ static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile)
// Extract flags from the affix list.
flags |= get_affix_flags(affile, afflist);
- if (affile->af_needaffix != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_needaffix))
+ if (affile->af_needaffix != 0 &&
+ flag_in_afflist(affile->af_flagtype, afflist,
+ affile->af_needaffix)) {
need_affix = true;
+ }
- if (affile->af_pfxpostpone)
+ if (affile->af_pfxpostpone) {
// Need to store the list of prefix IDs with the word.
pfxlen = get_pfxlist(affile, afflist, store_afflist);
+ }
- if (spin->si_compflags != NULL)
+ if (spin->si_compflags != NULL) {
// Need to store the list of compound flags with the word.
// Concatenate them to the list of prefix IDs.
get_compflags(affile, afflist, store_afflist + pfxlen);
+ }
}
// Add the word to the word tree(s).
if (store_word(spin, dw, flags, spin->si_region,
- store_afflist, need_affix) == FAIL)
+ store_afflist, need_affix) == FAIL) {
retval = FAIL;
+ }
if (afflist != NULL) {
// Find all matching suffixes and add the resulting words.
// Additionally do matching prefixes that combine.
if (store_aff_word(spin, dw, afflist, affile,
- &affile->af_suff, &affile->af_pref,
- CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL)
+ &affile->af_suff, &affile->af_pref,
+ CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL) {
retval = FAIL;
+ }
// Find all matching prefixes and add the resulting words.
if (store_aff_word(spin, dw, afflist, affile,
- &affile->af_pref, NULL,
- CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL)
+ &affile->af_pref, NULL,
+ CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL) {
retval = FAIL;
+ }
}
xfree(pc);
}
- if (duplicate > 0)
+ if (duplicate > 0) {
smsg(_("%d duplicate word(s) in %s"), duplicate, fname);
- if (spin->si_ascii && non_ascii > 0)
+ }
+ if (spin->si_ascii && non_ascii > 0) {
smsg(_("Ignored %d word(s) with non-ASCII characters in %s"),
non_ascii, fname);
+ }
hash_clear(&ht);
fclose(fd);
@@ -3189,24 +3311,34 @@ static int get_affix_flags(afffile_T *affile, char_u *afflist)
{
int flags = 0;
- if (affile->af_keepcase != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_keepcase))
+ if (affile->af_keepcase != 0 &&
+ flag_in_afflist(affile->af_flagtype, afflist,
+ affile->af_keepcase)) {
flags |= WF_KEEPCAP | WF_FIXCAP;
- if (affile->af_rare != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_rare))
+ }
+ if (affile->af_rare != 0 &&
+ flag_in_afflist(affile->af_flagtype, afflist, affile->af_rare)) {
flags |= WF_RARE;
- if (affile->af_bad != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_bad))
+ }
+ if (affile->af_bad != 0 &&
+ flag_in_afflist(affile->af_flagtype, afflist, affile->af_bad)) {
flags |= WF_BANNED;
- if (affile->af_needcomp != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_needcomp))
+ }
+ if (affile->af_needcomp != 0 &&
+ flag_in_afflist(affile->af_flagtype, afflist,
+ affile->af_needcomp)) {
flags |= WF_NEEDCOMP;
- if (affile->af_comproot != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_comproot))
+ }
+ if (affile->af_comproot != 0 &&
+ flag_in_afflist(affile->af_flagtype, afflist,
+ affile->af_comproot)) {
flags |= WF_COMPROOT;
- if (affile->af_nosuggest != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_nosuggest))
+ }
+ if (affile->af_nosuggest != 0 &&
+ flag_in_afflist(affile->af_flagtype, afflist,
+ affile->af_nosuggest)) {
flags |= WF_NOSUGGEST;
+ }
return flags;
}
@@ -3216,12 +3348,12 @@ static int get_affix_flags(afffile_T *affile, char_u *afflist)
// and return the number of affixes.
static int get_pfxlist(afffile_T *affile, char_u *afflist, char_u *store_afflist)
{
- char_u *p;
- char_u *prevp;
+ char_u *p;
+ char_u *prevp;
int cnt = 0;
int id;
char_u key[AH_KEY_LEN];
- hashitem_T *hi;
+ hashitem_T *hi;
for (p = afflist; *p != NUL; ) {
prevp = p;
@@ -3232,12 +3364,14 @@ static int get_pfxlist(afffile_T *affile, char_u *afflist, char_u *store_afflist
hi = hash_find(&affile->af_pref, key);
if (!HASHITEM_EMPTY(hi)) {
id = HI2AH(hi)->ah_newID;
- if (id != 0)
+ if (id != 0) {
store_afflist[cnt++] = id;
+ }
}
}
- if (affile->af_flagtype == AFT_NUM && *p == ',')
+ if (affile->af_flagtype == AFT_NUM && *p == ',') {
++p;
+ }
}
store_afflist[cnt] = NUL;
@@ -3249,11 +3383,11 @@ static int get_pfxlist(afffile_T *affile, char_u *afflist, char_u *store_afflist
// Puts the flags in "store_afflist[]".
static void get_compflags(afffile_T *affile, char_u *afflist, char_u *store_afflist)
{
- char_u *p;
- char_u *prevp;
+ char_u *p;
+ char_u *prevp;
int cnt = 0;
char_u key[AH_KEY_LEN];
- hashitem_T *hi;
+ hashitem_T *hi;
for (p = afflist; *p != NUL; ) {
prevp = p;
@@ -3261,48 +3395,47 @@ static void get_compflags(afffile_T *affile, char_u *afflist, char_u *store_affl
// A flag is a compound flag if it appears in "af_comp".
STRLCPY(key, prevp, p - prevp + 1);
hi = hash_find(&affile->af_comp, key);
- if (!HASHITEM_EMPTY(hi))
+ if (!HASHITEM_EMPTY(hi)) {
store_afflist[cnt++] = HI2CI(hi)->ci_newID;
+ }
}
- if (affile->af_flagtype == AFT_NUM && *p == ',')
+ if (affile->af_flagtype == AFT_NUM && *p == ',') {
++p;
+ }
}
store_afflist[cnt] = NUL;
}
-// Apply affixes to a word and store the resulting words.
-// "ht" is the hashtable with affentry_T that need to be applied, either
-// prefixes or suffixes.
-// "xht", when not NULL, is the prefix hashtable, to be used additionally on
-// the resulting words for combining affixes.
-//
-// Returns FAIL when out of memory.
-static int
-store_aff_word (
- spellinfo_T *spin, // spell info
- char_u *word, // basic word start
- char_u *afflist, // list of names of supported affixes
- afffile_T *affile,
- hashtab_T *ht,
- hashtab_T *xht,
- int condit, // CONDIT_SUF et al.
- int flags, // flags for the word
- char_u *pfxlist, // list of prefix IDs
- int pfxlen // nr of flags in "pfxlist" for prefixes, rest
- // is compound flags
-)
+/// Apply affixes to a word and store the resulting words.
+/// "ht" is the hashtable with affentry_T that need to be applied, either
+/// prefixes or suffixes.
+/// "xht", when not NULL, is the prefix hashtable, to be used additionally on
+/// the resulting words for combining affixes.
+///
+/// @param spin spell info
+/// @param word basic word start
+/// @param afflist list of names of supported affixes
+/// @param condit CONDIT_SUF et al.
+/// @param flags flags for the word
+/// @param pfxlist list of prefix IDs
+/// @param pfxlen nr of flags in "pfxlist" for prefixes, rest is compound flags
+///
+/// @return FAIL when out of memory.
+static int store_aff_word(spellinfo_T *spin, char_u *word, char_u *afflist, afffile_T *affile,
+ hashtab_T *ht, hashtab_T *xht, int condit, int flags, char_u *pfxlist,
+ int pfxlen)
{
int todo;
- hashitem_T *hi;
+ hashitem_T *hi;
affheader_T *ah;
- affentry_T *ae;
+ affentry_T *ae;
char_u newword[MAXWLEN];
int retval = OK;
int i, j;
- char_u *p;
+ char_u *p;
int use_flags;
- char_u *use_pfxlist;
+ char_u *use_pfxlist;
int use_pfxlen;
bool need_affix;
char_u store_afflist[MAXWLEN];
@@ -3320,7 +3453,7 @@ store_aff_word (
// supports this affix.
if (((condit & CONDIT_COMB) == 0 || ah->ah_combine)
&& flag_in_afflist(affile->af_flagtype, afflist,
- ah->ah_flag)) {
+ ah->ah_flag)) {
// Loop over all affix entries with this name.
for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next) {
// Check the condition. It's not logical to match case
@@ -3344,7 +3477,7 @@ store_aff_word (
== ((condit & CONDIT_AFF) == 0
|| ae->ae_flags == NULL
|| !flag_in_afflist(affile->af_flagtype,
- ae->ae_flags, affile->af_circumfix)))) {
+ ae->ae_flags, affile->af_circumfix)))) {
// Match. Remove the chop and add the affix.
if (xht == NULL) {
// prefix: chop/add at the start of the word
@@ -3374,8 +3507,9 @@ store_aff_word (
}
*p = NUL;
}
- if (ae->ae_add != NULL)
+ if (ae->ae_add != NULL) {
STRCAT(newword, ae->ae_add);
+ }
}
use_flags = flags;
@@ -3387,57 +3521,64 @@ store_aff_word (
// Extract flags from the affix list.
use_flags |= get_affix_flags(affile, ae->ae_flags);
- if (affile->af_needaffix != 0 && flag_in_afflist(
- affile->af_flagtype, ae->ae_flags,
- affile->af_needaffix))
+ if (affile->af_needaffix != 0 && flag_in_afflist(affile->af_flagtype, ae->ae_flags,
+ affile->af_needaffix)) {
need_affix = true;
+ }
// When there is a CIRCUMFIX flag the other affix
// must also have it and we don't add the word
// with one affix.
- if (affile->af_circumfix != 0 && flag_in_afflist(
- affile->af_flagtype, ae->ae_flags,
- affile->af_circumfix)) {
+ if (affile->af_circumfix != 0 && flag_in_afflist(affile->af_flagtype, ae->ae_flags,
+ affile->af_circumfix)) {
use_condit |= CONDIT_CFIX;
- if ((condit & CONDIT_CFIX) == 0)
+ if ((condit & CONDIT_CFIX) == 0) {
need_affix = true;
+ }
}
if (affile->af_pfxpostpone
|| spin->si_compflags != NULL) {
- if (affile->af_pfxpostpone)
+ if (affile->af_pfxpostpone) {
// Get prefix IDS from the affix list.
use_pfxlen = get_pfxlist(affile,
- ae->ae_flags, store_afflist);
- else
+ ae->ae_flags, store_afflist);
+ } else {
use_pfxlen = 0;
+ }
use_pfxlist = store_afflist;
// Combine the prefix IDs. Avoid adding the
// same ID twice.
for (i = 0; i < pfxlen; ++i) {
- for (j = 0; j < use_pfxlen; ++j)
- if (pfxlist[i] == use_pfxlist[j])
+ for (j = 0; j < use_pfxlen; ++j) {
+ if (pfxlist[i] == use_pfxlist[j]) {
break;
- if (j == use_pfxlen)
+ }
+ }
+ if (j == use_pfxlen) {
use_pfxlist[use_pfxlen++] = pfxlist[i];
+ }
}
- if (spin->si_compflags != NULL)
+ if (spin->si_compflags != NULL) {
// Get compound IDS from the affix list.
get_compflags(affile, ae->ae_flags,
- use_pfxlist + use_pfxlen);
- else
+ use_pfxlist + use_pfxlen);
+ } else {
use_pfxlist[use_pfxlen] = NUL;
+ }
// Combine the list of compound flags.
// Concatenate them to the prefix IDs list.
// Avoid adding the same ID twice.
for (i = pfxlen; pfxlist[i] != NUL; ++i) {
for (j = use_pfxlen;
- use_pfxlist[j] != NUL; ++j)
- if (pfxlist[i] == use_pfxlist[j])
+ use_pfxlist[j] != NUL; ++j) {
+ if (pfxlist[i] == use_pfxlist[j]) {
break;
+ }
+ }
if (use_pfxlist[j] == NUL) {
use_pfxlist[j++] = pfxlist[i];
use_pfxlist[j] = NUL;
@@ -3462,52 +3603,58 @@ store_aff_word (
// ... don't use a prefix list if combining
// affixes is not allowed. But do use the
// compound flags after them.
- if (!ah->ah_combine && use_pfxlist != NULL)
+ if (!ah->ah_combine && use_pfxlist != NULL) {
use_pfxlist += use_pfxlen;
+ }
}
// When compounding is supported and there is no
// "COMPOUNDPERMITFLAG" then forbid compounding on the
// side where the affix is applied.
if (spin->si_compflags != NULL && !ae->ae_comppermit) {
- if (xht != NULL)
+ if (xht != NULL) {
use_flags |= WF_NOCOMPAFT;
- else
+ } else {
use_flags |= WF_NOCOMPBEF;
+ }
}
// Store the modified word.
if (store_word(spin, newword, use_flags,
- spin->si_region, use_pfxlist,
- need_affix) == FAIL)
+ spin->si_region, use_pfxlist,
+ need_affix) == FAIL) {
retval = FAIL;
+ }
// When added a prefix or a first suffix and the affix
// has flags may add a(nother) suffix. RECURSIVE!
- if ((condit & CONDIT_SUF) && ae->ae_flags != NULL)
+ if ((condit & CONDIT_SUF) && ae->ae_flags != NULL) {
if (store_aff_word(spin, newword, ae->ae_flags,
- affile, &affile->af_suff, xht,
- use_condit & (xht == NULL
+ affile, &affile->af_suff, xht,
+ use_condit & (xht == NULL
? ~0 : ~CONDIT_SUF),
- use_flags, use_pfxlist, pfxlen) == FAIL)
+ use_flags, use_pfxlist, pfxlen) == FAIL) {
retval = FAIL;
+ }
+ }
// When added a suffix and combining is allowed also
// try adding a prefix additionally. Both for the
// word flags and for the affix flags. RECURSIVE!
if (xht != NULL && ah->ah_combine) {
if (store_aff_word(spin, newword,
- afflist, affile,
- xht, NULL, use_condit,
- use_flags, use_pfxlist,
- pfxlen) == FAIL
+ afflist, affile,
+ xht, NULL, use_condit,
+ use_flags, use_pfxlist,
+ pfxlen) == FAIL
|| (ae->ae_flags != NULL
&& store_aff_word(spin, newword,
- ae->ae_flags, affile,
- xht, NULL, use_condit,
- use_flags, use_pfxlist,
- pfxlen) == FAIL))
+ ae->ae_flags, affile,
+ xht, NULL, use_condit,
+ use_flags, use_pfxlist,
+ pfxlen) == FAIL)) {
retval = FAIL;
+ }
}
}
}
@@ -3521,12 +3668,12 @@ store_aff_word (
// Read a file with a list of words.
static int spell_read_wordfile(spellinfo_T *spin, char_u *fname)
{
- FILE *fd;
+ FILE *fd;
long lnum = 0;
char_u rline[MAXLINELEN];
- char_u *line;
- char_u *pc = NULL;
- char_u *p;
+ char_u *line;
+ char_u *pc = NULL;
+ char_u *p;
int l;
int retval = OK;
bool did_word = false;
@@ -3550,15 +3697,18 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname)
++lnum;
// Skip comment lines.
- if (*rline == '#')
+ if (*rline == '#') {
continue;
+ }
// Remove CR, LF and white space from the end.
l = (int)STRLEN(rline);
- while (l > 0 && rline[l - 1] <= ' ')
+ while (l > 0 && rline[l - 1] <= ' ') {
--l;
- if (l == 0)
+ }
+ if (l == 0) {
continue; // empty or blank line
+ }
rline[l] = NUL;
// Convert from "/encoding={encoding}" to 'encoding' when needed.
@@ -3586,16 +3736,17 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname)
smsg(_("/encoding= line after word ignored in %s line %ld: %s"),
fname, lnum, line - 1);
} else {
- char_u *enc;
+ char_u *enc;
// Setup for conversion to 'encoding'.
line += 9;
enc = enc_canonize(line);
if (!spin->si_ascii
&& convert_setup(&spin->si_conv, enc,
- p_enc) == FAIL)
+ p_enc) == FAIL) {
smsg(_("Conversion in %s not supported: from %s to %s"),
fname, line, p_enc);
+ }
xfree(enc);
spin->si_conv.vc_fail = true;
}
@@ -3635,15 +3786,16 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname)
if (p != NULL) {
*p++ = NUL;
while (*p != NUL) {
- if (*p == '=') // keep-case word
+ if (*p == '=') { // keep-case word
flags |= WF_KEEPCAP | WF_FIXCAP;
- else if (*p == '!') // Bad, bad, wicked word.
+ } else if (*p == '!') { // Bad, bad, wicked word.
flags |= WF_BANNED;
- else if (*p == '?') // Rare word.
+ } else if (*p == '?') { // Rare word.
flags |= WF_RARE;
- else if (ascii_isdigit(*p)) { // region number(s)
- if ((flags & WF_REGION) == 0) // first one
+ } else if (ascii_isdigit(*p)) { // region number(s)
+ if ((flags & WF_REGION) == 0) { // first one
regionmask = 0;
+ }
flags |= WF_REGION;
l = *p - '0';
@@ -3681,7 +3833,7 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname)
if (spin->si_ascii && non_ascii > 0) {
vim_snprintf((char *)IObuff, IOSIZE,
- _("Ignored %d words with non-ASCII characters"), non_ascii);
+ _("Ignored %d words with non-ASCII characters"), non_ascii);
spell_message(spin, IObuff);
}
@@ -3699,16 +3851,17 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname)
static void *getroom(spellinfo_T *spin, size_t len, bool align)
FUNC_ATTR_NONNULL_RET
{
- char_u *p;
- sblock_T *bl = spin->si_blocks;
+ char_u *p;
+ sblock_T *bl = spin->si_blocks;
assert(len <= SBLOCKSIZE);
-
- if (align && bl != NULL)
+
+ if (align && bl != NULL) {
// Round size up for alignment. On some systems structures need to be
// aligned to the size of a pointer (e.g., SPARC).
bl->sb_used = (bl->sb_used + sizeof(char *) - 1)
& ~(sizeof(char *) - 1);
+ }
if (bl == NULL || bl->sb_used + len > SBLOCKSIZE) {
// Allocate a block of memory. It is not freed until much later.
@@ -3737,7 +3890,7 @@ static char_u *getroom_save(spellinfo_T *spin, char_u *s)
// Free the list of allocated sblock_T.
static void free_blocks(sblock_T *bl)
{
- sblock_T *next;
+ sblock_T *next;
while (bl != NULL) {
next = bl->sb_next;
@@ -3754,22 +3907,20 @@ static wordnode_T *wordtree_alloc(spellinfo_T *spin)
return (wordnode_T *)getroom(spin, sizeof(wordnode_T), true);
}
-// Store a word in the tree(s).
-// Always store it in the case-folded tree. For a keep-case word this is
-// useful when the word can also be used with all caps (no WF_FIXCAP flag) and
-// used to find suggestions.
-// For a keep-case word also store it in the keep-case tree.
-// When "pfxlist" is not NULL store the word for each postponed prefix ID and
-// compound flag.
-static int
-store_word (
- spellinfo_T *spin,
- char_u *word,
- int flags, // extra flags, WF_BANNED
- int region, // supported region(s)
- const char_u *pfxlist, // list of prefix IDs or NULL
- bool need_affix // only store word with affix ID
-)
+/// Store a word in the tree(s).
+/// Always store it in the case-folded tree. For a keep-case word this is
+/// useful when the word can also be used with all caps (no WF_FIXCAP flag) and
+/// used to find suggestions.
+/// For a keep-case word also store it in the keep-case tree.
+/// When "pfxlist" is not NULL store the word for each postponed prefix ID and
+/// compound flag.
+///
+/// @param flags extra flags, wf_banned
+/// @param region supported region(s)
+/// @param pfxlist list of prefix ids or null
+/// @param need_affix only store word with affix id
+static int store_word(spellinfo_T *spin, char_u *word, int flags, int region, const char_u *pfxlist,
+ bool need_affix)
{
int len = (int)STRLEN(word);
int ct = captype(word, word + len);
@@ -3807,12 +3958,13 @@ store_word (
// When "flags" < 0 we are adding to the prefix tree where "flags" is used for
// "rare" and "region" is the condition nr.
// Returns FAIL when out of memory.
-static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int flags, int region, int affixID)
+static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int flags, int region,
+ int affixID)
{
- wordnode_T *node = root;
- wordnode_T *np;
- wordnode_T *copyp, **copyprev;
- wordnode_T **prev = NULL;
+ wordnode_T *node = root;
+ wordnode_T *np;
+ wordnode_T *copyp, **copyprev;
+ wordnode_T **prev = NULL;
int i;
// Add each byte of the word to the tree, including the NUL at the end.
@@ -3826,11 +3978,13 @@ static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int
for (copyp = node; copyp != NULL; copyp = copyp->wn_sibling) {
// Allocate a new node and copy the info.
np = get_wordnode(spin);
- if (np == NULL)
+ if (np == NULL) {
return FAIL;
+ }
np->wn_child = copyp->wn_child;
- if (np->wn_child != NULL)
+ if (np->wn_child != NULL) {
++np->wn_child->wn_refs; // child gets extra ref
+ }
np->wn_byte = copyp->wn_byte;
if (np->wn_byte == NUL) {
np->wn_flags = copyp->wn_flags;
@@ -3840,13 +3994,15 @@ static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int
// Link the new node in the list, there will be one ref.
np->wn_refs = 1;
- if (copyprev != NULL)
+ if (copyprev != NULL) {
*copyprev = np;
+ }
copyprev = &np->wn_sibling;
// Let "node" point to the head of the copied list.
- if (copyp == node)
+ if (copyp == node) {
node = np;
+ }
}
}
@@ -3877,22 +4033,24 @@ static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int
|| node->wn_affixID != affixID))) {
// Allocate a new node.
np = get_wordnode(spin);
- if (np == NULL)
+ if (np == NULL) {
return FAIL;
+ }
np->wn_byte = word[i];
// If "node" is NULL this is a new child or the end of the sibling
// list: ref count is one. Otherwise use ref count of sibling and
// make ref count of sibling one (matters when inserting in front
// of the list of siblings).
- if (node == NULL)
+ if (node == NULL) {
np->wn_refs = 1;
- else {
+ } else {
np->wn_refs = node->wn_refs;
node->wn_refs = 1;
}
- if (prev != NULL)
+ if (prev != NULL) {
*prev = np;
+ }
np->wn_sibling = node;
node = np;
}
@@ -3934,7 +4092,7 @@ static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int
#ifndef SPELL_COMPRESS_ALLWAYS
if (spin->si_compress_cnt == 1 // NOLINT(readability/braces)
? spin->si_free_count < MAXWLEN
- : spin->si_blocks_cnt >= compress_start)
+ : spin->si_blocks_cnt >= compress_start)
#endif
{
// Decrement the block counter. The effect is that we compress again
@@ -3973,17 +4131,18 @@ static wordnode_T *get_wordnode(spellinfo_T *spin)
{
wordnode_T *n;
- if (spin->si_first_free == NULL)
+ if (spin->si_first_free == NULL) {
n = (wordnode_T *)getroom(spin, sizeof(wordnode_T), true);
- else {
+ } else {
n = spin->si_first_free;
spin->si_first_free = n->wn_child;
memset(n, 0, sizeof(wordnode_T));
--spin->si_free_count;
}
#ifdef SPELL_PRINTTREE
- if (n != NULL)
+ if (n != NULL) {
n->wn_nr = ++spin->si_wordnode_nr;
+ }
#endif
return n;
}
@@ -3995,13 +4154,14 @@ static wordnode_T *get_wordnode(spellinfo_T *spin)
static int deref_wordnode(spellinfo_T *spin, wordnode_T *node)
FUNC_ATTR_NONNULL_ALL
{
- wordnode_T *np;
+ wordnode_T *np;
int cnt = 0;
if (--node->wn_refs == 0) {
for (np = node; np != NULL; np = np->wn_sibling) {
- if (np->wn_child != NULL)
+ if (np->wn_child != NULL) {
cnt += deref_wordnode(spin, np->wn_child);
+ }
free_wordnode(spin, np);
++cnt;
}
@@ -4021,8 +4181,7 @@ static void free_wordnode(spellinfo_T *spin, wordnode_T *n)
}
// Compress a tree: find tails that are identical and can be shared.
-static void wordtree_compress(spellinfo_T *spin, wordnode_T *root,
- const char *name)
+static void wordtree_compress(spellinfo_T *spin, wordnode_T *root, const char *name)
FUNC_ATTR_NONNULL_ALL
{
hashtab_T ht;
@@ -4039,12 +4198,13 @@ static void wordtree_compress(spellinfo_T *spin, wordnode_T *root,
if (spin->si_verbose || p_verbose > 2)
#endif
{
- if (tot > 1000000)
+ if (tot > 1000000) {
perc = (tot - n) / (tot / 100);
- else if (tot == 0)
+ } else if (tot == 0) {
perc = 0;
- else
+ } else {
perc = (tot - n) * 100 / tot;
+ }
vim_snprintf((char *)IObuff, IOSIZE,
_("Compressed %s of %ld nodes; %ld (%ld%%) remaining"),
name, tot, tot - n, perc);
@@ -4057,22 +4217,18 @@ static void wordtree_compress(spellinfo_T *spin, wordnode_T *root,
}
}
-// Compress a node, its siblings and its children, depth first.
-// Returns the number of compressed nodes.
-static long node_compress(
- spellinfo_T *spin,
- wordnode_T *node,
- hashtab_T *ht,
- long *tot // total count of nodes before compressing,
- // incremented while going through the tree
-)
+/// Compress a node, its siblings and its children, depth first.
+/// Returns the number of compressed nodes.
+///
+/// @param tot total count of nodes before compressing, incremented while going through the tree
+static long node_compress(spellinfo_T *spin, wordnode_T *node, hashtab_T *ht, long *tot)
FUNC_ATTR_NONNULL_ALL
{
- wordnode_T *np;
- wordnode_T *tp;
- wordnode_T *child;
+ wordnode_T *np;
+ wordnode_T *tp;
+ wordnode_T *child;
hash_T hash;
- hashitem_T *hi;
+ hashitem_T *hi;
long len = 0;
unsigned nr, n;
long compressed = 0;
@@ -4095,7 +4251,7 @@ static long node_compress(
// There are children we encountered before with a hash value
// identical to the current child. Now check if there is one
// that is really identical.
- for (tp = HI2WN(hi); tp != NULL; tp = tp->wn_u2.next)
+ for (tp = HI2WN(hi); tp != NULL; tp = tp->wn_u2.next) {
if (node_equal(child, tp)) {
// Found one! Now use that child in place of the
// current one. This means the current child and all
@@ -4105,6 +4261,7 @@ static long node_compress(
np->wn_child = tp;
break;
}
+ }
if (tp == NULL) {
// No other child with this hash value equals the child of
// the node, add it to the linked list after the first
@@ -4113,10 +4270,11 @@ static long node_compress(
child->wn_u2.next = tp->wn_u2.next;
tp->wn_u2.next = child;
}
- } else
+ } else {
// No other child has this hash value, add it to the
// hashtable.
hash_add_item(ht, hi, child->wn_u1.hashkey, hash);
+ }
}
}
*tot += len + 1; // add one for the node that stores the length
@@ -4127,12 +4285,13 @@ static long node_compress(
node->wn_u1.hashkey[0] = len;
nr = 0;
for (np = node; np != NULL; np = np->wn_sibling) {
- if (np->wn_byte == NUL)
+ if (np->wn_byte == NUL) {
// end node: use wn_flags, wn_region and wn_affixID
n = np->wn_flags + (np->wn_region << 8) + (np->wn_affixID << 16);
- else
+ } else {
// byte node: use the byte value and the child pointer
n = (unsigned)(np->wn_byte + ((uintptr_t)np->wn_child << 8));
+ }
nr = nr * 101 + n;
}
@@ -4156,18 +4315,20 @@ static long node_compress(
// Returns true when two nodes have identical siblings and children.
static bool node_equal(wordnode_T *n1, wordnode_T *n2)
{
- wordnode_T *p1;
- wordnode_T *p2;
+ wordnode_T *p1;
+ wordnode_T *p2;
for (p1 = n1, p2 = n2; p1 != NULL && p2 != NULL;
- p1 = p1->wn_sibling, p2 = p2->wn_sibling)
+ p1 = p1->wn_sibling, p2 = p2->wn_sibling) {
if (p1->wn_byte != p2->wn_byte
|| (p1->wn_byte == NUL
? (p1->wn_flags != p2->wn_flags
|| p1->wn_region != p2->wn_region
|| p1->wn_affixID != p2->wn_affixID)
- : (p1->wn_child != p2->wn_child)))
+ : (p1->wn_child != p2->wn_child))) {
break;
+ }
+ }
return p1 == NULL && p2 == NULL;
}
@@ -4176,8 +4337,8 @@ static bool node_equal(wordnode_T *n1, wordnode_T *n2)
// Function given to qsort() to sort the REP items on "from" string.
static int rep_compare(const void *s1, const void *s2)
{
- fromto_T *p1 = (fromto_T *)s1;
- fromto_T *p2 = (fromto_T *)s2;
+ fromto_T *p1 = (fromto_T *)s1;
+ fromto_T *p2 = (fromto_T *)s2;
return STRCMP(p1->ft_from, p2->ft_from);
}
@@ -4198,9 +4359,10 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname)
// <HEADER>: <fileID> <versionnr>
// <fileID>
size_t fwv = fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, 1, fd);
- if (fwv != (size_t)1)
+ if (fwv != (size_t)1) {
// Catch first write error, don't try writing more.
goto theend;
+ }
putc(VIMSPELLVERSION, fd); // <versionnr>
@@ -4225,8 +4387,9 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname)
fwv &= fwrite(spin->si_region_name, l, 1, fd);
// <regionname> ...
regionmask = (1 << spin->si_region_count) - 1;
- } else
+ } else {
regionmask = 0;
+ }
// SN_CHARFLAGS: <charflagslen> <charflags> <folcharslen> <folchars>
//
@@ -4254,10 +4417,12 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname)
fputc(128, fd); // <charflagslen>
for (size_t i = 128; i < 256; ++i) {
flags = 0;
- if (spelltab.st_isw[i])
+ if (spelltab.st_isw[i]) {
flags |= CF_WORD;
- if (spelltab.st_isu[i])
+ }
+ if (spelltab.st_isu[i]) {
flags |= CF_UPPER;
+ }
fputc(flags, fd); // <charflags>
}
@@ -4296,24 +4461,28 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname)
// round 3: SN_REPSAL section
for (unsigned int round = 1; round <= 3; ++round) {
garray_T *gap;
- if (round == 1)
+ if (round == 1) {
gap = &spin->si_rep;
- else if (round == 2) {
+ } else if (round == 2) {
// Don't write SN_SAL when using a SN_SOFO section
- if (spin->si_sofofr != NULL && spin->si_sofoto != NULL)
+ if (spin->si_sofofr != NULL && spin->si_sofoto != NULL) {
continue;
+ }
gap = &spin->si_sal;
- } else
+ } else {
gap = &spin->si_repsal;
+ }
// Don't write the section if there are no items.
- if (GA_EMPTY(gap))
+ if (GA_EMPTY(gap)) {
continue;
+ }
// Sort the REP/REPSAL items.
- if (round != 2)
+ if (round != 2) {
qsort(gap->ga_data, (size_t)gap->ga_len,
- sizeof(fromto_T), rep_compare);
+ sizeof(fromto_T), rep_compare);
+ }
int sect_id = round == 1 ? SN_REP : (round == 2 ? SN_SAL : SN_REPSAL);
putc(sect_id, fd); // <sectionID>
@@ -4329,18 +4498,22 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname)
l += 1 + STRLEN(ftp->ft_from); // count <*fromlen> and <*from>
l += 1 + STRLEN(ftp->ft_to); // count <*tolen> and <*to>
}
- if (round == 2)
+ if (round == 2) {
++l; // count <salflags>
+ }
put_bytes(fd, l, 4); // <sectionlen>
if (round == 2) {
int i = 0;
- if (spin->si_followup)
+ if (spin->si_followup) {
i |= SAL_F0LLOWUP;
- if (spin->si_collapse)
+ }
+ if (spin->si_collapse) {
i |= SAL_COLLAPSE;
- if (spin->si_rem_accents)
+ }
+ if (spin->si_rem_accents) {
i |= SAL_REM_ACCENTS;
+ }
putc(i, fd); // <salflags>
}
@@ -4354,11 +4527,11 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname)
l = STRLEN(p);
assert(l < INT_MAX);
putc((int)l, fd);
- if (l > 0)
+ if (l > 0) {
fwv &= fwrite(p, l, 1, fd);
+ }
}
}
-
}
// SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto>
@@ -4389,19 +4562,22 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname)
for (unsigned int round = 1; round <= 2; ++round) {
size_t todo;
size_t len = 0;
- hashitem_T *hi;
+ hashitem_T *hi;
todo = spin->si_commonwords.ht_used;
- for (hi = spin->si_commonwords.ht_array; todo > 0; ++hi)
+ for (hi = spin->si_commonwords.ht_array; todo > 0; ++hi) {
if (!HASHITEM_EMPTY(hi)) {
size_t l = STRLEN(hi->hi_key) + 1;
len += l;
- if (round == 2) // <word>
+ if (round == 2) { // <word>
fwv &= fwrite(hi->hi_key, l, 1, fd);
+ }
--todo;
}
- if (round == 1)
+ }
+ if (round == 1) {
put_bytes(fd, len, 4); // <sectionlen>
+ }
}
}
@@ -4509,12 +4685,13 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname)
spin->si_memtot = 0;
for (unsigned int round = 1; round <= 3; ++round) {
wordnode_T *tree;
- if (round == 1)
+ if (round == 1) {
tree = spin->si_foldroot->wn_sibling;
- else if (round == 2)
+ } else if (round == 2) {
tree = spin->si_keeproot->wn_sibling;
- else
+ } else {
tree = spin->si_prefroot->wn_sibling;
+ }
// Clear the index and wnode fields in the tree.
clear_node(tree);
@@ -4534,16 +4711,20 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname)
}
// Write another byte to check for errors (file system full).
- if (putc(0, fd) == EOF)
+ if (putc(0, fd) == EOF) {
retval = FAIL;
+ }
theend:
- if (fclose(fd) == EOF)
+ if (fclose(fd) == EOF) {
retval = FAIL;
+ }
- if (fwv != (size_t)1)
+ if (fwv != (size_t)1) {
retval = FAIL;
- if (retval == FAIL)
+ }
+ if (retval == FAIL) {
EMSG(_(e_write));
+ }
return retval;
}
@@ -4553,54 +4734,54 @@ theend:
// space.
static void clear_node(wordnode_T *node)
{
- wordnode_T *np;
+ wordnode_T *np;
- if (node != NULL)
+ if (node != NULL) {
for (np = node; np != NULL; np = np->wn_sibling) {
np->wn_u1.index = 0;
np->wn_u2.wnode = NULL;
- if (np->wn_byte != NUL)
+ if (np->wn_byte != NUL) {
clear_node(np->wn_child);
+ }
}
+ }
}
-// Dump a word tree at node "node".
-//
-// This first writes the list of possible bytes (siblings). Then for each
-// byte recursively write the children.
-//
-// NOTE: The code here must match the code in read_tree_node(), since
-// assumptions are made about the indexes (so that we don't have to write them
-// in the file).
-//
-// Returns the number of nodes used.
-static int
-put_node (
- FILE *fd, // NULL when only counting
- wordnode_T *node,
- int idx,
- int regionmask,
- bool prefixtree // true for PREFIXTREE
-)
+/// Dump a word tree at node "node".
+///
+/// This first writes the list of possible bytes (siblings). Then for each
+/// byte recursively write the children.
+///
+/// NOTE: The code here must match the code in read_tree_node(), since
+/// assumptions are made about the indexes (so that we don't have to write them
+/// in the file).
+///
+/// @param fd NULL when only counting
+/// @param prefixtree true for PREFIXTREE
+///
+/// @return the number of nodes used.
+static int put_node(FILE *fd, wordnode_T *node, int idx, int regionmask, bool prefixtree)
{
// If "node" is zero the tree is empty.
- if (node == NULL)
+ if (node == NULL) {
return 0;
+ }
// Store the index where this node is written.
node->wn_u1.index = idx;
// Count the number of siblings.
int siblingcount = 0;
- for (wordnode_T *np = node; np != NULL; np = np->wn_sibling)
+ for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) {
++siblingcount;
+ }
// Write the sibling count.
- if (fd != NULL)
+ if (fd != NULL) {
putc(siblingcount, fd); // <siblingcount>
-
+ }
// Write each sibling byte and optionally extra info.
for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) {
if (np->wn_byte == 0) {
@@ -4611,9 +4792,9 @@ put_node (
// associated condition nr (stored in wn_region). The
// byte value is misused to store the "rare" and "not
// combining" flags
- if (np->wn_flags == (uint16_t)PFX_FLAGS)
+ if (np->wn_flags == (uint16_t)PFX_FLAGS) {
putc(BY_NOFLAGS, fd); // <byte>
- else {
+ } else {
putc(BY_FLAGS, fd); // <byte>
putc(np->wn_flags, fd); // <pflags>
}
@@ -4622,10 +4803,12 @@ put_node (
} else {
// For word trees we write the flag/region items.
int flags = np->wn_flags;
- if (regionmask != 0 && np->wn_region != regionmask)
+ if (regionmask != 0 && np->wn_region != regionmask) {
flags |= WF_REGION;
- if (np->wn_affixID != 0)
+ }
+ if (np->wn_affixID != 0) {
flags |= WF_AFX;
+ }
if (flags == 0) {
// word without flags or region
putc(BY_NOFLAGS, fd); // <byte>
@@ -4638,10 +4821,12 @@ put_node (
putc(BY_FLAGS, fd); // <byte>
putc(flags, fd); // <flags>
}
- if (flags & WF_REGION)
+ if (flags & WF_REGION) {
putc(np->wn_region, fd); // <region>
- if (flags & WF_AFX)
+ }
+ if (flags & WF_AFX) {
putc(np->wn_affixID, fd); // <affixID>
+ }
}
}
}
@@ -4653,15 +4838,17 @@ put_node (
putc(BY_INDEX, fd); // <byte>
put_bytes(fd, (uintmax_t)np->wn_child->wn_u1.index, 3); // <nodeidx>
}
- } else if (np->wn_child->wn_u2.wnode == NULL)
+ } else if (np->wn_child->wn_u2.wnode == NULL) {
// We will write the child below and give it an index.
np->wn_child->wn_u2.wnode = node;
+ }
- if (fd != NULL)
+ if (fd != NULL) {
if (putc(np->wn_byte, fd) == EOF) { // <byte> or <xbyte>
EMSG(_(e_write));
return 0;
}
+ }
}
}
@@ -4670,10 +4857,12 @@ put_node (
int newindex = idx + siblingcount + 1;
// Recursively dump the children of each sibling.
- for (wordnode_T *np = node; np != NULL; np = np->wn_sibling)
- if (np->wn_byte != 0 && np->wn_child->wn_u2.wnode == node)
+ for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) {
+ if (np->wn_byte != 0 && np->wn_child->wn_u2.wnode == node) {
newindex = put_node(fd, np->wn_child, newindex, regionmask,
- prefixtree);
+ prefixtree);
+ }
+ }
return newindex;
}
@@ -4684,8 +4873,8 @@ put_node (
void ex_mkspell(exarg_T *eap)
{
int fcount;
- char_u **fnames;
- char_u *arg = eap->arg;
+ char_u **fnames;
+ char_u *arg = eap->arg;
bool ascii = false;
if (STRNCMP(arg, "-ascii", 6) == 0) {
@@ -4705,9 +4894,9 @@ void ex_mkspell(exarg_T *eap)
// Writes the file with the name "wfname", with ".spl" changed to ".sug".
static void spell_make_sugfile(spellinfo_T *spin, char_u *wfname)
{
- char_u *fname = NULL;
+ char_u *fname = NULL;
int len;
- slang_T *slang;
+ slang_T *slang;
bool free_slang = false;
// Read back the .spl file that was written. This fills the required
@@ -4724,8 +4913,9 @@ static void spell_make_sugfile(spellinfo_T *spin, char_u *wfname)
if (slang == NULL) {
spell_message(spin, (char_u *)_("Reading back spell file..."));
slang = spell_load_file(wfname, NULL, NULL, false);
- if (slang == NULL)
+ if (slang == NULL) {
return;
+ }
free_slang = true;
}
@@ -4740,15 +4930,17 @@ static void spell_make_sugfile(spellinfo_T *spin, char_u *wfname)
// Go through the trie of good words, soundfold each word and add it to
// the soundfold trie.
spell_message(spin, (char_u *)_("Performing soundfolding..."));
- if (sug_filltree(spin, slang) == FAIL)
+ if (sug_filltree(spin, slang) == FAIL) {
goto theend;
+ }
// Create the table which links each soundfold word with a list of the
// good words it may come from. Creates buffer "spin->si_spellbuf".
// This also removes the wordnr from the NUL byte entries to make
// compression possible.
- if (sug_maketable(spin) == FAIL)
+ if (sug_maketable(spin) == FAIL) {
goto theend;
+ }
smsg(_("Number of words after soundfolding: %" PRId64),
(int64_t)spin->si_spellbuf->b_ml.ml_line_count);
@@ -4768,8 +4960,9 @@ static void spell_make_sugfile(spellinfo_T *spin, char_u *wfname)
theend:
xfree(fname);
- if (free_slang)
+ if (free_slang) {
slang_free(slang);
+ }
free_blocks(spin->si_blocks);
close_spellbuf(spin->si_spellbuf);
}
@@ -4777,8 +4970,8 @@ theend:
// Build the soundfold trie for language "slang".
static int sug_filltree(spellinfo_T *spin, slang_T *slang)
{
- char_u *byts;
- idx_T *idxs;
+ char_u *byts;
+ idx_T *idxs;
int depth;
idx_T arridx[MAXWLEN];
int curi[MAXWLEN];
@@ -4809,13 +5002,13 @@ static int sug_filltree(spellinfo_T *spin, slang_T *slang)
if (curi[depth] > byts[arridx[depth]]) {
// Done all bytes at this node, go up one level.
idxs[arridx[depth]] = wordcount[depth];
- if (depth > 0)
+ if (depth > 0) {
wordcount[depth - 1] += wordcount[depth];
+ }
--depth;
line_breakcheck();
} else {
-
// Do one more byte at this node.
n = arridx[depth] + curi[depth];
++curi[depth];
@@ -4829,9 +5022,10 @@ static int sug_filltree(spellinfo_T *spin, slang_T *slang)
// We use the "flags" field for the MSB of the wordnr,
// "region" for the LSB of the wordnr.
if (tree_add_word(spin, tsalword, spin->si_foldroot,
- words_done >> 16, words_done & 0xffff,
- 0) == FAIL)
+ words_done >> 16, words_done & 0xffff,
+ 0) == FAIL) {
return FAIL;
+ }
++words_done;
++wordcount[depth];
@@ -4880,25 +5074,22 @@ static int sug_maketable(spellinfo_T *spin)
ga_init(&ga, 1, 100);
// recursively go through the tree
- if (sug_filltable(spin, spin->si_foldroot->wn_sibling, 0, &ga) == -1)
+ if (sug_filltable(spin, spin->si_foldroot->wn_sibling, 0, &ga) == -1) {
res = FAIL;
+ }
ga_clear(&ga);
return res;
}
-// Fill the table for one node and its children.
-// Returns the wordnr at the start of the node.
-// Returns -1 when out of memory.
-static int
-sug_filltable (
- spellinfo_T *spin,
- wordnode_T *node,
- int startwordnr,
- garray_T *gap // place to store line of numbers
-)
+/// Fill the table for one node and its children.
+/// Returns the wordnr at the start of the node.
+/// Returns -1 when out of memory.
+///
+/// @param gap place to store line of numbers
+static int sug_filltable(spellinfo_T *spin, wordnode_T *node, int startwordnr, garray_T *gap)
{
- wordnode_T *p, *np;
+ wordnode_T *p, *np;
int wordnr = startwordnr;
int nr;
int prev_nr;
@@ -4918,7 +5109,7 @@ sug_filltable (
nr -= prev_nr;
prev_nr += nr;
gap->ga_len += offset2bytes(nr,
- (char_u *)gap->ga_data + gap->ga_len);
+ (char_u *)gap->ga_data + gap->ga_len);
}
// add the NUL byte
@@ -4932,8 +5123,9 @@ sug_filltable (
// Remove extra NUL entries, we no longer need them. We don't
// bother freeing the nodes, the won't be reused anyway.
- while (p->wn_sibling != NULL && p->wn_sibling->wn_byte == NUL)
+ while (p->wn_sibling != NULL && p->wn_sibling->wn_byte == NUL) {
p->wn_sibling = p->wn_sibling->wn_sibling;
+ }
// Clear the flags on the remaining NUL node, so that compression
// works a lot better.
@@ -4941,8 +5133,9 @@ sug_filltable (
p->wn_region = 0;
} else {
wordnr = sug_filltable(spin, p->wn_child, wordnr, gap);
- if (wordnr == -1)
+ if (wordnr == -1) {
return -1;
+ }
}
}
return wordnr;
@@ -5002,7 +5195,7 @@ static void sug_write(spellinfo_T *spin, char_u *fname)
spell_message(spin, IObuff);
// <SUGHEADER>: <fileID> <versionnr> <timestamp>
- if (fwrite(VIMSUGMAGIC, VIMSUGMAGICL, (size_t)1, fd) != 1) { // <fileID>
+ if (fwrite(VIMSUGMAGIC, VIMSUGMAGICL, (size_t)1, fd) != 1) { // <fileID>
EMSG(_(e_write));
goto theend;
}
@@ -5049,11 +5242,12 @@ static void sug_write(spellinfo_T *spin, char_u *fname)
}
// Write another byte to check for errors.
- if (putc(0, fd) == EOF)
+ if (putc(0, fd) == EOF) {
EMSG(_(e_write));
+ }
vim_snprintf((char *)IObuff, IOSIZE,
- _("Estimated runtime memory use: %d bytes"), spin->si_memtot);
+ _("Estimated runtime memory use: %d bytes"), spin->si_memtot);
spell_message(spin, IObuff);
theend:
@@ -5062,23 +5256,20 @@ theend:
}
-// Create a Vim spell file from one or more word lists.
-// "fnames[0]" is the output file name.
-// "fnames[fcount - 1]" is the last input file name.
-// Exception: when "fnames[0]" ends in ".add" it's used as the input file name
-// and ".spl" is appended to make the output file name.
-static void
-mkspell (
- int fcount,
- char_u **fnames,
- bool ascii, // -ascii argument given
- bool over_write, // overwrite existing output file
- bool added_word // invoked through "zg"
-)
+/// Create a Vim spell file from one or more word lists.
+/// "fnames[0]" is the output file name.
+/// "fnames[fcount - 1]" is the last input file name.
+/// Exception: when "fnames[0]" ends in ".add" it's used as the input file name
+/// and ".spl" is appended to make the output file name.
+///
+/// @param ascii -ascii argument given
+/// @param over_write overwrite existing output file
+/// @param added_word invoked through "zg"
+static void mkspell(int fcount, char_u **fnames, bool ascii, bool over_write, bool added_word)
{
- char_u *fname = NULL;
- char_u *wfname;
- char_u **innames;
+ char_u *fname = NULL;
+ char_u *wfname;
+ char_u **innames;
int incount;
afffile_T *(afile[MAXREGIONS]);
int i;
@@ -5114,26 +5305,29 @@ mkspell (
// "path/en.latin1.add.spl".
incount = 1;
vim_snprintf((char *)wfname, MAXPATHL, "%s.spl", fnames[0]);
- } else if (fcount == 1) {
+ } else if (fcount == 1) {
// For ":mkspell path/vim" output file is "path/vim.latin1.spl".
incount = 1;
vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL,
- fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc());
- } else if (len > 4 && STRCMP(fnames[0] + len - 4, ".spl") == 0) {
+ fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc());
+ } else if (len > 4 && STRCMP(fnames[0] + len - 4, ".spl") == 0) {
// Name ends in ".spl", use as the file name.
STRLCPY(wfname, fnames[0], MAXPATHL);
- } else
+ } else {
// Name should be language, make the file name from it.
vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL,
- fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc());
+ fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc());
+ }
// Check for .ascii.spl.
- if (strstr((char *)path_tail(wfname), SPL_FNAME_ASCII) != NULL)
+ if (strstr((char *)path_tail(wfname), SPL_FNAME_ASCII) != NULL) {
spin.si_ascii = true;
+ }
// Check for .add.spl.
- if (strstr((char *)path_tail(wfname), SPL_FNAME_ADD) != NULL)
+ if (strstr((char *)path_tail(wfname), SPL_FNAME_ADD) != NULL) {
spin.si_add = true;
+ }
}
if (incount <= 0) {
@@ -5184,8 +5378,9 @@ mkspell (
// one in the .spl file if the .aff file doesn't define one. That's
// better than guessing the contents, the table will match a
// previously loaded spell file.
- if (!spin.si_add)
+ if (!spin.si_add) {
spin.si_clear_chartab = true;
+ }
// Read all the .aff and .dic files.
// Text is converted to 'encoding'.
@@ -5199,28 +5394,31 @@ mkspell (
// Read the .aff file. Will init "spin->si_conv" based on the
// "SET" line.
afile[i] = spell_read_aff(&spin, fname);
- if (afile[i] == NULL)
+ if (afile[i] == NULL) {
error = true;
- else {
+ } else {
// Read the .dic file and store the words in the trees.
vim_snprintf((char *)fname, MAXPATHL, "%s.dic",
- innames[i]);
- if (spell_read_dic(&spin, fname, afile[i]) == FAIL)
+ innames[i]);
+ if (spell_read_dic(&spin, fname, afile[i]) == FAIL) {
error = true;
+ }
}
} else {
// No .aff file, try reading the file as a word list. Store
// the words in the trees.
- if (spell_read_wordfile(&spin, innames[i]) == FAIL)
+ if (spell_read_wordfile(&spin, innames[i]) == FAIL) {
error = true;
+ }
}
// Free any conversion stuff.
convert_setup(&spin.si_conv, NULL, NULL);
}
- if (spin.si_compflags != NULL && spin.si_nobreak)
+ if (spin.si_compflags != NULL && spin.si_nobreak) {
MSG(_("Warning: both compounding and NOBREAK specified"));
+ }
if (!error && !got_int) {
// Combine tails in the tree.
@@ -5240,12 +5438,13 @@ mkspell (
spell_message(&spin, (char_u *)_("Done!"));
vim_snprintf((char *)IObuff, IOSIZE,
- _("Estimated runtime memory use: %d bytes"), spin.si_memtot);
+ _("Estimated runtime memory use: %d bytes"), spin.si_memtot);
spell_message(&spin, IObuff);
// If the file is loaded need to reload it.
- if (!error)
+ if (!error) {
spell_reload_one(wfname, added_word);
+ }
}
// Free the allocated memory.
@@ -5258,18 +5457,20 @@ mkspell (
hash_clear_all(&spin.si_commonwords, 0);
// Free the .aff file structures.
- for (i = 0; i < incount; ++i)
- if (afile[i] != NULL)
+ for (i = 0; i < incount; ++i) {
+ if (afile[i] != NULL) {
spell_free_aff(afile[i]);
+ }
+ }
// Free all the bits and pieces at once.
free_blocks(spin.si_blocks);
// If there is soundfolding info and no NOSUGFILE item create the
// .sug file with the soundfolded word trie.
- if (spin.si_sugtime != 0 && !error && !got_int)
+ if (spin.si_sugtime != 0 && !error && !got_int) {
spell_make_sugfile(&spin, wfname);
-
+ }
}
theend:
@@ -5283,12 +5484,14 @@ static void spell_message(const spellinfo_T *spin, char_u *str)
FUNC_ATTR_NONNULL_ALL
{
if (spin->si_verbose || p_verbose > 2) {
- if (!spin->si_verbose)
+ if (!spin->si_verbose) {
verbose_enter();
+ }
MSG(str);
ui_flush();
- if (!spin->si_verbose)
+ if (!spin->si_verbose) {
verbose_leave();
+ }
}
}
@@ -5305,32 +5508,29 @@ void ex_spell(exarg_T *eap)
eap->cmdidx == CMD_spellundo);
}
-// Add "word[len]" to 'spellfile' as a good or bad word.
-void
-spell_add_word (
- char_u *word,
- int len,
- SpellAddType what, // SPELL_ADD_ values
- int idx, // "zG" and "zW": zero, otherwise index in
- // 'spellfile'
- bool undo // true for "zug", "zuG", "zuw" and "zuW"
-)
+/// Add "word[len]" to 'spellfile' as a good or bad word.
+///
+/// @param what SPELL_ADD_ values
+/// @param idx "zG" and "zW": zero, otherwise index in 'spellfile'
+/// @param bool // true for "zug", "zuG", "zuw" and "zuW"
+void spell_add_word(char_u *word, int len, SpellAddType what, int idx, bool undo)
{
- FILE *fd = NULL;
- buf_T *buf = NULL;
+ FILE *fd = NULL;
+ buf_T *buf = NULL;
bool new_spf = false;
- char_u *fname;
- char_u *fnamebuf = NULL;
+ char_u *fname;
+ char_u *fnamebuf = NULL;
char_u line[MAXWLEN * 2];
long fpos, fpos_next = 0;
int i;
- char_u *spf;
+ char_u *spf;
if (idx == 0) { // use internal wordlist
if (int_wordlist == NULL) {
int_wordlist = vim_tempname();
- if (int_wordlist == NULL)
+ if (int_wordlist == NULL) {
return;
+ }
}
fname = int_wordlist;
} else {
@@ -5348,8 +5548,9 @@ spell_add_word (
for (spf = curwin->w_s->b_p_spf, i = 1; *spf != NUL; ++i) {
copy_option_part(&spf, fnamebuf, MAXPATHL, ",");
- if (i == idx)
+ if (i == idx) {
break;
+ }
if (*spf == NUL) {
EMSGN(_("E765: 'spellfile' does not have %" PRId64 " entries"), idx);
xfree(fnamebuf);
@@ -5359,8 +5560,9 @@ spell_add_word (
// Check that the user isn't editing the .add file somewhere.
buf = buflist_findname_exp(fnamebuf);
- if (buf != NULL && buf->b_ml.ml_mfp == NULL)
+ if (buf != NULL && buf->b_ml.ml_mfp == NULL) {
buf = NULL;
+ }
if (buf != NULL && bufIsChanged(buf)) {
EMSG(_(e_bufloaded));
xfree(fnamebuf);
@@ -5402,8 +5604,9 @@ spell_add_word (
}
}
}
- if (fd != NULL)
+ if (fd != NULL) {
fclose(fd);
+ }
}
}
@@ -5450,8 +5653,9 @@ spell_add_word (
mkspell(1, &fname, false, true, true);
// If the .add file is edited somewhere, reload it.
- if (buf != NULL)
+ if (buf != NULL) {
buf_reload(buf, buf->b_orig_mode);
+ }
redraw_all_later(SOME_VALID);
}
@@ -5461,13 +5665,13 @@ spell_add_word (
// Initialize 'spellfile' for the current buffer.
static void init_spellfile(void)
{
- char_u *buf;
+ char_u *buf;
int l;
- char_u *fname;
- char_u *rtp;
- char_u *lend;
+ char_u *fname;
+ char_u *rtp;
+ char_u *lend;
bool aspath = false;
- char_u *lstart = curbuf->b_s.b_p_spl;
+ char_u *lstart = curbuf->b_s.b_p_spl;
if (*curwin->w_s->b_p_spl != NUL && !GA_EMPTY(&curwin->w_s->b_langp)) {
buf = xmalloc(MAXPATHL);
@@ -5475,31 +5679,33 @@ static void init_spellfile(void)
// Find the end of the language name. Exclude the region. If there
// is a path separator remember the start of the tail.
for (lend = curwin->w_s->b_p_spl; *lend != NUL
- && vim_strchr((char_u *)",._", *lend) == NULL; ++lend)
+ && vim_strchr((char_u *)",._", *lend) == NULL; ++lend) {
if (vim_ispathsep(*lend)) {
aspath = true;
lstart = lend + 1;
}
+ }
// Loop over all entries in 'runtimepath'. Use the first one where we
// are allowed to write.
rtp = p_rtp;
while (*rtp != NUL) {
- if (aspath)
+ if (aspath) {
// Use directory of an entry with path, e.g., for
// "/dir/lg.utf-8.spl" use "/dir".
STRLCPY(buf, curbuf->b_s.b_p_spl,
- lstart - curbuf->b_s.b_p_spl);
- else
+ lstart - curbuf->b_s.b_p_spl);
+ } else {
// Copy the path from 'runtimepath' to buf[].
copy_option_part(&rtp, buf, MAXPATHL, ",");
+ }
if (os_file_is_writable((char *)buf) == 2) {
// Use the first language name from 'spelllang' and the
// encoding used in the first loaded .spl file.
- if (aspath)
+ if (aspath) {
STRLCPY(buf, curbuf->b_s.b_p_spl,
- lend - curbuf->b_s.b_p_spl + 1);
- else {
+ lend - curbuf->b_s.b_p_spl + 1);
+ } else {
// Create the "spell" directory if it doesn't exist yet.
l = (int)STRLEN(buf);
vim_snprintf((char *)buf + l, MAXPATHL - l, "/spell");
@@ -5509,7 +5715,7 @@ static void init_spellfile(void)
l = (int)STRLEN(buf);
vim_snprintf((char *)buf + l, MAXPATHL - l,
- "/%.*s", (int)(lend - lstart), lstart);
+ "/%.*s", (int)(lend - lstart), lstart);
}
l = (int)STRLEN(buf);
fname = LANGP_ENTRY(curwin->w_s->b_langp, 0)
@@ -5529,19 +5735,16 @@ static void init_spellfile(void)
}
}
-// Set the spell character tables from strings in the .spl file.
-static void
-set_spell_charflags (
- char_u *flags,
- int cnt, // length of "flags"
- char_u *fol
-)
+/// Set the spell character tables from strings in the .spl file.
+///
+/// @param cnt length of "flags"
+static void set_spell_charflags(char_u *flags, int cnt, char_u *fol)
{
// We build the new tables here first, so that we can compare with the
// previous one.
spelltab_T new_st;
int i;
- char_u *p = fol;
+ char_u *p = fol;
int c;
clear_spell_chartab(&new_st);
@@ -5555,8 +5758,9 @@ set_spell_charflags (
if (*p != NUL) {
c = mb_ptr2char_adv((const char_u **)&p);
new_st.st_fold[i + 128] = c;
- if (i + 128 != c && new_st.st_isu[i + 128] && c < 256)
+ if (i + 128 != c && new_st.st_isu[i + 128] && c < 256) {
new_st.st_upper[c] = i + 128;
+ }
}
}
@@ -5593,9 +5797,9 @@ static int write_spell_prefcond(FILE *fd, garray_T *gap)
{
assert(gap->ga_len >= 0);
- if (fd != NULL)
+ if (fd != NULL) {
put_bytes(fd, (uintmax_t)gap->ga_len, 2); // <prefcondcnt>
-
+ }
size_t totlen = 2 + (size_t)gap->ga_len; // <prefcondcnt> and <condlen> bytes
size_t x = 1; // collect return value of fwrite()
for (int i = 0; i < gap->ga_len; ++i) {
@@ -5609,8 +5813,9 @@ static int write_spell_prefcond(FILE *fd, garray_T *gap)
x &= fwrite(p, len, 1, fd);
}
totlen += len;
- } else if (fd != NULL)
+ } else if (fd != NULL) {
fputc(0, fd);
+ }
}
assert(totlen <= INT_MAX);
@@ -5620,7 +5825,7 @@ static int write_spell_prefcond(FILE *fd, garray_T *gap)
// Use map string "map" for languages "lp".
static void set_map_str(slang_T *lp, char_u *map)
{
- char_u *p;
+ char_u *p;
int headc = 0;
int c;
int i;
@@ -5632,8 +5837,9 @@ static void set_map_str(slang_T *lp, char_u *map)
lp->sl_has_map = true;
// Init the array and hash tables empty.
- for (i = 0; i < 256; ++i)
+ for (i = 0; i < 256; ++i) {
lp->sl_map_array[i] = 0;
+ }
hash_init(&lp->sl_map_hash);
// The similar characters are stored separated with slashes:
@@ -5654,9 +5860,9 @@ static void set_map_str(slang_T *lp, char_u *map)
if (c >= 256) {
int cl = mb_char2len(c);
int headcl = mb_char2len(headc);
- char_u *b;
+ char_u *b;
hash_T hash;
- hashitem_T *hi;
+ hashitem_T *hi;
b = xmalloc(cl + headcl + 2);
utf_char2bytes(c, b);
@@ -5673,8 +5879,9 @@ static void set_map_str(slang_T *lp, char_u *map)
EMSG(_("E783: duplicate char in MAP entry"));
xfree(b);
}
- } else
+ } else {
lp->sl_map_array[c] = headc;
+ }
}
}
}
diff --git a/src/nvim/spellfile.h b/src/nvim/spellfile.h
index 633ee014a7..235bc07f61 100644
--- a/src/nvim/spellfile.h
+++ b/src/nvim/spellfile.h
@@ -3,9 +3,9 @@
#include <stdbool.h>
+#include "nvim/ex_cmds_defs.h"
#include "nvim/spell_defs.h"
#include "nvim/types.h"
-#include "nvim/ex_cmds_defs.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "spellfile.h.generated.h"
diff --git a/src/nvim/state.c b/src/nvim/state.c
index 02d63d8ab1..4eb0073873 100644
--- a/src/nvim/state.c
+++ b/src/nvim/state.c
@@ -3,19 +3,18 @@
#include <assert.h>
-#include "nvim/lib/kvec.h"
-
#include "nvim/ascii.h"
+#include "nvim/edit.h"
+#include "nvim/ex_docmd.h"
+#include "nvim/getchar.h"
+#include "nvim/lib/kvec.h"
#include "nvim/log.h"
-#include "nvim/state.h"
-#include "nvim/vim.h"
#include "nvim/main.h"
-#include "nvim/getchar.h"
#include "nvim/option_defs.h"
-#include "nvim/ui.h"
#include "nvim/os/input.h"
-#include "nvim/ex_docmd.h"
-#include "nvim/edit.h"
+#include "nvim/state.h"
+#include "nvim/ui.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "state.c.generated.h"
@@ -162,6 +161,11 @@ char *get_mode(void)
if (State & VREPLACE_FLAG) {
buf[0] = 'R';
buf[1] = 'v';
+ if (ins_compl_active()) {
+ buf[2] = 'c';
+ } else if (ctrl_x_mode_not_defined_yet()) {
+ buf[2] = 'x';
+ }
} else {
if (State & REPLACE_FLAG) {
buf[0] = 'R';
@@ -191,6 +195,8 @@ char *get_mode(void)
|| restart_edit == 'V') {
buf[1] = 'i';
buf[2] = (char)restart_edit;
+ } else if (curbuf->terminal) {
+ buf[1] = 't';
}
}
diff --git a/src/nvim/state.h b/src/nvim/state.h
index 8027514148..b93d57d035 100644
--- a/src/nvim/state.h
+++ b/src/nvim/state.h
@@ -5,8 +5,8 @@
typedef struct vim_state VimState;
-typedef int(*state_check_callback)(VimState *state);
-typedef int(*state_execute_callback)(VimState *state, int key);
+typedef int (*state_check_callback)(VimState *state);
+typedef int (*state_execute_callback)(VimState *state, int key);
struct vim_state {
state_check_callback check;
diff --git a/src/nvim/strings.c b/src/nvim/strings.c
index 79a3db4843..11c1aa1760 100644
--- a/src/nvim/strings.c
+++ b/src/nvim/strings.c
@@ -1,28 +1,26 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+#include <assert.h>
#include <inttypes.h>
+#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <string.h>
-#include <math.h>
-#include <assert.h>
-#include "nvim/assert.h"
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/strings.h"
-#include "nvim/file_search.h"
+#include "nvim/assert.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/diff.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
+#include "nvim/eval/encode.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
+#include "nvim/file_search.h"
#include "nvim/fileio.h"
-#include "nvim/func_attr.h"
#include "nvim/fold.h"
#include "nvim/func_attr.h"
#include "nvim/getchar.h"
@@ -35,8 +33,10 @@
#include "nvim/message.h"
#include "nvim/misc1.h"
#include "nvim/move.h"
-#include "nvim/option.h"
#include "nvim/ops.h"
+#include "nvim/option.h"
+#include "nvim/os/os.h"
+#include "nvim/os/shell.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/quickfix.h"
@@ -44,12 +44,11 @@
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/spell.h"
+#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/tag.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/os/os.h"
-#include "nvim/os/shell.h"
-#include "nvim/eval/encode.h"
/// Copy "string" into newly allocated memory.
char_u *vim_strsave(const char_u *string)
@@ -84,8 +83,7 @@ char_u *vim_strsave_escaped(const char_u *string, const char_u *esc_chars)
* characters where rem_backslash() would remove the backslash.
* Escape the characters with "cc".
*/
-char_u *vim_strsave_escaped_ext(const char_u *string, const char_u *esc_chars,
- char_u cc, bool bsl)
+char_u *vim_strsave_escaped_ext(const char_u *string, const char_u *esc_chars, char_u cc, bool bsl)
FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
/*
@@ -100,9 +98,10 @@ char_u *vim_strsave_escaped_ext(const char_u *string, const char_u *esc_chars,
p += l - 1;
continue;
}
- if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p)))
- ++length; /* count a backslash */
- ++length; /* count an ordinary char */
+ if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p))) {
+ ++length; // count a backslash
+ }
+ ++length; // count an ordinary char
}
char_u *escaped_string = xmalloc(length);
@@ -112,11 +111,12 @@ char_u *vim_strsave_escaped_ext(const char_u *string, const char_u *esc_chars,
if (l > 1) {
memcpy(p2, p, l);
p2 += l;
- p += l - 1; /* skip multibyte char */
+ p += l - 1; // skip multibyte char
continue;
}
- if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p)))
+ if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p))) {
*p2++ = cc;
+ }
*p2++ = *p;
}
*p2 = NUL;
@@ -182,12 +182,11 @@ char *vim_strnsave_unquoted(const char *const string, const size_t length)
* When "do_newline" is false do not escape newline unless it is csh shell.
* Returns the result in allocated memory.
*/
-char_u *vim_strsave_shellescape(const char_u *string,
- bool do_special, bool do_newline)
+char_u *vim_strsave_shellescape(const char_u *string, bool do_special, bool do_newline)
FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
- char_u *d;
- char_u *escaped_string;
+ char_u *d;
+ char_u *escaped_string;
size_t l;
int csh_like;
bool fish_like;
@@ -202,7 +201,7 @@ char_u *vim_strsave_shellescape(const char_u *string,
// itself must be escaped to get a literal '\'.
fish_like = fish_like_shell();
- /* First count the number of extra bytes required. */
+ // First count the number of extra bytes required.
size_t length = STRLEN(string) + 3; // two quotes and a trailing NUL
for (const char_u *p = string; *p != NUL; MB_PTR_ADV(p)) {
#ifdef WIN32
@@ -217,12 +216,13 @@ char_u *vim_strsave_shellescape(const char_u *string,
}
if ((*p == '\n' && (csh_like || do_newline))
|| (*p == '!' && (csh_like || do_special))) {
- ++length; /* insert backslash */
- if (csh_like && do_special)
- ++length; /* insert backslash */
+ ++length; // insert backslash
+ if (csh_like && do_special) {
+ ++length; // insert backslash
+ }
}
if (do_special && find_cmdline_var(p, &l) >= 0) {
- ++length; /* insert backslash */
+ ++length; // insert backslash
p += l - 1;
}
if (*p == '\\' && fish_like) {
@@ -230,7 +230,7 @@ char_u *vim_strsave_shellescape(const char_u *string,
}
}
- /* Allocate memory for the result and fill it. */
+ // Allocate memory for the result and fill it.
escaped_string = xmalloc(length);
d = escaped_string;
@@ -264,15 +264,17 @@ char_u *vim_strsave_shellescape(const char_u *string,
if ((*p == '\n' && (csh_like || do_newline))
|| (*p == '!' && (csh_like || do_special))) {
*d++ = '\\';
- if (csh_like && do_special)
+ if (csh_like && do_special) {
*d++ = '\\';
+ }
*d++ = *p++;
continue;
}
if (do_special && find_cmdline_var(p, &l) >= 0) {
- *d++ = '\\'; /* insert backslash */
- while (--l != SIZE_MAX) /* copy the var */
+ *d++ = '\\'; // insert backslash
+ while (--l != SIZE_MAX) { // copy the var
*d++ = *p++;
+ }
continue;
}
if (*p == '\\' && fish_like) {
@@ -285,11 +287,11 @@ char_u *vim_strsave_shellescape(const char_u *string,
}
// add terminating quote and finish with a NUL
-# ifdef WIN32
+#ifdef WIN32
if (!p_ssl) {
*d++ = '"';
} else
-# endif
+#endif
*d++ = '\'';
*d = NUL;
@@ -384,11 +386,12 @@ char *strcase_save(const char *const orig, bool upper)
void del_trailing_spaces(char_u *ptr)
FUNC_ATTR_NONNULL_ALL
{
- char_u *q;
+ char_u *q;
q = ptr + STRLEN(ptr);
- while (--q > ptr && ascii_iswhite(q[0]) && q[-1] != '\\' && q[-1] != Ctrl_V)
+ while (--q > ptr && ascii_iswhite(q[0]) && q[-1] != '\\' && q[-1] != Ctrl_V) {
*q = NUL;
+ }
}
#if (!defined(HAVE_STRCASECMP) && !defined(HAVE_STRICMP))
@@ -404,14 +407,16 @@ int vim_stricmp(const char *s1, const char *s2)
for (;; ) {
i = (int)TOLOWER_LOC(*s1) - (int)TOLOWER_LOC(*s2);
- if (i != 0)
- return i; /* this character different */
- if (*s1 == NUL)
- break; /* strings match until NUL */
+ if (i != 0) {
+ return i; // this character different
+ }
+ if (*s1 == NUL) {
+ break; // strings match until NUL
+ }
++s1;
++s2;
}
- return 0; /* strings match */
+ return 0; // strings match
}
#endif
@@ -428,15 +433,17 @@ int vim_strnicmp(const char *s1, const char *s2, size_t len)
while (len > 0) {
i = (int)TOLOWER_LOC(*s1) - (int)TOLOWER_LOC(*s2);
- if (i != 0)
- return i; /* this character different */
- if (*s1 == NUL)
- break; /* strings match until NUL */
+ if (i != 0) {
+ return i; // this character different
+ }
+ if (*s1 == NUL) {
+ break; // strings match until NUL
+ }
++s1;
++s2;
--len;
}
- return 0; /* strings match */
+ return 0; // strings match
}
#endif
@@ -490,10 +497,13 @@ bool has_non_ascii(const char_u *s)
{
const char_u *p;
- if (s != NULL)
- for (p = s; *p != NUL; ++p)
- if (*p >= 128)
+ if (s != NULL) {
+ for (p = s; *p != NUL; ++p) {
+ if (*p >= 128) {
return true;
+ }
+ }
+ }
return false;
}
@@ -504,7 +514,7 @@ bool has_non_ascii_len(const char *const s, const size_t len)
{
if (s != NULL) {
for (size_t i = 0; i < len; i++) {
- if ((uint8_t) s[i] >= 128) {
+ if ((uint8_t)s[i] >= 128) {
return true;
}
}
@@ -527,7 +537,7 @@ char_u *concat_str(const char_u *restrict str1, const char_u *restrict str2)
static const char *const e_printf =
- N_("E766: Insufficient arguments for printf()");
+ N_("E766: Insufficient arguments for printf()");
/// Get number argument from idxp entry in tvs
///
@@ -606,15 +616,14 @@ static const void *tv_ptr(const typval_T *const tvs, int *const idxp)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
#define OFF(attr) offsetof(union typval_vval_union, attr)
- STATIC_ASSERT(
- OFF(v_string) == OFF(v_list)
- && OFF(v_string) == OFF(v_dict)
- && OFF(v_string) == OFF(v_partial)
- && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_list)
- && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_dict)
- && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_partial),
- "Strings, dictionaries, lists and partials are expected to be pointers, "
- "so that all three of them can be accessed via v_string");
+ STATIC_ASSERT(OFF(v_string) == OFF(v_list)
+ && OFF(v_string) == OFF(v_dict)
+ && OFF(v_string) == OFF(v_partial)
+ && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_list)
+ && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_dict)
+ && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_partial),
+ "Strings, dictionaries, lists and partials are expected to be pointers, "
+ "so that all three of them can be accessed via v_string");
#undef OFF
const int idx = *idxp - 1;
if (tvs[idx].v_type == VAR_UNKNOWN) {
@@ -735,8 +744,8 @@ int vim_snprintf(char *str, size_t str_m, const char *fmt, ...)
// Return the representation of infinity for printf() function:
// "-inf", "inf", "+inf", " inf", "-INF", "INF", "+INF" or " INF".
-static const char *infinity_str(bool positive, char fmt_spec,
- int force_sign, int space_for_positive)
+static const char *infinity_str(bool positive, char fmt_spec, int force_sign,
+ int space_for_positive)
{
static const char *table[] = {
"-inf", "inf", "+inf", " inf",
@@ -765,8 +774,7 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap)
///
/// @return Number of bytes excluding NUL byte that would be written to the
/// string if str_m was greater or equal to the return value.
-int vim_vsnprintf_typval(
- char *str, size_t str_m, const char *fmt, va_list ap, typval_T *const tvs)
+int vim_vsnprintf_typval(char *str, size_t str_m, const char *fmt, va_list ap, typval_T *const tvs)
{
size_t str_l = 0;
bool str_avail = str_l < str_m;
@@ -800,7 +808,7 @@ int vim_vsnprintf_typval(
char length_modifier = '\0';
// temporary buffer for simple numeric->string conversion
-# define TMP_LEN 350 // 1e308 seems reasonable as the maximum printable
+#define TMP_LEN 350 // 1e308 seems reasonable as the maximum printable
char tmp[TMP_LEN];
// string address in case of string argument
@@ -832,15 +840,22 @@ int vim_vsnprintf_typval(
// parse flags
while (true) {
switch (*p) {
- case '0': zero_padding = 1; p++; continue;
- case '-': justify_left = 1; p++; continue;
- // if both '0' and '-' flags appear, '0' should be ignored
- case '+': force_sign = 1; space_for_positive = 0; p++; continue;
- case ' ': force_sign = 1; p++; continue;
- // if both ' ' and '+' flags appear, ' ' should be ignored
- case '#': alternate_form = 1; p++; continue;
- case '\'': p++; continue;
- default: break;
+ case '0':
+ zero_padding = 1; p++; continue;
+ case '-':
+ justify_left = 1; p++; continue;
+ // if both '0' and '-' flags appear, '0' should be ignored
+ case '+':
+ force_sign = 1; space_for_positive = 0; p++; continue;
+ case ' ':
+ force_sign = 1; p++; continue;
+ // if both ' ' and '+' flags appear, ' ' should be ignored
+ case '#':
+ alternate_form = 1; p++; continue;
+ case '\'':
+ p++; continue;
+ default:
+ break;
}
break;
}
@@ -905,444 +920,447 @@ int vim_vsnprintf_typval(
// common synonyms
switch (fmt_spec) {
- case 'i': fmt_spec = 'd'; break;
- case 'D': fmt_spec = 'd'; length_modifier = 'l'; break;
- case 'U': fmt_spec = 'u'; length_modifier = 'l'; break;
- case 'O': fmt_spec = 'o'; length_modifier = 'l'; break;
- default: break;
+ case 'i':
+ fmt_spec = 'd'; break;
+ case 'D':
+ fmt_spec = 'd'; length_modifier = 'l'; break;
+ case 'U':
+ fmt_spec = 'u'; length_modifier = 'l'; break;
+ case 'O':
+ fmt_spec = 'o'; length_modifier = 'l'; break;
+ default:
+ break;
}
switch (fmt_spec) {
- case 'b': case 'B':
- case 'd': case 'u': case 'o': case 'x': case 'X':
- if (tvs && length_modifier == '\0') {
- length_modifier = '2';
- }
+ case 'b':
+ case 'B':
+ case 'd':
+ case 'u':
+ case 'o':
+ case 'x':
+ case 'X':
+ if (tvs && length_modifier == '\0') {
+ length_modifier = '2';
+ }
}
// get parameter value, do initial processing
switch (fmt_spec) {
- // '%' and 'c' behave similar to 's' regarding flags and field widths
- case '%': case 'c': case 's': case 'S':
- str_arg_l = 1;
- switch (fmt_spec) {
- case '%':
- str_arg = p;
- break;
-
- case 'c': {
- const int j = tvs ? (int)tv_nr(tvs, &arg_idx) : va_arg(ap, int);
- // standard demands unsigned char
- uchar_arg = (unsigned char)j;
- str_arg = (char *)&uchar_arg;
- break;
- }
+ // '%' and 'c' behave similar to 's' regarding flags and field widths
+ case '%':
+ case 'c':
+ case 's':
+ case 'S':
+ str_arg_l = 1;
+ switch (fmt_spec) {
+ case '%':
+ str_arg = p;
+ break;
- case 's':
- case 'S':
- str_arg = tvs ? tv_str(tvs, &arg_idx, &tofree)
- : va_arg(ap, const char *);
- if (!str_arg) {
- str_arg = "[NULL]";
- str_arg_l = 6;
- } else if (!precision_specified) {
- // make sure not to address string beyond the specified
- // precision
- str_arg_l = strlen(str_arg);
- } else if (precision == 0) {
- // truncate string if necessary as requested by precision
- str_arg_l = 0;
- } else {
- // memchr on HP does not like n > 2^31
- // TODO(elmart): check if this still holds / is relevant
- str_arg_l = (size_t)((char *)xmemscan(str_arg,
- NUL,
- MIN(precision,
- 0x7fffffff))
- - str_arg);
- }
- if (fmt_spec == 'S') {
- if (min_field_width != 0) {
- min_field_width += (strlen(str_arg)
- - mb_string2cells((char_u *)str_arg));
- }
- if (precision) {
- char_u *p1;
- size_t i = 0;
-
- for (p1 = (char_u *)str_arg; *p1;
- p1 += mb_ptr2len(p1)) {
- i += (size_t)utf_ptr2cells(p1);
- if (i > precision) {
- break;
- }
- }
- str_arg_l = (size_t)(p1 - (char_u *)str_arg);
+ case 'c': {
+ const int j = tvs ? (int)tv_nr(tvs, &arg_idx) : va_arg(ap, int);
+ // standard demands unsigned char
+ uchar_arg = (unsigned char)j;
+ str_arg = (char *)&uchar_arg;
+ break;
+ }
+
+ case 's':
+ case 'S':
+ str_arg = tvs ? tv_str(tvs, &arg_idx, &tofree)
+ : va_arg(ap, const char *);
+ if (!str_arg) {
+ str_arg = "[NULL]";
+ str_arg_l = 6;
+ } else if (!precision_specified) {
+ // make sure not to address string beyond the specified
+ // precision
+ str_arg_l = strlen(str_arg);
+ } else if (precision == 0) {
+ // truncate string if necessary as requested by precision
+ str_arg_l = 0;
+ } else {
+ // memchr on HP does not like n > 2^31
+ // TODO(elmart): check if this still holds / is relevant
+ str_arg_l = (size_t)((char *)xmemscan(str_arg,
+ NUL,
+ MIN(precision,
+ 0x7fffffff))
+ - str_arg);
+ }
+ if (fmt_spec == 'S') {
+ if (min_field_width != 0) {
+ min_field_width += (strlen(str_arg)
+ - mb_string2cells((char_u *)str_arg));
+ }
+ if (precision) {
+ char_u *p1;
+ size_t i = 0;
+
+ for (p1 = (char_u *)str_arg; *p1;
+ p1 += mb_ptr2len(p1)) {
+ i += (size_t)utf_ptr2cells(p1);
+ if (i > precision) {
+ break;
}
}
- break;
-
- default:
- break;
+ str_arg_l = (size_t)(p1 - (char_u *)str_arg);
+ }
}
break;
- case 'd':
- case 'u':
- case 'b': case 'B':
- case 'o':
- case 'x': case 'X':
- case 'p': {
- // u, b, B, o, x, X and p conversion specifiers imply
- // the value is unsigned; d implies a signed value
-
- // 0 if numeric argument is zero (or if pointer is NULL for 'p'),
- // +1 if greater than zero (or non NULL for 'p'),
- // -1 if negative (unsigned argument is never negative)
- int arg_sign = 0;
-
- intmax_t arg = 0;
- uintmax_t uarg = 0;
-
- // only defined for p conversion
- const void *ptr_arg = NULL;
-
- if (fmt_spec == 'p') {
- ptr_arg = tvs ? tv_ptr(tvs, &arg_idx) : va_arg(ap, void *);
- if (ptr_arg) {
- arg_sign = 1;
- }
- } else if (fmt_spec == 'd') {
- // signed
- switch (length_modifier) {
- case '\0': {
- arg = (int)(tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, int));
- break;
- }
- case 'h': {
- // char and short arguments are passed as int16_t
- arg = (int16_t)(tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, int));
- break;
- }
- case 'l': {
- arg = (tvs ? (long)tv_nr(tvs, &arg_idx) : va_arg(ap, long));
- break;
- }
- case '2': {
- arg = (
- tvs
+ default:
+ break;
+ }
+ break;
+
+ case 'd':
+ case 'u':
+ case 'b':
+ case 'B':
+ case 'o':
+ case 'x':
+ case 'X':
+ case 'p': {
+ // u, b, B, o, x, X and p conversion specifiers imply
+ // the value is unsigned; d implies a signed value
+
+ // 0 if numeric argument is zero (or if pointer is NULL for 'p'),
+ // +1 if greater than zero (or non NULL for 'p'),
+ // -1 if negative (unsigned argument is never negative)
+ int arg_sign = 0;
+
+ intmax_t arg = 0;
+ uintmax_t uarg = 0;
+
+ // only defined for p conversion
+ const void *ptr_arg = NULL;
+
+ if (fmt_spec == 'p') {
+ ptr_arg = tvs ? tv_ptr(tvs, &arg_idx) : va_arg(ap, void *);
+ if (ptr_arg) {
+ arg_sign = 1;
+ }
+ } else if (fmt_spec == 'd') {
+ // signed
+ switch (length_modifier) {
+ case '\0':
+ arg = (int)(tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, int));
+ break;
+ case 'h':
+ // char and short arguments are passed as int16_t
+ arg = (int16_t)(tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, int));
+ break;
+ case 'l':
+ arg = (tvs ? (long)tv_nr(tvs, &arg_idx) : va_arg(ap, long));
+ break;
+ case '2':
+ arg = (
+ tvs
? (long long)tv_nr(tvs, &arg_idx) // NOLINT (runtime/int)
: va_arg(ap, long long)); // NOLINT (runtime/int)
- break;
- }
- case 'z': {
- arg = (tvs
+ break;
+ case 'z':
+ arg = (tvs
? (ptrdiff_t)tv_nr(tvs, &arg_idx)
: va_arg(ap, ptrdiff_t));
- break;
- }
- }
- if (arg > 0) {
- arg_sign = 1;
- } else if (arg < 0) {
- arg_sign = -1;
- }
- } else {
- // unsigned
- switch (length_modifier) {
- case '\0': {
- uarg = (unsigned int)(tvs
+ break;
+ }
+ if (arg > 0) {
+ arg_sign = 1;
+ } else if (arg < 0) {
+ arg_sign = -1;
+ }
+ } else {
+ // unsigned
+ switch (length_modifier) {
+ case '\0':
+ uarg = (unsigned int)(tvs
? tv_nr(tvs, &arg_idx)
: va_arg(ap, unsigned int));
- break;
- }
- case 'h': {
- uarg = (uint16_t)(tvs
+ break;
+ case 'h':
+ uarg = (uint16_t)(tvs
? tv_nr(tvs, &arg_idx)
: va_arg(ap, unsigned int));
- break;
- }
- case 'l': {
- uarg = (tvs
+ break;
+ case 'l':
+ uarg = (tvs
? (unsigned long)tv_nr(tvs, &arg_idx)
: va_arg(ap, unsigned long));
- break;
- }
- case '2': {
- uarg = (uintmax_t)(unsigned long long)( // NOLINT (runtime/int)
- tvs
+ break;
+ case '2':
+ uarg = (uintmax_t)(unsigned long long)( // NOLINT (runtime/int)
+ tvs
? ((unsigned long long) // NOLINT (runtime/int)
tv_nr(tvs, &arg_idx))
: va_arg(ap, unsigned long long)); // NOLINT (runtime/int)
- break;
- }
- case 'z': {
- uarg = (tvs
+ break;
+ case 'z':
+ uarg = (tvs
? (size_t)tv_nr(tvs, &arg_idx)
: va_arg(ap, size_t));
- break;
- }
- }
- arg_sign = (uarg != 0);
+ break;
}
+ arg_sign = (uarg != 0);
+ }
- str_arg = tmp;
- str_arg_l = 0;
+ str_arg = tmp;
+ str_arg_l = 0;
- // For d, i, u, o, x, and X conversions, if precision is specified,
- // '0' flag should be ignored. This is so with Solaris 2.6, Digital
- // UNIX 4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with Perl.
- if (precision_specified) {
- zero_padding = 0;
- }
+ // For d, i, u, o, x, and X conversions, if precision is specified,
+ // '0' flag should be ignored. This is so with Solaris 2.6, Digital
+ // UNIX 4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with Perl.
+ if (precision_specified) {
+ zero_padding = 0;
+ }
- if (fmt_spec == 'd') {
- if (force_sign && arg_sign >= 0) {
- tmp[str_arg_l++] = space_for_positive ? ' ' : '+';
- }
- // leave negative numbers for snprintf to handle, to
- // avoid handling tricky cases like (short int)-32768
- } else if (alternate_form) {
- if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X'
- || fmt_spec == 'b' || fmt_spec == 'B')) {
- tmp[str_arg_l++] = '0';
- tmp[str_arg_l++] = fmt_spec;
- }
- // alternate form should have no effect for p * conversion, but ...
+ if (fmt_spec == 'd') {
+ if (force_sign && arg_sign >= 0) {
+ tmp[str_arg_l++] = space_for_positive ? ' ' : '+';
}
-
- zero_padding_insertion_ind = str_arg_l;
- if (!precision_specified) {
- precision = 1; // default precision is 1
+ // leave negative numbers for snprintf to handle, to
+ // avoid handling tricky cases like (short int)-32768
+ } else if (alternate_form) {
+ if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X'
+ || fmt_spec == 'b' || fmt_spec == 'B')) {
+ tmp[str_arg_l++] = '0';
+ tmp[str_arg_l++] = fmt_spec;
}
- if (precision == 0 && arg_sign == 0) {
- // when zero value is formatted with an explicit precision 0,
- // resulting formatted string is empty (d, i, u, b, B, o, x, X, p)
- } else {
- switch (fmt_spec) {
- case 'p': { // pointer
- str_arg_l += (size_t)snprintf(tmp + str_arg_l,
- sizeof(tmp) - str_arg_l,
- "%p", ptr_arg);
- break;
- }
- case 'd': { // signed
- str_arg_l += (size_t)snprintf(tmp + str_arg_l,
- sizeof(tmp) - str_arg_l,
- "%" PRIdMAX, arg);
- break;
- }
- case 'b': case 'B': { // binary
- size_t bits = 0;
- for (bits = sizeof(uintmax_t) * 8; bits > 0; bits--) {
- if ((uarg >> (bits - 1)) & 0x1) {
- break;
- }
- }
+ // alternate form should have no effect for p * conversion, but ...
+ }
- while (bits > 0) {
- tmp[str_arg_l++] = ((uarg >> --bits) & 0x1) ? '1' : '0';
- }
- break;
- }
- default: { // unsigned
- // construct a simple format string for snprintf
- char f[] = "%" PRIuMAX;
- f[sizeof("%" PRIuMAX) - 1 - 1] = fmt_spec;
- assert(PRIuMAX[sizeof(PRIuMAX) - 1 - 1] == 'u');
- str_arg_l += (size_t)snprintf(tmp + str_arg_l,
- sizeof(tmp) - str_arg_l,
- f, uarg);
+ zero_padding_insertion_ind = str_arg_l;
+ if (!precision_specified) {
+ precision = 1; // default precision is 1
+ }
+ if (precision == 0 && arg_sign == 0) {
+ // when zero value is formatted with an explicit precision 0,
+ // resulting formatted string is empty (d, i, u, b, B, o, x, X, p)
+ } else {
+ switch (fmt_spec) {
+ case 'p': // pointer
+ str_arg_l += (size_t)snprintf(tmp + str_arg_l,
+ sizeof(tmp) - str_arg_l,
+ "%p", ptr_arg);
+ break;
+ case 'd': // signed
+ str_arg_l += (size_t)snprintf(tmp + str_arg_l,
+ sizeof(tmp) - str_arg_l,
+ "%" PRIdMAX, arg);
+ break;
+ case 'b':
+ case 'B': { // binary
+ size_t bits = 0;
+ for (bits = sizeof(uintmax_t) * 8; bits > 0; bits--) {
+ if ((uarg >> (bits - 1)) & 0x1) {
break;
}
}
- assert(str_arg_l < sizeof(tmp));
- // include the optional minus sign and possible "0x" in the region
- // before the zero padding insertion point
- if (zero_padding_insertion_ind < str_arg_l
- && tmp[zero_padding_insertion_ind] == '-') {
- zero_padding_insertion_ind++;
- }
- if (zero_padding_insertion_ind + 1 < str_arg_l
- && tmp[zero_padding_insertion_ind] == '0'
- && (tmp[zero_padding_insertion_ind + 1] == 'x'
- || tmp[zero_padding_insertion_ind + 1] == 'X'
- || tmp[zero_padding_insertion_ind + 1] == 'b'
- || tmp[zero_padding_insertion_ind + 1] == 'B')) {
- zero_padding_insertion_ind += 2;
+ while (bits > 0) {
+ tmp[str_arg_l++] = ((uarg >> --bits) & 0x1) ? '1' : '0';
}
+ break;
+ }
+ default: { // unsigned
+ // construct a simple format string for snprintf
+ char f[] = "%" PRIuMAX;
+ f[sizeof("%" PRIuMAX) - 1 - 1] = fmt_spec;
+ assert(PRIuMAX[sizeof(PRIuMAX) - 1 - 1] == 'u');
+ str_arg_l += (size_t)snprintf(tmp + str_arg_l,
+ sizeof(tmp) - str_arg_l,
+ f, uarg);
+ break;
+ }
}
+ assert(str_arg_l < sizeof(tmp));
- {
- size_t num_of_digits = str_arg_l - zero_padding_insertion_ind;
-
- if (alternate_form && fmt_spec == 'o'
- // unless zero is already the first character
- && !(zero_padding_insertion_ind < str_arg_l
- && tmp[zero_padding_insertion_ind] == '0')) {
- // assure leading zero for alternate-form octal numbers
- if (!precision_specified
- || precision < num_of_digits + 1) {
- // precision is increased to force the first character to be
- // zero, except if a zero value is formatted with an explicit
- // precision of zero
- precision = num_of_digits + 1;
- }
- }
- // zero padding to specified precision?
- if (num_of_digits < precision) {
- number_of_zeros_to_pad = precision - num_of_digits;
- }
+ // include the optional minus sign and possible "0x" in the region
+ // before the zero padding insertion point
+ if (zero_padding_insertion_ind < str_arg_l
+ && tmp[zero_padding_insertion_ind] == '-') {
+ zero_padding_insertion_ind++;
}
- // zero padding to specified minimal field width?
- if (!justify_left && zero_padding) {
- const int n = (int)(min_field_width - (str_arg_l
- + number_of_zeros_to_pad));
- if (n > 0) {
- number_of_zeros_to_pad += (size_t)n;
- }
+ if (zero_padding_insertion_ind + 1 < str_arg_l
+ && tmp[zero_padding_insertion_ind] == '0'
+ && (tmp[zero_padding_insertion_ind + 1] == 'x'
+ || tmp[zero_padding_insertion_ind + 1] == 'X'
+ || tmp[zero_padding_insertion_ind + 1] == 'b'
+ || tmp[zero_padding_insertion_ind + 1] == 'B')) {
+ zero_padding_insertion_ind += 2;
}
- break;
}
- case 'f':
- case 'F':
- case 'e':
- case 'E':
- case 'g':
- case 'G':
- {
- // floating point
- char format[40];
- int remove_trailing_zeroes = false;
-
- double f = tvs ? tv_float(tvs, &arg_idx) : va_arg(ap, double);
- double abs_f = f < 0 ? -f : f;
-
- if (fmt_spec == 'g' || fmt_spec == 'G') {
- // can't use %g directly, cause it prints "1.0" as "1"
- if ((abs_f >= 0.001 && abs_f < 10000000.0) || abs_f == 0.0) {
- fmt_spec = ASCII_ISUPPER(fmt_spec) ? 'F' : 'f';
- } else {
- fmt_spec = fmt_spec == 'g' ? 'e' : 'E';
- }
- remove_trailing_zeroes = true;
+ {
+ size_t num_of_digits = str_arg_l - zero_padding_insertion_ind;
+
+ if (alternate_form && fmt_spec == 'o'
+ // unless zero is already the first character
+ && !(zero_padding_insertion_ind < str_arg_l
+ && tmp[zero_padding_insertion_ind] == '0')) {
+ // assure leading zero for alternate-form octal numbers
+ if (!precision_specified
+ || precision < num_of_digits + 1) {
+ // precision is increased to force the first character to be
+ // zero, except if a zero value is formatted with an explicit
+ // precision of zero
+ precision = num_of_digits + 1;
}
+ }
+ // zero padding to specified precision?
+ if (num_of_digits < precision) {
+ number_of_zeros_to_pad = precision - num_of_digits;
+ }
+ }
+ // zero padding to specified minimal field width?
+ if (!justify_left && zero_padding) {
+ const int n = (int)(min_field_width - (str_arg_l
+ + number_of_zeros_to_pad));
+ if (n > 0) {
+ number_of_zeros_to_pad += (size_t)n;
+ }
+ }
+ break;
+ }
- if (xisinf(f)
- || (strchr("fF", fmt_spec) != NULL && abs_f > 1.0e307)) {
- xstrlcpy(tmp, infinity_str(f > 0.0, fmt_spec,
- force_sign, space_for_positive),
- sizeof(tmp));
- str_arg_l = strlen(tmp);
- zero_padding = 0;
- } else if (xisnan(f)) {
- // Not a number: nan or NAN
- memmove(tmp, ASCII_ISUPPER(fmt_spec) ? "NAN" : "nan", 4);
- str_arg_l = 3;
- zero_padding = 0;
- } else {
- // Regular float number
- format[0] = '%';
- size_t l = 1;
- if (force_sign) {
- format[l++] = space_for_positive ? ' ' : '+';
- }
- if (precision_specified) {
- size_t max_prec = TMP_LEN - 10;
+ case 'f':
+ case 'F':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G': {
+ // floating point
+ char format[40];
+ int remove_trailing_zeroes = false;
+
+ double f = tvs ? tv_float(tvs, &arg_idx) : va_arg(ap, double);
+ double abs_f = f < 0 ? -f : f;
+
+ if (fmt_spec == 'g' || fmt_spec == 'G') {
+ // can't use %g directly, cause it prints "1.0" as "1"
+ if ((abs_f >= 0.001 && abs_f < 10000000.0) || abs_f == 0.0) {
+ fmt_spec = ASCII_ISUPPER(fmt_spec) ? 'F' : 'f';
+ } else {
+ fmt_spec = fmt_spec == 'g' ? 'e' : 'E';
+ }
+ remove_trailing_zeroes = true;
+ }
- // make sure we don't get more digits than we have room for
- if ((fmt_spec == 'f' || fmt_spec == 'F') && abs_f > 1.0) {
- max_prec -= (size_t)log10(abs_f);
- }
- if (precision > max_prec) {
- precision = max_prec;
- }
- l += (size_t)snprintf(format + l, sizeof(format) - l, ".%d",
- (int)precision);
- }
+ if (xisinf(f)
+ || (strchr("fF", fmt_spec) != NULL && abs_f > 1.0e307)) {
+ xstrlcpy(tmp, infinity_str(f > 0.0, fmt_spec,
+ force_sign, space_for_positive),
+ sizeof(tmp));
+ str_arg_l = strlen(tmp);
+ zero_padding = 0;
+ } else if (xisnan(f)) {
+ // Not a number: nan or NAN
+ memmove(tmp, ASCII_ISUPPER(fmt_spec) ? "NAN" : "nan", 4);
+ str_arg_l = 3;
+ zero_padding = 0;
+ } else {
+ // Regular float number
+ format[0] = '%';
+ size_t l = 1;
+ if (force_sign) {
+ format[l++] = space_for_positive ? ' ' : '+';
+ }
+ if (precision_specified) {
+ size_t max_prec = TMP_LEN - 10;
- // Cast to char to avoid a conversion warning on Ubuntu 12.04.
- assert(l + 1 < sizeof(format));
- format[l] = (char)(fmt_spec == 'F' ? 'f' : fmt_spec);
- format[l + 1] = NUL;
+ // make sure we don't get more digits than we have room for
+ if ((fmt_spec == 'f' || fmt_spec == 'F') && abs_f > 1.0) {
+ max_prec -= (size_t)log10(abs_f);
+ }
+ if (precision > max_prec) {
+ precision = max_prec;
+ }
+ l += (size_t)snprintf(format + l, sizeof(format) - l, ".%d",
+ (int)precision);
+ }
- str_arg_l = (size_t)snprintf(tmp, sizeof(tmp), format, f);
- assert(str_arg_l < sizeof(tmp));
+ // Cast to char to avoid a conversion warning on Ubuntu 12.04.
+ assert(l + 1 < sizeof(format));
+ format[l] = (char)(fmt_spec == 'F' ? 'f' : fmt_spec);
+ format[l + 1] = NUL;
- if (remove_trailing_zeroes) {
- int i;
- char *tp;
+ str_arg_l = (size_t)snprintf(tmp, sizeof(tmp), format, f);
+ assert(str_arg_l < sizeof(tmp));
- // using %g or %G: remove superfluous zeroes
- if (fmt_spec == 'f' || fmt_spec == 'F') {
- tp = tmp + str_arg_l - 1;
- } else {
- tp = (char *)vim_strchr((char_u *)tmp,
- fmt_spec == 'e' ? 'e' : 'E');
- if (tp) {
- // remove superfluous '+' and leading zeroes from exponent
- if (tp[1] == '+') {
- // change "1.0e+07" to "1.0e07"
- STRMOVE(tp + 1, tp + 2);
- str_arg_l--;
- }
- i = (tp[1] == '-') ? 2 : 1;
- while (tp[i] == '0') {
- // change "1.0e07" to "1.0e7"
- STRMOVE(tp + i, tp + i + 1);
- str_arg_l--;
- }
- tp--;
- }
- }
+ if (remove_trailing_zeroes) {
+ int i;
+ char *tp;
- if (tp != NULL && !precision_specified) {
- // remove trailing zeroes, but keep the one just after a dot
- while (tp > tmp + 2 && *tp == '0' && tp[-1] != '.') {
- STRMOVE(tp, tp + 1);
- tp--;
- str_arg_l--;
- }
+ // using %g or %G: remove superfluous zeroes
+ if (fmt_spec == 'f' || fmt_spec == 'F') {
+ tp = tmp + str_arg_l - 1;
+ } else {
+ tp = (char *)vim_strchr((char_u *)tmp,
+ fmt_spec == 'e' ? 'e' : 'E');
+ if (tp) {
+ // remove superfluous '+' and leading zeroes from exponent
+ if (tp[1] == '+') {
+ // change "1.0e+07" to "1.0e07"
+ STRMOVE(tp + 1, tp + 2);
+ str_arg_l--;
}
- } else {
- // Be consistent: some printf("%e") use 1.0e+12 and some
- // 1.0e+012; remove one zero in the last case.
- char *tp = (char *)vim_strchr((char_u *)tmp,
- fmt_spec == 'e' ? 'e' : 'E');
- if (tp && (tp[1] == '+' || tp[1] == '-') && tp[2] == '0'
- && ascii_isdigit(tp[3]) && ascii_isdigit(tp[4])) {
- STRMOVE(tp + 2, tp + 3);
+ i = (tp[1] == '-') ? 2 : 1;
+ while (tp[i] == '0') {
+ // change "1.0e07" to "1.0e7"
+ STRMOVE(tp + i, tp + i + 1);
str_arg_l--;
}
+ tp--;
}
}
- if (zero_padding && min_field_width > str_arg_l
- && (tmp[0] == '-' || force_sign)) {
- // Padding 0's should be inserted after the sign.
- number_of_zeros_to_pad = min_field_width - str_arg_l;
- zero_padding_insertion_ind = 1;
+
+ if (tp != NULL && !precision_specified) {
+ // remove trailing zeroes, but keep the one just after a dot
+ while (tp > tmp + 2 && *tp == '0' && tp[-1] != '.') {
+ STRMOVE(tp, tp + 1);
+ tp--;
+ str_arg_l--;
+ }
+ }
+ } else {
+ // Be consistent: some printf("%e") use 1.0e+12 and some
+ // 1.0e+012; remove one zero in the last case.
+ char *tp = (char *)vim_strchr((char_u *)tmp,
+ fmt_spec == 'e' ? 'e' : 'E');
+ if (tp && (tp[1] == '+' || tp[1] == '-') && tp[2] == '0'
+ && ascii_isdigit(tp[3]) && ascii_isdigit(tp[4])) {
+ STRMOVE(tp + 2, tp + 3);
+ str_arg_l--;
}
- str_arg = tmp;
- break;
}
+ }
+ if (zero_padding && min_field_width > str_arg_l
+ && (tmp[0] == '-' || force_sign)) {
+ // Padding 0's should be inserted after the sign.
+ number_of_zeros_to_pad = min_field_width - str_arg_l;
+ zero_padding_insertion_ind = 1;
+ }
+ str_arg = tmp;
+ break;
+ }
- default:
- // unrecognized conversion specifier, keep format string as-is
- zero_padding = 0; // turn zero padding off for non-numeric conversion
- justify_left = 1;
- min_field_width = 0; // reset flags
-
- // discard the unrecognized conversion, just keep
- // the unrecognized conversion character
- str_arg = p;
- str_arg_l = 0;
- if (*p) {
- str_arg_l++; // include invalid conversion specifier
- }
- // unchanged if not at end-of-string
- break;
+ default:
+ // unrecognized conversion specifier, keep format string as-is
+ zero_padding = 0; // turn zero padding off for non-numeric conversion
+ justify_left = 1;
+ min_field_width = 0; // reset flags
+
+ // discard the unrecognized conversion, just keep
+ // the unrecognized conversion character
+ str_arg = p;
+ str_arg_l = 0;
+ if (*p) {
+ str_arg_l++; // include invalid conversion specifier
+ }
+ // unchanged if not at end-of-string
+ break;
}
if (*p) {
diff --git a/src/nvim/strings.h b/src/nvim/strings.h
index f2876c6307..893b0ea269 100644
--- a/src/nvim/strings.h
+++ b/src/nvim/strings.h
@@ -1,12 +1,12 @@
#ifndef NVIM_STRINGS_H
#define NVIM_STRINGS_H
-#include <stdbool.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <string.h>
-#include "nvim/types.h"
#include "nvim/eval/typval.h"
+#include "nvim/types.h"
/// Append string to string and return pointer to the next byte
///
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index 10cc2ea9b8..1e14f988f1 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -93,7 +93,7 @@ typedef struct hl_group {
static garray_T highlight_ga = GA_EMPTY_INIT_VALUE;
Map(cstr_t, int) highlight_unames = MAP_INIT;
-static inline struct hl_group * HL_TABLE(void)
+static inline struct hl_group *HL_TABLE(void)
{
return ((struct hl_group *)((highlight_ga.ga_data)));
}
@@ -230,11 +230,10 @@ struct name_list {
static char *(spo_name_tab[SPO_COUNT]) =
{ "ms=", "me=", "hs=", "he=", "rs=", "re=", "lc=" };
-/* The sp_off_flags are computed like this:
- * offset from the start of the matched text: (1 << SPO_XX_OFF)
- * offset from the end of the matched text: (1 << (SPO_XX_OFF + SPO_COUNT))
- * When both are present, only one is used.
- */
+// The sp_off_flags are computed like this:
+// offset from the start of the matched text: (1 << SPO_XX_OFF)
+// offset from the end of the matched text: (1 << (SPO_XX_OFF + SPO_COUNT))
+// When both are present, only one is used.
#define SPTYPE_MATCH 1 // match keyword with this group ID
#define SPTYPE_START 2 // match a regexp, start of item
@@ -345,7 +344,7 @@ static int next_seqnr = 1; // value to use for si_seqnr
*/
static int next_match_col; // column for start of next match
static lpos_T next_match_m_endpos; // position for end of next match
-static lpos_T next_match_h_startpos; // pos. for highl. start of next match
+static lpos_T next_match_h_startpos; // pos. for highl. start of next match
static lpos_T next_match_h_endpos; // pos. for highl. end of next match
static int next_match_idx; // index of matched item
static long next_match_flags; // flags for next match
@@ -383,7 +382,7 @@ static int current_line_id = 0; // unique number for current line
#define CUR_STATE(idx) ((stateitem_T *)(current_state.ga_data))[idx]
static bool syn_time_on = false;
-# define IF_SYN_TIME(p) (p)
+#define IF_SYN_TIME(p) (p)
// Set the timeout used for syntax highlighting.
// Use NULL to reset, no timeout.
@@ -492,8 +491,8 @@ void syntax_start(win_T *wp, linenr_T lnum)
// First line is always valid, no matter "minlines".
first_stored = 1;
} else {
- /* Need to parse "minlines" lines before state can be considered
- * valid to store. */
+ // Need to parse "minlines" lines before state can be considered
+ // valid to store.
first_stored = current_lnum + syn_block->b_syn_sync_minlines;
}
} else {
@@ -514,12 +513,12 @@ void syntax_start(win_T *wp, linenr_T lnum)
(void)syn_finish_line(false);
current_lnum++;
- /* If we parsed at least "minlines" lines or started at a valid
- * state, the current state is considered valid. */
+ // If we parsed at least "minlines" lines or started at a valid
+ // state, the current state is considered valid.
if (current_lnum >= first_stored) {
- /* Check if the saved state entry is for the current line and is
- * equal to the current state. If so, then validate all saved
- * states that depended on a change before the parsed line. */
+ // Check if the saved state entry is for the current line and is
+ // equal to the current state. If so, then validate all saved
+ // states that depended on a change before the parsed line.
if (prev == NULL) {
prev = syn_stack_find_entry(current_lnum - 1);
}
@@ -548,19 +547,18 @@ void syntax_start(win_T *wp, linenr_T lnum)
sp = sp->sst_next;
}
load_current_state(prev);
- }
- /* Store the state at this line when it's the first one, the line
- * where we start parsing, or some distance from the previously
- * saved state. But only when parsed at least 'minlines'. */
- else if (prev == NULL
- || current_lnum == lnum
- || current_lnum >= prev->sst_lnum + dist) {
+ } else if (prev == NULL
+ // Store the state at this line when it's the first one, the line
+ // where we start parsing, or some distance from the previously
+ // saved state. But only when parsed at least 'minlines'.
+ || current_lnum == lnum
+ || current_lnum >= prev->sst_lnum + dist) {
prev = store_current_state();
}
}
- /* This can take a long time: break when CTRL-C pressed. The current
- * state will be wrong then. */
+ // This can take a long time: break when CTRL-C pressed. The current
+ // state will be wrong then.
line_breakcheck();
if (got_int) {
current_lnum = lnum;
@@ -578,7 +576,7 @@ void syntax_start(win_T *wp, linenr_T lnum)
static void clear_syn_state(synstate_T *p)
{
if (p->sst_stacksize > SST_FIX_STATES) {
-# define UNREF_BUFSTATE_EXTMATCH(bs) unref_extmatch((bs)->bs_extmatch)
+#define UNREF_BUFSTATE_EXTMATCH(bs) unref_extmatch((bs)->bs_extmatch)
GA_DEEP_CLEAR(&(p->sst_union.sst_ga), bufstate_T, UNREF_BUFSTATE_EXTMATCH);
} else {
for (int i = 0; i < p->sst_stacksize; i++) {
@@ -592,7 +590,7 @@ static void clear_syn_state(synstate_T *p)
*/
static void clear_current_state(void)
{
-# define UNREF_STATEITEM_EXTMATCH(si) unref_extmatch((si)->si_extmatch)
+#define UNREF_STATEITEM_EXTMATCH(si) unref_extmatch((si)->si_extmatch)
GA_DEEP_CLEAR(&current_state, stateitem_T, UNREF_STATEITEM_EXTMATCH);
}
@@ -664,8 +662,8 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
* 1. Search backwards for the end of a C-style comment.
*/
if (syn_block->b_syn_sync_flags & SF_CCOMMENT) {
- /* Need to make syn_buf the current buffer for a moment, to be able to
- * use find_start_comment(). */
+ // Need to make syn_buf the current buffer for a moment, to be able to
+ // use find_start_comment().
curwin_save = curwin;
curwin = wp;
curbuf_save = curbuf;
@@ -793,9 +791,9 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
++current_col;
}
- /* syn_current_attr() will have skipped the check for
- * an item that ends here, need to do that now. Be
- * careful not to go past the NUL. */
+ // syn_current_attr() will have skipped the check for
+ // an item that ends here, need to do that now. Be
+ // careful not to go past the NUL.
prev_current_col = current_col;
if (syn_getcurline()[current_col] != NUL) {
++current_col;
@@ -987,9 +985,8 @@ static void syn_update_ends(bool startofline)
check_keepend();
}
-/****************************************
- * Handling of the state stack cache.
- */
+/////////////////////////////////////////
+// Handling of the state stack cache.
/*
* EXPLANATION OF THE SYNTAX STATE STACK CACHE
@@ -1081,8 +1078,8 @@ static void syn_stack_alloc(void)
}
if (syn_block->b_sst_array != NULL) {
- /* When shrinking the array, cleanup the existing stack.
- * Make sure that all valid entries fit in the new array. */
+ // When shrinking the array, cleanup the existing stack.
+ // Make sure that all valid entries fit in the new array.
while (syn_block->b_sst_len - syn_block->b_sst_freecount + 2 > len
&& syn_stack_cleanup()) {
;
@@ -1165,9 +1162,9 @@ static void syn_stack_apply_changes_block(synblock_T *block, buf_T *buf)
p = np;
continue;
}
- /* This state is below the changed area. Remember the line
- * that needs to be parsed before this entry can be made valid
- * again. */
+ // This state is below the changed area. Remember the line
+ // that needs to be parsed before this entry can be made valid
+ // again.
if (p->sst_change_lnum != 0 && p->sst_change_lnum > buf->b_mod_top) {
if (p->sst_change_lnum + buf->b_mod_xlines > buf->b_mod_top) {
p->sst_change_lnum += buf->b_mod_xlines;
@@ -1638,8 +1635,8 @@ int get_syntax_attr(const colnr_T col, bool *const can_spell, const bool keep_st
int attr = 0;
if (can_spell != NULL) {
- /* Default: Only do spelling when there is no @Spell cluster or when
- * ":syn spell toplevel" was used. */
+ // Default: Only do spelling when there is no @Spell cluster or when
+ // ":syn spell toplevel" was used.
*can_spell = syn_block->b_syn_spell == SYNSPL_DEFAULT
? (syn_block->b_spell_cluster_id == 0)
: (syn_block->b_syn_spell == SYNSPL_TOP);
@@ -1703,7 +1700,7 @@ static int syn_current_attr(const bool syncing, const bool displaying, bool *con
regmmatch_T regmatch;
lpos_T pos;
reg_extmatch_T *cur_extmatch = NULL;
- char_u buf_chartab[32]; // chartab array for syn iskeyword
+ char_u buf_chartab[32]; // chartab array for syn iskeyword
char_u *line; // current line. NOTE: becomes invalid after
// looking for a pattern match!
@@ -1901,15 +1898,15 @@ static int syn_current_attr(const bool syncing, const bool displaying, bool *con
syn_add_start_off(&pos, &regmatch,
spp, SPO_MS_OFF, -1);
if (pos.lnum > current_lnum) {
- /* must have used end of match in a next line,
- * we can't handle that */
+ // must have used end of match in a next line,
+ // we can't handle that
spp->sp_startcol = MAXCOL;
continue;
}
startcol = pos.col;
- /* remember the next column where this pattern
- * matches in the current line */
+ // remember the next column where this pattern
+ // matches in the current line
spp->sp_startcol = startcol;
/*
@@ -1999,8 +1996,8 @@ static int syn_current_attr(const bool syncing, const bool displaying, bool *con
/*
* keep the best match so far in next_match_*
*/
- /* Highlighting must start after startpos and end
- * before endpos. */
+ // Highlighting must start after startpos and end
+ // before endpos.
if (hl_startpos.lnum == current_lnum
&& (int)hl_startpos.col < startcol) {
hl_startpos.col = startcol;
@@ -2029,8 +2026,8 @@ static int syn_current_attr(const bool syncing, const bool displaying, bool *con
if (next_match_idx >= 0 && next_match_col == (int)current_col) {
synpat_T *lspp;
- /* When a zero-width item matched which has a nextgroup,
- * don't push the item but set nextgroup. */
+ // When a zero-width item matched which has a nextgroup,
+ // don't push the item but set nextgroup.
lspp = &(SYN_ITEMS(syn_block)[next_match_idx]);
if (next_match_m_endpos.lnum == current_lnum
&& next_match_m_endpos.col == current_col
@@ -2127,8 +2124,8 @@ static int syn_current_attr(const bool syncing, const bool displaying, bool *con
* done in the current item.
*/
if (syn_block->b_spell_cluster_id == 0) {
- /* There is no @Spell cluster: Do spelling for items without
- * @NoSpell cluster. */
+ // There is no @Spell cluster: Do spelling for items without
+ // @NoSpell cluster.
if (syn_block->b_nospell_cluster_id == 0
|| current_trans_id == 0) {
*can_spell = (syn_block->b_syn_spell != SYNSPL_NOTOP);
@@ -2180,8 +2177,8 @@ static int syn_current_attr(const bool syncing, const bool displaying, bool *con
}
}
} else if (can_spell != NULL) {
- /* Default: Only do spelling when there is no @Spell cluster or when
- * ":syn spell toplevel" was used. */
+ // Default: Only do spelling when there is no @Spell cluster or when
+ // ":syn spell toplevel" was used.
*can_spell = syn_block->b_syn_spell == SYNSPL_DEFAULT
? (syn_block->b_spell_cluster_id == 0)
: (syn_block->b_syn_spell == SYNSPL_TOP);
@@ -2365,8 +2362,8 @@ static void check_state_ends(void)
current_next_list = NULL;
}
- /* When the ended item has "extend", another item with
- * "keepend" now needs to check for its end. */
+ // When the ended item has "extend", another item with
+ // "keepend" now needs to check for its end.
had_extend = (cur_si->si_flags & HL_EXTEND);
pop_current_state();
@@ -2541,9 +2538,9 @@ static void update_si_end(stateitem_T *sip, int startcol, bool force)
return;
}
- /* Don't update when it's already done. Can be a match of an end pattern
- * that started in a previous line. Watch out: can also be a "keepend"
- * from a containing item. */
+ // Don't update when it's already done. Can be a match of an end pattern
+ // that started in a previous line. Watch out: can also be a "keepend"
+ // from a containing item.
if (!force && sip->si_m_endpos.lnum >= current_lnum) {
return;
}
@@ -2822,8 +2819,8 @@ static void find_endpos(int idx, lpos_T *startpos, lpos_T *m_endpos, lpos_T *hl_
}
limit_pos(hl_endpos, m_endpos);
- /* now the match ends where the highlighting ends, it is turned
- * into the matchgroup for the end */
+ // now the match ends where the highlighting ends, it is turned
+ // into the matchgroup for the end
*m_endpos = *hl_endpos;
} else {
*end_idx = 0;
@@ -4393,8 +4390,8 @@ static void syn_cmd_include(exarg_T *eap, int syncing)
prev_toplvl_grp = curwin->w_s->b_syn_topgrp;
curwin->w_s->b_syn_topgrp = sgl_id;
if (source
- ? do_source(eap->arg, false, DOSO_NONE) == FAIL
- : source_runtime(eap->arg, DIP_ALL) == FAIL) {
+ ? do_source((char *)eap->arg, false, DOSO_NONE) == FAIL
+ : source_runtime((char *)eap->arg, DIP_ALL) == FAIL) {
EMSG2(_(e_notopen), eap->arg);
}
curwin->w_s->b_syn_topgrp = prev_toplvl_grp;
@@ -4423,7 +4420,7 @@ static void syn_cmd_keyword(exarg_T *eap, int syncing)
if (eap->skip) {
syn_id = -1;
} else {
- syn_id = syn_check_group(arg, (int)(group_name_end - arg));
+ syn_id = syn_check_group((char *)arg, (int)(group_name_end - arg));
}
if (syn_id != 0) {
// Allocate a buffer, for removing backslashes in the keyword.
@@ -4560,7 +4557,7 @@ static void syn_cmd_match(exarg_T *eap, int syncing)
if (!ends_excmd(*rest) || eap->skip) {
rest = NULL;
} else {
- if ((syn_id = syn_check_group(arg, (int)(group_name_end - arg))) != 0) {
+ if ((syn_id = syn_check_group((char *)arg, (int)(group_name_end - arg))) != 0) {
syn_incl_toplevel(syn_id, &syn_opt_arg.flags);
/*
* Store the pattern in the syn_items list
@@ -4709,7 +4706,7 @@ static void syn_cmd_region(exarg_T *eap, int syncing)
if ((p - rest == 4 && STRNCMP(rest, "NONE", 4) == 0) || eap->skip) {
matchgroup_id = 0;
} else {
- matchgroup_id = syn_check_group(rest, (int)(p - rest));
+ matchgroup_id = syn_check_group((char *)rest, (int)(p - rest));
if (matchgroup_id == 0) {
illegal = true;
break;
@@ -4768,7 +4765,7 @@ static void syn_cmd_region(exarg_T *eap, int syncing)
rest = NULL;
} else {
ga_grow(&(curwin->w_s->b_syn_patterns), pat_count);
- if ((syn_id = syn_check_group(arg, (int)(group_name_end - arg))) != 0) {
+ if ((syn_id = syn_check_group((char *)arg, (int)(group_name_end - arg))) != 0) {
syn_incl_toplevel(syn_id, &syn_opt_arg.flags);
/*
* Store the start/skip/end in the syn_items list
@@ -5264,8 +5261,7 @@ static void syn_cmd_sync(exarg_T *eap, int syncing)
if (!ends_excmd(*next_arg)) {
arg_end = skiptowhite(next_arg);
if (!eap->skip) {
- curwin->w_s->b_syn_sync_id = syn_check_group(next_arg,
- (int)(arg_end - next_arg));
+ curwin->w_s->b_syn_sync_id = syn_check_group((char *)next_arg, (int)(arg_end - next_arg));
}
next_arg = skipwhite(arg_end);
} else if (!eap->skip) {
@@ -5447,7 +5443,7 @@ static int get_id_list(char_u **const arg, const int keylen, int16_t **const lis
* Handle full group name.
*/
if (vim_strpbrk(name + 1, (char_u *)"\\.*^$~[") == NULL) {
- id = syn_check_group(name + 1, (int)(end - p));
+ id = syn_check_group((char *)(name + 1), (int)(end - p));
} else {
// Handle match of regexp with group names.
*name = '^';
@@ -5571,8 +5567,8 @@ static int in_id_list(stateitem_T *cur_si, int16_t *list, struct sp_syn *ssp, in
// If ssp has a "containedin" list and "cur_si" is in it, return TRUE.
if (cur_si != NULL && ssp->cont_in_list != NULL
&& !(cur_si->si_flags & HL_MATCH)) {
- /* Ignore transparent items without a contains argument. Double check
- * that we don't go back past the first one. */
+ // Ignore transparent items without a contains argument. Double check
+ // that we don't go back past the first one.
while ((cur_si->si_flags & HL_TRANS_CONT)
&& cur_si > (stateitem_T *)(current_state.ga_data)) {
--cur_si;
@@ -5636,8 +5632,8 @@ static int in_id_list(stateitem_T *cur_si, int16_t *list, struct sp_syn *ssp, in
}
if (item >= SYNID_CLUSTER) {
scl_list = SYN_CLSTR(syn_block)[item - SYNID_CLUSTER].scl_list;
- /* restrict recursiveness to 30 to avoid an endless loop for a
- * cluster that includes itself (indirectly) */
+ // restrict recursiveness to 30 to avoid an endless loop for a
+ // cluster that includes itself (indirectly)
if (scl_list != NULL && depth < 30) {
++depth;
r = in_id_list(NULL, scl_list, ssp, contained);
@@ -5654,7 +5650,7 @@ static int in_id_list(stateitem_T *cur_si, int16_t *list, struct sp_syn *ssp, in
struct subcommand {
char *name; // subcommand name
- void (*func)(exarg_T *, int); // function to call
+ void (*func)(exarg_T *, int); // function to call
};
static struct subcommand subcommands[] =
@@ -5932,8 +5928,8 @@ int syn_get_sub_char(void)
int syn_get_stack_item(int i)
{
if (i >= current_state.ga_len) {
- /* Need to invalidate the state, because we didn't properly finish it
- * for the last character, "keep_state" was TRUE. */
+ // Need to invalidate the state, because we didn't properly finish it
+ // for the last character, "keep_state" was TRUE.
invalidate_current_state();
current_col = MAXCOL;
return -1;
@@ -6217,6 +6213,26 @@ static const char *highlight_init_both[] = {
"default link Delimiter Special",
"default link SpecialComment Special",
"default link Debug Special",
+ "default DiagnosticError ctermfg=1 guifg=Red",
+ "default DiagnosticWarn ctermfg=3 guifg=Orange",
+ "default DiagnosticInfo ctermfg=4 guifg=LightBlue",
+ "default DiagnosticHint ctermfg=7 guifg=LightGrey",
+ "default DiagnosticUnderlineError cterm=underline gui=underline guisp=Red",
+ "default DiagnosticUnderlineWarn cterm=underline gui=underline guisp=Orange",
+ "default DiagnosticUnderlineInfo cterm=underline gui=underline guisp=LightBlue",
+ "default DiagnosticUnderlineHint cterm=underline gui=underline guisp=LightGrey",
+ "default link DiagnosticVirtualTextError DiagnosticError",
+ "default link DiagnosticVirtualTextWarn DiagnosticWarn",
+ "default link DiagnosticVirtualTextInfo DiagnosticInfo",
+ "default link DiagnosticVirtualTextHint DiagnosticHint",
+ "default link DiagnosticFloatingError DiagnosticError",
+ "default link DiagnosticFloatingWarn DiagnosticWarn",
+ "default link DiagnosticFloatingInfo DiagnosticInfo",
+ "default link DiagnosticFloatingHint DiagnosticHint",
+ "default link DiagnosticSignError DiagnosticError",
+ "default link DiagnosticSignWarn DiagnosticWarn",
+ "default link DiagnosticSignInfo DiagnosticInfo",
+ "default link DiagnosticSignHint DiagnosticHint",
NULL
};
@@ -6597,10 +6613,10 @@ int load_colors(char_u *name)
buf = xmalloc(buflen);
apply_autocmds(EVENT_COLORSCHEMEPRE, name, curbuf->b_fname, false, curbuf);
snprintf((char *)buf, buflen, "colors/%s.vim", name);
- retval = source_runtime(buf, DIP_START + DIP_OPT);
+ retval = source_runtime((char *)buf, DIP_START + DIP_OPT);
if (retval == FAIL) {
snprintf((char *)buf, buflen, "colors/%s.lua", name);
- retval = source_runtime(buf, DIP_START + DIP_OPT);
+ retval = source_runtime((char *)buf, DIP_START + DIP_OPT);
}
xfree(buf);
apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, false, curbuf);
@@ -6793,13 +6809,11 @@ void do_highlight(const char *line, const bool forceit, const bool init)
return;
}
- from_id = syn_check_group((const char_u *)from_start,
- (int)(from_end - from_start));
+ from_id = syn_check_group(from_start, (int)(from_end - from_start));
if (strncmp(to_start, "NONE", 4) == 0) {
to_id = 0;
} else {
- to_id = syn_check_group((const char_u *)to_start,
- (int)(to_end - to_start));
+ to_id = syn_check_group(to_start, (int)(to_end - to_start));
}
if (from_id > 0) {
@@ -6860,7 +6874,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
}
// Find the group name in the table. If it does not exist yet, add it.
- id = syn_check_group((const char_u *)line, (int)(name_end - line));
+ id = syn_check_group(line, (int)(name_end - line));
if (id == 0) { // Failed (out of memory).
return;
}
@@ -7664,11 +7678,11 @@ char_u *syn_id2name(int id)
/// @param len length of \p pp
///
/// @return 0 for failure else the id of the group
-int syn_check_group(const char_u *name, int len)
+int syn_check_group(const char *name, int len)
{
- int id = syn_name2id_len(name, len);
+ int id = syn_name2id_len((char_u *)name, len);
if (id == 0) { // doesn't exist yet
- return syn_add_group(vim_strnsave(name, len));
+ return syn_add_group(vim_strnsave((char_u *)name, len));
}
return id;
}
@@ -7714,7 +7728,7 @@ static int syn_add_group(char_u *name)
char *const name_up = (char *)vim_strsave_up(name);
// Append another syntax_highlight entry.
- struct hl_group * hlgp = GA_APPEND_VIA_PTR(struct hl_group, &highlight_ga);
+ struct hl_group *hlgp = GA_APPEND_VIA_PTR(struct hl_group, &highlight_ga);
memset(hlgp, 0, sizeof(*hlgp));
hlgp->sg_name = name;
hlgp->sg_rgb_bg = -1;
@@ -7868,7 +7882,7 @@ void highlight_changed(void)
/// Translate builtin highlight groups into attributes for quick lookup.
for (int hlf = 0; hlf < HLF_COUNT; hlf++) {
- id = syn_check_group((char_u *)hlf_names[hlf], STRLEN(hlf_names[hlf]));
+ id = syn_check_group(hlf_names[hlf], STRLEN(hlf_names[hlf]));
if (id == 0) {
abort();
}
diff --git a/src/nvim/syntax.h b/src/nvim/syntax.h
index 38f848f178..15fc084a0a 100644
--- a/src/nvim/syntax.h
+++ b/src/nvim/syntax.h
@@ -3,31 +3,31 @@
#include <stdbool.h>
-#include "nvim/globals.h"
#include "nvim/buffer_defs.h"
#include "nvim/ex_cmds_defs.h"
+#include "nvim/globals.h"
-#define HL_CONTAINED 0x01 /* not used on toplevel */
-#define HL_TRANSP 0x02 /* has no highlighting */
-#define HL_ONELINE 0x04 /* match within one line only */
-#define HL_HAS_EOL 0x08 /* end pattern that matches with $ */
-#define HL_SYNC_HERE 0x10 /* sync point after this item (syncing only) */
-#define HL_SYNC_THERE 0x20 /* sync point at current line (syncing only) */
-#define HL_MATCH 0x40 /* use match ID instead of item ID */
-#define HL_SKIPNL 0x80 /* nextgroup can skip newlines */
-#define HL_SKIPWHITE 0x100 /* nextgroup can skip white space */
-#define HL_SKIPEMPTY 0x200 /* nextgroup can skip empty lines */
-#define HL_KEEPEND 0x400 /* end match always kept */
-#define HL_EXCLUDENL 0x800 /* exclude NL from match */
-#define HL_DISPLAY 0x1000 /* only used for displaying, not syncing */
-#define HL_FOLD 0x2000 /* define fold */
-#define HL_EXTEND 0x4000 /* ignore a keepend */
-#define HL_MATCHCONT 0x8000 /* match continued from previous line */
-#define HL_TRANS_CONT 0x10000 /* transparent item without contains arg */
-#define HL_CONCEAL 0x20000 /* can be concealed */
-#define HL_CONCEALENDS 0x40000 /* can be concealed */
-
-#define SYN_GROUP_STATIC(s) syn_check_group((char_u *)S_LEN(s))
+#define HL_CONTAINED 0x01 // not used on toplevel
+#define HL_TRANSP 0x02 // has no highlighting
+#define HL_ONELINE 0x04 // match within one line only
+#define HL_HAS_EOL 0x08 // end pattern that matches with $
+#define HL_SYNC_HERE 0x10 // sync point after this item (syncing only)
+#define HL_SYNC_THERE 0x20 // sync point at current line (syncing only)
+#define HL_MATCH 0x40 // use match ID instead of item ID
+#define HL_SKIPNL 0x80 // nextgroup can skip newlines
+#define HL_SKIPWHITE 0x100 // nextgroup can skip white space
+#define HL_SKIPEMPTY 0x200 // nextgroup can skip empty lines
+#define HL_KEEPEND 0x400 // end match always kept
+#define HL_EXCLUDENL 0x800 // exclude NL from match
+#define HL_DISPLAY 0x1000 // only used for displaying, not syncing
+#define HL_FOLD 0x2000 // define fold
+#define HL_EXTEND 0x4000 // ignore a keepend
+#define HL_MATCHCONT 0x8000 // match continued from previous line
+#define HL_TRANS_CONT 0x10000 // transparent item without contains arg
+#define HL_CONCEAL 0x20000 // can be concealed
+#define HL_CONCEALENDS 0x40000 // can be concealed
+
+#define SYN_GROUP_STATIC(s) syn_check_group(S_LEN(s))
typedef struct {
char *name;
diff --git a/src/nvim/syntax_defs.h b/src/nvim/syntax_defs.h
index 5ee0611d58..526be905e9 100644
--- a/src/nvim/syntax_defs.h
+++ b/src/nvim/syntax_defs.h
@@ -3,18 +3,18 @@
#include "nvim/highlight_defs.h"
-# define SST_MIN_ENTRIES 150 /* minimal size for state stack array */
-# define SST_MAX_ENTRIES 1000 /* maximal size for state stack array */
-# define SST_FIX_STATES 7 /* size of sst_stack[]. */
-# define SST_DIST 16 /* normal distance between entries */
-# define SST_INVALID (synstate_T *)-1 /* invalid syn_state pointer */
+#define SST_MIN_ENTRIES 150 // minimal size for state stack array
+#define SST_MAX_ENTRIES 1000 // maximal size for state stack array
+#define SST_FIX_STATES 7 // size of sst_stack[].
+#define SST_DIST 16 // normal distance between entries
+#define SST_INVALID (synstate_T *)-1 // invalid syn_state pointer
typedef struct syn_state synstate_T;
#include "nvim/buffer_defs.h"
#include "nvim/regexp_defs.h"
-/* struct passed to in_id_list() */
+// struct passed to in_id_list()
struct sp_syn {
int inc_tag; // ":syn include" unique tag
int16_t id; // highlight group ID of item
@@ -27,7 +27,7 @@ struct sp_syn {
typedef struct keyentry keyentry_T;
struct keyentry {
- keyentry_T *ke_next; // next entry with identical "keyword[]"
+ keyentry_T *ke_next; // next entry with identical "keyword[]"
struct sp_syn k_syn; // struct passed to in_id_list()
int16_t *next_list; // ID list for next match (if non-zero)
int flags;
@@ -39,11 +39,11 @@ struct keyentry {
* Struct used to store one state of the state stack.
*/
typedef struct buf_state {
- int bs_idx; /* index of pattern */
- int bs_flags; /* flags for pattern */
- int bs_seqnr; /* stores si_seqnr */
- int bs_cchar; /* stores si_cchar */
- reg_extmatch_T *bs_extmatch; /* external matches from start pattern */
+ int bs_idx; // index of pattern
+ int bs_flags; // flags for pattern
+ int bs_seqnr; // stores si_seqnr
+ int bs_cchar; // stores si_cchar
+ reg_extmatch_T *bs_extmatch; // external matches from start pattern
} bufstate_T;
/*
@@ -51,11 +51,11 @@ typedef struct buf_state {
* Used by b_sst_array[].
*/
struct syn_state {
- synstate_T *sst_next; /* next entry in used or free list */
- linenr_T sst_lnum; /* line number for this state */
+ synstate_T *sst_next; // next entry in used or free list
+ linenr_T sst_lnum; // line number for this state
union {
- bufstate_T sst_stack[SST_FIX_STATES]; /* short state stack */
- garray_T sst_ga; /* growarray for long state stack */
+ bufstate_T sst_stack[SST_FIX_STATES]; // short state stack
+ garray_T sst_ga; // growarray for long state stack
} sst_union;
int sst_next_flags; // flags for sst_next_list
int sst_stacksize; // number of states on the stack
diff --git a/src/nvim/tag.c b/src/nvim/tag.c
index c63cdad098..c22d344878 100644
--- a/src/nvim/tag.c
+++ b/src/nvim/tag.c
@@ -10,9 +10,7 @@
#include <stdbool.h>
#include <string.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/tag.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
@@ -22,18 +20,21 @@
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
+#include "nvim/file_search.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
+#include "nvim/garray.h"
#include "nvim/if_cscope.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
+#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/file_search.h"
-#include "nvim/garray.h"
-#include "nvim/memory.h"
#include "nvim/move.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/os/time.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/quickfix.h"
@@ -41,30 +42,29 @@
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/strings.h"
+#include "nvim/tag.h"
#include "nvim/ui.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/os/os.h"
-#include "nvim/os/time.h"
-#include "nvim/os/input.h"
/*
* Structure to hold pointers to various items in a tag line.
*/
typedef struct tag_pointers {
// filled in by parse_tag_line():
- char_u *tagname; // start of tag name (skip "file:")
- char_u *tagname_end; // char after tag name
- char_u *fname; // first char of file name
- char_u *fname_end; // char after file name
- char_u *command; // first char of command
+ char_u *tagname; // start of tag name (skip "file:")
+ char_u *tagname_end; // char after tag name
+ char_u *fname; // first char of file name
+ char_u *fname_end; // char after file name
+ char_u *command; // first char of command
// filled in by parse_match():
- char_u *command_end; // first char after command
- char_u *tag_fname; // file name of the tags file. This is used
+ char_u *command_end; // first char after command
+ char_u *tag_fname; // file name of the tags file. This is used
// when 'tr' is set.
- char_u *tagkind; // "kind:" value
- char_u *tagkind_end; // end of tagkind
- char_u *user_data; // user_data string
- char_u *user_data_end; // end of user_data
+ char_u *tagkind; // "kind:" value
+ char_u *tagkind_end; // end of tagkind
+ char_u *user_data; // user_data string
+ char_u *user_data_end; // end of user_data
linenr_T tagline; // "line:" value
} tagptrs_T;
@@ -72,11 +72,11 @@ typedef struct tag_pointers {
* Structure to hold info about the tag pattern being used.
*/
typedef struct {
- char_u *pat; /* the pattern */
- int len; /* length of pat[] */
- char_u *head; /* start of pattern head */
- int headlen; /* length of head[] */
- regmatch_T regmatch; /* regexp program, may be NULL */
+ char_u *pat; // the pattern
+ int len; // length of pat[]
+ char_u *head; // start of pattern head
+ int headlen; // length of head[]
+ regmatch_T regmatch; // regexp program, may be NULL
} pat_T;
// The matching tags are first stored in one of the hash tables. In
@@ -93,11 +93,11 @@ typedef struct {
#define MT_MASK 7 // mask for printing priority
#define MT_COUNT 16
-static char *mt_names[MT_COUNT/2] =
-{"FSC", "F C", "F ", "FS ", " SC", " C", " ", " S "};
+static char *mt_names[MT_COUNT/2] =
+{ "FSC", "F C", "F ", "FS ", " SC", " C", " ", " S " };
-#define NOTAGFILE 99 /* return value for jumpto_tag */
-static char_u *nofile_fname = NULL; /* fname for NOTAGFILE error */
+#define NOTAGFILE 99 // return value for jumpto_tag
+static char_u *nofile_fname = NULL; // fname for NOTAGFILE error
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -111,7 +111,7 @@ static char_u *recurmsg
static char_u *tfu_inv_ret_msg
= (char_u *)N_("E987: invalid return value from tagfunc");
-static char_u *tagmatchname = NULL; /* name of last used tag */
+static char_u *tagmatchname = NULL; // name of last used tag
/*
* Tag for preview window is remembered separately, to avoid messing up the
@@ -124,36 +124,31 @@ static int tfu_in_use = false; // disallow recursive call of tagfunc
// Used instead of NUL to separate tag fields in the growarrays.
#define TAG_SEP 0x02
-/*
- * Jump to tag; handling of tag commands and tag stack
- *
- * *tag != NUL: ":tag {tag}", jump to new tag, add to tag stack
- *
- * type == DT_TAG: ":tag [tag]", jump to newer position or same tag again
- * type == DT_HELP: like DT_TAG, but don't use regexp.
- * type == DT_POP: ":pop" or CTRL-T, jump to old position
- * type == DT_NEXT: jump to next match of same tag
- * type == DT_PREV: jump to previous match of same tag
- * type == DT_FIRST: jump to first match of same tag
- * type == DT_LAST: jump to last match of same tag
- * type == DT_SELECT: ":tselect [tag]", select tag from a list of all matches
- * type == DT_JUMP: ":tjump [tag]", jump to tag or select tag from a list
- * type == DT_CSCOPE: use cscope to find the tag
- * type == DT_LTAG: use location list for displaying tag matches
- * type == DT_FREE: free cached matches
- *
- * for cscope, returns TRUE if we jumped to tag or aborted, FALSE otherwise
- */
-int
-do_tag(
- char_u *tag, // tag (pattern) to jump to
- int type,
- int count,
- int forceit, // :ta with !
- int verbose // print "tag not found" message
-)
+/// Jump to tag; handling of tag commands and tag stack
+///
+/// *tag != NUL: ":tag {tag}", jump to new tag, add to tag stack
+///
+/// type == DT_TAG: ":tag [tag]", jump to newer position or same tag again
+/// type == DT_HELP: like DT_TAG, but don't use regexp.
+/// type == DT_POP: ":pop" or CTRL-T, jump to old position
+/// type == DT_NEXT: jump to next match of same tag
+/// type == DT_PREV: jump to previous match of same tag
+/// type == DT_FIRST: jump to first match of same tag
+/// type == DT_LAST: jump to last match of same tag
+/// type == DT_SELECT: ":tselect [tag]", select tag from a list of all matches
+/// type == DT_JUMP: ":tjump [tag]", jump to tag or select tag from a list
+/// type == DT_CSCOPE: use cscope to find the tag
+/// type == DT_LTAG: use location list for displaying tag matches
+/// type == DT_FREE: free cached matches
+///
+/// for cscope, returns TRUE if we jumped to tag or aborted, FALSE otherwise
+///
+/// @param tag tag (pattern) to jump to
+/// @param forceit :ta with !
+/// @param verbose print "tag not found" message
+int do_tag(char_u *tag, int type, int count, int forceit, int verbose)
{
- taggy_T *tagstack = curwin->w_tagstack;
+ taggy_T *tagstack = curwin->w_tagstack;
int tagstackidx = curwin->w_tagstackidx;
int tagstacklen = curwin->w_tagstacklen;
int cur_match = 0;
@@ -170,16 +165,16 @@ do_tag(
fmark_T saved_fmark;
int jumped_to_tag = false;
int new_num_matches;
- char_u **new_matches;
+ char_u **new_matches;
int use_tagstack;
int skip_msg = false;
char_u *buf_ffname = curbuf->b_ffname; // name for priority computation
int use_tfu = 1;
- /* remember the matches for the last used tag */
+ // remember the matches for the last used tag
static int num_matches = 0;
- static int max_num_matches = 0; /* limit used for match search */
- static char_u **matches = NULL;
+ static int max_num_matches = 0; // limit used for match search
+ static char_u **matches = NULL;
static int flags;
if (tfu_in_use) {
@@ -189,7 +184,7 @@ do_tag(
#ifdef EXITFREE
if (type == DT_FREE) {
- /* remove the list of matches */
+ // remove the list of matches
FreeWild(num_matches, matches);
cs_free_tags();
num_matches = 0;
@@ -207,7 +202,7 @@ do_tag(
free_string_option(nofile_fname);
nofile_fname = NULL;
- clearpos(&saved_fmark.mark); /* shutup gcc 4.0 */
+ clearpos(&saved_fmark.mark); // shutup gcc 4.0
saved_fmark.fnum = 0;
// Don't add a tag to the tagstack if 'tagstack' has been reset.
@@ -226,7 +221,7 @@ do_tag(
use_tagstack = true;
}
- /* new pattern, add to the tag stack */
+ // new pattern, add to the tag stack
if (*tag != NUL
&& (type == DT_TAG || type == DT_SELECT || type == DT_JUMP
|| type == DT_LTAG
@@ -235,8 +230,8 @@ do_tag(
if (g_do_tagpreview != 0) {
if (ptag_entry.tagname != NULL
&& STRCMP(ptag_entry.tagname, tag) == 0) {
- /* Jumping to same tag: keep the current match, so that
- * the CursorHold autocommand example works. */
+ // Jumping to same tag: keep the current match, so that
+ // the CursorHold autocommand example works.
cur_match = ptag_entry.cur_match;
cur_fnum = ptag_entry.cur_fnum;
} else {
@@ -252,7 +247,7 @@ do_tag(
tagstack_clear_entry(&tagstack[--tagstacklen]);
}
- /* if the tagstack is full: remove oldest entry */
+ // if the tagstack is full: remove oldest entry
if (++tagstacklen > TAGSTACKSIZE) {
tagstacklen = TAGSTACKSIZE;
tagstack_clear_entry(&tagstack[0]);
@@ -293,7 +288,7 @@ do_tag(
* way to the bottom now.
*/
tagstackidx = 0;
- } else if (tagstackidx >= tagstacklen) { // count == 0?
+ } else if (tagstackidx >= tagstacklen) { // count == 0?
EMSG(_(topmsg));
goto end_do_tag;
}
@@ -321,8 +316,9 @@ do_tag(
curwin->w_cursor.col = saved_fmark.mark.col;
curwin->w_set_curswant = true;
check_cursor();
- if ((fdo_flags & FDO_TAG) && old_KeyTyped)
+ if ((fdo_flags & FDO_TAG) && old_KeyTyped) {
foldOpenCursor();
+ }
// remove the old list of matches
FreeWild(num_matches, matches);
@@ -333,8 +329,7 @@ do_tag(
}
if (type == DT_TAG
- || type == DT_LTAG
- ) {
+ || type == DT_LTAG) {
if (g_do_tagpreview != 0) {
cur_match = ptag_entry.cur_match;
cur_fnum = ptag_entry.cur_fnum;
@@ -350,7 +345,7 @@ do_tag(
tagstackidx = tagstacklen - 1;
EMSG(_(topmsg));
save_pos = false;
- } else if (tagstackidx < 0) { // must have been count == 0
+ } else if (tagstackidx < 0) { // must have been count == 0
EMSG(_(bottommsg));
tagstackidx = 0;
goto end_do_tag;
@@ -367,23 +362,28 @@ do_tag(
cur_match = ptag_entry.cur_match;
cur_fnum = ptag_entry.cur_fnum;
} else {
- if (--tagstackidx < 0)
+ if (--tagstackidx < 0) {
tagstackidx = 0;
+ }
cur_match = tagstack[tagstackidx].cur_match;
cur_fnum = tagstack[tagstackidx].cur_fnum;
}
switch (type) {
- case DT_FIRST: cur_match = count - 1; break;
+ case DT_FIRST:
+ cur_match = count - 1; break;
case DT_SELECT:
case DT_JUMP:
case DT_CSCOPE:
- case DT_LAST: cur_match = MAXCOL - 1; break;
- case DT_NEXT: cur_match += count; break;
- case DT_PREV: cur_match -= count; break;
+ case DT_LAST:
+ cur_match = MAXCOL - 1; break;
+ case DT_NEXT:
+ cur_match += count; break;
+ case DT_PREV:
+ cur_match -= count; break;
}
- if (cur_match >= MAXCOL)
+ if (cur_match >= MAXCOL) {
cur_match = MAXCOL - 1;
- else if (cur_match < 0) {
+ } else if (cur_match < 0) {
EMSG(_("E425: Cannot go before first matching tag"));
skip_msg = true;
cur_match = 0;
@@ -407,9 +407,9 @@ do_tag(
tagstack[tagstackidx].fmark.fnum = curbuf->b_fnum;
}
- /* Curwin will change in the call to jumpto_tag() if ":stag" was
- * used or an autocommand jumps to another window; store value of
- * tagstackidx now. */
+ // Curwin will change in the call to jumpto_tag() if ":stag" was
+ // used or an autocommand jumps to another window; store value of
+ // tagstackidx now.
curwin->w_tagstackidx = tagstackidx;
if (type != DT_SELECT && type != DT_JUMP) {
curwin->w_tagstack[tagstackidx].cur_match = cur_match;
@@ -418,14 +418,15 @@ do_tag(
}
}
- /* When not using the current buffer get the name of buffer "cur_fnum".
- * Makes sure that the tag order doesn't change when using a remembered
- * position for "cur_match". */
+ // When not using the current buffer get the name of buffer "cur_fnum".
+ // Makes sure that the tag order doesn't change when using a remembered
+ // position for "cur_match".
if (cur_fnum != curbuf->b_fnum) {
buf_T *buf = buflist_findnr(cur_fnum);
- if (buf != NULL)
+ if (buf != NULL) {
buf_ffname = buf->b_ffname;
+ }
}
/*
@@ -433,7 +434,7 @@ do_tag(
*/
for (;; ) {
int other_name;
- char_u *name;
+ char_u *name;
// When desired match not found yet, try to find it (and others).
if (use_tagstack) {
@@ -466,8 +467,9 @@ do_tag(
if (!no_regexp && *name == '/') {
flags = TAG_REGEXP;
++name;
- } else
+ } else {
flags = TAG_NOIC;
+ }
if (type == DT_CSCOPE) {
flags = TAG_CSCOPE;
@@ -490,9 +492,9 @@ do_tag(
* to the start. Avoids that the order changes when using
* ":tnext" and jumping to another file. */
if (!new_tag && !other_name) {
- int j, k;
- int idx = 0;
- tagptrs_T tagp, tagp2;
+ int j, k;
+ int idx = 0;
+ tagptrs_T tagp, tagp2;
// Find the position of each old match in the new list. Need
// to use parse_match() to find the tag line.
@@ -517,8 +519,9 @@ do_tag(
}
if (num_matches <= 0) {
- if (verbose)
+ if (verbose) {
EMSG2(_("E426: tag not found: %s"), name);
+ }
g_do_tagpreview = 0;
} else {
bool ask_for_selection = false;
@@ -533,7 +536,7 @@ do_tag(
} else if (type == DT_SELECT || (type == DT_JUMP && num_matches > 1)) {
print_tag_list(new_tag, use_tagstack, num_matches, matches);
ask_for_selection = true;
- } else if (type == DT_LTAG) {
+ } else if (type == DT_LTAG) {
if (add_llist_tags(tag, num_matches, matches) == FAIL) {
goto end_do_tag;
}
@@ -563,16 +566,17 @@ do_tag(
* There will be an EMSG("file doesn't exist") below then. */
if ((type == DT_NEXT || type == DT_FIRST)
&& nofile_fname == NULL) {
- if (num_matches == 1)
+ if (num_matches == 1) {
EMSG(_("E427: There is only one matching tag"));
- else
+ } else {
EMSG(_("E428: Cannot go beyond last matching tag"));
+ }
skip_msg = true;
}
cur_match = num_matches - 1;
}
if (use_tagstack) {
- tagptrs_T tagp2;
+ tagptrs_T tagp2;
tagstack[tagstackidx].cur_match = cur_match;
tagstack[tagstackidx].cur_fnum = cur_fnum;
@@ -581,12 +585,12 @@ do_tag(
if (use_tfu && parse_match(matches[cur_match], &tagp2) == OK
&& tagp2.user_data) {
XFREE_CLEAR(tagstack[tagstackidx].user_data);
- tagstack[tagstackidx].user_data = vim_strnsave(
- tagp2.user_data, tagp2.user_data_end - tagp2.user_data);
+ tagstack[tagstackidx].user_data = vim_strnsave(tagp2.user_data,
+ tagp2.user_data_end - tagp2.user_data);
}
tagstackidx++;
- } else if (g_do_tagpreview != 0) {
+ } else if (g_do_tagpreview != 0) {
ptag_entry.cur_match = cur_match;
ptag_entry.cur_fnum = cur_fnum;
}
@@ -595,8 +599,9 @@ do_tag(
* Only when going to try the next match, report that the previous
* file didn't exist. Otherwise an EMSG() is given below.
*/
- if (nofile_fname != NULL && error_cur_match != cur_match)
+ if (nofile_fname != NULL && error_cur_match != cur_match) {
smsg(_("File \"%s\" does not exist"), nofile_fname);
+ }
ic = (matches[cur_match][0] & MT_IC_OFF);
@@ -631,7 +636,7 @@ do_tag(
// Let the SwapExists event know what tag we are jumping to.
vim_snprintf((char *)IObuff, IOSIZE, ":ta %s\r", name);
- set_vim_var_string(VV_SWAPCOMMAND, (char *) IObuff, -1);
+ set_vim_var_string(VV_SWAPCOMMAND, (char *)IObuff, -1);
/*
* Jump to the desired match.
@@ -648,11 +653,12 @@ do_tag(
&& (max_num_matches != MAXCOL
|| cur_match < num_matches - 1))) {
error_cur_match = cur_match;
- if (use_tagstack)
+ if (use_tagstack) {
--tagstackidx;
- if (type == DT_PREV)
+ }
+ if (type == DT_PREV) {
--cur_match;
- else {
+ } else {
type = DT_NEXT;
++cur_match;
}
@@ -662,8 +668,9 @@ do_tag(
} else {
/* We may have jumped to another window, check that
* tagstackidx is still valid. */
- if (use_tagstack && tagstackidx > curwin->w_tagstacklen)
+ if (use_tagstack && tagstackidx > curwin->w_tagstacklen) {
tagstackidx = curwin->w_tagstackidx;
+ }
jumped_to_tag = true;
}
}
@@ -684,331 +691,322 @@ end_do_tag:
//
// List all the matching tags.
//
-static void
-print_tag_list(
- int new_tag,
- int use_tagstack,
- int num_matches,
- char_u **matches)
+static void print_tag_list(int new_tag, int use_tagstack, int num_matches, char_u **matches)
{
- taggy_T *tagstack = curwin->w_tagstack;
- int tagstackidx = curwin->w_tagstackidx;
- int i;
- char_u *p;
- char_u *command_end;
- tagptrs_T tagp;
- int taglen;
- int attr;
-
- // Assume that the first match indicates how long the tags can
- // be, and align the file names to that.
- parse_match(matches[0], &tagp);
- taglen = (int)(tagp.tagname_end - tagp.tagname + 2);
- if (taglen < 18) {
- taglen = 18;
- }
- if (taglen > Columns - 25) {
- taglen = MAXCOL;
- }
- if (msg_col == 0) {
- msg_didout = false; // overwrite previous message
- }
- msg_start();
- msg_puts_attr(_(" # pri kind tag"), HL_ATTR(HLF_T));
- msg_clr_eos();
+ taggy_T *tagstack = curwin->w_tagstack;
+ int tagstackidx = curwin->w_tagstackidx;
+ int i;
+ char_u *p;
+ char_u *command_end;
+ tagptrs_T tagp;
+ int taglen;
+ int attr;
+
+ // Assume that the first match indicates how long the tags can
+ // be, and align the file names to that.
+ parse_match(matches[0], &tagp);
+ taglen = (int)(tagp.tagname_end - tagp.tagname + 2);
+ if (taglen < 18) {
+ taglen = 18;
+ }
+ if (taglen > Columns - 25) {
+ taglen = MAXCOL;
+ }
+ if (msg_col == 0) {
+ msg_didout = false; // overwrite previous message
+ }
+ msg_start();
+ msg_puts_attr(_(" # pri kind tag"), HL_ATTR(HLF_T));
+ msg_clr_eos();
+ taglen_advance(taglen);
+ msg_puts_attr(_("file\n"), HL_ATTR(HLF_T));
+
+ for (i = 0; i < num_matches && !got_int; i++) {
+ parse_match(matches[i], &tagp);
+ if (!new_tag && (
+ (g_do_tagpreview != 0
+ && i == ptag_entry.cur_match)
+ || (use_tagstack
+ && i == tagstack[tagstackidx].cur_match))) {
+ *IObuff = '>';
+ } else {
+ *IObuff = ' ';
+ }
+ vim_snprintf((char *)IObuff + 1, IOSIZE - 1,
+ "%2d %s ", i + 1,
+ mt_names[matches[i][0] & MT_MASK]);
+ msg_puts((char *)IObuff);
+ if (tagp.tagkind != NULL) {
+ msg_outtrans_len(tagp.tagkind,
+ (int)(tagp.tagkind_end - tagp.tagkind));
+ }
+ msg_advance(13);
+ msg_outtrans_len_attr(tagp.tagname,
+ (int)(tagp.tagname_end - tagp.tagname),
+ HL_ATTR(HLF_T));
+ msg_putchar(' ');
taglen_advance(taglen);
- msg_puts_attr(_("file\n"), HL_ATTR(HLF_T));
-
- for (i = 0; i < num_matches && !got_int; i++) {
- parse_match(matches[i], &tagp);
- if (!new_tag && (
- (g_do_tagpreview != 0
- && i == ptag_entry.cur_match)
- || (use_tagstack
- && i == tagstack[tagstackidx].cur_match))) {
- *IObuff = '>';
- } else {
- *IObuff = ' ';
+
+ // Find out the actual file name. If it is long, truncate
+ // it and put "..." in the middle
+ p = tag_full_fname(&tagp);
+ if (p != NULL) {
+ msg_outtrans_attr(p, HL_ATTR(HLF_D));
+ XFREE_CLEAR(p);
+ }
+ if (msg_col > 0) {
+ msg_putchar('\n');
+ }
+ if (got_int) {
+ break;
+ }
+ msg_advance(15);
+
+ // print any extra fields
+ command_end = tagp.command_end;
+ if (command_end != NULL) {
+ p = command_end + 3;
+ while (*p && *p != '\r' && *p != '\n') {
+ while (*p == TAB) {
+ p++;
}
- vim_snprintf((char *)IObuff + 1, IOSIZE - 1,
- "%2d %s ", i + 1,
- mt_names[matches[i][0] & MT_MASK]);
- msg_puts((char *)IObuff);
- if (tagp.tagkind != NULL) {
- msg_outtrans_len(tagp.tagkind,
- (int)(tagp.tagkind_end - tagp.tagkind));
+
+ // skip "file:" without a value (static tag)
+ if (STRNCMP(p, "file:", 5) == 0 && ascii_isspace(p[5])) {
+ p += 5;
+ continue;
}
- msg_advance(13);
- msg_outtrans_len_attr(tagp.tagname,
- (int)(tagp.tagname_end - tagp.tagname),
- HL_ATTR(HLF_T));
- msg_putchar(' ');
- taglen_advance(taglen);
-
- // Find out the actual file name. If it is long, truncate
- // it and put "..." in the middle
- p = tag_full_fname(&tagp);
- if (p != NULL) {
- msg_outtrans_attr(p, HL_ATTR(HLF_D));
- XFREE_CLEAR(p);
+ // skip "kind:<kind>" and "<kind>"
+ if (p == tagp.tagkind
+ || (p + 5 == tagp.tagkind
+ && STRNCMP(p, "kind:", 5) == 0)) {
+ p = tagp.tagkind_end;
+ continue;
}
- if (msg_col > 0) {
+ // print all other extra fields
+ attr = HL_ATTR(HLF_CM);
+ while (*p && *p != '\r' && *p != '\n') {
+ if (msg_col + ptr2cells(p) >= Columns) {
msg_putchar('\n');
+ if (got_int) {
+ break;
+ }
+ msg_advance(15);
+ }
+ p = msg_outtrans_one(p, attr);
+ if (*p == TAB) {
+ msg_puts_attr(" ", attr);
+ break;
+ }
+ if (*p == ':') {
+ attr = 0;
+ }
}
+ }
+ if (msg_col > 15) {
+ msg_putchar('\n');
if (got_int) {
- break;
+ break;
}
msg_advance(15);
+ }
+ } else {
+ for (p = tagp.command;
+ *p && *p != '\r' && *p != '\n';
+ p++) {
+ }
+ command_end = p;
+ }
- // print any extra fields
- command_end = tagp.command_end;
- if (command_end != NULL) {
- p = command_end + 3;
- while (*p && *p != '\r' && *p != '\n') {
- while (*p == TAB) {
- p++;
- }
-
- // skip "file:" without a value (static tag)
- if (STRNCMP(p, "file:", 5) == 0 && ascii_isspace(p[5])) {
- p += 5;
- continue;
- }
- // skip "kind:<kind>" and "<kind>"
- if (p == tagp.tagkind
- || (p + 5 == tagp.tagkind
- && STRNCMP(p, "kind:", 5) == 0)) {
- p = tagp.tagkind_end;
- continue;
- }
- // print all other extra fields
- attr = HL_ATTR(HLF_CM);
- while (*p && *p != '\r' && *p != '\n') {
- if (msg_col + ptr2cells(p) >= Columns) {
- msg_putchar('\n');
- if (got_int) {
- break;
- }
- msg_advance(15);
- }
- p = msg_outtrans_one(p, attr);
- if (*p == TAB) {
- msg_puts_attr(" ", attr);
- break;
- }
- if (*p == ':') {
- attr = 0;
- }
- }
- }
- if (msg_col > 15) {
- msg_putchar('\n');
- if (got_int) {
- break;
- }
- msg_advance(15);
- }
- } else {
- for (p = tagp.command;
- *p && *p != '\r' && *p != '\n';
- p++) {
- }
- command_end = p;
- }
-
- // Put the info (in several lines) at column 15.
- // Don't display "/^" and "?^".
- p = tagp.command;
- if (*p == '/' || *p == '?') {
- p++;
- if (*p == '^') {
- p++;
- }
- }
- // Remove leading whitespace from pattern
- while (p != command_end && ascii_isspace(*p)) {
- p++;
- }
+ // Put the info (in several lines) at column 15.
+ // Don't display "/^" and "?^".
+ p = tagp.command;
+ if (*p == '/' || *p == '?') {
+ p++;
+ if (*p == '^') {
+ p++;
+ }
+ }
+ // Remove leading whitespace from pattern
+ while (p != command_end && ascii_isspace(*p)) {
+ p++;
+ }
- while (p != command_end) {
- if (msg_col + (*p == TAB ? 1 : ptr2cells(p)) > Columns) {
- msg_putchar('\n');
- }
- if (got_int) {
- break;
- }
- msg_advance(15);
+ while (p != command_end) {
+ if (msg_col + (*p == TAB ? 1 : ptr2cells(p)) > Columns) {
+ msg_putchar('\n');
+ }
+ if (got_int) {
+ break;
+ }
+ msg_advance(15);
- // skip backslash used for escaping a command char or
- // a backslash
- if (*p == '\\' && (*(p + 1) == *tagp.command
- || *(p + 1) == '\\')) {
- p++;
- }
+ // skip backslash used for escaping a command char or
+ // a backslash
+ if (*p == '\\' && (*(p + 1) == *tagp.command
+ || *(p + 1) == '\\')) {
+ p++;
+ }
- if (*p == TAB) {
- msg_putchar(' ');
- p++;
- } else {
- p = msg_outtrans_one(p, 0);
- }
+ if (*p == TAB) {
+ msg_putchar(' ');
+ p++;
+ } else {
+ p = msg_outtrans_one(p, 0);
+ }
- // don't display the "$/;\"" and "$?;\""
- if (p == command_end - 2 && *p == '$'
- && *(p + 1) == *tagp.command) {
- break;
- }
- // don't display matching '/' or '?'
- if (p == command_end - 1 && *p == *tagp.command
- && (*p == '/' || *p == '?')) {
- break;
- }
- }
- if (msg_col) {
- msg_putchar('\n');
- }
- os_breakcheck();
+ // don't display the "$/;\"" and "$?;\""
+ if (p == command_end - 2 && *p == '$'
+ && *(p + 1) == *tagp.command) {
+ break;
+ }
+ // don't display matching '/' or '?'
+ if (p == command_end - 1 && *p == *tagp.command
+ && (*p == '/' || *p == '?')) {
+ break;
+ }
}
- if (got_int) {
- got_int = false; // only stop the listing
+ if (msg_col) {
+ msg_putchar('\n');
}
+ os_breakcheck();
+ }
+ if (got_int) {
+ got_int = false; // only stop the listing
+ }
}
//
// Add the matching tags to the location list for the current
// window.
//
-static int
-add_llist_tags(
- char_u *tag,
- int num_matches,
- char_u **matches)
+static int add_llist_tags(char_u *tag, int num_matches, char_u **matches)
{
- list_T *list;
- char_u tag_name[128 + 1];
- char_u *fname;
- char_u *cmd;
- int i;
- char_u *p;
- tagptrs_T tagp;
-
- fname = xmalloc(MAXPATHL + 1);
- cmd = xmalloc(CMDBUFFSIZE + 1);
- list = tv_list_alloc(0);
-
- for (i = 0; i < num_matches; i++) {
- int len, cmd_len;
- long lnum;
- dict_T *dict;
-
- parse_match(matches[i], &tagp);
-
- // Save the tag name
- len = (int)(tagp.tagname_end - tagp.tagname);
- if (len > 128) {
- len = 128;
- }
- xstrlcpy((char *)tag_name, (const char *)tagp.tagname, len + 1);
- tag_name[len] = NUL;
+ list_T *list;
+ char_u tag_name[128 + 1];
+ char_u *fname;
+ char_u *cmd;
+ int i;
+ char_u *p;
+ tagptrs_T tagp;
- // Save the tag file name
- p = tag_full_fname(&tagp);
- if (p == NULL) {
- continue;
- }
- xstrlcpy((char *)fname, (const char *)p, MAXPATHL);
- XFREE_CLEAR(p);
-
- // Get the line number or the search pattern used to locate
- // the tag.
- lnum = 0;
- if (isdigit(*tagp.command)) {
- // Line number is used to locate the tag
- lnum = atol((char *)tagp.command);
- } else {
- char_u *cmd_start, *cmd_end;
+ fname = xmalloc(MAXPATHL + 1);
+ cmd = xmalloc(CMDBUFFSIZE + 1);
+ list = tv_list_alloc(0);
- // Search pattern is used to locate the tag
+ for (i = 0; i < num_matches; i++) {
+ int len, cmd_len;
+ long lnum;
+ dict_T *dict;
- // Locate the end of the command
- cmd_start = tagp.command;
- cmd_end = tagp.command_end;
- if (cmd_end == NULL) {
- for (p = tagp.command;
- *p && *p != '\r' && *p != '\n'; p++) {
- }
- cmd_end = p;
- }
+ parse_match(matches[i], &tagp);
- // Now, cmd_end points to the character after the
- // command. Adjust it to point to the last
- // character of the command.
- cmd_end--;
+ // Save the tag name
+ len = (int)(tagp.tagname_end - tagp.tagname);
+ if (len > 128) {
+ len = 128;
+ }
+ STRLCPY(tag_name, tagp.tagname, len + 1);
+ tag_name[len] = NUL;
- // Skip the '/' and '?' characters at the
- // beginning and end of the search pattern.
- if (*cmd_start == '/' || *cmd_start == '?') {
- cmd_start++;
- }
+ // Save the tag file name
+ p = tag_full_fname(&tagp);
+ if (p == NULL) {
+ continue;
+ }
+ STRLCPY(fname, p, MAXPATHL);
+ XFREE_CLEAR(p);
+
+ // Get the line number or the search pattern used to locate
+ // the tag.
+ lnum = 0;
+ if (isdigit(*tagp.command)) {
+ // Line number is used to locate the tag
+ lnum = atol((char *)tagp.command);
+ } else {
+ char_u *cmd_start, *cmd_end;
- if (*cmd_end == '/' || *cmd_end == '?') {
- cmd_end--;
- }
+ // Search pattern is used to locate the tag
- len = 0;
- cmd[0] = NUL;
+ // Locate the end of the command
+ cmd_start = tagp.command;
+ cmd_end = tagp.command_end;
+ if (cmd_end == NULL) {
+ for (p = tagp.command;
+ *p && *p != '\r' && *p != '\n'; p++) {
+ }
+ cmd_end = p;
+ }
- // If "^" is present in the tag search pattern, then
- // copy it first.
- if (*cmd_start == '^') {
- STRCPY(cmd, "^");
- cmd_start++;
- len++;
- }
+ // Now, cmd_end points to the character after the
+ // command. Adjust it to point to the last
+ // character of the command.
+ cmd_end--;
- // Precede the tag pattern with \V to make it very
- // nomagic.
- STRCAT(cmd, "\\V");
- len += 2;
+ // Skip the '/' and '?' characters at the
+ // beginning and end of the search pattern.
+ if (*cmd_start == '/' || *cmd_start == '?') {
+ cmd_start++;
+ }
- cmd_len = (int)(cmd_end - cmd_start + 1);
- if (cmd_len > (CMDBUFFSIZE - 5)) {
- cmd_len = CMDBUFFSIZE - 5;
- }
- snprintf((char *)cmd + len, CMDBUFFSIZE + 1 - len,
- "%.*s", cmd_len, cmd_start);
- len += cmd_len;
-
- if (cmd[len - 1] == '$') {
- // Replace '$' at the end of the search pattern
- // with '\$'
- cmd[len - 1] = '\\';
- cmd[len] = '$';
- len++;
- }
+ if (*cmd_end == '/' || *cmd_end == '?') {
+ cmd_end--;
+ }
- cmd[len] = NUL;
- }
+ len = 0;
+ cmd[0] = NUL;
- dict = tv_dict_alloc();
- tv_list_append_dict(list, dict);
+ // If "^" is present in the tag search pattern, then
+ // copy it first.
+ if (*cmd_start == '^') {
+ STRCPY(cmd, "^");
+ cmd_start++;
+ len++;
+ }
- tv_dict_add_str(dict, S_LEN("text"), (const char *)tag_name);
- tv_dict_add_str(dict, S_LEN("filename"), (const char *)fname);
- tv_dict_add_nr(dict, S_LEN("lnum"), lnum);
- if (lnum == 0) {
- tv_dict_add_str(dict, S_LEN("pattern"), (const char *)cmd);
- }
+ // Precede the tag pattern with \V to make it very
+ // nomagic.
+ STRCAT(cmd, "\\V");
+ len += 2;
+
+ cmd_len = (int)(cmd_end - cmd_start + 1);
+ if (cmd_len > (CMDBUFFSIZE - 5)) {
+ cmd_len = CMDBUFFSIZE - 5;
+ }
+ snprintf((char *)cmd + len, CMDBUFFSIZE + 1 - len,
+ "%.*s", cmd_len, cmd_start);
+ len += cmd_len;
+
+ if (cmd[len - 1] == '$') {
+ // Replace '$' at the end of the search pattern
+ // with '\$'
+ cmd[len - 1] = '\\';
+ cmd[len] = '$';
+ len++;
+ }
+
+ cmd[len] = NUL;
}
- vim_snprintf((char *)IObuff, IOSIZE, "ltag %s", tag);
- set_errorlist(curwin, list, ' ', IObuff, NULL);
+ dict = tv_dict_alloc();
+ tv_list_append_dict(list, dict);
- tv_list_free(list);
- XFREE_CLEAR(fname);
- XFREE_CLEAR(cmd);
+ tv_dict_add_str(dict, S_LEN("text"), (const char *)tag_name);
+ tv_dict_add_str(dict, S_LEN("filename"), (const char *)fname);
+ tv_dict_add_nr(dict, S_LEN("lnum"), lnum);
+ if (lnum == 0) {
+ tv_dict_add_str(dict, S_LEN("pattern"), (const char *)cmd);
+ }
+ }
- return OK;
+ vim_snprintf((char *)IObuff, IOSIZE, "ltag %s", tag);
+ set_errorlist(curwin, list, ' ', IObuff, NULL);
+
+ tv_list_free(list);
+ XFREE_CLEAR(fname);
+ XFREE_CLEAR(cmd);
+
+ return OK;
}
/*
@@ -1024,8 +1022,9 @@ static void taglen_advance(int l)
if (l == MAXCOL) {
msg_putchar('\n');
msg_advance(24);
- } else
+ } else {
msg_advance(13 + l);
+ }
}
/*
@@ -1034,18 +1033,19 @@ static void taglen_advance(int l)
void do_tags(exarg_T *eap)
{
int i;
- char_u *name;
- taggy_T *tagstack = curwin->w_tagstack;
+ char_u *name;
+ taggy_T *tagstack = curwin->w_tagstack;
int tagstackidx = curwin->w_tagstackidx;
int tagstacklen = curwin->w_tagstacklen;
- /* Highlight title */
+ // Highlight title
MSG_PUTS_TITLE(_("\n # TO tag FROM line in file/text"));
for (i = 0; i < tagstacklen; ++i) {
if (tagstack[i].tagname != NULL) {
name = fm_getname(&(tagstack[i].fmark), 30);
- if (name == NULL) /* file name not available */
+ if (name == NULL) { // file name not available
continue;
+ }
msg_putchar('\n');
vim_snprintf((char *)IObuff, IOSIZE, "%c%2d %2d %-15s %5ld ",
@@ -1059,10 +1059,11 @@ void do_tags(exarg_T *eap)
? HL_ATTR(HLF_D) : 0);
xfree(name);
}
- ui_flush(); /* show one line at a time */
+ ui_flush(); // show one line at a time
}
- if (tagstackidx == tagstacklen) /* idx at top of stack */
+ if (tagstackidx == tagstacklen) { // idx at top of stack
MSG_PUTS("\n>");
+ }
}
@@ -1078,15 +1079,17 @@ static int tag_strnicmp(char_u *s1, char_u *s2, size_t len)
while (len > 0) {
i = TOUPPER_ASC(*s1) - TOUPPER_ASC(*s2);
- if (i != 0)
- return i; /* this character different */
- if (*s1 == NUL)
- break; /* strings match until NUL */
+ if (i != 0) {
+ return i; // this character different
+ }
+ if (*s1 == NUL) {
+ break; // strings match until NUL
+ }
++s1;
++s2;
--len;
}
- return 0; /* strings match */
+ return 0; // strings match
}
@@ -1098,50 +1101,56 @@ static void prepare_pats(pat_T *pats, int has_re)
pats->head = pats->pat;
pats->headlen = pats->len;
if (has_re) {
- /* When the pattern starts with '^' or "\\<", binary searching can be
- * used (much faster). */
- if (pats->pat[0] == '^')
+ // When the pattern starts with '^' or "\\<", binary searching can be
+ // used (much faster).
+ if (pats->pat[0] == '^') {
pats->head = pats->pat + 1;
- else if (pats->pat[0] == '\\' && pats->pat[1] == '<')
+ } else if (pats->pat[0] == '\\' && pats->pat[1] == '<') {
pats->head = pats->pat + 2;
- if (pats->head == pats->pat)
+ }
+ if (pats->head == pats->pat) {
pats->headlen = 0;
- else
+ } else {
for (pats->headlen = 0; pats->head[pats->headlen] != NUL;
- ++pats->headlen)
+ ++pats->headlen) {
if (vim_strchr((char_u *)(p_magic ? ".[~*\\$" : "\\$"),
- pats->head[pats->headlen]) != NULL)
+ pats->head[pats->headlen]) != NULL) {
break;
- if (p_tl != 0 && pats->headlen > p_tl) /* adjust for 'taglength' */
+ }
+ }
+ }
+ if (p_tl != 0 && pats->headlen > p_tl) { // adjust for 'taglength'
pats->headlen = p_tl;
+ }
}
- if (has_re)
+ if (has_re) {
pats->regmatch.regprog = vim_regcomp(pats->pat, p_magic ? RE_MAGIC : 0);
- else
+ } else {
pats->regmatch.regprog = NULL;
+ }
}
-//
-// Call the user-defined function to generate a list of tags used by
-// find_tags().
-//
-// Return OK if at least 1 tag has been successfully found,
-// NOTDONE if the function returns v:null, and FAIL otherwise.
-//
-static int find_tagfunc_tags(
- char_u *pat, // pattern supplied to the user-defined function
- garray_T *ga, // the tags will be placed here
- int *match_count, // here the number of tags found will be placed
- int flags, // flags from find_tags (TAG_*)
- char_u *buf_ffname) // name of buffer for priority
+/// Call the user-defined function to generate a list of tags used by
+/// find_tags().
+///
+/// Return OK if at least 1 tag has been successfully found,
+/// NOTDONE if the function returns v:null, and FAIL otherwise.
+///
+/// @param pat pattern supplied to the user-defined function
+/// @param ga the tags will be placed here
+/// @param match_count here the number of tags found will be placed
+/// @param flags flags from find_tags (TAG_*)
+/// @param buf_ffname name of buffer for priority
+static int find_tagfunc_tags(char_u *pat, garray_T *ga, int *match_count, int flags,
+ char_u *buf_ffname)
{
- pos_T save_pos;
- list_T *taglist;
- int ntags = 0;
- int result = FAIL;
- typval_T args[4];
- typval_T rettv;
+ pos_T save_pos;
+ list_T *taglist;
+ int ntags = 0;
+ int result = FAIL;
+ typval_T args[4];
+ typval_T rettv;
char_u flagString[4];
taggy_T *tag = &curwin->w_tagstack[curwin->w_tagstackidx];
@@ -1195,12 +1204,12 @@ static int find_tagfunc_tags(
taglist = rettv.vval.v_list;
TV_LIST_ITER_CONST(taglist, li, {
- char_u *res_name;
- char_u *res_fname;
- char_u *res_cmd;
- char_u *res_kind;
- int has_extra = 0;
- int name_only = flags & TAG_NAMES;
+ char_u *res_name;
+ char_u *res_fname;
+ char_u *res_cmd;
+ char_u *res_kind;
+ int has_extra = 0;
+ int name_only = flags & TAG_NAMES;
if (TV_LIST_ITEM_TV(li)->v_type != VAR_DICT) {
EMSG(_(tfu_inv_ret_msg));
@@ -1326,50 +1335,46 @@ static int find_tagfunc_tags(
return result;
}
-/*
- * find_tags() - search for tags in tags files
- *
- * Return FAIL if search completely failed (*num_matches will be 0, *matchesp
- * will be NULL), OK otherwise.
- *
- * There is a priority in which type of tag is recognized.
- *
- * 6. A static or global tag with a full matching tag for the current file.
- * 5. A global tag with a full matching tag for another file.
- * 4. A static tag with a full matching tag for another file.
- * 3. A static or global tag with an ignore-case matching tag for the
- * current file.
- * 2. A global tag with an ignore-case matching tag for another file.
- * 1. A static tag with an ignore-case matching tag for another file.
- *
- * Tags in an emacs-style tags file are always global.
- *
- * flags:
- * TAG_HELP only search for help tags
- * TAG_NAMES only return name of tag
- * TAG_REGEXP use "pat" as a regexp
- * TAG_NOIC don't always ignore case
- * TAG_KEEP_LANG keep language
- * TAG_CSCOPE use cscope results for tags
- * TAG_NO_TAGFUNC do not call the 'tagfunc' function
- */
-int
-find_tags(
- char_u *pat, // pattern to search for
- int *num_matches, // return: number of matches found
- char_u ***matchesp, // return: array of matches found
- int flags,
- int mincount, /* MAXCOL: find all matches
- other: minimal number of matches */
- char_u *buf_ffname /* name of buffer for priority */
-)
+/// find_tags() - search for tags in tags files
+///
+/// Return FAIL if search completely failed (*num_matches will be 0, *matchesp
+/// will be NULL), OK otherwise.
+///
+/// There is a priority in which type of tag is recognized.
+///
+/// 6. A static or global tag with a full matching tag for the current file.
+/// 5. A global tag with a full matching tag for another file.
+/// 4. A static tag with a full matching tag for another file.
+/// 3. A static or global tag with an ignore-case matching tag for the
+/// current file.
+/// 2. A global tag with an ignore-case matching tag for another file.
+/// 1. A static tag with an ignore-case matching tag for another file.
+///
+/// Tags in an emacs-style tags file are always global.
+///
+/// flags:
+/// TAG_HELP only search for help tags
+/// TAG_NAMES only return name of tag
+/// TAG_REGEXP use "pat" as a regexp
+/// TAG_NOIC don't always ignore case
+/// TAG_KEEP_LANG keep language
+/// TAG_CSCOPE use cscope results for tags
+/// TAG_NO_TAGFUNC do not call the 'tagfunc' function
+///
+/// @param pat pattern to search for
+/// @param num_matches return: number of matches found
+/// @param matchesp return: array of matches found
+/// @param mincount MAXCOL: find all matches other: minimal number of matches */
+/// @param buf_ffname name of buffer for priority
+int find_tags(char_u *pat, int *num_matches, char_u ***matchesp, int flags, int mincount,
+ char_u *buf_ffname)
{
- FILE *fp;
- char_u *lbuf; /* line buffer */
- int lbuf_size = LSIZE; /* length of lbuf */
- char_u *tag_fname; /* name of tag file */
- tagname_T tn; /* info for get_tagfname() */
- int first_file; /* trying first tag file */
+ FILE *fp;
+ char_u *lbuf; // line buffer
+ int lbuf_size = LSIZE; // length of lbuf
+ char_u *tag_fname; // name of tag file
+ tagname_T tn; // info for get_tagfname()
+ int first_file; // trying first tag file
tagptrs_T tagp;
bool did_open = false; // did open a tag file
bool stop_searching = false; // stop when match found or error
@@ -1377,8 +1382,8 @@ find_tags(
int is_static; // current tag line is static
int is_current; // file name matches
bool eof = false; // found end-of-file
- char_u *p;
- char_u *s;
+ char_u *p;
+ char_u *s;
int i;
int tag_file_sorted = NUL; // !_TAG_FILE_SORTED value
struct tag_search_info { // Binary search file offsets
@@ -1396,17 +1401,17 @@ find_tags(
off_T offset;
int round;
enum {
- TS_START, /* at start of file */
- TS_LINEAR /* linear searching forward, till EOF */
- , TS_BINARY, /* binary searching */
- TS_SKIP_BACK, /* skipping backwards */
- TS_STEP_FORWARD /* stepping forwards */
- } state; /* Current search state */
+ TS_START, // at start of file
+ TS_LINEAR, // linear searching forward, till EOF
+ TS_BINARY, // binary searching
+ TS_SKIP_BACK, // skipping backwards
+ TS_STEP_FORWARD // stepping forwards
+ } state; // Current search state
int cmplen;
- int match; /* matches */
- int match_no_ic = 0; /* matches with rm_ic == FALSE */
- int match_re; /* match with regexp */
+ int match; // matches
+ int match_no_ic = 0; // matches with rm_ic == FALSE
+ int match_re; // match with regexp
int matchoff = 0;
int save_emsg_off;
@@ -1416,16 +1421,16 @@ find_tags(
hashtab_T ht_match[MT_COUNT]; // stores matches by key
hash_T hash = 0;
int match_count = 0; // number of matches found
- char_u **matches;
+ char_u **matches;
int mtt;
int help_save;
int help_pri = 0;
- char_u *help_lang_find = NULL; // lang to be found
+ char_u *help_lang_find = NULL; // lang to be found
char_u help_lang[3]; // lang of current tags file
- char_u *saved_pat = NULL; // copy of pat[]
+ char_u *saved_pat = NULL; // copy of pat[]
bool is_txt = false;
- pat_T orgpat; /* holds unconverted pattern info */
+ pat_T orgpat; // holds unconverted pattern info
vimconv_T vimconv;
int findall = (mincount == MAXCOL || mincount == TAG_MANY);
@@ -1447,22 +1452,22 @@ find_tags(
// Change the value of 'ignorecase' according to 'tagcase' for the
// duration of this function.
switch (curbuf->b_tc_flags ? curbuf->b_tc_flags : tc_flags) {
- case TC_FOLLOWIC:
- break;
- case TC_IGNORE:
- p_ic = true;
- break;
- case TC_MATCH:
- p_ic = false;
- break;
- case TC_FOLLOWSCS:
- p_ic = ignorecase(pat);
- break;
- case TC_SMART:
- p_ic = ignorecase_opt(pat, true, true);
- break;
- default:
- abort();
+ case TC_FOLLOWIC:
+ break;
+ case TC_IGNORE:
+ p_ic = true;
+ break;
+ case TC_MATCH:
+ p_ic = false;
+ break;
+ case TC_FOLLOWSCS:
+ p_ic = ignorecase(pat);
+ break;
+ case TC_SMART:
+ p_ic = ignorecase_opt(pat, true, true);
+ break;
+ default:
+ abort();
}
help_save = curbuf->b_help;
@@ -1480,7 +1485,7 @@ find_tags(
hash_init(&ht_match[mtt]);
}
- STRCPY(tag_fname, "from cscope"); /* for error messages */
+ STRCPY(tag_fname, "from cscope"); // for error messages
/*
* Initialize a few variables
@@ -1495,8 +1500,8 @@ find_tags(
orgpat.len = (int)STRLEN(pat);
if (curbuf->b_help) {
- /* When "@ab" is specified use only the "ab" language, otherwise
- * search all languages. */
+ // When "@ab" is specified use only the "ab" language, otherwise
+ // search all languages.
if (orgpat.len > 3 && pat[orgpat.len - 3] == '@'
&& ASCII_ISALPHA(pat[orgpat.len - 2])
&& ASCII_ISALPHA(pat[orgpat.len - 1])) {
@@ -1506,15 +1511,17 @@ find_tags(
orgpat.len -= 3;
}
}
- if (p_tl != 0 && orgpat.len > p_tl) /* adjust for 'taglength' */
+ if (p_tl != 0 && orgpat.len > p_tl) { // adjust for 'taglength'
orgpat.len = p_tl;
+ }
save_emsg_off = emsg_off;
- emsg_off = TRUE; /* don't want error for invalid RE here */
+ emsg_off = TRUE; // don't want error for invalid RE here
prepare_pats(&orgpat, has_re);
emsg_off = save_emsg_off;
- if (has_re && orgpat.regmatch.regprog == NULL)
+ if (has_re && orgpat.regmatch.regprog == NULL) {
goto findtag_end;
+ }
// This is only to avoid a compiler warning for using search_info
// uninitialised.
@@ -1580,8 +1587,9 @@ find_tags(
/* When searching for a specific language skip tags files
* for other languages. */
if (help_lang_find != NULL
- && STRICMP(help_lang, help_lang_find) != 0)
+ && STRICMP(help_lang, help_lang_find) != 0) {
continue;
+ }
/* For CTRL-] in a help file prefer a match with the same
* language. */
@@ -1591,23 +1599,26 @@ find_tags(
&& (i = (int)STRLEN(curbuf->b_fname)) > 4
&& curbuf->b_fname[i - 1] == 'x'
&& curbuf->b_fname[i - 4] == '.'
- && STRNICMP(curbuf->b_fname + i - 3, help_lang, 2) == 0)
+ && STRNICMP(curbuf->b_fname + i - 3, help_lang, 2) == 0) {
help_pri = 0;
- else {
+ } else {
help_pri = 1;
for (s = p_hlg; *s != NUL; ++s) {
- if (STRNICMP(s, help_lang, 2) == 0)
+ if (STRNICMP(s, help_lang, 2) == 0) {
break;
+ }
++help_pri;
- if ((s = vim_strchr(s, ',')) == NULL)
+ if ((s = vim_strchr(s, ',')) == NULL) {
break;
+ }
}
if (s == NULL || *s == NUL) {
- /* Language not in 'helplang': use last, prefer English,
- * unless found already. */
- ++help_pri;
- if (STRICMP(help_lang, "en") != 0)
+ // Language not in 'helplang': use last, prefer English,
+ // unless found already.
+ help_pri++;
+ if (STRICMP(help_lang, "en") != 0) {
++help_pri;
+ }
}
}
}
@@ -1624,7 +1635,7 @@ find_tags(
}
did_open = true; // remember that we found at least one file
- state = TS_START; /* we're at the start of the file */
+ state = TS_START; // we're at the start of the file
/*
* Read and parse the lines in the file one by one
@@ -1636,31 +1647,34 @@ find_tags(
} else {
fast_breakcheck();
}
- if ((flags & TAG_INS_COMP)) /* Double brackets for gcc */
+ if ((flags & TAG_INS_COMP)) { // Double brackets for gcc
ins_compl_check_keys(30, false);
+ }
if (got_int || compl_interrupted) {
stop_searching = true;
break;
}
- /* When mincount is TAG_MANY, stop when enough matches have been
- * found (for completion). */
+ // When mincount is TAG_MANY, stop when enough matches have been
+ // found (for completion).
if (mincount == TAG_MANY && match_count >= TAG_MANY) {
stop_searching = true;
retval = OK;
break;
}
- if (get_it_again)
+ if (get_it_again) {
goto line_read_in;
+ }
/*
* For binary search: compute the next offset to use.
*/
if (state == TS_BINARY) {
offset = search_info.low_offset + ((search_info.high_offset
- search_info.low_offset) / 2);
- if (offset == search_info.curr_offset)
- break; /* End the binary search without a match. */
- else
+ if (offset == search_info.curr_offset) {
+ break; // End the binary search without a match.
+ } else {
search_info.curr_offset = offset;
+ }
} else if (state == TS_SKIP_BACK) {
// Skipping back (after a match during binary search).
search_info.curr_offset -= lbuf_size * 2;
@@ -1676,13 +1690,13 @@ find_tags(
* start of the next line.
*/
if (state == TS_BINARY || state == TS_SKIP_BACK) {
- /* Adjust the search file offset to the correct position */
+ // Adjust the search file offset to the correct position
search_info.curr_offset_used = search_info.curr_offset;
vim_fseek(fp, search_info.curr_offset, SEEK_SET);
eof = vim_fgets(lbuf, lbuf_size, fp);
if (!eof && search_info.curr_offset != 0) {
- /* The explicit cast is to work around a bug in gcc 3.4.2
- * (repeated below). */
+ // The explicit cast is to work around a bug in gcc 3.4.2
+ // (repeated below).
search_info.curr_offset = vim_ftell(fp);
if (search_info.curr_offset == search_info.high_offset) {
// oops, gone a bit too far; try from low offset
@@ -1691,13 +1705,13 @@ find_tags(
}
eof = vim_fgets(lbuf, lbuf_size, fp);
}
- /* skip empty and blank lines */
+ // skip empty and blank lines
while (!eof && vim_isblankline(lbuf)) {
search_info.curr_offset = vim_ftell(fp);
eof = vim_fgets(lbuf, lbuf_size, fp);
}
if (eof) {
- /* Hit end of file. Skip backwards. */
+ // Hit end of file. Skip backwards.
state = TS_SKIP_BACK;
search_info.match_offset = vim_ftell(fp);
search_info.curr_offset = search_info.curr_offset_used;
@@ -1708,7 +1722,7 @@ find_tags(
* Not jumping around in the file: Read the next line.
*/
else {
- /* skip empty and blank lines */
+ // skip empty and blank lines
do {
eof = use_cscope
? cs_fgets(lbuf, lbuf_size)
@@ -1716,21 +1730,21 @@ find_tags(
} while (!eof && vim_isblankline(lbuf));
if (eof) {
- break; /* end of file */
+ break; // end of file
}
}
line_read_in:
if (vimconv.vc_type != CONV_NONE) {
- char_u *conv_line;
+ char_u *conv_line;
int len;
- /* Convert every line. Converting the pattern from 'enc' to
- * the tags file encoding doesn't work, because characters are
- * not recognized. */
+ // Convert every line. Converting the pattern from 'enc' to
+ // the tags file encoding doesn't work, because characters are
+ // not recognized.
conv_line = string_convert(&vimconv, lbuf, NULL);
if (conv_line != NULL) {
- /* Copy or swap lbuf and conv_line. */
+ // Copy or swap lbuf and conv_line.
len = (int)STRLEN(conv_line) + 1;
if (len > lbuf_size) {
xfree(lbuf);
@@ -1750,34 +1764,35 @@ line_read_in:
* format, and for "not sorted" flag.
*/
if (state == TS_START) {
- /* The header ends when the line sorts below "!_TAG_". When
- * case is folded lower case letters sort before "_". */
+ // The header ends when the line sorts below "!_TAG_". When
+ // case is folded lower case letters sort before "_".
if (STRNCMP(lbuf, "!_TAG_", 6) <= 0
|| (lbuf[0] == '!' && ASCII_ISLOWER(lbuf[1]))) {
- if (STRNCMP(lbuf, "!_TAG_", 6) != 0)
- /* Non-header item before the header, e.g. "!" itself.
- */
+ if (STRNCMP(lbuf, "!_TAG_", 6) != 0) {
+ // Non-header item before the header, e.g. "!" itself.
goto parse_line;
+ }
/*
* Read header line.
*/
- if (STRNCMP(lbuf, "!_TAG_FILE_SORTED\t", 18) == 0)
+ if (STRNCMP(lbuf, "!_TAG_FILE_SORTED\t", 18) == 0) {
tag_file_sorted = lbuf[18];
+ }
if (STRNCMP(lbuf, "!_TAG_FILE_ENCODING\t", 20) == 0) {
- /* Prepare to convert every line from the specified
- * encoding to 'encoding'. */
- for (p = lbuf + 20; *p > ' ' && *p < 127; ++p)
- ;
+ // Prepare to convert every line from the specified
+ // encoding to 'encoding'.
+ for (p = lbuf + 20; *p > ' ' && *p < 127; p++) {
+ }
*p = NUL;
convert_setup(&vimconv, lbuf + 20, p_enc);
}
- /* Read the next line. Unrecognized flags are ignored. */
+ // Read the next line. Unrecognized flags are ignored.
continue;
}
- /* Headers ends. */
+ // Headers ends.
/*
* When there is no tag head, or ignoring case, need to do a
@@ -1788,23 +1803,24 @@ line_read_in:
* flag set.
* For cscope, it's always linear.
*/
- if (linear || use_cscope)
+ if (linear || use_cscope) {
state = TS_LINEAR;
- else if (tag_file_sorted == NUL)
+ } else if (tag_file_sorted == NUL) {
state = TS_BINARY;
- else if (tag_file_sorted == '1')
+ } else if (tag_file_sorted == '1') {
state = TS_BINARY;
- else if (tag_file_sorted == '2') {
+ } else if (tag_file_sorted == '2') {
state = TS_BINARY;
sortic = true;
orgpat.regmatch.rm_ic = (p_ic || !noic);
- } else
+ } else {
state = TS_LINEAR;
+ }
if (state == TS_BINARY && orgpat.regmatch.rm_ic && !sortic) {
- /* Binary search won't work for ignoring case, use linear
- * search. */
- linear = TRUE;
+ // Binary search won't work for ignoring case, use linear
+ // search.
+ linear = true;
state = TS_LINEAR;
}
@@ -1865,20 +1881,23 @@ parse_line:
* there is no regexp, or the tag is too short.
*/
cmplen = (int)(tagp.tagname_end - tagp.tagname);
- if (p_tl != 0 && cmplen > p_tl) /* adjust for 'taglength' */
+ if (p_tl != 0 && cmplen > p_tl) { // adjust for 'taglength'
cmplen = p_tl;
- if (has_re && orgpat.headlen < cmplen)
+ }
+ if (has_re && orgpat.headlen < cmplen) {
cmplen = orgpat.headlen;
- else if (state == TS_LINEAR && orgpat.headlen != cmplen)
+ } else if (state == TS_LINEAR && orgpat.headlen != cmplen) {
continue;
+ }
if (state == TS_BINARY) {
/*
* Simplistic check for unsorted tags file.
*/
i = (int)tagp.tagname[0];
- if (sortic)
+ if (sortic) {
i = TOUPPER_ASC(tagp.tagname[0]);
+ }
if (i < search_info.low_char || i > search_info.high_char) {
sort_error = true;
}
@@ -1886,27 +1905,28 @@ parse_line:
/*
* Compare the current tag with the searched tag.
*/
- if (sortic)
+ if (sortic) {
tagcmp = tag_strnicmp(tagp.tagname, orgpat.head,
- (size_t)cmplen);
- else
+ (size_t)cmplen);
+ } else {
tagcmp = STRNCMP(tagp.tagname, orgpat.head, cmplen);
+ }
/*
* A match with a shorter tag means to search forward.
* A match with a longer tag means to search backward.
*/
if (tagcmp == 0) {
- if (cmplen < orgpat.headlen)
+ if (cmplen < orgpat.headlen) {
tagcmp = -1;
- else if (cmplen > orgpat.headlen)
+ } else if (cmplen > orgpat.headlen) {
tagcmp = 1;
+ }
}
if (tagcmp == 0) {
- /* We've located the tag, now skip back and search
- * forward until the first matching tag is found.
- */
+ // We've located the tag, now skip back and search
+ // forward until the first matching tag is found.
state = TS_SKIP_BACK;
search_info.match_offset = search_info.curr_offset;
continue;
@@ -1915,37 +1935,40 @@ parse_line:
search_info.curr_offset = vim_ftell(fp);
if (search_info.curr_offset < search_info.high_offset) {
search_info.low_offset = search_info.curr_offset;
- if (sortic)
+ if (sortic) {
search_info.low_char =
TOUPPER_ASC(tagp.tagname[0]);
- else
+ } else {
search_info.low_char = tagp.tagname[0];
+ }
continue;
}
}
if (tagcmp > 0
&& search_info.curr_offset != search_info.high_offset) {
search_info.high_offset = search_info.curr_offset;
- if (sortic)
+ if (sortic) {
search_info.high_char =
TOUPPER_ASC(tagp.tagname[0]);
- else
+ } else {
search_info.high_char = tagp.tagname[0];
+ }
continue;
}
- /* No match yet and are at the end of the binary search. */
+ // No match yet and are at the end of the binary search.
break;
- } else if (state == TS_SKIP_BACK) {
+ } else if (state == TS_SKIP_BACK) {
assert(cmplen >= 0);
- if (mb_strnicmp(tagp.tagname, orgpat.head, (size_t)cmplen) != 0)
+ if (mb_strnicmp(tagp.tagname, orgpat.head, (size_t)cmplen) != 0) {
state = TS_STEP_FORWARD;
- else
- /* Have to skip back more. Restore the curr_offset
- * used, otherwise we get stuck at a long line. */
+ } else {
+ // Have to skip back more. Restore the curr_offset
+ // used, otherwise we get stuck at a long line.
search_info.curr_offset = search_info.curr_offset_used;
+ }
continue;
- } else if (state == TS_STEP_FORWARD) {
+ } else if (state == TS_STEP_FORWARD) {
assert(cmplen >= 0);
if (mb_strnicmp(tagp.tagname, orgpat.head, (size_t)cmplen) != 0) {
if ((off_T)vim_ftell(fp) > search_info.match_offset) {
@@ -1954,23 +1977,27 @@ parse_line:
continue; // before first match
}
}
- } else
- /* skip this match if it can't match */
- assert(cmplen >= 0);
- if (mb_strnicmp(tagp.tagname, orgpat.head, (size_t)cmplen) != 0)
+ } else {
+ // skip this match if it can't match
+ assert(cmplen >= 0);
+ }
+ if (mb_strnicmp(tagp.tagname, orgpat.head, (size_t)cmplen) != 0) {
continue;
+ }
// Can be a matching tag, isolate the file name and command.
tagp.fname = tagp.tagname_end + 1;
tagp.fname_end = vim_strchr(tagp.fname, TAB);
tagp.command = tagp.fname_end + 1;
- if (tagp.fname_end == NULL)
+ if (tagp.fname_end == NULL) {
i = FAIL;
- else
+ } else {
i = OK;
- } else
+ }
+ } else {
i = parse_tag_line(lbuf,
- &tagp);
+ &tagp);
+ }
if (i == FAIL) {
line_error = true;
break;
@@ -1981,20 +2008,23 @@ parse_line:
* a regexp).
*/
cmplen = (int)(tagp.tagname_end - tagp.tagname);
- if (p_tl != 0 && cmplen > p_tl) /* adjust for 'taglength' */
+ if (p_tl != 0 && cmplen > p_tl) { // adjust for 'taglength'
cmplen = p_tl;
- /* if tag length does not match, don't try comparing */
- if (orgpat.len != cmplen)
+ }
+ // if tag length does not match, don't try comparing
+ if (orgpat.len != cmplen) {
match = FALSE;
- else {
+ } else {
if (orgpat.regmatch.rm_ic) {
assert(cmplen >= 0);
match = mb_strnicmp(tagp.tagname, orgpat.pat, (size_t)cmplen) == 0;
- if (match)
+ if (match) {
match_no_ic = (STRNCMP(tagp.tagname, orgpat.pat,
- cmplen) == 0);
- } else
+ cmplen) == 0);
+ }
+ } else {
match = (STRNCMP(tagp.tagname, orgpat.pat, cmplen) == 0);
+ }
}
/*
@@ -2012,7 +2042,7 @@ parse_line:
if (orgpat.regmatch.rm_ic) {
orgpat.regmatch.rm_ic = FALSE;
match_no_ic = vim_regexec(&orgpat.regmatch, tagp.tagname,
- (colnr_T)0);
+ (colnr_T)0);
orgpat.regmatch.rm_ic = TRUE;
}
}
@@ -2025,7 +2055,7 @@ parse_line:
int len = 0;
if (use_cscope) {
- /* Don't change the ordering, always use the same table. */
+ // Don't change the ordering, always use the same table.
mtt = MT_GL_OTH;
} else {
// Decide in which array to store this match.
@@ -2035,27 +2065,31 @@ parse_line:
// Decide in which of the sixteen tables to store this match.
if (is_static) {
- if (is_current)
+ if (is_current) {
mtt = MT_ST_CUR;
- else
+ } else {
mtt = MT_ST_OTH;
+ }
} else {
- if (is_current)
+ if (is_current) {
mtt = MT_GL_CUR;
- else
+ } else {
mtt = MT_GL_OTH;
+ }
}
- if (orgpat.regmatch.rm_ic && !match_no_ic)
+ if (orgpat.regmatch.rm_ic && !match_no_ic) {
mtt += MT_IC_OFF;
- if (match_re)
+ }
+ if (match_re) {
mtt += MT_RE_OFF;
+ }
}
// Add the found match in ht_match[mtt] and ga_match[mtt].
// Store the info we need later, which depends on the kind of
// tags we are dealing with.
if (help_only) {
-# define ML_EXTRA 3
+#define ML_EXTRA 3
// Append the help-heuristic number after the tagname, for
// sorting it later. The heuristic is ignored for
// detecting duplicates.
@@ -2074,7 +2108,7 @@ parse_line:
+ help_pri);
*tagp.tagname_end = TAB;
- } else if (name_only) {
+ } else if (name_only) {
if (get_it_again) {
char_u *temp_end = tagp.command;
@@ -2148,7 +2182,7 @@ parse_line:
hash_add_item(&ht_match[mtt], hi, mfp, hash);
ga_grow(&ga_match[mtt], 1);
((char_u **)(ga_match[mtt].ga_data))
- [ga_match[mtt].ga_len++] = mfp;
+ [ga_match[mtt].ga_len++] = mfp;
match_count++;
} else {
// duplicate tag, drop it
@@ -2156,9 +2190,10 @@ parse_line:
}
}
}
- if (use_cscope && eof)
+ if (use_cscope && eof) {
break;
- } /* forever */
+ }
+ } // forever
if (line_error) {
EMSG2(_("E431: Format error in tags file \"%s\""), tag_fname);
@@ -2169,10 +2204,12 @@ parse_line:
line_error = false;
}
- if (!use_cscope)
+ if (!use_cscope) {
fclose(fp);
- if (vimconv.vc_type != CONV_NONE)
+ }
+ if (vimconv.vc_type != CONV_NONE) {
convert_setup(&vimconv, NULL, NULL);
+ }
tag_file_sorted = NUL;
if (sort_error) {
@@ -2188,27 +2225,31 @@ parse_line:
stop_searching = true;
}
- if (stop_searching || use_cscope)
+ if (stop_searching || use_cscope) {
break;
+ }
+ } // end of for-each-file loop
- } /* end of for-each-file loop */
-
- if (!use_cscope)
+ if (!use_cscope) {
tagname_free(&tn);
+ }
/* stop searching when already did a linear search, or when TAG_NOIC
* used, and 'ignorecase' not set or already did case-ignore search */
- if (stop_searching || linear || (!p_ic && noic) || orgpat.regmatch.rm_ic)
+ if (stop_searching || linear || (!p_ic && noic) || orgpat.regmatch.rm_ic) {
break;
- if (use_cscope)
+ }
+ if (use_cscope) {
break;
- orgpat.regmatch.rm_ic = TRUE; /* try another time while ignoring case */
+ }
+ orgpat.regmatch.rm_ic = TRUE; // try another time while ignoring case
}
if (!stop_searching) {
- if (!did_open && verbose) /* never opened any tags file */
+ if (!did_open && verbose) { // never opened any tags file
EMSG(_("E433: No tags file"));
- retval = OK; /* It's OK even when no tag found */
+ }
+ retval = OK; // It's OK even when no tag found
}
findtag_end:
@@ -2220,13 +2261,15 @@ findtag_end:
* Move the matches from the ga_match[] arrays into one list of
* matches. When retval == FAIL, free the matches.
*/
- if (retval == FAIL)
+ if (retval == FAIL) {
match_count = 0;
+ }
- if (match_count > 0)
+ if (match_count > 0) {
matches = xmalloc(match_count * sizeof(char_u *));
- else
+ } else {
matches = NULL;
+ }
match_count = 0;
for (mtt = 0; mtt < MT_COUNT; mtt++) {
for (i = 0; i < ga_match[mtt].ga_len; i++) {
@@ -2245,7 +2288,7 @@ findtag_end:
}
}
}
- matches[match_count++] = (char_u *)mfp;
+ matches[match_count++] = mfp;
}
}
@@ -2275,7 +2318,7 @@ static void found_tagfile_cb(char_u *fname, void *cookie)
char_u *const tag_fname = vim_strsave(fname);
#ifdef BACKSLASH_IN_FILENAME
- slash_adjust(tag_fname);
+ slash_adjust(tag_fname);
#endif
simplify_filename(tag_fname);
GA_APPEND(char_u *, &tag_fnames, tag_fname);
@@ -2293,24 +2336,22 @@ void free_tag_stuff(void)
#endif
-/*
- * Get the next name of a tag file from the tag file list.
- * For help files, use "tags" file only.
- *
- * Return FAIL if no more tag file names, OK otherwise.
- */
-int
-get_tagfname(
- tagname_T *tnp, // holds status info
- int first, // TRUE when first file name is wanted
- char_u *buf // pointer to buffer of MAXPATHL chars
-)
+/// Get the next name of a tag file from the tag file list.
+/// For help files, use "tags" file only.
+///
+/// @param tnp holds status info
+/// @param first TRUE when first file name is wanted
+/// @param buf pointer to buffer of MAXPATHL chars
+///
+/// @return FAIL if no more tag file names, OK otherwise.
+int get_tagfname(tagname_T *tnp, int first, char_u *buf)
{
- char_u *fname = NULL;
- char_u *r_ptr;
+ char_u *fname = NULL;
+ char_u *r_ptr;
- if (first)
+ if (first) {
memset(tnp, 0, sizeof(tagname_T));
+ }
if (curbuf->b_help) {
/*
@@ -2328,8 +2369,9 @@ get_tagfname(
if (tnp->tn_hf_idx >= tag_fnames.ga_len) {
/* Not found in 'runtimepath', use 'helpfile', if it exists and
* wasn't used yet, replacing "help.txt" with "tags". */
- if (tnp->tn_hf_idx > tag_fnames.ga_len || *p_hf == NUL)
+ if (tnp->tn_hf_idx > tag_fnames.ga_len || *p_hf == NUL) {
return FAIL;
+ }
++tnp->tn_hf_idx;
STRCPY(buf, p_hf);
STRCPY(path_tail(buf), "tags");
@@ -2367,14 +2409,15 @@ get_tagfname(
for (;; ) {
if (tnp->tn_did_filefind_init) {
fname = vim_findfile(tnp->tn_search_ctx);
- if (fname != NULL)
+ if (fname != NULL) {
break;
+ }
tnp->tn_did_filefind_init = FALSE;
} else {
- char_u *filename = NULL;
+ char_u *filename = NULL;
- /* Stop when used all parts of 'tags'. */
+ // Stop when used all parts of 'tags'.
if (*tnp->tn_np == NUL) {
vim_findfile_cleanup(tnp->tn_search_ctx);
tnp->tn_search_ctx = NULL;
@@ -2395,12 +2438,13 @@ get_tagfname(
*filename++ = NUL;
tnp->tn_search_ctx = vim_findfile_init(buf, filename,
- r_ptr, 100,
- FALSE, /* don't free visited list */
- FINDFILE_FILE, /* we search for a file */
- tnp->tn_search_ctx, TRUE, curbuf->b_ffname);
- if (tnp->tn_search_ctx != NULL)
+ r_ptr, 100,
+ FALSE, // don't free visited list
+ FINDFILE_FILE, // we search for a file
+ tnp->tn_search_ctx, TRUE, curbuf->b_ffname);
+ if (tnp->tn_search_ctx != NULL) {
tnp->tn_did_filefind_init = TRUE;
+ }
}
}
@@ -2420,43 +2464,44 @@ void tagname_free(tagname_T *tnp)
ga_clear_strings(&tag_fnames);
}
-/*
- * Parse one line from the tags file. Find start/end of tag name, start/end of
- * file name and start of search pattern.
- *
- * If is_etag is TRUE, tagp->fname and tagp->fname_end are not set.
- *
- * Return FAIL if there is a format error in this line, OK otherwise.
- */
-static int
-parse_tag_line(
- char_u *lbuf, // line to be parsed
- tagptrs_T *tagp
-)
+/// Parse one line from the tags file. Find start/end of tag name, start/end of
+/// file name and start of search pattern.
+///
+/// If is_etag is TRUE, tagp->fname and tagp->fname_end are not set.
+///
+/// @param lbuf line to be parsed
+///
+/// @return FAIL if there is a format error in this line, OK otherwise.
+static int parse_tag_line(char_u *lbuf, tagptrs_T *tagp)
{
- char_u *p;
+ char_u *p;
- /* Isolate the tagname, from lbuf up to the first white */
+ // Isolate the tagname, from lbuf up to the first white
tagp->tagname = lbuf;
p = vim_strchr(lbuf, TAB);
- if (p == NULL)
+ if (p == NULL) {
return FAIL;
+ }
tagp->tagname_end = p;
- /* Isolate file name, from first to second white space */
- if (*p != NUL)
+ // Isolate file name, from first to second white space
+ if (*p != NUL) {
++p;
+ }
tagp->fname = p;
p = vim_strchr(p, TAB);
- if (p == NULL)
+ if (p == NULL) {
return FAIL;
+ }
tagp->fname_end = p;
- /* find start of search command, after second white space */
- if (*p != NUL)
+ // find start of search command, after second white space
+ if (*p != NUL) {
++p;
- if (*p == NUL)
+ }
+ if (*p == NUL) {
return FAIL;
+ }
tagp->command = p;
return OK;
@@ -2466,12 +2511,12 @@ parse_tag_line(
* Check if tagname is a static tag
*
* Static tags produced by the older ctags program have the format:
- * 'file:tag file /pattern'.
+ * 'file:tag file /pattern'.
* This is only recognized when both occurrence of 'file' are the same, to
* avoid recognizing "string::string" or ":exit".
*
* Static tags produced by the new ctags program have the format:
- * 'tag file /pattern/;"<Tab>file:' "
+ * 'tag file /pattern/;"<Tab>file:' "
*
* Return TRUE if it is a static tag and adjust *tagname to the real tag.
* Return FALSE if it is not a static tag.
@@ -2484,8 +2529,9 @@ static bool test_for_static(tagptrs_T *tagp)
p = tagp->command;
while ((p = vim_strchr(p, '\t')) != NULL) {
++p;
- if (STRNCMP(p, "file:", 5) == 0)
+ if (STRNCMP(p, "file:", 5) == 0) {
return TRUE;
+ }
}
return FALSE;
@@ -2501,32 +2547,29 @@ static size_t matching_line_len(const char_u *const lbuf)
return (p - lbuf) + STRLEN(p);
}
-/*
- * Parse a line from a matching tag. Does not change the line itself.
- *
- * The line that we get looks like this:
- * Emacs tag: <mtt><tag_fname><NUL><ebuf><NUL><lbuf>
- * other tag: <mtt><tag_fname><NUL><NUL><lbuf>
- * without Emacs tags: <mtt><tag_fname><NUL><lbuf>
- *
- * Return OK or FAIL.
- */
-static int
-parse_match(
- char_u *lbuf, // input: matching line
- tagptrs_T *tagp // output: pointers into the line
-)
+/// Parse a line from a matching tag. Does not change the line itself.
+///
+/// The line that we get looks like this:
+/// Emacs tag: <mtt><tag_fname><NUL><ebuf><NUL><lbuf>
+/// other tag: <mtt><tag_fname><NUL><NUL><lbuf>
+/// without Emacs tags: <mtt><tag_fname><NUL><lbuf>
+///
+/// @param lbuf input: matching line
+/// @param tagp output: pointers into the line
+///
+/// @return OK or FAIL.
+static int parse_match(char_u *lbuf, tagptrs_T *tagp)
{
int retval;
- char_u *p;
- char_u *pc, *pt;
+ char_u *p;
+ char_u *pc, *pt;
tagp->tag_fname = lbuf + 1;
lbuf += STRLEN(tagp->tag_fname) + 2;
- /* Find search pattern and the file name for non-etags. */
+ // Find search pattern and the file name for non-etags.
retval = parse_tag_line(lbuf,
- tagp);
+ tagp);
tagp->tagkind = NULL;
tagp->user_data = NULL;
@@ -2534,7 +2577,7 @@ parse_match(
tagp->command_end = NULL;
if (retval == OK) {
- /* Try to find a kind field: "kind:<kind>" or just "<kind>"*/
+ // Try to find a kind field: "kind:<kind>" or just "<kind>"
p = tagp->command;
if (find_extra(&p) == OK) {
tagp->command_end = p;
@@ -2562,8 +2605,9 @@ parse_match(
if (pc == NULL || (pt != NULL && pc > pt)) {
tagp->tagkind = p;
}
- if (pt == NULL)
+ if (pt == NULL) {
break;
+ }
p = pt;
MB_PTR_ADV(p);
}
@@ -2602,32 +2646,30 @@ static char_u *tag_full_fname(tagptrs_T *tagp)
return fullname;
}
-/*
- * Jump to a tag that has been found in one of the tag files
- *
- * returns OK for success, NOTAGFILE when file not found, FAIL otherwise.
- */
-static int jumpto_tag(
- const char_u *lbuf_arg, // line from the tags file for this tag
- int forceit, // :ta with !
- int keep_help // keep help flag (FALSE for cscope)
-)
+/// Jump to a tag that has been found in one of the tag files
+///
+/// @param lbuf_arg line from the tags file for this tag
+/// @param forceit :ta with !
+/// @param keep_help keep help flag (FALSE for cscope)
+///
+/// @return OK for success, NOTAGFILE when file not found, FAIL otherwise.
+static int jumpto_tag(const char_u *lbuf_arg, int forceit, int keep_help)
{
int save_magic;
bool save_p_ws;
int save_p_scs, save_p_ic;
linenr_T save_lnum;
- char_u *str;
- char_u *pbuf; /* search pattern buffer */
- char_u *pbuf_end;
- char_u *tofree_fname = NULL;
- char_u *fname;
+ char_u *str;
+ char_u *pbuf; // search pattern buffer
+ char_u *pbuf_end;
+ char_u *tofree_fname = NULL;
+ char_u *fname;
tagptrs_T tagp;
int retval = FAIL;
int getfile_result = GETFILE_UNUSED;
int search_options;
- win_T *curwin_save = NULL;
- char_u *full_fname = NULL;
+ win_T *curwin_save = NULL;
+ char_u *full_fname = NULL;
const bool old_KeyTyped = KeyTyped; // getting the file may reset it
const int l_g_do_tagpreview = g_do_tagpreview;
const size_t len = matching_line_len(lbuf_arg) + 1;
@@ -2636,7 +2678,7 @@ static int jumpto_tag(
pbuf = xmalloc(LSIZE);
- /* parse the match line into the tagp structure */
+ // parse the match line into the tagp structure
if (parse_match(lbuf, &tagp) == FAIL) {
tagp.fname_end = NULL;
goto erret;
@@ -2646,7 +2688,7 @@ static int jumpto_tag(
*tagp.fname_end = NUL;
fname = tagp.fname;
- /* copy the command to pbuf[], remove trailing CR/NL */
+ // copy the command to pbuf[], remove trailing CR/NL
str = tagp.command;
for (pbuf_end = pbuf; *str && *str != '\n' && *str != '\r'; ) {
*pbuf_end++ = *str++;
@@ -2680,8 +2722,8 @@ static int jumpto_tag(
* autocommand event (e.g., http://sys/file).
*/
if (!os_path_exists(fname)
- && !has_autocmd(EVENT_BUFREADCMD, fname, NULL)
- ) {
+ && !has_autocmd(EVENT_BUFREADCMD, fname,
+ NULL)) {
retval = NOTAGFILE;
xfree(nofile_fname);
nofile_fname = vim_strsave(fname);
@@ -2692,8 +2734,8 @@ static int jumpto_tag(
if (l_g_do_tagpreview != 0) {
- postponed_split = 0; /* don't split again below */
- curwin_save = curwin; /* Save current window */
+ postponed_split = 0; // don't split again below
+ curwin_save = curwin; // Save current window
/*
* If we are reusing a window, we may change dir when
@@ -2750,10 +2792,11 @@ static int jumpto_tag(
if (keep_help) {
/* A :ta from a help file will keep the b_help flag set. For ":ptag"
* we need to use the flag from the window where we came from. */
- if (l_g_do_tagpreview != 0)
+ if (l_g_do_tagpreview != 0) {
keep_help_flag = curwin_save->w_buffer->b_help;
- else
+ } else {
keep_help_flag = curbuf->b_help;
+ }
}
if (getfile_result == GETFILE_UNUSED) {
@@ -2777,10 +2820,11 @@ static int jumpto_tag(
* command. If 'cpoptions' does not contain 't', the search pattern
* is not stored.
*/
- if (vim_strchr(p_cpo, CPO_TAGPAT) != NULL)
+ if (vim_strchr(p_cpo, CPO_TAGPAT) != NULL) {
search_options = 0;
- else
+ } else {
search_options = SEARCH_KEEP;
+ }
/*
* If the command is a search, try here.
@@ -2791,14 +2835,15 @@ static int jumpto_tag(
* anything following.
*/
str = pbuf;
- if (pbuf[0] == '/' || pbuf[0] == '?')
+ if (pbuf[0] == '/' || pbuf[0] == '?') {
str = skip_regexp(pbuf + 1, pbuf[0], FALSE, NULL) + 1;
- if (str > pbuf_end - 1) { /* search command with nothing following */
+ }
+ if (str > pbuf_end - 1) { // search command with nothing following
save_p_ws = p_ws;
save_p_ic = p_ic;
save_p_scs = p_scs;
- p_ws = true; /* need 'wrapscan' for backward searches */
- p_ic = FALSE; /* don't ignore case now */
+ p_ws = true; // need 'wrapscan' for backward searches
+ p_ic = FALSE; // don't ignore case now
p_scs = FALSE;
save_lnum = curwin->w_cursor.lnum;
if (tagp.tagline > 0) {
@@ -2898,15 +2943,17 @@ static int jumpto_tag(
* For a help buffer: Put the cursor line at the top of the window,
* the help subject will be below it.
*/
- if (curbuf->b_help)
+ if (curbuf->b_help) {
set_topline(curwin, curwin->w_cursor.lnum);
- if ((fdo_flags & FDO_TAG) && old_KeyTyped)
+ }
+ if ((fdo_flags & FDO_TAG) && old_KeyTyped) {
foldOpenCursor();
+ }
}
if (l_g_do_tagpreview != 0
&& curwin != curwin_save && win_valid(curwin_save)) {
- /* Return cursor to where we were */
+ // Return cursor to where we were
validate_cursor();
redraw_later(curwin, VALID);
win_enter(curwin_save, true);
@@ -2935,11 +2982,10 @@ erret:
// If 'tagrelative' option set, change fname (name of file containing tag)
// according to tag_fname (name of tag file containing fname).
// Returns a pointer to allocated memory.
-static char_u *expand_tag_fname(char_u *fname, char_u *const tag_fname,
- const bool expand)
+static char_u *expand_tag_fname(char_u *fname, char_u *const tag_fname, const bool expand)
{
- char_u *p;
- char_u *expanded_fname = NULL;
+ char_u *p;
+ char_u *expanded_fname = NULL;
expand_T xpc;
/*
@@ -2949,9 +2995,10 @@ static char_u *expand_tag_fname(char_u *fname, char_u *const tag_fname,
ExpandInit(&xpc);
xpc.xp_context = EXPAND_FILES;
expanded_fname = ExpandOne(&xpc, fname, NULL,
- WILD_LIST_NOTFOUND|WILD_SILENT, WILD_EXPAND_FREE);
- if (expanded_fname != NULL)
+ WILD_LIST_NOTFOUND|WILD_SILENT, WILD_EXPAND_FREE);
+ if (expanded_fname != NULL) {
fname = expanded_fname;
+ }
}
char_u *retval;
@@ -2961,13 +3008,14 @@ static char_u *expand_tag_fname(char_u *fname, char_u *const tag_fname,
retval = xmalloc(MAXPATHL);
STRCPY(retval, tag_fname);
STRLCPY(retval + (p - tag_fname), fname,
- MAXPATHL - (p - tag_fname));
+ MAXPATHL - (p - tag_fname));
/*
* Translate names like "src/a/../b/file.c" into "src/b/file.c".
*/
simplify_filename(retval);
- } else
+ } else {
retval = vim_strsave(fname);
+ }
xfree(expanded_fname);
@@ -2984,9 +3032,9 @@ static int test_for_current(char_u *fname, char_u *fname_end, char_u *tag_fname,
{
int c;
int retval = FALSE;
- char_u *fullname;
+ char_u *fullname;
- if (buf_ffname != NULL) { /* if the buffer has a name */
+ if (buf_ffname != NULL) { // if the buffer has a name
{
c = *fname_end;
*fname_end = NUL;
@@ -3053,13 +3101,8 @@ static void tagstack_clear_entry(taggy_T *item)
XFREE_CLEAR(item->user_data);
}
-int
-expand_tags (
- int tagnames, /* expand tag names */
- char_u *pat,
- int *num_file,
- char_u ***file
-)
+/// @param tagnames expand tag names
+int expand_tags(int tagnames, char_u *pat, int *num_file, char_u ***file)
{
int i;
int extra_flag;
@@ -3116,17 +3159,13 @@ expand_tags (
}
-/*
- * Add a tag field to the dictionary "dict".
- * Return OK or FAIL.
- */
-static int
-add_tag_field(
- dict_T *dict,
- const char *field_name,
- const char_u *start, // start of the value
- const char_u *end // after the value; can be NULL
-)
+/// Add a tag field to the dictionary "dict".
+/// Return OK or FAIL.
+///
+/// @param start start of the value
+/// @param end after the value; can be NULL
+static int add_tag_field(dict_T *dict, const char *field_name, const char_u *start,
+ const char_u *end)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
int len = 0;
@@ -3145,12 +3184,14 @@ add_tag_field(
if (start != NULL) {
if (end == NULL) {
end = start + STRLEN(start);
- while (end > start && (end[-1] == '\r' || end[-1] == '\n'))
+ while (end > start && (end[-1] == '\r' || end[-1] == '\n')) {
--end;
+ }
}
len = (int)(end - start);
- if (len > MAXPATHL - 1)
+ if (len > MAXPATHL - 1) {
len = MAXPATHL - 1;
+ }
STRLCPY(buf, start, len + 1);
}
buf[len] = NUL;
@@ -3165,9 +3206,9 @@ add_tag_field(
int get_tags(list_T *list, char_u *pat, char_u *buf_fname)
{
int num_matches, i, ret;
- char_u **matches;
- char_u *full_fname;
- dict_T *dict;
+ char_u **matches;
+ char_u *full_fname;
+ dict_T *dict;
tagptrs_T tp;
bool is_static;
@@ -3178,7 +3219,7 @@ int get_tags(list_T *list, char_u *pat, char_u *buf_fname)
int parse_result = parse_match(matches[i], &tp);
// Avoid an unused variable warning in release builds.
- (void) parse_result;
+ (void)parse_result;
assert(parse_result == OK);
is_static = test_for_static(&tp);
@@ -3216,29 +3257,35 @@ int get_tags(list_T *list, char_u *pat, char_u *buf_fname)
// skip "file:" (static tag)
p += 4;
} else if (!ascii_iswhite(*p)) {
- char_u *s, *n;
+ char_u *s, *n;
int len;
/* Add extra field as a dict entry. Fields are
* separated by Tabs. */
n = p;
- while (*p != NUL && *p >= ' ' && *p < 127 && *p != ':')
+ while (*p != NUL && *p >= ' ' && *p < 127 && *p != ':') {
++p;
+ }
len = (int)(p - n);
if (*p == ':' && len > 0) {
s = ++p;
- while (*p != NUL && *p >= ' ')
+ while (*p != NUL && *p >= ' ') {
++p;
+ }
n[len] = NUL;
- if (add_tag_field(dict, (char *)n, s, p) == FAIL)
+ if (add_tag_field(dict, (char *)n, s, p) == FAIL) {
ret = FAIL;
+ }
n[len] = ':';
- } else
- /* Skip field without colon. */
- while (*p != NUL && *p >= ' ')
+ } else {
+ // Skip field without colon.
+ while (*p != NUL && *p >= ' ') {
++p;
- if (*p == NUL)
+ }
+ }
+ if (*p == NUL) {
break;
+ }
}
}
}
@@ -3319,14 +3366,8 @@ static void tagstack_shift(win_T *wp)
}
// Push a new item to the tag stack
-static void tagstack_push_item(
- win_T *wp,
- char_u *tagname,
- int cur_fnum,
- int cur_match,
- pos_T mark,
- int fnum,
- char_u *user_data)
+static void tagstack_push_item(win_T *wp, char_u *tagname, int cur_fnum, int cur_match, pos_T mark,
+ int fnum, char_u *user_data)
{
taggy_T *tagstack = wp->w_tagstack;
int idx = wp->w_tagstacklen; // top of the stack
@@ -3382,13 +3423,12 @@ static void tagstack_push_items(win_T *wp, list_T *l)
if (mark.col > 0) {
mark.col--;
}
- tagstack_push_item(
- wp,
- tagname,
- (int)tv_dict_get_number(itemdict, "bufnr"),
- (int)tv_dict_get_number(itemdict, "matchnr") - 1,
- mark, fnum,
- (char_u *)tv_dict_get_string(itemdict, "user_data", true));
+ tagstack_push_item(wp,
+ tagname,
+ (int)tv_dict_get_number(itemdict, "bufnr"),
+ (int)tv_dict_get_number(itemdict, "matchnr") - 1,
+ mark, fnum,
+ (char_u *)tv_dict_get_string(itemdict, "user_data", true));
}
}
diff --git a/src/nvim/tag.h b/src/nvim/tag.h
index 9f671043b3..64bacceb1b 100644
--- a/src/nvim/tag.h
+++ b/src/nvim/tag.h
@@ -1,24 +1,24 @@
#ifndef NVIM_TAG_H
#define NVIM_TAG_H
-#include "nvim/types.h"
#include "nvim/ex_cmds_defs.h"
+#include "nvim/types.h"
/*
* Values for do_tag().
*/
-#define DT_TAG 1 /* jump to newer position or same tag again */
-#define DT_POP 2 /* jump to older position */
-#define DT_NEXT 3 /* jump to next match of same tag */
-#define DT_PREV 4 /* jump to previous match of same tag */
-#define DT_FIRST 5 /* jump to first match of same tag */
-#define DT_LAST 6 /* jump to first match of same tag */
-#define DT_SELECT 7 /* jump to selection from list */
-#define DT_HELP 8 /* like DT_TAG, but no wildcards */
-#define DT_JUMP 9 /* jump to new tag or selection from list */
-#define DT_CSCOPE 10 /* cscope find command (like tjump) */
-#define DT_LTAG 11 /* tag using location list */
-#define DT_FREE 99 /* free cached matches */
+#define DT_TAG 1 // jump to newer position or same tag again
+#define DT_POP 2 // jump to older position
+#define DT_NEXT 3 // jump to next match of same tag
+#define DT_PREV 4 // jump to previous match of same tag
+#define DT_FIRST 5 // jump to first match of same tag
+#define DT_LAST 6 // jump to first match of same tag
+#define DT_SELECT 7 // jump to selection from list
+#define DT_HELP 8 // like DT_TAG, but no wildcards
+#define DT_JUMP 9 // jump to new tag or selection from list
+#define DT_CSCOPE 10 // cscope find command (like tjump)
+#define DT_LTAG 11 // tag using location list
+#define DT_FREE 99 // free cached matches
//
// flags for find_tags().
@@ -40,11 +40,11 @@
* Structure used for get_tagfname().
*/
typedef struct {
- char_u *tn_tags; /* value of 'tags' when starting */
- char_u *tn_np; /* current position in tn_tags */
+ char_u *tn_tags; // value of 'tags' when starting
+ char_u *tn_np; // current position in tn_tags
int tn_did_filefind_init;
int tn_hf_idx;
- void *tn_search_ctx;
+ void *tn_search_ctx;
} tagname_T;
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index 3335fa500a..fb025265f2 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -37,45 +37,44 @@
// Some code from pangoterm http://www.leonerd.org.uk/code/pangoterm
#include <assert.h>
-#include <stdio.h>
-#include <stdint.h>
#include <stdbool.h>
-
+#include <stdint.h>
+#include <stdio.h>
#include <vterm.h>
-#include "nvim/log.h"
-#include "nvim/vim.h"
-#include "nvim/terminal.h"
-#include "nvim/message.h"
-#include "nvim/memory.h"
-#include "nvim/option.h"
-#include "nvim/highlight.h"
-#include "nvim/macros.h"
-#include "nvim/mbyte.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/change.h"
-#include "nvim/ascii.h"
+#include "nvim/edit.h"
+#include "nvim/event/loop.h"
+#include "nvim/event/time.h"
+#include "nvim/ex_cmds.h"
+#include "nvim/ex_docmd.h"
+#include "nvim/fileio.h"
#include "nvim/getchar.h"
-#include "nvim/ui.h"
-#include "nvim/syntax.h"
-#include "nvim/screen.h"
+#include "nvim/highlight.h"
#include "nvim/keymap.h"
-#include "nvim/edit.h"
-#include "nvim/mouse.h"
-#include "nvim/memline.h"
+#include "nvim/log.h"
+#include "nvim/macros.h"
+#include "nvim/main.h"
#include "nvim/map.h"
+#include "nvim/mbyte.h"
+#include "nvim/memline.h"
+#include "nvim/memory.h"
+#include "nvim/message.h"
#include "nvim/misc1.h"
+#include "nvim/mouse.h"
#include "nvim/move.h"
-#include "nvim/main.h"
+#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/screen.h"
#include "nvim/state.h"
-#include "nvim/ex_docmd.h"
-#include "nvim/ex_cmds.h"
+#include "nvim/syntax.h"
+#include "nvim/terminal.h"
+#include "nvim/ui.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/fileio.h"
-#include "nvim/event/loop.h"
-#include "nvim/event/time.h"
-#include "nvim/os/input.h"
-#include "nvim/api/private/helpers.h"
typedef struct terminal_state {
VimState state;
@@ -210,7 +209,7 @@ Terminal *terminal_open(buf_T *buf, TerminalOptions opts)
buf->b_p_ma = false; // 'nomodifiable'
buf->b_p_ul = -1; // 'undolevels'
buf->b_p_scbk = // 'scrollback' (initialize local from global)
- (p_scbk < 0) ? 10000 : MAX(1, p_scbk);
+ (p_scbk < 0) ? 10000 : MAX(1, p_scbk);
buf->b_p_tw = 0; // 'textwidth'
set_option_value("wrap", false, NULL, OPT_LOCAL);
set_option_value("list", false, NULL, OPT_LOCAL);
@@ -359,11 +358,21 @@ void terminal_enter(void)
// Disable these options in terminal-mode. They are nonsense because cursor is
// placed at end of buffer to "follow" output. #11072
win_T *save_curwin = curwin;
- int save_w_p_cul = curwin->w_p_cul;
+ bool save_w_p_cul = curwin->w_p_cul;
+ char_u *save_w_p_culopt = NULL;
+ char_u save_w_p_culopt_flags = curwin->w_p_culopt_flags;
int save_w_p_cuc = curwin->w_p_cuc;
long save_w_p_so = curwin->w_p_so;
long save_w_p_siso = curwin->w_p_siso;
- curwin->w_p_cul = false;
+ if (curwin->w_p_cul && curwin->w_p_culopt_flags & CULOPT_NBR) {
+ if (strcmp((char *)curwin->w_p_culopt, "number")) {
+ save_w_p_culopt = curwin->w_p_culopt;
+ curwin->w_p_culopt = (char_u *)xstrdup("number");
+ }
+ curwin->w_p_culopt_flags = CULOPT_NBR;
+ } else {
+ curwin->w_p_cul = false;
+ }
curwin->w_p_cuc = false;
curwin->w_p_so = 0;
curwin->w_p_siso = 0;
@@ -387,9 +396,16 @@ void terminal_enter(void)
if (save_curwin == curwin) { // save_curwin may be invalid (window closed)!
curwin->w_p_cul = save_w_p_cul;
+ if (save_w_p_culopt) {
+ xfree(curwin->w_p_culopt);
+ curwin->w_p_culopt = save_w_p_culopt;
+ }
+ curwin->w_p_culopt_flags = save_w_p_culopt_flags;
curwin->w_p_cuc = save_w_p_cuc;
curwin->w_p_so = save_w_p_so;
curwin->w_p_siso = save_w_p_siso;
+ } else if (save_w_p_culopt) {
+ xfree(save_w_p_culopt);
}
// draw the unfocused cursor
@@ -452,56 +468,56 @@ static int terminal_execute(VimState *state, int key)
TerminalState *s = (TerminalState *)state;
switch (key) {
- case K_LEFTMOUSE:
- case K_LEFTDRAG:
- case K_LEFTRELEASE:
- case K_MOUSEMOVE:
- case K_MIDDLEMOUSE:
- case K_MIDDLEDRAG:
- case K_MIDDLERELEASE:
- case K_RIGHTMOUSE:
- case K_RIGHTDRAG:
- case K_RIGHTRELEASE:
- case K_MOUSEDOWN:
- case K_MOUSEUP:
- if (send_mouse_event(s->term, key)) {
- return 0;
- }
- break;
-
- case K_EVENT:
- // We cannot let an event free the terminal yet. It is still needed.
- s->term->refcount++;
- state_handle_k_event();
- s->term->refcount--;
- if (s->term->buf_handle == 0) {
- s->close = true;
- return 0;
- }
- break;
+ case K_LEFTMOUSE:
+ case K_LEFTDRAG:
+ case K_LEFTRELEASE:
+ case K_MOUSEMOVE:
+ case K_MIDDLEMOUSE:
+ case K_MIDDLEDRAG:
+ case K_MIDDLERELEASE:
+ case K_RIGHTMOUSE:
+ case K_RIGHTDRAG:
+ case K_RIGHTRELEASE:
+ case K_MOUSEDOWN:
+ case K_MOUSEUP:
+ if (send_mouse_event(s->term, key)) {
+ return 0;
+ }
+ break;
+
+ case K_EVENT:
+ // We cannot let an event free the terminal yet. It is still needed.
+ s->term->refcount++;
+ state_handle_k_event();
+ s->term->refcount--;
+ if (s->term->buf_handle == 0) {
+ s->close = true;
+ return 0;
+ }
+ break;
- case K_COMMAND:
- do_cmdline(NULL, getcmdkeycmd, NULL, 0);
- break;
+ case K_COMMAND:
+ do_cmdline(NULL, getcmdkeycmd, NULL, 0);
+ break;
- case Ctrl_N:
- if (s->got_bsl) {
- return 0;
- }
- FALLTHROUGH;
+ case Ctrl_N:
+ if (s->got_bsl) {
+ return 0;
+ }
+ FALLTHROUGH;
- default:
- if (key == Ctrl_BSL && !s->got_bsl) {
- s->got_bsl = true;
- break;
- }
- if (s->term->closed) {
- s->close = true;
- return 0;
- }
+ default:
+ if (key == Ctrl_BSL && !s->got_bsl) {
+ s->got_bsl = true;
+ break;
+ }
+ if (s->term->closed) {
+ s->close = true;
+ return 0;
+ }
- s->got_bsl = false;
- terminal_send_key(s->term, key);
+ s->got_bsl = false;
+ terminal_send_key(s->term, key);
}
if (curbuf->terminal == NULL) {
@@ -554,30 +570,30 @@ static bool is_filter_char(int c)
{
unsigned int flag = 0;
switch (c) {
- case 0x08:
- flag = TPF_BS;
- break;
- case 0x09:
- flag = TPF_HT;
- break;
- case 0x0A:
- case 0x0D:
- break;
- case 0x0C:
- flag = TPF_FF;
- break;
- case 0x1b:
- flag = TPF_ESC;
- break;
- case 0x7F:
- flag = TPF_DEL;
- break;
- default:
- if (c < ' ') {
- flag = TPF_C0;
- } else if (c >= 0x80 && c <= 0x9F) {
- flag = TPF_C1;
- }
+ case 0x08:
+ flag = TPF_BS;
+ break;
+ case 0x09:
+ flag = TPF_HT;
+ break;
+ case 0x0A:
+ case 0x0D:
+ break;
+ case 0x0C:
+ flag = TPF_FF;
+ break;
+ case 0x1b:
+ flag = TPF_ESC;
+ break;
+ case 0x7F:
+ flag = TPF_DEL;
+ break;
+ default:
+ if (c < ' ') {
+ flag = TPF_C0;
+ } else if (c >= 0x80 && c <= 0x9F) {
+ flag = TPF_C1;
+ }
}
return !!(tpf_flags & flag);
}
@@ -666,8 +682,7 @@ static int get_rgb(VTermState *state, VTermColor color)
}
-void terminal_get_line_attributes(Terminal *term, win_T *wp, int linenr,
- int *term_attrs)
+void terminal_get_line_attributes(Terminal *term, win_T *wp, int linenr, int *term_attrs)
{
int height, width;
vterm_get_size(term->vt, &height, &width);
@@ -701,12 +716,12 @@ void terminal_get_line_attributes(Terminal *term, win_T *wp, int linenr,
bool bg_set = vt_bg_idx && vt_bg_idx <= 16 && term->color_set[vt_bg_idx-1];
int hl_attrs = (cell.attrs.bold ? HL_BOLD : 0)
- | (cell.attrs.italic ? HL_ITALIC : 0)
- | (cell.attrs.reverse ? HL_INVERSE : 0)
- | (cell.attrs.underline ? HL_UNDERLINE : 0)
- | (cell.attrs.strike ? HL_STRIKETHROUGH: 0)
- | ((fg_indexed && !fg_set) ? HL_FG_INDEXED : 0)
- | ((bg_indexed && !bg_set) ? HL_BG_INDEXED : 0);
+ | (cell.attrs.italic ? HL_ITALIC : 0)
+ | (cell.attrs.reverse ? HL_INVERSE : 0)
+ | (cell.attrs.underline ? HL_UNDERLINE : 0)
+ | (cell.attrs.strike ? HL_STRIKETHROUGH: 0)
+ | ((fg_indexed && !fg_set) ? HL_FG_INDEXED : 0)
+ | ((bg_indexed && !bg_set) ? HL_BG_INDEXED : 0);
int attr_id = 0;
@@ -757,12 +772,11 @@ static int term_damage(VTermRect rect, void *data)
static int term_moverect(VTermRect dest, VTermRect src, void *data)
{
invalidate_terminal(data, MIN(dest.start_row, src.start_row),
- MAX(dest.end_row, src.end_row));
+ MAX(dest.end_row, src.end_row));
return 1;
}
-static int term_movecursor(VTermPos new, VTermPos old, int visible,
- void *data)
+static int term_movecursor(VTermPos new, VTermPos old, int visible, void *data)
{
Terminal *term = data;
term->cursor.row = new.row;
@@ -791,26 +805,26 @@ static int term_settermprop(VTermProp prop, VTermValue *val, void *data)
Terminal *term = data;
switch (prop) {
- case VTERM_PROP_ALTSCREEN:
- break;
-
- case VTERM_PROP_CURSORVISIBLE:
- term->cursor.visible = val->boolean;
- invalidate_terminal(term, term->cursor.row, term->cursor.row + 1);
- break;
-
- case VTERM_PROP_TITLE: {
- buf_T *buf = handle_get_buffer(term->buf_handle);
- buf_set_term_title(buf, val->string);
- break;
- }
+ case VTERM_PROP_ALTSCREEN:
+ break;
+
+ case VTERM_PROP_CURSORVISIBLE:
+ term->cursor.visible = val->boolean;
+ invalidate_terminal(term, term->cursor.row, term->cursor.row + 1);
+ break;
+
+ case VTERM_PROP_TITLE: {
+ buf_T *buf = handle_get_buffer(term->buf_handle);
+ buf_set_term_title(buf, val->string);
+ break;
+ }
- case VTERM_PROP_MOUSE:
- term->forward_mouse = (bool)val->number;
- break;
+ case VTERM_PROP_MOUSE:
+ term->forward_mouse = (bool)val->number;
+ break;
- default:
- return 0;
+ default:
+ return 0;
}
return 1;
@@ -844,12 +858,11 @@ static int term_sb_push(int cols, const VTermScreenCell *cells, void *data)
// Make room at the start by shifting to the right.
memmove(term->sb_buffer + 1, term->sb_buffer,
- sizeof(term->sb_buffer[0]) * (term->sb_current - 1));
-
+ sizeof(term->sb_buffer[0]) * (term->sb_current - 1));
} else if (term->sb_current > 0) {
// Make room at the start by shifting to the right.
memmove(term->sb_buffer + 1, term->sb_buffer,
- sizeof(term->sb_buffer[0]) * term->sb_current);
+ sizeof(term->sb_buffer[0]) * term->sb_current);
}
if (!sbrow) {
@@ -894,7 +907,7 @@ static int term_sb_pop(int cols, VTermScreenCell *cells, void *data)
term->sb_current--;
// Forget the "popped" row by shifting the rest onto it.
memmove(term->sb_buffer, term->sb_buffer + 1,
- sizeof(term->sb_buffer[0]) * (term->sb_current));
+ sizeof(term->sb_buffer[0]) * (term->sb_current));
size_t cols_to_copy = (size_t)cols;
if (cols_to_copy > sbrow->cols) {
@@ -919,35 +932,41 @@ static int term_sb_pop(int cols, VTermScreenCell *cells, void *data)
static void convert_modifiers(int key, VTermModifier *statep)
{
- if (mod_mask & MOD_MASK_SHIFT) { *statep |= VTERM_MOD_SHIFT; }
- if (mod_mask & MOD_MASK_CTRL) { *statep |= VTERM_MOD_CTRL; }
- if (mod_mask & MOD_MASK_ALT) { *statep |= VTERM_MOD_ALT; }
+ if (mod_mask & MOD_MASK_SHIFT) {
+ *statep |= VTERM_MOD_SHIFT;
+ }
+ if (mod_mask & MOD_MASK_CTRL) {
+ *statep |= VTERM_MOD_CTRL;
+ }
+ if (mod_mask & MOD_MASK_ALT) {
+ *statep |= VTERM_MOD_ALT;
+ }
switch (key) {
- case K_S_TAB:
- case K_S_UP:
- case K_S_DOWN:
- case K_S_LEFT:
- case K_S_RIGHT:
- case K_S_F1:
- case K_S_F2:
- case K_S_F3:
- case K_S_F4:
- case K_S_F5:
- case K_S_F6:
- case K_S_F7:
- case K_S_F8:
- case K_S_F9:
- case K_S_F10:
- case K_S_F11:
- case K_S_F12:
- *statep |= VTERM_MOD_SHIFT;
- break;
-
- case K_C_LEFT:
- case K_C_RIGHT:
- *statep |= VTERM_MOD_CTRL;
- break;
+ case K_S_TAB:
+ case K_S_UP:
+ case K_S_DOWN:
+ case K_S_LEFT:
+ case K_S_RIGHT:
+ case K_S_F1:
+ case K_S_F2:
+ case K_S_F3:
+ case K_S_F4:
+ case K_S_F5:
+ case K_S_F6:
+ case K_S_F7:
+ case K_S_F8:
+ case K_S_F9:
+ case K_S_F10:
+ case K_S_F11:
+ case K_S_F12:
+ *statep |= VTERM_MOD_SHIFT;
+ break;
+
+ case K_C_LEFT:
+ case K_C_RIGHT:
+ *statep |= VTERM_MOD_CTRL;
+ break;
}
}
@@ -956,115 +975,212 @@ static VTermKey convert_key(int key, VTermModifier *statep)
convert_modifiers(key, statep);
switch (key) {
- case K_BS: return VTERM_KEY_BACKSPACE;
- case K_S_TAB: FALLTHROUGH;
- case TAB: return VTERM_KEY_TAB;
- case Ctrl_M: return VTERM_KEY_ENTER;
- case ESC: return VTERM_KEY_ESCAPE;
-
- case K_S_UP: FALLTHROUGH;
- case K_UP: return VTERM_KEY_UP;
- case K_S_DOWN: FALLTHROUGH;
- case K_DOWN: return VTERM_KEY_DOWN;
- case K_S_LEFT: FALLTHROUGH;
- case K_C_LEFT: FALLTHROUGH;
- case K_LEFT: return VTERM_KEY_LEFT;
- case K_S_RIGHT: FALLTHROUGH;
- case K_C_RIGHT: FALLTHROUGH;
- case K_RIGHT: return VTERM_KEY_RIGHT;
-
- case K_INS: return VTERM_KEY_INS;
- case K_DEL: return VTERM_KEY_DEL;
- case K_HOME: return VTERM_KEY_HOME;
- case K_END: return VTERM_KEY_END;
- case K_PAGEUP: return VTERM_KEY_PAGEUP;
- case K_PAGEDOWN: return VTERM_KEY_PAGEDOWN;
-
- case K_K0: FALLTHROUGH;
- case K_KINS: return VTERM_KEY_KP_0;
- case K_K1: FALLTHROUGH;
- case K_KEND: return VTERM_KEY_KP_1;
- case K_K2: FALLTHROUGH;
- case K_KDOWN: return VTERM_KEY_KP_2;
- case K_K3: FALLTHROUGH;
- case K_KPAGEDOWN: return VTERM_KEY_KP_3;
- case K_K4: FALLTHROUGH;
- case K_KLEFT: return VTERM_KEY_KP_4;
- case K_K5: FALLTHROUGH;
- case K_KORIGIN: return VTERM_KEY_KP_5;
- case K_K6: FALLTHROUGH;
- case K_KRIGHT: return VTERM_KEY_KP_6;
- case K_K7: FALLTHROUGH;
- case K_KHOME: return VTERM_KEY_KP_7;
- case K_K8: FALLTHROUGH;
- case K_KUP: return VTERM_KEY_KP_8;
- case K_K9: FALLTHROUGH;
- case K_KPAGEUP: return VTERM_KEY_KP_9;
- case K_KDEL: FALLTHROUGH;
- case K_KPOINT: return VTERM_KEY_KP_PERIOD;
- case K_KENTER: return VTERM_KEY_KP_ENTER;
- case K_KPLUS: return VTERM_KEY_KP_PLUS;
- case K_KMINUS: return VTERM_KEY_KP_MINUS;
- case K_KMULTIPLY: return VTERM_KEY_KP_MULT;
- case K_KDIVIDE: return VTERM_KEY_KP_DIVIDE;
-
- case K_S_F1: FALLTHROUGH;
- case K_F1: return VTERM_KEY_FUNCTION(1);
- case K_S_F2: FALLTHROUGH;
- case K_F2: return VTERM_KEY_FUNCTION(2);
- case K_S_F3: FALLTHROUGH;
- case K_F3: return VTERM_KEY_FUNCTION(3);
- case K_S_F4: FALLTHROUGH;
- case K_F4: return VTERM_KEY_FUNCTION(4);
- case K_S_F5: FALLTHROUGH;
- case K_F5: return VTERM_KEY_FUNCTION(5);
- case K_S_F6: FALLTHROUGH;
- case K_F6: return VTERM_KEY_FUNCTION(6);
- case K_S_F7: FALLTHROUGH;
- case K_F7: return VTERM_KEY_FUNCTION(7);
- case K_S_F8: FALLTHROUGH;
- case K_F8: return VTERM_KEY_FUNCTION(8);
- case K_S_F9: FALLTHROUGH;
- case K_F9: return VTERM_KEY_FUNCTION(9);
- case K_S_F10: FALLTHROUGH;
- case K_F10: return VTERM_KEY_FUNCTION(10);
- case K_S_F11: FALLTHROUGH;
- case K_F11: return VTERM_KEY_FUNCTION(11);
- case K_S_F12: FALLTHROUGH;
- case K_F12: return VTERM_KEY_FUNCTION(12);
-
- case K_F13: return VTERM_KEY_FUNCTION(13);
- case K_F14: return VTERM_KEY_FUNCTION(14);
- case K_F15: return VTERM_KEY_FUNCTION(15);
- case K_F16: return VTERM_KEY_FUNCTION(16);
- case K_F17: return VTERM_KEY_FUNCTION(17);
- case K_F18: return VTERM_KEY_FUNCTION(18);
- case K_F19: return VTERM_KEY_FUNCTION(19);
- case K_F20: return VTERM_KEY_FUNCTION(20);
- case K_F21: return VTERM_KEY_FUNCTION(21);
- case K_F22: return VTERM_KEY_FUNCTION(22);
- case K_F23: return VTERM_KEY_FUNCTION(23);
- case K_F24: return VTERM_KEY_FUNCTION(24);
- case K_F25: return VTERM_KEY_FUNCTION(25);
- case K_F26: return VTERM_KEY_FUNCTION(26);
- case K_F27: return VTERM_KEY_FUNCTION(27);
- case K_F28: return VTERM_KEY_FUNCTION(28);
- case K_F29: return VTERM_KEY_FUNCTION(29);
- case K_F30: return VTERM_KEY_FUNCTION(30);
- case K_F31: return VTERM_KEY_FUNCTION(31);
- case K_F32: return VTERM_KEY_FUNCTION(32);
- case K_F33: return VTERM_KEY_FUNCTION(33);
- case K_F34: return VTERM_KEY_FUNCTION(34);
- case K_F35: return VTERM_KEY_FUNCTION(35);
- case K_F36: return VTERM_KEY_FUNCTION(36);
- case K_F37: return VTERM_KEY_FUNCTION(37);
-
- default: return VTERM_KEY_NONE;
+ case K_BS:
+ return VTERM_KEY_BACKSPACE;
+ case K_S_TAB:
+ FALLTHROUGH;
+ case TAB:
+ return VTERM_KEY_TAB;
+ case Ctrl_M:
+ return VTERM_KEY_ENTER;
+ case ESC:
+ return VTERM_KEY_ESCAPE;
+
+ case K_S_UP:
+ FALLTHROUGH;
+ case K_UP:
+ return VTERM_KEY_UP;
+ case K_S_DOWN:
+ FALLTHROUGH;
+ case K_DOWN:
+ return VTERM_KEY_DOWN;
+ case K_S_LEFT:
+ FALLTHROUGH;
+ case K_C_LEFT:
+ FALLTHROUGH;
+ case K_LEFT:
+ return VTERM_KEY_LEFT;
+ case K_S_RIGHT:
+ FALLTHROUGH;
+ case K_C_RIGHT:
+ FALLTHROUGH;
+ case K_RIGHT:
+ return VTERM_KEY_RIGHT;
+
+ case K_INS:
+ return VTERM_KEY_INS;
+ case K_DEL:
+ return VTERM_KEY_DEL;
+ case K_HOME:
+ return VTERM_KEY_HOME;
+ case K_END:
+ return VTERM_KEY_END;
+ case K_PAGEUP:
+ return VTERM_KEY_PAGEUP;
+ case K_PAGEDOWN:
+ return VTERM_KEY_PAGEDOWN;
+
+ case K_K0:
+ FALLTHROUGH;
+ case K_KINS:
+ return VTERM_KEY_KP_0;
+ case K_K1:
+ FALLTHROUGH;
+ case K_KEND:
+ return VTERM_KEY_KP_1;
+ case K_K2:
+ FALLTHROUGH;
+ case K_KDOWN:
+ return VTERM_KEY_KP_2;
+ case K_K3:
+ FALLTHROUGH;
+ case K_KPAGEDOWN:
+ return VTERM_KEY_KP_3;
+ case K_K4:
+ FALLTHROUGH;
+ case K_KLEFT:
+ return VTERM_KEY_KP_4;
+ case K_K5:
+ FALLTHROUGH;
+ case K_KORIGIN:
+ return VTERM_KEY_KP_5;
+ case K_K6:
+ FALLTHROUGH;
+ case K_KRIGHT:
+ return VTERM_KEY_KP_6;
+ case K_K7:
+ FALLTHROUGH;
+ case K_KHOME:
+ return VTERM_KEY_KP_7;
+ case K_K8:
+ FALLTHROUGH;
+ case K_KUP:
+ return VTERM_KEY_KP_8;
+ case K_K9:
+ FALLTHROUGH;
+ case K_KPAGEUP:
+ return VTERM_KEY_KP_9;
+ case K_KDEL:
+ FALLTHROUGH;
+ case K_KPOINT:
+ return VTERM_KEY_KP_PERIOD;
+ case K_KENTER:
+ return VTERM_KEY_KP_ENTER;
+ case K_KPLUS:
+ return VTERM_KEY_KP_PLUS;
+ case K_KMINUS:
+ return VTERM_KEY_KP_MINUS;
+ case K_KMULTIPLY:
+ return VTERM_KEY_KP_MULT;
+ case K_KDIVIDE:
+ return VTERM_KEY_KP_DIVIDE;
+
+ case K_S_F1:
+ FALLTHROUGH;
+ case K_F1:
+ return VTERM_KEY_FUNCTION(1);
+ case K_S_F2:
+ FALLTHROUGH;
+ case K_F2:
+ return VTERM_KEY_FUNCTION(2);
+ case K_S_F3:
+ FALLTHROUGH;
+ case K_F3:
+ return VTERM_KEY_FUNCTION(3);
+ case K_S_F4:
+ FALLTHROUGH;
+ case K_F4:
+ return VTERM_KEY_FUNCTION(4);
+ case K_S_F5:
+ FALLTHROUGH;
+ case K_F5:
+ return VTERM_KEY_FUNCTION(5);
+ case K_S_F6:
+ FALLTHROUGH;
+ case K_F6:
+ return VTERM_KEY_FUNCTION(6);
+ case K_S_F7:
+ FALLTHROUGH;
+ case K_F7:
+ return VTERM_KEY_FUNCTION(7);
+ case K_S_F8:
+ FALLTHROUGH;
+ case K_F8:
+ return VTERM_KEY_FUNCTION(8);
+ case K_S_F9:
+ FALLTHROUGH;
+ case K_F9:
+ return VTERM_KEY_FUNCTION(9);
+ case K_S_F10:
+ FALLTHROUGH;
+ case K_F10:
+ return VTERM_KEY_FUNCTION(10);
+ case K_S_F11:
+ FALLTHROUGH;
+ case K_F11:
+ return VTERM_KEY_FUNCTION(11);
+ case K_S_F12:
+ FALLTHROUGH;
+ case K_F12:
+ return VTERM_KEY_FUNCTION(12);
+
+ case K_F13:
+ return VTERM_KEY_FUNCTION(13);
+ case K_F14:
+ return VTERM_KEY_FUNCTION(14);
+ case K_F15:
+ return VTERM_KEY_FUNCTION(15);
+ case K_F16:
+ return VTERM_KEY_FUNCTION(16);
+ case K_F17:
+ return VTERM_KEY_FUNCTION(17);
+ case K_F18:
+ return VTERM_KEY_FUNCTION(18);
+ case K_F19:
+ return VTERM_KEY_FUNCTION(19);
+ case K_F20:
+ return VTERM_KEY_FUNCTION(20);
+ case K_F21:
+ return VTERM_KEY_FUNCTION(21);
+ case K_F22:
+ return VTERM_KEY_FUNCTION(22);
+ case K_F23:
+ return VTERM_KEY_FUNCTION(23);
+ case K_F24:
+ return VTERM_KEY_FUNCTION(24);
+ case K_F25:
+ return VTERM_KEY_FUNCTION(25);
+ case K_F26:
+ return VTERM_KEY_FUNCTION(26);
+ case K_F27:
+ return VTERM_KEY_FUNCTION(27);
+ case K_F28:
+ return VTERM_KEY_FUNCTION(28);
+ case K_F29:
+ return VTERM_KEY_FUNCTION(29);
+ case K_F30:
+ return VTERM_KEY_FUNCTION(30);
+ case K_F31:
+ return VTERM_KEY_FUNCTION(31);
+ case K_F32:
+ return VTERM_KEY_FUNCTION(32);
+ case K_F33:
+ return VTERM_KEY_FUNCTION(33);
+ case K_F34:
+ return VTERM_KEY_FUNCTION(34);
+ case K_F35:
+ return VTERM_KEY_FUNCTION(35);
+ case K_F36:
+ return VTERM_KEY_FUNCTION(36);
+ case K_F37:
+ return VTERM_KEY_FUNCTION(37);
+
+ default:
+ return VTERM_KEY_NONE;
}
}
-static void mouse_action(Terminal *term, int button, int row, int col,
- bool drag, VTermModifier mod)
+static void mouse_action(Terminal *term, int button, int row, int col, bool drag, VTermModifier mod)
{
if (term->pressed_button && (term->pressed_button != button || !drag)) {
// release the previous button
@@ -1100,22 +1216,32 @@ static bool send_mouse_event(Terminal *term, int c)
bool drag = false;
switch (c) {
- case K_LEFTDRAG: drag = true; FALLTHROUGH;
- case K_LEFTMOUSE: button = 1; break;
- case K_MOUSEMOVE: drag = true; button = 0; break;
- case K_MIDDLEDRAG: drag = true; FALLTHROUGH;
- case K_MIDDLEMOUSE: button = 2; break;
- case K_RIGHTDRAG: drag = true; FALLTHROUGH;
- case K_RIGHTMOUSE: button = 3; break;
- case K_MOUSEDOWN: button = 4; break;
- case K_MOUSEUP: button = 5; break;
- default: return false;
+ case K_LEFTDRAG:
+ drag = true; FALLTHROUGH;
+ case K_LEFTMOUSE:
+ button = 1; break;
+ case K_MOUSEMOVE:
+ drag = true; button = 0; break;
+ case K_MIDDLEDRAG:
+ drag = true; FALLTHROUGH;
+ case K_MIDDLEMOUSE:
+ button = 2; break;
+ case K_RIGHTDRAG:
+ drag = true; FALLTHROUGH;
+ case K_RIGHTMOUSE:
+ button = 3; break;
+ case K_MOUSEDOWN:
+ button = 4; break;
+ case K_MOUSEUP:
+ button = 5; break;
+ default:
+ return false;
}
mouse_action(term, button, row, col - offset, drag, 0);
size_t len = vterm_output_read(term->vt, term->textbuf,
sizeof(term->textbuf));
- terminal_send(term, term->textbuf, (size_t)len);
+ terminal_send(term, term->textbuf, len);
return false;
}
@@ -1162,7 +1288,7 @@ static void fetch_row(Terminal *term, int row, int end_col)
if (cell.chars[0]) {
for (int i = 0; cell.chars[i]; i++) {
cell_len += utf_char2bytes((int)cell.chars[i],
- (uint8_t *)ptr + cell_len);
+ (uint8_t *)ptr + cell_len);
}
} else {
*ptr = ' ';
@@ -1181,8 +1307,7 @@ static void fetch_row(Terminal *term, int row, int end_col)
term->textbuf[line_len] = 0;
}
-static bool fetch_cell(Terminal *term, int row, int col,
- VTermScreenCell *cell)
+static bool fetch_cell(Terminal *term, int row, int col, VTermScreenCell *cell)
{
if (row < 0) {
ScrollbackLine *sbrow = term->sb_buffer[-row - 1];
@@ -1197,8 +1322,8 @@ static bool fetch_cell(Terminal *term, int row, int col,
return false;
}
} else {
- vterm_screen_get_cell(term->vts, (VTermPos){.row = row, .col = col},
- cell);
+ vterm_screen_get_cell(term->vts, (VTermPos){ .row = row, .col = col },
+ cell);
}
return true;
}
diff --git a/src/nvim/terminal.h b/src/nvim/terminal.h
index f2b0e232c3..001adbadc3 100644
--- a/src/nvim/terminal.h
+++ b/src/nvim/terminal.h
@@ -1,8 +1,8 @@
#ifndef NVIM_TERMINAL_H
#define NVIM_TERMINAL_H
-#include <stddef.h>
#include <stdbool.h>
+#include <stddef.h>
#include <stdint.h>
typedef struct terminal Terminal;
diff --git a/src/nvim/testdir/samples/memfile_test.c b/src/nvim/testdir/samples/memfile_test.c
index 7023064637..73f67fb250 100644
--- a/src/nvim/testdir/samples/memfile_test.c
+++ b/src/nvim/testdir/samples/memfile_test.c
@@ -1,6 +1,8 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+// uncrustify:off
+
/* vi:set ts=8 sts=4 sw=4 noet:
*
* VIM - Vi IMproved by Bram Moolenaar
diff --git a/src/nvim/testdir/test_arglist.vim b/src/nvim/testdir/test_arglist.vim
index 01d8f32893..8fd60d6a5a 100644
--- a/src/nvim/testdir/test_arglist.vim
+++ b/src/nvim/testdir/test_arglist.vim
@@ -88,7 +88,7 @@ func Test_argadd_empty_curbuf()
argadd Xargadd
call assert_equal(curbuf, bufnr('%'))
call assert_equal('', bufname('%'))
- call assert_equal(1, line('$'))
+ call assert_equal(1, '$'->line())
rew
call assert_notequal(curbuf, '%'->bufnr())
call assert_equal('Xargadd', '%'->bufname())
diff --git a/src/nvim/testdir/test_autochdir.vim b/src/nvim/testdir/test_autochdir.vim
index d071f4b325..0b76828dd7 100644
--- a/src/nvim/testdir/test_autochdir.vim
+++ b/src/nvim/testdir/test_autochdir.vim
@@ -8,13 +8,21 @@ func Test_set_filename()
let cwd = getcwd()
call test_autochdir()
set acd
+
+ let s:li = []
+ autocmd DirChanged auto call add(s:li, "autocd")
+ autocmd DirChanged auto call add(s:li, expand("<afile>"))
+
new
w samples/Xtest
call assert_equal("Xtest", expand('%'))
call assert_equal("samples", substitute(getcwd(), '.*/\(\k*\)', '\1', ''))
+ call assert_equal(["autocd", getcwd()], s:li)
+
bwipe!
+ au! DirChanged
set noacd
- exe 'cd ' . cwd
+ call chdir(cwd)
call delete('samples/Xtest')
endfunc
diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim
index 015979e1be..c350a17236 100644
--- a/src/nvim/testdir/test_autocmd.vim
+++ b/src/nvim/testdir/test_autocmd.vim
@@ -42,9 +42,7 @@ if has('timers')
endfunc
func Test_cursorhold_insert_with_timer_interrupt()
- if !has('job')
- return
- endif
+ CheckFeature job
" Need to move the cursor.
call feedkeys("ggG", "xt")
@@ -551,9 +549,7 @@ endfunc
func Test_OptionSet()
CheckFunction test_override
- if !has("eval") || !exists("+autochdir")
- return
- endif
+ CheckOption autochdir
call test_override('starting', 1)
set nocp
@@ -1328,6 +1324,71 @@ func Test_autocommand_all_events()
call assert_fails('au * x bwipe', 'E1155:')
endfunc
+function s:Before_test_dirchanged()
+ augroup test_dirchanged
+ autocmd!
+ augroup END
+ let s:li = []
+ let s:dir_this = getcwd()
+ let s:dir_foo = s:dir_this . '/Xfoo'
+ call mkdir(s:dir_foo)
+ let s:dir_bar = s:dir_this . '/Xbar'
+ call mkdir(s:dir_bar)
+endfunc
+
+function s:After_test_dirchanged()
+ call chdir(s:dir_this)
+ call delete(s:dir_foo, 'd')
+ call delete(s:dir_bar, 'd')
+ augroup test_dirchanged
+ autocmd!
+ augroup END
+endfunc
+
+function Test_dirchanged_global()
+ call s:Before_test_dirchanged()
+ autocmd test_dirchanged DirChanged global call add(s:li, "cd:")
+ autocmd test_dirchanged DirChanged global call add(s:li, expand("<afile>"))
+ call chdir(s:dir_foo)
+ call assert_equal(["cd:", s:dir_foo], s:li)
+ call chdir(s:dir_foo)
+ call assert_equal(["cd:", s:dir_foo], s:li)
+ exe 'lcd ' .. fnameescape(s:dir_bar)
+ call assert_equal(["cd:", s:dir_foo], s:li)
+ call s:After_test_dirchanged()
+endfunc
+
+function Test_dirchanged_local()
+ call s:Before_test_dirchanged()
+ autocmd test_dirchanged DirChanged window call add(s:li, "lcd:")
+ autocmd test_dirchanged DirChanged window call add(s:li, expand("<afile>"))
+ call chdir(s:dir_foo)
+ call assert_equal([], s:li)
+ exe 'lcd ' .. fnameescape(s:dir_bar)
+ call assert_equal(["lcd:", s:dir_bar], s:li)
+ exe 'lcd ' .. fnameescape(s:dir_bar)
+ call assert_equal(["lcd:", s:dir_bar], s:li)
+ call s:After_test_dirchanged()
+endfunc
+
+function Test_dirchanged_auto()
+ CheckFunction test_autochdir
+ CheckOption autochdir
+ call s:Before_test_dirchanged()
+ call test_autochdir()
+ autocmd test_dirchanged DirChanged auto call add(s:li, "auto:")
+ autocmd test_dirchanged DirChanged auto call add(s:li, expand("<afile>"))
+ set acd
+ cd ..
+ call assert_equal([], s:li)
+ exe 'edit ' . s:dir_foo . '/Xfile'
+ call assert_equal(s:dir_foo, getcwd())
+ call assert_equal(["auto:", s:dir_foo], s:li)
+ set noacd
+ bwipe!
+ call s:After_test_dirchanged()
+endfunc
+
" Test TextChangedI and TextChangedP
" See test/functional/viml/completion_spec.lua'
func Test_ChangedP()
diff --git a/src/nvim/testdir/test_breakindent.vim b/src/nvim/testdir/test_breakindent.vim
index 97b570e64f..277050876e 100644
--- a/src/nvim/testdir/test_breakindent.vim
+++ b/src/nvim/testdir/test_breakindent.vim
@@ -418,8 +418,8 @@ endfunc
func Test_breakindent11()
" test strdisplaywidth()
call s:test_windows('setl cpo-=n sbr=>> nu nuw=4 nolist briopt= ts=4')
- let text=getline(2)
- let width = strlen(text[1:])+indent(2)+strlen(&sbr)*3 " text wraps 3 times
+ let text = getline(2)
+ let width = strlen(text[1:]) + indent(2) + strlen(&sbr) * 3 " text wraps 3 times
call assert_equal(width, strdisplaywidth(text))
call s:close_windows('set sbr=')
endfunc
@@ -431,7 +431,7 @@ func Test_breakindent11_vartabs()
" test strdisplaywidth()
call s:test_windows('setl cpo-=n sbr=>> nu nuw=4 nolist briopt= ts=4 vts=4')
let text = getline(2)
- let width = strlen(text[1:])+indent(2)+strlen(&sbr)*3 " text wraps 3 times
+ let width = strlen(text[1:]) + 2->indent() + strlen(&sbr) * 3 " text wraps 3 times
call assert_equal(width, strdisplaywidth(text))
call s:close_windows('set sbr= vts&')
endfunc
diff --git a/src/nvim/testdir/test_bufline.vim b/src/nvim/testdir/test_bufline.vim
index b4e8a0bc71..765ae17736 100644
--- a/src/nvim/testdir/test_bufline.vim
+++ b/src/nvim/testdir/test_bufline.vim
@@ -9,7 +9,7 @@ func Test_setbufline_getbufline()
hide
call assert_equal(0, setbufline(b, 1, ['foo', 'bar']))
call assert_equal(['foo'], getbufline(b, 1))
- call assert_equal(['bar'], getbufline(b, 2))
+ call assert_equal(['bar'], getbufline(b, '$'))
call assert_equal(['foo', 'bar'], getbufline(b, 1, 2))
exe "bd!" b
call assert_equal([], getbufline(b, 1, 2))
@@ -21,7 +21,7 @@ func Test_setbufline_getbufline()
call assert_equal(1, setbufline(b, 5, ['x']))
call assert_equal(1, setbufline(1234, 1, ['x']))
call assert_equal(0, setbufline(b, 4, ['d', 'e']))
- call assert_equal(['c'], getbufline(b, 3))
+ call assert_equal(['c'], b->getbufline(3))
call assert_equal(['d'], getbufline(b, 4))
call assert_equal(['e'], getbufline(b, 5))
call assert_equal([], getbufline(b, 6))
@@ -82,6 +82,7 @@ func Test_appendbufline()
call setline(1, ['a', 'b', 'c'])
let b = bufnr('%')
wincmd w
+ call assert_equal(1, appendbufline(b, -1, ['x']))
call assert_equal(1, appendbufline(b, 4, ['x']))
call assert_equal(1, appendbufline(1234, 1, ['x']))
call assert_equal(0, appendbufline(b, 3, ['d', 'e']))
@@ -104,8 +105,11 @@ func Test_deletebufline()
exe "bd!" b
call assert_equal(1, b->deletebufline(1))
+ call assert_equal(1, deletebufline(-1, 1))
+
split Xtest
call setline(1, ['a', 'b', 'c'])
+ call cursor(line('$'), 1)
let b = bufnr('%')
wincmd w
call assert_equal(1, deletebufline(b, 4))
diff --git a/src/nvim/testdir/test_bufwintabinfo.vim b/src/nvim/testdir/test_bufwintabinfo.vim
index 4b5b55e6bf..bb672cf0ec 100644
--- a/src/nvim/testdir/test_bufwintabinfo.vim
+++ b/src/nvim/testdir/test_bufwintabinfo.vim
@@ -77,7 +77,7 @@ function Test_getbufwintabinfo()
call assert_equal('green', winlist[2].variables.signal)
call assert_equal(w4_id, winlist[3].winid)
- let winfo = getwininfo(w5_id)[0]
+ let winfo = w5_id->getwininfo()[0]
call assert_equal(2, winfo.tabnr)
call assert_equal([], getwininfo(3))
@@ -88,7 +88,7 @@ function Test_getbufwintabinfo()
call assert_equal(2, tablist[1].tabnr)
call assert_equal('build', tablist[0].variables.space)
call assert_equal(w2_id, tablist[0].windows[0])
- call assert_equal([], gettabinfo(3))
+ call assert_equal([], 3->gettabinfo())
tabonly | only
@@ -106,7 +106,7 @@ function Test_getbufwintabinfo()
endfunction
function Test_get_buf_options()
- let opts = getbufvar(bufnr('%'), '&')
+ let opts = bufnr()->getbufvar('&')
call assert_equal(v:t_dict, type(opts))
call assert_equal(8, opts.tabstop)
endfunc
diff --git a/src/nvim/testdir/test_cd.vim b/src/nvim/testdir/test_cd.vim
index 02a23bf82f..0bba321ee2 100644
--- a/src/nvim/testdir/test_cd.vim
+++ b/src/nvim/testdir/test_cd.vim
@@ -12,7 +12,7 @@ func Test_cd_up_and_down()
let path = getcwd()
cd ..
call assert_notequal(path, getcwd())
- exe 'cd ' . path
+ exe 'cd ' .. fnameescape(path)
call assert_equal(path, getcwd())
endfunc
@@ -23,7 +23,7 @@ func Test_cd_no_arg()
cd
call assert_equal($HOME, getcwd())
call assert_notequal(path, getcwd())
- exe 'cd ' . path
+ exe 'cd ' .. fnameescape(path)
call assert_equal(path, getcwd())
else
" Test that cd without argument echoes cwd on non-Unix systems.
@@ -43,6 +43,20 @@ func Test_cd_minus()
call assert_equal(path_dotdot, getcwd())
cd -
call assert_equal(path, getcwd())
+
+ " Test for :cd - without a previous directory
+ let lines =<< trim [SCRIPT]
+ call assert_fails('cd -', 'E186:')
+ call assert_fails('call chdir("-")', 'E186:')
+ call writefile(v:errors, 'Xresult')
+ qall!
+ [SCRIPT]
+ call writefile(lines, 'Xscript')
+ if RunVim([], [], '--clean -S Xscript')
+ call assert_equal([], readfile('Xresult'))
+ endif
+ call delete('Xscript')
+ call delete('Xresult')
endfunc
func Test_cd_with_cpo_chdir()
@@ -61,7 +75,7 @@ func Test_cd_with_cpo_chdir()
" :cd should succeed when buffer has been written.
w!
- exe 'cd ' . path
+ exe 'cd ' .. fnameescape(path)
call assert_equal(path, getcwd())
call delete('Xfoo')
@@ -69,6 +83,124 @@ func Test_cd_with_cpo_chdir()
bw!
endfunc
+" Test for chdir()
+func Test_chdir_func()
+ let topdir = getcwd()
+ call mkdir('Xdir/y/z', 'p')
+
+ " Create a few tabpages and windows with different directories
+ new
+ cd Xdir
+ tabnew
+ tcd y
+ below new
+ below new
+ lcd z
+
+ tabfirst
+ call assert_match('^\[global\] .*/Xdir$', trim(execute('verbose pwd')))
+ call chdir('..')
+ call assert_equal('y', fnamemodify(getcwd(1, 2), ':t'))
+ call assert_equal('z', fnamemodify(getcwd(3, 2), ':t'))
+ tabnext | wincmd t
+ call assert_match('^\[tabpage\] .*/y$', trim(execute('verbose pwd')))
+ call chdir('..')
+ call assert_equal('Xdir', fnamemodify(getcwd(1, 2), ':t'))
+ call assert_equal('Xdir', fnamemodify(getcwd(2, 2), ':t'))
+ call assert_equal('z', fnamemodify(getcwd(3, 2), ':t'))
+ call assert_equal('testdir', fnamemodify(getcwd(1, 1), ':t'))
+ 3wincmd w
+ call assert_match('^\[window\] .*/z$', trim(execute('verbose pwd')))
+ call chdir('..')
+ call assert_equal('Xdir', fnamemodify(getcwd(1, 2), ':t'))
+ call assert_equal('Xdir', fnamemodify(getcwd(2, 2), ':t'))
+ call assert_equal('y', fnamemodify(getcwd(3, 2), ':t'))
+ call assert_equal('testdir', fnamemodify(getcwd(1, 1), ':t'))
+
+ " Error case
+ call assert_fails("call chdir('dir-abcd')", 'E472:')
+ silent! let d = chdir("dir_abcd")
+ call assert_equal("", d)
+ " Should not crash
+ call chdir(d)
+
+ only | tabonly
+ call chdir(topdir)
+ call delete('Xdir', 'rf')
+endfunc
+
+" Test for changing to the previous directory '-'
+func Test_prev_dir()
+ let topdir = getcwd()
+ call mkdir('Xdir/a/b/c', 'p')
+
+ " Create a few tabpages and windows with different directories
+ new | only
+ tabnew | new
+ tabnew
+ tabfirst
+ cd Xdir
+ tabnext | wincmd t
+ tcd a
+ wincmd w
+ lcd b
+ tabnext
+ tcd a/b/c
+
+ " Change to the previous directory twice in all the windows.
+ tabfirst
+ cd - | cd -
+ tabnext | wincmd t
+ tcd - | tcd -
+ wincmd w
+ lcd - | lcd -
+ tabnext
+ tcd - | tcd -
+
+ " Check the directory of all the windows
+ tabfirst
+ call assert_equal('Xdir', fnamemodify(getcwd(), ':t'))
+ tabnext | wincmd t
+ call assert_equal('a', fnamemodify(getcwd(), ':t'))
+ wincmd w
+ call assert_equal('b', fnamemodify(getcwd(), ':t'))
+ tabnext
+ call assert_equal('c', fnamemodify(getcwd(), ':t'))
+
+ " Change to the previous directory using chdir()
+ tabfirst
+ call chdir("-") | call chdir("-")
+ tabnext | wincmd t
+ call chdir("-") | call chdir("-")
+ wincmd w
+ call chdir("-") | call chdir("-")
+ tabnext
+ call chdir("-") | call chdir("-")
+
+ " Check the directory of all the windows
+ tabfirst
+ call assert_equal('Xdir', fnamemodify(getcwd(), ':t'))
+ tabnext | wincmd t
+ call assert_equal('a', fnamemodify(getcwd(), ':t'))
+ wincmd w
+ call assert_equal('b', fnamemodify(getcwd(), ':t'))
+ tabnext
+ call assert_equal('c', fnamemodify(getcwd(), ':t'))
+
+ only | tabonly
+ call chdir(topdir)
+ call delete('Xdir', 'rf')
+endfunc
+
+func Test_lcd_split()
+ let curdir = getcwd()
+ lcd ..
+ split
+ lcd -
+ call assert_equal(curdir, getcwd())
+ quit!
+endfunc
+
func Test_cd_from_non_existing_dir()
CheckNotMSWindows
diff --git a/src/nvim/testdir/test_changelist.vim b/src/nvim/testdir/test_changelist.vim
index dd6ea9600c..ce77c1f3c7 100644
--- a/src/nvim/testdir/test_changelist.vim
+++ b/src/nvim/testdir/test_changelist.vim
@@ -8,8 +8,8 @@ func Test_getchangelist()
bwipe!
enew
- call assert_equal([], getchangelist(10))
- call assert_equal([[], 0], getchangelist('%'))
+ call assert_equal([], 10->getchangelist())
+ call assert_equal([[], 0], getchangelist())
call writefile(['line1', 'line2', 'line3'], 'Xfile1.txt')
call writefile(['line1', 'line2', 'line3'], 'Xfile2.txt')
diff --git a/src/nvim/testdir/test_clientserver.vim b/src/nvim/testdir/test_clientserver.vim
index 53704bd094..f3db472b03 100644
--- a/src/nvim/testdir/test_clientserver.vim
+++ b/src/nvim/testdir/test_clientserver.vim
@@ -34,7 +34,7 @@ func Test_client_server()
" When using valgrind it takes much longer.
call WaitForAssert({-> assert_match(name, serverlist())})
- call remote_foreground(name)
+ eval name->remote_foreground()
call remote_send(name, ":let testvar = 'yes'\<CR>")
call WaitFor('remote_expr("' . name . '", "exists(\"testvar\") ? testvar : \"\"", "", 1) == "yes"')
@@ -53,7 +53,7 @@ func Test_client_server()
endif
" Wait for the server to be up and answering requests.
sleep 100m
- call WaitForAssert({-> assert_true(remote_expr(name, "v:version", "", 1) != "")})
+ call WaitForAssert({-> assert_true(name->remote_expr("v:version", "", 1) != "")})
call remote_send(name, ":let testvar = 'maybe'\<CR>")
call WaitForAssert({-> assert_equal('maybe', remote_expr(name, "testvar", "", 2))})
@@ -72,7 +72,7 @@ func Test_client_server()
" Expression evaluated locally.
if v:servername == ''
- call remote_startserver('MYSELF')
+ eval 'MYSELF'->remote_startserver()
" May get MYSELF1 when running the test again.
call assert_match('MYSELF', v:servername)
endif
@@ -80,11 +80,11 @@ func Test_client_server()
call assert_equal('myself', remote_expr(v:servername, 'testvar'))
call remote_send(name, ":call server2client(expand('<client>'), 'got it')\<CR>", 'g:myserverid')
- call assert_equal('got it', remote_read(g:myserverid, 2))
+ call assert_equal('got it', g:myserverid->remote_read(2))
call remote_send(name, ":call server2client(expand('<client>'), 'another')\<CR>", 'g:myserverid')
let peek_result = 'nothing'
- let r = remote_peek(g:myserverid, 'peek_result')
+ let r = g:myserverid->remote_peek('peek_result')
" unpredictable whether the result is already available.
if r > 0
call assert_equal('another', peek_result)
@@ -98,7 +98,7 @@ func Test_client_server()
call assert_equal('another', g:peek_result)
call assert_equal('another', remote_read(g:myserverid, 2))
- call remote_send(name, ":qa!\<CR>")
+ eval name->remote_send(":qa!\<CR>")
try
call WaitForAssert({-> assert_equal("dead", job_status(job))})
finally
diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim
index 5a6824b5c1..ffca415282 100644
--- a/src/nvim/testdir/test_cmdline.vim
+++ b/src/nvim/testdir/test_cmdline.vim
@@ -260,7 +260,7 @@ func Test_getcompletion()
endif
let groupcount = len(getcompletion('', 'event'))
call assert_true(groupcount > 0)
- let matchcount = len(getcompletion('File', 'event'))
+ let matchcount = len('File'->getcompletion('event'))
call assert_true(matchcount > 0)
call assert_true(groupcount > matchcount)
diff --git a/src/nvim/testdir/test_cursor_func.vim b/src/nvim/testdir/test_cursor_func.vim
index 53b7da517e..46847e0663 100644
--- a/src/nvim/testdir/test_cursor_func.vim
+++ b/src/nvim/testdir/test_cursor_func.vim
@@ -25,6 +25,12 @@ func Test_move_cursor()
call cursor(9, 1)
call assert_equal([4, 1, 0, 1], getcurpos()[1:])
+ call setline(1, ["\<TAB>"])
+ call cursor(1, 1, 1)
+ call assert_equal([1, 1, 1], getcurpos()[1:3])
+
+ call assert_equal(-1, cursor(-1, -1))
+
quit!
endfunc
diff --git a/src/nvim/testdir/test_edit.vim b/src/nvim/testdir/test_edit.vim
index e1393e875b..2b389c015f 100644
--- a/src/nvim/testdir/test_edit.vim
+++ b/src/nvim/testdir/test_edit.vim
@@ -201,11 +201,11 @@ func Test_edit_07()
endfu
au InsertCharPre <buffer> :call DoIt()
call feedkeys("A\<f5>\<c-p>u\<cr>\<c-l>\<cr>", 'tx')
- call assert_equal(["Jan\<c-l>",''], getline(1,'$'))
+ call assert_equal(["Jan\<c-l>",''], 1->getline('$'))
%d
call setline(1, 'J')
call feedkeys("A\<f5>\<c-p>u\<down>\<c-l>\<cr>", 'tx')
- call assert_equal(["January"], getline(1,'$'))
+ call assert_equal(["January"], 1->getline('$'))
delfu ListMonths
delfu DoIt
@@ -348,7 +348,7 @@ func Test_edit_12()
call cursor(2, 4)
call feedkeys("R^\<c-d>", 'tnix')
call assert_equal(["\tabc", "def"], getline(1, '$'))
- call assert_equal([0, 2, 2, 0], getpos('.'))
+ call assert_equal([0, 2, 2, 0], '.'->getpos())
%d
call setline(1, ["\tabc", "\t\tdef"])
call cursor(2, 2)
diff --git a/src/nvim/testdir/test_environ.vim b/src/nvim/testdir/test_environ.vim
index a25d83753c..cc15b63824 100644
--- a/src/nvim/testdir/test_environ.vim
+++ b/src/nvim/testdir/test_environ.vim
@@ -15,7 +15,7 @@ endfunc
func Test_getenv()
unlet! $TESTENV
- call assert_equal(v:null, getenv('TESTENV'))
+ call assert_equal(v:null, 'TESTENV'->getenv())
let $TESTENV = 'foo'
call assert_equal('foo', getenv('TESTENV'))
endfunc
diff --git a/src/nvim/testdir/test_escaped_glob.vim b/src/nvim/testdir/test_escaped_glob.vim
index 2bfd82c296..1a4fd8bdab 100644
--- a/src/nvim/testdir/test_escaped_glob.vim
+++ b/src/nvim/testdir/test_escaped_glob.vim
@@ -16,7 +16,7 @@ function Test_glob()
" Execute these commands in the sandbox, so that using the shell fails.
" Setting 'shell' to an invalid name causes a memory leak.
sandbox call assert_equal("", glob('Xxx\{'))
- sandbox call assert_equal("", glob('Xxx\$'))
+ sandbox call assert_equal("", 'Xxx\$'->glob())
w! Xxx\{
" } to fix highlighting
w! Xxx\$
@@ -28,7 +28,7 @@ endfunction
function Test_globpath()
sandbox call assert_equal(expand("sautest/autoload/globone.vim\nsautest/autoload/globtwo.vim"),
- \ globpath('sautest/autoload', 'glob*.vim'))
+ \ globpath('sautest/autoload', 'glob*.vim'))
sandbox call assert_equal([expand('sautest/autoload/globone.vim'), expand('sautest/autoload/globtwo.vim')],
- \ globpath('sautest/autoload', 'glob*.vim', 0, 1))
+ \ 'glob*.vim'->globpath('sautest/autoload', 0, 1))
endfunction
diff --git a/src/nvim/testdir/test_eval_stuff.vim b/src/nvim/testdir/test_eval_stuff.vim
index f7b6704610..883ba5de3d 100644
--- a/src/nvim/testdir/test_eval_stuff.vim
+++ b/src/nvim/testdir/test_eval_stuff.vim
@@ -174,6 +174,132 @@ func Test_number_max_min_size()
call assert_true(v:numbermax > 9999999)
endfunc
+func Assert_reg(name, type, value, valuestr, expr, exprstr)
+ call assert_equal(a:type, getregtype(a:name))
+ call assert_equal(a:value, getreg(a:name))
+ call assert_equal(a:valuestr, string(getreg(a:name, 0, 1)))
+ call assert_equal(a:expr, getreg(a:name, 1))
+ call assert_equal(a:exprstr, string(getreg(a:name, 1, 1)))
+endfunc
+
+func Test_let_register()
+ let @" = 'abc'
+ call Assert_reg('"', 'v', "abc", "['abc']", "abc", "['abc']")
+ let @" = "abc\n"
+ call Assert_reg('"', 'V', "abc\n", "['abc']", "abc\n", "['abc']")
+ let @" = "abc\<C-m>"
+ call Assert_reg('"', 'V', "abc\r\n", "['abc\r']", "abc\r\n", "['abc\r']")
+ let @= = '"abc"'
+ call Assert_reg('=', 'v', "abc", "['abc']", '"abc"', "['\"abc\"']")
+endfunc
+
+func Assert_regput(name, result)
+ new
+ execute "silent normal! o==\n==\e\"" . a:name . "P"
+ call assert_equal(a:result, getline(2, line('$')))
+ bwipe!
+endfunc
+
+func Test_setreg_basic()
+ call setreg('a', 'abcA', 'c')
+ call Assert_reg('a', 'v', "abcA", "['abcA']", "abcA", "['abcA']")
+ call Assert_regput('a', ['==', '=abcA='])
+
+ call setreg('A', 'abcAc', 'c')
+ call Assert_reg('A', 'v', "abcAabcAc", "['abcAabcAc']", "abcAabcAc", "['abcAabcAc']")
+ call Assert_regput('a', ['==', '=abcAabcAc='])
+
+ call setreg('A', 'abcAl', 'l')
+ call Assert_reg('A', 'V', "abcAabcAcabcAl\n", "['abcAabcAcabcAl']", "abcAabcAcabcAl\n", "['abcAabcAcabcAl']")
+ call Assert_regput('a', ['==', 'abcAabcAcabcAl', '=='])
+
+ call setreg('A', 'abcAc2','c')
+ call Assert_reg('A', 'v', "abcAabcAcabcAl\nabcAc2", "['abcAabcAcabcAl', 'abcAc2']", "abcAabcAcabcAl\nabcAc2", "['abcAabcAcabcAl', 'abcAc2']")
+ call Assert_regput('a', ['==', '=abcAabcAcabcAl', 'abcAc2='])
+
+ call setreg('b', 'abcB', 'v')
+ call Assert_reg('b', 'v', "abcB", "['abcB']", "abcB", "['abcB']")
+ call Assert_regput('b', ['==', '=abcB='])
+
+ call setreg('b', 'abcBc', 'ca')
+ call Assert_reg('b', 'v', "abcBabcBc", "['abcBabcBc']", "abcBabcBc", "['abcBabcBc']")
+ call Assert_regput('b', ['==', '=abcBabcBc='])
+
+ call setreg('b', 'abcBb', 'ba')
+ call Assert_reg('b', "\<C-V>5", "abcBabcBcabcBb", "['abcBabcBcabcBb']", "abcBabcBcabcBb", "['abcBabcBcabcBb']")
+ call Assert_regput('b', ['==', '=abcBabcBcabcBb='])
+
+ call setreg('b', 'abcBc2','ca')
+ call Assert_reg('b', "v", "abcBabcBcabcBb\nabcBc2", "['abcBabcBcabcBb', 'abcBc2']", "abcBabcBcabcBb\nabcBc2", "['abcBabcBcabcBb', 'abcBc2']")
+ call Assert_regput('b', ['==', '=abcBabcBcabcBb', 'abcBc2='])
+
+ call setreg('b', 'abcBb2','b50a')
+ call Assert_reg('b', "\<C-V>50", "abcBabcBcabcBb\nabcBc2abcBb2", "['abcBabcBcabcBb', 'abcBc2abcBb2']", "abcBabcBcabcBb\nabcBc2abcBb2", "['abcBabcBcabcBb', 'abcBc2abcBb2']")
+ call Assert_regput('b', ['==', '=abcBabcBcabcBb =', ' abcBc2abcBb2'])
+
+ call setreg('c', 'abcC', 'l')
+ call Assert_reg('c', 'V', "abcC\n", "['abcC']", "abcC\n", "['abcC']")
+ call Assert_regput('c', ['==', 'abcC', '=='])
+
+ call setreg('C', 'abcCl', 'l')
+ call Assert_reg('C', 'V', "abcC\nabcCl\n", "['abcC', 'abcCl']", "abcC\nabcCl\n", "['abcC', 'abcCl']")
+ call Assert_regput('c', ['==', 'abcC', 'abcCl', '=='])
+
+ call setreg('C', 'abcCc', 'c')
+ call Assert_reg('C', 'v', "abcC\nabcCl\nabcCc", "['abcC', 'abcCl', 'abcCc']", "abcC\nabcCl\nabcCc", "['abcC', 'abcCl', 'abcCc']")
+ call Assert_regput('c', ['==', '=abcC', 'abcCl', 'abcCc='])
+
+ call setreg('d', 'abcD', 'V')
+ call Assert_reg('d', 'V', "abcD\n", "['abcD']", "abcD\n", "['abcD']")
+ call Assert_regput('d', ['==', 'abcD', '=='])
+
+ call setreg('D', 'abcDb', 'b')
+ call Assert_reg('d', "\<C-V>5", "abcD\nabcDb", "['abcD', 'abcDb']", "abcD\nabcDb", "['abcD', 'abcDb']")
+ call Assert_regput('d', ['==', '=abcD =', ' abcDb'])
+
+ call setreg('e', 'abcE', 'b')
+ call Assert_reg('e', "\<C-V>4", "abcE", "['abcE']", "abcE", "['abcE']")
+ call Assert_regput('e', ['==', '=abcE='])
+
+ call setreg('E', 'abcEb', 'b')
+ call Assert_reg('E', "\<C-V>5", "abcE\nabcEb", "['abcE', 'abcEb']", "abcE\nabcEb", "['abcE', 'abcEb']")
+ call Assert_regput('e', ['==', '=abcE =', ' abcEb'])
+
+ call setreg('E', 'abcEl', 'l')
+ call Assert_reg('E', "V", "abcE\nabcEb\nabcEl\n", "['abcE', 'abcEb', 'abcEl']", "abcE\nabcEb\nabcEl\n", "['abcE', 'abcEb', 'abcEl']")
+ call Assert_regput('e', ['==', 'abcE', 'abcEb', 'abcEl', '=='])
+
+ call setreg('f', 'abcF', "\<C-v>")
+ call Assert_reg('f', "\<C-V>4", "abcF", "['abcF']", "abcF", "['abcF']")
+ call Assert_regput('f', ['==', '=abcF='])
+
+ call setreg('F', 'abcFc', 'c')
+ call Assert_reg('F', "v", "abcF\nabcFc", "['abcF', 'abcFc']", "abcF\nabcFc", "['abcF', 'abcFc']")
+ call Assert_regput('f', ['==', '=abcF', 'abcFc='])
+
+ call setreg('g', 'abcG', 'b10')
+ call Assert_reg('g', "\<C-V>10", "abcG", "['abcG']", "abcG", "['abcG']")
+ call Assert_regput('g', ['==', '=abcG ='])
+
+ call setreg('h', 'abcH', "\<C-v>10")
+ call Assert_reg('h', "\<C-V>10", "abcH", "['abcH']", "abcH", "['abcH']")
+ call Assert_regput('h', ['==', '=abcH ='])
+
+ call setreg('I', 'abcI')
+ call Assert_reg('I', "v", "abcI", "['abcI']", "abcI", "['abcI']")
+ call Assert_regput('I', ['==', '=abcI='])
+
+ " Error cases
+ call assert_fails('call setreg()', 'E119:')
+ call assert_fails('call setreg(1)', 'E119:')
+ call assert_fails('call setreg(1, 2, 3, 4)', 'E118:')
+ call assert_fails('call setreg([], 2)', 'E730:')
+ call assert_fails('call setreg(1, 2, [])', 'E730:')
+ call assert_fails('call setreg("/", ["1", "2"])', 'E883:')
+ call assert_fails('call setreg("=", ["1", "2"])', 'E883:')
+ call assert_fails('call setreg(1, ["", "", [], ""])', 'E730:')
+endfunc
+
func Test_curly_assignment()
let s:svar = 'svar'
let g:gvar = 'gvar'
diff --git a/src/nvim/testdir/test_expand_func.vim b/src/nvim/testdir/test_expand_func.vim
index 9588d3b89d..44d2c156d5 100644
--- a/src/nvim/testdir/test_expand_func.vim
+++ b/src/nvim/testdir/test_expand_func.vim
@@ -37,6 +37,15 @@ func Test_expand_sflnum()
delcommand Flnum
endfunc
+func Test_expand()
+ new
+ call assert_equal("", expand('%:S'))
+ call assert_equal('3', '<slnum>'->expand())
+ call assert_equal(['4'], expand('<slnum>', v:false, v:true))
+ " Don't add any line above this, otherwise <slnum> will change.
+ quit
+endfunc
+
func Test_expand_sfile()
call assert_match('test_expand_func\.vim$', s:sfile)
call assert_match('^function .*\.\.Test_expand_sfile$', expand('<sfile>'))
diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim
index c49285621a..6343c47fde 100644
--- a/src/nvim/testdir/test_expr.vim
+++ b/src/nvim/testdir/test_expr.vim
@@ -147,7 +147,7 @@ function Test_printf_spec_s()
call assert_equal(string(value), printf('%s', value))
" funcref
- call assert_equal('printf', printf('%s', function('printf')))
+ call assert_equal('printf', printf('%s', 'printf'->function()))
" partial
call assert_equal(string(function('printf', ['%s'])), printf('%s', function('printf', ['%s'])))
@@ -477,7 +477,7 @@ func Test_funcref()
endfunc
call assert_equal(2, OneByName())
call assert_equal(1, OneByRef())
- let OneByRef = funcref('One')
+ let OneByRef = 'One'->funcref()
call assert_equal(2, OneByRef())
call assert_fails('echo funcref("{")', 'E475:')
let OneByRef = funcref("One", repeat(["foo"], 20))
diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim
index cc789cb6bd..18e59bb6b7 100644
--- a/src/nvim/testdir/test_filetype.vim
+++ b/src/nvim/testdir/test_filetype.vim
@@ -112,7 +112,7 @@ let s:filename_checks = {
\ 'coco': ['file.atg'],
\ 'conaryrecipe': ['file.recipe'],
\ 'conf': ['auto.master'],
- \ 'config': ['configure.in', 'configure.ac', 'Pipfile', '/etc/hostname.file'],
+ \ 'config': ['configure.in', 'configure.ac', '/etc/hostname.file'],
\ 'context': ['tex/context/any/file.tex', 'file.mkii', 'file.mkiv', 'file.mkvi', 'file.mkxl', 'file.mklx'],
\ 'cpp': ['file.cxx', 'file.c++', 'file.hh', 'file.hxx', 'file.hpp', 'file.ipp', 'file.moc', 'file.tcc', 'file.inl', 'file.tlh'],
\ 'crm': ['file.crm'],
@@ -259,7 +259,7 @@ let s:filename_checks = {
\ 'jgraph': ['file.jgr'],
\ 'jovial': ['file.jov', 'file.j73', 'file.jovial'],
\ 'jproperties': ['file.properties', 'file.properties_xx', 'file.properties_xx_xx', 'some.properties_xx_xx_file'],
- \ 'json': ['file.json', 'file.jsonp', 'file.json-patch', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb'],
+ \ 'json': ['file.json', 'file.jsonp', 'file.json-patch', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb', '.babelrc', '.eslintrc', '.prettierrc', '.firebaserc'],
\ 'jsonc': ['file.jsonc'],
\ 'jsp': ['file.jsp'],
\ 'julia': ['file.jl'],
@@ -344,6 +344,7 @@ let s:filename_checks = {
\ 'nanorc': ['/etc/nanorc', 'file.nanorc', 'any/etc/nanorc'],
\ 'ncf': ['file.ncf'],
\ 'netrc': ['.netrc'],
+ \ 'nginx': ['file.nginx', 'nginxfile.conf', 'filenginx.conf', 'any/etc/nginx/file', 'any/usr/local/nginx/conf/file', 'any/nginx/file.conf'],
\ 'ninja': ['file.ninja'],
\ 'nqc': ['file.nqc'],
\ 'nroff': ['file.tr', 'file.nr', 'file.roff', 'file.tmac', 'file.mom', 'tmac.file'],
@@ -491,7 +492,7 @@ let s:filename_checks = {
\ 'tak': ['file.tak'],
\ 'taskdata': ['pending.data', 'completed.data', 'undo.data'],
\ 'taskedit': ['file.task'],
- \ 'tcl': ['file.tcl', 'file.tk', 'file.itcl', 'file.itk', 'file.jacl'],
+ \ 'tcl': ['file.tcl', 'file.tm', 'file.tk', 'file.itcl', 'file.itk', 'file.jacl', '.tclshrc', 'tclsh.rc', '.wishrc'],
\ 'teraterm': ['file.ttl'],
\ 'terminfo': ['file.ti'],
\ 'tex': ['file.latex', 'file.sty', 'file.dtx', 'file.ltx', 'file.bbl'],
@@ -502,8 +503,8 @@ let s:filename_checks = {
\ 'tidy': ['.tidyrc', 'tidyrc', 'tidy.conf'],
\ 'tilde': ['file.t.html'],
\ 'tli': ['file.tli'],
- \ 'tmux': ['tmuxfile.conf', '.tmuxfile.conf', '.tmux-file.conf', '.tmux.conf', 'tmux-file.conf', 'tmux.conf'],
- \ 'toml': ['file.toml'],
+ \ 'tmux': ['tmuxfile.conf', '.tmuxfile.conf', '.tmux-file.conf', '.tmux.conf', 'tmux-file.conf', 'tmux.conf', 'tmux.conf.local'],
+ \ 'toml': ['file.toml', 'Gopkg.lock', 'Pipfile', '/home/user/.cargo/config'],
\ 'tpp': ['file.tpp'],
\ 'treetop': ['file.treetop'],
\ 'trustees': ['trustees.conf'],
@@ -553,6 +554,7 @@ let s:filename_checks = {
\ 'xml': ['/etc/blkid.tab', '/etc/blkid.tab.old', 'file.xmi', 'file.csproj', 'file.csproj.user', 'file.ui', 'file.tpm', '/etc/xdg/menus/file.menu', 'fglrxrc', 'file.xlf', 'file.xliff', 'file.xul', 'file.wsdl', 'file.wpl', 'any/etc/blkid.tab', 'any/etc/blkid.tab.old', 'any/etc/xdg/menus/file.menu'],
\ 'xmodmap': ['anyXmodmap', 'Xmodmap', 'some-Xmodmap', 'some-xmodmap', 'some-xmodmap-file', 'xmodmap', 'xmodmap-file'],
\ 'xf86conf': ['xorg.conf', 'xorg.conf-4'],
+ \ 'xpm': ['file.xpm'],
\ 'xpm2': ['file.xpm2'],
\ 'xquery': ['file.xq', 'file.xql', 'file.xqm', 'file.xquery', 'file.xqy'],
\ 'xs': ['file.xs'],
@@ -567,7 +569,6 @@ let s:filename_checks = {
\ 'zsh': ['.zprofile', '/etc/zprofile', '.zfbfmarks', 'file.zsh', '.zcompdump', '.zlogin', '.zlogout', '.zshenv', '.zshrc', '.zcompdump-file', '.zlog', '.zlog-file', '.zsh', '.zsh-file', 'any/etc/zprofile', 'zlog', 'zlog-file', 'zsh', 'zsh-file'],
\
\ 'help': [$VIMRUNTIME . '/doc/help.txt'],
- \ 'xpm': ['file.xpm'],
\ }
let s:filename_case_checks = {
@@ -917,4 +918,17 @@ func Test_m_file()
call delete('Xfile.m')
filetype off
endfunc
+
+func Test_xpm_file()
+ filetype on
+
+ call writefile(['this is XPM2'], 'file.xpm')
+ split file.xpm
+ call assert_equal('xpm2', &filetype)
+ bwipe!
+
+ call delete('file.xpm')
+ filetype off
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_find_complete.vim b/src/nvim/testdir/test_find_complete.vim
index 0a00d9432f..32ca9672ef 100644
--- a/src/nvim/testdir/test_find_complete.vim
+++ b/src/nvim/testdir/test_find_complete.vim
@@ -36,7 +36,7 @@ func Test_find_complete()
" We shouldn't find any file till this point
call mkdir('in/path', 'p')
- exe 'cd ' . cwd
+ call chdir(cwd)
call writefile(['Holy Grail'], 'Xfind/file.txt')
call writefile(['Jimmy Hoffa'], 'Xfind/in/file.txt')
call writefile(['Another Holy Grail'], 'Xfind/in/stuff.txt')
@@ -133,12 +133,12 @@ func Test_find_complete()
call assert_equal('Voyager 2', getline(1))
" Check for correct handling of shorten_fname()'s behavior on windows
- exec "cd " . cwd . "/Xfind/in"
+ call chdir(cwd .. "/Xfind/in")
call feedkeys(":find file\t\n", "xt")
call assert_equal('Jimmy Hoffa', getline(1))
" Test for relative to current buffer 'path' item
- exec "cd " . cwd . "/Xfind/"
+ call chdir(cwd . "/Xfind/")
set path=./path
" Open the file where Jimmy Hoffa is found
e in/file.txt
@@ -157,7 +157,7 @@ func Test_find_complete()
call assert_equal('Another Holy Grail', getline(1))
enew | only
- exe 'cd ' . cwd
+ call chdir(cwd)
call delete('Xfind', 'rf')
set path&
endfunc
diff --git a/src/nvim/testdir/test_findfile.vim b/src/nvim/testdir/test_findfile.vim
index 2195bf527e..5a20475d3d 100644
--- a/src/nvim/testdir/test_findfile.vim
+++ b/src/nvim/testdir/test_findfile.vim
@@ -50,7 +50,7 @@ func Test_findfile()
set path=.
call assert_equal('Xdir2/foo', findfile('foo'))
call assert_equal('', findfile('bar'))
- call assert_equal('Xdir2/foobar', findfile('foobar'))
+ call assert_equal('Xdir2/foobar', 'foobar'->findfile())
" Empty {path} 2nd argument is the same as no 2nd argument.
call assert_equal('Xdir2/foo', findfile('foo', ''))
@@ -113,7 +113,7 @@ func Test_findfile()
call assert_match('.*/Xdir1/bar', findfile('bar', '**;', 2))
bwipe!
- exe 'cd ' . save_dir
+ call chdir(save_dir)
call CleanFiles()
let &path = save_path
let &shellslash = save_shellslash
@@ -138,7 +138,7 @@ func Test_finddir()
cd Xdir1
call assert_equal('Xdir2', finddir('Xdir2'))
- call assert_equal('', finddir('Xdir3'))
+ call assert_equal('', 'Xdir3'->finddir())
" Files should not be found (findfile() finds them).
call assert_equal('', finddir('foo'))
@@ -171,7 +171,7 @@ func Test_finddir()
call assert_match('.*/Xdir1/Xdir2', finddir('Xdir2', '**;', 2))
call assert_equal('Xdir3', finddir('Xdir3', '**;', 1))
- exe 'cd ' . save_dir
+ call chdir(save_dir)
call CleanFiles()
let &path = save_path
let &shellslash = save_shellslash
diff --git a/src/nvim/testdir/test_float_func.vim b/src/nvim/testdir/test_float_func.vim
index 78675d7016..1e0c75c49d 100644
--- a/src/nvim/testdir/test_float_func.vim
+++ b/src/nvim/testdir/test_float_func.vim
@@ -15,6 +15,7 @@ func Test_abs()
call assert_equal("str2float('inf')", string(abs(1.0/0.0)))
call assert_equal("str2float('inf')", string(abs(-1.0/0.0)))
call assert_equal("str2float('nan')", string(abs(0.0/0.0)))
+ call assert_equal('12', string(abs('12abc')))
call assert_equal('12', string(abs('-12abc')))
call assert_fails("call abs([])", 'E745:')
call assert_fails("call abs({})", 'E728:')
diff --git a/src/nvim/testdir/test_fnameescape.vim b/src/nvim/testdir/test_fnameescape.vim
index 0bafdc29fb..cdb96ba5ff 100644
--- a/src/nvim/testdir/test_fnameescape.vim
+++ b/src/nvim/testdir/test_fnameescape.vim
@@ -13,7 +13,7 @@ func Test_fnameescape()
let fname = 'Xemark!'
let status = v:false
try
- exe "w! " . fnameescape(fname)
+ exe "w! " . fname->fnameescape()
let status = v:true
endtry
call assert_true(status, "ExclamationMark")
diff --git a/src/nvim/testdir/test_fnamemodify.vim b/src/nvim/testdir/test_fnamemodify.vim
index fe1df8fd4a..411f7ebbb3 100644
--- a/src/nvim/testdir/test_fnamemodify.vim
+++ b/src/nvim/testdir/test_fnamemodify.vim
@@ -13,7 +13,7 @@ func Test_fnamemodify()
call assert_equal('a', fnamemodify('../testdir/a', ':.'))
call assert_equal('~/testdir/test.out', fnamemodify('test.out', ':~'))
call assert_equal('~/testdir/a', fnamemodify('../testdir/a', ':~'))
- call assert_equal('a', fnamemodify('../testdir/a', ':t'))
+ call assert_equal('a', '../testdir/a'->fnamemodify(':t'))
call assert_equal('', fnamemodify('.', ':p:t'))
call assert_equal('test.out', fnamemodify('test.out', ':p:t'))
call assert_equal('out', fnamemodify('test.out', ':p:e'))
diff --git a/src/nvim/testdir/test_fold.vim b/src/nvim/testdir/test_fold.vim
index 2cc5b47cb0..5586fe2151 100644
--- a/src/nvim/testdir/test_fold.vim
+++ b/src/nvim/testdir/test_fold.vim
@@ -88,7 +88,7 @@ func Test_indent_fold2()
setl fen fdm=marker
2
norm! >>
- let a=map(range(1,5), 'foldclosed(v:val)')
+ let a=map(range(1,5), 'v:val->foldclosed()')
call assert_equal([-1,-1,-1,4,4], a)
bw!
endfunc
@@ -132,7 +132,7 @@ func Test_indent_fold_with_read()
call assert_equal(0, foldlevel(3))
call assert_equal(0, foldlevel(4))
call assert_equal(1, foldlevel(5))
- call assert_equal(7, foldclosedend(5))
+ call assert_equal(7, 5->foldclosedend())
bwipe!
set foldmethod&
@@ -207,7 +207,7 @@ func Test_update_folds_expr_read()
%foldclose
call assert_equal(2, foldclosedend(1))
call assert_equal(0, foldlevel(3))
- call assert_equal(0, foldlevel(4))
+ call assert_equal(0, 4->foldlevel())
call assert_equal(6, foldclosedend(5))
call assert_equal(10, foldclosedend(7))
call assert_equal(14, foldclosedend(11))
@@ -663,7 +663,7 @@ func Test_fold_move()
call assert_equal(10, foldclosed(10))
call assert_equal(11, foldclosedend(10))
call assert_equal('+-- 2 lines: Line2', foldtextresult(2))
- call assert_equal('+-- 2 lines: Line8', foldtextresult(10))
+ call assert_equal('+-- 2 lines: Line8', 10->foldtextresult())
set fdm& sw& fdl&
enew!
diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim
index e82fefc7fc..d10fad690c 100644
--- a/src/nvim/testdir/test_functions.vim
+++ b/src/nvim/testdir/test_functions.vim
@@ -56,6 +56,7 @@ func Test_empty()
endif
call assert_equal(0, empty(function('Test_empty')))
+ call assert_equal(0, empty(function('Test_empty', [0])))
endfunc
func Test_len()
@@ -294,7 +295,7 @@ func Test_resolve_unix()
call delete('Xlink')
silent !ln -s -f Xlink2/ Xlink1
- call assert_equal('Xlink2', resolve('Xlink1'))
+ call assert_equal('Xlink2', 'Xlink1'->resolve())
call assert_equal('Xlink2/', resolve('Xlink1/'))
call delete('Xlink1')
@@ -359,10 +360,10 @@ endfunc
func Test_pathshorten()
call assert_equal('', pathshorten(''))
call assert_equal('foo', pathshorten('foo'))
- call assert_equal('/foo', pathshorten('/foo'))
+ call assert_equal('/foo', '/foo'->pathshorten())
call assert_equal('f/', pathshorten('foo/'))
call assert_equal('f/bar', pathshorten('foo/bar'))
- call assert_equal('f/b/foobar', pathshorten('foo/bar/foobar'))
+ call assert_equal('f/b/foobar', 'foo/bar/foobar'->pathshorten())
call assert_equal('/f/b/foobar', pathshorten('/foo/bar/foobar'))
call assert_equal('.f/bar', pathshorten('.foo/bar'))
call assert_equal('~f/bar', pathshorten('~foo/bar'))
@@ -585,6 +586,8 @@ func Test_mode()
exe "normal iabc\<C-X>\<C-L>\<F2>\<Esc>u"
call assert_equal('i-ic', g:current_modes)
+ exe "normal R\<F2>\<Esc>"
+ call assert_equal('R-R', g:current_modes)
" R_CTRL-P: Multiple matches
exe "normal RBa\<C-P>\<F2>\<Esc>u"
call assert_equal('R-Rc', g:current_modes)
@@ -619,8 +622,44 @@ func Test_mode()
exe "normal Rabc\<C-X>\<C-L>\<F2>\<Esc>u"
call assert_equal('R-Rc', g:current_modes)
- call assert_equal('n', mode(0))
- call assert_equal('n', mode(1))
+ exe "normal gR\<F2>\<Esc>"
+ call assert_equal('R-Rv', g:current_modes)
+ " gR_CTRL-P: Multiple matches
+ exe "normal gRBa\<C-P>\<F2>\<Esc>u"
+ call assert_equal('R-Rvc', g:current_modes)
+ " gR_CTRL-P: Single match
+ exe "normal gRBro\<C-P>\<F2>\<Esc>u"
+ call assert_equal('R-Rvc', g:current_modes)
+ " gR_CTRL-X
+ exe "normal gRBa\<C-X>\<F2>\<Esc>u"
+ call assert_equal('R-Rvx', g:current_modes)
+ " gR_CTRL-X CTRL-P: Multiple matches
+ exe "normal gRBa\<C-X>\<C-P>\<F2>\<Esc>u"
+ call assert_equal('R-Rvc', g:current_modes)
+ " gR_CTRL-X CTRL-P: Single match
+ exe "normal gRBro\<C-X>\<C-P>\<F2>\<Esc>u"
+ call assert_equal('R-Rvc', g:current_modes)
+ " gR_CTRL-X CTRL-P + CTRL-P: Single match
+ exe "normal gRBro\<C-X>\<C-P>\<C-P>\<F2>\<Esc>u"
+ call assert_equal('R-Rvc', g:current_modes)
+ " gR_CTRL-X CTRL-L: Multiple matches
+ exe "normal gR\<C-X>\<C-L>\<F2>\<Esc>u"
+ call assert_equal('R-Rvc', g:current_modes)
+ " gR_CTRL-X CTRL-L: Single match
+ exe "normal gRBlu\<C-X>\<C-L>\<F2>\<Esc>u"
+ call assert_equal('R-Rvc', g:current_modes)
+ " gR_CTRL-P: No match
+ exe "normal gRCom\<C-P>\<F2>\<Esc>u"
+ call assert_equal('R-Rvc', g:current_modes)
+ " gR_CTRL-X CTRL-P: No match
+ exe "normal gRCom\<C-X>\<C-P>\<F2>\<Esc>u"
+ call assert_equal('R-Rvc', g:current_modes)
+ " gR_CTRL-X CTRL-L: No match
+ exe "normal gRabc\<C-X>\<C-L>\<F2>\<Esc>u"
+ call assert_equal('R-Rvc', g:current_modes)
+
+ call assert_equal('n', 0->mode())
+ call assert_equal('n', 1->mode())
" i_CTRL-O
exe "normal i\<C-O>:call Save_mode()\<Cr>\<Esc>"
@@ -672,10 +711,34 @@ func Test_mode()
call assert_equal('c-cv', g:current_modes)
" How to test Ex mode?
+ " Test mode in operatorfunc (it used to be Operator-pending).
+ set operatorfunc=OperatorFunc
+ function OperatorFunc(_)
+ call Save_mode()
+ endfunction
+ execute "normal! g@l\<Esc>"
+ call assert_equal('n-n', g:current_modes)
+ execute "normal! i\<C-o>g@l\<Esc>"
+ call assert_equal('n-niI', g:current_modes)
+ execute "normal! R\<C-o>g@l\<Esc>"
+ call assert_equal('n-niR', g:current_modes)
+ execute "normal! gR\<C-o>g@l\<Esc>"
+ call assert_equal('n-niV', g:current_modes)
+
+ if has('terminal')
+ term
+ call feedkeys("\<C-W>N", 'xt')
+ call assert_equal('n', mode())
+ call assert_equal('nt', mode(1))
+ call feedkeys("aexit\<CR>", 'xt')
+ endif
+
bwipe!
iunmap <F2>
xunmap <F2>
set complete&
+ set operatorfunc&
+ delfunction OperatorFunc
endfunc
func Test_append()
@@ -776,7 +839,7 @@ endfunc
func Test_match_func()
call assert_equal(4, match('testing', 'ing'))
- call assert_equal(4, match('testing', 'ing', 2))
+ call assert_equal(4, 'testing'->match('ing', 2))
call assert_equal(-1, match('testing', 'ing', 5))
call assert_equal(-1, match('testing', 'ing', 8))
call assert_equal(1, match(['vim', 'testing', 'execute'], 'ing'))
@@ -785,7 +848,7 @@ endfunc
func Test_matchend()
call assert_equal(7, matchend('testing', 'ing'))
- call assert_equal(7, matchend('testing', 'ing', 2))
+ call assert_equal(7, 'testing'->matchend('ing', 2))
call assert_equal(-1, matchend('testing', 'ing', 5))
call assert_equal(-1, matchend('testing', 'ing', 8))
call assert_equal(match(['vim', 'testing', 'execute'], 'ing'), matchend(['vim', 'testing', 'execute'], 'ing'))
@@ -794,13 +857,13 @@ endfunc
func Test_matchlist()
call assert_equal(['acd', 'a', '', 'c', 'd', '', '', '', '', ''], matchlist('acd', '\(a\)\?\(b\)\?\(c\)\?\(.*\)'))
- call assert_equal(['d', '', '', '', 'd', '', '', '', '', ''], matchlist('acd', '\(a\)\?\(b\)\?\(c\)\?\(.*\)', 2))
+ call assert_equal(['d', '', '', '', 'd', '', '', '', '', ''], 'acd'->matchlist('\(a\)\?\(b\)\?\(c\)\?\(.*\)', 2))
call assert_equal([], matchlist('acd', '\(a\)\?\(b\)\?\(c\)\?\(.*\)', 4))
endfunc
func Test_matchstr()
call assert_equal('ing', matchstr('testing', 'ing'))
- call assert_equal('ing', matchstr('testing', 'ing', 2))
+ call assert_equal('ing', 'testing'->matchstr('ing', 2))
call assert_equal('', matchstr('testing', 'ing', 5))
call assert_equal('', matchstr('testing', 'ing', 8))
call assert_equal('testing', matchstr(['vim', 'testing', 'execute'], 'ing'))
@@ -809,7 +872,7 @@ endfunc
func Test_matchstrpos()
call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing'))
- call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing', 2))
+ call assert_equal(['ing', 4, 7], 'testing'->matchstrpos('ing', 2))
call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 5))
call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 8))
call assert_equal(['ing', 1, 4, 7], matchstrpos(['vim', 'testing', 'execute'], 'ing'))
@@ -830,21 +893,21 @@ Test
call assert_equal(0, nextnonblank(-1))
call assert_equal(0, nextnonblank(0))
call assert_equal(1, nextnonblank(1))
- call assert_equal(4, nextnonblank(2))
+ call assert_equal(4, 2->nextnonblank())
call assert_equal(4, nextnonblank(3))
call assert_equal(4, nextnonblank(4))
call assert_equal(6, nextnonblank(5))
call assert_equal(6, nextnonblank(6))
call assert_equal(7, nextnonblank(7))
- call assert_equal(0, nextnonblank(8))
+ call assert_equal(0, 8->nextnonblank())
call assert_equal(0, prevnonblank(-1))
call assert_equal(0, prevnonblank(0))
- call assert_equal(1, prevnonblank(1))
+ call assert_equal(1, 1->prevnonblank())
call assert_equal(1, prevnonblank(2))
call assert_equal(1, prevnonblank(3))
call assert_equal(4, prevnonblank(4))
- call assert_equal(4, prevnonblank(5))
+ call assert_equal(4, 5->prevnonblank())
call assert_equal(6, prevnonblank(6))
call assert_equal(7, prevnonblank(7))
call assert_equal(0, prevnonblank(8))
@@ -866,7 +929,7 @@ func Test_byte2line_line2byte()
call assert_equal([-1, -1, 1, 1, 2, 2, 2, 3, 3, -1],
\ map(range(-1, 8), 'v:val->byte2line()'))
call assert_equal([-1, -1, 1, 3, 6, 8, -1],
- \ map(range(-1, 5), 'line2byte(v:val)'))
+ \ map(range(-1, 5), 'v:val->line2byte()'))
set fileformat=dos
call assert_equal([-1, -1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, -1],
@@ -961,6 +1024,7 @@ func Test_count()
call assert_equal(1, count(l, 'a', 0, 1))
call assert_equal(2, count(l, 'a', 1, 1))
call assert_fails('call count(l, "a", 0, 10)', 'E684:')
+ call assert_fails('call count(l, "a", [])', 'E745:')
let d = {1: 'a', 2: 'a', 3: 'A', 4: 'b'}
call assert_equal(2, count(d, 'a'))
@@ -988,6 +1052,8 @@ func Test_count()
call assert_equal(2, count("foo", "O", 1))
call assert_equal(2, count("fooooo", "oo"))
call assert_equal(0, count("foo", ""))
+
+ call assert_fails('call count(0, 0)', 'E712:')
endfunc
func Test_changenr()
@@ -1015,7 +1081,7 @@ func Test_filewritable()
call assert_equal(0, filewritable('Xfilewritable'))
call assert_notequal(0, setfperm('Xfilewritable', 'rw-r-----'))
- call assert_equal(1, filewritable('Xfilewritable'))
+ call assert_equal(1, 'Xfilewritable'->filewritable())
call assert_equal(0, filewritable('doesnotexist'))
@@ -1026,12 +1092,12 @@ endfunc
func Test_Executable()
if has('win32')
call assert_equal(1, executable('notepad'))
- call assert_equal(1, executable('notepad.exe'))
+ call assert_equal(1, 'notepad.exe'->executable())
call assert_equal(0, executable('notepad.exe.exe'))
call assert_equal(0, executable('shell32.dll'))
call assert_equal(0, executable('win.ini'))
elseif has('unix')
- call assert_equal(1, executable('cat'))
+ call assert_equal(1, 'cat'->executable())
call assert_equal(0, executable('nodogshere'))
" get "cat" path and remove the leading /
@@ -1040,8 +1106,7 @@ func Test_Executable()
" check that the relative path works in /
lcd /
call assert_equal(1, executable(catcmd))
- " let result = catcmd->exepath()
- let result = exepath(catcmd)
+ let result = catcmd->exepath()
" when using chroot looking for sbin/cat can return bin/cat, that is OK
if catcmd =~ '\<sbin\>' && result =~ '\<bin\>'
call assert_equal('/' .. substitute(catcmd, '\<sbin\>', 'bin', ''), result)
@@ -1086,7 +1151,7 @@ endfunc
func Test_hlexists()
call assert_equal(0, hlexists('does_not_exist'))
- " call assert_equal(0, hlexists('Number'))
+ " call assert_equal(0, 'Number'->hlexists())
call assert_equal(0, highlight_exists('does_not_exist'))
" call assert_equal(0, highlight_exists('Number'))
syntax on
@@ -1119,7 +1184,7 @@ endfunc
func Test_inputlist()
call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>1\<cr>", 'tx')
call assert_equal(1, c)
- call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>2\<cr>", 'tx')
+ call feedkeys(":let c = ['Select color:', '1. red', '2. green', '3. blue']->inputlist()\<cr>2\<cr>", 'tx')
call assert_equal(2, c)
call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>3\<cr>", 'tx')
call assert_equal(3, c)
@@ -1251,7 +1316,7 @@ func Test_trim()
call assert_fails('call trim(" vim ", " ", -1)', 'E475:')
call assert_fails('call trim(" vim ", " ", 3)', 'E475:')
- let chars = join(map(range(1, 0x20) + [0xa0], {n -> nr2char(n)}), '')
+ let chars = join(map(range(1, 0x20) + [0xa0], {n -> n->nr2char()}), '')
call assert_equal("x", trim(chars . "x" . chars))
endfunc
@@ -1265,7 +1330,7 @@ func Test_func_range_with_edit()
" is invalid in that buffer.
call writefile(['just one line'], 'Xfuncrange2')
new
- call setline(1, range(10))
+ call setline(1, 10->range())
write Xfuncrange1
call assert_fails('5,8call EditAnotherFile()', 'E16:')
@@ -1278,7 +1343,7 @@ func Test_func_exists_on_reload()
call writefile(['func ExistingFunction()', 'echo "yes"', 'endfunc'], 'Xfuncexists')
call assert_equal(0, exists('*ExistingFunction'))
source Xfuncexists
- call assert_equal(1, exists('*ExistingFunction'))
+ call assert_equal(1, '*ExistingFunction'->exists())
" Redefining a function when reloading a script is OK.
source Xfuncexists
call assert_equal(1, exists('*ExistingFunction'))
@@ -1309,7 +1374,7 @@ func Test_func_sandbox()
sandbox let F = {-> 'hello'}
call assert_equal('hello', F())
- sandbox let F = {-> execute("normal ix\<Esc>")}
+ sandbox let F = {-> "normal ix\<Esc>"->execute()}
call assert_fails('call F()', 'E48:')
unlet F
@@ -1372,7 +1437,7 @@ func Test_reg_executing_and_recording()
let g:regs = []
func TestFunc() abort
let g:regs += [reg_executing()]
- let g:typed = input('?')
+ let g:typed = '?'->input()
let g:regs += [reg_executing()]
endfunc
call feedkeys("@qy\<CR>", 'xt')
@@ -1388,6 +1453,25 @@ func Test_reg_executing_and_recording()
unlet s:reg_stat
endfunc
+func Test_inputsecret()
+ map W :call TestFunc()<CR>
+ let @q = "W"
+ let g:typed1 = ''
+ let g:typed2 = ''
+ let g:regs = []
+ func TestFunc() abort
+ let g:typed1 = '?'->inputsecret()
+ let g:typed2 = inputsecret('password: ')
+ endfunc
+ call feedkeys("@qsomething\<CR>else\<CR>", 'xt')
+ call assert_equal("something", g:typed1)
+ call assert_equal("else", g:typed2)
+ delfunc TestFunc
+ unmap W
+ unlet g:typed1
+ unlet g:typed2
+endfunc
+
func Test_getchar()
call feedkeys('a', '')
call assert_equal(char2nr('a'), getchar())
@@ -1445,17 +1529,17 @@ func Test_libcall_libcallnr()
endif
if has('win32')
- call assert_equal($USERPROFILE, libcall(libc, 'getenv', 'USERPROFILE'))
+ call assert_equal($USERPROFILE, 'USERPROFILE'->libcall(libc, 'getenv'))
else
- call assert_equal($HOME, libcall(libc, 'getenv', 'HOME'))
+ call assert_equal($HOME, 'HOME'->libcall(libc, 'getenv'))
endif
" If function returns NULL, libcall() should return an empty string.
call assert_equal('', libcall(libc, 'getenv', 'X_ENV_DOES_NOT_EXIT'))
" Test libcallnr() with string and integer argument.
- call assert_equal(4, libcallnr(libc, 'strlen', 'abcd'))
- call assert_equal(char2nr('A'), libcallnr(libc, 'toupper', char2nr('a')))
+ call assert_equal(4, 'abcd'->libcallnr(libc, 'strlen'))
+ call assert_equal(char2nr('A'), char2nr('a')->libcallnr(libc, 'toupper'))
call assert_fails("call libcall(libc, 'Xdoesnotexist_', '')", 'E364:')
call assert_fails("call libcallnr(libc, 'Xdoesnotexist_', '')", 'E364:')
@@ -1518,7 +1602,7 @@ func Test_readdir()
call assert_equal(['bar.txt', 'dir', 'foo.txt'], sort(files))
" Only results containing "f"
- let files = readdir('Xdir', { x -> stridx(x, 'f') !=- 1 })
+ let files = 'Xdir'->readdir({ x -> stridx(x, 'f') !=- 1 })
call assert_equal(['foo.txt'], sort(files))
" Only .txt files
@@ -1551,6 +1635,14 @@ func Test_call()
call assert_fails("call call('Mylen', [], 0)", 'E715:')
endfunc
+func Test_char2nr()
+ call assert_equal(12354, char2nr('あ', 1))
+endfunc
+
+func Test_eventhandler()
+ call assert_equal(0, eventhandler())
+endfunc
+
" Test for the eval() function
func Test_eval()
call assert_fails("call eval('5 a')", 'E488:')
diff --git a/src/nvim/testdir/test_getcwd.vim b/src/nvim/testdir/test_getcwd.vim
index ca098781e4..a75583cd2c 100644
--- a/src/nvim/testdir/test_getcwd.vim
+++ b/src/nvim/testdir/test_getcwd.vim
@@ -17,7 +17,7 @@ func GetCwdInfo(win, tab)
let lflag = haslocaldir(a:win)
else
let dirname = fnamemodify(getcwd(a:win, a:tab), mod)
- let lflag = haslocaldir(a:win, a:tab)
+ let lflag = a:win->haslocaldir(a:tab)
endif
return bufname . ' ' . dirname . ' ' . lflag
endfunc
@@ -35,7 +35,7 @@ function SetUp()
" we start from a clean state.
call delete("Xtopdir", "rf")
new
- call mkdir('Xtopdir')
+ eval 'Xtopdir'->mkdir()
cd Xtopdir
let g:topdir = getcwd()
call mkdir('Xdir1')
@@ -46,7 +46,7 @@ endfunction
let g:cwd=getcwd()
function TearDown()
q
- exec "cd " . g:cwd
+ call chdir(g:cwd)
call delete("Xtopdir", "rf")
endfunction
diff --git a/src/nvim/testdir/test_getvar.vim b/src/nvim/testdir/test_getvar.vim
index 3b61d68ebc..5a96548893 100644
--- a/src/nvim/testdir/test_getvar.vim
+++ b/src/nvim/testdir/test_getvar.vim
@@ -12,8 +12,8 @@ func Test_var()
let def_str = "Chance"
call assert_equal('Dance', getwinvar(1, 'var_str'))
call assert_equal('Dance', getwinvar(1, 'var_str', def_str))
- call assert_equal({'var_str': 'Dance'}, getwinvar(1, ''))
- call assert_equal({'var_str': 'Dance'}, getwinvar(1, '', def_str))
+ call assert_equal({'var_str': 'Dance'}, 1->getwinvar(''))
+ call assert_equal({'var_str': 'Dance'}, 1->getwinvar('', def_str))
unlet w:var_str
call assert_equal('Chance', getwinvar(1, 'var_str', def_str))
call assert_equal({}, getwinvar(1, ''))
@@ -31,7 +31,7 @@ func Test_var()
let t:other = 777
let def_list = [4, 5, 6, 7]
tabrewind
- call assert_equal([1, 2, 3], gettabvar(3, 'var_list'))
+ call assert_equal([1, 2, 3], 3->gettabvar('var_list'))
call assert_equal([1, 2, 3], gettabvar(3, 'var_list', def_list))
call assert_equal({'var_list': [1, 2, 3], 'other': 777}, gettabvar(3, ''))
call assert_equal({'var_list': [1, 2, 3], 'other': 777},
@@ -61,7 +61,7 @@ func Test_var()
let def_dict = {'dict2': 'newval'}
wincmd b
tabrewind
- call assert_equal({'dict': 'tabwin'}, gettabwinvar(2, 3, 'var_dict'))
+ call assert_equal({'dict': 'tabwin'}, 2->gettabwinvar(3, 'var_dict'))
call assert_equal({'dict': 'tabwin'},
\ gettabwinvar(2, 3, 'var_dict', def_dict))
call assert_equal({'var_dict': {'dict': 'tabwin'}}, gettabwinvar(2, 3, ''))
diff --git a/src/nvim/testdir/test_glob2regpat.vim b/src/nvim/testdir/test_glob2regpat.vim
index 354f239ef1..a423a4a9f0 100644
--- a/src/nvim/testdir/test_glob2regpat.vim
+++ b/src/nvim/testdir/test_glob2regpat.vim
@@ -10,7 +10,7 @@ endfunc
func Test_glob2regpat_valid()
call assert_equal('^foo\.', glob2regpat('foo.*'))
- call assert_equal('^foo.$', glob2regpat('foo?'))
+ call assert_equal('^foo.$', 'foo?'->glob2regpat())
call assert_equal('\.vim$', glob2regpat('*.vim'))
call assert_equal('^[abc]$', glob2regpat('[abc]'))
call assert_equal('^foo bar$', glob2regpat('foo\ bar'))
diff --git a/src/nvim/testdir/test_history.vim b/src/nvim/testdir/test_history.vim
index 16aad9889e..2f0dc2dae1 100644
--- a/src/nvim/testdir/test_history.vim
+++ b/src/nvim/testdir/test_history.vim
@@ -13,7 +13,7 @@ function History_Tests(hist)
call assert_equal(-1, histnr(a:hist))
call assert_equal('', histget(a:hist))
- call assert_true(histadd(a:hist, 'ls'))
+ call assert_true('ls'->histadd(a:hist))
call assert_true(histadd(a:hist, 'buffers'))
call assert_equal('buffers', histget(a:hist))
call assert_equal('ls', histget(a:hist, -2))
@@ -22,14 +22,14 @@ function History_Tests(hist)
call assert_equal('', histget(a:hist, -5))
call assert_equal(2, histnr(a:hist))
call assert_true(histdel(a:hist, 2))
- call assert_false(histdel(a:hist, 7))
+ call assert_false(a:hist->histdel(7))
call assert_equal(1, histnr(a:hist))
call assert_equal('ls', histget(a:hist, -1))
call assert_true(histadd(a:hist, 'buffers'))
call assert_true(histadd(a:hist, 'ls'))
- call assert_equal('ls', histget(a:hist, -1))
- call assert_equal(4, histnr(a:hist))
+ call assert_equal('ls', a:hist->histget(-1))
+ call assert_equal(4, a:hist->histnr())
let a=execute('history ' . a:hist)
call assert_match("^\n # \\S* history\n 3 buffers\n> 4 ls$", a)
diff --git a/src/nvim/testdir/test_jumplist.vim b/src/nvim/testdir/test_jumplist.vim
index be1af5e705..9cfbbe2029 100644
--- a/src/nvim/testdir/test_jumplist.vim
+++ b/src/nvim/testdir/test_jumplist.vim
@@ -39,7 +39,7 @@ func Test_getjumplist()
" Traverse the jump list and verify the results
5
exe "normal \<C-O>"
- call assert_equal(2, getjumplist(1)[1])
+ call assert_equal(2, 1->getjumplist()[1])
exe "normal 2\<C-O>"
call assert_equal(0, getjumplist(1, 1)[1])
exe "normal 3\<C-I>"
diff --git a/src/nvim/testdir/test_lispwords.vim b/src/nvim/testdir/test_lispwords.vim
index 4c05504cf1..aa5a738bdf 100644
--- a/src/nvim/testdir/test_lispwords.vim
+++ b/src/nvim/testdir/test_lispwords.vim
@@ -43,6 +43,9 @@ func Test_lisp_indent()
\ ',@body',
\ '(princ "</a>")))'
\ ])
+ call assert_equal(7, lispindent(2))
+ call assert_equal(5, 6->lispindent())
+
set lisp
set lispwords&
let save_copt = &cpoptions
diff --git a/src/nvim/testdir/test_listdict.vim b/src/nvim/testdir/test_listdict.vim
index ae035fa519..f6c404d390 100644
--- a/src/nvim/testdir/test_listdict.vim
+++ b/src/nvim/testdir/test_listdict.vim
@@ -573,7 +573,7 @@ func Test_lockvar_script_autoload()
set rtp+=./sautest
lockvar g:footest#x
unlockvar g:footest#x
- call assert_equal(-1, islocked('g:footest#x'))
+ call assert_equal(-1, 'g:footest#x'->islocked())
call assert_equal(0, exists('g:footest#x'))
call assert_equal(1, g:footest#x)
let &rtp = old_rtp
diff --git a/src/nvim/testdir/test_maparg.vim b/src/nvim/testdir/test_maparg.vim
index 238d2f900d..5b082198cf 100644
--- a/src/nvim/testdir/test_maparg.vim
+++ b/src/nvim/testdir/test_maparg.vim
@@ -1,5 +1,6 @@
" Tests for maparg().
" Also test utf8 map with a 0x80 byte.
+" Also test mapcheck()
function s:SID()
return str2nr(matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_SID$'))
@@ -22,7 +23,7 @@ function Test_maparg()
call assert_equal({'silent': 1, 'noremap': 1, 'script': 1, 'lhs': 'bar', 'mode': 'v',
\ 'nowait': 0, 'expr': 1, 'sid': sid, 'lnum': lnum + 2,
\ 'rhs': 'isbar', 'buffer': 1},
- \ maparg('bar', '', 0, 1))
+ \ 'bar'->maparg('', 0, 1))
let lnum = expand('<sflnum>')
map <buffer> <nowait> foo bar
call assert_equal({'silent': 0, 'noremap': 0, 'script': 0, 'lhs': 'foo', 'mode': ' ',
@@ -51,6 +52,45 @@ function Test_maparg()
unmap abc
endfunction
+func Test_mapcheck()
+ call assert_equal('', mapcheck('a'))
+ call assert_equal('', mapcheck('abc'))
+ call assert_equal('', mapcheck('ax'))
+ call assert_equal('', mapcheck('b'))
+
+ map a something
+ call assert_equal('something', mapcheck('a'))
+ call assert_equal('something', mapcheck('a', 'n'))
+ call assert_equal('', mapcheck('a', 'c'))
+ call assert_equal('', mapcheck('a', 'i'))
+ call assert_equal('something', 'abc'->mapcheck())
+ call assert_equal('something', 'ax'->mapcheck())
+ call assert_equal('', mapcheck('b'))
+ unmap a
+
+ map ab foobar
+ call assert_equal('foobar', mapcheck('a'))
+ call assert_equal('foobar', mapcheck('abc'))
+ call assert_equal('', mapcheck('ax'))
+ call assert_equal('', mapcheck('b'))
+ unmap ab
+
+ map abc barfoo
+ call assert_equal('barfoo', mapcheck('a'))
+ call assert_equal('barfoo', mapcheck('a', 'n', 0))
+ call assert_equal('', mapcheck('a', 'n', 1))
+ call assert_equal('barfoo', mapcheck('abc'))
+ call assert_equal('', mapcheck('ax'))
+ call assert_equal('', mapcheck('b'))
+ unmap abc
+
+ abbr ab abbrev
+ call assert_equal('abbrev', mapcheck('a', 'i', 1))
+ call assert_equal('', mapcheck('a', 'n', 1))
+ call assert_equal('', mapcheck('a', 'i', 0))
+ unabbr ab
+endfunc
+
function Test_range_map()
new
" Outside of the range, minimum
diff --git a/src/nvim/testdir/test_match.vim b/src/nvim/testdir/test_match.vim
index 505a052a19..70271aa32f 100644
--- a/src/nvim/testdir/test_match.vim
+++ b/src/nvim/testdir/test_match.vim
@@ -14,7 +14,7 @@ function Test_match()
2match MyGroup2 /FIXME/
3match MyGroup3 /XXX/
call assert_equal(['MyGroup1', 'TODO'], matcharg(1))
- call assert_equal(['MyGroup2', 'FIXME'], matcharg(2))
+ call assert_equal(['MyGroup2', 'FIXME'], 2->matcharg())
call assert_equal(['MyGroup3', 'XXX'], matcharg(3))
" --- Check that "matcharg()" returns an empty list if the argument is not 1,
@@ -43,7 +43,7 @@ function Test_match()
" --- Check that "matchdelete()" deletes the matches defined in the previous
" --- test correctly.
call matchdelete(m1)
- call matchdelete(m2)
+ eval m2->matchdelete()
call matchdelete(m3)
call assert_equal([], getmatches())
@@ -55,7 +55,7 @@ function Test_match()
" --- Check that "clearmatches()" clears all matches defined by ":match" and
" --- "matchadd()".
let m1 = matchadd("MyGroup1", "TODO")
- let m2 = matchadd("MyGroup2", "FIXME", 42)
+ let m2 = "MyGroup2"->matchadd("FIXME", 42)
let m3 = matchadd("MyGroup3", "XXX", 60, 17)
match MyGroup1 /COFFEE/
2match MyGroup2 /HUMPPA/
@@ -117,7 +117,7 @@ function Test_match()
call clearmatches()
call setline(1, 'abcdΣabcdef')
- call matchaddpos("MyGroup1", [[1, 4, 2], [1, 9, 2]])
+ eval "MyGroup1"->matchaddpos([[1, 4, 2], [1, 9, 2]])
1
redraw!
let v1 = screenattr(1, 1)
diff --git a/src/nvim/testdir/test_method.vim b/src/nvim/testdir/test_method.vim
index d34448e09e..cdf688b857 100644
--- a/src/nvim/testdir/test_method.vim
+++ b/src/nvim/testdir/test_method.vim
@@ -1,5 +1,7 @@
" Tests for ->method()
+source check.vim
+
func Test_list_method()
let l = [1, 2, 3]
call assert_equal([1, 2, 3, 4], [1, 2, 3]->add(4))
@@ -118,6 +120,7 @@ func Test_method_funcref()
endfunc
func Test_method_float()
+ CheckFeature float
eval 1.234->string()->assert_equal('1.234')
eval -1.234->string()->assert_equal('-1.234')
endfunc
diff --git a/src/nvim/testdir/test_perl.vim b/src/nvim/testdir/test_perl.vim
index 872194a804..b911a982f9 100644
--- a/src/nvim/testdir/test_perl.vim
+++ b/src/nvim/testdir/test_perl.vim
@@ -32,7 +32,7 @@ endfunc
funct Test_VIM_Blob()
call assert_equal('0z', perleval('VIM::Blob("")'))
- call assert_equal('0z31326162', perleval('VIM::Blob("12ab")'))
+ call assert_equal('0z31326162', 'VIM::Blob("12ab")'->perleval())
call assert_equal('0z00010203', perleval('VIM::Blob("\x00\x01\x02\x03")'))
call assert_equal('0z8081FEFF', perleval('VIM::Blob("\x80\x81\xfe\xff")'))
endfunc
diff --git a/src/nvim/testdir/test_popup.vim b/src/nvim/testdir/test_popup.vim
index 710450293c..eb367cfe5c 100644
--- a/src/nvim/testdir/test_popup.vim
+++ b/src/nvim/testdir/test_popup.vim
@@ -950,6 +950,10 @@ func Test_popup_complete_info_01()
\ ["\<C-X>", 'ctrl_x'],
\ ["\<C-X>\<C-N>", 'keyword'],
\ ["\<C-X>\<C-P>", 'keyword'],
+ \ ["\<C-X>\<C-E>", 'scroll'],
+ \ ["\<C-X>\<C-Y>", 'scroll'],
+ \ ["\<C-X>\<C-E>\<C-E>\<C-Y>", 'scroll'],
+ \ ["\<C-X>\<C-Y>\<C-E>\<C-Y>", 'scroll'],
\ ["\<C-X>\<C-L>", 'whole_line'],
\ ["\<C-X>\<C-F>", 'files'],
\ ["\<C-X>\<C-]>", 'tags'],
diff --git a/src/nvim/testdir/test_prompt_buffer.vim b/src/nvim/testdir/test_prompt_buffer.vim
index 6fc5850be3..3da46eb1a6 100644
--- a/src/nvim/testdir/test_prompt_buffer.vim
+++ b/src/nvim/testdir/test_prompt_buffer.vim
@@ -110,11 +110,8 @@ func Test_prompt_garbage_collect()
new
set buftype=prompt
- " Nvim doesn't support method call syntax yet.
- " eval bufnr('')->prompt_setcallback(function('MyPromptCallback', [{}]))
- " eval bufnr('')->prompt_setinterrupt(function('MyPromptInterrupt', [{}]))
- eval prompt_setcallback(bufnr(''), function('MyPromptCallback', [{}]))
- eval prompt_setinterrupt(bufnr(''), function('MyPromptInterrupt', [{}]))
+ eval bufnr('')->prompt_setcallback(function('MyPromptCallback', [{}]))
+ eval bufnr('')->prompt_setinterrupt(function('MyPromptInterrupt', [{}]))
call test_garbagecollect_now()
" Must not crash
call feedkeys("\<CR>\<C-C>", 'xt')
diff --git a/src/nvim/testdir/test_python2.vim b/src/nvim/testdir/test_python2.vim
index 5895ac85a8..ae8bc57c7f 100644
--- a/src/nvim/testdir/test_python2.vim
+++ b/src/nvim/testdir/test_python2.vim
@@ -59,7 +59,7 @@ func Test_vim_function()
try
py f = vim.Function('\x80\xfdR' + vim.eval('s:foo()'))
- call assert_equal(name, pyeval('f.name'))
+ call assert_equal(name, 'f.name'->pyeval())
catch
call assert_false(v:exception)
endtry
diff --git a/src/nvim/testdir/test_python3.vim b/src/nvim/testdir/test_python3.vim
index 637648817c..54da3d2eba 100644
--- a/src/nvim/testdir/test_python3.vim
+++ b/src/nvim/testdir/test_python3.vim
@@ -59,7 +59,7 @@ func Test_vim_function()
try
py3 f = vim.Function(b'\x80\xfdR' + vim.eval('s:foo()').encode())
- call assert_equal(name, py3eval('f.name'))
+ call assert_equal(name, 'f.name'->py3eval())
catch
call assert_false(v:exception)
endtry
diff --git a/src/nvim/testdir/test_pyx2.vim b/src/nvim/testdir/test_pyx2.vim
index 10ff3b6e58..b6ed80f842 100644
--- a/src/nvim/testdir/test_pyx2.vim
+++ b/src/nvim/testdir/test_pyx2.vim
@@ -35,7 +35,7 @@ endfunc
func Test_pyxeval()
pyx import sys
- call assert_match(s:py2pattern, split(pyxeval('sys.version'))[0])
+ call assert_match(s:py2pattern, split('sys.version'->pyxeval())[0])
endfunc
diff --git a/src/nvim/testdir/test_registers.vim b/src/nvim/testdir/test_registers.vim
index 53069b3d31..fd8653a2eb 100644
--- a/src/nvim/testdir/test_registers.vim
+++ b/src/nvim/testdir/test_registers.vim
@@ -283,4 +283,84 @@ func Test_insert_small_delete()
bwipe!
endfunc
+" Test for getting register info
+func Test_get_reginfo()
+ enew
+ call setline(1, ['foo', 'bar'])
+
+ exe 'norm! "zyy'
+ let info = getreginfo('"')
+ call assert_equal('z', info.points_to)
+ call setreg('y', 'baz')
+ call assert_equal('z', getreginfo('').points_to)
+ call setreg('y', { 'isunnamed': v:true })
+ call assert_equal('y', getreginfo('"').points_to)
+
+ exe '$put'
+ call assert_equal(getreg('y'), getline(3))
+ call setreg('', 'qux')
+ call assert_equal('0', getreginfo('').points_to)
+ call setreg('x', 'quux')
+ call assert_equal('0', getreginfo('').points_to)
+
+ let info = getreginfo('')
+ call assert_equal(getreg('', 1, 1), info.regcontents)
+ call assert_equal(getregtype(''), info.regtype)
+
+ exe "norm! 0\<c-v>e" .. '"zy'
+ let info = getreginfo('z')
+ call assert_equal(getreg('z', 1, 1), info.regcontents)
+ call assert_equal(getregtype('z'), info.regtype)
+ call assert_equal(1, +info.isunnamed)
+
+ let info = getreginfo('"')
+ call assert_equal('z', info.points_to)
+
+ bwipe!
+endfunc
+
+" Test for restoring register with dict from getreginfo
+func Test_set_register_dict()
+ enew!
+
+ call setreg('"', #{ regcontents: ['one', 'two'],
+ \ regtype: 'V', points_to: 'z' })
+ call assert_equal(['one', 'two'], getreg('"', 1, 1))
+ let info = getreginfo('"')
+ call assert_equal('z', info.points_to)
+ call assert_equal('V', info.regtype)
+ call assert_equal(1, +getreginfo('z').isunnamed)
+
+ call setreg('x', #{ regcontents: ['three', 'four'],
+ \ regtype: 'v', isunnamed: v:true })
+ call assert_equal(['three', 'four'], getreg('"', 1, 1))
+ let info = getreginfo('"')
+ call assert_equal('x', info.points_to)
+ call assert_equal('v', info.regtype)
+ call assert_equal(1, +getreginfo('x').isunnamed)
+
+ call setreg('y', #{ regcontents: 'five',
+ \ regtype: "\<c-v>", isunnamed: v:false })
+ call assert_equal("\<c-v>4", getreginfo('y').regtype)
+ call assert_equal(0, +getreginfo('y').isunnamed)
+ call assert_equal(['three', 'four'], getreg('"', 1, 1))
+ call assert_equal('x', getreginfo('"').points_to)
+
+ call setreg('"', #{ regcontents: 'six' })
+ call assert_equal('0', getreginfo('"').points_to)
+ call assert_equal(1, +getreginfo('0').isunnamed)
+ call assert_equal(['six'], getreginfo('0').regcontents)
+ call assert_equal(['six'], getreginfo('"').regcontents)
+
+ let @x = 'one'
+ call setreg('x', {})
+ call assert_equal(1, len(split(execute('reg x'), '\n')))
+
+ call assert_fails("call setreg('0', #{regtype: 'V'}, 'v')", 'E118:')
+ call assert_fails("call setreg('0', #{regtype: 'X'})", 'E475:')
+ call assert_fails("call setreg('0', #{regtype: 'vy'})", 'E475:')
+
+ bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_reltime.vim b/src/nvim/testdir/test_reltime.vim
index 2ef2fbba23..37b9e783c6 100644
--- a/src/nvim/testdir/test_reltime.vim
+++ b/src/nvim/testdir/test_reltime.vim
@@ -8,11 +8,11 @@ func Test_reltime()
let now = reltime()
sleep 10m
let later = reltime()
- let elapsed = reltime(now)
+ let elapsed = now->reltime()
call assert_true(reltimestr(elapsed) =~ '0\.0')
- call assert_true(reltimestr(elapsed) != '0.0')
+ call assert_true(elapsed->reltimestr() != '0.0')
call assert_true(reltimefloat(elapsed) < 0.1)
- call assert_true(reltimefloat(elapsed) > 0.0)
+ call assert_true(elapsed->reltimefloat() > 0.0)
let same = reltime(now, now)
call assert_equal('0.000', split(reltimestr(same))[0][:4])
diff --git a/src/nvim/testdir/test_rename.vim b/src/nvim/testdir/test_rename.vim
index 2311caf790..3887fcfabf 100644
--- a/src/nvim/testdir/test_rename.vim
+++ b/src/nvim/testdir/test_rename.vim
@@ -25,7 +25,7 @@ func Test_rename_file_ignore_case()
set fileignorecase
call writefile(['foo'], 'Xrename')
- call assert_equal(0, rename('Xrename', 'XRENAME'))
+ call assert_equal(0, 'Xrename'->rename('XRENAME'))
call assert_equal(['foo'], readfile('XRENAME'))
diff --git a/src/nvim/testdir/test_search.vim b/src/nvim/testdir/test_search.vim
index 5ba24d047c..7570049e7c 100644
--- a/src/nvim/testdir/test_search.vim
+++ b/src/nvim/testdir/test_search.vim
@@ -1338,7 +1338,7 @@ func Test_search_display_pattern()
call cursor(1, 1)
let @/ = 'foo'
- let pat = escape(@/, '()*?'. '\s\+')
+ let pat = @/->escape('()*?'. '\s\+')
let g:a = execute(':unsilent :norm! n')
call assert_match(pat, g:a)
diff --git a/src/nvim/testdir/test_startup.vim b/src/nvim/testdir/test_startup.vim
index daebe25466..b140077111 100644
--- a/src/nvim/testdir/test_startup.vim
+++ b/src/nvim/testdir/test_startup.vim
@@ -27,8 +27,8 @@ func Test_after_comes_later()
set guioptions+=M
let $HOME = "/does/not/exist"
set loadplugins
- set rtp=Xhere,Xafter,Xanother
- set packpath=Xhere,Xafter
+ set rtp=Xhere,Xdir/after,Xanother
+ set packpath=Xhere,Xdir/after
set nomore
let g:sequence = ""
[CODE]
@@ -50,8 +50,8 @@ func Test_after_comes_later()
call mkdir('Xhere/pack/foo/start/foobar/plugin', 'p')
call writefile(['let g:sequence .= "pack "'], 'Xhere/pack/foo/start/foobar/plugin/foo.vim')
- call mkdir('Xafter/plugin', 'p')
- call writefile(['let g:sequence .= "after "'], 'Xafter/plugin/later.vim')
+ call mkdir('Xdir/after/plugin', 'p')
+ call writefile(['let g:sequence .= "after "'], 'Xdir/after/plugin/later.vim')
if RunVim(before, after, '')
@@ -74,7 +74,7 @@ func Test_after_comes_later()
call delete('Xsequence')
call delete('Xhere', 'rf')
call delete('Xanother', 'rf')
- call delete('Xafter', 'rf')
+ call delete('Xdir', 'rf')
endfunc
func Test_pack_in_rtp_when_plugins_run()
diff --git a/src/nvim/testdir/test_stat.vim b/src/nvim/testdir/test_stat.vim
index 5b7df33d2c..170358e023 100644
--- a/src/nvim/testdir/test_stat.vim
+++ b/src/nvim/testdir/test_stat.vim
@@ -10,7 +10,7 @@ func CheckFileTime(doSleep)
let fl = ['Hello World!']
for fname in fnames
call writefile(fl, fname)
- call add(times, getftime(fname))
+ call add(times, fname->getftime())
if a:doSleep
sleep 1
endif
@@ -19,8 +19,8 @@ func CheckFileTime(doSleep)
let time_correct = (times[0] <= times[1] && times[1] <= times[2])
if a:doSleep || time_correct
call assert_true(time_correct, printf('Expected %s <= %s <= %s', times[0], times[1], times[2]))
- call assert_equal(strlen(fl[0] . "\n"), getfsize(fnames[0]))
- call assert_equal('file', getftype(fnames[0]))
+ call assert_equal(strlen(fl[0] . "\n"), fnames[0]->getfsize())
+ call assert_equal('file', fnames[0]->getftype())
call assert_equal('rw-', getfperm(fnames[0])[0:2])
let result = 1
endif
diff --git a/src/nvim/testdir/test_syn_attr.vim b/src/nvim/testdir/test_syn_attr.vim
index 353054fec8..fa0b08fde5 100644
--- a/src/nvim/testdir/test_syn_attr.vim
+++ b/src/nvim/testdir/test_syn_attr.vim
@@ -8,7 +8,7 @@ func Test_missing_attr()
call assert_equal('1', synIDattr(hlID("Mine"), "inverse", 'cterm'))
hi Mine cterm=standout gui=undercurl
call assert_equal('1', synIDattr(hlID("Mine"), "standout", 'cterm'))
- call assert_equal('1', synIDattr(hlID("Mine"), "undercurl", 'gui'))
+ call assert_equal('1', synIDattr("Mine"->hlID(), "undercurl", 'gui'))
hi Mine gui=strikethrough
call assert_equal('1', synIDattr(hlID("Mine"), "strikethrough", 'gui'))
hi Mine cterm=NONE gui=NONE
diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim
index 0fa7f85f0d..15182893e9 100644
--- a/src/nvim/testdir/test_tagjump.vim
+++ b/src/nvim/testdir/test_tagjump.vim
@@ -316,7 +316,7 @@ func Test_getsettagstack()
enew | only
call settagstack(1, {'items' : []})
call assert_equal(0, gettagstack(1).length)
- call assert_equal([], gettagstack(1).items)
+ call assert_equal([], 1->gettagstack().items)
" Error cases
call assert_equal({}, gettagstack(100))
call assert_equal(-1, settagstack(100, {'items' : []}))
diff --git a/src/nvim/testdir/test_true_false.vim b/src/nvim/testdir/test_true_false.vim
index 315ba188cb..f3c7fff4a6 100644
--- a/src/nvim/testdir/test_true_false.vim
+++ b/src/nvim/testdir/test_true_false.vim
@@ -104,7 +104,7 @@ func Test_true_false_arg()
call Try_arg_true_false('maparg("asdf", "i", %v%)', "", "asdff")
call Try_arg_true_false('FilterMapArg(maparg("asdf", "i", 1, %v%))', "asdff", {'rhs': 'asdff'})
- call Try_arg_true_false('hasmapto("asdf", "i", %v%)', 0, 1)
+ call Try_arg_true_false('"asdf"->hasmapto("i", %v%)', 0, 1)
new colored
call setline(1, '<here>')
diff --git a/src/nvim/testdir/test_utf8.vim b/src/nvim/testdir/test_utf8.vim
index 735efac36d..da72da087f 100644
--- a/src/nvim/testdir/test_utf8.vim
+++ b/src/nvim/testdir/test_utf8.vim
@@ -111,7 +111,7 @@ func Test_list2str_str2list_utf8()
let s = "\u304b\u3099\u3044"
let l = [0x304b, 0x3099, 0x3044]
call assert_equal(l, str2list(s, 1))
- call assert_equal(s, list2str(l, 1))
+ call assert_equal(s, l->list2str(1))
if &enc ==# 'utf-8'
call assert_equal(str2list(s), str2list(s, 1))
call assert_equal(list2str(l), list2str(l, 1))
diff --git a/src/nvim/testdir/test_vimscript.vim b/src/nvim/testdir/test_vimscript.vim
index b18ce563d3..34733f127f 100644
--- a/src/nvim/testdir/test_vimscript.vim
+++ b/src/nvim/testdir/test_vimscript.vim
@@ -635,7 +635,7 @@ function! MSG(enr, emsg)
if v:errmsg == ""
Xout "Message missing."
else
- let v:errmsg = escape(v:errmsg, '"')
+ let v:errmsg = v:errmsg->escape('"')
Xout "Unexpected message:" v:errmsg
endif
endif
diff --git a/src/nvim/tui/input.h b/src/nvim/tui/input.h
index ed76455189..2a8ea32a88 100644
--- a/src/nvim/tui/input.h
+++ b/src/nvim/tui/input.h
@@ -2,8 +2,8 @@
#define NVIM_TUI_INPUT_H
#include <stdbool.h>
-
#include <termkey.h>
+
#include "nvim/event/stream.h"
#include "nvim/event/time.h"
diff --git a/src/nvim/tui/terminfo_defs.h b/src/nvim/tui/terminfo_defs.h
index 8d77dc7225..40261058dc 100644
--- a/src/nvim/tui/terminfo_defs.h
+++ b/src/nvim/tui/terminfo_defs.h
@@ -1,6 +1,8 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+// uncrustify:off
+
//
// Generated by scripts/update_terminfo.sh and ncurses 6.1.20180127
//
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index fb5e12c20e..fcfe862044 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -59,12 +59,12 @@
#define LINUXSET1C "\x1b[?1c"
#ifdef NVIM_UNIBI_HAS_VAR_FROM
-#define UNIBI_SET_NUM_VAR(var, num) \
+# define UNIBI_SET_NUM_VAR(var, num) \
do { \
(var) = unibi_var_from_num((num)); \
} while (0)
#else
-#define UNIBI_SET_NUM_VAR(var, num) (var).i = (num);
+# define UNIBI_SET_NUM_VAR(var, num) (var).i = (num);
#endif
typedef struct {
@@ -178,7 +178,7 @@ UI *tui_start(void)
return ui_bridge_attach(ui, tui_main, tui_scheduler);
}
-static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index, char * buf, size_t len)
+static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index, char *buf, size_t len)
{
const char *str = unibi_get_str(data->ut, unibi_index);
if (!str) {
@@ -1019,22 +1019,8 @@ static void tui_mouse_on(UI *ui)
{
TUIData *data = ui->data;
if (!data->mouse_enabled) {
-#ifdef WIN32
- // Windows versions with vtp(ENABLE_VIRTUAL_TERMINAL_PROCESSING) and
- // no vti(ENABLE_VIRTUAL_TERMINAL_INPUT) will need to use mouse tracking of
- // libuv. For this reason, vtp (vterm) state of libuv is temporarily
- // disabled because the control sequence needs to be processed by libuv
- // instead of Windows vtp.
- // ref. https://docs.microsoft.com/en-us/windows/console/setconsolemode
- flush_buf(ui);
- os_set_vtp(false);
-#endif
unibi_out_ext(ui, data->unibi_ext.enable_mouse);
data->mouse_enabled = true;
-#ifdef WIN32
- flush_buf(ui);
- os_set_vtp(true);
-#endif
}
}
@@ -1042,22 +1028,8 @@ static void tui_mouse_off(UI *ui)
{
TUIData *data = ui->data;
if (data->mouse_enabled) {
-#ifdef WIN32
- // Windows versions with vtp(ENABLE_VIRTUAL_TERMINAL_PROCESSING) and
- // no vti(ENABLE_VIRTUAL_TERMINAL_INPUT) will need to use mouse tracking of
- // libuv. For this reason, vtp (vterm) state of libuv is temporarily
- // disabled because the control sequence needs to be processed by libuv
- // instead of Windows vtp.
- // ref. https://docs.microsoft.com/en-us/windows/console/setconsolemode
- flush_buf(ui);
- os_set_vtp(false);
-#endif
unibi_out_ext(ui, data->unibi_ext.disable_mouse);
data->mouse_enabled = false;
-#ifdef WIN32
- flush_buf(ui);
- os_set_vtp(true);
-#endif
}
}
@@ -1483,7 +1455,7 @@ static void tui_guess_size(UI *ui)
height = unibi_get_num(data->ut, unibi_lines);
width = unibi_get_num(data->ut, unibi_columns);
-end:
+ end:
if (width <= 0 || height <= 0) {
// use the defaults
width = DFLT_COLS;
@@ -1569,7 +1541,7 @@ static int unibi_find_ext_str(unibi_term *ut, const char *name)
{
size_t max = unibi_count_ext_str(ut);
for (size_t i = 0; i < max; i++) {
- const char * n = unibi_get_ext_str_name(ut, i);
+ const char *n = unibi_get_ext_str_name(ut, i);
if (n && 0 == strcmp(n, name)) {
return (int)i;
}
@@ -1581,7 +1553,7 @@ static int unibi_find_ext_bool(unibi_term *ut, const char *name)
{
size_t max = unibi_count_ext_bool(ut);
for (size_t i = 0; i < max; i++) {
- const char * n = unibi_get_ext_bool_name(ut, i);
+ const char *n = unibi_get_ext_bool_name(ut, i);
if (n && 0 == strcmp(n, name)) {
return (int)i;
}
@@ -2111,14 +2083,14 @@ static void flush_buf(UI *ui)
static const char *tui_get_stty_erase(void)
{
static char stty_erase[2] = { 0 };
-#if defined(HAVE_TERMIOS_H)
+# if defined(HAVE_TERMIOS_H)
struct termios t;
if (tcgetattr(input_global_fd(), &t) != -1) {
stty_erase[0] = (char)t.c_cc[VERASE];
stty_erase[1] = '\0';
DLOG("stty/termios:erase=%s", stty_erase);
}
-#endif
+# endif
return stty_erase;
}
diff --git a/src/nvim/types.h b/src/nvim/types.h
index 2dbeecbf6d..604155c33e 100644
--- a/src/nvim/types.h
+++ b/src/nvim/types.h
@@ -1,8 +1,8 @@
#ifndef NVIM_TYPES_H
#define NVIM_TYPES_H
-#include <stdint.h>
#include <stdbool.h>
+#include <stdint.h>
// dummy to pass an ACL to a function
typedef void *vim_acl_T;
diff --git a/src/nvim/ugrid.c b/src/nvim/ugrid.c
index 9e4aaff878..ef84cdf334 100644
--- a/src/nvim/ugrid.c
+++ b/src/nvim/ugrid.c
@@ -2,14 +2,14 @@
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include <assert.h>
+#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
-#include <limits.h>
#include "nvim/assert.h"
-#include "nvim/vim.h"
-#include "nvim/ui.h"
#include "nvim/ugrid.h"
+#include "nvim/ui.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ugrid.c.generated.h"
@@ -79,8 +79,7 @@ void ugrid_scroll(UGrid *grid, int top, int bot, int left, int right, int count)
}
}
-static void clear_region(UGrid *grid, int top, int bot, int left, int right,
- sattr_T attr)
+static void clear_region(UGrid *grid, int top, int bot, int left, int right, sattr_T attr)
{
for (int row = top; row <= bot; row++) {
UGRID_FOREACH_CELL(grid, row, left, right+1, {
diff --git a/src/nvim/ugrid.h b/src/nvim/ugrid.h
index 19c2e99ebb..ae11153c61 100644
--- a/src/nvim/ugrid.h
+++ b/src/nvim/ugrid.h
@@ -1,8 +1,8 @@
#ifndef NVIM_UGRID_H
#define NVIM_UGRID_H
-#include "nvim/ui.h"
#include "nvim/globals.h"
+#include "nvim/ui.h"
typedef struct ucell UCell;
typedef struct ugrid UGrid;
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index 09709d0f43..aad72af025 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -3,40 +3,40 @@
#include <assert.h>
#include <inttypes.h>
+#include <limits.h>
#include <stdbool.h>
#include <string.h>
-#include <limits.h>
-#include "nvim/vim.h"
-#include "nvim/log.h"
+#include "nvim/ascii.h"
#include "nvim/aucmd.h"
-#include "nvim/ui.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/cursor_shape.h"
#include "nvim/diff.h"
+#include "nvim/event/loop.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_getln.h"
#include "nvim/fold.h"
+#include "nvim/garray.h"
+#include "nvim/highlight.h"
+#include "nvim/log.h"
#include "nvim/main.h"
-#include "nvim/ascii.h"
-#include "nvim/misc1.h"
#include "nvim/mbyte.h"
-#include "nvim/garray.h"
#include "nvim/memory.h"
+#include "nvim/misc1.h"
#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/option.h"
-#include "nvim/os_unix.h"
-#include "nvim/event/loop.h"
-#include "nvim/os/time.h"
#include "nvim/os/input.h"
#include "nvim/os/signal.h"
+#include "nvim/os/time.h"
+#include "nvim/os_unix.h"
#include "nvim/popupmnu.h"
#include "nvim/screen.h"
-#include "nvim/highlight.h"
+#include "nvim/ui.h"
#include "nvim/ui_compositor.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/cursor_shape.h"
#ifdef FEAT_TUI
# include "nvim/tui/tui.h"
#else
@@ -70,9 +70,9 @@ static int pending_has_mouse = -1;
static size_t uilog_seen = 0;
static char uilog_last_event[1024] = { 0 };
-#ifndef EXITFREE
-#define entered_free_all_mem false
-#endif
+# ifndef EXITFREE
+# define entered_free_all_mem false
+# endif
# define UI_LOG(funname) \
do { \
@@ -95,7 +95,7 @@ static char uilog_last_event[1024] = { 0 };
// UI_CALL invokes a function on all registered UI instances.
// This is called by code generated by generators/gen_api_ui_events.lua
// C code should use ui_call_{funname} instead.
-# define UI_CALL(cond, funname, ...) \
+#define UI_CALL(cond, funname, ...) \
do { \
bool any_call = false; \
for (size_t i = 0; i < ui_count; i++) { \
@@ -115,7 +115,7 @@ static char uilog_last_event[1024] = { 0 };
#endif
#ifndef EXITFREE
-#undef entered_free_all_mem
+# undef entered_free_all_mem
#endif
void ui_init(void)
@@ -382,8 +382,8 @@ void ui_set_ext_option(UI *ui, UIExtension ext, bool active)
}
}
-void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol,
- int clearattr, bool wrap)
+void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol, int clearattr,
+ bool wrap)
{
assert(0 <= row && row < grid->Rows);
LineFlags flags = wrap ? kLineFlagWrap : 0;
@@ -515,23 +515,23 @@ void ui_check_mouse(void)
// normal editing mode (not at hit-return message).
for (char_u *p = p_mouse; *p; p++) {
switch (*p) {
- case 'a':
- if (vim_strchr((char_u *)MOUSE_A, checkfor) != NULL) {
- has_mouse = true;
- return;
- }
- break;
- case MOUSE_HELP:
- if (checkfor != MOUSE_RETURN && curbuf->b_help) {
- has_mouse = true;
- return;
- }
- break;
- default:
- if (checkfor == *p) {
- has_mouse = true;
- return;
- }
+ case 'a':
+ if (vim_strchr((char_u *)MOUSE_A, checkfor) != NULL) {
+ has_mouse = true;
+ return;
+ }
+ break;
+ case MOUSE_HELP:
+ if (checkfor != MOUSE_RETURN && curbuf->b_help) {
+ has_mouse = true;
+ return;
+ }
+ break;
+ default:
+ if (checkfor == *p) {
+ has_mouse = true;
+ return;
+ }
}
}
}
diff --git a/src/nvim/ui.h b/src/nvim/ui.h
index d00243d35f..7cc0bd9eff 100644
--- a/src/nvim/ui.h
+++ b/src/nvim/ui.h
@@ -1,12 +1,12 @@
#ifndef NVIM_UI_H
#define NVIM_UI_H
-#include <stddef.h>
#include <stdbool.h>
+#include <stddef.h>
#include <stdint.h>
-#include "nvim/globals.h"
#include "nvim/api/private/defs.h"
+#include "nvim/globals.h"
#include "nvim/highlight_defs.h"
typedef enum {
@@ -70,6 +70,7 @@ struct ui_t {
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ui.h.generated.h"
+
# include "ui_events_call.h.generated.h"
#endif
diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c
index 25f45b8fe6..3402df817a 100644
--- a/src/nvim/ui_bridge.c
+++ b/src/nvim/ui_bridge.c
@@ -5,18 +5,18 @@
// Used by the built-in TUI and libnvim-based UIs.
#include <assert.h>
+#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
-#include <limits.h>
+#include "nvim/api/private/helpers.h"
#include "nvim/log.h"
#include "nvim/main.h"
-#include "nvim/vim.h"
-#include "nvim/ui.h"
#include "nvim/memory.h"
-#include "nvim/ui_bridge.h"
#include "nvim/ugrid.h"
-#include "nvim/api/private/helpers.h"
+#include "nvim/ui.h"
+#include "nvim/ui_bridge.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ui_bridge.c.generated.h"
@@ -26,8 +26,7 @@
// Schedule a function call on the UI bridge thread.
#define UI_BRIDGE_CALL(ui, name, argc, ...) \
- ((UIBridgeData *)ui)->scheduler( \
- event_create(ui_bridge_##name##_event, argc, __VA_ARGS__), UI(ui))
+ ((UIBridgeData *)ui)->scheduler(event_create(ui_bridge_##name##_event, argc, __VA_ARGS__), UI(ui))
#define INT2PTR(i) ((void *)(intptr_t)i)
#define PTR2INT(p) ((Integer)(intptr_t)p)
@@ -41,6 +40,8 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)
UIBridgeData *rv = xcalloc(1, sizeof(UIBridgeData));
rv->ui = ui;
rv->bridge.rgb = ui->rgb;
+ rv->bridge.width = ui->width;
+ rv->bridge.height = ui->height;
rv->bridge.stop = ui_bridge_stop;
rv->bridge.grid_resize = ui_bridge_grid_resize;
rv->bridge.grid_clear = ui_bridge_grid_clear;
@@ -136,8 +137,8 @@ static void ui_bridge_stop_event(void **argv)
ui->stop(ui);
}
-static void ui_bridge_hl_attr_define(UI *ui, Integer id, HlAttrs attrs,
- HlAttrs cterm_attrs, Array info)
+static void ui_bridge_hl_attr_define(UI *ui, Integer id, HlAttrs attrs, HlAttrs cterm_attrs,
+ Array info)
{
HlAttrs *a = xmalloc(sizeof(HlAttrs));
*a = attrs;
@@ -161,11 +162,9 @@ static void ui_bridge_raw_line_event(void **argv)
xfree(argv[8]);
xfree(argv[9]);
}
-static void ui_bridge_raw_line(UI *ui, Integer grid, Integer row,
- Integer startcol, Integer endcol,
- Integer clearcol, Integer clearattr,
- LineFlags flags, const schar_T *chunk,
- const sattr_T *attrs)
+static void ui_bridge_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Integer endcol,
+ Integer clearcol, Integer clearattr, LineFlags flags,
+ const schar_T *chunk, const sattr_T *attrs)
{
size_t ncol = (size_t)(endcol-startcol);
schar_T *c = xmemdup(chunk, ncol * sizeof(schar_T));
diff --git a/src/nvim/ui_bridge.h b/src/nvim/ui_bridge.h
index dba461550f..a62ed15621 100644
--- a/src/nvim/ui_bridge.h
+++ b/src/nvim/ui_bridge.h
@@ -5,11 +5,11 @@
#include <uv.h>
-#include "nvim/ui.h"
#include "nvim/event/defs.h"
+#include "nvim/ui.h"
typedef struct ui_bridge_data UIBridgeData;
-typedef void(*ui_main_fn)(UIBridgeData *bridge, UI *ui);
+typedef void (*ui_main_fn)(UIBridgeData *bridge, UI *ui);
struct ui_bridge_data {
UI bridge; // actual UI passed to ui_attach
UI *ui; // UI pointer that will have its callback called in
diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c
index 9c9aec1cf5..d7becb4fd4 100644
--- a/src/nvim/ui_compositor.c
+++ b/src/nvim/ui_compositor.c
@@ -7,27 +7,27 @@
// Layer-based compositing: https://en.wikipedia.org/wiki/Digital_compositing
#include <assert.h>
+#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
-#include <limits.h>
+#include "nvim/api/private/helpers.h"
+#include "nvim/ascii.h"
+#include "nvim/highlight.h"
#include "nvim/lib/kvec.h"
#include "nvim/log.h"
+#include "nvim/lua/executor.h"
#include "nvim/main.h"
-#include "nvim/ascii.h"
-#include "nvim/vim.h"
-#include "nvim/ui.h"
-#include "nvim/highlight.h"
#include "nvim/memory.h"
#include "nvim/message.h"
+#include "nvim/os/os.h"
#include "nvim/popupmnu.h"
-#include "nvim/ui_compositor.h"
-#include "nvim/ugrid.h"
#include "nvim/screen.h"
#include "nvim/syntax.h"
-#include "nvim/api/private/helpers.h"
-#include "nvim/lua/executor.h"
-#include "nvim/os/os.h"
+#include "nvim/ugrid.h"
+#include "nvim/ui.h"
+#include "nvim/ui_compositor.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ui_compositor.c.generated.h"
@@ -89,10 +89,10 @@ void ui_comp_init(void)
void ui_comp_syn_init(void)
{
- dbghl_normal = syn_check_group((char_u *)S_LEN("RedrawDebugNormal"));
- dbghl_clear = syn_check_group((char_u *)S_LEN("RedrawDebugClear"));
- dbghl_composed = syn_check_group((char_u *)S_LEN("RedrawDebugComposed"));
- dbghl_recompose = syn_check_group((char_u *)S_LEN("RedrawDebugRecompose"));
+ dbghl_normal = syn_check_group(S_LEN("RedrawDebugNormal"));
+ dbghl_clear = syn_check_group(S_LEN("RedrawDebugClear"));
+ dbghl_composed = syn_check_group(S_LEN("RedrawDebugComposed"));
+ dbghl_recompose = syn_check_group(S_LEN("RedrawDebugRecompose"));
}
void ui_comp_attach(UI *ui)
@@ -123,8 +123,8 @@ bool ui_comp_should_draw(void)
/// TODO(bfredl): later on the compositor should just use win_float_pos events,
/// though that will require slight event order adjustment: emit the win_pos
/// events in the beginning of update_screen(0), rather than in ui_flush()
-bool ui_comp_put_grid(ScreenGrid *grid, int row, int col, int height, int width,
- bool valid, bool on_top)
+bool ui_comp_put_grid(ScreenGrid *grid, int row, int col, int height, int width, bool valid,
+ bool on_top)
{
bool moved;
@@ -257,8 +257,7 @@ static void ui_comp_raise_grid(ScreenGrid *grid, size_t new_index)
}
}
-static void ui_comp_grid_cursor_goto(UI *ui, Integer grid_handle,
- Integer r, Integer c)
+static void ui_comp_grid_cursor_goto(UI *ui, Integer grid_handle, Integer r, Integer c)
{
if (!ui_comp_should_draw() || !ui_comp_set_grid((int)grid_handle)) {
return;
@@ -304,8 +303,7 @@ ScreenGrid *ui_comp_mouse_focus(int row, int col)
/// Baseline implementation. This is always correct, but we can sometimes
/// do something more efficient (where efficiency means smaller deltas to
/// the downstream UI.)
-static void compose_line(Integer row, Integer startcol, Integer endcol,
- LineFlags flags)
+static void compose_line(Integer row, Integer startcol, Integer endcol, LineFlags flags)
{
// If rightleft is set, startcol may be -1. In such cases, the assertions
// will fail because no overlap is found. Adjust startcol to prevent it.
@@ -447,8 +445,8 @@ static void compose_line(Integer row, Integer startcol, Integer endcol,
(const sattr_T *)attrbuf+skipstart);
}
-static void compose_debug(Integer startrow, Integer endrow, Integer startcol,
- Integer endcol, int syn_id, bool delay)
+static void compose_debug(Integer startrow, Integer endrow, Integer startcol, Integer endcol,
+ int syn_id, bool delay)
{
if (!(rdb_flags & RDB_COMPOSITOR)) {
return;
@@ -479,8 +477,7 @@ static void debug_delay(Integer lines)
}
-static void compose_area(Integer startrow, Integer endrow,
- Integer startcol, Integer endcol)
+static void compose_area(Integer startrow, Integer endrow, Integer startcol, Integer endcol)
{
compose_debug(startrow, endrow, startcol, endcol, dbghl_recompose, true);
endrow = MIN(endrow, default_grid.Rows);
@@ -505,11 +502,9 @@ void ui_comp_compose_grid(ScreenGrid *grid)
}
}
-static void ui_comp_raw_line(UI *ui, Integer grid, Integer row,
- Integer startcol, Integer endcol,
- Integer clearcol, Integer clearattr,
- LineFlags flags, const schar_T *chunk,
- const sattr_T *attrs)
+static void ui_comp_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Integer endcol,
+ Integer clearcol, Integer clearattr, LineFlags flags,
+ const schar_T *chunk, const sattr_T *attrs)
{
if (!ui_comp_should_draw() || !ui_comp_set_grid((int)grid)) {
return;
@@ -529,11 +524,11 @@ static void ui_comp_raw_line(UI *ui, Integer grid, Integer row,
// when resizing nvim, a window will be attempted to be drawn on the older
// and possibly larger global screen size.
if (row >= default_grid.Rows) {
- DLOG("compositor: invalid row %"PRId64" on grid %"PRId64, row, grid);
+ DLOG("compositor: invalid row %" PRId64 " on grid %" PRId64, row, grid);
return;
}
if (clearcol > default_grid.Columns) {
- DLOG("compositor: invalid last column %"PRId64" on grid %"PRId64,
+ DLOG("compositor: invalid last column %" PRId64 " on grid %" PRId64,
clearcol, grid);
if (startcol >= default_grid.Columns) {
return;
@@ -572,8 +567,8 @@ void ui_comp_set_screen_valid(bool valid)
}
}
-static void ui_comp_msg_set_pos(UI *ui, Integer grid, Integer row,
- Boolean scrolled, String sep_char)
+static void ui_comp_msg_set_pos(UI *ui, Integer grid, Integer row, Boolean scrolled,
+ String sep_char)
{
msg_grid.comp_row = (int)row;
if (scrolled && row > 0) {
@@ -617,9 +612,8 @@ static bool curgrid_covered_above(int row)
return kv_size(layers)-(above_msg?1:0) > curgrid->comp_index+1;
}
-static void ui_comp_grid_scroll(UI *ui, Integer grid, Integer top,
- Integer bot, Integer left, Integer right,
- Integer rows, Integer cols)
+static void ui_comp_grid_scroll(UI *ui, Integer grid, Integer top, Integer bot, Integer left,
+ Integer right, Integer rows, Integer cols)
{
if (!ui_comp_should_draw() || !ui_comp_set_grid((int)grid)) {
return;
@@ -653,8 +647,7 @@ static void ui_comp_grid_scroll(UI *ui, Integer grid, Integer top,
}
}
-static void ui_comp_grid_resize(UI *ui, Integer grid,
- Integer width, Integer height)
+static void ui_comp_grid_resize(UI *ui, Integer grid, Integer width, Integer height)
{
if (grid == 1) {
ui_composed_call_grid_resize(1, width, height);
diff --git a/src/nvim/ui_compositor.h b/src/nvim/ui_compositor.h
index 70e01c3a21..01538105cb 100644
--- a/src/nvim/ui_compositor.h
+++ b/src/nvim/ui_compositor.h
@@ -1,8 +1,8 @@
#ifndef NVIM_UI_COMPOSITOR_H
#define NVIM_UI_COMPOSITOR_H
-#include "nvim/ui.h"
#include "nvim/event/defs.h"
+#include "nvim/ui.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ui_compositor.h.generated.h"
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index fb96d7e6ff..5261f9e2ec 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -69,54 +69,53 @@
* All data is allocated and will all be freed when the buffer is unloaded.
*/
-/* Uncomment the next line for including the u_check() function. This warns
- * for errors in the debug information. */
-/* #define U_DEBUG 1 */
-#define UH_MAGIC 0x18dade /* value for uh_magic when in use */
-#define UE_MAGIC 0xabc123 /* value for ue_magic when in use */
+// Uncomment the next line for including the u_check() function. This warns
+// for errors in the debug information.
+// #define U_DEBUG 1
+#define UH_MAGIC 0x18dade // value for uh_magic when in use
+#define UE_MAGIC 0xabc123 // value for ue_magic when in use
#include <assert.h>
+#include <fcntl.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
#include <string.h>
-#include <fcntl.h>
#include "auto/config.h"
-
-#include "nvim/buffer.h"
#include "nvim/ascii.h"
+#include "nvim/buffer.h"
+#include "nvim/buffer_updates.h"
#include "nvim/change.h"
-#include "nvim/undo.h"
#include "nvim/cursor.h"
#include "nvim/edit.h"
+#include "nvim/extmark.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
-#include "nvim/buffer_updates.h"
-#include "nvim/pos.h" // MAXLNUM
+#include "nvim/garray.h"
+#include "nvim/lib/kvec.h"
#include "nvim/mark.h"
-#include "nvim/extmark.h"
#include "nvim/memline.h"
+#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/memory.h"
-#include "nvim/garray.h"
#include "nvim/option.h"
+#include "nvim/os/os.h"
+#include "nvim/os/time.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
+#include "nvim/pos.h" // MAXLNUM
#include "nvim/sha256.h"
#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/types.h"
-#include "nvim/os/os.h"
-#include "nvim/os/time.h"
-#include "nvim/lib/kvec.h"
+#include "nvim/undo.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "undo.c.generated.h"
#endif
-/* used in undo_end() to report number of added and deleted lines */
+// used in undo_end() to report number of added and deleted lines
static long u_newcount, u_oldcount;
/*
@@ -136,13 +135,12 @@ static int seen_b_u_curhead;
static int seen_b_u_newhead;
static int header_count;
-static void u_check_tree(u_header_T *uhp,
- u_header_T *exp_uh_next,
- u_header_T *exp_uh_alt_prev) {
+static void u_check_tree(u_header_T *uhp, u_header_T *exp_uh_next, u_header_T *exp_uh_alt_prev) {
u_entry_T *uep;
- if (uhp == NULL)
+ if (uhp == NULL) {
return;
+ }
++header_count;
if (uhp == curbuf->b_u_curhead && ++seen_b_u_curhead > 1) {
EMSG("b_u_curhead found twice (looping?)");
@@ -153,22 +151,22 @@ static void u_check_tree(u_header_T *uhp,
return;
}
- if (uhp->uh_magic != UH_MAGIC)
+ if (uhp->uh_magic != UH_MAGIC) {
EMSG("uh_magic wrong (may be using freed memory)");
- else {
- /* Check pointers back are correct. */
+ } else {
+ // Check pointers back are correct.
if (uhp->uh_next.ptr != exp_uh_next) {
EMSG("uh_next wrong");
smsg("expected: 0x%x, actual: 0x%x",
- exp_uh_next, uhp->uh_next.ptr);
+ exp_uh_next, uhp->uh_next.ptr);
}
if (uhp->uh_alt_prev.ptr != exp_uh_alt_prev) {
EMSG("uh_alt_prev wrong");
smsg("expected: 0x%x, actual: 0x%x",
- exp_uh_alt_prev, uhp->uh_alt_prev.ptr);
+ exp_uh_alt_prev, uhp->uh_alt_prev.ptr);
}
- /* Check the undo tree at this header. */
+ // Check the undo tree at this header.
for (uep = uhp->uh_entry; uep != NULL; uep = uep->ue_next) {
if (uep->ue_magic != UE_MAGIC) {
EMSG("ue_magic wrong (may be using freed memory)");
@@ -176,10 +174,10 @@ static void u_check_tree(u_header_T *uhp,
}
}
- /* Check the next alt tree. */
+ // Check the next alt tree.
u_check_tree(uhp->uh_alt_next.ptr, uhp->uh_next.ptr, uhp);
- /* Check the next header in this branch. */
+ // Check the next header in this branch.
u_check_tree(uhp->uh_prev.ptr, uhp, NULL);
}
}
@@ -192,14 +190,16 @@ static void u_check(int newhead_may_be_NULL) {
u_check_tree(curbuf->b_u_oldhead, NULL, NULL);
if (seen_b_u_newhead == 0 && curbuf->b_u_oldhead != NULL
- && !(newhead_may_be_NULL && curbuf->b_u_newhead == NULL))
+ && !(newhead_may_be_NULL && curbuf->b_u_newhead == NULL)) {
EMSGN("b_u_newhead invalid: 0x%x", curbuf->b_u_newhead);
- if (curbuf->b_u_curhead != NULL && seen_b_u_curhead == 0)
+ }
+ if (curbuf->b_u_curhead != NULL && seen_b_u_curhead == 0) {
EMSGN("b_u_curhead invalid: 0x%x", curbuf->b_u_curhead);
+ }
if (header_count != curbuf->b_u_numhead) {
EMSG("b_u_numhead invalid");
smsg("expected: %" PRId64 ", actual: %" PRId64,
- (int64_t)header_count, (int64_t)curbuf->b_u_numhead);
+ (int64_t)header_count, (int64_t)curbuf->b_u_numhead);
}
}
@@ -228,11 +228,12 @@ int u_save_cursor(void)
int u_save(linenr_T top, linenr_T bot)
{
if (top >= bot || bot > (curbuf->b_ml.ml_line_count + 1)) {
- return FAIL; /* rely on caller to do error messages */
+ return FAIL; // rely on caller to do error messages
}
- if (top + 2 == bot)
+ if (top + 2 == bot) {
u_saveline((linenr_T)(top + 1));
+ }
return u_savecommon(curbuf, top, bot, (linenr_T)0, false);
}
@@ -268,9 +269,8 @@ int u_inssub(linenr_T lnum)
*/
int u_savedel(linenr_T lnum, long nlines)
{
- return u_savecommon(
- curbuf, lnum - 1, lnum + nlines,
- nlines == curbuf->b_ml.ml_line_count ? 2 : lnum, false);
+ return u_savecommon(curbuf, lnum - 1, lnum + nlines,
+ nlines == curbuf->b_ml.ml_line_count ? 2 : lnum, false);
}
/// Return true when undo is allowed. Otherwise print an error message and
@@ -291,8 +291,8 @@ bool undo_allowed(buf_T *buf)
return false;
}
- /* Don't allow changes in the buffer while editing the cmdline. The
- * caller of getcmdline() may get confused. */
+ // Don't allow changes in the buffer while editing the cmdline. The
+ // caller of getcmdline() may get confused.
if (textlock != 0) {
EMSG(_(e_secure));
return false;
@@ -327,16 +327,14 @@ static inline void zero_fmark_additional_data(fmark_T *fmarks)
* Careful: may trigger autocommands that reload the buffer.
* Returns FAIL when lines could not be saved, OK otherwise.
*/
-int u_savecommon(buf_T *buf,
- linenr_T top, linenr_T bot,
- linenr_T newbot, int reload)
+int u_savecommon(buf_T *buf, linenr_T top, linenr_T bot, linenr_T newbot, int reload)
{
linenr_T lnum;
long i;
- u_header_T *uhp;
- u_header_T *old_curhead;
- u_entry_T *uep;
- u_entry_T *prev_uep;
+ u_header_T *uhp;
+ u_header_T *old_curhead;
+ u_entry_T *uep;
+ u_entry_T *prev_uep;
long size;
if (!reload) {
@@ -381,8 +379,9 @@ int u_savecommon(buf_T *buf,
#ifdef U_DEBUG
uhp->uh_magic = UH_MAGIC;
#endif
- } else
+ } else {
uhp = NULL;
+ }
/*
* If we undid more than we redid, move the entry lists before and
@@ -399,7 +398,7 @@ int u_savecommon(buf_T *buf,
*/
while (buf->b_u_numhead > get_undolevel(buf)
&& buf->b_u_oldhead != NULL) {
- u_header_T *uhfree = buf->b_u_oldhead;
+ u_header_T *uhfree = buf->b_u_oldhead;
if (uhfree == old_curhead) {
// Can't reconnect the branch, delete all of it.
@@ -459,11 +458,12 @@ int u_savecommon(buf_T *buf,
uhp->uh_walk = 0;
uhp->uh_entry = NULL;
uhp->uh_getbot_entry = NULL;
- uhp->uh_cursor = curwin->w_cursor; /* save cursor pos. for undo */
- if (virtual_active() && curwin->w_cursor.coladd > 0)
+ uhp->uh_cursor = curwin->w_cursor; // save cursor pos. for undo
+ if (virtual_active() && curwin->w_cursor.coladd > 0) {
uhp->uh_cursor_vcol = getviscol();
- else
+ } else {
uhp->uh_cursor_vcol = -1;
+ }
// save changed and buffer empty flag for undo
uhp->uh_flags = (buf->b_changed ? UH_CHANGED : 0) +
@@ -499,8 +499,9 @@ int u_savecommon(buf_T *buf,
uep = u_get_headentry(buf);
prev_uep = NULL;
for (i = 0; i < 10; ++i) {
- if (uep == NULL)
+ if (uep == NULL) {
break;
+ }
/* If lines have been inserted/deleted we give up.
* Also when the line was included in a multi-line save. */
@@ -509,14 +510,14 @@ int u_savecommon(buf_T *buf,
!= (uep->ue_bot == 0
? buf->b_ml.ml_line_count + 1
: uep->ue_bot))
- : uep->ue_lcount != buf->b_ml.ml_line_count)
+ : uep->ue_lcount != buf->b_ml.ml_line_count)
|| (uep->ue_size > 1
&& top >= uep->ue_top
&& top + 2 <= uep->ue_top + uep->ue_size + 1)) {
break;
}
- /* If it's the same line we can skip saving it again. */
+ // If it's the same line we can skip saving it again.
if (uep->ue_size == 1 && uep->ue_top == top) {
if (i > 0) {
/* It's not the last entry: get ue_bot for the last
@@ -609,25 +610,25 @@ int u_savecommon(buf_T *buf,
// magic at start of undofile
-# define UF_START_MAGIC "Vim\237UnDo\345"
-# define UF_START_MAGIC_LEN 9
+#define UF_START_MAGIC "Vim\237UnDo\345"
+#define UF_START_MAGIC_LEN 9
// magic at start of header
-# define UF_HEADER_MAGIC 0x5fd0
+#define UF_HEADER_MAGIC 0x5fd0
// magic after last header
-# define UF_HEADER_END_MAGIC 0xe7aa
+#define UF_HEADER_END_MAGIC 0xe7aa
// magic at start of entry
-# define UF_ENTRY_MAGIC 0xf518
+#define UF_ENTRY_MAGIC 0xf518
// magic after last entry
-# define UF_ENTRY_END_MAGIC 0x3581
+#define UF_ENTRY_END_MAGIC 0x3581
// 2-byte undofile version number
-# define UF_VERSION 3
+#define UF_VERSION 3
-/* extra fields for header */
-# define UF_LAST_SAVE_NR 1
+// extra fields for header
+#define UF_LAST_SAVE_NR 1
-/* extra fields for uhp */
-# define UHP_SAVE_NR 1
+// extra fields for uhp
+#define UHP_SAVE_NR 1
static char_u e_not_open[] = N_("E828: Cannot open undo file for writing: %s");
@@ -640,7 +641,7 @@ void u_compute_hash(buf_T *buf, char_u *hash)
{
context_sha256_T ctx;
linenr_T lnum;
- char_u *p;
+ char_u *p;
sha256_start(&ctx);
for (lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++) {
@@ -688,7 +689,7 @@ char *u_get_undo_file_name(const char *const buf_ffname, const bool reading)
// Loop over 'undodir'. When reading find the first file that exists.
// When not reading use the first directory that exists or ".".
- dirp = (char *) p_udir;
+ dirp = (char *)p_udir;
while (*dirp != NUL) {
size_t dir_len = copy_option_part((char_u **)&dirp, (char_u *)dir_name,
MAXPATHL, ",");
@@ -698,7 +699,7 @@ char *u_get_undo_file_name(const char *const buf_ffname, const bool reading)
const size_t ffname_len = strlen(ffname);
undo_file_name = xmalloc(ffname_len + 6);
memmove(undo_file_name, ffname, ffname_len + 1);
- char *const tail = (char *) path_tail((char_u *) undo_file_name);
+ char *const tail = (char *)path_tail((char_u *)undo_file_name);
const size_t tail_len = strlen(tail);
memmove(tail + 1, tail, tail_len + 1);
*tail = '.';
@@ -754,8 +755,7 @@ char *u_get_undo_file_name(const char *const buf_ffname, const bool reading)
///
/// @param[in] mesg Identifier of the corruption kind.
/// @param[in] file_name File in which error occurred.
-static void corruption_error(const char *const mesg,
- const char *const file_name)
+static void corruption_error(const char *const mesg, const char *const file_name)
FUNC_ATTR_NONNULL_ALL
{
EMSG3(_("E825: Corrupted undo file (%s): %s"), mesg, file_name);
@@ -763,8 +763,8 @@ static void corruption_error(const char *const mesg,
static void u_free_uhp(u_header_T *uhp)
{
- u_entry_T *nuep;
- u_entry_T *uep;
+ u_entry_T *nuep;
+ u_entry_T *uep;
uep = uhp->uh_entry;
while (uep != NULL) {
@@ -890,8 +890,7 @@ static bool serialize_uhp(bufinfo_T *bi, u_header_T *uhp)
return true;
}
-static u_header_T *unserialize_uhp(bufinfo_T *bi,
- const char *file_name)
+static u_header_T *unserialize_uhp(bufinfo_T *bi, const char *file_name)
{
u_header_T *uhp = xmalloc(sizeof(u_header_T));
memset(uhp, 0, sizeof(u_header_T));
@@ -999,7 +998,7 @@ static bool serialize_extmark(bufinfo_T *bi, ExtmarkUndoObject extup)
undo_write_bytes(bi, (uintmax_t)extup.type, 4);
if (!undo_write(bi, (uint8_t *)&(extup.data.splice),
sizeof(ExtmarkSplice))) {
- return false;
+ return false;
}
} else if (extup.type == kExtmarkMove) {
undo_write_bytes(bi, (uintmax_t)UF_ENTRY_MAGIC, 2);
@@ -1013,8 +1012,7 @@ static bool serialize_extmark(bufinfo_T *bi, ExtmarkUndoObject extup)
return true;
}
-static ExtmarkUndoObject *unserialize_extmark(bufinfo_T *bi, bool *error,
- const char *filename)
+static ExtmarkUndoObject *unserialize_extmark(bufinfo_T *bi, bool *error, const char *filename)
{
UndoObjectType type;
uint8_t *buf = NULL;
@@ -1039,7 +1037,7 @@ static ExtmarkUndoObject *unserialize_extmark(bufinfo_T *bi, bool *error,
}
extup->data.move = *(ExtmarkMove *)buf;
} else {
- goto error;
+ goto error;
}
xfree(buf);
@@ -1080,8 +1078,7 @@ static bool serialize_uep(bufinfo_T *bi, u_entry_T *uep)
return true;
}
-static u_entry_T *unserialize_uep(bufinfo_T * bi, bool *error,
- const char *file_name)
+static u_entry_T *unserialize_uep(bufinfo_T *bi, bool *error, const char *file_name)
{
u_entry_T *uep = xmalloc(sizeof(u_entry_T));
memset(uep, 0, sizeof(u_entry_T));
@@ -1171,24 +1168,23 @@ static void unserialize_visualinfo(bufinfo_T *bi, visualinfo_T *info)
/// @param[in] buf Buffer for which undo file is written.
/// @param[in] hash Hash value of the buffer text. Must have #UNDO_HASH_SIZE
/// size.
-void u_write_undo(const char *const name, const bool forceit, buf_T *const buf,
- char_u *const hash)
+void u_write_undo(const char *const name, const bool forceit, buf_T *const buf, char_u *const hash)
FUNC_ATTR_NONNULL_ARG(3, 4)
{
- u_header_T *uhp;
+ u_header_T *uhp;
char *file_name;
int mark;
#ifdef U_DEBUG
int headers_written = 0;
#endif
int fd;
- FILE *fp = NULL;
+ FILE *fp = NULL;
int perm;
bool write_ok = false;
bufinfo_T bi;
if (name == NULL) {
- file_name = u_get_undo_file_name((char *) buf->b_ffname, false);
+ file_name = u_get_undo_file_name((char *)buf->b_ffname, false);
if (file_name == NULL) {
if (p_verbose > 0) {
verbose_enter();
@@ -1198,7 +1194,7 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf,
return;
}
} else {
- file_name = (char *) name;
+ file_name = (char *)name;
}
/*
@@ -1221,16 +1217,18 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf,
* file, and delete it. */
if (os_path_exists((char_u *)file_name)) {
if (name == NULL || !forceit) {
- /* Check we can read it and it's an undo file. */
+ // Check we can read it and it's an undo file.
fd = os_open(file_name, O_RDONLY, 0);
if (fd < 0) {
if (name != NULL || p_verbose > 0) {
- if (name == NULL)
+ if (name == NULL) {
verbose_enter();
+ }
smsg(_("Will not overwrite with undo file, cannot read: %s"),
file_name);
- if (name == NULL)
+ if (name == NULL) {
verbose_leave();
+ }
}
goto theend;
} else {
@@ -1240,12 +1238,14 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf,
if (len < UF_START_MAGIC_LEN
|| memcmp(mbuf, UF_START_MAGIC, UF_START_MAGIC_LEN) != 0) {
if (name != NULL || p_verbose > 0) {
- if (name == NULL)
+ if (name == NULL) {
verbose_enter();
+ }
smsg(_("Will not overwrite, this is not an undo file: %s"),
file_name);
- if (name == NULL)
+ if (name == NULL) {
verbose_leave();
+ }
}
goto theend;
}
@@ -1276,7 +1276,7 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf,
}
#ifdef U_DEBUG
- /* Check there is no problem in undo info before writing. */
+ // Check there is no problem in undo info before writing.
u_check(FALSE);
#endif
@@ -1323,7 +1323,7 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf,
mark = ++lastmark;
uhp = buf->b_u_oldhead;
while (uhp != NULL) {
- /* Serialize current UHP if we haven't seen it */
+ // Serialize current UHP if we haven't seen it
if (uhp->uh_walk != mark) {
uhp->uh_walk = mark;
#ifdef U_DEBUG
@@ -1334,19 +1334,20 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf,
}
}
- /* Now walk through the tree - algorithm from undo_time(). */
- if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != mark)
+ // Now walk through the tree - algorithm from undo_time().
+ if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != mark) {
uhp = uhp->uh_prev.ptr;
- else if (uhp->uh_alt_next.ptr != NULL
- && uhp->uh_alt_next.ptr->uh_walk != mark)
+ } else if (uhp->uh_alt_next.ptr != NULL
+ && uhp->uh_alt_next.ptr->uh_walk != mark) {
uhp = uhp->uh_alt_next.ptr;
- else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL
- && uhp->uh_next.ptr->uh_walk != mark)
+ } else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL
+ && uhp->uh_next.ptr->uh_walk != mark) {
uhp = uhp->uh_next.ptr;
- else if (uhp->uh_alt_prev.ptr != NULL)
+ } else if (uhp->uh_alt_prev.ptr != NULL) {
uhp = uhp->uh_alt_prev.ptr;
- else
+ } else {
uhp = uhp->uh_next.ptr;
+ }
}
if (undo_write_bytes(&bi, (uintmax_t)UF_HEADER_END_MAGIC, 2)) {
@@ -1361,14 +1362,15 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf,
write_error:
fclose(fp);
- if (!write_ok)
+ if (!write_ok) {
EMSG2(_("E829: write error in undo file: %s"), file_name);
+ }
#ifdef HAVE_ACL
if (buf->b_ffname != NULL) {
vim_acl_T acl;
- /* For systems that support ACL: get the ACL from the original file. */
+ // For systems that support ACL: get the ACL from the original file.
acl = mch_get_acl(buf->b_ffname);
mch_set_acl((char_u *)file_name, acl);
mch_free_acl(acl);
@@ -1376,8 +1378,9 @@ write_error:
#endif
theend:
- if (file_name != name)
+ if (file_name != name) {
xfree(file_name);
+ }
}
/// Loads the undo tree from an undo file.
@@ -1385,8 +1388,7 @@ theend:
/// a bit more verbose.
/// Otherwise use curbuf->b_ffname to generate the undo file name.
/// "hash[UNDO_HASH_SIZE]" must be the hash value of the buffer text.
-void u_read_undo(char *name, const char_u *hash,
- const char_u *orig_name FUNC_ATTR_UNUSED)
+void u_read_undo(char *name, const char_u *hash, const char_u *orig_name FUNC_ATTR_UNUSED)
FUNC_ATTR_NONNULL_ARG(2)
{
u_header_T **uhp_table = NULL;
@@ -1394,7 +1396,7 @@ void u_read_undo(char *name, const char_u *hash,
char *file_name;
if (name == NULL) {
- file_name = u_get_undo_file_name((char *) curbuf->b_ffname, true);
+ file_name = u_get_undo_file_name((char *)curbuf->b_ffname, true);
if (file_name == NULL) {
return;
}
@@ -1405,7 +1407,7 @@ void u_read_undo(char *name, const char_u *hash,
FileInfo file_info_orig;
FileInfo file_info_undo;
if (os_fileinfo((const char *)orig_name, &file_info_orig)
- && os_fileinfo((char *)file_name, &file_info_undo)
+ && os_fileinfo(file_name, &file_info_undo)
&& file_info_orig.stat.st_uid != file_info_undo.stat.st_uid
&& file_info_undo.stat.st_uid != getuid()) {
if (p_verbose > 0) {
@@ -1418,7 +1420,7 @@ void u_read_undo(char *name, const char_u *hash,
}
#endif
} else {
- file_name = (char *) name;
+ file_name = name;
}
if (p_verbose > 0) {
@@ -1465,7 +1467,7 @@ void u_read_undo(char *name, const char_u *hash,
verbose_enter();
}
give_warning((char_u *)
- _("File contents changed, cannot use undo info"), true);
+ _("File contents changed, cannot use undo info"), true);
if (name == NULL) {
verbose_leave();
}
@@ -1508,15 +1510,15 @@ void u_read_undo(char *name, const char_u *hash,
}
int what = undo_read_byte(&bi);
switch (what) {
- case UF_LAST_SAVE_NR:
- last_save_nr = undo_read_4c(&bi);
- break;
+ case UF_LAST_SAVE_NR:
+ last_save_nr = undo_read_4c(&bi);
+ break;
- default:
- // field not supported, skip
- while (--len >= 0) {
- (void)undo_read_byte(&bi);
- }
+ default:
+ // field not supported, skip
+ while (--len >= 0) {
+ (void)undo_read_byte(&bi);
+ }
}
}
@@ -1559,7 +1561,7 @@ void u_read_undo(char *name, const char_u *hash,
size_t amount = num_head * sizeof(int) + 1;
int *uhp_table_used = xmalloc(amount);
memset(uhp_table_used, 0, amount);
-# define SET_FLAG(j) ++ uhp_table_used[j]
+# define SET_FLAG(j) ++uhp_table_used[j]
#else
# define SET_FLAG(j)
#endif
@@ -1666,10 +1668,11 @@ void u_read_undo(char *name, const char_u *hash,
error:
xfree(line_ptr);
if (uhp_table != NULL) {
- for (long i = 0; i < num_read_uhps; i++)
+ for (long i = 0; i < num_read_uhps; i++) {
if (uhp_table[i] != NULL) {
u_free_uhp(uhp_table[i]);
}
+ }
xfree(uhp_table);
}
@@ -1844,7 +1847,7 @@ bool u_undo_and_forget(int count)
to_forget->uh_alt_next.ptr = NULL;
curbuf->b_u_curhead->uh_alt_prev.ptr = to_forget->uh_alt_prev.ptr;
curbuf->b_u_seq_cur = curbuf->b_u_curhead->uh_next.ptr ?
- curbuf->b_u_curhead->uh_next.ptr->uh_seq : 0;
+ curbuf->b_u_curhead->uh_next.ptr->uh_seq : 0;
} else if (curbuf->b_u_newhead) {
curbuf->b_u_seq_cur = curbuf->b_u_newhead->uh_seq;
}
@@ -1876,8 +1879,9 @@ static void u_doit(int startcount, bool quiet, bool do_buf_event)
u_newcount = 0;
u_oldcount = 0;
- if (curbuf->b_ml.ml_flags & ML_EMPTY)
+ if (curbuf->b_ml.ml_flags & ML_EMPTY) {
u_oldcount = -1;
+ }
while (count--) {
/* Do the change warning now, so that it triggers FileChangedRO when
* needed. This may cause the file to be reloaded, that must happen
@@ -1894,7 +1898,7 @@ static void u_doit(int startcount, bool quiet, bool do_buf_event)
}
// nothing to undo
if (curbuf->b_u_numhead == 0 || curbuf->b_u_curhead == NULL) {
- /* stick curbuf->b_u_curhead at end */
+ // stick curbuf->b_u_curhead at end
curbuf->b_u_curhead = curbuf->b_u_oldhead;
beep_flush();
if (count == startcount - 1) {
@@ -1917,10 +1921,11 @@ static void u_doit(int startcount, bool quiet, bool do_buf_event)
u_undoredo(false, do_buf_event);
- /* Advance for next redo. Set "newhead" when at the end of the
- * redoable changes. */
- if (curbuf->b_u_curhead->uh_prev.ptr == NULL)
+ // Advance for next redo. Set "newhead" when at the end of the
+ // redoable changes.
+ if (curbuf->b_u_curhead->uh_prev.ptr == NULL) {
curbuf->b_u_newhead = curbuf->b_u_curhead;
+ }
curbuf->b_u_curhead = curbuf->b_u_curhead->uh_prev.ptr;
}
}
@@ -1941,8 +1946,8 @@ void undo_time(long step, bool sec, bool file, bool absolute)
long closest_start;
long closest_seq = 0;
long val;
- u_header_T *uhp = NULL;
- u_header_T *last;
+ u_header_T *uhp = NULL;
+ u_header_T *last;
int mark;
int nomark = 0; // shut up compiler
int round;
@@ -1958,11 +1963,12 @@ void undo_time(long step, bool sec, bool file, bool absolute)
u_newcount = 0;
u_oldcount = 0;
- if (curbuf->b_ml.ml_flags & ML_EMPTY)
+ if (curbuf->b_ml.ml_flags & ML_EMPTY) {
u_oldcount = -1;
+ }
- /* "target" is the node below which we want to be.
- * Init "closest" to a value we can't reach. */
+ // "target" is the node below which we want to be.
+ // Init "closest" to a value we can't reach.
if (absolute) {
target = step;
closest = -1;
@@ -1971,40 +1977,45 @@ void undo_time(long step, bool sec, bool file, bool absolute)
target = (long)(curbuf->b_u_time_cur) + step;
} else if (dofile) {
if (step < 0) {
- /* Going back to a previous write. If there were changes after
- * the last write, count that as moving one file-write, so
- * that ":earlier 1f" undoes all changes since the last save. */
+ // Going back to a previous write. If there were changes after
+ // the last write, count that as moving one file-write, so
+ // that ":earlier 1f" undoes all changes since the last save.
uhp = curbuf->b_u_curhead;
- if (uhp != NULL)
+ if (uhp != NULL) {
uhp = uhp->uh_next.ptr;
- else
+ } else {
uhp = curbuf->b_u_newhead;
- if (uhp != NULL && uhp->uh_save_nr != 0)
+ }
+ if (uhp != NULL && uhp->uh_save_nr != 0) {
/* "uh_save_nr" was set in the last block, that means
* there were no changes since the last write */
target = curbuf->b_u_save_nr_cur + step;
- else
- /* count the changes since the last write as one step */
+ } else {
+ // count the changes since the last write as one step
target = curbuf->b_u_save_nr_cur + step + 1;
- if (target <= 0)
+ }
+ if (target <= 0) {
/* Go to before first write: before the oldest change. Use
* the sequence number for that. */
dofile = false;
+ }
} else {
- /* Moving forward to a newer write. */
+ // Moving forward to a newer write.
target = curbuf->b_u_save_nr_cur + step;
if (target > curbuf->b_u_save_nr_last) {
- /* Go to after last write: after the latest change. Use
- * the sequence number for that. */
+ // Go to after last write: after the latest change. Use
+ // the sequence number for that.
target = curbuf->b_u_seq_last + 1;
dofile = false;
}
}
- } else
+ } else {
target = curbuf->b_u_seq_cur + step;
+ }
if (step < 0) {
- if (target < 0)
+ if (target < 0) {
target = 0;
+ }
closest = -1;
} else {
if (dosec) {
@@ -2044,10 +2055,11 @@ void undo_time(long step, bool sec, bool file, bool absolute)
mark = ++lastmark;
nomark = ++lastmark;
- if (curbuf->b_u_curhead == NULL) /* at leaf of the tree */
+ if (curbuf->b_u_curhead == NULL) { // at leaf of the tree
uhp = curbuf->b_u_newhead;
- else
+ } else {
uhp = curbuf->b_u_curhead;
+ }
while (uhp != NULL) {
uhp->uh_walk = mark;
@@ -2060,22 +2072,22 @@ void undo_time(long step, bool sec, bool file, bool absolute)
}
if (round == 1 && !(dofile && val == 0)) {
- /* Remember the header that is closest to the target.
- * It must be at least in the right direction (checked with
- * "b_u_seq_cur"). When the timestamp is equal find the
- * highest/lowest sequence number. */
+ // Remember the header that is closest to the target.
+ // It must be at least in the right direction (checked with
+ // "b_u_seq_cur"). When the timestamp is equal find the
+ // highest/lowest sequence number.
if ((step < 0 ? uhp->uh_seq <= curbuf->b_u_seq_cur
- : uhp->uh_seq > curbuf->b_u_seq_cur)
+ : uhp->uh_seq > curbuf->b_u_seq_cur)
&& ((dosec && val == closest)
? (step < 0
? uhp->uh_seq < closest_seq
- : uhp->uh_seq > closest_seq)
- : closest == closest_start
+ : uhp->uh_seq > closest_seq)
+ : closest == closest_start
|| (val > target
? (closest > target
? val - target <= closest - target
: val - target <= target - closest)
- : (closest > target
+ : (closest > target
? target - val <= closest - target
: target - val <= target - closest)))) {
closest = val;
@@ -2083,45 +2095,47 @@ void undo_time(long step, bool sec, bool file, bool absolute)
}
}
- /* Quit searching when we found a match. But when searching for a
- * time we need to continue looking for the best uh_seq. */
+ // Quit searching when we found a match. But when searching for a
+ // time we need to continue looking for the best uh_seq.
if (target == val && !dosec) {
target = uhp->uh_seq;
break;
}
- /* go down in the tree if we haven't been there */
+ // go down in the tree if we haven't been there
if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != nomark
- && uhp->uh_prev.ptr->uh_walk != mark)
+ && uhp->uh_prev.ptr->uh_walk != mark) {
uhp = uhp->uh_prev.ptr;
-
- /* go to alternate branch if we haven't been there */
+ }
+ // go to alternate branch if we haven't been there
else if (uhp->uh_alt_next.ptr != NULL
&& uhp->uh_alt_next.ptr->uh_walk != nomark
- && uhp->uh_alt_next.ptr->uh_walk != mark)
+ && uhp->uh_alt_next.ptr->uh_walk != mark) {
uhp = uhp->uh_alt_next.ptr;
-
- /* go up in the tree if we haven't been there and we are at the
- * start of alternate branches */
- else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL
- && uhp->uh_next.ptr->uh_walk != nomark
- && uhp->uh_next.ptr->uh_walk != mark) {
- /* If still at the start we don't go through this change. */
- if (uhp == curbuf->b_u_curhead)
+ } else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL
+ // go up in the tree if we haven't been there and we are at the
+ // start of alternate branches
+ && uhp->uh_next.ptr->uh_walk != nomark
+ && uhp->uh_next.ptr->uh_walk != mark) {
+ // If still at the start we don't go through this change.
+ if (uhp == curbuf->b_u_curhead) {
uhp->uh_walk = nomark;
+ }
uhp = uhp->uh_next.ptr;
} else {
- /* need to backtrack; mark this node as useless */
+ // need to backtrack; mark this node as useless
uhp->uh_walk = nomark;
- if (uhp->uh_alt_prev.ptr != NULL)
+ if (uhp->uh_alt_prev.ptr != NULL) {
uhp = uhp->uh_alt_prev.ptr;
- else
+ } else {
uhp = uhp->uh_next.ptr;
+ }
}
}
- if (uhp != NULL) /* found it */
+ if (uhp != NULL) { // found it
break;
+ }
if (absolute) {
EMSGN(_("E830: Undo number %" PRId64 " not found"), step);
@@ -2129,10 +2143,11 @@ void undo_time(long step, bool sec, bool file, bool absolute)
}
if (closest == closest_start) {
- if (step < 0)
+ if (step < 0) {
MSG(_("Already at oldest change"));
- else
+ } else {
MSG(_("Already at newest change"));
+ }
return;
}
@@ -2153,10 +2168,11 @@ target_zero:
change_warning(curbuf, 0);
uhp = curbuf->b_u_curhead;
- if (uhp == NULL)
+ if (uhp == NULL) {
uhp = curbuf->b_u_newhead;
- else
+ } else {
uhp = uhp->uh_next.ptr;
+ }
if (uhp == NULL
|| (target > 0 && uhp->uh_walk != mark)
|| (uhp->uh_seq == target && !above)) {
@@ -2264,24 +2280,24 @@ target_zero:
/// @param do_buf_event If `true`, send buffer updates.
static void u_undoredo(int undo, bool do_buf_event)
{
- char_u **newarray = NULL;
+ char_u **newarray = NULL;
linenr_T oldsize;
linenr_T newsize;
linenr_T top, bot;
linenr_T lnum;
linenr_T newlnum = MAXLNUM;
long i;
- u_entry_T *uep, *nuep;
- u_entry_T *newlist = NULL;
+ u_entry_T *uep, *nuep;
+ u_entry_T *newlist = NULL;
int old_flags;
int new_flags;
fmark_T namedm[NMARKS];
visualinfo_T visualinfo;
bool empty_buffer; // buffer became empty
- u_header_T *curhead = curbuf->b_u_curhead;
+ u_header_T *curhead = curbuf->b_u_curhead;
- /* Don't want autocommands using the undo structures here, they are
- * invalid till the end. */
+ // Don't want autocommands using the undo structures here, they are
+ // invalid till the end.
block_autocmds();
#ifdef U_DEBUG
@@ -2307,8 +2323,9 @@ static void u_undoredo(int undo, bool do_buf_event)
for (uep = curhead->uh_entry; uep != NULL; uep = nuep) {
top = uep->ue_top;
bot = uep->ue_bot;
- if (bot == 0)
+ if (bot == 0) {
bot = curbuf->b_ml.ml_line_count + 1;
+ }
if (top > curbuf->b_ml.ml_line_count || top >= bot
|| bot > curbuf->b_ml.ml_line_count + 1) {
unblock_autocmds();
@@ -2317,8 +2334,8 @@ static void u_undoredo(int undo, bool do_buf_event)
return;
}
- oldsize = bot - top - 1; /* number of lines before undo */
- newsize = uep->ue_size; /* number of lines after undo */
+ oldsize = bot - top - 1; // number of lines before undo
+ newsize = uep->ue_size; // number of lines after undo
if (top < newlnum) {
/* If the saved cursor is somewhere in this undo block, move it to
@@ -2332,13 +2349,15 @@ static void u_undoredo(int undo, bool do_buf_event)
/* Use the first line that actually changed. Avoids that
* undoing auto-formatting puts the cursor in the previous
* line. */
- for (i = 0; i < newsize && i < oldsize; ++i)
- if (STRCMP(uep->ue_array[i], ml_get(top + 1 + i)) != 0)
+ for (i = 0; i < newsize && i < oldsize; ++i) {
+ if (STRCMP(uep->ue_array[i], ml_get(top + 1 + i)) != 0) {
break;
+ }
+ }
if (i == newsize && newlnum == MAXLNUM && uep->ue_next == NULL) {
newlnum = top;
curwin->w_cursor.lnum = newlnum + 1;
- } else if (i < newsize) {
+ } else if (i < newsize) {
newlnum = top + i;
curwin->w_cursor.lnum = newlnum + 1;
}
@@ -2347,12 +2366,12 @@ static void u_undoredo(int undo, bool do_buf_event)
empty_buffer = false;
- /* delete the lines between top and bot and save them in newarray */
+ // delete the lines between top and bot and save them in newarray
if (oldsize > 0) {
newarray = xmalloc(sizeof(char_u *) * (size_t)oldsize);
- /* delete backwards, it goes faster in most cases */
+ // delete backwards, it goes faster in most cases
for (lnum = bot - 1, i = oldsize; --i >= 0; --lnum) {
- /* what can we do when we run out of memory? */
+ // what can we do when we run out of memory?
newarray[i] = u_save_line(lnum);
/* remember we deleted the last line in the buffer, and a
* dummy empty line will be inserted */
@@ -2361,10 +2380,11 @@ static void u_undoredo(int undo, bool do_buf_event)
}
ml_delete(lnum, false);
}
- } else
+ } else {
newarray = NULL;
+ }
- /* insert the lines in u_array between top and bot */
+ // insert the lines in u_array between top and bot
if (newsize) {
for (lnum = top, i = 0; i < newsize; ++i, ++lnum) {
/*
@@ -2395,13 +2415,15 @@ static void u_undoredo(int undo, bool do_buf_event)
changed_lines(top + 1, 0, bot, newsize - oldsize, do_buf_event);
- /* set '[ and '] mark */
- if (top + 1 < curbuf->b_op_start.lnum)
+ // set '[ and '] mark
+ if (top + 1 < curbuf->b_op_start.lnum) {
curbuf->b_op_start.lnum = top + 1;
- if (newsize == 0 && top + 1 > curbuf->b_op_end.lnum)
+ }
+ if (newsize == 0 && top + 1 > curbuf->b_op_end.lnum) {
curbuf->b_op_end.lnum = top + 1;
- else if (top + newsize > curbuf->b_op_end.lnum)
+ } else if (top + newsize > curbuf->b_op_end.lnum) {
curbuf->b_op_end.lnum = top + newsize;
+ }
u_newcount += newsize;
u_oldcount += oldsize;
@@ -2424,7 +2446,7 @@ static void u_undoredo(int undo, bool do_buf_event)
undo_info = kv_A(curhead->uh_extmark, i);
extmark_apply_undo(undo_info, undo);
}
- // redo
+ // redo
} else {
for (i = 0; i < (int)kv_size(curhead->uh_extmark); i++) {
undo_info = kv_A(curhead->uh_extmark, i);
@@ -2482,17 +2504,20 @@ static void u_undoredo(int undo, bool do_buf_event)
* Otherwise the cursor should go to the first undone line.
*/
if (curhead->uh_cursor.lnum + 1 == curwin->w_cursor.lnum
- && curwin->w_cursor.lnum > 1)
+ && curwin->w_cursor.lnum > 1) {
--curwin->w_cursor.lnum;
+ }
if (curwin->w_cursor.lnum <= curbuf->b_ml.ml_line_count) {
if (curhead->uh_cursor.lnum == curwin->w_cursor.lnum) {
curwin->w_cursor.col = curhead->uh_cursor.col;
- if (virtual_active() && curhead->uh_cursor_vcol >= 0)
+ if (virtual_active() && curhead->uh_cursor_vcol >= 0) {
coladvance((colnr_T)curhead->uh_cursor_vcol);
- else
+ } else {
curwin->w_cursor.coladd = 0;
- } else
+ }
+ } else {
beginline(BL_SOL | BL_FIX);
+ }
} else {
/* We get here with the current cursor line being past the end (eg
* after adding lines at the end of the file, and then undoing it).
@@ -2502,27 +2527,29 @@ static void u_undoredo(int undo, bool do_buf_event)
curwin->w_cursor.coladd = 0;
}
- /* Make sure the cursor is on an existing line and column. */
+ // Make sure the cursor is on an existing line and column.
check_cursor();
- /* Remember where we are for "g-" and ":earlier 10s". */
+ // Remember where we are for "g-" and ":earlier 10s".
curbuf->b_u_seq_cur = curhead->uh_seq;
- if (undo)
+ if (undo) {
/* We are below the previous undo. However, to make ":earlier 1s"
* work we compute this as being just above the just undone change. */
curbuf->b_u_seq_cur = curhead->uh_next.ptr ?
- curhead->uh_next.ptr->uh_seq : 0;
+ curhead->uh_next.ptr->uh_seq : 0;
+ }
- /* Remember where we are for ":earlier 1f" and ":later 1f". */
+ // Remember where we are for ":earlier 1f" and ":later 1f".
if (curhead->uh_save_nr != 0) {
- if (undo)
+ if (undo) {
curbuf->b_u_save_nr_cur = curhead->uh_save_nr - 1;
- else
+ } else {
curbuf->b_u_save_nr_cur = curhead->uh_save_nr;
+ }
}
- /* The timestamp can be the same for multiple changes, just use the one of
- * the undone/redone change. */
+ // The timestamp can be the same for multiple changes, just use the one of
+ // the undone/redone change.
curbuf->b_u_time_cur = curhead->uh_time;
unblock_autocmds();
@@ -2534,17 +2561,18 @@ static void u_undoredo(int undo, bool do_buf_event)
/// If we deleted or added lines, report the number of less/more lines.
/// Otherwise, report the number of changes (this may be incorrect
/// in some cases, but it's better than nothing).
-static void u_undo_end(
- bool did_undo, ///< just did an undo
- bool absolute, ///< used ":undo N"
- bool quiet)
+///
+/// @param did_undo just did an undo
+/// @param absolute used ":undo N"
+static void u_undo_end(bool did_undo, bool absolute, bool quiet)
{
- char *msgstr;
- u_header_T *uhp;
+ char *msgstr;
+ u_header_T *uhp;
char_u msgbuf[80];
- if ((fdo_flags & FDO_UNDO) && KeyTyped)
+ if ((fdo_flags & FDO_UNDO) && KeyTyped) {
foldOpenCursor();
+ }
if (quiet
|| global_busy // no messages until global is finished
@@ -2552,28 +2580,30 @@ static void u_undo_end(
return;
}
- if (curbuf->b_ml.ml_flags & ML_EMPTY)
+ if (curbuf->b_ml.ml_flags & ML_EMPTY) {
--u_newcount;
+ }
u_oldcount -= u_newcount;
- if (u_oldcount == -1)
+ if (u_oldcount == -1) {
msgstr = N_("more line");
- else if (u_oldcount < 0)
+ } else if (u_oldcount < 0) {
msgstr = N_("more lines");
- else if (u_oldcount == 1)
+ } else if (u_oldcount == 1) {
msgstr = N_("line less");
- else if (u_oldcount > 1)
+ } else if (u_oldcount > 1) {
msgstr = N_("fewer lines");
- else {
+ } else {
u_oldcount = u_newcount;
- if (u_newcount == 1)
+ if (u_newcount == 1) {
msgstr = N_("change");
- else
+ } else {
msgstr = N_("changes");
+ }
}
if (curbuf->b_u_curhead != NULL) {
- /* For ":undo N" we prefer a "after #N" message. */
+ // For ":undo N" we prefer a "after #N" message.
if (absolute && curbuf->b_u_curhead->uh_next.ptr != NULL) {
uhp = curbuf->b_u_curhead->uh_next.ptr;
did_undo = false;
@@ -2600,14 +2630,13 @@ static void u_undo_end(
}
}
- smsg_attr_keep(
- 0,
- _("%" PRId64 " %s; %s #%" PRId64 " %s"),
- u_oldcount < 0 ? (int64_t)-u_oldcount : (int64_t)u_oldcount,
- _(msgstr),
- did_undo ? _("before") : _("after"),
- uhp == NULL ? (int64_t)0L : (int64_t)uhp->uh_seq,
- msgbuf);
+ smsg_attr_keep(0,
+ _("%" PRId64 " %s; %s #%" PRId64 " %s"),
+ u_oldcount < 0 ? (int64_t)-u_oldcount : (int64_t)u_oldcount,
+ _(msgstr),
+ did_undo ? _("before") : _("after"),
+ uhp == NULL ? (int64_t)0L : (int64_t)uhp->uh_seq,
+ msgbuf);
}
/// u_sync: stop adding to the current entry list
@@ -2634,7 +2663,7 @@ void u_sync(bool force)
void ex_undolist(exarg_T *eap)
{
garray_T ga;
- u_header_T *uhp;
+ u_header_T *uhp;
int mark;
int nomark;
int changes = 1;
@@ -2657,50 +2686,50 @@ void ex_undolist(exarg_T *eap)
add_time(IObuff + STRLEN(IObuff), IOSIZE - STRLEN(IObuff),
uhp->uh_time);
if (uhp->uh_save_nr > 0) {
- while (STRLEN(IObuff) < 33)
+ while (STRLEN(IObuff) < 33) {
STRCAT(IObuff, " ");
+ }
vim_snprintf_add((char *)IObuff, IOSIZE,
- " %3ld", uhp->uh_save_nr);
+ " %3ld", uhp->uh_save_nr);
}
GA_APPEND(char_u *, &ga, vim_strsave(IObuff));
}
uhp->uh_walk = mark;
- /* go down in the tree if we haven't been there */
+ // go down in the tree if we haven't been there
if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != nomark
&& uhp->uh_prev.ptr->uh_walk != mark) {
uhp = uhp->uh_prev.ptr;
++changes;
}
- /* go to alternate branch if we haven't been there */
+ // go to alternate branch if we haven't been there
else if (uhp->uh_alt_next.ptr != NULL
&& uhp->uh_alt_next.ptr->uh_walk != nomark
- && uhp->uh_alt_next.ptr->uh_walk != mark)
+ && uhp->uh_alt_next.ptr->uh_walk != mark) {
uhp = uhp->uh_alt_next.ptr;
-
- /* go up in the tree if we haven't been there and we are at the
- * start of alternate branches */
- else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL
- && uhp->uh_next.ptr->uh_walk != nomark
- && uhp->uh_next.ptr->uh_walk != mark) {
+ } else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL
+ // go up in the tree if we haven't been there and we are at the
+ // start of alternate branches
+ && uhp->uh_next.ptr->uh_walk != nomark
+ && uhp->uh_next.ptr->uh_walk != mark) {
uhp = uhp->uh_next.ptr;
--changes;
} else {
- /* need to backtrack; mark this node as done */
+ // need to backtrack; mark this node as done
uhp->uh_walk = nomark;
- if (uhp->uh_alt_prev.ptr != NULL)
+ if (uhp->uh_alt_prev.ptr != NULL) {
uhp = uhp->uh_alt_prev.ptr;
- else {
+ } else {
uhp = uhp->uh_next.ptr;
--changes;
}
}
}
- if (GA_EMPTY(&ga))
+ if (GA_EMPTY(&ga)) {
MSG(_("Nothing to undo"));
- else {
+ } else {
sort_strings((char_u **)ga.ga_data, ga.ga_len);
msg_start();
@@ -2757,17 +2786,18 @@ void u_unchanged(buf_T *buf)
*/
void u_find_first_changed(void)
{
- u_header_T *uhp = curbuf->b_u_newhead;
- u_entry_T *uep;
+ u_header_T *uhp = curbuf->b_u_newhead;
+ u_entry_T *uep;
linenr_T lnum;
- if (curbuf->b_u_curhead != NULL || uhp == NULL)
- return; /* undid something in an autocmd? */
-
- /* Check that the last undo block was for the whole file. */
+ if (curbuf->b_u_curhead != NULL || uhp == NULL) {
+ return; // undid something in an autocmd?
+ }
+ // Check that the last undo block was for the whole file.
uep = uhp->uh_entry;
- if (uep->ue_top != 0 || uep->ue_bot != 0)
+ if (uep->ue_top != 0 || uep->ue_bot != 0) {
return;
+ }
for (lnum = 1; lnum < curbuf->b_ml.ml_line_count
&& lnum <= uep->ue_size; lnum++) {
@@ -2778,7 +2808,7 @@ void u_find_first_changed(void)
}
}
if (curbuf->b_ml.ml_line_count != uep->ue_size) {
- /* lines added or deleted at the end, put the cursor there */
+ // lines added or deleted at the end, put the cursor there
clearpos(&(uhp->uh_cursor));
uhp->uh_cursor.lnum = lnum;
}
@@ -2790,27 +2820,30 @@ void u_find_first_changed(void)
*/
void u_update_save_nr(buf_T *buf)
{
- u_header_T *uhp;
+ u_header_T *uhp;
++buf->b_u_save_nr_last;
buf->b_u_save_nr_cur = buf->b_u_save_nr_last;
uhp = buf->b_u_curhead;
- if (uhp != NULL)
+ if (uhp != NULL) {
uhp = uhp->uh_next.ptr;
- else
+ } else {
uhp = buf->b_u_newhead;
- if (uhp != NULL)
+ }
+ if (uhp != NULL) {
uhp->uh_save_nr = buf->b_u_save_nr_last;
+ }
}
static void u_unch_branch(u_header_T *uhp)
{
- u_header_T *uh;
+ u_header_T *uh;
for (uh = uhp; uh != NULL; uh = uh->uh_prev.ptr) {
uh->uh_flags |= UH_CHANGED;
- if (uh->uh_alt_next.ptr != NULL)
- u_unch_branch(uh->uh_alt_next.ptr); /* recursive */
+ if (uh->uh_alt_next.ptr != NULL) {
+ u_unch_branch(uh->uh_alt_next.ptr); // recursive
+ }
}
}
@@ -2829,11 +2862,11 @@ static u_entry_T *u_get_headentry(buf_T *buf)
/*
* u_getbot(): compute the line number of the previous u_save
- * It is called only when b_u_synced is false.
+ * It is called only when b_u_synced is false.
*/
static void u_getbot(buf_T *buf)
{
- u_entry_T *uep;
+ u_entry_T *uep;
linenr_T extra;
uep = u_get_headentry(buf); // check for corrupt undo list
@@ -2864,95 +2897,91 @@ static void u_getbot(buf_T *buf)
buf->b_u_synced = true;
}
-/*
- * Free one header "uhp" and its entry list and adjust the pointers.
- */
-static void
-u_freeheader(
- buf_T *buf,
- u_header_T *uhp,
- u_header_T **uhpp // if not NULL reset when freeing this header
-)
-{
- u_header_T *uhap;
-
- /* When there is an alternate redo list free that branch completely,
- * because we can never go there. */
- if (uhp->uh_alt_next.ptr != NULL)
+/// Free one header "uhp" and its entry list and adjust the pointers.
+///
+/// @param uhpp if not NULL reset when freeing this header
+static void u_freeheader(buf_T *buf, u_header_T *uhp, u_header_T **uhpp)
+{
+ u_header_T *uhap;
+
+ // When there is an alternate redo list free that branch completely,
+ // because we can never go there.
+ if (uhp->uh_alt_next.ptr != NULL) {
u_freebranch(buf, uhp->uh_alt_next.ptr, uhpp);
+ }
- if (uhp->uh_alt_prev.ptr != NULL)
+ if (uhp->uh_alt_prev.ptr != NULL) {
uhp->uh_alt_prev.ptr->uh_alt_next.ptr = NULL;
+ }
- /* Update the links in the list to remove the header. */
- if (uhp->uh_next.ptr == NULL)
+ // Update the links in the list to remove the header.
+ if (uhp->uh_next.ptr == NULL) {
buf->b_u_oldhead = uhp->uh_prev.ptr;
- else
+ } else {
uhp->uh_next.ptr->uh_prev.ptr = uhp->uh_prev.ptr;
+ }
- if (uhp->uh_prev.ptr == NULL)
+ if (uhp->uh_prev.ptr == NULL) {
buf->b_u_newhead = uhp->uh_next.ptr;
- else
+ } else {
for (uhap = uhp->uh_prev.ptr; uhap != NULL;
- uhap = uhap->uh_alt_next.ptr)
+ uhap = uhap->uh_alt_next.ptr) {
uhap->uh_next.ptr = uhp->uh_next.ptr;
+ }
+ }
u_freeentries(buf, uhp, uhpp);
}
-/*
- * Free an alternate branch and any following alternate branches.
- */
-static void
-u_freebranch(
- buf_T *buf,
- u_header_T *uhp,
- u_header_T **uhpp // if not NULL reset when freeing this header
-)
+/// Free an alternate branch and any following alternate branches.
+///
+/// @param uhpp if not NULL reset when freeing this header
+static void u_freebranch(buf_T *buf, u_header_T *uhp, u_header_T **uhpp)
{
- u_header_T *tofree, *next;
+ u_header_T *tofree, *next;
- /* If this is the top branch we may need to use u_freeheader() to update
- * all the pointers. */
+ // If this is the top branch we may need to use u_freeheader() to update
+ // all the pointers.
if (uhp == buf->b_u_oldhead) {
- while (buf->b_u_oldhead != NULL)
+ while (buf->b_u_oldhead != NULL) {
u_freeheader(buf, buf->b_u_oldhead, uhpp);
+ }
return;
}
- if (uhp->uh_alt_prev.ptr != NULL)
+ if (uhp->uh_alt_prev.ptr != NULL) {
uhp->uh_alt_prev.ptr->uh_alt_next.ptr = NULL;
+ }
next = uhp;
while (next != NULL) {
tofree = next;
- if (tofree->uh_alt_next.ptr != NULL)
- u_freebranch(buf, tofree->uh_alt_next.ptr, uhpp); /* recursive */
+ if (tofree->uh_alt_next.ptr != NULL) {
+ u_freebranch(buf, tofree->uh_alt_next.ptr, uhpp); // recursive
+ }
next = tofree->uh_prev.ptr;
u_freeentries(buf, tofree, uhpp);
}
}
-/*
- * Free all the undo entries for one header and the header itself.
- * This means that "uhp" is invalid when returning.
- */
-static void
-u_freeentries(
- buf_T *buf,
- u_header_T *uhp,
- u_header_T **uhpp // if not NULL reset when freeing this header
-)
+/// Free all the undo entries for one header and the header itself.
+/// This means that "uhp" is invalid when returning.
+///
+/// @param uhpp if not NULL reset when freeing this header
+static void u_freeentries(buf_T *buf, u_header_T *uhp, u_header_T **uhpp)
{
- u_entry_T *uep, *nuep;
+ u_entry_T *uep, *nuep;
- /* Check for pointers to the header that become invalid now. */
- if (buf->b_u_curhead == uhp)
+ // Check for pointers to the header that become invalid now.
+ if (buf->b_u_curhead == uhp) {
buf->b_u_curhead = NULL;
- if (buf->b_u_newhead == uhp)
- buf->b_u_newhead = NULL; /* freeing the newest entry */
- if (uhpp != NULL && uhp == *uhpp)
+ }
+ if (buf->b_u_newhead == uhp) {
+ buf->b_u_newhead = NULL; // freeing the newest entry
+ }
+ if (uhpp != NULL && uhp == *uhpp) {
*uhpp = NULL;
+ }
for (uep = uhp->uh_entry; uep != NULL; uep = nuep) {
nuep = uep->ue_next;
@@ -2973,8 +3002,9 @@ u_freeentries(
*/
static void u_freeentry(u_entry_T *uep, long n)
{
- while (n > 0)
+ while (n > 0) {
xfree(uep->ue_array[--n]);
+ }
xfree((char_u *)uep->ue_array);
#ifdef U_DEBUG
uep->ue_magic = 0;
@@ -2999,16 +3029,19 @@ void u_clearall(buf_T *buf)
*/
void u_saveline(linenr_T lnum)
{
- if (lnum == curbuf->b_u_line_lnum) /* line is already saved */
+ if (lnum == curbuf->b_u_line_lnum) { // line is already saved
return;
- if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) /* should never happen */
+ }
+ if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) { // should never happen
return;
+ }
u_clearline();
curbuf->b_u_line_lnum = lnum;
- if (curwin->w_cursor.lnum == lnum)
+ if (curwin->w_cursor.lnum == lnum) {
curbuf->b_u_line_colnr = curwin->w_cursor.col;
- else
+ } else {
curbuf->b_u_line_colnr = 0;
+ }
curbuf->b_u_line_ptr = u_save_line(lnum);
}
@@ -3033,7 +3066,7 @@ void u_clearline(void)
void u_undoline(void)
{
colnr_T t;
- char_u *oldp;
+ char_u *oldp;
if (curbuf->b_u_line_ptr == NULL
|| curbuf->b_u_line_lnum > curbuf->b_ml.ml_line_count) {
@@ -3050,12 +3083,15 @@ void u_undoline(void)
oldp = u_save_line(curbuf->b_u_line_lnum);
ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, true);
changed_bytes(curbuf->b_u_line_lnum, 0);
+ extmark_splice_cols(curbuf, (int)curbuf->b_u_line_lnum-1, 0, (colnr_T)STRLEN(oldp),
+ (colnr_T)STRLEN(curbuf->b_u_line_ptr), kExtmarkUndo);
xfree(curbuf->b_u_line_ptr);
curbuf->b_u_line_ptr = oldp;
t = curbuf->b_u_line_colnr;
- if (curwin->w_cursor.lnum == curbuf->b_u_line_lnum)
+ if (curwin->w_cursor.lnum == curbuf->b_u_line_lnum) {
curbuf->b_u_line_colnr = curwin->w_cursor.col;
+ }
curwin->w_cursor.col = t;
curwin->w_cursor.lnum = curbuf->b_u_line_lnum;
check_cursor_col();
@@ -3106,8 +3142,8 @@ bool bufIsChanged(buf_T *buf)
{
// In a "prompt" buffer we do respect 'modified', so that we can control
// closing the window by setting or resetting that option.
- return (!bt_dontwrite(buf) || bt_prompt(buf))
- && (buf->b_changed || file_ff_differs(buf, true));
+ return (!bt_dontwrite(buf) || bt_prompt(buf))
+ && (buf->b_changed || file_ff_differs(buf, true));
}
// Return true if any buffer has changes. Also buffers that are not written.
diff --git a/src/nvim/undo.h b/src/nvim/undo.h
index 802cdc5583..f494d4de86 100644
--- a/src/nvim/undo.h
+++ b/src/nvim/undo.h
@@ -1,8 +1,8 @@
#ifndef NVIM_UNDO_H
#define NVIM_UNDO_H
-#include "nvim/undo_defs.h"
#include "nvim/ex_cmds_defs.h"
+#include "nvim/undo_defs.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "undo.h.generated.h"
diff --git a/src/nvim/undo_defs.h b/src/nvim/undo_defs.h
index b46295a15d..3267b2f71e 100644
--- a/src/nvim/undo_defs.h
+++ b/src/nvim/undo_defs.h
@@ -3,32 +3,32 @@
#include <time.h> // for time_t
-#include "nvim/pos.h"
#include "nvim/extmark_defs.h"
#include "nvim/mark_defs.h"
+#include "nvim/pos.h"
typedef struct u_header u_header_T;
-/* Structure to store info about the Visual area. */
+// Structure to store info about the Visual area.
typedef struct {
- pos_T vi_start; /* start pos of last VIsual */
- pos_T vi_end; /* end position of last VIsual */
- int vi_mode; /* VIsual_mode of last VIsual */
- colnr_T vi_curswant; /* MAXCOL from w_curswant */
+ pos_T vi_start; // start pos of last VIsual
+ pos_T vi_end; // end position of last VIsual
+ int vi_mode; // VIsual_mode of last VIsual
+ colnr_T vi_curswant; // MAXCOL from w_curswant
} visualinfo_T;
#include "nvim/buffer_defs.h"
typedef struct u_entry u_entry_T;
struct u_entry {
- u_entry_T *ue_next; /* pointer to next entry in list */
- linenr_T ue_top; /* number of line above undo block */
- linenr_T ue_bot; /* number of line below undo block */
- linenr_T ue_lcount; /* linecount when u_save called */
- char_u **ue_array; /* array of lines in undo block */
- long ue_size; /* number of lines in ue_array */
+ u_entry_T *ue_next; // pointer to next entry in list
+ linenr_T ue_top; // number of line above undo block
+ linenr_T ue_bot; // number of line below undo block
+ linenr_T ue_lcount; // linecount when u_save called
+ char_u **ue_array; // array of lines in undo block
+ long ue_size; // number of lines in ue_array
#ifdef U_DEBUG
- int ue_magic; /* magic number to check allocation */
+ int ue_magic; // magic number to check allocation
#endif
};
@@ -36,26 +36,26 @@ struct u_header {
/* The following have a pointer and a number. The number is used when
* reading the undo file in u_read_undo() */
union {
- u_header_T *ptr; /* pointer to next undo header in list */
+ u_header_T *ptr; // pointer to next undo header in list
long seq;
} uh_next;
union {
- u_header_T *ptr; /* pointer to previous header in list */
+ u_header_T *ptr; // pointer to previous header in list
long seq;
} uh_prev;
union {
- u_header_T *ptr; /* pointer to next header for alt. redo */
+ u_header_T *ptr; // pointer to next header for alt. redo
long seq;
} uh_alt_next;
union {
- u_header_T *ptr; /* pointer to previous header for alt. redo */
+ u_header_T *ptr; // pointer to previous header for alt. redo
long seq;
} uh_alt_prev;
- long uh_seq; /* sequence number, higher == newer undo */
- int uh_walk; /* used by undo_time() */
- u_entry_T *uh_entry; /* pointer to first entry */
- u_entry_T *uh_getbot_entry; /* pointer to where ue_bot must be set */
- pos_T uh_cursor; /* cursor position before saving */
+ long uh_seq; // sequence number, higher == newer undo
+ int uh_walk; // used by undo_time()
+ u_entry_T *uh_entry; // pointer to first entry
+ u_entry_T *uh_getbot_entry; // pointer to where ue_bot must be set
+ pos_T uh_cursor; // cursor position before saving
long uh_cursor_vcol;
int uh_flags; // see below
fmark_T uh_namedm[NMARKS]; // marks before undo/after redo
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 7c197f1b7f..9e2358c9a3 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -6,32 +6,32 @@
/// Nvim was forked from Vim 7.4.160.
/// Vim originated from Stevie version 3.6 (Fish disk 217) by GRWalter (Fred).
-#include <inttypes.h>
#include <assert.h>
+#include <inttypes.h>
#include <limits.h>
#include "nvim/api/private/helpers.h"
-#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/buffer.h"
-#include "nvim/iconv.h"
-#include "nvim/version.h"
#include "nvim/charset.h"
+#include "nvim/iconv.h"
+#include "nvim/lua/executor.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
-#include "nvim/lua/executor.h"
+#include "nvim/version.h"
+#include "nvim/vim.h"
// version info generated by the build system
#include "auto/versiondef.h"
// for ":version", ":intro", and "nvim --version"
#ifndef NVIM_VERSION_MEDIUM
-#define NVIM_VERSION_MEDIUM "v" STR(NVIM_VERSION_MAJOR)\
-"." STR(NVIM_VERSION_MINOR) "." STR(NVIM_VERSION_PATCH)\
-NVIM_VERSION_PRERELEASE
+# define NVIM_VERSION_MEDIUM "v" STR(NVIM_VERSION_MAJOR)\
+ "." STR(NVIM_VERSION_MINOR) "." STR(NVIM_VERSION_PATCH)\
+ NVIM_VERSION_PRERELEASE
#endif
#define NVIM_VERSION_LONG "NVIM " NVIM_VERSION_MEDIUM
@@ -50,23 +50,23 @@ char *version_cflags = "Compilation: " NVIM_VERSION_CFLAGS;
static char *features[] = {
#ifdef HAVE_ACL
-"+acl",
+ "+acl",
#else
-"-acl",
+ "-acl",
#endif
#if defined(HAVE_ICONV)
-"+iconv",
+ "+iconv",
#else
-"-iconv",
+ "-iconv",
#endif
#ifdef FEAT_TUI
-"+tui",
+ "+tui",
#else
-"-tui",
+ "-tui",
#endif
-NULL
+ NULL
};
// clang-format off
@@ -2017,9 +2017,9 @@ void ex_version(exarg_T *eap)
/// When "wrap" is TRUE wrap the string in [].
/// @param s
/// @param wrap
-static void version_msg_wrap(char_u *s, int wrap)
+static void version_msg_wrap(char *s, int wrap)
{
- int len = (int)vim_strsize(s) + (wrap ? 2 : 0);
+ int len = vim_strsize((char_u *)s) + (wrap ? 2 : 0);
if (!got_int
&& (len < Columns)
@@ -2032,7 +2032,7 @@ static void version_msg_wrap(char_u *s, int wrap)
if (wrap) {
msg_puts("[");
}
- msg_puts((char *)s);
+ msg_puts(s);
if (wrap) {
msg_puts("]");
}
@@ -2041,7 +2041,7 @@ static void version_msg_wrap(char_u *s, int wrap)
static void version_msg(char *s)
{
- version_msg_wrap((char_u *)s, false);
+ version_msg_wrap(s, false);
}
/// List all features.
@@ -2070,7 +2070,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 = (int)vim_strsize(items[i]) + (i == current ? 2 : 0);
+ int l = vim_strsize(items[i]) + (i == current ? 2 : 0);
if (l > width) {
width = l;
@@ -2082,7 +2082,7 @@ void list_in_columns(char_u **items, int size, int current)
if (Columns < width) {
// Not enough screen columns - show one per line
for (i = 0; i < item_count; i++) {
- version_msg_wrap(items[i], i == current);
+ version_msg_wrap((char *)items[i], i == current);
if (msg_col > 0 && i < item_count - 1) {
msg_putchar('\n');
}
diff --git a/src/nvim/version.h b/src/nvim/version.h
index 4af038dd6c..a19e863152 100644
--- a/src/nvim/version.h
+++ b/src/nvim/version.h
@@ -5,8 +5,8 @@
#include "nvim/macros.h"
// defined in version.c
-extern char* Version;
-extern char* longVersion;
+extern char *Version;
+extern char *longVersion;
//
// Vim version number, name, etc. Patchlevel is defined in version.c.
diff --git a/src/nvim/vim.h b/src/nvim/vim.h
index f61f9a5e01..7d49ca6ff1 100644
--- a/src/nvim/vim.h
+++ b/src/nvim/vim.h
@@ -1,8 +1,8 @@
#ifndef NVIM_VIM_H
#define NVIM_VIM_H
-#include "nvim/types.h"
#include "nvim/pos.h" // for linenr_T, MAXCOL, etc...
+#include "nvim/types.h"
// Some defines from the old feature.h
#define SESSION_FILE "Session.vim"
@@ -30,11 +30,10 @@ enum { NUMBUFLEN = 65 };
#define ROOT_UID 0
+#include "nvim/gettext.h"
#include "nvim/keymap.h"
#include "nvim/macros.h"
-#include "nvim/gettext.h"
-
// special attribute addition: Put message in history
#define MSG_HIST 0x1000
@@ -57,8 +56,8 @@ enum { NUMBUFLEN = 65 };
#define REPLACE_FLAG 0x40 // Replace mode flag
#define REPLACE (REPLACE_FLAG + INSERT)
-# define VREPLACE_FLAG 0x80 // Virtual-replace mode flag
-# define VREPLACE (REPLACE_FLAG + VREPLACE_FLAG + INSERT)
+#define VREPLACE_FLAG 0x80 // Virtual-replace mode flag
+#define VREPLACE (REPLACE_FLAG + VREPLACE_FLAG + INSERT)
#define LREPLACE (REPLACE_FLAG + LANGMAP)
#define NORMAL_BUSY (0x100 + NORMAL) // Normal mode, busy with a command
@@ -251,7 +250,7 @@ enum { FOLD_TEXT_LEN = 51 }; //!< buffer size for get_foldtext()
#define STRNCAT(d, s, n) strncat((char *)(d), (char *)(s), (size_t)(n))
#define STRLCAT(d, s, n) xstrlcat((char *)(d), (char *)(s), (size_t)(n))
-# define vim_strpbrk(s, cs) (char_u *)strpbrk((char *)(s), (char *)(cs))
+#define vim_strpbrk(s, cs) (char_u *)strpbrk((char *)(s), (char *)(cs))
// Character used as separated in autoload function/variable names.
#define AUTOLOAD_CHAR '#'
@@ -260,7 +259,7 @@ enum { FOLD_TEXT_LEN = 51 }; //!< buffer size for get_foldtext()
// Prefer using emsgf(), because perror() may send the output to the wrong
// destination and mess up the screen.
-#define PERROR(msg) (void) emsgf("%s: %s", msg, strerror(errno))
+#define PERROR(msg) (void)emsgf("%s: %s", msg, strerror(errno))
#define SHOWCMD_COLS 10 // columns needed by shown command
@@ -301,28 +300,16 @@ enum { FOLD_TEXT_LEN = 51 }; //!< buffer size for get_foldtext()
# define mch_msg(str) printf("%s", (str))
#endif
-#include "nvim/globals.h" // global variables and messages
#include "nvim/buffer_defs.h" // buffer and windows
#include "nvim/ex_cmds_defs.h" // Ex command defines
-
-// Used for flags in do_in_path()
-#define DIP_ALL 0x01 // all matches, not just the first one
-#define DIP_DIR 0x02 // find directories instead of files
-#define DIP_ERR 0x04 // give an error message when none found
-#define DIP_START 0x08 // also use "start" directory in 'packpath'
-#define DIP_OPT 0x10 // also use "opt" directory in 'packpath'
-#define DIP_NORTP 0x20 // do not use 'runtimepath'
-#define DIP_NOAFTER 0x40 // skip "after" directories
-#define DIP_AFTER 0x80 // only use "after" directories
-#define DIP_LUA 0x100 // also use ".lua" files
-#define DIP_DIRFILE 0x200 // find both files and directories
+#include "nvim/globals.h" // global variables and messages
// Lowest number used for window ID. Cannot have this many windows per tab.
#define LOWEST_WIN_ID 1000
// BSD is supposed to cover FreeBSD and similar systems.
#if (defined(BSD) || defined(__FreeBSD_kernel__)) \
- && (defined(S_ISCHR) || defined(S_IFCHR))
+ && (defined(S_ISCHR) || defined(S_IFCHR))
# define OPEN_CHR_FILES
#endif
diff --git a/src/nvim/viml/parser/expressions.c b/src/nvim/viml/parser/expressions.c
index c2aa923c49..39687a8e8d 100644
--- a/src/nvim/viml/parser/expressions.c
+++ b/src/nvim/viml/parser/expressions.c
@@ -936,7 +936,7 @@ static const char *intchar2str(const int ch)
}
#ifdef UNIT_TESTING
-#include <stdio.h>
+# include <stdio.h>
REAL_FATTR_UNUSED
static inline void viml_pexpr_debug_print_ast_node(const ExprASTNode *const *const eastnode_p,
@@ -971,14 +971,14 @@ static inline void viml_pexpr_debug_print_token(const ParserState *const pstate,
{
fprintf(stderr, "\ntkn: %s\n", viml_pexpr_repr_token(pstate, token, NULL));
}
-#define PSTACK(msg) \
+# define PSTACK(msg) \
viml_pexpr_debug_print_ast_stack(&ast_stack, #msg)
-#define PSTACK_P(msg) \
+# define PSTACK_P(msg) \
viml_pexpr_debug_print_ast_stack(ast_stack, #msg)
-#define PNODE_P(eastnode_p, msg) \
+# define PNODE_P(eastnode_p, msg) \
viml_pexpr_debug_print_ast_node((const ExprASTNode *const *)eastnode_p, \
(#msg))
-#define PTOKEN(tkn) \
+# define PTOKEN(tkn) \
viml_pexpr_debug_print_token(pstate, tkn)
#endif
diff --git a/src/nvim/viml/parser/expressions.h b/src/nvim/viml/parser/expressions.h
index 838a742271..325df643e7 100644
--- a/src/nvim/viml/parser/expressions.h
+++ b/src/nvim/viml/parser/expressions.h
@@ -1,13 +1,13 @@
#ifndef NVIM_VIML_PARSER_EXPRESSIONS_H
#define NVIM_VIML_PARSER_EXPRESSIONS_H
+#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
-#include <stdbool.h>
+#include "nvim/eval/typval.h"
#include "nvim/types.h"
#include "nvim/viml/parser/parser.h"
-#include "nvim/eval/typval.h"
// Defines whether to ignore case:
// == kCCStrategyUseOption
@@ -80,7 +80,7 @@ typedef enum {
} ExprAssignmentType;
#define EXPR_OPT_SCOPE_LIST \
- ((char[]){ kExprOptScopeGlobal, kExprOptScopeLocal })
+ ((char[]){ kExprOptScopeGlobal, kExprOptScopeLocal })
/// All possible variable scopes
typedef enum {
@@ -96,11 +96,11 @@ typedef enum {
} ExprVarScope;
#define EXPR_VAR_SCOPE_LIST \
- ((char[]) { \
- kExprVarScopeScript, kExprVarScopeGlobal, kExprVarScopeVim, \
- kExprVarScopeBuffer, kExprVarScopeWindow, kExprVarScopeTabpage, \
- kExprVarScopeLocal, kExprVarScopeBuffer, kExprVarScopeArguments, \
- })
+ ((char[]) { \
+ kExprVarScopeScript, kExprVarScopeGlobal, kExprVarScopeVim, \
+ kExprVarScopeBuffer, kExprVarScopeWindow, kExprVarScopeTabpage, \
+ kExprVarScopeLocal, kExprVarScopeBuffer, kExprVarScopeArguments, \
+ })
/// Lexer token
typedef struct {
diff --git a/src/nvim/viml/parser/parser.h b/src/nvim/viml/parser/parser.h
index 7ac49709d8..b2933c3781 100644
--- a/src/nvim/viml/parser/parser.h
+++ b/src/nvim/viml/parser/parser.h
@@ -1,12 +1,12 @@
#ifndef NVIM_VIML_PARSER_PARSER_H
#define NVIM_VIML_PARSER_PARSER_H
+#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
-#include <assert.h>
-#include "nvim/lib/kvec.h"
#include "nvim/func_attr.h"
+#include "nvim/lib/kvec.h"
#include "nvim/mbyte.h"
#include "nvim/memory.h"
@@ -82,9 +82,9 @@ typedef struct {
} ParserState;
static inline void viml_parser_init(
- ParserState *const ret_pstate,
- const ParserLineGetter get_line, void *const cookie,
- ParserHighlight *const colors)
+ ParserState *const ret_pstate,
+ const ParserLineGetter get_line, void *const cookie,
+ ParserHighlight *const colors)
REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ARG(1, 2);
/// Initialize a new parser state instance
@@ -94,10 +94,8 @@ static inline void viml_parser_init(
/// @param[in] cookie Argument for the get_line function.
/// @param[in] colors Where to save highlighting. May be NULL if it is not
/// needed.
-static inline void viml_parser_init(
- ParserState *const ret_pstate,
- const ParserLineGetter get_line, void *const cookie,
- ParserHighlight *const colors)
+static inline void viml_parser_init(ParserState *const ret_pstate, const ParserLineGetter get_line,
+ void *const cookie, ParserHighlight *const colors)
{
*ret_pstate = (ParserState) {
.reader = {
@@ -194,8 +192,7 @@ static inline void viml_parser_advance(ParserState *const pstate,
///
/// @param pstate Parser state to advance.
/// @param[in] len Number of bytes to advance.
-static inline void viml_parser_advance(ParserState *const pstate,
- const size_t len)
+static inline void viml_parser_advance(ParserState *const pstate, const size_t len)
{
assert(pstate->pos.line == kv_size(pstate->reader.lines) - 1);
const ParserLine pline = kv_last(pstate->reader.lines);
@@ -219,10 +216,8 @@ static inline void viml_parser_highlight(ParserState *const pstate,
/// @param[in] start Start position of the highlight.
/// @param[in] len Highlighting chunk length.
/// @param[in] group Highlight group.
-static inline void viml_parser_highlight(ParserState *const pstate,
- const ParserPosition start,
- const size_t len,
- const char *const group)
+static inline void viml_parser_highlight(ParserState *const pstate, const ParserPosition start,
+ const size_t len, const char *const group)
{
if (pstate->colors == NULL || len == 0) {
return;
@@ -231,9 +226,9 @@ static inline void viml_parser_highlight(ParserState *const pstate,
|| kv_Z(*pstate->colors, 0).start.line < start.line
|| kv_Z(*pstate->colors, 0).end_col <= start.col);
kvi_push(*pstate->colors, ((ParserHighlightChunk) {
- .start = start,
- .end_col = start.col + len,
- .group = group,
+ .start = start,
+ .end_col = start.col + len,
+ .group = group,
}));
}
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 4bbdaefd1f..dfe1ffdbd4 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -23,6 +23,7 @@
#include "nvim/fold.h"
#include "nvim/garray.h"
#include "nvim/getchar.h"
+#include "nvim/globals.h"
#include "nvim/hashtab.h"
#include "nvim/main.h"
#include "nvim/mark.h"
@@ -62,7 +63,7 @@
#define NOWIN (win_T *)-1 // non-existing window
-# define ROWS_AVAIL (Rows - p_ch - tabline_height())
+#define ROWS_AVAIL (Rows - p_ch - tabline_height())
/// flags for win_enter_ext()
typedef enum {
@@ -90,7 +91,7 @@ void do_window(int nchar, long Prenum, int xchar)
Prenum1 = Prenum == 0 ? 1 : Prenum;
-# define CHECK_CMDWIN \
+#define CHECK_CMDWIN \
do { \
if (cmdwin_type != 0) { \
EMSG(_(e_cmdwin)); \
@@ -298,8 +299,8 @@ newwindow:
tabpage_T *oldtab = curtab;
tabpage_T *newtab;
- /* First create a new tab with the window, then go back to
- * the old tab and close the window there. */
+ // First create a new tab with the window, then go back to
+ // the old tab and close the window there.
wp = curwin;
if (win_new_tabpage((int)Prenum, NULL) == OK
&& valid_tabpage(oldtab)) {
@@ -519,8 +520,8 @@ wingotofile:
postponed_split = -1;
}
- /* Execute the command right here, required when
- * "wincmd g}" was used in a function. */
+ // Execute the command right here, required when
+ // "wincmd g}" was used in a function.
do_nv_ident('g', xchar);
break;
@@ -853,12 +854,12 @@ void ui_ext_win_position(win_T *wp)
bool east = c.anchor & kFloatAnchorEast;
bool south = c.anchor & kFloatAnchorSouth;
- int comp_row = (int)row - (south ? wp->w_height : 0);
- int comp_col = (int)col - (east ? wp->w_width : 0);
+ int comp_row = (int)row - (south ? wp->w_height_outer : 0);
+ int comp_col = (int)col - (east ? wp->w_width_outer : 0);
comp_row += grid->comp_row;
comp_col += grid->comp_col;
- comp_row = MAX(MIN(comp_row, Rows-wp->w_height_outer-1), 0);
- comp_col = MAX(MIN(comp_col, Columns-wp->w_width_outer), 0);
+ comp_row = MAX(MIN(comp_row, Rows - wp->w_height_outer - 1), 0);
+ comp_col = MAX(MIN(comp_col, Columns - wp->w_width_outer), 0);
wp->w_winrow = comp_row;
wp->w_wincol = comp_col;
bool valid = (wp->w_redr_type == 0);
@@ -922,8 +923,8 @@ int win_split(int size, int flags)
return FAIL;
}
- /* When creating the help window make a snapshot of the window layout.
- * Otherwise clear the snapshot, it's now invalid. */
+ // When creating the help window make a snapshot of the window layout.
+ // Otherwise clear the snapshot, it's now invalid.
if (flags & WSP_HELP) {
make_snapshot(SNAP_HELP_IDX);
} else {
@@ -1260,8 +1261,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
frame_append(curfrp, frp);
}
- /* Set w_fraction now so that the cursor keeps the same relative
- * vertical position. */
+ // Set w_fraction now so that the cursor keeps the same relative
+ // vertical position.
if (!did_set_fraction) {
set_fraction(oldwin);
}
@@ -1287,8 +1288,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
}
frp->fr_height = curfrp->fr_height;
- /* "new_size" of the current window goes to the new window, use
- * one column for the vertical separator */
+ // "new_size" of the current window goes to the new window, use
+ // one column for the vertical separator
win_new_width(wp, new_size);
if (before) {
wp->w_vsep_width = 1;
@@ -1328,8 +1329,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
}
frp->fr_width = curfrp->fr_width;
- /* "new_size" of the current window goes to the new window, use
- * one row for the status line */
+ // "new_size" of the current window goes to the new window, use
+ // one row for the status line
win_new_height(wp, new_size);
if (flags & (WSP_TOP | WSP_BOT)) {
int new_fr_height = curfrp->fr_height - new_size;
@@ -1388,8 +1389,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
'v');
}
- /* Don't change the window height/width to 'winheight' / 'winwidth' if a
- * size was given. */
+ // Don't change the window height/width to 'winheight' / 'winwidth' if a
+ // size was given.
if (flags & WSP_VERT) {
i = p_wiw;
if (size != 0) {
@@ -1462,6 +1463,8 @@ static void win_init(win_T *newp, win_T *oldp, int flags)
}
newp->w_localdir = (oldp->w_localdir == NULL)
? NULL : vim_strsave(oldp->w_localdir);
+ newp->w_prevdir = (oldp->w_prevdir == NULL)
+ ? NULL : vim_strsave(oldp->w_prevdir);
// copy tagstack and folds
for (i = 0; i < oldp->w_tagstacklen; i++) {
@@ -1589,8 +1592,8 @@ int make_windows(int count, bool vertical)
int todo;
if (vertical) {
- /* Each windows needs at least 'winminwidth' lines and a separator
- * column. */
+ // Each windows needs at least 'winminwidth' lines and a separator
+ // column.
maxcount = (curwin->w_width + curwin->w_vsep_width
- (p_wiw - p_wmw)) / (p_wmw + 1);
} else {
@@ -1679,8 +1682,8 @@ static void win_exchange(long Prenum)
frp = curwin->w_frame->fr_prev;
}
- /* We can only exchange a window with another window, not with a frame
- * containing windows. */
+ // We can only exchange a window with another window, not with a frame
+ // containing windows.
if (frp == NULL || frp->fr_win == NULL || frp->fr_win == curwin) {
return;
}
@@ -1890,8 +1893,8 @@ void win_move_after(win_T *win1, win_T *win2)
win1->w_status_height = win2->w_status_height;
win2->w_status_height = height;
if (win1->w_vsep_width == 1) {
- /* Remove the vertical separator from win1, add it to the last
- * window, win2. Adjust the frame widths. */
+ // Remove the vertical separator from win1, add it to the last
+ // window, win2. Adjust the frame widths.
win2->w_vsep_width = 1;
win2->w_frame->fr_width += 1;
win1->w_vsep_width = 0;
@@ -1955,8 +1958,8 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
bool hnc;
if (topfr->fr_layout == FR_LEAF) {
- /* Set the width/height of this frame.
- * Redraw when size or position changes */
+ // Set the width/height of this frame.
+ // Redraw when size or position changes
if (topfr->fr_height != height || topfr->fr_win->w_winrow != row
|| topfr->fr_width != width ||
topfr->fr_win->w_wincol != col) {
@@ -2028,8 +2031,8 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
} else if (totwincount > 1
&& (room + (totwincount - 2))
/ (totwincount - 1) > p_wiw) {
- /* Can make all windows wider than 'winwidth', spread
- * the room equally. */
+ // Can make all windows wider than 'winwidth', spread
+ // the room equally.
next_curwin_size = (room + p_wiw
+ (totwincount - 1) * p_wmw
+ (totwincount - 1)) / totwincount;
@@ -2084,8 +2087,8 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
new_size += n;
}
- /* Skip frame that is full width when splitting or closing a
- * window, unless equalizing all frames. */
+ // Skip frame that is full width when splitting or closing a
+ // window, unless equalizing all frames.
if (!current || dir != 'v' || topfr->fr_parent != NULL
|| (new_size != fr->fr_width)
|| frame_has_win(fr, next_curwin)) {
@@ -2120,8 +2123,8 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
m = frame_minheight(topfr, next_curwin);
room = height - m;
if (room < 0) {
- /* The room is less then 'winheight', use all space for the
- * current window. */
+ // The room is less then 'winheight', use all space for the
+ // current window.
next_curwin_size = p_wh + room;
room = 0;
} else {
@@ -2159,8 +2162,8 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
} else if (totwincount > 1
&& (room + (totwincount - 2))
/ (totwincount - 1) > p_wh) {
- /* can make all windows higher than 'winheight',
- * spread the room equally. */
+ // can make all windows higher than 'winheight',
+ // spread the room equally.
next_curwin_size = (room + p_wh
+ (totwincount - 1) * p_wmh
+ (totwincount - 1)) / totwincount;
@@ -2214,8 +2217,8 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
}
new_size += n;
}
- /* Skip frame that is full width when splitting or closing a
- * window, unless equalizing all frames. */
+ // Skip frame that is full width when splitting or closing a
+ // window, unless equalizing all frames.
if (!current || dir != 'h' || topfr->fr_parent != NULL
|| (new_size != fr->fr_height)
|| frame_has_win(fr, next_curwin)) {
@@ -2263,8 +2266,8 @@ void close_windows(buf_T *buf, int keep_curwin)
&& !(wp->w_closing || wp->w_buffer->b_locked > 0)) {
win_close_othertab(wp, false, tp);
- /* Start all over, the tab page may be closed and
- * autocommands may change the window layout. */
+ // Start all over, the tab page may be closed and
+ // autocommands may change the window layout.
nexttp = first_tabpage;
break;
}
@@ -2630,8 +2633,8 @@ int win_close(win_T *win, bool free_buf)
*/
last_status(false);
- /* After closing the help window, try restoring the window layout from
- * before it was opened. */
+ // After closing the help window, try restoring the window layout from
+ // before it was opened.
if (help_window) {
restore_snapshot(SNAP_HELP_IDX, close_curwin);
}
@@ -2703,8 +2706,8 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, false);
}
- /* Careful: Autocommands may have closed the tab page or made it the
- * current tab page. */
+ // Careful: Autocommands may have closed the tab page or made it the
+ // current tab page.
for (ptp = first_tabpage; ptp != NULL && ptp != tp; ptp = ptp->tp_next) {
;
}
@@ -2863,9 +2866,9 @@ win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp)
frame_remove(frp_close);
if (frp_close->fr_parent->fr_layout == FR_COL) {
- /* When 'winfixheight' is set, try to find another frame in the column
- * (as close to the closed frame as possible) to distribute the height
- * to. */
+ // When 'winfixheight' is set, try to find another frame in the column
+ // (as close to the closed frame as possible) to distribute the height
+ // to.
if (frp2->fr_win != NULL && frp2->fr_win->w_p_wfh) {
frp = frp_close->fr_prev;
frp3 = frp_close->fr_next;
@@ -2922,8 +2925,8 @@ win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp)
*dirp = 'h';
}
- /* If rows/columns go to a window below/right its positions need to be
- * updated. Can only be done after the sizes have been updated. */
+ // If rows/columns go to a window below/right its positions need to be
+ // updated. Can only be done after the sizes have been updated.
if (frp2 == frp_close->fr_next) {
int row = win->w_winrow;
int col = win->w_wincol;
@@ -2932,8 +2935,8 @@ win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp)
}
if (frp2->fr_next == NULL && frp2->fr_prev == NULL) {
- /* There is no other frame in this list, move its info to the parent
- * and remove it. */
+ // There is no other frame in this list, move its info to the parent
+ // and remove it.
frp2->fr_parent->fr_layout = frp2->fr_layout;
frp2->fr_parent->fr_child = frp2->fr_child;
FOR_ALL_FRAMES(frp, frp2->fr_child) {
@@ -2951,8 +2954,8 @@ win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp)
frp2 = frp->fr_parent;
if (frp2 != NULL && frp2->fr_layout == frp->fr_layout) {
- /* The frame above the parent has the same layout, have to merge
- * the frames into this list. */
+ // The frame above the parent has the same layout, have to merge
+ // the frames into this list.
if (frp2->fr_child == frp) {
frp2->fr_child = frp->fr_child;
}
@@ -3641,8 +3644,8 @@ static int win_alloc_firstwin(win_T *oldwin)
{
curwin = win_alloc(NULL, false);
if (oldwin == NULL) {
- /* Very first window, need to create an empty buffer for it and
- * initialize from scratch. */
+ // Very first window, need to create an empty buffer for it and
+ // initialize from scratch.
curbuf = buflist_new(NULL, NULL, 1L, BLN_LISTED);
if (curbuf == NULL) {
return FAIL;
@@ -3732,6 +3735,7 @@ void free_tabpage(tabpage_T *tp)
}
xfree(tp->tp_localdir);
+ xfree(tp->tp_prevdir);
xfree(tp);
}
@@ -4014,10 +4018,10 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, bool trigger_enter_a
const int row = win_comp_pos(); // recompute w_winrow for all windows
diff_need_scrollbind = true;
- /* The tabpage line may have appeared or disappeared, may need to resize
- * the frames for that. When the Vim window was resized need to update
- * frame sizes too. Use the stored value of p_ch, so that it can be
- * different for each tab page. */
+ // The tabpage line may have appeared or disappeared, may need to resize
+ // the frames for that. When the Vim window was resized need to update
+ // frame sizes too. Use the stored value of p_ch, so that it can be
+ // different for each tab page.
if (p_ch != curtab->tp_ch_used) {
clear_cmdline = true;
}
@@ -4112,8 +4116,8 @@ void goto_tabpage(int n)
tp = curtab->tp_next;
}
} else if (n < 0) {
- /* "gT": go to previous tab page, wrap around end. "N gT" repeats
- * this N times. */
+ // "gT": go to previous tab page, wrap around end. "N gT" repeats
+ // this N times.
ttp = curtab;
for (i = n; i < 0; ++i) {
for (tp = first_tabpage; tp->tp_next != ttp && tp->tp_next != NULL;
@@ -4540,9 +4544,9 @@ static void win_enter_ext(win_T *const wp, const int flags)
}
}
if (os_chdir(new_dir) == 0) {
- if (!p_acd && !strequal(new_dir, cwd)) {
+ if (!p_acd && pathcmp(new_dir, cwd, -1) != 0) {
do_autocmd_dirchanged(new_dir, curwin->w_localdir
- ? kCdScopeWindow : kCdScopeTab, true);
+ ? kCdScopeWindow : kCdScopeTabpage, kCdCauseWindow);
}
shorten_fnames(true);
}
@@ -4550,8 +4554,8 @@ static void win_enter_ext(win_T *const wp, const int flags)
// Window doesn't have a local directory and we are not in the global
// directory: Change to the global directory.
if (os_chdir((char *)globaldir) == 0) {
- if (!p_acd && !strequal((char *)globaldir, cwd)) {
- do_autocmd_dirchanged((char *)globaldir, kCdScopeGlobal, true);
+ if (!p_acd && pathcmp((char *)globaldir, cwd, -1) != 0) {
+ do_autocmd_dirchanged((char *)globaldir, kCdScopeGlobal, kCdCauseWindow);
}
}
XFREE_CLEAR(globaldir);
@@ -4677,9 +4681,9 @@ static win_T *win_alloc(win_T *after, bool hidden)
new_wp->w_vars = tv_dict_alloc();
init_var_dict(new_wp->w_vars, &new_wp->w_winvar, VAR_SCOPE);
- /* Don't execute autocommands while the window is not properly
- * initialized yet. gui_create_scrollbar() may trigger a FocusGained
- * event. */
+ // Don't execute autocommands while the window is not properly
+ // initialized yet. gui_create_scrollbar() may trigger a FocusGained
+ // event.
block_autocmds();
/*
* link the window in the window list
@@ -4742,8 +4746,8 @@ static void win_free(win_T *wp, tabpage_T *tp)
// reduce the reference count to the argument list.
alist_unlink(wp->w_alist);
- /* Don't execute autocommands while the window is halfway being deleted.
- * gui_mch_destroy_scrollbar() may trigger a FocusGained event. */
+ // Don't execute autocommands while the window is halfway being deleted.
+ // gui_mch_destroy_scrollbar() may trigger a FocusGained event.
block_autocmds();
clear_winopt(&wp->w_onebuf_opt);
@@ -4770,6 +4774,7 @@ static void win_free(win_T *wp, tabpage_T *tp)
}
xfree(wp->w_localdir);
+ xfree(wp->w_prevdir);
/* Remove the window from the b_wininfo lists, it may happen that the
* freed memory is re-used for another window. */
@@ -5200,8 +5205,8 @@ static void frame_setheight(frame_T *curfrp, int height)
frame_new_height(curfrp, height, false, false);
}
} else if (curfrp->fr_parent->fr_layout == FR_ROW) {
- /* Row of frames: Also need to resize frames left and right of this
- * one. First check for the minimal height of these. */
+ // Row of frames: Also need to resize frames left and right of this
+ // one. First check for the minimal height of these.
h = frame_minheight(curfrp->fr_parent, NULL);
if (height < h) {
height = h;
@@ -5261,13 +5266,13 @@ static void frame_setheight(frame_T *curfrp, int height)
*/
take = height - curfrp->fr_height;
- /* If there is not enough room, also reduce the height of a window
- * with 'winfixheight' set. */
+ // If there is not enough room, also reduce the height of a window
+ // with 'winfixheight' set.
if (height > room + room_cmdline - room_reserved) {
room_reserved = room + room_cmdline - height;
}
- /* If there is only a 'winfixheight' window and making the
- * window smaller, need to make the other window taller. */
+ // If there is only a 'winfixheight' window and making the
+ // window smaller, need to make the other window taller.
if (take < 0 && room - curfrp->fr_height < room_reserved) {
room_reserved = 0;
}
@@ -5342,8 +5347,8 @@ void win_setwidth(int width)
void win_setwidth_win(int width, win_T *wp)
{
- /* Always keep current window at least one column wide, even when
- * 'winminwidth' is zero. */
+ // Always keep current window at least one column wide, even when
+ // 'winminwidth' is zero.
if (wp == curwin) {
if (width < p_wmw) {
width = p_wmw;
@@ -5394,8 +5399,8 @@ static void frame_setwidth(frame_T *curfrp, int width)
}
if (curfrp->fr_parent->fr_layout == FR_COL) {
- /* Column of frames: Also need to resize frames above and below of
- * this one. First check for the minimal width of these. */
+ // Column of frames: Also need to resize frames above and below of
+ // this one. First check for the minimal width of these.
w = frame_minwidth(curfrp->fr_parent, NULL);
if (width < w) {
width = w;
@@ -5442,13 +5447,13 @@ static void frame_setwidth(frame_T *curfrp, int width)
*/
take = width - curfrp->fr_width;
- /* If there is not enough room, also reduce the width of a window
- * with 'winfixwidth' set. */
+ // If there is not enough room, also reduce the width of a window
+ // with 'winfixwidth' set.
if (width > room - room_reserved) {
room_reserved = room - width;
}
- /* If there is only a 'winfixwidth' window and making the
- * window smaller, need to make the other window narrower. */
+ // If there is only a 'winfixwidth' window and making the
+ // window smaller, need to make the other window narrower.
if (take < 0 && room - curfrp->fr_width < room_reserved) {
room_reserved = 0;
}
@@ -5557,8 +5562,8 @@ void win_drag_status_line(win_T *dragwin, int offset)
curfr = fr;
if (fr != topframe) { // more than one window
fr = fr->fr_parent;
- /* When the parent frame is not a column of frames, its parent should
- * be. */
+ // When the parent frame is not a column of frames, its parent should
+ // be.
if (fr->fr_layout != FR_COL) {
curfr = fr;
if (fr != topframe) { // only a row of windows, may drag statusline
@@ -6009,9 +6014,9 @@ void command_height(void)
frame_T *frp;
int old_p_ch = curtab->tp_ch_used;
- /* Use the value of p_ch that we remembered. This is needed for when the
- * GUI starts up, we can't be sure in what order things happen. And when
- * p_ch was changed in another tab page. */
+ // Use the value of p_ch that we remembered. This is needed for when the
+ // GUI starts up, we can't be sure in what order things happen. And when
+ // p_ch was changed in another tab page.
curtab->tp_ch_used = p_ch;
// Find bottom frame with width of screen.
@@ -6270,8 +6275,8 @@ static void last_status_rec(frame_T *fr, bool statusline)
EMSG(_(e_noroom));
return;
}
- /* In a column of frames: go to frame above. If already at
- * the top or in a row of frames: go to parent. */
+ // In a column of frames: go to frame above. If already at
+ // the top or in a row of frames: go to parent.
if (fp->fr_parent->fr_layout == FR_COL && fp->fr_prev != NULL) {
fp = fp->fr_prev;
} else {
@@ -6693,7 +6698,7 @@ int match_add(win_T *wp, const char *const grp, const char *const pat, int prio,
cur = cur->next;
}
}
- if ((hlg_id = syn_check_group((const char_u *)grp, strlen(grp))) == 0) {
+ if ((hlg_id = syn_check_group(grp, strlen(grp))) == 0) {
return -1;
}
if (pat != NULL && (regprog = vim_regcomp((char_u *)pat, RE_MAGIC)) == NULL) {
@@ -7058,13 +7063,13 @@ void win_id2tabwin(typval_T *const argvars, typval_T *const rettv)
tv_list_append_number(list, winnr);
}
-win_T * win_id2wp(typval_T *argvars)
+win_T *win_id2wp(typval_T *argvars)
{
return win_id2wp_tp(argvars, NULL);
}
// Return the window and tab pointer of window "id".
-win_T * win_id2wp_tp(typval_T *argvars, tabpage_T **tpp)
+win_T *win_id2wp_tp(typval_T *argvars, tabpage_T **tpp)
{
int id = tv_get_number(&argvars[0]);
diff --git a/src/nvim/window.h b/src/nvim/window.h
index 82b3fe5e88..7e465a9f08 100644
--- a/src/nvim/window.h
+++ b/src/nvim/window.h
@@ -5,11 +5,11 @@
#include "nvim/buffer_defs.h"
-/* Values for file_name_in_line() */
-#define FNAME_MESS 1 /* give error message */
-#define FNAME_EXP 2 /* expand to path */
-#define FNAME_HYP 4 /* check for hypertext link */
-#define FNAME_INCL 8 /* apply 'includeexpr' */
+// Values for file_name_in_line()
+#define FNAME_MESS 1 // give error message
+#define FNAME_EXP 2 // expand to path
+#define FNAME_HYP 4 // check for hypertext link
+#define FNAME_INCL 8 // apply 'includeexpr'
#define FNAME_REL 16 /* ".." and "./" are relative to the (current)
file instead of the current directory */
#define FNAME_UNESC 32 // remove backslashes used for escaping
@@ -17,20 +17,20 @@
/*
* arguments for win_split()
*/
-#define WSP_ROOM 1 /* require enough room */
-#define WSP_VERT 2 /* split vertically */
-#define WSP_TOP 4 /* window at top-left of shell */
-#define WSP_BOT 8 /* window at bottom-right of shell */
-#define WSP_HELP 16 /* creating the help window */
-#define WSP_BELOW 32 /* put new window below/right */
-#define WSP_ABOVE 64 /* put new window above/left */
-#define WSP_NEWLOC 128 /* don't copy location list */
+#define WSP_ROOM 1 // require enough room
+#define WSP_VERT 2 // split vertically
+#define WSP_TOP 4 // window at top-left of shell
+#define WSP_BOT 8 // window at bottom-right of shell
+#define WSP_HELP 16 // creating the help window
+#define WSP_BELOW 32 // put new window below/right
+#define WSP_ABOVE 64 // put new window above/left
+#define WSP_NEWLOC 128 // don't copy location list
/*
* Minimum screen size
*/
-#define MIN_COLUMNS 12 /* minimal columns for screen */
-#define MIN_LINES 2 /* minimal lines for screen */
+#define MIN_COLUMNS 12 // minimal columns for screen
+#define MIN_LINES 2 // minimal lines for screen
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "window.h.generated.h"
diff --git a/contrib/uncrustify.cfg b/src/uncrustify.cfg
index d82bb47ec3..13d1f472ed 100644
--- a/contrib/uncrustify.cfg
+++ b/src/uncrustify.cfg
@@ -1,4 +1,4 @@
-# Uncrustify-0.73.0-164-c9a58467
+# Uncrustify-0.73.0-199-0dfafb27
#
# General options
@@ -44,12 +44,12 @@ disable_processing_nl_cont = false # true/false
# file.
#
# Default: *INDENT-OFF*
-disable_processing_cmt = "uncrustify:indent-off" # string
+disable_processing_cmt = "uncrustify:off" # string
# Specify the marker used in comments to (re)enable processing in a file.
#
# Default: *INDENT-ON*
-enable_processing_cmt = "uncrustify:indent-on" # string
+enable_processing_cmt = "uncrustify:on" # string
# Enable parsing of digraphs.
enable_digraphs = false # true/false
@@ -196,7 +196,7 @@ sp_between_ptr_star = ignore # ignore/add/remove/force/not_defined
# Add or remove space after pointer star '*', if followed by a word.
#
# Overrides sp_type_func.
-sp_after_ptr_star = ignore # ignore/add/remove/force/not_defined
+sp_after_ptr_star = remove # ignore/add/remove/force/not_defined
# Add or remove space after pointer caret '^', if followed by a word.
sp_after_ptr_block_caret = ignore # ignore/add/remove/force/not_defined
@@ -208,7 +208,7 @@ sp_after_ptr_star_qualifier = ignore # ignore/add/remove/force/not_defined
# prototype or function definition.
#
# Overrides sp_after_ptr_star and sp_type_func.
-sp_after_ptr_star_func = ignore # ignore/add/remove/force/not_defined
+sp_after_ptr_star_func = remove # ignore/add/remove/force/not_defined
# Add or remove space after a pointer star '*' in the trailing return of a
# function prototype or function definition.
@@ -259,7 +259,7 @@ sp_before_byref_func = ignore # ignore/add/remove/force/not_defined
# following word.
#
# Default: force
-sp_after_type = ignore # ignore/add/remove/force/not_defined
+sp_after_type = force # ignore/add/remove/force/not_defined
# Add or remove space between 'decltype(...)' and word,
# brace or function call.
@@ -447,12 +447,18 @@ sp_before_ellipsis = ignore # ignore/add/remove/force/not_defined
# Add or remove space between a type and '...'.
sp_type_ellipsis = ignore # ignore/add/remove/force/not_defined
+# Add or remove space between a '*' and '...'.
+sp_ptr_type_ellipsis = ignore # ignore/add/remove/force/not_defined
+
# (D) Add or remove space between a type and '?'.
sp_type_question = ignore # ignore/add/remove/force/not_defined
# Add or remove space between ')' and '...'.
sp_paren_ellipsis = ignore # ignore/add/remove/force/not_defined
+# Add or remove space between '&&' and '...'.
+sp_byref_ellipsis = ignore # ignore/add/remove/force/not_defined
+
# Add or remove space between ')' and a qualifier such as 'const'.
sp_paren_qualifier = ignore # ignore/add/remove/force/not_defined
@@ -466,9 +472,13 @@ sp_after_class_colon = ignore # ignore/add/remove/force/not_defined
sp_before_class_colon = ignore # ignore/add/remove/force/not_defined
# Add or remove space after class constructor ':'.
+#
+# Default: add
sp_after_constr_colon = ignore # ignore/add/remove/force/not_defined
# Add or remove space before class constructor ':'.
+#
+# Default: add
sp_before_constr_colon = ignore # ignore/add/remove/force/not_defined
# Add or remove space before case ':'.
@@ -507,6 +517,12 @@ sp_sizeof_ellipsis = ignore # ignore/add/remove/force/not_defined
# Add or remove space between 'sizeof...' and '('.
sp_sizeof_ellipsis_paren = ignore # ignore/add/remove/force/not_defined
+# Add or remove space between '...' and a parameter pack.
+sp_ellipsis_parameter_pack = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between a parameter pack and '...'.
+sp_parameter_pack_ellipsis = ignore # ignore/add/remove/force/not_defined
+
# Add or remove space between 'decltype' and '('.
sp_decltype_paren = ignore # ignore/add/remove/force/not_defined
@@ -523,14 +539,21 @@ sp_inside_braces_struct = ignore # ignore/add/remove/force/not_defined
sp_inside_braces_oc_dict = ignore # ignore/add/remove/force/not_defined
# Add or remove space after open brace in an unnamed temporary
-# direct-list-initialization.
+# direct-list-initialization
+# if statement is a brace_init_lst
+# works only if sp_brace_brace is set to ignore.
sp_after_type_brace_init_lst_open = ignore # ignore/add/remove/force/not_defined
# Add or remove space before close brace in an unnamed temporary
-# direct-list-initialization.
+# direct-list-initialization
+# if statement is a brace_init_lst
+# works only if sp_brace_brace is set to ignore.
sp_before_type_brace_init_lst_close = ignore # ignore/add/remove/force/not_defined
-# Add or remove space inside an unnamed temporary direct-list-initialization.
+# Add or remove space inside an unnamed temporary direct-list-initialization
+# if statement is a brace_init_lst
+# works only if sp_brace_brace is set to ignore
+# works only if sp_before_type_brace_init_lst_close is set to ignore.
sp_inside_type_brace_init_lst = ignore # ignore/add/remove/force/not_defined
# Add or remove space inside '{' and '}'.
@@ -775,7 +798,7 @@ sp_sign = ignore # ignore/add/remove/force/not_defined
# applied, as in '(--x)' or 'y++;'.
#
# Default: remove
-sp_incdec = ignore # ignore/add/remove/force/not_defined
+sp_incdec = remove # ignore/add/remove/force/not_defined
# Add or remove space before a backslash-newline at the end of a line.
#
@@ -1084,11 +1107,16 @@ indent_class_on_colon = false # true/false
# Whether to indent the stuff after a leading class initializer colon.
indent_constr_colon = false # true/false
-# Virtual indent from the ':' for member initializers.
+# Virtual indent from the ':' for leading member initializers.
#
# Default: 2
indent_ctor_init_leading = 2 # unsigned number
+# Virtual indent from the ':' for following member initializers.
+#
+# Default: 2
+indent_ctor_init_following = 2 # unsigned number
+
# Additional indent for constructor initializer list.
# Negative values decrease indent down to the first column.
indent_ctor_init = 0 # number
@@ -2020,7 +2048,7 @@ nl_constr_colon = ignore # ignore/add/remove/force/not_defined
# Whether to collapse a two-line namespace, like 'namespace foo\n{ decl; }'
# into a single line. If true, prevents other brace newline rules from turning
-# such code into four lines.
+# such code into four lines. If true, it also preserves one-liner namespaces.
nl_namespace_two_to_one_liner = false # true/false
# Whether to remove a newline in simple unbraced if statements, turning them
@@ -2318,7 +2346,7 @@ pos_conditional = ignore # ignore/break/force/lead/trail/join/
pos_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
# The position of the comma in enum entries.
-pos_enum_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
+pos_enum_comma = trail # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
# The position of the comma in the base class list if there is more than one
# line. Affects nl_class_init_args.
@@ -3029,7 +3057,7 @@ mod_sort_oc_property_nullability_weight = 0 # number
# Add or remove indentation of preprocessor directives inside #if blocks
# at brace level 0 (file-level).
-pp_indent = ignore # ignore/add/remove/force/not_defined
+pp_indent = remove # ignore/add/remove/force/not_defined
# Whether to indent #if/#else/#endif at the brace level. If false, these are
# indented from column 1.
@@ -3044,7 +3072,7 @@ pp_indent_at_level = false # true/false
pp_indent_count = 1 # unsigned number
# Add or remove space after # based on pp_level of #if blocks.
-pp_space = ignore # ignore/add/remove/force/not_defined
+pp_space = force # ignore/add/remove/force/not_defined
# Sets the number of spaces per level added with pp_space.
pp_space_count = 0 # unsigned number
@@ -3255,29 +3283,29 @@ debug_truncate = 0 # unsigned number
# `macro-close END_MESSAGE_MAP`
#
#
-set PREPROC FUNC_API_CHECK_TEXTLOCK
-set PREPROC FUNC_API_DEPRECATED_SINCE
-set PREPROC FUNC_API_FAST
-set PREPROC FUNC_API_LUA_ONLY
-set PREPROC FUNC_API_NOEXPORT
-set PREPROC FUNC_API_REMOTE_ONLY
-set PREPROC FUNC_API_SINCE
-set PREPROC FUNC_ATTR_ALWAYS_INLINE
-set PREPROC FUNC_ATTR_CONST
-set PREPROC FUNC_ATTR_MALLOC
-set PREPROC FUNC_ATTR_NONNULL_ALL
-set PREPROC FUNC_ATTR_NONNULL_ARG
-set PREPROC FUNC_ATTR_NONNULL_RET
-set PREPROC FUNC_ATTR_NORETURN
-set PREPROC FUNC_ATTR_NO_SANITIZE_UNDEFINED
-set PREPROC FUNC_ATTR_PRINTF
-set PREPROC FUNC_ATTR_PURE
-set PREPROC FUNC_ATTR_UNUSED
-set PREPROC FUNC_ATTR_WARN_UNUSED_RESULT
-set PREPROC REAL_FATTR_ALWAYS_INLINE
-set PREPROC REAL_FATTR_CONST
-set PREPROC REAL_FATTR_NONNULL_ALL
-set PREPROC REAL_FATTR_PURE
-set PREPROC REAL_FATTR_WARN_UNUSED_RESULT
-# option(s) with 'not default' value: 61
+set QUESTION FUNC_API_CHECK_TEXTLOCK
+set QUESTION FUNC_API_DEPRECATED_SINCE
+set QUESTION FUNC_API_FAST
+set QUESTION FUNC_API_LUA_ONLY
+set QUESTION FUNC_API_NOEXPORT
+set QUESTION FUNC_API_REMOTE_ONLY
+set QUESTION FUNC_API_SINCE
+set QUESTION FUNC_ATTR_ALWAYS_INLINE
+set QUESTION FUNC_ATTR_CONST
+set QUESTION FUNC_ATTR_MALLOC
+set QUESTION FUNC_ATTR_NONNULL_ALL
+set QUESTION FUNC_ATTR_NONNULL_ARG
+set QUESTION FUNC_ATTR_NONNULL_RET
+set QUESTION FUNC_ATTR_NORETURN
+set QUESTION FUNC_ATTR_NO_SANITIZE_UNDEFINED
+set QUESTION FUNC_ATTR_PRINTF
+set QUESTION FUNC_ATTR_PURE
+set QUESTION FUNC_ATTR_UNUSED
+set QUESTION FUNC_ATTR_WARN_UNUSED_RESULT
+set QUESTION REAL_FATTR_ALWAYS_INLINE
+set QUESTION REAL_FATTR_CONST
+set QUESTION REAL_FATTR_NONNULL_ALL
+set QUESTION REAL_FATTR_PURE
+set QUESTION REAL_FATTR_WARN_UNUSED_RESULT
+# option(s) with 'not default' value: 66
#
diff --git a/test/config/paths.lua.in b/test/config/paths.lua.in
index 7fe5d8ad80..e3979981ba 100644
--- a/test/config/paths.lua.in
+++ b/test/config/paths.lua.in
@@ -19,5 +19,6 @@ if module.test_luajit_prg == '' then
end
end
table.insert(module.include_paths, "${CMAKE_BINARY_DIR}/include")
+table.insert(module.include_paths, "${CMAKE_BINARY_DIR}/src/nvim/auto")
return module
diff --git a/test/functional/api/buffer_spec.lua b/test/functional/api/buffer_spec.lua
index 81fad206da..01fcfab543 100644
--- a/test/functional/api/buffer_spec.lua
+++ b/test/functional/api/buffer_spec.lua
@@ -707,4 +707,59 @@ describe('api/buf', function()
eq({3, 0}, curbuf('get_mark', 'v'))
end)
end)
+
+ describe('nvim_buf_set_mark', function()
+ it('works with buffer local marks', function()
+ curbufmeths.set_lines(-1, -1, true, {'a', 'bit of', 'text'})
+ eq(true, curbufmeths.set_mark('z', 1, 1))
+ eq({1, 1}, curbufmeths.get_mark('z'))
+ end)
+ it('works with file/uppercase marks', function()
+ curbufmeths.set_lines(-1, -1, true, {'a', 'bit of', 'text'})
+ eq(true, curbufmeths.set_mark('Z', 3, 1))
+ eq({3, 1}, curbufmeths.get_mark('Z'))
+ end)
+ it('fails when invalid marks names are used', function()
+ eq(false, pcall(curbufmeths.set_mark, '!', 1, 0))
+ eq(false, pcall(curbufmeths.set_mark, 'fail', 1, 0))
+ end)
+ it('fails when invalid buffer number is used', function()
+ eq(false, pcall(meths.buf_set_mark, 99, 'a', 1, 1))
+ end)
+ end)
+
+ describe('nvim_buf_del_mark', function()
+ it('works with buffer local marks', function()
+ curbufmeths.set_lines(-1, -1, true, {'a', 'bit of', 'text'})
+ curbufmeths.set_mark('z', 3, 1)
+ eq(true, curbufmeths.del_mark('z'))
+ eq({0, 0}, curbufmeths.get_mark('z'))
+ end)
+ it('works with file/uppercase marks', function()
+ curbufmeths.set_lines(-1, -1, true, {'a', 'bit of', 'text'})
+ curbufmeths.set_mark('Z', 3, 3)
+ eq(true, curbufmeths.del_mark('Z'))
+ eq({0, 0}, curbufmeths.get_mark('Z'))
+ end)
+ it('returns false in marks not set in this buffer', function()
+ local abuf = meths.create_buf(false,true)
+ bufmeths.set_lines(abuf, -1, -1, true, {'a', 'bit of', 'text'})
+ bufmeths.set_mark(abuf, 'A', 2, 2)
+ eq(false, curbufmeths.del_mark('A'))
+ eq({2, 2}, bufmeths.get_mark(abuf, 'A'))
+ end)
+ it('returns false if mark was not deleted', function()
+ curbufmeths.set_lines(-1, -1, true, {'a', 'bit of', 'text'})
+ curbufmeths.set_mark('z', 3, 1)
+ eq(true, curbufmeths.del_mark('z'))
+ eq(false, curbufmeths.del_mark('z')) -- Mark was already deleted
+ end)
+ it('fails when invalid marks names are used', function()
+ eq(false, pcall(curbufmeths.del_mark, '!'))
+ eq(false, pcall(curbufmeths.del_mark, 'fail'))
+ end)
+ it('fails when invalid buffer number is used', function()
+ eq(false, pcall(meths.buf_del_mark, 99, 'a'))
+ end)
+ end)
end)
diff --git a/test/functional/api/command_spec.lua b/test/functional/api/command_spec.lua
index 37331d11c7..6f929ad1ca 100644
--- a/test/functional/api/command_spec.lua
+++ b/test/functional/api/command_spec.lua
@@ -21,7 +21,7 @@ describe('nvim_get_commands', function()
it('validates input', function()
eq('builtin=true not implemented', pcall_err(meths.get_commands,
{builtin=true}))
- eq('unexpected key: foo', pcall_err(meths.get_commands,
+ eq("Invalid key: 'foo'", pcall_err(meths.get_commands,
{foo='blah'}))
end)
diff --git a/test/functional/api/keymap_spec.lua b/test/functional/api/keymap_spec.lua
index 4194945645..dd8eef7ca0 100644
--- a/test/functional/api/keymap_spec.lua
+++ b/test/functional/api/keymap_spec.lua
@@ -436,16 +436,16 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
end)
it('error on invalid optnames', function()
- eq('Invalid key: silentt',
+ eq("Invalid key: 'silentt'",
pcall_err(meths.set_keymap, 'n', 'lhs', 'rhs', {silentt = true}))
- eq('Invalid key: sidd',
+ eq("Invalid key: 'sidd'",
pcall_err(meths.set_keymap, 'n', 'lhs', 'rhs', {sidd = false}))
- eq('Invalid key: nowaiT',
+ eq("Invalid key: 'nowaiT'",
pcall_err(meths.set_keymap, 'n', 'lhs', 'rhs', {nowaiT = false}))
end)
it('error on <buffer> option key', function()
- eq('Invalid key: buffer',
+ eq("Invalid key: 'buffer'",
pcall_err(meths.set_keymap, 'n', 'lhs', 'rhs', {buffer = true}))
end)
@@ -454,8 +454,8 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
-- note: need '%' to escape hyphens, which have special meaning in lua
it('throws an error when given non-boolean value for '..opt, function()
local opts = {}
- opts[opt] = 2
- eq('Gave non-boolean value for an opt: '..opt,
+ opts[opt] = 'fooo'
+ eq(opt..' is not a boolean',
pcall_err(meths.set_keymap, 'n', 'lhs', 'rhs', opts))
end)
end
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index ffef6a6066..c95c24fabe 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -12,14 +12,17 @@ local funcs = helpers.funcs
local iswin = helpers.iswin
local meths = helpers.meths
local matches = helpers.matches
+local mkdir_p = helpers.mkdir_p
local ok, nvim_async, feed = helpers.ok, helpers.nvim_async, helpers.feed
local is_os = helpers.is_os
local parse_context = helpers.parse_context
local request = helpers.request
+local rmdir = helpers.rmdir
local source = helpers.source
local next_msg = helpers.next_msg
local tmpname = helpers.tmpname
local write_file = helpers.write_file
+local exec_lua = helpers.exec_lua
local pcall_err = helpers.pcall_err
local format_string = helpers.format_string
@@ -89,6 +92,14 @@ describe('API', function()
nvim('exec', 'set nowrap', false)
eq('nowrap\n\tLast set from anonymous :source',
nvim('exec', 'verbose set wrap?', true))
+
+ -- Using script var to force creation of a script item
+ nvim('exec', [[
+ let s:a = 1
+ set nowrap
+ ]], false)
+ eq('nowrap\n\tLast set from anonymous :source (script id 1)',
+ nvim('exec', 'verbose set wrap?', true))
end)
it('multiline input', function()
@@ -130,6 +141,43 @@ describe('API', function()
-- try no spaces before continuations to catch off-by-one error
nvim('exec', 'let ab = #{\n\\a: 98,\n"\\ b: 2\n\\}', false)
eq({a = 98}, request('nvim_eval', 'g:ab'))
+
+ -- Script scope (s:)
+ eq('ahoy! script-scoped varrrrr', nvim('exec', [[
+ let s:pirate = 'script-scoped varrrrr'
+ function! s:avast_ye_hades(s) abort
+ return a:s .. ' ' .. s:pirate
+ endfunction
+ echo <sid>avast_ye_hades('ahoy!')
+ ]], true))
+
+ eq('ahoy! script-scoped varrrrr', nvim('exec', [[
+ let s:pirate = 'script-scoped varrrrr'
+ function! Avast_ye_hades(s) abort
+ return a:s .. ' ' .. s:pirate
+ endfunction
+ echo nvim_exec('echo Avast_ye_hades(''ahoy!'')', 1)
+ ]], true))
+
+ eq('Vim(call):E5555: API call: Vim(echo):E121: Undefined variable: s:pirate',
+ pcall_err(request, 'nvim_exec', [[
+ let s:pirate = 'script-scoped varrrrr'
+ call nvim_exec('echo s:pirate', 1)
+ ]], false))
+
+ -- Script items are created only on script var access
+ eq('1\n0', nvim('exec', [[
+ echo expand("<SID>")->empty()
+ let s:a = 123
+ echo expand("<SID>")->empty()
+ ]], true))
+
+ eq('1\n0', nvim('exec', [[
+ echo expand("<SID>")->empty()
+ function s:a() abort
+ endfunction
+ echo expand("<SID>")->empty()
+ ]], true))
end)
it('non-ASCII input', function()
@@ -1117,7 +1165,7 @@ describe('API', function()
describe('nvim_get_context', function()
it('validates args', function()
- eq('unexpected key: blah',
+ eq("Invalid key: 'blah'",
pcall_err(nvim, 'get_context', {blah={}}))
eq('invalid value for key: types',
pcall_err(nvim, 'get_context', {types=42}))
@@ -1574,6 +1622,18 @@ describe('API', function()
end)
describe('nvim_list_runtime_paths', function()
+ setup(function()
+ local pathsep = helpers.get_pathsep()
+ mkdir_p('Xtest'..pathsep..'a')
+ mkdir_p('Xtest'..pathsep..'b')
+ end)
+ teardown(function()
+ rmdir 'Xtest'
+ end)
+ before_each(function()
+ meths.set_current_dir 'Xtest'
+ end)
+
it('returns nothing with empty &runtimepath', function()
meths.set_option('runtimepath', '')
eq({}, meths.list_runtime_paths())
@@ -1601,8 +1661,7 @@ describe('API', function()
local long_path = ('/a'):rep(8192)
meths.set_option('runtimepath', long_path)
local paths_list = meths.list_runtime_paths()
- neq({long_path}, paths_list)
- eq({long_path:sub(1, #(paths_list[1]))}, paths_list)
+ eq({}, paths_list)
end)
end)
@@ -2206,6 +2265,9 @@ describe('API', function()
[2] = {background = tonumber('0xffff40'), bg_indexed = true};
[3] = {background = Screen.colors.Plum1, fg_indexed = true, foreground = tonumber('0x00e000')};
[4] = {bold = true, reverse = true, background = Screen.colors.Plum1};
+ [5] = {foreground = Screen.colors.Blue, background = Screen.colors.LightMagenta, bold = true};
+ [6] = {bold = true};
+ [7] = {reverse = true, background = Screen.colors.LightMagenta};
})
end)
@@ -2253,5 +2315,203 @@ describe('API', function()
|
]]}
end)
+
+ it('can handle input', function()
+ screen:try_resize(50, 10)
+ eq({3, 2}, exec_lua [[
+ buf = vim.api.nvim_create_buf(1,1)
+
+ stream = ''
+ do_the_echo = false
+ function input(_,t1,b1,data)
+ stream = stream .. data
+ _G.vals = {t1, b1}
+ if do_the_echo then
+ vim.api.nvim_chan_send(t1, data)
+ end
+ end
+
+ term = vim.api.nvim_open_term(buf, {on_input=input})
+ vim.api.nvim_open_win(buf, true, {width=40, height=5, row=1, col=1, relative='editor'})
+ return {term, buf}
+ ]])
+
+ screen:expect{grid=[[
+ |
+ {0:~}{1:^ }{0: }|
+ {0:~}{1: }{0: }|
+ {0:~}{1: }{0: }|
+ {0:~}{1: }{0: }|
+ {0:~}{1: }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]]}
+
+ feed 'iba<c-x>bla'
+ screen:expect{grid=[[
+ |
+ {0:~}{7: }{1: }{0: }|
+ {0:~}{1: }{0: }|
+ {0:~}{1: }{0: }|
+ {0:~}{1: }{0: }|
+ {0:~}{1: }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {6:-- TERMINAL --} |
+ ]]}
+
+ eq('ba\024bla', exec_lua [[ return stream ]])
+ eq({3,2}, exec_lua [[ return vals ]])
+
+ exec_lua [[ do_the_echo = true ]]
+ feed 'herrejösses!'
+
+ screen:expect{grid=[[
+ |
+ {0:~}{1:herrejösses!}{7: }{1: }{0: }|
+ {0:~}{1: }{0: }|
+ {0:~}{1: }{0: }|
+ {0:~}{1: }{0: }|
+ {0:~}{1: }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {6:-- TERMINAL --} |
+ ]]}
+ eq('ba\024blaherrejösses!', exec_lua [[ return stream ]])
+ end)
+ end)
+
+ describe('nvim_del_mark', function()
+ it('works', function()
+ local buf = meths.create_buf(false,true)
+ meths.buf_set_lines(buf, -1, -1, true, {'a', 'bit of', 'text'})
+ eq(true, meths.buf_set_mark(buf, 'F', 2, 2))
+ eq(true, meths.del_mark('F'))
+ eq({0, 0}, meths.buf_get_mark(buf, 'F'))
+ end)
+ it('fails when invalid marks are used', function()
+ eq(false, pcall(meths.del_mark, 'f'))
+ eq(false, pcall(meths.del_mark, '!'))
+ eq(false, pcall(meths.del_mark, 'fail'))
+ end)
+ end)
+ describe('nvim_get_mark', function()
+ it('works', function()
+ local buf = meths.create_buf(false,true)
+ meths.buf_set_lines(buf, -1, -1, true, {'a', 'bit of', 'text'})
+ meths.buf_set_mark(buf, 'F', 2, 2)
+ meths.buf_set_name(buf, "mybuf")
+ local mark = meths.get_mark('F')
+ -- Compare the path tail ony
+ assert(string.find(mark[4], "mybuf$"))
+ eq({2, 2, buf.id, mark[4]}, mark)
+ end)
+ it('fails when invalid marks are used', function()
+ eq(false, pcall(meths.del_mark, 'f'))
+ eq(false, pcall(meths.del_mark, '!'))
+ eq(false, pcall(meths.del_mark, 'fail'))
+ end)
+ it('returns the expected when mark is not set', function()
+ eq(true, meths.del_mark('A'))
+ eq({0, 0, 0, ''}, meths.get_mark('A'))
+ end)
+ it('works with deleted buffers', function()
+ local fname = tmpname()
+ write_file(fname, 'a\nbit of\text')
+ nvim("command", "edit " .. fname)
+ local buf = meths.get_current_buf()
+
+ meths.buf_set_mark(buf, 'F', 2, 2)
+ nvim("command", "new") -- Create new buf to avoid :bd failing
+ nvim("command", "bd! " .. buf.id)
+ os.remove(fname)
+
+ local mark = meths.get_mark('F')
+ -- To avoid comparing relative vs absolute path
+ local mfname = mark[4]
+ local tail_patt = [[[\/][^\/]*$]]
+ -- tail of paths should be equals
+ eq(fname:match(tail_patt), mfname:match(tail_patt))
+ eq({2, 2, buf.id, mark[4]}, mark)
+ end)
+ end)
+ describe('nvim_eval_statusline', function()
+ it('works', function()
+ eq({
+ str = '%StatusLineStringWithHighlights',
+ width = 31
+ },
+ meths.eval_statusline(
+ '%%StatusLineString%#WarningMsg#WithHighlights',
+ {}))
+ end)
+ it('doesn\'t exceed maxwidth', function()
+ eq({
+ str = 'Should be trun>',
+ width = 15
+ },
+ meths.eval_statusline(
+ 'Should be truncated%<',
+ { maxwidth = 15 }))
+ end)
+ describe('highlight parsing', function()
+ it('works', function()
+ eq({
+ str = "TextWithWarningHighlightTextWithUserHighlight",
+ width = 45,
+ highlights = {
+ { start = 0, group = 'WarningMsg' },
+ { start = 24, group = 'User1' }
+ },
+ },
+ meths.eval_statusline(
+ '%#WarningMsg#TextWithWarningHighlight%1*TextWithUserHighlight',
+ { highlights = true }))
+ end)
+ it('works with no highlight', function()
+ eq({
+ str = "TextWithNoHighlight",
+ width = 19,
+ highlights = {
+ { start = 0, group = 'StatusLine' },
+ },
+ },
+ meths.eval_statusline(
+ 'TextWithNoHighlight',
+ { highlights = true }))
+ end)
+ it('works with inactive statusline', function()
+ command('split')
+
+ eq({
+ str = 'TextWithNoHighlightTextWithWarningHighlight',
+ width = 43,
+ highlights = {
+ { start = 0, group = 'StatusLineNC' },
+ { start = 19, group = 'WarningMsg' }
+ }
+ },
+ meths.eval_statusline(
+ 'TextWithNoHighlight%#WarningMsg#TextWithWarningHighlight',
+ { winid = meths.list_wins()[2].id, highlights = true }))
+ end)
+ it('works with tabline', function()
+ eq({
+ str = 'TextWithNoHighlightTextWithWarningHighlight',
+ width = 43,
+ highlights = {
+ { start = 0, group = 'TabLineFill' },
+ { start = 19, group = 'WarningMsg' }
+ }
+ },
+ meths.eval_statusline(
+ 'TextWithNoHighlight%#WarningMsg#TextWithWarningHighlight',
+ { use_tabline = true, highlights = true }))
+ end)
+ end)
end)
end)
diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua
index c49d6405f4..11755a9d97 100644
--- a/test/functional/api/window_spec.lua
+++ b/test/functional/api/window_spec.lua
@@ -1,8 +1,9 @@
local helpers = require('test.functional.helpers')(after_each)
local clear, nvim, curbuf, curbuf_contents, window, curwin, eq, neq,
- ok, feed, insert, eval = helpers.clear, helpers.nvim, helpers.curbuf,
+ ok, feed, insert, eval, tabpage = helpers.clear, helpers.nvim, helpers.curbuf,
helpers.curbuf_contents, helpers.window, helpers.curwin, helpers.eq,
- helpers.neq, helpers.ok, helpers.feed, helpers.insert, helpers.eval
+ helpers.neq, helpers.ok, helpers.feed, helpers.insert, helpers.eval,
+ helpers.tabpage
local poke_eventloop = helpers.poke_eventloop
local curwinmeths = helpers.curwinmeths
local funcs = helpers.funcs
@@ -11,6 +12,7 @@ local NIL = helpers.NIL
local meths = helpers.meths
local command = helpers.command
local pcall_err = helpers.pcall_err
+local assert_alive = helpers.assert_alive
-- check if str is visible at the beginning of some line
local function is_visible(str)
@@ -206,7 +208,7 @@ describe('API/win', function()
end)
end)
- describe('{get,set}_option', function()
+ describe('nvim_win_get_option, nvim_win_set_option', function()
it('works', function()
curwin('set_option', 'colorcolumn', '4,3')
eq('4,3', curwin('get_option', 'colorcolumn'))
@@ -224,6 +226,18 @@ describe('API/win', function()
pcall_err(curwin, 'get_option', 'statusline'))
eq('', eval('&l:statusline')) -- confirm local value was not copied
end)
+
+ it('after switching windows #15390', function()
+ nvim('command', 'tabnew')
+ local tab1 = unpack(nvim('list_tabpages'))
+ local win1 = unpack(tabpage('list_wins', tab1))
+ window('set_option', win1, 'statusline', 'window-status')
+ nvim('command', 'split')
+ nvim('command', 'wincmd J')
+ nvim('command', 'wincmd j')
+ eq('window-status', window('get_option', win1, 'statusline'))
+ assert_alive()
+ end)
end)
describe('get_position', function()
@@ -354,13 +368,13 @@ describe('API/win', function()
local win = meths.open_win(0, true, {
relative='editor', row=10, col=10, width=50, height=10
})
- local tabpage = eval('tabpagenr()')
+ local tab = eval('tabpagenr()')
command('tabprevious')
eq(1, eval('tabpagenr()'))
meths.win_close(win, false)
- eq(1001, meths.tabpage_get_win(tabpage).id)
- helpers.assert_alive()
+ eq(1001, meths.tabpage_get_win(tab).id)
+ assert_alive()
end)
end)
diff --git a/test/functional/autocmd/dirchanged_spec.lua b/test/functional/autocmd/dirchanged_spec.lua
index 6f2da24cf2..f4a1642ebf 100644
--- a/test/functional/autocmd/dirchanged_spec.lua
+++ b/test/functional/autocmd/dirchanged_spec.lua
@@ -6,6 +6,7 @@ local command = h.command
local eq = h.eq
local eval = h.eval
local request = h.request
+local iswin = h.iswin
describe('autocmd DirChanged', function()
local curdir = string.gsub(lfs.currentdir(), '\\', '/')
@@ -14,6 +15,11 @@ describe('autocmd DirChanged', function()
curdir .. '/Xtest-functional-autocmd-dirchanged.dir2',
curdir .. '/Xtest-functional-autocmd-dirchanged.dir3',
}
+ local win_dirs = {
+ curdir .. '\\XTEST-FUNCTIONAL-AUTOCMD-DIRCHANGED.DIR1',
+ curdir .. '\\XTEST-FUNCTIONAL-AUTOCMD-DIRCHANGED.DIR2',
+ curdir .. '\\XTEST-FUNCTIONAL-AUTOCMD-DIRCHANGED.DIR3',
+ }
setup(function() for _, dir in pairs(dirs) do h.mkdir(dir) end end)
teardown(function() for _, dir in pairs(dirs) do h.rmdir(dir) end end)
@@ -27,17 +33,20 @@ describe('autocmd DirChanged', function()
command([[autocmd DirChanged * let g:getcwd = substitute(g:getcwd, '\\', '/', 'g')]])
end)
- it('sets v:event', function()
+ it('sets v:event and <amatch>', function()
command('lcd '..dirs[1])
eq({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev'))
+ eq('window', eval('g:amatch'))
eq(1, eval('g:cdcount'))
command('tcd '..dirs[2])
- eq({cwd=dirs[2], scope='tab', changed_window=false}, eval('g:ev'))
+ eq({cwd=dirs[2], scope='tabpage', changed_window=false}, eval('g:ev'))
+ eq('tabpage', eval('g:amatch'))
eq(2, eval('g:cdcount'))
command('cd '..dirs[3])
eq({cwd=dirs[3], scope='global', changed_window=false}, eval('g:ev'))
+ eq('global', eval('g:amatch'))
eq(3, eval('g:cdcount'))
end)
@@ -63,17 +72,6 @@ describe('autocmd DirChanged', function()
eq(dirs[3], eval('getcwd()'))
end)
- it('sets <amatch> to CWD "scope"', function()
- command('lcd '..dirs[1])
- eq('window', eval('g:amatch'))
-
- command('tcd '..dirs[2])
- eq('tab', eval('g:amatch'))
-
- command('cd '..dirs[3])
- eq('global', eval('g:amatch'))
- end)
-
it('does not trigger if :cd fails', function()
command('let g:ev = {}')
@@ -106,13 +104,79 @@ describe('autocmd DirChanged', function()
command('split '..dirs[1]..'/foo')
eq({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev'))
+ eq('auto', eval('g:amatch'))
command('split '..dirs[2]..'/bar')
eq({cwd=dirs[2], scope='window', changed_window=false}, eval('g:ev'))
+ eq('auto', eval('g:amatch'))
eq(2, eval('g:cdcount'))
end)
+ it('does not trigger if directory has not changed', function()
+ command('lcd '..dirs[1])
+ eq({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev'))
+ eq('window', eval('g:amatch'))
+ eq(1, eval('g:cdcount'))
+ command('let g:ev = {}')
+ command('lcd '..dirs[1])
+ eq({}, eval('g:ev'))
+ eq(1, eval('g:cdcount'))
+
+ if iswin() then
+ command('lcd '..win_dirs[1])
+ eq({}, eval('g:ev'))
+ eq(1, eval('g:cdcount'))
+ end
+
+ command('tcd '..dirs[2])
+ eq({cwd=dirs[2], scope='tabpage', changed_window=false}, eval('g:ev'))
+ eq('tabpage', eval('g:amatch'))
+ eq(2, eval('g:cdcount'))
+ command('let g:ev = {}')
+ command('tcd '..dirs[2])
+ eq({}, eval('g:ev'))
+ eq(2, eval('g:cdcount'))
+
+ if iswin() then
+ command('tcd '..win_dirs[2])
+ eq({}, eval('g:ev'))
+ eq(2, eval('g:cdcount'))
+ end
+
+ command('cd '..dirs[3])
+ eq({cwd=dirs[3], scope='global', changed_window=false}, eval('g:ev'))
+ eq('global', eval('g:amatch'))
+ eq(3, eval('g:cdcount'))
+ command('let g:ev = {}')
+ command('cd '..dirs[3])
+ eq({}, eval('g:ev'))
+ eq(3, eval('g:cdcount'))
+
+ if iswin() then
+ command('cd '..win_dirs[3])
+ eq({}, eval('g:ev'))
+ eq(3, eval('g:cdcount'))
+ end
+
+ command('set autochdir')
+
+ command('split '..dirs[1]..'/foo')
+ eq({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev'))
+ eq('auto', eval('g:amatch'))
+ eq(4, eval('g:cdcount'))
+ command('let g:ev = {}')
+ command('split '..dirs[1]..'/bar')
+ eq({}, eval('g:ev'))
+ eq(4, eval('g:cdcount'))
+
+ if iswin() then
+ command('split '..win_dirs[1]..'/baz')
+ eq({}, eval('g:ev'))
+ eq(4, eval('g:cdcount'))
+ end
+ end)
+
it("is triggered by switching to win/tab with different CWD #6054", function()
command('lcd '..dirs[3]) -- window 3
command('split '..dirs[2]..'/foo') -- window 2
@@ -122,6 +186,7 @@ describe('autocmd DirChanged', function()
command('2wincmd w') -- window 2
eq({cwd=dirs[2], scope='window', changed_window=true}, eval('g:ev'))
+ eq('window', eval('g:amatch'))
eq(4, eval('g:cdcount'))
command('tabnew') -- tab 2 (tab-local CWD)
@@ -129,8 +194,10 @@ describe('autocmd DirChanged', function()
command('tcd '..dirs[3])
command('tabnext') -- tab 1 (no tab-local CWD)
eq({cwd=dirs[2], scope='window', changed_window=true}, eval('g:ev'))
+ eq('window', eval('g:amatch'))
command('tabnext') -- tab 2
- eq({cwd=dirs[3], scope='tab', changed_window=true}, eval('g:ev'))
+ eq({cwd=dirs[3], scope='tabpage', changed_window=true}, eval('g:ev'))
+ eq('tabpage', eval('g:amatch'))
eq(7, eval('g:cdcount'))
command('tabnext') -- tab 1
@@ -138,6 +205,31 @@ describe('autocmd DirChanged', function()
eq(9, eval('g:cdcount'))
command('tabnext') -- tab 2 (has the *same* CWD)
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+
+ if iswin() then
+ command('tabnew') -- tab 3
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('tcd '..win_dirs[3])
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('tabnext') -- tab 1
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('tabprevious') -- tab 3
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('tabprevious') -- tab 2
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('tabprevious') -- tab 1
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('lcd '..win_dirs[3]) -- window 3
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('tabnext') -- tab 2
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('tabnext') -- tab 3
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('tabnext') -- tab 1
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('tabprevious') -- tab 3
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ end
end)
it('is triggered by nvim_set_current_dir()', function()
diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua
index f057420dde..cc6e2c8067 100644
--- a/test/functional/core/startup_spec.lua
+++ b/test/functional/core/startup_spec.lua
@@ -20,6 +20,7 @@ local retry = helpers.retry
local rmdir = helpers.rmdir
local sleep = helpers.sleep
local iswin = helpers.iswin
+local startswith = helpers.startswith
local write_file = helpers.write_file
local meths = helpers.meths
@@ -310,7 +311,8 @@ describe('startup', function()
end)
local function pack_clear(cmd)
- clear{args={'--cmd', 'set packpath=test/functional/fixtures', '--cmd', cmd}, env={XDG_CONFIG_HOME='test/functional/fixtures/'}}
+ -- add packages after config dir in rtp but before config/after
+ clear{args={'--cmd', 'set packpath=test/functional/fixtures', '--cmd', 'let paths=split(&rtp, ",")', '--cmd', 'let &rtp = paths[0]..",test/functional/fixtures,test/functional/fixtures/middle,"..join(paths[1:],",")', '--cmd', cmd}, env={XDG_CONFIG_HOME='test/functional/fixtures/'}}
end
@@ -326,6 +328,15 @@ describe('startup', function()
eq({9003, '\thowdy'}, exec_lua [[ return { _G.y, _G.z } ]])
end)
+ it("handles require from &packpath in an async handler", function()
+ -- NO! you cannot just speed things up by calling async functions during startup!
+ -- It doesn't make anything actually faster! NOOOO!
+ pack_clear [[ lua require'async_leftpad'('brrrr', 'async_res') ]]
+
+ -- haha, async leftpad go brrrrr
+ eq('\tbrrrr', exec_lua [[ return _G.async_res ]])
+ end)
+
it("handles :packadd during startup", function()
-- control group: opt/bonus is not availabe by default
pack_clear [[
@@ -351,12 +362,57 @@ describe('startup', function()
it("handles the correct order with start packages and after/", function()
pack_clear [[ lua _G.test_loadorder = {} vim.cmd "runtime! filen.lua" ]]
- eq({'ordinary', 'FANCY', 'ordinary after', 'FANCY after'}, exec_lua [[ return _G.test_loadorder ]])
+ eq({'ordinary', 'FANCY', 'mittel', 'FANCY after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]])
+ end)
+
+ it("handles the correct order with start packages and after/ after startup", function()
+ pack_clear [[ lua _G.test_loadorder = {} ]]
+ command [[ runtime! filen.lua ]]
+ eq({'ordinary', 'FANCY', 'mittel', 'FANCY after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]])
+ end)
+
+ it("handles the correct order with globpath(&rtp, ...)", function()
+ pack_clear [[ set loadplugins | lua _G.test_loadorder = {} ]]
+ command [[
+ for x in globpath(&rtp, "filen.lua",1,1)
+ call v:lua.dofile(x)
+ endfor
+ ]]
+ eq({'ordinary', 'FANCY', 'mittel', 'FANCY after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]])
+
+ local rtp = meths.get_option'rtp'
+ ok(startswith(rtp, 'test/functional/fixtures/nvim,test/functional/fixtures/pack/*/start/*,test/functional/fixtures/start/*,test/functional/fixtures,test/functional/fixtures/middle,'), 'rtp='..rtp)
end)
it("handles the correct order with opt packages and after/", function()
pack_clear [[ lua _G.test_loadorder = {} vim.cmd "packadd! superspecial\nruntime! filen.lua" ]]
- eq({'ordinary', 'SuperSpecial', 'FANCY', 'SuperSpecial after', 'ordinary after', 'FANCY after'}, exec_lua [[ return _G.test_loadorder ]])
+ eq({'ordinary', 'SuperSpecial', 'FANCY', 'mittel', 'FANCY after', 'SuperSpecial after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]])
+ end)
+
+ it("handles the correct order with opt packages and after/ after startup", function()
+ pack_clear [[ lua _G.test_loadorder = {} ]]
+ command [[
+ packadd! superspecial
+ runtime! filen.lua
+ ]]
+ eq({'ordinary', 'SuperSpecial', 'FANCY', 'mittel', 'FANCY after', 'SuperSpecial after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]])
+ end)
+
+ it("handles the correct order with opt packages and globpath(&rtp, ...)", function()
+ pack_clear [[ set loadplugins | lua _G.test_loadorder = {} ]]
+ command [[
+ packadd! superspecial
+ for x in globpath(&rtp, "filen.lua",1,1)
+ call v:lua.dofile(x)
+ endfor
+ ]]
+ eq({'ordinary', 'SuperSpecial', 'FANCY', 'mittel', 'SuperSpecial after', 'FANCY after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]])
+ end)
+
+ it("handles the correct order with a package that changes packpath", function()
+ pack_clear [[ lua _G.test_loadorder = {} vim.cmd "packadd! funky\nruntime! filen.lua" ]]
+ eq({'ordinary', 'funky!', 'FANCY', 'mittel', 'FANCY after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]])
+ eq({'ordinary', 'funky!', 'mittel', 'ordinary after'}, exec_lua [[ return _G.nested_order ]])
end)
end)
@@ -472,7 +528,7 @@ describe('user config init', function()
clear{ args_rm={'-u' }, env=xenv }
eq(1, eval('g:lua_rc'))
- eq(init_lua_path, eval('$MYVIMRC'))
+ eq(funcs.fnamemodify(init_lua_path, ':p'), eval('$MYVIMRC'))
end)
describe 'with explicitly provided config'(function()
diff --git a/test/functional/editor/meta_key_spec.lua b/test/functional/editor/meta_key_spec.lua
index 2a9541ba96..c219204409 100644
--- a/test/functional/editor/meta_key_spec.lua
+++ b/test/functional/editor/meta_key_spec.lua
@@ -11,15 +11,20 @@ describe('meta-keys #8226 #13042', function()
end)
it('ALT/META, normal-mode', function()
- -- Unmapped ALT-chords behave as ESC+c
+ -- Unmapped ALT-chord behaves as ESC+c.
insert('hello')
feed('0<A-x><M-x>')
expect('llo')
+ -- Unmapped ALT-chord resolves isolated (non-ALT) ESC mapping. #13086 #15869
+ command('nnoremap <ESC> A<lt>ESC><Esc>')
+ command('nnoremap ; A;<Esc>')
+ feed('<A-;><M-;>')
+ expect('llo<ESC>;<ESC>;')
-- Mapped ALT-chord behaves as mapped.
command('nnoremap <M-l> Ameta-l<Esc>')
command('nnoremap <A-j> Aalt-j<Esc>')
feed('<A-j><M-l>')
- expect('lloalt-jmeta-l')
+ expect('llo<ESC>;<ESC>;alt-jmeta-l')
end)
it('ALT/META, visual-mode', function()
@@ -27,11 +32,15 @@ describe('meta-keys #8226 #13042', function()
insert('peaches')
feed('viw<A-x>viw<M-x>')
expect('peach')
+ -- Unmapped ALT-chord resolves isolated (non-ALT) ESC mapping. #13086 #15869
+ command('vnoremap <ESC> A<lt>ESC>')
+ feed('viw<A-;><ESC>viw<M-;><ESC>')
+ expect('peach<ESC>;<ESC>;')
-- Mapped ALT-chord behaves as mapped.
command('vnoremap <M-l> Ameta-l<Esc>')
command('vnoremap <A-j> Aalt-j<Esc>')
feed('viw<A-j>viw<M-l>')
- expect('peachalt-jmeta-l')
+ expect('peach<ESC>;<ESC>;alt-jmeta-l')
end)
it('ALT/META insert-mode', function()
diff --git a/test/functional/editor/mode_visual_spec.lua b/test/functional/editor/mode_visual_spec.lua
index e9c117a1e5..468ae00e01 100644
--- a/test/functional/editor/mode_visual_spec.lua
+++ b/test/functional/editor/mode_visual_spec.lua
@@ -14,6 +14,7 @@ describe('visual-mode', function()
it("select-mode Ctrl-O doesn't cancel Ctrl-O mode when processing event #15688", function()
feed('iHello World<esc>gh<c-o>')
eq({mode='vs', blocking=false}, meths.get_mode()) -- fast event
+ eq({mode='vs', blocking=false}, meths.get_mode()) -- again #15288
eq(2, eval('1+1')) -- causes K_EVENT key
eq({mode='vs', blocking=false}, meths.get_mode()) -- still in ctrl-o mode
feed('^')
diff --git a/test/functional/ex_cmds/source_spec.lua b/test/functional/ex_cmds/source_spec.lua
index bdf6ae76d1..fa650d611b 100644
--- a/test/functional/ex_cmds/source_spec.lua
+++ b/test/functional/ex_cmds/source_spec.lua
@@ -25,12 +25,19 @@ describe(':source', function()
let b = #{
\ k: "v"
"\ (o_o)
- \ }]])
+ \ }
+ let c = expand("<SID>")->empty()
+ let s:s = 0zbeef.cafe
+ let d = s:s]])
command('source')
eq('2', meths.exec('echo a', true))
eq("{'k': 'v'}", meths.exec('echo b', true))
+ -- Script items are created only on script var access
+ eq("1", meths.exec('echo c', true))
+ eq("0zBEEFCAFE", meths.exec('echo d', true))
+
exec('set cpoptions+=C')
eq('Vim(let):E15: Invalid expression: #{', exc_exec('source'))
end)
@@ -43,7 +50,11 @@ describe(':source', function()
let b = #{
"\ (>_<)
\ K: "V"
- \ }]])
+ \ }
+ function! s:C() abort
+ return expand("<SID>") .. "C()"
+ endfunction
+ let D = {-> s:C()}]])
-- Source the 2nd line only
feed('ggjV')
@@ -55,6 +66,11 @@ describe(':source', function()
feed_command(':source')
eq('4', meths.exec('echo a', true))
eq("{'K': 'V'}", meths.exec('echo b', true))
+ eq("<SNR>1_C()", meths.exec('echo D()', true))
+
+ -- Source last line only
+ feed_command(':$source')
+ eq('Vim(echo):E117: Unknown function: s:C', exc_exec('echo D()'))
exec('set cpoptions+=C')
eq('Vim(let):E15: Invalid expression: #{', exc_exec("'<,'>source"))
diff --git a/test/functional/fixtures/autoload/health/full_render.vim b/test/functional/fixtures/autoload/health/full_render.vim
new file mode 100644
index 0000000000..2064b8606e
--- /dev/null
+++ b/test/functional/fixtures/autoload/health/full_render.vim
@@ -0,0 +1,8 @@
+function! health#full_render#check()
+ call health#report_start("report 1")
+ call health#report_ok("life is fine")
+ call health#report_warn("no what installed", ["pip what", "make what"])
+ call health#report_start("report 2")
+ call health#report_info("stuff is stable")
+ call health#report_error("why no hardcopy", [":h :hardcopy", ":h :TOhtml"])
+endfunction
diff --git a/test/functional/fixtures/fake-lsp-server.lua b/test/functional/fixtures/fake-lsp-server.lua
index 9579525502..9abf478070 100644
--- a/test/functional/fixtures/fake-lsp-server.lua
+++ b/test/functional/fixtures/fake-lsp-server.lua
@@ -43,11 +43,11 @@ end
local function read_message()
local line = io.read("*l")
local length = line:lower():match("content%-length:%s*(%d+)")
- return vim.fn.json_decode(io.read(2 + length):sub(2))
+ return vim.json.decode(io.read(2 + length):sub(2))
end
local function send(payload)
- io.stdout:write(format_message_with_content_length(vim.fn.json_encode(payload)))
+ io.stdout:write(format_message_with_content_length(vim.json.encode(payload)))
end
local function respond(id, err, result)
@@ -246,6 +246,35 @@ function tests.capabilities_for_client_supports_method()
}
end
+function tests.check_forward_request_cancelled()
+ skeleton {
+ on_init = function(_)
+ return { capabilities = {} }
+ end;
+ body = function()
+ expect_request("error_code_test", function()
+ return {code = -32800}, nil, {method = "error_code_test", client_id=1}
+ end)
+ notify('finish')
+ end;
+ }
+end
+
+function tests.check_forward_content_modified()
+ skeleton {
+ on_init = function(_)
+ return { capabilities = {} }
+ end;
+ body = function()
+ expect_request("error_code_test", function()
+ return {code = -32801}, nil, {method = "error_code_test", client_id=1}
+ end)
+ expect_notification('finish')
+ notify('finish')
+ end;
+ }
+end
+
function tests.basic_finish()
skeleton {
on_init = function(params)
@@ -564,6 +593,35 @@ function tests.decode_nil()
}
end
+
+function tests.code_action_with_resolve()
+ skeleton {
+ on_init = function()
+ return {
+ capabilities = {
+ codeActionProvider = {
+ resolveProvider = true
+ }
+ }
+ }
+ end;
+ body = function()
+ notify('start')
+ local cmd = {
+ title = 'Command 1',
+ command = 'dummy1'
+ }
+ expect_request('textDocument/codeAction', function()
+ return nil, { cmd, }
+ end)
+ expect_request('codeAction/resolve', function()
+ return nil, cmd
+ end)
+ notify('shutdown')
+ end;
+ }
+end
+
-- Tests will be indexed by TEST_NAME
local kill_timer = vim.loop.new_timer()
diff --git a/test/functional/fixtures/lua/test_plug/autoload/health/test_plug.vim b/test/functional/fixtures/lua/test_plug/autoload/health/test_plug.vim
new file mode 100644
index 0000000000..de05f56e9e
--- /dev/null
+++ b/test/functional/fixtures/lua/test_plug/autoload/health/test_plug.vim
@@ -0,0 +1,3 @@
+function! health#success1#check()
+ call health#report_start("If you see this I'm broken")
+endfunction
diff --git a/test/functional/fixtures/lua/test_plug/health/init.lua b/test/functional/fixtures/lua/test_plug/health/init.lua
new file mode 100644
index 0000000000..d07632cff4
--- /dev/null
+++ b/test/functional/fixtures/lua/test_plug/health/init.lua
@@ -0,0 +1,11 @@
+local M = {}
+local health = require("health")
+
+M.check = function()
+ health.report_start("report 1")
+ health.report_ok("everything is fine")
+ health.report_start("report 2")
+ health.report_ok("nothing to see here")
+end
+
+return M
diff --git a/test/functional/fixtures/lua/test_plug/submodule/health.lua b/test/functional/fixtures/lua/test_plug/submodule/health.lua
new file mode 100644
index 0000000000..d07632cff4
--- /dev/null
+++ b/test/functional/fixtures/lua/test_plug/submodule/health.lua
@@ -0,0 +1,11 @@
+local M = {}
+local health = require("health")
+
+M.check = function()
+ health.report_start("report 1")
+ health.report_ok("everything is fine")
+ health.report_start("report 2")
+ health.report_ok("nothing to see here")
+end
+
+return M
diff --git a/test/functional/fixtures/lua/test_plug/submodule_failed/health.lua b/test/functional/fixtures/lua/test_plug/submodule_failed/health.lua
new file mode 100644
index 0000000000..3a8af6ebb2
--- /dev/null
+++ b/test/functional/fixtures/lua/test_plug/submodule_failed/health.lua
@@ -0,0 +1,12 @@
+local M = {}
+local health = require("health")
+
+M.check = function()
+ health.report_start("report 1")
+ health.report_ok("everything is fine")
+ health.report_warn("About to add a number to nil")
+ local a = nil + 2
+ return a
+end
+
+return M
diff --git a/test/functional/fixtures/middle/filen.lua b/test/functional/fixtures/middle/filen.lua
new file mode 100644
index 0000000000..fce50cc776
--- /dev/null
+++ b/test/functional/fixtures/middle/filen.lua
@@ -0,0 +1 @@
+table.insert(_G.test_loadorder, "mittel")
diff --git a/test/functional/fixtures/pack/foo/opt/funky/filen.lua b/test/functional/fixtures/pack/foo/opt/funky/filen.lua
new file mode 100644
index 0000000000..a33b83c2a7
--- /dev/null
+++ b/test/functional/fixtures/pack/foo/opt/funky/filen.lua
@@ -0,0 +1,12 @@
+table.insert(_G.test_loadorder, "funky!")
+
+if not _G.nesty then
+ _G.nesty = true
+ local save_order = _G.test_loadorder
+ _G.test_loadorder = {}
+ _G.vim.o.pp = "" -- funky!
+ vim.cmd [[runtime! filen.lua ]]
+ _G.nested_order = _G.test_loadorder
+ _G.test_loadorder = save_order
+ _G.nesty = nil
+end
diff --git a/test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_y.lua b/test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_y.lua
new file mode 100644
index 0000000000..7daa7733a0
--- /dev/null
+++ b/test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_y.lua
@@ -0,0 +1 @@
+return "I am fancy_y.lua"
diff --git a/test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_z.lua b/test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_z.lua
new file mode 100644
index 0000000000..6e81afdd70
--- /dev/null
+++ b/test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_z.lua
@@ -0,0 +1 @@
+return "I am fancy_z.lua"
diff --git a/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x.lua b/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x.lua
new file mode 100644
index 0000000000..1b897a96cc
--- /dev/null
+++ b/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x.lua
@@ -0,0 +1 @@
+return "I am fancy_x.lua"
diff --git a/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x/init.lua b/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x/init.lua
new file mode 100644
index 0000000000..8c27a43cab
--- /dev/null
+++ b/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x/init.lua
@@ -0,0 +1 @@
+return "I am init.lua of fancy_x!"
diff --git a/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_y/init.lua b/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_y/init.lua
new file mode 100644
index 0000000000..b66cbee4f6
--- /dev/null
+++ b/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_y/init.lua
@@ -0,0 +1,2 @@
+
+return "I am init.lua of fancy_y!"
diff --git a/test/functional/fixtures/start/nvim-leftpad/lua/async_leftpad.lua b/test/functional/fixtures/start/nvim-leftpad/lua/async_leftpad.lua
new file mode 100644
index 0000000000..a312572c5b
--- /dev/null
+++ b/test/functional/fixtures/start/nvim-leftpad/lua/async_leftpad.lua
@@ -0,0 +1,3 @@
+return function (val, res)
+ vim.loop.new_async(function() _G[res] = require'leftpad'(val) end):send()
+end
diff --git a/test/functional/legacy/delete_spec.lua b/test/functional/legacy/delete_spec.lua
index f2ced8942d..141d9583e6 100644
--- a/test/functional/legacy/delete_spec.lua
+++ b/test/functional/legacy/delete_spec.lua
@@ -1,6 +1,7 @@
local helpers = require('test.functional.helpers')(after_each)
local clear, source = helpers.clear, helpers.source
local eq, eval, command = helpers.eq, helpers.eval, helpers.command
+local exc_exec = helpers.exc_exec
describe('Test for delete()', function()
before_each(clear)
@@ -38,7 +39,7 @@ describe('Test for delete()', function()
eq(eval("['a', 'b']"), eval("readfile('Xdir1/Xfile')"))
eq(1, eval("isdirectory('Xdir1/subdir')"))
eq(eval("['a', 'b']"), eval("readfile('Xdir1/subdir/Xfile')"))
- eq(1, eval("isdirectory('Xdir1/empty')"))
+ eq(1, eval("'Xdir1/empty'->isdirectory()"))
eq(0, eval("delete('Xdir1', 'rf')"))
eq(0, eval("isdirectory('Xdir1')"))
eq(-1, eval("delete('Xdir1', 'd')"))
@@ -114,4 +115,10 @@ describe('Test for delete()', function()
eq(0, eval("delete('Xdir4/Xfile')"))
eq(0, eval("delete('Xdir4', 'd')"))
end)
+
+ it('gives correct emsgs', function()
+ eq('Vim(call):E474: Invalid argument', exc_exec("call delete('')"))
+ eq('Vim(call):E15: Invalid expression: 0',
+ exc_exec("call delete('foo', 0)"))
+ end)
end)
diff --git a/test/functional/legacy/eval_spec.lua b/test/functional/legacy/eval_spec.lua
index 3b407ce5f5..b5de5cd232 100644
--- a/test/functional/legacy/eval_spec.lua
+++ b/test/functional/legacy/eval_spec.lua
@@ -600,7 +600,6 @@ describe('eval', function()
command([[call ErrExe('call setreg(1)')]])
command([[call ErrExe('call setreg(1, 2, 3, 4)')]])
command([=[call ErrExe('call setreg([], 2)')]=])
- command([[call ErrExe('call setreg(1, {})')]])
command([=[call ErrExe('call setreg(1, 2, [])')]=])
command([=[call ErrExe('call setreg("/", ["1", "2"])')]=])
command([=[call ErrExe('call setreg("=", ["1", "2"])')]=])
@@ -615,8 +614,6 @@ describe('eval', function()
Vim(call):E118: Too many arguments for function: setreg
Executing call setreg([], 2)
Vim(call):E730: using List as a String
- Executing call setreg(1, {})
- Vim(call):E731: using Dictionary as a String
Executing call setreg(1, 2, [])
Vim(call):E730: using List as a String
Executing call setreg("/", ["1", "2"])
diff --git a/test/functional/legacy/expand_spec.lua b/test/functional/legacy/expand_spec.lua
index f238128b31..cd3713eabe 100644
--- a/test/functional/legacy/expand_spec.lua
+++ b/test/functional/legacy/expand_spec.lua
@@ -81,7 +81,7 @@ describe('expand file name', function()
call assert_equal('e Xfile1', expandcmd('e %'))
edit Xfile2
edit Xfile1
- call assert_equal('e Xfile2', expandcmd('e #'))
+ call assert_equal('e Xfile2', 'e #'->expandcmd())
edit Xfile2
edit Xfile3
edit Xfile4
diff --git a/test/functional/legacy/file_perm_spec.lua b/test/functional/legacy/file_perm_spec.lua
index 8fdee95e91..ccdbfe0534 100644
--- a/test/functional/legacy/file_perm_spec.lua
+++ b/test/functional/legacy/file_perm_spec.lua
@@ -3,7 +3,7 @@ require('os')
local helpers = require('test.functional.helpers')(after_each)
local clear, call, eq = helpers.clear, helpers.call, helpers.eq
-local neq, exc_exec = helpers.neq, helpers.exc_exec
+local neq, exc_exec, eval = helpers.neq, helpers.exc_exec, helpers.eval
describe('Test getting and setting file permissions', function()
local tempfile = helpers.tmpname()
@@ -14,11 +14,12 @@ describe('Test getting and setting file permissions', function()
end)
it('file permissions', function()
+ -- eval() is used to test VimL method syntax for setfperm() and getfperm()
eq('', call('getfperm', tempfile))
- eq(0, call('setfperm', tempfile, 'r--------'))
+ eq(0, eval("'" .. tempfile .. "'->setfperm('r--------')"))
call('writefile', {'one'}, tempfile)
- eq(9, call('len', call('getfperm', tempfile)))
+ eq(9, eval("len('" .. tempfile .. "'->getfperm())"))
eq(1, call('setfperm', tempfile, 'rwx------'))
if helpers.is_os('win') then
diff --git a/test/functional/legacy/fnamemodify_spec.lua b/test/functional/legacy/fnamemodify_spec.lua
index 7e859bf0cf..6a5538c26f 100644
--- a/test/functional/legacy/fnamemodify_spec.lua
+++ b/test/functional/legacy/fnamemodify_spec.lua
@@ -60,12 +60,6 @@ describe('filename modifiers', function()
call assert_equal("'abc\\\ndef'", fnamemodify("abc\ndef", ':S'))
endif
endfunc
-
- func Test_expand()
- new
- call assert_equal("", expand('%:S'))
- quit
- endfunc
]=])
end)
@@ -73,9 +67,4 @@ describe('filename modifiers', function()
call('Test_fnamemodify')
expected_empty()
end)
-
- it('works for :S in an unnamed buffer', function()
- call('Test_expand')
- expected_empty()
- end)
end)
diff --git a/test/functional/lua/api_spec.lua b/test/functional/lua/api_spec.lua
index fdf79d55b2..8551c3d2a0 100644
--- a/test/functional/lua/api_spec.lua
+++ b/test/functional/lua/api_spec.lua
@@ -194,6 +194,10 @@ describe('luaeval(vim.api.…)', function()
exc_exec([[call luaeval("vim.api.nvim__id_dictionary(1)")]]))
eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Unexpected type',
exc_exec([[call luaeval("vim.api.nvim__id_dictionary({[vim.type_idx]=vim.types.array})")]]))
+
+ eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected lua table',
+ exc_exec([[call luaeval("vim.api.nvim_set_keymap('', '', '', '')")]]))
+
-- TODO: check for errors with Tabpage argument
-- TODO: check for errors with Window argument
-- TODO: check for errors with Buffer argument
diff --git a/test/functional/lua/buffer_updates_spec.lua b/test/functional/lua/buffer_updates_spec.lua
index 073927bf22..c83a50b78b 100644
--- a/test/functional/lua/buffer_updates_spec.lua
+++ b/test/functional/lua/buffer_updates_spec.lua
@@ -1050,6 +1050,102 @@ describe('lua: nvim_buf_attach on_bytes', function()
}
end)
+ it("sends updates on U", function()
+ feed("ggiAAA<cr>BBB")
+ feed("<esc>gg$a CCC")
+
+ local check_events = setup_eventcheck(verify, nil)
+
+ feed("ggU")
+
+ check_events {
+ { "test1", "bytes", 1, 6, 0, 7, 7, 0, 0, 0, 0, 3, 3 };
+ }
+ end)
+
+ it("delete in completely empty buffer", function()
+ local check_events = setup_eventcheck(verify, nil)
+
+ command "delete"
+ check_events { }
+ end)
+
+ it("delete the only line of a buffer", function()
+ local check_events = setup_eventcheck(verify, {"AAA"})
+
+ command "delete"
+ check_events {
+ { "test1", "bytes", 1, 3, 0, 0, 0, 1, 0, 4, 1, 0, 1 };
+ }
+ end)
+
+ it("delete the last line of a buffer with two lines", function()
+ local check_events = setup_eventcheck(verify, {"AAA", "BBB"})
+
+ command "2delete"
+ check_events {
+ { "test1", "bytes", 1, 3, 1, 0, 4, 1, 0, 4, 0, 0, 0 };
+ }
+ end)
+
+ it(":sort lines", function()
+ local check_events = setup_eventcheck(verify, {"CCC", "BBB", "AAA"})
+
+ command "%sort"
+ check_events {
+ { "test1", "bytes", 1, 3, 0, 0, 0, 3, 0, 12, 3, 0, 12 };
+ }
+ end)
+
+ it("handles already sorted lines", function()
+ local check_events = setup_eventcheck(verify, {"AAA", "BBB", "CCC"})
+
+ command "%sort"
+ check_events { }
+ end)
+
+ local function test_lockmarks(mode)
+ local description = (mode ~= "") and mode or "(baseline)"
+ it("test_lockmarks " .. description .. " %delete _", function()
+ local check_events = setup_eventcheck(verify, {"AAA", "BBB", "CCC"})
+
+ command(mode .. " %delete _")
+ check_events {
+ { "test1", "bytes", 1, 3, 0, 0, 0, 3, 0, 12, 1, 0, 1 };
+ }
+ end)
+
+ it("test_lockmarks " .. description .. " append()", function()
+ local check_events = setup_eventcheck(verify)
+
+ command(mode .. " call append(0, 'CCC')")
+ check_events {
+ { "test1", "bytes", 1, 2, 0, 0, 0, 0, 0, 0, 1, 0, 4 };
+ }
+
+ command(mode .. " call append(1, 'BBBB')")
+ check_events {
+ { "test1", "bytes", 1, 3, 1, 0, 4, 0, 0, 0, 1, 0, 5 };
+ }
+
+ command(mode .. " call append(2, '')")
+ check_events {
+ { "test1", "bytes", 1, 4, 2, 0, 9, 0, 0, 0, 1, 0, 1 };
+ }
+
+ command(mode .. " $delete _")
+ check_events {
+ { "test1", "bytes", 1, 5, 3, 0, 10, 1, 0, 1, 0, 0, 0 };
+ }
+
+ eq("CCC|BBBB|", table.concat(meths.buf_get_lines(0, 0, -1, true), "|"))
+ end)
+ end
+
+ -- check that behavior is identical with and without "lockmarks"
+ test_lockmarks ""
+ test_lockmarks "lockmarks"
+
teardown(function()
os.remove "Xtest-reload"
os.remove "Xtest-undofile"
diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua
index 29dd5c60da..1cbfa224cc 100644
--- a/test/functional/lua/diagnostic_spec.lua
+++ b/test/functional/lua/diagnostic_spec.lua
@@ -14,48 +14,32 @@ describe('vim.diagnostic', function()
exec_lua [[
require('vim.diagnostic')
- function make_error(msg, x1, y1, x2, y2)
+ function make_diagnostic(msg, x1, y1, x2, y2, severity, source)
return {
lnum = x1,
col = y1,
end_lnum = x2,
end_col = y2,
message = msg,
- severity = vim.diagnostic.severity.ERROR,
+ severity = severity,
+ source = source,
}
end
- function make_warning(msg, x1, y1, x2, y2)
- return {
- lnum = x1,
- col = y1,
- end_lnum = x2,
- end_col = y2,
- message = msg,
- severity = vim.diagnostic.severity.WARN,
- }
+ function make_error(msg, x1, y1, x2, y2, source)
+ return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.ERROR, source)
end
- function make_info(msg, x1, y1, x2, y2)
- return {
- lnum = x1,
- col = y1,
- end_lnum = x2,
- end_col = y2,
- message = msg,
- severity = vim.diagnostic.severity.INFO,
- }
+ function make_warning(msg, x1, y1, x2, y2, source)
+ return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.WARN, source)
end
- function make_hint(msg, x1, y1, x2, y2)
- return {
- lnum = x1,
- col = y1,
- end_lnum = x2,
- end_col = y2,
- message = msg,
- severity = vim.diagnostic.severity.HINT,
- }
+ function make_info(msg, x1, y1, x2, y2, source)
+ return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.INFO, source)
+ end
+
+ function make_hint(msg, x1, y1, x2, y2, source)
+ return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.HINT, source)
end
function count_diagnostics(bufnr, severity, namespace)
@@ -489,6 +473,78 @@ describe('vim.diagnostic', function()
end)
describe('config()', function()
+ it('works with global, namespace, and ephemeral options', function()
+ eq(1, exec_lua [[
+ vim.diagnostic.config({
+ virtual_text = false,
+ })
+
+ vim.diagnostic.config({
+ virtual_text = true,
+ underline = false,
+ }, diagnostic_ns)
+
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
+ make_error('Some Error', 4, 4, 4, 4),
+ })
+
+ return count_extmarks(diagnostic_bufnr, diagnostic_ns)
+ ]])
+
+ eq(1, exec_lua [[
+ vim.diagnostic.config({
+ virtual_text = false,
+ })
+
+ vim.diagnostic.config({
+ virtual_text = false,
+ underline = false,
+ }, diagnostic_ns)
+
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
+ make_error('Some Error', 4, 4, 4, 4),
+ }, {virtual_text = true})
+
+ return count_extmarks(diagnostic_bufnr, diagnostic_ns)
+ ]])
+
+ eq(0, exec_lua [[
+ vim.diagnostic.config({
+ virtual_text = false,
+ })
+
+ vim.diagnostic.config({
+ virtual_text = {severity=vim.diagnostic.severity.ERROR},
+ underline = false,
+ }, diagnostic_ns)
+
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
+ make_warning('Some Warning', 4, 4, 4, 4),
+ }, {virtual_text = true})
+
+ return count_extmarks(diagnostic_bufnr, diagnostic_ns)
+ ]])
+
+ eq(1, exec_lua [[
+ vim.diagnostic.config({
+ virtual_text = false,
+ })
+
+ vim.diagnostic.config({
+ virtual_text = {severity=vim.diagnostic.severity.ERROR},
+ underline = false,
+ }, diagnostic_ns)
+
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
+ make_warning('Some Warning', 4, 4, 4, 4),
+ }, {
+ virtual_text = {} -- An empty table uses default values
+ })
+
+ return count_extmarks(diagnostic_bufnr, diagnostic_ns)
+ ]])
+ end)
+
it('can use functions for config values', function()
exec_lua [[
vim.diagnostic.config({
@@ -590,6 +646,118 @@ describe('vim.diagnostic', function()
eq({'Error', 'Warn', 'Info'}, result[1])
eq({'Info', 'Warn', 'Error'}, result[2])
end)
+
+ it('can show diagnostic sources in virtual text', function()
+ local result = exec_lua [[
+ local diagnostics = {
+ make_error('Some error', 0, 0, 0, 0, 'source x'),
+ }
+
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics, {
+ underline = false,
+ virtual_text = {
+ prefix = '',
+ source = 'always',
+ }
+ })
+
+ local extmarks = vim.api.nvim_buf_get_extmarks(diagnostic_bufnr, diagnostic_ns, 0, -1, {details = true})
+ local virt_text = extmarks[1][4].virt_text[2][1]
+ return virt_text
+ ]]
+ eq(' source x: Some error', result)
+
+ result = exec_lua [[
+ vim.diagnostic.config({
+ underline = false,
+ virtual_text = {
+ prefix = '',
+ source = 'if_many',
+ }
+ }, diagnostic_ns)
+
+ local extmarks = vim.api.nvim_buf_get_extmarks(diagnostic_bufnr, diagnostic_ns, 0, -1, {details = true})
+ local virt_text = extmarks[1][4].virt_text[2][1]
+ return virt_text
+ ]]
+ eq(' Some error', result)
+
+ result = exec_lua [[
+ local diagnostics = {
+ make_error('Some error', 0, 0, 0, 0, 'source x'),
+ make_error('Another error', 1, 1, 1, 1, 'source y'),
+ }
+
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics, {
+ underline = false,
+ virtual_text = {
+ prefix = '',
+ source = 'if_many',
+ }
+ })
+
+ local extmarks = vim.api.nvim_buf_get_extmarks(diagnostic_bufnr, diagnostic_ns, 0, -1, {details = true})
+ local virt_text = {extmarks[1][4].virt_text[2][1], extmarks[2][4].virt_text[2][1]}
+ return virt_text
+ ]]
+ eq(' source x: Some error', result[1])
+ eq(' source y: Another error', result[2])
+ end)
+
+ it('supports a format function for diagnostic messages', function()
+ local result = exec_lua [[
+ vim.diagnostic.config({
+ underline = false,
+ virtual_text = {
+ prefix = '',
+ format = function(diagnostic)
+ if diagnostic.severity == vim.diagnostic.severity.ERROR then
+ return string.format("🔥 %s", diagnostic.message)
+ end
+ return string.format("👀 %s", diagnostic.message)
+ end,
+ }
+ })
+
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
+ make_warning('Warning', 0, 0, 0, 0),
+ make_error('Error', 1, 0, 1, 0),
+ })
+
+ local extmarks = vim.api.nvim_buf_get_extmarks(diagnostic_bufnr, diagnostic_ns, 0, -1, {details = true})
+ return {extmarks[1][4].virt_text, extmarks[2][4].virt_text}
+ ]]
+ eq(" 👀 Warning", result[1][2][1])
+ eq(" 🔥 Error", result[2][2][1])
+ end)
+
+ it('includes source for formatted diagnostics', function()
+ local result = exec_lua [[
+ vim.diagnostic.config({
+ underline = false,
+ virtual_text = {
+ prefix = '',
+ source = 'always',
+ format = function(diagnostic)
+ if diagnostic.severity == vim.diagnostic.severity.ERROR then
+ return string.format("🔥 %s", diagnostic.message)
+ end
+ return string.format("👀 %s", diagnostic.message)
+ end,
+ }
+ })
+
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
+ make_warning('Warning', 0, 0, 0, 0, 'some_linter'),
+ make_error('Error', 1, 0, 1, 0, 'another_linter'),
+ })
+
+ local extmarks = vim.api.nvim_buf_get_extmarks(diagnostic_bufnr, diagnostic_ns, 0, -1, {details = true})
+ return {extmarks[1][4].virt_text, extmarks[2][4].virt_text}
+ ]]
+ eq(" some_linter: 👀 Warning", result[1][2][1])
+ eq(" another_linter: 🔥 Error", result[2][2][1])
+ end)
end)
describe('set()', function()
@@ -778,10 +946,124 @@ describe('vim.diagnostic', function()
return count_extmarks(diagnostic_bufnr, diagnostic_ns)
]])
end)
+
+ it('sets signs', function()
+ local result = exec_lua [[
+ vim.diagnostic.config({
+ signs = true,
+ })
+
+ local diagnostics = {
+ make_error('Error', 1, 1, 1, 2),
+ make_warning('Warning', 3, 3, 3, 3),
+ }
+
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
+
+ return vim.fn.sign_getplaced(diagnostic_bufnr, {group = '*'})[1].signs
+ ]]
+
+ eq({2, 'DiagnosticSignError'}, {result[1].lnum, result[1].name})
+ eq({4, 'DiagnosticSignWarn'}, {result[2].lnum, result[2].name})
+ end)
end)
- describe('show_line_diagnostics()', function()
- it('creates floating window and returns popup bufnr and winnr if current line contains diagnostics', function()
+ describe('open_float()', function()
+ it('can show diagnostics from the whole buffer', function()
+ eq({'1. Syntax error', '2. Some warning'}, exec_lua [[
+ local diagnostics = {
+ make_error("Syntax error", 0, 1, 0, 3),
+ make_warning("Some warning", 1, 1, 1, 3),
+ }
+ vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
+ local float_bufnr, winnr = vim.diagnostic.open_float(0, {show_header = false})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
+ ]])
+ end)
+
+ it('can show diagnostics from a single line', function()
+ -- Using cursor position
+ eq({'1. Some warning'}, exec_lua [[
+ local diagnostics = {
+ make_error("Syntax error", 0, 1, 0, 3),
+ make_warning("Some warning", 1, 1, 1, 3),
+ }
+ vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
+ vim.api.nvim_win_set_cursor(0, {2, 1})
+ local float_bufnr, winnr = vim.diagnostic.open_float(0, {show_header=false, scope="line"})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
+ ]])
+
+ -- With specified position
+ eq({'1. Some warning'}, exec_lua [[
+ local diagnostics = {
+ make_error("Syntax error", 0, 1, 0, 3),
+ make_warning("Some warning", 1, 1, 1, 3),
+ }
+ vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
+ vim.api.nvim_win_set_cursor(0, {1, 1})
+ local float_bufnr, winnr = vim.diagnostic.open_float(0, {show_header=false, scope="line", pos=1})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
+ ]])
+ end)
+
+ it('can show diagnostics from a specific position', function()
+ -- Using cursor position
+ eq({'1. Syntax error'}, exec_lua [[
+ local diagnostics = {
+ make_error("Syntax error", 1, 1, 1, 2),
+ make_warning("Some warning", 1, 3, 1, 4),
+ }
+ vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
+ vim.api.nvim_win_set_cursor(0, {2, 2})
+ local float_bufnr, winnr = vim.diagnostic.open_float(0, {show_header=false, scope="cursor"})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
+ ]])
+
+ -- With specified position
+ eq({'1. Some warning'}, exec_lua [[
+ local diagnostics = {
+ make_error("Syntax error", 1, 1, 1, 2),
+ make_warning("Some warning", 1, 3, 1, 4),
+ }
+ vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
+ vim.api.nvim_win_set_cursor(0, {1, 1})
+ local float_bufnr, winnr = vim.diagnostic.open_float(0, {show_header=false, scope="cursor", pos={1,3}})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
+ ]])
+
+ -- With column position past the end of the line. #16062
+ eq({'1. Syntax error'}, exec_lua [[
+ local first_line_len = #vim.api.nvim_buf_get_lines(diagnostic_bufnr, 0, 1, true)[1]
+ local diagnostics = {
+ make_error("Syntax error", 0, first_line_len + 1, 1, 0),
+ }
+ vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
+ vim.api.nvim_win_set_cursor(0, {1, 1})
+ local float_bufnr, winnr = vim.diagnostic.open_float(0, {show_header=false, scope="cursor", pos={0,first_line_len}})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
+ ]])
+ end)
+
+ it('creates floating window and returns float bufnr and winnr if current line contains diagnostics', function()
-- Two lines:
-- Diagnostic:
-- 1. <msg>
@@ -791,8 +1073,10 @@ describe('vim.diagnostic', function()
}
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
- local popup_bufnr, winnr = vim.diagnostic.show_line_diagnostics()
- return #vim.api.nvim_buf_get_lines(popup_bufnr, 0, -1, false)
+ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, {scope="line"})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return #lines
]])
end)
@@ -808,8 +1092,10 @@ describe('vim.diagnostic', function()
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, buf_1_diagnostics)
vim.diagnostic.set(other_ns, other_bufnr, buf_2_diagnostics)
- local popup_bufnr, winnr = vim.diagnostic.show_line_diagnostics()
- return #vim.api.nvim_buf_get_lines(popup_bufnr, 0, -1, false)
+ local float_bufnr, winnr = vim.diagnostic.open_float()
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return #lines
]])
end)
@@ -824,12 +1110,14 @@ describe('vim.diagnostic', function()
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, ns_1_diagnostics)
vim.diagnostic.set(other_ns, diagnostic_bufnr, ns_2_diagnostics)
- local popup_bufnr, winnr = vim.diagnostic.show_line_diagnostics({namespace = diagnostic_ns})
- return #vim.api.nvim_buf_get_lines(popup_bufnr, 0, -1, false)
+ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, {namespace = diagnostic_ns})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return #lines
]])
end)
- it('creates floating window and returns popup bufnr and winnr without header, if requested', function()
+ it('creates floating window and returns float bufnr and winnr without header, if requested', function()
-- One line (since no header):
-- 1. <msg>
eq(1, exec_lua [[
@@ -838,39 +1126,105 @@ describe('vim.diagnostic', function()
}
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
- local popup_bufnr, winnr = vim.diagnostic.show_line_diagnostics {show_header = false}
- return #vim.api.nvim_buf_get_lines(popup_bufnr, 0, -1, false)
+ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, {show_header = false})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return #lines
]])
end)
- end)
- describe('set_signs()', function()
- -- TODO(tjdevries): Find out why signs are not displayed when set from Lua...??
- pending('sets signs by default', function()
- exec_lua [[
- vim.diagnostic.config({
- update_in_insert = true,
- signs = true,
+ it('clamps diagnostic line numbers within the valid range', function()
+ eq(1, exec_lua [[
+ local diagnostics = {
+ make_error("Syntax error", 6, 0, 6, 0),
+ }
+ vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
+ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, {show_header = false, scope = "line", pos = 5})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return #lines
+ ]])
+ end)
+
+ it('can show diagnostic source', function()
+ exec_lua [[vim.api.nvim_win_set_buf(0, diagnostic_bufnr)]]
+
+ eq({"1. Syntax error"}, exec_lua [[
+ local diagnostics = {
+ make_error("Syntax error", 0, 1, 0, 3, "source x"),
+ }
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
+ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, {
+ show_header = false,
+ source = "if_many",
})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
+ ]])
+
+ eq({"1. source x: Syntax error"}, exec_lua [[
+ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, {
+ show_header = false,
+ source = "always",
+ })
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
+ ]])
+ eq({"1. source x: Syntax error", "2. source y: Another error"}, exec_lua [[
local diagnostics = {
- make_error('Delayed Diagnostic', 1, 1, 1, 2),
- make_error('Delayed Diagnostic', 3, 3, 3, 3),
+ make_error("Syntax error", 0, 1, 0, 3, "source x"),
+ make_error("Another error", 0, 1, 0, 3, "source y"),
+ }
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
+ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, {
+ show_header = false,
+ source = "if_many",
+ })
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
+ ]])
+ end)
+
+ it('respects severity_sort', function()
+ exec_lua [[vim.api.nvim_win_set_buf(0, diagnostic_bufnr)]]
+
+ eq({"1. Syntax error", "2. Info", "3. Error", "4. Warning"}, exec_lua [[
+ local diagnostics = {
+ make_error("Syntax error", 0, 1, 0, 3),
+ make_info('Info', 0, 3, 0, 4),
+ make_error('Error', 0, 2, 0, 2),
+ make_warning('Warning', 0, 0, 0, 1),
}
- vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
- vim.diagnostic._set_signs(diagnostic_ns, diagnostic_bufnr, diagnostics)
- -- return vim.fn.sign_getplaced()
- ]]
+ vim.diagnostic.config({severity_sort = false})
- nvim("input", "o")
- nvim("input", "<esc>")
+ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, { show_header = false })
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
+ ]])
+
+ eq({"1. Syntax error", "2. Error", "3. Warning", "4. Info"}, exec_lua [[
+ vim.diagnostic.config({severity_sort = true})
+ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, { show_header = false })
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
+ ]])
- -- TODO(tjdevries): Find a way to get the signs to display in the test...
- eq(nil, exec_lua [[
- return im.fn.sign_getplaced()[1].signs
+ eq({"1. Info", "2. Warning", "3. Error", "4. Syntax error"}, exec_lua [[
+ vim.diagnostic.config({severity_sort = { reverse = true } })
+ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, { show_header = false })
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
]])
end)
end)
diff --git a/test/functional/lua/ffi_spec.lua b/test/functional/lua/ffi_spec.lua
new file mode 100644
index 0000000000..80c01a2b8c
--- /dev/null
+++ b/test/functional/lua/ffi_spec.lua
@@ -0,0 +1,62 @@
+local helpers = require('test.functional.helpers')(after_each)
+local eq = helpers.eq
+local exec_lua = helpers.exec_lua
+local clear = helpers.clear
+
+before_each(clear)
+
+describe('ffi.cdef', function()
+ it('can use Neovim core functions', function()
+ if not exec_lua("return pcall(require, 'ffi')") then
+ pending('missing LuaJIT FFI')
+ end
+
+ eq(12, exec_lua[[
+ local ffi = require('ffi')
+
+ ffi.cdef('int curwin_col_off(void);')
+
+ vim.cmd('set number numberwidth=4 signcolumn=yes:4')
+
+ return ffi.C.curwin_col_off()
+ ]])
+
+ eq(20, exec_lua[=[
+ local ffi = require('ffi')
+
+ ffi.cdef[[
+ typedef unsigned char char_u;
+ typedef struct window_S win_T;
+ typedef struct {} stl_hlrec_t;
+ typedef struct {} StlClickRecord;
+ typedef struct {} Error;
+
+ win_T *find_window_by_handle(int Window, Error *err);
+
+ int build_stl_str_hl(
+ win_T *wp,
+ char_u *out,
+ size_t outlen,
+ char_u *fmt,
+ int use_sandbox,
+ char_u fillchar,
+ int maxwidth,
+ stl_hlrec_t **hltab,
+ StlClickRecord **tabtab
+ );
+ ]]
+
+ return ffi.C.build_stl_str_hl(
+ ffi.C.find_window_by_handle(0, ffi.new('Error')),
+ ffi.new('char_u[1024]'),
+ 1024,
+ ffi.cast('char_u*', 'StatusLineOfLength20'),
+ 0,
+ 0,
+ 0,
+ nil,
+ nil
+ )
+ ]=])
+ end)
+end)
diff --git a/test/functional/lua/json_spec.lua b/test/functional/lua/json_spec.lua
new file mode 100644
index 0000000000..fbb21bfd57
--- /dev/null
+++ b/test/functional/lua/json_spec.lua
@@ -0,0 +1,133 @@
+local helpers = require('test.functional.helpers')(after_each)
+local clear = helpers.clear
+local NIL = helpers.NIL
+local exec_lua = helpers.exec_lua
+local eq = helpers.eq
+
+describe('vim.json.decode function', function()
+ before_each(function()
+ clear()
+ end)
+
+ it('parses null, true, false', function()
+ eq(NIL, exec_lua([[return vim.json.decode('null')]]))
+ eq(true, exec_lua([[return vim.json.decode('true')]]))
+ eq(false, exec_lua([[return vim.json.decode('false')]]))
+ end)
+
+ it('parses integer numbers', function()
+ eq(100000, exec_lua([[return vim.json.decode('100000')]]))
+ eq(-100000, exec_lua([[return vim.json.decode('-100000')]]))
+ eq(100000, exec_lua([[return vim.json.decode(' 100000 ')]]))
+ eq(-100000, exec_lua([[return vim.json.decode(' -100000 ')]]))
+ eq(0, exec_lua([[return vim.json.decode('0')]]))
+ eq(0, exec_lua([[return vim.json.decode('-0')]]))
+ end)
+
+ it('parses floating-point numbers', function()
+ -- This behavior differs from vim.fn.json_decode, which return '100000.0'
+ eq('100000', exec_lua([[return tostring(vim.json.decode('100000.0'))]]))
+ eq(100000.5, exec_lua([[return vim.json.decode('100000.5')]]))
+ eq(-100000.5, exec_lua([[return vim.json.decode('-100000.5')]]))
+ eq(-100000.5e50, exec_lua([[return vim.json.decode('-100000.5e50')]]))
+ eq(100000.5e50, exec_lua([[return vim.json.decode('100000.5e50')]]))
+ eq(100000.5e50, exec_lua([[return vim.json.decode('100000.5e+50')]]))
+ eq(-100000.5e-50, exec_lua([[return vim.json.decode('-100000.5e-50')]]))
+ eq(100000.5e-50, exec_lua([[return vim.json.decode('100000.5e-50')]]))
+ eq(100000e-50, exec_lua([[return vim.json.decode('100000e-50')]]))
+ eq(0.5, exec_lua([[return vim.json.decode('0.5')]]))
+ eq(0.005, exec_lua([[return vim.json.decode('0.005')]]))
+ eq(0.005, exec_lua([[return vim.json.decode('0.00500')]]))
+ eq(0.5, exec_lua([[return vim.json.decode('0.00500e+002')]]))
+ eq(0.00005, exec_lua([[return vim.json.decode('0.00500e-002')]]))
+
+ eq(-0.0, exec_lua([[return vim.json.decode('-0.0')]]))
+ eq(-0.0, exec_lua([[return vim.json.decode('-0.0e0')]]))
+ eq(-0.0, exec_lua([[return vim.json.decode('-0.0e+0')]]))
+ eq(-0.0, exec_lua([[return vim.json.decode('-0.0e-0')]]))
+ eq(-0.0, exec_lua([[return vim.json.decode('-0e-0')]]))
+ eq(-0.0, exec_lua([[return vim.json.decode('-0e-2')]]))
+ eq(-0.0, exec_lua([[return vim.json.decode('-0e+2')]]))
+
+ eq(0.0, exec_lua([[return vim.json.decode('0.0')]]))
+ eq(0.0, exec_lua([[return vim.json.decode('0.0e0')]]))
+ eq(0.0, exec_lua([[return vim.json.decode('0.0e+0')]]))
+ eq(0.0, exec_lua([[return vim.json.decode('0.0e-0')]]))
+ eq(0.0, exec_lua([[return vim.json.decode('0e-0')]]))
+ eq(0.0, exec_lua([[return vim.json.decode('0e-2')]]))
+ eq(0.0, exec_lua([[return vim.json.decode('0e+2')]]))
+ end)
+
+ it('parses containers', function()
+ eq({1}, exec_lua([[return vim.json.decode('[1]')]]))
+ eq({NIL, 1}, exec_lua([[return vim.json.decode('[null, 1]')]]))
+ eq({['1']=2}, exec_lua([[return vim.json.decode('{"1": 2}')]]))
+ eq({['1']=2, ['3']={{['4']={['5']={{}, 1}}}}},
+ exec_lua([[return vim.json.decode('{"1": 2, "3": [{"4": {"5": [ [], 1]}}]}')]]))
+ end)
+
+ it('parses strings properly', function()
+ eq('\n', exec_lua([=[return vim.json.decode([["\n"]])]=]))
+ eq('', exec_lua([=[return vim.json.decode([[""]])]=]))
+ eq('\\/"\t\b\n\r\f', exec_lua([=[return vim.json.decode([["\\\/\"\t\b\n\r\f"]])]=]))
+ eq('/a', exec_lua([=[return vim.json.decode([["\/a"]])]=]))
+ -- Unicode characters: 2-byte, 3-byte
+ eq('«',exec_lua([=[return vim.json.decode([["«"]])]=]))
+ eq('ફ',exec_lua([=[return vim.json.decode([["ફ"]])]=]))
+ end)
+
+ it('parses surrogate pairs properly', function()
+ eq('\240\144\128\128', exec_lua([[return vim.json.decode('"\\uD800\\uDC00"')]]))
+ end)
+
+ it('accepts all spaces in every position where space may be put', function()
+ local s = ' \t\n\r \t\r\n \n\t\r \n\r\t \r\t\n \r\n\t\t \n\r\t \r\n\t\n \r\t\n\r \t\r \n\t\r\n \n \t\r\n \r\t\n\t \r\n\t\r \n\r \t\n\r\t \r \t\n\r \n\t\r\t \n\r\t\n \r\n \t\r\n\t'
+ local str = ('%s{%s"key"%s:%s[%s"val"%s,%s"val2"%s]%s,%s"key2"%s:%s1%s}%s'):gsub('%%s', s)
+ eq({key={'val', 'val2'}, key2=1}, exec_lua([[return vim.json.decode(...)]], str))
+ end)
+
+end)
+
+describe('vim.json.encode function', function()
+ before_each(function()
+ clear()
+ end)
+
+ it('dumps strings', function()
+ eq('"Test"', exec_lua([[return vim.json.encode('Test')]]))
+ eq('""', exec_lua([[return vim.json.encode('')]]))
+ eq('"\\t"', exec_lua([[return vim.json.encode('\t')]]))
+ eq('"\\n"', exec_lua([[return vim.json.encode('\n')]]))
+ -- vim.fn.json_encode return \\u001B
+ eq('"\\u001b"', exec_lua([[return vim.json.encode('\27')]]))
+ eq('"þÿþ"', exec_lua([[return vim.json.encode('þÿþ')]]))
+ end)
+
+ it('dumps numbers', function()
+ eq('0', exec_lua([[return vim.json.encode(0)]]))
+ eq('10', exec_lua([[return vim.json.encode(10)]]))
+ eq('-10', exec_lua([[return vim.json.encode(-10)]]))
+ end)
+
+ it('dumps floats', function()
+ eq('10.5', exec_lua([[return vim.json.encode(10.5)]]))
+ eq('-10.5', exec_lua([[return vim.json.encode(-10.5)]]))
+ eq('-1e-05', exec_lua([[return vim.json.encode(-1e-5)]]))
+ end)
+
+ it('dumps lists', function()
+ eq('[]', exec_lua([[return vim.json.encode({})]]))
+ eq('[[]]', exec_lua([[return vim.json.encode({{}})]]))
+ eq('[[],[]]', exec_lua([[return vim.json.encode({{}, {}})]]))
+ end)
+
+ it('dumps dictionaries', function()
+ eq('{}', exec_lua([[return vim.json.encode(vim.empty_dict())]]))
+ eq('{"d":[]}', exec_lua([[return vim.json.encode({d={}})]]))
+ end)
+
+ it('dumps vim.NIL', function()
+ eq('null', exec_lua([[return vim.json.encode(vim.NIL)]]))
+ end)
+
+end)
diff --git a/test/functional/lua/luaeval_spec.lua b/test/functional/lua/luaeval_spec.lua
index 255e99032f..0675ec9abd 100644
--- a/test/functional/lua/luaeval_spec.lua
+++ b/test/functional/lua/luaeval_spec.lua
@@ -86,14 +86,15 @@ describe('luaeval()', function()
-- meaningful later.
it('correctly evaluates scalars', function()
+ -- Also test method call (->) syntax
eq(1, funcs.luaeval('1'))
- eq(0, eval('type(luaeval("1"))'))
+ eq(0, eval('"1"->luaeval()->type()'))
eq(1.5, funcs.luaeval('1.5'))
- eq(5, eval('type(luaeval("1.5"))'))
+ eq(5, eval('"1.5"->luaeval()->type()'))
eq("test", funcs.luaeval('"test"'))
- eq(1, eval('type(luaeval("\'test\'"))'))
+ eq(1, eval('"\'test\'"->luaeval()->type()'))
eq('', funcs.luaeval('""'))
eq('\000', funcs.luaeval([['\0']]))
diff --git a/test/functional/lua/ui_spec.lua b/test/functional/lua/ui_spec.lua
new file mode 100644
index 0000000000..94f1b5840b
--- /dev/null
+++ b/test/functional/lua/ui_spec.lua
@@ -0,0 +1,46 @@
+local helpers = require('test.functional.helpers')(after_each)
+local eq = helpers.eq
+local exec_lua = helpers.exec_lua
+local clear = helpers.clear
+
+describe('vim.ui', function()
+ before_each(function()
+ clear()
+ end)
+
+
+ describe('select', function()
+ it('can select an item', function()
+ local result = exec_lua[[
+ local items = {
+ { name = 'Item 1' },
+ { name = 'Item 2' },
+ }
+ local opts = {
+ format_item = function(entry)
+ return entry.name
+ end
+ }
+ local selected
+ local cb = function(item)
+ selected = item
+ end
+ -- inputlist would require input and block the test;
+ local choices
+ vim.fn.inputlist = function(x)
+ choices = x
+ return 1
+ end
+ vim.ui.select(items, opts, cb)
+ vim.wait(100, function() return selected ~= nil end)
+ return {selected, choices}
+ ]]
+ eq({ name = 'Item 1' }, result[1])
+ eq({
+ 'Select one of:',
+ '1: Item 1',
+ '2: Item 2',
+ }, result[2])
+ end)
+ end)
+end)
diff --git a/test/functional/lua/uri_spec.lua b/test/functional/lua/uri_spec.lua
index 052a8a1ecd..81f1820986 100644
--- a/test/functional/lua/uri_spec.lua
+++ b/test/functional/lua/uri_spec.lua
@@ -2,6 +2,7 @@ local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local exec_lua = helpers.exec_lua
local eq = helpers.eq
+local write_file = require('test.helpers').write_file
describe('URI methods', function()
before_each(function()
@@ -158,6 +159,22 @@ describe('URI methods', function()
end)
+ describe('uri from bufnr', function()
+ it('Windows paths should not be treated as uris', function()
+ if not helpers.iswin() then return end
+
+ local file = helpers.tmpname()
+ write_file(file, 'Test content')
+ local test_case = string.format([[
+ local file = '%s'
+ return vim.uri_from_bufnr(vim.fn.bufadd(file))
+ ]], file)
+ local expected_uri = 'file:///' .. file:gsub("\\", "/")
+ eq(expected_uri, exec_lua(test_case))
+ os.remove(file)
+ end)
+ end)
+
describe('uri to bufnr', function()
it('uri_to_bufnr & uri_from_bufnr returns original uri for non-file uris', function()
local uri = 'jdt://contents/java.base/java.util/List.class?=sql/%5C/home%5C/user%5C/.jabba%5C/jdk%5C/openjdk%5C@1.14.0%5C/lib%5C/jrt-fs.jar%60java.base=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/en%5C/java%5C/javase%5C/14%5C/docs%5C/api%5C/=/%3Cjava.util(List.class'
diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua
index f3d265cb92..3123063b8c 100644
--- a/test/functional/lua/vim_spec.lua
+++ b/test/functional/lua/vim_spec.lua
@@ -237,29 +237,34 @@ describe('lua stdlib', function()
end)
it("vim.split", function()
- local split = function(str, sep, plain)
- return exec_lua('return vim.split(...)', str, sep, plain)
+ local split = function(str, sep, kwargs)
+ return exec_lua('return vim.split(...)', str, sep, kwargs)
end
local tests = {
- { "a,b", ",", false, { 'a', 'b' } },
- { ":aa::bb:", ":", false, { '', 'aa', '', 'bb', '' } },
- { "::ee::ff:", ":", false, { '', '', 'ee', '', 'ff', '' } },
- { "ab", ".", false, { '', '', '' } },
- { "a1b2c", "[0-9]", false, { 'a', 'b', 'c' } },
- { "xy", "", false, { 'x', 'y' } },
- { "here be dragons", " ", false, { "here", "be", "dragons"} },
- { "axaby", "ab?", false, { '', 'x', 'y' } },
- { "f v2v v3v w2w ", "([vw])2%1", false, { 'f ', ' v3v ', ' ' } },
- { "", "", false, {} },
- { "", "a", false, { '' } },
- { "x*yz*oo*l", "*", true, { 'x', 'yz', 'oo', 'l' } },
+ { "a,b", ",", false, false, { 'a', 'b' } },
+ { ":aa::bb:", ":", false, false, { '', 'aa', '', 'bb', '' } },
+ { ":aa::bb:", ":", false, true, { 'aa', '', 'bb' } },
+ { "::ee::ff:", ":", false, false, { '', '', 'ee', '', 'ff', '' } },
+ { "::ee::ff:", ":", false, true, { 'ee', '', 'ff' } },
+ { "ab", ".", false, false, { '', '', '' } },
+ { "a1b2c", "[0-9]", false, false, { 'a', 'b', 'c' } },
+ { "xy", "", false, false, { 'x', 'y' } },
+ { "here be dragons", " ", false, false, { "here", "be", "dragons"} },
+ { "axaby", "ab?", false, false, { '', 'x', 'y' } },
+ { "f v2v v3v w2w ", "([vw])2%1", false, false, { 'f ', ' v3v ', ' ' } },
+ { "", "", false, false, {} },
+ { "", "a", false, false, { '' } },
+ { "x*yz*oo*l", "*", true, false, { 'x', 'yz', 'oo', 'l' } },
}
for _, t in ipairs(tests) do
- eq(t[4], split(t[1], t[2], t[3]))
+ eq(t[5], split(t[1], t[2], {plain=t[3], trimempty=t[4]}))
end
+ -- Test old signature
+ eq({'x', 'yz', 'oo', 'l'}, split("x*yz*oo*l", "*", true))
+
local loops = {
{ "abc", ".-" },
}
@@ -283,9 +288,8 @@ describe('lua stdlib', function()
vim/shared.lua:0: in function <vim/shared.lua:0>]]),
pcall_err(split, 'string', 1))
eq(dedent([[
- Error executing lua: vim/shared.lua:0: plain: expected boolean, got number
+ Error executing lua: vim/shared.lua:0: kwargs: expected table, got number
stack traceback:
- vim/shared.lua:0: in function 'gsplit'
vim/shared.lua:0: in function <vim/shared.lua:0>]]),
pcall_err(split, 'string', 'string', 1))
end)
@@ -992,6 +996,9 @@ describe('lua stdlib', function()
vim.g.to_delete = nil
]]
eq(NIL, funcs.luaeval "vim.g.to_delete")
+
+ matches([[^Error executing lua: .*: attempt to index .* nil value]],
+ pcall_err(exec_lua, 'return vim.g[0].testing'))
end)
it('vim.b', function()
@@ -1001,18 +1008,25 @@ describe('lua stdlib', function()
vim.api.nvim_buf_set_var(0, "floaty", 5120.1)
vim.api.nvim_buf_set_var(0, "nullvar", vim.NIL)
vim.api.nvim_buf_set_var(0, "to_delete", {hello="world"})
+ BUF = vim.api.nvim_create_buf(false, true)
+ vim.api.nvim_buf_set_var(BUF, "testing", "bye")
]]
eq('hi', funcs.luaeval "vim.b.testing")
+ eq('bye', funcs.luaeval "vim.b[BUF].testing")
eq(123, funcs.luaeval "vim.b.other")
eq(5120.1, funcs.luaeval "vim.b.floaty")
eq(NIL, funcs.luaeval "vim.b.nonexistant")
+ eq(NIL, funcs.luaeval "vim.b[BUF].nonexistant")
eq(NIL, funcs.luaeval "vim.b.nullvar")
-- lost over RPC, so test locally:
eq({false, true}, exec_lua [[
return {vim.b.nonexistant == vim.NIL, vim.b.nullvar == vim.NIL}
]])
+ matches([[^Error executing lua: .*: attempt to index .* nil value]],
+ pcall_err(exec_lua, 'return vim.b[BUF][0].testing'))
+
eq({hello="world"}, funcs.luaeval "vim.b.to_delete")
exec_lua [[
vim.b.to_delete = nil
@@ -1033,11 +1047,22 @@ describe('lua stdlib', function()
vim.api.nvim_win_set_var(0, "testing", "hi")
vim.api.nvim_win_set_var(0, "other", 123)
vim.api.nvim_win_set_var(0, "to_delete", {hello="world"})
+ BUF = vim.api.nvim_create_buf(false, true)
+ WIN = vim.api.nvim_open_win(BUF, false, {
+ width=10, height=10,
+ relative='win', row=0, col=0
+ })
+ vim.api.nvim_win_set_var(WIN, "testing", "bye")
]]
eq('hi', funcs.luaeval "vim.w.testing")
+ eq('bye', funcs.luaeval "vim.w[WIN].testing")
eq(123, funcs.luaeval "vim.w.other")
eq(NIL, funcs.luaeval "vim.w.nonexistant")
+ eq(NIL, funcs.luaeval "vim.w[WIN].nonexistant")
+
+ matches([[^Error executing lua: .*: attempt to index .* nil value]],
+ pcall_err(exec_lua, 'return vim.w[WIN][0].testing'))
eq({hello="world"}, funcs.luaeval "vim.w.to_delete")
exec_lua [[
@@ -1064,6 +1089,12 @@ describe('lua stdlib', function()
eq('hi', funcs.luaeval "vim.t.testing")
eq(123, funcs.luaeval "vim.t.other")
eq(NIL, funcs.luaeval "vim.t.nonexistant")
+ eq('hi', funcs.luaeval "vim.t[0].testing")
+ eq(123, funcs.luaeval "vim.t[0].other")
+ eq(NIL, funcs.luaeval "vim.t[0].nonexistant")
+
+ matches([[^Error executing lua: .*: attempt to index .* nil value]],
+ pcall_err(exec_lua, 'return vim.t[0][0].testing'))
eq({hello="world"}, funcs.luaeval "vim.t.to_delete")
exec_lua [[
@@ -1092,6 +1123,8 @@ describe('lua stdlib', function()
eq(funcs.luaeval "vim.api.nvim_get_vvar('progpath')", funcs.luaeval "vim.v.progpath")
eq(false, funcs.luaeval "vim.v['false']")
eq(NIL, funcs.luaeval "vim.v.null")
+ matches([[^Error executing lua: .*: attempt to index .* nil value]],
+ pcall_err(exec_lua, 'return vim.v[0].progpath'))
end)
it('vim.bo', function()
@@ -2255,7 +2288,7 @@ end)
describe('lua: require("mod") from packages', function()
before_each(function()
- command('set rtp+=test/functional/fixtures')
+ command('set rtp+=test/functional/fixtures pp+=test/functional/fixtures')
end)
it('propagates syntax error', function()
@@ -2266,4 +2299,13 @@ describe('lua: require("mod") from packages', function()
matches("unexpected symbol", syntax_error_msg)
end)
+
+ it('uses the right order of mod.lua vs mod/init.lua', function()
+ -- lua/fancy_x.lua takes precedence over lua/fancy_x/init.lua
+ eq('I am fancy_x.lua', exec_lua [[ return require'fancy_x' ]])
+ -- but lua/fancy_y/init.lua takes precedence over after/lua/fancy_y.lua
+ eq('I am init.lua of fancy_y!', exec_lua [[ return require'fancy_y' ]])
+ -- safety check: after/lua/fancy_z.lua is still loaded
+ eq('I am fancy_z.lua', exec_lua [[ return require'fancy_z' ]])
+ end)
end)
diff --git a/test/functional/plugin/health_spec.lua b/test/functional/plugin/health_spec.lua
index 85c67be8f9..b84e9d1533 100644
--- a/test/functional/plugin/health_spec.lua
+++ b/test/functional/plugin/health_spec.lua
@@ -1,4 +1,5 @@
local helpers = require('test.functional.helpers')(after_each)
+local global_helpers = require('test.helpers')
local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
@@ -35,6 +36,7 @@ describe(':checkhealth', function()
clear()
eq('nvim', getcompletion('nvim', 'checkhealth')[1])
eq('provider', getcompletion('prov', 'checkhealth')[1])
+ eq('vim.lsp', getcompletion('vim.ls', 'checkhealth')[1])
end)
end)
@@ -48,42 +50,34 @@ describe('health.vim', function()
command("set runtimepath+=test/functional/fixtures")
end)
- it("health#report_*()", function()
- helpers.source([[
- let g:health_report = execute([
- \ "call health#report_start('Check Bar')",
- \ "call health#report_ok('Bar status')",
- \ "call health#report_ok('Other Bar status')",
- \ "call health#report_warn('Zub')",
- \ "call health#report_start('Baz')",
- \ "call health#report_warn('Zim', ['suggestion 1', 'suggestion 2'])"
- \ ])
- ]])
- local result = helpers.eval("g:health_report")
-
- helpers.eq(helpers.dedent([[
-
-
- ## Check Bar
- - OK: Bar status
- - OK: Other Bar status
- - WARNING: Zub
-
- ## Baz
- - WARNING: Zim
+ describe(":checkhealth", function()
+ it("functions health#report_*() render correctly", function()
+ command("checkhealth full_render")
+ helpers.expect([[
+
+ full_render: health#full_render#check
+ ========================================================================
+ ## report 1
+ - OK: life is fine
+ - WARNING: no what installed
- ADVICE:
- - suggestion 1
- - suggestion 2]]),
- result)
- end)
+ - pip what
+ - make what
+ ## report 2
+ - INFO: stuff is stable
+ - ERROR: why no hardcopy
+ - ADVICE:
+ - :help |:hardcopy|
+ - :help |:TOhtml|
+ ]])
+ end)
- describe(":checkhealth", function()
it("concatenates multiple reports", function()
- command("checkhealth success1 success2")
+ command("checkhealth success1 success2 test_plug")
helpers.expect([[
- health#success1#check
+ success1: health#success1#check
========================================================================
## report 1
- OK: everything is fine
@@ -91,25 +85,111 @@ describe('health.vim', function()
## report 2
- OK: nothing to see here
- health#success2#check
+ success2: health#success2#check
========================================================================
## another 1
- OK: ok
+
+ test_plug: require("test_plug.health").check()
+ ========================================================================
+ ## report 1
+ - OK: everything is fine
+
+ ## report 2
+ - OK: nothing to see here
+ ]])
+ end)
+
+ it("lua plugins, skips vimscript healthchecks with the same name", function()
+ command("checkhealth test_plug")
+ -- Existing file in test/functional/fixtures/lua/test_plug/autoload/health/test_plug.vim
+ -- and the Lua healthcheck is used instead.
+ helpers.expect([[
+
+ test_plug: require("test_plug.health").check()
+ ========================================================================
+ ## report 1
+ - OK: everything is fine
+
+ ## report 2
+ - OK: nothing to see here
]])
end)
+ it("lua plugins submodules", function()
+ command("checkhealth test_plug.submodule")
+ helpers.expect([[
+
+ test_plug.submodule: require("test_plug.submodule.health").check()
+ ========================================================================
+ ## report 1
+ - OK: everything is fine
+
+ ## report 2
+ - OK: nothing to see here
+ ]])
+ end)
+
+ it("lua plugins submodules with expression '*'", function()
+ command("checkhealth test_plug*")
+ local buf_lines = helpers.curbuf('get_lines', 0, -1, true)
+ -- avoid dealing with path separators
+ local received = table.concat(buf_lines, '\n', 1, #buf_lines - 2)
+ local expected = helpers.dedent([[
+
+ test_plug: require("test_plug.health").check()
+ ========================================================================
+ ## report 1
+ - OK: everything is fine
+
+ ## report 2
+ - OK: nothing to see here
+
+ test_plug.submodule: require("test_plug.submodule.health").check()
+ ========================================================================
+ ## report 1
+ - OK: everything is fine
+
+ ## report 2
+ - OK: nothing to see here
+
+ test_plug.submodule_failed: require("test_plug.submodule_failed.health").check()
+ ========================================================================
+ - ERROR: Failed to run healthcheck for "test_plug.submodule_failed" plugin. Exception:
+ function health#check, line 24]])
+ eq(expected, received)
+ end)
+
it("gracefully handles broken healthcheck", function()
command("checkhealth broken")
helpers.expect([[
- health#broken#check
+ broken: health#broken#check
========================================================================
- ERROR: Failed to run healthcheck for "broken" plugin. Exception:
- function health#check[21]..health#broken#check, line 1
+ function health#check[24]..health#broken#check, line 1
caused an error
]])
end)
+ it("gracefully handles broken lua healthcheck", function()
+ command("checkhealth test_plug.submodule_failed")
+ local buf_lines = helpers.curbuf('get_lines', 0, -1, true)
+ local received = table.concat(buf_lines, '\n', 1, #buf_lines - 2)
+ -- avoid dealing with path separators
+ local lua_err = "attempt to perform arithmetic on a nil value"
+ local last_line = buf_lines[#buf_lines - 1]
+ assert(string.find(last_line, lua_err) ~= nil, "Lua error not present")
+
+ local expected = global_helpers.dedent([[
+
+ test_plug.submodule_failed: require("test_plug.submodule_failed.health").check()
+ ========================================================================
+ - ERROR: Failed to run healthcheck for "test_plug.submodule_failed" plugin. Exception:
+ function health#check, line 24]])
+ eq(expected, received)
+ end)
+
it("highlights OK, ERROR", function()
local screen = Screen.new(72, 10)
screen:attach()
@@ -126,23 +206,24 @@ describe('health.vim', function()
command("set laststatus=0")
screen:expect{grid=[[
^ |
- {Heading:health#foo#check} |
+ {Heading:foo: } |
{Bar:========================================================================}|
- {Bullet: -} {Error:ERROR:} No healthcheck found for "foo" plugin. |
+ {Bullet: -} {Error:ERROR}: No healthcheck found for "foo" plugin. |
|
- {Heading:health#success1#check} |
+ {Heading:success1: health#success1#check} |
{Bar:========================================================================}|
{Heading2:##}{Heading: report 1} |
- {Bullet: -} {Ok:OK:} everything is fine |
+ {Bullet: -} {Ok:OK}: everything is fine |
|
]]}
end)
it("gracefully handles invalid healthcheck", function()
command("checkhealth non_existent_healthcheck")
+ -- luacheck: ignore 613
helpers.expect([[
- health#non_existent_healthcheck#check
+ non_existent_healthcheck:
========================================================================
- ERROR: No healthcheck found for "non_existent_healthcheck" plugin.
]])
diff --git a/test/functional/plugin/lsp/codelens_spec.lua b/test/functional/plugin/lsp/codelens_spec.lua
index e48a0ad260..c8b75e65fc 100644
--- a/test/functional/plugin/lsp/codelens_spec.lua
+++ b/test/functional/plugin/lsp/codelens_spec.lua
@@ -58,5 +58,33 @@ describe('vim.lsp.codelens', function()
]], bufnr)
eq({[1] = {'Lens1', 'LspCodeLens'}}, virtual_text_chunks)
+
+ end)
+ it('codelens uses client commands', function()
+ local fake_uri = "file:///fake/uri"
+ local cmd = exec_lua([[
+ fake_uri = ...
+ local bufnr = vim.uri_to_bufnr(fake_uri)
+ vim.fn.bufload(bufnr)
+ vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {'One line'})
+ local lenses = {
+ {
+ range = {
+ start = { line = 0, character = 0, },
+ ['end'] = { line = 0, character = 8 }
+ },
+ command = { title = 'Lens1', command = 'Dummy' }
+ },
+ }
+ vim.lsp.codelens.on_codelens(nil, lenses, {method='textDocument/codeLens', client_id=1, bufnr=bufnr})
+ local cmd_called = nil
+ vim.lsp.commands['Dummy'] = function(command)
+ cmd_called = command
+ end
+ vim.api.nvim_set_current_buf(bufnr)
+ vim.lsp.codelens.run()
+ return cmd_called
+ ]], fake_uri)
+ eq({ command = 'Dummy', title = 'Lens1' }, cmd)
end)
end)
diff --git a/test/functional/plugin/lsp/diagnostic_spec.lua b/test/functional/plugin/lsp/diagnostic_spec.lua
index 353de667ea..243ad6bdb8 100644
--- a/test/functional/plugin/lsp/diagnostic_spec.lua
+++ b/test/functional/plugin/lsp/diagnostic_spec.lua
@@ -428,6 +428,32 @@ describe('vim.lsp.diagnostic', function()
end)
end)
end)
+
+ it('maintains LSP information when translating diagnostics', function()
+ local result = exec_lua [[
+ local diagnostics = {
+ make_error("Error 1", 1, 1, 1, 5),
+ }
+
+ diagnostics[1].code = 42
+ diagnostics[1].tags = {"foo", "bar"}
+ diagnostics[1].data = "Hello world"
+
+ vim.lsp.diagnostic.on_publish_diagnostics(nil, {
+ uri = fake_uri,
+ diagnostics = diagnostics,
+ }, {client_id=1})
+
+ return {
+ vim.diagnostic.get(diagnostic_bufnr, {lnum=1})[1],
+ vim.lsp.diagnostic.get_line_diagnostics(diagnostic_bufnr, 1)[1],
+ }
+ ]]
+ eq({code = 42, tags = {"foo", "bar"}, data = "Hello world"}, result[1].user_data.lsp)
+ eq(42, result[2].code)
+ eq({"foo", "bar"}, result[2].tags)
+ eq("Hello world", result[2].data)
+ end)
end)
describe("vim.lsp.diagnostic.get_line_diagnostics", function()
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua
index 6ad37110c7..ce50abb50d 100644
--- a/test/functional/plugin/lsp_spec.lua
+++ b/test/functional/plugin/lsp_spec.lua
@@ -132,37 +132,38 @@ local function test_rpc_server(config)
end
describe('LSP', function()
- describe('server_name specified', function()
- before_each(function()
- clear_notrace()
- -- Run an instance of nvim on the file which contains our "scripts".
- -- Pass TEST_NAME to pick the script.
- local test_name = "basic_init"
- exec_lua([=[
- lsp = require('vim.lsp')
- local test_name, fixture_filename, logfile = ...
- function test__start_client()
- return lsp.start_client {
- cmd_env = {
- NVIM_LOG_FILE = logfile;
- };
- cmd = {
- vim.v.progpath, '-Es', '-u', 'NONE', '--headless',
- "-c", string.format("lua TEST_NAME = %q", test_name),
- "-c", "luafile "..fixture_filename;
- };
- root_dir = vim.loop.cwd();
- }
- end
- TEST_CLIENT1 = test__start_client()
- ]=], test_name, fake_lsp_code, fake_lsp_logfile)
- end)
+ before_each(function()
+ clear_notrace()
- after_each(function()
- exec_lua("lsp._vim_exit_handler()")
- -- exec_lua("lsp.stop_all_clients(true)")
- end)
+ -- Run an instance of nvim on the file which contains our "scripts".
+ -- Pass TEST_NAME to pick the script.
+ local test_name = "basic_init"
+ exec_lua([=[
+ lsp = require('vim.lsp')
+ local test_name, fixture_filename, logfile = ...
+ function test__start_client()
+ return lsp.start_client {
+ cmd_env = {
+ NVIM_LOG_FILE = logfile;
+ };
+ cmd = {
+ vim.v.progpath, '-Es', '-u', 'NONE', '--headless',
+ "-c", string.format("lua TEST_NAME = %q", test_name),
+ "-c", "luafile "..fixture_filename;
+ };
+ root_dir = vim.loop.cwd();
+ }
+ end
+ TEST_CLIENT1 = test__start_client()
+ ]=], test_name, fake_lsp_code, fake_lsp_logfile)
+ end)
+ after_each(function()
+ exec_lua("lsp._vim_exit_handler()")
+ -- exec_lua("lsp.stop_all_clients(true)")
+ end)
+
+ describe('server_name specified', function()
it('start_client(), stop_client()', function()
retry(nil, 4000, function()
eq(1, exec_lua('return #lsp.get_active_clients()'))
@@ -334,7 +335,6 @@ describe('LSP', function()
}
end)
it('workspace/configuration returns NIL per section if client was started without config.settings', function()
- clear_notrace()
fake_lsp_server_setup('workspace/configuration no settings')
eq({ NIL, NIL, }, exec_lua [[
local result = {
@@ -405,7 +405,7 @@ describe('LSP', function()
}
end)
- it('should call unsupported_method when trying to call an unsupported method', function()
+ it('should not call unsupported_method when trying to call an unsupported method', function()
local expected_handlers = {
{NIL, {}, {method="shutdown", client_id=1}};
}
@@ -415,24 +415,12 @@ describe('LSP', function()
exec_lua([=[
BUFFER = vim.api.nvim_get_current_buf()
lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)
- vim.lsp.handlers['textDocument/typeDefinition'] = function(err, result, ctx)
- local method = ctx.method
- vim.lsp._last_lsp_handler = { err = err; method = method }
- end
- vim.lsp._unsupported_method = function(method)
- vim.lsp._last_unsupported_method = method
- return 'fake-error'
- end
- vim.lsp.buf.type_definition()
+ vim.lsp.handlers['textDocument/typeDefinition'] = function() end
]=])
end;
on_init = function(client)
client.stop()
- local method = exec_lua("return vim.lsp._last_unsupported_method")
- eq("textDocument/typeDefinition", method)
- local lsp_cb_call = exec_lua("return vim.lsp._last_lsp_handler")
- eq("fake-error", lsp_cb_call.err)
- eq("textDocument/typeDefinition", lsp_cb_call.method)
+ exec_lua("vim.lsp.buf.type_definition()")
exec_lua [[
vim.api.nvim_command(BUFFER.."bwipeout")
]]
@@ -447,7 +435,7 @@ describe('LSP', function()
}
end)
- it('shouldn\'t call unsupported_method when no client and trying to call an unsupported method', function()
+ it('should not call unsupported_method when no client and trying to call an unsupported method', function()
local expected_handlers = {
{NIL, {}, {method="shutdown", client_id=1}};
}
@@ -455,20 +443,12 @@ describe('LSP', function()
test_name = "capabilities_for_client_supports_method";
on_setup = function()
exec_lua([=[
- vim.lsp.handlers['textDocument/typeDefinition'] = function(err, method)
- vim.lsp._last_lsp_handler = { err = err; method = method }
- end
- vim.lsp._unsupported_method = function(method)
- vim.lsp._last_unsupported_method = method
- return 'fake-error'
- end
- vim.lsp.buf.type_definition()
+ vim.lsp.handlers['textDocument/typeDefinition'] = function() end
]=])
end;
on_init = function(client)
client.stop()
- eq(NIL, exec_lua("return vim.lsp._last_unsupported_method"))
- eq(NIL, exec_lua("return vim.lsp._last_lsp_handler"))
+ exec_lua("vim.lsp.buf.type_definition()")
end;
on_exit = function(code, signal)
eq(0, code, "exit code", fake_lsp_logfile)
@@ -480,6 +460,55 @@ describe('LSP', function()
}
end)
+ it('should not forward RequestCancelled to callback', function()
+ local expected_handlers = {
+ {NIL, {}, {method="finish", client_id=1}};
+ }
+ local client
+ test_rpc_server {
+ test_name = "check_forward_request_cancelled";
+ on_init = function(_client)
+ _client.request("error_code_test")
+ client = _client
+ end;
+ on_exit = function(code, signal)
+ eq(0, code, "exit code", fake_lsp_logfile)
+ eq(0, signal, "exit signal", fake_lsp_logfile)
+ eq(0, #expected_handlers, "did not call expected handler")
+ end;
+ on_handler = function(err, _, ctx)
+ eq(table.remove(expected_handlers), {err, {}, ctx}, "expected handler")
+ if ctx.method == 'finish' then client.stop() end
+ end;
+ }
+ end)
+
+ it('should forward ContentModified to callback', function()
+ local expected_handlers = {
+ {NIL, {}, {method="finish", client_id=1}};
+ {{code = -32801}, NIL, {method = "error_code_test", client_id=1}};
+ }
+ local client
+ test_rpc_server {
+ test_name = "check_forward_content_modified";
+ on_init = function(_client)
+ _client.request("error_code_test")
+ client = _client
+ end;
+ on_exit = function(code, signal)
+ eq(0, code, "exit code", fake_lsp_logfile)
+ eq(0, signal, "exit signal", fake_lsp_logfile)
+ eq(0, #expected_handlers, "did not call expected handler")
+ end;
+ on_handler = function(err, _, ctx)
+ eq(table.remove(expected_handlers), {err, _, ctx}, "expected handler")
+ -- if ctx.method == 'error_code_test' then client.notify("finish") end
+ if ctx.method ~= 'finish' then client.notify('finish') end
+ if ctx.method == 'finish' then client.stop() end
+ end;
+ }
+ end)
+
it('should not send didOpen if the buffer closes before init', function()
local expected_handlers = {
{NIL, {}, {method="shutdown", client_id=1}};
@@ -1135,10 +1164,11 @@ describe('LSP', function()
eq({ 2, 6 }, funcs.nvim_win_get_cursor(0))
end)
- it('fix the cursor to the valid column if the content was removed', function()
+ it('fix the cursor to the valid col if the content was removed', function()
funcs.nvim_win_set_cursor(0, { 2, 6 })
local edits = {
- make_edit(1, 0, 1, 19, '')
+ make_edit(1, 0, 1, 6, ''),
+ make_edit(1, 6, 1, 19, '')
}
exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1)
eq({
@@ -1151,6 +1181,19 @@ describe('LSP', function()
eq({ 2, 0 }, funcs.nvim_win_get_cursor(0))
end)
+ it('fix the cursor to the valid row if the content was removed', function()
+ funcs.nvim_win_set_cursor(0, { 2, 6 })
+ local edits = {
+ make_edit(1, 0, 1, 6, ''),
+ make_edit(0, 18, 5, 0, '')
+ }
+ exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1)
+ eq({
+ 'First line of text';
+ }, buf_lines(1))
+ eq({ 1, 6 }, funcs.nvim_win_get_cursor(0))
+ end)
+
it('fix the cursor row', function()
funcs.nvim_win_set_cursor(0, { 3, 0 })
local edits = {
@@ -2022,83 +2065,6 @@ describe('LSP', function()
end)
end)
- describe('lsp.util.make_floating_popup_options', function()
- before_each(function()
- exec_lua [[
- local bufnr = vim.uri_to_bufnr("file:///fake/uri")
- local winheight = vim.fn.winheight(0)
- for i = 1, winheight do
- vim.api.nvim_buf_set_lines(bufnr, 0, 0, false, {''})
- end
- vim.api.nvim_win_set_buf(0, bufnr)
- vim.api.nvim_win_set_cursor(0, {winheight, 0})
- ]]
- end)
-
- local function popup_row(opts)
- return exec_lua([[
- return vim.lsp.util.make_floating_popup_options(...).row
- ]], 2, 2, opts)
- end
-
- local err_pattern = "^Error executing lua: %.%.%./util%.lua:0: invalid floating preview border: .*%. :help vim%.api%.nvim_open_win%(%)$"
-
- it('calculates default border height correctly', function()
- eq(0, popup_row())
- end)
-
- it('calculates string border height correctly', function()
- eq(0, popup_row({border = 'none'}))
- eq(-2, popup_row({border = 'single'}))
- eq(-2, popup_row({border = 'double'}))
- eq(-2, popup_row({border = 'rounded'}))
- eq(-2, popup_row({border = 'solid'}))
- eq(-1, popup_row({border = 'shadow'}))
- end)
-
- it('error on invalid string border', function()
- matches(err_pattern, pcall_err(popup_row, {border = ''}))
- matches(err_pattern, pcall_err(popup_row, {border = 'invalid'}))
- end)
-
- it('error on invalid array border length', function()
- matches(err_pattern, pcall_err(popup_row, {border = {}}))
- matches(err_pattern, pcall_err(popup_row, {border = {'', '', ''}}))
- matches(err_pattern, pcall_err(popup_row, {border = {'', '', '', '', ''}}))
- end)
-
- it('error on invalid array border member type', function()
- matches(err_pattern, pcall_err(popup_row, {border = {0}}))
- end)
-
- it('calculates 8-array border height correctly', function()
- eq(0, popup_row({border = {'', '', '', '', '', '', '', ''}}))
- eq(-2, popup_row({border = {'', '~', '', '~', '', '~', '', '~'}}))
- eq(-1, popup_row({border = {'', '', '', '~', '', '~', '', ''}}))
- eq(0, popup_row({border = {'', '', '', {'~', 'NormalFloat'}, '', '', '', {'~', 'NormalFloat'}}}))
- eq(-2, popup_row({border = {'', {'~', 'NormalFloat'}, '', '', '', {'~', 'NormalFloat'}, '', ''}}))
- end)
-
- it('calculates 4-array border height correctly', function()
- eq(0, popup_row({border = {'', '', '', ''}}))
- eq(-2, popup_row({border = {'', '~', '', '~'}}))
- eq(0, popup_row({border = {'', '', '', {'~', 'NormalFloat'}}}))
- eq(-2, popup_row({border = {'', {'~', 'NormalFloat'}, '', ''}}))
- end)
-
- it('calculates 2-array border height correctly', function()
- eq(0, popup_row({border = {'', ''}}))
- eq(-2, popup_row({border = {'', '~'}}))
- eq(-2, popup_row({border = {'', {'~', 'NormalFloat'}}}))
- end)
-
- it('calculates 1-array border height correctly', function()
- eq(0, popup_row({border = {''}}))
- eq(-2, popup_row({border = {'~'}}))
- eq(-2, popup_row({border = {{'~', 'NormalFloat'}}}))
- end)
- end)
-
describe('lsp.util._make_floating_popup_size', function()
before_each(function()
exec_lua [[ contents =
@@ -2353,6 +2319,10 @@ describe('LSP', function()
eq(0, signal, "exit signal", fake_lsp_logfile)
end;
on_handler = function(err, result, ctx)
+ -- Don't compare & assert params, they're not relevant for the testcase
+ -- This allows us to be lazy and avoid declaring them
+ ctx.params = nil
+
eq(table.remove(test.expected_handlers), {err, result, ctx}, "expected handler")
if ctx.method == 'start' then
exec_lua("vim.lsp.buf.rename()")
@@ -2370,4 +2340,59 @@ describe('LSP', function()
end
end)
+ describe('vim.lsp.buf.code_action', function()
+ it('Calls client side command if available', function()
+ local client
+ local expected_handlers = {
+ {NIL, {}, {method="shutdown", client_id=1}};
+ {NIL, {}, {method="start", client_id=1}};
+ }
+ test_rpc_server {
+ test_name = 'code_action_with_resolve',
+ on_init = function(client_)
+ client = client_
+ end,
+ on_setup = function()
+ end,
+ on_exit = function(code, signal)
+ eq(0, code, "exit code", fake_lsp_logfile)
+ eq(0, signal, "exit signal", fake_lsp_logfile)
+ end,
+ on_handler = function(err, result, ctx)
+ eq(table.remove(expected_handlers), {err, result, ctx})
+ if ctx.method == 'start' then
+ exec_lua([[
+ vim.lsp.commands['dummy1'] = function(cmd)
+ vim.lsp.commands['dummy2'] = function()
+ end
+ end
+ local bufnr = vim.api.nvim_get_current_buf()
+ vim.lsp.buf_attach_client(bufnr, TEST_RPC_CLIENT_ID)
+ vim.fn.inputlist = function()
+ return 1
+ end
+ vim.lsp.buf.code_action()
+ ]])
+ elseif ctx.method == 'shutdown' then
+ eq('function', exec_lua[[return type(vim.lsp.commands['dummy2'])]])
+ client.stop()
+ end
+ end
+ }
+ end)
+ end)
+ describe('vim.lsp.commands', function()
+ it('Accepts only string keys', function()
+ matches(
+ '.*The key for commands in `vim.lsp.commands` must be a string',
+ pcall_err(exec_lua, 'vim.lsp.commands[1] = function() end')
+ )
+ end)
+ it('Accepts only function values', function()
+ matches(
+ '.*Command added to `vim.lsp.commands` must be a function',
+ pcall_err(exec_lua, 'vim.lsp.commands.dummy = 10')
+ )
+ end)
+ end)
end)
diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua
index 103ae59b8e..7dcca231ee 100644
--- a/test/functional/terminal/buffer_spec.lua
+++ b/test/functional/terminal/buffer_spec.lua
@@ -22,14 +22,28 @@ describe(':terminal buffer', function()
it('terminal-mode forces various options', function()
feed([[<C-\><C-N>]])
- command('setlocal cursorline cursorcolumn scrolloff=4 sidescrolloff=7')
- eq({ 1, 1, 4, 7 }, eval('[&l:cursorline, &l:cursorcolumn, &l:scrolloff, &l:sidescrolloff]'))
- eq('n', eval('mode()'))
+ command('setlocal cursorline cursorlineopt=both cursorcolumn scrolloff=4 sidescrolloff=7')
+ eq({ 'both', 1, 1, 4, 7 }, eval('[&l:cursorlineopt, &l:cursorline, &l:cursorcolumn, &l:scrolloff, &l:sidescrolloff]'))
+ eq('nt', eval('mode(1)'))
-- Enter terminal-mode ("insert" mode in :terminal).
feed('i')
- eq('t', eval('mode()'))
- eq({ 0, 0, 0, 0 }, eval('[&l:cursorline, &l:cursorcolumn, &l:scrolloff, &l:sidescrolloff]'))
+ eq('t', eval('mode(1)'))
+ eq({ 'number', 1, 0, 0, 0 }, eval('[&l:cursorlineopt, &l:cursorline, &l:cursorcolumn, &l:scrolloff, &l:sidescrolloff]'))
+ end)
+
+ it('terminal-mode does not change cursorlineopt if cursorline is disabled', function()
+ feed([[<C-\><C-N>]])
+ command('setlocal nocursorline cursorlineopt=both')
+ feed('i')
+ eq({ 0, 'both' }, eval('[&l:cursorline, &l:cursorlineopt]'))
+ end)
+
+ it('terminal-mode disables cursorline when cursorlineopt is only set to "line', function()
+ feed([[<C-\><C-N>]])
+ command('setlocal cursorline cursorlineopt=line')
+ feed('i')
+ eq({ 0, 'line' }, eval('[&l:cursorline, &l:cursorlineopt]'))
end)
describe('when a new file is edited', function()
diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua
index 707c355069..065dd72485 100644
--- a/test/functional/terminal/ex_terminal_spec.lua
+++ b/test/functional/terminal/ex_terminal_spec.lua
@@ -96,19 +96,28 @@ describe(':terminal', function()
eq(3, #jumps)
end)
+ it('nvim_get_mode() in :terminal', function()
+ command(':terminal')
+ eq({ blocking=false, mode='nt' }, nvim('get_mode'))
+ feed('i')
+ eq({ blocking=false, mode='t' }, nvim('get_mode'))
+ feed([[<C-\><C-N>]])
+ eq({ blocking=false, mode='nt' }, nvim('get_mode'))
+ end)
+
it(':stopinsert RPC request exits terminal-mode #7807', function()
command(':terminal')
feed('i[tui] insert-mode')
eq({ blocking=false, mode='t' }, nvim('get_mode'))
command('stopinsert')
- eq({ blocking=false, mode='n' }, nvim('get_mode'))
+ eq({ blocking=false, mode='nt' }, nvim('get_mode'))
end)
it(':stopinsert in normal mode doesn\'t break insert mode #9889', function()
command(':terminal')
- eq({ blocking=false, mode='n' }, nvim('get_mode'))
+ eq({ blocking=false, mode='nt' }, nvim('get_mode'))
command(':stopinsert')
- eq({ blocking=false, mode='n' }, nvim('get_mode'))
+ eq({ blocking=false, mode='nt' }, nvim('get_mode'))
feed('a')
eq({ blocking=false, mode='t' }, nvim('get_mode'))
end)
diff --git a/test/functional/terminal/mouse_spec.lua b/test/functional/terminal/mouse_spec.lua
index 0eb5901b3b..3d8441b93c 100644
--- a/test/functional/terminal/mouse_spec.lua
+++ b/test/functional/terminal/mouse_spec.lua
@@ -33,16 +33,16 @@ describe(':terminal mouse', function()
describe('when the terminal has focus', function()
it('will exit focus on mouse-scroll', function()
- eq('t', eval('mode()'))
+ eq('t', eval('mode(1)'))
feed('<ScrollWheelUp><0,0>')
- eq('n', eval('mode()'))
+ eq('nt', eval('mode(1)'))
end)
it('will exit focus on <C-\\> + mouse-scroll', function()
- eq('t', eval('mode()'))
+ eq('t', eval('mode(1)'))
feed('<C-\\>')
feed('<ScrollWheelUp><0,0>')
- eq('n', eval('mode()'))
+ eq('nt', eval('mode(1)'))
end)
describe('with mouse events enabled by the program', function()
@@ -94,7 +94,7 @@ describe(':terminal mouse', function()
-- When the display area such as a number is clicked, it returns to the
-- normal mode.
feed('<LeftMouse><3,0>')
- eq('n', eval('mode()'))
+ eq('nt', eval('mode(1)'))
screen:expect([[
{7: 11 }^line28 |
{7: 12 }line29 |
diff --git a/test/functional/terminal/window_split_tab_spec.lua b/test/functional/terminal/window_split_tab_spec.lua
index 188afa1e84..c92107082e 100644
--- a/test/functional/terminal/window_split_tab_spec.lua
+++ b/test/functional/terminal/window_split_tab_spec.lua
@@ -111,7 +111,7 @@ describe(':terminal', function()
command('terminal')
feed('a<Cmd>wincmd j<CR>')
eq(2, eval("winnr()"))
- eq('t', eval('mode()'))
+ eq('t', eval('mode(1)'))
end)
end)
diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua
index 4373d17890..8074f91215 100644
--- a/test/functional/ui/decorations_spec.lua
+++ b/test/functional/ui/decorations_spec.lua
@@ -790,3 +790,511 @@ end]]
helpers.assert_alive()
end)
end)
+
+describe('decorations: virtual lines', function()
+ local screen, ns
+ before_each(function()
+ clear()
+ screen = Screen.new(50, 12)
+ screen:attach()
+ screen:set_default_attr_ids {
+ [1] = {bold=true, foreground=Screen.colors.Blue};
+ [2] = {foreground = Screen.colors.Cyan4};
+ [3] = {background = Screen.colors.Yellow1};
+ [4] = {bold = true};
+ [5] = {background = Screen.colors.Yellow, foreground = Screen.colors.Blue};
+ [6] = {foreground = Screen.colors.Blue};
+ [7] = {foreground = Screen.colors.SlateBlue};
+ [8] = {background = Screen.colors.WebGray, foreground = Screen.colors.DarkBlue};
+ [9] = {foreground = Screen.colors.Brown};
+ }
+
+ ns = meths.create_namespace 'test'
+ end)
+
+ local example_text = [[
+if (h->n_buckets < new_n_buckets) { // expand
+ khkey_t *new_keys = (khkey_t *)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t));
+ h->keys = new_keys;
+ if (kh_is_map && val_size) {
+ char *new_vals = krealloc( h->vals_buf, new_n_buckets * val_size);
+ h->vals_buf = new_vals;
+ }
+}]]
+
+ it('works with one line', function()
+ insert(example_text)
+ feed 'gg'
+ meths.buf_set_extmark(0, ns, 1, 33, {
+ virt_lines={ {{">> ", "NonText"}, {"krealloc", "Identifier"}, {": change the size of an allocation"}}};
+ virt_lines_above=true;
+ })
+
+ screen:expect{grid=[[
+ ^if (h->n_buckets < new_n_buckets) { // expand |
+ {1:>> }{2:krealloc}: change the size of an allocation |
+ khkey_t *new_keys = (khkey_t *)krealloc((void *)|
+ h->keys, new_n_buckets * sizeof(khkey_t)); |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = krealloc( h->vals_buf, new_n_|
+ buckets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ } |
+ |
+ ]]}
+
+ feed '/krealloc<cr>'
+ screen:expect{grid=[[
+ if (h->n_buckets < new_n_buckets) { // expand |
+ {1:>> }{2:krealloc}: change the size of an allocation |
+ khkey_t *new_keys = (khkey_t *){3:^krealloc}((void *)|
+ h->keys, new_n_buckets * sizeof(khkey_t)); |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = {3:krealloc}( h->vals_buf, new_n_|
+ buckets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ } |
+ /krealloc |
+ ]]}
+
+ -- virtual line remains anchored to the extmark
+ feed 'i<cr>'
+ screen:expect{grid=[[
+ if (h->n_buckets < new_n_buckets) { // expand |
+ khkey_t *new_keys = (khkey_t *) |
+ {1:>> }{2:krealloc}: change the size of an allocation |
+ {3:^krealloc}((void *)h->keys, new_n_buckets * sizeof(k|
+ hkey_t)); |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = {3:krealloc}( h->vals_buf, new_n_|
+ buckets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ {4:-- INSERT --} |
+ ]]}
+
+ feed '<esc>3+'
+ screen:expect{grid=[[
+ if (h->n_buckets < new_n_buckets) { // expand |
+ khkey_t *new_keys = (khkey_t *) |
+ {1:>> }{2:krealloc}: change the size of an allocation |
+ {3:krealloc}((void *)h->keys, new_n_buckets * sizeof(k|
+ hkey_t)); |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ ^char *new_vals = {3:krealloc}( h->vals_buf, new_n_|
+ buckets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ |
+ ]]}
+
+ meths.buf_set_extmark(0, ns, 5, 0, {
+ virt_lines = { {{"^^ REVIEW:", "Todo"}, {" new_vals variable seems unneccesary?", "Comment"}} };
+ })
+ -- TODO: what about the cursor??
+ screen:expect{grid=[[
+ if (h->n_buckets < new_n_buckets) { // expand |
+ khkey_t *new_keys = (khkey_t *) |
+ {3:krealloc}((void *)h->keys, new_n_buckets * sizeof(k|
+ hkey_t)); |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = {3:krealloc}( h->vals_buf, new_n_|
+ buck^ets * val_size); |
+ {5:^^ REVIEW:}{6: new_vals variable seems unneccesary?} |
+ h->vals_buf = new_vals; |
+ } |
+ |
+ ]]}
+
+ meths.buf_clear_namespace(0, ns, 0, -1)
+ screen:expect{grid=[[
+ if (h->n_buckets < new_n_buckets) { // expand |
+ khkey_t *new_keys = (khkey_t *) |
+ {3:krealloc}((void *)h->keys, new_n_buckets * sizeof(k|
+ hkey_t)); |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = {3:krealloc}( h->vals_buf, new_n_|
+ buck^ets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ } |
+ |
+ ]]}
+ end)
+
+
+ it('works with text at the beginning of the buffer', function()
+ insert(example_text)
+ feed 'gg'
+
+ screen:expect{grid=[[
+ ^if (h->n_buckets < new_n_buckets) { // expand |
+ khkey_t *new_keys = (khkey_t *)krealloc((void *)|
+ h->keys, new_n_buckets * sizeof(khkey_t)); |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = krealloc( h->vals_buf, new_n_|
+ buckets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ } |
+ {1:~ }|
+ |
+ ]]}
+
+ meths.buf_set_extmark(0, ns, 0, 0, {
+ virt_lines={
+ {{"refactor(khash): ", "Special"}, {"take size of values as parameter"}};
+ {{"Author: Dev Devsson, "}, {"Tue Aug 31 10:13:37 2021", "Comment"}};
+ };
+ virt_lines_above=true;
+ right_gravity=false;
+ })
+
+ -- placing virt_text on topline does not automatically cause a scroll
+ screen:expect{grid=[[
+ ^if (h->n_buckets < new_n_buckets) { // expand |
+ khkey_t *new_keys = (khkey_t *)krealloc((void *)|
+ h->keys, new_n_buckets * sizeof(khkey_t)); |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = krealloc( h->vals_buf, new_n_|
+ buckets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ } |
+ {1:~ }|
+ |
+ ]], unchanged=true}
+
+ feed '<c-b>'
+ screen:expect{grid=[[
+ {7:refactor(khash): }take size of values as parameter |
+ Author: Dev Devsson, {6:Tue Aug 31 10:13:37 2021} |
+ ^if (h->n_buckets < new_n_buckets) { // expand |
+ khkey_t *new_keys = (khkey_t *)krealloc((void *)|
+ h->keys, new_n_buckets * sizeof(khkey_t)); |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = krealloc( h->vals_buf, new_n_|
+ buckets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ |
+ ]]}
+ end)
+
+ it('works with text et the end of the buffer', function()
+ insert(example_text)
+ feed 'G'
+
+ screen:expect{grid=[[
+ if (h->n_buckets < new_n_buckets) { // expand |
+ khkey_t *new_keys = (khkey_t *)krealloc((void *)|
+ h->keys, new_n_buckets * sizeof(khkey_t)); |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = krealloc( h->vals_buf, new_n_|
+ buckets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ ^} |
+ {1:~ }|
+ |
+ ]]}
+
+ local id = meths.buf_set_extmark(0, ns, 7, 0, {
+ virt_lines={{{"Grugg"}}};
+ right_gravity=false;
+ })
+
+ screen:expect{grid=[[
+ if (h->n_buckets < new_n_buckets) { // expand |
+ khkey_t *new_keys = (khkey_t *)krealloc((void *)|
+ h->keys, new_n_buckets * sizeof(khkey_t)); |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = krealloc( h->vals_buf, new_n_|
+ buckets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ ^} |
+ Grugg |
+ |
+ ]]}
+
+ meths.buf_del_extmark(0, ns, id)
+ screen:expect{grid=[[
+ if (h->n_buckets < new_n_buckets) { // expand |
+ khkey_t *new_keys = (khkey_t *)krealloc((void *)|
+ h->keys, new_n_buckets * sizeof(khkey_t)); |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = krealloc( h->vals_buf, new_n_|
+ buckets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ ^} |
+ {1:~ }|
+ |
+ ]]}
+ end)
+
+ it('works with a block scrolling up', function()
+ screen:try_resize(30, 7)
+ insert("aa\nbb\ncc\ndd\nee\nff\ngg\nhh")
+ feed 'gg'
+
+ meths.buf_set_extmark(0, ns, 6, 0, {
+ virt_lines={
+ {{"they see me"}};
+ {{"scrolling", "Special"}};
+ {{"they"}};
+ {{"hatin'", "Special"}};
+ };
+ })
+
+ screen:expect{grid=[[
+ ^aa |
+ bb |
+ cc |
+ dd |
+ ee |
+ ff |
+ |
+ ]]}
+
+ feed '<c-e>'
+ screen:expect{grid=[[
+ ^bb |
+ cc |
+ dd |
+ ee |
+ ff |
+ gg |
+ |
+ ]]}
+
+ feed '<c-e>'
+ screen:expect{grid=[[
+ ^cc |
+ dd |
+ ee |
+ ff |
+ gg |
+ they see me |
+ |
+ ]]}
+
+ feed '<c-e>'
+ screen:expect{grid=[[
+ ^dd |
+ ee |
+ ff |
+ gg |
+ they see me |
+ {7:scrolling} |
+ |
+ ]]}
+
+ feed '<c-e>'
+ screen:expect{grid=[[
+ ^ee |
+ ff |
+ gg |
+ they see me |
+ {7:scrolling} |
+ they |
+ |
+ ]]}
+
+ feed '<c-e>'
+ screen:expect{grid=[[
+ ^ff |
+ gg |
+ they see me |
+ {7:scrolling} |
+ they |
+ {7:hatin'} |
+ |
+ ]]}
+
+ feed '<c-e>'
+ screen:expect{grid=[[
+ ^gg |
+ they see me |
+ {7:scrolling} |
+ they |
+ {7:hatin'} |
+ hh |
+ |
+ ]]}
+
+ feed '<c-e>'
+ screen:expect{grid=[[
+ they see me |
+ {7:scrolling} |
+ they |
+ {7:hatin'} |
+ ^hh |
+ {1:~ }|
+ |
+ ]]}
+
+ feed '<c-e>'
+ screen:expect{grid=[[
+ {7:scrolling} |
+ they |
+ {7:hatin'} |
+ ^hh |
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ feed '<c-e>'
+ screen:expect{grid=[[
+ they |
+ {7:hatin'} |
+ ^hh |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ feed '<c-e>'
+ screen:expect{grid=[[
+ {7:hatin'} |
+ ^hh |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ feed '<c-e>'
+ screen:expect{grid=[[
+ ^hh |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ end)
+
+ it('works with sign and numbercolumns', function()
+ insert(example_text)
+ feed 'gg'
+ command 'set number signcolumn=yes'
+ screen:expect{grid=[[
+ {8: }{9: 1 }^if (h->n_buckets < new_n_buckets) { // expan|
+ {8: }{9: }d |
+ {8: }{9: 2 } khkey_t *new_keys = (khkey_t *)krealloc((v|
+ {8: }{9: }oid *)h->keys, new_n_buckets * sizeof(khkey_|
+ {8: }{9: }t)); |
+ {8: }{9: 3 } h->keys = new_keys; |
+ {8: }{9: 4 } if (kh_is_map && val_size) { |
+ {8: }{9: 5 } char *new_vals = krealloc( h->vals_buf, |
+ {8: }{9: }new_n_buckets * val_size); |
+ {8: }{9: 6 } h->vals_buf = new_vals; |
+ {8: }{9: 7 } } |
+ |
+ ]]}
+
+ meths.buf_set_extmark(0, ns, 2, 0, {
+ virt_lines={
+ {{"Some special", "Special"}};
+ {{"remark about codes", "Comment"}};
+ };
+ })
+
+ screen:expect{grid=[[
+ {8: }{9: 1 }^if (h->n_buckets < new_n_buckets) { // expan|
+ {8: }{9: }d |
+ {8: }{9: 2 } khkey_t *new_keys = (khkey_t *)krealloc((v|
+ {8: }{9: }oid *)h->keys, new_n_buckets * sizeof(khkey_|
+ {8: }{9: }t)); |
+ {8: }{9: 3 } h->keys = new_keys; |
+ {8: }{9: }{7:Some special} |
+ {8: }{9: }{6:remark about codes} |
+ {8: }{9: 4 } if (kh_is_map && val_size) { |
+ {8: }{9: 5 } char *new_vals = krealloc( h->vals_buf, |
+ {8: }{9: }new_n_buckets * val_size); |
+ |
+ ]]}
+
+ meths.buf_set_extmark(0, ns, 2, 0, {
+ virt_lines={
+ {{"Some special", "Special"}};
+ {{"remark about codes", "Comment"}};
+ };
+ virt_lines_leftcol=true;
+ })
+ screen:expect{grid=[[
+ {8: }{9: 1 }^if (h->n_buckets < new_n_buckets) { // expan|
+ {8: }{9: }d |
+ {8: }{9: 2 } khkey_t *new_keys = (khkey_t *)krealloc((v|
+ {8: }{9: }oid *)h->keys, new_n_buckets * sizeof(khkey_|
+ {8: }{9: }t)); |
+ {8: }{9: 3 } h->keys = new_keys; |
+ {7:Some special} |
+ {6:remark about codes} |
+ {8: }{9: 4 } if (kh_is_map && val_size) { |
+ {8: }{9: 5 } char *new_vals = krealloc( h->vals_buf, |
+ {8: }{9: }new_n_buckets * val_size); |
+ |
+ ]]}
+ end)
+
+
+ it('works with hard tabs', function()
+ insert(example_text)
+ feed 'gg'
+ meths.buf_set_extmark(0, ns, 1, 0, {
+ virt_lines={ {{">>", "NonText"}, {"\tvery\ttabby", "Identifier"}, {"text\twith\ttabs"}}};
+ })
+ screen:expect{grid=[[
+ ^if (h->n_buckets < new_n_buckets) { // expand |
+ khkey_t *new_keys = (khkey_t *)krealloc((void *)|
+ h->keys, new_n_buckets * sizeof(khkey_t)); |
+ {1:>>}{2: very tabby}text with tabs |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = krealloc( h->vals_buf, new_n_|
+ buckets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ } |
+ |
+ ]]}
+
+ command 'set tabstop=4'
+ screen:expect{grid=[[
+ ^if (h->n_buckets < new_n_buckets) { // expand |
+ khkey_t *new_keys = (khkey_t *)krealloc((void *)|
+ h->keys, new_n_buckets * sizeof(khkey_t)); |
+ {1:>>}{2: very tabby}text with tabs |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = krealloc( h->vals_buf, new_n_|
+ buckets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ } |
+ |
+ ]]}
+ end)
+
+end)
diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua
index ccf5f963d1..6c2c4b398a 100644
--- a/test/functional/ui/float_spec.lua
+++ b/test/functional/ui/float_spec.lua
@@ -46,6 +46,7 @@ describe('float window', function()
[24] = {foreground = Screen.colors.Black, background = Screen.colors.Grey80};
[25] = {blend = 100, background = Screen.colors.Gray0};
[26] = {blend = 80, background = Screen.colors.Gray0};
+ [27] = {background = Screen.colors.LightGray};
}
it('behavior', function()
@@ -109,6 +110,21 @@ describe('float window', function()
assert_alive()
end)
+ it('closed immediately by autocmd after win_enter #15548', function()
+ eq('Error executing lua: [string "<nvim>"]:0: Window was closed immediately',
+ pcall_err(exec_lua, [[
+ vim.cmd "autocmd BufLeave * ++once quit!"
+ local buf = vim.api.nvim_create_buf(true, true)
+ vim.api.nvim_open_win(buf, true, {
+ relative = "win",
+ row = 0, col = 0,
+ width = 1, height = 1,
+ noautocmd = false,
+ })
+ ]]))
+ assert_alive()
+ end)
+
it('opened with correct height', function()
local height = exec_lua([[
vim.api.nvim_set_option("winheight", 20)
@@ -1514,7 +1530,7 @@ describe('float window', function()
it('API has proper error messages', function()
local buf = meths.create_buf(false,false)
- eq("Invalid key 'bork'",
+ eq("Invalid key: 'bork'",
pcall_err(meths.open_win,buf, false, {width=20,height=2,bork=true}))
eq("'win' key is only valid with relative='win'",
pcall_err(meths.open_win,buf, false, {width=20,height=2,relative='editor',row=0,col=0,win=0}))
@@ -1527,13 +1543,15 @@ describe('float window', function()
eq("'relative' requires 'row'/'col' or 'bufpos'",
pcall_err(meths.open_win,buf, false, {width=20,height=2,relative='editor'}))
eq("'width' key must be a positive Integer",
- pcall_err(meths.open_win,buf, false, {width=-1,height=2,relative='editor'}))
+ pcall_err(meths.open_win,buf, false, {width=-1,height=2,relative='editor', row=0, col=0}))
eq("'height' key must be a positive Integer",
- pcall_err(meths.open_win,buf, false, {width=20,height=-1,relative='editor'}))
+ pcall_err(meths.open_win,buf, false, {width=20,height=-1,relative='editor', row=0, col=0}))
eq("'height' key must be a positive Integer",
- pcall_err(meths.open_win,buf, false, {width=20,height=0,relative='editor'}))
- eq("Must specify 'width' and 'height'",
- pcall_err(meths.open_win,buf, false, {relative='editor'}))
+ pcall_err(meths.open_win,buf, false, {width=20,height=0,relative='editor', row=0, col=0}))
+ eq("Must specify 'width'",
+ pcall_err(meths.open_win,buf, false, {relative='editor', row=0, col=0}))
+ eq("Must specify 'height'",
+ pcall_err(meths.open_win,buf, false, {relative='editor', row=0, col=0, width=2}))
end)
it('can be placed relative window or cursor', function()
@@ -1866,6 +1884,293 @@ describe('float window', function()
end
end)
+ it('always anchor to corner including border', function()
+ screen:try_resize(40,13)
+ meths.buf_set_lines(0, 0, -1, true, {'just some example text', 'some more example text'})
+ feed('ggeee')
+ command('below split')
+ if multigrid then
+ screen:expect([[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ {5:[No Name] [+] }|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ {4:[No Name] [+] }|
+ [3:----------------------------------------]|
+ ## grid 2
+ just some example text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ |
+ ## grid 4
+ just some exampl^e text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ]])
+ else
+ screen:expect([[
+ just some example text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {5:[No Name] [+] }|
+ just some exampl^e text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {4:[No Name] [+] }|
+ |
+ ]])
+ end
+
+ local buf = meths.create_buf(false, false)
+ meths.buf_set_lines(buf, 0, -1, true, {' halloj! ',
+ ' BORDAA '})
+ local win = meths.open_win(buf, false, {relative='cursor', width=9, height=2, row=1, col=-2, border="double"})
+
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ {5:[No Name] [+] }|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ {4:[No Name] [+] }|
+ [3:----------------------------------------]|
+ ## grid 2
+ just some example text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ |
+ ## grid 4
+ just some exampl^e text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 6
+ {5:╔═════════╗}|
+ {5:║}{1: halloj! }{5:║}|
+ {5:║}{1: BORDAA }{5:║}|
+ {5:╚═════════╝}|
+ ]], float_pos={
+ [6] = {{id = 1003}, "NW", 4, 1, 14, true}
+ }}
+ else
+ screen:expect([[
+ just some example text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {5:[No Name] [+] }|
+ just some exampl^e text |
+ some more exam{5:╔═════════╗} |
+ {0:~ }{5:║}{1: halloj! }{5:║}{0: }|
+ {0:~ }{5:║}{1: BORDAA }{5:║}{0: }|
+ {0:~ }{5:╚═════════╝}{0: }|
+ {4:[No Name] [+] }|
+ |
+ ]])
+ end
+
+ meths.win_set_config(win, {relative='cursor', row=0, col=-2, anchor='NE'})
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ {5:[No Name] [+] }|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ {4:[No Name] [+] }|
+ [3:----------------------------------------]|
+ ## grid 2
+ just some example text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ |
+ ## grid 4
+ just some exampl^e text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 6
+ {5:╔═════════╗}|
+ {5:║}{1: halloj! }{5:║}|
+ {5:║}{1: BORDAA }{5:║}|
+ {5:╚═════════╝}|
+ ]], float_pos={
+ [6] = {{id = 1003}, "NE", 4, 0, 14, true}
+ }}
+ else
+ screen:expect([[
+ just some example text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {5:[No Name] [+] }|
+ jus{5:╔═════════╗}pl^e text |
+ som{5:║}{1: halloj! }{5:║}ple text |
+ {0:~ }{5:║}{1: BORDAA }{5:║}{0: }|
+ {0:~ }{5:╚═════════╝}{0: }|
+ {0:~ }|
+ {4:[No Name] [+] }|
+ |
+ ]])
+ end
+
+ meths.win_set_config(win, {relative='cursor', row=1, col=-2, anchor='SE'})
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ {5:[No Name] [+] }|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ {4:[No Name] [+] }|
+ [3:----------------------------------------]|
+ ## grid 2
+ just some example text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ |
+ ## grid 4
+ just some exampl^e text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 6
+ {5:╔═════════╗}|
+ {5:║}{1: halloj! }{5:║}|
+ {5:║}{1: BORDAA }{5:║}|
+ {5:╚═════════╝}|
+ ]], float_pos={
+ [6] = {{id = 1003}, "SE", 4, 1, 14, true}
+ }}
+ else
+ screen:expect([[
+ just some example text |
+ some more example text |
+ {0:~ }|
+ {0:~ }{5:╔═════════╗}{0: }|
+ {0:~ }{5:║}{1: halloj! }{5:║}{0: }|
+ {5:[No║}{1: BORDAA }{5:║ }|
+ jus{5:╚═════════╝}pl^e text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {4:[No Name] [+] }|
+ |
+ ]])
+ end
+
+ meths.win_set_config(win, {relative='cursor', row=0, col=-2, anchor='SW'})
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ {5:[No Name] [+] }|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ {4:[No Name] [+] }|
+ [3:----------------------------------------]|
+ ## grid 2
+ just some example text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ |
+ ## grid 4
+ just some exampl^e text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 6
+ {5:╔═════════╗}|
+ {5:║}{1: halloj! }{5:║}|
+ {5:║}{1: BORDAA }{5:║}|
+ {5:╚═════════╝}|
+ ]], float_pos={
+ [6] = {{id = 1003}, "SW", 4, 0, 14, true}
+ }}
+ else
+ screen:expect([[
+ just some example text |
+ some more example text |
+ {0:~ }{5:╔═════════╗}{0: }|
+ {0:~ }{5:║}{1: halloj! }{5:║}{0: }|
+ {0:~ }{5:║}{1: BORDAA }{5:║}{0: }|
+ {5:[No Name] [+] ╚═════════╝ }|
+ just some exampl^e text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {4:[No Name] [+] }|
+ |
+ ]])
+ end
+ end)
+
it('can be placed relative text in a window', function()
screen:try_resize(30,5)
local firstwin = meths.get_current_win().id
@@ -5870,6 +6175,132 @@ describe('float window', function()
end)
end)
+ it("left drag changes visual selection in float window", function()
+ local buf = meths.create_buf(false,false)
+ meths.buf_set_lines(buf, 0, -1, true, {'foo', 'bar'})
+ meths.open_win(buf, false, {relative='editor', width=20, height=3, row=2, col=5})
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [3:----------------------------------------]|
+ ## grid 2
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ |
+ ## grid 5
+ {1:foo }|
+ {1:bar }|
+ {2:~ }|
+ ]], float_pos={
+ [5] = {{id = 1002}, "NW", 1, 2, 5, true, 50};
+ }, win_viewport={
+ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1};
+ [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 2};
+ }}
+ meths.input_mouse('left', 'press', '', 5, 0, 0)
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [3:----------------------------------------]|
+ ## grid 2
+ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ |
+ ## grid 5
+ {1:^foo }|
+ {1:bar }|
+ {2:~ }|
+ ]], float_pos={
+ [5] = {{id = 1002}, "NW", 1, 2, 5, true, 50};
+ }, win_viewport={
+ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1};
+ [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 2};
+ }}
+ meths.input_mouse('left', 'drag', '', 5, 1, 2)
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [3:----------------------------------------]|
+ ## grid 2
+ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ {3:-- VISUAL --} |
+ ## grid 5
+ {27:foo}{1: }|
+ {27:ba}{1:^r }|
+ {2:~ }|
+ ]], float_pos={
+ [5] = {{id = 1002}, "NW", 1, 2, 5, true, 50};
+ }, win_viewport={
+ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1};
+ [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 1, curcol = 2, linecount = 2};
+ }}
+ else
+ screen:expect{grid=[[
+ ^ |
+ {0:~ }|
+ {0:~ }{1:foo }{0: }|
+ {0:~ }{1:bar }{0: }|
+ {0:~ }{2:~ }{0: }|
+ {0:~ }|
+ |
+ ]]}
+
+ meths.input_mouse('left', 'press', '', 0, 2, 5)
+ screen:expect{grid=[[
+ |
+ {0:~ }|
+ {0:~ }{1:^foo }{0: }|
+ {0:~ }{1:bar }{0: }|
+ {0:~ }{2:~ }{0: }|
+ {0:~ }|
+ |
+ ]]}
+
+ meths.input_mouse('left', 'drag', '', 0, 3, 7)
+ screen:expect{grid=[[
+ |
+ {0:~ }|
+ {0:~ }{27:foo}{1: }{0: }|
+ {0:~ }{27:ba}{1:^r }{0: }|
+ {0:~ }{2:~ }{0: }|
+ {0:~ }|
+ {3:-- VISUAL --} |
+ ]]}
+ end
+ end)
+
it("'winblend' option", function()
screen:try_resize(50,9)
screen:set_default_attr_ids({
diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua
index 712c1f377a..b6e2f2311f 100644
--- a/test/functional/ui/inccommand_spec.lua
+++ b/test/functional/ui/inccommand_spec.lua
@@ -1487,6 +1487,29 @@ describe("inccommand=nosplit", function()
]])
eq(eval('v:null'), eval('v:exiting'))
end)
+
+ it("does not break bar-separated command #8796", function()
+ source([[
+ function! F()
+ if v:false | return | endif
+ endfun
+ ]])
+ command('call timer_start(10, {-> F()}, {"repeat":-1})')
+ feed(':%s/')
+ sleep(20) -- Allow some timer activity.
+ screen:expect([[
+ Inc substitution on |
+ two lines |
+ Inc substitution on |
+ two lines |
+ |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ :%s/^ |
+ ]])
+ end)
end)
describe(":substitute, 'inccommand' with a failing expression", function()
diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua
index 7bca741ae3..baacef358f 100644
--- a/test/functional/ui/mouse_spec.lua
+++ b/test/functional/ui/mouse_spec.lua
@@ -585,6 +585,69 @@ describe('ui/mouse/input', function()
]])
end)
+ it('left drag changes visual selection in split layout', function()
+ screen:try_resize(53,14)
+ command('set mouse=a')
+ command('vsplit')
+ command('wincmd l')
+ command('below split')
+ command('enew')
+ feed('ifoo\nbar<esc>')
+
+ screen:expect{grid=[[
+ testing {4:│}testing |
+ mouse {4:│}mouse |
+ support and selection {4:│}support and selection |
+ {0:~ }{4:│}{0:~ }|
+ {0:~ }{4:│}{0:~ }|
+ {0:~ }{4:│[No Name] [+] }|
+ {0:~ }{4:│}foo{0:$} |
+ {0:~ }{4:│}ba^r{0:$} |
+ {0:~ }{4:│}{0:~ }|
+ {0:~ }{4:│}{0:~ }|
+ {0:~ }{4:│}{0:~ }|
+ {0:~ }{4:│}{0:~ }|
+ {4:[No Name] [+] }{5:[No Name] [+] }|
+ |
+ ]]}
+
+ meths.input_mouse('left', 'press', '', 0, 6, 27)
+ screen:expect{grid=[[
+ testing {4:│}testing |
+ mouse {4:│}mouse |
+ support and selection {4:│}support and selection |
+ {0:~ }{4:│}{0:~ }|
+ {0:~ }{4:│}{0:~ }|
+ {0:~ }{4:│[No Name] [+] }|
+ {0:~ }{4:│}^foo{0:$} |
+ {0:~ }{4:│}bar{0:$} |
+ {0:~ }{4:│}{0:~ }|
+ {0:~ }{4:│}{0:~ }|
+ {0:~ }{4:│}{0:~ }|
+ {0:~ }{4:│}{0:~ }|
+ {4:[No Name] [+] }{5:[No Name] [+] }|
+ |
+ ]]}
+ meths.input_mouse('left', 'drag', '', 0, 7, 30)
+
+ screen:expect{grid=[[
+ testing {4:│}testing |
+ mouse {4:│}mouse |
+ support and selection {4:│}support and selection |
+ {0:~ }{4:│}{0:~ }|
+ {0:~ }{4:│}{0:~ }|
+ {0:~ }{4:│[No Name] [+] }|
+ {0:~ }{4:│}{1:foo}{3:$} |
+ {0:~ }{4:│}{1:bar}{0:^$} |
+ {0:~ }{4:│}{0:~ }|
+ {0:~ }{4:│}{0:~ }|
+ {0:~ }{4:│}{0:~ }|
+ {0:~ }{4:│}{0:~ }|
+ {4:[No Name] [+] }{5:[No Name] [+] }|
+ {2:-- VISUAL --} |
+ ]]}
+ end)
+
it('two clicks will select the word and enter VISUAL', function()
feed('<LeftMouse><2,2><LeftMouse><2,2>')
screen:expect([[
@@ -1384,4 +1447,128 @@ describe('ui/mouse/input', function()
end) -- level 3 - wrapped
end)
+
+ it('getmousepos works correctly', function()
+ local winwidth = meths.get_option('winwidth')
+ -- Set winwidth=1 so that window sizes don't change.
+ meths.set_option('winwidth', 1)
+ command('tabedit')
+ local tabpage = meths.get_current_tabpage()
+ insert('hello')
+ command('vsplit')
+ local opts = {
+ relative='editor',
+ width=12,
+ height=1,
+ col=8,
+ row=1,
+ anchor='NW',
+ style='minimal',
+ border='single',
+ focusable=1
+ }
+ local float = meths.open_win(meths.get_current_buf(), false, opts)
+ command('redraw')
+ local lines = meths.get_option('lines')
+ local columns = meths.get_option('columns')
+
+ -- Test that screenrow and screencol are set properly for all positions.
+ for row = 0, lines - 1 do
+ for col = 0, columns - 1 do
+ -- Skip the X button that would close the tab.
+ if row ~= 0 or col ~= columns - 1 then
+ meths.input_mouse('left', 'press', '', 0, row, col)
+ meths.set_current_tabpage(tabpage)
+ local mousepos = funcs.getmousepos()
+ eq(row + 1, mousepos.screenrow)
+ eq(col + 1, mousepos.screencol)
+ -- All other values should be 0 when clicking on the command line.
+ if row == lines - 1 then
+ eq(0, mousepos.winid)
+ eq(0, mousepos.winrow)
+ eq(0, mousepos.wincol)
+ eq(0, mousepos.line)
+ eq(0, mousepos.column)
+ end
+ end
+ end
+ end
+
+ -- Test that mouse position values are properly set for the floating window
+ -- with a border. 1 is added to the height and width to account for the
+ -- border.
+ for win_row = 0, opts.height + 1 do
+ for win_col = 0, opts.width + 1 do
+ local row = win_row + opts.row
+ local col = win_col + opts.col
+ meths.input_mouse('left', 'press', '', 0, row, col)
+ local mousepos = funcs.getmousepos()
+ eq(float.id, mousepos.winid)
+ eq(win_row + 1, mousepos.winrow)
+ eq(win_col + 1, mousepos.wincol)
+ local line = 0
+ local column = 0
+ if win_row > 0 and win_row < opts.height + 1
+ and win_col > 0 and win_col < opts.width + 1 then
+ -- Because of border, win_row and win_col don't need to be
+ -- incremented by 1.
+ line = math.min(win_row, funcs.line('$'))
+ column = math.min(win_col, #funcs.getline(line) + 1)
+ end
+ eq(line, mousepos.line)
+ eq(column, mousepos.column)
+ end
+ end
+
+ -- Test that mouse position values are properly set for the floating
+ -- window, after removing the border.
+ opts.border = 'none'
+ meths.win_set_config(float, opts)
+ command('redraw')
+ for win_row = 0, opts.height - 1 do
+ for win_col = 0, opts.width - 1 do
+ local row = win_row + opts.row
+ local col = win_col + opts.col
+ meths.input_mouse('left', 'press', '', 0, row, col)
+ local mousepos = funcs.getmousepos()
+ eq(float.id, mousepos.winid)
+ eq(win_row + 1, mousepos.winrow)
+ eq(win_col + 1, mousepos.wincol)
+ local line = math.min(win_row + 1, funcs.line('$'))
+ local column = math.min(win_col + 1, #funcs.getline(line) + 1)
+ eq(line, mousepos.line)
+ eq(column, mousepos.column)
+ end
+ end
+
+ -- Test that mouse position values are properly set for ordinary windows.
+ -- Set the float to be unfocusable instead of closing, to additionally test
+ -- that getmousepos does not consider unfocusable floats. (see discussion
+ -- in PR #14937 for details).
+ opts.focusable = false
+ meths.win_set_config(float, opts)
+ command('redraw')
+ for nr = 1, 2 do
+ for win_row = 0, funcs.winheight(nr) - 1 do
+ for win_col = 0, funcs.winwidth(nr) - 1 do
+ local row = win_row + funcs.win_screenpos(nr)[1] - 1
+ local col = win_col + funcs.win_screenpos(nr)[2] - 1
+ meths.input_mouse('left', 'press', '', 0, row, col)
+ local mousepos = funcs.getmousepos()
+ eq(funcs.win_getid(nr), mousepos.winid)
+ eq(win_row + 1, mousepos.winrow)
+ eq(win_col + 1, mousepos.wincol)
+ local line = math.min(win_row + 1, funcs.line('$'))
+ local column = math.min(win_col + 1, #funcs.getline(line) + 1)
+ eq(line, mousepos.line)
+ eq(column, mousepos.column)
+ end
+ end
+ end
+
+ -- Restore state and release mouse.
+ command('tabclose!')
+ meths.set_option('winwidth', winwidth)
+ meths.input_mouse('left', 'release', '', 0, 0, 0)
+ end)
end)
diff --git a/test/functional/vimscript/json_functions_spec.lua b/test/functional/vimscript/json_functions_spec.lua
index c3b607b544..5d1597f53d 100644
--- a/test/functional/vimscript/json_functions_spec.lua
+++ b/test/functional/vimscript/json_functions_spec.lua
@@ -168,7 +168,8 @@ describe('json_decode() function', function()
end)
it('parses floating-point numbers', function()
- eq('100000.0', eval('string(json_decode("100000.0"))'))
+ -- Also test method call (->) syntax
+ eq('100000.0', eval('"100000.0"->json_decode()->string()'))
eq(100000.5, funcs.json_decode('100000.5'))
eq(-100000.5, funcs.json_decode('-100000.5'))
eq(-100000.5e50, funcs.json_decode('-100000.5e50'))
@@ -549,11 +550,12 @@ describe('json_encode() function', function()
end)
it('dumps floats', function()
- eq('0.0', eval('json_encode(0.0)'))
+ -- Also test method call (->) syntax
+ eq('0.0', eval('0.0->json_encode()'))
eq('10.5', funcs.json_encode(10.5))
eq('-10.5', funcs.json_encode(-10.5))
eq('-1.0e-5', funcs.json_encode(-1e-5))
- eq('1.0e50', eval('json_encode(1.0e50)'))
+ eq('1.0e50', eval('1.0e50->json_encode()'))
end)
it('fails to dump NaN and infinite values', function()
diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt
index 72c4b72a21..29ff0daa8d 100644
--- a/third-party/CMakeLists.txt
+++ b/third-party/CMakeLists.txt
@@ -144,14 +144,8 @@ endif()
include(ExternalProject)
-if(WIN32)
- # "nvim" branch of https://github.com/neovim/libuv
- set(LIBUV_URL https://github.com/neovim/libuv/archive/b899d12b0d56d217f31222da83f8c398355b69ef.tar.gz)
- set(LIBUV_SHA256 eb7e37b824887e1b31a4e31d1d9bad4c03d8b98532d9cce5f67a3b70495a4b2a)
-else()
- set(LIBUV_URL https://github.com/libuv/libuv/archive/v1.34.2.tar.gz)
- set(LIBUV_SHA256 0d9d38558b45c006c1ea4e8529bae64caf8becda570295ea74e3696362aeb7f2)
-endif()
+set(LIBUV_URL https://github.com/libuv/libuv/archive/v1.42.0.tar.gz)
+set(LIBUV_SHA256 371e5419708f6aaeb8656671f89400b92a9bba6443369af1bb70bcd6e4b3c764)
set(MSGPACK_URL https://github.com/msgpack/msgpack-c/releases/download/cpp-3.0.0/msgpack-3.0.0.tar.gz)
set(MSGPACK_SHA256 bfbb71b7c02f806393bc3cbc491b40523b89e64f83860c58e3e54af47de176e4)
@@ -163,8 +157,8 @@ set(LUAJIT_SHA256 2e3f74bc279f46cc463abfc67b36e69faaf0366237004771f4cac4bf2a9f5e
set(LUA_URL https://www.lua.org/ftp/lua-5.1.5.tar.gz)
set(LUA_SHA256 2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333)
-set(LUAROCKS_URL https://github.com/luarocks/luarocks/archive/v3.2.1.tar.gz)
-set(LUAROCKS_SHA256 0cab9f79311083f33e4d8f5a76021604f1d3f7141ce9a2ef1d8b717d92058370)
+set(LUAROCKS_URL https://github.com/luarocks/luarocks/archive/v3.7.0.tar.gz)
+set(LUAROCKS_SHA256 968c98ae894cea2c850f077133e3feb9f8ce94df7a33a5611bd4d25e07c94925)
set(UNIBILIUM_URL https://github.com/neovim/unibilium/archive/92d929f.tar.gz)
set(UNIBILIUM_SHA256 29815283c654277ef77a3adcc8840db79ddbb20a0f0b0c8f648bd8cd49a02e4b)
@@ -175,9 +169,9 @@ set(LIBTERMKEY_SHA256 6945bd3c4aaa83da83d80a045c5563da4edd7d0374c62c0d35aec09eb3
set(LIBVTERM_URL http://www.leonerd.org.uk/code/libvterm/libvterm-0.1.4.tar.gz)
set(LIBVTERM_SHA256 bc70349e95559c667672fc8c55b9527d9db9ada0fb80a3beda533418d782d3dd)
-set(LUV_VERSION 1.40.0-0)
+set(LUV_VERSION 1.42.0-0)
set(LUV_URL https://github.com/luvit/luv/archive/${LUV_VERSION}.tar.gz)
-set(LUV_SHA256 23167a3d5dbc1e30df1f106ffae0a4c5bd50993da2066dc1f7e1842bb9fb6cd0)
+set(LUV_SHA256 8caee38de2fba0da32abbe96f55244e4a2c67d6cdde161a1935af94bffd5470f)
set(LUA_COMPAT53_URL https://github.com/keplerproject/lua-compat-5.3/archive/v0.9.tar.gz)
set(LUA_COMPAT53_SHA256 ad05540d2d96a48725bb79a1def35cf6652a4e2ec26376e2617c8ce2baa6f416)
@@ -209,8 +203,8 @@ set(LIBICONV_SHA256 ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc891
set(TREESITTER_C_URL https://github.com/tree-sitter/tree-sitter-c/archive/5aa0bbb.tar.gz)
set(TREESITTER_C_SHA256 a5dcb37460d83002dfae7f9a208170ddbc9a047f231b9d6b75da7d36d707db2f)
-set(TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/v0.20.0.tar.gz)
-set(TREESITTER_SHA256 4a8070b9de17c3b8096181fe8530320ab3e8cca685d8bee6a3e8d164b5fb47da)
+set(TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/7890a29db0b186b7b21a0a95d99fa6c562b8316b.tar.gz)
+set(TREESITTER_SHA256 634006b0336a5eef1b07d2f80a4d4f8ac1522bf15759ec3e5dda0032a734fb19)
if(USE_BUNDLED_UNIBILIUM)
include(BuildUnibilium)
diff --git a/third-party/cmake/BuildLibuv.cmake b/third-party/cmake/BuildLibuv.cmake
index c5f7d6d5ab..32fe2659a4 100644
--- a/third-party/cmake/BuildLibuv.cmake
+++ b/third-party/cmake/BuildLibuv.cmake
@@ -1,5 +1,3 @@
-include(CMakeParseArguments)
-
# BuildLibuv(TARGET targetname CONFIGURE_COMMAND ... BUILD_COMMAND ... INSTALL_COMMAND ...)
# Reusable function to build libuv, wraps ExternalProject_Add.
# Failing to pass a command argument will result in no command being run
diff --git a/third-party/cmake/BuildLibvterm.cmake b/third-party/cmake/BuildLibvterm.cmake
index c3485dac25..09f2ba7f2c 100644
--- a/third-party/cmake/BuildLibvterm.cmake
+++ b/third-party/cmake/BuildLibvterm.cmake
@@ -1,5 +1,3 @@
-include(CMakeParseArguments)
-
# BuildLibvterm(CONFIGURE_COMMAND ... BUILD_COMMAND ... INSTALL_COMMAND ...)
# Failing to pass a command argument will result in no command being run
function(BuildLibvterm)
diff --git a/third-party/cmake/BuildLua.cmake b/third-party/cmake/BuildLua.cmake
index c3f789509e..a40cb7dcb2 100644
--- a/third-party/cmake/BuildLua.cmake
+++ b/third-party/cmake/BuildLua.cmake
@@ -1,5 +1,3 @@
-include(CMakeParseArguments)
-
# BuildLua(CONFIGURE_COMMAND ... BUILD_COMMAND ... INSTALL_COMMAND ...)
# Reusable function to build lua, wraps ExternalProject_Add.
# Failing to pass a command argument will result in no command being run
diff --git a/third-party/cmake/BuildLuajit.cmake b/third-party/cmake/BuildLuajit.cmake
index ca41a7cee3..512d5ef5ae 100644
--- a/third-party/cmake/BuildLuajit.cmake
+++ b/third-party/cmake/BuildLuajit.cmake
@@ -1,5 +1,3 @@
-include(CMakeParseArguments)
-
# BuildLuajit(TARGET targetname CONFIGURE_COMMAND ... BUILD_COMMAND ... INSTALL_COMMAND ...)
# Reusable function to build luajit, wraps ExternalProject_Add.
# Failing to pass a command argument will result in no command being run
diff --git a/third-party/cmake/BuildLuarocks.cmake b/third-party/cmake/BuildLuarocks.cmake
index a961ec69c7..0cef37736d 100644
--- a/third-party/cmake/BuildLuarocks.cmake
+++ b/third-party/cmake/BuildLuarocks.cmake
@@ -202,6 +202,11 @@ if(USE_BUNDLED_BUSTED)
set(LUV_ARGS "CFLAGS=-O0 -g3 -fPIC")
if(USE_BUNDLED_LIBUV)
list(APPEND LUV_ARGS LIBUV_DIR=${HOSTDEPS_INSTALL_DIR})
+ # workaround for bug introduced in
+ # https://github.com/luarocks/luarocks/commit/83126ba324846b754ffc5e0345341f01262b3f86
+ if(MSVC)
+ list(APPEND LUV_ARGS LIBUV_LIBDIR=${HOSTDEPS_INSTALL_DIR}/lib)
+ endif()
endif()
SET(LUV_PRIVATE_ARGS LUA_COMPAT53_INCDIR=${DEPS_BUILD_DIR}/src/lua-compat-5.3/c-api)
add_custom_command(OUTPUT ${ROCKS_DIR}/luv
diff --git a/third-party/cmake/BuildLuv.cmake b/third-party/cmake/BuildLuv.cmake
index f5d45c7ff7..69f3b60ecf 100644
--- a/third-party/cmake/BuildLuv.cmake
+++ b/third-party/cmake/BuildLuv.cmake
@@ -1,5 +1,3 @@
-include(CMakeParseArguments)
-
# BuildLuv(PATCH_COMMAND ... CONFIGURE_COMMAND ... BUILD_COMMAND ... INSTALL_COMMAND ...)
# Reusable function to build luv, wraps ExternalProject_Add.
# Failing to pass a command argument will result in no command being run
diff --git a/third-party/cmake/BuildMsgpack.cmake b/third-party/cmake/BuildMsgpack.cmake
index 30af5f060b..39a8a64d23 100644
--- a/third-party/cmake/BuildMsgpack.cmake
+++ b/third-party/cmake/BuildMsgpack.cmake
@@ -1,5 +1,3 @@
-include(CMakeParseArguments)
-
# BuildMsgpack(CONFIGURE_COMMAND ... BUILD_COMMAND ... INSTALL_COMMAND ...)
# Reusable function to build msgpack, wraps ExternalProject_Add.
# Failing to pass a command argument will result in no command being run
diff --git a/third-party/cmake/BuildTreesitter.cmake b/third-party/cmake/BuildTreesitter.cmake
index a55b2e36e8..0aa2706d7d 100644
--- a/third-party/cmake/BuildTreesitter.cmake
+++ b/third-party/cmake/BuildTreesitter.cmake
@@ -1,5 +1,3 @@
-include(CMakeParseArguments)
-
# BuildTreeSitter(TARGET targetname CONFIGURE_COMMAND ... BUILD_COMMAND ... INSTALL_COMMAND ...)
function(BuildTreeSitter)
cmake_parse_arguments(_treesitter
diff --git a/third-party/cmake/GetBinaryDeps.cmake b/third-party/cmake/GetBinaryDeps.cmake
index 982bf62265..04e3f95a29 100644
--- a/third-party/cmake/GetBinaryDeps.cmake
+++ b/third-party/cmake/GetBinaryDeps.cmake
@@ -1,6 +1,3 @@
-# Download and install binary dependencies for windows
-include(CMakeParseArguments)
-
# This is similar to the build recipes, but instead downloads a third party
# binary and installs it under the DEPS_PREFIX.
# The INSTALL_COMMAND is executed in the folder where downloaded files are