Imported Upstream version 8.0.586 88/163388/1 upstream/8.0.586
authorDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 11 Dec 2017 03:10:38 +0000 (12:10 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 11 Dec 2017 03:12:18 +0000 (12:12 +0900)
Change-Id: I42cb89812f8dd54a007634018e8e18b746c06e6c
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
590 files changed:
.hgignore
.travis.yml
Filelist
Makefile
README.md
nsis/gvim.nsi
runtime/autoload/ada.vim
runtime/autoload/javascriptcomplete.vim
runtime/autoload/rust.vim [new file with mode: 0644]
runtime/autoload/rustfmt.vim [new file with mode: 0644]
runtime/compiler/bdf.vim
runtime/compiler/cargo.vim [new file with mode: 0644]
runtime/compiler/csslint.vim [new file with mode: 0644]
runtime/compiler/gcc.vim
runtime/compiler/ghc.vim [new file with mode: 0644]
runtime/compiler/pylint.vim [new file with mode: 0644]
runtime/compiler/rst.vim
runtime/compiler/rustc.vim [new file with mode: 0644]
runtime/defaults.vim
runtime/doc/Makefile
runtime/doc/autocmd.txt
runtime/doc/change.txt
runtime/doc/channel.txt
runtime/doc/cmdline.txt
runtime/doc/develop.txt
runtime/doc/diff.txt
runtime/doc/editing.txt
runtime/doc/eval.txt
runtime/doc/filetype.txt
runtime/doc/fold.txt
runtime/doc/ft_rust.txt [new file with mode: 0644]
runtime/doc/hangulin.txt
runtime/doc/helphelp.txt
runtime/doc/if_mzsch.txt
runtime/doc/if_pyth.txt
runtime/doc/if_ruby.txt
runtime/doc/indent.txt
runtime/doc/index.txt
runtime/doc/insert.txt
runtime/doc/intro.txt
runtime/doc/map.txt
runtime/doc/message.txt
runtime/doc/mlang.txt
runtime/doc/motion.txt
runtime/doc/options.txt
runtime/doc/os_mac.txt
runtime/doc/os_win32.txt
runtime/doc/pattern.txt
runtime/doc/pi_gzip.txt
runtime/doc/pi_logipat.txt
runtime/doc/quickfix.txt
runtime/doc/quickref.txt
runtime/doc/remote.txt
runtime/doc/repeat.txt
runtime/doc/scroll.txt
runtime/doc/starting.txt
runtime/doc/syntax.txt
runtime/doc/tabpage.txt
runtime/doc/tags
runtime/doc/term.txt
runtime/doc/todo.txt
runtime/doc/usr_02.txt
runtime/doc/usr_03.txt
runtime/doc/usr_22.txt
runtime/doc/usr_41.txt
runtime/doc/various.txt
runtime/doc/version6.txt
runtime/doc/version7.txt
runtime/doc/version8.txt
runtime/doc/windows.txt
runtime/filetype.vim
runtime/ftplugin/a2ps.vim
runtime/ftplugin/alsaconf.vim
runtime/ftplugin/arch.vim
runtime/ftplugin/automake.vim
runtime/ftplugin/awk.vim [new file with mode: 0644]
runtime/ftplugin/bdf.vim
runtime/ftplugin/calendar.vim
runtime/ftplugin/cdrdaoconf.vim
runtime/ftplugin/conf.vim
runtime/ftplugin/crm.vim
runtime/ftplugin/css.vim
runtime/ftplugin/cvsrc.vim
runtime/ftplugin/denyhosts.vim
runtime/ftplugin/dictconf.vim
runtime/ftplugin/dictdconf.vim
runtime/ftplugin/dircolors.vim
runtime/ftplugin/dosini.vim
runtime/ftplugin/elinks.vim
runtime/ftplugin/eterm.vim
runtime/ftplugin/fetchmail.vim
runtime/ftplugin/framescript.vim
runtime/ftplugin/gpg.vim
runtime/ftplugin/group.vim
runtime/ftplugin/grub.vim
runtime/ftplugin/hamster.vim
runtime/ftplugin/haskell.vim
runtime/ftplugin/help.vim
runtime/ftplugin/hostconf.vim
runtime/ftplugin/hostsaccess.vim
runtime/ftplugin/indent.vim
runtime/ftplugin/ld.vim
runtime/ftplugin/lftp.vim
runtime/ftplugin/libao.vim
runtime/ftplugin/limits.vim
runtime/ftplugin/loginaccess.vim
runtime/ftplugin/logindefs.vim
runtime/ftplugin/m4.vim
runtime/ftplugin/mailaliases.vim
runtime/ftplugin/mailcap.vim
runtime/ftplugin/man.vim
runtime/ftplugin/manconf.vim
runtime/ftplugin/modconf.vim
runtime/ftplugin/mplayerconf.vim
runtime/ftplugin/muttrc.vim
runtime/ftplugin/nanorc.vim
runtime/ftplugin/netrc.vim
runtime/ftplugin/nsis.vim
runtime/ftplugin/pamconf.vim
runtime/ftplugin/passwd.vim
runtime/ftplugin/pinfo.vim
runtime/ftplugin/procmail.vim
runtime/ftplugin/prolog.vim
runtime/ftplugin/protocols.vim
runtime/ftplugin/quake.vim
runtime/ftplugin/racc.vim
runtime/ftplugin/readline.vim
runtime/ftplugin/rnc.vim
runtime/ftplugin/rst.vim
runtime/ftplugin/rust.vim [new file with mode: 0644]
runtime/ftplugin/screen.vim
runtime/ftplugin/sensors.vim
runtime/ftplugin/services.vim
runtime/ftplugin/setserial.vim
runtime/ftplugin/sieve.vim
runtime/ftplugin/slpconf.vim
runtime/ftplugin/slpreg.vim
runtime/ftplugin/slpspi.vim
runtime/ftplugin/sql.vim
runtime/ftplugin/sshconfig.vim
runtime/ftplugin/sudoers.vim
runtime/ftplugin/sysctl.vim
runtime/ftplugin/terminfo.vim
runtime/ftplugin/tmux.vim [new file with mode: 0644]
runtime/ftplugin/treetop.vim
runtime/ftplugin/udevconf.vim
runtime/ftplugin/udevperm.vim
runtime/ftplugin/udevrules.vim
runtime/ftplugin/updatedb.vim
runtime/ftplugin/xdefaults.vim
runtime/ftplugin/xf86conf.vim
runtime/ftplugin/xinetd.vim
runtime/ftplugin/xmodmap.vim
runtime/ftplugin/yaml.vim
runtime/indent/automake.vim
runtime/indent/config.vim
runtime/indent/css.vim
runtime/indent/dictconf.vim
runtime/indent/dictdconf.vim
runtime/indent/docbk.vim
runtime/indent/dtd.vim
runtime/indent/eiffel.vim
runtime/indent/eterm.vim
runtime/indent/fortran.vim
runtime/indent/framescript.vim
runtime/indent/html.vim
runtime/indent/java.vim
runtime/indent/javascript.vim
runtime/indent/ld.vim
runtime/indent/make.vim
runtime/indent/php.vim
runtime/indent/r.vim
runtime/indent/readline.vim
runtime/indent/rhelp.vim
runtime/indent/rst.vim
runtime/indent/rust.vim [new file with mode: 0644]
runtime/indent/sas.vim [new file with mode: 0644]
runtime/indent/scala.vim
runtime/indent/tcl.vim
runtime/indent/tcsh.vim
runtime/indent/tf.vim
runtime/indent/treetop.vim
runtime/indent/verilog.vim
runtime/indent/xf86conf.vim
runtime/indent/xinetd.vim
runtime/indent/yacc.vim
runtime/keymap/armenian-eastern_utf-8.vim
runtime/keymap/armenian-western_utf-8.vim
runtime/macros/less.vim
runtime/macros/matchit.vim
runtime/menu.vim
runtime/mswin.vim
runtime/optwin.vim
runtime/pack/dist/opt/matchit/plugin/matchit.vim
runtime/plugin/gzip.vim
runtime/plugin/tarPlugin.vim
runtime/scripts.vim
runtime/synmenu.vim
runtime/syntax/a2ps.vim
runtime/syntax/alsaconf.vim
runtime/syntax/arch.vim
runtime/syntax/autohotkey.vim
runtime/syntax/bdf.vim
runtime/syntax/c.vim
runtime/syntax/calendar.vim
runtime/syntax/cdrdaoconf.vim
runtime/syntax/cdrtoc.vim
runtime/syntax/cmusrc.vim
runtime/syntax/crm.vim
runtime/syntax/css.vim
runtime/syntax/cvsrc.vim
runtime/syntax/debchangelog.vim
runtime/syntax/debcontrol.vim
runtime/syntax/debsources.vim
runtime/syntax/denyhosts.vim
runtime/syntax/dictconf.vim
runtime/syntax/dictdconf.vim
runtime/syntax/elinks.vim
runtime/syntax/erlang.vim
runtime/syntax/eterm.vim
runtime/syntax/fetchmail.vim
runtime/syntax/fortran.vim
runtime/syntax/framescript.vim
runtime/syntax/gpg.vim
runtime/syntax/group.vim
runtime/syntax/grub.vim
runtime/syntax/hostconf.vim
runtime/syntax/html.vim
runtime/syntax/indent.vim
runtime/syntax/initex.vim
runtime/syntax/ld.vim
runtime/syntax/ldapconf.vim
runtime/syntax/lftp.vim
runtime/syntax/libao.vim
runtime/syntax/limits.vim
runtime/syntax/litestep.vim
runtime/syntax/loginaccess.vim
runtime/syntax/logindefs.vim
runtime/syntax/mailaliases.vim
runtime/syntax/manconf.vim
runtime/syntax/matlab.vim
runtime/syntax/modconf.vim
runtime/syntax/nanorc.vim
runtime/syntax/nasm.vim
runtime/syntax/netrc.vim
runtime/syntax/pamconf.vim
runtime/syntax/passwd.vim
runtime/syntax/php.vim
runtime/syntax/pinfo.vim
runtime/syntax/plaintex.vim
runtime/syntax/protocols.vim
runtime/syntax/quake.vim
runtime/syntax/r.vim
runtime/syntax/racc.vim
runtime/syntax/readline.vim
runtime/syntax/rmd.vim
runtime/syntax/rnc.vim
runtime/syntax/rust.vim [new file with mode: 0644]
runtime/syntax/sas.vim
runtime/syntax/scala.vim
runtime/syntax/sensors.vim
runtime/syntax/services.vim
runtime/syntax/setserial.vim
runtime/syntax/sh.vim
runtime/syntax/sieve.vim
runtime/syntax/slpconf.vim
runtime/syntax/slpreg.vim
runtime/syntax/slpspi.vim
runtime/syntax/sshconfig.vim
runtime/syntax/sshdconfig.vim
runtime/syntax/sudoers.vim
runtime/syntax/sysctl.vim
runtime/syntax/terminfo.vim
runtime/syntax/tex.vim
runtime/syntax/tmux.vim [new file with mode: 0644]
runtime/syntax/treetop.vim
runtime/syntax/udevconf.vim
runtime/syntax/udevperm.vim
runtime/syntax/udevrules.vim
runtime/syntax/updatedb.vim
runtime/syntax/vim.vim
runtime/syntax/xinetd.vim
runtime/syntax/xmodmap.vim
runtime/syntax/xpm.vim
runtime/syntax/xpm2.vim
runtime/syntax/zsh.vim
runtime/tutor/tutor.es
runtime/tutor/tutor.fr
runtime/tutor/tutor.fr.utf-8
runtime/tutor/tutor.it
runtime/tutor/tutor.it.utf-8
runtime/tutor/tutor.pt
runtime/tutor/tutor.pt.utf-8
src/INSTALL
src/Make_cyg_ming.mak
src/Make_mvc.mak
src/Makefile
src/arabic.c
src/auto/config.mk
src/auto/configure
src/blowfish.c
src/buffer.c
src/channel.c
src/charset.c
src/config.h.in
src/config.mk.dist
src/configure.ac [moved from src/configure.in with 99% similarity]
src/create_cmdidxs.vim [new file with mode: 0644]
src/crypt.c
src/dict.c
src/diff.c
src/edit.c
src/eval.c
src/evalfunc.c
src/ex_cmdidxs.h [new file with mode: 0644]
src/ex_cmds.c
src/ex_cmds.h
src/ex_cmds2.c
src/ex_docmd.c
src/ex_eval.c
src/ex_getln.c
src/farsi.c
src/fileio.c
src/fold.c
src/getchar.c
src/globals.h
src/gui.c
src/gui_at_sb.c
src/gui_athena.c
src/gui_beval.c
src/gui_gtk.c
src/gui_gtk_f.c
src/gui_gtk_f.h
src/gui_gtk_x11.c
src/gui_motif.c
src/gui_w32.c
src/gui_x11.c
src/gui_xmdlg.c
src/hangulin.c
src/hardcopy.c
src/hashtab.c
src/if_cscope.c
src/if_lua.c
src/if_perl.xs
src/if_py_both.h
src/if_python.c
src/if_python3.c
src/if_ruby.c
src/if_tcl.c
src/if_xcmdsrv.c
src/install-sh [new file with mode: 0755]
src/installman.sh
src/installml.sh
src/json.c
src/json_test.c
src/keymap.h
src/kword_test.c [new file with mode: 0644]
src/list.c
src/macros.h
src/main.aap
src/main.c
src/mark.c
src/mbyte.c
src/memfile.c
src/memline.c
src/menu.c
src/message.c
src/message_test.c
src/misc1.c
src/misc2.c
src/mkinstalldirs [deleted file]
src/move.c
src/mysign
src/netbeans.c
src/normal.c
src/ops.c
src/option.c
src/option.h
src/os_amiga.c
src/os_mswin.c
src/os_unix.c
src/os_unix.h
src/os_unixx.h
src/os_vms_conf.h
src/os_w32exe.c
src/os_win32.c
src/os_win32.h
src/osdef1.h.in
src/po/Makefile
src/po/eo.po
src/po/fr.po
src/po/zh_CN.UTF-8.po
src/po/zh_CN.cp936.po
src/popupmnu.c
src/proto/channel.pro
src/proto/edit.pro
src/proto/eval.pro
src/proto/ex_cmds2.pro
src/proto/ex_eval.pro
src/proto/fold.pro
src/proto/getchar.pro
src/proto/if_cscope.pro
src/proto/if_xcmdsrv.pro
src/proto/main.pro
src/proto/mark.pro
src/proto/mbyte.pro
src/proto/message.pro
src/proto/misc2.pro
src/proto/ops.pro
src/proto/os_mswin.pro
src/proto/os_win32.pro
src/proto/quickfix.pro
src/proto/syntax.pro
src/proto/tag.pro
src/proto/term.pro
src/proto/ui.pro
src/proto/window.pro
src/pty.c
src/quickfix.c
src/regexp.c
src/regexp_nfa.c
src/screen.c
src/search.c
src/spell.c
src/spellfile.c
src/structs.h
src/swis.s [deleted file]
src/syntax.c
src/tag.c
src/term.c
src/term.h
src/testdir/Make_all.mak
src/testdir/Make_dos.mak
src/testdir/Make_ming.mak
src/testdir/Make_vms.mms
src/testdir/Makefile
src/testdir/README.txt
src/testdir/gen_opt_test.vim [new file with mode: 0644]
src/testdir/gui_init.vim [new file with mode: 0644]
src/testdir/gui_preinit.vim [new file with mode: 0644]
src/testdir/pyxfile/py2_magic.py [new file with mode: 0644]
src/testdir/pyxfile/py2_shebang.py [new file with mode: 0644]
src/testdir/pyxfile/py3_magic.py [new file with mode: 0644]
src/testdir/pyxfile/py3_shebang.py [new file with mode: 0644]
src/testdir/pyxfile/pyx.py [new file with mode: 0644]
src/testdir/runtest.vim
src/testdir/setup_gui.vim [new file with mode: 0644]
src/testdir/shared.vim
src/testdir/test103.in
src/testdir/test14.in
src/testdir/test29.in
src/testdir/test3.in
src/testdir/test3.ok
src/testdir/test30.in
src/testdir/test32.in
src/testdir/test45.in
src/testdir/test49.vim
src/testdir/test72.in
src/testdir/test73.in
src/testdir/test77.in
src/testdir/test78.in
src/testdir/test85.in
src/testdir/test87.in
src/testdir/test89.in [deleted file]
src/testdir/test89.ok [deleted file]
src/testdir/test91.in
src/testdir/test91.ok
src/testdir/test92.in [deleted file]
src/testdir/test92.ok [deleted file]
src/testdir/test93.in [deleted file]
src/testdir/test93.ok [deleted file]
src/testdir/test94.in
src/testdir/test_alot.vim
src/testdir/test_alot_utf8.vim
src/testdir/test_arabic.vim [new file with mode: 0644]
src/testdir/test_arglist.vim
src/testdir/test_assert.vim
src/testdir/test_assign.vim
src/testdir/test_autocmd.vim
src/testdir/test_breakindent.in [deleted file]
src/testdir/test_breakindent.ok [deleted file]
src/testdir/test_breakindent.vim [new file with mode: 0644]
src/testdir/test_cd.vim [new file with mode: 0644]
src/testdir/test_changedtick.vim [new file with mode: 0644]
src/testdir/test_channel.py
src/testdir/test_channel.vim
src/testdir/test_channel_pipe.py
src/testdir/test_charsearch_utf8.vim [new file with mode: 0644]
src/testdir/test_cindent.vim [new file with mode: 0644]
src/testdir/test_clientserver.vim [new file with mode: 0644]
src/testdir/test_close_count.in
src/testdir/test_cmdline.vim
src/testdir/test_cscope.vim
src/testdir/test_cursor_func.vim
src/testdir/test_delete.vim
src/testdir/test_diffmode.vim
src/testdir/test_digraph.vim
src/testdir/test_display.vim [new file with mode: 0644]
src/testdir/test_edit.vim [new file with mode: 0644]
src/testdir/test_erasebackword.in
src/testdir/test_ex_z.vim [new file with mode: 0644]
src/testdir/test_expand_dllpath.vim
src/testdir/test_expr.vim
src/testdir/test_farsi.vim
src/testdir/test_fileformat.vim
src/testdir/test_filter_cmd.vim
src/testdir/test_findfile.vim [new file with mode: 0644]
src/testdir/test_float_func.vim [new file with mode: 0644]
src/testdir/test_fnamemodify.vim
src/testdir/test_fold.vim [new file with mode: 0644]
src/testdir/test_functions.vim [new file with mode: 0644]
src/testdir/test_ga.vim [new file with mode: 0644]
src/testdir/test_global.vim [new file with mode: 0644]
src/testdir/test_goto.vim
src/testdir/test_gui.vim
src/testdir/test_gui_init.vim [new file with mode: 0644]
src/testdir/test_help.vim [new file with mode: 0644]
src/testdir/test_help_tagjump.vim
src/testdir/test_hide.vim [new file with mode: 0644]
src/testdir/test_history.vim
src/testdir/test_json.vim
src/testdir/test_listlbr.in [deleted file]
src/testdir/test_listlbr.ok [deleted file]
src/testdir/test_listlbr.vim [new file with mode: 0644]
src/testdir/test_listlbr_utf8.in [deleted file]
src/testdir/test_listlbr_utf8.ok [deleted file]
src/testdir/test_listlbr_utf8.vim [new file with mode: 0644]
src/testdir/test_lua.vim [new file with mode: 0644]
src/testdir/test_makeencoding.py [new file with mode: 0644]
src/testdir/test_makeencoding.vim [new file with mode: 0644]
src/testdir/test_mapping.vim
src/testdir/test_marks.vim
src/testdir/test_menu.vim
src/testdir/test_mksession.vim [new file with mode: 0644]
src/testdir/test_mksession_utf8.vim [new file with mode: 0644]
src/testdir/test_nested_function.vim
src/testdir/test_normal.vim
src/testdir/test_number.vim [new file with mode: 0644]
src/testdir/test_options.vim
src/testdir/test_packadd.vim
src/testdir/test_paste.vim [new file with mode: 0644]
src/testdir/test_perl.vim
src/testdir/test_popup.vim
src/testdir/test_profile.vim [new file with mode: 0644]
src/testdir/test_put.vim [new file with mode: 0644]
src/testdir/test_python2.vim [new file with mode: 0644]
src/testdir/test_python3.vim [new file with mode: 0644]
src/testdir/test_pyx2.vim [new file with mode: 0644]
src/testdir/test_pyx3.vim [new file with mode: 0644]
src/testdir/test_quickfix.vim
src/testdir/test_quotestar.vim [new file with mode: 0644]
src/testdir/test_recover.vim [new file with mode: 0644]
src/testdir/test_regexp_utf8.vim
src/testdir/test_retab.vim [new file with mode: 0644]
src/testdir/test_ruby.vim
src/testdir/test_search.vim
src/testdir/test_spell.vim [new file with mode: 0644]
src/testdir/test_startup.vim
src/testdir/test_stat.vim
src/testdir/test_statusline.vim
src/testdir/test_substitute.vim
src/testdir/test_syntax.vim
src/testdir/test_system.vim [new file with mode: 0644]
src/testdir/test_tabpage.vim
src/testdir/test_tagjump.vim
src/testdir/test_taglist.vim [new file with mode: 0644]
src/testdir/test_tcl.vim [new file with mode: 0644]
src/testdir/test_textobjects.vim
src/testdir/test_undo.vim
src/testdir/test_unlet.vim
src/testdir/test_usercommands.vim
src/testdir/test_utf8.in [deleted file]
src/testdir/test_utf8.ok [deleted file]
src/testdir/test_utf8.vim [new file with mode: 0644]
src/testdir/test_viminfo.vim
src/testdir/test_vimscript.vim [moved from src/testdir/test_viml.vim with 92% similarity]
src/testdir/test_visual.vim
src/testdir/test_window_cmd.vim
src/testdir/test_window_id.vim
src/testdir/unix.vim
src/testdir/view_util.vim [new file with mode: 0644]
src/ui.c
src/undo.c
src/userfunc.c
src/version.c
src/vim.h
src/winclip.c
src/window.c
src/workshop.c
uninstal.txt

index 901d8f7..53b6afb 100644 (file)
--- a/.hgignore
+++ b/.hgignore
@@ -7,6 +7,7 @@ src/xxd/xxd
 src/auto/if_perl.c
 src/auto/gui_gtk_gresources.c
 src/auto/gui_gtk_gresources.h
+src/objects/.dirstamp
 src/tags
 
 # We do need src/auto/configure.
@@ -79,4 +80,8 @@ src/testdir/test.log
 src/testdir/dostmp/*
 src/testdir/messages
 src/testdir/viminfo
+src/testdir/opt_test.vim
 src/memfile_test
+src/json_test
+src/message_test
+src/kword_test
index af3eb1f..a0b8d21 100644 (file)
@@ -1,19 +1,63 @@
 language: c
 
+os:
+  - osx
+  - linux
+
 compiler:
   - clang
   - gcc
 
 env:
-  - COVERAGE=yes CFLAGS=--coverage LDFLAGS=--coverage FEATURES=huge SHADOWOPT= SRCDIR=./src
+  - BUILD=yes TEST=scripttests COVERAGE=yes CFLAGS=--coverage LDFLAGS=--coverage FEATURES=huge SHADOWOPT= SRCDIR=./src CHECK_AUTOCONF=no
     "CONFOPT='--enable-perlinterp --enable-pythoninterp --enable-python3interp --enable-rubyinterp --enable-luainterp'"
-    CHECK_AUTOCONF=yes
-  - COVERAGE=no FEATURES=normal CONFOPT= SHADOWOPT="-C src/shadow" SRCDIR=./src/shadow CHECK_AUTOCONF=no
-  - COVERAGE=no FEATURES=small CONFOPT= SHADOWOPT= SRCDIR=./src CHECK_AUTOCONF=no
-  - COVERAGE=no FEATURES=tiny  CONFOPT= SHADOWOPT= SRCDIR=./src CHECK_AUTOCONF=no
+  - BUILD=no TEST=unittests COVERAGE=yes CFLAGS=--coverage LDFLAGS=--coverage FEATURES=huge SHADOWOPT= SRCDIR=./src CHECK_AUTOCONF=yes
+  - BUILD=yes TEST=test COVERAGE=no FEATURES=normal CONFOPT= SHADOWOPT="-C src/shadow" SRCDIR=./src/shadow CHECK_AUTOCONF=no
+  - BUILD=yes TEST=test COVERAGE=no FEATURES=small CONFOPT= SHADOWOPT= SRCDIR=./src CHECK_AUTOCONF=no
+  - BUILD=yes TEST=test COVERAGE=no FEATURES=tiny  CONFOPT= SHADOWOPT= SRCDIR=./src CHECK_AUTOCONF=no
+    # Mac OSX build
+  - BUILD=yes TEST=test COVERAGE=no FEATURES=huge SHADOWOPT= SRCDIR=./src CHECK_AUTOCONF=no
+    "CONFOPT='--enable-perlinterp --enable-pythoninterp --enable-rubyinterp --enable-luainterp'"
+    # ASAN build
+  - BUILD=yes TEST=test SANITIZER_CFLAGS="-g -O1 -DABORT_ON_INTERNAL_ERROR -DEXITFREE -fsanitize=address -fno-omit-frame-pointer"
+    FEATURES=huge SRCDIR=./src CHECK_AUTOCONF=no ASAN_OPTIONS="print_stacktrace=1 log_path=asan"
+    "CONFOPT='--enable-perlinterp --enable-pythoninterp --enable-rubyinterp --enable-luainterp'"
 
 sudo: false
 
+# instead of a 2*2*8 matrix (2*os + 2*compiler + 8*env),
+# exclude some builds on mac os x and linux
+# linux: 2*compiler + 5*env + mac: 2*compiler + 2*env
+matrix:
+  exclude:
+    - os: osx
+      env: BUILD=yes TEST=test COVERAGE=no FEATURES=normal CONFOPT= SHADOWOPT="-C src/shadow" SRCDIR=./src/shadow CHECK_AUTOCONF=no
+    - os: osx
+      env: BUILD=no TEST=unittests COVERAGE=yes CFLAGS=--coverage LDFLAGS=--coverage FEATURES=huge SHADOWOPT= SRCDIR=./src CHECK_AUTOCONF=yes
+    - os: osx
+      env: BUILD=yes TEST=test COVERAGE=no FEATURES=small CONFOPT= SHADOWOPT= SRCDIR=./src CHECK_AUTOCONF=no
+    - os: osx
+      env: BUILD=yes TEST=scripttests COVERAGE=yes CFLAGS=--coverage LDFLAGS=--coverage FEATURES=huge SHADOWOPT= SRCDIR=./src CHECK_AUTOCONF=no
+            "CONFOPT='--enable-perlinterp --enable-pythoninterp --enable-python3interp --enable-rubyinterp --enable-luainterp'"
+    - os: osx
+      env: BUILD=yes TEST=test SANITIZER_CFLAGS="-g -O1 -DABORT_ON_INTERNAL_ERROR -DEXITFREE -fsanitize=address -fno-omit-frame-pointer"
+            FEATURES=huge SRCDIR=./src CHECK_AUTOCONF=no ASAN_OPTIONS="print_stacktrace=1 log_path=asan"
+            "CONFOPT='--enable-perlinterp --enable-pythoninterp --enable-rubyinterp --enable-luainterp'"
+    - os: linux
+      compiler: gcc
+      env: BUILD=yes TEST=test SANITIZER_CFLAGS="-g -O1 -DABORT_ON_INTERNAL_ERROR -DEXITFREE -fsanitize=address -fno-omit-frame-pointer"
+            FEATURES=huge SRCDIR=./src CHECK_AUTOCONF=no ASAN_OPTIONS="print_stacktrace=1 log_path=asan"
+            "CONFOPT='--enable-perlinterp --enable-pythoninterp --enable-rubyinterp --enable-luainterp'"
+    - os: linux
+      compiler: clang
+      env: BUILD=no TEST=unittests COVERAGE=yes CFLAGS=--coverage LDFLAGS=--coverage FEATURES=huge SHADOWOPT= SRCDIR=./src CHECK_AUTOCONF=yes
+    - os: linux
+      compiler: clang
+      env: BUILD=yes TEST=test COVERAGE=no FEATURES=small CONFOPT= SHADOWOPT= SRCDIR=./src CHECK_AUTOCONF=no
+    - os: linux
+      env: BUILD=yes TEST=test COVERAGE=no FEATURES=huge SHADOWOPT= SRCDIR=./src CHECK_AUTOCONF=no
+            "CONFOPT='--enable-perlinterp --enable-pythoninterp --enable-rubyinterp --enable-luainterp'"
+
 branches:
   except:
     - /^v[0-9]/
@@ -28,18 +72,33 @@ addons:
       - python3-dev
       - liblua5.1-0-dev
       - lua5.1
+      - cscope
 
 before_install:
-  - pip install --user cpp-coveralls
+  - if [ "$COVERAGE" = "yes" ]; then pip install --user cpp-coveralls; fi
+    # needed for https support for coveralls
+    # building cffi only works with gcc, not with clang
+  - if [ "$COVERAGE" = "yes" ]; then CC=gcc pip install --user pyopenssl ndg-httpsclient pyasn1; fi
+    # Lua is not installed on Travis OSX
+  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install lua; export LUA_PREFIX=/usr/local; fi
+
+# Start virtual framebuffer to be able to test the GUI. Does not work on OS X.
+before_script:
+  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then export DISPLAY=:99.0 && sh -e /etc/init.d/xvfb start && sleep 3; fi
 
 script:
   - NPROC=$(getconf _NPROCESSORS_ONLN)
   - if [ "$CHECK_AUTOCONF" = "yes" -a "$CC" = "gcc" ]; then make -C src autoconf; fi
-  - if [ "x$SHADOWOPT" != x ]; then make -C src shadow; fi && (cd ${SRCDIR} && ./configure --with-features=$FEATURES $CONFOPT --enable-fail-if-missing && make -j$NPROC)
-  - ${SRCDIR}/vim --version
-  - make $SHADOWOPT test
+  - if [ "x$SHADOWOPT" != x ]; then make -C src shadow; fi
+  - (cd ${SRCDIR} && ./configure --with-features=$FEATURES $CONFOPT --enable-fail-if-missing && if [ "$BUILD" = "yes" ]; then make -j$NPROC; fi)
+  - if [ "$BUILD" = "yes" ]; then ${SRCDIR}/vim --version; fi
+  - if [ -n "$ASAN_OPTIONS" ]; then export PATH=/usr/lib/llvm-$(clang -v 2>&1 | sed -n 's/.*version \([1-9]\.[0-9][0-9]*\).*/\1/p')/bin:$PATH; fi
+  - make $SHADOWOPT $TEST
+  - if [ -n "$ASAN_OPTIONS" ]; then for log in $(find -type f -name 'asan.*' -size +0); do cat "$log"; err=1; done; fi
+  - if [ -n "$err" ]; then exit 1; fi
 
 after_success:
-  - if [ x"$COVERAGE" = "xyes" ]; then ~/.local/bin/coveralls -b $SRCDIR -x .xs -e ${SRCDIR}/xxd -e ${SRCDIR}/if_perl.c --encodings utf-8 latin-1 EUC-KR; fi
+  - if [ "$COVERAGE" = "yes" ]; then ~/.local/bin/coveralls -b $SRCDIR -x .xs -e ${SRCDIR}/xxd -e ${SRCDIR}/if_perl.c --encodings utf-8 latin-1 EUC-KR; fi
+  - if [ "$COVERAGE" = "yes" ]; then  cd $SRCDIR && bash <(curl -s https://codecov.io/bash) ; fi
 
 # vim:set sts=2 sw=2 tw=0 et:
index 7334e5e..6d8e2e8 100644 (file)
--- a/Filelist
+++ b/Filelist
@@ -24,6 +24,7 @@ SRC_ALL =     \
                src/edit.c \
                src/eval.c \
                src/evalfunc.c \
+               src/ex_cmdidxs.h \
                src/ex_cmds.c \
                src/ex_cmds.h \
                src/ex_cmds2.c \
@@ -45,6 +46,7 @@ SRC_ALL =     \
                src/hashtab.c \
                src/json.c \
                src/json_test.c \
+               src/kword_test.c \
                src/list.c \
                src/keymap.h \
                src/macros.h \
@@ -96,6 +98,7 @@ SRC_ALL =     \
                src/tee/tee.c \
                src/xxd/xxd.c \
                src/main.aap \
+               src/testdir/gen_opt_test.vim \
                src/testdir/main.aap \
                src/testdir/README.txt \
                src/testdir/Make_all.mak \
@@ -104,7 +107,11 @@ SRC_ALL =  \
                src/testdir/sautest/autoload/*.vim \
                src/testdir/runtest.vim \
                src/testdir/shared.vim \
+               src/testdir/view_util.vim \
                src/testdir/setup.vim \
+               src/testdir/gui_init.vim \
+               src/testdir/setup_gui.vim \
+               src/testdir/gui_preinit.vim \
                src/testdir/test[0-9]*.ok \
                src/testdir/test[0-9]*a.ok \
                src/testdir/test_[a-z]*.ok \
@@ -122,6 +129,7 @@ SRC_ALL =   \
                src/testdir/pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py \
                src/testdir/python_after/*.py \
                src/testdir/python_before/*.py \
+               src/testdir/pyxfile/*.py \
                src/testdir/bench*.in \
                src/testdir/bench*.vim \
                src/testdir/samples/*.txt \
@@ -207,7 +215,8 @@ SRC_UNIX =  \
                src/config.mk.dist \
                src/config.mk.in \
                src/configure \
-               src/configure.in \
+               src/configure.ac \
+               src/create_cmdidxs.vim \
                src/gui_at_fs.c \
                src/gui_at_sb.c \
                src/gui_at_sb.h \
@@ -231,7 +240,7 @@ SRC_UNIX =  \
                src/link.sh \
                src/installman.sh \
                src/installml.sh \
-               src/mkinstalldirs \
+               src/install-sh \
                src/os_unix.c \
                src/os_unix.h \
                src/os_unixx.h \
@@ -717,7 +726,6 @@ EXTRA =             \
                farsi/README.txt \
                farsi/fonts/*/far-* \
                runtime/vimlogo.xpm \
-               src/swis.s \
                src/tee/Makefile \
                src/tee/Make_mvc.mak \
                src/tee/tee.c \
index 9f48a35..d198316 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -120,8 +120,9 @@ MINOR = 0
 #
 # MS-Windows:
 # - Run make on Unix to update the ".mo" files.
-# - Get libintl-8.dll and libiconv-2.dll. E.g. from
+# - Get libintl-8.dll, libiconv-2.dll and libgcc_s_sjlj-1.dll. E.g. from
 #   https://mlocati.github.io/gettext-iconv-windows/ .
+#   Use the "shared-32.zip file and extract the archive to get the files.
 #   Put them in the top directory, "make dosrt" uses them.
 # - > make dossrc
 #   > make dosrt
@@ -468,6 +469,7 @@ dosrt_files: dist prepare no_title.vim
            done
        cp libintl-8.dll dist/vim/$(VIMRTDIR)/
        cp libiconv-2.dll dist/vim/$(VIMRTDIR)/
+       cp libgcc_s_sjlj-1.dll dist/vim/$(VIMRTDIR)/
 
 
 # Used before uploading.  Don't delete the AAPDIR/sign files!
index 71bc498..53795a7 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,5 +1,6 @@
 `README.md` for version 8.0 of Vim: Vi IMproved.
 [![Build Status](https://travis-ci.org/vim/vim.svg?branch=master)](https://travis-ci.org/vim/vim)
+[![Coverage Status](https://codecov.io/gh/vim/vim/coverage.svg?branch=master)](https://codecov.io/gh/vim/vim?branch=master)
 [![Coverage Status](https://coveralls.io/repos/vim/vim/badge.svg?branch=master&service=github)](https://coveralls.io/github/vim/vim?branch=master)
 [![Appveyor Build status](https://ci.appveyor.com/api/projects/status/o2qht2kjm02sgghk?svg=true)](https://ci.appveyor.com/project/chrisbra/vim)
 [![Coverity Scan](https://scan.coverity.com/projects/241/badge.svg)](https://scan.coverity.com/projects/vim)
index 26d7aab..74a5433 100644 (file)
@@ -385,6 +385,7 @@ SectionEnd
                File ${VIMRT}\libintl-8.dll
                File ${VIMRT}\libiconv-2.dll
                File /nonfatal ${VIMRT}\libwinpthread-1.dll
+               File /nonfatal ${VIMRT}\libgcc_s_sjlj-1.dll
        SectionEnd
 !endif
 
index 1f8234a..ce3a193 100644 (file)
@@ -2,12 +2,13 @@
 "  Description: Perform Ada specific completion & tagging.
 "     Language: Ada (2005)
 "         $Id: ada.vim 887 2008-07-08 14:29:01Z krischik $
-"   Maintainer: Martin Krischik <krischik@users.sourceforge.net>
+"   Maintainer: Mathias Brousset <mathiasb17@gmail.com>
+"              Martin Krischik <krischik@users.sourceforge.net>
 "              Taylor Venable <taylor@metasyntax.net>
 "              Neil Bird <neil@fnxweb.com>
 "              Ned Okie <nokie@radford.edu>
 "      $Author: krischik $
-"       $Date: 2008-07-08 16:29:01 +0200 (Di, 08 Jul 2008) $
+"       $Date: 2017-01-31 20:20:05 +0200 (Mon, 01 Jan 2017) $
 "      Version: 4.6
 "    $Revision: 887 $
 "     $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/ada.vim $
@@ -23,6 +24,7 @@
 "              09.05.2007 MK Session just won't work no matter how much
 "                            tweaking is done
 "              19.09.2007 NO still some mapleader problems
+"              31.01.2017 MB fix more mapleader problems
 "    Help Page: ft-ada-functions
 "------------------------------------------------------------------------------
 
@@ -447,7 +449,7 @@ function ada#Switch_Session (New_Session)
 
       if a:New_Session != v:this_session
         "
-        "  We actualy got a new session - otherwise there
+        "  We actually got a new session - otherwise there
         "  is nothing to do.
         "
         if strlen (v:this_session) > 0
@@ -585,11 +587,11 @@ function ada#Map_Menu (Text, Keys, Command)
        \ " :"    . a:Command . "<CR>"
       execute
        \ "nnoremap <buffer>" .
-       \ escape(l:leader . "a" . a:Keys , '\') .
+       \ " <Leader>a" . a:Keys .
        \" :" . a:Command
       execute
        \ "inoremap <buffer>" .
-       \ escape(l:leader . "a" . a:Keys , '\') .
+       \ " <Learder>a" . a:Keys .
        \" <C-O>:" . a:Command
    endif
    return
index 2abe41b..14bc3d7 100644 (file)
@@ -1,7 +1,7 @@
 " Vim completion script
 " Language:    Java Script
 " Maintainer:  Mikolaj Machowski ( mikmach AT wp DOT pl )
-" Last Change: 2006 Apr 30
+" Last Change: 2017 Mar 04
 
 function! javascriptcomplete#CompleteJS(findstart, base)
   if a:findstart
@@ -563,7 +563,7 @@ function! javascriptcomplete#CompleteJS(findstart, base)
        for i in arguments
                let g:ia = i
                let f_elements = matchlist(i, 'function\s\+\(\k\+\)\s*(\(.\{-}\))')
-               if len(f_elements) == 3
+               if len(f_elements) >= 3
                        let b:js_menuinfo[f_elements[1].'('] = f_elements[2]
                endif
        endfor
diff --git a/runtime/autoload/rust.vim b/runtime/autoload/rust.vim
new file mode 100644 (file)
index 0000000..34a3b41
--- /dev/null
@@ -0,0 +1,415 @@
+" Author: Kevin Ballard
+" Description: Helper functions for Rust commands/mappings
+" Last Modified: May 27, 2014
+" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
+
+" Jump {{{1
+
+function! rust#Jump(mode, function) range
+       let cnt = v:count1
+       normal! m'
+       if a:mode ==# 'v'
+               norm! gv
+       endif
+       let foldenable = &foldenable
+       set nofoldenable
+       while cnt > 0
+               execute "call <SID>Jump_" . a:function . "()"
+               let cnt = cnt - 1
+       endwhile
+       let &foldenable = foldenable
+endfunction
+
+function! s:Jump_Back()
+       call search('{', 'b')
+       keepjumps normal! w99[{
+endfunction
+
+function! s:Jump_Forward()
+       normal! j0
+       call search('{', 'b')
+       keepjumps normal! w99[{%
+       call search('{')
+endfunction
+
+" Run {{{1
+
+function! rust#Run(bang, args)
+       let args = s:ShellTokenize(a:args)
+       if a:bang
+               let idx = index(l:args, '--')
+               if idx != -1
+                       let rustc_args = idx == 0 ? [] : l:args[:idx-1]
+                       let args = l:args[idx+1:]
+               else
+                       let rustc_args = l:args
+                       let args = []
+               endif
+       else
+               let rustc_args = []
+       endif
+
+       let b:rust_last_rustc_args = l:rustc_args
+       let b:rust_last_args = l:args
+
+       call s:WithPath(function("s:Run"), rustc_args, args)
+endfunction
+
+function! s:Run(dict, rustc_args, args)
+       let exepath = a:dict.tmpdir.'/'.fnamemodify(a:dict.path, ':t:r')
+       if has('win32')
+               let exepath .= '.exe'
+       endif
+
+       let relpath = get(a:dict, 'tmpdir_relpath', a:dict.path)
+       let rustc_args = [relpath, '-o', exepath] + a:rustc_args
+
+       let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
+
+       let pwd = a:dict.istemp ? a:dict.tmpdir : ''
+       let output = s:system(pwd, shellescape(rustc) . " " . join(map(rustc_args, 'shellescape(v:val)')))
+       if output != ''
+               echohl WarningMsg
+               echo output
+               echohl None
+       endif
+       if !v:shell_error
+               exe '!' . shellescape(exepath) . " " . join(map(a:args, 'shellescape(v:val)'))
+       endif
+endfunction
+
+" Expand {{{1
+
+function! rust#Expand(bang, args)
+       let args = s:ShellTokenize(a:args)
+       if a:bang && !empty(l:args)
+               let pretty = remove(l:args, 0)
+       else
+               let pretty = "expanded"
+       endif
+       call s:WithPath(function("s:Expand"), pretty, args)
+endfunction
+
+function! s:Expand(dict, pretty, args)
+       try
+               let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
+
+               if a:pretty =~? '^\%(everybody_loops$\|flowgraph=\)'
+                       let flag = '--xpretty'
+               else
+                       let flag = '--pretty'
+               endif
+               let relpath = get(a:dict, 'tmpdir_relpath', a:dict.path)
+               let args = [relpath, '-Z', 'unstable-options', l:flag, a:pretty] + a:args
+               let pwd = a:dict.istemp ? a:dict.tmpdir : ''
+               let output = s:system(pwd, shellescape(rustc) . " " . join(map(args, 'shellescape(v:val)')))
+               if v:shell_error
+                       echohl WarningMsg
+                       echo output
+                       echohl None
+               else
+                       new
+                       silent put =output
+                       1
+                       d
+                       setl filetype=rust
+                       setl buftype=nofile
+                       setl bufhidden=hide
+                       setl noswapfile
+                       " give the buffer a nice name
+                       let suffix = 1
+                       let basename = fnamemodify(a:dict.path, ':t:r')
+                       while 1
+                               let bufname = basename
+                               if suffix > 1 | let bufname .= ' ('.suffix.')' | endif
+                               let bufname .= '.pretty.rs'
+                               if bufexists(bufname)
+                                       let suffix += 1
+                                       continue
+                               endif
+                               exe 'silent noautocmd keepalt file' fnameescape(bufname)
+                               break
+                       endwhile
+               endif
+       endtry
+endfunction
+
+function! rust#CompleteExpand(lead, line, pos)
+       if a:line[: a:pos-1] =~ '^RustExpand!\s*\S*$'
+               " first argument and it has a !
+               let list = ["normal", "expanded", "typed", "expanded,identified", "flowgraph=", "everybody_loops"]
+               if !empty(a:lead)
+                       call filter(list, "v:val[:len(a:lead)-1] == a:lead")
+               endif
+               return list
+       endif
+
+       return glob(escape(a:lead, "*?[") . '*', 0, 1)
+endfunction
+
+" Emit {{{1
+
+function! rust#Emit(type, args)
+       let args = s:ShellTokenize(a:args)
+       call s:WithPath(function("s:Emit"), a:type, args)
+endfunction
+
+function! s:Emit(dict, type, args)
+       try
+               let output_path = a:dict.tmpdir.'/output'
+
+               let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
+
+               let relpath = get(a:dict, 'tmpdir_relpath', a:dict.path)
+               let args = [relpath, '--emit', a:type, '-o', output_path] + a:args
+               let pwd = a:dict.istemp ? a:dict.tmpdir : ''
+               let output = s:system(pwd, shellescape(rustc) . " " . join(map(args, 'shellescape(v:val)')))
+               if output != ''
+                       echohl WarningMsg
+                       echo output
+                       echohl None
+               endif
+               if !v:shell_error
+                       new
+                       exe 'silent keepalt read' fnameescape(output_path)
+                       1
+                       d
+                       if a:type == "llvm-ir"
+                               setl filetype=llvm
+                               let extension = 'll'
+                       elseif a:type == "asm"
+                               setl filetype=asm
+                               let extension = 's'
+                       endif
+                       setl buftype=nofile
+                       setl bufhidden=hide
+                       setl noswapfile
+                       if exists('l:extension')
+                               " give the buffer a nice name
+                               let suffix = 1
+                               let basename = fnamemodify(a:dict.path, ':t:r')
+                               while 1
+                                       let bufname = basename
+                                       if suffix > 1 | let bufname .= ' ('.suffix.')' | endif
+                                       let bufname .= '.'.extension
+                                       if bufexists(bufname)
+                                               let suffix += 1
+                                               continue
+                                       endif
+                                       exe 'silent noautocmd keepalt file' fnameescape(bufname)
+                                       break
+                               endwhile
+                       endif
+               endif
+       endtry
+endfunction
+
+" Utility functions {{{1
+
+" Invokes func(dict, ...)
+" Where {dict} is a dictionary with the following keys:
+"   'path' - The path to the file
+"   'tmpdir' - The path to a temporary directory that will be deleted when the
+"              function returns.
+"   'istemp' - 1 if the path is a file inside of {dict.tmpdir} or 0 otherwise.
+" If {istemp} is 1 then an additional key is provided:
+"   'tmpdir_relpath' - The {path} relative to the {tmpdir}.
+"
+" {dict.path} may be a path to a file inside of {dict.tmpdir} or it may be the
+" existing path of the current buffer. If the path is inside of {dict.tmpdir}
+" then it is guaranteed to have a '.rs' extension.
+function! s:WithPath(func, ...)
+       let buf = bufnr('')
+       let saved = {}
+       let dict = {}
+       try
+               let saved.write = &write
+               set write
+               let dict.path = expand('%')
+               let pathisempty = empty(dict.path)
+
+               " Always create a tmpdir in case the wrapped command wants it
+               let dict.tmpdir = tempname()
+               call mkdir(dict.tmpdir)
+
+               if pathisempty || !saved.write
+                       let dict.istemp = 1
+                       " if we're doing this because of nowrite, preserve the filename
+                       if !pathisempty
+                               let filename = expand('%:t:r').".rs"
+                       else
+                               let filename = 'unnamed.rs'
+                       endif
+                       let dict.tmpdir_relpath = filename
+                       let dict.path = dict.tmpdir.'/'.filename
+
+                       let saved.mod = &mod
+                       set nomod
+
+                       silent exe 'keepalt write! ' . fnameescape(dict.path)
+                       if pathisempty
+                               silent keepalt 0file
+                       endif
+               else
+                       let dict.istemp = 0
+                       update
+               endif
+
+               call call(a:func, [dict] + a:000)
+       finally
+               if bufexists(buf)
+                       for [opt, value] in items(saved)
+                               silent call setbufvar(buf, '&'.opt, value)
+                               unlet value " avoid variable type mismatches
+                       endfor
+               endif
+               if has_key(dict, 'tmpdir') | silent call s:RmDir(dict.tmpdir) | endif
+       endtry
+endfunction
+
+function! rust#AppendCmdLine(text)
+       call setcmdpos(getcmdpos())
+       let cmd = getcmdline() . a:text
+       return cmd
+endfunction
+
+" Tokenize the string according to sh parsing rules
+function! s:ShellTokenize(text)
+       " states:
+       " 0: start of word
+       " 1: unquoted
+       " 2: unquoted backslash
+       " 3: double-quote
+       " 4: double-quoted backslash
+       " 5: single-quote
+       let l:state = 0
+       let l:current = ''
+       let l:args = []
+       for c in split(a:text, '\zs')
+               if l:state == 0 || l:state == 1 " unquoted
+                       if l:c ==# ' '
+                               if l:state == 0 | continue | endif
+                               call add(l:args, l:current)
+                               let l:current = ''
+                               let l:state = 0
+                       elseif l:c ==# '\'
+                               let l:state = 2
+                       elseif l:c ==# '"'
+                               let l:state = 3
+                       elseif l:c ==# "'"
+                               let l:state = 5
+                       else
+                               let l:current .= l:c
+                               let l:state = 1
+                       endif
+               elseif l:state == 2 " unquoted backslash
+                       if l:c !=# "\n" " can it even be \n?
+                               let l:current .= l:c
+                       endif
+                       let l:state = 1
+               elseif l:state == 3 " double-quote
+                       if l:c ==# '\'
+                               let l:state = 4
+                       elseif l:c ==# '"'
+                               let l:state = 1
+                       else
+                               let l:current .= l:c
+                       endif
+               elseif l:state == 4 " double-quoted backslash
+                       if stridx('$`"\', l:c) >= 0
+                               let l:current .= l:c
+                       elseif l:c ==# "\n" " is this even possible?
+                               " skip it
+                       else
+                               let l:current .= '\'.l:c
+                       endif
+                       let l:state = 3
+               elseif l:state == 5 " single-quoted
+                       if l:c == "'"
+                               let l:state = 1
+                       else
+                               let l:current .= l:c
+                       endif
+               endif
+       endfor
+       if l:state != 0
+               call add(l:args, l:current)
+       endif
+       return l:args
+endfunction
+
+function! s:RmDir(path)
+       " sanity check; make sure it's not empty, /, or $HOME
+       if empty(a:path)
+               echoerr 'Attempted to delete empty path'
+               return 0
+       elseif a:path == '/' || a:path == $HOME
+               echoerr 'Attempted to delete protected path: ' . a:path
+               return 0
+       endif
+       return system("rm -rf " . shellescape(a:path))
+endfunction
+
+" Executes {cmd} with the cwd set to {pwd}, without changing Vim's cwd.
+" If {pwd} is the empty string then it doesn't change the cwd.
+function! s:system(pwd, cmd)
+       let cmd = a:cmd
+       if !empty(a:pwd)
+               let cmd = 'cd ' . shellescape(a:pwd) . ' && ' . cmd
+       endif
+       return system(cmd)
+endfunction
+
+" Playpen Support {{{1
+" Parts of gist.vim by Yasuhiro Matsumoto <mattn.jp@gmail.com> reused
+" gist.vim available under the BSD license, available at
+" http://github.com/mattn/gist-vim
+function! s:has_webapi()
+    if !exists("*webapi#http#post")
+       try
+           call webapi#http#post()
+       catch
+       endtry
+    endif
+    return exists("*webapi#http#post")
+endfunction
+
+function! rust#Play(count, line1, line2, ...) abort
+    redraw
+
+    let l:rust_playpen_url = get(g:, 'rust_playpen_url', 'https://play.rust-lang.org/')
+    let l:rust_shortener_url = get(g:, 'rust_shortener_url', 'https://is.gd/')
+
+    if !s:has_webapi()
+       echohl ErrorMsg | echomsg ':RustPlay depends on webapi.vim (https://github.com/mattn/webapi-vim)' | echohl None
+       return
+    endif
+
+    let bufname = bufname('%')
+    if a:count < 1
+       let content = join(getline(a:line1, a:line2), "\n")
+    else
+       let save_regcont = @"
+       let save_regtype = getregtype('"')
+       silent! normal! gvy
+       let content = @"
+       call setreg('"', save_regcont, save_regtype)
+    endif
+
+    let body = l:rust_playpen_url."?code=".webapi#http#encodeURI(content)
+
+    if strlen(body) > 5000
+       echohl ErrorMsg | echomsg 'Buffer too large, max 5000 encoded characters ('.strlen(body).')' | echohl None
+       return
+    endif
+
+    let payload = "format=simple&url=".webapi#http#encodeURI(body)
+    let res = webapi#http#post(l:rust_shortener_url.'create.php', payload, {})
+    let url = res.content
+
+    redraw | echomsg 'Done: '.url
+endfunction
+
+" }}}1
+
+" vim: set noet sw=8 ts=8:
diff --git a/runtime/autoload/rustfmt.vim b/runtime/autoload/rustfmt.vim
new file mode 100644 (file)
index 0000000..a689b5e
--- /dev/null
@@ -0,0 +1,107 @@
+" Author: Stephen Sugden <stephen@stephensugden.com>
+"
+" Adapted from https://github.com/fatih/vim-go
+" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
+
+if !exists("g:rustfmt_autosave")
+       let g:rustfmt_autosave = 0
+endif
+
+if !exists("g:rustfmt_command")
+       let g:rustfmt_command = "rustfmt"
+endif
+
+if !exists("g:rustfmt_options")
+       let g:rustfmt_options = ""
+endif
+
+if !exists("g:rustfmt_fail_silently")
+       let g:rustfmt_fail_silently = 0
+endif
+
+let s:got_fmt_error = 0
+
+function! s:RustfmtCommandRange(filename, line1, line2)
+       let l:arg = {"file": shellescape(a:filename), "range": [a:line1, a:line2]}
+       return printf("%s %s --write-mode=overwrite --file-lines '[%s]'", g:rustfmt_command, g:rustfmt_options, json_encode(l:arg))
+endfunction
+
+function! s:RustfmtCommand(filename)
+       return g:rustfmt_command . " --write-mode=overwrite " . g:rustfmt_options . " " . shellescape(a:filename)
+endfunction
+
+function! s:RunRustfmt(command, curw, tmpname)
+       if exists("*systemlist")
+               let out = systemlist(a:command)
+       else
+               let out = split(system(a:command), '\r\?\n')
+       endif
+
+       if v:shell_error == 0 || v:shell_error == 3
+               " remove undo point caused via BufWritePre
+               try | silent undojoin | catch | endtry
+
+               " Replace current file with temp file, then reload buffer
+               call rename(a:tmpname, expand('%'))
+               silent edit!
+               let &syntax = &syntax
+
+               " only clear location list if it was previously filled to prevent
+               " clobbering other additions
+               if s:got_fmt_error
+                       let s:got_fmt_error = 0
+                       call setloclist(0, [])
+                       lwindow
+               endif
+       elseif g:rustfmt_fail_silently == 0
+               " otherwise get the errors and put them in the location list
+               let errors = []
+
+               for line in out
+                       " src/lib.rs:13:5: 13:10 error: expected `,`, or `}`, found `value`
+                       let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\):\s*\(\d\+:\d\+\s*\)\?\s*error: \(.*\)')
+                       if !empty(tokens)
+                               call add(errors, {"filename": @%,
+                                                \"lnum":     tokens[2],
+                                                \"col":      tokens[3],
+                                                \"text":     tokens[5]})
+                       endif
+               endfor
+
+               if empty(errors)
+                       % | " Couldn't detect rustfmt error format, output errors
+               endif
+
+               if !empty(errors)
+                       call setloclist(0, errors, 'r')
+                       echohl Error | echomsg "rustfmt returned error" | echohl None
+               endif
+
+               let s:got_fmt_error = 1
+               lwindow
+               " We didn't use the temp file, so clean up
+               call delete(a:tmpname)
+       endif
+
+       call winrestview(a:curw)
+endfunction
+
+function! rustfmt#FormatRange(line1, line2)
+       let l:curw = winsaveview()
+       let l:tmpname = expand("%:p:h") . "/." . expand("%:p:t") . ".rustfmt"
+       call writefile(getline(1, '$'), l:tmpname)
+
+       let command = s:RustfmtCommandRange(l:tmpname, a:line1, a:line2)
+
+       call s:RunRustfmt(command, l:curw, l:tmpname)
+endfunction
+
+function! rustfmt#Format()
+       let l:curw = winsaveview()
+       let l:tmpname = expand("%:p:h") . "/." . expand("%:p:t") . ".rustfmt"
+       call writefile(getline(1, '$'), l:tmpname)
+
+       let command = s:RustfmtCommand(l:tmpname)
+
+       call s:RunRustfmt(command, l:curw, l:tmpname)
+endfunction
index ca33776..b062e84 100644 (file)
@@ -1,7 +1,7 @@
 " Vim compiler file
-" Compiler:         BDF to PCF Conversion
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Compiler:             BDF to PCF Conversion
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("current_compiler")
   finish
diff --git a/runtime/compiler/cargo.vim b/runtime/compiler/cargo.vim
new file mode 100644 (file)
index 0000000..bd48666
--- /dev/null
@@ -0,0 +1,35 @@
+" Vim compiler file
+" Compiler:         Cargo Compiler
+" Maintainer:       Damien Radtke <damienradtke@gmail.com>
+" Latest Revision:  2014 Sep 24
+" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
+
+if exists('current_compiler')
+       finish
+endif
+runtime compiler/rustc.vim
+let current_compiler = "cargo"
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+if exists(':CompilerSet') != 2
+       command -nargs=* CompilerSet setlocal <args>
+endif
+
+if exists('g:cargo_makeprg_params')
+       execute 'CompilerSet makeprg=cargo\ '.escape(g:cargo_makeprg_params, ' \|"').'\ $*'
+else
+       CompilerSet makeprg=cargo\ $*
+endif
+
+" Ignore general cargo progress messages
+CompilerSet errorformat+=
+                       \%-G%\\s%#Downloading%.%#,
+                       \%-G%\\s%#Compiling%.%#,
+                       \%-G%\\s%#Finished%.%#,
+                       \%-G%\\s%#error:\ Could\ not\ compile\ %.%#,
+                       \%-G%\\s%#To\ learn\ more\\,%.%#
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
diff --git a/runtime/compiler/csslint.vim b/runtime/compiler/csslint.vim
new file mode 100644 (file)
index 0000000..14c4289
--- /dev/null
@@ -0,0 +1,16 @@
+" Vim compiler file
+" Compiler:    csslint for CSS
+" Maintainer: Daniel Moch <daniel@danielmoch.com>
+" Last Change: 2016 May 21
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "csslint"
+
+if exists(":CompilerSet") != 2         " older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+CompilerSet makeprg=csslint\ --format=compact
+CompilerSet errorformat=%-G,%-G%f:\ lint\ free!,%f:\ line\ %l\\,\ col\ %c\\,\ %trror\ -\ %m,%f:\ line\ %l\\,\ col\ %c\\,\ %tarning\ -\ %m,%f:\ line\ %l\\,\ col\ %c\\,\ %m
index 19ea2ed..1af568d 100644 (file)
@@ -1,7 +1,7 @@
 " Vim compiler file
-" Compiler:         GNU C Compiler
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2010-10-14
+" Compiler:             GNU C Compiler
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2010-10-14
 "                      added line suggested by Anton Lindqvist 2016 Mar 31
 
 if exists("current_compiler")
diff --git a/runtime/compiler/ghc.vim b/runtime/compiler/ghc.vim
new file mode 100644 (file)
index 0000000..c98ae30
--- /dev/null
@@ -0,0 +1,26 @@
+" Vim compiler file
+" Compiler:         GHC Haskell Compiler
+" Maintainer:       Daniel Campoverde <alx@sillybytes.net>
+" Latest Revision:  2016-11-29
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "ghc"
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+CompilerSet errorformat=
+    \%-G%.%#:\ build,
+    \%-G%.%#preprocessing\ library\ %.%#,
+    \%-G[%.%#]%.%#,
+    \%E%f:%l:%c:\ %m,
+    \%-G--%.%#
+
+if exists('g:compiler_ghc_ignore_unmatched_lines')
+  CompilerSet errorformat+=%-G%.%#
+endif
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
diff --git a/runtime/compiler/pylint.vim b/runtime/compiler/pylint.vim
new file mode 100644 (file)
index 0000000..93079ce
--- /dev/null
@@ -0,0 +1,16 @@
+" Vim compiler file
+" Compiler:    Pylint for Python
+" Maintainer: Daniel Moch <daniel@danielmoch.com>
+" Last Change: 2016 May 20
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "pylint"
+
+if exists(":CompilerSet") != 2         " older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+CompilerSet makeprg=pylint\ --output-format=text\ --msg-template=\"{path}:{line}:{column}:{C}:\ [{symbol}]\ {msg}\"\ --reports=no
+CompilerSet errorformat=%A%f:%l:%c:%t:\ %m,%A%f:%l:\ %m,%A%f:(%l):\ %m,%-Z%p^%.%#,%-G%.%#
index 15d2d79..392bea6 100644 (file)
@@ -1,7 +1,8 @@
 " Vim compiler file
-" Compiler:         reStructuredText Documentation Format
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Compiler:             sphinx >= 1.0.8, http://www.sphinx-doc.org
+" Description:          reStructuredText Documentation Format
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2017-03-31
 
 if exists("current_compiler")
   finish
@@ -11,12 +12,18 @@ let current_compiler = "rst"
 let s:cpo_save = &cpo
 set cpo&vim
 
-setlocal errorformat=
-      \%f:%l:\ (%tEBUG/0)\ %m,
-      \%f:%l:\ (%tNFO/1)\ %m,
-      \%f:%l:\ (%tARNING/2)\ %m,
-      \%f:%l:\ (%tRROR/3)\ %m,
-      \%f:%l:\ (%tEVERE/3)\ %m,
+if exists(":CompilerSet") != 2
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+CompilerSet errorformat=
+      \%f\\:%l:\ %tEBUG:\ %m,
+      \%f\\:%l:\ %tNFO:\ %m,
+      \%f\\:%l:\ %tARNING:\ %m,
+      \%f\\:%l:\ %tRROR:\ %m,
+      \%f\\:%l:\ %tEVERE:\ %m,
+      \%f\\:%s:\ %tARNING:\ %m,
+      \%f\\:%s:\ %tRROR:\ %m,
       \%D%*\\a[%*\\d]:\ Entering\ directory\ `%f',
       \%X%*\\a[%*\\d]:\ Leaving\ directory\ `%f',
       \%DMaking\ %*\\a\ in\ %f
diff --git a/runtime/compiler/rustc.vim b/runtime/compiler/rustc.vim
new file mode 100644 (file)
index 0000000..c27bdc9
--- /dev/null
@@ -0,0 +1,46 @@
+" Vim compiler file
+" Compiler:         Rust Compiler
+" Maintainer:       Chris Morgan <me@chrismorgan.info>
+" Latest Revision:  2013 Jul 12
+" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
+
+if exists("current_compiler")
+       finish
+endif
+let current_compiler = "rustc"
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+if exists(":CompilerSet") != 2
+       command -nargs=* CompilerSet setlocal <args>
+endif
+
+if exists("g:rustc_makeprg_no_percent") && g:rustc_makeprg_no_percent != 0
+       CompilerSet makeprg=rustc
+else
+       CompilerSet makeprg=rustc\ \%
+endif
+
+" Old errorformat (before nightly 2016/08/10)
+CompilerSet errorformat=
+                       \%f:%l:%c:\ %t%*[^:]:\ %m,
+                       \%f:%l:%c:\ %*\\d:%*\\d\ %t%*[^:]:\ %m,
+                       \%-G%f:%l\ %s,
+                       \%-G%*[\ ]^,
+                       \%-G%*[\ ]^%*[~],
+                       \%-G%*[\ ]...
+
+" New errorformat (after nightly 2016/08/10)
+CompilerSet errorformat+=
+                       \%-G,
+                       \%-Gerror:\ aborting\ %.%#,
+                       \%-Gerror:\ Could\ not\ compile\ %.%#,
+                       \%Eerror:\ %m,
+                       \%Eerror[E%n]:\ %m,
+                       \%Wwarning:\ %m,
+                       \%Inote:\ %m,
+                       \%C\ %#-->\ %f:%l:%c
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
index 43ff1e0..6fd43db 100644 (file)
@@ -1,7 +1,7 @@
 " The default vimrc file.
 "
 " Maintainer:  Bram Moolenaar <Bram@vim.org>
-" Last change: 2016 Sep 02
+" Last change: 2017 Apr 12
 "
 " This is loaded if no vimrc file was found.
 " Except when Vim is run with "-u NONE" or "-C".
@@ -21,7 +21,16 @@ endif
 
 " Use Vim settings, rather than Vi settings (much better!).
 " This must be first, because it changes other options as a side effect.
-set nocompatible
+" Avoid side effects when it was already reset.
+if &compatible
+  set nocompatible
+endif
+
+" When the +eval feature is missing, the set command above will be skipped.
+" Use a trick to reset compatible only when the +eval feature is missing.
+silent! while 0
+  set nocompatible
+silent! endwhile
 
 " Allow backspacing over everything in insert mode.
 set backspace=indent,eol,start
index 33a09be..1a0e841 100644 (file)
@@ -30,6 +30,7 @@ DOCS = \
        filetype.txt \
        fold.txt \
        ft_ada.txt \
+       ft_rust.txt \
        ft_sql.txt \
        gui.txt \
        gui_w32.txt \
@@ -165,6 +166,7 @@ HTMLS = \
        filetype.html \
        fold.html \
        ft_ada.html \
+       ft_rust.html \
        ft_sql.html \
        gui.html \
        gui_w32.html \
index b901f21..575e852 100644 (file)
@@ -1,4 +1,4 @@
-*autocmd.txt*   For Vim version 8.0.  Last change: 2016 Sep 27
+*autocmd.txt*   For Vim version 8.0.  Last change: 2017 Apr 07
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -33,7 +33,7 @@ files matching *.c.  You can also use autocommands to implement advanced
 features, such as editing compressed files (see |gzip-example|).  The usual
 place to put autocommands is in your .vimrc or .exrc file.
 
-                                               *E203* *E204* *E143* *E855*
+                                       *E203* *E204* *E143* *E855* *E937*
 WARNING: Using autocommands is very powerful, and may lead to unexpected side
 effects.  Be careful not to destroy your text.
 - It's a good idea to do some testing on an expendable copy of a file first.
@@ -621,7 +621,7 @@ FileChangedShell            When Vim notices that the modification time of
                                to tell Vim what to do next.
                                NOTE: When this autocommand is executed, the
                                current buffer "%" may be different from the
-                               buffer that was changed "<afile>".
+                               buffer that was changed, which is in "<afile>".
                                NOTE: The commands must not change the current
                                buffer, jump to another buffer or delete a
                                buffer.  *E246* *E811*
index 6dced7b..8cca763 100644 (file)
@@ -1,4 +1,4 @@
-*change.txt*    For Vim version 8.0.  Last change: 2016 Oct 02
+*change.txt*    For Vim version 8.0.  Last change: 2017 Feb 12
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -635,12 +635,14 @@ For other systems the tmpnam() library function is used.
                        For the {pattern} see |pattern|.
                        {string} can be a literal string, or something
                        special; see |sub-replace-special|.
+                                                       *E939*
                        When [range] and [count] are omitted, replace in the
-                       current line only.
-                       When [count] is given, replace in [count] lines,
-                       starting with the last line in [range].  When [range]
-                       is omitted start in the current line.
-                       Also see |cmdline-ranges|.
+                       current line only.  When [count] is given, replace in
+                       [count] lines, starting with the last line in [range].
+                       When [range] is omitted start in the current line.
+                       [count] must be a positive number.  Also see
+                       |cmdline-ranges|.
+
                        See |:s_flags| for [flags].
 
 :[range]s[ubstitute] [flags] [count]
@@ -684,6 +686,7 @@ g&                  Synonym for `:%s//~/&` (repeat last substitute with
                                                        *:s_flags*
 The flags that you can use for the substitute commands:
 
+                                                       *:&&*
 [&]    Must be the first one: Keep the flags from the previous substitute
        command.  Examples: >
                :&&
index bfd7246..3078d31 100644 (file)
@@ -1,4 +1,4 @@
-*channel.txt*      For Vim version 8.0.  Last change: 2016 Oct 27
+*channel.txt*      For Vim version 8.0.  Last change: 2016 Dec 02
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -155,7 +155,13 @@ Use |ch_status()| to see if the channel could be opened.
        func MyCloseHandler(channel)
 <              Vim will invoke callbacks that handle data before invoking
                close_cb, thus when this function is called no more data will
-               be received.
+               be passed to the callbacks.
+                                                       *channel-drop*
+"drop"         Specifies when to drop messages:
+                   "auto"      When there is no callback to handle a message.
+                               The "close_cb" is also considered for this.
+                   "never"     All messages will be kept.
+
                                                        *waittime*
 "waittime"     The time to wait for the connection to be made in
                milliseconds.  A negative number waits forever.
@@ -369,7 +375,7 @@ Leave out the fourth argument if no response is to be sent:
 ==============================================================================
 6. Using a RAW or NL channel                           *channel-raw*
 
-If mode is RAW or NL then a message can be send like this: >
+If mode is RAW or NL then a message can be sent like this: >
     let response = ch_evalraw(channel, {string})
 
 The {string} is sent as-is.  The response will be what can be read from the
@@ -418,7 +424,11 @@ This uses the channel timeout.  To read without a timeout, just get any
 message that is available: >
        let output = ch_read(channel, {'timeout': 0})
 When no message was available then the result is v:none for a JSON or JS mode
-channels, an empty string for a RAW or NL channel.
+channels, an empty string for a RAW or NL channel.  You can use |ch_canread()|
+to check if there is something to read.
+
+Note that when there is no callback message are dropped.  To avoid that add a
+close callback to the channel.
 
 To read all output from a RAW channel that is available: >
        let output = ch_readraw(channel)
@@ -534,7 +544,7 @@ You will want to do something more useful than "echomsg".
 
 To start another process without creating a channel: >
     let job = job_start(command,
-       \ {"in_io": "null", "out_io": "null", "err_io": "null"})
+       \ {"in_io": "null", "out_io": "null", "err_io": "null"})
 
 This starts {command} in the background, Vim does not wait for it to finish.
 
@@ -595,6 +605,10 @@ See |job_setoptions()| and |ch_setoptions()|.
                                                *job-close_cb*
 "close_cb": handler    Callback for when the channel is closed.  Same as
                        "close_cb" on |ch_open()|, see |close_cb|.
+                                               *job-drop*
+"drop"                 Specifies when to drop messages.  Same as "drop" on
+                       |ch_open()|, see |channel-drop|.  For "auto" the
+                       exit_cb is not considered.
                                                *job-exit_cb*
 "exit_cb": handler     Callback for when the job ends.  The arguments are the
                        job and the exit status.
@@ -629,7 +643,7 @@ See |job_setoptions()| and |ch_setoptions()|.
 "channel": {channel}   Use an existing channel instead of creating a new one.
                        The parts of the channel that get used for the new job
                        will be disconnected from what they were used before.
-                       If the channel was still use by another job this may
+                       If the channel was still used by another job this may
                        cause I/O errors.
                        Existing callbacks and other settings remain.
 
@@ -647,7 +661,7 @@ See |job_setoptions()| and |ch_setoptions()|.
 "out_io": "null"       disconnect stdout (goes to /dev/null)
 "out_io": "pipe"       stdout is connected to the channel (default)
 "out_io": "file"       stdout writes to a file
-"out_io": "buffer"     stdout appends to a buffer (see below)
+"out_io": "buffer"     stdout appends to a buffer (see below)
 "out_name": "/path/file" the name of the file or buffer to write to
 "out_buf": number      the number of the buffer to write to
 "out_modifiable": 0    when writing to a buffer, 'modifiable' will be off
@@ -660,7 +674,7 @@ See |job_setoptions()| and |ch_setoptions()|.
 "err_io": "null"       disconnect stderr  (goes to /dev/null)
 "err_io": "pipe"       stderr is connected to the channel (default)
 "err_io": "file"       stderr writes to a file
-"err_io": "buffer"     stderr appends to a buffer (see below)
+"err_io": "buffer"     stderr appends to a buffer (see below)
 "err_name": "/path/file" the name of the file or buffer to write to
 "err_buf": number      the number of the buffer to write to
 "err_modifiable": 0    when writing to a buffer, 'modifiable' will be off
index 8eb3a93..aab2a3e 100644 (file)
@@ -359,8 +359,11 @@ terminals)
                List entries 6 to 12 from the search history: >
                        :history / 6,12
 <
-               List the recent five entries from all histories: >
-                       :history all -5,
+               List the penultimate entry from all histories: >
+                       :history all -2
+<
+               List the most recent two entries from all histories: >
+                       :history all -2,
 
 :keepp[atterns] {command}                      *:keepp* *:keeppatterns*
                Execute {command}, without adding anything to the search
@@ -1057,10 +1060,10 @@ There are several ways to leave the command-line window:
                Insert and in Normal mode.
 CTRL-C         Continue in Command-line mode.  The command-line under the
                cursor is used as the command-line.  Works both in Insert and
-               in Normal mode.  ":close" also works.  There is no redraw,
-               thus the window will remain visible.
+               in Normal mode.  There is no redraw, thus the window will
+               remain visible.
 :quit          Discard the command line and go back to Normal mode.
-               ":exit", ":xit" and CTRL-\ CTRL-N also work.
+               ":close", ":exit", ":xit" and CTRL-\ CTRL-N also work.
 :qall          Quit Vim, unless there are changes in some buffer.
 :qall!         Quit Vim, discarding changes to any buffer.
 
index a2477f0..dc49c09 100644 (file)
@@ -1,4 +1,4 @@
-*develop.txt*   For Vim version 8.0.  Last change: 2016 Jan 31
+*develop.txt*   For Vim version 8.0.  Last change: 2017 Jan 05
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -177,7 +177,7 @@ The basic steps to make changes to the code:
 5. Make a patch with "git diff".  You can also create a pull request on
    github, but it's the diff that matters.
 6. Make a note about what changed, preferably mentioning the problem and the
-   solution.  Send an email to the vim-dev maillist with an explanation and
+   solution.  Send an email to the |vim-dev| maillist with an explanation and
    include the diff. Or create a pull request on github.
 
 
index 378874f..7361d42 100644 (file)
@@ -1,4 +1,4 @@
-*diff.txt*      For Vim version 8.0.  Last change: 2016 Aug 24
+*diff.txt*      For Vim version 8.0.  Last change: 2017 Feb 03
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -131,6 +131,8 @@ file for a moment and come back to the same file and be in diff mode again.
                related options only happens in a window that has 'diff' set,
                if the current window does not have 'diff' set then no options
                in it are changed.
+               Hidden buffers are also removed from the list of diff'ed
+               buffers.
 
 The `:diffoff` command resets the relevant options to the values they had when
 using `:diffsplit`, `:diffpatch` , `:diffthis`. or starting Vim in diff mode.
@@ -164,7 +166,8 @@ The alignment of text will go wrong when:
 
 All the buffers edited in a window where the 'diff' option is set will join in
 the diff.  This is also possible for hidden buffers.  They must have been
-edited in a window first for this to be possible.
+edited in a window first for this to be possible.  To get rid of the hidden
+buffers use `:diffoff!`.
 
                                        *:DiffOrig* *diff-original-file*
 Since 'diff' is a window-local option, it's possible to view the same buffer
index 1260194..25cbe9c 100644 (file)
@@ -1,4 +1,4 @@
-*editing.txt*   For Vim version 8.0.  Last change: 2016 Sep 27
+*editing.txt*   For Vim version 8.0.  Last change: 2017 Apr 10
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -276,7 +276,7 @@ If you want to keep the changed buffer without saving it, switch on the
 
                                                        *:vie* *:view*
 :vie[w][!] [++opt] [+cmd] file
-                       When used in Ex mode: Leave |Ex mode|, go back to
+                       When used in Ex mode: Leave |Ex-mode|, go back to
                        Normal mode.  Otherwise same as |:edit|, but set
                        'readonly' option for this buffer.  {not in Vi}
 
@@ -977,12 +977,12 @@ WRITING WITH MULTIPLE BUFFERS                             *buffer-write*
 
                                                        *:wa* *:wall*
 :wa[ll]                        Write all changed buffers.  Buffers without a file
-                       name or which are readonly are not written. {not in
-                       Vi}
+                       name cause an error message.  Buffers which are
+                       readonly are not written. {not in Vi}
 
 :wa[ll]!               Write all changed buffers, even the ones that are
                        readonly.  Buffers without a file name are not
-                       written. {not in Vi}
+                       written and cause an error message. {not in Vi}
 
 
 Vim will warn you if you try to overwrite a file that has been changed
@@ -1558,6 +1558,13 @@ If you want to automatically reload a file when it has been changed outside of
 Vim, set the 'autoread' option.  This doesn't work at the moment you write the
 file though, only when the file wasn't changed inside of Vim.
 
+If you do not want to be asked or automatically reload the file, you can use
+this: >
+       set buftype=nofile
+
+Or, when starting gvim from a shell: >
+       gvim file.log -c "set buftype=nofile"
+
 Note that if a FileChangedShell autocommand is defined you will not get a
 warning message or prompt.  The autocommand is expected to handle this.
 
index b34bf48..c8351eb 100644 (file)
@@ -1,4 +1,4 @@
-*eval.txt*     For Vim version 8.0.  Last change: 2016 Nov 04
+*eval.txt*     For Vim version 8.0.  Last change: 2017 Apr 22
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1329,7 +1329,8 @@ b:changedtick     The total number of changes to the current buffer.  It is
                    :   let my_changedtick = b:changedtick
                    :   call My_Update()
                    :endif
-<
+<              You cannot change or delete the b:changedtick variable.
+
                                                *window-variable* *w:var* *w:*
 A variable name that is preceded with "w:" is local to the current window.  It
 is deleted when the window is closed.
@@ -1788,8 +1789,11 @@ v:progpath       Contains the command with which Vim was invoked, including the
                |--remote-expr|.
                To get the full path use: >
                        echo exepath(v:progpath)
-<              NOTE: This does not work when the command is a relative path
-               and the current directory has changed.
+<              If the path is relative it will be expanded to the full path,
+               so that it still works after `:cd`. Thus starting "./vim"
+               results in "/home/user/path/to/vim/src/vim".
+               On MS-Windows the executable may be called "vim.exe", but the
+               ".exe" is not added to v:progpath.
                Read-only.
 
                                        *v:register* *register-variable*
@@ -1900,6 +1904,8 @@ v:termresponse    The escape sequence returned by the terminal for the |t_RV|
 
                                        *v:testing* *testing-variable*
 v:testing      Must be set before using `test_garbagecollect_now()`.
+               Also, when set certain error messages won't be shown for 2
+               seconds. (e.g. "'dictionary' option is empty") 
 
                                *v:this_session* *this_session-variable*
 v:this_session Full filename of the last loaded or saved session file.  See
@@ -1980,19 +1986,27 @@ argidx()                        Number  current index in the argument list
 arglistid([{winnr} [, {tabnr}]]) Number        argument list id
 argv({nr})                     String  {nr} entry of the argument list
 argv()                         List    the argument list
-assert_equal({exp}, {act} [, {msg}])     none  assert {exp} is equal to {act}
-assert_exception({error} [, {msg}])      none  assert {error} is in v:exception
-assert_fails({cmd} [, {error}])          none  assert {cmd} fails
-assert_false({actual} [, {msg}])         none  assert {actual} is false
+assert_equal({exp}, {act} [, {msg}])
+                               none    assert {exp} is equal to {act}
+assert_exception({error} [, {msg}])
+                               none    assert {error} is in v:exception
+assert_fails({cmd} [, {error}])        none    assert {cmd} fails
+assert_false({actual} [, {msg}])
+                               none    assert {actual} is false
 assert_inrange({lower}, {upper}, {actual} [, {msg}])
                                none    assert {actual} is inside the range
-assert_match({pat}, {text} [, {msg}])    none  assert {pat} matches {text}
-assert_notequal({exp}, {act} [, {msg}])  none  assert {exp} is not equal {act}
-assert_notmatch({pat}, {text} [, {msg}]) none  assert {pat} not matches {text}
-assert_true({actual} [, {msg}])          none  assert {actual} is true
+assert_match({pat}, {text} [, {msg}])
+                               none    assert {pat} matches {text}
+assert_notequal({exp}, {act} [, {msg}])
+                               none    assert {exp} is not equal {act}
+assert_notmatch({pat}, {text} [, {msg}])
+                               none    assert {pat} not matches {text}
+assert_report({msg})           none    report a test failure
+assert_true({actual} [, {msg}])        none    assert {actual} is true
 asin({expr})                   Float   arc sine of {expr}
 atan({expr})                   Float   arc tangent of {expr}
 atan2({expr1}, {expr2})                Float   arc tangent of {expr1} / {expr2}
+balloon_show({msg})            none    show {msg} inside the balloon
 browse({save}, {title}, {initdir}, {default})
                                String  put up a file requester
 browsedir({title}, {initdir})  String  put up a directory requester
@@ -2009,6 +2023,7 @@ byteidxcomp({expr}, {nr}) Number  byte index of {nr}'th char in {expr}
 call({func}, {arglist} [, {dict}])
                                any     call {func} with arguments {arglist}
 ceil({expr})                   Float   round {expr} up
+ch_canread({handle})           Number  check if there is something to read
 ch_close({handle})             none    close {handle}
 ch_close_in({handle})          none    close in part of {handle}
 ch_evalexpr({handle}, {expr} [, {options}])
@@ -2221,8 +2236,8 @@ matchstr({expr}, {pat}[, {start}[, {count}]])
                                String  {count}'th match of {pat} in {expr}
 matchstrpos({expr}, {pat}[, {start}[, {count}]])
                                List    {count}'th match of {pat} in {expr}
-max({list})                    Number  maximum value of items in {list}
-min({list})                    Number  minimum value of items in {list}
+max({expr})                    Number  maximum value of items in {expr}
+min({expr})                    Number  minimum value of items in {expr}
 mkdir({name} [, {path} [, {prot}]])
                                Number  create directory {name}
 mode([expr])                   String  current editing mode
@@ -2238,6 +2253,7 @@ printf({fmt}, {expr1}...) String  format text
 pumvisible()                   Number  whether popup menu is visible
 pyeval({expr})                 any     evaluate |Python| expression
 py3eval({expr})                        any     evaluate |python3| expression
+pyxeval({expr})                        any     evaluate |python_x| expression
 range({expr} [, {max} [, {stride}]])
                                List    items from {expr} to {max}
 readfile({fname} [, {binary} [, {max}]])
@@ -2245,14 +2261,17 @@ readfile({fname} [, {binary} [, {max}]])
 reltime([{start} [, {end}]])   List    get time value
 reltimefloat({time})           Float   turn the time value into a Float
 reltimestr({time})             String  turn time value into a String
-remote_expr({server}, {string} [, {idvar}])
+remote_expr({server}, {string} [, {idvar} [, {timeout}]])
                                String  send expression
 remote_foreground({server})    Number  bring Vim server to the foreground
 remote_peek({serverid} [, {retvar}])
                                Number  check for reply string
-remote_read({serverid})                String  read reply string
+remote_read({serverid} [, {timeout}])
+                               String  read reply string
 remote_send({server}, {string} [, {idvar}])
                                String  send key sequence
+remote_startserver({name})     none    become server {name}
+                               String  send key sequence
 remove({list}, {idx} [, {end}])        any     remove items {idx}-{end} from {list}
 remove({dict}, {key})          any     remove entry {key} from {dict}
 rename({from}, {to})           Number  rename (move) file from {from} to {to}
@@ -2345,7 +2364,7 @@ systemlist({expr} [, {input}])    List    output of shell command/filter {expr}
 tabpagebuflist([{arg}])                List    list of buffer numbers in tab page
 tabpagenr([{arg}])             Number  number of current or last tab page
 tabpagewinnr({tabarg}[, {arg}]) Number number of current window in tab page
-taglist({expr})                        List    list of tags matching {expr}
+taglist({expr}[, {filename}])  List    list of tags matching {expr}
 tagfiles()                     List    tags files used
 tan({expr})                    Float   tangent of {expr}
 tanh({expr})                   Float   hyperbolic tangent of {expr}
@@ -2353,14 +2372,15 @@ tempname()                      String  name for a temporary file
 test_alloc_fail({id}, {countdown}, {repeat})
                                none    make memory allocation fail
 test_autochdir()               none    enable 'autochdir' during startup
-test_disable_char_avail({expr}) none   test without typeahead
 test_garbagecollect_now()      none    free memory right now for testing
+test_ignore_error({expr})      none    ignore a specific error
 test_null_channel()            Channel null value for testing
 test_null_dict()               Dict    null value for testing
 test_null_job()                        Job     null value for testing
 test_null_list()               List    null value for testing
 test_null_partial()            Funcref null value for testing
 test_null_string()             String  null value for testing
+test_override({expr}, {val})    none   test with Vim internal overrides
 test_settime({expr})           none    set current time for testing
 timer_info([{id}])             List    information about timers
 timer_pause({id}, {pause})     none    pause or unpause a timer
@@ -2571,7 +2591,10 @@ assert_notmatch({pattern}, {actual} [, {msg}])
                The opposite of `assert_match()`: add an error message to
                |v:errors| when {pattern} matches {actual}.
 
-assert_true({actual} [, {msg}])                                        *assert_true()*
+assert_report({msg})                                   *assert_report()*
+               Report a test failure directly, using {msg}.
+
+assert_true({actual} [, {msg}])                                *assert_true()*
                When {actual} is not true an error message is added to
                |v:errors|, like with |assert_equal()|.
                A value is TRUE when it is a non-zero number.  When {actual}
@@ -2615,6 +2638,28 @@ atan2({expr1}, {expr2})                                  *atan2()*
 <                      2.356194
                {only available when compiled with the |+float| feature}
 
+balloon_show({msg})                                    *balloon_show()*
+               Show {msg} inside the balloon.
+               Example: >
+                       func GetBalloonContent()
+                          " initiate getting the content
+                          return ''
+                       endfunc
+                       set balloonexpr=GetBalloonContent()
+
+                       func BalloonCallback(result)
+                         call balloon_show(a:result)
+                       endfunc
+<
+               The intended use is that fetching the content of the balloon
+               is initiated from 'balloonexpr'.  It will invoke an
+               asynchronous method, in which a callback invokes
+               balloon_show().  The 'balloonexpr' itself can return an
+               empty string or a placeholder.
+
+               When showing a balloon is not possible nothing happens, no
+               error message.
+               {only available when compiled with the +balloon_eval feature}
 
                                                        *browse()*
 browse({save}, {title}, {initdir}, {default})
@@ -2810,186 +2855,28 @@ ceil({expr})                                                   *ceil()*
 <                      4.0
                {only available when compiled with the |+float| feature}
 
-changenr()                                             *changenr()*
-               Return the number of the most recent change.  This is the same
-               number as what is displayed with |:undolist| and can be used
-               with the |:undo| command.
-               When a change was made it is the number of that change.  After
-               redo it is the number of the redone change.  After undo it is
-               one less than the number of the undone change.
-
-char2nr({expr}[, {utf8}])                                      *char2nr()*
-               Return number value of the first char in {expr}.  Examples: >
-                       char2nr(" ")            returns 32
-                       char2nr("ABC")          returns 65
-<              When {utf8} is omitted or zero, the current 'encoding' is used.
-               Example for "utf-8": >
-                       char2nr("á")            returns 225
-                       char2nr("á"[0])         returns 195
-<              With {utf8} set to 1, always treat as utf-8 characters.
-               A combining character is a separate character.
-               |nr2char()| does the opposite.
-
-cindent({lnum})                                                *cindent()*
-               Get the amount of indent for line {lnum} according the C
-               indenting rules, as with 'cindent'.
-               The indent is counted in spaces, the value of 'tabstop' is
-               relevant.  {lnum} is used just like in |getline()|.
-               When {lnum} is invalid or Vim was not compiled the |+cindent|
-               feature, -1 is returned.
-               See |C-indenting|.
-
-clearmatches()                                         *clearmatches()*
-               Clears all matches previously defined by |matchadd()| and the
-               |:match| commands.
-
-                                                       *col()*
-col({expr})    The result is a Number, which is the byte index of the column
-               position given with {expr}.  The accepted positions are:
-                   .       the cursor position
-                   $       the end of the cursor line (the result is the
-                           number of bytes in the cursor line plus one)
-                   'x      position of mark x (if the mark is not set, 0 is
-                           returned)
-                   v       In Visual mode: the start of the Visual area (the
-                           cursor is the end).  When not in Visual mode
-                           returns the cursor position.  Differs from |'<| in
-                           that it's updated right away.
-               Additionally {expr} can be [lnum, col]: a |List| with the line
-               and column number. Most useful when the column is "$", to get
-               the last column of a specific line.  When "lnum" or "col" is
-               out of range then col() returns zero.
-               To get the line number use |line()|.  To get both use
-               |getpos()|.
-               For the screen column position use |virtcol()|.
-               Note that only marks in the current file can be used.
-               Examples: >
-                       col(".")                column of cursor
-                       col("$")                length of cursor line plus one
-                       col("'t")               column of mark t
-                       col("'" . markname)     column of mark markname
-<              The first column is 1.  0 is returned for an error.
-               For an uppercase mark the column may actually be in another
-               buffer.
-               For the cursor position, when 'virtualedit' is active, the
-               column is one higher if the cursor is after the end of the
-               line.  This can be used to obtain the column in Insert mode: >
-                       :imap <F2> <C-O>:let save_ve = &ve<CR>
-                               \<C-O>:set ve=all<CR>
-                               \<C-O>:echo col(".") . "\n" <Bar>
-                               \let &ve = save_ve<CR>
-<
-
-complete({startcol}, {matches})                        *complete()* *E785*
-               Set the matches for Insert mode completion.
-               Can only be used in Insert mode.  You need to use a mapping
-               with CTRL-R = (see |i_CTRL-R|).  It does not work after CTRL-O
-               or with an expression mapping.
-               {startcol} is the byte offset in the line where the completed
-               text start.  The text up to the cursor is the original text
-               that will be replaced by the matches.  Use col('.') for an
-               empty string.  "col('.') - 1" will replace one character by a
-               match.
-               {matches} must be a |List|.  Each |List| item is one match.
-               See |complete-items| for the kind of items that are possible.
-               Note that the after calling this function you need to avoid
-               inserting anything that would cause completion to stop.
-               The match can be selected with CTRL-N and CTRL-P as usual with
-               Insert mode completion.  The popup menu will appear if
-               specified, see |ins-completion-menu|.
-               Example: >
-       inoremap <F5> <C-R>=ListMonths()<CR>
-
-       func! ListMonths()
-         call complete(col('.'), ['January', 'February', 'March',
-               \ 'April', 'May', 'June', 'July', 'August', 'September',
-               \ 'October', 'November', 'December'])
-         return ''
-       endfunc
-<              This isn't very useful, but it shows how it works.  Note that
-               an empty string is returned to avoid a zero being inserted.
+ch_canread({handle})                                           *ch_canread()*
+               Return non-zero when there is something to read from {handle}.
+               {handle} can be a Channel or a Job that has a Channel.
 
-complete_add({expr})                           *complete_add()*
-               Add {expr} to the list of matches.  Only to be used by the
-               function specified with the 'completefunc' option.
-               Returns 0 for failure (empty string or out of memory),
-               1 when the match was added, 2 when the match was already in
-               the list.
-               See |complete-functions| for an explanation of {expr}.  It is
-               the same as one item in the list that 'omnifunc' would return.
+               This is useful to read from a channel at a convenient time,
+               e.g. from a timer.
 
-complete_check()                               *complete_check()*
-               Check for a key typed while looking for completion matches.
-               This is to be used when looking for matches takes some time.
-               Returns |TRUE| when searching for matches is to be aborted,
-               zero otherwise.
-               Only to be used by the function specified with the
-               'completefunc' option.
+               Note that messages are dropped when the channel does not have
+               a callback.  Add a close callback to avoid that.
 
-                                               *confirm()*
-confirm({msg} [, {choices} [, {default} [, {type}]]])
-               Confirm() offers the user a dialog, from which a choice can be
-               made.  It returns the number of the choice.  For the first
-               choice this is 1.
-               Note: confirm() is only supported when compiled with dialog
-               support, see |+dialog_con| and |+dialog_gui|.
-
-               {msg} is displayed in a |dialog| with {choices} as the
-               alternatives.  When {choices} is missing or empty, "&OK" is
-               used (and translated).
-               {msg} is a String, use '\n' to include a newline.  Only on
-               some systems the string is wrapped when it doesn't fit.
-
-               {choices} is a String, with the individual choices separated
-               by '\n', e.g. >
-                       confirm("Save changes?", "&Yes\n&No\n&Cancel")
-<              The letter after the '&' is the shortcut key for that choice.
-               Thus you can type 'c' to select "Cancel".  The shortcut does
-               not need to be the first letter: >
-                       confirm("file has been modified", "&Save\nSave &All")
-<              For the console, the first letter of each choice is used as
-               the default shortcut key.
-
-               The optional {default} argument is the number of the choice
-               that is made if the user hits <CR>.  Use 1 to make the first
-               choice the default one.  Use 0 to not set a default.  If
-               {default} is omitted, 1 is used.
-
-               The optional {type} argument gives the type of dialog.  This
-               is only used for the icon of the GTK, Mac, Motif and Win32
-               GUI.  It can be one of these values: "Error", "Question",
-               "Info", "Warning" or "Generic".  Only the first character is
-               relevant.  When {type} is omitted, "Generic" is used.
-
-               If the user aborts the dialog by pressing <Esc>, CTRL-C,
-               or another valid interrupt key, confirm() returns 0.
-
-               An example: >
-   :let choice = confirm("What do you want?", "&Apples\n&Oranges\n&Bananas", 2)
-   :if choice == 0
-   :   echo "make up your mind!"
-   :elseif choice == 3
-   :   echo "tasteful"
-   :else
-   :   echo "I prefer bananas myself."
-   :endif
-<              In a GUI dialog, buttons are used.  The layout of the buttons
-               depends on the 'v' flag in 'guioptions'.  If it is included,
-               the buttons are always put vertically.  Otherwise,  confirm()
-               tries to put the buttons in one horizontal line.  If they
-               don't fit, a vertical layout is used anyway.  For some systems
-               the horizontal layout is always used.
+               {only available when compiled with the |+channel| feature}
 
 ch_close({handle})                                             *ch_close()*
                Close {handle}.  See |channel-close|.
-               {handle} can be Channel or a Job that has a Channel.
+               {handle} can be Channel or a Job that has a Channel.
                A close callback is not invoked.
 
                {only available when compiled with the |+channel| feature}
 
 ch_close_in({handle})                                          *ch_close_in()*
                Close the "in" part of {handle}.  See |channel-close-in|.
-               {handle} can be Channel or a Job that has a Channel.
+               {handle} can be Channel or a Job that has a Channel.
                A close callback is not invoked.
 
                {only available when compiled with the |+channel| feature}
@@ -2998,7 +2885,7 @@ ch_evalexpr({handle}, {expr} [, {options}])                       *ch_evalexpr()*
                Send {expr} over {handle}.  The {expr} is encoded
                according to the type of channel.  The function cannot be used
                with a raw channel.  See |channel-use|.
-               {handle} can be Channel or a Job that has a Channel.
+               {handle} can be Channel or a Job that has a Channel.
                                                                *E917*
                {options} must be a Dictionary.  It must not have a "callback"
                entry.  It can have a "timeout" entry to specify the timeout
@@ -3012,7 +2899,7 @@ ch_evalexpr({handle}, {expr} [, {options}])                       *ch_evalexpr()*
 
 ch_evalraw({handle}, {string} [, {options}])           *ch_evalraw()*
                Send {string} over {handle}.
-               {handle} can be Channel or a Job that has a Channel.
+               {handle} can be Channel or a Job that has a Channel.
 
                Works like |ch_evalexpr()|, but does not encode the request or
                decode the response.  The caller is responsible for the
@@ -3025,7 +2912,7 @@ ch_evalraw({handle}, {string} [, {options}])              *ch_evalraw()*
 
 ch_getbufnr({handle}, {what})                           *ch_getbufnr()*
                Get the buffer number that {handle} is using for {what}.
-               {handle} can be Channel or a Job that has a Channel.
+               {handle} can be Channel or a Job that has a Channel.
                {what} can be "err" for stderr, "out" for stdout or empty for
                socket output.
                Returns -1 when there is no buffer.
@@ -3071,7 +2958,7 @@ ch_log({msg} [, {handle}])                                        *ch_log()*
                |ch_logfile()|.
                When {handle} is passed the channel number is used for the
                message.
-               {handle} can be Channel or a Job that has a Channel.  The
+               {handle} can be Channel or a Job that has a Channel.  The
                Channel must be open for the channel number to be used.
 
 ch_logfile({fname} [, {mode}])                                 *ch_logfile()*
@@ -3099,7 +2986,7 @@ ch_open({address} [, {options}])                          *ch_open()*
 
 ch_read({handle} [, {options}])                                        *ch_read()*
                Read from {handle} and return the received message.
-               {handle} can be Channel or a Job that has a Channel.
+               {handle} can be Channel or a Job that has a Channel.
                See |channel-more|.
                {only available when compiled with the |+channel| feature}
 
@@ -3113,7 +3000,7 @@ ch_sendexpr({handle}, {expr} [, {options}])                       *ch_sendexpr()*
                according to the type of channel.  The function cannot be used
                with a raw channel.
                See |channel-use|.                              *E912*
-               {handle} can be Channel or a Job that has a Channel.
+               {handle} can be Channel or a Job that has a Channel.
 
                {only available when compiled with the |+channel| feature}
 
@@ -3134,7 +3021,7 @@ ch_setoptions({handle}, {options})                        *ch_setoptions()*
                        "timeout"       default read timeout in msec
                        "mode"          mode for the whole channel
                See |ch_open()| for more explanation.
-               {handle} can be Channel or a Job that has a Channel.
+               {handle} can be Channel or a Job that has a Channel.
 
                Note that changing the mode may cause queued messages to be
                lost.
@@ -3148,7 +3035,7 @@ ch_status({handle} [, {options}])                         *ch_status()*
                        "open"          channel can be used
                        "buffered"      channel can be read, not written to
                        "closed"        channel can not be used
-               {handle} can be Channel or a Job that has a Channel.
+               {handle} can be Channel or a Job that has a Channel.
                "buffered" is used when the channel was closed but there is
                still data that can be obtained with |ch_read()|.
 
@@ -3157,6 +3044,176 @@ ch_status({handle} [, {options}])                               *ch_status()*
                "err".  For example, to get the error status: >
                        ch_status(job, {"part": "err"})
 <
+changenr()                                             *changenr()*
+               Return the number of the most recent change.  This is the same
+               number as what is displayed with |:undolist| and can be used
+               with the |:undo| command.
+               When a change was made it is the number of that change.  After
+               redo it is the number of the redone change.  After undo it is
+               one less than the number of the undone change.
+
+char2nr({expr}[, {utf8}])                                      *char2nr()*
+               Return number value of the first char in {expr}.  Examples: >
+                       char2nr(" ")            returns 32
+                       char2nr("ABC")          returns 65
+<              When {utf8} is omitted or zero, the current 'encoding' is used.
+               Example for "utf-8": >
+                       char2nr("á")            returns 225
+                       char2nr("á"[0])         returns 195
+<              With {utf8} set to 1, always treat as utf-8 characters.
+               A combining character is a separate character.
+               |nr2char()| does the opposite.
+
+cindent({lnum})                                                *cindent()*
+               Get the amount of indent for line {lnum} according the C
+               indenting rules, as with 'cindent'.
+               The indent is counted in spaces, the value of 'tabstop' is
+               relevant.  {lnum} is used just like in |getline()|.
+               When {lnum} is invalid or Vim was not compiled the |+cindent|
+               feature, -1 is returned.
+               See |C-indenting|.
+
+clearmatches()                                         *clearmatches()*
+               Clears all matches previously defined by |matchadd()| and the
+               |:match| commands.
+
+                                                       *col()*
+col({expr})    The result is a Number, which is the byte index of the column
+               position given with {expr}.  The accepted positions are:
+                   .       the cursor position
+                   $       the end of the cursor line (the result is the
+                           number of bytes in the cursor line plus one)
+                   'x      position of mark x (if the mark is not set, 0 is
+                           returned)
+                   v       In Visual mode: the start of the Visual area (the
+                           cursor is the end).  When not in Visual mode
+                           returns the cursor position.  Differs from |'<| in
+                           that it's updated right away.
+               Additionally {expr} can be [lnum, col]: a |List| with the line
+               and column number. Most useful when the column is "$", to get
+               the last column of a specific line.  When "lnum" or "col" is
+               out of range then col() returns zero.
+               To get the line number use |line()|.  To get both use
+               |getpos()|.
+               For the screen column position use |virtcol()|.
+               Note that only marks in the current file can be used.
+               Examples: >
+                       col(".")                column of cursor
+                       col("$")                length of cursor line plus one
+                       col("'t")               column of mark t
+                       col("'" . markname)     column of mark markname
+<              The first column is 1.  0 is returned for an error.
+               For an uppercase mark the column may actually be in another
+               buffer.
+               For the cursor position, when 'virtualedit' is active, the
+               column is one higher if the cursor is after the end of the
+               line.  This can be used to obtain the column in Insert mode: >
+                       :imap <F2> <C-O>:let save_ve = &ve<CR>
+                               \<C-O>:set ve=all<CR>
+                               \<C-O>:echo col(".") . "\n" <Bar>
+                               \let &ve = save_ve<CR>
+<
+
+complete({startcol}, {matches})                        *complete()* *E785*
+               Set the matches for Insert mode completion.
+               Can only be used in Insert mode.  You need to use a mapping
+               with CTRL-R = (see |i_CTRL-R|).  It does not work after CTRL-O
+               or with an expression mapping.
+               {startcol} is the byte offset in the line where the completed
+               text start.  The text up to the cursor is the original text
+               that will be replaced by the matches.  Use col('.') for an
+               empty string.  "col('.') - 1" will replace one character by a
+               match.
+               {matches} must be a |List|.  Each |List| item is one match.
+               See |complete-items| for the kind of items that are possible.
+               Note that the after calling this function you need to avoid
+               inserting anything that would cause completion to stop.
+               The match can be selected with CTRL-N and CTRL-P as usual with
+               Insert mode completion.  The popup menu will appear if
+               specified, see |ins-completion-menu|.
+               Example: >
+       inoremap <F5> <C-R>=ListMonths()<CR>
+
+       func! ListMonths()
+         call complete(col('.'), ['January', 'February', 'March',
+               \ 'April', 'May', 'June', 'July', 'August', 'September',
+               \ 'October', 'November', 'December'])
+         return ''
+       endfunc
+<              This isn't very useful, but it shows how it works.  Note that
+               an empty string is returned to avoid a zero being inserted.
+
+complete_add({expr})                           *complete_add()*
+               Add {expr} to the list of matches.  Only to be used by the
+               function specified with the 'completefunc' option.
+               Returns 0 for failure (empty string or out of memory),
+               1 when the match was added, 2 when the match was already in
+               the list.
+               See |complete-functions| for an explanation of {expr}.  It is
+               the same as one item in the list that 'omnifunc' would return.
+
+complete_check()                               *complete_check()*
+               Check for a key typed while looking for completion matches.
+               This is to be used when looking for matches takes some time.
+               Returns |TRUE| when searching for matches is to be aborted,
+               zero otherwise.
+               Only to be used by the function specified with the
+               'completefunc' option.
+
+                                               *confirm()*
+confirm({msg} [, {choices} [, {default} [, {type}]]])
+               Confirm() offers the user a dialog, from which a choice can be
+               made.  It returns the number of the choice.  For the first
+               choice this is 1.
+               Note: confirm() is only supported when compiled with dialog
+               support, see |+dialog_con| and |+dialog_gui|.
+
+               {msg} is displayed in a |dialog| with {choices} as the
+               alternatives.  When {choices} is missing or empty, "&OK" is
+               used (and translated).
+               {msg} is a String, use '\n' to include a newline.  Only on
+               some systems the string is wrapped when it doesn't fit.
+
+               {choices} is a String, with the individual choices separated
+               by '\n', e.g. >
+                       confirm("Save changes?", "&Yes\n&No\n&Cancel")
+<              The letter after the '&' is the shortcut key for that choice.
+               Thus you can type 'c' to select "Cancel".  The shortcut does
+               not need to be the first letter: >
+                       confirm("file has been modified", "&Save\nSave &All")
+<              For the console, the first letter of each choice is used as
+               the default shortcut key.
+
+               The optional {default} argument is the number of the choice
+               that is made if the user hits <CR>.  Use 1 to make the first
+               choice the default one.  Use 0 to not set a default.  If
+               {default} is omitted, 1 is used.
+
+               The optional {type} argument gives the type of dialog.  This
+               is only used for the icon of the GTK, Mac, Motif and Win32
+               GUI.  It can be one of these values: "Error", "Question",
+               "Info", "Warning" or "Generic".  Only the first character is
+               relevant.  When {type} is omitted, "Generic" is used.
+
+               If the user aborts the dialog by pressing <Esc>, CTRL-C,
+               or another valid interrupt key, confirm() returns 0.
+
+               An example: >
+   :let choice = confirm("What do you want?", "&Apples\n&Oranges\n&Bananas", 2)
+   :if choice == 0
+   :   echo "make up your mind!"
+   :elseif choice == 3
+   :   echo "tasteful"
+   :else
+   :   echo "I prefer bananas myself."
+   :endif
+<              In a GUI dialog, buttons are used.  The layout of the buttons
+               depends on the 'v' flag in 'guioptions'.  If it is included,
+               the buttons are always put vertically.  Otherwise,  confirm()
+               tries to put the buttons in one horizontal line.  If they
+               don't fit, a vertical layout is used anyway.  For some systems
+               the horizontal layout is always used.
+
                                                        *copy()*
 copy({expr})   Make a copy of {expr}.  For Numbers and Strings this isn't
                different from using {expr} directly.
@@ -3413,7 +3470,7 @@ execute({command} [, {silent}])                                   *execute()*
                        ""              no `:silent` used
                        "silent"        `:silent` used
                        "silent!"       `:silent!` used
-               The default is 'silent'.  Note that with "silent!", unlike
+               The default is "silent".  Note that with "silent!", unlike
                `:redir`, error messages are dropped.  When using an external
                command the screen may be messed up, use `system()` instead.
                                                        *E930*
@@ -3879,11 +3936,14 @@ foldtext()      Returns a String, to be displayed for a closed fold.  This is
                |v:foldstart|, |v:foldend| and |v:folddashes| variables.
                The returned string looks like this: >
                        +-- 45 lines: abcdef
-<              The number of dashes depends on the foldlevel.  The "45" is
-               the number of lines in the fold.  "abcdef" is the text in the
-               first non-blank line of the fold.  Leading white space, "//"
-               or "/*" and the text from the 'foldmarker' and 'commentstring'
-               options is removed.
+<              The number of leading dashes depends on the foldlevel.  The
+               "45" is the number of lines in the fold.  "abcdef" is the text
+               in the first non-blank line of the fold.  Leading white space,
+               "//" or "/*" and the text from the 'foldmarker' and
+               'commentstring' options is removed.
+               When used to draw the actual foldtext, the rest of the line
+               will be filled with the fold char from the 'fillchars'
+               setting.
                {not available when compiled without the |+folding| feature}
 
 foldtextresult({lnum})                                 *foldtextresult()*
@@ -4015,10 +4075,10 @@ get({dict}, {key} [, {default}])
 get({func}, {what})
                Get an item with from Funcref {func}.  Possible values for
                {what} are:
-                       'name'  The function name
-                       'func'  The function
-                       'dict'  The dictionary
-                       'args'  The list with arguments
+                       "name"  The function name
+                       "func"  The function
+                       "dict"  The dictionary
+                       "args"  The list with arguments
 
                                                        *getbufinfo()*
 getbufinfo([{expr}])
@@ -4158,6 +4218,10 @@ getchar([expr])                                          *getchar()*
                          exe "normal " . v:mouse_col . "|"
                        endif
 <
+               When using bracketed paste only the first character is
+               returned, the rest of the pasted text is dropped.
+               |xterm-bracketed-paste|.
+
                There is no prompt, you will somehow have to make clear to the
                user that a character has to be typed.
                There is no mapping for the character.
@@ -4315,12 +4379,14 @@ getcurpos()     Get the position of the cursor.  This is like getpos('.'), but
                includes an extra item in the list:
                    [bufnum, lnum, col, off, curswant] ~
                The "curswant" number is the preferred column when moving the
-               cursor vertically.
+               cursor vertically.  Also see |getpos()|.
+
                This can be used to save and restore the cursor position: >
                        let save_cursor = getcurpos()
                        MoveTheCursorAround
                        call setpos('.', save_cursor)
-<
+<              Note that this only works within the window.  See
+               |winrestview()| for restoring more state.
                                                        *getcwd()*
 getcwd([{winnr} [, {tabnr}]])
                The result is a String, which is the name of the current
@@ -4353,8 +4419,8 @@ getfontname([{name}])                                     *getfontname()*
                Only works when the GUI is running, thus not in your vimrc or
                gvimrc file.  Use the |GUIEnter| autocommand to use this
                function just after the GUI has started.
-               Note that the GTK 2 GUI accepts any font name, thus checking
-               for a valid name does not work.
+               Note that the GTK GUI accepts any font name, thus checking for
+               a valid name does not work.
 
 getfperm({fname})                                      *getfperm()*
                The result is a String, which is the read, write, and execute
@@ -4618,13 +4684,16 @@ gettabwinvar({tabnr}, {winnr}, {varname} [, {def}])             *gettabwinvar()*
 <
                                                        *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
-               -1 if the information is not available.
+               the left hand side of the GUI Vim window. Also works for an
+               xterm.
+               The result will be -1 if the information is not available.
+               The value can be used with `:winpos`.
 
                                                        *getwinposy()*
 getwinposy()   The result is a Number, which is the Y coordinate in pixels of
-               the top of the GUI Vim window.  The result will be -1 if the
-               information is not available.
+               the top of the GUI Vim window.  Also works for an xterm.
+               The result will be -1 if the information is not available.
+               The value can be used with `:winpos`.
 
 getwininfo([{winid}])                                  *getwininfo()*
                Returns information about windows as a List with Dictionaries.
@@ -5216,6 +5285,7 @@ join({list} [, {sep}])                                    *join()*
 js_decode({string})                                    *js_decode()*
                This is similar to |json_decode()| with these differences:
                - Object key names do not have to be in quotes.
+               - Strings can be in single quotes.
                - Empty items in an array (between two commas) are allowed and
                  result in v:none items.
 
@@ -5239,12 +5309,29 @@ json_decode({string})                                   *json_decode()*
                in Vim values.  See |json_encode()| for the relation between
                JSON and Vim values.
                The decoding is permissive:
-               - A trailing comma in an array and object is ignored.
+               - A trailing comma in an array and object is ignored, e.g.
+                 "[1, 2, ]" is the same as "[1, 2]".
                - More floating point numbers are recognized, e.g. "1." for
-                 "1.0".
-               The result must be a valid Vim type:
-               - An empty object member name is not allowed.
-               - Duplicate object member names are not allowed.
+                 "1.0", or "001.2" for "1.2". Special floating point values
+                 "Infinity" and "NaN" (capitalization ignored) are accepted.
+               - Leading zeroes in integer numbers are ignored, e.g. "012"
+                 for "12" or "-012" for "-12".
+               - Capitalization is ignored in literal names null, true or
+                 false, e.g. "NULL" for "null", "True" for "true".
+               - Control characters U+0000 through U+001F which are not
+                 escaped in strings are accepted, e.g. "       " (tab
+                 character in string) for "\t".
+               - Backslash in an invalid 2-character sequence escape is
+                 ignored, e.g. "\a" is decoded as "a".
+               - A correct surrogate pair in JSON strings should normally be
+                 a 12 character sequence such as "\uD834\uDD1E", but
+                 json_decode() silently accepts truncated surrogate pairs
+                 such as "\uD834" or "\uD834\u"
+                                                               *E938*
+               A duplicate key in an object, valid in rfc7159, is not
+               accepted by json_decode() as the result must be a valid Vim
+               type, e.g. this fails: {"a":"b", "a":"c"}
+
 
 json_encode({expr})                                    *json_encode()*
                Encode {expr} as JSON and return this as a string.
@@ -5347,8 +5434,10 @@ line({expr})     The result is a Number, which is the line number of the file
                    $       the last line in the current buffer
                    'x      position of mark x (if the mark is not set, 0 is
                            returned)
-                   w0      first line visible in current window
-                   w$      last line visible in current window
+                   w0      first line visible in current window (one if the
+                           display isn't updated, e.g. in silent Ex mode)
+                   w$      last line visible in current window (this is one
+                           less than "w0" if no lines are visible)
                    v       In Visual mode: the start of the Visual area (the
                            cursor is the end).  When not in Visual mode
                            returns the cursor position.  Differs from |'<| in
@@ -5781,16 +5870,20 @@ matchstrpos({expr}, {pat}[, {start}[, {count}]])                *matchstrpos()*
                The type isn't changed, it's not necessarily a String.
 
                                                        *max()*
-max({list})    Return the maximum value of all items in {list}.
-               If {list} is not a list or one of the items in {list} cannot
-               be used as a Number this results in an error.
-               An empty |List| results in zero.
+max({expr})    Return the maximum value of all items in {expr}.
+               {expr} can be a list or a dictionary.  For a dictionary,
+               it returns the maximum of all values in the dictionary.
+               If {expr} is neither a list nor a dictionary, or one of the
+               items in {expr} cannot be used as a Number this results in
+                an error.  An empty |List| or |Dictionary| results in zero.
 
                                                        *min()*
-min({list})    Return the minimum value of all items in {list}.
-               If {list} is not a list or one of the items in {list} cannot
-               be used as a Number this results in an error.
-               An empty |List| results in zero.
+min({expr})    Return the minimum value of all items in {expr}.
+               {expr} can be a list or a dictionary.  For a dictionary,
+               it returns the minimum of all values in the dictionary.
+               If {expr} is neither a list nor a dictionary, or one of the
+               items in {expr} cannot be used as a Number this results in
+                an error.  An empty |List| or |Dictionary| results in zero.
 
                                                        *mkdir()* *E739*
 mkdir({name} [, {path} [, {prot}]])
@@ -5824,9 +5917,13 @@ mode([expr])     Return a string that indicates the current mode.
                        S       Select by line
                        CTRL-S  Select blockwise
                        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|
-                       c       Command-line
+                       Rx      Replace mode |i_CTRL-X| completion
+                       c       Command-line editing
                        cv      Vim Ex mode |gQ|
                        ce      Normal Ex mode |Q|
                        r       Hit-enter prompt
@@ -5950,7 +6047,7 @@ printf({fmt}, {expr1} ...)                                *printf()*
                  %e    floating point number as 1.23e3, inf, -inf or nan
                  %E    floating point number as 1.23E3, INF, -INF or NAN
                  %g    floating point number, as %f or %e depending on value
-                 %G    floating point number, as %f or %E depending on value
+                 %G    floating point number, as %F or %E depending on value
                  %%    the % character itself
 
                Conversion specifications start with '%' and end with the
@@ -6148,6 +6245,14 @@ pyeval({expr})                                           *pyeval()*
                non-string keys result in error.
                {only available when compiled with the |+python| feature}
 
+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()|
+               {only available when compiled with the |+python| or the
+               |+python3| feature}
+
                                                        *E726* *E727*
 range({expr} [, {max} [, {stride}]])                           *range()*
                Returns a |List| with Numbers:
@@ -6239,15 +6344,17 @@ reltimestr({time})                              *reltimestr()*
                {only available when compiled with the |+reltime| feature}
 
                                                        *remote_expr()* *E449*
-remote_expr({server}, {string} [, {idvar}])
+remote_expr({server}, {string} [, {idvar} [, {timeout}]])
                Send the {string} to {server}.  The string is sent as an
                expression and the result is returned after evaluation.
                The result must be a String or a |List|.  A |List| is turned
                into a String by joining the items with a line break in
                between (not at the end), like with join(expr, "\n").
-               If {idvar} is present, it is taken as the name of a
-               variable and a {serverid} for later use with
+               If {idvar} is present and not empty, it is taken as the name
+               of a variable and a {serverid} for later use with
                remote_read() is stored there.
+               If {timeout} is given the read times out after this many
+               seconds.  Otherwise a timeout of 600 seconds is used.
                See also |clientserver| |RemoteReply|.
                This function is not available in the |sandbox|.
                {only available when compiled with the |+clientserver| feature}
@@ -6286,9 +6393,10 @@ remote_peek({serverid} [, {retvar}])             *remote_peek()*
                        :let repl = ""
                        :echo "PEEK: ".remote_peek(id, "repl").": ".repl
 
-remote_read({serverid})                                *remote_read()*
+remote_read({serverid}, [{timeout}])                   *remote_read()*
                Return the oldest available reply from {serverid} and consume
-               it.  It blocks until a reply is available.
+               it.  Unless a {timeout} in seconds is given, it blocks until a
+               reply is available.
                See also |clientserver|.
                This function is not available in the |sandbox|.
                {only available when compiled with the |+clientserver| feature}
@@ -6306,6 +6414,7 @@ remote_send({server}, {string} [, {idvar}])
                See also |clientserver| |RemoteReply|.
                This function is not available in the |sandbox|.
                {only available when compiled with the |+clientserver| feature}
+
                Note: Any errors will be reported in the server and may mess
                up the display.
                Examples: >
@@ -6317,6 +6426,12 @@ remote_send({server}, {string} [, {idvar}])
                :echo remote_send("gvim", ":sleep 10 | echo ".
                 \ 'server2client(expand("<client>"), "HELLO")<CR>')
 <
+                                       *remote_startserver()* *E941* *E942*
+remote_startserver({name})
+               Become the server {name}.  This fails if already running as a
+               server, when |v:servername| is not empty.
+               {only available when compiled with the |+clientserver| feature}
+
 remove({list}, {idx} [, {end}])                                *remove()*
                Without {end}: Remove the item at {idx} from |List| {list} and
                return the item.
@@ -6774,10 +6889,12 @@ setpos({expr}, {list})
                    [bufnum, lnum, col, off, curswant]
 
                "bufnum" is the buffer number.  Zero can be used for the
-               current buffer.  Setting the cursor is only possible for
-               the current buffer.  To set a mark in another buffer you can
-               use the |bufnr()| function to turn a file name into a buffer
-               number.
+               current buffer.  When setting an uppercase mark "bufnum" is
+               used for the mark position.  For other marks it specifies the
+               buffer to set the mark in.  You can use the |bufnr()| function
+               to turn a file name into a buffer number.
+               For setting the cursor and the ' mark "bufnum" is ignored,
+               since these are associated with a window, not a buffer.
                Does not change the jumplist.
 
                "lnum" and "col" are the position in the buffer.  The first
@@ -6828,6 +6945,7 @@ setqflist({list} [, {action}[, {what}]])          *setqflist()*
                    nr          error number
                    text        description of the error
                    type        single-character error type, 'E', 'W', etc.
+                   valid       recognized error message
 
                The "col", "vcol", "nr", "type" and "text" entries are
                optional.  Either "lnum" or "pattern" entry can be used to
@@ -6837,21 +6955,26 @@ setqflist({list} [, {action}[, {what}]])                *setqflist()*
                item will not be handled as an error line.
                If both "pattern" and "lnum" are present then "pattern" will
                be used.
+               If the "valid" entry is not supplied, then the valid flag is
+               set when "bufnr" is a valid buffer or "filename" exists.
                If you supply an empty {list}, the quickfix list will be
                cleared.
                Note that the list is not exactly the same as what
                |getqflist()| returns.
 
-                                                       *E927*
-               If {action} is set to 'a', then the items from {list} are
-               added to the existing quickfix list. If there is no existing
-               list, then a new list is created.
+               {action} values:                                *E927*
+               'a'     The items from {list} are added to the existing
+                       quickfix list. If there is no existing list, then a
+                       new list is created.
                
-               If {action} is set to 'r', then the items from the current
-               quickfix list are replaced with the items from {list}.  This
-               can also be used to clear the list: >
-                       :call setqflist([], 'r')
+               'r'     The items from the current quickfix list are replaced
+                       with the items from {list}.  This can also be used to
+                       clear the list: >
+                               :call setqflist([], 'r')
 <      
+               'f'     All the quickfix lists in the quickfix stack are
+                       freed.
+
                If {action} is not present or is set to ' ', then a new list
                is created.
 
@@ -6873,7 +6996,7 @@ setqflist({list} [, {action}[, {what}]])          *setqflist()*
 
                This function can be used to create a quickfix list
                independent of the 'errorformat' setting.  Use a command like
-               ":cc 1" to jump to the first position.
+               `:cc 1` to jump to the first position.
 
 
                                                        *setreg()*
@@ -7235,7 +7358,7 @@ strcharpart({src}, {start}[, {len}])                      *strcharpart()*
                Like |strpart()| but using character index and length instead
                of byte index and length.
                When a character index is used where a character does not
-               exist it is assumed to be one byte.  For example: >
+               exist it is assumed to be one character.  For example: >
                        strcharpart('abc', -1, 2)
 <              results in 'a'.
 
@@ -7548,7 +7671,11 @@ system({expr} [, {input}])                               *system()* *E677*
                If {input} is given and is a |List| it is written to the file
                in a way |writefile()| does with {binary} set to "b" (i.e.
                with a newline between each list item with newlines inside
-               list items converted to NULs).  
+               list items converted to NULs).
+               When {input} is given and is a number that is a valid id for
+               an existing buffer then the content of the buffer is written
+               to the file line by line, each line terminated by a NL and
+               NULs characters where the text has a NL.
 
                Pipes are not used, the 'shelltemp' option is not used.
 
@@ -7598,7 +7725,8 @@ systemlist({expr} [, {input}])                            *systemlist()*
                Same as |system()|, but returns a |List| with lines (parts of 
                output separated by NL) with NULs transformed into NLs. Output 
                is the same as |readfile()| will output with {binary} argument 
-               set to "b".
+               set to "b".  Note that on MS-Windows you may get trailing CR
+               characters.
 
                Returns an empty string on error.
 
@@ -7643,8 +7771,13 @@ tagfiles()       Returns a |List| with the file names used to search for tags
                for the current buffer.  This is the 'tags' option expanded.
 
 
-taglist({expr})                                                        *taglist()*
+taglist({expr}[, {filename}])                          *taglist()*
                Returns a list of tags matching the regular expression {expr}.
+
+               If {filename} is passed it is used to prioritize the results
+               in the same way that |:tselect| does. See |tag-priority|.
+               {filename} should be the full path of the file.
+
                Each list item is a dictionary with at least the following
                entries:
                        name            Name of the tag.
@@ -7667,7 +7800,7 @@ taglist({expr})                                                   *taglist()*
                may appear, they give the name of the entity the tag is
                contained in.
 
-               The ex-command 'cmd' can be either an ex search pattern, a
+               The ex-command "cmd" can be either an ex search pattern, a
                line number or a line number followed by a byte number.
 
                If there are no matching tags, then an empty list is returned.
@@ -7726,20 +7859,21 @@ test_autochdir()                                        *test_autochdir()*
                Set a flag to enable the effect of 'autochdir' before Vim
                startup has finished.
 
-                                               *test_disable_char_avail()*
-test_disable_char_avail({expr})
-               When {expr} is 1 the internal char_avail() function will
-               return |FALSE|.  When {expr} is 0 the char_avail() function will
-               function normally.
-               Only use this for a test where typeahead causes the test not
-               to work.  E.g., to trigger the CursorMovedI autocommand event.
-
 test_garbagecollect_now()                       *test_garbagecollect_now()*
                Like garbagecollect(), but executed right away.  This must
                only be called directly to avoid any structure to exist
                internally, and |v:testing| must have been set before calling
                any function.
 
+test_ignore_error({expr})                       *test_ignore_error()*
+               Ignore any error containing {expr}.  A normal message is given
+               instead.
+               This is only meant to be used in tests, where catching the
+               error with try/catch cannot be used (because it skips over
+               following code).
+               {expr} is used literally, not as a pattern.
+               There is currently no way to revert this.
+
 test_null_channel()                                    *test_null_channel()*
                Return a Channel that is null. Only useful for testing.
                {only available when compiled with the +channel feature}
@@ -7760,10 +7894,24 @@ test_null_partial()                                     *test_null_partial()*
 test_null_string()                                     *test_null_string()*
                Return a String that is null. Only useful for testing.
 
+test_override({name}, {val})                           *test_override()*
+               Overrides certain parts of Vims internal processing to be able
+               to run tests. Only to be used for testing Vim!
+               The override is enabled when {val} is non-zero and removed
+               when {val} is zero.
+               Current supported values for name are: 
+
+               name         effect when {val} is non-zero ~
+               redraw       disable the redrawing() function
+               char_avail   disable the char_avail() function
+               ALL          clear all overrides ({val} is not used)
+
 test_settime({expr})                                   *test_settime()*
                Set the time Vim uses internally.  Currently only used for
                timestamps in the history, as they are used in viminfo, and
                for undo.
+               Using a value of 1 makes Vim not sleep after a warning or
+               error message.
                {expr} must evaluate to a number.  When the value is zero the
                normal behavior is restored.
 
@@ -8115,7 +8263,7 @@ winnr([{arg}])    The result is a Number, which is the number of the current
                is returned.
                The number can be used with |CTRL-W_w| and ":wincmd w"
                |:wincmd|.
-               Also see |tabpagewinnr()|.
+               Also see |tabpagewinnr()| and |win_getid()|.
 
                                                        *winrestcmd()*
 winrestcmd()   Returns a sequence of |:resize| commands that should restore
@@ -8348,7 +8496,7 @@ listcmds          Compiled with commands for the buffer list |:files|
                        and the argument list |arglist|.
 localmap               Compiled with local mappings and abbr. |:map-local|
 lua                    Compiled with Lua interface |Lua|.
-mac                    Any Macintosh version of Vim.
+mac                    Any Macintosh version of Vim, but not all OS X.
 macunix                        Compiled for OS X, with darwin
 osx                    Compiled for OS X, with or without darwin
 menu                   Compiled with support for |:menu|.
@@ -8382,6 +8530,7 @@ printer                   Compiled with |:hardcopy| support.
 profile                        Compiled with |:profile| support.
 python                 Compiled with Python 2.x interface. |has-python|
 python3                        Compiled with Python 3.x interface. |has-python|
+pythonx                        Compiled with |python_x| interface. |has-pythonx|
 qnx                    QNX version of Vim.
 quickfix               Compiled with |quickfix| support.
 reltime                        Compiled with |reltime()| support.
@@ -8416,7 +8565,10 @@ tgetent                  Compiled with tgetent support, able to use a termcap
 timers                 Compiled with |timer_start()| support.
 title                  Compiled with window title support |'title'|.
 toolbar                        Compiled with support for |gui-toolbar|.
+ttyin                  input is a terminal (tty)
+ttyout                 output is a terminal (tty)
 unix                   Unix version of Vim.
+unnamedplus            Compiled with support for "unnamedplus" in 'clipboard'
 user_commands          User-defined commands.
 vertsplit              Compiled with vertically split windows |:vsplit|.
 vim_starting           True while initial source'ing takes place. |startup|
@@ -8920,6 +9072,11 @@ This does NOT work: >
                        value and the global value are changed.
                        Example: >
                                :let &path = &path . ',/usr/local/include'
+<                      This also works for terminal codes in the form t_xx.
+                       But only for alphanumerical names.  Example: >
+                               :let &t_k1 = "\<Esc>[234;"
+<                      When the code does not exist yet it will be created as
+                       a terminal key code, there is no error.
 
 :let &{option-name} .= {expr1}
                        For a string option: Append {expr1} to the value.
@@ -9027,9 +9184,12 @@ This does NOT work: >
                                :lockvar v
                                :let v = 'asdf'         " fails!
                                :unlet v
-<                                                      *E741*
+<                                                      *E741* *E940*
                        If you try to change a locked variable you get an
-                       error message: "E741: Value is locked: {name}"
+                       error message: "E741: Value is locked: {name}".
+                       If you try to lock or unlock a built-in variable you
+                       get an error message: "E940: Cannot lock or unlock
+                       variable {name}".
 
                        [depth] is relevant when locking a |List| or
                        |Dictionary|.  It specifies how deep the locking goes:
@@ -10513,6 +10673,22 @@ missing: >
        :  echo "You will _never_ see this message"
        :endif
 
+To execute a command only when the |+eval| feature is disabled requires a trick,
+as this example shows: >
+       if 1
+         nnoremap : :"
+       endif
+       normal :set history=111<CR>
+       if 1
+         nunmap :
+       endif
+
+The "<CR>" here is a real CR character, type CTRL-V Enter to get it.
+
+When the |+eval| feature is available the ":" is remapped to add a double
+quote, which has the effect of commenting-out the command.  without the
+|+eval| feature the nnoremap command is skipped and the command is executed.
+
 ==============================================================================
 11. The sandbox                                        *eval-sandbox* *sandbox* *E48*
 
index 4c9b2b0..795b259 100644 (file)
@@ -1,4 +1,4 @@
-*filetype.txt*  For Vim version 8.0.  Last change: 2016 Sep 09
+*filetype.txt*  For Vim version 8.0.  Last change: 2017 Mar 28
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -353,12 +353,12 @@ define yourself.  There are a few ways to avoid this:
    You need to define your own mapping before the plugin is loaded (before
    editing a file of that type).  The plugin will then skip installing the
    default mapping.
-
+                                               *no_mail_maps*
 3. Disable defining mappings for a specific filetype by setting a variable,
    which contains the name of the filetype.  For the "mail" filetype this
    would be: >
        :let no_mail_maps = 1
-
+<                                              *no_plugin_maps*
 4. Disable defining mappings for all filetypes by setting a variable: >
        :let no_plugin_maps = 1
 <
@@ -573,6 +573,8 @@ Man {number} {name}
 
 Global mapping:
 <Leader>K      Displays the manual page for the word under the cursor.
+<Plug>ManPreGetPage  idem, allows for using a mapping: >
+                       nmap <F1> <Plug>ManPreGetPage<CR>
 
 Local mappings:
 CTRL-]         Jump to the manual page for the word under the cursor.
@@ -661,6 +663,12 @@ Since the text for this plugin is rather long it has been put in a separate
 file: |pi_spec.txt|.
 
 
+RUST                                                   *ft-rust*
+
+Since the text for this plugin is rather long it has been put in a separate
+file: |ft_rust.txt|.
+
+
 SQL                                                    *ft-sql*
 
 Since the text for this plugin is rather long it has been put in a separate
index 6a99488..bdf4a48 100644 (file)
@@ -1,4 +1,4 @@
-*fold.txt*      For Vim version 8.0.  Last change: 2016 Jan 02
+*fold.txt*      For Vim version 8.0.  Last change: 2017 Mar 18
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -64,7 +64,7 @@ whichever is lower.  These are empty or white lines and lines starting
 with a character in 'foldignore'.  White space is skipped before checking for
 characters in 'foldignore'.  For C use "#" to ignore preprocessor lines.
 
-When you want to ignore lines in another way, use the 'expr' method.  The
+When you want to ignore lines in another way, use the "expr" method.  The
 |indent()| function can be used in 'foldexpr' to get the indent of a line.
 
 
@@ -79,7 +79,7 @@ This will call a function to compute the fold level: >
        :set foldexpr=MyFoldLevel(v:lnum)
 This will make a fold out of paragraphs separated by blank lines: >
        :set foldexpr=getline(v:lnum)=~'^\\s*$'&&getline(v:lnum+1)=~'\\S'?'<1':1
-this does the same: >
+This does the same: >
        :set foldexpr=getline(v:lnum-1)=~'^\\s*$'&&getline(v:lnum)=~'\\S'?'>1':1
 
 Note that backslashes must be used to escape characters that ":set" handles
@@ -139,7 +139,7 @@ fold level.  But note that foldlevel() may return -1 if the level is not known
 yet.  And it returns the level at the start of the line, while a fold might
 end in that line.
 
-It may happened that folds are not updated properly.  You can use |zx| or |zX|
+It may happen that folds are not updated properly.  You can use |zx| or |zX|
 to force updating folds.
 
 
@@ -203,7 +203,7 @@ and the level given by the marker:
 1. If a marker with the same fold level is encountered, the previous fold
    ends and another fold with the same level starts.
 2. If a marker with a higher fold level is found, a nested fold is started.
-3. if a marker with a lower fold level is found, all folds up to and including
+3. If a marker with a lower fold level is found, all folds up to and including
    this level end and a fold with the specified level starts.
 
 The number indicates the fold level.  A zero cannot be used (a marker with
diff --git a/runtime/doc/ft_rust.txt b/runtime/doc/ft_rust.txt
new file mode 100644 (file)
index 0000000..c2e21e4
--- /dev/null
@@ -0,0 +1,237 @@
+*ft_rust.txt*      Filetype plugin for Rust
+
+==============================================================================
+CONTENTS                                                      *rust*
+
+1. Introduction                                                   |rust-intro|
+2. Settings                                                    |rust-settings|
+3. Commands                                                    |rust-commands|
+4. Mappings                                                    |rust-mappings|
+
+==============================================================================
+INTRODUCTION                                                      *rust-intro*
+
+This plugin provides syntax and supporting functionality for the Rust
+filetype.
+
+==============================================================================
+SETTINGS                                                       *rust-settings*
+
+This plugin has a few variables you can define in your vimrc that change the
+behavior of the plugin.
+
+                                                                *g:rustc_path*
+g:rustc_path~
+       Set this option to the path to rustc for use in the |:RustRun| and
+       |:RustExpand| commands. If unset, "rustc" will be located in $PATH: >
+           let g:rustc_path = $HOME."/bin/rustc"
+<
+
+                                                  *g:rustc_makeprg_no_percent*
+g:rustc_makeprg_no_percent~
+       Set this option to 1 to have 'makeprg' default to "rustc" instead of
+       "rustc %": >
+           let g:rustc_makeprg_no_percent = 1
+<
+
+                                                              *g:rust_conceal*
+g:rust_conceal~
+       Set this option to turn on the basic |conceal| support: >
+           let g:rust_conceal = 1
+<
+
+                                                     *g:rust_conceal_mod_path*
+g:rust_conceal_mod_path~
+       Set this option to turn on |conceal| for the path connecting token
+       "::": >
+           let g:rust_conceal_mod_path = 1
+<
+
+                                                          *g:rust_conceal_pub*
+g:rust_conceal_pub~
+       Set this option to turn on |conceal| for the "pub" token: >
+           let g:rust_conceal_pub = 1
+<
+
+                                                     *g:rust_recommended_style*
+g:rust_recommended_style~
+        Set this option to enable vim indentation and textwidth settings to
+        conform to style conventions of the rust standard library (i.e. use 4
+        spaces for indents and sets 'textwidth' to 99). This option is enabled
+       by default. To disable it: >
+           let g:rust_recommended_style = 0
+<
+
+                                                                 *g:rust_fold*
+g:rust_fold~
+       Set this option to turn on |folding|: >
+           let g:rust_fold = 1
+<
+       Value           Effect ~
+       0               No folding
+       1               Braced blocks are folded. All folds are open by
+                       default.
+       2               Braced blocks are folded. 'foldlevel' is left at the
+                       global value (all folds are closed by default).
+
+                                                  *g:rust_bang_comment_leader*
+g:rust_bang_comment_leader~
+       Set this option to 1 to preserve the leader on multi-line doc comments
+       using the /*! syntax: >
+           let g:rust_bang_comment_leader = 1
+<
+
+                                                 *g:ftplugin_rust_source_path*
+g:ftplugin_rust_source_path~
+       Set this option to a path that should be prepended to 'path' for Rust
+       source files: >
+           let g:ftplugin_rust_source_path = $HOME.'/dev/rust'
+<
+
+                                                       *g:rustfmt_command*
+g:rustfmt_command~
+       Set this option to the name of the 'rustfmt' executable in your $PATH. If
+       not specified it defaults to 'rustfmt' : >
+           let g:rustfmt_command = 'rustfmt'
+<
+                                                       *g:rustfmt_autosave*
+g:rustfmt_autosave~
+       Set this option to 1 to run |:RustFmt| automatically when saving a
+       buffer. If not specified it defaults to 0 : >
+           let g:rustfmt_autosave = 0
+<
+                                                       *g:rustfmt_fail_silently*
+g:rustfmt_fail_silently~
+       Set this option to 1 to prevent 'rustfmt' from populating the
+       |location-list| with errors. If not specified it defaults to 0: >
+           let g:rustfmt_fail_silently = 0
+<
+                                                       *g:rustfmt_options*
+g:rustfmt_options~
+       Set this option to a string of options to pass to 'rustfmt'. The
+       write-mode is already set to 'overwrite'. If not specified it
+       defaults to '' : >
+           let g:rustfmt_options = ''
+<
+
+                                                          *g:rust_playpen_url*
+g:rust_playpen_url~
+       Set this option to override the url for the playpen to use: >
+           let g:rust_playpen_url = 'https://play.rust-lang.org/'
+<
+
+                                                        *g:rust_shortener_url*
+g:rust_shortener_url~
+       Set this option to override the url for the url shortener: >
+           let g:rust_shortener_url = 'https://is.gd/'
+<
+
+
+==============================================================================
+COMMANDS                                                       *rust-commands*
+
+:RustRun  [args]                                                    *:RustRun*
+:RustRun! [rustc-args] [--] [args]
+               Compiles and runs the current file. If it has unsaved changes,
+               it will be saved first using |:update|. If the current file is
+               an unnamed buffer, it will be written to a temporary file
+               first. The compiled binary is always placed in a temporary
+               directory, but is run from the current directory.
+
+               The arguments given to |:RustRun| will be passed to the
+               compiled binary.
+
+               If ! is specified, the arguments are passed to rustc instead.
+               A "--" argument will separate the rustc arguments from the
+               arguments passed to the binary.
+
+               If |g:rustc_path| is defined, it is used as the path to rustc.
+               Otherwise it is assumed rustc can be found in $PATH.
+
+:RustExpand  [args]                                              *:RustExpand*
+:RustExpand! [TYPE] [args]
+               Expands the current file using --pretty and displays the
+               results in a new split. If the current file has unsaved
+               changes, it will be saved first using |:update|. If the
+               current file is an unnamed buffer, it will be written to a
+               temporary file first.
+
+               The arguments given to |:RustExpand| will be passed to rustc.
+               This is largely intended for specifying various --cfg
+               configurations.
+
+               If ! is specified, the first argument is the expansion type to
+               pass to rustc --pretty. Otherwise it will default to
+               "expanded".
+
+               If |g:rustc_path| is defined, it is used as the path to rustc.
+               Otherwise it is assumed rustc can be found in $PATH.
+
+:RustEmitIr [args]                                               *:RustEmitIr*
+               Compiles the current file to LLVM IR and displays the results
+               in a new split. If the current file has unsaved changes, it
+               will be saved first using |:update|. If the current file is an
+               unnamed buffer, it will be written to a temporary file first.
+
+               The arguments given to |:RustEmitIr| will be passed to rustc.
+
+               If |g:rustc_path| is defined, it is used as the path to rustc.
+               Otherwise it is assumed rustc can be found in $PATH.
+
+:RustEmitAsm [args]                                             *:RustEmitAsm*
+               Compiles the current file to assembly and displays the results
+               in a new split. If the current file has unsaved changes, it
+               will be saved first using |:update|. If the current file is an
+               unnamed buffer, it will be written to a temporary file first.
+
+               The arguments given to |:RustEmitAsm| will be passed to rustc.
+
+               If |g:rustc_path| is defined, it is used as the path to rustc.
+               Otherwise it is assumed rustc can be found in $PATH.
+
+:RustPlay                                                          *:RustPlay*
+               This command will only work if you have web-api.vim installed
+               (available at https://github.com/mattn/webapi-vim).  It sends the
+               current selection, or if nothing is selected, the entirety of the
+               current buffer to the Rust playpen, and emits a message with the
+               shortened URL to the playpen.
+
+               |g:rust_playpen_url| is the base URL to the playpen, by default
+               "https://play.rust-lang.org/".
+
+               |g:rust_shortener_url| is the base url for the shorterner, by
+               default "https://is.gd/"
+
+:RustFmt                                                       *:RustFmt*
+               Runs |g:rustfmt_command| on the current buffer. If
+               |g:rustfmt_options| is set then those will be passed to the
+               executable.
+
+               If |g:rustfmt_fail_silently| is 0 (the default) then it
+               will populate the |location-list| with the errors from
+               |g:rustfmt_command|. If |g:rustfmt_fail_silently| is set to 1
+               then it will not populate the |location-list|.
+
+:RustFmtRange                                                  *:RustFmtRange*
+               Runs |g:rustfmt_command| with selected range. See
+               |:RustFmt| for any other information.
+
+==============================================================================
+MAPPINGS                                                       *rust-mappings*
+
+This plugin defines mappings for |[[| and |]]| to support hanging indents.
+
+It also has a few other mappings:
+
+                                                       *rust_<D-r>*
+<D-r>                  Executes |:RustRun| with no arguments.
+                       Note: This binding is only available in MacVim.
+
+                                                       *rust_<D-R>*
+<D-R>                  Populates the command line with |:RustRun|! using the
+                       arguments given to the last invocation, but does not
+                       execute it.
+                       Note: This binding is only available in MacVim.
+
+==============================================================================
+ vim:tw=78:sw=4:noet:ts=8:ft=help:norl:
index 40901a6..0092501 100644 (file)
@@ -81,8 +81,8 @@ And there should be no ':set guifont'.  If it exists, then Gvim ignores
 ':set guifontset'.  It means VIM runs without fontset supporting.
 So, you can see only English.  Hangul does not be correctly displayed.
 
-After 'fontset' feature is enabled, VIM does not allow using english
-font only in 'font' setting for syntax.
+After "fontset" feature is enabled, VIM does not allow using english
+font only in "font" setting for syntax.
 For example, if you use >
    :set guifontset=eng_font,your_font
 in your .gvimrc, then you should do for syntax >
index b51fe78..80fc70c 100644 (file)
@@ -1,4 +1,4 @@
-*helphelp.txt* For Vim version 8.0.  Last change: 2016 Apr 01
+*helphelp.txt* For Vim version 8.0.  Last change: 2017 Mar 19
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -28,10 +28,16 @@ Help on help files                                  *helphelp*
 
                                                *{subject}* *E149* *E661*
 :h[elp] {subject}      Like ":help", additionally jump to the tag {subject}.
-                       {subject} can include wildcards like "*", "?" and
+                       For example:  >
+                               :help options
+
+<                      {subject} can include wildcards such as "*", "?" and
                        "[a-z]":
                           :help z?     jump to help for any "z" command
                           :help z.     jump to the help for "z."
+                       But when a tag exists it is taken literally:
+                          :help :?     jump to help for ":?"
+
                        If there is no full match for the pattern, or there
                        are several matches, the "best" match will be used.
                        A sophisticated algorithm is used to decide which
@@ -68,18 +74,19 @@ Help on help files                                  *helphelp*
                        example to find help for CTRL-V in Insert mode: >
                                :help i^V
 <
-                       To use a regexp |pattern|, first do ":help" and then
+                       It is also possible to first do ":help" and then
                        use ":tag {pattern}" in the help window.  The
                        ":tnext" command can then be used to jump to other
                        matches, "tselect" to list matches and choose one. >
-                               :help index| :tse z.
+                               :help index
+                               :tselect /.*mode
 
 <                      When there is no argument you will see matches for
                        "help", to avoid listing all possible matches (that
                        would be very slow).
                        The number of matches displayed is limited to 300.
 
-                       This command can be followed by '|' and another
+                       The `:help` command can be followed by '|' and another
                        command, but you don't need to escape the '|' inside a
                        help command.  So these both work: >
                                :help |
@@ -135,7 +142,8 @@ Help on help files                                  *helphelp*
                        already opened, then the location list for that window
                        is used.  Otherwise, a new help window is opened and
                        the location list for that window is set.  The
-                       location list for the current window is not changed.
+                       location list for the current window is not changed
+                       then.
 
                                                        *:exu* *:exusage*
 :exu[sage]             Show help on Ex commands.  Added to simulate the Nvi
@@ -307,7 +315,7 @@ the applicable Vim version.  The last field specifies the last modification
 date of the file.  Each field is separated by a tab.
 
 At the bottom of the help file, place a Vim modeline to set the 'textwidth'
-and 'tabstop' options and the 'filetype' to 'help'.  Never set a global option
+and 'tabstop' options and the 'filetype' to "help".  Never set a global option
 in such a modeline, that can have consequences undesired by whoever reads that
 help.
 
index 9ef6c3d..7e206f5 100644 (file)
@@ -249,7 +249,7 @@ Windows                                                         *mzscheme-window*
 5. mzeval() Vim function                                   *mzscheme-mzeval*
 
 To facilitate bi-directional interface, you can use |mzeval()| function to
-evaluate MzScheme expressions and pass their values to VimL.
+evaluate MzScheme expressions and pass their values to Vim script.
 
 ==============================================================================
 6. Using Function references                               *mzscheme-funcref*
index 5929bcf..6f1c202 100644 (file)
@@ -1,4 +1,4 @@
-*if_pyth.txt*   For Vim version 8.0.  Last change: 2016 Sep 17
+*if_pyth.txt*   For Vim version 8.0.  Last change: 2017 Mar 09
 
 
                  VIM REFERENCE MANUAL    by Paul Moore
@@ -16,6 +16,8 @@ The Python Interface to Vim                           *python* *Python*
 8. pyeval(), py3eval() Vim functions           |python-pyeval|
 9. Dynamic loading                             |python-dynamic|
 10. Python 3                                   |python3|
+11. Python X                                   |python_x|
+12. Building with Python support               |python-building|
 
 {Vi does not have any of these commands}
 
@@ -173,8 +175,8 @@ vim.eval(str)                                               *python-eval*
 
            :py tagList = vim.eval('taglist("eval_expr")')
 <      The latter will return a python list of python dicts, for instance:
-       [{'cmd': '/^eval_expr(arg, nextcmd)$/', 'static': 0, 'name':
-       'eval_expr', 'kind': 'f', 'filename': './src/eval.c'}]
+       [{'cmd': '/^eval_expr(arg, nextcmd)$/', 'static': 0, 'name': ~
+       'eval_expr', 'kind': 'f', 'filename': './src/eval.c'}] ~
 
 vim.bindeval(str)                                      *python-bindeval*
        Like |python-eval|, but returns special objects described in 
@@ -675,11 +677,11 @@ vim.Function object                               *python-Function*
                      dictionary. Note that explicit `self` keyword used when 
                      calling resulting object overrides this attribute.
         auto_rebind  Boolean. True if partial created from this Python object 
-                     and stored in the VimL dictionary should be automatically 
-                     rebound to the dictionary it is stored in when this 
-                     dictionary is indexed. Exposes Vim internal difference 
-                     between `dict.func` (auto_rebind=True) and 
-                     `function(dict.func,dict)` (auto_rebind=False). This 
+                     and stored in the Vim script dictionary should be
+                     automatically rebound to the dictionary it is stored in
+                     when this dictionary is indexed. Exposes Vim internal
+                     difference between `dict.func` (auto_rebind=True) and
+                     `function(dict.func,dict)` (auto_rebind=False). This
                      attribute makes no sense if `self` attribute is `None`.
 
     Constructor additionally accepts `args`, `self` and `auto_rebind` 
@@ -710,7 +712,8 @@ vim.Function object                         *python-Function*
 8. pyeval() and py3eval() Vim functions                        *python-pyeval*
 
 To facilitate bi-directional interface, you can use |pyeval()| and |py3eval()| 
-functions to evaluate Python expressions and pass their values to VimL.
+functions to evaluate Python expressions and pass their values to Vim script.
+|pyxeval()| is also available.
 
 ==============================================================================
 9. Dynamic loading                                     *python-dynamic*
@@ -729,9 +732,11 @@ To use the Python interface the Python DLL must be in your search path.  In a
 console window type "path" to see what directories are used.  The 'pythondll'
 or 'pythonthreedll' option can be also used to specify the Python DLL.
 
-The name of the DLL must match the Python version Vim was compiled with.
-Currently the name is "python24.dll".  That is for Python 2.4.  To know for
-sure edit "gvim.exe" and search for "python\d*.dll\c".
+The name of the DLL should match the Python version Vim was compiled with.
+Currently the name for Python 2 is "python27.dll", that is for Python 2.7.
+That is the default value for 'pythondll'.  For Python 3 it is python35.dll
+(Python 3.5).  To know for sure edit "gvim.exe" and search for
+"python\d*.dll\c".
 
 
 Unix ~
@@ -812,4 +817,90 @@ loaded at a time, just checking if Python 2 or 3 are available will prevent
 the other one from being available.
 
 ==============================================================================
+11. Python X                                           *python_x* *pythonx*
+
+Because most python code can be written so that it works with python 2.6+ and
+python 3 the pyx* functions and commands have been written.  They work exactly
+the same as the Python 2 and 3 variants, but select the Python version using
+the 'pyxversion' setting.
+
+You should set 'pyxversion' in your |.vimrc| to prefer Python 2 or Python 3
+for Python commands. If you change this setting at runtime you may risk that
+state of plugins (such as initialization) may be lost.
+
+If you want to use a module, you can put it in the {rtp}/pythonx directory.
+See |pythonx-directory|.
+
+                                                       *:pyx* *:pythonx*
+The `:pyx` and `:pythonx` commands work similar to `:python`.  A simple check
+if the `:pyx` command is working: >
+       :pyx print("Hello")
+
+To see what version of Python is being used: >
+       :pyx import sys
+       :pyx print(sys.version)
+<
+                                       *:pyxfile* *python_x-special-comments*
+The `:pyxfile` command works similar to `:pyfile`.  However you can add one of
+these comments to force Vim using `:pyfile` or `:py3file`: >
+  #!/any string/python2                " Shebang. Must be the first line of the file.
+  #!/any string/python3                " Shebang. Must be the first line of the file.
+  # requires python 2.x                " Maximum lines depend on 'modelines'.
+  # requires python 3.x                " Maximum lines depend on 'modelines'.
+Unlike normal modelines, the bottom of the file is not checked.
+If none of them are found, the 'pyxversion' setting is used.
+                                                       *W20* *W21*
+If Vim does not support the selected Python version a silent message will be
+printed.  Use `:messages` to read them.
+
+                                                       *:pyxdo*
+The `:pyxdo` command works similar to `:pydo`.
+
+                                                       *has-pythonx*
+You can test if pyx* commands are available with: >
+       if has('pythonx')
+         echo 'pyx* commands are available. (Python ' . &pyx . ')'
+       endif
+
+When compiled with only one of |+python| or |+python3|, the has() returns 1.
+When compiled with both |+python| and |+python3|, the test depends on the
+'pyxversion' setting.  If 'pyxversion' is 0, it tests Python 3 first, and if
+it is not available then Python 2.  If 'pyxversion' is 2 or 3, it tests only
+Python 2 or 3 respectively.
+
+Note that for `has('pythonx')` to work it may try to dynamically load Python 3
+or 2.  This may have side effects, especially when Vim can only load one of
+the two.
+
+If a user prefers Python 2 and want to fallback to Python 3, he needs to set
+'pyxversion' explicitly in his |.vimrc|.  E.g.: >
+       if has('python')
+         set pyx=2
+       elseif has('python3')
+         set pyx=3
+       endif
+
+==============================================================================
+12. Building with Python support                       *python-building*
+
+A few hints for building with Python 2 or 3 support.
+
+UNIX
+
+See src/Makefile for how to enable including the Python interface.
+
+On Ubuntu you will want to install these packages for Python 2:
+       python
+       python-dev
+For Python 3:
+       python3
+       pytyon3-dev
+For Python 3.6:
+       python3.6
+       pytyon3.6-dev
+
+If you have more than one version of Python 3, you need to link python3 to the
+one you prefer, before running configure.
+
+==============================================================================
  vim:tw=78:ts=8:ft=help:norl:
index b00dd45..f79ecc1 100644 (file)
@@ -72,7 +72,7 @@ To see what version of Ruby you have: >
 
                                                        *:rubyfile* *:rubyf*
 :rubyf[ile] {file}     Execute the Ruby script in {file}.  This is the same as
-                       ":ruby load 'file'", but allows file name completion.
+                       `:ruby load 'file'`, but allows file name completion.
 
 Executing Ruby commands is not possible in the |sandbox|.
 
index fdb7c67..efb0a7d 100644 (file)
@@ -325,6 +325,21 @@ The examples below assume a 'shiftwidth' of 4.
                      void function();       void function();
                  }                          }
 <
+                                                       *cino-E*
+       EN    Indent inside C++ linkage specifications (extern "C" or
+             extern "C++") N characters extra compared to a normal block.
+             (default 0).
+
+               cino=                      cino=E-s >
+                 extern "C" {               extern "C" {
+                     void function();       void function();
+                 }                          }
+
+                 extern "C"                 extern "C"
+                 {                          {
+                     void function();       void function();
+                 }                          }
+<
                                                        *cino-p*
        pN    Parameter declarations for K&R-style function declarations will
              be indented N characters from the margin.  (default
@@ -554,7 +569,7 @@ The examples below assume a 'shiftwidth' of 4.
 
 
 The defaults, spelled out in full, are:
-       cinoptions=>s,e0,n0,f0,{0,}0,^0,L-1,:s,=s,l0,b0,gs,hs,N0,ps,ts,is,+s,
+       cinoptions=>s,e0,n0,f0,{0,}0,^0,L-1,:s,=s,l0,b0,gs,hs,N0,E0,ps,ts,is,+s,
                        c3,C0,/0,(2s,us,U0,w0,W0,k0,m0,j0,J0,)20,*70,#0
 
 Vim puts a line in column 1 if:
index 4ebf999..ed10b46 100644 (file)
@@ -1,4 +1,4 @@
-*index.txt*     For Vim version 8.0.  Last change: 2016 Sep 27
+*index.txt*     For Vim version 8.0.  Last change: 2017 Apr 22
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -309,10 +309,10 @@ tag               char          note action in Normal mode        ~
 |B|            B               1  cursor N WORDS backward
 |C|            ["x]C           2  change from the cursor position to the end
                                   of the line, and N-1 more lines [into
-                                  buffer x]; synonym for "c$"
+                                  register x]; synonym for "c$"
 |D|            ["x]D           2  delete the characters under the cursor
                                   until the end of the line and N-1 more
-                                  lines [into buffer x]; synonym for "d$"
+                                  lines [into register x]; synonym for "d$"
 |E|            E               1  cursor forward to the end of WORD N
 |F|            F{char}         1  cursor to the Nth occurrence of {char} to
                                   the left
@@ -329,13 +329,13 @@ tag               char          note action in Normal mode        ~
                                   opposite direction
 |O|            O               2  begin a new line above the cursor and
                                   insert text, repeat N times
-|P|            ["x]P           2  put the text [from buffer x] before the
+|P|            ["x]P           2  put the text [from register x] before the
                                   cursor N times
 |Q|            Q                  switch to "Ex" mode
 |R|            R               2  enter replace mode: overtype existing
                                   characters, repeat the entered text N-1
                                   times
-|S|            ["x]S           2  delete N lines [into buffer x] and start
+|S|            ["x]S           2  delete N lines [into register x] and start
                                   insert; synonym for "cc".
 |T|            T{char}         1  cursor till after Nth occurrence of {char}
                                   to the left
@@ -343,8 +343,8 @@ tag         char          note action in Normal mode        ~
 |V|            V                  start linewise Visual mode
 |W|            W               1  cursor N WORDS forward
 |X|            ["x]X           2  delete N characters before the cursor [into
-                                  buffer x]
-|Y|            ["x]Y              yank N lines [into buffer x]; synonym for
+                                  register x]
+|Y|            ["x]Y              yank N lines [into register x]; synonym for
                                   "yy"
 |ZZ|           ZZ                 store current file if modified, and exit
 |ZQ|           ZQ                 exit current file always
@@ -367,12 +367,12 @@ tag               char          note action in Normal mode        ~
 |`}|           `}              1  cursor to the end of the current paragraph
 |a|            a               2  append text after the cursor N times
 |b|            b               1  cursor N words backward
-|c|            ["x]c{motion}   2  delete Nmove text [into buffer x] and start
+|c|            ["x]c{motion}   2  delete Nmove text [into register x] and
+                                  start insert
+|cc|           ["x]cc          2  delete N lines [into register x] and start
                                   insert
-|cc|           ["x]cc          2  delete N lines [into buffer x] and start
-                                  insert
-|d|            ["x]d{motion}   2  delete Nmove text [into buffer x]
-|dd|           ["x]dd          2  delete N lines [into buffer x]
+|d|            ["x]d{motion}   2  delete Nmove text [into register x]
+|dd|           ["x]dd          2  delete N lines [into register x]
 |do|           do              2  same as ":diffget"
 |dp|           dp              2  same as ":diffput"
 |e|            e               1  cursor forward to the end of word N
@@ -398,16 +398,16 @@ tag               char          note action in Normal mode        ~
 |q?|           q?                 edit ? command-line in command-line window
 |r|            r{char}         2  replace N chars with {char}
 |s|            ["x]s           2  (substitute) delete N characters [into
-                                  buffer x] and start insert
+                                  register x] and start insert
 |t|            t{char}         1  cursor till before Nth occurrence of {char}
                                   to the right
 |u|            u               2  undo changes
 |v|            v                  start characterwise Visual mode
 |w|            w               1  cursor N words forward
 |x|            ["x]x           2  delete N characters under and after the
-                                  cursor [into buffer x]
-|y|            ["x]y{motion}      yank Nmove text [into buffer x]
-|yy|           ["x]yy             yank N lines [into buffer x]
+                                  cursor [into register x]
+|y|            ["x]y{motion}      yank Nmove text [into register x]
+|yy|           ["x]yy             yank N lines [into register x]
 |z|            z{char}            commands starting with 'z', see |z| below
 |{|            {               1  cursor N paragraphs backward
 |bar|          |               1  cursor to column N
@@ -1004,10 +1004,12 @@ tag             command       action in Command-line editing mode       ~
 |c_<CR>|       <CR>            execute entered command
 |c_CTRL-M|     CTRL-M          same as <CR>
 |c_CTRL-N|     CTRL-N          after using 'wildchar' with multiple matches:
-                               go to next match, otherwise: same as <Down>
+                               go to next match, otherwise: recall older
+                               command-line from history.
                CTRL-O          not used
 |c_CTRL-P|     CTRL-P          after using 'wildchar' with multiple matches:
-                               go to previous match, otherwise: same as <Up>
+                               go to previous match, otherwise: recall older
+                               command-line from history.
 |c_CTRL-Q|     CTRL-Q          same as CTRL-V, unless it's used for terminal
                                control flow
 |c_CTRL-R|     CTRL-R {0-9a-z"%#*:= CTRL-F CTRL-P CTRL-W CTRL-A}
@@ -1440,6 +1442,10 @@ tag            command         action ~
 |:python|      :py[thon]       execute Python command
 |:pydo|                :pyd[o]         execute Python command for each line
 |:pyfile|      :pyf[ile]       execute Python script file
+|:pyx|         :pyx            execute |python_x| command
+|:pythonx|     :pythonx        same as :pyx
+|:pyxdo|       :pyxd[o]        execute |python_x| command for each line
+|:pyxfile|     :pyxf[ile]      execute |python_x| script file
 |:quit|                :q[uit]         quit current window (when one window quit Vim)
 |:quitall|     :quita[ll]      quit Vim
 |:qall|                :qa[ll]         quit Vim
index d2959df..2c6900e 100644 (file)
@@ -1,4 +1,4 @@
-*insert.txt*    For Vim version 8.0.  Last change: 2016 Jan 31
+*insert.txt*    For Vim version 8.0.  Last change: 2017 Apr 07
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -159,7 +159,8 @@ CTRL-R CTRL-R {0-9a-z"%#*+/:.-=}                    *i_CTRL-R_CTRL-R*
 CTRL-R CTRL-O {0-9a-z"%#*+/:.-=}                       *i_CTRL-R_CTRL-O*
                Insert the contents of a register literally and don't
                auto-indent.  Does the same as pasting with the mouse
-               |<MiddleMouse>|.
+               |<MiddleMouse>|. When the register is linewise this will
+               insert the text above the current line, like with `P`.
                Does not replace characters!
                The '.' register (last inserted text) is still inserted as
                typed.  {not in Vi}
@@ -1103,7 +1104,7 @@ items:
        empty           when non-zero this match will be added even when it is
                        an empty string
 
-All of these except 'icase', 'dup' and 'empty' must be a string.  If an item
+All of these except "icase", "dup" and "empty" must be a string.  If an item
 does not meet these requirements then an error message is given and further
 items in the list are not used.  You can mix string and Dictionary items in
 the returned list.
index 5845905..d6664ff 100644 (file)
@@ -96,21 +96,18 @@ mention that.
 
                                                *mail-list* *maillist*
 There are several mailing lists for Vim:
-<vim@vim.org>
+<vim@vim.org>                                  *vim-use* *vim_use*
        For discussions about using existing versions of Vim: Useful mappings,
        questions, answers, where to get a specific version, etc.  There are
        quite a few people watching this list and answering questions, also
        for beginners.  Don't hesitate to ask your question here.
-<vim-dev@vim.org>                              *vim-dev* *vimdev*
+<vim-dev@vim.org>                              *vim-dev* *vim_dev* *vimdev*
        For discussions about changing Vim: New features, porting, patches,
        beta-test versions, etc.
-<vim-announce@vim.org>                         *vim-announce*
+<vim-announce@vim.org>                         *vim-announce* *vim_announce*
        Announcements about new versions of Vim; also for beta-test versions
        and ports to different systems.  This is a read-only list.
-<vim-multibyte@vim.org>                                *vim-multibyte*
-       For discussions about using and improving the multi-byte aspects of
-       Vim.
-<vim-mac@vim.org>                              *vim-mac*
+<vim-mac@vim.org>                              *vim-mac* *vim_mac*
        For discussions about using and improving the Macintosh version of
        Vim.
 
index e644f83..7d723ce 100644 (file)
@@ -1,4 +1,4 @@
-*map.txt*       For Vim version 8.0.  Last change: 2016 Oct 15
+*map.txt*       For Vim version 8.0.  Last change: 2017 Mar 10
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -584,7 +584,8 @@ Upper and lowercase differences are ignored.
 
                                                        *map-comments*
 It is not possible to put a comment after these commands, because the '"'
-character is considered to be part of the {lhs} or {rhs}.
+character is considered to be part of the {lhs} or {rhs}. However, one can
+use |", since this starts a new, empty command with a comment.
 
                                                        *map_bar* *map-bar*
 Since the '|' character is used to separate a map command from the next
index 83e2198..5eeba0c 100644 (file)
@@ -1,4 +1,4 @@
-*message.txt*   For Vim version 8.0.  Last change: 2016 Sep 01
+*message.txt*   For Vim version 8.0.  Last change: 2017 Mar 25
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -129,8 +129,9 @@ closed properly.  Mostly harmless.
   Command too recursive
 
 This happens when an Ex command executes an Ex command that executes an Ex
-command, etc.  This is only allowed 200 times.  When it's more there probably
-is an endless loop.  Probably a |:execute| or |:source| command is involved.
+command, etc.  The limit is 200 or the value of 'maxfuncdepth', whatever is
+larger.  When it's more there probably is an endless loop.  Probably a
+|:execute| or |:source| command is involved.
 
                                                        *E254*  >
   Cannot allocate color {name}
@@ -767,6 +768,13 @@ Example: >
 You tried to execute a command that is neither an Ex command nor
 a user-defined command.
 
+                                                       *E943*  >
+  Command table needs to be updated, run 'make cmdidxs'
+
+This can only happen when changing the source code, when adding a command in
+src/ex_cmds.h.  The lookup table then needs to be updated, by running: >
+       make cmdidxs
+
 ==============================================================================
 3. Messages                                            *messages*
 
index aa9a94c..2d27912 100644 (file)
@@ -1,4 +1,4 @@
-*mlang.txt*     For Vim version 8.0.  Last change: 2016 Jan 16
+*mlang.txt*     For Vim version 8.0.  Last change: 2017 Mar 04
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -179,6 +179,7 @@ Send an e-mail to the Vim maintainer <maintainer@vim.org>.
                        special characters like "&" and "<Tab>" need to be
                        included.  Spaces and dots need to be escaped with a
                        backslash, just like in other |:menu| commands.
+                       Case in {english} is ignored.
 
 See the $VIMRUNTIME/lang directory for examples.
 
index 269f092..673d1c5 100644 (file)
@@ -1,4 +1,4 @@
-*motion.txt*    For Vim version 8.0.  Last change: 2016 Jul 12
+*motion.txt*    For Vim version 8.0.  Last change: 2017 Mar 12
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -193,7 +193,7 @@ l           or                                      *l*
 
                                                        *$* *<End>* *<kEnd>*
 $  or <End>            To the end of the line.  When a count is given also go
-                       [count - 1] lines downward |inclusive|.
+                       [count - 1] lines downward. |inclusive| motion.
                        In Visual mode the cursor goes to just after the last
                        character in the line.
                        When 'virtualedit' is active, "$" may move the cursor
@@ -915,6 +915,7 @@ was made yet in the current file.
                        then the position can be near the end of what the
                        command changed.  For example when inserting a word,
                        the position will be on the last character.
+                       To jump to older changes use |g;|.
                        {not in Vi}
 
                                                        *'(* *`(*
index 390fab0..927931c 100644 (file)
@@ -1,4 +1,4 @@
-*options.txt*  For Vim version 8.0.  Last change: 2016 Oct 12
+*options.txt*  For Vim version 8.0.  Last change: 2017 Mar 22
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -242,7 +242,7 @@ opt+=val" the expansion is done before the adding or removing.
 Handling of local options                      *local-options*
 
 Some of the options only apply to a window or buffer.  Each window or buffer
-has its own copy of this option, thus can each have their own value.  This
+has its own copy of this option, thus each can have its own value.  This
 allows you to set 'list' in one window but not in another.  And set
 'shiftwidth' to 3 in one buffer and 4 in another.
 
@@ -727,6 +727,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        which can be easier to read at certain sizes on certain displays.
        Setting this option can sometimes cause problems if 'guifont' is set
        to its default (empty string).
+       NOTE: This option is reset when 'compatible' is set.
 
                        *'autochdir'* *'acd'* *'noautochdir'* *'noacd'*
 'autochdir' 'acd'      boolean (default off)
@@ -760,6 +761,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        - Disable the use of 'keymap' (without changing its value).
        Note that 'arabicshape' and 'delcombine' are not reset (it is a global
        option).
+       NOTE: This option is reset when 'compatible' is set.
        Also see |arabic.txt|.
 
                                        *'arabicshape'* *'arshape'*
@@ -781,6 +783,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        form.
        Arabic is a complex language which requires other settings, for
        further details see |arabic.txt|.
+       NOTE: This option is set when 'compatible' is set.
 
                        *'autoindent'* *'ai'* *'noautoindent'* *'noai'*
 'autoindent' 'ai'      boolean (default off)
@@ -993,6 +996,9 @@ A jump table for the options with a short description can be found at |Q_op|.
        the system may refuse to do this.  In that case the "auto" value will
        again not rename the file.
 
+       NOTE: This option is set to the Vi default value when 'compatible' is
+       set and to the Vim default value when 'compatible' is reset.
+
                                                *'backupdir'* *'bdir'*
 'backupdir' 'bdir'     string  (default for Amiga: ".,t:",
                                 for MS-DOS and Win32: ".,$TEMP,c:/tmp,c:/temp"
@@ -1120,6 +1126,9 @@ A jump table for the options with a short description can be found at |Q_op|.
     set bexpr=MyBalloonExpr()
     set ballooneval
 <
+       Also see |balloon_show()|, can be used if the content of the balloon
+       is to be fetched asynchronously.
+
        NOTE: The balloon is displayed only if the cursor is on a text
        character.  If the result of evaluating 'balloonexpr' is not empty,
        Vim does not try to send a message to an external debugger (Netbeans
@@ -1136,6 +1145,7 @@ A jump table for the options with a short description can be found at |Q_op|.
 <      When they are supported "\n" characters will start a new line.  If the
        expression evaluates to a |List| this is equal to using each List item
        as a string and putting "\n" in between them.
+       NOTE: This option is set to "" when 'compatible' is set.
 
                                                *'belloff'* *'bo'*
 'belloff' 'bo'         string  (default "")
@@ -1173,8 +1183,8 @@ A jump table for the options with a short description can be found at |Q_op|.
        wildmode    More matches in |cmdline-completion| available
                    (depends on the 'wildmode' setting).
 
-       This is most useful, to fine tune when in insert mode the bell should
-       be rung. For normal mode and ex commands, the bell is often rung to
+       This is most useful to fine tune when in Insert mode the bell should
+       be rung. For Normal mode and Ex commands, the bell is often rung to
        indicate that an error occurred. It can be silenced by adding the
        "error" keyword.
 
@@ -1256,6 +1266,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        Every wrapped line will continue visually indented (same amount of
        space as the beginning of that line), thus preserving horizontal blocks
        of text.
+       NOTE: This option is reset when 'compatible' is set.
 
                                                *'breakindentopt'* *'briopt'*
 'breakindentopt' 'briopt' string (default empty)
@@ -1432,6 +1443,8 @@ A jump table for the options with a short description can be found at |Q_op|.
                :exe "set cedit=\<Esc>"
 <      |Nvi| also has this option, but it only uses the first character.
        See |cmdwin|.
+       NOTE: This option is set to the Vim default value when 'compatible'
+       is reset.
 
                                *'charconvert'* *'ccv'* *E202* *E214* *E513*
 'charconvert' 'ccv'    string (default "")
@@ -1702,12 +1715,14 @@ A jump table for the options with a short description can be found at |Q_op|.
                        {not in Vi}
        This option has the effect of making Vim either more Vi-compatible, or
        make Vim behave in a more useful way.
+
        This is a special kind of option, because when it's set or reset,
-       other options are also changed as a side effect.  CAREFUL: Setting or
-       resetting this option can have a lot of unexpected effects: Mappings
-       are interpreted in another way, undo behaves differently, etc.  If you
-       set this option in your vimrc file, you should probably put it at the
-       very start.
+       other options are also changed as a side effect.
+       NOTE: Setting or resetting this option can have a lot of unexpected
+       effects: Mappings are interpreted in another way, undo behaves
+       differently, etc.  If you set this option in your vimrc file, you
+       should probably put it at the very start.
+
        By default this option is on and the Vi defaults are used for the
        options.  This default was chosen for those people who want to use Vim
        just like Vi, and don't even (want to) know about the 'compatible'
@@ -1722,70 +1737,98 @@ A jump table for the options with a short description can be found at |Q_op|.
        |posix-compliance|.
        You can also set this option with the "-C" argument, and reset it with
        "-N".  See |-C| and |-N|.
-       Switching this option off makes the Vim defaults be used for options
-       that have a different Vi and Vim default value.  See the options
-       marked with a '+' below.  Other options are not modified.
-       At the moment this option is set, several other options will be set
-       or reset to make Vim as Vi-compatible as possible.  See the table
-       below.  This can be used if you want to revert to Vi compatible
-       editing.
-       See also 'cpoptions'.
-
-       option          + set value     effect  ~
-
-       'allowrevins'     off           no CTRL-_ command
-       'backspace'       ""            normal backspace
-       'backupcopy'      Unix: "yes"   backup file is a copy
-                         else: "auto"  copy or rename backup file
-       'backup'          off           no backup file
-       'cedit'         + ""            no key to open the |cmdwin|
-       'cindent'         off           no C code indentation
-       'cpoptions'     + (all flags)   Vi-compatible flags
-       'cscopetag'       off           don't use cscope for ":tag"
-       'cscopetagorder'  0             see |cscopetagorder|
-       'cscopeverbose'   off           see |cscopeverbose|
-       'digraph'         off           no digraphs
-       'esckeys'       + off           no <Esc>-keys in Insert mode
-       'expandtab'       off           tabs not expanded to spaces
-       'fileformats'   + ""            no automatic file format detection,
+       See 'cpoptions' for more fine tuning of Vi compatibility.
+
+       When this option is set, numerous other options are set to make Vim as
+       Vi-compatible as possible.  When this option is unset, various options
+       are set to make Vim more useful.  The table below lists all the
+       options affected.
+       The {?} column indicates when the options are affected:
+       +  Means that the option is set to the value given in {set value} when
+          'compatible' is set.
+       &  Means that the option is set to the value given in {set value} when
+          'compatible' is set AND is set to its Vim default value when
+          'compatible' is unset.
+       -  Means the option is NOT changed when setting 'compatible' but IS
+          set to its Vim default when 'compatible' is unset.
+       The {effect} column summarises the change when 'compatible' is set.
+
+       option          ? set value     effect ~
+
+       'allowrevins'   + off           no CTRL-_ command
+       'antialias'     + off           don't use antialiased fonts
+       'arabic'        + off           reset arabic-related options
+       'arabicshape'   + on            correct character shapes
+       'backspace'     + ""            normal backspace
+       'backup'        + off           no backup file
+       'backupcopy'    & Unix: "yes"   backup file is a copy
+                         else: "auto"  copy or rename backup file
+       'balloonexpr'   + ""            text to show in evaluation balloon
+       'breakindent'   + off           don't indent when wrapping lines
+       'cedit'         - {unchanged}   {set vim default only on resetting 'cp'}
+       'cindent'       + off           no C code indentation
+       'compatible'    - {unchanged}   {set vim default only on resetting 'cp'}
+       'copyindent'    + off           don't copy indent structure
+       'cpoptions'     & (all flags)   Vi-compatible flags
+       'cscopepathcomp'+ 0             don't show directories in tags list
+       'cscoperelative'+ off           
+       'cscopetag'     + off           don't use cscope for ":tag"
+       'cscopetagorder'+ 0             see |cscopetagorder|
+       'cscopeverbose' + off           see |cscopeverbose|
+       'delcombine'    + off           unicode: delete whole char combination
+       'digraph'       + off           no digraphs
+       'esckeys'       & off           no <Esc>-keys in Insert mode
+       'expandtab'     + off           tabs not expanded to spaces
+       'fileformats'   & ""            no automatic file format detection,
                          "dos,unix"    except for DOS, Windows and OS/2
-       'formatoptions' + "vt"          Vi compatible formatting
-       'gdefault'        off           no default 'g' flag for ":s"
-       'history'       + 0             no commandline history
-       'hkmap'           off           no Hebrew keyboard mapping
-       'hkmapp'          off           no phonetic Hebrew keyboard mapping
-       'hlsearch'        off           no highlighting of search matches
-       'incsearch'       off           no incremental searching
-       'indentexpr'      ""            no indenting by expression
-       'insertmode'      off           do not start in Insert mode
-       'iskeyword'     + "@,48-57,_"   keywords contain alphanumeric
+       'formatexpr'    + ""            use 'formatprg' for auto-formatting
+       'formatoptions' & "vt"          Vi compatible formatting
+       'gdefault'      + off           no default 'g' flag for ":s"
+       'history'       & 0             no commandline history
+       'hkmap'         + off           no Hebrew keyboard mapping
+       'hkmapp'        + off           no phonetic Hebrew keyboard mapping
+       'hlsearch'      + off           no highlighting of search matches
+       'incsearch'     + off           no incremental searching
+       'indentexpr'    + ""            no indenting by expression
+       'insertmode'    + off           do not start in Insert mode
+       'iskeyword'     & "@,48-57,_"   keywords contain alphanumeric
                                                characters and '_'
-       'joinspaces'      on            insert 2 spaces after period
-       'modeline'      + off           no modelines
-       'more'          + off           no pauses in listings
-       'revins'          off           no reverse insert
-       'ruler'           off           no ruler
-       'scrolljump'      1             no jump scroll
-       'scrolloff'       0             no scroll offset
-       'shiftround'      off           indent not rounded to shiftwidth
-       'shortmess'     + ""            no shortening of messages
-       'showcmd'       + off           command characters not shown
-       'showmode'      + off           current mode not shown
-       'smartcase'       off           no automatic ignore case switch
-       'smartindent'     off           no smart indentation
-       'smarttab'        off           no smart tab size
-       'softtabstop'     0             tabs are always 'tabstop' positions
-       'startofline'     on            goto startofline with some commands
-       'tagrelative'   + off           tag file names are not relative
-       'textauto'      + off           no automatic textmode detection
-       'textwidth'       0             no automatic line wrap
-       'tildeop'         off           tilde is not an operator
-       'ttimeout'        off           no terminal timeout
-       'viminfo'       + {unchanged}   no viminfo file 
-       'whichwrap'     + ""            left-right movements don't wrap
-       'wildchar'      + CTRL-E        only when the current value is <Tab>
+       'joinspaces'    + on            insert 2 spaces after period
+       'modeline'      & off           no modelines
+       'more'          & off           no pauses in listings
+       'mzquantum'     - {unchanged}   {set vim default only on resetting 'cp'}
+       'numberwidth'   & 8             min number of columns for line number
+       'preserveindent'+ off           don't preserve current indent structure
+                                               when changing it
+       'revins'        + off           no reverse insert
+       'ruler'         + off           no ruler
+       'scrolljump'    + 1             no jump scroll
+       'scrolloff'     + 0             no scroll offset
+       'shelltemp'     - {unchanged}   {set vim default only on resetting 'cp'}
+       'shiftround'    + off           indent not rounded to shiftwidth
+       'shortmess'     & ""            no shortening of messages
+       'showcmd'       & off           command characters not shown
+       'showmode'      & off           current mode not shown
+       'sidescrolloff' + 0             cursor moves to edge of screen in scroll
+       'smartcase'     + off           no automatic ignore case switch
+       'smartindent'   + off           no smart indentation
+       'smarttab'      + off           no smart tab size
+       'softtabstop'   + 0             tabs are always 'tabstop' positions
+       'startofline'   + on            goto startofline with some commands
+       'tagcase'       & "followic"    'ignorecase' when searching tags file
+       'tagrelative'   & off           tag file names are not relative
+       'termguicolors' + off           don't use highlight-(guifg|guibg)
+       'textauto'      & off           no automatic textmode detection
+       'textwidth'     + 0             no automatic line wrap
+       'tildeop'       + off           tilde is not an operator
+       'ttimeout'      + off           no terminal timeout
+       'undofile'      + off           don't use an undo file
+       'viminfo'       - {unchanged}   {set Vim default only on resetting 'cp'}
+       'virtualedit'   + ""            cursor can only be placed on characters
+       'whichwrap'     & ""            left-right movements don't wrap
+       'wildchar'      & CTRL-E        only when the current value is <Tab>
                                        use CTRL-E for cmdline completion
-       'writebackup'     on or off     depends on the |+writebackup| feature
+       'writebackup'   + on or off     depends on the |+writebackup| feature
 
                                                *'complete'* *'cpt'* *E535*
 'complete' 'cpt'       string  (default: ".,w,b,u,t,i")
@@ -1960,7 +2003,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        existing line.  'expandtab' has no effect on these characters, a Tab
        remains a Tab.  If the new indent is greater than on the existing
        line, the remaining space is filled in the normal manner.
-       NOTE: 'copyindent' is reset when 'compatible' is set.
+       NOTE: This option is reset when 'compatible' is set.
        Also see 'preserveindent'.
 
                                                *'cpoptions'* *'cpo'* *cpo*
@@ -2321,6 +2364,7 @@ A jump table for the options with a short description can be found at |Q_op|.
                        {not in Vi}
        Determines how many components of the path to show in a list of tags.
        See |cscopepathcomp|.
+       NOTE: This option is set to 0 when 'compatible' is set.
 
                                                *'cscopeprg'* *'csprg'*
 'cscopeprg' 'csprg'    string  (default "cscope")
@@ -2350,6 +2394,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        In the absence of a prefix (-P) for cscope. setting this option enables
        to use the basename of cscope.out path as the prefix.
        See |cscoperelative|.
+       NOTE: This option is reset when 'compatible' is set.
 
                                *'cscopetag'* *'cst'* *'nocscopetag'* *'nocst'*
 'cscopetag' 'cst'      boolean (default off)
@@ -2469,6 +2514,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        This is useful for Arabic, Hebrew and many other languages where one
        may have combining characters overtop of base characters, and want
        to remove only the combining ones.
+       NOTE: This option is reset when 'compatible' is set.
 
                                                *'dictionary'* *'dict'*
 'dictionary' 'dict'    string  (default "")
@@ -2684,8 +2730,8 @@ A jump table for the options with a short description can be found at |Q_op|.
        This option cannot be set from a |modeline|.  It would most likely
        corrupt the text.
 
-       NOTE: For GTK+ 2 it is highly recommended to set 'encoding' to
-       "utf-8".  Although care has been taken to allow different values of
+       NOTE: For GTK+ 2 or later, it is highly recommended to set 'encoding'
+       to "utf-8".  Although care has been taken to allow different values of
        'encoding', "utf-8" is the natural choice for the environment and
        avoids unnecessary conversion overhead.  "utf-8" has not been made
        the default to prevent different behavior of the GUI and terminal
@@ -2883,6 +2929,8 @@ A jump table for the options with a short description can be found at |Q_op|.
        done when writing the file.  For reading see below.
        When 'fileencoding' is empty, the same value as 'encoding' will be
        used (no conversion when reading or writing a file).
+       No error will be given when the value is set, only when it is used,
+       only when writing a file.
        Conversion will also be done when 'encoding' and 'fileencoding' are
        both a Unicode encoding and 'fileencoding' is not utf-8.  That's
        because internally Unicode is always stored as utf-8.
@@ -3387,6 +3435,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        The expression will be evaluated in the |sandbox| when set from a
        modeline, see |sandbox-option|.  That stops the option from working,
        since changing the buffer text is not allowed.
+       NOTE: This option is set to "" when 'compatible' is set.
 
                                        *'formatoptions'* *'fo'*
 'formatoptions' 'fo'   string (Vim default: "tcq", Vi default: "vt")
@@ -3417,7 +3466,7 @@ A jump table for the options with a short description can be found at |Q_op|.
 
                                                *'formatprg'* *'fp'*
 'formatprg' 'fp'       string (default "")
-                       global
+                       global or local to buffer |global-local|
                        {not in Vi}
        The name of an external program that will be used to format the lines
        selected with the |gq| operator.  The program must take the input on
@@ -3596,6 +3645,14 @@ A jump table for the options with a short description can be found at |Q_op|.
        On systems where 'guifontset' is supported (X11) and 'guifontset' is
        not empty, then 'guifont' is not used.
 
+       Note: As to the GTK GUIs, no error is given against any invalid names,
+       and the first element of the list is always picked up and made use of.
+       This is because, instead of identifying a given name with a font, the
+       GTK GUIs use it to construct a pattern and try to look up a font which
+       best matches the pattern among available fonts, and this way, the
+       matching never fails.  An invalid name doesn't matter because a number
+       of font properties other than name will do to get the matching done.
+
        Spaces after a comma are ignored.  To include a comma in a font name
        precede it with a backslash.  Setting an option requires an extra
        backslash before a space and a backslash.  See also
@@ -3618,7 +3675,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        The font name depends on the GUI used.  See |setting-guifont| for a
        way to set 'guifont' for various systems.
 
-       For the GTK+ 2 GUI the font name looks like this: >
+       For the GTK+ 2 and 3 GUIs, the font name looks like this: >
            :set guifont=Andale\ Mono\ 11
 <      That's all.  XLFDs are not used.  For Chinese this is reported to work
        well: >
@@ -3627,13 +3684,15 @@ A jump table for the options with a short description can be found at |Q_op|.
              set guifontwide=Microsoft\ Yahei\ 12,WenQuanYi\ Zen\ Hei\ 12
            endif
 <
+        (Replace gui_gtk2 with gui_gtk3 for the GTK+ 3 GUI)
+
        For Mac OSX you can use something like this: >
            :set guifont=Monaco:h10
 <      Also see 'macatsui', it can help fix display problems.
                                                                *E236*
        Note that the fonts must be mono-spaced (all characters have the same
-       width).  An exception is GTK 2: all fonts are accepted, but
-       mono-spaced fonts look best.
+       width).  An exception is GTK: all fonts are accepted, but mono-spaced
+       fonts look best.
 
        To preview a font on X11, you might be able to use the "xfontsel"
        program.  The "xlsfonts" program gives a list of all available fonts.
@@ -3671,7 +3730,7 @@ A jump table for the options with a short description can be found at |Q_op|.
                        {not in Vi}
                        {only available when compiled with GUI enabled and
                        with the |+xfontset| feature}
-                       {not available in the GTK+ GUI}
+                       {not available in the GTK+ GUI}
        When not empty, specifies two (or more) fonts to be used.  The first
        one for normal English, the second one for your special language.  See
        |xfontset|.
@@ -3700,7 +3759,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        Note: The size of these fonts must be exactly twice as wide as the one
        specified with 'guifont' and the same height.
 
-       All GUI versions but GTK+ 2:
+       All GUI versions but GTK+:
 
        'guifontwide' is only used when 'encoding' is set to "utf-8" and
        'guifontset' is empty or invalid.
@@ -3708,7 +3767,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        'guifontwide' is empty Vim will attempt to find a matching
        double-width font and set 'guifontwide' to it.
 
-       GTK+ 2 GUI only:                        *guifontwide_gtk2*
+       GTK+ GUI only:                          *guifontwide_gtk*
 
        If set and valid, 'guifontwide' is always used for double width
        characters, even if 'encoding' is not set to "utf-8".
@@ -3871,6 +3930,8 @@ A jump table for the options with a short description can be found at |Q_op|.
 
        The format of this option is like that of 'statusline'.
        'guitabtooltip' is used for the tooltip, see below.
+       The expression will be evaluated in the |sandbox| when set from a
+       modeline, see |sandbox-option|.
 
        Only used when the GUI tab pages line is displayed.  'e' must be
        present in 'guioptions'.  For the non-GUI tab pages line 'tabline' is
@@ -4034,31 +4095,6 @@ A jump table for the options with a short description can be found at |Q_op|.
        define one.  The default uses a different group for each occasion.
        See |highlight-default| for the default highlight groups.
 
-                                *'hlsearch'* *'hls'* *'nohlsearch'* *'nohls'*
-'hlsearch' 'hls'       boolean (default off)
-                       global
-                       {not in Vi}
-                       {not available when compiled without the
-                       |+extra_search| feature}
-       When there is a previous search pattern, highlight all its matches.
-       The type of highlighting used can be set with the 'l' occasion in the
-       'highlight' option.  This uses the "Search" highlight group by
-       default.  Note that only the matching text is highlighted, any offsets
-       are not applied.
-       See also: 'incsearch' and |:match|.
-       When you get bored looking at the highlighted matches, you can turn it
-       off with |:nohlsearch|.  This does not change the option value, as
-       soon as you use a search command, the highlighting comes back.
-       'redrawtime' specifies the maximum time spent on finding matches.
-       When the search pattern can match an end-of-line, Vim will try to
-       highlight all of the matched text.  However, this depends on where the
-       search starts.  This will be the first line in the window or the first
-       line below a closed fold.  A match in a previous line which is not
-       drawn may not continue in a newly drawn line.
-       You can specify whether the highlight status is restored on startup
-       with the 'h' flag in 'viminfo' |viminfo-h|.
-       NOTE: This option is reset when 'compatible' is set.
-
                                                *'history'* *'hi'*
 'history' 'hi'         number  (Vim default: 50, Vi default: 0,
                                                 set to 200 in |defaults.vim|)
@@ -4093,6 +4129,31 @@ A jump table for the options with a short description can be found at |Q_op|.
        See |rileft.txt|.
        NOTE: This option is reset when 'compatible' is set.
 
+                                *'hlsearch'* *'hls'* *'nohlsearch'* *'nohls'*
+'hlsearch' 'hls'       boolean (default off)
+                       global
+                       {not in Vi}
+                       {not available when compiled without the
+                       |+extra_search| feature}
+       When there is a previous search pattern, highlight all its matches.
+       The type of highlighting used can be set with the 'l' occasion in the
+       'highlight' option.  This uses the "Search" highlight group by
+       default.  Note that only the matching text is highlighted, any offsets
+       are not applied.
+       See also: 'incsearch' and |:match|.
+       When you get bored looking at the highlighted matches, you can turn it
+       off with |:nohlsearch|.  This does not change the option value, as
+       soon as you use a search command, the highlighting comes back.
+       'redrawtime' specifies the maximum time spent on finding matches.
+       When the search pattern can match an end-of-line, Vim will try to
+       highlight all of the matched text.  However, this depends on where the
+       search starts.  This will be the first line in the window or the first
+       line below a closed fold.  A match in a previous line which is not
+       drawn may not continue in a newly drawn line.
+       You can specify whether the highlight status is restored on startup
+       with the 'h' flag in 'viminfo' |viminfo-h|.
+       NOTE: This option is reset when 'compatible' is set.
+
                                                *'icon'* *'noicon'*
 'icon'                 boolean (default off, on when title can be restored)
                        global
@@ -4372,7 +4433,7 @@ A jump table for the options with a short description can be found at |Q_op|.
 <      Error messages will be suppressed, unless the 'debug' option contains
        "msg".
        See |indent-expression|.
-       NOTE: This option is made empty when 'compatible' is set.
+       NOTE: This option is set to "" when 'compatible' is set.
 
        The expression will be evaluated in the |sandbox| when set from a
        modeline, see |sandbox-option|.
@@ -4947,6 +5008,25 @@ A jump table for the options with a short description can be found at |Q_op|.
        This option cannot be set from a |modeline| or in the |sandbox|, for
        security reasons.
 
+                                       *'makeencoding'* *'menc'*
+'makeencoding' 'menc'  string  (default "")
+                       global or local to buffer |global-local|
+                       {only available when compiled with the |+multi_byte|
+                       feature}
+                       {not in Vi}
+       Encoding used for reading the output of external commands.  When empty,
+       encoding is not converted.
+       This is used for `:make`, `:lmake`, `:grep`, `:lgrep`, `:grepadd`,
+       `:lgrepadd`, `:cfile`, `:cgetfile`, `:caddfile`, `:lfile`, `:lgetfile`,
+       and `:laddfile`.
+
+       This would be mostly useful when you use MS-Windows and set 'encoding'
+       to "utf-8".  If |+iconv| is enabled and GNU libiconv is used, setting
+       'makeencoding' to "char" has the same effect as setting to the system
+       locale encoding.  Example: >
+               :set encoding=utf-8
+               :set makeencoding=char  " system locale is used
+<
                                                *'makeprg'* *'mp'*
 'makeprg' 'mp'         string  (default "make", VMS: "MMS")
                        global or local to buffer |global-local|
@@ -5019,6 +5099,8 @@ A jump table for the options with a short description can be found at |Q_op|.
        catches endless recursion.  When using a recursive function with
        more depth, set 'maxfuncdepth' to a bigger number.  But this will use
        more memory, there is the danger of failing when memory is exhausted.
+       Increasing this limit above 200 also changes the maximum for Ex
+       command resursion, see |E169|.
        See also |:function|.
 
                                                *'maxmapdepth'* *'mmd'* *E223*
@@ -5140,7 +5222,7 @@ A jump table for the options with a short description can be found at |Q_op|.
                        {not in Vi}             *E21*
        When off the buffer contents cannot be changed.  The 'fileformat' and
        'fileencoding' options also can't be changed.
-       Can be reset with the |-M| command line argument.
+       Can be reset on startup with the |-M| command line argument.
 
                                *'modified'* *'mod'* *'nomodified'* *'nomod'*
 'modified' 'mod'       boolean (default off)
@@ -5342,6 +5424,8 @@ A jump table for the options with a short description can be found at |Q_op|.
                        feature}
        The number of milliseconds between polls for MzScheme threads.
        Negative or zero value means no thread scheduling.
+       NOTE: This option is set to the Vim default value when 'compatible'
+       is reset.
 
                                                        *'nrformats'* *'nf'*
 'nrformats' 'nf'       string  (default "bin,octal,hex",
@@ -5407,7 +5491,8 @@ A jump table for the options with a short description can be found at |Q_op|.
        is set. Thus with the Vim default of 4 there is room for a line number
        up to 999. When the buffer has 1000 lines five columns will be used.
        The minimum value is 1, the maximum value is 10.
-       NOTE: 'numberwidth' is reset to 8 when 'compatible' is set.
+       NOTE: This option is set to the Vi default value when 'compatible' is
+       set and to the Vim default value when 'compatible' is reset.
 
                                                *'omnifunc'* *'ofu'*
 'omnifunc' 'ofu'       string  (default: empty)
@@ -5647,7 +5732,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        a Tab.
        NOTE: When using ">>" multiple times the resulting indent is a mix of
        tabs and spaces.  You might not like this.
-       NOTE: 'preserveindent' is reset when 'compatible' is set.
+       NOTE: This option is reset when 'compatible' is set.
        Also see 'copyindent'.
        Use |:retab| to clean up white space.
 
@@ -5699,6 +5784,8 @@ A jump table for the options with a short description can be found at |Q_op|.
                        and |+postscript| features}
        Expression used to print the PostScript produced with |:hardcopy|.
        See |pexpr-option|.
+       This option cannot be set from a |modeline| or in the |sandbox|, for
+       security reasons.
 
                                                *'printfont'* *'pfn'*
 'printfont' 'pfn'      string  (default "courier")
@@ -5783,6 +5870,34 @@ A jump table for the options with a short description can be found at |Q_op|.
        This option cannot be set from a |modeline| or in the |sandbox|, for
        security reasons.
 
+                                               *'pyxversion'* *'pyx'*
+'pyxversion' 'pyx'     number  (default depends on the build)
+                       global
+                       {not in Vi}
+                       {only available when compiled with the |+python| or
+                       the |+python3| feature}
+       Specifies the python version used for pyx* functions and commands
+       |python_x|.  The default value is as follows:
+
+               Compiled with                Default ~
+               |+python| and |+python3|        0
+               only |+python|                  2
+               only |+python3|                 3
+
+       Available values are 0, 2 and 3.
+       If 'pyxversion' is 0, it is set to 2 or 3 after the first execution of
+       any python2/3 commands or functions.  E.g. `:py` sets to 2, and `:py3`
+       sets to 3. `:pyx` sets it to 3 if Python 3 is available, otherwise sets
+       to 2 if Python 2 is available.
+       See also: |has-pythonx|
+
+       If Vim is compiled with only |+python| or |+python3| setting
+       'pyxversion' has no effect.  The pyx* functions and commands are
+       always the same as the compiled version.
+
+       This option cannot be set from a |modeline| or in the |sandbox|, for
+       security reasons.
+
                                                *'quoteescape'* *'qe'*
 'quoteescape' 'qe'     string  (default "\")
                        local to buffer
@@ -5803,6 +5918,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        buffer, unless the 'Z' flag is in 'cpoptions'.
        {not in Vi:}  When using the ":view" command the 'readonly' option is
        set for the newly edited buffer.
+       See 'modifiable' for disallowing changes to the buffer.
 
                                                *'redrawtime'* *'rdt'*
 'redrawtime' 'rdt'     number  (default 2000)
@@ -6354,9 +6470,6 @@ A jump table for the options with a short description can be found at |Q_op|.
        "-f" is not inside the quotes, because it is not part of the command
        name.  And Vim automagically recognizes the backslashes that are path
        separators.
-       For Dos 32 bits (DJGPP), you can set the $DJSYSFLAGS environment
-       variable to change the way external commands are executed.  See the
-       libc.inf file of DJGPP.
        Under MS-Windows, when the executable ends in ".com" it must be
        included.  Thus setting the shell to "command.com" or "4dos.com"
        works, but "command" and "4dos" do not work for all commands (e.g.,
@@ -6376,8 +6489,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        Flag passed to the shell to execute "!" and ":!" commands; e.g.,
        "bash.exe -c ls" or "command.com /c dir".  For the MS-DOS-like
        systems, the default is set according to the value of 'shell', to
-       reduce the need to set this option by the user.  It's not used for
-       OS/2 (EMX figures this out itself).
+       reduce the need to set this option by the user.
        On Unix it can have more than one flag.  Each white space separated
        part is passed as an argument to the shell command.
        See |option-backslash| about including spaces and backslashes.
@@ -6496,6 +6608,8 @@ A jump table for the options with a short description can be found at |Q_op|.
        'shelltemp' is off.
        The `system()` function does not respect this option and always uses
        temp files.
+       NOTE: This option is set to the Vim default value when 'compatible'
+       is reset.
 
                                                *'shelltype'* *'st'*
 'shelltype' 'st'       number  (default 0)
@@ -6812,7 +6926,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        mapping: ":inoremap # X^H#", where ^H is entered with CTRL-V CTRL-H.
        When using the ">>" command, lines starting with '#' are not shifted
        right.
-       NOTE: 'smartindent' is reset when 'compatible' is set.
+       NOTE: This option is reset when 'compatible' is set.
        This option is reset when 'paste' is set and restored when 'paste' is
        reset.
 
@@ -7000,7 +7114,7 @@ A jump table for the options with a short description can be found at |Q_op|.
                        word.  The expression must evaluate to a List of
                        Lists, each with a suggestion and a score.
                        Example:
-                               [['the', 33], ['that', 44]]
+                               [['the', 33], ['that', 44]] ~
                        Set 'verbose' and use |z=| to see the scores that the
                        internal methods use.  A lower score is better.
                        This may invoke |spellsuggest()| if you temporarily
@@ -7467,6 +7581,8 @@ A jump table for the options with a short description can be found at |Q_op|.
           ignore       Ignore case
           match        Match case
           smart        Ignore case unless an upper case letter is used
+       NOTE: This option is set to the Vi default value when 'compatible' is
+       set and to the Vim default value when 'compatible' is reset.
 
                                                *'taglength'* *'tl'*
 'taglength' 'tl'       number  (default 0)
@@ -7571,7 +7687,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        For further details see |arabic.txt|.
 
                                        *'termencoding'* *'tenc'*
-'termencoding' 'tenc'  string  (default ""; with GTK+ GUI: "utf-8"; with
+'termencoding' 'tenc'  string  (default ""; with GTK+ GUI: "utf-8"; with
                                                    Macintosh GUI: "macroman")
                        global
                        {only available when compiled with the |+multi_byte|
@@ -7583,7 +7699,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        display).  Except for the Mac when 'macatsui' is off, then
        'termencoding' should be "macroman".
                                                                *E617*
-       Note: This does not apply to the GTK+ GUI.  After the GUI has been
+       Note: This does not apply to the GTK+ GUI.  After the GUI has been
        successfully initialized, 'termencoding' is forcibly set to "utf-8".
        Any attempts to set a different value will be rejected, and an error
        message is shown.
@@ -7613,6 +7729,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        compatible terminal.
        If setting this option does not work (produces a colorless UI)
        reading |xterm-true-color| might help.
+       NOTE: This option is reset when 'compatible' is set.
 
                                                *'terse'* *'noterse'*
 'terse'                        boolean (default off)
@@ -7688,7 +7805,7 @@ A jump table for the options with a short description can be found at |Q_op|.
 'timeout' 'to'         boolean (default on)
                        global
                                                *'ttimeout'* *'nottimeout'*
-'ttimeout'             boolean (default off, set in |defaults.vim|))
+'ttimeout'             boolean (default off, set in |defaults.vim|)
                        global
                        {not in Vi}
        These two options together determine the behavior when part of a
@@ -7723,7 +7840,7 @@ A jump table for the options with a short description can be found at |Q_op|.
                        global
                        {not in all versions of Vi}
                                                *'ttimeoutlen'* *'ttm'*
-'ttimeoutlen' 'ttm'    number  (default -1, set to 100 in |defaults.vim|))
+'ttimeoutlen' 'ttm'    number  (default -1, set to 100 in |defaults.vim|)
                        global
                        {not in Vi}
        The time in milliseconds that is waited for a key code or mapped key
@@ -7818,7 +7935,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        Amiga console, Win32 console, all GUI versions and terminals with a
        non-empty 't_ts' option).
        When Vim was compiled with HAVE_X11 defined, the original title will
-       be restored if possible |X11|.
+       be restored if possible, see |X11|.
        When this option contains printf-style '%' items, they will be
        expanded according to the rules used for 'statusline'.
        Example: >
@@ -7866,7 +7983,7 @@ A jump table for the options with a short description can be found at |Q_op|.
 'toolbariconsize' 'tbis'       string  (default "small")
                                global
                                {not in Vi}
-                               {only in the GTK+ GUI}
+                               {only in the GTK+ GUI}
        Controls the size of toolbar icons.  The possible values are:
                tiny            Use tiny icons.
                small           Use small icons (default).
@@ -8023,6 +8140,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        The undo file is not read when 'undoreload' causes the buffer from
        before a reload to be saved for undo.
        When 'undofile' is turned off the undo file is NOT deleted.
+       NOTE: This option is reset when 'compatible' is set.
 
                                                *'undolevels'* *'ul'*
 'undolevels' 'ul'      number  (default 100, 1000 for Unix, VMS,
@@ -8278,6 +8396,8 @@ A jump table for the options with a short description can be found at |Q_op|.
 
        This option cannot be set from a |modeline| or in the |sandbox|, for
        security reasons.
+       NOTE: This option is set to the Vim default value when 'compatible'
+       is reset.
 
                                            *'virtualedit'* *'ve'*
 'virtualedit' 've'     string  (default "")
@@ -8306,6 +8426,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        The `g$` command will move to the end of the screen line.
        It doesn't make sense to combine "all" with "onemore", but you will
        not get a warning for it.
+       NOTE: This option is set to "" when 'compatible' is set.
 
                        *'visualbell'* *'vb'* *'novisualbell'* *'novb'* *beep*
 'visualbell' 'vb'      boolean (default off)
index 82e4d75..53010b1 100644 (file)
@@ -12,11 +12,12 @@ NOTE: This file is a bit outdated.  You might find more useful info here:
        http://macvim.org/
 
 1. Filename Convention         |mac-filename|
-2. .vimrc an .vim files                |mac-vimfile|
-3. FAQ                         |mac-faq|
-4. Known Lack                  |mac-lack|
-5. Mac Bug Report              |mac-bug|
-6. Compiling Vim               |mac-compile|
+2. .vimrc and .vim files       |mac-vimfile|
+3. Standard mappings           |mac-standard-mappings|
+4. FAQ                         |mac-faq|
+5. Known Lack                  |mac-lack|
+6. Mac Bug Report              |mac-bug|
+7. Compiling Vim               |mac-compile|
 
 There was a Mac port for version 3.0 of Vim.  Here are the first few lines
 from the old file:
@@ -72,7 +73,18 @@ the |'nocompatible'| option is set, otherwise it will only handle mac format
 files.
 
 ==============================================================================
-3. Mac FAQ                                             *mac-faq*
+3. Standard mappings                           *mac-standard-mappings*
+
+The following mappings are available for cut/copy/paste from/to clipboard.
+
+key            Normal  Visual    Insert        Description ~
+Command-v      "*P     "-d"*P    <C-R>*        paste text       *<D-v>*
+Command-c              "*y                     copy Visual text *<D-c>*
+Command-x              "*d                     cut Visual text  *<D-x>*
+Backspace              "*d                     cut Visual text
+
+==============================================================================
+4. Mac FAQ                                             *mac-faq*
 
 On the internet:  http://macvim.org/OSX/index.php#FAQ
 
@@ -95,13 +107,13 @@ A: The following trick works with most shells.  Put it in your vimrc file.
        let $PATH = matchstr(s:path, 'VIMPATH\zs.\{-}\ze\n')
 
 ==============================================================================
-4. Mac Lack                                            *mac-lack*
+5. Mac Lack                                            *mac-lack*
 
 In a terminal CTRL-^ needs to be entered as Shift-Control-6.  CTRL-@ as
 Shift-Control-2.
 
 ==============================================================================
-5. Mac Bug Report                                      *mac-bug*
+6. Mac Bug Report                                      *mac-bug*
 
 When reporting any Mac specific bug or feature change, please use the vim-mac
 maillist |vim-mac|.  However, you need to be subscribed.  An alternative is to
@@ -110,7 +122,7 @@ send a message to the current MacVim maintainers:
        mac@vim.org
 
 ==============================================================================
-6. Compiling Vim                                       *mac-compile*
+7. Compiling Vim                                       *mac-compile*
 
 See the file "src/INSTALLmac.txt" that comes with the source files.
 
index 7357542..98b37d0 100644 (file)
@@ -1,4 +1,4 @@
-*os_win32.txt*  For Vim version 8.0.  Last change: 2016 Oct 12
+*os_win32.txt*  For Vim version 8.0.  Last change: 2017 Mar 21
 
 
                  VIM REFERENCE MANUAL    by George Reilly
@@ -212,10 +212,19 @@ A. You can't!  This is a limitation of the NT console.  NT 5.0 is reported to
    be able to set the blink rate for all console windows at the same time.
 
                                                        *:!start*
-Q. How can I run an external command or program asynchronously?
-A. When using :! to run an external command, you can run it with "start": >
-       :!start winfile.exe<CR>
-<  Using "start" stops Vim switching to another screen, opening a new console,
+Q. How can I asynchronously run an external command or program, or open a
+   document or URL with its default program?
+A. When using :! to run an external command, you can run it with "start". For
+   example, to run notepad: >
+       :!start notepad
+<   To open "image.jpg" with the default image viewer: >
+        :!start image.jpg
+<   To open the folder of the current file in Windows Explorer: >
+        :!start %:h
+<   To open the Vim home page with the default browser: >
+        :!start http://www.vim.org/
+<
+   Using "start" stops Vim switching to another screen, opening a new console,
    or waiting for the program to complete; it indicates that you are running a
    program that does not affect the files you are editing.  Programs begun
    with :!start do not get passed Vim's open file handles, which means they do
index 7c834b3..d676409 100644 (file)
@@ -1,4 +1,4 @@
-*pattern.txt*   For Vim version 8.0.  Last change: 2016 Sep 11
+*pattern.txt*   For Vim version 8.0.  Last change: 2017 Mar 29
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -869,10 +869,13 @@ $ At end of pattern or in front of "\|", "\)" or "\n" ('magic' on):
 \%V    Match inside the Visual area.  When Visual mode has already been
        stopped match in the area that |gv| would reselect.
        This is a |/zero-width| match.  To make sure the whole pattern is
-       inside the Visual area put it at the start and end of the pattern,
-       e.g.: >
+       inside the Visual area put it at the start and just before the end of
+       the pattern, e.g.: >
+               /\%Vfoo.*ba\%Vr
+<      This also works if only "foo bar" was Visually selected. This: >
                /\%Vfoo.*bar\%V
-<      Only works for the current buffer.
+<      would match "foo bar" if the Visual selection continues after the "r".
+       Only works for the current buffer.
 
                                                */\%#* *cursor-position*
 \%#    Matches with the cursor position.  Only works when matching in a
@@ -1082,25 +1085,27 @@ x       A single character, with no special meaning, matches itself
        - A character class expression is evaluated to the set of characters
          belonging to that character class.  The following character classes
          are supported:
-                         Name          Contents ~
-*[:alnum:]*              [:alnum:]     ASCII letters and digits
-*[:alpha:]*              [:alpha:]     ASCII letters
-*[:blank:]*              [:blank:]     space and tab characters
-*[:cntrl:]*              [:cntrl:]     control characters
-*[:digit:]*              [:digit:]     decimal digits
-*[:graph:]*              [:graph:]     printable characters excluding space
-*[:lower:]*              [:lower:]     lowercase letters (all letters when
+                 Name        Func      Contents ~
+*[:alnum:]*      [:alnum:]   isalnum   ASCII letters and digits
+*[:alpha:]*      [:alpha:]   isalpha   ASCII letters
+*[:blank:]*      [:blank:]             space and tab
+*[:cntrl:]*      [:cntrl:]   iscntrl   ASCII control characters
+*[:digit:]*      [:digit:]             decimal digits '0' to '9'
+*[:graph:]*      [:graph:]   isgraph   ASCII printable characters excluding
+                                       space
+*[:lower:]*      [:lower:]   (1)       lowercase letters (all letters when
                                        'ignorecase' is used)
-*[:print:]*              [:print:]     printable characters including space
-*[:punct:]*              [:punct:]     ASCII punctuation characters
-*[:space:]*              [:space:]     whitespace characters
-*[:upper:]*              [:upper:]     uppercase letters (all letters when
+*[:print:]*      [:print:]   (2)       printable characters including space
+*[:punct:]*      [:punct:]   ispunct   ASCII punctuation characters
+*[:space:]*      [:space:]             whitespace characters: space, tab, CR,
+                                       NL, vertical tab, form feed
+*[:upper:]*      [:upper:]   (3)       uppercase letters (all letters when
                                        'ignorecase' is used)
-*[:xdigit:]*             [:xdigit:]    hexadecimal digits
-*[:return:]*             [:return:]    the <CR> character
-*[:tab:]*                [:tab:]       the <Tab> character
-*[:escape:]*             [:escape:]    the <Esc> character
-*[:backspace:]*                  [:backspace:] the <BS> character
+*[:xdigit:]*     [:xdigit:]            hexadecimal digits: 0-9, a-f, A-F
+*[:return:]*     [:return:]            the <CR> character
+*[:tab:]*        [:tab:]               the <Tab> character
+*[:escape:]*     [:escape:]            the <Esc> character
+*[:backspace:]*          [:backspace:]         the <BS> character
          The brackets in character class expressions are additional to the
          brackets delimiting a collection.  For example, the following is a
          plausible pattern for a UNIX filename: "[-./[:alnum:]_~]\+" That is,
@@ -1111,6 +1116,13 @@ x        A single character, with no special meaning, matches itself
          regexp engine.  See |two-engines|.  In the future these items may
          work for multi-byte characters.  For now, to get all "alpha"
          characters you can use: [[:lower:][:upper:]].
+
+         The "Func" column shows what library function is used.  The
+         implementation depends on the system.  Otherwise:
+         (1) Uses islower() for ASCII and Vim builtin rules for other
+         characters when built with the |+multi_byte| feature.
+         (2) Uses Vim builtin rules
+         (3) As with (1) but using isupper()
                                                        */[[=* *[==]*
        - An equivalence class.  This means that characters are matched that
          have almost the same meaning, e.g., when ignoring accents.  This
index 7049570..d8f63ac 100644 (file)
@@ -1,4 +1,4 @@
-*pi_gzip.txt*   For Vim version 8.0.  Last change: 2016 Oct 30
+*pi_gzip.txt*   For Vim version 8.0.  Last change: 2016 Nov 06
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -28,6 +28,7 @@ with these extensions:
        *.lzma          lzma
        *.xz            xz
        *.lz            lzip
+       *.zst           zstd
 
 That's actually the only thing you need to know.  There are no options.
 
index d2eac80..f8d6662 100644 (file)
@@ -1,4 +1,4 @@
-*logiPat.txt*  Logical Patterns                                Jun 22, 2015
+*pi_logipat.txt*       Logical Patterns                        Jun 22, 2015
 
 Author:  Charles E. Campbell  <NdrOchip@ScampbellPfamily.AbizM>
 Copyright: (c) 2004-2015 by Charles E. Campbell        *logiPat-copyright*
index 39a0b86..0ee2466 100644 (file)
@@ -1,4 +1,4 @@
-*quickfix.txt*  For Vim version 8.0.  Last change: 2016 Nov 04
+*quickfix.txt*  For Vim version 8.0.  Last change: 2017 Mar 06
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -45,10 +45,13 @@ The 'errorformat' option should be set to match the error messages from your
 compiler (see |errorformat| below).
 
                                                *location-list* *E776*
-A location list is similar to a quickfix list and contains a list of positions
-in files.  A location list is associated with a window and each window can
-have a separate location list.  A location list can be associated with only
-one window.  The location list is independent of the quickfix list.
+A location list is a window-local quickfix list. You get one after commands
+like `:lvimgrep`, `:lgrep`, `:lhelpgrep`, `:lmake`, etc., which create a
+location list instead of a quickfix list as the corresponding `:vimgrep`,
+`:grep`, `:helpgrep`, `:make` do.
+A location list is associated with a window and each window can have a
+separate location list.  A location list can be associated with only one
+window.  The location list is independent of the quickfix list.
 
 When a window with a location list is split, the new window gets a copy of the
 location list.  When there are no longer any references to a location list,
@@ -164,6 +167,9 @@ processing a quickfix or location list command, it will be aborted.
                        keep Vim running while compiling.  If you give the
                        name of the errorfile, the 'errorfile' option will
                        be set to [errorfile].  See |:cc| for [!].
+                       If the encoding of the error file differs from the
+                       'encoding' option, you can use the 'makeencoding'
+                       option to specify the encoding.
 
                                                        *:lf* *:lfile*
 :lf[ile][!] [errorfile]        Same as ":cfile", except the location list for the
@@ -175,6 +181,9 @@ processing a quickfix or location list command, it will be aborted.
 :cg[etfile] [errorfile]                                        *:cg* *:cgetfile*
                        Read the error file.  Just like ":cfile" but don't
                        jump to the first error.
+                       If the encoding of the error file differs from the
+                       'encoding' option, you can use the 'makeencoding'
+                       option to specify the encoding.
 
 
 :lg[etfile] [errorfile]                                        *:lg* *:lgetfile*
@@ -185,6 +194,9 @@ processing a quickfix or location list command, it will be aborted.
 :caddf[ile] [errorfile]        Read the error file and add the errors from the
                        errorfile to the current quickfix list. If a quickfix
                        list is not present, then a new list is created.
+                       If the encoding of the error file differs from the
+                       'encoding' option, you can use the 'makeencoding'
+                       option to specify the encoding.
 
                                                        *:laddf* *:laddfile*
 :laddf[ile] [errorfile]        Same as ":caddfile", except the location list for the
@@ -320,6 +332,7 @@ use this code: >
        endfunction
 
        au QuickfixCmdPost make call QfMakeConv()
+Another option is using 'makeencoding'.
 
 
 EXECUTE A COMMAND IN ALL THE BUFFERS IN QUICKFIX OR LOCATION LIST:
@@ -586,6 +599,9 @@ lists, use ":cnewer 99" first.
                           like |:cnext| and |:cprevious|, see above.
                        This command does not accept a comment, any "
                        characters are considered part of the arguments.
+                       If the encoding of the program output differs from the
+                       'encoding' option, you can use the 'makeencoding'
+                       option to specify the encoding.
 
                                                        *:lmak* *:lmake*
 :lmak[e][!] [arguments]
@@ -645,6 +661,7 @@ read the error messages: >
        au QuickfixCmdPost make call QfMakeConv()
 
 (Example by Faque Cheng)
+Another option is using 'makeencoding'.
 
 ==============================================================================
 5. Using :vimgrep and :grep                            *grep* *lid*
@@ -759,6 +776,9 @@ id-utils) in a similar way to its compiler integration (see |:make| above).
                        When 'grepprg' is "internal" this works like
                        |:vimgrep|.  Note that the pattern needs to be
                        enclosed in separator characters then.
+                       If the encoding of the program output differs from the
+                       'encoding' option, you can use the 'makeencoding'
+                       option to specify the encoding.
 
                                                            *:lgr* *:lgrep*
 :lgr[ep][!] [arguments]        Same as ":grep", except the location list for the
@@ -783,6 +803,10 @@ id-utils) in a similar way to its compiler integration (see |:make| above).
                                  \ | catch /E480:/
                                  \ | endtry"
 <
+                       If the encoding of the program output differs from the
+                       'encoding' option, you can use the 'makeencoding'
+                       option to specify the encoding.
+
                                                        *:lgrepa* *:lgrepadd*
 :lgrepa[dd][!] [arguments]
                        Same as ":grepadd", except the location list for the
@@ -1399,7 +1423,7 @@ prints information about entering a directory in the form "Making all in dir".
    Making all in dir2            ./dir1/dir2
 
    This can be solved by printing absolute directories in the "enter directory"
-   message or by printing "leave directory" messages..
+   message or by printing "leave directory" messages.
 
 To avoid this problem, ensure to print absolute directory names and "leave
 directory" messages.
index 4ffc836..e64a5f6 100644 (file)
@@ -1,4 +1,4 @@
-*quickref.txt*  For Vim version 8.0.  Last change: 2016 Aug 21
+*quickref.txt*  For Vim version 8.0.  Last change: 2016 Dec 16
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -782,6 +782,7 @@ Short explanation of each option:           *option-list*
 'macatsui'                 Mac GUI: use ATSUI text drawing
 'magic'                            changes special characters in search patterns
 'makeef'         'mef'     name of the errorfile for ":make"
+'makeencoding'   'menc'    encoding of external make/grep commands
 'makeprg'        'mp'      program to use for the ":make" command
 'matchpairs'     'mps'     pairs of characters that "%" can match
 'matchtime'      'mat'     tenths of a second to show matching paren
@@ -835,6 +836,7 @@ Short explanation of each option:           *option-list*
 'pumheight'      'ph'      maximum height of the popup menu
 'pythondll'                name of the Python 2 dynamic library
 'pythonthreedll'           name of the Python 3 dynamic library
+'pyxversion'     'pyx'     Python version used for pyx* commands
 'quoteescape'    'qe'      escape characters used in a string
 'readonly'       'ro'      disallow writing the buffer
 'redrawtime'     'rdt'     timeout for 'hlsearch' and |:match| highlighting
@@ -1067,6 +1069,8 @@ Short explanation of each option:         *option-list*
 |c_<Up>|       <Up>/<Down>        recall older/newer command-line that starts
                                      with current command
 |c_<S-Up>|     <S-Up>/<S-Down>    recall older/newer command-line from history
+|c_CTRL-G|     CTRL-G             next match when 'incsearch' is active
+|c_CTRL-T|     CTRL-T             previous match when 'incsearch' is active
 |:history|     :his[tory]         show older command-lines
 
 Context-sensitive completion on the command-line:
index 86fdd49..cecdd6a 100644 (file)
@@ -1,4 +1,4 @@
-*remote.txt*    For Vim version 8.0.  Last change: 2015 Mar 01
+*remote.txt*    For Vim version 8.0.  Last change: 2017 Mar 18
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -149,6 +149,7 @@ the description in |eval.txt| or use CTRL-] on the function name to jump to
 the full explanation.
 
     synopsis                                explanation ~
+    remote_startserver( name)               run a server
     remote_expr( server, string, idvar)      send expression
     remote_send( server, string, idvar)      send key sequence
     serverlist()                            get a list of available servers
index e704681..8f81053 100644 (file)
@@ -1,4 +1,4 @@
-*repeat.txt*    For Vim version 8.0.  Last change: 2016 Sep 11
+*repeat.txt*    For Vim version 8.0.  Last change: 2017 Feb 06
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -305,6 +305,11 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|.
                        Mark) in utf-8 format Vim will recognize it, no need
                        to use ":scriptencoding utf-8" then.
 
+                       If you set the 'encoding' option in your |.vimrc|,
+                       `:scriptencoding` must be placed after that. E.g.: >
+                               set encoding=utf-8
+                               scriptencoding utf-8
+<
                        When compiled without the |+multi_byte| feature this
                        command is ignored.
                        {not in Vi}
index b3696d3..35301f6 100644 (file)
@@ -1,4 +1,4 @@
-*scroll.txt*    For Vim version 8.0.  Last change: 2006 Aug 27
+*scroll.txt*    For Vim version 8.0.  Last change: 2016 Nov 10
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -108,7 +108,8 @@ z^                  Without [count]: Redraw with the line just above the
 3. Scrolling relative to cursor                                *scroll-cursor*
 
 The following commands reposition the edit window (the part of the buffer that
-you see) while keeping the cursor on the same line:
+you see) while keeping the cursor on the same line.  Note that the 'scrolloff'
+option may cause context lines to show above and below the cursor.
 
                                                        *z<CR>*
 z<CR>                  Redraw, line [count] at top of window (default
@@ -220,7 +221,7 @@ past its buffer's limits.
 However, if a 'scrollbind' window that has a relative offset that is past its
 buffer's limits is given the cursor focus, the other 'scrollbind' windows must
 jump to a location where the current window's relative offset is valid.  This
-behavior can be changed by clearing the 'jump' flag from the 'scrollopt'
+behavior can be changed by clearing the "jump" flag from the 'scrollopt'
 option.
 
                                                *syncbind* *:syncbind* *:sync*
index 8ce3c63..eb1fdc8 100644 (file)
@@ -1,4 +1,4 @@
-*starting.txt*  For Vim version 8.0.  Last change: 2016 Sep 09
+*starting.txt*  For Vim version 8.0.  Last change: 2017 Jan 15
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -230,6 +230,7 @@ a slash.  Thus "-R" means recovery and "-/R" readonly.
                the executable "view" has the same effect as the -R argument.
                The 'updatecount' option will be set to 10000, meaning that
                the swap file will not be updated automatically very often.
+               See |-M| for disallowing modifications.
 
                                                        *-m*
 -m             Modifications not allowed to be written.  The 'write' option
@@ -421,6 +422,10 @@ a slash.  Thus "-R" means recovery and "-/R" readonly.
                not connected to a terminal.  This will avoid the warning and
                the two second delay that would happen. {not in Vi}
 
+                                                       *--ttyfail*
+--ttyfail      When the stdin or stdout is not a terminal (tty) then exit
+               right away.
+
                                                        *-d*
 -d             Start in diff mode, like |vimdiff|.
                {not in Vi} {not available when compiled without the |+diff|
@@ -1215,7 +1220,7 @@ There are several ways to exit Vim:
 - Use `:cquit`.  Also when there are changes.
 
 When using `:cquit` or when there was an error message Vim exits with exit
-code 1.  Errors can be avoided by using `:silent!`.
+code 1.  Errors can be avoided by using `:silent!` or with `:catch`.
 
 ==============================================================================
 8. Saving settings                                     *save-settings*
index 2138f02..4a47c33 100644 (file)
@@ -1,4 +1,4 @@
-*syntax.txt*   For Vim version 8.0.  Last change: 2016 Oct 30
+*syntax.txt*   For Vim version 8.0.  Last change: 2017 Feb 06
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1476,7 +1476,7 @@ algorithm should work in the vast majority of cases.  In some cases, such as a
 file that begins with 500 or more full-line comments, the script may
 incorrectly decide that the fortran code is in fixed form.  If that happens,
 just add a non-comment statement beginning anywhere in the first five columns
-of the first twenty five lines, save (:w) and then reload (:e!) the file.
+of the first twenty-five lines, save (:w) and then reload (:e!) the file.
 
 Tabs in fortran files ~
 Tabs are not recognized by the Fortran standards.  Tabs are not a good idea in
@@ -2646,9 +2646,9 @@ later, and part earlier) adds.
 
 RESTRUCTURED TEXT                      *rst.vim* *ft-rst-syntax*
 
-You may set what syntax definitions should be used for code blocks via
+You may set what syntax definitions should be used for code blocks via >
        let rst_syntax_code_list = ['vim', 'lisp', ...]
-
+<
 
 REXX                                           *rexx.vim* *ft-rexx-syntax*
 
@@ -2933,6 +2933,13 @@ reduce this, the "sh_maxlines" internal variable can be set.  Example: >
 The default is to use the twice sh_minlines.  Set it to a smaller number to
 speed up displaying.  The disadvantage is that highlight errors may appear.
 
+syntax/sh.vim tries to flag certain problems as errors; usually things like
+extra ']'s, 'done's, 'fi's, etc.  If you find the error handling problematic
+for your purposes, you may suppress such error highlighting by putting
+the following line in your .vimrc: >
+
+       let g:sh_no_error= 1
+<
 
                                                *sh-embed*  *sh-awk*
  Sh: EMBEDDING LANGUAGES~
@@ -3235,11 +3242,11 @@ syntax highlighting script handles this with the following logic:
        * If g:tex_stylish exists and is 1
                then the file will be treated as a "sty" file, so the "_"
                will be allowed as part of keywords
-               (irregardless of g:tex_isk)
+               (regardless of g:tex_isk)
        * Else if the file's suffix is sty, cls, clo, dtx, or ltx,
                then the file will be treated as a "sty" file, so the "_"
                will be allowed as part of keywords
-               (irregardless of g:tex_isk)
+               (regardless of g:tex_isk)
 
        * If g:tex_isk exists, then it will be used for the local 'iskeyword'
        * Else the local 'iskeyword' will be set to 48-57,a-z,A-Z,192-255
@@ -3320,8 +3327,8 @@ Some folding is now supported with syntax/vim.vim: >
    g:vimsyn_folding =~ 't' : fold tcl      script
 <
                                                        *g:vimsyn_noerror*
-Not all error highlighting that syntax/vim.vim does may be correct; VimL is a
-difficult language to highlight correctly.  A way to suppress error
+Not all error highlighting that syntax/vim.vim does may be correct; Vim script
+is a difficult language to highlight correctly.  A way to suppress error
 highlighting is to put the following line in your |vimrc|: >
 
        let g:vimsyn_noerror = 1
@@ -3479,6 +3486,8 @@ DEFINING CASE                                             *:syn-case* *E390*
        "ignore".  Note that any items before this are not affected, and all
        items until the next ":syntax case" command are affected.
 
+:sy[ntax] case
+       Show either "syntax case match" or "syntax case ignore" (translated).
 
 SPELL CHECKING                                         *:syn-spell*
 
@@ -3496,6 +3505,11 @@ SPELL CHECKING                                           *:syn-spell*
 
        To activate spell checking the 'spell' option must be set.
 
+:sy[ntax] spell
+       Show either "syntax spell toplevel", "syntax spell notoplevel" or
+       "syntax spell default" (translated).
+
+
 SYNTAX ISKEYWORD SETTING                               *:syn-iskeyword*
 
 :sy[ntax] iskeyword [clear | {option}]
@@ -4089,6 +4103,9 @@ IMPLICIT CONCEAL                                  *:syn-conceal-implicit*
        off" returns to the normal state where the "conceal" flag must be
        given explicitly.
 
+:sy[ntax] conceal
+       Show either "syntax conceal on" or "syntax conceal off" (translated).
+
 ==============================================================================
 7. Syntax patterns                             *:syn-pattern* *E401* *E402*
 
index bc40981..e72388c 100644 (file)
@@ -139,6 +139,10 @@ something else.
                    :+tabclose      " close the next tab page
                    :1tabclose      " close the first tab page
                    :$tabclose      " close the last tab page
+                   :tabclose -2    " close the two previous tab page
+                   :tabclose +     " close the next tab page
+                   :tabclose 3     " close the third tab page
+                   :tabclose $     " close the last tab page
 <
                                                        *:tabo* *:tabonly*
 :tabo[nly][!]  Close all other tab pages.
@@ -153,13 +157,20 @@ something else.
                                    " one
 
 :{count}tabo[nly][!]
-               Close all tab pages except the {count}th one. >
+:tabo[nly][!] {count}
+               Close all tab pages except {count} one. >
                    :.tabonly       " as above
                    :-tabonly       " close all tab pages except the previous
                                    " one
                    :+tabonly       " close all tab pages except the next one
                    :1tabonly       " close all tab pages except the first one
                    :$tabonly       " close all tab pages except the last one
+                   :tabonly -      " close all tab pages except the previous
+                                   " one
+                   :tabonly +2     " close all tab pages except the two next
+                                   " one
+                   :tabonly 1      " close all tab pages except the first one
+                   :tabonly $      " close all tab pages except the last one
 
 
 SWITCHING TO ANOTHER TAB PAGE:
@@ -174,7 +185,20 @@ gt                                 *i_CTRL-<PageDown>* *i_<C-PageDown>*
                Go to the next tab page.  Wraps around from the last to the
                first one.
 
+:{count}tabn[ext]
 :tabn[ext] {count}
+               Go to tab page {count}.  The first tab page has number one. >
+                   :-tabnext   " go to the previous tab page
+                   :+tabnext   " go to the next tab page
+                   :+2tabnext  " go to the two next tab page
+                   :1tabnext   " go to the first tab page
+                   :$tabnext   " go to the last tab page
+                   :tabnext $  " as above
+                   :tabnext -  " go to the previous tab page
+                   :tabnext -1 " as above
+                   :tabnext +  " go to the next tab page
+                   :tabnext +1 " as above
+
 {count}<C-PageDown>
 {count}gt      Go to tab page {count}.  The first tab page has number one.
 
index 166ff59..f128394 100644 (file)
@@ -427,6 +427,7 @@ $VIM_POSIX  vi_diff.txt     /*$VIM_POSIX*
 'macatsui'     options.txt     /*'macatsui'*
 'magic'        options.txt     /*'magic'*
 'makeef'       options.txt     /*'makeef'*
+'makeencoding' options.txt     /*'makeencoding'*
 'makeprg'      options.txt     /*'makeprg'*
 'mat'  options.txt     /*'mat'*
 'matchpairs'   options.txt     /*'matchpairs'*
@@ -439,6 +440,7 @@ $VIM_POSIX  vi_diff.txt     /*$VIM_POSIX*
 'maxmemtot'    options.txt     /*'maxmemtot'*
 'mco'  options.txt     /*'mco'*
 'mef'  options.txt     /*'mef'*
+'menc' options.txt     /*'menc'*
 'menuitems'    options.txt     /*'menuitems'*
 'mesg' vi_diff.txt     /*'mesg'*
 'mfd'  options.txt     /*'mfd'*
@@ -774,6 +776,8 @@ $VIM_POSIX  vi_diff.txt     /*$VIM_POSIX*
 'pvw'  options.txt     /*'pvw'*
 'pythondll'    options.txt     /*'pythondll'*
 'pythonthreedll'       options.txt     /*'pythonthreedll'*
+'pyx'  options.txt     /*'pyx'*
+'pyxversion'   options.txt     /*'pyxversion'*
 'qe'   options.txt     /*'qe'*
 'quote motion.txt      /*'quote*
 'quoteescape'  options.txt     /*'quoteescape'*
@@ -923,6 +927,8 @@ $VIM_POSIX  vi_diff.txt     /*$VIM_POSIX*
 't_AB' term.txt        /*'t_AB'*
 't_AF' term.txt        /*'t_AF'*
 't_AL' term.txt        /*'t_AL'*
+'t_BD' term.txt        /*'t_BD'*
+'t_BE' term.txt        /*'t_BE'*
 't_CS' term.txt        /*'t_CS'*
 't_CV' term.txt        /*'t_CV'*
 't_Ce' term.txt        /*'t_Ce'*
@@ -939,6 +945,7 @@ $VIM_POSIX  vi_diff.txt     /*$VIM_POSIX*
 't_F7' term.txt        /*'t_F7'*
 't_F8' term.txt        /*'t_F8'*
 't_F9' term.txt        /*'t_F9'*
+'t_GP' term.txt        /*'t_GP'*
 't_IE' term.txt        /*'t_IE'*
 't_IS' term.txt        /*'t_IS'*
 't_K1' term.txt        /*'t_K1'*
@@ -961,6 +968,8 @@ $VIM_POSIX  vi_diff.txt     /*$VIM_POSIX*
 't_KJ' term.txt        /*'t_KJ'*
 't_KK' term.txt        /*'t_KK'*
 't_KL' term.txt        /*'t_KL'*
+'t_PE' term.txt        /*'t_PE'*
+'t_PS' term.txt        /*'t_PS'*
 't_RB' term.txt        /*'t_RB'*
 't_RI' term.txt        /*'t_RI'*
 't_RV' term.txt        /*'t_RV'*
@@ -1357,6 +1366,7 @@ $VIM_POSIX        vi_diff.txt     /*$VIM_POSIX*
 --servername   remote.txt      /*--servername*
 --socketid     starting.txt    /*--socketid*
 --startuptime  starting.txt    /*--startuptime*
+--ttyfail      starting.txt    /*--ttyfail*
 --version      starting.txt    /*--version*
 --windowid     starting.txt    /*--windowid*
 -A     starting.txt    /*-A*
@@ -1844,6 +1854,7 @@ $VIM_POSIX        vi_diff.txt     /*$VIM_POSIX*
 :$     cmdline.txt     /*:$*
 :%     cmdline.txt     /*:%*
 :&     change.txt      /*:&*
+:&&    change.txt      /*:&&*
 :'     cmdline.txt     /*:'*
 :,     cmdline.txt     /*:,*
 :.     cmdline.txt     /*:.*
@@ -1917,6 +1928,13 @@ $VIM_POSIX       vi_diff.txt     /*$VIM_POSIX*
 :Print various.txt     /*:Print*
 :Rexplore      pi_netrw.txt    /*:Rexplore*
 :RmVimball     pi_vimball.txt  /*:RmVimball*
+:RustEmitAsm   ft_rust.txt     /*:RustEmitAsm*
+:RustEmitIr    ft_rust.txt     /*:RustEmitIr*
+:RustExpand    ft_rust.txt     /*:RustExpand*
+:RustFmt       ft_rust.txt     /*:RustFmt*
+:RustFmtRange  ft_rust.txt     /*:RustFmtRange*
+:RustPlay      ft_rust.txt     /*:RustPlay*
+:RustRun       ft_rust.txt     /*:RustRun*
 :Sexplore      pi_netrw.txt    /*:Sexplore*
 :TOhtml        syntax.txt      /*:TOhtml*
 :TarDiff       pi_tar.txt      /*:TarDiff*
@@ -2720,6 +2738,10 @@ $VIM_POSIX       vi_diff.txt     /*$VIM_POSIX*
 :pyfile        if_pyth.txt     /*:pyfile*
 :python        if_pyth.txt     /*:python*
 :python3       if_pyth.txt     /*:python3*
+:pythonx       if_pyth.txt     /*:pythonx*
+:pyx   if_pyth.txt     /*:pyx*
+:pyxdo if_pyth.txt     /*:pyxdo*
+:pyxfile       if_pyth.txt     /*:pyxfile*
 :q     editing.txt     /*:q*
 :qa    editing.txt     /*:qa*
 :qall  editing.txt     /*:qall*
@@ -3256,6 +3278,9 @@ $VIM_POSIX        vi_diff.txt     /*$VIM_POSIX*
 <Char> map.txt /*<Char>*
 <CursorHold>   autocmd.txt     /*<CursorHold>*
 <D-    intro.txt       /*<D-*
+<D-c>  os_mac.txt      /*<D-c>*
+<D-v>  os_mac.txt      /*<D-v>*
+<D-x>  os_mac.txt      /*<D-x>*
 <Del>  change.txt      /*<Del>*
 <Down> motion.txt      /*<Down>*
 <Drop> change.txt      /*<Drop>*
@@ -4486,7 +4511,14 @@ E933     eval.txt        /*E933*
 E934   sign.txt        /*E934*
 E935   eval.txt        /*E935*
 E936   autocmd.txt     /*E936*
+E937   autocmd.txt     /*E937*
+E938   eval.txt        /*E938*
+E939   change.txt      /*E939*
 E94    windows.txt     /*E94*
+E940   eval.txt        /*E940*
+E941   eval.txt        /*E941*
+E942   eval.txt        /*E942*
+E943   message.txt     /*E943*
 E95    message.txt     /*E95*
 E96    diff.txt        /*E96*
 E97    diff.txt        /*E97*
@@ -4766,6 +4798,8 @@ W16       message.txt     /*W16*
 W17    arabic.txt      /*W17*
 W18    syntax.txt      /*W18*
 W19    autocmd.txt     /*W19*
+W20    if_pyth.txt     /*W20*
+W21    if_pyth.txt     /*W21*
 WORD   motion.txt      /*WORD*
 WWW    intro.txt       /*WWW*
 Win32  os_win32.txt    /*Win32*
@@ -4993,6 +5027,7 @@ assert_inrange()  eval.txt        /*assert_inrange()*
 assert_match() eval.txt        /*assert_match()*
 assert_notequal()      eval.txt        /*assert_notequal()*
 assert_notmatch()      eval.txt        /*assert_notmatch()*
+assert_report()        eval.txt        /*assert_report()*
 assert_true()  eval.txt        /*assert_true()*
 at     motion.txt      /*at*
 atan() eval.txt        /*atan()*
@@ -5056,6 +5091,7 @@ backup-changed    version4.txt    /*backup-changed*
 backup-extension       version4.txt    /*backup-extension*
 backup-table   editing.txt     /*backup-table*
 balloon-eval   debugger.txt    /*balloon-eval*
+balloon_show() eval.txt        /*balloon_show()*
 bar    motion.txt      /*bar*
 bars   help.txt        /*bars*
 base_font_name_list    mbyte.txt       /*base_font_name_list*
@@ -5248,6 +5284,7 @@ catch-text        eval.txt        /*catch-text*
 cc     change.txt      /*cc*
 ceil() eval.txt        /*ceil()*
 ch.vim syntax.txt      /*ch.vim*
+ch_canread()   eval.txt        /*ch_canread()*
 ch_close()     eval.txt        /*ch_close()*
 ch_close_in()  eval.txt        /*ch_close_in()*
 ch_evalexpr()  eval.txt        /*ch_evalexpr()*
@@ -5295,6 +5332,7 @@ channel-close     channel.txt     /*channel-close*
 channel-close-in       channel.txt     /*channel-close-in*
 channel-commands       channel.txt     /*channel-commands*
 channel-demo   channel.txt     /*channel-demo*
+channel-drop   channel.txt     /*channel-drop*
 channel-functions      usr_41.txt      /*channel-functions*
 channel-mode   channel.txt     /*channel-mode*
 channel-more   channel.txt     /*channel-more*
@@ -5327,6 +5365,7 @@ cino-:    indent.txt      /*cino-:*
 cino-= indent.txt      /*cino-=*
 cino-> indent.txt      /*cino->*
 cino-C indent.txt      /*cino-C*
+cino-E indent.txt      /*cino-E*
 cino-J indent.txt      /*cino-J*
 cino-L indent.txt      /*cino-L*
 cino-M indent.txt      /*cino-M*
@@ -6104,6 +6143,7 @@ ft-rexx-syntax    syntax.txt      /*ft-rexx-syntax*
 ft-rst-syntax  syntax.txt      /*ft-rst-syntax*
 ft-ruby-omni   insert.txt      /*ft-ruby-omni*
 ft-ruby-syntax syntax.txt      /*ft-ruby-syntax*
+ft-rust        filetype.txt    /*ft-rust*
 ft-scheme-syntax       syntax.txt      /*ft-scheme-syntax*
 ft-sdl-syntax  syntax.txt      /*ft-sdl-syntax*
 ft-sed-syntax  syntax.txt      /*ft-sed-syntax*
@@ -6136,6 +6176,7 @@ ft-xpm-syntax     syntax.txt      /*ft-xpm-syntax*
 ft-yaml-syntax syntax.txt      /*ft-yaml-syntax*
 ft-zsh-syntax  syntax.txt      /*ft-zsh-syntax*
 ft_ada.txt     ft_ada.txt      /*ft_ada.txt*
+ft_rust.txt    ft_rust.txt     /*ft_rust.txt*
 ft_sql.txt     ft_sql.txt      /*ft_sql.txt*
 ftdetect       filetype.txt    /*ftdetect*
 ftp    pi_netrw.txt    /*ftp*
@@ -6213,6 +6254,7 @@ g:decada.Make_Command     ft_ada.txt      /*g:decada.Make_Command*
 g:decada.Unit_Name()   ft_ada.txt      /*g:decada.Unit_Name()*
 g:filetype_csh syntax.txt      /*g:filetype_csh*
 g:filetype_r   syntax.txt      /*g:filetype_r*
+g:ftplugin_rust_source_path    ft_rust.txt     /*g:ftplugin_rust_source_path*
 g:gnat ft_ada.txt      /*g:gnat*
 g:gnat.Error_Format    ft_ada.txt      /*g:gnat.Error_Format*
 g:gnat.Find()  ft_ada.txt      /*g:gnat.Find()*
@@ -6342,6 +6384,20 @@ g:netrw_win95ftp pi_netrw.txt    /*g:netrw_win95ftp*
 g:netrw_winsize        pi_netrw.txt    /*g:netrw_winsize*
 g:netrw_wiw    pi_netrw.txt    /*g:netrw_wiw*
 g:netrw_xstrlen        pi_netrw.txt    /*g:netrw_xstrlen*
+g:rust_bang_comment_leader     ft_rust.txt     /*g:rust_bang_comment_leader*
+g:rust_conceal ft_rust.txt     /*g:rust_conceal*
+g:rust_conceal_mod_path        ft_rust.txt     /*g:rust_conceal_mod_path*
+g:rust_conceal_pub     ft_rust.txt     /*g:rust_conceal_pub*
+g:rust_fold    ft_rust.txt     /*g:rust_fold*
+g:rust_playpen_url     ft_rust.txt     /*g:rust_playpen_url*
+g:rust_recommended_style       ft_rust.txt     /*g:rust_recommended_style*
+g:rust_shortener_url   ft_rust.txt     /*g:rust_shortener_url*
+g:rustc_makeprg_no_percent     ft_rust.txt     /*g:rustc_makeprg_no_percent*
+g:rustc_path   ft_rust.txt     /*g:rustc_path*
+g:rustfmt_autosave     ft_rust.txt     /*g:rustfmt_autosave*
+g:rustfmt_command      ft_rust.txt     /*g:rustfmt_command*
+g:rustfmt_fail_silently        ft_rust.txt     /*g:rustfmt_fail_silently*
+g:rustfmt_options      ft_rust.txt     /*g:rustfmt_options*
 g:syntax_on    syntax.txt      /*g:syntax_on*
 g:tar_browseoptions    pi_tar.txt      /*g:tar_browseoptions*
 g:tar_cmd      pi_tar.txt      /*g:tar_cmd*
@@ -6572,7 +6628,7 @@ gui-x11-various   gui_x11.txt     /*gui-x11-various*
 gui.txt        gui.txt /*gui.txt*
 gui_w32.txt    gui_w32.txt     /*gui_w32.txt*
 gui_x11.txt    gui_x11.txt     /*gui_x11.txt*
-guifontwide_gtk2       options.txt     /*guifontwide_gtk2*
+guifontwide_gtk        options.txt     /*guifontwide_gtk*
 guifontwide_win_mbyte  options.txt     /*guifontwide_win_mbyte*
 guioptions_a   options.txt     /*guioptions_a*
 guu    change.txt      /*guu*
@@ -6597,6 +6653,7 @@ hangulin.txt      hangulin.txt    /*hangulin.txt*
 has()  eval.txt        /*has()*
 has-patch      eval.txt        /*has-patch*
 has-python     if_pyth.txt     /*has-python*
+has-pythonx    if_pyth.txt     /*has-pythonx*
 has_key()      eval.txt        /*has_key()*
 haskell.vim    syntax.txt      /*haskell.vim*
 haslocaldir()  eval.txt        /*haslocaldir()*
@@ -6960,6 +7017,7 @@ job-callback      channel.txt     /*job-callback*
 job-channel-overview   channel.txt     /*job-channel-overview*
 job-close_cb   channel.txt     /*job-close_cb*
 job-control    channel.txt     /*job-control*
+job-drop       channel.txt     /*job-drop*
 job-err_cb     channel.txt     /*job-err_cb*
 job-err_io     channel.txt     /*job-err_io*
 job-exit_cb    channel.txt     /*job-exit_cb*
@@ -7095,7 +7153,6 @@ logiPat-man       pi_logipat.txt  /*logiPat-man*
 logiPat-manual pi_logipat.txt  /*logiPat-manual*
 logiPat-operators      pi_logipat.txt  /*logiPat-operators*
 logiPat-pattern        pi_logipat.txt  /*logiPat-pattern*
-logiPat.txt    pi_logipat.txt  /*logiPat.txt*
 long-lines     version5.txt    /*long-lines*
 love   intro.txt       /*love*
 lowercase      change.txt      /*lowercase*
@@ -7126,6 +7183,7 @@ mac-compile       os_mac.txt      /*mac-compile*
 mac-faq        os_mac.txt      /*mac-faq*
 mac-filename   os_mac.txt      /*mac-filename*
 mac-lack       os_mac.txt      /*mac-lack*
+mac-standard-mappings  os_mac.txt      /*mac-standard-mappings*
 mac-vimfile    os_mac.txt      /*mac-vimfile*
 macintosh      os_mac.txt      /*macintosh*
 macro  map.txt /*macro*
@@ -7636,6 +7694,8 @@ nice      todo.txt        /*nice*
 no-eval-feature        eval.txt        /*no-eval-feature*
 no-type-checking       eval.txt        /*no-type-checking*
 no_buffers_menu        gui.txt /*no_buffers_menu*
+no_mail_maps   filetype.txt    /*no_mail_maps*
+no_plugin_maps filetype.txt    /*no_plugin_maps*
 non-greedy     pattern.txt     /*non-greedy*
 non-zero-arg   eval.txt        /*non-zero-arg*
 none-variable  eval.txt        /*none-variable*
@@ -7777,6 +7837,7 @@ php3.vim  syntax.txt      /*php3.vim*
 phtml.vim      syntax.txt      /*phtml.vim*
 pi_getscript.txt       pi_getscript.txt        /*pi_getscript.txt*
 pi_gzip.txt    pi_gzip.txt     /*pi_gzip.txt*
+pi_logipat.txt pi_logipat.txt  /*pi_logipat.txt*
 pi_netrw.txt   pi_netrw.txt    /*pi_netrw.txt*
 pi_paren.txt   pi_paren.txt    /*pi_paren.txt*
 pi_spec.txt    pi_spec.txt     /*pi_spec.txt*
@@ -7864,6 +7925,7 @@ python-bindeval   if_pyth.txt     /*python-bindeval*
 python-bindeval-objects        if_pyth.txt     /*python-bindeval-objects*
 python-buffer  if_pyth.txt     /*python-buffer*
 python-buffers if_pyth.txt     /*python-buffers*
+python-building        if_pyth.txt     /*python-building*
 python-chdir   if_pyth.txt     /*python-chdir*
 python-command if_pyth.txt     /*python-command*
 python-commands        if_pyth.txt     /*python-commands*
@@ -7894,7 +7956,11 @@ python.vim       syntax.txt      /*python.vim*
 python2-directory      if_pyth.txt     /*python2-directory*
 python3        if_pyth.txt     /*python3*
 python3-directory      if_pyth.txt     /*python3-directory*
+python_x       if_pyth.txt     /*python_x*
+python_x-special-comments      if_pyth.txt     /*python_x-special-comments*
+pythonx        if_pyth.txt     /*pythonx*
 pythonx-directory      if_pyth.txt     /*pythonx-directory*
+pyxeval()      eval.txt        /*pyxeval()*
 q      repeat.txt      /*q*
 q/     cmdline.txt     /*q\/*
 q:     cmdline.txt     /*q:*
@@ -7988,6 +8054,7 @@ remote_foreground()       eval.txt        /*remote_foreground()*
 remote_peek()  eval.txt        /*remote_peek()*
 remote_read()  eval.txt        /*remote_read()*
 remote_send()  eval.txt        /*remote_send()*
+remote_startserver()   eval.txt        /*remote_startserver()*
 remove()       eval.txt        /*remove()*
 remove-filetype        filetype.txt    /*remove-filetype*
 remove-option-flags    options.txt     /*remove-option-flags*
@@ -8043,6 +8110,13 @@ russian-issues   russian.txt     /*russian-issues*
 russian-keymap russian.txt     /*russian-keymap*
 russian-l18n   russian.txt     /*russian-l18n*
 russian.txt    russian.txt     /*russian.txt*
+rust   ft_rust.txt     /*rust*
+rust-commands  ft_rust.txt     /*rust-commands*
+rust-intro     ft_rust.txt     /*rust-intro*
+rust-mappings  ft_rust.txt     /*rust-mappings*
+rust-settings  ft_rust.txt     /*rust-settings*
+rust_<D-R>     ft_rust.txt     /*rust_<D-R>*
+rust_<D-r>     ft_rust.txt     /*rust_<D-r>*
 rview  starting.txt    /*rview*
 rvim   starting.txt    /*rvim*
 rxvt   syntax.txt      /*rxvt*
@@ -8436,6 +8510,8 @@ t_@7      term.txt        /*t_@7*
 t_AB   term.txt        /*t_AB*
 t_AF   term.txt        /*t_AF*
 t_AL   term.txt        /*t_AL*
+t_BD   term.txt        /*t_BD*
+t_BE   term.txt        /*t_BE*
 t_CS   term.txt        /*t_CS*
 t_CV   term.txt        /*t_CV*
 t_Ce   term.txt        /*t_Ce*
@@ -8452,6 +8528,7 @@ t_F6      term.txt        /*t_F6*
 t_F7   term.txt        /*t_F7*
 t_F8   term.txt        /*t_F8*
 t_F9   term.txt        /*t_F9*
+t_GP   term.txt        /*t_GP*
 t_IE   term.txt        /*t_IE*
 t_IS   term.txt        /*t_IS*
 t_K1   term.txt        /*t_K1*
@@ -8474,6 +8551,8 @@ t_KI      term.txt        /*t_KI*
 t_KJ   term.txt        /*t_KJ*
 t_KK   term.txt        /*t_KK*
 t_KL   term.txt        /*t_KL*
+t_PE   term.txt        /*t_PE*
+t_PS   term.txt        /*t_PS*
 t_RB   term.txt        /*t_RB*
 t_RI   term.txt        /*t_RI*
 t_RV   term.txt        /*t_RV*
@@ -8705,20 +8784,23 @@ termcap-options term.txt        /*termcap-options*
 termcap-title  term.txt        /*termcap-title*
 terminal-colors        os_unix.txt     /*terminal-colors*
 terminal-info  term.txt        /*terminal-info*
+terminal-key-codes     term.txt        /*terminal-key-codes*
 terminal-options       term.txt        /*terminal-options*
+terminal-output-codes  term.txt        /*terminal-output-codes*
 terminfo       term.txt        /*terminfo*
 termresponse-variable  eval.txt        /*termresponse-variable*
 test-functions usr_41.txt      /*test-functions*
 test_alloc_fail()      eval.txt        /*test_alloc_fail()*
 test_autochdir()       eval.txt        /*test_autochdir()*
-test_disable_char_avail()      eval.txt        /*test_disable_char_avail()*
 test_garbagecollect_now()      eval.txt        /*test_garbagecollect_now()*
+test_ignore_error()    eval.txt        /*test_ignore_error()*
 test_null_channel()    eval.txt        /*test_null_channel()*
 test_null_dict()       eval.txt        /*test_null_dict()*
 test_null_job()        eval.txt        /*test_null_job()*
 test_null_list()       eval.txt        /*test_null_list()*
 test_null_partial()    eval.txt        /*test_null_partial()*
 test_null_string()     eval.txt        /*test_null_string()*
+test_override()        eval.txt        /*test_override()*
 test_settime() eval.txt        /*test_settime()*
 testing        eval.txt        /*testing*
 testing-variable       eval.txt        /*testing-variable*
@@ -9119,15 +9201,19 @@ vim-dev intro.txt       /*vim-dev*
 vim-mac        intro.txt       /*vim-mac*
 vim-modes      intro.txt       /*vim-modes*
 vim-modes-intro        intro.txt       /*vim-modes-intro*
-vim-multibyte  intro.txt       /*vim-multibyte*
 vim-script-intro       usr_41.txt      /*vim-script-intro*
+vim-use        intro.txt       /*vim-use*
 vim-variable   eval.txt        /*vim-variable*
 vim.vim        syntax.txt      /*vim.vim*
 vim7   version7.txt    /*vim7*
 vim8   version8.txt    /*vim8*
 vim:   options.txt     /*vim:*
+vim_announce   intro.txt       /*vim_announce*
+vim_dev        intro.txt       /*vim_dev*
 vim_did_enter-variable eval.txt        /*vim_did_enter-variable*
+vim_mac        intro.txt       /*vim_mac*
 vim_starting   eval.txt        /*vim_starting*
+vim_use        intro.txt       /*vim_use*
 vimball        pi_vimball.txt  /*vimball*
 vimball-contents       pi_vimball.txt  /*vimball-contents*
 vimball-extract        pi_vimball.txt  /*vimball-extract*
@@ -9321,6 +9407,7 @@ xterm-8-bit       term.txt        /*xterm-8-bit*
 xterm-8bit     term.txt        /*xterm-8bit*
 xterm-blink    syntax.txt      /*xterm-blink*
 xterm-blinking-cursor  syntax.txt      /*xterm-blinking-cursor*
+xterm-bracketed-paste  term.txt        /*xterm-bracketed-paste*
 xterm-clipboard        term.txt        /*xterm-clipboard*
 xterm-codes    term.txt        /*xterm-codes*
 xterm-color    syntax.txt      /*xterm-color*
index 7e8b3cc..62c23ca 100644 (file)
@@ -1,4 +1,4 @@
-*term.txt*      For Vim version 8.0.  Last change: 2016 Sep 02
+*term.txt*      For Vim version 8.0.  Last change: 2017 Apr 11
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -89,6 +89,28 @@ an external command (e.g., "!!"), the terminal will be put into Normal mode
 for a moment.  This means that you can stop the output to the screen by
 hitting a printing key.  Output resumes when you hit <BS>.
 
+                                               *xterm-bracketed-paste*
+When the 't_BE' option is set then 't_BE' will be sent to the
+terminal when entering "raw" mode and 't_BD' when leaving "raw" mode.  The
+terminal is then expected to put 't_PS' before pasted text and 't_PE' after
+pasted text.  This way Vim can separate text that is pasted from characters
+that are typed.  The pasted text is handled like when the middle mouse button
+is used, it is inserted literally and not interpreted as commands.
+
+When the cursor is in the first column, the pasted text will be inserted
+before it.  Otherwise the pasted text is appended after the cursor position.
+This means one cannot paste after the first column.  Unfortunately Vim does
+not have a way to tell where the mouse pointer was.
+
+Note that in some situations Vim will not recognize the bracketed paste and
+you will get the raw text.  In other situations Vim will only get the first
+pasted character and drop the rest, e.g. when using the "r" command.  If you
+have a problem with this, disable bracketed paste by putting this in your
+.vimrc: >
+       set t_BE=
+If this is done while Vim is running the 't_BD' will be sent to the terminal
+to disable bracketed paste.
+
                                                        *cs7-problem*
 Note: If the terminal settings are changed after running Vim, you might have
 an illegal combination of settings.  This has been reported on Solaris 2.5
@@ -230,7 +252,7 @@ But any non-empty string means that the flag is set.  An empty string means
 that the flag is not set.  't_CS' works like this too, but it isn't a termcap
 flag.
 
-OUTPUT CODES
+OUTPUT CODES                                           *terminal-output-codes*
        option  meaning ~
 
        t_AB    set background color (ANSI)                     *t_AB* *'t_AB'*
@@ -292,6 +314,7 @@ Added by Vim (there are no standard codes for these):
        t_IS    set icon text start                             *t_IS* *'t_IS'*
        t_IE    set icon text end                               *t_IE* *'t_IE'*
        t_WP    set window position (Y, X) in pixels            *t_WP* *'t_WP'*
+       t_GP    get window position (Y, X) in pixels            *t_GP* *'t_GP'*
        t_WS    set window size (height, width) in characters   *t_WS* *'t_WS'*
        t_SI    start insert mode (bar cursor shape)            *t_SI* *'t_SI'*
        t_SR    start replace mode (underline cursor shape)     *t_SR* *'t_SR'*
@@ -306,8 +329,12 @@ Added by Vim (there are no standard codes for these):
                |xterm-true-color|
        t_8b    set background color (R, G, B)                  *t_8b* *'t_8b'*
                |xterm-true-color|
+       t_BE    enable bracketed paste mode                     *t_BE* *'t_BE'*
+               |xterm-bracketed-paste|
+       t_BD    disable bracketed paste mode                    *t_BD* *'t_BD'*
+               |xterm-bracketed-paste|
 
-KEY CODES
+KEY CODES                                              *terminal-key-codes*
 Note: Use the <> form if possible
 
        option  name            meaning ~
@@ -398,6 +425,9 @@ Note: Use the <> form if possible
        t_KK    <k8>            keypad 8                 *<k8>* *t_KK* *'t_KK'*
        t_KL    <k9>            keypad 9                 *<k9>* *t_KL* *'t_KL'*
                <Mouse>         leader of mouse code            *<Mouse>*
+                                                               *t_PS* *'t_PS'*
+       t_PS    start of bracketed paste |xterm-bracketed-paste|
+       t_PE    end of bracketed paste |xterm-bracketed-paste|  *t_PE* *'t_PE'*
 
 Note about t_so and t_mr: When the termcap entry "so" is not present the
 entry for "mr" is used.  And vice versa.  The same is done for "se" and "me".
index f9349d0..6b38586 100644 (file)
@@ -1,4 +1,4 @@
-*todo.txt*      For Vim version 8.0.  Last change: 2016 Nov 06
+*todo.txt*      For Vim version 8.0.  Last change: 2017 Apr 23
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -28,17 +28,28 @@ See |develop.txt| for development plans.  You can vote for which items should
 be worked on, but only if you sponsor Vim development.  See |sponsor|.
 
 Issues can also be entered online: https://github.com/vim/vim/issues
-Updates will be forwarded to the vim_dev maillist.  Issues entered there will
-not be repeated below, unless there is extra information.
+Only use this for bug reports, not for questions!  Those belong on the
+maillist.  Updates will be forwarded to the |vim_dev| maillist.  Issues
+entered there will not be repeated below, unless there is extra information.
 
                                                        *known-bugs*
 -------------------- Known bugs and current work -----------------------
 
+Remove the Farsi code?
+
 +channel:
+- job_stop() should not always close the channel, e.g. for "int".
+  (Martin Gammelsæter, 2017 Apr 11, #1632)
+  Only assume killed on "kill".
+  Check job->jv_status not to be JOB_ENDED.
+- Try out background make plugin: 
+  https://github.com/AndrewVos/vim-make-background
 - Problem with stderr on Windows? (Vincent Rischmann, 2016 Aug 31, #1026)
 - Add 'cwd' argument to start_job(): directory to change to in the child.
     check for valid directory before forking.
   Part of patch for environment, Yasuhiro Matsumoto, #1160
+- When out_cb executes :sleep, the close_cb may be invoked. (Daniel Hahler,
+  2016 Dec 11, #1320)
 - Implement |job-term| ?
 - Channel test fails with Motif.  Sometimes kills the X11 server.
 - When a message in the queue but there is no callback, drop it after a while?
@@ -53,6 +64,7 @@ not be repeated below, unless there is extra information.
   connecting in the main loop with zero timeout.
 - job_start(): run job in a newly opened terminal.
     With xterm could use -S{pty}.
+    Although user could use "xterm -e 'cmd arg'".
 
 Regexp problems:
 - Since 7.4.704 the old regex engine fails to match [[:print:]] in 0xf6.
@@ -69,8 +81,8 @@ Regexp problems:
 - Issue 164: freeze on regexp search.
 - Ignorecase not handled properly for multi-byte characters. (Axel Bender,
   2013 Dec 11)
-- Using \@> and \?. (Brett Stahlman, 2013 Dec 21) Remark from Marcin Szamotulski
-  Remark from Brett 2014 Jan 6 and 7.
+- Using \@> and \?. (Brett Stahlman, 2013 Dec 21) Remark from Marcin
+  Szamotulski; Remark from Brett 2014 Jan 6 and 7.
 - NFA regexp doesn't handle \%<v correctly. (Ingo Karkat, 2014 May 12)
 - Does not work with NFA regexp engine:
   \%u, \%x, \%o, \%d followed by a composing character
@@ -96,48 +108,113 @@ Regexp problems:
 - The pattern "\1" with the old engine gives E65, with the new engine it
   matches the empty string. (Dominique Pelle, 2015 Oct 2, Nov 24)
   had_endbrace[] is set but not initialized or used.
+- Difference between two engines: ".*\zs\/\@>\/" on text "///"
+  (Chris Paul, 2016 Nov 13)  New engine not greedy enough?
 
-Patch to support nested namespace syntax. (Pauli, 2016 Oct 30, #1214)
+Running test_gui and test_gui_init with Motif sometimes kills the window
+manager.  Problem with Motif?
 
-Make html indent file use javascript indent, now that it's not just cindent.
-#1220
+Memory leak in test97?  The string is actually freed.  Weird.
 
-json_encode(): should convert to utf-8. (Nikolai Pavlov, 2016 Jan 23)
-What if there is an invalid character?
+Patch for shellescape(). (Christian Brabandt, 2017 Apr 20, #1590)
 
-Bug: Json with same key should not give internal error. (Lcd, 2016 Oct 26)
-Make dict_add give a duplicate key error.
+Patch for flickering redraw. (Hirohito Higashi, 2017 Apr 23, #1637)
 
-Should json_encode()/json_decode() restrict recursiveness?
-Or avoid recursiveness.
+New value "uselast" for 'switchbuf'. (Lemonboy, 2017 Apr 23, #1652)
 
-Allow using json with empty key?  Dict already has it.
+Add a toolbar in the terminal.  Can be global, above all windows, or specific
+for one window.
+Use tb_set(winid, [{'text': 'stop', 'cb': callback, 'hi': 'Green'}])
+    tb_highlight(winid, 'ToolBar')
+    tb_get(winid)
+
+json_encode(): should convert to utf-8. (Nikolai Pavlov, 2016 Jan 23)
+What if there is an invalid character?
 
 Json string with trailing \u should be an error. (Lcd)
 
-Patch to reset ex_exitvalue after catch. (Christian Brabandt, 2016 Oct 23)
+When session file has name in argument list but the buffer was deleted, the
+buffer is not deleted when using the session file. (#1393)
+Should add the buffer in hidden state.
 
-Patch to deal with changed configure events in GTK 3. (Jan Alexander Steffens,
-2016 Oct 23 #1193)
-Remarks from nuko8, 2016 Nov 2.
+When an item in the quickfix list has a file name that does not exist, behave
+like the item was not a match for :cnext.
 
 Wrong diff highlighting with three files. (2016 Oct 20, #1186)
 Also get E749 on exit.
+Another example in #1309
+
+Patch to change all use of &sw to shiftwidth(). (Tyru, 2017 Feb 19)
+Wait until maintainers integrate it.
+
+When deleting a mark or register, leave a tombstone, so that it's also deleted
+when writing viminfo (and the delete was the most recent action). #1339
 
-Patch for better explanation of 'compatible' side effects.
-https://github.com/vim/vim/pull/1161/files
+Suggestion to improve pt-br spell checking. (Marcelo D Montu, 2016 Dec 15,
+#1330)
 
 Error in test_startup_utf8 on Solaris. (Danek Duvall, 2016 Aug 17)
 
+Completion for :!cmd shows each match twice. #1435
+
+GTK: When adding a timer from 'balloonexpr' it won't fire, because
+g_main_context_iteration() doesn't return.  Need to trigger an event when the
+timer expires.
+
+Screen update bug related to matchparen.  (Chris Heath, 2017 Mar 4, #1532)
+
+Rule to use "^" for statusline does not work if a space is defined with
+highlighting for both stl and stlnc.  Patch by Ken Hamada (itchyny, 2016 Dec 11)
+
+8   "stl" and "stlnc" in 'fillchars' don't work for multi-byte characters.
+    Patch by Christian Wellenbrock, 2013 Jul 5.
+
+Using CTRL-G_U in InsertCharPre causes trouble for redo. (Israel Chauca
+Fuentes, 2017 Feb 12, #1470)
+
+Check for errors E704 and E705 only does VAR_FUNC, should also do VAR_PARTIAL.
+(Nikolai Pavlov, 2017 Mar 13, #1557)
+Make a function to check for function-like type?
+
 Screen updated delayed when using CTRL-O u in Insert mode.
 (Barlik, #1191)  Perhaps because status message?
 
+Implement optional arguments for functions.
+    func Foo(start, count = 1 all = 1)
+    call Foo(12)
+    call Foo(12, all = 0)
+    call Foo(12, 15, 0)
+
+writefile() does not abort as soon as an error is found. (Nikolai Pavlov,
+2017 Feb 14, #1476)
+
+Patch to support on-the-spot and over-the-spot input method. (Ken Takata, 2017
+Feb 14).
+
+Add a command to take a range of lines, filter them and put the output
+somewhere else.  :{range}copy {dest} !cmd
+
+Patch to fix that empty first tab is not in session.
+(Hirohito Higashi, 2016 Nov 25, #1282)
+
 Patch for restoring wide characters in the console buffer.
 (Ken Takata, 2016 Jun 7)
 
 Patch to fix escaping of job arguments. (Yasuhiro Matsumoto, 2016 Oct 5)
 Update Oct 14: https://gist.github.com/mattn/d47e7d3bfe5ade4be86062b565a4bfca
 
+Characters deleted on completion. (Adrià Farrés, 2017 Apr 20, #1645)
+Remarks from Christian Brabandt (Apr 21)
+
+The TermResponse event is not triggered when a plugin has set 'eventignore' to
+"all".  Netrw does this. (Gary Johnson, 2017 Jan 24)
+Postpone the event until 'eventignore' is reset.
+
+Patch to make urxvt mouse work better, recognize Esc[*M termcap code.
+(Maurice Bos, 2017 Feb 17, #1486)
+
+Expanding /**/ is slow.  Idea by Luc Hermitte, 2017 Apr 14.
+
 Once .exe with updated installer is available: Add remark to download page
 about /S and /D options (Ken Takata, 2016 Apr 13)
 Or point to nightly builds: https://github.com/vim/vim-win32-installer/releases
@@ -145,14 +222,41 @@ Or point to nightly builds: https://github.com/vim/vim-win32-installer/releases
 Problem passing non-UTF-8 strings to Python 3. (Björn Linse, 2016 Sep 11,
 #1053)  With patch, does it work?
 
+Using --remote to open a file in which a # appears does not work on
+MS-Windows.  Perhaps in \#  the \ is seen as a path separator. (Axel Bender,
+2017 Feb 9)  Can we expand wildcards first and send the path literally to the
+receiving Vim?  Or make an exception for #, it's not useful remotely.
+
+":sbr" docs state it respect 'switchbuf', but "vsplit" does not cause a
+vertical split. (Haldean Brown, 2017 Mar 1)
+
 Use ADDR_OTHER instead of ADDR_LINES for many more commands.
 Add tests for using number larger than number of lines in buffer.
 
+Might be useful to have isreadonly(), like we have islocked().
+Avoids exceptions, e.g. when using the b: namespace as a dict.
+
 Patch to make v:shell_error writable. (Christian Brabandt, 2016 Sep 27)
-Is there another solution?
+Useful to restore it.  Is there another solution?
 
-On MS-Windows with 'clipboard' set to "unnamed" this doesn't work to double
-lines: :g/^/normal yyp   On Unix it works OK.  (Bryce Orgill, 2016 Nov 5)
+"ci[" does not look for next [ like ci" does look for next ".
+(J.F. 2017 Jan 7)
+
+Patch for wrong cursor position on wrapped line, involving breakindent.
+(Ozaki Kiichi, 2016 Nov 25)
+Does this also fix #1408 ?
+
+Patch for 'cursorlinenr' option. (Ozaki Kiichi, 2016 Nov 30)
+
+When 'completeopt' has "noselect" does not insert a newline. (Lifepillar, 2017
+Apr 23, #1653)
+
+Window resizing with 'winfixheight': With a vertical split the height changes
+anyway. (Tommy allen, 2017 Feb 21, #1502)
+
+When adding an item to a new quickfix list make ":cnext" jump to that item.
+Make a difference being at the first item and not having used :cnext at all.
+(Afanasiy Fet, 2017 Jan 3)
 
 Invalid behavior with NULL list. (Nikolai Pavlov, #768)
 E.g. deepcopy(test_null_list())
@@ -162,6 +266,15 @@ Patch to make it possible to extend a list with itself.
 
 Patch to add Zstandard compressed file support. (Nick Terrell, 2016 Oct 24)
 
+Patch to add trim() function. (Bukn, 2016 Nov 25, #1280)
+
+Patch to add MODIFIED_BY to MSVC build file. (Chen Lei, 2016 Nov 24, #1275)
+
+Patch to change argument of :marks. (LemonBoy, 2017 Jan 29, #1426)
+
+On Windows buffer completion sees backslash as escape char instead of path
+separator. (Toffanim, 2016 Nov 24, #1274)
+
 min() and max() spawn lots of error messages if sorted list/dictionary
 contains invalid data (Nikolay Pavlov, 2016 Sep 4, #1039)
 
@@ -179,18 +292,34 @@ sort() is not stable when using numeric/float sort (Nikolay Pavlov, 2016 Sep
 
 Patch to add "cmdline" completion to getcompletion(). (Shougo, Oct 1, #1140)
 
+Feature request: Complete members of a dictionary. (Luc Hermitte, 2017 Jan 4,
+#1350)
+
+Undo message is not always properly displayed.  Patch by Ken Takata, 2013 oct
+3.  Doesn't work properly according to Yukihiro Nakadaira.
+Also see #1635.
+
 Patch for systemlist(), add empty item. (thinca, Sep 30, #1135)
 Add an argument to choose binary or non-binary (like readfile()), when omitted
 use the current behavior.
 Include the test.
 
+Patch to add tagfunc().  Cleaned up by Christian Brabandt, 2013 Jun 22.
+New update 2017 Apr 10, #1628
+
+Unnamed register only contains the last deleted text when appending deleted
+text to a register. (Wolfgang Jeltsch, reproduced by Ben Fritz, 2017 Apr 10)
+
 When 'keywordprg' starts with ":" the argument is still escaped as a shell
 command argument. (Romain Lafourcade, 2016 Oct 16, #1175)
 
+Patch to support CamelCase for spell checking: See a lower-to-upper case
+change as a word boundary. (btucker-MPCData, 2016 Nov 6, #1235)
+
 Idea from Sven: record sequence of keys.  Useful to show others what they are
 doing (look over the shoulder), and also to see what happened.
 Probably list of keystrokes, with some annotations for mode changes.
-Could store in logfile to be able to analyise it with an external command.
+Could store in logfile to be able to analyse it with an external command.
 E.g. to see when's the last time a plugin command was used.
 
 execute() cannot be used with command completeion. (Daniel Hahler, 2016 Oct 1,
@@ -198,12 +327,10 @@ execute() cannot be used with command completeion. (Daniel Hahler, 2016 Oct 1,
 
 cmap using execute() has side effects. (Killthemule, 2016 Aug 17, #983)
 
-Patch to change order of compiler flags. (Yousong Zhou, 2016 Sep 19, #1100)
-
 Patch to order results from taglist(). (Duncan McDougall, 2016 Oct 25)
 
-Patch for :pyx, run python commands depending on the supported version.
-(Marc Weber, update from Ken Takata, 2016 Sep 19)
+patch for 'spellcamelcase' option: spellcheck each CamelCased word.
+(Ben Tucker, 2016 Dec 2)
 
 When using ":diffput" through a mapping, undo in the target buffer isn't
 synced.  (Ryan Carney, 2016 Sep 14)
@@ -220,7 +347,7 @@ Also with latest version.
 Cannot delete a file with square brackets with delete(). (#696)
 
 Patch to add ":syn foldlevel" to use fold level further down the line.
-(Brad King, 2016 Oct 19)
+(Brad King, 2016 Oct 19, update 2017 Jan 30)
 
 Completion for input() does not expand environment variables. (chdiza, 2016
 Jul 25, #948)
@@ -228,14 +355,22 @@ Jul 25, #948)
 Patch to fix wrong encoding of error message on Cygwin/MSYS terminal.
 (Ken Takata, 2016 Oct 4)
 
+Patch to add 'systemencoding', convert between 'encoding' and this for file
+names, shell commands and the like.  (Kikuchan, 2010 Oct 14)
+Assume the system converts between the actual encoding of the filesystem to
+the system encoding (usually utf-8).
+
 'hlsearch' interferes with a Conceal match. (Rom Grk, 2016 Aug 9)
 
 Patch to add context information to quickfix/location list. (Yegappan
-Lakshmanan, 2016 Aug 25)
+Lakshmanan, 2016 Aug 25, #1012)
 
 MS-Windows: use WS_HIDE instead of SW_SHOWMINNOACTIVE in os_win32.c?
 Otherwise task flickers in taskbar.
 
+Bogus characters inserted when triggering indent while changing test.
+(Vitor Antunes, 2016 Nov 22, #1269)
+
 Should make ":@r" handle line continuation. (Cesar Romani, 2016 Jun 26)
 Also for ":@.".
 
@@ -244,6 +379,9 @@ Repeating 'opfunc' in a function only works once. (Tarmean, 2016 Jul 15, #925)
 Have a way to get the call stack, in a function and from an exception.
 #1125
 
+Patch to add 'pythonhome' and 'pythonthreehome' options. (Kazuki Sakamoto,
+2016 Nov 21, #1266)
+
 Second problem in #966: ins_compl_add_tv() uses get_dict_string() multiple
 times, overwrites the one buffer. (Nikolay Pavlov, 2016 Aug 5)
 
@@ -289,16 +427,13 @@ When doing "vi buf.md" a BufNew autocommand for *.md is not triggered.
 Because of using the initial buffer? (Dun Peal, 2016 May 12)
 
 Patch to add the :bvimgrep command.  (Christian Brabandt, 2014 Nov 12)
-Updated 2016 Jun 10, #858
+Updated 2016 Jun 10, #858  Update 2017 Mar 28: use <buffer>
 
 Add redrawtabline command. (Naruhiko Nishino, 2016 Jun 11)
 
 Neovim patch for utfc_ptr2char_len() https://github.com/neovim/neovim/pull/4574
 No test, needs some work to include.
 
-Patch to make finding duplicate tags much faster, using a hashtab. (James
-McCoy, 2016 Sept 14, #1046)  Should work now.
->
 Patch to improve indenting for C++ constructor with initializer list.
 (Hirohito Higashi, 2016 Mar 31)
 
@@ -306,6 +441,9 @@ Add stronger encryption.  Could use libsodium (NaCl).
 https://github.com/jedisct1/libsodium/
 Possibly include the needed code so that it can be build everywhere.
 
+Add a way to restart a timer.  It's similar to timer_stop() and timer_start(),
+but the reference remains valid.
+
 Patch to add setbufline(). (email from Yasuhiro Matsumoto, patch by Ozaki
 Kiichi, 2016 Feb 28)
 Update Mar 8: https://gist.github.com/mattn/23c1f50999084992ca98
@@ -359,13 +497,8 @@ Should use /usr/local/share/applications or /usr/share/applications.
 Or use $XDG_DATA_DIRS.
 Also need to run update-desktop-database (Kuriyama Kazunobu, 2015 Nov 4)
 
-Patch to introduce 'cmdencoding'. (Ken Takata, Aug 18?)
-Better help Aug 19.
-Problem: applies to too many commands, such as :cbuffer.
-Updated patch with three options, 2016 Sep 8.
-    Win32: When running ":make" and 'encoding' differs from the system locale,
-    the output should be converted.  Esp. when 'encoding' is "utf-8". (Yongwei
-    Wu) Should we use 'termencoding' for this?
+Test object i{ and it do not behave the same. #1379
+Do not include the linebreak at the start?
 
 Patch to have text objects defined by arbitrary single characters. (Daniel
 Thau, 2013 Nov 20, 2014 Jan 29, 2014 Jan 31)
@@ -380,6 +513,9 @@ Access to uninitialized memory in match_backref() regexp_nda.c:4882
 ":cd C:\Windows\System32\drivers\etc*" does not work, even though the
 directory exists. (Sergio Gallelli, 2013 Dec 29)
 
+In debug mode one can inspect variables, but not the function parameters
+(starting with a:). (Luc Hermitte, 2017 Jan 4, #1352)
+
 7   Add a watchpoint in the debug mode: An expression that breaks execution
     when evaluating to non-zero.  Add the "watchadd expr" command, stop when
     the value of the expression changes.  ":watchdel" deletes an item,
@@ -468,6 +604,9 @@ Patch to add :mapgroup, put mappings in a group like augroup.
 Value returned by virtcol() changes depending on how lines wrap.  This is
 inconsistent with the documentation.
 
+Value of virtcol() for '[ and '] depend on multi-byte character.
+(Luchr, #277)
+
 Can we cache the syntax attributes, so that updates for 'relativenumber' and
 'cursorline'/'cursorcolumn' are a lot faster?
 
@@ -784,9 +923,6 @@ Patch to handle integer overflow. (Aaron Burrow, 2013 Dec 12)
 Patch to add "ntab" item in 'listchars' to repeat first character. (Nathaniel
 Braun, pragm, 2013 Oct 13)  A better solution 2014 Mar 5.
 
-Undo message is not always properly displayed.  Patch by Ken Takata, 2013 oct
-3.  Doesn't work properly according to Yukihiro Nakadaira.
-
 /[b-a] gives error E16, should probably be E769.
 
 7   Windows XP: When using "ClearType" for text smoothing, a column of yellow
@@ -861,11 +997,6 @@ highlighted as the cursor line.  (Alessandro Ivaldi, 2013 Jun 4)
 
 Two highlighting bugs. (ZyX, 2013 Aug 18)
 
-Patch to add the bufferlist() function. (Yegappan Lakshmanan, 2013 May 5)
-May 17: with winlist() and tabpagelist().
-May 19: with local variables.
-May 28: with options
-
 Patch to support 'u' in interactive substitute. (Christian Brabandt, 2012 Sep
 28)  With tests: Oct 9.
 
@@ -931,6 +1062,9 @@ Patch for :tabcloseleft, after closing a tab go to left tab. (William Bowers,
 Patch to improve equivalence classes in regexp patterns.
 (Christian Brabandt, 2013 Jan 16, update Jan 17)
 
+Patch to add new regexp classes :ident:, :keyword:, :fname:.
+(ichizok, 2016 Jan 12, #1373)
+
 Patch with suggestions for starting.txt. (Tony Mechelynck, 2012 Oct 24)
 But use Gnome instead of GTK?
 
@@ -941,9 +1075,6 @@ Szamotulski, 2012 Nov 8)
 Session file creation: 'autochdir' causes trouble.  Keep it off until after
 loading all files.
 
-8   "stl" and "stlnc" in 'fillchars' don't work for multi-byte characters.
-    Patch by Christian Wellenbrock, 2013 Jul 5.
-
 MS-Windows resizing problems:
 - Windows window on screen positioning: Patch by Yukihiro Nakadaira, 2012 Jun
   20.  Uses getWindowRect() instead of GetWindowPlacement()
@@ -956,8 +1087,6 @@ MS-Windows resizing problems:
 Patch to append regexp to tag commands to make it possible to select one out
 of many matches. (Cody Cutler, 2013 Mar 28)
 
-Patch to add tagfunc().  Cleaned up by Christian Brabandt, 2013 Jun 22.
-
 The input map for CTRL-O in mswin.vim causes problems after CTRL-X CTRL-O.
 Suggestion for another map. (Philip Mat, 2012 Jun 18)
 But use "gi" instead of "a".  Or use CTRL-\ CTRL-O.
@@ -968,9 +1097,6 @@ Aug 16)
 When there are no command line arguments ":next" and ":argu" give E163, which
 is confusing.  Should say "the argument list is empty".
 
-xterm supports escape sequences to mark a paste operation.  Need to be
-enabled. (Bruno Sutic, 2014 Jul 11)  How to know the terminal supports this?
-
 URXVT:
 - will get stuck if byte sequence does not contain the expected semicolon.
 - Use urxvt mouse support also in xterm.  Explanations:
@@ -1111,8 +1237,6 @@ right type.
 string() can't parse back "inf" and "nan".  Fix documentation or fix code?
 (ZyX, 2010 Aug 23)
 
-Make 'formatprg' global-local. (Sung Pae)
-
 When doing "redir => s:foo" in a script and then "redir END" somewhere else
 (e.g. in a function) it can't find s:foo.
 When a script contains "redir => s:foo" but doesn't end redirection, a
@@ -1250,11 +1374,6 @@ Regexp engine performance:
     7.2.274.  (Christian Brabandt, 2010 May 27) Generally, folding with
     'foldmethod' set to "syntax" is slow.  Do profiling to find out why.
 
-Patch to add 'systemencoding', convert between 'encoding' and this for file
-names, shell commands and the like.  (Kikuchan, 2010 Oct 14)
-Assume the system converts between the actual encoding of the filesystem to
-the system encoding (usually utf-8).
-
 Problem producing tags file when hebrew.frx is present.  It has a BOM.
 Results in E670. (Tony Mechelynck, 2010 May 2)
 
@@ -1273,6 +1392,7 @@ With "tw=55 fo+=a" typing space before ) doesn't work well. (Scott Mcdermott,
 
 Patch to add random number generator. (Hong Xu, 2010 Nov 8, update Nov 10)
 Alternative from Christian Brabandt. (2010 Sep 19)
+New one from Yasuhiro Matsumoto, #1277.
 
 Messages in message.txt are highlighted as examples.
 
@@ -3830,7 +3950,7 @@ Code size:
     left out.
 8   When compiled with a GUI-only version, the termcap entries for terminals
     can be removed.
-8   Can the check for libelf in configure.in be removed?
+8   Can the check for libelf in configure.ac be removed?
 
 
 Messages:
@@ -5552,7 +5672,7 @@ From vile:
 Far future and "big" extensions:
 -   Instead of using a Makefile and autoconf, use a simple shell script to
     find the C compiler and do everything with C code.  Translate something
-    like an Aap recipe and configure.in to C.  Avoids depending on Python,
+    like an Aap recipe and configure.ac to C.  Avoids depending on Python,
     thus will work everywhere.  With batch file to find the C compiler it
     would also work on MS-Windows.
 -   Make it easy to setup Vim for groups of users: novice vi users, novice
index 48dede8..2ccde79 100644 (file)
@@ -1,4 +1,4 @@
-*usr_02.txt*   For Vim version 8.0.  Last change: 2016 Jan 16
+*usr_02.txt*   For Vim version 8.0.  Last change: 2017 Mar 14
 
                     VIM USER MANUAL - by Bram Moolenaar
 
@@ -554,7 +554,7 @@ Summary:                                    *help-summary*  >
 8) Ex-commands always start with ":", so to go to the :s command help: >
        :help :s
 
-9) Commands specifically for debugging start with ">".  To go to to the help
+9) Commands specifically for debugging start with ">".  To go to the help
    for the "cont" debug command: >
        :help >cont
 
@@ -589,7 +589,7 @@ Summary:                                    *help-summary*  >
     register: >
        :help quote:
 
-13) Vim Script (VimL) is available at >
+13) Vim script is available at >
        :help eval.txt
 <   Certain aspects of the language are available at :h expr-X where "X" is a
    single letter. E.g.  >
@@ -599,10 +599,10 @@ Summary:                                  *help-summary*  >
    Also important is >
        :help function-list
 <   to find a short description of all functions available.  Help topics for
-   VimL functions always include the "()", so: >
+   Vim script functions always include the "()", so: >
        :help append()
-<   talks about the append VimL function rather than how to append text in the
-   current buffer.
+<   talks about the append Vim script function rather than how to append text
+   in the current buffer.
 
 14) Mappings are talked about in the help page :h |map.txt|. Use >
        :help mapmode-i
@@ -663,7 +663,7 @@ Summary:                                    *help-summary*  >
 22) Autocommand events can be found by their name: >
        :help BufWinLeave
 <    To see all possible events: >
-       :help autocommands-events
+       :help autocommand-events
 
 23) Command-line switches always start with "-".  So for the help of the -f
     command switch of Vim use: >
index 2c66172..fe0e4b0 100644 (file)
@@ -182,7 +182,7 @@ the following:
 
 This tells you that you might want to fix something on line 33.  So how do you
 find line 33?  One way is to do "9999k" to go to the top of the file and "32j"
-to go down thirty two lines.  It is not a good way, but it works.  A much
+to go down thirty-two lines.  It is not a good way, but it works.  A much
 better way of doing things is to use the "G" command.  With a count, this
 command positions you at the given line number.  For example, "33G" puts you
 on line 33.  (For a better way of going through a compiler's error list, see
index f0efbc5..68352da 100644 (file)
@@ -1,4 +1,4 @@
-*usr_22.txt*   For Vim version 8.0.  Last change: 2012 Nov 15
+*usr_22.txt*   For Vim version 8.0.  Last change: 2016 Dec 13
 
                     VIM USER MANUAL - by Bram Moolenaar
 
@@ -93,7 +93,7 @@ browser.  This is what you get: >
         o................Browsing with a Horizontal Split...........|netrw-o|
         p................Use Preview Window.........................|netrw-p|
         P................Edit in Previous Window....................|netrw-p|
-        q................Listing Bookmarks and History..............|netrw-q|
+        q................Listing Bookmarks and History..............|netrw-qb|
         r................Reversing Sorting Order....................|netrw-r|
 <      (etc)
 
index 2e2fd4f..d675c5e 100644 (file)
@@ -1,4 +1,4 @@
-*usr_41.txt*   For Vim version 8.0.  Last change: 2016 Sep 01
+*usr_41.txt*   For Vim version 8.0.  Last change: 2017 Mar 28
 
                     VIM USER MANUAL - by Bram Moolenaar
 
@@ -95,7 +95,7 @@ Then there is the ":let i += 1" command.  This does the same thing as
 to the same variable.
 
 The example was given to explain the commands, but would you really want to
-make such a loop it can be written much more compact: >
+make such a loop, it can be written much more compact: >
 
        :for i in range(1, 4)
        :  echo "count is" i
@@ -693,6 +693,7 @@ Other computation:                                  *bitwise-function*
 Variables:                                             *var-functions*
        type()                  type of a variable
        islocked()              check if a variable is locked
+       funcref()               get a Funcref for a function reference
        function()              get a Funcref for a function name
        getbufvar()             get a variable value from a specific buffer
        setbufvar()             set a variable in a specific buffer
@@ -884,9 +885,11 @@ GUI:                                               *gui-functions*
        getfontname()           get name of current font being used
        getwinposx()            X position of the GUI Vim window
        getwinposy()            Y position of the GUI Vim window
+       balloon_show()          set the balloon content
 
 Vim server:                                    *server-functions*
        serverlist()            return the list of server names
+       remote_startserve()     run a server
        remote_send()           send command characters to a Vim server
        remote_expr()           evaluate an expression in a Vim server
        server2client()         send a reply to a client of a Vim server
@@ -918,18 +921,22 @@ Testing:                              *test-functions*
        assert_true()           assert that an expression is true
        assert_exception()      assert that a command throws an exception
        assert_fails()          assert that a function call fails
+       assert_report()         report a test failure
        test_alloc_fail()       make memory allocation fail
        test_autochdir()        enable 'autochdir' during startup
-       test_disable_char_avail()       test without typeahead
-       test_garbagecollect_now()       free memory right now
+       test_override()         test with Vim internal overrides
+       test_garbagecollect_now()   free memory right now
+       test_ignore_error()     ignore a specific error message
        test_null_channel()     return a null Channel
        test_null_dict()        return a null Dict
        test_null_job()         return a null Job
        test_null_list()        return a null List
        test_null_partial()     return a null Partial function
        test_null_string()      return a null String
+       test_settime()          set the time Vim uses internally
 
 Inter-process communication:               *channel-functions*
+       ch_canread()            check if there is something to read
        ch_open()               open a channel
        ch_close()              close a channel
        ch_close_in()           close the in part of a channel
@@ -999,6 +1006,7 @@ Various:                                   *various-functions*
        perleval()              evaluate Perl expression (|+perl|)
        py3eval()               evaluate Python expression (|+python3|)
        pyeval()                evaluate Python expression (|+python|)
+       pyxeval()               evaluate |python_x| expression
 
 ==============================================================================
 *41.7* Defining a function
@@ -1586,7 +1594,7 @@ WHITE SPACE
 Blank lines are allowed and ignored.
 
 Leading whitespace characters (blanks and TABs) are always ignored.  The
-whitespaces between parameters (e.g. between the 'set' and the 'cpoptions' in
+whitespaces between parameters (e.g. between the "set" and the "cpoptions" in
 the example below) are reduced to one blank character and plays the role of a
 separator, the whitespaces after the last (visible) character may or may not
 be ignored depending on the situation, see below.
@@ -2269,8 +2277,8 @@ plugin for the mail filetype: >
        endif
 
 Two global variables are used:
-no_plugin_maps         disables mappings for all filetype plugins
-no_mail_maps           disables mappings for a specific filetype
+|no_plugin_maps|       disables mappings for all filetype plugins
+|no_mail_maps|         disables mappings for the "mail" filetype
 
 
 USER COMMANDS
index 2bcb1ca..b3aa4b5 100644 (file)
@@ -1,4 +1,4 @@
-*various.txt*   For Vim version 8.0.  Last change: 2016 Sep 06
+*various.txt*   For Vim version 8.0.  Last change: 2017 Feb 24
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -527,12 +527,14 @@ N  *+X11*         Unix only: can restore window title |X11|
 :redi[r] END           End redirecting messages.  {not in Vi}
 
                                                        *:filt* *:filter*
-:filt[er] {pat} {command}
-:filt[er] /{pat}/ {command}
-                       Restrict the output of {command} to matches with {pat}.
-                       For example, to list only xml files: >
+:filt[er][!] {pat} {command}
+:filt[er][!] /{pat}/ {command}
+                       Restrict the output of {command} to lines matching
+                       with {pat}.  For example, to list only xml files: >
                                :filter /\.xml$/ oldfiles
-<
+<                      If the [!] is given, restrict the output of {command}
+                       to lines that do NOT match {pat}.
+
                        {pat} is a Vim search pattern.  Instead of enclosing
                        it in / any non-ID character (see |'isident'|) can be
                        used, so long as it does not appear in {pat}.  Without
@@ -634,7 +636,7 @@ K                   Run a program to lookup the keyword under the
                        with the command >
                                :!{program} {keyword}
 <                      There is an example of a program to use in the tools
-                       directory of Vim.  It is called 'ref' and does a
+                       directory of Vim.  It is called "ref" and does a
                        simple spelling check.
                        Special cases:
                        - If 'keywordprg' begins with ":" it is invoked as
index 53f1a21..f0205dd 100644 (file)
@@ -886,7 +886,7 @@ Adjusted test2 for this.
 Allow using a URL in 'path'.  Makes ":find index.html" work.
 
 GTK: Allow dropping a http:// and ftp:// URL on Vim.  The netrw plugin takes
-care of downloading the file. (MiKael Berthe)
+care of downloading the file. (Mikael Berthe)
 
 
 Window for command-line editing                                *new-cmdwin*
@@ -5388,7 +5388,7 @@ Files:        src/os_win32.c
 
 Patch 6.0.256 (extra)
 Problem:    Win32: ":highlight Comment guifg=asdf" does not give an error
-           message. (Randall W.  Morris)  Also for other systems.
+           message. (Randall W. Morris)  Also for other systems.
 Solution:   Add gui_get_color() to give one error message for all systems.
 Files:     src/gui.c, src/gui_amiga.c, src/gui_athena.c, src/gui_motif.c,
            src/gui_riscos.c, src/gui_x11.c, src/gui_gtk_x11.c,
@@ -9955,7 +9955,7 @@ Use "copy /y" in Make_bc5.mak to avoid a prompt for overwriting.
 
 Patch 6.2.001
 Problem:    The ":stopinsert" command doesn't have a help tag.
-Solution:   Add the tag. (Antoine J.  Mechelynck)
+Solution:   Add the tag. (Antoine J. Mechelynck)
 Files:     runtime/doc/insert.txt, runtime/doc/tags
 
 Patch 6.2.002
index e5ed6df..98ea0a3 100644 (file)
@@ -1445,7 +1445,7 @@ g CTRL-G also shows the number of characters if it differs from the number of
 bytes.
 
 Completion for ":debug" and entering an expression for the '=' register.  Skip
-":" between range and command name. (Peter winters)
+":" between range and command name. (Peter Winters)
 
 CTRL-Q in Insert mode now works like CTRL-V by default.  Previously it was
 ignored.
@@ -3371,7 +3371,7 @@ Files:        runtime/scripts.vim
 Patch 7.0.050
 Problem:    After using the netbeans interface close command a stale pointer
            may be used.
-Solution:   Clear the pointer to the closed buffer. (Xaview de Gaye)
+Solution:   Clear the pointer to the closed buffer. (Xavier de Gaye)
 Files:     src/netbeans.c
 
 Patch 7.0.051 (after 7.0.44)
@@ -10202,7 +10202,7 @@ objects in place of `str()` ones avoiding possibility of UnicodeDecodeError.
 interfaces to some extent. Extent will be improved in the future.
 
 Added special |python-vars| objects also available for |python-buffer| and 
-|python-window|. They ease access to VimL variables from Python.
+|python-window|. They ease access to Vim script variables from Python.
 
 Now you no longer need to alter `sys.path` to import your module: special 
 hooks are responsible for importing from {rtp}/python2, {rtp}/python3 and 
@@ -16272,7 +16272,7 @@ Files:      src/regexp_nfa.c, src/testdir/test64.in, src/testdir/test64.ok
 
 Patch 7.3.1026
 Problem:    New regexp: pattern that includes a new-line matches too early.
-           (john McGowan)
+           (John McGowan)
 Solution:   Do not start searching in the second line.
 Files:     src/regexp_nfa.c, src/testdir/test64.in, src/testdir/test64.ok
 
index a419bd7..09285c6 100644 (file)
@@ -1,4 +1,4 @@
-*version8.txt*  For Vim version 8.0.  Last change: 2016 Nov 06
+*version8.txt*  For Vim version 8.0.  Last change: 2017 Apr 23
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -181,6 +181,12 @@ Insert mode commands: ~
 |i_CTRL-G_U|   CTRL-G U        don't break undo with next cursor movement
 
 
+Cmdline mode commands: ~
+
+|/_CTRL-G|     CTRL-G          move to the next match in 'incsearch' mode
+|/_CTRL-T|     CTRL-T          move to the previous match in 'incsearch' mode
+
+
 Options: ~
 
 'belloff'              do not ring the bell for these reasons
@@ -194,9 +200,9 @@ Options: ~
 'perldll'              name of the Perl dynamic library
 'pythondll'            name of the Python 2 dynamic library
 'pythonthreedll'       name of the Python 3 dynamic library
-'signcolumn'           when to display the sign column
 'renderoptions'                options for text rendering on Windows
 'rubydll'              name of the Ruby dynamic library
+'signcolumn'           when to display the sign column
 'tagcase'              how to handle case when searching in tags files
 'tcldll'               name of the Tcl dynamic library
 'termguicolors'                use GUI colors for the terminal
@@ -224,6 +230,7 @@ Ex commands: ~
 Ex command modifiers: ~
 
 |:keeppatterns|                following command keeps search pattern history
+|<mods>|               supply command modifiers to user defined commands
 
 
 New and extended functions: ~
@@ -289,7 +296,7 @@ New and extended functions: ~
 |systemlist()|         get the result of a shell command as a list
 |test_alloc_fail()|    make memory allocation fail
 |test_autochdir()|     test 'autochdir' functionality
-|test_disable_char_avail()| test without typeahead
+test_disable_char_avail() test without typeahead (removed later)
 |test_garbagecollect_now()| free memory right now
 |test_null_channel()|  return a null Channel
 |test_null_dict()|     return a null Dict
@@ -419,7 +426,7 @@ When no vimrc file is found, the |defaults.vim| script is loaded to set more
 useful default values for new users.  That includes setting 'nocompatible'.
 Thus Vim no longer starts up in Vi compatible mode.  If you do want that,
 either create a .vimrc file that does "set compatible" or start Vim with
-"Vim -C".
+"vim -C".
 
 
 Support removed ~
@@ -1859,7 +1866,7 @@ Files:        runtime/doc/eval.txt, src/eval.c, src/testdir/test60.in,
            src/testdir/test60.ok
 
 Patch 7.4.237 (after 7.4.236)
-Problem:    When some patches was not included has("patch-7.4.123") may return
+Problem:    When some patches were not included has("patch-7.4.123") may return
            true falsely.
 Solution:   Check for the specific patch number.
 Files:     runtime/doc/eval.txt, src/eval.c
@@ -3429,7 +3436,7 @@ Files:        runtime/doc/options.txt, src/Makefile, src/regexp.c, src/regexp.h,
 Patch 7.4.498 (after 7.4.497)
 Problem:    Typo in DOS makefile.
 Solution:   Change exists to exist. (Ken Takata)
-Files:     src/testdirMake_dos.mak
+Files:     src/testdir/Make_dos.mak
 
 Patch 7.4.499
 Problem:    substitute() can be slow with long strings.
@@ -14923,4 +14930,3111 @@ Solution:   Define ONE_WINDOW and add #ifdef.
 Files:      src/globals.h, src/buffer.c, src/ex_docmd.c, src/move.c,
             src/screen.c, src/quickfix.c, src/window.c
 
+Patch 8.0.0070
+Problem:    Tests referred in Makefile that no longer exist.
+Solution:   Remove test71 and test74 entries. (Michael Soyka)
+Files:      src/testdir/Mak_ming.mak
+
+Patch 8.0.0071
+Problem:    Exit value from a shell command is wrong. (Hexchain Tong)
+Solution:   Do not check for ended jobs while waiting for a shell command.
+            (ichizok, closes #1196)
+Files:      src/os_unix.c
+
+Patch 8.0.0072
+Problem:    MS-Windows: Crash with long font name. (Henry Hu)
+Solution:   Fix comparing with LF_FACESIZE. (Ken Takata, closes #1243)
+Files:      src/os_mswin.c
+
+Patch 8.0.0073 (after 8.0.0069)
+Problem:    More comparisons between firstwin and lastwin.
+Solution:   Use ONE_WINDOW for consistency. (Hirohito Higashi)
+Files:      src/buffer.c, src/ex_cmds.c, src/ex_docmd.c, src/option.c,
+            src/window.c
+
+Patch 8.0.0074
+Problem:    Cannot make Vim fail on an internal error.
+Solution:   Add IEMSG() and IEMSG2(). (Dominique Pelle)  Avoid reporting an
+            internal error without mentioning where.
+Files:      src/globals.h, src/blowfish.c, src/dict.c, src/edit.c, src/eval.c,
+            src/evalfunc.c, src/ex_eval.c, src/getchar.c, src/gui_beval.c,
+            src/gui_w32.c, src/hangulin.c, src/hashtab.c, src/if_cscope.c,
+            src/json.c, src/memfile.c, src/memline.c, src/message.c,
+            src/misc2.c, src/option.c, src/quickfix.c, src/regexp.c,
+            src/spell.c, src/undo.c, src/userfunc.c, src/vim.h, src/window.c,
+            src/proto/misc2.pro, src/proto/message.pro, src/Makefile
+
+Patch 8.0.0075
+Problem:    Using number for exception type lacks type checking.
+Solution:   Use an enum.
+Files:      src/structs.h, src/ex_docmd.c, src/ex_eval.c,
+            src/proto/ex_eval.pro
+
+Patch 8.0.0076
+Problem:    Channel log has double parens ()().
+Solution:   Remove () for write_buf_line. (Yasuhiro Matsumoto)
+Files:      src/channel.c
+
+Patch 8.0.0077
+Problem:    The GUI code is not tested by Travis.
+Solution:   Install the virtual framebuffer.
+Files:      .travis.yml
+
+Patch 8.0.0078
+Problem:    Accessing freed memory in quickfix.
+Solution:   Reset pointer when freeing 'errorformat'. (Dominique Pelle)
+Files:      src/quickfix.c, src/testdir/test_quickfix.vim
+
+Patch 8.0.0079
+Problem:    Accessing freed memory in quickfix. (Dominique Pelle)
+Solution:   Do not free the current list when adding to it.
+Files:      src/quickfix.c, src/testdir/test_quickfix.vim
+
+Patch 8.0.0080
+Problem:    The OS X build fails on Travis.
+Solution:   Skip the virtual framebuffer on OS X.
+Files:      .travis.yml
+
+Patch 8.0.0081
+Problem:    Inconsistent function names.
+Solution:   Rename do_cscope to ex_cscope.  Clean up comments.
+Files:      src/ex_cmds.h, src/if_cscope.c, src/ex_docmd.c,
+            src/proto/if_cscope.pro
+
+Patch 8.0.0082
+Problem:    Extension for configure should be ".ac".
+Solution:   Rename configure.in to configure.ac. (James McCoy, closes #1173)
+Files:      src/configure.in, src/configure.ac, Filelist, src/Makefile,
+            src/blowfish.c, src/channel.c, src/config.h.in, src/main.aap,
+            src/os_unix.c, src/INSTALL, src/mysign
+
+Patch 8.0.0083
+Problem:    Using freed memory with win_getid(). (Dominique Pelle)
+Solution:   For the current tab use curwin.
+Files:      src/window.c, src/testdir/test_window_id.vim
+
+Patch 8.0.0084
+Problem:    Using freed memory when adding to a quickfix list. (Dominique
+            Pelle)
+Solution:   Clear the directory name.
+Files:      src/quickfix.c, src/testdir/test_quickfix.vim
+
+Patch 8.0.0085
+Problem:    Using freed memory with recursive function call. (Dominique Pelle)
+Solution:   Make a copy of the function name.
+Files:      src/eval.c, src/testdir/test_nested_function.vim
+
+Patch 8.0.0086
+Problem:    Cannot add a comment after ":hide". (Norio Takagi)
+Solution:   Make it work, add a test. (Hirohito Higashi)
+Files:      src/Makefile, src/ex_cmds.h, src/ex_docmd.c,
+            src/testdir/Make_all.mak, src/testdir/test_hide.vim
+
+Patch 8.0.0087
+Problem:    When the channel callback gets job info the job may already have
+            been deleted. (lifepillar)
+Solution:   Do not delete the job when the channel is still useful. (ichizok,
+            closes #1242, closes #1245)
+Files:      src/channel.c, src/eval.c, src/os_unix.c, src/os_win32.c,
+            src/structs.h, src/testdir/test_channel.vim
+
+Patch 8.0.0088
+Problem:    When a test fails in Setup or Teardown the problem is not reported.
+Solution:   Add a try/catch. (Hirohito Higashi)
+Files:      src/testdir/runtest.vim
+
+Patch 8.0.0089
+Problem:    Various problems with GTK 3.22.2.
+Solution:   Fix the problems, add #ifdefs. (Kazunobu Kuriyama)
+Files:      src/gui_beval.c, src/gui_gtk.c, src/gui_gtk_x11.c
+
+Patch 8.0.0090
+Problem:    Cursor moved after last character when using 'breakindent'.
+Solution:   Fix the cursor positioning.  Turn the breakindent test into new
+            style.  (Christian Brabandt)
+Files:      src/screen.c, src/testdir/Make_all.mak,
+            src/testdir/test_breakindent.in, src/testdir/test_breakindent.ok,
+            src/testdir/test_breakindent.vim, src/Makefile
+
+Patch 8.0.0091
+Problem:    Test_help_complete sometimes fails in MS-Windows console.
+Solution:   Use getcompletion() instead of feedkeys() and command line
+            completion. (Hirohito Higashi)
+Files:      src/testdir/test_help_tagjump.vim
+
+Patch 8.0.0092
+Problem:    C indenting does not support nested namespaces that C++ 17 has.
+Solution:   Add check that passes double colon inside a name. (Pauli, closes
+            #1214)
+Files:      src/misc1.c, src/testdir/test3.in, src/testdir/test3.ok
+
+Patch 8.0.0093
+Problem:    Not using multiprocess build feature.
+Solution:   Enable multiprocess build with MSVC 10. (Ken Takata)
+Files:      src/Make_mvc.mak
+
+Patch 8.0.0094
+Problem:    When vimrun.exe is not found the error message is not properly
+            encoded.
+Solution:   Use utf-16 and MessageBoxW(). (Ken Takata)
+Files:      src/os_win32.c
+
+Patch 8.0.0095
+Problem:    Problems with GTK 3.22.2 fixed in 3.22.4.
+Solution:   Adjust the #ifdefs. (Kazunobu Kuriyama)
+Files:      src/gui_gtk_x11.c
+
+Patch 8.0.0096
+Problem:    When the input or output is not a tty Vim appears to hang.
+Solution:   Add the --ttyfail argument.  Also add the "ttyin" and "ttyout"
+            features to be able to check in Vim script.
+Files:      src/globals.h, src/structs.h, src/main.c, src/evalfunc.c,
+            runtime/doc/starting.txt, runtime/doc/eval.txt
+
+Patch 8.0.0097
+Problem:    When a channel callback consumes a lot of time Vim becomes
+            unresponsive. (skywind)
+Solution:   Bail out of checking channel readahead after 100 msec.
+Files:      src/os_unix.c, src/misc2.c, src/vim.h, src/os_win32.c,
+            src/channel.c
+
+Patch 8.0.0098 (after 8.0.0097)
+Problem:    Can't build on MS-Windows.
+Solution:   Add missing parenthesis.
+Files:      src/vim.h
+
+Patch 8.0.0099
+Problem:    Popup menu always appears above the cursor when it is in the lower
+            half of the screen. (Matt Gardner)
+Solution:   Compute the available space better. (Hirohito Higashi,
+            closes #1241)
+Files:      src/popupmnu.c
+
+Patch 8.0.0100
+Problem:    Options that are a file name may contain non-filename characters.
+Solution:   Check for more invalid characters.
+Files:      src/option.c
+
+Patch 8.0.0101
+Problem:    Some options are not strictly checked.
+Solution:   Add flags for strickter checks.
+Files:      src/option.c
+
+Patch 8.0.0102 (after 8.0.0101)
+Problem:    Cannot set 'dictionary' to a path.
+Solution:   Allow for slash and backslash.  Add a test (partly by Daisuke
+            Suzuki, closes #1279, closes #1284)
+Files:      src/option.c, src/testdir/test_options.vim
+
+Patch 8.0.0103
+Problem:    May not process channel readahead. (skywind)
+Solution:   If there is readahead don't block on input.
+Files:      src/channel.c, src/proto/channel.pro, src/os_unix.c,
+            src/os_win32.c, src/misc2.c
+
+Patch 8.0.0104
+Problem:    Value of 'thesaurus' option not checked properly.
+Solution:   Add P_NDNAME flag. (Daisuke Suzuki)
+Files:      src/option.c, src/testdir/test_options.vim
+
+Patch 8.0.0105
+Problem:    When using ch_read() with zero timeout, can't tell the difference
+            between reading an empty line and nothing available.
+Solution:   Add ch_canread().
+Files:      src/evalfunc.c, src/channel.c, src/proto/channel.pro,
+            src/testdir/test_channel.vim, src/testdir/shared.vim,
+            runtime/doc/eval.txt, runtime/doc/channel.txt
+
+Patch 8.0.0106 (after 8.0.0100)
+Problem:    Cannot use a semicolon in 'backupext'. (Jeff)
+Solution:   Allow for a few more characters when "secure" isn't set.
+Files:      src/option.c
+
+Patch 8.0.0107
+Problem:    When reading channel output in a timer, messages may go missing.
+            (Skywind)
+Solution:   Add the "drop" option.  Write error messages in the channel log.
+            Don't have ch_canread() check for the channel being open.
+Files:      src/structs.h, src/channel.c, src/message.c, src/evalfunc.c,
+            src/proto/channel.pro, runtime/doc/channel.txt
+
+Patch 8.0.0108 (after 8.0.0107)
+Problem:    The channel "drop" option is not tested.
+Solution:   Add a test.
+Files:      src/testdir/test_channel.vim
+
+Patch 8.0.0109
+Problem:    Still checking if memcmp() exists while every system should have
+            it now.
+Solution:   Remove vim_memcmp().  (James McCoy, closes #1295)
+Files:      src/config.h.in, src/configure.ac, src/misc2.c, src/os_vms_conf.h,
+            src/osdef1.h.in, src/search.c, src/tag.c, src/vim.h
+
+Patch 8.0.0110
+Problem:    Drop command doesn't use existing window.
+Solution:   Check the window width properly. (Hirohito Higashi)
+Files:      src/buffer.c, src/testdir/test_tabpage.vim
+
+Patch 8.0.0111
+Problem:    The :history command is not tested.
+Solution:   Add tests. (Dominique Pelle)
+Files:      runtime/doc/cmdline.txt, src/testdir/test_history.vim
+
+Patch 8.0.0112
+Problem:    Tests 92 and 93 are old style.
+Solution:   Make test92 and test93 new style. (Hirohito Higashi, closes #1289)
+Files:      src/Makefile, src/testdir/Make_all.mak, src/testdir/Make_vms.mms,
+            src/testdir/test92.in, src/testdir/test92.ok,
+            src/testdir/test93.in, src/testdir/test93.ok,
+            src/testdir/test_mksession.vim,
+            src/testdir/test_mksession_utf8.vim
+
+Patch 8.0.0113
+Problem:    MS-Windows: message box to prompt for saving changes may appear on
+            the wrong monitor.
+Solution:   Adjust the CenterWindow function. (Ken Takata)
+Files:      src/gui_w32.c
+
+Patch 8.0.0114
+Problem:    Coding style not optimal.
+Solution:   Add spaces. (Ken Takata)
+Files:      src/gui_w32.c, src/os_mswin.c
+
+Patch 8.0.0115
+Problem:    When building with Cygwin libwinpthread isn't found.
+Solution:   Link winpthread statically. (jmmerz, closes #1255, closes #1256)
+Files:      src/Make_cyg_ming.mak
+
+Patch 8.0.0116
+Problem:    When reading English help and using CTRl-] the language from
+            'helplang' is used.
+Solution:   Make help tag jumps keep the language. (Tatsuki, test by Hirohito
+            Higashi, closes #1249)
+Files:      src/tag.c, src/testdir/test_help_tagjump.vim
+
+Patch 8.0.0117
+Problem:    Parallel make fails. (J. Lewis Muir)
+Solution:   Make sure the objects directory exists. (closes #1259)
+Files:      src/Makefile
+
+Patch 8.0.0118
+Problem:    "make proto" adds extra function prototype.
+Solution:   Add #ifdef.
+Files:      src/misc2.c
+
+Patch 8.0.0119
+Problem:    No test for using CTRL-R on the command line.
+Solution:   Add a test. (Dominique Pelle) And some more.
+Files:      src/testdir/test_cmdline.vim
+
+Patch 8.0.0120
+Problem:    Channel test is still flaky on OS X.
+Solution:   Set the drop argument to "never".
+Files:      src/testdir/test_channel.vim
+
+Patch 8.0.0121
+Problem:    Setting 'cursorline' changes the curswant column. (Daniel Hahler)
+Solution:   Add the P_RWINONLY flag. (closes #1297)
+Files:      src/option.c, src/testdir/test_goto.vim
+
+Patch 8.0.0122
+Problem:    Channel test is still flaky on OS X.
+Solution:   Add a short sleep.
+Files:      src/testdir/test_channel.py
+
+Patch 8.0.0123
+Problem:    Modern Sun compilers define "__sun" instead of "sun".
+Solution:   Use __sun. (closes #1296)
+Files:      src/mbyte.c, src/pty.c, src/os_unixx.h, src/vim.h
+
+Patch 8.0.0124
+Problem:    Internal error for assert_inrange(1, 1).
+Solution:   Adjust number of allowed arguments. (Dominique Pelle)
+Files:      src/evalfunc.c, src/testdir/test_assert.vim
+
+Patch 8.0.0125
+Problem:    Not enough testing for entering Ex commands.
+Solution:   Add test for CTRL-\ e {expr}. (Dominique Pelle)
+Files:      src/testdir/test_cmdline.vim
+
+Patch 8.0.0126
+Problem:    Display problem with 'foldcolumn' and a wide character.
+            (esiegerman)
+Solution:   Don't use "extra" but an allocated buffer. (Christian Brabandt,
+            closes #1310)
+Files:      src/screen.c, src/testdir/Make_all.mak, src/Makefile,
+            src/testdir/test_display.vim
+
+Patch 8.0.0127
+Problem:    Cancelling completion still inserts text when formatting is done 
+            for 'textwidth'. (lacygoill)
+Solution:   Don't format when CTRL-E was typed. (Hirohito Higashi,
+            closes #1312)
+Files:      src/edit.c, src/testdir/test_popup.vim
+
+Patch 8.0.0128 (after 8.0.0126)
+Problem:    Display test fails on MS-Windows.
+Solution:   Set 'isprint' to "@".
+Files:      src/testdir/test_display.vim
+
+Patch 8.0.0129
+Problem:    Parallel make still doesn't work. (Lewis Muir)
+Solution:   Define OBJ_MAIN.
+Files:      src/Makefile
+
+Patch 8.0.0130
+Problem:    Configure uses "ushort" while the Vim code doesn't.
+Solution:   Use "unsigned short" instead. (Fredrik Fornwall, closes #1314)
+Files:      src/configure.ac, src/auto/configure
+
+Patch 8.0.0131
+Problem:    Not enough test coverage for syntax commands.
+Solution:   Add more tests. (Dominique Pelle)
+Files:      src/testdir/test_syntax.vim
+
+Patch 8.0.0132 (after 8.0.0131)
+Problem:    Test fails because of using :finish.
+Solution:   Change to return.
+Files:      src/testdir/test_syntax.vim
+
+Patch 8.0.0133
+Problem:    "2;'(" causes ml_get errors in an empty buffer.  (Dominique Pelle)
+Solution:   Check the cursor line earlier.
+Files:      src/ex_docmd.c, src/testdir/test_cmdline.vim
+
+Patch 8.0.0134
+Problem:    Null pointer access reported by UBsan.
+Solution:   Check curwin->w_buffer is not NULL. (Yegappan Lakshmanan)
+Files:      src/ex_cmds.c
+
+Patch 8.0.0135
+Problem:    An address relative to the current line, ":.,+3y", does not work
+            properly on a closed fold. (Efraim Yawitz)
+Solution:   Correct for including the closed fold. (Christian Brabandt)
+Files:      src/ex_docmd.c, src/testdir/test_fold.vim,
+            src/testdir/Make_all.mak, src/Makefile
+
+Patch 8.0.0136
+Problem:    When using indent folding and changing indent the wrong fold is
+            opened. (Jonathan Fudger)
+Solution:   Open the fold under the cursor a bit later. (Christian Brabandt)
+Files:      src/ops.c, src/testdir/test_fold.vim
+
+Patch 8.0.0137
+Problem:    When 'maxfuncdepth' is set above 200 the nesting is limited to
+            200. (Brett Stahlman)
+Solution:   Allow for Ex command recursion depending on 'maxfuncdepth'.
+Files:      src/ex_docmd.c, src/testdir/test_nested_function.vim
+
+Patch 8.0.0138 (after 8.0.0137)
+Problem:    Small build fails.
+Solution:   Add #ifdef.
+Files:      src/ex_docmd.c
+
+Patch 8.0.0139 (after 8.0.0135)
+Problem:    Warning for unused argument.
+Solution:   Add UNUSED.
+Files:      src/ex_docmd.c
+
+Patch 8.0.0140
+Problem:    Pasting inserted text in Visual mode does not work properly.
+            (Matthew Malcomson)
+Solution:   Stop Visual mode before stuffing the inserted text. (Christian
+            Brabandt, from neovim #5709)
+Files:      src/ops.c, src/testdir/test_visual.vim
+
+Patch 8.0.0141 (after 8.0.0137)
+Problem:    Nested function test fails on AppVeyor.
+Solution:   Disable the test on Windows for now.
+Files:      src/testdir/test_nested_function.vim
+
+Patch 8.0.0142
+Problem:    Normal colors are wrong with 'termguicolors'.
+Solution:   Initialize to INVALCOLOR instead of zero. (Ben Jackson, closes
+            #1344)
+Files:      src/syntax.c
+
+Patch 8.0.0143
+Problem:    Line number of current buffer in getbufinfo() is wrong.
+Solution:   For the current buffer use the current line number. (Ken Takata)
+Files:      src/evalfunc.c
+
+Patch 8.0.0144
+Problem:    When using MSVC the GvimExt directory is cleaned twice.
+Solution:   Remove the lines. (Ken Takata)
+Files:      src/Make_mvc.mak
+
+Patch 8.0.0145
+Problem:    Running tests on MS-Windows is a little bit noisy.
+Solution:   Redirect some output to "nul". (Ken Takata)
+Files:      src/testdir/Make_dos.mak
+
+Patch 8.0.0146
+Problem:    When using 'termguicolors' on MS-Windows the RGB definition causes
+            the colors to be wrong.
+Solution:   Undefined RGB and use our own. (Gabriel Barta)
+Files:      src/term.c
+
+Patch 8.0.0147
+Problem:    searchpair() does not work when 'magic' is off. (Chris Paul)
+Solution:   Add \m in the pattern. (Christian Brabandt, closes #1341)
+Files:      src/evalfunc.c, src/testdir/test_search.vim
+
+Patch 8.0.0148
+Problem:    When a C preprocessor statement has two line continuations the
+            following line does not have the right indent. (Ken Takata)
+Solution:   Add the indent of the previous continuation line. (Hirohito
+            Higashi)
+Files:      src/misc1.c, src/testdir/test3.in, src/testdir/test3.ok
+
+Patch 8.0.0149
+Problem:    ":earlier" and ":later" do not work after startup or reading the
+            undo file.
+Solution:   Use absolute time stamps instead of relative to the Vim start
+            time. (Christian Brabandt, Pavel Juhas, closes #1300, closes
+            #1254)
+Files:      src/testdir/test_undo.vim, src/undo.c
+
+Patch 8.0.0150
+Problem:    When the pattern of :filter does not have a separator then
+            completion of the command fails.
+Solution:   Skip over the pattern. (Ozaki Kiichi, clodes #1299)
+Files:      src/ex_docmd.c, src/testdir/test_filter_cmd.vim
+
+Patch 8.0.0151
+Problem:    To pass buffer content to system() and systemlist() one has to
+            first create a string or list.
+Solution:   Allow passing a buffer number. (LemonBoy, closes #1240)
+Files:      runtime/doc/eval.txt, src/Makefile, src/evalfunc.c,
+            src/testdir/Make_all.mak, src/testdir/test_system.vim
+
+Patch 8.0.0152
+Problem:    Running the channel test creates channellog.
+Solution:   Delete the debug line.
+Files:      src/testdir/test_channel.vim
+
+Patch 8.0.0153 (after 8.0.0151)
+Problem:    system() test fails on MS-Windows.
+Solution:   Deal with extra space and CR.
+Files:      src/testdir/test_system.vim
+
+Patch 8.0.0154 (after 8.0.0151)
+Problem:    system() test fails on OS/X.
+Solution:   Deal with leading spaces.
+Files:      src/testdir/test_system.vim
+
+Patch 8.0.0155
+Problem:    When sorting zero elements a NULL pointer is passed to qsort(),
+            which ubsan warns for.
+Solution:   Don't call qsort() if there are no elements. (Dominique Pelle)
+Files:      src/syntax.c
+
+Patch 8.0.0156
+Problem:    Several float functions are not covered by tests.
+Solution:   Add float tests. (Dominique Pelle)
+Files:      src/Makefile, src/testdir/test_alot.vim,
+            src/testdir/test_float_func.vim
+
+Patch 8.0.0157
+Problem:    No command line completion for ":syntax spell" and ":syntax sync".
+Solution:   Implement the completion. (Dominique Pelle)
+Files:      src/syntax.c, src/testdir/test_syntax.vim
+
+Patch 8.0.0158 (after 8.0.0156)
+Problem:    On MS-Windows some float functions return a different value when
+            passed unusual values.  strtod() doesn't work for "inf" and "nan".
+Solution:   Accept both results.  Fix str2float() for MS-Windows.  Also
+            reorder assert function arguments.
+Files:      src/testdir/test_float_func.vim, src/eval.c
+
+Patch 8.0.0159
+Problem:    Using a NULL pointer when using feedkeys() to trigger drawing a
+            tabline.
+Solution:   Skip drawing a tabline if TabPageIdxs is NULL. (Dominique Pelle)
+            Also fix recursing into getcmdline() from the cmd window.
+Files:      src/screen.c, src/ex_getln.c
+
+Patch 8.0.0160
+Problem:    EMSG() is sometimes used for internal errors.
+Solution:   Change them to IEMSG(). (Dominique Pelle)  And a few more.
+Files:      src/regexp_nfa.c, src/channel.c, src/eval.c
+
+Patch 8.0.0161 (after 8.0.0159)
+Problem:    Build fails when using small features.
+Solution:   Update #ifdef for using save_ccline. (Hirohito Higashi)
+Files:      src/ex_getln.c
+
+Patch 8.0.0162
+Problem:    Build error on Fedora 23 with small features and gnome2.
+Solution:   Undefine ngettext(). (Hirohito Higashi)
+Files:      src/gui_gtk.c, src/gui_gtk_x11.c
+
+Patch 8.0.0163
+Problem:    Ruby 2.4 no longer supports rb_cFixnum.
+Solution:   move rb_cFixnum into an #ifdef. (Kazuki Sakamoto, closes #1365)
+Files:      src/if_ruby.c
+
+Patch 8.0.0164
+Problem:    Outdated and misplaced comments.
+Solution:   Fix the comments.
+Files:      src/charset.c, src/getchar.c, src/list.c, src/misc2.c,
+            src/testdir/README.txt
+
+Patch 8.0.0165
+Problem:    Ubsan warns for integer overflow.
+Solution:   Swap two conditions. (Dominique Pelle)
+Files:      src/regexp_nfa.c
+
+Patch 8.0.0166
+Problem:    JSON with a duplicate key gives an internal error. (Lcd)
+Solution:   Give a normal error.  Avoid an error when parsing JSON from a
+            remote client fails.
+Files:      src/evalfunc.c, src/json.c, src/channel.c,
+            src/testdir/test_json.vim
+
+Patch 8.0.0167
+Problem:    str2nr() and str2float() do not always work with negative values.
+Solution:   Be more flexible about handling signs. (LemonBoy, closes #1332)
+            Add more tests.
+Files:      src/evalfunc.c, src/testdir/test_float_func.vim,
+            src/testdir/test_functions.vim, src/testdir/test_alot.vim,
+            src/Makefile
+
+Patch 8.0.0168
+Problem:    Still some float functionality is not covered by tests.
+Solution:   Add more tests. (Dominique Pelle, closes #1364)
+Files:      src/testdir/test_float_func.vim
+
+Patch 8.0.0169
+Problem:    For complicated string json_decode() may run out of stack space.
+Solution:   Change the recursive solution into an iterative solution.
+Files:      src/json.c
+
+Patch 8.0.0170 (after 8.0.0169)
+Problem:    Channel test fails for using freed memory.
+Solution:   Fix memory use in json_decode().
+Files:      src/json.c
+
+Patch 8.0.0171
+Problem:    JS style JSON does not support single quotes.
+Solution:   Allow for single quotes. (Yasuhiro Matsumoto, closes #1371)
+Files:      src/json.c, src/testdir/test_json.vim, src/json_test.c,
+            runtime/doc/eval.txt
+
+Patch 8.0.0172 (after 8.0.0159)
+Problem:    The command selected in the command line window is not executed.
+            (Andrey Starodubtsev)
+Solution:   Save and restore the command line at a lower level. (closes #1370)
+Files:      src/ex_getln.c, src/testdir/test_history.vim
+
+Patch 8.0.0173
+Problem:    When compiling with EBCDIC defined the build fails. (Yaroslav
+            Kuzmin)
+Solution:   Move sortFunctions() to the right file.  Avoid warning for
+            redefining __SUSV3.
+Files:      src/eval.c, src/evalfunc.c, src/os_unixx.h
+
+Patch 8.0.0174
+Problem:    For completion "locale -a" is executed on MS-Windows, even though
+            it most likely won't work.
+Solution:   Skip executing "locale -a" on MS-Windows. (Ken Takata)
+Files:      src/ex_cmds2.c
+
+Patch 8.0.0175
+Problem:    Setting language in gvim on MS-Windows does not work when
+            libintl.dll is dynamically linked with msvcrt.dll.
+Solution:   Use putenv() from libintl as well. (Ken Takata, closes #1082)
+Files:      src/mbyte.c, src/misc1.c, src/os_win32.c, src/proto/os_win32.pro,
+            src/vim.h
+
+Patch 8.0.0176
+Problem:    Using :change in between :function and :endfunction fails.
+Solution:   Recognize :change inside a function. (ichizok, closes #1374)
+Files:      src/userfunc.c, src/testdir/test_viml.vim
+
+Patch 8.0.0177
+Problem:    When opening a buffer on a directory and inside a try/catch then
+            the BufEnter event is not triggered.
+Solution:   Return NOTDONE from readfile() for a directory and deal with the
+            three possible return values. (Justin M. Keyes, closes #1375,
+            closes #1353)
+Files:      src/buffer.c, src/ex_cmds.c, src/ex_docmd.c, src/fileio.c,
+            src/memline.c
+
+Patch 8.0.0178
+Problem:    test_command_count may fail when a previous test interferes, seen
+            on MS-Windows.
+Solution:   Run it separately.
+Files:      src/testdir/test_alot.vim, src/testdir/Make_all.mak
+
+Patch 8.0.0179
+Problem:    'formatprg' is a global option but the value may depend on the
+            type of buffer. (Sung Pae)
+Solution:   Make 'formatprg' global-local. (closes #1380)
+Files:      src/structs.h, src/option.h, src/option.c, src/normal.c,
+            runtime/doc/options.txt, src/testdir/test_normal.vim
+
+Patch 8.0.0180
+Problem:    Error E937 is used both for duplicate key in JSON and for trying
+            to delete a buffer that is in use.
+Solution:   Rename the JSON error to E938. (Norio Takagi, closes #1376)
+Files:      src/json.c, src/testdir/test_json.vim
+
+Patch 8.0.0181
+Problem:    When 'cursorbind' and 'cursorcolumn' are both on, the column
+            highlignt in non-current windows is wrong.
+Solution:   Add validate_cursor(). (Masanori Misono, closes #1372)
+Files:      src/move.c
+
+Patch 8.0.0182
+Problem:    When 'cursorbind' and 'cursorline' are set, but 'cursorcolumn' is
+            not, then the cursor line highlighting is not updated. (Hirohito
+            Higashi)
+Solution:   Call redraw_later() with NOT_VALID.
+Files:      src/move.c
+
+Patch 8.0.0183
+Problem:    Ubsan warns for using a pointer that is not aligned.
+Solution:   First copy the address. (Yegappan Lakshmanan)
+Files:      src/channel.c
+
+Patch 8.0.0184
+Problem:    When in Ex mode and an error is caught by try-catch, Vim still
+            exits with a non-zero exit code.
+Solution:   Don't set ex_exitval when inside a try-catch. (partly by Christian
+            Brabandt)
+Files:      src/message.c, src/testdir/test_system.vim
+
+Patch 8.0.0185 (after 8.0.0184)
+Problem:    The system() test fails on MS-Windows.
+Solution:   Skip the test on MS-Windows.
+Files:      src/testdir/test_system.vim
+
+Patch 8.0.0186
+Problem:    The error message from assert_notequal() is confusing.
+Solution:   Only mention the expected value.
+Files:      src/eval.c, src/testdir/test_assert.vim
+
+Patch 8.0.0187
+Problem:    Building with a new Ruby version fails.
+Solution:   Use ruby_sysinit() instead of NtInitialize(). (Tomas Volf,
+            closes #1382)
+Files:      src/if_ruby.c
+
+Patch 8.0.0188 (after 8.0.0182)
+Problem:    Using NOT_VALID for redraw_later() to update the cursor
+            line/column highlighting is not efficient.
+Solution:   Call validate_cursor() when 'cul' or 'cuc' is set.
+Files:      src/move.c
+
+Patch 8.0.0189
+Problem:    There are no tests for the :profile command.
+Solution:   Add tests. (Dominique Pelle, closes #1383)
+Files:      src/Makefile, src/testdir/Make_all.mak,
+            src/testdir/test_profile.vim
+
+Patch 8.0.0190
+Problem:    Detecting duplicate tags uses a slow linear search.
+Solution:   Use a much faster hash table solution. (James McCoy, closes #1046)
+            But don't add hi_keylen, it makes hash tables 50% bigger.
+Files:      src/tag.c
+
+Patch 8.0.0191 (after 8.0.0187)
+Problem:    Some systems do not have ruby_sysinit(), causing the build to
+            fail.
+Solution:   Clean up how ruby_sysinit() and NtInitialize() are used. (Taro
+            Muraoka)
+Files:      src/if_ruby.c
+
+Patch 8.0.0192 (after 8.0.0190)
+Problem:    Build fails with tiny features.
+Solution:   Change #ifdef for hash_clear().  Avoid warning for unused
+            argument.
+Files:      src/hashtab.c, src/if_cscope.c
+
+Patch 8.0.0193 (after 8.0.0188)
+Problem:    Accidentally removed #ifdef.
+Solution:   Put it back. (Masanori Misono)
+Files:      src/move.c
+
+Patch 8.0.0194 (after 8.0.0189)
+Problem:    Profile tests fails if total and self time are equal.
+Solution:   Make one time optional.
+Files:      src/testdir/test_profile.vim
+
+Patch 8.0.0195 (after 8.0.0190)
+Problem:    Jumping to a tag that is a static item in the current file fails.
+            (Kazunobu Kuriyama)
+Solution:   Make sure the first byte of the tag key is not NUL. (Suggested by
+            James McCoy, closes #1387)
+Files:      src/tag.c, src/testdir/test_tagjump.vim
+
+Patch 8.0.0196 (after 8.0.0194)
+Problem:    The test for :profile is slow and does not work on MS-Windows.
+Solution:   Use the "-es" argument. (Dominique Pelle)  Swap single and double
+            quotes for system()
+Files:      src/testdir/test_profile.vim
+
+Patch 8.0.0197
+Problem:    On MS-Windows the system() test skips a few parts.
+Solution:   Swap single and double quotes for the command.
+Files:      src/testdir/test_system.vim
+
+Patch 8.0.0198
+Problem:    Some syntax arguments take effect even after "if 0". (Taylor
+            Venable)
+Solution:   Properly skip the syntax statements.  Make "syn case" and "syn
+            conceal" report the current state.  Fix that "syn clear" didn't
+            reset the conceal flag.  Add tests for :syntax skipping properly.
+Files:      src/syntax.c, src/testdir/test_syntax.vim
+
+Patch 8.0.0199
+Problem:    Warning for an unused parameter when the libcall feature is
+            disabled.  Warning for a function type cast when compiling with
+            -pedantic.
+Solution:   Add UNUSED.  Use a different type cast. (Damien Molinier)
+Files:      src/evalfunc.c, src/os_unix.c
+
+Patch 8.0.0200
+Problem:    Some syntax arguments are not tested.
+Solution:   Add more syntax command tests.
+Files:      src/testdir/test_syntax.vim
+
+Patch 8.0.0201
+Problem:    When completing a group name for a highlight or syntax command
+            cleared groups are included.
+Solution:   Skip groups that have been cleared.
+Files:      src/syntax.c, src/testdir/test_syntax.vim
+
+Patch 8.0.0202
+Problem:    No test for invalid syntax group name.
+Solution:   Add a test for group name error and warning.
+Files:      src/testdir/test_syntax.vim
+
+Patch 8.0.0203
+Problem:    Order of complication flags is sometimes wrong.
+Solution:   Put interface-specific flags before ALL_CFLAGS. (idea by Yousong
+            Zhou, closes #1100)
+Files:      src/Makefile
+
+Patch 8.0.0204
+Problem:    Compiler warns for uninitialized variable. (Tony Mechelynck)
+Solution:   When skipping set "id" to -1.
+Files:      src/syntax.c
+
+Patch 8.0.0205
+Problem:    After :undojoin some commands don't work properly, such as :redo.
+            (Matthew Malcomson)
+Solution:   Don't set curbuf->b_u_curhead. (closes #1390)
+Files:      src/undo.c, src/testdir/test_undo.vim
+
+Patch 8.0.0206
+Problem:    Test coverage for :retab insufficient.
+Solution:   Add test for :retab. (Dominique Pelle, closes #1391)
+Files:      src/Makefile, src/testdir/Make_all.mak, src/testdir/test_retab.vim
+
+Patch 8.0.0207
+Problem:    Leaking file descriptor when system() cannot find the buffer.
+            (Coverity)
+Solution:   Close the file descriptor.  (Dominique Pelle, closes #1398)
+Files:      src/evalfunc.c
+
+Patch 8.0.0208
+Problem:    Internally used commands for CTRL-Z and mouse click end up in
+            history. (Matthew Malcomson)
+Solution:   Use do_cmdline_cmd() instead of stuffing them in the readahead
+            buffer. (James McCoy, closes #1395)
+Files:      src/edit.c, src/normal.c
+
+Patch 8.0.0209
+Problem:    When using :substitute with the "c" flag and 'cursorbind' is set
+            the cursor is not updated in other windows.
+Solution:   Call do_check_cursorbind(). (Masanori Misono)
+Files:      src/ex_cmds.c
+
+Patch 8.0.0210
+Problem:    Vim does not support bracketed paste, as implemented by xterm and
+            other terminals.
+Solution:   Add t_BE, t_BD, t_PS and t_PE.
+Files:      src/term.c, src/term.h, src/option.c, src/misc2.c, src/keymap.h,
+            src/edit.c, src/normal.c, src/evalfunc.c, src/getchar.c,
+            src/vim.h, src/proto/edit.pro, runtime/doc/term.txt
+
+Patch 8.0.0211 (after 8.0.0210)
+Problem:    Build fails if the multi-byte feature is disabled.
+Solution:   Change #ifdef around ins_char_bytes.
+Files:      src/misc1.c
+
+Patch 8.0.0212
+Problem:    The buffer used to store a key name theoreticaly could be too
+            small. (Coverity)
+Solution:   Count all possible modifier characters.  Add a check for the
+            length just in case.
+Files:      src/keymap.h, src/misc2.c
+
+Patch 8.0.0213
+Problem:    The Netbeans "specialKeys" command does not check if the argument
+            fits in the buffer. (Coverity)
+Solution:   Add a length check.
+Files:      src/netbeans.c
+
+Patch 8.0.0214
+Problem:    Leaking memory when syntax cluster id is unknown. (Coverity)
+Solution:   Free the memory.
+Files:      src/syntax.c
+
+Patch 8.0.0215
+Problem:    When a Cscope line contains CTRL-L a NULL pointer may be used.
+            (Coverity)
+Solution:   Don't check for an emacs tag in a cscope line.
+Files:      src/tag.c
+
+Patch 8.0.0216
+Problem:    When decoding JSON with a JS style object the JSON test may use a
+            NULL pointer. (Coverity)
+Solution:   Check for a NULL pointer.
+Files:      src/json.c, src/json_test.c
+
+Patch 8.0.0217 (after 8.0.0215)
+Problem:    Build fails without the cscope feature.
+Solution:   Add #ifdef.
+Files:      src/tag.c
+
+Patch 8.0.0218
+Problem:    No command line completion for :cexpr, :cgetexpr, :caddexpr, etc.
+Solution:   Make completion work. (Yegappan Lakshmanan)  Add a test.
+Files:      src/ex_docmd.c, src/testdir/test_cmdline.vim
+
+Patch 8.0.0219
+Problem:    Ubsan reports errors for integer overflow.
+Solution:   Define macros for minimum and maximum values.  Select an
+            expression based on the value. (Mike Williams)
+Files:      src/charset.c, src/eval.c, src/evalfunc.c, src/structs.h,
+            src/testdir/test_viml.vim
+
+Patch 8.0.0220
+Problem:    Completion for :match does not show "none" and other missing
+            highlight names.
+Solution:   Skip over cleared entries before checking the index to be at the
+            end.
+Files:      src/syntax.c, src/testdir/test_cmdline.vim
+
+Patch 8.0.0221
+Problem:    Checking if PROTO is defined inside a function has no effect.
+Solution:   Remove the check for PROTO. (Hirohito Higashi)
+Files:      src/misc1.c
+
+Patch 8.0.0222
+Problem:    When a multi-byte character ends in a zero byte, putting blockwise
+            text puts it before the character instead of after it.
+Solution:   Use int instead of char for the character under the cursor.
+            (Luchr, closes #1403)  Add a test.
+Files:      src/ops.c, src/testdir/test_put.vim, src/Makefile,
+            src/testdir/test_alot.vim
+
+Patch 8.0.0223
+Problem:    Coverity gets confused by the flags passed to find_tags() and
+            warnts for an uninitialized variable.
+Solution:   Disallow using cscope and help tags at the same time.
+Files:      src/tag.c
+
+Patch 8.0.0224
+Problem:    When 'fileformats' is changed in a BufReadPre auto command, it
+            does not take effect in readfile(). (Gary Johnson)
+Solution:   Check the value of 'fileformats' after executing auto commands.
+            (Christian Brabandt)
+Files:      src/fileio.c, src/testdir/test_fileformat.vim
+
+Patch 8.0.0225
+Problem:    When a block is visually selected and put is used on the end of
+            the selection only one line is changed.
+Solution:   Check for the end properly. (Christian Brabandt, neovim issue
+            5781)
+Files:      src/ops.c, src/testdir/test_put.vim
+
+Patch 8.0.0226
+Problem:    The test for patch 8.0.0224 misses the CR characters and passes
+            even without the fix. (Christian Brabandt)
+Solution:   Use double quotes and \<CR>.
+Files:      src/testidr/test_fileformat.vim
+
+Patch 8.0.0227
+Problem:    Crash when 'fileformat' is forced to "dos" and the first line in
+            the file is empty and does not have a CR character.
+Solution:   Don't check for CR before the start of the buffer.
+Files:      src/fileio.c, src/testidr/test_fileformat.vim
+
+Patch 8.0.0228 (after 8.0.0210)
+Problem:    When pasting test in an xterm on the command line it is surrounded
+            by <PasteStart> and <PasteEnd>. (Johannes Kaltenbach)
+Solution:   Add missing changes.
+Files:      src/ex_getln.c, src/term.c
+
+Patch 8.0.0229 (after 8.0.0179)
+Problem:    When freeing a buffer the local value of the 'formatprg' option is
+            not cleared.
+Solution:   Add missing change.
+Files:      src/buffer.c
+
+Patch 8.0.0230 (after 8.0.0210)
+Problem:    When using bracketed paste line breaks are not respected.
+Solution:   Turn CR characters into a line break if the text is being
+            inserted. (closes #1404)
+Files:      src/edit.c
+
+Patch 8.0.0231
+Problem:    There are no tests for bracketed paste mode.
+Solution:   Add a test.  Fix repeating with "normal .".
+Files:      src/edit.c, src/testdir/test_paste.vim, src/Makefile,
+            src/testdir/Make_all.mak
+
+Patch 8.0.0232
+Problem:    Pasting in Insert mode does not work when bracketed paste is used
+            and 'esckeys' is off.
+Solution:   When 'esckeys' is off disable bracketed paste in Insert mode.
+Files:      src/edit.c
+
+Patch 8.0.0233 (after 8.0.0231)
+Problem:    The paste test fails if the GUI is being used.
+Solution:   Skip the test in the GUI.
+Files:      src/testdir/test_paste.vim
+
+Patch 8.0.0234 (after 8.0.0225)
+Problem:    When several lines are visually selected and one of them is short,
+            using put may cause a crash. (Axel Bender)
+Solution:   Check for a short line. (Christian Brabandt)
+Files:      src/ops.c, src/testdir/test_put.vim
+
+Patch 8.0.0235
+Problem:    Memory leak detected when running tests for diff mode.
+Solution:   Free p_extra_free.
+Files:      src/screen.c
+
+Patch 8.0.0236 (after 8.0.0234)
+Problem:    Gcc complains that a variable may be used uninitialized. Confusion
+            between variable and label name. (John Marriott)
+Solution:   Initialize it.  Rename end to end_lnum.
+Files:      src/ops.c
+
+Patch 8.0.0237
+Problem:    When setting wildoptions=tagfile the completion context is not set
+            correctly. (desjardins)
+Solution:   Check for EXPAND_TAGS_LISTFILES. (Christian Brabandt, closes #1399)
+Files:      src/ex_getln.c, src/testdir/test_cmdline.vim
+
+Patch 8.0.0238
+Problem:    When using bracketed paste autoindent causes indent to be
+            increased.
+Solution:   Disable 'ai' and set 'paste' temporarily. (Ken Takata)
+Files:      src/edit.c, src/testdir/test_paste.vim
+
+Patch 8.0.0239
+Problem:    The address sanitizer sometimes finds errors, but it needs to be
+            run manually.
+Solution:   Add an environment to Travis with clang and the address sanitizer.
+            (Christian Brabandt)  Also include changes only on github.
+Files:      .travis.yml
+
+Patch 8.0.0240 (after 8.0.0239)
+Problem:    The clang build on CI fails with one configuration.
+Solution:   Redo a previous patch that was accidentally reverted.
+Files:      .travis.yml
+
+Patch 8.0.0241
+Problem:    Vim defines a mch_memmove() function but it doesn't work, thus is
+            always unused.
+Solution:   Remove the mch_memmove implementation. (suggested by Dominique
+            Pelle)
+Files:      src/os_unix.h, src/misc2.c, src/vim.h
+
+Patch 8.0.0242
+Problem:    Completion of user defined functions is not covered by tests.
+Solution:   Add tests.  Also test various errors of user-defined commands.
+            (Dominique Pelle, closes #1413)
+Files:      src/testdir/test_usercommands.vim
+
+Patch 8.0.0243
+Problem:    When making a character lower case with tolower() changes the byte
+            cound, it is not made lower case.
+Solution:   Add strlow_save(). (Dominique Pelle, closes #1406)
+Files:      src/evalfunc.c, src/misc2.c, src/proto/misc2.pro,
+            src/testdir/test_functions.vim
+
+Patch 8.0.0244
+Problem:    When the user sets t_BE empty after startup to disable bracketed
+            paste, this has no direct effect.
+Solution:   When t_BE is made empty write t_BD.  When t_BE is made non-empty
+            write the new value.
+Files:      src/option.c
+
+Patch 8.0.0245
+Problem:    The generated zh_CN.cp936.po message file is not encoded properly.
+Solution:   Instead of using zh_CN.po as input, use zh_CN.UTF-8.po.
+Files:      src/po/Makefile
+
+Patch 8.0.0246
+Problem:    Compiler warnings for int to pointer conversion.
+Solution:   Fix macro for mch_memmove(). (John Marriott)
+Files:      src/vim.h
+
+Patch 8.0.0247
+Problem:    Under some circumstances, one needs to type Ctrl-N or Ctrl-P twice
+            to have a menu entry selected. (Lifepillar)
+Solution:   call ins_compl_free(). (Christian Brabandt, closes #1411)
+Files:      src/edit.c, src/testdir/test_popup.vim
+
+Patch 8.0.0248
+Problem:    vim_strcat() cannot handle overlapping arguments.
+Solution:   Use mch_memmove() instead of strcpy(). (Justin M Keyes,
+            closes #1415)
+Files:      src/misc2.c
+
+Patch 8.0.0249
+Problem:    When two submits happen quick after each other, the tests for the
+            first one may error out.
+Solution:   Use a git depth of 10 instead of 1. (Christian Brabandt)
+Files:      .travis.yml
+
+Patch 8.0.0250
+Problem:    When virtcol() gets a column that is not the first byte of a
+            multi-byte character the result is unpredictable. (Christian
+            Ludwig)
+Solution:   Correct the column to the first byte of a multi-byte character.
+            Change the utf-8 test to new style.
+Files:      src/charset.c, src/testdir/test_utf8.in, src/testdir/test_utf8.ok,
+            src/testdir/test_utf8.vim, src/Makefile, src/testdir/Make_all.mak,
+            src/testdir/test_alot_utf8.vim
+
+Patch 8.0.0251
+Problem:    It is not so easy to write a script that works with both Python 2
+            and Python 3, even when the Python code works with both.
+Solution:   Add 'pyxversion', :pyx, etc. (Marc Weber, Ken Takata)
+Files:      Filelist, runtime/doc/eval.txt, runtime/doc/if_pyth.txt,
+            runtime/doc/index.txt, runtime/doc/options.txt,
+            runtime/optwin.vim, runtime/doc/quickref.txt,
+            runtime/doc/usr_41.txt, src/Makefile, src/evalfunc.c,
+            src/ex_cmds.h, src/ex_cmds2.c, src/ex_docmd.c, src/if_python.c,
+            src/if_python3.c, src/option.c, src/option.h,
+            src/proto/ex_cmds2.pro, src/testdir/Make_all.mak,
+            src/testdir/pyxfile/py2_magic.py,
+            src/testdir/pyxfile/py2_shebang.py,
+            src/testdir/pyxfile/py3_magic.py,
+            src/testdir/pyxfile/py3_shebang.py, src/testdir/pyxfile/pyx.py,
+            src/testdir/test_pyx2.vim, src/testdir/test_pyx3.vim
+            src/userfunc.c
+
+Patch 8.0.0252
+Problem:    Characters below 256 that are not one byte are not always
+            recognized as word characters.
+Solution:   Make vim_iswordc() and vim_iswordp() work the same way. Add a test
+            for this. (Ozaki Kiichi)
+Files:      src/Makefile, src/charset.c, src/kword_test.c, src/mbyte.c,
+            src/proto/mbyte.pro
+
+Patch 8.0.0253
+Problem:    When creating a session when winminheight is 2 or larger and
+            loading that session gives an error.
+Solution:   Also set winminheight before setting winheight to 1. (Rafael
+            Bodill, neovim #5717)
+Files:      src/ex_docmd.c, src/testdir/test_mksession.vim
+
+Patch 8.0.0254
+Problem:    When using an assert function one can either specify a message or
+            get a message about what failed, not both.
+Solution:   Concatenate the error with the message.
+Files:      src/eval.c, src/testdir/test_assert.vim
+
+Patch 8.0.0255
+Problem:    When calling setpos() with a buffer argument it often is ignored.
+            (Matthew Malcomson)
+Solution:   Make the buffer argument work for all marks local to a buffer.
+            (neovim #5713)  Add more tests.
+Files:      src/mark.c, src/testdir/test_marks.vim, runtime/doc/eval.txt
+
+Patch 8.0.0256 (after 8.0.0255)
+Problem:    Tests fail because some changes were not included.
+Solution:   Add changes to evalfunc.c
+Files:      src/evalfunc.c
+
+Patch 8.0.0257 (after 8.0.0252)
+Problem:    The keyword test file is not included in the archive.
+Solution:   Update the list of files.
+Files:      Filelist
+
+Patch 8.0.0258 (after 8.0.0253)
+Problem:    mksession test leaves file behind.
+Solution:   Delete the file.  Rename files to start with "X".
+Files:      src/testdir/test_mksession.vim
+
+Patch 8.0.0259
+Problem:    Tab commands do not handle count correctly. (Ken Hamada)
+Solution:   Add ADDR_TABS_RELATIVE. (Hirohito Higashi)
+Files:      runtime/doc/tabpage.txt, src/ex_cmds.h, src/ex_docmd.c,
+            src/testdir/test_tabpage.vim
+
+Patch 8.0.0260
+Problem:    Build fails with tiny features.
+Solution:   Move get_tabpage_arg() inside #ifdef.
+Files:      src/ex_docmd.c
+
+Patch 8.0.0261
+Problem:    Not enough test coverage for eval functions.
+Solution:   Add more tests. (Dominique Pelle, closes #1420)
+Files:      src/testdir/test_functions.vim
+
+Patch 8.0.0262
+Problem:    Farsi support is barely tested.
+Solution:   Add more tests for Farsi.  Clean up the code.
+Files:      src/edit.c, src/farsi.c, src/testdir/test_farsi.vim
+
+Patch 8.0.0263
+Problem:    Farsi support is not tested enough.
+Solution:   Add more tests for Farsi.  Clean up the code.
+Files:      src/farsi.c, src/testdir/test_farsi.vim
+
+Patch 8.0.0264
+Problem:    Memory error reported by ubsan, probably for using the string
+            returned by execute().
+Solution:   NUL terminate the result of execute().
+Files:      src/evalfunc.c
+
+Patch 8.0.0265
+Problem:    May get ml_get error when :pydo deletes lines or switches to
+            another buffer. (Nikolai Pavlov, issue #1421)
+Solution:   Check the buffer and line every time.
+Files:      src/if_py_both.h, src/testdir/test_python2.vim,
+            src/testdir/test_python3.vim, src/Makefile,
+            src/testdir/Make_all.mak
+
+Patch 8.0.0266
+Problem:    Compiler warning for using uninitialized variable.
+Solution:   Set tab_number also when there is an error.
+Files:      src/ex_docmd.c
+
+Patch 8.0.0267
+Problem:    A channel test sometimes fails on Mac.
+Solution:   Add the test to the list of flaky tests.
+Files:      src/testdir/runtest.vim
+
+Patch 8.0.0268
+Problem:    May get ml_get error when :luado deletes lines or switches to
+            another buffer. (Nikolai Pavlov, issue #1421)
+Solution:   Check the buffer and line every time.
+Files:      src/if_lua.c, src/testdir/test_lua.vim, src/Makefile,
+            src/testdir/Make_all.mak
+
+Patch 8.0.0269
+Problem:    May get ml_get error when :perldo deletes lines or switches to
+            another buffer. (Nikolai Pavlov, issue #1421)
+Solution:   Check the buffer and line every time.
+Files:      src/if_perl.xs, src/testdir/test_perl.vim
+
+Patch 8.0.0270
+Problem:    May get ml_get error when :rubydo deletes lines or switches to
+            another buffer. (Nikolai Pavlov, issue #1421)
+Solution:   Check the buffer and line every time.
+Files:      src/if_ruby.c, src/testdir/test_ruby.vim
+
+Patch 8.0.0271
+Problem:    May get ml_get error when :tcldo deletes lines or switches to
+            another buffer. (Nikolai Pavlov, closes #1421)
+Solution:   Check the buffer and line every time.
+Files:      src/if_tcl.c, src/testdir/test_tcl.vim, src/Makefile,
+            src/testdir/Make_all.mak
+
+Patch 8.0.0272
+Problem:    Crash on exit is not detected when running tests.
+Solution:   Remove the dash before the command. (Dominique Pelle, closes
+            #1425)
+Files:      src/testdir/Makefile
+
+Patch 8.0.0273
+Problem:    Dead code detected by Coverity when not using gnome.
+Solution:   Rearrange the #ifdefs to avoid dead code.
+Files:      src/gui_gtk_x11.c
+
+Patch 8.0.0274
+Problem:    When update_single_line() is called recursively, or another screen
+            update happens while it is busy, errors may occur.
+Solution:   Check and update updating_screen. (Christian Brabandt)
+Files:      src/screen.c
+
+Patch 8.0.0275
+Problem:    When checking for CTRL-C typed the GUI may detect a screen resize
+            and redraw the screen, causing trouble.
+Solution:   Set updating_screen in ui_breakcheck().
+Files:      src/ui.c
+
+Patch 8.0.0276
+Problem:    Checking for FEAT_GUI_GNOME inside GTK 3 code is unnecessary.
+Solution:   Remove the #ifdef. (Kazunobu Kuriyama)
+Files:      src/gui_gtk_x11.c
+
+Patch 8.0.0277
+Problem:    The GUI test may trigger fontconfig and take a long time.
+Solution:   Set $XDG_CACHE_HOME. (Kazunobu Kuriyama)
+Files:      src/testdir/unix.vim, src/testdir/test_gui.vim
+
+Patch 8.0.0278 (after 8.0.0277)
+Problem:    GUI test fails on MS-Windows.
+Solution:   Check that tester_HOME exists.
+Files:      src/testdir/test_gui.vim
+
+Patch 8.0.0279
+Problem:    With MSVC 2015 the dll name is vcruntime140.dll.
+Solution:   Check the MSVC version and use the right dll name. (Ken Takata)
+Files:      src/Make_mvc.mak
+
+Patch 8.0.0280
+Problem:    On MS-Windows setting an environment variable with multi-byte
+            strings does not work well.
+Solution:   Use wputenv when possible. (Taro Muraoka, Ken Takata)
+Files:      src/misc1.c, src/os_win32.c, src/os_win32.h,
+            src/proto/os_win32.pro, src/vim.h
+
+Patch 8.0.0281
+Problem:    MS-Windows files are still using ARGSUSED while most other files
+            have UNUSED.
+Solution:   Change ARGSUSED to UNUSED or delete it.
+Files:      src/os_win32.c, src/gui_w32.c, src/os_mswin.c, src/os_w32exe.c,
+            src/winclip.c
+
+Patch 8.0.0282
+Problem:    When doing a Visual selection and using "I" to go to insert mode,
+            CTRL-O needs to be used twice to go to Normal mode. (Coacher)
+Solution:   Check for the return value of edit(). (Christian Brabandt,
+            closes #1290)
+Files:      src/normal.c, src/ops.c
+
+Patch 8.0.0283
+Problem:    The return value of mode() does not indicate that completion is
+            active in Replace and Insert mode. (Zhen-Huan (Kenny) Hu)
+Solution:   Add "c" or "x" for two kinds of completion. (Yegappan Lakshmanan,
+            closes #1397)  Test some more modes.
+Files:      runtime/doc/eval.txt, src/evalfunc.c,
+            src/testdir/test_functions.vim, src/testdir/test_mapping.vim
+
+Patch 8.0.0284
+Problem:    The Test_collapse_buffers() test failed once, looks like it is
+            flaky.
+Solution:   Add it to the list of flaky tests.
+Files:      src/testdir/runtest.vim
+
+Patch 8.0.0285 (after 8.0.0277)
+Problem:    Tests fail with tiny build on Unix.
+Solution:   Only set g:tester_HOME when build with the +eval feature.
+Files:      src/testdir/unix.vim
+
+Patch 8.0.0286
+Problem:    When concealing is active and the screen is resized in the GUI it
+            is not immediately redrawn.
+Solution:   Use update_prepare() and update_finish() from
+            update_single_line().
+Files:      src/screen.c
+
+Patch 8.0.0287
+Problem:    Cannot access the arguments of the current function in debug mode.
+            (Luc Hermitte)
+Solution:   use get_funccal(). (Lemonboy, closes #1432, closes #1352)
+Files:      src/userfunc.c
+
+Patch 8.0.0288 (after 8.0.0284)
+Problem:    Errors reported while running tests.
+Solution:   Put comma in the right place.
+Files:      src/testdir/runtest.vim
+
+Patch 8.0.0289
+Problem:    No test for "ga" and :ascii.
+Solution:   Add a test. (Dominique Pelle, closes #1429)
+Files:      src/Makefile, src/testdir/test_alot.vim, src/testdir/test_ga.vim
+
+Patch 8.0.0290
+Problem:    If a wide character doesn't fit at the end of the screen line, and
+            the line doesn't fit on the screen, then the cursor position may
+            be wrong. (anliting)
+Solution:   Don't skip over wide character. (Christian Brabandt, closes #1408)
+Files:      src/screen.c
+
+Patch 8.0.0291 (after 8.0.0282)
+Problem:    Visual block insertion does not insert in all lines.
+Solution:   Don't bail out of insert too early. Add a test. (Christian
+            Brabandt, closes #1290)
+Files:      src/ops.c, src/testdir/test_visual.vim
+
+Patch 8.0.0292
+Problem:    The stat test is a bit slow.
+Solution:   Remove a couple of sleep comments and reduce another.
+Files:      src/testdir/test_stat.vim
+
+Patch 8.0.0293
+Problem:    Some tests have a one or three second wait.
+Solution:   Reset the 'showmode' option.  Use a test time of one to disable
+            sleep after an error or warning message.
+Files:      src/misc1.c, src/testdir/runtest.vim, src/testdir/test_normal.vim
+
+Patch 8.0.0294
+Problem:    Argument list is not stored correctly in a session file.
+            (lgpasquale)
+Solution:   Use "$argadd" instead of "argadd". (closes #1434)
+Files:      src/ex_docmd.c, src/testdir/test_mksession.vim
+
+Patch 8.0.0295 (after 8.0.0293)
+Problem:    test_viml hangs.
+Solution:   Put resetting 'more' before sourcing the script.
+Files:      src/testdir/runtest.vim
+
+Patch 8.0.0296
+Problem:    Bracketed paste can only append, not insert.
+Solution:   When the cursor is in the first column insert the text.
+Files:      src/normal.c, src/testdir/test_paste.vim, runtime/doc/term.txt
+
+Patch 8.0.0297
+Problem:    Double free on exit when using a closure. (James McCoy)
+Solution:   Split free_al_functions in two parts. (closes #1428)
+Files:      src/userfunc.c, src/structs.h
+
+Patch 8.0.0298
+Problem:    Ex command range with repeated search does not work. (Bruce
+            DeVisser)
+Solution:   Skip over \/, \? and \&.
+Files:      src/ex_docmd.c, src/testdir/test_cmdline.vim
+
+Patch 8.0.0299
+Problem:    When the GUI window is resized Vim does not always take over the
+            new size. (Luchr)
+Solution:   Reset new_p_guifont in gui_resize_shell().  Call
+            gui_may_resize_shell() in the main loop.
+Files:      src/main.c, src/gui.c
+
+Patch 8.0.0300
+Problem:    Cannot stop diffing hidden buffers. (Daniel Hahler)
+Solution:   When using :diffoff! make the whole list if diffed buffers empty.
+            (closes #736)
+Files:      src/diff.c, src/testdir/test_diffmode.vim
+
+Patch 8.0.0301
+Problem:    No tests for ":set completion" and various errors of the :set
+            command.
+Solution:   Add more :set tests. (Dominique Pelle, closes #1440)
+Files:      src/testdir/test_options.vim
+
+Patch 8.0.0302
+Problem:    Cannot set terminal key codes with :let.
+Solution:   Make it work.
+Files:      src/option.c, src/testdir/test_assign.vim
+
+Patch 8.0.0303
+Problem:    Bracketed paste does not work in Visual mode.
+Solution:   Delete the text before pasting
+Files:      src/normal.c, src/ops.c, src/proto/ops.pro,
+            src/testdir/test_paste.vim
+
+Patch 8.0.0304 (after 8.0.0302)
+Problem:    Assign test fails in the GUI.
+Solution:   Skip the test for setting t_k1.
+Files:      src/testdir/test_assign.vim
+
+Patch 8.0.0305
+Problem:    Invalid memory access when option has duplicate flag.
+Solution:   Correct pointer computation. (Dominique Pelle, closes #1442)
+Files:      src/option.c, src/testdir/test_options.vim
+
+Patch 8.0.0306
+Problem:    mode() not sufficiently tested.
+Solution:   Add more tests. (Yegappan Lakshmanan)
+Files:      src/testdir/test_functions.vim
+
+Patch 8.0.0307
+Problem:    Asan detects a memory error when EXITFREE is defined. (Dominique
+            Pelle)
+Solution:   In getvcol() check for ml_get_buf() returning an empty string.
+            Also skip adjusting the scroll position.  Set "exiting" in
+            mch_exit() for all systems.
+Files:      src/charset.c, src/window.c, src/os_mswin.c, src/os_win32.c,
+            src/os_amiga.c
+
+Patch 8.0.0308
+Problem:    When using a symbolic link, the package path will not be inserted
+            at the right position in 'runtimepath'. (Dugan Chen, Norio Takagi)
+Solution:   Resolve symbolic links when finding the right position in
+            'runtimepath'. (Hirohito Higashi)
+Files:      src/ex_cmds2.c, src/testdir/test_packadd.vim
+
+Patch 8.0.0309
+Problem:    Cannot use an empty key in json.
+Solution:   Allow for using an empty key.
+Files:      src/json.c, src/testdir/test_json.vim
+
+Patch 8.0.0310
+Problem:    Not enough testing for GUI functionality.
+Solution:   Add tests for v:windowid and getwinpos[xy](). (Kazunobu Kuriyama)
+Files:      src/testdir/test_gui.vim
+
+Patch 8.0.0311
+Problem:    Linebreak tests are old style.
+Solution:   Turn the tests into new style. Share utility functions. (Ozaki
+            Kiichi, closes #1444)
+Files:      src/Makefile, src/testdir/Make_all.mak,
+            src/testdir/test_breakindent.vim, src/testdir/test_listlbr.in,
+            src/testdir/test_listlbr.ok, src/testdir/test_listlbr.vim,
+            src/testdir/test_listlbr_utf8.in,
+            src/testdir/test_listlbr_utf8.ok,
+            src/testdir/test_listlbr_utf8.vim, src/testdir/view_util.vim
+
+Patch 8.0.0312
+Problem:    When a json message arrives in pieces, the start is dropped and
+            the decoding fails.
+Solution:   Do not drop the start when it is still needed. (Kay Zheng)  Add a
+            test.  Reset the timeout when something is received.
+Files:      src/channel.c, src/testdir/test_channel.vim, src/structs.h,
+            src/testdir/test_channel_pipe.py
+
+Patch 8.0.0313 (after 8.0.0310)
+Problem:    Not enough testing for GUI functionality.
+Solution:   Add tests for the GUI font. (Kazunobu Kuriyama)
+Files:      src/testdir/test_gui.vim
+
+Patch 8.0.0314
+Problem:    getcmdtype(), getcmdpos() and getcmdline() are not tested.
+Solution:   Add tests. (Yegappan Lakshmanan)
+Files:      src/testdir/test_cmdline.vim
+
+Patch 8.0.0315
+Problem:    ":help :[range]" does not work. (Tony Mechelynck)
+Solution:   Translate to insert a backslash.
+Files:      src/ex_cmds.c
+
+Patch 8.0.0316
+Problem:    ":help z?" does not work. (Pavol Juhas)
+Solution:   Remove exception for z?.
+Files:      src/ex_cmds.c
+
+Patch 8.0.0317
+Problem:    No test for setting 'guifont'.
+Solution:   Add a test for X11 GUIs. (Kazunobu Kuriyama)
+Files:      src/testdir/test_gui.vim
+
+Patch 8.0.0318
+Problem:    Small mistake in 7x13 font name.
+Solution:   Use ISO 8859-1 name instead of 10646-1. (Kazunobu Kuriyama)
+Files:      src/testdir/test_gui.vim
+
+Patch 8.0.0319
+Problem:    Insert mode completion does not respect "start" in 'backspace'.
+Solution:   Check whether backspace can go before where insert started.
+            (Hirohito Higashi)
+Files:      src/edit.c, src/testdir/test_popup.vim
+
+Patch 8.0.0320
+Problem:    Warning for unused variable with small build.
+Solution:   Change #ifdef to exclude FEAT_CMDWIN. (Kazunobu Kuriyama)
+Files:      src/ex_getln.c
+
+Patch 8.0.0321
+Problem:    When using the tiny version trying to load the matchit plugin
+            gives an error. On MS-Windows some default mappings fail.
+Solution:   Add a check if the command used is available. (Christian Brabandt)
+Files:      runtime/mswin.vim, runtime/macros/matchit.vim
+
+Patch 8.0.0322
+Problem:    Possible overflow with spell file where the tree length is
+            corrupted.
+Solution:   Check for an invalid length (suggested by shqking)
+Files:      src/spellfile.c
+
+Patch 8.0.0323
+Problem:    When running the command line tests there is a one second wait.
+Solution:   Change an Esc to Ctrl-C. (Yegappan Lakshmanan)
+Files:      src/testdir/test_cmdline.vim
+
+Patch 8.0.0324
+Problem:    Illegal memory access with "1;y".
+Solution:   Call check_cursor() instead of check_cursor_lnum(). (Dominique
+            Pelle, closes #1455)
+Files:      src/ex_docmd.c, src/testdir/test_cmdline.vim
+
+Patch 8.0.0325
+Problem:    Packadd test does not clean up symlink.
+Solution:   Delete the link. (Hirohito Higashi)
+Files:      src/testdir/test_packadd.vim
+
+Patch 8.0.0326 (after 8.0.0325)
+Problem:    Packadd test uses wrong directory name.
+Solution:   Use the variable name value. (Hirohito Higashi)
+Files:      src/testdir/test_packadd.vim
+
+Patch 8.0.0327
+Problem:    The E11 error message in the command line window is not
+            translated.
+Solution:   use _(). (Hirohito Higashi)
+Files:      src/ex_docmd.c
+
+Patch 8.0.0328
+Problem:    The "zero count" error doesn't have a number. (Hirohito Higashi)
+Solution:   Give it a number and be more specific about the error.
+Files:      src/globals.h
+
+Patch 8.0.0329
+Problem:    Xfontset and guifontwide are not tested.
+Solution:   Add tests. (Kazunobu Kuriyama)
+Files:      src/testdir/test_gui.vim
+
+Patch 8.0.0330
+Problem:    Illegal memory access after "vapo". (Dominique Pelle)
+Solution:   Fix the cursor column.
+Files:      src/search.c, src/testdir/test_visual.vim
+
+Patch 8.0.0331
+Problem:    Restoring help snapshot accesses freed memory. (Dominique Pelle)
+Solution:   Don't restore a snapshot when the window closes.
+Files:      src/window.c, src/Makefile, src/testdir/Make_all.mak,
+            src/testdir/test_help.vim
+
+Patch 8.0.0332
+Problem:    GUI test fails on some systems.
+Solution:   Try different language settings. (Kazunobu Kuriyama)
+Files:      src/testdir/test_gui.vim
+
+Patch 8.0.0333
+Problem:    Illegal memory access when 'complete' ends in a backslash.
+Solution:   Check for trailing backslash. (Dominique Pelle, closes #1478)
+Files:      src/option.c, src/testdir/test_options.vim
+
+Patch 8.0.0334
+Problem:    Can't access b:changedtick from a dict reference.
+Solution:   Make changedtick a member of the b: dict. (inspired by neovim
+            #6112)
+Files:      src/structs.h, src/buffer.c, src/edit.c, src/eval.c,
+            src/evalfunc.c, src/ex_docmd.c, src/main.c, src/globals.h,
+            src/fileio.c, src/memline.c, src/misc1.c, src/syntax.c,
+            src/proto/eval.pro, src/testdir/test_changedtick.vim,
+            src/Makefile, src/testdir/test_alot.vim, src/testdir/test91.in,
+            src/testdir/test91.ok, src/testdir/test_functions.vim
+
+Patch 8.0.0335 (after 8.0.0335)
+Problem:    Functions test fails.
+Solution:   Use the right buffer number.
+Files:      src/testdir/test_functions.vim
+
+Patch 8.0.0336
+Problem:    Flags of :substitute not sufficiently tested.
+Solution:   Test up to two letter flag combinations. (James McCoy, closes
+            #1479)
+Files:      src/testdir/test_substitute.vim
+
+Patch 8.0.0337
+Problem:    Invalid memory access in :recover command.
+Solution:   Avoid access before directory name. (Dominique Pelle,
+            closes #1488)
+Files:      src/Makefile, src/memline.c, src/testdir/test_alot.vim,
+            src/testdir/test_recover.vim
+
+Patch 8.0.0338 (after 8.0.0337)
+Problem:    :recover test fails on MS-Windows.
+Solution:   Use non-existing directory on MS-Windows.
+Files:      src/testdir/test_recover.vim
+
+Patch 8.0.0339
+Problem:    Illegal memory access with vi'
+Solution:   For quoted text objects bail out if the Visual area spans more
+            than one line.
+Files:      src/search.c, src/testdir/test_visual.vim
+
+Patch 8.0.0340
+Problem:    Not checking return valud of dict_add(). (Coverity)
+Solution:   Handle a failure.
+Files:      src/buffer.c
+
+Patch 8.0.0341
+Problem:    When using complete() and typing a character undo is saved after
+            the character was inserted. (Shougo)
+Solution:   Save for undo before inserting the character.
+Files:      src/edit.c, src/testdir/test_popup.vim
+
+Patch 8.0.0342
+Problem:    Double free when compiled with EXITFREE and setting 'ttytype'.
+Solution:   Avoid setting P_ALLOCED on 'ttytype'. (Dominique Pelle,
+            closes #1461)
+Files:      src/option.c, src/testdir/test_options.vim
+
+Patch 8.0.0343
+Problem:    b:changedtick can be unlocked, even though it has no effect.
+            (Nikolai Pavlov)
+Solution:   Add a check and error E940. (closes #1496)
+Files:      src/eval.c, src/testdir/test_changedtick.vim, runtime/doc/eval.txt
+
+Patch 8.0.0344
+Problem:    Unlet command leaks memory. (Nikolai Pavlov)
+Solution:   Free the memory on error. (closes #1497)
+Files:      src/eval.c, src/testdir/test_unlet.vim
+
+Patch 8.0.0345
+Problem:    islocked('d.changedtick') does not work.
+Solution:   Make it work.
+Files:      src/buffer.c, src/eval.c, src/evalfunc.c, src/vim.h,
+            src/testdir/test_changedtick.vim,
+
+Patch 8.0.0346
+Problem:    Vim relies on limits.h to be included indirectly, but on Solaris 9
+            it may not be. (Ben Fritz)
+Solution:   Always include limits.h.
+Files:      src/os_unixx.h, src/vim.h
+
+Patch 8.0.0347
+Problem:    When using CTRL-X CTRL-U inside a comment, the use of the comment
+            leader may not work. (Klement)
+Solution:   Save and restore did_ai. (Christian Brabandt, closes #1494)
+Files:      src/edit.c, src/testdir/test_popup.vim
+
+Patch 8.0.0348
+Problem:    When building with a shadow directory on macOS lacks the
+            +clipboard feature.
+Solution:   Link *.m files, specifically os_macosx.m. (Kazunobu Kuriyama)
+Files:      src/Makefile
+
+Patch 8.0.0349
+Problem:    Redrawing errors with GTK 3.
+Solution:   When updating, first clear all rectangles and then draw them.
+            (Kazunobu Kuriyama, Christian Ludwig, closes #848)
+Files:      src/gui_gtk_x11.c
+
+Patch 8.0.0350
+Problem:    Not enough test coverage for Perl.
+Solution:   Add more Perl tests. (Dominique Perl, closes #1500)
+Files:      src/testdir/test_perl.vim
+
+Patch 8.0.0351
+Problem:    No test for concatenating an empty string that results from out of
+            bounds indexing.
+Solution:   Add a simple test.
+Files:      src/testdir/test_expr.vim
+
+Patch 8.0.0352
+Problem:    The condition for when a typval needs to be cleared is too
+            complicated.
+Solution:   Init the type to VAR_UNKNOWN and clear it always.
+Files:      src/eval.c
+
+Patch 8.0.0353
+Problem:    If [RO] in the status line is translated to a longer string, it is
+            trunctted to 4 bytes.
+Solution:   Skip over the resulting string. (Jente Hidskes, closes #1499)
+Files:      src/screen.c
+
+Patch 8.0.0354
+Problem:    Test to check that setting termcap key fails sometimes.
+Solution:   Check for "t_k1" to exist. (Christian Brabandt, closes #1459)
+Files:      src/testdir/test_assign.vim
+
+Patch 8.0.0355
+Problem:    Using uninitialized memory when 'isfname' is empty.
+Solution:   Don't call getpwnam() without an argument. (Dominique Pelle,
+            closes #1464)
+Files:      src/misc1.c, src/testdir/test_options.vim
+
+Patch 8.0.0356 (after 8.0.0342)
+Problem:    Leaking memory when setting 'ttytype'.
+Solution:   Get free_oldval from the right option entry.
+Files:      src/option.c
+
+Patch 8.0.0357
+Problem:    Crash when setting 'guicursor' to weird value.
+Solution:   Avoid negative size. (Dominique Pelle, closes #1465)
+Files:      src/misc2.c, src/testdir/test_options.vim
+
+Patch 8.0.0358
+Problem:    Invalid memory access in C-indent code.
+Solution:   Don't go over end of empty line. (Dominique Pelle, closes #1492)
+Files:      src/edit.c, src/testdir/test_options.vim
+
+Patch 8.0.0359
+Problem:    'number' and 'relativenumber' are not properly tested.
+Solution:   Add tests, change old style to new style tests. (Ozaki Kiichi,
+            closes #1447)
+Files:      src/Makefile, src/testdir/Make_all.mak, src/testdir/Make_vms.mms,
+            src/testdir/test89.in, src/testdir/test89.ok,
+            src/testdir/test_alot.vim, src/testdir/test_findfile.vim,
+            src/testdir/test_number.vim
+
+Patch 8.0.0360
+Problem:    Sometimes VimL is used, which is confusing.
+Solution:   Consistently use "Vim script". (Hirohito Higashi)
+Files:      runtime/doc/if_mzsch.txt, runtime/doc/if_pyth.txt,
+            runtime/doc/syntax.txt, runtime/doc/usr_02.txt,
+            runtime/doc/version7.txt, src/Makefile, src/eval.c,
+            src/ex_getln.c, src/if_py_both.h, src/if_xcmdsrv.c,
+            src/testdir/Make_all.mak, src/testdir/runtest.vim,
+            src/testdir/test49.vim, src/testdir/test_vimscript.vim,
+            src/testdir/test_viml.vim
+
+Patch 8.0.0361
+Problem:    GUI initialisation is not sufficiently tested.
+Solution:   Add the gui_init test. (Kazunobu Kuriyama)
+Files:      src/Makefile, src/testdir/Make_all.mak, src/testdir/Make_dos.mak,
+            src/testdir/Make_ming.mak, src/testdir/Makefile,
+            src/testdir/gui_init.vim, src/testdir/setup_gui.vim,
+            src/testdir/test_gui.vim, src/testdir/test_gui_init.vim, Filelist
+
+Patch 8.0.0362 (after 8.0.0361)
+Problem:    Tests fail on MS-Windows.
+Solution:   Use $*.vim instead of $<.
+Files:      src/testdir/Make_dos.mak
+
+Patch 8.0.0363
+Problem:    Travis is too slow to keep up with patches.
+Solution:   Increase git depth to 20
+Files:      .travis.yml
+
+Patch 8.0.0364
+Problem:    ]s does not move cursor with two spell errors in one line. (Manuel
+            Ortega)
+Solution:   Don't stop search immediately when wrapped, search the line first.
+            (Ken Takata)  Add a test.
+Files:      src/spell.c, src/Makefile, src/testdir/test_spell.vim,
+            src/testdir/Make_all.mak
+
+Patch 8.0.0365
+Problem:    Might free a dict item that wasn't allocated.
+Solution:   Call dictitem_free(). (Nikolai Pavlov)  Use this for
+            b:changedtick.
+Files:      src/dict.c, src/structs.h, src/buffer.c, src/edit.c,
+            src/evalfunc.c, src/ex_docmd.c, src/fileio.c, src/main.c,
+            src/memline.c, src/misc1.c, src/syntax.c
+
+Patch 8.0.0366 (after 8.0.0365)
+Problem:    Build fails with tiny features.
+Solution:   Add #ifdef.
+Files:      src/buffer.c
+
+Patch 8.0.0367
+Problem:    If configure defines _LARGE_FILES some include files are included
+            before it is defined.
+Solution:   Include vim.h first. (Sam Thursfield, closes #1508)
+Files:      src/gui_at_sb.c, src/gui_athena.c, src/gui_motif.c, src/gui_x11.c,
+            src/gui_xmdlg.c
+
+Patch 8.0.0368
+Problem:    Not all options are tested with a range of values.
+Solution:   Generate a test script from the source code.
+Files:      Filelist, src/gen_opt_test.vim, src/testdir/test_options.vim,
+            src/Makefile
+
+Patch 8.0.0369 (after 8.0.0368)
+Problem:    The 'balloondelay', 'ballooneval' and 'balloonexpr' options are
+            not defined without the +balloon_eval feature. Testing that an
+            option value fails does not work for unsupported options.
+Solution:   Make the options defined but not supported.  Don't test if
+            setting unsupported options fails.
+Files:      src/option.c, src/gen_opt_test.vim
+
+Patch 8.0.0370
+Problem:    Invalid memory access when setting wildchar empty.
+Solution:   Avoid going over the end of the option value. (Dominique Pelle,
+            closes #1509)  Make option test check all number options with
+            empty value.
+Files:      src/gen_opt_test.vim, src/option.c, src/testdir/test_options.vim
+
+Patch 8.0.0371 (after 8.0.0365)
+Problem:    Leaking memory when setting v:completed_item.
+Solution:   Or the flags instead of setting them.
+Files:      src/eval.c
+
+Patch 8.0.0372
+Problem:    More options are not always defined.
+Solution:   Consistently define all possible options.
+Files:      src/option.c, src/testdir/test_expand_dllpath.vim
+
+Patch 8.0.0373
+Problem:    Build fails without +folding.
+Solution:   Move misplaced #ifdef.
+Files:      src/option.c
+
+Patch 8.0.0374
+Problem:    Invalid memory access when using :sc in Ex mode. (Dominique Pelle)
+Solution:   Avoid the column being negative.  Also fix a hang in Ex mode.
+Files:      src/ex_getln.c, src/ex_cmds.c, src/testdir/test_substitute.vim
+
+Patch 8.0.0375
+Problem:    The "+ register is not tested.
+Solution:   Add a test using another Vim instance to change the "+ register.
+            (Kazunobu Kuriyama)
+Files:      src/testdir/test_gui.vim
+
+Patch 8.0.0376
+Problem:    Size computations in spell file reading are not exactly right.
+Solution:   Make "len" a "long" and check with LONG_MAX.
+Files:      src/spellfile.c
+
+Patch 8.0.0377
+Problem:    Possible overflow when reading corrupted undo file.
+Solution:   Check if allocated size is not too big. (King)
+Files:      src/undo.c
+
+Patch 8.0.0378
+Problem:    Another possible overflow when reading corrupted undo file.
+Solution:   Check if allocated size is not too big. (King)
+Files:      src/undo.c
+
+Patch 8.0.0379
+Problem:    CTRL-Z and mouse click use CTRL-O unnecessary.
+Solution:   Remove stuffing CTRL-O. (James McCoy, closes #1453)
+Files:      src/edit.c, src/normal.c
+
+Patch 8.0.0380
+Problem:    With 'linebreak' set and 'breakat' includes ">" a double-wide
+            character results in "<<" displayed.
+Solution:   Check for the character not to be replaced. (Ozaki Kiichi,
+            closes #1456)
+Files:      src/screen.c, src/testdir/test_listlbr_utf8.vim
+
+Patch 8.0.0381
+Problem:    Diff mode is not sufficiently tested.
+Solution:   Add more diff mode tests. (Dominique Pelle, closes #1515)
+Files:      src/testdir/test_diffmode.vim
+
+Patch 8.0.0382 (after 8.0.0380)
+Problem:    Warning in tiny build for unused variable. (Tony Mechelynck)
+Solution:   Add #ifdefs.
+Files:      src/screen.c
+
+Patch 8.0.0383 (after 8.0.0382)
+Problem:    Misplaced #ifdef. (Christ van Willigen)
+Solution:   Split assignment.
+Files:      src/screen.c
+
+Patch 8.0.0384
+Problem:    Timer test failed for no apparent reason.
+Solution:   Mark the test as flaky.
+Files:      src/testdir/runtest.vim
+
+Patch 8.0.0385
+Problem:    No tests for arabic.
+Solution:   Add a first test for arabic. (Dominique Pelle, closes #1518)
+Files:      src/Makefile, src/testdir/Make_all.mak,
+            src/testdir/test_arabic.vim
+
+Patch 8.0.0386
+Problem:    Tiny build has a problem with generating the options test.
+Solution:   Change the "if" to skip over statements.
+Files:      src/gen_opt_test.vim
+
+Patch 8.0.0387
+Problem:    compiler warnings
+Solution:   Add type casts. (Christian Brabandt)
+Files:      src/channel.c, src/memline.c, 
+
+Patch 8.0.0388
+Problem:    filtering lines through "cat", without changing the line count,
+            changes manual folds.
+Solution:   Change how marks and folds are adjusted. (Matthew Malcomson, from
+            neovim #6194.
+Files:      src/fold.c, src/testdir/test_fold.vim
+
+Patch 8.0.0389
+Problem:    Test for arabic does not check what is displayed.
+Solution:   Improve what is asserted. (Dominique Pelle, closes #1523)
+            Add a first shaping test.
+Files:      src/testdir/test_arabic.vim
+
+Patch 8.0.0390
+Problem:    When the window scrolls horizontally when the popup menu is
+            displayed part of it may not be cleared. (Neovim issue #6184)
+Solution:   Remove the menu when the windows scrolled. (closes #1524)
+Files:      src/edit.c
+
+Patch 8.0.0391
+Problem:    Arabic support is verbose and not well tested.
+Solution:   Simplify the code.  Add more tests.
+Files:      src/arabic.c, src/testdir/test_arabic.vim
+
+Patch 8.0.0392
+Problem:    GUI test fails with Athena and Motif.
+Solution:   Add test_ignore_error().  Use it to ignore the "failed to create
+            input context" error.
+Files:      src/message.c, src/proto/message.pro, src/evalfunc.c,
+            src/testdir/test_gui.vim, runtime/doc/eval.txt
+
+Patch 8.0.0393 (after 8.0.0190)
+Problem:    When the same tag appears more than once, the order is
+            unpredictable. (Charles Campbell)
+Solution:   Besides using a dict for finding duplicates, use a grow array for
+            keeping the tags in sequence.
+Files:      src/tag.c, src/testdir/test_tagjump.vim
+
+Patch 8.0.0394
+Problem:    Tabs are not aligned when scrolling horizontally and a Tab doesn't
+            fit. (Axel Bender)
+Solution:   Handle a Tab as a not fitting character. (Christian Brabandt)
+            Also fix that ":redraw" does not scroll horizontally to show the
+            cursor.  And fix the test that depended on the old behavior.
+Files:      src/screen.c, src/ex_docmd.c, src/testdir/test_listlbr.vim,
+            src/testdir/test_listlbr_utf8.vim,
+            src/testdir/test_breakindent.vim
+
+Patch 8.0.0395 (after 8.0.0392)
+Problem:    Testing the + register fails with Motif.
+Solution:   Also ignore the "failed to create input context" error in the
+            second gvim.  Don't use msg() when it would result in a dialog.
+Files:      src/message.c, src/testdir/test_gui.vim, src/testdir/setup_gui.vim
+
+Patch 8.0.0396
+Problem:    'balloonexpr' only works synchronously.
+Solution:   Add balloon_show(). (Jusufadis Bakamovic, closes #1449)
+Files:      runtime/doc/eval.txt, src/evalfunc.c, src/os_unix.c,
+            src/os_win32.c
+
+Patch 8.0.0397 (after 8.0.0392)
+Problem:    Cannot build with the viminfo feature but without the eval
+            feature.
+Solution:   Adjust #ifdef. (John Marriott)
+Files:      src/message.c, src/misc2.c
+
+Patch 8.0.0398
+Problem:    Illegal memory access with "t".
+Solution:   Use strncmp() instead of memcmp(). (Dominique Pelle, closes #1528)
+Files:      src/search.c, src/testdir/test_search.vim
+
+Patch 8.0.0399
+Problem:    Crash when using balloon_show() when not supported. (Hirohito
+            Higashi)
+Solution:   Check for balloonEval not to be NULL. (Ken Takata)
+Files:      src/evalfunc.c, src/testdir/test_functions.vim
+
+Patch 8.0.0400
+Problem:    Some tests have a one second delay.
+Solution:   Add --not-a-term in RunVim().
+Files:      src/testdir/shared.vim
+
+Patch 8.0.0401
+Problem:    Test fails with missing balloon feature.
+Solution:   Add check for balloon feature.
+Files:      src/testdir/test_functions.vim
+
+Patch 8.0.0402
+Problem:    :map completion does not have <special>. (Dominique Pelle)
+Solution:   Recognize <special> in completion.  Add a test.
+Files:      src/getchar.c, src/testdir/test_cmdline.vim
+
+Patch 8.0.0403
+Problem:    GUI tests may fail.
+Solution:   Ignore the E285 error better. (Kazunobu Kuriyama)
+Files:      src/testdir/test_gui.vim, src/testdir/test_gui_init.vim
+
+Patch 8.0.0404
+Problem:    Not enough testing for quickfix.
+Solution:   Add some more tests. (Yegappan Lakshmanan)
+Files:      src/testdir/test_quickfix.vim
+
+Patch 8.0.0405
+Problem:    v:progpath may become invalid after ":cd".
+Solution:   Turn v:progpath into a full path if needed.
+Files:      src/main.c, src/testdir/test_startup.vim, runtime/doc/eval.txt
+
+Patch 8.0.0406
+Problem:    The arabic shaping code is verbose.
+Solution:   Shorten the code without changing the functionality.
+Files:      src/arabic.c
+
+Patch 8.0.0407 (after 8.0.0388)
+Problem:    Filtering folds with marker method not tested.
+Solution:   Also set 'foldmethod' to "marker".
+Files:      src/testdir/test_fold.vim
+
+Patch 8.0.0408
+Problem:    Updating folds does not work properly when inserting a file and a
+            few other situations.
+Solution:   Adjust the way folds are updated. (Matthew Malcomson)
+Files:      src/fold.c, src/testdir/test_fold.vim
+
+Patch 8.0.0409
+Problem:    set_progpath is defined but not always used
+Solution:   Adjust #ifdef.
+Files:      src/main.c
+
+Patch 8.0.0410
+Problem:    Newer gettext/iconv library has extra dll file.
+Solution:   Add the file to the Makefile and nsis script. (Christian Brabandt)
+Files:      Makefile, nsis/gvim.nsi
+
+Patch 8.0.0411
+Problem:    We can't change the case in menu entries, it breaks translations.
+Solution:   Ignore case when looking up a menu translation.
+Files:      src/menu.c, src/testdir/test_menu.vim
+
+Patch 8.0.0412 (after 8.0.0411)
+Problem:    Menu test fails on MS-Windows.
+Solution:   Use a menu entry with only ASCII characters.
+Files:      src/testdir/test_menu.vim
+
+Patch 8.0.0413 (after 8.0.0412)
+Problem:    Menu test fails on MS-Windows using gvim.
+Solution:   First delete the English menus.
+Files:      src/testdir/test_menu.vim
+
+Patch 8.0.0414
+Problem:    Balloon eval is not tested.
+Solution:   Add a few balloon tests. (Kazunobu Kuriyama)
+Files:      src/testdir/test_gui.vim
+
+Patch 8.0.0415 (after 8.0.0414)
+Problem:    Balloon test fails on MS-Windows.
+Solution:   Test with 0x7fffffff instead of 0xffffffff.
+Files:      src/testdir/test_gui.vim
+
+Patch 8.0.0416
+Problem:    Setting v:progpath is not quite right.
+Solution:   On MS-Windows add the extension. On Unix use the full path for a
+            relative directory. (partly by James McCoy, closes #1531)
+Files:      src/main.c, src/os_win32.c, src/os_unix.c
+
+Patch 8.0.0417
+Problem:    Test for the clipboard fails sometimes.
+Solution:   Add it to the flaky tests.
+Files:      src/testdir/runtest.vim
+
+Patch 8.0.0418
+Problem:    ASAN logs are disabled and don't cause a failure.
+Solution:   Enable ASAN logs and fail if not empty. (James McCoy,
+            closes #1425)
+Files:      .travis.yml
+
+Patch 8.0.0419
+Problem:    Test for v:progpath fails on MS-Windows.
+Solution:   Expand to full path.  Also add ".exe" when the path is an absolute
+            path.
+Files:      src/os_win32.c, src/main.c
+
+Patch 8.0.0420
+Problem:    When running :make the output may be in the system encoding,
+            different from 'encoding'.
+Solution:   Add the 'makeencoding' option. (Ken Takata)
+Files:      runtime/doc/options.txt, runtime/doc/quickfix.txt,
+            runtime/doc/quickref.txt, src/Makefile, src/buffer.c,
+            src/if_cscope.c, src/main.c, src/option.c, src/option.h,
+            src/proto/quickfix.pro, src/quickfix.c, src/structs.h,
+            src/testdir/Make_all.mak, src/testdir/test_makeencoding.py,
+            src/testdir/test_makeencoding.vim
+
+Patch 8.0.0421
+Problem:    Diff mode is displayed wrong when adding a line at the end of a
+            buffer.
+Solution:   Adjust marks in diff mode. (James McCoy, closes #1329)
+Files:      src/misc1.c, src/ops.c, src/testdir/test_diffmode.vim
+
+Patch 8.0.0422
+Problem:    Python test fails with Python 3.6.
+Solution:   Convert new exception messages to old ones. (closes #1359)
+Files:      src/testdir/test87.in
+
+Patch 8.0.0423
+Problem:    The effect of adding "#" to 'cinoptions' is not always removed.
+            (David Briscoe)
+Solution:   Reset b_ind_hash_comment. (Christian Brabandt, closes #1475)
+Files:      src/misc1.c, src/Makefile, src/testdir/Make_all.mak,
+            src/testdir/test_cindent.vim, src/testdir/test3.in
+
+Patch 8.0.0424
+Problem:    Compiler warnings on MS-Windows. (Ajit Thakkar)
+Solution:   Add type casts.
+Files:      src/os_win32.c
+
+Patch 8.0.0425
+Problem:    Build errors when building without folding.
+Solution:   Add #ifdefs. (John Marriott)
+Files:      src/diff.c, src/edit.c, src/option.c, src/syntax.c
+
+Patch 8.0.0426
+Problem:    Insufficient testing for statusline.
+Solution:   Add several tests. (Dominique Pelle, closes #1534)
+Files:      src/testdir/test_statusline.vim
+
+Patch 8.0.0427
+Problem:    'makeencoding' missing from the options window.
+Solution:   Add the entry.
+Files:      runtime/optwin.vim
+
+Patch 8.0.0428
+Problem:    Git and hg see new files after running tests. (Manuel Ortega)
+Solution:   Add the generated file to .hgignore (or .gitignore). Delete the
+            resulting verbose file. (Christian Brabandt)  Improve dependency
+            on opt_test.vim.  Reset the 'more' option.
+Files:      .hgignore, src/gen_opt_test.vim, src/testdir/gen_opt_test.vim,
+            src/Makefile, src/testdir/Make_all.mak, src/testdir/Makefile,
+            src/testdir/Make_dos.mak, src/testdir/Make_ming.mak,
+            Filelist
+
+Patch 8.0.0429
+Problem:    Options test does not always test everything.
+Solution:   Fix dependency for opt_test.vim.  Give a message when opt_test.vim
+            was not found.
+Files:      src/testdir/test_options.vim, src/testdir/gen_opt_test.vim,
+            src/testdir/Makefile, src/testdir/Make_all.mak,
+            src/testdir/Make_dos.mak, src/testdir/Make_ming.mak
+
+Patch 8.0.0430
+Problem:    Options test fails or hangs on MS-Windows.
+Solution:   Run it separately instead of part of test_alot.  Use "-S" instead
+            of "-u" to run the script.  Fix failures.
+Files:      src/testdir/Make_all.mak, src/testdir/test_alot.vim,
+            src/testdir/Makefile, src/testdir/Make_dos.mak,
+            src/testdir/Make_ming.mak, src/testdir/gen_opt_test.vim
+
+Patch 8.0.0431
+Problem:    'cinoptions' cannot set indent for extern block.
+Solution:   Add the "E" flag in 'cinoptions'. (Hirohito Higashi)
+Files:      runtime/doc/indent.txt, src/misc1.c, src/structs.h,
+            src/testdir/test_cindent.vim
+
+Patch 8.0.0432
+Problem:    "make shadow" creates an invalid link.
+Solution:   Don't link "*.vim". (Kazunobu Kuriyama)
+Files:      src/Makefile
+
+Patch 8.0.0433
+Problem:    Quite a few beeps when running tests.
+Solution:   Set 'belloff' for these tests. (Christian Brabandt)
+Files:      src/testdir/test103.in, src/testdir/test14.in,
+            src/testdir/test29.in, src/testdir/test30.in,
+            src/testdir/test32.in, src/testdir/test45.in,
+            src/testdir/test72.in, src/testdir/test73.in,
+            src/testdir/test77.in, src/testdir/test78.in,
+            src/testdir/test85.in, src/testdir/test94.in,
+            src/testdir/test_alot.vim, src/testdir/test_alot_utf8.vim,
+            src/testdir/test_close_count.in, src/testdir/test_cmdline.vim,
+            src/testdir/test_diffmode.vim, src/testdir/test_digraph.vim,
+            src/testdir/test_erasebackword.in, src/testdir/test_normal.vim,
+            src/testdir/test_packadd.vim, src/testdir/test_search.vim,
+            src/testdir/test_textobjects.vim, src/testdir/test_undo.vim,
+            src/testdir/test_usercommands.vim, src/testdir/test_visual.vim
+
+Patch 8.0.0434
+Problem:    Clang version not correctly detected.
+Solution:   Adjust the configure script. (Kazunobu Kuriyama)
+Files:      src/configure.ac, src/auto/configure
+
+Patch 8.0.0435
+Problem:    Some functions are not tested.
+Solution:   Add more tests for functions. (Dominique Pelle, closes #1541)
+Files:      src/testdir/test_functions.vim
+
+Patch 8.0.0436
+Problem:    Running the options test sometimes resizes the terminal.
+Solution:   Clear out t_WS.
+Files:      src/testdir/gen_opt_test.vim
+
+Patch 8.0.0437
+Problem:    The packadd test does not create the symlink correctly and does
+            not test the right thing.
+Solution:   Create the directory and symlink correctly.
+Files:      src/testdir/test_packadd.vim
+
+Patch 8.0.0438
+Problem:    The fnamemodify test changes 'shell' in a way later tests may not
+            be able to use system().
+Solution:   Save and restore 'shell'.
+Files:      src/testdir/test_fnamemodify.vim
+
+Patch 8.0.0439
+Problem:    Using ":%argdel" while the argument list is already empty gives an
+            error. (Pavol Juhas)
+Solution:   Don't give an error. (closes #1546)
+Files:      src/ex_cmds2.c, src/testdir/test_arglist.vim
+
+Patch 8.0.0440
+Problem:    Not enough test coverage in Insert mode.
+Solution:   Add lots of tests.  Add test_override(). (Christian Brabandt,
+            closes #1521)
+Files:      runtime/doc/eval.txt, runtime/doc/usr_41.txt, src/edit.c,
+            src/evalfunc.c, src/globals.h,  src/screen.c,
+            src/testdir/Make_all.mak, src/testdir/test_cursor_func.vim,
+            src/testdir/test_edit.vim, src/testdir/test_search.vim,
+            src/testdir/test_assert.vim, src/Makefile, src/testdir/runtest.vim
+
+Patch 8.0.0441
+Problem:    Dead code in #ifdef.
+Solution:   Remove the #ifdef and #else part.
+Files:      src/option.c
+
+Patch 8.0.0442
+Problem:    Patch shell command uses double quotes around the argument, which
+            allows for $HOME to be expanded. (Etienne)
+Solution:   Use single quotes on Unix. (closes #1543)
+Files:      src/diff.c, src/testdir/test_diffmode.vim
+
+Patch 8.0.0443
+Problem:    Terminal width is set to 80 in test3.
+Solution:   Instead of setting 'columns' set 'wrapmargin' depending on
+            'columns.
+Files:      src/testdir/test3.in
+
+Patch 8.0.0444 (after 8.0.0442)
+Problem:    Diffpatch fails when the file name has a quote.
+Solution:   Escape the name properly. (zetzei)
+Files:      src/diff.c, src/testdir/test_diffmode.vim
+
+Patch 8.0.0445
+Problem:    Getpgid is not supported on all systems.
+Solution:   Add a configure check.
+Files:      src/configure.ac, src/auto/configure, src/config.h.in,
+            src/os_unix.c
+
+Patch 8.0.0446
+Problem:    The ";" command does not work after characters with a lower byte
+            that is NUL.
+Solution:   Properly check for not having a previous character. (Hirohito
+            Higashi)
+Files:      src/Makefile, src/search.c, src/testdir/test_alot_utf8.vim,
+            src/testdir/test_charsearch_utf8.vim
+
+Patch 8.0.0447
+Problem:    Getting font name does not work on X11.
+Solution:   Implement gui_mch_get_fontname() for X11.  Add more GUI tests.
+            (Kazunobu Kuriyama)
+Files:      src/gui_x11.c, src/syntax.c, src/testdir/Make_dos.mak,
+            src/testdir/Make_ming.mak, src/testdir/Makefile,
+            src/testdir/gui_init.vim, src/testdir/gui_preinit.vim,
+            src/testdir/test_gui.vim, src/testdir/test_gui_init.vim,
+            Filelist
+
+Patch 8.0.0448
+Problem:    Some macros are in lower case, which can be confusing.
+Solution:   Make a few lower case macros upper case.
+Files:      src/macros.h, src/buffer.c, src/charset.c, src/ops.c, src/diff.c,
+            src/edit.c, src/evalfunc.c, src/ex_cmds.c, src/ex_getln.c,
+            src/fileio.c, src/fold.c, src/gui.c, src/gui_beval.c, src/main.c,
+            src/mark.c, src/misc1.c, src/move.c, src/normal.c,
+            src/option.c, src/popupmnu.c, src/regexp.c, src/screen.c,
+            src/search.c, src/spell.c, src/tag.c, src/ui.c, src/undo.c,
+            src/version.c, src/workshop.c, src/if_perl.xs
+
+Patch 8.0.0449 (after 8.0.0448)
+Problem:    Part of fold patch accidentally included.
+Solution:   Revert that part of the patch.
+Files:      src/ex_cmds.c
+
+Patch 8.0.0450
+Problem:    v:progpath is not reliably set.
+Solution:   Read /proc/self/exe if possible. (idea by Michal Grochmal)
+            Also fixes missing #if.
+Files:      src/main.c, src/config.h.in
+
+Patch 8.0.0451
+Problem:    Some macros are in lower case.
+Solution:   Make a few more macros upper case. Avoid lower case macros use an
+            argument twice.
+Files:      src/macros.h, src/charset.c, src/misc2.c, src/proto/misc2.pro,
+            src/edit.c, src/eval.c, src/ex_cmds.c, src/ex_cmds2.c,
+            src/ex_docmd.c, src/ex_getln.c, src/fileio.c, src/fold.c,
+            src/gui.c, src/gui_gtk.c, src/mark.c, src/memline.c, src/mbyte.c,
+            src/menu.c, src/message.c, src/misc1.c, src/ops.c, src/option.c,
+            src/os_amiga.c, src/os_mswin.c, src/os_unix.c, src/os_win32.c,
+            src/popupmnu.c, src/regexp.c, src/regexp_nfa.c, src/screen.c,
+            src/search.c, src/spell.c, src/spellfile.c, src/syntax.c,
+            src/tag.c, src/ui.c, src/undo.c, src/window.c
+
+Patch 8.0.0452
+Problem:    Some macros are in lower case.
+Solution:   Make a few more macros upper case.
+Files:      src/vim.h, src/macros.h, src/evalfunc.c, src/fold.c,
+            src/gui_gtk.c, src/gui_gtk_x11.c, src/charset.c, src/diff.c,
+            src/edit.c, src/eval.c, src/ex_cmds.c, src/ex_cmds2.c,
+            src/ex_docmd.c, src/ex_getln.c, src/fileio.c, src/getchar.c,
+            src/gui.c, src/gui_w32.c, src/if_cscope.c, src/mbyte.c,
+            src/menu.c, src/message.c, src/misc1.c, src/misc2.c, src/normal.c,
+            src/ops.c, src/option.c, src/os_unix.c, src/os_win32.c,
+            src/quickfix.c, src/regexp.c, src/regexp_nfa.c, src/screen.c,
+            src/search.c, src/spell.c, src/syntax.c, src/tag.c, src/userfunc.c
+
+Patch 8.0.0453
+Problem:    Adding fold marker creates new comment.
+Solution:   Use an existing comment if possible. (LemonBoy, closes #1549)
+Files:      src/ops.c, src/proto/ops.pro, src/fold.c,
+            src/testdir/test_fold.vim
+
+Patch 8.0.0454
+Problem:    Compiler warnings for comparing unsigned char with 256 always
+            being true. (Manuel Ortega)
+Solution:   Add type cast.
+Files:      src/screen.c, src/charset.c
+
+Patch 8.0.0455
+Problem:    The mode test may hang in Test_mode(). (Michael Soyka)
+Solution:   Set 'complete' to only search the current buffer (as suggested by
+            Michael)
+Files:      src/testdir/test_functions.vim
+
+Patch 8.0.0456
+Problem:    Typo in MinGW test makefile.
+Solution:   Change an underscore to a dot. (Michael Soyka)
+Files:      src/testdir/Make_ming.mak
+
+Patch 8.0.0457
+Problem:    Using :move messes up manual folds.
+Solution:   Split adjusting marks and folds.  Add foldMoveRange(). (neovim
+            patch #6221)
+Files:      src/ex_cmds.c, src/fold.c, src/mark.c, src/proto/fold.pro,
+            src/proto/mark.pro src/testdir/test_fold.vim
+
+Patch 8.0.0458
+Problem:    Potential crash if adding list or dict to dict fails.
+Solution:   Make sure the reference count is correct. (Nikolai Pavlov, closes
+            #1555)
+Files:      src/dict.c
+
+Patch 8.0.0459 (after 8.0.0457)
+Problem:    Old fix for :move messing up folding no longer needed, now that we
+            have a proper solution.
+Solution:   Revert patch 7.4.700. (Christian Brabandt)
+Files:      src/ex_cmds.c
+
+Patch 8.0.0460 (after 8.0.0452)
+Problem:    Can't build on HPUX.
+Solution:   Fix argument names in vim_stat(). (John Marriott)
+Files:      src/misc2.c
+
+Patch 8.0.0461 (after 8.0.0457)
+Problem:    Test 45 hangs on MS-Windows.
+Solution:   Reset 'shiftwidth'.  Also remove redundent function.
+Files:      src/fold.c, src/testdir/test45.in
+
+Patch 8.0.0462
+Problem:    If an MS-Windows tests succeeds at first and then fails in a way
+            it does not produce a test.out file it looks like the test
+            succeeded.
+Solution:   Delete the previous output file.
+Files:      src/testdir/Make_dos.mak
+
+Patch 8.0.0463
+Problem:    Resetting 'compatible' in defaults.vim has unexpected side
+            effects. (David Fishburn)
+Solution:   Only reset 'compatible' if it was set.
+Files:      runtime/defaults.vim
+
+Patch 8.0.0464
+Problem:    Can't find executable name on Solaris and FreeBSD.
+Solution:   Check for "/proc/self/path/a.out". (Danek Duvall) And for
+            "/proc/curproc/file".
+Files:      src/config.h.in, src/configure.ac, src/main.c,
+            src/auto/configure
+
+Patch 8.0.0465
+Problem:    Off-by-one error in using :move with folding.
+Solution:   Correct off-by-one mistakes and add more tests. (Matthew
+            Malcomson)
+Files:      src/fold.c, src/testdir/test_fold.vim
+
+Patch 8.0.0466
+Problem:    There are still a few macros that should be all-caps.
+Solution:   Make a few more macros all-caps.
+Files:      src/buffer.c, src/edit.c, src/ex_cmds.c, src/ex_cmds2.c,
+           src/ex_docmd.c, src/ex_getln.c, src/farsi.c, src/fileio.c,
+           src/getchar.c, src/gui_beval.c, src/hardcopy.c, src/if_cscope.c,
+           src/if_xcmdsrv.c, src/mark.c, src/memline.c, src/menu.c,
+           src/message.c, src/misc1.c, src/normal.c, src/ops.c, src/option.c,
+           src/quickfix.c, src/screen.c, src/search.c, src/syntax.c,
+           src/tag.c, src/term.c, src/term.h, src/ui.c, src/undo.c,
+           src/userfunc.c, src/version.c, src/vim.h
+
+Patch 8.0.0467
+Problem:    Using g< after :for does not show the right output. (Marcin
+            Szamotulski)
+Solution:   Call msg_sb_eol() in :echomsg.
+Files:      src/eval.c
+
+Patch 8.0.0468
+Problem:    After aborting an Ex command g< does not work. (Marcin
+            Szamotulski)
+Solution:   Postpone clearing scrollback messages to until the command line
+            has been entered.  Also fix that the screen isn't redrawn if after
+            g< the command line is cancelled.
+Files:      src/message.c, src/proto/message.pro, src/ex_getln.c, src/misc2.c,
+            src/gui.c
+
+Patch 8.0.0469
+Problem:    Compiler warnings on MS-Windows.
+Solution:   Add type casts. (Christian Brabandt)
+Files:      src/fold.c
+
+Patch 8.0.0470
+Problem:    Not enough testing for help commands.
+Solution:   Add a few more help tests. (Dominique Pelle, closes #1565)
+Files:      src/testdir/test_help.vim, src/testdir/test_help_tagjump.vim
+
+Patch 8.0.0471
+Problem:    Exit callback test sometimes fails.
+Solution:   Add it to the list of flaky tests.
+Files:      src/testdir/runtest.vim
+
+Patch 8.0.0472
+Problem:    When a test fails and test.log is created, Test_edit_CTRL_I
+            matches it instead of test1.in.
+Solution:   Match with runtest.vim instead.
+Files:      src/testdir/test_edit.vim
+
+Patch 8.0.0473
+Problem:    No test covering arg_all().
+Solution:   Add a test expanding ##.
+Files:      src/testdir/test_arglist.vim
+
+Patch 8.0.0474
+Problem:    The client-server feature is not tested.
+Solution:   Add a test.
+Files:      src/Makefile, src/testdir/Make_all.mak, src/testdir/shared.vim,
+            src/testdir/test_clientserver.vim, src/os_mswin.c
+
+Patch 8.0.0475
+Problem:    Not enough testing for the client-server feature.
+Solution:   Add more tests.  Add the remote_startserver() function.  Fix that
+            a locally evaluated expression uses function-local variables.
+Files:      src/if_xcmdsrv.c, src/evalfunc.c, src/os_mswin.c,
+            src/proto/main.pro, src/testdir/test_clientserver.vim,
+            runtime/doc/eval.txt
+
+Patch 8.0.0476 (after 8.0.0475)
+Problem:    Missing change to main.c.
+Solution:   Add new function.
+Files:      src/main.c
+
+Patch 8.0.0477
+Problem:    The client-server test may hang when failing.
+Solution:   Set a timer.  Add assert_report()
+Files:      src/testdir/test_clientserver.vim, src/testdir/runtest.vim,
+            src/eval.c, src/evalfunc.c, src/proto/eval.pro, src/if_xcmdsrv.c,
+            src/os_mswin.c, runtime/doc/eval.txt
+
+Patch 8.0.0478
+Problem:    Tests use assert_true(0) and assert_false(1) to report errors.
+Solution:   Use assert_report().
+Files:      src/testdir/test_cscope.vim, src/testdir/test_expr.vim,
+            src/testdir/test_perl.vim, src/testdir/test_channel.vim,
+            src/testdir/test_cursor_func.vim, src/testdir/test_gui.vim,
+            src/testdir/test_menu.vim, src/testdir/test_popup.vim,
+            src/testdir/test_viminfo.vim, src/testdir/test_vimscript.vim,
+            src/testdir/test_assert.vim
+
+Patch 8.0.0479
+Problem:    remote_peek() is not tested.
+Solution:   Add a test.
+Files:      src/testdir/test_clientserver.vim, src/testdir/runtest.vim
+
+Patch 8.0.0480
+Problem:    The remote_peek() test fails on MS-Windows.
+Solution:   Check for pending messages. Also report errors in the first run if
+            a flaky test fails twice.
+Files:      src/os_mswin.c, src/testdir/runtest.vim
+
+Patch 8.0.0481
+Problem:    Unnecessary if statement.
+Solution:   Remove the statement.  Fix "it's" vs "its" mistakes. (Dominique
+            Pelle, closes #1568)
+Files:      src/syntax.c
+
+Patch 8.0.0482
+Problem:    The setbufvar() function may mess up the window layout. (Kay Z.)
+Solution:   Do not check the window to be valid if it is NULL.
+Files:      src/window.c, src/testdir/test_functions.vim
+
+Patch 8.0.0483
+Problem:    Illegal memory access when using :all. (Dominique Pelle)
+Solution:   Adjust the cursor position right after setting "curwin".
+Files:      src/window.c, src/testdir/test_window_cmd.vim
+
+Patch 8.0.0484
+Problem:    Using :lhelpgrep with an argument that should fail does not
+            produce an error if the previous :helpgrep worked.
+Solution:   Use another way to detect that autocommands made the quickfix info
+            invalid. (Yegappan Lakshmanan)
+Files:      src/quickfix.c, src/testdir/test_quickfix.vim
+
+Patch 8.0.0485
+Problem:    Not all windows commands are tested.
+Solution:   Add more tests for windows commands. (Dominique Pelle,
+            closes #1575) Run test_autocmd separately, it interferes with
+            other tests.  Fix tests that depended on side effects.
+Files:      src/testdir/test_window_cmd.vim, src/testdir/test_alot.vim,
+            src/testdir/test_autocmd.vim, src/testdir/test_fnamemodify.vim,
+            src/testdir/test_functions.vim, src/testdir/test_delete.vim,
+            src/testdir/Make_all.mak
+
+Patch 8.0.0486
+Problem:    Crash and endless loop when closing windows in a SessionLoadPost
+            autocommand.
+Solution:   Check for valid tabpage.  (partly neovim #6308)
+Files:      src/testdir/test_autocmd.vim, src/fileio.c, src/proto/window.pro,
+            src/window.c
+
+Patch 8.0.0487
+Problem:    The autocmd test hangs on MS-Windows.
+Solution:   Skip the hanging tests for now.
+Files:      src/testdir/test_autocmd.vim
+
+Patch 8.0.0488
+Problem:    Running tests leaves an "xxx" file behind.
+Solution:   Delete the 'verbosefile' after resetting the option.
+Files:      src/testdir/gen_opt_test.vim
+
+Patch 8.0.0489
+Problem:    Clipboard and "* register is not tested.
+Solution:   Add a test for Mac and X11. (Kazunobu Kuriyama)
+Files:      src/Makefile, src/testdir/Make_all.mak,
+            src/testdir/test_quotestar.vim, src/testdir/runtest.vim
+
+Patch 8.0.0490
+Problem:    Splitting a 'winfixwidth' window vertically makes it one column
+            smaller. (Dominique Pelle)
+Solution:   Add one to the width for the separator.
+Files:      src/window.c, src/testdir/test_window_cmd.vim
+
+Patch 8.0.0491
+Problem:    The quotestar test fails when a required feature is missing.
+Solution:   Prepend "Skipped" to the thrown exception.
+Files:      src/testdir/test_quotestar.vim
+
+Patch 8.0.0492
+Problem:    A failing client-server request can make Vim hang.
+Solution:   Add a timeout argument to functions that wait.
+Files:      src/evalfunc.c, src/if_xcmdsrv.c, src/proto/if_xcmdsrv.pro,
+            src/main.c, src/os_mswin.c, src/proto/os_mswin.pro,
+            src/vim.h, runtime/doc/eval.txt, src/testdir/test_clientserver.vim
+
+Patch 8.0.0493
+Problem:    Crash with cd command with very long argument.
+Solution:   Check for running out of space. (Dominique pending, closes #1576)
+Files:      src/testdir/test_alot.vim, src/testdir/test_cd.vim, src/Makefile,
+            src/misc2.c
+
+Patch 8.0.0494
+Problem:    Build failure with older compiler on MS-Windows.
+Solution:   Move declaration to start of block.
+Files:      src/evalfunc.c, src/main.c, src/os_mswin.c
+
+Patch 8.0.0495
+Problem:    The quotestar test uses a timer instead of a timeout, thus it
+            cannot be rerun like a flaky test.
+Solution:   Remove the timer and add a timeout. (Kazunobu Kuriyama)
+Files:      src/testdir/test_quotestar.vim
+
+Patch 8.0.0496
+Problem:    Insufficient testing for folding.
+Solution:   Add a couple more fold tests. (Dominique Pelle, closes #1579)
+Files:      src/testdir/test_fold.vim
+
+Patch 8.0.0497
+Problem:    Arabic support is not fully tested.
+Solution:   Add more tests for the untested functions.  Comment out
+            unreachable code.
+Files:      src/arabic.c, src/testdir/test_arabic.vim
+
+Patch 8.0.0498
+Problem:    Two autocmd tests are skipped on MS-Windows.
+Solution:   Make the test pass on MS-Windows. Write the messages in a file
+            instead of getting the output of system().
+Files:      src/testdir/test_autocmd.vim
+
+Patch 8.0.0499
+Problem:    taglist() does not prioritize tags for a buffer.
+Solution:   Add an optional buffer argument. (Duncan McDougall, closes #1194) 
+Files:      runtime/doc/eval.txt, src/evalfunc.c, src/proto/tag.pro,
+            src/Makefile, src/tag.c, src/testdir/test_alot.vim,
+            src/testdir/test_taglist.vim
+
+Patch 8.0.0500
+Problem:    Quotestar test is still a bit flaky.
+Solution:   Add a slower check for v:version.
+Files:      src/testdir/test_quotestar.vim
+
+Patch 8.0.0501
+Problem:    On MS-Windows ":!start" does not work as expected.
+Solution:   When creating a process fails try passing the argument to
+            ShellExecute().  (Katsuya Hino, closes #1570)
+Files:      runtime/doc/os_win32.txt, src/os_win32.c
+
+Patch 8.0.0502
+Problem:    Coverity complains about possible NULL pointer.
+Solution:   Add an assert(), let's see if this works on all systems.
+Files:      src/window.c
+
+Patch 8.0.0503
+Problem:    Endless loop in updating folds with 32 bit ints.
+Solution:   Subtract from LHS instead of add to the RHS. (Matthew Malcomson)
+Files:      src/fold.c
+
+Patch 8.0.0504
+Problem:    Looking up an Ex command is a bit slow.
+Solution:   Instead of just using the first letter, also use the second letter
+            to skip ahead in the list of commands. Generate the table with a
+            Perl script. (Dominique Pelle, closes #1589)
+Files:      src/Makefile, src/create_cmdidxs.pl, src/ex_docmd.c, Filelist
+
+Patch 8.0.0505
+Problem:    Failed window split for :stag not handled. (Coverity CID 99204)
+Solution:   If the split fails skip to the end. (bstaletic, closes #1577)
+Files:      src/tag.c
+
+Patch 8.0.0506 (after 8.0.0504)
+Problem:    Can't build with ANSI C.
+Solution:   Move declarations to start of block.
+Files:      src/ex_docmd.c
+
+Patch 8.0.0507
+Problem:    Client-server tests fail when $DISPLAY is not set.
+Solution:   Check for E240 before running the test.
+Files:      src/testdir/test_quotestar.vim, src/testdir/test_clientserver.vim
+
+Patch 8.0.0508
+Problem:    Coveralls no longer shows per-file coverage.
+Solution:   Add coverage from codecov.io. (Christian Brabandt)
+Files:      .travis.yml
+
+Patch 8.0.0509
+Problem:    No link to codecov.io results.
+Solution:   Add a badge to the readme file.
+Files:      README.md
+
+Patch 8.0.0510 (after 8.0.0509)
+Problem:    Typo in link to codecov.io results.
+Solution:   Remove duplicate https:.
+Files:      README.md
+
+Patch 8.0.0511
+Problem:    Menuage for skipping client-server tests is unclear.
+Solution:   Be more specific about what's missing (Hirohito Higashi, Kazunobu
+            Kuriyama)
+Files:      src/testdir/test_quotestar.vim, src/testdir/test_clientserver.vim
+
+Patch 8.0.0512
+Problem:    Check for available characters takes too long.
+Solution:   Only check did_start_blocking if wtime is negative. (Daisuke
+            Suzuki, closes #1591)
+Files:      src/os_unix.c
+
+Patch 8.0.0513 (after 8.0.0201)
+Problem:    Getting name of cleared highlight group is wrong. (Matt Wozniski)
+Solution:   Only skip over cleared names for completion. (closes #1592)
+            Also fix that a cleared group causes duplicate completions.
+Files:      src/syntax.c, src/proto/syntax.pro, src/evalfunc.c,
+            src/ex_cmds.c, src/testdir/test_syntax.vim,
+            src/testdir/test_cmdline.vim
+
+Patch 8.0.0514
+Problem:    Script for creating cmdidxs can be improved.
+Solution:   Count skipped lines instead of collecting the lines.  Add "const".
+            (Dominique Pelle, closes #1594)
+Files:      src/create_cmdidxs.pl, src/ex_docmd.c
+
+Patch 8.0.0515
+Problem:    ml_get errors in silent Ex mode. (Dominique Pelle)
+Solution:   Clear valid flags when setting the cursor.  Set the topline when
+            not in full screen mode.
+Files:      src/ex_docmd.c, src/move.c, src/testdir/test_startup.vim
+
+Patch 8.0.0516
+Problem:    A large count on a normal command causes trouble. (Dominique
+            Pelle)
+Solution:   Make "opcount" long.
+Files:      src/globals.h, src/testdir/test_normal.vim
+
+Patch 8.0.0517
+Problem:    There is no way to remove quickfix lists (for testing).
+Solution:   Add the 'f' action to setqflist(). Add tests. (Yegappan
+            Lakshmanan)
+Files:      runtime/doc/eval.txt, src/evalfunc.c, src/quickfix.c,
+            src/testdir/test_quickfix.vim
+
+Patch 8.0.0518
+Problem:    Storing a zero byte from a multi-byte character causes fold text
+            to show up wrong.
+Solution:   Avoid putting zero in ScreenLines. (Christian Brabandt,
+            closes #1567)
+Files:      src/screen.c, src/testdir/test_display.vim
+
+Patch 8.0.0519
+Problem:    Character classes are not well tested. They can differ between
+            platforms.
+Solution:   Add tests.  In the documentation make clear which classes depend
+            on what library function.  Only use :cntrl: and :graph: for ASCII.
+            (Kazunobu Kuriyama, Dominique Pelle, closes #1560)
+            Update the documentation.
+Files:      src/regexp.c, src/regexp_nfa.c, runtime/doc/pattern.txt,
+            src/testdir/test_regexp_utf8.vim
+
+Patch 8.0.0520
+Problem:    Using a function pointer instead of the actual function, which we
+            know.
+Solution:   Change mb_ functions to utf_ functions when already checked for
+            Unicode. (Dominique Pelle, closes #1582)
+Files:      src/message.c, src/misc2.c, src/regexp.c, src/regexp_nfa.c,
+            src/screen.c, src/spell.c
+
+Patch 8.0.0521
+Problem:    GtkForm handling is outdated.
+Solution:   Get rid of event filter functions.  Get rid of GtkForm.width and
+            .height.  Eliminate gtk_widget_size_request() calls. (Kazunobu
+            Kuriyama)
+Files:      src/gui_gtk_f.c, src/gui_gtk_f.h
+
+Patch 8.0.0522
+Problem:    MS-Windows: when 'clipboard' is "unnamed" yyp does not work in a
+            :global command.
+Solution:   When setting the clipboard was postponed, do not clear the
+            register.
+Files:      src/ops.c, src/proto/ui.pro, src/ui.c, src/globals.h,
+            src/testdir/test_global.vim, src/Makefile,
+            src/testdir/test_alot.vim
+
+Patch 8.0.0523
+Problem:    dv} deletes part of a multi-byte character. (Urtica Dioica)
+Solution:   Include the whole character.
+Files:      src/search.c, src/testdir/test_normal.vim
+
+Patch 8.0.0524 (after 8.0.0518)
+Problem:    Folds are messed up when 'encodin' is "utf-8".
+Solution:   Also set the fold character when it's not multi-byte.
+Files:      src/screen.c, src/testdir/test_display.vim
+
+Patch 8.0.0525
+Solution:   Completion for user command argument not tested.
+Problem:    Add a test.
+Files:      src/testdir/test_cmdline.vim
+
+Patch 8.0.0526
+Problem:    Coverity complains about possible negative value.
+Solution:   Check return value of ftell() not to be negative.
+Files:      src/os_unix.c
+
+Patch 8.0.0527
+Problem:    RISC OS support was removed long ago, but one file is still
+            included.
+Solution:   Delete the file. (Thomas Dziedzic, closes #1603)
+Files:      Filelist, src/swis.s
+
+Patch 8.0.0528
+Problem:    When 'wildmenu' is set and 'wildmode' has "longest" then the first
+            file name is highlighted, even though the text shows the longest
+            match.
+Solution:   Do not highlight the first match. (LemonBoy, closes #1602)
+Files:      src/ex_getln.c
+
+Patch 8.0.0529
+Problem:    Line in test commented out.
+Solution:   Uncomment the lines for character classes that were failing before
+            8.0.0519. (Dominique Pelle, closes #1599)
+Files:      src/testdir/test_regexp_utf8.vim
+
+Patch 8.0.0530
+Problem:    Buffer overflow when 'columns' is very big. (Nikolai Pavlov)
+Solution:   Correctly compute where to truncate.  Fix translation.
+            (closes #1600)
+Files:      src/edit.c, src/testdir/test_edit.vim
+
+Patch 8.0.0531 (after 8.0.0530)
+Problem:    Test with long directory name fails on non-unix systems.
+Solution:   Skip the test on non-unix systems.
+Files:      src/testdir/test_edit.vim
+
+Patch 8.0.0532 (after 8.0.0531)
+Problem:    Test with long directory name fails on Mac.
+Solution:   Skip the test on Mac systems.
+Files:      src/testdir/test_edit.vim
+
+Patch 8.0.0533
+Problem:    Abbreviation doesn't work after backspacing newline. (Hkonrk)
+Solution:   Set the insert start column. (closes #1609)
+Files:      src/testdir/test_mapping.vim, src/edit.c
+
+Patch 8.0.0534
+Problem:    Defaults.vim does not work well with tiny features. (crd477)
+Solution:   When the +eval feature is not available always reset 'compatible'.
+Files:      runtime/defaults.vim
+
+Patch 8.0.0535
+Problem:    Memory leak when exiting from within a user function.
+Solution:   Clear the function call stack on exit.
+Files:      src/userfunc.c
+
+Patch 8.0.0536
+Problem:    Quickfix window not updated when freeing quickfix stack.
+Solution:   Update the quickfix window. (Yegappan Lakshmanan)
+Files:      src/quickfix.c, src/testdir/test_quickfix.vim
+
+Patch 8.0.0537
+Problem:    Illegal memory access with :z and large count.
+Solution:   Check for number overflow, using long instead of int. (Dominique
+            Pelle, closes #1612)
+Files:      src/Makefile, src/ex_cmds.c, src/testdir/test_alot.vim,
+            src/testdir/test_ex_z.vim
+
+Patch 8.0.0538
+Problem:    No test for falling back to default term value.
+Solution:   Add a test.
+Files:      src/testdir/test_startup.vim
+
+Patch 8.0.0539 (after 8.0.0538)
+Problem:    Startup test fails on Mac.
+Solution:   Use another term name, "unknown" is known. Avoid a 2 second delay.
+Files:      src/testdir/test_startup.vim, src/main.c, src/proto/main.pro,
+            src/term.c
+
+Patch 8.0.0540 (after 8.0.0540)
+Problem:    Building unit tests fails.
+Solution:   Move params outside of #ifdef.
+Files:      src/main.c, src/message_test.c
+
+Patch 8.0.0541
+Problem:    Compiler warning on MS-Windows.
+Solution:   Add a type cast. (Mike Williams)
+Files:      src/edit.c
+
+Patch 8.0.0542
+Problem:    getpos() can return a negative line number. (haya14busa)
+Solution:   Handle a zero topline and botline. (closes #1613)
+Files:      src/eval.c, runtime/doc/eval.txt
+
+Patch 8.0.0543
+Problem:    Test_edit causes older xfce4-terminal to close. (Dominique Pelle)
+Solution:   Reduce number of columns to 2000.  Try to restore the window
+            position.
+Files:      src/testdir/test_edit.vim, src/evalfunc.c, src/term.c,
+            src/proto/term.pro, src/term.h
+
+Patch 8.0.0544
+Problem:    Cppcheck warnings.
+Solution:   Use temp variable. Change NUL to NULL. Swap conditions. (Dominique
+            Pelle)
+Files:      src/channel.c, src/edit.c, src/farsi.c
+
+Patch 8.0.0545
+Problem:    Edit test may fail on some systems.
+Solution:   If creating a directory with a very long path fails, bail out.
+Files:      src/testdir/test_edit.vim
+
+Patch 8.0.0546
+Problem:    Swap file exists briefly when opening the command window.
+Solution:   Set the noswapfile command modifier before splitting the window.
+            (James McCoy, closes #1620)
+Files:      src/ex_getln.c, src/option.c
+
+Patch 8.0.0547
+Problem:    Extra line break in verbosefile when using ":echomsg". (Ingo
+            Karkat)
+Solution:   Don't call msg_start(). (closes #1618)
+Files:      src/eval.c, src/testdir/test_cmdline.vim
+
+Patch 8.0.0548
+Problem:    Saving the redo buffer only works one time, resulting in the "."
+            command not working well for a function call inside another
+            function call. (Ingo Karkat)
+Solution:   Save the redo buffer at every user function call. (closes #1619)
+Files:      src/getchar.c, src/proto/getchar.pro, src/structs.h,
+            src/fileio.c, src/userfunc.c, src/testdir/test_functions.vim
+
+Patch 8.0.0549
+Problem:    No test for the 8g8 command.
+Solution:   Add a test. (Dominique Pelle, closes #1615)
+Files:      src/testdir/test_normal.vim
+
+Patch 8.0.0550
+Problem:    Some etags format tags file use 0x01, breaking the parsing.
+Solution:   Use 0x02 for TAG_SEP. (James McCoy, closes #1614)
+Files:      src/tag.c, src/testdir/test_taglist.vim
+
+Patch 8.0.0551
+Problem:    The typeahead buffer is reallocated too often.
+Solution:   Re-use the existing buffer if possible.
+Files:      src/getchar.c
+
+Patch 8.0.0552
+Problem:    Toupper and tolower don't work properly for Turkish when 'casemap'
+            is empty. (Bjorn Linse)
+Solution:   Check the 'casemap' options when deciding how to upper/lower case.
+Files:      src/charset.c, src/testdir/test_normal.vim
+
+Patch 8.0.0553 (after 8.0.0552)
+Problem:    Toupper/tolower test with Turkish locale fails on Mac.
+Solution:   Skip the test on Mac.
+Files:      src/testdir/test_normal.vim
+
+Patch 8.0.0554 (after 8.0.0552)
+Problem:    Toupper and tolower don't work properly for Turkish when 'casemap'
+            contains "keepascii". (Bjorn Linse)
+Solution:   When 'casemap' contains "keepascii" use ASCII toupper/tolower.
+Files:      src/charset.c, src/testdir/test_normal.vim
+
+Patch 8.0.0555 (after 8.0.0552)
+Problem:    Toupper/tolower test fails on OSX without Darwin.
+Solution:   Skip that part of the test also for OSX. (Kazunobu Kuriyama)
+Files:      src/testdir/test_normal.vim
+
+Patch 8.0.0556
+Problem:    Getting the window position fails if both the GUI and term
+            code is built in.
+Solution:   Return after getting the GUI window position. (Kazunobu Kuriyama)
+Files:      src/evalfunc.c
+
+Patch 8.0.0557
+Problem:    GTK: using static gravities is not useful.
+Solution:   Remove setting static gravities. (Kazunobu Kuriyama)
+Files:      src/gui_gtk_f.c
+
+Patch 8.0.0558
+Problem:    The :ownsyntax command is not tested.
+Solution:   Add a test. (Dominique Pelle, closes #1622)
+Files:      src/testdir/test_syntax.vim
+
+Patch 8.0.0559
+Problem:    Setting ttytype to xxx does not always fail as expected. (Marvin
+            Schmidt)
+Solution:   Catch both possible errors. (closes #1601)
+Files:      src/testdir/test_options.vim
+
+Patch 8.0.0560
+Problem:    :windo allows for ! but it's not supported.
+Solution:   Disallow passing !. (Hirohito Higashi)
+Files:      src/ex_cmds.h
+
+Patch 8.0.0561
+Problem:    Undefined behavior when using backslash after empty line.
+Solution:   Check for an empty line. (Dominique Pelle, closes #1631)
+Files:      src/misc2.c, src/testdir/test_vimscript.vim
+
+Patch 8.0.0562
+Problem:    Not enough test coverage for syntax commands.
+Solution:   Add a few more tests. (Dominique Pelle, closes #1624)
+Files:      src/testdir/test_cmdline.vim, src/testdir/test_syntax.vim
+
+Patch 8.0.0563
+Problem:    Crash when getting the window position in tmux. (Marvin Schmidt)
+Solution:   Add t_GP to the list of terminal options. (closes #1627)
+Files:      src/option.c
+
+Patch 8.0.0564
+Problem:    Cannot detect Bazel BUILD files on some systems.
+Solution:   Check for BUILD after script checks. (Issue #1340)
+Files:      runtime/filetype.vim
+
+Patch 8.0.0565
+Problem:    Using freed memory in :caddbuf after clearing quickfix list.
+            (Dominique Pelle)
+Solution:   Set qf_last to NULL.
+Files:      src/quickfix.c
+
+Patch 8.0.0566
+Problem:    Setting nocompatible for the tiny version moves the cursor.
+Solution:   Use another trick to skip commands when the +eval feature is
+            present. (Christian Brabandt, closes #1630)
+Files:      runtime/defaults.vim
+
+Patch 8.0.0567
+Problem:    Call for requesting color and ambiwidth is too early. (Hirohito
+            Higashi)
+Solution:   Move the call down to below resetting "starting".
+Files:      src/main.c
+
+Patch 8.0.0568
+Problem:    "1gd" may hang.
+Solution:   Don't get stuck in one position. (Christian Brabandt, closes #1643)
+Files:      src/testdir/test_goto.vim, src/normal.c
+
+Patch 8.0.0569
+Problem:    Bracketed paste is still enabled when executing a shell command.
+            (Michael Smith)
+Solution:   Disable brackted paste when going into cooked mode. (closes #1638)
+Files:      src/term.c
+
+Patch 8.0.0570
+Problem:    Can't run make with several jobs, creating directories has a race
+            condition.
+Solution:   Use the MKDIR_P autoconf mechanism. (Eric N. Vander Weele,
+            closes #1639)
+Files:      src/configure.ac, src/auto/configure, src/Makefile,
+            src/config.mk.in, src/install-sh, src/mkinstalldirs, Filelist
+
+Patch 8.0.0571
+Problem:    The cursor line number becomes negative when using :z^ in an empty
+            buffer. (neovim #6557)
+Solution:   Correct the line number.  Also reset the column.
+Files:      src/testdir/test_ex_z.vim, src/ex_cmds.c
+
+Patch 8.0.0572
+Problem:    Building the command table requires Perl.
+Solution:   Use a Vim script solution. (Dominique Pelle, closes #1641)
+Files:      src/Makefile, src/create_cmdidxs.pl, src/create_cmdidxs.vim,
+            src/ex_cmdidxs.h, src/ex_docmd.c, Filelist
+
+Patch 8.0.0573
+Problem:    Running parallel make after distclean fails. (Manuel Ortega)
+Solution:   Instead of using targets "scratch config myself" use "reconfig".
+Files:      src/Makefile, src/config.mk.dist
+
+Patch 8.0.0574
+Problem:    Get only one quickfix list after :caddbuf.
+Solution:   Reset qf_multiline. (Yegappan Lakshmanan)
+Files:      src/quickfix.c, src/testdir/test_quickfix.vim
+
+Patch 8.0.0575
+Problem:    Using freed memory when resetting 'indentexpr' while evaluating
+            it. (Dominique Pelle)
+Solution:   Make a copy of 'indentexpr'.
+Files:      src/misc1.c, src/testdir/test_options.vim
+
+Patch 8.0.0576 (after 8.0.0570 and 8.0.0573)
+Problem:    Can't build when configure choses "install-sh". (Daniel Hahler)
+Solution:   Always use install-sh.  Fix remaining use of mkinstalldirs.
+            (closes #1647)
+Files:      src/installman.sh, src/installml.sh, src/config.mk.in,
+            src/configure.ac, src/auto/configure, src/Makefile
+
+Patch 8.0.0577 (after 8.0.0575)
+Problem:    Warning for uninitialized variable. (John Marriott)
+Solution:   Initialize "indent".
+Files:      src/misc1.c
+
+Patch 8.0.0578
+Problem:    :simalt on MS-Windows does not work properly.
+Solution:   Put something in the typeahead buffer. (Christian Brabandt)
+Files:      src/gui_w32.c
+
+Patch 8.0.0579
+Problem:    Duplicate test case for quickfix.
+Solution:   Remove the function. (Yegappan Lakshmanan)
+Files:      src/testdir/test_quickfix.vim
+
+Patch 8.0.0580
+Problem:    Cannot set the valid flag with setqflist().
+Solution:   Add the "valid" argument. (Yegappan Lakshmanan, closes #1642)
+Files:      runtime/doc/eval.txt, src/quickfix.c,
+            src/testdir/test_quickfix.vim
+
+Patch 8.0.0581
+Problem:    Moving folded text is sometimes not correct.
+Solution:   Bail out when "move_end" is zero. (Matthew Malcomson)
+Files:      src/fold.c, src/testdir/test_fold.vim
+
+Patch 8.0.0582
+Problem:    Illegal memory access with z= command. (Dominique Pelle)
+Solution:   Avoid case folded text to be longer than the original text.  Use
+            MB_PTR2LEN() instead of MB_BYTE2LEN().
+Files:      src/spell.c, src/testdir/test_spell.vim
+
+Patch 8.0.0583
+Problem:    Fold test hangs on MS-Windows.
+Solution:   Avoid overflow in compare.
+Files:      src/fold.c
+
+Patch 8.0.0584
+Problem:    Memory leak when executing quickfix tests.
+Solution:   Free the list reference. (Yegappan Lakshmanan)
+Files:      src/quickfix.c
+
+Patch 8.0.0585
+Problem:    Test_options fails when run in the GUI.
+Solution:   Also check the 'imactivatekey' value when the GUI is not running.
+            Specify test values that work and that fail.
+Files:      src/option.c, src/testdir/gen_opt_test.vim
+
+Patch 8.0.0586
+Problem:    No test for mapping timing out.
+Solution:   Add a test.
+Files:      src/testdir/test_mapping.vim
+
  vim:tw=78:ts=8:ft=help:norl:
index 3c695e6..fac7381 100644 (file)
@@ -1,4 +1,4 @@
-*windows.txt*   For Vim version 8.0.  Last change: 2016 Oct 21
+*windows.txt*   For Vim version 8.0.  Last change: 2016 Dec 01
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -696,6 +696,8 @@ can also get to them with the buffer list commands, like ":bnext".
                - If the file is not open in a window edit the file in the
                  current window.  If the current buffer can't be |abandon|ed,
                  the window is split first.
+               - Windows that are not in the argument list or are not full
+                 width will be closed if possible.
                The |argument-list| is set, like with the |:next| command.
                The purpose of this command is that it can be used from a
                program that wants Vim to edit another file, e.g., a debugger.
index df8f7fd..3871165 100644 (file)
@@ -1,7 +1,7 @@
 " Vim support file to detect file types
 "
 " Maintainer:  Bram Moolenaar <Bram@vim.org>
-" Last Change: 2016 Oct 31
+" Last Change: 2017 Apr 20
 
 " Listen very carefully, I will say this only once
 if exists("did_load_filetypes")
@@ -288,7 +288,8 @@ au BufNewFile,BufRead *.bib                 setf bib
 au BufNewFile,BufRead *.bst                    setf bst
 
 " BIND configuration
-au BufNewFile,BufRead named.conf,rndc.conf     setf named
+" sudoedit uses namedXXXX.conf
+au BufNewFile,BufRead named*.conf,rndc*.conf   setf named
 
 " BIND zone
 au BufNewFile,BufRead named.root               setf bindzone
@@ -309,7 +310,11 @@ au BufNewFile,BufRead *.bl                 setf blank
 au BufNewFile,BufRead */etc/blkid.tab,*/etc/blkid.tab.old   setf xml
 
 " Bazel (http://bazel.io)
-autocmd BufRead,BufNewFile *.bzl,BUILD,WORKSPACE setfiletype bzl
+autocmd BufRead,BufNewFile *.bzl,WORKSPACE     setf bzl
+if has("fname_case")
+  " There is another check for BUILD further below.
+  autocmd BufRead,BufNewFile BUILD             setf bzl
+endif
 
 " C or lpc
 au BufNewFile,BufRead *.c                      call s:FTlpc()
@@ -673,8 +678,14 @@ au BufNewFile,BufRead *.dtd                        setf dtd
 " DTS/DSTI (device tree files)
 au BufNewFile,BufRead *.dts,*.dtsi             setf dts
 
-" EDIF (*.edf,*.edif,*.edn,*.edo)
-au BufNewFile,BufRead *.ed\(f\|if\|n\|o\)      setf edif
+" EDIF (*.edf,*.edif,*.edn,*.edo) or edn
+au BufNewFile,BufRead *.ed\(f\|if\|o\)         setf edif
+au BufNewFile,BufRead *.edn
+       \ if getline(1) =~ '^\s*(\s*edif\>' |
+       \   setf edif |
+       \ else |
+       \   setf clojure |
+       \ endif
 
 " EditorConfig (close enough to dosini)
 au BufNewFile,BufRead .editorconfig            setf dosini
@@ -1357,6 +1368,9 @@ endfunc
 " Not Quite C
 au BufNewFile,BufRead *.nqc                    setf nqc
 
+" NSE - Nmap Script Engine - uses Lua syntax
+au BufNewFile,BufRead *.nse                    setf lua
+
 " NSIS
 au BufNewFile,BufRead *.nsi,*.nsh              setf nsis
 
@@ -2119,7 +2133,10 @@ au BufNewFile,BufRead ssh_config,*/.ssh/config   setf sshconfig
 au BufNewFile,BufRead sshd_config              setf sshdconfig
 
 " Stata
-au BufNewFile,BufRead *.ado,*.class,*.do,*.imata,*.mata   setf stata
+au BufNewFile,BufRead *.ado,*.do,*.imata,*.mata        setf stata
+" Also *.class, but not when it's a Java bytecode file
+au BufNewFile,BufRead *.class
+       \ if getline(1) !~ "^\xca\xfe\xba\xbe" | setf stata | endif
 
 " SMCL
 au BufNewFile,BufRead *.hlp,*.ihlp,*.smcl      setf smcl
@@ -2271,6 +2288,9 @@ au BufNewFile,BufRead .tidyrc,tidyrc              setf tidy
 " TF mud client
 au BufNewFile,BufRead *.tf,.tfrc,tfrc          setf tf
 
+" tmux configuration
+au BufNewFile,BufRead {.,}tmux*.conf           setf tmux
+
 " TPP - Text Presentation Program
 au BufNewFile,BufReadPost *.tpp                        setf tpp
 
@@ -2586,6 +2606,11 @@ au BufNewFile,BufRead *asterisk*/*voicemail.conf* call s:StarSetf('asteriskvm')
 " Bazaar version control
 au BufNewFile,BufRead bzr_log.*                        setf bzr
 
+" Bazel build file
+if !has("fname_case")
+  au BufNewFile,BufRead BUILD                  setf bzl
+endif
+
 " BIND zone
 au BufNewFile,BufRead */named/db.*,*/bind/db.* call s:StarSetf('bindzone')
 
index 6653351..0e24e30 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         a2ps(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             a2ps(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 5d763c8..6d9d80a 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         alsaconf(8) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             alsaconf(8) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 71d831e..1c697b8 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         GNU Arch inventory file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             GNU Arch inventory file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 20b06af..9f981a7 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         Automake
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             Automake
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
diff --git a/runtime/ftplugin/awk.vim b/runtime/ftplugin/awk.vim
new file mode 100644 (file)
index 0000000..dcefc85
--- /dev/null
@@ -0,0 +1,18 @@
+" Vim filetype plugin
+" Language:    awk, nawk, gawk, mawk
+" Maintainer:  Antonio Colombo <azc100@gmail.com>
+" Last Change: 2017 Feb 17
+
+" This plugin was prepared by Mark Sikora
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Don't load another plugin for this buffer
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl commentstring<"
+
+setlocal commentstring=#\ %s
index 120c5df..85b7b40 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         BDF font definition
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             BDF font definition
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 6f117e3..f454ba1 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         calendar(1) input file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             calendar(1) input file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 557fd82..563bb8f 100644 (file)
@@ -1,6 +1,6 @@
 " Vim filetype plugin file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2007-12-04
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2007-12-04
 
 if exists("b:did_ftplugin")
   finish
index 1b110e4..ff2add1 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         generic configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             generic configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index e86e683..06baee8 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         CRM114
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             CRM114
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 43d1edf..ea44244 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         CSS
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             CSS
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index c410530..34b1484 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         cvs(1) RC file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             cvs(1) RC file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 557fd82..563bb8f 100644 (file)
@@ -1,6 +1,6 @@
 " Vim filetype plugin file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2007-12-04
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2007-12-04
 
 if exists("b:did_ftplugin")
   finish
index 659046c..71a2b67 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         dict(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             dict(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index ee738c5..0ee4c9d 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         dictd(8) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             dictd(8) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 3b3d046..d07d1e3 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         dircolors(1) input file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             dircolors(1) input file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 461403c..0d0f0f8 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         Configuration File (ini file) for MSDOS/MS Windows
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             Configuration File (ini file) for MSDOS/MS Windows
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 7d92575..921f9c2 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         elinks(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             elinks(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index e072c63..e2f88ef 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         eterm(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             eterm(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index a0d4650..33bb417 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         fetchmail(1) RC File
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             fetchmail(1) RC File
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 805401a..48fe0ac 100644 (file)
@@ -1,7 +1,7 @@
 " Vim ftplugin file
-" Language:         FrameScript
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-19
+" Language:             FrameScript
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-19
 
 let s:cpo_save = &cpo
 set cpo&vim
index 5caa1f6..3f890e5 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         gpg(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             gpg(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index eef3cd6..e6b76ba 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         group(5) user group file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             group(5) user group file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 21c4e36..cd6e113 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         grub(8) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             grub(8) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index c23adc4..6c0630f 100644 (file)
@@ -1,8 +1,8 @@
 " Vim filetype plugin
 " Language:    Hamster Script
 " Version:     2.0.6.0
-" Maintainer:  David Fishburn <fishburn@ianywhere.com>
-" Last Change: Wed Nov 08 2006 12:03:09 PM
+" Maintainer:  David Fishburn <dfishburn dot vim at gmail dot com>
+" Last Change: 2017 Mar 18
 
 " Only do this when not done yet for this buffer
 if exists("b:did_ftplugin")
@@ -13,7 +13,7 @@ endif
 let b:did_ftplugin = 1
 
 let s:cpo_save = &cpo
-set cpo-=C
+set cpo&vim
 
 let b:undo_ftplugin = "setl fo< com< tw< commentstring<"
        \ . "| unlet! b:match_ignorecase b:match_words b:match_skip"
index 144f9f6..de77bdf 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         Haskell
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             Haskell
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index a0a0f29..9eb7214 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         Vim help file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             Vim help file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 557fd82..563bb8f 100644 (file)
@@ -1,6 +1,6 @@
 " Vim filetype plugin file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2007-12-04
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2007-12-04
 
 if exists("b:did_ftplugin")
   finish
index a2f55ac..d32485f 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         hosts_access(5) control file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             hosts_access(5) control file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 0e195b0..e6d928a 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         indent(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             indent(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 31ce5c9..1ab80d5 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         ld(1) script
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             ld(1) script
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 9e2eeb5..5bc496c 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         lftp(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             lftp(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 38bd3de..0ce5831 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         libao.conf(5) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             libao.conf(5) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index cd5b7b5..90a10a6 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         limits(5) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             limits(5) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 7c44f97..d27114a 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         login.access(5) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             login.access(5) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 668d08a..7873396 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         login.defs(5) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             login.defs(5) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 0ffe0ac..3745507 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         m4
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             m4
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 1b10c86..0ae4b45 100644 (file)
@@ -1,6 +1,6 @@
 " Vim filetype plugin file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index f4c8c23..ba8573c 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         Mailcap configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             Mailcap configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 6939493..c7fc3bb 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
 " Language:    man
 " Maintainer:  SungHyun Nam <goweol@gmail.com>
-" Last Change:         2016 Jun 20
+" Last Change:         2017 Jan 18
 
 " To make the ":Man" command available before editing a manual page, source
 " this script from your startup vimrc file.
@@ -47,6 +47,7 @@ endif
 if exists(":Man") != 2
   com -nargs=+ Man call s:GetPage(<f-args>)
   nmap <Leader>K :call <SID>PreGetPage(0)<CR>
+  nmap <Plug>ManPreGetPage :call <SID>PreGetPage(0)<CR>
 endif
 
 " Define functions only once.
@@ -96,7 +97,7 @@ func <SID>GetCmdArg(sect, page)
 endfunc
 
 func <SID>FindPage(sect, page)
-  let where = system("/usr/bin/man ".s:man_find_arg.' '.s:GetCmdArg(a:sect, a:page))
+  let where = system("man ".s:man_find_arg.' '.s:GetCmdArg(a:sect, a:page))
   if where !~ "^/"
     if matchstr(where, " [^ ]*$") !~ "^ /"
       return 0
@@ -175,7 +176,7 @@ func <SID>GetPage(...)
     let $MANWIDTH = winwidth(0)
     let unsetwidth = 1
   endif
-  silent exec "r!/usr/bin/man ".s:GetCmdArg(sect, page)." | col -b"
+  silent exec "r !man ".s:GetCmdArg(sect, page)." | col -b"
   if unsetwidth
     let $MANWIDTH = ''
   endif
index a249a97..aa85408 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         man.conf(5) - man configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             man.conf(5) - man configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index f200e9f..c8e76b5 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         modules.conf(5) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             modules.conf(5) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 65034a8..8654760 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         mplayer(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             mplayer(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index a109e5d..c8ad0f2 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         mutt RC File
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             mutt RC File
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:did_ftplugin")
   finish
index be20d12..e45ebac 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         nanorc(5) - GNU nano configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             nanorc(5) - GNU nano configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 105a1d3..02ee327 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         netrc(5) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             netrc(5) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index acc2620..949691b 100644 (file)
@@ -1,7 +1,7 @@
 " Vim ftplugin file
-" Language:         NSIS script
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             NSIS script
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 let s:cpo_save = &cpo
 set cpo&vim
index 96d9646..f0a693e 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         pam(8) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             pam(8) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 5088c43..f6e0f50 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         passwd(5) password file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             passwd(5) password file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 6ec1f87..50473a8 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         pinfo(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             pinfo(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index cc2ceed..d64f192 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         procmail(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             procmail(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index caeb574..f4e7d13 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         Prolog
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             Prolog
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 2486ff9..83856ce 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         protocols(5) - Internet protocols definition file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             protocols(5) - Internet protocols definition file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index f62693b..c3a2e52 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         Quake[1-3] configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             Quake[1-3] configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 7ff22f8..0cd852c 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         Racc input file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             Racc input file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 0a4dbb5..e9ef93e 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         readline(3) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             readline(3) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 2b8fd50..90aa111 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         Relax NG compact syntax
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             Relax NG compact syntax
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index b871cf1..e61213e 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         reStructuredText documentation format
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             reStructuredText documentation format
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
diff --git a/runtime/ftplugin/rust.vim b/runtime/ftplugin/rust.vim
new file mode 100644 (file)
index 0000000..7efca59
--- /dev/null
@@ -0,0 +1,197 @@
+" Language:     Rust
+" Description:  Vim ftplugin for Rust
+" Maintainer:   Chris Morgan <me@chrismorgan.info>
+" Maintainer:   Kevin Ballard <kevin@sb.org>
+" Last Change:  June 08, 2016
+" For bugs, patches and license go to https://github.com/rust-lang/rust.vim 
+
+if exists("b:did_ftplugin")
+       finish
+endif
+let b:did_ftplugin = 1
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+augroup rust.vim
+autocmd!
+
+" Variables {{{1
+
+" The rust source code at present seems to typically omit a leader on /*!
+" comments, so we'll use that as our default, but make it easy to switch.
+" This does not affect indentation at all (I tested it with and without
+" leader), merely whether a leader is inserted by default or not.
+if exists("g:rust_bang_comment_leader") && g:rust_bang_comment_leader != 0
+       " Why is the `,s0:/*,mb:\ ,ex:*/` there, you ask? I don't understand why,
+       " but without it, */ gets indented one space even if there were no
+       " leaders. I'm fairly sure that's a Vim bug.
+       setlocal comments=s1:/*,mb:*,ex:*/,s0:/*,mb:\ ,ex:*/,:///,://!,://
+else
+       setlocal comments=s0:/*!,m:\ ,ex:*/,s1:/*,mb:*,ex:*/,:///,://!,://
+endif
+setlocal commentstring=//%s
+setlocal formatoptions-=t formatoptions+=croqnl
+" j was only added in 7.3.541, so stop complaints about its nonexistence
+silent! setlocal formatoptions+=j
+
+" smartindent will be overridden by indentexpr if filetype indent is on, but
+" otherwise it's better than nothing.
+setlocal smartindent nocindent
+
+if !exists("g:rust_recommended_style") || g:rust_recommended_style != 0
+       setlocal tabstop=4 shiftwidth=4 softtabstop=4 expandtab
+       setlocal textwidth=99
+endif
+
+" This includeexpr isn't perfect, but it's a good start
+setlocal includeexpr=substitute(v:fname,'::','/','g')
+
+setlocal suffixesadd=.rs
+
+if exists("g:ftplugin_rust_source_path")
+    let &l:path=g:ftplugin_rust_source_path . ',' . &l:path
+endif
+
+if exists("g:loaded_delimitMate")
+       if exists("b:delimitMate_excluded_regions")
+               let b:rust_original_delimitMate_excluded_regions = b:delimitMate_excluded_regions
+       endif
+
+       let s:delimitMate_extra_excluded_regions = ',rustLifetimeCandidate,rustGenericLifetimeCandidate'
+
+       " For this buffer, when delimitMate issues the `User delimitMate_map`
+       " event in the autocommand system, add the above-defined extra excluded
+       " regions to delimitMate's state, if they have not already been added.
+       autocmd User <buffer>
+               \ if expand('<afile>') ==# 'delimitMate_map' && match(
+               \     delimitMate#Get("excluded_regions"),
+               \     s:delimitMate_extra_excluded_regions) == -1
+               \|  let b:delimitMate_excluded_regions =
+               \       delimitMate#Get("excluded_regions")
+               \       . s:delimitMate_extra_excluded_regions
+               \|endif
+
+       " For this buffer, when delimitMate issues the `User delimitMate_unmap`
+       " event in the autocommand system, delete the above-defined extra excluded
+       " regions from delimitMate's state (the deletion being idempotent and
+       " having no effect if the extra excluded regions are not present in the
+       " targeted part of delimitMate's state).
+       autocmd User <buffer>
+               \ if expand('<afile>') ==# 'delimitMate_unmap'
+               \|  let b:delimitMate_excluded_regions = substitute(
+               \       delimitMate#Get("excluded_regions"),
+               \       '\C\V' . s:delimitMate_extra_excluded_regions,
+               \       '', 'g')
+               \|endif
+endif
+
+if has("folding") && exists('g:rust_fold') && g:rust_fold != 0
+       let b:rust_set_foldmethod=1
+       setlocal foldmethod=syntax
+       if g:rust_fold == 2
+               setlocal foldlevel<
+       else
+               setlocal foldlevel=99
+       endif
+endif
+
+if has('conceal') && exists('g:rust_conceal') && g:rust_conceal != 0
+       let b:rust_set_conceallevel=1
+       setlocal conceallevel=2
+endif
+
+" Motion Commands {{{1
+
+" Bind motion commands to support hanging indents
+nnoremap <silent> <buffer> [[ :call rust#Jump('n', 'Back')<CR>
+nnoremap <silent> <buffer> ]] :call rust#Jump('n', 'Forward')<CR>
+xnoremap <silent> <buffer> [[ :call rust#Jump('v', 'Back')<CR>
+xnoremap <silent> <buffer> ]] :call rust#Jump('v', 'Forward')<CR>
+onoremap <silent> <buffer> [[ :call rust#Jump('o', 'Back')<CR>
+onoremap <silent> <buffer> ]] :call rust#Jump('o', 'Forward')<CR>
+
+" Commands {{{1
+
+" See |:RustRun| for docs
+command! -nargs=* -complete=file -bang -buffer RustRun call rust#Run(<bang>0, <q-args>)
+
+" See |:RustExpand| for docs
+command! -nargs=* -complete=customlist,rust#CompleteExpand -bang -buffer RustExpand call rust#Expand(<bang>0, <q-args>)
+
+" See |:RustEmitIr| for docs
+command! -nargs=* -buffer RustEmitIr call rust#Emit("llvm-ir", <q-args>)
+
+" See |:RustEmitAsm| for docs
+command! -nargs=* -buffer RustEmitAsm call rust#Emit("asm", <q-args>)
+
+" See |:RustPlay| for docs
+command! -range=% RustPlay :call rust#Play(<count>, <line1>, <line2>, <f-args>)
+
+" See |:RustFmt| for docs
+command! -buffer RustFmt call rustfmt#Format()
+
+" See |:RustFmtRange| for docs
+command! -range -buffer RustFmtRange call rustfmt#FormatRange(<line1>, <line2>)
+
+" Mappings {{{1
+
+" Bind ⌘R in MacVim to :RustRun
+nnoremap <silent> <buffer> <D-r> :RustRun<CR>
+" Bind ⌘⇧R in MacVim to :RustRun! pre-filled with the last args
+nnoremap <buffer> <D-R> :RustRun! <C-r>=join(b:rust_last_rustc_args)<CR><C-\>erust#AppendCmdLine(' -- ' . join(b:rust_last_args))<CR>
+
+if !exists("b:rust_last_rustc_args") || !exists("b:rust_last_args")
+       let b:rust_last_rustc_args = []
+       let b:rust_last_args = []
+endif
+
+" Cleanup {{{1
+
+let b:undo_ftplugin = "
+               \ setlocal formatoptions< comments< commentstring< includeexpr< suffixesadd<
+               \|setlocal tabstop< shiftwidth< softtabstop< expandtab< textwidth<
+               \|if exists('b:rust_original_delimitMate_excluded_regions')
+                 \|let b:delimitMate_excluded_regions = b:rust_original_delimitMate_excluded_regions
+                 \|unlet b:rust_original_delimitMate_excluded_regions
+               \|else
+                 \|unlet! b:delimitMate_excluded_regions
+               \|endif
+               \|if exists('b:rust_set_foldmethod')
+                 \|setlocal foldmethod< foldlevel<
+                 \|unlet b:rust_set_foldmethod
+               \|endif
+               \|if exists('b:rust_set_conceallevel')
+                 \|setlocal conceallevel<
+                 \|unlet b:rust_set_conceallevel
+               \|endif
+               \|unlet! b:rust_last_rustc_args b:rust_last_args
+               \|delcommand RustRun
+               \|delcommand RustExpand
+               \|delcommand RustEmitIr
+               \|delcommand RustEmitAsm
+               \|delcommand RustPlay
+               \|nunmap <buffer> <D-r>
+               \|nunmap <buffer> <D-R>
+               \|nunmap <buffer> [[
+               \|nunmap <buffer> ]]
+               \|xunmap <buffer> [[
+               \|xunmap <buffer> ]]
+               \|ounmap <buffer> [[
+               \|ounmap <buffer> ]]
+               \|set matchpairs-=<:>
+               \"
+
+" }}}1
+
+" Code formatting on save
+if get(g:, "rustfmt_autosave", 0)
+       autocmd BufWritePre *.rs silent! call rustfmt#Format()
+endif
+
+augroup END
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+" vim: set noet sw=8 ts=8:
index 95c3849..c22089b 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         screen(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             screen(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 813d14c..c02a729 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         sensors.conf(5) - libsensors configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             sensors.conf(5) - libsensors configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index d34349e..dda08ac 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         services(5) - Internet network services list
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             services(5) - Internet network services list
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index f9d5945..e5823f4 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         setserial(8) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             setserial(8) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 9a8759c..3092b5d 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         Sieve filtering language input file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             Sieve filtering language input file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 0c45689..a975a49 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         RFC 2614 - An API for Service Location configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             RFC 2614 - An API for Service Location configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index e9d533e..74c7285 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         RFC 2614 - An API for Service Location registration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             RFC 2614 - An API for Service Location registration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 8d64d47..633555e 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         RFC 2614 - An API for Service Location SPI file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             RFC 2614 - An API for Service Location SPI file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index c2bc857..4d6fcd9 100644 (file)
@@ -1,8 +1,8 @@
 " SQL filetype plugin file
 " Language:    SQL (Common for Oracle, Microsoft SQL Server, Sybase)
-" Version:     11.0
+" Version:     12.0
 " Maintainer:  David Fishburn <dfishburn dot vim at gmail dot com>
-" Last Change: 2013 May 13
+" Last Change: 2017 Mar 07
 " Download:    http://vim.sourceforge.net/script.php?script_id=454
 
 " For more details please use:
 "
 " History
 "
+" Version 12.0 (April 2013)
+"
+" NF: Added support for "BEGIN TRY ... END TRY ... BEGIN CATCH ... END CATCH
+" BF: This plugin is designed to be used with other plugins to enable the 
+"     SQL completion with Perl, Python, Java, ...  The loading mechanism 
+"     was not checking if the SQL objects were created, which can lead to 
+"     the plugin not loading the SQL support.
+"
 " Version 11.0 (May 2013)
 "
 " NF: Updated to use SyntaxComplete's new regex support for syntax groups.
 
 
 " Only do this when not done yet for this buffer
-if exists("b:did_ftplugin")
-  finish
+" This ftplugin can be used with other ftplugins.  So ensure loading
+" happens if all elements of this plugin have not yet loaded.
+if exists("b:did_ftplugin") && exists("b:current_ftplugin") && b:current_ftplugin == 'sql'
+    finish
 endif
 
 let s:save_cpo = &cpo
 set cpo&vim
 
 " Disable autowrapping for code, but enable for comments
-" t    Auto-wrap text using textwidth
+" t     Auto-wrap text using textwidth
 " c     Auto-wrap comments using textwidth, inserting the current comment
 "       leader automatically.
 setlocal formatoptions-=t
@@ -171,6 +181,9 @@ if !exists("*SQL_SetType")
         if exists("b:current_syntax")
             " echomsg 'SQLSetType - clearing syntax'
             syntax clear
+            if exists("b:current_syntax")
+                unlet b:current_syntax
+            endif
         endif
         if exists("b:did_indent")
             " echomsg 'SQLSetType - clearing indent'
@@ -187,7 +200,7 @@ if !exists("*SQL_SetType")
         " Do not specify a buffer local variable if it is
         " the default value
         if new_sql_type == 'sql'
-          let new_sql_type = 'sqloracle'
+            let new_sql_type = 'sqloracle'
         endif
         let b:sql_type_override = new_sql_type
 
@@ -234,25 +247,26 @@ if exists("b:sql_type_override")
     " echo 'sourcing buffer ftplugin/'.b:sql_type_override.'.vim'
     if globpath(&runtimepath, 'ftplugin/'.b:sql_type_override.'.vim') != ''
         exec 'runtime ftplugin/'.b:sql_type_override.'.vim'
-    " else
-    "     echomsg 'ftplugin/'.b:sql_type_override.' not exist, using default'
+        " else
+        "     echomsg 'ftplugin/'.b:sql_type_override.' not exist, using default'
     endif
 elseif exists("g:sql_type_default")
     " echo 'sourcing global ftplugin/'.g:sql_type_default.'.vim'
     if globpath(&runtimepath, 'ftplugin/'.g:sql_type_default.'.vim') != ''
         exec 'runtime ftplugin/'.g:sql_type_default.'.vim'
-    " else
-    "     echomsg 'ftplugin/'.g:sql_type_default.'.vim not exist, using default'
+        " else
+        "     echomsg 'ftplugin/'.g:sql_type_default.'.vim not exist, using default'
     endif
 endif
 
 " If the above runtime command succeeded, do not load the default settings
-if exists("b:did_ftplugin")
-  finish
+" as they should have already been loaded from a previous run.
+if exists("b:did_ftplugin") && exists("b:current_ftplugin") && b:current_ftplugin == 'sql'
+    finish
 endif
 
 let b:undo_ftplugin = "setl comments< formatoptions< define< omnifunc<" .
-                   \ " | unlet! b:browsefilter b:match_words"
+            \ " | unlet! b:browsefilter b:match_words"
 
 " Don't load another plugin for this buffer
 let b:did_ftplugin     = 1
@@ -261,7 +275,7 @@ let b:current_ftplugin = 'sql'
 " Win32 can filter files in the browse dialog
 if has("gui_win32") && !exists("b:browsefilter")
     let b:browsefilter = "SQL Files (*.sql)\t*.sql\n" .
-         \ "All Files (*.*)\t*.*\n"
+                \ "All Files (*.*)\t*.*\n"
 endif
 
 " Some standard expressions for use with the matchit strings
@@ -312,14 +326,24 @@ if !exists("b:match_words")
     " WHEN column_not_found THEN
     " WHEN OTHERS THEN
     "
+    " begin try
+    " end try
+    " begin catch
+    " end catch
+    "
     " create[ or replace] procedure|function|event
-                " \ '^\s*\<\%(do\|for\|while\|loop\)\>.*:'.
+    " \ '^\s*\<\%(do\|for\|while\|loop\)\>.*:'.
 
     " For ColdFusion support
     setlocal matchpairs+=<:>
     let b:match_words = &matchpairs .
-               \ ',\<begin\>:\<end\>\W*$,'.
-               \
+                \ ',\%(\<begin\)\%(\s\+\%(try\|catch\)\>\)\@!:\<end\>\W*$,'.
+                \
+                \ '\<begin\s\+try\>:'.
+                \ '\<end\s\+try\>:'.
+                \ '\<begin\s\+catch\>:'.
+                \ '\<end\s\+catch\>,'.
+                \
                 \ s:notend . '\<if\>:'.
                 \ '\<elsif\>\|\<elseif\>\|\<else\>:'.
                 \ '\<end\s\+if\>,'.
@@ -339,14 +363,14 @@ if !exists("b:match_words")
                 \ '\%(\<create\s\+' . s:or_replace . '\)\?'.
                 \ '\%(function\|procedure\|event\):'.
                 \ '\<returns\?\>'
-                " \ '\<begin\>\|\<returns\?\>:'.
-                " \ '\<end\>\(;\)\?\s*$'
-                " \ '\<exception\>:'.s:when_no_matched_or_others.
-                " \ ':\<when\s\+others\>,'.
-               "
-                " \ '\%(\<exception\>\|\%('. s:notend . '\<case\>\)\):'.
-                " \ '\%(\<default\>\|'.s:when_no_matched_or_others.'\):'.
-                " \ '\%(\%(\<when\s\+others\>\)\|\<end\s\+case\>\),' .
+    " \ '\<begin\>\|\<returns\?\>:'.
+    " \ '\<end\>\(;\)\?\s*$'
+    " \ '\<exception\>:'.s:when_no_matched_or_others.
+    " \ ':\<when\s\+others\>,'.
+    "
+    " \ '\%(\<exception\>\|\%('. s:notend . '\<case\>\)\):'.
+    " \ '\%(\<default\>\|'.s:when_no_matched_or_others.'\):'.
+    " \ '\%(\%(\<when\s\+others\>\)\|\<end\s\+case\>\),' .
 endif
 
 " Define how to find the macro definition of a variable using the various
index f940af9..d933ce0 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         OpenSSH client configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             OpenSSH client configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 5756302..38dbf55 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         sudoers(5) configuration files
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             sudoers(5) configuration files
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index fb1098d..8d331ce 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         sysctl.conf(5) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             sysctl.conf(5) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 7ce31d1..0ffcc58 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         terminfo(5) definition
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             terminfo(5) definition
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
diff --git a/runtime/ftplugin/tmux.vim b/runtime/ftplugin/tmux.vim
new file mode 100644 (file)
index 0000000..ed91549
--- /dev/null
@@ -0,0 +1,12 @@
+" Vim filetype plugin file
+" Language:    tmux(1) configuration file
+" URL:                 https://github.com/ericpruitt/tmux.vim/
+" Maintainer:  Eric Pruitt <eric.pruitt@gmail.com>
+" Last Changed: 2017 Mar 10
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+setlocal commentstring=#\ %s
index 2da3c40..f978d15 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         Treetop
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2011-03-14
+" Language:             Treetop
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2011-03-14
 
 if exists("b:did_ftplugin")
   finish
index 6042e14..0bbd86a 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         udev(8) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             udev(8) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index e7ad31d..f8fb4d4 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         udev(8) permissions file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             udev(8) permissions file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index be8d646..6404f6c 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         udev(8) rules file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             udev(8) rules file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index f4e7bce..3015918 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         updatedb.conf(5) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             updatedb.conf(5) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index cd85182..c1aff70 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         X resources files like ~/.Xdefaults (xrdb)
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             X resources files like ~/.Xdefaults (xrdb)
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index ab7569a..5a21539 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         XFree86 Configuration File
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             XFree86 Configuration File
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index f209af1..2b7b64e 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         xinetd.conf(5) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             xinetd.conf(5) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 027ae09..77fccd5 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         xmodmap(1) definition file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             xmodmap(1) definition file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index b88803a..ceff36f 100644 (file)
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:         YAML (YAML Ain't Markup Language)
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-09
+" Language:             YAML (YAML Ain't Markup Language)
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-09
 
 if exists("b:did_ftplugin")
   finish
index 5fbc222..7e38f92 100644 (file)
@@ -1,7 +1,7 @@
 " Vim indent file
-" Language:        automake
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:                automake
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:did_indent")
   finish
index 7eb1657..074f467 100644 (file)
@@ -1,8 +1,8 @@
 " Vim indent file
-" Language:         Autoconf configure.{ac,in} file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-12-20
-" TODO:             how about nested [()]'s in one line
+" 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 '\\\@!'?
 
 " Only load this indent file when no other was loaded.
index f0a272e..4d15b8d 100644 (file)
@@ -2,6 +2,7 @@
 " Language:        CSS
 " Maintainer:      Nikolai Weibull <now@bitwi.se>
 " Latest Revision:  2012-05-30
+"                  Use of shiftwidth() added by Oleg Zubchenko.        
 
 if exists("b:did_indent")
   finish
@@ -75,8 +76,8 @@ function GetCSSIndent()
     return 0
   endif
 
-  return indent(pnum) + s:count_braces(pnum, 1) * &sw
-        \ - s:count_braces(v:lnum, 0) * &sw
+  return indent(pnum) + s:count_braces(pnum, 1) * shiftwidth()
+        \ - s:count_braces(v:lnum, 0) * shiftwidth()
 endfunction
 
 let &cpo = s:keepcpo
index adbc1a5..2e15c76 100644 (file)
@@ -1,7 +1,7 @@
 " Vim indent file
-" Language:         dict(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-12-20
+" Language:             dict(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-12-20
 
 if exists("b:did_indent")
   finish
index 9427342..5c4fbda 100644 (file)
@@ -1,7 +1,7 @@
 " Vim indent file
-" Language:         dictd(8) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-12-20
+" Language:             dictd(8) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-12-20
 
 if exists("b:did_indent")
   finish
index 3fde2a1..d8661ff 100644 (file)
@@ -1,7 +1,7 @@
 " Vim indent file
-" Language:        DocBook Documentation Format
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:                DocBook Documentation Format
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:did_indent")
   finish
index 88c0c51..5633362 100644 (file)
@@ -1,7 +1,7 @@
 " Vim indent file
-" Language:        DTD (Document Type Definition for XML)
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2011-07-08
+" Language:                DTD (Document Type Definition for XML)
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2011-07-08
 
 let s:cpo_save = &cpo
 set cpo&vim
@@ -84,7 +84,7 @@ function GetDTDIndent()
 
   let [declaration, end] = s:lex1(line, col)
   if declaration == ""
-    return indent + &sw
+    return indent + shiftwidth()
   elseif declaration == '--'
     " We’re looking at a comment.  Now, simply determine if the comment is
     " terminated or not.  If it isn’t, let Vim take care of that using
@@ -100,7 +100,7 @@ function GetDTDIndent()
     " Check for element name.  If none exists, indent one level.
     let [name, end] = s:lex(line, end)
     if name == ""
-      return indent + &sw
+      return indent + shiftwidth()
     endif
 
     " Check for token following element name.  This can be a specification of
@@ -113,7 +113,7 @@ function GetDTDIndent()
       let n += 1
     endwhile
     if token == ""
-      return indent + &sw
+      return indent + shiftwidth()
     endif
 
     " Next comes the content model.  If the token we’ve found isn’t a
@@ -148,7 +148,7 @@ function GetDTDIndent()
           return indent
         endif
         " TODO: Should use s:lex here on getline(v:lnum) and check for >.
-        return getline(v:lnum) =~ '^\s*>' || count(values(seen), 0) == 0 ? indent : (indent + &sw)
+        return getline(v:lnum) =~ '^\s*>' || count(values(seen), 0) == 0 ? indent : (indent + shiftwidth())
       endif
 
       " If we’ve seen an addition or exception already and this is of the same
@@ -167,7 +167,7 @@ function GetDTDIndent()
     " Check for element name.  If none exists, indent one level.
     let [name, end] = s:lex(line, end)
     if name == ""
-      return indent + &sw
+      return indent + shiftwidth()
     endif
 
     " Check for any number of attributes.
@@ -180,7 +180,7 @@ function GetDTDIndent()
       let [name, end] = s:lex(line, end)
       if name == ""
         " TODO: Should use s:lex here on getline(v:lnum) and check for >.
-        return getline(v:lnum) =~ '^\s*>' ? indent : (indent + &sw)
+        return getline(v:lnum) =~ '^\s*>' ? indent : (indent + shiftwidth())
       elseif name == ">"
         return indent
       endif
@@ -194,14 +194,14 @@ function GetDTDIndent()
       " (CDATA|NMTOKEN|NMTOKENS|ID|IDREF|IDREFS|ENTITY|ENTITIES)?
       let [value, end] = s:lex(line, end, '^\%((\|[^[:space:]]\+\)')
       if value == ""
-        return indent + &sw * 2
+        return indent + shiftwidth() * 2
       elseif value == 'NOTATION'
         " If this is a enumerated value based on notations, read another token
         " for the actual value.  If it doesn’t exist, indent three levels.
         " TODO: If validating according to above, value must be equal to '('.
         let [value, end] = s:lex(line, end, '^\%((\|[^[:space:]]\+\)')
         if value == ""
-          return indent + &sw * 3
+          return indent + shiftwidth() * 3
         endif
       endif
 
@@ -216,13 +216,13 @@ function GetDTDIndent()
       " two levels.
       let [default, end] = s:lex(line, end, '^\%("\_[^"]*"\|#\(REQUIRED\|IMPLIED\|FIXED\)\)')
       if default == ""
-        return indent + &sw * 2
+        return indent + shiftwidth() * 2
       elseif default == '#FIXED'
         " We need to look for the fixed value.  If non exists, indent three
         " levels.
         let [default, end] = s:lex(line, end, '^"\_[^"]*"')
         if default == ""
-          return indent + &sw * 3
+          return indent + shiftwidth() * 3
         endif
       endif
     endwhile
@@ -233,11 +233,11 @@ function GetDTDIndent()
     " again, if none exists, indent one level.
     let [name, end] = s:lex(line, end)
     if name == ""
-      return indent + &sw
+      return indent + shiftwidth()
     elseif name == '%'
       let [name, end] = s:lex(line, end)
       if name == ""
-        return indent + &sw
+        return indent + shiftwidth()
       endif
     endif
 
@@ -256,27 +256,27 @@ function GetDTDIndent()
     " we’re now done with this entity.
     let [value, end] = s:lex(line, end)
     if value == ""
-      return indent + &sw
+      return indent + shiftwidth()
     elseif value == 'SYSTEM' || value == 'PUBLIC'
       let [quoted_string, end] = s:lex(line, end, '\%("[^"]\+"\|''[^'']\+''\)')
       if quoted_string == ""
-        return indent + &sw * 2
+        return indent + shiftwidth() * 2
       endif
 
       if value == 'PUBLIC'
         let [quoted_string, end] = s:lex(line, end, '\%("[^"]\+"\|''[^'']\+''\)')
         if quoted_string == ""
-          return indent + &sw * 2
+          return indent + shiftwidth() * 2
         endif
       endif
 
       let [ndata, end] = s:lex(line, end)
       if ndata == ""
-        return indent + &sw
+        return indent + shiftwidth()
       endif
 
       let [name, end] = s:lex(line, end)
-      return name == "" ? (indent + &sw * 2) : indent
+      return name == "" ? (indent + shiftwidth() * 2) : indent
     else
       return indent
     endif
@@ -284,24 +284,24 @@ function GetDTDIndent()
     " Check for notation name.  If none exists, indent one level.
     let [name, end] = s:lex(line, end)
     if name == ""
-      return indent + &sw
+      return indent + shiftwidth()
     endif
 
     " Now check for the external ID.  If none exists, indent one level.
     let [id, end] = s:lex(line, end)
     if id == ""
-      return indent + &sw
+      return indent + shiftwidth()
     elseif id == 'SYSTEM' || id == 'PUBLIC'
       let [quoted_string, end] = s:lex(line, end, '\%("[^"]\+"\|''[^'']\+''\)')
       if quoted_string == ""
-        return indent + &sw * 2
+        return indent + shiftwidth() * 2
       endif
 
       if id == 'PUBLIC'
         let [quoted_string, end] = s:lex(line, end, '\%("[^"]\+"\|''[^'']\+''\|>\)')
         if quoted_string == ""
           " TODO: Should use s:lex here on getline(v:lnum) and check for >.
-          return getline(v:lnum) =~ '^\s*>' ? indent : (indent + &sw * 2)
+          return getline(v:lnum) =~ '^\s*>' ? indent : (indent + shiftwidth() * 2)
         elseif quoted_string == '>'
           return indent
         endif
index 87e82e8..d7667a8 100644 (file)
@@ -2,9 +2,10 @@
 " Language:    Eiffel
 " Maintainer:  Jocelyn Fiat <jfiat@eiffel.com>
 " Previous-Maintainer: David Clarke <gadicath@dishevelled.net>
+" Contributions from: Takuya Fujiwara
 " Contributions from: Thilo Six
-" $Date: 2004/12/09 21:33:52 $
-" $Revision: 1.3 $
+" $Date: 2017/03/08 06:00:00 $
+" $Revision: 1.4 $
 " URL: https://github.com/eiffelhub/vim-eiffel
 
 " Only load this indent file when no other was loaded.
@@ -28,7 +29,7 @@ let b:undo_indent = "setl smartindent< indentkeys< indentexpr< autoindent< comme
 " Define some stuff
 " keywords grouped by indenting
 let s:trust_user_indent = '\(+\)\(\s*\(--\).*\)\=$'
-let s:relative_indent = '^\s*\(deferred\|class\|feature\|creation\|inherit\|loop\|from\|until\|if\|else\|elseif\|ensure\|require\|check\|do\|local\|invariant\|variant\|rename\|redefine\|do\|export\)\>'
+let s:relative_indent = '^\s*\(deferred\|class\|feature\|creation\|inherit\|loop\|from\|across\|until\|if\|else\|elseif\|ensure\|require\|check\|do\|local\|invariant\|variant\|rename\|redefine\|do\|export\)\>'
 let s:outdent = '^\s*\(else\|invariant\|variant\|do\|require\|until\|loop\|local\)\>'
 let s:no_indent = '^\s*\(class\|feature\|creation\|inherit\)\>'
 let s:single_dent = '^[^-]\+[[:alnum:]]\+ is\(\s*\(--\).*\)\=$'
@@ -63,23 +64,23 @@ function GetEiffelIndent()
   " Add a 'shiftwidth' after lines that start with an indent word
   let ind = indent(lnum)
   if getline(lnum) =~ s:relative_indent
-    let ind = ind + &sw
+    let ind = ind + shiftwidth()
   endif
 
   " Indent to single indent
   if getline(v:lnum) =~ s:single_dent && getline(v:lnum) !~ s:relative_indent
           \ && getline(v:lnum) !~ '\s*\<\(and\|or\|implies\)\>'
-     let ind = &sw
+     let ind = shiftwidth()
   endif
 
   " Indent to double indent
   if getline(v:lnum) =~ s:inheritance_dent
-     let ind = 2 * &sw
+     let ind = 2 * shiftwidth()
   endif
 
   " Indent line after the first line of the function definition
   if getline(lnum) =~ s:single_dent
-     let ind = ind + &sw
+     let ind = ind + shiftwidth()
   endif
 
   " The following should always be at the start of a line, no indenting
@@ -91,17 +92,17 @@ function GetEiffelIndent()
   " or first thing after the 'do'
   if getline(v:lnum) =~ s:outdent && getline(v:lnum - 1) !~ s:single_dent
        \ && getline(v:lnum - 1) !~ '^\s*do\>'
-    let ind = ind - &sw
+    let ind = ind - shiftwidth()
   endif
 
   " Subtract a shiftwidth for end statements
   if getline(v:lnum) =~ '^\s*end\>'
-    let ind = ind - &sw
+    let ind = ind - shiftwidth()
   endif
 
   " set indent of zero end statements that are at an indent of 3, this should
   " only ever be the class's end.
-  if getline(v:lnum) =~ '^\s*end\>' && ind == &sw
+  if getline(v:lnum) =~ '^\s*end\>' && ind == shiftwidth()
     let ind = 0
   endif
 
index f25f5f4..8ee342f 100644 (file)
@@ -1,7 +1,7 @@
 " Vim indent file
-" Language:         Eterm configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-12-20
+" Language:             Eterm configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-12-20
 
 if exists("b:did_indent")
   finish
@@ -25,11 +25,11 @@ function GetEtermIndent()
   let ind = indent(lnum)
 
   if getline(lnum) =~ '^\s*begin\>'
-    let ind = ind + &sw
+    let ind = ind + shiftwidth()
   endif
 
   if getline(v:lnum) =~ '^\s*end\>'
-    let ind = ind - &sw
+    let ind = ind - shiftwidth()
   endif
 
   return ind
index c9bee78..2ba69e8 100644 (file)
@@ -1,7 +1,7 @@
 " Vim indent file
 " Language:    Fortran 2008 (and older: Fortran 2003, 95, 90, and 77)
-" Version:     0.46
-" Last Change: 2016 Sep. 27
+" Version:     47
+" Last Change: 2016 Oct. 29
 " Maintainer:  Ajit J. Thakkar <ajit@unb.ca>; <http://www2.unb.ca/~ajit/>
 " Usage:       For instructions, do :help fortran-indent from Vim
 " Credits:
@@ -100,9 +100,9 @@ function FortranGetIndent(lnum)
     endif
   endif
 
-  "Add a shiftwidth to statements following if, else, else if, case,
+  "Add a shiftwidth to statements following if, else, else if, case, class,
   "where, else where, forall, type, interface and associate statements
-  if prevstat =~? '^\s*\(case\|else\|else\s*if\|else\s*where\)\>'
+  if prevstat =~? '^\s*\(case\|class\|else\|else\s*if\|else\s*where\)\>'
        \ ||prevstat=~? '^\s*\(type\|interface\|associate\|enum\)\>'
        \ ||prevstat=~?'^\s*\(\d\+\s\)\=\s*\(\a\w*\s*:\)\=\s*\(forall\|where\|block\)\>'
        \ ||prevstat=~? '^\s*\(\d\+\s\)\=\s*\(\a\w*\s*:\)\=\s*if\>'
@@ -136,11 +136,11 @@ function FortranGetIndent(lnum)
     endif
   endif
 
-  "Subtract a shiftwidth from else, else if, elsewhere, case, end if,
+  "Subtract a shiftwidth from else, else if, elsewhere, case, class, end if,
   " end where, end select, end forall, end interface, end associate,
   " end enum, end type, end block and end type statements
   if getline(v:lnum) =~? '^\s*\(\d\+\s\)\=\s*'
-        \. '\(else\|else\s*if\|else\s*where\|case\|'
+        \. '\(else\|else\s*if\|else\s*where\|case\|class\|'
         \. 'end\s*\(if\|where\|select\|interface\|'
         \. 'type\|forall\|associate\|enum\|block\)\)\>'
     let ind = ind - shiftwidth()
index 49ff92a..f9a274e 100644 (file)
@@ -1,7 +1,7 @@
 " Vim indent file
-" Language:         FrameScript
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-07-19
+" Language:             FrameScript
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-07-19
 
 if exists("b:did_indent")
   finish
@@ -30,11 +30,11 @@ function GetFrameScriptIndent()
   let ind = indent(lnum)
 
   if getline(lnum) =~? '^\s*\%(If\|Loop\|Sub\)'
-    let ind = ind + &sw
+    let ind = ind + shiftwidth()
   endif
 
   if getline(v:lnum) =~? '^\s*\%(Else\|End\%(If\|Loop\|Sub\)\)'
-    let ind = ind - &sw
+    let ind = ind - shiftwidth()
   endif
 
   return ind
index 13adaae..57ba53e 100644 (file)
@@ -2,7 +2,7 @@
 " Header: "{{{
 " Maintainer:  Bram Moolenaar
 " Original Author: Andy Wokula <anwoku@yahoo.de>
-" Last Change: 2016 Mar 30
+" Last Change: 2017 Jan 17
 " Version:     1.0
 " Description: HTML indent script with cached state for faster indenting on a
 "              range of lines.
 if exists("b:did_indent") "{{{
   finish
 endif
+
+" Load the Javascript indent script first, it defines GetJavascriptIndent().
+" Undo the rest.
+" Load base python indent.
+if !exists('*GetJavascriptIndent')
+  runtime! indent/javascript.vim
+endif
 let b:did_indent = 1
 
 setlocal indentexpr=HtmlIndent()
 setlocal indentkeys=o,O,<Return>,<>>,{,},!^F
 
-" "j1" is included to make cindent() work better with Javascript.
-setlocal cino=j1
-" "J1" should be included, but it doen't work properly before 7.4.355.
-if has("patch-7.4.355")
-  setlocal cino+=J1
-endif
-" Before patch 7.4.355 indenting after "(function() {" does not work well, add
-" )2 to limit paren search.
-if !has("patch-7.4.355")
-  setlocal cino+=)2
-endif
-
 " Needed for % to work when finding start/end of a tag.
 setlocal matchpairs+=<:>
 
-let b:undo_indent = "setlocal inde< indk< cino<"
+let b:undo_indent = "setlocal inde< indk<"
 
 " b:hi_indent keeps state to speed up indenting consecutive lines.
 let b:hi_indent = {"lnum": -1}
@@ -596,7 +591,7 @@ func! s:Alien3()
     return eval(b:hi_js1indent)
   endif
   if b:hi_indent.scripttype == "javascript"
-    return cindent(v:lnum)
+    return GetJavascriptIndent()
   else
     return -1
   endif
index e0aec0f..49f8010 100644 (file)
@@ -1,12 +1,14 @@
 " Vim indent file
 " Language:    Java
 " Previous Maintainer: Toby Allsopp <toby.allsopp@peace.com>
-" Current Maintainer: Hong Xu <xuhdev@gmail.com>
-" Last Change: 2012 May 18
-" Version: 1.0
+" Current Maintainer: Hong Xu <hong@topbug.net>
+" Homepage: http://www.vim.org/scripts/script.php?script_id=3899
+"           https://github.com/xuhdev/indent-java.vim
+" Last Change: 2016 Mar 7
+" Version: 1.1
 " License: Same as Vim.
-" Copyright (c) 2012 Hong Xu
-" Before 2012, this file is maintained by Toby Allsopp.
+" Copyright (c) 2012-2016 Hong Xu
+" Before 2012, this file was maintained by Toby Allsopp.
 
 " Only load this indent file when no other was loaded.
 if exists("b:did_indent")
@@ -29,6 +31,7 @@ let b:undo_indent = "set cin< cino< indentkeys< indentexpr<"
 if exists("*GetJavaIndent")
   finish
 endif
+
 let s:keepcpo= &cpo
 set cpo&vim
 
@@ -70,7 +73,7 @@ function GetJavaIndent()
 
   " If the previous line starts with '@', we should have the same indent as
   " the previous one
-  if getline(lnum) =~ '^\s*@\S\+\s*$'
+  if getline(lnum) =~ '^\s*@.*$'
     return indent(lnum)
   endif
 
@@ -85,9 +88,9 @@ function GetJavaIndent()
 
   " Try to align "throws" lines for methods and "extends" and "implements" for
   " classes.
-  if getline(v:lnum) =~ '^\s*\(extends\|implements\)\>'
-        \ && getline(lnum) !~ '^\s*\(extends\|implements\)\>'
-    let theIndent = theIndent + &sw
+  if getline(v:lnum) =~ '^\s*\(throws\|extends\|implements\)\>'
+        \ && getline(lnum) !~ '^\s*\(throws\|extends\|implements\)\>'
+    let theIndent = theIndent + shiftwidth()
   endif
 
   " correct for continuation lines of "throws", "implements" and "extends"
@@ -96,27 +99,27 @@ function GetJavaIndent()
   if strlen(cont_kw) > 0
     let amount = strlen(cont_kw) + 1
     if getline(lnum) !~ ',\s*$'
-      let theIndent = theIndent - (amount + &sw)
+      let theIndent = theIndent - (amount + shiftwidth())
       if theIndent < 0
         let theIndent = 0
       endif
     elseif prev == lnum
       let theIndent = theIndent + amount
       if cont_kw ==# 'throws'
-        let theIndent = theIndent + &sw
+        let theIndent = theIndent + shiftwidth()
       endif
     endif
   elseif getline(prev) =~ '^\s*\(throws\|implements\|extends\)\>'
         \ && (getline(prev) =~ '{\s*$'
         \  || getline(v:lnum) =~ '^\s*{\s*$')
-    let theIndent = theIndent - &sw
+    let theIndent = theIndent - shiftwidth()
   endif
 
   " When the line starts with a }, try aligning it with the matching {,
   " skipping over "throws", "extends" and "implements" clauses.
   if getline(v:lnum) =~ '^\s*}\s*\(//.*\|/\*.*\)\=$'
     call cursor(v:lnum, 1)
-    silent normal %
+    silent normal! %
     let lnum = line('.')
     if lnum < v:lnum
       while lnum > 1
index 0d6c11d..304c0fe 100644 (file)
@@ -2,7 +2,7 @@
 " Language: Javascript
 " Maintainer: Chris Paul ( https://github.com/bounceme )
 " URL: https://github.com/pangloss/vim-javascript
-" Last Change: August 25, 2016
+" Last Change: March 21, 2017
 
 " Only load this indent file when no other was loaded.
 if exists('b:did_indent')
@@ -12,11 +12,14 @@ let b:did_indent = 1
 
 " Now, set up our indentation expression and keys that trigger it.
 setlocal indentexpr=GetJavascriptIndent()
-setlocal nolisp noautoindent nosmartindent
-setlocal indentkeys=0{,0},0),0],:,!^F,o,O,e
-setlocal cinoptions+=j1,J1
+setlocal autoindent nolisp nosmartindent
+setlocal indentkeys+=0],0)
+" Testable with something like:
+" vim  -eNs "+filetype plugin indent on" "+syntax on" "+set ft=javascript" \
+"       "+norm! gg=G" '+%print' '+:q!' testfile.js \
+"       | diff -uBZ testfile.js -
 
-let b:undo_indent = 'setlocal indentexpr< smartindent< autoindent< indentkeys< cinoptions<'
+let b:undo_indent = 'setlocal indentexpr< smartindent< autoindent< indentkeys<'
 
 " Only define the function once.
 if exists('*GetJavascriptIndent')
@@ -33,162 +36,342 @@ if exists('*shiftwidth')
   endfunction
 else
   function s:sw()
-    return &sw
+    return &l:shiftwidth == 0 ? &l:tabstop : &l:shiftwidth
   endfunction
 endif
 
-let s:line_pre = '^\s*\%(\%(\%(\/\*.\{-}\)\=\*\+\/\s*\)\=\)\@>'
-let s:expr_case = s:line_pre . '\%(\%(case\>.\+\)\|default\)\s*:'
-" Regex of syntax group names that are or delimit string or are comments.
-let s:syng_strcom = '\%(s\%(tring\|pecial\)\|comment\|regex\|doc\|template\)'
-
-" Regex of syntax group names that are strings or documentation.
-let s:syng_comment = '\%(comment\|doc\)'
-
-" Expression used to check whether we should skip a match with searchpair().
-let s:skip_expr = "synIDattr(synID(line('.'),col('.'),0),'name') =~? '".s:syng_strcom."'"
+" Performance for forwards search(): start search at pos rather than masking
+" matches before pos.
+let s:z = has('patch-7.4.984') ? 'z' : ''
 
+" searchpair() wrapper
 if has('reltime')
-  function s:GetPair(start,end,flags,time)
-    return searchpair(a:start,'',a:end,a:flags,s:skip_expr,max([prevnonblank(v:lnum) - 2000,0]),a:time)
+  function s:GetPair(start,end,flags,skip,time,...)
+    return searchpair('\m'.a:start,'','\m'.a:end,a:flags,a:skip,max([prevnonblank(v:lnum) - 2000,0] + a:000),a:time)
   endfunction
 else
-  function s:GetPair(start,end,flags,n)
-    return searchpair(a:start,'',a:end,a:flags,0,max([prevnonblank(v:lnum) - 2000,0]))
+  function s:GetPair(start,end,flags,skip,...)
+    return searchpair('\m'.a:start,'','\m'.a:end,a:flags,a:skip,max([prevnonblank(v:lnum) - 1000,get(a:000,1)]))
   endfunction
 endif
 
-let s:line_term = '\s*\%(\%(\/\%(\%(\*.\{-}\*\/\)\|\%(\*\+\)\)\)\s*\)\=$'
+" Regex of syntax group names that are or delimit string or are comments.
+let s:syng_strcom = 'string\|comment\|regex\|special\|doc\|template\%(braces\)\@!'
+let s:syng_str = 'string\|template\|special'
+let s:syng_com = 'comment\|doc'
+" Expression used to check whether we should skip a match with searchpair().
+let s:skip_expr = "synIDattr(synID(line('.'),col('.'),0),'name') =~? '".s:syng_strcom."'"
 
-" configurable regexes that define continuation lines, not including (, {, or [.
-if !exists('g:javascript_opfirst')
-  let g:javascript_opfirst = '\%([<>,:?^%|*&]\|\/[^/*]\|\([-.+]\)\1\@!\|=>\@!\|in\%(stanceof\)\=\>\)'
-endif
-if !exists('g:javascript_continuation')
-  let g:javascript_continuation = '\%([<=,.?/*:^%|&]\|+\@<!+\|-\@<!-\|=\@<!>\|\<in\%(stanceof\)\=\)'
-endif
+function s:parse_cino(f) abort
+  return float2nr(eval(substitute(substitute(join(split(
+        \ matchstr(&cino,'.*'.a:f.'\zs[^,]*'), 's',1), '*'.s:W)
+        \ , '^-\=\zs\*','',''), '^-\=\zs\.','0.','')))
+endfunction
 
-let g:javascript_opfirst = s:line_pre . g:javascript_opfirst
-let g:javascript_continuation .= s:line_term
+function s:skip_func()
+  if getline('.') =~ '\%<'.col('.').'c\/.\{-}\/\|\%>'.col('.').'c[''"]\|\\$'
+    return eval(s:skip_expr)
+  elseif s:checkIn || search('\m`\|\${\|\*\/','nW'.s:z,s:looksyn)
+    let s:checkIn = eval(s:skip_expr)
+  endif
+  let s:looksyn = line('.')
+  return s:checkIn
+endfunction
 
-function s:OneScope(lnum,text,add)
-  return a:text =~# '\%(\<else\|\<do\|=>\)' . s:line_term ? 'no b' :
-        \ ((a:add && a:text =~ s:line_pre . '$' && search('\%' . s:PrevCodeLine(a:lnum - 1) . 'l.)' . s:line_term)) ||
-        \ cursor(a:lnum, match(a:text, ')' . s:line_term)) > -1) &&
-        \ s:GetPair('(', ')', 'cbW', 100) > 0 && search('\C\l\+\_s*\%#','bW') &&
-        \ (a:add || ((expand('<cword>') !=# 'while' || !s:GetPair('\C\<do\>', '\C\<while\>','nbW',100)) &&
-        \ (expand('<cword>') !=# 'each' || search('\C\<for\_s\+\%#','nbW')))) ? expand('<cword>') : ''
+function s:alternatePair(stop)
+  let pos = getpos('.')[1:2]
+  let pat = '[][(){};]'
+  while search('\m'.pat,'bW',a:stop)
+    if s:skip_func() | continue | endif
+    let idx = stridx('])};',s:looking_at())
+    if idx is 3 | let pat = '[{}()]' | continue | endif
+    if idx + 1
+      if s:GetPair(['\[','(','{'][idx], '])}'[idx],'bW','s:skip_func()',2000,a:stop) <= 0
+        break
+      endif
+    else
+      return
+    endif
+  endwhile
+  call call('cursor',pos)
 endfunction
 
-" https://github.com/sweet-js/sweet.js/wiki/design#give-lookbehind-to-the-reader
-function s:IsBlock()
-  return getline(line('.'))[col('.')-1] == '{' && !search(
-        \ '\C\%(\<return\s*\|\%([-=~!<*+,.?^%|&\[(]\|=\@<!>\|\*\@<!\/\|\<\%(var\|const\|let\|import\|export\%(\_s\+default\)\=\|yield\|delete\|void\|t\%(ypeof\|hrow\)\|new\|in\%(stanceof\)\=\)\)\_s*\)\%#','bnW') &&
-        \ (!search(':\_s*\%#','bW') || (!s:GetPair('[({[]','[])}]','bW',200) || s:IsBlock()))
+function s:save_pos(f,...)
+  let l:pos = getpos('.')[1:2]
+  let ret = call(a:f,a:000)
+  call call('cursor',l:pos)
+  return ret
+endfunction
+
+function s:syn_at(l,c)
+  return synIDattr(synID(a:l,a:c,0),'name')
+endfunction
+
+function s:looking_at()
+  return getline('.')[col('.')-1]
+endfunction
+
+function s:token()
+  return s:looking_at() =~ '\k' ? expand('<cword>') : s:looking_at()
+endfunction
+
+function s:previous_token()
+  let l:pos = getpos('.')[1:2]
+  if search('\m\k\{1,}\zs\k\|\S','bW')
+    if (getline('.')[col('.')-2:col('.')-1] == '*/' || line('.') != l:pos[0] &&
+          \ getline('.') =~ '\%<'.col('.').'c\/\/') && s:syn_at(line('.'),col('.')) =~? s:syng_com
+      while search('\m\S\ze\_s*\/[/*]','bW')
+        if s:syn_at(line('.'),col('.')) !~? s:syng_com
+          return s:token()
+        endif
+      endwhile
+    else
+      return s:token()
+    endif
+  endif
+  call call('cursor',l:pos)
+  return ''
+endfunction
+
+function s:expr_col()
+  if getline('.')[col('.')-2] == ':'
+    return 1
+  endif
+  let bal = 0
+  while search('\m[{}?:;]','bW')
+    if eval(s:skip_expr) | continue | endif
+    " switch (looking_at())
+    exe {   '}': "if s:GetPair('{','}','bW',s:skip_expr,200) <= 0 | return | endif",
+          \ ';': "return",
+          \ '{': "return getpos('.')[1:2] != b:js_cache[1:] && !s:IsBlock()",
+          \ ':': "let bal -= getline('.')[max([col('.')-2,0]):col('.')] !~ '::'",
+          \ '?': "let bal += 1 | if bal > 0 | return 1 | endif" }[s:looking_at()]
+  endwhile
+endfunction
+
+" configurable regexes that define continuation lines, not including (, {, or [.
+let s:opfirst = '^' . get(g:,'javascript_opfirst',
+      \ '\C\%([<>=,?^%|*/&]\|\([-.:+]\)\1\@!\|!=\|in\%(stanceof\)\=\>\)')
+let s:continuation = get(g:,'javascript_continuation',
+      \ '\C\%([-+<>=,.~!?/*^%|&:]\|\<\%(typeof\|new\|delete\|void\|in\|instanceof\|await\)\)') . '$'
+
+function s:continues(ln,con)
+  if !cursor(a:ln, match(' '.a:con,s:continuation))
+    let teol = s:looking_at()
+    if teol == '/'
+      return s:syn_at(line('.'),col('.')) !~? 'regex'
+    elseif teol =~ '[-+>]'
+      return getline('.')[col('.')-2] != tr(teol,'>','=')
+    elseif teol =~ '\l'
+      return s:previous_token() != '.'
+    elseif teol == ':'
+      return s:expr_col()
+    endif
+    return 1
+  endif
 endfunction
 
-" Auxiliary Functions {{{2
+" get the line of code stripped of comments and move cursor to the last
+" non-comment char.
+function s:Trim(ln)
+  let pline = substitute(getline(a:ln),'\s*$','','')
+  let l:max = max([strridx(pline,'//'), strridx(pline,'/*')])
+  while l:max != -1 && s:syn_at(a:ln, strlen(pline)) =~? s:syng_com
+    let pline = pline[: l:max]
+    let l:max = max([strridx(pline,'//'), strridx(pline,'/*')])
+    let pline = substitute(pline[:-2],'\s*$','','')
+  endwhile
+  return pline is '' || cursor(a:ln,strlen(pline)) ? pline : pline
+endfunction
 
-" Find line above 'lnum' that isn't empty, in a comment, or in a string.
+" Find line above 'lnum' that isn't empty or in a comment
 function s:PrevCodeLine(lnum)
-  let l:lnum = prevnonblank(a:lnum)
-  while l:lnum
-    if synIDattr(synID(l:lnum,matchend(getline(l:lnum), '^\s*[^''"]'),0),'name') !~? s:syng_strcom
-      return l:lnum
+  let [l:pos, l:n] = [getpos('.')[1:2], prevnonblank(a:lnum)]
+  while l:n
+    if getline(l:n) =~ '^\s*\/[/*]'
+      let l:n = prevnonblank(l:n-1)
+    elseif stridx(getline(l:n), '*/') + 1 && s:syn_at(l:n,1) =~? s:syng_com
+      call cursor(l:n,1)
+      keepjumps norm! [*
+      let l:n = search('\m\S','nbW')
+    else
+      break
     endif
-    let l:lnum = prevnonblank(l:lnum - 1)
   endwhile
+  call call('cursor',l:pos)
+  return l:n
 endfunction
 
 " Check if line 'lnum' has a balanced amount of parentheses.
 function s:Balanced(lnum)
-  let [open_0,open_2,open_4] = [0,0,0]
+  let l:open = 0
   let l:line = getline(a:lnum)
   let pos = match(l:line, '[][(){}]', 0)
   while pos != -1
-    if synIDattr(synID(a:lnum,pos + 1,0),'name') !~? s:syng_strcom
-      let idx = stridx('(){}[]', l:line[pos])
-      if idx % 2 == 0
-        let open_{idx} = open_{idx} + 1
-      else
-        let open_{idx - 1} = open_{idx - 1} - 1
+    if s:syn_at(a:lnum,pos + 1) !~? s:syng_strcom
+      let l:open += match(' ' . l:line[pos],'[[({]')
+      if l:open < 0
+        return
       endif
     endif
-    let pos = match(l:line, '[][(){}]', pos + 1)
+    let pos = match(l:line, (l:open ?
+          \ '['.escape(tr(l:line[pos],'({[]})',')}][{(').l:line[pos],']').']' :
+          \ '[][(){}]'), pos + 1)
   endwhile
-  return (!open_4 + !open_2 + !open_0) - 2
+  return !l:open
 endfunction
-" }}}
 
-function GetJavascriptIndent()
-  if !exists('b:js_cache')
-    let b:js_cache = [0,0,0]
+function s:OneScope(lnum)
+  let pline = s:Trim(a:lnum)
+  let kw = 'else do'
+  if pline[-1:] == ')' && s:GetPair('(', ')', 'bW', s:skip_expr, 100) > 0
+    if s:previous_token() =~# '^\%(await\|each\)$'
+      call s:previous_token()
+      let kw = 'for'
+    else
+      let kw = 'for if let while with'
+    endif
   endif
+  return pline[-2:] == '=>' || index(split(kw),s:token()) + 1 &&
+        \ s:save_pos('s:previous_token') != '.'
+endfunction
+
+" returns braceless levels started by 'i' and above lines * &sw. 'num' is the
+" lineNr which encloses the entire context, 'cont' if whether line 'i' + 1 is
+" a continued expression, which could have started in a braceless context
+function s:iscontOne(i,num,cont)
+  let [l:i, l:num, bL] = [a:i, a:num + !a:num, 0]
+  let pind = a:num ? indent(l:num) + s:W : 0
+  let ind = indent(l:i) + (a:cont ? 0 : s:W)
+  while l:i >= l:num && (ind > pind || l:i == l:num)
+    if indent(l:i) < ind && s:OneScope(l:i)
+      let bL += s:W
+      let l:i = line('.')
+    elseif !a:cont || bL || ind < indent(a:i)
+      break
+    endif
+    let ind = min([ind, indent(l:i)])
+    let l:i = s:PrevCodeLine(l:i - 1)
+  endwhile
+  return bL
+endfunction
+
+" https://github.com/sweet-js/sweet.js/wiki/design#give-lookbehind-to-the-reader
+function s:IsBlock()
+  if s:looking_at() == '{'
+    let l:n = line('.')
+    let char = s:previous_token()
+    if match(s:stack,'\cxml\|jsx') + 1 && s:syn_at(line('.'),col('.')-1) =~? 'xml\|jsx'
+      return char != '{'
+    elseif char =~ '\k'
+      if char ==# 'type'
+        return s:previous_token() !~# '^\%(im\|ex\)port$'
+      endif
+      return index(split('return const let import export extends yield default delete var await void typeof throw case new of in instanceof')
+            \ ,char) < (line('.') != l:n) || s:save_pos('s:previous_token') == '.'
+    elseif char == '>'
+      return getline('.')[col('.')-2] == '=' || s:syn_at(line('.'),col('.')) =~? '^jsflow'
+    elseif char == ':'
+      return !s:save_pos('s:expr_col')
+    elseif char == '/'
+      return s:syn_at(line('.'),col('.')) =~? 'regex'
+    endif
+    return char !~ '[=~!<*,?^%|&([]' &&
+          \ (char !~ '[-+]' || l:n != line('.') && getline('.')[col('.')-2] == char)
+  endif
+endfunction
+
+function GetJavascriptIndent()
+  let b:js_cache = get(b:,'js_cache',[0,0,0])
   " Get the current line.
-  let l:line = getline(v:lnum)
-  let syns = synIDattr(synID(v:lnum, 1, 0), 'name')
+  call cursor(v:lnum,1)
+  let l:line = getline('.')
+  " use synstack as it validates syn state and works in an empty line
+  let s:stack = map(synstack(v:lnum,1),"synIDattr(v:val,'name')")
+  let syns = get(s:stack,-1,'')
 
-  " start with strings,comments,etc.{{{2
-  if (l:line !~ '^[''"`]' && syns =~? '\%(string\|template\)') ||
-        \ (l:line !~ '^\s*[/*]' && syns =~? s:syng_comment)
+  " start with strings,comments,etc.
+  if syns =~? s:syng_com
+    if l:line =~ '^\s*\*'
+      return cindent(v:lnum)
+    elseif l:line !~ '^\s*\/[/*]'
+      return -1
+    endif
+  elseif syns =~? s:syng_str
+    if b:js_cache[0] == v:lnum - 1 && s:Balanced(v:lnum-1)
+      let b:js_cache[0] = v:lnum
+    endif
     return -1
   endif
-  if l:line !~ '^\%(\/\*\|\s*\/\/\)' && syns =~? s:syng_comment
-    return cindent(v:lnum)
-  endif
   let l:lnum = s:PrevCodeLine(v:lnum - 1)
-  if l:lnum == 0
-    return 0
+  if !l:lnum
+    return
   endif
 
-  if (l:line =~# s:expr_case)
-    let cpo_switch = &cpo
-    set cpo+=%
-    let ind = cindent(v:lnum)
-    let &cpo = cpo_switch
-    return ind
+  let l:line = substitute(l:line,'^\s*','','')
+  if l:line[:1] == '/*'
+    let l:line = substitute(l:line,'^\%(\/\*.\{-}\*\/\s*\)*','','')
+  endif
+  if l:line =~ '^\/[/*]'
+    let l:line = ''
   endif
-  "}}}
 
-  " the containing paren, bracket, curly. Memoize, last lineNr either has the
-  " same scope or starts a new one, unless if it closed a scope.
-  call cursor(v:lnum,1)
-  if b:js_cache[0] >= l:lnum  && b:js_cache[0] < v:lnum && b:js_cache[0] &&
-        \ (b:js_cache[0] > l:lnum || s:Balanced(l:lnum) > 0)
-    let num = b:js_cache[1]
-  elseif syns != '' && l:line[0] =~ '\s'
-    let pattern = syns =~? 'block' ? ['{','}'] : syns =~? 'jsparen' ? ['(',')'] :
-          \ syns =~? 'jsbracket'? ['\[','\]'] : ['[({[]','[])}]']
-    let num = s:GetPair(pattern[0],pattern[1],'bW',2000)
+  " the containing paren, bracket, or curly. Many hacks for performance
+  let idx = index([']',')','}'],l:line[0])
+  if b:js_cache[0] >= l:lnum && b:js_cache[0] < v:lnum &&
+        \ (b:js_cache[0] > l:lnum || s:Balanced(l:lnum))
+    call call('cursor',b:js_cache[1:])
   else
-    let num = s:GetPair('[({[]','[])}]','bW',2000)
+    let [s:looksyn, s:checkIn, top] = [v:lnum - 1, 0, (!indent(l:lnum) &&
+          \ s:syn_at(l:lnum,1) !~? s:syng_str) * l:lnum]
+    if idx + 1
+      call s:GetPair(['\[','(','{'][idx],'])}'[idx],'bW','s:skip_func()',2000,top)
+    elseif getline(v:lnum) !~ '^\S' && syns =~? 'block'
+      call s:GetPair('{','}','bW','s:skip_func()',2000,top)
+    else
+      call s:alternatePair(top)
+    endif
   endif
-  let b:js_cache = [v:lnum,num,line('.') == v:lnum ? b:js_cache[2] : col('.')]
 
-  if l:line =~ s:line_pre . '[])}]'
-    return indent(num)
-  endif
+  let b:js_cache = [v:lnum] + (line('.') == v:lnum ? [0,0] : getpos('.')[1:2])
+  let num = b:js_cache[1]
 
-  call cursor(b:js_cache[1],b:js_cache[2])
-
-  let swcase = getline(l:lnum) =~# s:expr_case
-  let pline = swcase ? getline(l:lnum) : substitute(getline(l:lnum), '\%(:\@<!\/\/.*\)$', '','')
-  let inb = num == 0 || num < l:lnum && ((l:line !~ s:line_pre . ',' && pline !~ ',' . s:line_term) || s:IsBlock())
-  let switch_offset = num == 0 || s:OneScope(num, strpart(getline(num),0,b:js_cache[2] - 1),1) !=# 'switch' ? 0 :
-        \ &cino !~ ':' || !has('float') ?  s:sw() :
-        \ float2nr(str2float(matchstr(&cino,'.*:\zs[-0-9.]*')) * (&cino =~# '.*:[^,]*s' ? s:sw() : 1))
-
-  " most significant, find the indent amount
-  if inb && !swcase && ((l:line =~# g:javascript_opfirst || pline =~# g:javascript_continuation) ||
-        \ num < l:lnum && s:OneScope(l:lnum,pline,0) =~# '\<\%(for\|each\|if\|let\|no\sb\|w\%(hile\|ith\)\)\>' &&
-        \ l:line !~ s:line_pre . '{')
-    return (num > 0 ? indent(num) : -s:sw()) + (s:sw() * 2) + switch_offset
-  elseif num > 0
-    return indent(num) + s:sw() + switch_offset
+  let [s:W, isOp, bL, switch_offset] = [s:sw(),0,0,0]
+  if !num || s:IsBlock()
+    let ilnum = line('.')
+    let pline = s:save_pos('s:Trim',l:lnum)
+    if num && s:looking_at() == ')' && s:GetPair('(', ')', 'bW', s:skip_expr, 100) > 0
+      let num = ilnum == num ? line('.') : num
+      if idx < 0 && s:previous_token() ==# 'switch' && s:previous_token() != '.'
+        if &cino !~ ':'
+          let switch_offset = s:W
+        else
+          let switch_offset = max([-indent(num),s:parse_cino(':')])
+        endif
+        if pline[-1:] != '.' && l:line =~# '^\%(default\|case\)\>'
+          return indent(num) + switch_offset
+        endif
+      endif
+    endif
+    if idx < 0 && pline[-1:] !~ '[{;]'
+      let isOp = (l:line =~# s:opfirst || s:continues(l:lnum,pline)) * s:W
+      let bL = s:iscontOne(l:lnum,b:js_cache[1],isOp)
+      let bL -= (bL && l:line[0] == '{') * s:W
+    endif
+  elseif idx < 0 && getline(b:js_cache[1])[b:js_cache[2]-1] == '(' && &cino =~ '('
+    let pval = s:parse_cino('(')
+    return !pval ? (s:parse_cino('w') ? 0 : -(!!search('\m\S','W'.s:z,num))) + virtcol('.') :
+          \ max([indent('.') + pval + (s:GetPair('(',')','nbrmW',s:skip_expr,100,num) * s:W),0])
   endif
 
+  " main return
+  if l:line =~ '^\%([])}]\||}\)'
+    return max([indent(num),0])
+  elseif num
+    return indent(num) + s:W + switch_offset + bL + isOp
+  endif
+  return bL + isOp
 endfunction
 
-
 let &cpo = s:cpo_save
 unlet s:cpo_save
index eccf42b..a72a3a9 100644 (file)
@@ -1,7 +1,7 @@
 " Vim indent file
-" Language:         ld(1) script
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-12-20
+" Language:             ld(1) script
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-12-20
 
 if exists("b:did_indent")
   finish
@@ -65,7 +65,7 @@ function GetLDIndent()
   if line =~ '^\s*\*'
     return cindent(v:lnum)
   elseif line =~ '^\s*}'
-    return indent(v:lnum) - &sw
+    return indent(v:lnum) - shiftwidth()
   endif
 
   let pnum = s:prevnonblanknoncomment(v:lnum - 1)
@@ -73,11 +73,11 @@ function GetLDIndent()
     return 0
   endif
 
-  let ind = indent(pnum) + s:count_braces(pnum, 1) * &sw
+  let ind = indent(pnum) + s:count_braces(pnum, 1) * shiftwidth()
 
   let pline = getline(pnum)
   if pline =~ '}\s*$'
-    let ind -= (s:count_braces(pnum, 0) - (pline =~ '^\s*}' ? 1 : 0)) * &sw
+    let ind -= (s:count_braces(pnum, 0) - (pline =~ '^\s*}' ? 1 : 0)) * shiftwidth()
   endif
 
   return ind
index 8412fbb..66a8a40 100644 (file)
@@ -1,7 +1,7 @@
 " Vim indent file
-" Language:         Makefile
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2007-05-07
+" Language:             Makefile
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2007-05-07
 
 if exists("b:did_indent")
   finish
@@ -48,14 +48,14 @@ function GetMakeIndent()
     if prev_prev_line =~ s:continuation_rx
       return indent(prev_lnum)
     elseif prev_line =~ s:rule_rx
-      return &sw
+      return shiftwidth()
     elseif prev_line =~ s:assignment_rx
       call cursor(prev_lnum, 1)
       if search(s:assignment_rx, 'W') != 0
         return virtcol('.') - 1
       else
         " TODO: ?
-        return &sw
+        return shiftwidth()
       endif
     else
       " TODO: OK, this might be a continued shell command, so perhaps indent
@@ -66,7 +66,7 @@ function GetMakeIndent()
       "    return indent(prev_lnum) + 2
       "  endif
       "endif
-      return indent(prev_lnum) + &sw
+      return indent(prev_lnum) + shiftwidth()
     endif
   elseif prev_prev_line =~ s:continuation_rx
     let folded_line = s:remove_continuation(prev_prev_line) . ' ' . s:remove_continuation(prev_line)
@@ -102,13 +102,13 @@ function GetMakeIndent()
       return &ts
     endif
   elseif prev_line =~ s:conditional_directive_rx
-    return &sw
+    return shiftwidth()
   else
     let line = getline(v:lnum)
     if line =~ s:just_inserted_rule_rx
       return 0
     elseif line =~ s:end_conditional_directive_rx
-      return v:lnum - 1 == 0 ? 0 : indent(v:lnum - 1) - &sw
+      return v:lnum - 1 == 0 ? 0 : indent(v:lnum - 1) - shiftwidth()
     else
       return v:lnum - 1 == 0 ? 0 : indent(v:lnum - 1)
     endif
index 07ecd8f..06b49f3 100644 (file)
@@ -3,8 +3,8 @@
 " Author:      John Wellesz <John.wellesz (AT) teaser (DOT) fr>
 " URL:         http://www.2072productions.com/vim/indent/php.vim
 " Home:                https://github.com/2072/PHP-Indenting-for-VIm
-" Last Change: 2015 September 8th
-" Version:     1.60
+" Last Change: 2017 March 12th
+" Version:     1.62
 "
 "
 "      Type :help php-indent for available options
@@ -141,11 +141,13 @@ let s:PHP_validVariable = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'
 let s:notPhpHereDoc = '\%(break\|return\|continue\|exit\|die\|else\)'
 let s:blockstart = '\%(\%(\%(}\s*\)\=else\%(\s\+\)\=\)\=if\>\|\%(}\s*\)\?else\>\|do\>\|while\>\|switch\>\|case\>\|default\>\|for\%(each\)\=\>\|declare\>\|class\>\|trait\>\|use\>\|interface\>\|abstract\>\|final\>\|try\>\|\%(}\s*\)\=catch\>\|\%(}\s*\)\=finally\>\)'
 let s:functionDecl = '\<function\>\%(\s\+'.s:PHP_validVariable.'\)\=\s*(.*'
-let s:endline= '\s*\%(//.*\|#.*\|/\*.*\*/\s*\)\=$'
+let s:endline = '\s*\%(//.*\|#.*\|/\*.*\*/\s*\)\=$'
+let s:unstated = '\%(^\s*'.s:blockstart.'.*)\|\%(//.*\)\@<!\<e'.'lse\>\)'.s:endline
 
 
-let s:terminated = '\%(\%(;\%(\s*\%(?>\|}\)\)\=\|<<<\s*[''"]\=\a\w*[''"]\=$\|^\s*}\|^\s*'.s:PHP_validVariable.':\)'.s:endline.'\)\|^[^''"`]*[''"`]$'
+let s:terminated = '\%(\%(;\%(\s*\%(?>\|}\)\)\=\|<<<\s*[''"]\=\a\w*[''"]\=$\|^\s*}\|^\s*'.s:PHP_validVariable.':\)'.s:endline.'\)'
 let s:PHP_startindenttag = '<?\%(.*?>\)\@!\|<script[^>]*>\%(.*<\/script>\)\@!'
+let s:structureHead = '^\s*\%(' . s:blockstart . '\)\|'. s:functionDecl . s:endline . '\|\<new\s\+class\>'
 
 
 
@@ -214,10 +216,28 @@ function! GetLastRealCodeLNum(startline) " {{{
                let lnum = lnum - 1
            endwhile
        elseif lastline =~ '^[^''"`]*[''"`][;,]'.s:endline
-           let tofind=substitute( lastline, '^.*\([''"`]\)[;,].*$', '^[^\1]\\+[\1]$', '')
-           while getline(lnum) !~? tofind && lnum > 1
-               let lnum = lnum - 1
+
+           let tofind=substitute( lastline, '^.*\([''"`]\)[;,].*$', '^[^\1]\\+[\1]$\\|^[^\1]\\+[=([]\\s*[\1]', '')
+           let trylnum = lnum
+           while getline(trylnum) !~? tofind && trylnum > 1
+               let trylnum = trylnum - 1
            endwhile
+
+           if trylnum == 1
+               break
+           else
+               if lastline =~ ';'.s:endline
+                   while getline(trylnum) !~? s:terminated && getline(trylnum) !~? '{'.s:endline && trylnum > 1
+                       let trylnum = prevnonblank(trylnum - 1)
+                   endwhile
+
+
+                   if trylnum == 1
+                       break
+                   end
+               end
+               let lnum = trylnum
+           end
        else
            break
        endif
@@ -262,7 +282,7 @@ function! FindOpenBracket(lnum, blockStarter) " {{{
        while line > 1
            let linec = getline(line)
 
-           if linec =~ s:terminated || linec =~ '^\s*\%(' . s:blockstart . '\)\|'. s:functionDecl . s:endline
+           if linec =~ s:terminated || linec =~ s:structureHead
                break
            endif
 
@@ -273,6 +293,20 @@ function! FindOpenBracket(lnum, blockStarter) " {{{
     return line
 endfun " }}}
 
+let s:blockChars = {'{':1, '[': 1, '(': 1, ')':-1, ']':-1, '}':-1}
+function! BalanceDirection (str)
+
+    let balance = 0
+
+    for c in split(a:str, '\zs')
+       if has_key(s:blockChars, c)
+           let balance += s:blockChars[c]
+       endif
+    endfor
+
+    return balance
+endfun
+
 function! FindTheIfOfAnElse (lnum, StopAfterFirstPrevElse) " {{{
 
     if getline(a:lnum) =~# '^\s*}\s*else\%(if\)\=\>'
@@ -457,7 +491,7 @@ function! GetPhpIndent()
 
        if synname!=""
            if synname == "SpecStringEntrails"
-               let b:InPHPcode = -1
+               let b:InPHPcode = -1 " thumb down
                let b:InPHPcode_tofind = ""
            elseif synname != "phpHereDoc" && synname != "phpHereDocDelimiter"
                let b:InPHPcode = 1
@@ -540,7 +574,7 @@ function! GetPhpIndent()
                let b:InPHPcode_and_script = 1
            endif
 
-       elseif last_line =~ '^[^''"`]\+[''"`]$'
+       elseif last_line =~ '^[^''"`]\+[''"`]$' " a string identifier with nothing after it and no other string identifier before
            let b:InPHPcode = -1
            let b:InPHPcode_tofind = substitute( last_line, '^.*\([''"`]\).*$', '^[^\1]*\1[;,]$', '')
        elseif last_line =~? '<<<\s*[''"]\=\a\w*[''"]\=$'
@@ -660,7 +694,8 @@ function! GetPhpIndent()
 
     let terminated = s:terminated
 
-    let unstated   = '\%(^\s*'.s:blockstart.'.*)\|\%(//.*\)\@<!\<e'.'lse\>\)'.endline
+    let unstated  = s:unstated
+
 
     if ind != b:PHP_default_indenting && cline =~# '^\s*else\%(if\)\=\>'
        let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
@@ -673,7 +708,7 @@ function! GetPhpIndent()
 
        while last_line_num > 1
 
-           if previous_line =~ terminated || previous_line =~ '^\s*\%(' . s:blockstart . '\)\|'. s:functionDecl . endline
+           if previous_line =~ terminated || previous_line =~ s:structureHead
 
                let ind = indent(last_line_num)
 
@@ -689,7 +724,7 @@ function! GetPhpIndent()
        endwhile
 
     elseif last_line =~# unstated && cline !~ '^\s*);\='.endline
-       let ind = ind + s:sw()
+       let ind = ind + s:sw() " we indent one level further when the preceding line is not stated
        return ind + addSpecial
 
     elseif (ind != b:PHP_default_indenting || last_line =~ '^[)\]]' ) && last_line =~ terminated
@@ -699,7 +734,7 @@ function! GetPhpIndent()
 
        let isSingleLineBlock = 0
        while 1
-           if ! isSingleLineBlock && previous_line =~ '^\s*}\|;\s*}'.endline
+           if ! isSingleLineBlock && previous_line =~ '^\s*}\|;\s*}'.endline " XXX
 
                call cursor(last_line_num, 1)
                if previous_line !~ '^}'
@@ -780,10 +815,10 @@ function! GetPhpIndent()
     if !LastLineClosed
 
 
-       if last_line =~# '[{(\[]'.endline || last_line =~? '\h\w*\s*(.*,$' && AntepenultimateLine !~ '[,(\[]'.endline
+       if last_line =~# '[{(\[]'.endline || last_line =~? '\h\w*\s*(.*,$' && AntepenultimateLine !~ '[,(\[]'.endline && BalanceDirection(last_line) > 0
 
            let dontIndent = 0
-           if last_line =~ '\S\+\s*{'.endline && last_line !~ '^\s*)\s*{'.endline && last_line !~ '^\s*\%(' . s:blockstart . '\)\|'. s:functionDecl . s:endline
+           if last_line =~ '\S\+\s*{'.endline && last_line !~ '^\s*[)\]]\+\s*{'.endline && last_line !~ s:structureHead
                let dontIndent = 1
            endif
 
@@ -797,9 +832,9 @@ function! GetPhpIndent()
                return ind + addSpecial
            endif
 
-       elseif last_line =~ '\S\+\s*),'.endline
+       elseif last_line =~ '\S\+\s*),'.endline && BalanceDirection(last_line) < 0
            call cursor(lnum, 1)
-           call search('),'.endline, 'W')
+           call search('),'.endline, 'W') " line never begins with ) so no need for 'c' flag
            let openedparent = searchpair('(', '', ')', 'bW', 'Skippmatch()')
            if openedparent != lnum
                let ind = indent(openedparent)
@@ -809,7 +844,7 @@ function! GetPhpIndent()
            let ind = ind + s:sw()
 
 
-    elseif AntepenultimateLine =~ '{'.endline || AntepenultimateLine =~ terminated || AntepenultimateLine =~# s:defaultORcase
+       elseif AntepenultimateLine =~ '{'.endline && AntepenultimateLine !~? '^\s*use\>' || AntepenultimateLine =~ terminated || AntepenultimateLine =~# s:defaultORcase
            let ind = ind + s:sw()
        endif
 
index 01f3812..373b0e6 100644 (file)
@@ -274,7 +274,7 @@ function GetRIndent()
         let nlnum = s:Get_prev_line(nlnum)
         let nline = SanitizeRLine(getline(nlnum)) . nline
       endwhile
-      if nline =~ '^\s*function\s*(' && indent(nlnum) == &sw
+      if nline =~ '^\s*function\s*(' && indent(nlnum) == shiftwidth()
         return 0
       endif
     endif
@@ -285,7 +285,7 @@ function GetRIndent()
 
   " line is an incomplete command:
   if line =~ '\<\(if\|while\|for\|function\)\s*()$' || line =~ '\<else$' || line =~ '<-$' || line =~ '->$'
-    return indent(lnum) + &sw
+    return indent(lnum) + shiftwidth()
   endif
 
   " Deal with () and []
@@ -293,14 +293,14 @@ function GetRIndent()
   let pb = s:Get_paren_balance(line, '(', ')')
 
   if line =~ '^\s*{$' || line =~ '(\s*{' || (pb == 0 && (line =~ '{$' || line =~ '(\s*{$'))
-    return indent(lnum) + &sw
+    return indent(lnum) + shiftwidth()
   endif
 
   let s:curtabstop = repeat(' ', &tabstop)
 
   if g:r_indent_align_args == 1
     if pb > 0 && line =~ '{$'
-      return s:Get_last_paren_idx(line, '(', ')', pb) + &sw
+      return s:Get_last_paren_idx(line, '(', ')', pb) + shiftwidth()
     endif
 
     let bb = s:Get_paren_balance(line, '[', ']')
@@ -364,11 +364,11 @@ function GetRIndent()
       if oline =~ g:r_indent_op_pattern && s:Get_paren_balance(line, "(", ")") == 0
         return indent(lnum)
       else
-        return indent(lnum) + &sw
+        return indent(lnum) + shiftwidth()
       endif
     else
       if oline =~ g:r_indent_op_pattern && s:Get_paren_balance(line, "(", ")") == 0
-        return indent(lnum) - &sw
+        return indent(lnum) - shiftwidth()
       endif
     endif
   endif
@@ -383,7 +383,7 @@ function GetRIndent()
       let line = linepiece . line
     endwhile
     if line =~ '{$' && post_block == 0
-      return indent(lnum) + &sw
+      return indent(lnum) + shiftwidth()
     endif
 
     " Now we can do some tests again
@@ -393,19 +393,19 @@ function GetRIndent()
     if post_block == 0
       let newl = SanitizeRLine(line)
       if newl =~ '\<\(if\|while\|for\|function\)\s*()$' || newl =~ '\<else$' || newl =~ '<-$'
-        return indent(lnum) + &sw
+        return indent(lnum) + shiftwidth()
       endif
     endif
   endif
 
   if cline =~ '^\s*else'
     if line =~ '<-\s*if\s*()'
-      return indent(lnum) + &sw
+      return indent(lnum) + shiftwidth()
     else
       if line =~ '\<if\s*()'
         return indent(lnum)
       else
-        return indent(lnum) - &sw
+        return indent(lnum) - shiftwidth()
       endif
     endif
   endif
@@ -474,12 +474,12 @@ function GetRIndent()
   let ind = indent(lnum)
 
   if g:r_indent_align_args == 0 && pb != 0
-    let ind += pb * &sw
+    let ind += pb * shiftwidth()
     return ind
   endif
 
   if g:r_indent_align_args == 0 && bb != 0
-    let ind += bb * &sw
+    let ind += bb * shiftwidth()
     return ind
   endif
 
@@ -489,7 +489,7 @@ function GetRIndent()
     let pind = 0
   endif
 
-  if ind == pind || (ind == (pind  + &sw) && pline =~ '{$' && ppost_else == 0)
+  if ind == pind || (ind == (pind  + shiftwidth()) && pline =~ '{$' && ppost_else == 0)
     return ind
   endif
 
@@ -509,7 +509,7 @@ function GetRIndent()
       let pbb = s:Get_paren_balance(pline, '[', ']')
     endwhile
     let pind = indent(plnum)
-    if ind == (pind  + &sw) && pline =~ '{$'
+    if ind == (pind  + shiftwidth()) && pline =~ '{$'
       return ind
     endif
   endwhile
index 6ac2185..e202ddf 100644 (file)
@@ -1,7 +1,7 @@
 " Vim indent file
-" Language:         readline configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-12-20
+" Language:             readline configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-12-20
 
 if exists("b:did_indent")
   finish
@@ -25,11 +25,11 @@ function GetReadlineIndent()
   let ind = indent(lnum)
 
   if getline(lnum) =~ '^\s*$\(if\|else\)\>'
-    let ind = ind + &sw
+    let ind = ind + shiftwidth()
   endif
 
   if getline(v:lnum) =~ '^\s*$\(else\|endif\)\>'
-    let ind = ind - &sw
+    let ind = ind - shiftwidth()
   endif
 
   return ind
index 9dc2031..cf69ae3 100644 (file)
@@ -82,7 +82,7 @@ function GetRHelpIndent()
   let closeb = strlen(line2) - strlen(line3)
   let bb = openb - closeb
 
-  let ind = indent(lnum) + (bb * &sw)
+  let ind = indent(lnum) + (bb * shiftwidth())
 
   if line =~ '^\s*}\s*$'
     let ind = indent(lnum)
index 80d3308..c1ef8c9 100644 (file)
@@ -1,7 +1,7 @@
 " Vim indent file
-" Language:         reStructuredText Documentation Format
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2011-08-03
+" Language:             reStructuredText Documentation Format
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2011-08-03
 
 if exists("b:did_indent")
   finish
diff --git a/runtime/indent/rust.vim b/runtime/indent/rust.vim
new file mode 100644 (file)
index 0000000..a3051f0
--- /dev/null
@@ -0,0 +1,213 @@
+" Vim indent file
+" Language:         Rust
+" Author:           Chris Morgan <me@chrismorgan.info>
+" Last Change:      2017 Mar 21
+" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+       finish
+endif
+let b:did_indent = 1
+
+setlocal cindent
+setlocal cinoptions=L0,(0,Ws,J1,j1
+setlocal cinkeys=0{,0},!^F,o,O,0[,0]
+" Don't think cinwords will actually do anything at all... never mind
+setlocal cinwords=for,if,else,while,loop,impl,mod,unsafe,trait,struct,enum,fn,extern
+
+" Some preliminary settings
+setlocal nolisp                " Make sure lisp indenting doesn't supersede us
+setlocal autoindent    " indentexpr isn't much help otherwise
+" Also do indentkeys, otherwise # gets shoved to column 0 :-/
+setlocal indentkeys=0{,0},!^F,o,O,0[,0]
+
+setlocal indentexpr=GetRustIndent(v:lnum)
+
+" Only define the function once.
+if exists("*GetRustIndent")
+       finish
+endif
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+" Come here when loading the script the first time.
+
+function! s:get_line_trimmed(lnum)
+       " Get the line and remove a trailing comment.
+       " Use syntax highlighting attributes when possible.
+       " NOTE: this is not accurate; /* */ or a line continuation could trick it
+       let line = getline(a:lnum)
+       let line_len = strlen(line)
+       if has('syntax_items')
+               " If the last character in the line is a comment, do a binary search for
+               " the start of the comment.  synID() is slow, a linear search would take
+               " too long on a long line.
+               if synIDattr(synID(a:lnum, line_len, 1), "name") =~ 'Comment\|Todo'
+                       let min = 1
+                       let max = line_len
+                       while min < max
+                               let col = (min + max) / 2
+                               if synIDattr(synID(a:lnum, col, 1), "name") =~ 'Comment\|Todo'
+                                       let max = col
+                               else
+                                       let min = col + 1
+                               endif
+                       endwhile
+                       let line = strpart(line, 0, min - 1)
+               endif
+               return substitute(line, "\s*$", "", "")
+       else
+               " Sorry, this is not complete, nor fully correct (e.g. string "//").
+               " Such is life.
+               return substitute(line, "\s*//.*$", "", "")
+       endif
+endfunction
+
+function! s:is_string_comment(lnum, col)
+       if has('syntax_items')
+               for id in synstack(a:lnum, a:col)
+                       let synname = synIDattr(id, "name")
+                       if synname == "rustString" || synname =~ "^rustComment"
+                               return 1
+                       endif
+               endfor
+       else
+               " without syntax, let's not even try
+               return 0
+       endif
+endfunction
+
+function GetRustIndent(lnum)
+
+       " Starting assumption: cindent (called at the end) will do it right
+       " normally. We just want to fix up a few cases.
+
+       let line = getline(a:lnum)
+
+       if has('syntax_items')
+               let synname = synIDattr(synID(a:lnum, 1, 1), "name")
+               if synname == "rustString"
+                       " If the start of the line is in a string, don't change the indent
+                       return -1
+               elseif synname =~ '\(Comment\|Todo\)'
+                                       \ && line !~ '^\s*/\*'  " not /* opening line
+                       if synname =~ "CommentML" " multi-line
+                               if line !~ '^\s*\*' && getline(a:lnum - 1) =~ '^\s*/\*'
+                                       " This is (hopefully) the line after a /*, and it has no
+                                       " leader, so the correct indentation is that of the
+                                       " previous line.
+                                       return GetRustIndent(a:lnum - 1)
+                               endif
+                       endif
+                       " If it's in a comment, let cindent take care of it now. This is
+                       " for cases like "/*" where the next line should start " * ", not
+                       " "* " as the code below would otherwise cause for module scope
+                       " Fun fact: "  /*\n*\n*/" takes two calls to get right!
+                       return cindent(a:lnum)
+               endif
+       endif
+
+       " cindent gets second and subsequent match patterns/struct members wrong,
+       " as it treats the comma as indicating an unfinished statement::
+       "
+       " match a {
+       "     b => c,
+       "         d => e,
+       "         f => g,
+       " };
+
+       " Search backwards for the previous non-empty line.
+       let prevlinenum = prevnonblank(a:lnum - 1)
+       let prevline = s:get_line_trimmed(prevlinenum)
+       while prevlinenum > 1 && prevline !~ '[^[:blank:]]'
+               let prevlinenum = prevnonblank(prevlinenum - 1)
+               let prevline = s:get_line_trimmed(prevlinenum)
+       endwhile
+
+       " Handle where clauses nicely: subsequent values should line up nicely.
+       if prevline[len(prevline) - 1] == ","
+                               \ && prevline =~# '^\s*where\s'
+               return indent(prevlinenum) + 6
+       endif
+
+       if prevline[len(prevline) - 1] == ","
+                               \ && s:get_line_trimmed(a:lnum) !~ '^\s*[\[\]{}]'
+                               \ && prevline !~ '^\s*fn\s'
+                               \ && prevline !~ '([^()]\+,$'
+                               \ && s:get_line_trimmed(a:lnum) !~ '^\s*\S\+\s*=>'
+               " Oh ho! The previous line ended in a comma! I bet cindent will try to
+               " take this too far... For now, let's normally use the previous line's
+               " indent.
+
+               " One case where this doesn't work out is where *this* line contains
+               " square or curly brackets; then we normally *do* want to be indenting
+               " further.
+               "
+               " Another case where we don't want to is one like a function
+               " definition with arguments spread over multiple lines:
+               "
+               " fn foo(baz: Baz,
+               "        baz: Baz) // <-- cindent gets this right by itself
+               "
+               " Another case is similar to the previous, except calling a function
+               " instead of defining it, or any conditional expression that leaves
+               " an open paren:
+               "
+               " foo(baz,
+               "     baz);
+               "
+               " if baz && (foo ||
+               "            bar) {
+               "
+               " Another case is when the current line is a new match arm.
+               "
+               " There are probably other cases where we don't want to do this as
+               " well. Add them as needed.
+               return indent(prevlinenum)
+       endif
+
+       if !has("patch-7.4.355")
+               " cindent before 7.4.355 doesn't do the module scope well at all; e.g.::
+               "
+               " static FOO : &'static [bool] = [
+               " true,
+               "        false,
+               "        false,
+               "        true,
+               "        ];
+               "
+               "        uh oh, next statement is indented further!
+
+               " Note that this does *not* apply the line continuation pattern properly;
+               " that's too hard to do correctly for my liking at present, so I'll just
+               " start with these two main cases (square brackets and not returning to
+               " column zero)
+
+               call cursor(a:lnum, 1)
+               if searchpair('{\|(', '', '}\|)', 'nbW',
+                                       \ 's:is_string_comment(line("."), col("."))') == 0
+                       if searchpair('\[', '', '\]', 'nbW',
+                                               \ 's:is_string_comment(line("."), col("."))') == 0
+                               " Global scope, should be zero
+                               return 0
+                       else
+                               " At the module scope, inside square brackets only
+                               "if getline(a:lnum)[0] == ']' || search('\[', '', '\]', 'nW') == a:lnum
+                               if line =~ "^\\s*]"
+                                       " It's the closing line, dedent it
+                                       return 0
+                               else
+                                       return &shiftwidth
+                               endif
+                       endif
+               endif
+       endif
+
+       " Fall back on cindent, which does it mostly right
+       return cindent(a:lnum)
+endfunction
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
diff --git a/runtime/indent/sas.vim b/runtime/indent/sas.vim
new file mode 100644 (file)
index 0000000..d591b27
--- /dev/null
@@ -0,0 +1,138 @@
+" Vim indent file
+" Language:     SAS
+" Maintainer:   Zhen-Huan Hu <wildkeny@gmail.com>
+" Version:      3.0.1
+" Last Change:  Mar 13, 2017
+
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=GetSASIndent()
+setlocal indentkeys+=;,=~data,=~proc,=~macro
+
+if exists("*GetSASIndent")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+" Regex that captures the start of a data/proc section
+let s:section_str = '\v%(^|;)\s*%(data|proc)>'
+" Regex that captures the end of a run-processing section
+let s:section_run = '\v%(^|;)\s*run\s*;'
+" Regex that captures the end of a data/proc section
+let s:section_end = '\v%(^|;)\s*%(quit|enddata)\s*;'
+
+" Regex that captures the start of a control block (anything inside a section)
+let s:block_str = '\v<%(do>%([^;]+<%(to|over)>[^;]+)=|%(define|layout|method|select)>[^;]+|begingraph)\s*;'
+" Regex that captures the end of a control block (anything inside a section)
+let s:block_end = '\v<%(end|endlayout|endgraph)\s*;'
+
+" Regex that captures the start of a macro
+let s:macro_str = '\v%(^|;)\s*\%macro>'
+" Regex that captures the end of a macro
+let s:macro_end = '\v%(^|;)\s*\%mend\s*;'
+
+" Regex that defines the end of the program
+let s:program_end = '\v%(^|;)\s*endsas\s*;'
+
+" List of procs supporting run-processing
+let s:run_processing_procs = [
+      \ 'catalog', 'chart', 'datasets', 'document', 'ds2', 'plot', 'sql',
+      \ 'gareabar', 'gbarline', 'gchart', 'gkpi', 'gmap', 'gplot', 'gradar', 'greplay', 'gslide', 'gtile',
+      \ 'anova', 'arima', 'catmod', 'factex', 'glm', 'model', 'optex', 'plan', 'reg',
+      \ 'iml',
+      \ ]
+
+" Find the line number of previous keyword defined by the regex
+function! s:PrevMatch(lnum, regex)
+  let prev_lnum = prevnonblank(a:lnum - 1)
+  while prev_lnum > 0
+    let prev_line = getline(prev_lnum)
+    if prev_line =~ a:regex
+      break
+    else
+      let prev_lnum = prevnonblank(prev_lnum - 1)
+    endif
+  endwhile
+  return prev_lnum
+endfunction
+
+" Main function
+function! GetSASIndent()
+  let prev_lnum = prevnonblank(v:lnum - 1)
+  if prev_lnum ==# 0
+    " Leave the indentation of the first line unchanged
+    return indent(1)
+  else
+    let prev_line = getline(prev_lnum)
+    " Previous non-blank line contains the start of a macro/section/block
+    " while not the end of a macro/section/block (at the same line)
+    if (prev_line =~ s:section_str && prev_line !~ s:section_run && prev_line !~ s:section_end) ||
+          \ (prev_line =~ s:block_str && prev_line !~ s:block_end) ||
+          \ (prev_line =~ s:macro_str && prev_line !~ s:macro_end)
+      let ind = indent(prev_lnum) + &sts
+    elseif prev_line =~ s:section_run && prev_line !~ s:section_end
+      let prev_section_str_lnum = s:PrevMatch(v:lnum, s:section_str)
+      let prev_section_end_lnum = max([
+            \ s:PrevMatch(v:lnum, s:section_end),
+            \ s:PrevMatch(v:lnum, s:macro_end  ),
+            \ s:PrevMatch(v:lnum, s:program_end)])
+      " Check if the section supports run-processing
+      if prev_section_end_lnum < prev_section_str_lnum &&
+            \ getline(prev_section_str_lnum) =~ '\v%(^|;)\s*proc\s+%(' .
+            \ join(s:run_processing_procs, '|') . ')>'
+        let ind = indent(prev_lnum) + &sts
+      else
+        let ind = indent(prev_lnum)
+      endif
+    else
+      let ind = indent(prev_lnum)
+    endif
+  endif
+  " Re-adjustments based on the inputs of the current line
+  let curr_line = getline(v:lnum)
+  if curr_line =~ s:program_end
+    " End of the program
+    " Same indentation as the first non-blank line
+    return indent(nextnonblank(1))
+  elseif curr_line =~ s:macro_end
+    " Current line is the end of a macro
+    " Match the indentation of the start of the macro
+    return indent(s:PrevMatch(v:lnum, s:macro_str))
+  elseif curr_line =~ s:block_end && curr_line !~ s:block_str
+    " Re-adjust if current line is the end of a block
+    " while not the beginning of a block (at the same line)
+    " Returning the indent of previous block start directly
+    " would not work due to nesting
+    let ind = ind - &sts
+  elseif curr_line =~ s:section_str || curr_line =~ s:section_run || curr_line =~ s:section_end
+    " Re-adjust if current line is the start/end of a section
+    " since the end of a section could be inexplicit
+    let prev_section_str_lnum = s:PrevMatch(v:lnum, s:section_str)
+    " Check if the previous section supports run-processing
+    if getline(prev_section_str_lnum) =~ '\v%(^|;)\s*proc\s+%(' .
+          \ join(s:run_processing_procs, '|') . ')>'
+      let prev_section_end_lnum = max([
+            \ s:PrevMatch(v:lnum, s:section_end),
+            \ s:PrevMatch(v:lnum, s:macro_end  ),
+            \ s:PrevMatch(v:lnum, s:program_end)])
+    else
+      let prev_section_end_lnum = max([
+            \ s:PrevMatch(v:lnum, s:section_end),
+            \ s:PrevMatch(v:lnum, s:section_run),
+            \ s:PrevMatch(v:lnum, s:macro_end  ),
+            \ s:PrevMatch(v:lnum, s:program_end)])
+    endif
+    if prev_section_end_lnum < prev_section_str_lnum
+      let ind = ind - &sts
+    endif
+  endif
+  return ind
+endfunction
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
index f97c79b..6fd8ca9 100644 (file)
@@ -412,24 +412,24 @@ function! GetScalaIndent()
     if prevline =~ '^\s*\.'
       return ind
     else
-      return ind + &shiftwidth
+      return ind + shiftwidth()
     endif
   endif
 
   " Indent html literals
   if prevline !~ '/>\s*$' && prevline =~ '^\s*<[a-zA-Z][^>]*>\s*$'
     call scala#ConditionalConfirm("3")
-    return ind + &shiftwidth
+    return ind + shiftwidth()
   endif
 
   " assumes curly braces around try-block
   if curline =~ '^\s*}\s*\<catch\>'
-    return ind - &shiftwidth
+    return ind - shiftwidth()
   elseif curline =~ '^\s*\<catch\>'
     return ind
   endif
 
-  " Add a 'shiftwidth' after lines that start a block
+  " Add a shiftwidth()' after lines that start a block
   " If 'if', 'for' or 'while' end with ), this is a one-line block
   " If 'val', 'var', 'def' end with =, this is a one-line block
   if (prevline =~ '^\s*\<\%(\%(}\?\s*else\s\+\)\?if\|for\|while\)\>.*[)=]\s*$' && scala#NumberOfBraceGroups(prevline) <= 1)
@@ -438,7 +438,7 @@ function! GetScalaIndent()
         \ || prevline =~ '^\s*\%(}\s*\)\?\<else\>\s*$'
         \ || prevline =~ '=\s*$'
     call scala#ConditionalConfirm("4")
-    let ind = ind + &shiftwidth
+    let ind = ind + shiftwidth()
   elseif prevline =~ '^\s*\<\%(}\?\s*else\s\+\)\?if\>' && curline =~ '^\s*}\?\s*\<else\>'
     return ind
   endif
@@ -447,7 +447,7 @@ function! GetScalaIndent()
   let bracketCount = scala#CountBrackets(prevline, '{', '}')
   if bracketCount > 0 || prevline =~ '.*{\s*$'
     call scala#ConditionalConfirm("5b")
-    let ind = ind + &shiftwidth
+    let ind = ind + shiftwidth()
   elseif bracketCount < 0
     call scala#ConditionalConfirm("6b")
     " if the closing brace actually completes the braces entirely, then we
@@ -475,7 +475,7 @@ function! GetScalaIndent()
     let bracketCount = scala#CountBrackets(prevline, '(', ')')
     if bracketCount > 0 || prevline =~ '.*(\s*$'
       call scala#ConditionalConfirm("5a")
-      let ind = ind + &shiftwidth
+      let ind = ind + shiftwidth()
     elseif bracketCount < 0
       call scala#ConditionalConfirm("6a")
       " if the closing brace actually completes the braces entirely, then we
@@ -497,7 +497,7 @@ function! GetScalaIndent()
       else
         " This is the only part that's different from from the '{', '}' one below
         " Yup... some refactoring is necessary at some point.
-        let ind = ind + (bracketCount * &shiftwidth)
+        let ind = ind + (bracketCount * shiftwidth())
         let lineCompletedBrackets = 1
       endif
     endif
@@ -506,10 +506,10 @@ function! GetScalaIndent()
   if curline =~ '^\s*}\?\s*\<else\>\%(\s\+\<if\>\s*(.*)\)\?\s*{\?\s*$' &&
    \ ! scala#LineIsCompleteIf(prevline) &&
    \ prevline !~ '^.*}\s*$'
-    let ind = ind - &shiftwidth
+    let ind = ind - shiftwidth()
   endif
 
-  " Subtract a 'shiftwidth' on '}' or html
+  " Subtract a shiftwidth()' on '}' or html
   let curCurlyCount = scala#CountCurlies(curline)
   if curCurlyCount < 0
     call scala#ConditionalConfirm("14a")
@@ -517,7 +517,7 @@ function! GetScalaIndent()
     return indent(matchline)
   elseif curline =~ '^\s*</[a-zA-Z][^>]*>'
     call scala#ConditionalConfirm("14c")
-    return ind - &shiftwidth
+    return ind - shiftwidth()
   endif
 
   let prevParenCount = scala#CountParens(prevline)
@@ -529,7 +529,7 @@ function! GetScalaIndent()
   let prevCurlyCount = scala#CountCurlies(prevline)
   if prevCurlyCount == 0 && prevline =~ '^.*\%(=>\|⇒\)\s*$' && prevline !~ '^\s*this\s*:.*\%(=>\|⇒\)\s*$' && curline !~ '^\s*\<case\>'
     call scala#ConditionalConfirm("16")
-    let ind = ind + &shiftwidth
+    let ind = ind + shiftwidth()
   endif
 
   if ind == originalIndentValue && curline =~ '^\s*\<case\>'
@@ -555,7 +555,7 @@ function! GetScalaIndent()
   if scala#LineIsAClosingXML(prevline)
     if scala#LineCompletesXML(prevlnum, prevline)
       call scala#ConditionalConfirm("20a")
-      return ind - &shiftwidth
+      return ind - shiftwidth()
     else
       call scala#ConditionalConfirm("20b")
       return ind
@@ -566,7 +566,7 @@ function! GetScalaIndent()
     "let indentMultiplier = scala#LineCompletesDefValr(prevlnum, prevline)
     "if indentMultiplier != 0
     "  call scala#ConditionalConfirm("19a")
-    "  let ind = ind - (indentMultiplier * &shiftwidth)
+    "  let ind = ind - (indentMultiplier * shiftwidth())
     let defValrLine = scala#Test(prevlnum, prevline, '{', '}')
     if defValrLine != -1
       call scala#ConditionalConfirm("21a")
@@ -575,10 +575,10 @@ function! GetScalaIndent()
       call scala#ConditionalConfirm("21b")
       if scala#GetLine(prevnonblank(prevlnum - 1)) =~ '^.*\<else\>\s*\%(//.*\)\?$'
         call scala#ConditionalConfirm("21c")
-        let ind = ind - &shiftwidth
+        let ind = ind - shiftwidth()
       elseif scala#LineCompletesIfElse(prevlnum, prevline)
         call scala#ConditionalConfirm("21d")
-        let ind = ind - &shiftwidth
+        let ind = ind - shiftwidth()
       elseif scala#CountParens(curline) < 0 && curline =~ '^\s*)' && scala#GetLine(scala#GetLineThatMatchesBracket('(', ')')) =~ '.*(\s*$'
         " Handles situations that look like this:
         "
@@ -592,7 +592,7 @@ function! GetScalaIndent()
         "     10
         "   ).somethingHere()
         call scala#ConditionalConfirm("21e")
-        let ind = ind - &shiftwidth
+        let ind = ind - shiftwidth()
       endif
     endif
   endif
index a92f57d..e9d61e4 100644 (file)
@@ -56,7 +56,7 @@ function GetTclIndent()
   if line =~ '^\s*\*'
     return cindent(v:lnum)
   elseif line =~ '^\s*}'
-    return indent(v:lnum) - &sw
+    return indent(v:lnum) - shiftwidth()
   endif
 
   let pnum = s:prevnonblanknoncomment(v:lnum - 1)
@@ -64,11 +64,11 @@ function GetTclIndent()
     return 0
   endif
 
-  let ind = indent(pnum) + s:count_braces(pnum, 1) * &sw
+  let ind = indent(pnum) + s:count_braces(pnum, 1) * shiftwidth()
 
   let pline = getline(pnum)
   if pline =~ '}\s*$'
-    let ind -= (s:count_braces(pnum, 0) - (pline =~ '^\s*}' ? 1 : 0)) * &sw
+    let ind -= (s:count_braces(pnum, 0) - (pline =~ '^\s*}' ? 1 : 0)) * shiftwidth()
   endif
 
   return ind
index 59a9d56..ed08e6c 100644 (file)
@@ -32,17 +32,17 @@ function TcshGetIndent()
     let ind = indent(lnum)
     let line = getline(lnum)
     if line =~ '\v^\s*%(while|foreach)>|^\s*%(case\s.*:|default:|else)\s*$|%(<then|\\)$'
-       let ind = ind + &sw
+       let ind = ind + shiftwidth()
     endif
 
     if line =~ '\v^\s*breaksw>'
-       let ind = ind - &sw
+       let ind = ind - shiftwidth()
     endif
 
     " Subtract indent if current line has on end, endif, case commands
     let line = getline(v:lnum)
     if line =~ '\v^\s*%(else|end|endif)\s*$'
-       let ind = ind - &sw
+       let ind = ind - shiftwidth()
     endif
 
     return ind
index 1759773..a980538 100644 (file)
@@ -1,8 +1,8 @@
 " Vim indent file
 " Language:     tf (TinyFugue)
 " Maintainer:   Christian J. Robinson <heptite@gmail.com>
-" URL:          http://christianrobinson.name/vim/indent/tf.vim
-" Last Change:  2002 May 29
+" URL:          http://www.vim.org/scripts/script.php?script_id=174
+" Last Change:  2017 Feb 25 
 
 " Only load this indent file when no other was loaded.
 if exists("b:did_indent")
@@ -38,14 +38,14 @@ function GetTFIndent()
        endif
 
        if line =~ '\(/def.*\\\|/for.*\(%;\s*\)\@\<!\\\)$'
-               let ind = ind + &sw
+               let ind = ind + shiftwidth()
        elseif line =~ '\(/if\|/else\|/then\)'
                if line !~ '/endif'
-                       let ind = ind + &sw
+                       let ind = ind + shiftwidth()
                endif
        elseif line =~ '/while'
                if line !~ '/done'
-                       let ind = ind + &sw
+                       let ind = ind + shiftwidth()
                endif
        endif
 
@@ -53,11 +53,11 @@ function GetTFIndent()
 
        if line =~ '\(/else\|/endif\|/then\)'
                if line !~ '/if'
-                       let ind = ind - &sw
+                       let ind = ind - shiftwidth()
                endif
        elseif line =~ '/done'
                if line !~ '/while'
-                       let ind = ind - &sw
+                       let ind = ind - shiftwidth()
                endif
        endif
 
index a2af78b..2c6eecf 100644 (file)
@@ -1,7 +1,7 @@
 " Vim indent file
-" Language:         Treetop
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2011-03-14
+" Language:             Treetop
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2011-03-14
 
 if exists("b:did_indent")
   finish
@@ -26,12 +26,12 @@ function GetTreetopIndent()
   let line = getline(pnum)
 
   if line =~ '^\s*\%(grammar\|module\|rule\)\>'
-    let ind += &sw
+    let ind += shiftwidth()
   endif
 
   let line = getline(v:lnum)
   if line =~ '^\s*end\>'
-    let ind -= &sw
+    let ind -= shiftwidth()
   end
 
   retur ind
index ecca462..6222dc3 100644 (file)
@@ -1,10 +1,12 @@
 " Language:     Verilog HDL
-" Maintainer:  Chih-Tsun Huang <cthuang@larc.ee.nthu.edu.tw>
-" Last Change: 2011 Dec 10 by Thilo Six
-" URL:         http://larc.ee.nthu.edu.tw/~cthuang/vim/indent/verilog.vim
+" Maintainer:  Chih-Tsun Huang <cthuang@cs.nthu.edu.tw>
+" Last Change: 2017 Feb 24 by Chih-Tsun Huang
+" URL:             http://www.cs.nthu.edu.tw/~cthuang/vim/indent/verilog.vim
 "
 " Credits:
 "   Suggestions for improvement, bug reports by
+"     Takuya Fujiwara <tyru.exe@gmail.com>
+"     Thilo Six <debian@Xk2c.de>
 "     Leo Butlero <lbutler@brocade.com>
 "
 " Buffer Variables:
@@ -38,7 +40,7 @@ function GetVerilogIndent()
   if exists('b:verilog_indent_width')
     let offset = b:verilog_indent_width
   else
-    let offset = &sw
+    let offset = shiftwidth()
   endif
   if exists('b:verilog_indent_modules')
     let indent_modules = offset
index 4174a24..5a8bc0f 100644 (file)
@@ -1,7 +1,7 @@
 " Vim indent file
-" Language:         XFree86 Configuration File
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-12-20
+" Language:             XFree86 Configuration File
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-12-20
 
 if exists("b:did_indent")
   finish
@@ -26,11 +26,11 @@ function GetXF86ConfIndent()
   let ind = indent(lnum)
 
   if getline(lnum) =~? '^\s*\(Sub\)\=Section\>'
-    let ind = ind + &sw
+    let ind = ind + shiftwidth()
   endif
 
   if getline(v:lnum) =~? '^\s*End\(Sub\)\=Section\>'
-    let ind = ind - &sw
+    let ind = ind - shiftwidth()
   endif
 
   return ind
index c812723..977ee3d 100644 (file)
@@ -1,7 +1,7 @@
 " Vim indent file
-" Language:         xinetd.conf(5) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-12-20
+" Language:             xinetd.conf(5) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-12-20
 
 if exists("b:did_indent")
   finish
@@ -47,8 +47,8 @@ function GetXinetdIndent()
     return 0
   endif
 
-  return indent(pnum) + s:count_braces(pnum, 1) * &sw
-        \ - s:count_braces(v:lnum, 0) * &sw
+  return indent(pnum) + s:count_braces(pnum, 1) * shiftwidth()
+        \ - s:count_braces(v:lnum, 0) * shiftwidth()
 endfunction
 
 let &cpo = s:keepcpo
index 2ab7d7b..01ad4fc 100644 (file)
@@ -1,7 +1,7 @@
 " Vim indent file
-" Language:         YACC input file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-12-20
+" Language:             YACC input file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-12-20
 
 " Only load this indent file when no other was loaded.
 if exists("b:did_indent")
index 7b03c5a..eaa60a7 100644 (file)
@@ -1,5 +1,5 @@
 " Maintainer: Benjamin Linskey <vim@benlinskey.com>
-" Last Changed: 2016 July 20
+" Last Changed: 2016 December 5
 " URL: https://github.com/blinskey/vim-armenian-keymaps
 
 let b:keymap_name = "hy"
@@ -98,6 +98,8 @@ f   ֆ
 7   .
 8   «
 9   »
+*   (
+(   )
 \\  '
 |   ՞
 
index e02485e..cf3efdc 100644 (file)
@@ -1,5 +1,5 @@
 " Maintainer: Benjamin Linskey <vim@benlinskey.com>
-" Last Changed: 2016 July 20
+" Last Changed: 2016 December 5
 " URL: https://github.com/blinskey/vim-armenian-keymaps
 
 let b:keymap_name = "hy"
@@ -98,6 +98,8 @@ f   ֆ
 7   .
 8   «
 9   »
+*   (
+(   )
 \\  '
 |   ՞
 
index 72b53f2..53857c6 100644 (file)
@@ -1,6 +1,6 @@
 " Vim script to work like "less"
 " Maintainer:  Bram Moolenaar <Bram@vim.org>
-" Last Change: 2015 Nov 15
+" Last Change: 2017 Mar 31
 
 " Avoid loading this file twice, allow the user to define his own script.
 if exists("loaded_less")
@@ -81,6 +81,10 @@ fun! s:Help()
   echo "\n"
   echo "/pattern  Search for pattern        ?pattern  Search backward for pattern"
   echo "n         next pattern match        N         Previous pattern match"
+  if &foldmethod != "manual"
+  echo "\n"
+    echo "zR        open all folds            zm        increase fold level"
+  endif
   echo "\n"
   echo ":n<Enter> Next file                 :p<Enter> Previous file"
   echo "\n"
@@ -96,7 +100,11 @@ map <C-F> <Space>
 map <PageDown> <Space>
 map <kPageDown> <Space>
 map <S-Down> <Space>
-map z <Space>
+" If 'foldmethod' was changed keep the "z" commands, e.g. "zR" to open all
+" folds.
+if &foldmethod == "manual"
+  map z <Space>
+endif
 map <Esc><Space> <Space>
 fun! s:NextPage()
   if line(".") == line("$")
index 9cfe2e5..f6f463f 100644 (file)
@@ -1,3 +1,5 @@
 " Load the matchit package.
 " For those users who were loading the matchit plugin from here.
-packadd matchit
+if 1
+    packadd matchit
+endif
index 5c34616..87ac937 100644 (file)
@@ -2,7 +2,7 @@
 " You can also use this as a start for your own set of menus.
 "
 " Maintainer:  Bram Moolenaar <Bram@vim.org>
-" Last Change: 2016 Jul 27
+" Last Change: 2017 Mar 04
 
 " Note that ":an" (short for ":anoremenu") is often used to make a menu work
 " in all modes and avoid side effects from mappings defined by the user.
@@ -70,7 +70,7 @@ endif
 " Help menu
 an 9999.10 &Help.&Overview<Tab><F1>    :help<CR>
 an 9999.20 &Help.&User\ Manual         :help usr_toc<CR>
-an 9999.30 &Help.&How-to\ links                :help how-to<CR>
+an 9999.30 &Help.&How-To\ Links                :help how-to<CR>
 an <silent> 9999.40 &Help.&Find\.\.\.  :call <SID>Helpfind()<CR>
 an 9999.45 &Help.-sep1-                        <Nop>
 an 9999.50 &Help.&Credits              :help credits<CR>
@@ -112,7 +112,7 @@ an 10.350 &File.Save\ &As\.\.\.<Tab>:sav    :browse confirm saveas<CR>
 
 if has("diff")
   an 10.400 &File.-SEP2-                       <Nop>
-  an 10.410 &File.Split\ &Diff\ with\.\.\.     :browse vert diffsplit<CR>
+  an 10.410 &File.Split\ &Diff\ With\.\.\.     :browse vert diffsplit<CR>
   an 10.420 &File.Split\ Patched\ &By\.\.\.    :browse vert diffpatch<CR>
 endif
 
@@ -214,25 +214,25 @@ endfun
 
 " Edit/Global Settings
 an 20.440.100 &Edit.&Global\ Settings.Toggle\ Pattern\ &Highlight<Tab>:set\ hls!       :set hls! hls?<CR>
-an 20.440.110 &Edit.&Global\ Settings.Toggle\ &Ignore-case<Tab>:set\ ic!       :set ic! ic?<CR>
-an 20.440.110 &Edit.&Global\ Settings.Toggle\ &Showmatch<Tab>:set\ sm! :set sm! sm?<CR>
-
-an 20.440.120 &Edit.&Global\ Settings.&Context\ lines.\ 1\  :set so=1<CR>
-an 20.440.120 &Edit.&Global\ Settings.&Context\ lines.\ 2\  :set so=2<CR>
-an 20.440.120 &Edit.&Global\ Settings.&Context\ lines.\ 3\  :set so=3<CR>
-an 20.440.120 &Edit.&Global\ Settings.&Context\ lines.\ 4\  :set so=4<CR>
-an 20.440.120 &Edit.&Global\ Settings.&Context\ lines.\ 5\  :set so=5<CR>
-an 20.440.120 &Edit.&Global\ Settings.&Context\ lines.\ 7\  :set so=7<CR>
-an 20.440.120 &Edit.&Global\ Settings.&Context\ lines.\ 10\  :set so=10<CR>
-an 20.440.120 &Edit.&Global\ Settings.&Context\ lines.\ 100\  :set so=100<CR>
+an 20.440.110 &Edit.&Global\ Settings.Toggle\ &Ignoring\ Case<Tab>:set\ ic!    :set ic! ic?<CR>
+an 20.440.110 &Edit.&Global\ Settings.Toggle\ &Showing\ Matched\ Pairs<Tab>:set\ sm!   :set sm! sm?<CR>
+
+an 20.440.120 &Edit.&Global\ Settings.&Context\ Lines.\ 1\  :set so=1<CR>
+an 20.440.120 &Edit.&Global\ Settings.&Context\ Lines.\ 2\  :set so=2<CR>
+an 20.440.120 &Edit.&Global\ Settings.&Context\ Lines.\ 3\  :set so=3<CR>
+an 20.440.120 &Edit.&Global\ Settings.&Context\ Lines.\ 4\  :set so=4<CR>
+an 20.440.120 &Edit.&Global\ Settings.&Context\ Lines.\ 5\  :set so=5<CR>
+an 20.440.120 &Edit.&Global\ Settings.&Context\ Lines.\ 7\  :set so=7<CR>
+an 20.440.120 &Edit.&Global\ Settings.&Context\ Lines.\ 10\  :set so=10<CR>
+an 20.440.120 &Edit.&Global\ Settings.&Context\ Lines.\ 100\  :set so=100<CR>
 
 an 20.440.130.40 &Edit.&Global\ Settings.&Virtual\ Edit.Never :set ve=<CR>
 an 20.440.130.50 &Edit.&Global\ Settings.&Virtual\ Edit.Block\ Selection :set ve=block<CR>
-an 20.440.130.60 &Edit.&Global\ Settings.&Virtual\ Edit.Insert\ mode :set ve=insert<CR>
+an 20.440.130.60 &Edit.&Global\ Settings.&Virtual\ Edit.Insert\ Mode :set ve=insert<CR>
 an 20.440.130.70 &Edit.&Global\ Settings.&Virtual\ Edit.Block\ and\ Insert :set ve=block,insert<CR>
 an 20.440.130.80 &Edit.&Global\ Settings.&Virtual\ Edit.Always :set ve=all<CR>
 an 20.440.140 &Edit.&Global\ Settings.Toggle\ Insert\ &Mode<Tab>:set\ im!      :set im!<CR>
-an 20.440.145 &Edit.&Global\ Settings.Toggle\ Vi\ C&ompatible<Tab>:set\ cp!    :set cp!<CR>
+an 20.440.145 &Edit.&Global\ Settings.Toggle\ Vi\ C&ompatibility<Tab>:set\ cp! :set cp!<CR>
 an <silent> 20.440.150 &Edit.&Global\ Settings.Search\ &Path\.\.\.  :call <SID>SearchP()<CR>
 an <silent> 20.440.160 &Edit.&Global\ Settings.Ta&g\ Files\.\.\.  :call <SID>TagFiles()<CR>
 "
@@ -276,13 +276,13 @@ endfun
 
 " Boolean options
 an 20.440.100 &Edit.F&ile\ Settings.Toggle\ Line\ &Numbering<Tab>:set\ nu!     :set nu! nu?<CR>
-an 20.440.105 &Edit.F&ile\ Settings.Toggle\ relati&ve\ Line\ Numbering<Tab>:set\ rnu!  :set rnu! rnu?<CR>
+an 20.440.105 &Edit.F&ile\ Settings.Toggle\ Relati&ve\ Line\ Numbering<Tab>:set\ rnu!  :set rnu! rnu?<CR>
 an 20.440.110 &Edit.F&ile\ Settings.Toggle\ &List\ Mode<Tab>:set\ list!        :set list! list?<CR>
-an 20.440.120 &Edit.F&ile\ Settings.Toggle\ Line\ &Wrap<Tab>:set\ wrap!        :set wrap! wrap?<CR>
-an 20.440.130 &Edit.F&ile\ Settings.Toggle\ W&rap\ at\ word<Tab>:set\ lbr!     :set lbr! lbr?<CR>
-an 20.440.160 &Edit.F&ile\ Settings.Toggle\ &expand-tab<Tab>:set\ et!  :set et! et?<CR>
-an 20.440.170 &Edit.F&ile\ Settings.Toggle\ &auto-indent<Tab>:set\ ai! :set ai! ai?<CR>
-an 20.440.180 &Edit.F&ile\ Settings.Toggle\ &C-indenting<Tab>:set\ cin!        :set cin! cin?<CR>
+an 20.440.120 &Edit.F&ile\ Settings.Toggle\ Line\ &Wrapping<Tab>:set\ wrap!    :set wrap! wrap?<CR>
+an 20.440.130 &Edit.F&ile\ Settings.Toggle\ W&rapping\ at\ Word<Tab>:set\ lbr! :set lbr! lbr?<CR>
+an 20.440.160 &Edit.F&ile\ Settings.Toggle\ Tab\ &Expanding<Tab>:set\ et!      :set et! et?<CR>
+an 20.440.170 &Edit.F&ile\ Settings.Toggle\ &Auto\ Indenting<Tab>:set\ ai!     :set ai! ai?<CR>
+an 20.440.180 &Edit.F&ile\ Settings.Toggle\ &C-Style\ Indenting<Tab>:set\ cin! :set cin! cin?<CR>
 
 " other options
 an 20.440.600 &Edit.F&ile\ Settings.-SEP2-             <Nop>
@@ -311,7 +311,7 @@ fun! s:TextWidth()
     " Remove leading zeros to avoid it being used as an octal number.
     " But keep a zero by itself.
     let tw = substitute(n, "^0*", "", "")
-    let &tw = tw == '' ? 0 : tw 
+    let &tw = tw == '' ? 0 : tw
   endif
 endfun
 
@@ -396,10 +396,10 @@ if !exists("g:ctags_command")
   endif
 endif
 
-an 40.300 &Tools.&Jump\ to\ this\ tag<Tab>g^]  g<C-]>
-vunmenu &Tools.&Jump\ to\ this\ tag<Tab>g^]
-vnoremenu &Tools.&Jump\ to\ this\ tag<Tab>g^]  g<C-]>
-an 40.310 &Tools.Jump\ &back<Tab>^T            <C-T>
+an 40.300 &Tools.&Jump\ to\ This\ Tag<Tab>g^]  g<C-]>
+vunmenu &Tools.&Jump\ to\ This\ Tag<Tab>g^]
+vnoremenu &Tools.&Jump\ to\ This\ Tag<Tab>g^]  g<C-]>
+an 40.310 &Tools.Jump\ &Back<Tab>^T            <C-T>
 an 40.320 &Tools.Build\ &Tags\ File            :exe "!" . g:ctags_command<CR>
 
 if has("folding") || has("spell")
@@ -410,17 +410,17 @@ endif
 if has("spell")
   an 40.335.110 &Tools.&Spelling.&Spell\ Check\ On             :set spell<CR>
   an 40.335.120 &Tools.&Spelling.Spell\ Check\ &Off            :set nospell<CR>
-  an 40.335.130 &Tools.&Spelling.To\ &Next\ error<Tab>]s       ]s
-  an 40.335.130 &Tools.&Spelling.To\ &Previous\ error<Tab>[s   [s
+  an 40.335.130 &Tools.&Spelling.To\ &Next\ Error<Tab>]s       ]s
+  an 40.335.130 &Tools.&Spelling.To\ &Previous\ Error<Tab>[s   [s
   an 40.335.140 &Tools.&Spelling.Suggest\ &Corrections<Tab>z=  z=
-  an 40.335.150 &Tools.&Spelling.&Repeat\ correction<Tab>:spellrepall  :spellrepall<CR>
+  an 40.335.150 &Tools.&Spelling.&Repeat\ Correction<Tab>:spellrepall  :spellrepall<CR>
   an 40.335.200 &Tools.&Spelling.-SEP1-                                <Nop>
-  an 40.335.210 &Tools.&Spelling.Set\ language\ to\ "en"       :set spl=en spell<CR>
-  an 40.335.220 &Tools.&Spelling.Set\ language\ to\ "en_au"    :set spl=en_au spell<CR>
-  an 40.335.230 &Tools.&Spelling.Set\ language\ to\ "en_ca"    :set spl=en_ca spell<CR>
-  an 40.335.240 &Tools.&Spelling.Set\ language\ to\ "en_gb"    :set spl=en_gb spell<CR>
-  an 40.335.250 &Tools.&Spelling.Set\ language\ to\ "en_nz"    :set spl=en_nz spell<CR>
-  an 40.335.260 &Tools.&Spelling.Set\ language\ to\ "en_us"    :set spl=en_us spell<CR>
+  an 40.335.210 &Tools.&Spelling.Set\ Language\ to\ "en"       :set spl=en spell<CR>
+  an 40.335.220 &Tools.&Spelling.Set\ Language\ to\ "en_au"    :set spl=en_au spell<CR>
+  an 40.335.230 &Tools.&Spelling.Set\ Language\ to\ "en_ca"    :set spl=en_ca spell<CR>
+  an 40.335.240 &Tools.&Spelling.Set\ Language\ to\ "en_gb"    :set spl=en_gb spell<CR>
+  an 40.335.250 &Tools.&Spelling.Set\ Language\ to\ "en_nz"    :set spl=en_nz spell<CR>
+  an 40.335.260 &Tools.&Spelling.Set\ Language\ to\ "en_us"    :set spl=en_us spell<CR>
   an <silent> 40.335.270 &Tools.&Spelling.&Find\ More\ Languages       :call <SID>SpellLang()<CR>
 
   let s:undo_spellang = ['aun &Tools.&Spelling.&Find\ More\ Languages']
@@ -437,7 +437,7 @@ if has("spell")
     endif
 
     if !exists("g:menutrans_set_lang_to")
-      let g:menutrans_set_lang_to = 'Set language to'
+      let g:menutrans_set_lang_to = 'Set Language to'
     endif
 
     let found = 0
@@ -474,14 +474,14 @@ endif
 " Tools.Fold Menu
 if has("folding")
   " open close folds
-  an 40.340.110 &Tools.&Folding.&Enable/Disable\ folds<Tab>zi          zi
+  an 40.340.110 &Tools.&Folding.&Enable/Disable\ Folds<Tab>zi          zi
   an 40.340.120 &Tools.&Folding.&View\ Cursor\ Line<Tab>zv             zv
-  an 40.340.120 &Tools.&Folding.Vie&w\ Cursor\ Line\ only<Tab>zMzx     zMzx
-  inoremenu 40.340.120 &Tools.&Folding.Vie&w\ Cursor\ Line\ only<Tab>zMzx  <C-O>zM<C-O>zx
-  an 40.340.130 &Tools.&Folding.C&lose\ more\ folds<Tab>zm             zm
-  an 40.340.140 &Tools.&Folding.&Close\ all\ folds<Tab>zM              zM
-  an 40.340.150 &Tools.&Folding.O&pen\ more\ folds<Tab>zr              zr
-  an 40.340.160 &Tools.&Folding.&Open\ all\ folds<Tab>zR               zR
+  an 40.340.120 &Tools.&Folding.Vie&w\ Cursor\ Line\ Only<Tab>zMzx     zMzx
+  inoremenu 40.340.120 &Tools.&Folding.Vie&w\ Cursor\ Line\ Only<Tab>zMzx  <C-O>zM<C-O>zx
+  an 40.340.130 &Tools.&Folding.C&lose\ More\ Folds<Tab>zm             zm
+  an 40.340.140 &Tools.&Folding.&Close\ All\ Folds<Tab>zM              zM
+  an 40.340.150 &Tools.&Folding.O&pen\ More\ Folds<Tab>zr              zr
+  an 40.340.160 &Tools.&Folding.&Open\ All\ Folds<Tab>zR               zR
   " fold method
   an 40.340.200 &Tools.&Folding.-SEP1-                 <Nop>
   an 40.340.210 &Tools.&Folding.Fold\ Met&hod.M&anual  :set fdm=manual<CR>
@@ -496,14 +496,14 @@ if has("folding")
   an 40.340.240 &Tools.&Folding.Delete\ &All\ Folds<Tab>zD     zD
   " moving around in folds
   an 40.340.300 &Tools.&Folding.-SEP2-                         <Nop>
-  an 40.340.310.10 &Tools.&Folding.Fold\ col&umn\ width.\ &0\  :set fdc=0<CR>
-  an 40.340.310.20 &Tools.&Folding.Fold\ col&umn\ width.\ &2\  :set fdc=2<CR>
-  an 40.340.310.30 &Tools.&Folding.Fold\ col&umn\ width.\ &3\  :set fdc=3<CR>
-  an 40.340.310.40 &Tools.&Folding.Fold\ col&umn\ width.\ &4\  :set fdc=4<CR>
-  an 40.340.310.50 &Tools.&Folding.Fold\ col&umn\ width.\ &5\  :set fdc=5<CR>
-  an 40.340.310.60 &Tools.&Folding.Fold\ col&umn\ width.\ &6\  :set fdc=6<CR>
-  an 40.340.310.70 &Tools.&Folding.Fold\ col&umn\ width.\ &7\  :set fdc=7<CR>
-  an 40.340.310.80 &Tools.&Folding.Fold\ col&umn\ width.\ &8\  :set fdc=8<CR>
+  an 40.340.310.10 &Tools.&Folding.Fold\ Col&umn\ Width.\ &0\  :set fdc=0<CR>
+  an 40.340.310.20 &Tools.&Folding.Fold\ Col&umn\ Width.\ &2\  :set fdc=2<CR>
+  an 40.340.310.30 &Tools.&Folding.Fold\ Col&umn\ Width.\ &3\  :set fdc=3<CR>
+  an 40.340.310.40 &Tools.&Folding.Fold\ Col&umn\ Width.\ &4\  :set fdc=4<CR>
+  an 40.340.310.50 &Tools.&Folding.Fold\ Col&umn\ Width.\ &5\  :set fdc=5<CR>
+  an 40.340.310.60 &Tools.&Folding.Fold\ Col&umn\ Width.\ &6\  :set fdc=6<CR>
+  an 40.340.310.70 &Tools.&Folding.Fold\ Col&umn\ Width.\ &7\  :set fdc=7<CR>
+  an 40.340.310.80 &Tools.&Folding.Fold\ Col&umn\ Width.\ &8\  :set fdc=8<CR>
 endif  " has folding
 
 if has("diff")
@@ -531,7 +531,7 @@ an 40.430.70 &Tools.Error\ &Window.&Close<Tab>:cclose       :cclose<CR>
 an 40.520 &Tools.-SEP3-                                        <Nop>
 an <silent> 40.530 &Tools.&Convert\ to\ HEX<Tab>:%!xxd
        \ :call <SID>XxdConv()<CR>
-an <silent> 40.540 &Tools.Conve&rt\ back<Tab>:%!xxd\ -r
+an <silent> 40.540 &Tools.Conve&rt\ Back<Tab>:%!xxd\ -r
        \ :call <SID>XxdBack()<CR>
 
 " Use a function to do the conversion, so that it also works with 'insertmode'
@@ -588,7 +588,7 @@ while strlen(s:n) > 0
   endif
   " Ignore case for VMS and windows
   let s:name = substitute(s:name, '\c.*[/\\:\]]\([^/\\:]*\)\.vim', '\1', '')
-  exe "an 30.440." . s:idx . ' &Tools.Se&T\ Compiler.' . s:name . " :compiler " . s:name . "<CR>"
+  exe "an 30.440." . s:idx . ' &Tools.Se&t\ Compiler.' . s:name . " :compiler " . s:name . "<CR>"
   unlet s:name
   unlet s:i
   let s:idx = s:idx + 10
@@ -829,8 +829,8 @@ an 70.345 &Window.Close\ &Other(s)<Tab>^Wo          :confirm only<CR>
 an 70.350 &Window.-SEP2-                               <Nop>
 an 70.355 &Window.Move\ &To.&Top<Tab>^WK               <C-W>K
 an 70.355 &Window.Move\ &To.&Bottom<Tab>^WJ            <C-W>J
-an 70.355 &Window.Move\ &To.&Left\ side<Tab>^WH                <C-W>H
-an 70.355 &Window.Move\ &To.&Right\ side<Tab>^WL       <C-W>L
+an 70.355 &Window.Move\ &To.&Left\ Side<Tab>^WH                <C-W>H
+an 70.355 &Window.Move\ &To.&Right\ Side<Tab>^WL       <C-W>L
 an 70.360 &Window.Rotate\ &Up<Tab>^WR                  <C-W>R
 an 70.362 &Window.Rotate\ &Down<Tab>^Wr                        <C-W>r
 an 70.365 &Window.-SEP3-                               <Nop>
@@ -913,7 +913,7 @@ if has("spell")
        let s:suglist = spellsuggest(w, 10)
       endif
       if len(s:suglist) > 0
-       let s:changeitem = 'change\ "' . escape(w, ' .'). '"\ to'
+       let s:changeitem = 'Change\ "' . escape(w, ' .'). '"\ to'
        let s:fromword = w
        let pri = 1
        " set 'cpo' to include the <CR>
@@ -925,10 +925,10 @@ if has("spell")
          let pri += 1
        endfor
 
-       let s:additem = 'add\ "' . escape(w, ' .') . '"\ to\ word\ list'
+       let s:additem = 'Add\ "' . escape(w, ' .') . '"\ to\ Word\ List'
        exe 'anoremenu 1.6 PopUp.' . s:additem . ' :spellgood ' . w . '<CR>'
 
-       let s:ignoreitem = 'ignore\ "' . escape(w, ' .') . '"'
+       let s:ignoreitem = 'Ignore\ "' . escape(w, ' .') . '"'
        exe 'anoremenu 1.7 PopUp.' . s:ignoreitem . ' :spellgood! ' . w . '<CR>'
 
        anoremenu 1.8 PopUp.-SpellSep- :
@@ -1067,7 +1067,7 @@ endif " !exists("did_install_default_menus")
 if !exists("did_install_syntax_menu")
   an 50.212 &Syntax.&Manual            :syn manual<CR>
   an 50.214 &Syntax.A&utomatic         :syn on<CR>
-  an <silent> 50.216 &Syntax.on/off\ for\ &This\ file :call <SID>SynOnOff()<CR>
+  an <silent> 50.216 &Syntax.On/Off\ for\ &This\ File :call <SID>SynOnOff()<CR>
   if !exists("*s:SynOnOff")
     fun s:SynOnOff()
       if has("syntax_items")
@@ -1095,14 +1095,14 @@ if (exists("did_load_filetypes") || exists("syntax_on"))
 if exists("do_syntax_sel_menu")
   runtime! synmenu.vim
 else
-  an 50.10 &Syntax.&Show\ filetypes\ in\ menu  :let do_syntax_sel_menu = 1<Bar>runtime! synmenu.vim<Bar>aunmenu &Syntax.&Show\ filetypes\ in\ menu<CR>
+  an 50.10 &Syntax.&Show\ File\ Types\ in\ Menu        :let do_syntax_sel_menu = 1<Bar>runtime! synmenu.vim<Bar>aunmenu &Syntax.&Show\ File\ Types\ in\ Menu<CR>
   an 50.195 &Syntax.-SEP1-             <Nop>
 endif
 
 an 50.210 &Syntax.&Off                 :syn off<CR>
 an 50.700 &Syntax.-SEP3-               <Nop>
-an 50.710 &Syntax.Co&lor\ test         :sp $VIMRUNTIME/syntax/colortest.vim<Bar>so %<CR>
-an 50.720 &Syntax.&Highlight\ test     :runtime syntax/hitest.vim<CR>
+an 50.710 &Syntax.Co&lor\ Test         :sp $VIMRUNTIME/syntax/colortest.vim<Bar>so %<CR>
+an 50.720 &Syntax.&Highlight\ Test     :runtime syntax/hitest.vim<CR>
 an 50.730 &Syntax.&Convert\ to\ HTML   :runtime syntax/2html.vim<CR>
 
 endif " !exists("did_install_syntax_menu")
index ca280d2..6dff7e7 100644 (file)
@@ -1,7 +1,7 @@
 " Set options and add mapping such that Vim behaves a lot like MS-Windows
 "
 " Maintainer:  Bram Moolenaar <Bram@vim.org>
-" Last change: 2012 Jul 25
+" Last change: 2017 Feb 09
 
 " bail out if this isn't wanted (mrsvim.vim uses this).
 if exists("g:skip_loading_mswin") && g:skip_loading_mswin
@@ -23,20 +23,22 @@ set backspace=indent,eol,start whichwrap+=<,>,[,]
 " backspace in Visual mode deletes selection
 vnoremap <BS> d
 
-" CTRL-X and SHIFT-Del are Cut
-vnoremap <C-X> "+x
-vnoremap <S-Del> "+x
+if has("clipboard")
+    " CTRL-X and SHIFT-Del are Cut
+    vnoremap <C-X> "+x
+    vnoremap <S-Del> "+x
 
-" CTRL-C and CTRL-Insert are Copy
-vnoremap <C-C> "+y
-vnoremap <C-Insert> "+y
+    " CTRL-C and CTRL-Insert are Copy
+    vnoremap <C-C> "+y
+    vnoremap <C-Insert> "+y
 
-" CTRL-V and SHIFT-Insert are Paste
-map <C-V>              "+gP
-map <S-Insert>         "+gP
+    " CTRL-V and SHIFT-Insert are Paste
+    map <C-V>          "+gP
+    map <S-Insert>             "+gP
 
-cmap <C-V>             <C-R>+
-cmap <S-Insert>                <C-R>+
+    cmap <C-V>         <C-R>+
+    cmap <S-Insert>            <C-R>+
+endif
 
 " Pasting blockwise and linewise selections is not possible in Insert and
 " Visual mode without the +virtualedit feature.  They are pasted as if they
@@ -44,8 +46,10 @@ cmap <S-Insert>              <C-R>+
 " Uses the paste.vim autoload script.
 " Use CTRL-G u to have CTRL-Z only undo the paste.
 
-exe 'inoremap <script> <C-V> <C-G>u' . paste#paste_cmd['i']
-exe 'vnoremap <script> <C-V> ' . paste#paste_cmd['v']
+if 1
+    exe 'inoremap <script> <C-V> <C-G>u' . paste#paste_cmd['i']
+    exe 'vnoremap <script> <C-V> ' . paste#paste_cmd['v']
+endif
 
 imap <S-Insert>                <C-V>
 vmap <S-Insert>                <C-V>
@@ -99,6 +103,18 @@ inoremap <C-F4> <C-O><C-W>c
 cnoremap <C-F4> <C-C><C-W>c
 onoremap <C-F4> <C-C><C-W>c
 
+if has("gui")
+  " CTRL-F is the search dialog
+  noremap <C-F> :promptfind<CR>
+  inoremap <C-F> <C-\><C-O>:promptfind<CR>
+  cnoremap <C-F> <C-\><C-C>:promptfind<CR>
+
+  " CTRL-H is the replace dialog
+  noremap <C-H> :promptrepl<CR>
+  inoremap <C-H> <C-\><C-O>:promptrepl<CR>
+  cnoremap <C-H> <C-\><C-C>:promptrepl<CR>
+endif
+
 " restore 'cpoptions'
 set cpo&
 if 1
index d759c04..2cbbd28 100644 (file)
@@ -1,7 +1,7 @@
 " These commands create the option window.
 "
 " Maintainer:  Bram Moolenaar <Bram@vim.org>
-" Last Change: 2016 Aug 21
+" Last Change: 2017 Mar 06
 
 " If there already is an option window, jump to that one.
 if bufwinnr("option-window") > 0
@@ -923,7 +923,7 @@ if has("folding")
   call append("$", "foldmarker\tmarkers used when 'foldmethod' is \"marker\"")
   call append("$", "\t(local to window)")
   call <SID>OptionL("fmr")
-  call append("$", "foldnestmax\tmaximum fold depth for when 'foldmethod is \"indent\" or \"syntax\"")
+  call append("$", "foldnestmax\tmaximum fold depth for when 'foldmethod' is \"indent\" or \"syntax\"")
   call append("$", "\t(local to window)")
   call <SID>OptionL("fdn")
 endif
@@ -1131,6 +1131,9 @@ if has("quickfix")
   call <SID>OptionG("gp", &gp)
   call append("$", "grepformat\tlist of formats for output of 'grepprg'")
   call <SID>OptionG("gfm", &gfm)
+  call append("$", "makeencoding\tencoding of the \":make\" and \":grep\" output")
+  call append("$", "\t(global or local to buffer)")
+  call <SID>OptionG("menc", &menc)
 endif
 
 
@@ -1324,6 +1327,10 @@ if exists("&perldll")
   call append("$", "perldll\tname of the Perl dynamic library")
   call <SID>OptionG("perldll", &perldll)
 endif
+if has('pythonx')
+  call append("$", "pyxversion\twhether to use Python 2 or 3")
+  call append("$", " \tset pyx=" . &wd)
+endif
 if exists("&pythondll")
   call append("$", "pythondll\tname of the Python 2 dynamic library")
   call <SID>OptionG("pythondll", &pythondll)
index 22acb06..4c9b845 100644 (file)
@@ -1,7 +1,7 @@
 "  matchit.vim: (global plugin) Extended "%" matching
-"  Last Change: 2016 Aug 21
+"  Last Change: 2017 March 26
 "  Maintainer:  Benji Fisher PhD   <benji@member.AMS.org>
-"  Version:     1.13.2, for Vim 6.3+
+"  Version:     1.13.3, for Vim 6.3+
 "              Fix from Fernando Torres included.
 "              Improvement from Ken Takata included.
 "  URL:                http://www.vim.org/script.php?script_id=39
@@ -89,12 +89,15 @@ let s:notslash = '\\\@<!\%(\\\\\)*'
 
 function! s:Match_wrapper(word, forward, mode) range
   " In s:CleanUp(), :execute "set" restore_options .
-  let restore_options = (&ic ? " " : " no") . "ignorecase"
-  if exists("b:match_ignorecase")
+  let restore_options = ""
+  if exists("b:match_ignorecase") && b:match_ignorecase != &ic
+    let restore_options .= (&ic ? " " : " no") . "ignorecase"
     let &ignorecase = b:match_ignorecase
   endif
-  let restore_options = " ve=" . &ve . restore_options
-  set ve=
+  if &ve != ''
+    let restore_options = " ve=" . &ve . restore_options
+    set ve=
+  endif
   " If this function was called from Visual mode, make sure that the cursor
   " is at the correct end of the Visual range:
   if a:mode == "v"
@@ -287,7 +290,9 @@ endfun
 " Restore options and do some special handling for Operator-pending mode.
 " The optional argument is the tail of the matching group.
 fun! s:CleanUp(options, mode, startline, startcol, ...)
-  execute "set" a:options
+  if strlen(a:options)
+    execute "set" a:options
+  endif
   " Open folds, if appropriate.
   if a:mode != "o"
     if &foldopen =~ "percent"
@@ -639,8 +644,9 @@ fun! s:MultiMatch(spflag, mode)
   if !exists("b:match_words") || b:match_words == ""
     return ""
   end
-  let restore_options = (&ic ? "" : "no") . "ignorecase"
-  if exists("b:match_ignorecase")
+  let restore_options = ""
+  if exists("b:match_ignorecase") && b:match_ignorecase != &ic
+    let restore_options .= (&ic ? " " : " no") . "ignorecase"
     let &ignorecase = b:match_ignorecase
   endif
   let startline = line(".")
index f7ee9dc..5e13b92 100644 (file)
@@ -20,29 +20,33 @@ augroup gzip
   "
   " Set binary mode before reading the file.
   " Use "gzip -d", gunzip isn't always available.
-  autocmd BufReadPre,FileReadPre       *.gz,*.bz2,*.Z,*.lzma,*.xz,*.lz setlocal bin
+  autocmd BufReadPre,FileReadPre       *.gz,*.bz2,*.Z,*.lzma,*.xz,*.lz,*.zst setlocal bin
   autocmd BufReadPost,FileReadPost     *.gz  call gzip#read("gzip -dn")
   autocmd BufReadPost,FileReadPost     *.bz2 call gzip#read("bzip2 -d")
   autocmd BufReadPost,FileReadPost     *.Z   call gzip#read("uncompress")
   autocmd BufReadPost,FileReadPost     *.lzma call gzip#read("lzma -d")
   autocmd BufReadPost,FileReadPost     *.xz  call gzip#read("xz -d")
   autocmd BufReadPost,FileReadPost     *.lz  call gzip#read("lzip -d")
+  autocmd BufReadPost,FileReadPost     *.zst call gzip#read("zstd -d --rm")
   autocmd BufWritePost,FileWritePost   *.gz  call gzip#write("gzip")
   autocmd BufWritePost,FileWritePost   *.bz2 call gzip#write("bzip2")
   autocmd BufWritePost,FileWritePost   *.Z   call gzip#write("compress -f")
   autocmd BufWritePost,FileWritePost   *.lzma call gzip#write("lzma -z")
   autocmd BufWritePost,FileWritePost   *.xz  call gzip#write("xz -z")
   autocmd BufWritePost,FileWritePost   *.lz  call gzip#write("lzip")
+  autocmd BufWritePost,FileWritePost   *.zst  call gzip#write("zstd --rm")
   autocmd FileAppendPre                        *.gz  call gzip#appre("gzip -dn")
   autocmd FileAppendPre                        *.bz2 call gzip#appre("bzip2 -d")
   autocmd FileAppendPre                        *.Z   call gzip#appre("uncompress")
   autocmd FileAppendPre                        *.lzma call gzip#appre("lzma -d")
   autocmd FileAppendPre                        *.xz   call gzip#appre("xz -d")
   autocmd FileAppendPre                        *.lz   call gzip#appre("lzip -d")
+  autocmd FileAppendPre                        *.zst call gzip#appre("zstd -d --rm")
   autocmd FileAppendPost               *.gz  call gzip#write("gzip")
   autocmd FileAppendPost               *.bz2 call gzip#write("bzip2")
   autocmd FileAppendPost               *.Z   call gzip#write("compress -f")
   autocmd FileAppendPost               *.lzma call gzip#write("lzma -z")
   autocmd FileAppendPost               *.xz call gzip#write("xz -z")
   autocmd FileAppendPost               *.lz call gzip#write("lzip")
+  autocmd FileAppendPost               *.zst call gzip#write("zstd --rm")
 augroup END
index 034cbe2..6d9e6bd 100644 (file)
@@ -40,6 +40,7 @@ augroup tar
   au BufReadCmd   *.tar.bz2            call tar#Browse(expand("<amatch>"))
   au BufReadCmd   *.tar.Z              call tar#Browse(expand("<amatch>"))
   au BufReadCmd   *.tgz                        call tar#Browse(expand("<amatch>"))
+  au BufReadCmd   *.tbz                        call tar#Browse(expand("<amatch>"))
   au BufReadCmd   *.tar.lzma   call tar#Browse(expand("<amatch>"))
   au BufReadCmd   *.tar.xz             call tar#Browse(expand("<amatch>"))
   au BufReadCmd   *.txz                        call tar#Browse(expand("<amatch>"))
index 2763828..c81253f 100644 (file)
@@ -1,7 +1,7 @@
 " Vim support file to detect file types in scripts
 "
 " Maintainer:  Bram Moolenaar <Bram@vim.org>
-" Last change: 2016 May 21
+" Last change: 2017 Mar 04
 
 " This file is called by an autocommand for every file that has just been
 " loaded into a buffer.  It checks if the type of file can be recognized by
@@ -124,6 +124,10 @@ if s:line1 =~ "^#!"
   elseif s:name =~ 'ruby'
     set ft=ruby
 
+    " JavaScript
+  elseif s:name =~ 'node\(js\)\=\>' || s:name =~ 'rhino\>'
+    set ft=javascript
+
     " BC calculator
   elseif s:name =~ '^bc\>'
     set ft=bc
@@ -156,6 +160,14 @@ if s:line1 =~ "^#!"
   elseif s:name =~ 'escript'
     set ft=erlang
 
+    " Haskell
+  elseif s:name =~ 'haskell'
+    set ft=haskell
+
+    " Scala
+  elseif s:name =~ 'scala\>'
+    set ft=scala
+
   endif
   unlet s:name
 
index 81e3667..b156cd2 100644 (file)
@@ -604,11 +604,11 @@ an 50.150.430 &Syntax.WXYZ.Zimbu :cal SetSyn("zimbu")<CR>
 
 an 50.195 &Syntax.-SEP1-                       <Nop>
 
-an <silent> 50.200 &Syntax.Set\ '&syntax'\ only :call <SID>Setsynonly()<CR>
+an <silent> 50.200 &Syntax.Set\ '&syntax'\ Only :call <SID>Setsynonly()<CR>
 fun! s:Setsynonly()
   let s:syntax_menu_synonly = 1
 endfun
-an <silent> 50.202 &Syntax.Set\ '&filetype'\ too :call <SID>Nosynonly()<CR>
+an <silent> 50.202 &Syntax.Set\ '&filetype'\ Too :call <SID>Nosynonly()<CR>
 fun! s:Nosynonly()
   if exists("s:syntax_menu_synonly")
     unlet s:syntax_menu_synonly
index 2a87d62..afe3af1 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         a2ps(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             a2ps(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index 8fd51f0..143fcc0 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         alsaconf(8) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             alsaconf(8) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index fa9c3f0..f9d095e 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         GNU Arch inventory file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2007-06-17
+" Language:             GNU Arch inventory file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2007-06-17
 
 if exists("b:current_syntax")
   finish
index 764f94b..c6a68f7 100644 (file)
@@ -1,8 +1,10 @@
 " Vim syntax file
 " Language:         AutoHotkey script file
-" Maintainer:       SungHyun Nam <goweol@gmail.com>
-" Previous Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2015-10-29
+" Maintainer:       Michael Wong
+"                   https://github.com/mmikeww/autohotkey.vim
+" Latest Revision:  2017-04-03
+" Previous Maintainers:       SungHyun Nam <goweol@gmail.com>
+"                             Nikolai Weibull <now@bitwi.se>
 
 if exists("b:current_syntax")
   finish
@@ -17,68 +19,11 @@ syn keyword autohotkeyTodo
       \ contained
       \ TODO FIXME XXX NOTE
 
-syn cluster autohotkeyCommentGroup
-      \ contains=
-      \   autohotkeyTodo,
-      \   @Spell
-
-syn match   autohotkeyComment
-      \ display
-      \ contains=@autohotkeyCommentGroup
-      \ '`\@<!;.*$'
-
-syn region  autohotkeyComment
-      \ contains=@autohotkeyCommentGroup
-      \ matchgroup=autohotkeyCommentStart
-      \ start='/\*'
-      \ end='\*/'
-
+" only these chars are valid as escape sequences:   ,%`;nrbtvaf
+" https://autohotkey.com/docs/commands/_EscapeChar.htm
 syn match   autohotkeyEscape
       \ display
-      \ '`.'
-
-syn match   autohotkeyHotkey
-      \ contains=autohotkeyKey,
-      \   autohotkeyHotkeyDelimiter
-      \ display
-      \ '^.\{-}::'
-
-syn match   autohotkeyKey
-      \ contained
-      \ display
-      \ '^.\{-}'
-
-syn match   autohotkeyDelimiter
-      \ contained
-      \ display
-      \ '::'
-
-syn match   autohotkeyHotstringDefinition
-      \ contains=autohotkeyHotstring,
-      \   autohotkeyHotstringDelimiter
-      \ display
-      \ '^:\%(B0\|C1\|K\d\+\|P\d\+\|S[IPE]\|Z\d\=\|[*?COR]\)*:.\{-}::'
-
-syn match   autohotkeyHotstring
-      \ contained
-      \ display
-      \ '.\{-}'
-
-syn match   autohotkeyHotstringDelimiter
-      \ contained
-      \ display
-      \ '::'
-
-syn match   autohotkeyHotstringDelimiter
-      \ contains=autohotkeyHotstringOptions
-      \ contained
-      \ display
-      \ ':\%(B0\|C1\|K\d\+\|P\d\+\|S[IPE]\|Z\d\=\|[*?COR]\):'
-
-syn match   autohotkeyHotstringOptions
-      \ contained
-      \ display
-      \ '\%(B0\|C1\|K\d\+\|P\d\+\|S[IPE]\|Z\d\=\|[*?COR]\)'
+      \ '`[,%`;nrbtvaf]'
 
 syn region autohotkeyString
       \ display
@@ -88,39 +33,46 @@ syn region autohotkeyString
       \ end=+"+
       \ contains=autohotkeyEscape
 
-syn region autohotkeyVariable
+syn match autohotkeyVariable
       \ display
       \ oneline
       \ contains=autohotkeyBuiltinVariable
-      \ matchgroup=autohotkeyVariableDelimiter
-      \ start="%"
-      \ end="%"
       \ keepend
+      \ '%\S\{-}%'
 
 syn keyword autohotkeyBuiltinVariable
       \ A_Space A_Tab
-      \ A_WorkingDir A_ScriptDir A_ScriptName A_ScriptFullPath A_LineNumber
-      \ A_LineFile A_AhkVersion A_AhkPAth A_IsCompiled A_ExitReason
-      \ A_YYYY A_MM A_DD A_MMMM A_MMM A_DDDD A_DDD A_WDay A_YWeek A_Hour A_Min
+      \ A_WorkingDir A_ScriptDir A_ScriptName A_ScriptFullPath A_ScriptHwnd A_LineNumber
+      \ A_LineFile A_ThisFunc A_ThisLabel A_AhkVersion A_AhkPath A_IsUnicode A_IsCompiled A_ExitReason
+      \ A_YYYY A_MM A_DD A_MMMM A_MMM A_DDDD A_DDD A_WDay A_YDay A_YWeek A_Hour A_Min
+      \ A_Mon A_Year A_MDay A_NumBatchLines
       \ A_Sec A_MSec A_Now A_NowUTC A_TickCount
-      \ A_IsSuspended A_BatchLines A_TitleMatchMode A_TitleMatchModeSpeed
-      \ A_DetectHiddenWindows A_DetectHiddenText A_AutoTrim A_STringCaseSense
-      \ A_FormatInteger A_FormatFloat A_KeyDelay A_WinDelay A_ControlDelay
-      \ A_MouseDelay A_DefaultMouseSpeed A_IconHidden A_IconTip A_IconFile
+      \ A_IsSuspended A_IsPaused A_IsCritical A_BatchLines A_TitleMatchMode A_TitleMatchModeSpeed
+      \ A_DetectHiddenWindows A_DetectHiddenText A_AutoTrim A_StringCaseSense
+      \ A_FileEncoding A_FormatInteger A_FormatFloat A_KeyDelay A_WinDelay A_ControlDelay
+      \ A_SendMode A_SendLevel A_StoreCapsLockMode A_KeyDelay A_KeyDelayDuration
+      \ A_KeyDelayPlay A_KeyDelayPlayDuration A_MouseDelayPlay
+      \ A_MouseDelay A_DefaultMouseSpeed A_RegView A_IconHidden A_IconTip A_IconFile
+      \ A_CoordModeToolTip A_CoordModePixel A_CoordModeMouse A_CoordModeCaret A_CoordModeMenu
       \ A_IconNumber
-      \ A_TimeIdle A_TimeIdlePhysical
+      \ A_TimeIdle A_TimeIdlePhysical A_DefaultGui A_DefaultListView A_DefaultTreeView
       \ A_Gui A_GuiControl A_GuiWidth A_GuiHeight A_GuiX A_GuiY A_GuiEvent
       \ A_GuiControlEvent A_EventInfo
       \ A_ThisMenuItem A_ThisMenu A_ThisMenuItemPos A_ThisHotkey A_PriorHotkey
-      \ A_TimeSinceThisHotkey A_TimeSincePriorHotkey A_EndChar
+      \ A_PriorKey A_TimeSinceThisHotkey A_TimeSincePriorHotkey A_EndChar
       \ ComSpec A_Temp A_OSType A_OSVersion A_Language A_ComputerName A_UserName
+      \ A_Is64BitOS A_PtrSize
       \ A_WinDir A_ProgramFiles ProgramFiles A_AppData A_AppDataCommon A_Desktop
       \ A_DesktopCommon A_StartMenu A_StartMenuCommon A_Programs
       \ A_ProgramsCommon A_Startup A_StartupCommon A_MyDocuments A_IsAdmin
-      \ A_ScreenWidth A_ScreenHeight A_IPAddress1 A_IPAddress2 A_IPAddress3
+      \ A_ScreenWidth A_ScreenHeight A_ScreenDPI A_IPAddress1 A_IPAddress2 A_IPAddress3
       \ A_IPAddress4
       \ A_Cursor A_CaretX A_CaretY Clipboard ClipboardAll ErrorLevel A_LastError
       \ A_Index A_LoopFileName A_LoopRegName A_LoopReadLine A_LoopField
+      \ A_LoopFileExt A_LoopFileFullPath A_LoopFileLongPath A_LoopFileShortPath
+      \ A_LoopFileShortName A_LoopFileDir A_LoopFileTimeModified A_LoopFileTimeCreated
+      \ A_LoopFileTimeAccessed A_LoopFileAttrib A_LoopFileSize A_LoopFileSizeKB A_LoopFileSizeMB
+      \ A_LoopRegType A_LoopRegKey A_LoopRegSubKey A_LoopRegTimeModified
 
 syn match   autohotkeyBuiltinVariable
       \ contained
@@ -130,7 +82,7 @@ syn match   autohotkeyBuiltinVariable
 syn keyword autohotkeyCommand
       \ ClipWait EnvGet EnvSet EnvUpdate
       \ Drive DriveGet DriveSpaceFree FileAppend FileCopy FileCopyDir
-      \ FileCreateDir FileCreateShortcut FileDelete FileGetAttrib
+      \ FileCreateDir FileCreateShortcut FileDelete FileGetAttrib FileEncoding
       \ FileGetShortcut FileGetSize FileGetTime FileGetVersion FileInstall
       \ FileMove FileMoveDir FileReadLine FileRead FileRecycle FileRecycleEmpty
       \ FileRemoveDir FileSelectFolder FileSelectFile FileSetAttrib FileSetTime
@@ -153,7 +105,8 @@ syn keyword autohotkeyCommand
       \ SoundSetWaveVolume
       \ FormatTime IfInString IfNotInString Sort StringCaseSense StringGetPos
       \ StringLeft StringRight StringLower StringUpper StringMid StringReplace
-      \ StringSplit StringTrimLeft StringTrimRight
+      \ StringSplit StringTrimLeft StringTrimRight StringLen
+      \ StrSplit StrReplace Throw
       \ Control ControlClick ControlFocus ControlGet ControlGetFocus
       \ ControlGetPos ControlGetText ControlMove ControlSend ControlSendRaw
       \ ControlSetText Menu PostMessage SendMessage SetControlDelay
@@ -164,23 +117,30 @@ syn keyword autohotkeyCommand
       \ WinGetText WinGetTitle WinHide WinKill WinMaximize WinMinimize
       \ WinMinimizeAll WinMinimizeAllUndo WinMove WinRestore WinSet
       \ WinSetTitle WinShow WinWait WinWaitActive WinWaitNotActive WinWaitClose
+      \ SetCapsLockState SetNumLockState SetScrollLockState
 
 syn keyword autohotkeyFunction
-      \ InStr RegExMatch RegExReplace StrLen SubStr Asc Chr
+      \ InStr RegExMatch RegExReplace StrLen SubStr Asc Chr Func
       \ DllCall VarSetCapacity WinActive WinExist IsLabel OnMessage 
       \ Abs Ceil Exp Floor Log Ln Mod Round Sqrt Sin Cos Tan ASin ACos ATan
-      \ FileExist GetKeyState
+      \ FileExist GetKeyState NumGet NumPut StrGet StrPut RegisterCallback
+      \ IsFunc Trim LTrim RTrim IsObject Object Array FileOpen
+      \ ComObjActive ComObjArray ComObjConnect ComObjCreate ComObjGet
+      \ ComObjError ComObjFlags ComObjQuery ComObjType ComObjValue ComObject
+      \ Format Exception
 
 syn keyword autohotkeyStatement
       \ Break Continue Exit ExitApp Gosub Goto OnExit Pause Return
-      \ Suspend Reload
+      \ Suspend Reload new class extends
 
 syn keyword autohotkeyRepeat
       \ Loop
 
 syn keyword autohotkeyConditional
       \ IfExist IfNotExist If IfEqual IfLess IfGreater Else
-      \ IfWinExist IfWinNotExist
+      \ IfWinExist IfWinNotExist IfWinActive IfWinNotActive
+      \ IfNotEqual IfLessOrEqual IfGreaterOrEqual
+      \ while until for in try catch finally
 
 syn match   autohotkeyPreProcStart
       \ nextgroup=
@@ -200,6 +160,7 @@ syn keyword autohotkeyPreProc
       \ HotkeyInterval HotKeyModifierTimeout
       \ Hotstring
       \ IfWinActive IfWinNotActive IfWinExist IfWinNotExist
+      \ If IfTimeout
       \ MaxHotkeysPerInterval MaxThreads MaxThreadsBuffer MaxThreadsPerHotkey
       \ UseHook InstallKeybdHook InstallMouseHook
       \ KeyHistory
@@ -213,9 +174,13 @@ syn keyword autohotkeyPreProc
       \ MaxMem
       \ NoEnv
       \ Persistent
+      \ LTrim
+      \ InputLevel
+      \ MenuMaskKey
+      \ Warn
 
 syn keyword autohotkeyMatchClass
-      \ ahk_group ahk_class ahk_id ahk_pid
+      \ ahk_group ahk_class ahk_id ahk_pid ahk_exe
 
 syn match   autohotkeyNumbers
       \ display
@@ -243,11 +208,74 @@ syn match   autohotkeyFloat
 syn keyword autohotkeyType
       \ local
       \ global
+      \ static
+      \ byref
 
 syn keyword autohotkeyBoolean
       \ true
       \ false
 
+syn match   autohotkeyHotkey
+      \ contains=autohotkeyKey,
+      \   autohotkeyHotkeyDelimiter
+      \ display
+      \ '^\s*\S*\%( Up\)\?::'
+
+syn match   autohotkeyKey
+      \ contained
+      \ display
+      \ '^.\{-}'
+
+syn match   autohotkeyDelimiter
+      \ contained
+      \ display
+      \ '::'
+
+" allowable hotstring options:
+" https://autohotkey.com/docs/Hotstrings.htm
+syn match   autohotkeyHotstringDefinition
+      \ contains=autohotkeyHotstring,
+      \   autohotkeyHotstringDelimiter
+      \ display
+      \ '^\s*:\%([*?]\|[BORZ]0\?\|C[01]\?\|K\d\+\|P\d\+\|S[IPE]\)*:.\{-}::'
+
+syn match   autohotkeyHotstring
+      \ contained
+      \ display
+      \ '.\{-}'
+
+syn match   autohotkeyHotstringDelimiter
+      \ contained
+      \ display
+      \ '::'
+
+syn match   autohotkeyHotstringDelimiter
+      \ contains=autohotkeyHotstringOptions
+      \ contained
+      \ display
+      \ ':\%([*?]\|[BORZ]0\?\|C[01]\?\|K\d\+\|P\d\+\|S[IPE]\)*:'
+
+syn match   autohotkeyHotstringOptions
+      \ contained
+      \ display
+      \ '\%([*?]\|[BORZ]0\?\|C[01]\?\|K\d\+\|P\d\+\|S[IPE]\)*'
+
+syn cluster autohotkeyCommentGroup
+      \ contains=
+      \   autohotkeyTodo,
+      \   @Spell
+
+syn match   autohotkeyComment
+      \ display
+      \ contains=@autohotkeyCommentGroup
+      \ '\%(^;\|\s\+;\).*$'
+
+syn region  autohotkeyComment
+      \ contains=@autohotkeyCommentGroup
+      \ matchgroup=autohotkeyCommentStart
+      \ start='^\s*/\*'
+      \ end='^\s*\*/'
+
 " TODO: Shouldn't we look for g:, b:,  variables before defaulting to
 " something?
 if exists("g:autohotkey_syntax_sync_minlines")
index d0c73eb..cc1a337 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         BDF font definition
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             BDF font definition
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index 2b946dd..16c7ce4 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
 " Language:    C
 " Maintainer:  Bram Moolenaar <Bram@vim.org>
-" Last Change: 2016 Oct 27
+" Last Change: 2016 Nov 18
 
 " Quit when a (custom) syntax file was already loaded
 if exists("b:current_syntax")
@@ -363,23 +363,23 @@ syn match cPreConditMatch display "^\s*\zs\(%:\|#\)\s*\(else\|endif\)\>"
 if !exists("c_no_if0")
   syn cluster  cCppOutInGroup  contains=cCppInIf,cCppInElse,cCppInElse2,cCppOutIf,cCppOutIf2,cCppOutElse,cCppInSkip,cCppOutSkip
   syn region   cCppOutWrapper  start="^\s*\zs\(%:\|#\)\s*if\s\+0\+\s*\($\|//\|/\*\|&\)" end=".\@=\|$" contains=cCppOutIf,cCppOutElse,@NoSpell fold
-  syn region   cCppOutIf       contained start="0\+" matchgroup=cCppOutWrapper end="^\s*\zs\(%:\|#\)\s*endif\>" contains=cCppOutIf2,cCppOutElse
+  syn region   cCppOutIf       contained start="0\+" matchgroup=cCppOutWrapper end="^\s*\(%:\|#\)\s*endif\>" contains=cCppOutIf2,cCppOutElse
   if !exists("c_no_if0_fold")
-    syn region cCppOutIf2      contained matchgroup=cCppOutWrapper start="0\+" end="^\s*\zs\(%:\|#\)\s*\(else\>\|elif\s\+\(0\+\s*\($\|//\|/\*\|&\)\)\@!\|endif\>\)"me=s-1 contains=cSpaceError,cCppOutSkip,@Spell fold
+    syn region cCppOutIf2      contained matchgroup=cCppOutWrapper start="0\+" end="^\s*\(%:\|#\)\s*\(else\>\|elif\s\+\(0\+\s*\($\|//\|/\*\|&\)\)\@!\|endif\>\)"me=s-1 contains=cSpaceError,cCppOutSkip,@Spell fold
   else
     syn region cCppOutIf2      contained matchgroup=cCppOutWrapper start="0\+" end="^\s*\(%:\|#\)\s*\(else\>\|elif\s\+\(0\+\s*\($\|//\|/\*\|&\)\)\@!\|endif\>\)"me=s-1 contains=cSpaceError,cCppOutSkip,@Spell
   endif
-  syn region   cCppOutElse     contained matchgroup=cCppOutWrapper start="^\s*\zs\(%:\|#\)\s*\(else\|elif\)" end="^\s*\zs\(%:\|#\)\s*endif\>"me=s-1 contains=TOP,cPreCondit
+  syn region   cCppOutElse     contained matchgroup=cCppOutWrapper start="^\s*\(%:\|#\)\s*\(else\|elif\)" end="^\s*\(%:\|#\)\s*endif\>"me=s-1 contains=TOP,cPreCondit
   syn region   cCppInWrapper   start="^\s*\zs\(%:\|#\)\s*if\s\+0*[1-9]\d*\s*\($\|//\|/\*\||\)" end=".\@=\|$" contains=cCppInIf,cCppInElse fold
-  syn region   cCppInIf        contained matchgroup=cCppInWrapper start="\d\+" end="^\s*\zs\(%:\|#\)\s*endif\>" contains=TOP,cPreCondit
+  syn region   cCppInIf        contained matchgroup=cCppInWrapper start="\d\+" end="^\s*\(%:\|#\)\s*endif\>" contains=TOP,cPreCondit
   if !exists("c_no_if0_fold")
-    syn region cCppInElse      contained start="^\s*\zs\(%:\|#\)\s*\(else\>\|elif\s\+\(0*[1-9]\d*\s*\($\|//\|/\*\||\)\)\@!\)" end=".\@=\|$" containedin=cCppInIf contains=cCppInElse2 fold
+    syn region cCppInElse      contained start="^\s*\(%:\|#\)\s*\(else\>\|elif\s\+\(0*[1-9]\d*\s*\($\|//\|/\*\||\)\)\@!\)" end=".\@=\|$" containedin=cCppInIf contains=cCppInElse2 fold
   else
-    syn region cCppInElse      contained start="^\s*\zs\(%:\|#\)\s*\(else\>\|elif\s\+\(0*[1-9]\d*\s*\($\|//\|/\*\||\)\)\@!\)" end=".\@=\|$" containedin=cCppInIf contains=cCppInElse2
+    syn region cCppInElse      contained start="^\s*\(%:\|#\)\s*\(else\>\|elif\s\+\(0*[1-9]\d*\s*\($\|//\|/\*\||\)\)\@!\)" end=".\@=\|$" containedin=cCppInIf contains=cCppInElse2
   endif
-  syn region   cCppInElse2     contained matchgroup=cCppInWrapper start="^\s*\zs\(%:\|#\)\s*\(else\|elif\)\([^/]\|/[^/*]\)*" end="^\s*\zs\(%:\|#\)\s*endif\>"me=s-1 contains=cSpaceError,cCppOutSkip,@Spell
-  syn region   cCppOutSkip     contained start="^\s*\zs\(%:\|#\)\s*\(if\>\|ifdef\>\|ifndef\>\)" skip="\\$" end="^\s*\zs\(%:\|#\)\s*endif\>" contains=cSpaceError,cCppOutSkip
-  syn region   cCppInSkip      contained matchgroup=cCppInWrapper start="^\s*\zs\(%:\|#\)\s*\(if\s\+\(\d\+\s*\($\|//\|/\*\||\|&\)\)\@!\|ifdef\>\|ifndef\>\)" skip="\\$" end="^\s*\zs\(%:\|#\)\s*endif\>" containedin=cCppOutElse,cCppInIf,cCppInSkip contains=TOP,cPreProc
+  syn region   cCppInElse2     contained matchgroup=cCppInWrapper start="^\s*\(%:\|#\)\s*\(else\|elif\)\([^/]\|/[^/*]\)*" end="^\s*\(%:\|#\)\s*endif\>"me=s-1 contains=cSpaceError,cCppOutSkip,@Spell
+  syn region   cCppOutSkip     contained start="^\s*\(%:\|#\)\s*\(if\>\|ifdef\>\|ifndef\>\)" skip="\\$" end="^\s*\(%:\|#\)\s*endif\>" contains=cSpaceError,cCppOutSkip
+  syn region   cCppInSkip      contained matchgroup=cCppInWrapper start="^\s*\(%:\|#\)\s*\(if\s\+\(\d\+\s*\($\|//\|/\*\||\|&\)\)\@!\|ifdef\>\|ifndef\>\)" skip="\\$" end="^\s*\(%:\|#\)\s*endif\>" containedin=cCppOutElse,cCppInIf,cCppInSkip contains=TOP,cPreProc
 endif
 syn region     cIncluded       display contained start=+"+ skip=+\\\\\|\\"+ end=+"+
 syn match      cIncluded       display contained "<[^>]*>"
index 588b41a..4250109 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         calendar(1) input file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             calendar(1) input file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index 5058c23..0fa6510 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         cdrdao(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2007-09-02
+" Language:             cdrdao(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2007-09-02
 
 if exists("b:current_syntax")
   finish
index fa752db..866784d 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         cdrdao(1) TOC file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2007-05-10
+" Language:             cdrdao(1) TOC file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2007-05-10
 
 if exists("b:current_syntax")
   finish
index e36a69c..b821aff 100644 (file)
@@ -1,6 +1,6 @@
 " Vim syntax file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2007-06-17
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2007-06-17
 
 if exists("b:current_syntax")
   finish
index 17b67d4..5285de3 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         CRM114
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             CRM114
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index 3dc3f5c..23db7b1 100644 (file)
@@ -6,7 +6,8 @@
 "               Nikolai Weibull (Add CSS2 support)
 " Maintainer:   Jules Wang      <w.jq0722@gmail.com>
 " URL:          https://github.com/JulesWang/css.vim
-" Last Change:  2015 Apr.17
+" Last Change:  2017 Jan 14
+"              cssClassName updated by Ryuichi Hayashida Jan 2016
 
 " quit when a syntax file was already loaded
 if !exists("main_syntax")
@@ -56,7 +57,7 @@ syn match cssSelectorOp2 "[~|^$*]\?=" contained
 syn region cssAttributeSelector matchgroup=cssSelectorOp start="\[" end="]" contains=cssUnicodeEscape,cssSelectorOp2,cssStringQ,cssStringQQ
 
 " .class and #id
-syn match cssClassName "\.[A-Za-z][A-Za-z0-9_-]\+" contains=cssClassNameDot
+syn match cssClassName "\.-\=[A-Za-z_][A-Za-z0-9_-]*" contains=cssClassNameDot
 syn match cssClassNameDot contained '\.'
 
 try
index 6c2c4ee..9522de6 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         cvs(1) RC file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             cvs(1) RC file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index a10e4ad..eb02aaf 100644 (file)
@@ -3,7 +3,7 @@
 " Maintainer:  Debian Vim Maintainers <pkg-vim-maintainers@lists.alioth.debian.org>
 " Former Maintainers: Gerfried Fuchs <alfie@ist.org>
 "                     Wichert Akkerman <wakkerma@debian.org>
-" Last Change: 2016 Aug 30
+" Last Change: 2016 Nov 12
 " URL: https://anonscm.debian.org/cgit/pkg-vim/vim.git/plain/runtime/syntax/debchangelog.vim
 
 " Standard syntax initialization
@@ -21,7 +21,7 @@ let binNMU='binary-only=yes'
 syn match debchangelogName     contained "^[[:alnum:]][[:alnum:].+-]\+ "
 exe 'syn match debchangelogFirstKV     contained "; \('.urgency.'\|'.binNMU.'\)"'
 exe 'syn match debchangelogOtherKV     contained ", \('.urgency.'\|'.binNMU.'\)"'
-syn match debchangelogTarget   contained "\v %(frozen|unstable|sid|%(testing|%(old)=stable)%(-proposed-updates|-security)=|experimental|squeeze-%(backports%(-sloppy)=|volatile|lts|security)|wheezy-%(backports%(-sloppy)=|security)|jessie%(-backports|-security)=|stretch|%(devel|precise|trusty|vivid|wily|xenial|yakkety)%(-%(security|proposed|updates|backports|commercial|partner))=)+"
+syn match debchangelogTarget   contained "\v %(frozen|unstable|sid|%(testing|%(old)=stable)%(-proposed-updates|-security)=|experimental|squeeze-%(backports%(-sloppy)=|volatile|lts|security)|wheezy-%(backports%(-sloppy)=|security)|jessie%(-backports|-security)=|stretch|%(devel|precise|trusty|vivid|wily|xenial|yakkety|zesty)%(-%(security|proposed|updates|backports|commercial|partner))=)+"
 syn match debchangelogVersion  contained "(.\{-})"
 syn match debchangelogCloses   contained "closes:\_s*\(bug\)\=#\=\_s\=\d\+\(,\_s*\(bug\)\=#\=\_s\=\d\+\)*"
 syn match debchangelogLP       contained "\clp:\s\+#\d\+\(,\s*#\d\+\)*"
index b52c496..b1bc9f8 100644 (file)
@@ -38,7 +38,7 @@ unlet s:kernels s:archs s:pairs
 syn match debcontrolMultiArch contained "\%(no\|foreign\|allowed\|same\)"
 syn match debcontrolName contained "[a-z0-9][a-z0-9+.-]\+"
 syn match debcontrolPriority contained "\(extra\|important\|optional\|required\|standard\)"
-syn match debcontrolSection contained "\v((contrib|non-free|non-US/main|non-US/contrib|non-US/non-free|restricted|universe|multiverse)/)?(admin|cli-mono|comm|database|debian-installer|debug|devel|doc|editors|education|electronics|embedded|fonts|games|gnome|gnustep|gnu-r|graphics|hamradio|haskell|httpd|interpreters|introspection|java|kde|kernel|libs|libdevel|lisp|localization|mail|math|metapackages|misc|net|news|ocaml|oldlibs|otherosfs|perl|php|python|ruby|science|shells|sound|text|tex|utils|vcs|video|web|x11|xfce|zope)"
+syn match debcontrolSection contained "\v((contrib|non-free|non-US/main|non-US/contrib|non-US/non-free|restricted|universe|multiverse)/)?(admin|cli-mono|comm|database|debian-installer|debug|devel|doc|editors|education|electronics|embedded|fonts|games|gnome|gnustep|gnu-r|graphics|hamradio|haskell|httpd|interpreters|introspection|java|javascript|kde|kernel|libs|libdevel|lisp|localization|mail|math|metapackages|misc|net|news|ocaml|oldlibs|otherosfs|perl|php|python|ruby|rust|science|shells|sound|text|tex|utils|vcs|video|web|x11|xfce|zope)"
 syn match debcontrolPackageType contained "u\?deb"
 syn match debcontrolVariable contained "\${.\{-}}"
 syn match debcontrolDmUpload contained "\cyes"
index 2777944..390c430 100644 (file)
@@ -2,7 +2,7 @@
 " Language:     Debian sources.list
 " Maintainer:   Debian Vim Maintainers <pkg-vim-maintainers@lists.alioth.debian.org>
 " Former Maintainer: Matthijs Mohlmann <matthijs@cacholong.nl>
-" Last Change: 2016 Sep 27
+" Last Change: 2016 Nov 12
 " URL: https://anonscm.debian.org/cgit/pkg-vim/vim.git/plain/runtime/syntax/debsources.vim
 
 " Standard syntax initialization
@@ -25,7 +25,7 @@ let s:supported = [
       \ 'oldstable', 'stable', 'testing', 'unstable', 'experimental',
       \ 'squeeze', 'wheezy', 'jessie', 'stretch', 'sid', 'rc-buggy',
       \
-      \ 'precise', 'trusty', 'xenial', 'yakkety', 'devel'
+      \ 'precise', 'trusty', 'xenial', 'yakkety', 'zesty', 'devel'
       \ ]
 let s:unsupported = [
       \ 'buzz', 'rex', 'bo', 'hamm', 'slink', 'potato',
index 0ec09ba..f32faab 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         denyhosts configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2007-06-25
+" Language:             denyhosts configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2007-06-25
 
 if exists("b:current_syntax")
   finish
index e7fa476..c762808 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         dict(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             dict(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index 44bf6f8..ecf5fd3 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         dictd(8) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             dictd(8) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index b4d9e02..98252a2 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         elinks(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2007-06-17
+" Language:             elinks(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2007-06-17
 
 if exists("b:current_syntax")
   finish
index 11b7634..870fcca 100644 (file)
@@ -1,9 +1,10 @@
 " Vim syntax file
 " Language:     Erlang (http://www.erlang.org)
 " Maintainer:   Csaba Hoch <csaba.hoch@gmail.com>
-" Last Update:  2013-Jul-25
+" Contributor:  Adam Rutkowski <hq@mtod.org>
+" Last Update:  2017-Mar-05
 " License:      Vim license
-" URL:          https://github.com/hcs42/vim-erlang
+" URL:          https://github.com/vim-erlang/vim-erlang-runtime
 
 " Acknowledgements: This script was originally created by Kresimir Marzic [1].
 " The script was then revamped by Csaba Hoch [2]. During the revamp, the new
@@ -46,7 +47,6 @@ syn match erlangComment           '%.*$' contains=erlangCommentAnnotation,erlang
 syn match erlangCommentAnnotation ' \@<=@\%(clear\|docfile\|end\|headerfile\|todo\|TODO\|type\|author\|copyright\|doc\|reference\|see\|since\|title\|version\|deprecated\|hidden\|private\|equiv\|spec\|throws\)' contained
 syn match erlangCommentAnnotation /`[^']*'/ contained
 syn keyword erlangTodo            TODO FIXME XXX contained
-syn match erlangShebang           '^#!.*'
 
 " Numbers (minimum base is 2, maximum is 36.)
 syn match erlangNumberInteger '\<\d\+\>'
@@ -56,12 +56,12 @@ syn match erlangNumberFloat   '\<\d\+\.\d\+\%([eE][+-]\=\d\+\)\=\>'
 " Strings, atoms, characters
 syn region erlangString            start=/"/ end=/"/ contains=erlangStringModifier
 syn region erlangQuotedAtom        start=/'/ end=/'/ contains=erlangQuotedAtomModifier
-syn match erlangStringModifier     '\~\a\|\\\%(\o\{1,3}\|x\x\x\|x{\x\+}\|\^.\|.\)' contained
-syn match erlangQuotedAtomModifier '\~\a\|\\\%(\o\{1,3}\|x\x\x\|x{\x\+}\|\^.\|.\)' contained
+syn match erlangStringModifier     '\\\%(\o\{1,3}\|x\x\x\|x{\x\+}\|\^.\|.\)\|\~\%([ni~]\|\%(-\=\d\+\|\*\)\=\.\=\%(\*\|\d\+\)\=\%(\..\)\=[tl]*[cfegswpWPBX#bx+]\)' contained
+syn match erlangQuotedAtomModifier '\\\%(\o\{1,3}\|x\x\x\|x{\x\+}\|\^.\|.\)' contained
 syn match erlangModifier           '\$\%([^\\]\|\\\%(\o\{1,3}\|x\x\x\|x{\x\+}\|\^.\|.\)\)'
 
 " Operators, separators
-syn match erlangOperator   '==\|=:=\|/=\|=/=\|<\|=<\|>\|>=\|++\|--\|=\|!\|<-\|+\|-\|\*\|\/'
+syn match erlangOperator   '==\|=:=\|/=\|=/=\|<\|=<\|>\|>=\|=>\|:=\|++\|--\|=\|!\|<-\|+\|-\|\*\|\/'
 syn keyword erlangOperator div rem or xor bor bxor bsl bsr and band not bnot andalso orelse
 syn match erlangBracket    '{\|}\|\[\|]\||\|||'
 syn match erlangPipe       '|'
@@ -72,14 +72,19 @@ syn match erlangAtom           '\<\l[[:alnum:]_@]*' contains=erlangBoolean
 syn keyword erlangBoolean      true false contained
 syn match erlangLocalFuncCall  '\<\a[[:alnum:]_@]*\>\%(\%(\s\|\n\|%.*\n\)*(\)\@=' contains=erlangBIF
 syn match erlangLocalFuncRef   '\<\a[[:alnum:]_@]*\>\%(\%(\s\|\n\|%.*\n\)*/\)\@='
-syn match erlangGlobalFuncCall '\<\%(\a[[:alnum:]_@]*\%(\s\|\n\|%.*\n\)*\.\%(\s\|\n\|%.*\n\)*\)*\a[[:alnum:]_@]*\%(\s\|\n\|%.*\n\)*:\%(\s\|\n\|%.*\n\)*\a[[:alnum:]_@]*\>\%(\%(\s\|\n\|%.*\n\)*(\)\@=' contains=erlangComment
-syn match erlangGlobalFuncRef  '\<\%(\a[[:alnum:]_@]*\%(\s\|\n\|%.*\n\)*\.\%(\s\|\n\|%.*\n\)*\)*\a[[:alnum:]_@]*\%(\s\|\n\|%.*\n\)*:\%(\s\|\n\|%.*\n\)*\a[[:alnum:]_@]*\>\%(\%(\s\|\n\|%.*\n\)*/\)\@=' contains=erlangComment
+syn match erlangGlobalFuncCall '\<\%(\a[[:alnum:]_@]*\%(\s\|\n\|%.*\n\)*\.\%(\s\|\n\|%.*\n\)*\)*\a[[:alnum:]_@]*\%(\s\|\n\|%.*\n\)*:\%(\s\|\n\|%.*\n\)*\a[[:alnum:]_@]*\>\%(\%(\s\|\n\|%.*\n\)*(\)\@=' contains=erlangComment,erlangVariable
+syn match erlangGlobalFuncRef  '\<\%(\a[[:alnum:]_@]*\%(\s\|\n\|%.*\n\)*\.\%(\s\|\n\|%.*\n\)*\)*\a[[:alnum:]_@]*\%(\s\|\n\|%.*\n\)*:\%(\s\|\n\|%.*\n\)*\a[[:alnum:]_@]*\>\%(\%(\s\|\n\|%.*\n\)*/\)\@=' contains=erlangComment,erlangVariable
 
-" Variables, macros, records
+" Variables, macros, records, maps
 syn match erlangVariable '\<[A-Z_][[:alnum:]_@]*'
 syn match erlangMacro    '??\=[[:alnum:]_@]\+'
 syn match erlangMacro    '\%(-define(\)\@<=[[:alnum:]_@]\+'
+syn match erlangMap      '#'
 syn match erlangRecord   '#\s*\l[[:alnum:]_@]*'
+syn region erlangQuotedRecord        start=/#\s*'/ end=/'/ contains=erlangQuotedAtomModifier
+
+" Shebang (this line has to be after the ErlangMap)
+syn match erlangShebang  '^#!.*'
 
 " Bitstrings
 syn match erlangBitType '\%(\/\%(\s\|\n\|%.*\n\)*\)\@<=\%(integer\|float\|binary\|bytes\|bitstring\|bits\|binary\|utf8\|utf16\|utf32\|signed\|unsigned\|big\|little\|native\|unit\)\%(\%(\s\|\n\|%.*\n\)*-\%(\s\|\n\|%.*\n\)*\%(integer\|float\|binary\|bytes\|bitstring\|bits\|binary\|utf8\|utf16\|utf32\|signed\|unsigned\|big\|little\|native\|unit\)\)*' contains=erlangComment
@@ -94,7 +99,7 @@ syn match erlangPreCondit '^\s*-\%(\s\|\n\|%.*\n\)*\%(ifdef\|ifndef\|else\|endif
 syn match erlangType      '^\s*-\%(\s\|\n\|%.*\n\)*\%(spec\|type\|opaque\|callback\)\>' contains=erlangComment
 
 " Keywords
-syn keyword erlangKeyword after begin case catch cond end fun if let of query
+syn keyword erlangKeyword after begin case catch cond end fun if let of
 syn keyword erlangKeyword receive when try
 
 " Build-in-functions (BIFs)
@@ -142,7 +147,6 @@ let b:erlang_syntax_synced = 1
 let s:old_style = (exists("g:erlang_old_style_highlight") &&
                   \g:erlang_old_style_highlight == 1)
 
-" Only when an item doesn't have highlighting yet
 
 " Comments
 hi def link erlangComment Comment
@@ -188,6 +192,8 @@ hi def link erlangGlobalFuncRef Function
 hi def link erlangVariable Normal
 hi def link erlangMacro Normal
 hi def link erlangRecord Normal
+hi def link erlangQuotedRecord Normal
+hi def link erlangMap Normal
 else
 hi def link erlangAtom String
 hi def link erlangLocalFuncCall Normal
@@ -197,6 +203,8 @@ hi def link erlangGlobalFuncRef Normal
 hi def link erlangVariable Identifier
 hi def link erlangMacro Macro
 hi def link erlangRecord Structure
+hi def link erlangQuotedRecord Structure
+hi def link erlangMap Structure
 endif
 
 " Bitstrings
index f6c50a2..9b43cb2 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         eterm(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-21
+" Language:             eterm(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-21
 
 if exists("b:current_syntax")
   finish
index 89de1ff..7a42105 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         fetchmail(1) RC File
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             fetchmail(1) RC File
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index 9d9ab69..4c26e78 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
 " Language:    Fortran 2008 (and older: Fortran 2003, 95, 90, and 77)
-" Version:     0.99
-" Last Change: 2016 Sep. 23
+" Version:     100
+" Last Change: 2016 Oct. 29
 " Maintainer:  Ajit J. Thakkar <ajit@unb.ca>; <http://www2.unb.ca/~ajit/>
 " Usage:       For instructions, do :help fortran-syntax from Vim
 " Credits:
@@ -397,6 +397,7 @@ if exists("fortran_fold")
     syn region fortranFunction transparent fold keepend extend start="^\s*\(elemental \|pure \|impure \|module \|recursive \)\=\s*\(\(\(real \|integer \|logical \|complex \|double \s*precision \)\s*\((\(\s*kind\s*=\)\=\s*\w\+\s*)\)\=\)\|type\s\+(\s*\w\+\s*) \|character \((\(\s*len\s*=\)\=\s*\d\+\s*)\|(\(\s*kind\s*=\)\=\s*\w\+\s*)\)\=\)\=\s*function\s\+\z(\a\w*\)" skip="^\([!c*]\|\s*#\).*$" excludenl end="\<end\s*\($\|function\(\s\+\z1\>\)\=\)" contains=ALLBUT,fortranProgram,fortranModule
     syn region fortranSubroutine transparent fold keepend extend start="^\s*\(elemental \|pure \|impure \|module \|recursive \)\=\s*subroutine\s\+\z(\a\w*\)" skip="^\([!c*]\|\s*#\).*$" excludenl end="\<end\s*\($\|subroutine\(\s\+\z1\>\)\=\)" contains=ALLBUT,fortranProgram,fortranModule
     syn region fortranBlockData transparent fold keepend start="\<block\s*data\(\s\+\z(\a\w*\)\)\=" skip="^\([!c*]\|\s*#\).*$" excludenl end="\<end\s*\($\|block\s*data\(\s\+\z1\>\)\=\)" contains=ALLBUT,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortran77Loop,fortranCase,fortran90Loop,fortranIfBlock
+    syn region fortranAssociate transparent fold keepend start="^\s*\<associate\s\+" skip="^\([!c*]\|\s*#\).*$" excludenl end="\<end\s*associate" contains=ALLBUT,fortranProgram,fortranModule,fortranSubroutine,fortranFunction
     syn region fortranInterface transparent fold keepend extend start="^\s*\(abstract \)\=\s*interface\>" skip="^\([!c*]\|\s*#\).*$" excludenl end="\<end\s*interface\>" contains=ALLBUT,fortranProgram,fortranModule,fortran77Loop,fortranCase,fortran90Loop,fortranIfBlock
     syn region fortranTypeDef transparent fold keepend extend start="^\s*type\s*\(,\s*\(public\|private\|abstract\)\)\=\s*::" skip="^\([!c*]\|\s*#\).*$" excludenl end="\<end\s*type\>" contains=ALLBUT,fortranProgram,fortranModule,fortran77Loop,fortranCase,fortran90Loop,fortranIfBlock,fortranInterface
   else
@@ -406,6 +407,7 @@ if exists("fortran_fold")
     syn region fortranFunction transparent fold keepend extend start="^\s*\(elemental \|pure \|impure \|module \|recursive \)\=\s*\(\(\(real \|integer \|logical \|complex \|double \s*precision \)\s*\((\(\s*kind\s*=\)\=\s*\w\+\s*)\)\=\)\|type\s\+(\s*\w\+\s*) \|character \((\(\s*len\s*=\)\=\s*\d\+\s*)\|(\(\s*kind\s*=\)\=\s*\w\+\s*)\)\=\)\=\s*function\s\+\z(\a\w*\)" skip="^\s*[!#].*$" excludenl end="\<end\s*\($\|function\(\s\+\z1\>\)\=\)" contains=ALLBUT,fortranProgram,fortranModule
     syn region fortranSubroutine transparent fold keepend extend start="^\s*\(elemental \|pure \|impure \|module \|recursive \)\=\s*subroutine\s\+\z(\a\w*\)" skip="^\s*[!#].*$" excludenl end="\<end\s*\($\|subroutine\(\s\+\z1\>\)\=\)" contains=ALLBUT,fortranProgram,fortranModule
     syn region fortranBlockData transparent fold keepend start="\<block\s*data\(\s\+\z(\a\w*\)\)\=" skip="^\s*[!#].*$" excludenl end="\<end\s*\($\|block\s*data\(\s\+\z1\>\)\=\)" contains=ALLBUT,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortran77Loop,fortranCase,fortran90Loop,fortranIfBlock
+    syn region fortranAssociate transparent fold keepend start="^\s*\<associate\s\+" skip="^\s*[!#].*$" excludenl end="\<end\s*associate" contains=ALLBUT,fortranProgram,fortranModule,fortranSubroutine,fortranFunction
     syn region fortranInterface transparent fold keepend extend start="^\s*\(abstract \)\=\s*interface\>" skip="^\s*[!#].*$" excludenl end="\<end\s*interface\>" contains=ALLBUT,fortranProgram,fortranModule,fortran77Loop,fortranCase,fortran90Loop,fortranIfBlock
     syn region fortranTypeDef transparent fold keepend extend start="^\s*type\s*\(,\s*\(public\|private\|abstract\)\)\=\s*::" skip="^\s*[!#].*$" excludenl end="\<end\s*type\>" contains=ALLBUT,fortranProgram,fortranModule,fortran77Loop,fortranCase,fortran90Loop,fortranIfBlock,fortranInterface
   endif
@@ -415,12 +417,12 @@ if exists("fortran_fold")
       syn region fortran77Loop transparent fold keepend start="\<do\s\+\z(\d\+\)" end="^\s*\z1\>" contains=ALLBUT,fortranUnitHeader,fortranStructure,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
       syn region fortran90Loop transparent fold keepend extend start="\(\<end\s\+\)\@<!\<do\(\s\+\a\|\s*$\)" skip="^\([!c*]\|\s*#\).*$" excludenl end="\<end\s*do\>" contains=ALLBUT,fortranUnitHeader,fortranStructure,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
       syn region fortranIfBlock transparent fold keepend extend start="\(\<e\(nd\|lse\)\s\+\)\@<!\<if\s*(.\+)\s*then\>" skip="^\([!c*]\|\s*#\).*$" end="\<end\s*if\>" contains=ALLBUT,fortranUnitHeader,fortranStructure,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
-      syn region fortranCase transparent fold keepend extend start="\<select\s*case\>" skip="^\([!c*]\|\s*#\).*$" end="\<end\s*select\>" contains=ALLBUT,fortranUnitHeader,fortranStructure,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
+      syn region fortranCase transparent fold keepend extend start="\<select\s*\(case\|type\)\>" skip="^\([!c*]\|\s*#\).*$" end="\<end\s*select\>" contains=ALLBUT,fortranUnitHeader,fortranStructure,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
     else
       syn region fortran77Loop transparent fold keepend start="\<do\s\+\z(\d\+\)" end="^\s*\z1\>" contains=ALLBUT,fortranUnitHeader,fortranStructure,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
       syn region fortran90Loop transparent fold keepend extend start="\(\<end\s\+\)\@<!\<do\(\s\+\a\|\s*$\)" skip="^\s*[!#].*$" excludenl end="\<end\s*do\>" contains=ALLBUT,fortranUnitHeader,fortranStructure,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
       syn region fortranIfBlock transparent fold keepend extend start="\(\<e\(nd\|lse\)\s\+\)\@<!\<if\s*(\(.\|&\s*\n\)\+)\(\s\|&\s*\n\)*then\>" skip="^\s*[!#].*$" end="\<end\s*if\>" contains=ALLBUT,fortranUnitHeader,fortranStructure,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
-      syn region fortranCase transparent fold keepend extend start="\<select\s*case\>" skip="^\s*[!#].*$" end="\<end\s*select\>" contains=ALLBUT,fortranUnitHeader,fortranStructure,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
+      syn region fortranCase transparent fold keepend extend start="\<select\s*\(case\|type\)\>" skip="^\s*[!#].*$" end="\<end\s*select\>" contains=ALLBUT,fortranUnitHeader,fortranStructure,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
     endif
   endif
 
index 39d75e8..8b16d04 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         FrameScript v4.0
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2007-02-22
+" Language:             FrameScript v4.0
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2007-02-22
 
 if exists("b:current_syntax")
   finish
index cde21ee..46e2099 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         gpg(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2010-10-14
+" Language:             gpg(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2010-10-14
 
 if exists("b:current_syntax")
   finish
index ab2d56d..f62a4a1 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         group(5) user group file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2012-08-05
+" Language:             group(5) user group file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2012-08-05
 
 if exists("b:current_syntax")
   finish
index f63449d..3743ae3 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         grub(8) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             grub(8) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index 4fc8af0..593ed72 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         host.conf(5) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2007-06-25
+" Language:             host.conf(5) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2007-06-25
 
 if exists("b:current_syntax")
   finish
index 336d8c9..49d3ab4 100644 (file)
@@ -1,9 +1,10 @@
 " Vim syntax file
-" Language:    HTML
-" Maintainer:  Claudio Fleiner <claudio@fleiner.com>
-" URL:         http://www.fleiner.com/vim/syntax/html.vim
-" Last Change: 2015 Jan 07
-"              included patch from David Felix
+" Language:             HTML
+" Maintainer:           Jorge Maldonado Ventura <jorgesumle@freakspot.net>
+" Previous Maintainer:  Claudio Fleiner <claudio@fleiner.com>
+" Repository:           https://notabug.org/jorgesumle/vim-html-syntax
+" Last Change:          2017 Jan 21
+"                       included patch from Jorge Maldonado Ventura
 
 " Please check :help html.vim for some comments and a description of the options
 
@@ -53,6 +54,14 @@ syn keyword htmlTagName contained abbr acronym bdo button col label
 syn keyword htmlTagName contained colgroup del fieldset iframe ins legend
 syn keyword htmlTagName contained object optgroup q s tbody tfoot thead
 
+" new html 5 tags
+syn keyword htmlTagName contained article aside audio bdi canvas data
+syn keyword htmlTagName contained datalist details embed figcaption figure
+syn keyword htmlTagName contained footer header hgroup keygen main mark
+syn keyword htmlTagName contained menuitem meter nav output picture
+syn keyword htmlTagName contained progress rb rp rt rtc ruby section
+syn keyword htmlTagName contained slot source template time track video wbr
+
 " legal arg names
 syn keyword htmlArg contained action
 syn keyword htmlArg contained align alink alt archive background bgcolor
@@ -87,6 +96,19 @@ syn keyword htmlArg contained multiple nohref nowrap object profile readonly
 syn keyword htmlArg contained rules scheme scope span standby style
 syn keyword htmlArg contained summary tabindex valuetype version
 
+" html 5 arg names
+syn keyword htmlArg contained allowfullscreen async autocomplete autofocus
+syn keyword htmlArg contained autoplay challenge contenteditable contextmenu
+syn keyword htmlArg contained controls crossorigin default dirname download
+syn keyword htmlArg contained draggable dropzone form formaction formenctype
+syn keyword htmlArg contained formmethod formnovalidate formtarget hidden
+syn keyword htmlArg contained high icon inputmode keytype kind list loop low
+syn keyword htmlArg contained max min minlength muted nonce novalidate open
+syn keyword htmlArg contained optimum pattern placeholder poster preload
+syn keyword htmlArg contained radiogroup required reversed sandbox spellcheck
+syn keyword htmlArg contained sizes srcset srcdoc srclang step title translate
+syn keyword htmlArg contained typemustmatch
+
 " special characters
 syn match htmlSpecialChar "&#\=[0-9A-Za-z]\{1,8};"
 
index 389101a..ddeae67 100644 (file)
@@ -1,10 +1,10 @@
 " Vim syntax file
-" Language:         indent(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2010-01-23
-"   indent_is_bsd:  If exists, will change somewhat to match BSD implementation
+" Language:             indent(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2010-01-23
+"   indent_is_bsd:      If exists, will change somewhat to match BSD implementation
 "
-" TODO: is the deny-all (a la lilo.vim nice or no?)...
+" TODO:     is the deny-all (a la lilo.vim nice or no?)...
 "       irritating to be wrong to the last char...
 "       would be sweet if right until one char fails
 
index 8f3462f..564a6e0 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         TeX (core definition)
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             TeX (core definition)
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
@@ -11,7 +11,7 @@ let s:cpo_save = &cpo
 set cpo&vim
 
 " This follows the grouping (sort of) found at
-" http://www.tug.org/utilities/plain/cseq.html#top-fam
+" http: //www.tug.org/utilities/plain/cseq.html#top-fam
 
 syn keyword initexTodo                          TODO FIXME XXX NOTE
 
index fc12919..22949d9 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         ld(1) script
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             ld(1) script
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index 70ddaab..662ea20 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         ldap.conf(5) configuration file.
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-12-11
+" Language:             ldap.conf(5) configuration file.
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-12-11
 
 if exists("b:current_syntax")
   finish
index 6a8e4f9..20ddee5 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         lftp(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2007-06-17
+" Language:             lftp(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2007-06-17
 
 if exists("b:current_syntax")
   finish
index 25b6e82..1a3bd90 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         libao.conf(5) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             libao.conf(5) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index a6d245a..96bd423 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         limits(5) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             limits(5) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index b4c15fa..e3d967f 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         LiteStep RC file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2007-02-22
+" Language:             LiteStep RC file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2007-02-22
 
 if exists("b:current_syntax")
   finish
index 07d60ee..650e067 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         login.access(5) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             login.access(5) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index 59d18e7..8cb4295 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         login.defs(5) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2010-11-29
+" Language:             login.defs(5) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2010-11-29
 
 if exists("b:current_syntax")
   finish
index 743068f..a5282aa 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         aliases(5) local alias database file
-" Maintainer:       Nikolai Weibull <nikolai@bitwi.se>
-" Latest Revision:  2008-04-14
+" Language:             aliases(5) local alias database file
+" Previous Maintainer:  Nikolai Weibull <nikolai@bitwi.se>
+" Latest Revision:      2008-04-14
 
 if exists("b:current_syntax")
   finish
index 90ecc8e..2c17568 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         man.conf(5) - man configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             man.conf(5) - man configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index 92ffbbc..5228bb5 100644 (file)
@@ -1,11 +1,13 @@
 " Vim syntax file
 " Language:    Matlab
-" Maintainer:  Maurizio Tranchero - maurizio(.)tranchero(@)gmail(.)com
+" Maintainer:  Alex Burka <vim@alexburka.com>
 " Credits:     Preben 'Peppe' Guldberg <peppe-vim@wielders.org>
+"              Maurizio Tranchero - maurizio(.)tranchero(@)gmail(.)com
 "              Original author: Mario Eusebio
-" Last Change: Wed Jan 13 11:12:34 CET 2010
-"              sinh added to matlab implicit commands
+" Last Change: Mon Jan 23 2017
+"              added support for cell mode
 " Change History:
+"              - now highlights cell-mode separator comments
 "              - 'global' and 'persistent' keyword are now recognized
 
 " quit when a syntax file was already loaded
@@ -60,6 +62,7 @@ syn match matlabComment                       "%.*$"  contains=matlabTodo,matlabTab
 " MT_ADDON - correctly highlights words after '...' as comments
 syn match matlabComment                        "\.\.\..*$"     contains=matlabTodo,matlabTab
 syn region matlabMultilineComment      start=+%{+ end=+%}+ contains=matlabTodo,matlabTab
+syn match matlabCellComment     "^%%.*$"
 
 syn keyword matlabOperator             break zeros default margin round ones rand
 syn keyword matlabOperator             ceil floor size clear zeros eye mean std cov
@@ -96,6 +99,7 @@ hi def link matlabOO                  Statement
 hi def link matlabSemicolon            SpecialChar
 hi def link matlabComment                      Comment
 hi def link matlabMultilineComment             Comment
+hi def link matlabCellComment          Todo
 hi def link matlabScope                        Type
 
 hi def link matlabArithmeticOperator   matlabOperator
index 54b6593..76b36ed 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         modules.conf(5) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2007-10-25
+" Language:             modules.conf(5) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2007-10-25
 
 if exists("b:current_syntax")
   finish
index 2ae4961..606ac7f 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         nanorc(5) - GNU nano configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             nanorc(5) - GNU nano configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index d648508..4f70a0f 100644 (file)
@@ -1,9 +1,10 @@
 " Vim syntax file
 " Language:    NASM - The Netwide Assembler (v0.98)
-" Maintainer:  Andriy Sokolov  <andriy145@gmail.com>
+" Maintainer:  Andrii Sokolov  <andriy145@gmail.com>
 " Original Author:     Manuel M.H. Stol        <Manuel.Stol@allieddata.nl>
 " Former Maintainer:   Manuel M.H. Stol        <Manuel.Stol@allieddata.nl>
-" Last Change: 2012 Feb 7
+" Contributors: Leonard König <leonard.r.koenig@gmail.com> (C string highlighting)
+" Last Change: 2017 Jan 23
 " NASM Home:   http://www.nasm.us/
 
 
@@ -67,8 +68,23 @@ syn match   nasmLabelError   "\<\~\s*\(\k*\s*:\|\$\=\.\k*\)"
 
 
 " Constants:
-syn match   nasmStringError    +["']+
+syn match   nasmStringError    +["'`]+
+" NASM is case sensitive here: eg. u-prefix allows for 4-digit, U-prefix for
+" 8-digit Unicode characters
+syn case match
+" one-char escape-sequences
+syn match   nasmCStringEscape  display contained "\\[’"‘\\\?abtnvfre]"
+" hex and octal numbers
+syn match   nasmCStringEscape  display contained "\\\(x\x\{2}\|\o\{1,3}\)"
+" Unicode characters
+syn match   nasmCStringEscape  display contained "\\\(u\x\{4}\|U\x\{8}\)"
+" ISO C99 format strings (copied from cFormat in runtime/syntax/c.vim)
+syn match   nasmCStringFormat  display "%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlLjzt]\|ll\|hh\)\=\([aAbdiuoxXDOUfFeEgGcCsSpn]\|\[\^\=.[^]]*\]\)" contained
+syn match   nasmCStringFormat  display "%%" contained
 syn match   nasmString         +\("[^"]\{-}"\|'[^']\{-}'\)+
+" Highlight C escape- and format-sequences within ``-strings
+syn match   nasmCString        +\(`[^`]\{-}`\)+ contains=nasmCStringEscape,nasmCStringFormat extend
+syn case ignore
 syn match   nasmBinNumber      "\<[0-1]\+b\>"
 syn match   nasmBinNumber      "\<\~[0-1]\+b\>"lc=1
 syn match   nasmOctNumber      "\<\o\+q\>"
@@ -443,7 +459,10 @@ hi def link nasmInCommentTodo      Todo
 
 " Constant Group:
 hi def link nasmString         String
+hi def link nasmCString        String
 hi def link nasmStringError    Error
+hi def link nasmCStringEscape  SpecialChar
+hi def link nasmCStringFormat  SpecialChar
 hi def link nasmBinNumber              Number
 hi def link nasmOctNumber              Number
 hi def link nasmDecNumber              Number
index 9f15d16..4d068a1 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         netrc(5) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2010-01-03
+" Language:             netrc(5) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2010-01-03
 
 if exists("b:current_syntax")
   finish
index e3c8ba8..10d667b 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         pam(8) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2011-08-03
+" Language:             pam(8) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2011-08-03
 
 
 if exists("b:current_syntax")
index cdaed58..ad90202 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         passwd(5) password file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-10-03
+" Language:             passwd(5) password file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-10-03
 
 if exists("b:current_syntax")
   finish
index f86a32f..34b0b6a 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
 " Language: php PHP 3/4/5/7
 " Maintainer: Jason Woofenden <jason@jasonwoof.com>
-" Last Change: Jul 27, 2016
+" Last Change: Dec 11, 2016
 " URL: https://jasonwoof.com/gitweb/?p=vim-syntax.git;a=blob;f=php.vim;hb=HEAD
 " Former Maintainers: Peter Hodge <toomuchphp-vim@yahoo.com>
 "         Debian VIM Maintainers <pkg-vim-maintainers@lists.alioth.debian.org>
@@ -495,7 +495,7 @@ syntax keyword phpSpecialFunction containedin=ALLBUT,phpComment,phpStringDouble,
 " Highlighting for __autoload slightly different from line above
 syntax keyword phpSpecialFunction containedin=ALLBUT,phpComment,phpStringDouble,phpStringSingle,phpIdentifier,phpMethodsVar
   \ __autoload
-highlight link phpSpecialFunction phpOperator
+hi def link phpSpecialFunction phpOperator
 
 " Highlighting for PHP5's built-in classes
 " - built-in classes harvested from get_declared_classes() in 5.1.4
@@ -518,14 +518,14 @@ syntax keyword phpClasses containedin=ALLBUT,phpComment,phpStringDouble,phpStrin
   \ DOMCharacterData DOMAttr DOMElement DOMText DOMComment DOMTypeinfo DOMUserDataHandler
   \ DOMLocator DOMConfiguration DOMCdataSection DOMDocumentType DOMNotation DOMEntity
   \ DOMEntityReference DOMProcessingInstruction DOMStringExtend DOMXPath
-highlight link phpClasses phpFunctions
+hi def link phpClasses phpFunctions
 
 " Highlighting for PHP5's built-in interfaces
 " - built-in classes harvested from get_declared_interfaces() in 5.1.4
 syntax keyword phpInterfaces containedin=ALLBUT,phpComment,phpStringDouble,phpStringSingle,phpIdentifier,phpMethodsVar
   \ Iterator IteratorAggregate RecursiveIterator OuterIterator SeekableIterator
   \ Traversable ArrayAccess Serializable Countable SplObserver SplSubject Reflector
-highlight link phpInterfaces phpConstant
+hi def link phpInterfaces phpConstant
 
 " option defaults:
 if ! exists('php_special_functions')
@@ -553,7 +553,7 @@ endif
 if php_alt_assignByReference
     " special highlighting for '=&' operator
     syntax match phpAssignByRef /=\s*&/ containedin=ALLBUT,phpComment,phpStringDouble,phpStringSingle
-    highlight link phpAssignByRef Type
+    hi def link phpAssignByRef Type
 endif
 
 if php_alt_comparisons
@@ -565,7 +565,7 @@ if php_alt_comparisons
   syntax case ignore
   syntax keyword phpComparison instanceof contained containedin=phpRegion
 
-  hi link phpComparison Statement
+  hi def link phpComparison Statement
 endif
 
 " ================================================================
@@ -645,21 +645,21 @@ hi def link phpTodo  Todo
 hi def link phpDocTodo Todo
 hi def link phpMemberSelector  Structure
 if exists("php_oldStyle")
-hi  phpIntVar guifg=Red ctermfg=DarkRed
-hi  phpEnvVar guifg=Red ctermfg=DarkRed
-hi  phpOperator guifg=SeaGreen ctermfg=DarkGreen
-hi  phpVarSelector guifg=SeaGreen ctermfg=DarkGreen
-hi  phpRelation guifg=SeaGreen ctermfg=DarkGreen
-hi  phpIdentifier guifg=DarkGray ctermfg=Brown
-hi  phpIdentifierSimply guifg=DarkGray ctermfg=Brown
+  hi def phpIntVar guifg=Red ctermfg=DarkRed
+  hi def phpEnvVar guifg=Red ctermfg=DarkRed
+  hi def phpOperator guifg=SeaGreen ctermfg=DarkGreen
+  hi def phpVarSelector guifg=SeaGreen ctermfg=DarkGreen
+  hi def phpRelation guifg=SeaGreen ctermfg=DarkGreen
+  hi def phpIdentifier guifg=DarkGray ctermfg=Brown
+  hi def phpIdentifierSimply guifg=DarkGray ctermfg=Brown
 else
-hi def link phpIntVar Identifier
-hi def link phpEnvVar Identifier
-hi def link phpOperator Operator
-hi def link phpVarSelector  Operator
-hi def link phpRelation Operator
-hi def link phpIdentifier Identifier
-hi def link phpIdentifierSimply Identifier
+  hi def link phpIntVar Identifier
+  hi def link phpEnvVar Identifier
+  hi def link phpOperator Operator
+  hi def link phpVarSelector  Operator
+  hi def link phpRelation Operator
+  hi def link phpIdentifier Identifier
+  hi def link phpIdentifierSimply Identifier
 endif
 
 
index bf4126e..cb9e60e 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         pinfo(1) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2007-06-17
+" Language:             pinfo(1) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2007-06-17
 
 if exists("b:current_syntax")
   finish
index 7020c68..5cb49a0 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         TeX (plain.tex format)
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-10-26
+" Language:             TeX (plain.tex format)
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-10-26
 
 if exists("b:current_syntax")
   finish
index 1dc109c..f31ca5a 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         protocols(5) - Internet protocols definition file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             protocols(5) - Internet protocols definition file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index 3a9b68d..7db5310 100644 (file)
@@ -1,11 +1,11 @@
 " Vim syntax file
-" Language:         Quake[1-3] configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2007-06-17
+" Language:             Quake[1-3] configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2007-06-17
 "               quake_is_quake1 - the syntax is to be used for quake1 configs
 "               quake_is_quake2 - the syntax is to be used for quake2 configs
 "               quake_is_quake3 - the syntax is to be used for quake3 configs
-" Credits:          Tomasz Kalkosinski wrote the original quake3Colors stuff
+" Credits:              Tomasz Kalkosinski wrote the original quake3Colors stuff
 
 if exists("b:current_syntax")
   finish
index 30a5b23..45ff498 100644 (file)
@@ -5,10 +5,10 @@
 "                    Tom Payne <tom@tompayne.org>
 " Contributor:        Johannes Ranke <jranke@uni-bremen.de>
 " Homepage:           https://github.com/jalvesaq/R-Vim-runtime
-" Last Change:       Thu Aug 25, 2016  08:52PM
+" Last Change:       Sat Apr 08, 2017  07:01PM
 " Filenames:         *.R *.r *.Rhistory *.Rt
 "
-" NOTE: The highlighting of R functions is defined in
+" NOTE: The highlighting of R functions might be defined in
 " runtime files created by a filetype plugin, if installed.
 "
 " CONFIGURATION:
@@ -18,7 +18,7 @@
 "
 "   ROxygen highlighting can be turned off by
 "
-"      let r_hl_roxygen = 0
+"      let r_syntax_hl_roxygen = 0
 "
 " Some lines of code were borrowed from Zhuojun Chen.
 
@@ -26,13 +26,25 @@ if exists("b:current_syntax")
   finish
 endif
 
-syn iskeyword @,48-57,_,.
+if has("patch-7.4.1142")
+  syn iskeyword @,48-57,_,.
+else
+  setlocal iskeyword=@,48-57,_,.
+endif
+
+" The variables g:r_hl_roxygen and g:r_syn_minlines were renamed on April 8, 2017.
+if exists("g:r_hl_roxygen")
+  let g:r_syntax_hl_roxygen = g:r_hl_roxygen
+endif
+if exists("g:r_syn_minlines")
+  let g:r_syntax_minlines = g:r_syn_minlines
+endif
 
 if exists("g:r_syntax_folding") && g:r_syntax_folding
   setlocal foldmethod=syntax
 endif
-if !exists("g:r_hl_roxygen")
-  let g:r_hl_roxygen = 1
+if !exists("g:r_syntax_hl_roxygen")
+  let g:r_syntax_hl_roxygen = 1
 endif
 
 syn case match
@@ -42,19 +54,106 @@ syn match rCommentTodo contained "\(BUG\|FIXME\|NOTE\|TODO\):"
 syn match rComment contains=@Spell,rCommentTodo,rOBlock "#.*"
 
 " Roxygen
-if g:r_hl_roxygen
-  syn region rOBlock start="^\s*\n#\{1,2}' " start="\%^#\{1,2}' " end="^\(#\{1,2}'\)\@!" contains=rOTitle,rOKeyword,rOExamples,@Spell keepend
-  syn region rOTitle start="^\s*\n#\{1,2}' " start="\%^#\{1,2}' " end="^\(#\{1,2}'\s*$\)\@=" contained contains=rOCommentKey
-  syn match rOCommentKey "#\{1,2}'" containedin=rOTitle contained
-
-  syn region rOExamples start="^#\{1,2}' @examples.*"rs=e+1,hs=e+1 end="^\(#\{1,2}' @.*\)\@=" end="^\(#\{1,2}'\)\@!" contained contains=rOKeyword
-
-  syn match rOKeyword contained "@\(param\|return\|name\|rdname\|examples\|example\|include\|docType\)"
-  syn match rOKeyword contained "@\(S3method\|TODO\|aliases\|alias\|assignee\|author\|callGraphDepth\|callGraph\)"
-  syn match rOKeyword contained "@\(callGraphPrimitives\|concept\|exportClass\|exportMethod\|exportPattern\|export\|formals\)"
-  syn match rOKeyword contained "@\(format\|importClassesFrom\|importFrom\|importMethodsFrom\|import\|keywords\|useDynLib\)"
-  syn match rOKeyword contained "@\(method\|noRd\|note\|references\|seealso\|setClass\|slot\|source\|title\|usage\)"
-  syn match rOKeyword contained "@\(family\|template\|templateVar\|description\|details\|inheritParams\|field\)"
+if g:r_syntax_hl_roxygen
+  " A roxygen block can start at the beginning of a file (first version) and
+  " after a blank line (second version). It ends when a line that does not
+  " contain a roxygen comment. In the following comments, any line containing
+  " a roxygen comment marker (one or two hash signs # followed by a single
+  " quote ' and preceded only by whitespace) is called a roxygen line. A
+  " roxygen line containing only a roxygen comment marker, optionally followed
+  " by whitespace is called an empty roxygen line.
+
+  " First we match all roxygen blocks as containing only a title. In case an
+  " empty roxygen line ending the title or a tag is found, this will be
+  " overriden later by the definitions of rOBlock.
+  syn match rOTitleBlock "\%^\(\s*#\{1,2}' .*\n\)\{1,}" contains=rOCommentKey,rOTitleTag
+  syn match rOTitleBlock "^\s*\n\(\s*#\{1,2}' .*\n\)\{1,}" contains=rOCommentKey,rOTitleTag
+
+  " When a roxygen block has a title and additional content, the title
+  " consists of one or more roxygen lines (as little as possible are matched),
+  " followed either by an empty roxygen line
+  syn region rOBlock start="\%^\(\s*#\{1,2}' .*\n\)\{-1,}\s*#\{1,2}'\s*$" end="^\s*\(#\{1,2}'\)\@!" contains=rOTitle,rOTag,rOExamples,@Spell keepend fold
+  syn region rOBlock start="^\s*\n\(\s*#\{1,2}' .*\n\)\{-1,}\s*#\{1,2}'\s*$" end="^\s*\(#\{1,2}'\)\@!" contains=rOTitle,rOTag,rOExamples,@Spell keepend fold
+
+  " or by a roxygen tag (we match everything starting with @ but not @@ which is used as escape sequence for a literal @).
+  syn region rOBlock start="\%^\(\s*#\{1,2}' .*\n\)\{-}\s*#\{1,2}' @\(@\)\@!" end="^\s*\(#\{1,2}'\)\@!" contains=rOTitle,rOTag,rOExamples,@Spell keepend fold
+  syn region rOBlock start="^\s*\n\(\s*#\{1,2}' .*\n\)\{-}\s*#\{1,2}' @\(@\)\@!" end="^\s*\(#\{1,2}'\)\@!" contains=rOTitle,rOTag,rOExamples,@Spell keepend fold
+
+  " If a block contains an @rdname, @describeIn tag, it may have paragraph breaks, but does not have a title
+  syn region rOBlockNoTitle start="\%^\(\s*#\{1,2}' .*\n\)\{-1,}\s*#\{1,2}'\s*\n\(\s*#\{1,2}'.*\n\)\{-}\s*#\{1,2}' @rdname" end="^\s*\(#\{1,2}'\)\@!" contains=rOTag,rOExamples,@Spell keepend fold
+  syn region rOBlockNoTitle start="^\s*\n\(\s*#\{1,2}' .*\n\)\{-1,}\s*#\{1,2}'\s*\n\(\s*#\{1,2}'.*\n\)\{-}\s*#\{1,2}' @rdname" end="^\s*\(#\{1,2}'\)\@!" contains=rOTag,rOExamples,@Spell keepend fold
+  syn region rOBlockNoTitle start="\%^\(\s*#\{1,2}' .*\n\)\{-1,}\s*#\{1,2}'\s*\n\(\s*#\{1,2}'.*\n\)\{-}\s*#\{1,2}' @describeIn" end="^\s*\(#\{1,2}'\)\@!" contains=rOTag,rOExamples,@Spell keepend fold
+  syn region rOBlockNoTitle start="^\s*\n\(\s*#\{1,2}' .*\n\)\{-1,}\s*#\{1,2}'\s*\n\(\s*#\{1,2}'.*\n\)\{-}\s*#\{1,2}' @describeIn" end="^\s*\(#\{1,2}'\)\@!" contains=rOTag,rOExamples,@Spell keepend fold
+
+  " A title as part of a block is always at the beginning of the block, i.e.
+  " either at the start of a file or after a completely empty line.
+  syn match rOTitle "\%^\(\s*#\{1,2}' .*\n\)\{-1,}\s*#\{1,2}'\s*$" contained contains=rOCommentKey,rOTitleTag
+  syn match rOTitle "^\s*\n\(\s*#\{1,2}' .*\n\)\{-1,}\s*#\{1,2}'\s*$" contained contains=rOCommentKey,rOTitleTag
+  syn match rOTitleTag contained "@title"
+
+  syn match rOCommentKey "#\{1,2}'" contained
+  syn region rOExamples start="^#\{1,2}' @examples.*"rs=e+1,hs=e+1 end="^\(#\{1,2}' @.*\)\@=" end="^\(#\{1,2}'\)\@!" contained contains=rOTag fold
+
+  " rOTag list generated from the lists in
+  " https://github.com/klutometis/roxygen/R/rd.R and
+  " https://github.com/klutometis/roxygen/R/namespace.R
+  " using s/^    \([A-Za-z0-9]*\) = .*/  syn match rOTag contained "@\1"/
+  " Plus we need the @include tag
+
+  " rd.R
+  syn match rOTag contained "@aliases"
+  syn match rOTag contained "@author"
+  syn match rOTag contained "@backref"
+  syn match rOTag contained "@concept"
+  syn match rOTag contained "@describeIn"
+  syn match rOTag contained "@description"
+  syn match rOTag contained "@details"
+  syn match rOTag contained "@docType"
+  syn match rOTag contained "@encoding"
+  syn match rOTag contained "@evalRd"
+  syn match rOTag contained "@example"
+  syn match rOTag contained "@examples"
+  syn match rOTag contained "@family"
+  syn match rOTag contained "@field"
+  syn match rOTag contained "@format"
+  syn match rOTag contained "@inherit"
+  syn match rOTag contained "@inheritParams"
+  syn match rOTag contained "@inheritDotParams"
+  syn match rOTag contained "@inheritSection"
+  syn match rOTag contained "@keywords"
+  syn match rOTag contained "@method"
+  syn match rOTag contained "@name"
+  syn match rOTag contained "@md"
+  syn match rOTag contained "@noMd"
+  syn match rOTag contained "@noRd"
+  syn match rOTag contained "@note"
+  syn match rOTag contained "@param"
+  syn match rOTag contained "@rdname"
+  syn match rOTag contained "@rawRd"
+  syn match rOTag contained "@references"
+  syn match rOTag contained "@return"
+  syn match rOTag contained "@section"
+  syn match rOTag contained "@seealso"
+  syn match rOTag contained "@slot"
+  syn match rOTag contained "@source"
+  syn match rOTag contained "@template"
+  syn match rOTag contained "@templateVar"
+  syn match rOTag contained "@title"
+  syn match rOTag contained "@usage"
+  " namespace.R
+  syn match rOTag contained "@export"
+  syn match rOTag contained "@exportClass"
+  syn match rOTag contained "@exportMethod"
+  syn match rOTag contained "@exportPattern"
+  syn match rOTag contained "@import"
+  syn match rOTag contained "@importClassesFrom"
+  syn match rOTag contained "@importFrom"
+  syn match rOTag contained "@importMethodsFrom"
+  syn match rOTag contained "@rawNamespace"
+  syn match rOTag contained "@S3method"
+  syn match rOTag contained "@useDynLib"
+  " other
+  syn match rOTag contained "@include"
 endif
 
 
@@ -168,12 +267,28 @@ syn match rBraceError "[)}]" contained
 syn match rCurlyError "[)\]]" contained
 syn match rParenError "[\]}]" contained
 
-if !exists("g:R_hi_fun")
-  let g:R_hi_fun = 1
+" Use Nvim-R to highlight functions dynamically if it is installed
+if !exists("g:r_syntax_fun_pattern")
+  let s:ff = split(substitute(globpath(&rtp, "R/functions.vim"), "functions.vim", "", "g"), "\n")
+  if len(s:ff) > 0
+    let g:r_syntax_fun_pattern = 0
+  else
+    let g:r_syntax_fun_pattern = 1
+  endif
 endif
-if g:R_hi_fun
-  " Nvim-R:
-  runtime R/functions.vim
+
+" Only use Nvim-R to highlight functions if they should not be highlighted
+" according to a generic pattern
+if g:r_syntax_fun_pattern == 1
+  syn match rFunction '[0-9a-zA-Z_\.]\+\s*\ze('
+else
+  if !exists("g:R_hi_fun")
+    let g:R_hi_fun = 1
+  endif
+  if g:R_hi_fun
+    " Nvim-R:
+    runtime R/functions.vim
+  endif
 endif
 
 syn match rDollar display contained "\$"
@@ -205,8 +320,8 @@ if &filetype == "rhelp"
   syn match rhSection "\\dontrun\>"
 endif
 
-if exists("r_syn_minlines")
-  exe "syn sync minlines=" . r_syn_minlines
+if exists("r_syntax_minlines")
+  exe "syn sync minlines=" . r_syntax_minlines
 else
   syn sync minlines=40
 endif
@@ -243,15 +358,17 @@ hi def link rStatement   Statement
 hi def link rString      String
 hi def link rStrError    Error
 hi def link rType        Type
-if g:r_hl_roxygen
-  hi def link rOKeyword    Title
-  hi def link rOBlock      Comment
+if g:r_syntax_hl_roxygen
+  hi def link rOTitleTag   Operator
+  hi def link rOTag        Operator
+  hi def link rOTitleBlock Title
+  hi def link rOBlock         Comment
+  hi def link rOBlockNoTitle  Comment
   hi def link rOTitle      Title
   hi def link rOCommentKey Comment
   hi def link rOExamples   SpecialComment
 endif
 
-
 let b:current_syntax="r"
 
 " vim: ts=8 sw=2
index d412227..2d4c176 100644 (file)
@@ -1,7 +1,7 @@
 " Vim default file
-" Language:         Racc input file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2008-06-22
+" Language:             Racc input file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2008-06-22
 
 if exists("b:current_syntax")
   finish
index 091722e..2ec0c8e 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         readline(3) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2012-04-25
+" Language:             readline(3) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2012-04-25
 "   readline_has_bash - if defined add support for bash specific
 "                       settings/functions
 
index 48fb5e0..0543535 100644 (file)
@@ -1,17 +1,26 @@
 " markdown Text with R statements
 " Language: markdown with R code chunks
 " Homepage: https://github.com/jalvesaq/R-Vim-runtime
-" Last Change: Tue Jun 28, 2016  10:09AM
+" Last Change: Sat Jan 28, 2017  10:06PM
 "
 " CONFIGURATION:
-"   To highlight chunk headers as R code, put in your vimrc:
+"   To highlight chunk headers as R code, put in your vimrc (e.g. .config/nvim/init.vim):
 "   let rmd_syn_hl_chunk = 1
+"
+"   For highlighting pandoc extensions to markdown like citations and TeX and
+"   many other advanced features like folding of markdown sections, it is
+"   recommended to install the vim-pandoc filetype plugin as well as the
+"   vim-pandoc-syntax filetype plugin from https://github.com/vim-pandoc.
+"
+" TODO:
+"   - Provide highlighting for rmarkdown parameters in yaml header
 
 if exists("b:current_syntax")
   finish
 endif
 
-" load all of pandoc info
+" load all of pandoc info, e.g. from
+" https://github.com/vim-pandoc/vim-pandoc-syntax
 runtime syntax/pandoc.vim
 if exists("b:current_syntax")
   let rmdIsPandoc = 1
@@ -22,28 +31,54 @@ else
   if exists("b:current_syntax")
     unlet b:current_syntax
   endif
-endif
 
-" load all of the r syntax highlighting rules into @R
-syntax include @R syntax/r.vim
-if exists("b:current_syntax")
-  unlet b:current_syntax
+  " load all of the yaml syntax highlighting rules into @yaml
+  syntax include @yaml syntax/yaml.vim
+  if exists("b:current_syntax")
+    unlet b:current_syntax
+  endif
+
+  " highlight yaml block commonly used for front matter
+  syntax region rmdYamlBlock matchgroup=rmdYamlBlockDelim start="^---" matchgroup=rmdYamlBlockDelim end="^---" contains=@yaml keepend fold
 endif
 
-if exists("g:rmd_syn_hl_chunk")
-  " highlight R code inside chunk header
-  syntax match rmdChunkDelim "^[ \t]*```{r" contained
-  syntax match rmdChunkDelim "}$" contained
+if !exists("g:rmd_syn_langs")
+  let g:rmd_syn_langs = ["r"]
 else
-  syntax match rmdChunkDelim "^[ \t]*```{r.*}$" contained
+  let s:hasr = 0
+  for s:lng in g:rmd_syn_langs
+    if s:lng == "r"
+      let s:hasr = 1
+    endif
+  endfor
+  if s:hasr == 0
+    let g:rmd_syn_langs += ["r"]
+  endif
 endif
-syntax match rmdChunkDelim "^[ \t]*```$" contained
-syntax region rmdChunk start="^[ \t]*``` *{r.*}$" end="^[ \t]*```$" contains=@R,rmdChunkDelim keepend fold
+
+for s:lng in g:rmd_syn_langs
+  exe 'syntax include @' . toupper(s:lng) . ' syntax/'. s:lng . '.vim'
+  if exists("b:current_syntax")
+    unlet b:current_syntax
+  endif
+  exe 'syntax region rmd' . toupper(s:lng) . 'Chunk start="^[ \t]*``` *{\(' . s:lng . '\|r.*engine\s*=\s*["' . "']" . s:lng . "['" . '"]\).*}$" end="^[ \t]*```$" contains=@' . toupper(s:lng) . ',rmd' . toupper(s:lng) . 'ChunkDelim keepend fold'
+
+  if exists("g:rmd_syn_hl_chunk") && s:lng == "r"
+    " highlight R code inside chunk header
+    syntax match rmdRChunkDelim "^[ \t]*```{r" contained
+    syntax match rmdRChunkDelim "}$" contained
+  else
+    exe 'syntax match rmd' . toupper(s:lng) . 'ChunkDelim "^[ \t]*```{\(' . s:lng . '\|r.*engine\s*=\s*["' . "']" . s:lng . "['" . '"]\).*}$" contained'
+  endif
+  exe 'syntax match rmd' . toupper(s:lng) . 'ChunkDelim "^[ \t]*```$" contained'
+endfor
+
 
 " also match and syntax highlight in-line R code
-syntax match rmdEndInline "`" contained
-syntax match rmdBeginInline "`r " contained
-syntax region rmdrInline start="`r "  end="`" contains=@R,rmdBeginInline,rmdEndInline keepend
+syntax region rmdrInline matchgroup=rmdInlineDelim start="`r "  end="`" contains=@R containedin=pandocLaTeXRegion,yamlFlowString keepend
+" I was not able to highlight rmdrInline inside a pandocLaTeXCommand, although
+" highlighting works within pandocLaTeXRegion and yamlFlowString. 
+syntax cluster texMathZoneGroup add=rmdrInline
 
 " match slidify special marker
 syntax match rmdSlidifySpecial "\*\*\*"
@@ -56,8 +91,6 @@ if rmdIsPandoc == 0
   if exists("b:current_syntax")
     unlet b:current_syntax
   endif
-  " Extend cluster
-  syn cluster texMathZoneGroup add=rmdrInline
   " Inline
   syntax match rmdLaTeXInlDelim "\$"
   syntax match rmdLaTeXInlDelim "\\\$"
@@ -65,19 +98,24 @@ if rmdIsPandoc == 0
   " Region
   syntax match rmdLaTeXRegDelim "\$\$" contained
   syntax match rmdLaTeXRegDelim "\$\$latex$" contained
-  syntax region rmdLaTeXRegion start="^\$\$" skip="\\\$" end="\$\$$" contains=@LaTeX,rmdLaTeXSt,rmdLaTeXRegDelim keepend
-  syntax region rmdLaTeXRegion2 start="^\\\[" end="\\\]" contains=@LaTeX,rmdLaTeXSt,rmdLaTeXRegDelim keepend
+  syntax match rmdLaTeXSt "\\[a-zA-Z]\+"
+  syntax region rmdLaTeXRegion start="^\$\$" skip="\\\$" end="\$\$$" contains=@LaTeX,rmdLaTeXRegDelim keepend
+  syntax region rmdLaTeXRegion2 start="^\\\[" end="\\\]" contains=@LaTeX,rmdLaTeXRegDelim keepend
+  hi def link rmdBlockQuote Comment
   hi def link rmdLaTeXSt Statement
   hi def link rmdLaTeXInlDelim Special
   hi def link rmdLaTeXRegDelim Special
 endif
 
-syn sync match rmdSyncChunk grouphere rmdChunk "^[ \t]*``` *{r"
+for s:lng in g:rmd_syn_langs
+  exe 'syn sync match rmd' . toupper(s:lng) . 'SyncChunk grouphere rmd' . toupper(s:lng) . 'Chunk /^[ \t]*``` *{\(' . s:lng . '\|r.*engine\s*=\s*["' . "']" . s:lng . "['" . '"]\)/'
+endfor
 
-hi def link rmdChunkDelim Special
-hi def link rmdBeginInline Special
-hi def link rmdEndInline Special
-hi def link rmdBlockQuote Comment
+hi def link rmdYamlBlockDelim Delim
+for s:lng in g:rmd_syn_langs
+  exe 'hi def link rmd' . toupper(s:lng) . 'ChunkDelim Special'
+endfor
+hi def link rmdInlineDelim Special
 hi def link rmdSlidifySpecial Special
 
 let b:current_syntax = "rmd"
index 8436c88..7d3907e 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         Relax NG compact syntax
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2007-06-17
+" Language:             Relax NG compact syntax
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2007-06-17
 
 if exists("b:current_syntax")
   finish
diff --git a/runtime/syntax/rust.vim b/runtime/syntax/rust.vim
new file mode 100644 (file)
index 0000000..5734330
--- /dev/null
@@ -0,0 +1,295 @@
+" Vim syntax file
+" Language:     Rust
+" Maintainer:   Patrick Walton <pcwalton@mozilla.com>
+" Maintainer:   Ben Blum <bblum@cs.cmu.edu>
+" Maintainer:   Chris Morgan <me@chrismorgan.info>
+" Last Change:  Feb 24, 2016
+" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
+
+if version < 600
+       syntax clear
+elseif exists("b:current_syntax")
+       finish
+endif
+
+" Syntax definitions {{{1
+" Basic keywords {{{2
+syn keyword   rustConditional match if else
+syn keyword   rustRepeat for loop while
+syn keyword   rustTypedef type nextgroup=rustIdentifier skipwhite skipempty
+syn keyword   rustStructure struct enum nextgroup=rustIdentifier skipwhite skipempty
+syn keyword   rustUnion union nextgroup=rustIdentifier skipwhite skipempty contained
+syn match rustUnionContextual /\<union\_s\+\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*/ transparent contains=rustUnion
+syn keyword   rustOperator    as
+
+syn match     rustAssert      "\<assert\(\w\)*!" contained
+syn match     rustPanic       "\<panic\(\w\)*!" contained
+syn keyword   rustKeyword     break
+syn keyword   rustKeyword     box nextgroup=rustBoxPlacement skipwhite skipempty
+syn keyword   rustKeyword     continue
+syn keyword   rustKeyword     extern nextgroup=rustExternCrate,rustObsoleteExternMod skipwhite skipempty
+syn keyword   rustKeyword     fn nextgroup=rustFuncName skipwhite skipempty
+syn keyword   rustKeyword     in impl let
+syn keyword   rustKeyword     pub nextgroup=rustPubScope skipwhite skipempty
+syn keyword   rustKeyword     return
+syn keyword   rustSuper       super
+syn keyword   rustKeyword     unsafe where
+syn keyword   rustKeyword     use nextgroup=rustModPath skipwhite skipempty
+" FIXME: Scoped impl's name is also fallen in this category
+syn keyword   rustKeyword     mod trait nextgroup=rustIdentifier skipwhite skipempty
+syn keyword   rustStorage     move mut ref static const
+syn match rustDefault /\<default\ze\_s\+\(impl\|fn\|type\|const\)\>/
+
+syn keyword   rustInvalidBareKeyword crate
+
+syn keyword rustPubScopeCrate crate contained
+syn match rustPubScopeDelim /[()]/ contained
+syn match rustPubScope /([^()]*)/ contained contains=rustPubScopeDelim,rustPubScopeCrate,rustSuper,rustModPath,rustModPathSep,rustSelf transparent
+
+syn keyword   rustExternCrate crate contained nextgroup=rustIdentifier,rustExternCrateString skipwhite skipempty
+" This is to get the `bar` part of `extern crate "foo" as bar;` highlighting.
+syn match   rustExternCrateString /".*"\_s*as/ contained nextgroup=rustIdentifier skipwhite transparent skipempty contains=rustString,rustOperator
+syn keyword   rustObsoleteExternMod mod contained nextgroup=rustIdentifier skipwhite skipempty
+
+syn match     rustIdentifier  contains=rustIdentifierPrime "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained
+syn match     rustFuncName    "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained
+
+syn region    rustBoxPlacement matchgroup=rustBoxPlacementParens start="(" end=")" contains=TOP contained
+" Ideally we'd have syntax rules set up to match arbitrary expressions. Since
+" we don't, we'll just define temporary contained rules to handle balancing
+" delimiters.
+syn region    rustBoxPlacementBalance start="(" end=")" containedin=rustBoxPlacement transparent
+syn region    rustBoxPlacementBalance start="\[" end="\]" containedin=rustBoxPlacement transparent
+" {} are handled by rustFoldBraces
+
+syn region rustMacroRepeat matchgroup=rustMacroRepeatDelimiters start="$(" end=")" contains=TOP nextgroup=rustMacroRepeatCount
+syn match rustMacroRepeatCount ".\?[*+]" contained
+syn match rustMacroVariable "$\w\+"
+
+" Reserved (but not yet used) keywords {{{2
+syn keyword   rustReservedKeyword alignof become do offsetof priv pure sizeof typeof unsized yield abstract virtual final override macro
+
+" Built-in types {{{2
+syn keyword   rustType        isize usize char bool u8 u16 u32 u64 u128 f32
+syn keyword   rustType        f64 i8 i16 i32 i64 i128 str Self
+
+" Things from the libstd v1 prelude (src/libstd/prelude/v1.rs) {{{2
+" This section is just straight transformation of the contents of the prelude,
+" to make it easy to update.
+
+" Reexported core operators {{{3
+syn keyword   rustTrait       Copy Send Sized Sync
+syn keyword   rustTrait       Drop Fn FnMut FnOnce
+
+" Reexported functions {{{3
+" There’s no point in highlighting these; when one writes drop( or drop::< it
+" gets the same highlighting anyway, and if someone writes `let drop = …;` we
+" don’t really want *that* drop to be highlighted.
+"syn keyword rustFunction drop
+
+" Reexported types and traits {{{3
+syn keyword rustTrait Box
+syn keyword rustTrait ToOwned
+syn keyword rustTrait Clone
+syn keyword rustTrait PartialEq PartialOrd Eq Ord
+syn keyword rustTrait AsRef AsMut Into From
+syn keyword rustTrait Default
+syn keyword rustTrait Iterator Extend IntoIterator
+syn keyword rustTrait DoubleEndedIterator ExactSizeIterator
+syn keyword rustEnum Option
+syn keyword rustEnumVariant Some None
+syn keyword rustEnum Result
+syn keyword rustEnumVariant Ok Err
+syn keyword rustTrait SliceConcatExt
+syn keyword rustTrait String ToString
+syn keyword rustTrait Vec
+
+" Other syntax {{{2
+syn keyword   rustSelf        self
+syn keyword   rustBoolean     true false
+
+" If foo::bar changes to foo.bar, change this ("::" to "\.").
+" If foo::bar changes to Foo::bar, change this (first "\w" to "\u").
+syn match     rustModPath     "\w\(\w\)*::[^<]"he=e-3,me=e-3
+syn match     rustModPathSep  "::"
+
+syn match     rustFuncCall    "\w\(\w\)*("he=e-1,me=e-1
+syn match     rustFuncCall    "\w\(\w\)*::<"he=e-3,me=e-3 " foo::<T>();
+
+" This is merely a convention; note also the use of [A-Z], restricting it to
+" latin identifiers rather than the full Unicode uppercase. I have not used
+" [:upper:] as it depends upon 'noignorecase'
+"syn match     rustCapsIdent    display "[A-Z]\w\(\w\)*"
+
+syn match     rustOperator     display "\%(+\|-\|/\|*\|=\|\^\|&\||\|!\|>\|<\|%\)=\?"
+" This one isn't *quite* right, as we could have binary-& with a reference
+syn match     rustSigil        display /&\s\+[&~@*][^)= \t\r\n]/he=e-1,me=e-1
+syn match     rustSigil        display /[&~@*][^)= \t\r\n]/he=e-1,me=e-1
+" This isn't actually correct; a closure with no arguments can be `|| { }`.
+" Last, because the & in && isn't a sigil
+syn match     rustOperator     display "&&\|||"
+" This is rustArrowCharacter rather than rustArrow for the sake of matchparen,
+" so it skips the ->; see http://stackoverflow.com/a/30309949 for details.
+syn match     rustArrowCharacter display "->"
+syn match     rustQuestionMark display "?\([a-zA-Z]\+\)\@!"
+
+syn match     rustMacro       '\w\(\w\)*!' contains=rustAssert,rustPanic
+syn match     rustMacro       '#\w\(\w\)*' contains=rustAssert,rustPanic
+
+syn match     rustEscapeError   display contained /\\./
+syn match     rustEscape        display contained /\\\([nrt0\\'"]\|x\x\{2}\)/
+syn match     rustEscapeUnicode display contained /\\u{\x\{1,6}}/
+syn match     rustStringContinuation display contained /\\\n\s*/
+syn region    rustString      start=+b"+ skip=+\\\\\|\\"+ end=+"+ contains=rustEscape,rustEscapeError,rustStringContinuation
+syn region    rustString      start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=rustEscape,rustEscapeUnicode,rustEscapeError,rustStringContinuation,@Spell
+syn region    rustString      start='b\?r\z(#*\)"' end='"\z1' contains=@Spell
+
+syn region    rustAttribute   start="#!\?\[" end="\]" contains=rustString,rustDerive,rustCommentLine,rustCommentBlock,rustCommentLineDocError,rustCommentBlockDocError
+syn region    rustDerive      start="derive(" end=")" contained contains=rustDeriveTrait
+" This list comes from src/libsyntax/ext/deriving/mod.rs
+" Some are deprecated (Encodable, Decodable) or to be removed after a new snapshot (Show).
+syn keyword   rustDeriveTrait contained Clone Hash RustcEncodable RustcDecodable Encodable Decodable PartialEq Eq PartialOrd Ord Rand Show Debug Default FromPrimitive Send Sync Copy
+
+" Number literals
+syn match     rustDecNumber   display "\<[0-9][0-9_]*\%([iu]\%(size\|8\|16\|32\|64\|128\)\)\="
+syn match     rustHexNumber   display "\<0x[a-fA-F0-9_]\+\%([iu]\%(size\|8\|16\|32\|64\|128\)\)\="
+syn match     rustOctNumber   display "\<0o[0-7_]\+\%([iu]\%(size\|8\|16\|32\|64\|128\)\)\="
+syn match     rustBinNumber   display "\<0b[01_]\+\%([iu]\%(size\|8\|16\|32\|64\|128\)\)\="
+
+" Special case for numbers of the form "1." which are float literals, unless followed by
+" an identifier, which makes them integer literals with a method call or field access,
+" or by another ".", which makes them integer literals followed by the ".." token.
+" (This must go first so the others take precedence.)
+syn match     rustFloat       display "\<[0-9][0-9_]*\.\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\|\.\)\@!"
+" To mark a number as a normal float, it must have at least one of the three things integral values don't have:
+" a decimal point and more numbers; an exponent; and a type suffix.
+syn match     rustFloat       display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\%([eE][+-]\=[0-9_]\+\)\=\(f32\|f64\)\="
+syn match     rustFloat       display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\=\%([eE][+-]\=[0-9_]\+\)\(f32\|f64\)\="
+syn match     rustFloat       display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\=\%([eE][+-]\=[0-9_]\+\)\=\(f32\|f64\)"
+
+" For the benefit of delimitMate
+syn region rustLifetimeCandidate display start=/&'\%(\([^'\\]\|\\\(['nrt0\\\"]\|x\x\{2}\|u{\x\{1,6}}\)\)'\)\@!/ end=/[[:cntrl:][:space:][:punct:]]\@=\|$/ contains=rustSigil,rustLifetime
+syn region rustGenericRegion display start=/<\%('\|[^[cntrl:][:space:][:punct:]]\)\@=')\S\@=/ end=/>/ contains=rustGenericLifetimeCandidate
+syn region rustGenericLifetimeCandidate display start=/\%(<\|,\s*\)\@<='/ end=/[[:cntrl:][:space:][:punct:]]\@=\|$/ contains=rustSigil,rustLifetime
+
+"rustLifetime must appear before rustCharacter, or chars will get the lifetime highlighting
+syn match     rustLifetime    display "\'\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*"
+syn match     rustLabel       display "\'\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*:"
+syn match   rustCharacterInvalid   display contained /b\?'\zs[\n\r\t']\ze'/
+" The groups negated here add up to 0-255 but nothing else (they do not seem to go beyond ASCII).
+syn match   rustCharacterInvalidUnicode   display contained /b'\zs[^[:cntrl:][:graph:][:alnum:][:space:]]\ze'/
+syn match   rustCharacter   /b'\([^\\]\|\\\(.\|x\x\{2}\)\)'/ contains=rustEscape,rustEscapeError,rustCharacterInvalid,rustCharacterInvalidUnicode
+syn match   rustCharacter   /'\([^\\]\|\\\(.\|x\x\{2}\|u{\x\{1,6}}\)\)'/ contains=rustEscape,rustEscapeUnicode,rustEscapeError,rustCharacterInvalid
+
+syn match rustShebang /\%^#![^[].*/
+syn region rustCommentLine                                                  start="//"                      end="$"   contains=rustTodo,@Spell
+syn region rustCommentLineDoc                                               start="//\%(//\@!\|!\)"         end="$"   contains=rustTodo,@Spell
+syn region rustCommentLineDocError                                          start="//\%(//\@!\|!\)"         end="$"   contains=rustTodo,@Spell contained
+syn region rustCommentBlock             matchgroup=rustCommentBlock         start="/\*\%(!\|\*[*/]\@!\)\@!" end="\*/" contains=rustTodo,rustCommentBlockNest,@Spell
+syn region rustCommentBlockDoc          matchgroup=rustCommentBlockDoc      start="/\*\%(!\|\*[*/]\@!\)"    end="\*/" contains=rustTodo,rustCommentBlockDocNest,@Spell
+syn region rustCommentBlockDocError     matchgroup=rustCommentBlockDocError start="/\*\%(!\|\*[*/]\@!\)"    end="\*/" contains=rustTodo,rustCommentBlockDocNestError,@Spell contained
+syn region rustCommentBlockNest         matchgroup=rustCommentBlock         start="/\*"                     end="\*/" contains=rustTodo,rustCommentBlockNest,@Spell contained transparent
+syn region rustCommentBlockDocNest      matchgroup=rustCommentBlockDoc      start="/\*"                     end="\*/" contains=rustTodo,rustCommentBlockDocNest,@Spell contained transparent
+syn region rustCommentBlockDocNestError matchgroup=rustCommentBlockDocError start="/\*"                     end="\*/" contains=rustTodo,rustCommentBlockDocNestError,@Spell contained transparent
+" FIXME: this is a really ugly and not fully correct implementation. Most
+" importantly, a case like ``/* */*`` should have the final ``*`` not being in
+" a comment, but in practice at present it leaves comments open two levels
+" deep. But as long as you stay away from that particular case, I *believe*
+" the highlighting is correct. Due to the way Vim's syntax engine works
+" (greedy for start matches, unlike Rust's tokeniser which is searching for
+" the earliest-starting match, start or end), I believe this cannot be solved.
+" Oh you who would fix it, don't bother with things like duplicating the Block
+" rules and putting ``\*\@<!`` at the start of them; it makes it worse, as
+" then you must deal with cases like ``/*/**/*/``. And don't try making it
+" worse with ``\%(/\@<!\*\)\@<!``, either...
+
+syn keyword rustTodo contained TODO FIXME XXX NB NOTE
+
+" Folding rules {{{2
+" Trivial folding rules to begin with.
+" FIXME: use the AST to make really good folding
+syn region rustFoldBraces start="{" end="}" transparent fold
+
+" Default highlighting {{{1
+hi def link rustDecNumber       rustNumber
+hi def link rustHexNumber       rustNumber
+hi def link rustOctNumber       rustNumber
+hi def link rustBinNumber       rustNumber
+hi def link rustIdentifierPrime rustIdentifier
+hi def link rustTrait           rustType
+hi def link rustDeriveTrait     rustTrait
+
+hi def link rustMacroRepeatCount   rustMacroRepeatDelimiters
+hi def link rustMacroRepeatDelimiters   Macro
+hi def link rustMacroVariable Define
+hi def link rustSigil         StorageClass
+hi def link rustEscape        Special
+hi def link rustEscapeUnicode rustEscape
+hi def link rustEscapeError   Error
+hi def link rustStringContinuation Special
+hi def link rustString        String
+hi def link rustCharacterInvalid Error
+hi def link rustCharacterInvalidUnicode rustCharacterInvalid
+hi def link rustCharacter     Character
+hi def link rustNumber        Number
+hi def link rustBoolean       Boolean
+hi def link rustEnum          rustType
+hi def link rustEnumVariant   rustConstant
+hi def link rustConstant      Constant
+hi def link rustSelf          Constant
+hi def link rustFloat         Float
+hi def link rustArrowCharacter rustOperator
+hi def link rustOperator      Operator
+hi def link rustKeyword       Keyword
+hi def link rustTypedef       Keyword " More precise is Typedef, but it doesn't feel right for Rust
+hi def link rustStructure     Keyword " More precise is Structure
+hi def link rustUnion         rustStructure
+hi def link rustPubScopeDelim Delimiter
+hi def link rustPubScopeCrate rustKeyword
+hi def link rustSuper         rustKeyword
+hi def link rustReservedKeyword Error
+hi def link rustRepeat        Conditional
+hi def link rustConditional   Conditional
+hi def link rustIdentifier    Identifier
+hi def link rustCapsIdent     rustIdentifier
+hi def link rustModPath       Include
+hi def link rustModPathSep    Delimiter
+hi def link rustFunction      Function
+hi def link rustFuncName      Function
+hi def link rustFuncCall      Function
+hi def link rustShebang       Comment
+hi def link rustCommentLine   Comment
+hi def link rustCommentLineDoc SpecialComment
+hi def link rustCommentLineDocError Error
+hi def link rustCommentBlock  rustCommentLine
+hi def link rustCommentBlockDoc rustCommentLineDoc
+hi def link rustCommentBlockDocError Error
+hi def link rustAssert        PreCondit
+hi def link rustPanic         PreCondit
+hi def link rustMacro         Macro
+hi def link rustType          Type
+hi def link rustTodo          Todo
+hi def link rustAttribute     PreProc
+hi def link rustDerive        PreProc
+hi def link rustDefault       StorageClass
+hi def link rustStorage       StorageClass
+hi def link rustObsoleteStorage Error
+hi def link rustLifetime      Special
+hi def link rustLabel         Label
+hi def link rustInvalidBareKeyword Error
+hi def link rustExternCrate   rustKeyword
+hi def link rustObsoleteExternMod Error
+hi def link rustBoxPlacementParens Delimiter
+hi def link rustQuestionMark  Special
+
+" Other Suggestions:
+" hi rustAttribute ctermfg=cyan
+" hi rustDerive ctermfg=cyan
+" hi rustAssert ctermfg=yellow
+" hi rustPanic ctermfg=red
+" hi rustMacro ctermfg=magenta
+
+syn sync minlines=200
+syn sync maxlines=500
+
+let b:current_syntax = "rust"
index 90d411d..82ffe60 100644 (file)
 " Vim syntax file
-" Language:    SAS
-" Maintainer:  James Kidd <james.kidd@covance.com>
-" Last Change:  2012 Apr 20
-"               Corrected bug causing some keywords to appear as strings instead
-"               18 Jul 2008 by Paulo Tanimoto <ptanimoto@gmail.com>
-"               Fixed comments with * taking multiple lines.
-"               Fixed highlighting of macro keywords.
-"               Added words to cases that didn't fit anywhere.
-"              02 Jun 2003
-"              Added highlighting for additional keywords and such;
-"              Attempted to match SAS default syntax colors;
-"              Changed syncing so it doesn't lose colors on large blocks;
-"              Much thanks to Bob Heckel for knowledgeable tweaking.
-"  quit when a syntax file was already loaded
-if exists("b:current_syntax")
-   finish
+" Language:     SAS
+" Maintainer:   Zhen-Huan Hu <wildkeny@gmail.com>
+" Original Maintainer: James Kidd <james.kidd@covance.com>
+" Version:      3.0.0
+" Last Change:  Mar 10, 2017
+"
+" 2017 Mar 7
+"
+" Upgrade version number to 3.0. Improvements include:
+" - Improve sync speed
+" - Largely enhance precision
+" - Update keywords in the latest SAS (as of Mar 2017)
+" - Add syntaxes for date/time constants
+" - Add syntax for data lines
+" - Add (back) syntax for TODO in comments
+"
+" 2017 Feb 9
+"
+" Add syntax folding 
+"
+" 2016 Oct 10
+"
+" Add highlighting for functions
+"
+" 2016 Sep 14
+"
+" Change the implementation of syntaxing
+" macro function names so that macro parameters same
+" as SAS keywords won't be highlighted
+" (Thank Joug Raw for the suggestion)
+" Add section highlighting:
+" - Use /** and **/ to define a section
+" - It functions the same as a comment but
+"   with different highlighting
+"
+" 2016 Jun 14
+"
+" Major changes so upgrade version number to 2.0
+" Overhaul the entire script (again). Improvements include:
+" - Higher precision
+" - Faster synchronization
+" - Separate color for control statements
+" - Highlight hash and java objects
+" - Highlight macro variables in double quoted strings
+" - Update all syntaxes based on SAS 9.4
+" - Add complete SAS/GRAPH and SAS/STAT procedure syntaxes
+" - Add Proc TEMPLATE and GTL syntaxes
+" - Add complete DS2 syntaxes
+" - Add basic IML syntaxes
+" - Many other improvements and bug fixes
+" Drop support for VIM version < 600
+
+if version < 600
+  syntax clear
+elseif exists('b:current_syntax')
+  finish
 endif
 
-syn case ignore
-
-syn region sasString   start=+"+  skip=+\\\\\|\\"+  end=+"+
-syn region sasString   start=+'+  skip=+\\\\\|\\"+  end=+'+
-
-" Want region from 'cards;' to ';' to be captured (Bob Heckel)
-syn region sasCards    start="^\s*CARDS.*" end="^\s*;\s*$"
-syn region sasCards    start="^\s*DATALINES.*" end="^\s*;\s*$"
-
-syn match sasNumber    "-\=\<\d*\.\=[0-9_]\>"
-
-" Block comment
-syn region sasComment  start="/\*"  end="\*/" contains=sasTodo
-
-" Ignore misleading //JCL SYNTAX... (Bob Heckel)
-syn region sasComment  start="[^/][^/]/\*"  end="\*/" contains=sasTodo
-
-" Previous code for comments was written by Bob Heckel
-" Comments with * may take multiple lines (Paulo Tanimoto)
-syn region sasComment start=";\s*\*"hs=s+1 end=";" contains=sasTodo
-
-" Comments with * starting after a semicolon (Paulo Tanimoto)
-syn region sasComment start="^\s*\*" end=";" contains=sasTodo
-
-" This line defines macro variables in code.  "hi def link" at end of file
-" defines the color scheme. Begin region with ampersand and end with
-" any non-word character offset by -1; put ampersand in the skip list
-" just in case it is used to concatenate macro variable values.
-
-" Thanks to ronald höllwarth for this fix to an intra-versioning
-" problem with this little feature
-
-syn region sasMacroVar start="&" skip="[_&]" end="\W"he=e-1
-
-
-" I dont think specific PROCs need to be listed if use this line (Bob Heckel).
-syn match sasProc              "^\s*PROC \w\+"
-syn keyword sasStep            RUN QUIT DATA
-
-
-" Base SAS Procs - version 8.1
-
-syn keyword sasConditional     DO ELSE END IF THEN UNTIL WHILE
-
-syn keyword sasStatement       ABORT ARRAY ATTRIB BY CALL CARDS CARDS4 CATNAME
-syn keyword sasStatement       CONTINUE DATALINES DATALINES4 DELETE DISPLAY
-syn keyword sasStatement       DM DROP ENDSAS ERROR FILE FILENAME FOOTNOTE
-syn keyword sasStatement       FORMAT GOTO INFILE INFORMAT INPUT KEEP
-syn keyword sasStatement       LABEL LEAVE LENGTH LIBNAME LINK LIST LOSTCARD
-syn keyword sasStatement       MERGE MISSING MODIFY OPTIONS OUTPUT PAGE
-syn keyword sasStatement       PUT REDIRECT REMOVE RENAME REPLACE RETAIN
-syn keyword sasStatement       RETURN SELECT SET SKIP STARTSAS STOP TITLE
-syn keyword sasStatement       UPDATE WAITSAS WHERE WINDOW X SYSTASK
+let s:cpo_save = &cpo
+set cpo&vim
 
-" Keywords that are used in Proc SQL
-" I left them as statements because SAS's enhanced editor highlights
-" them the same as normal statements used in data steps (Jim Kidd)
-
-syn keyword sasStatement       ADD AND ALTER AS CASCADE CHECK CREATE
-syn keyword sasStatement       DELETE DESCRIBE DISTINCT DROP FOREIGN
-syn keyword sasStatement       FROM GROUP HAVING INDEX INSERT INTO IN
-syn keyword sasStatement       KEY LIKE MESSAGE MODIFY MSGTYPE NOT
-syn keyword sasStatement       NULL ON OR ORDER PRIMARY REFERENCES
-syn keyword sasStatement       RESET RESTRICT SELECT SET TABLE
-syn keyword sasStatement       UNIQUE UPDATE VALIDATE VIEW WHERE
-
-" Match declarations have to appear one per line (Paulo Tanimoto)
-syn match sasStatement "FOOTNOTE\d"
-syn match sasStatement "TITLE\d"
-
-" Match declarations have to appear one per line (Paulo Tanimoto)
-syn match sasMacro "%BQUOTE"
-syn match sasMacro "%NRBQUOTE"
-syn match sasMacro "%CMPRES"
-syn match sasMacro "%QCMPRES"
-syn match sasMacro "%COMPSTOR"
-syn match sasMacro "%DATATYP"
-syn match sasMacro "%DISPLAY"
-syn match sasMacro "%DO"
-syn match sasMacro "%ELSE"
-syn match sasMacro "%END"
-syn match sasMacro "%EVAL"
-syn match sasMacro "%GLOBAL"
-syn match sasMacro "%GOTO"
-syn match sasMacro "%IF"
-syn match sasMacro "%INDEX"
-syn match sasMacro "%INPUT"
-syn match sasMacro "%KEYDEF"
-syn match sasMacro "%LABEL"
-syn match sasMacro "%LEFT"
-syn match sasMacro "%LENGTH"
-syn match sasMacro "%LET"
-syn match sasMacro "%LOCAL"
-syn match sasMacro "%LOWCASE"
-syn match sasMacro "%MACRO"
-syn match sasMacro "%MEND"
-syn match sasMacro "%NRBQUOTE"
-syn match sasMacro "%NRQUOTE"
-syn match sasMacro "%NRSTR"
-syn match sasMacro "%PUT"
-syn match sasMacro "%QCMPRES"
-syn match sasMacro "%QLEFT"
-syn match sasMacro "%QLOWCASE"
-syn match sasMacro "%QSCAN"
-syn match sasMacro "%QSUBSTR"
-syn match sasMacro "%QSYSFUNC"
-syn match sasMacro "%QTRIM"
-syn match sasMacro "%QUOTE"
-syn match sasMacro "%QUPCASE"
-syn match sasMacro "%SCAN"
-syn match sasMacro "%STR"
-syn match sasMacro "%SUBSTR"
-syn match sasMacro "%SUPERQ"
-syn match sasMacro "%SYSCALL"
-syn match sasMacro "%SYSEVALF"
-syn match sasMacro "%SYSEXEC"
-syn match sasMacro "%SYSFUNC"
-syn match sasMacro "%SYSGET"
-syn match sasMacro "%SYSLPUT"
-syn match sasMacro "%SYSPROD"
-syn match sasMacro "%SYSRC"
-syn match sasMacro "%SYSRPUT"
-syn match sasMacro "%THEN"
-syn match sasMacro "%TO"
-syn match sasMacro "%TRIM"
-syn match sasMacro "%UNQUOTE"
-syn match sasMacro "%UNTIL"
-syn match sasMacro "%UPCASE"
-syn match sasMacro "%VERIFY"
-syn match sasMacro "%WHILE"
-syn match sasMacro "%WINDOW"
-
-" SAS Functions
-
-syn keyword sasFunction        ABS ADDR AIRY ARCOS ARSIN ATAN ATTRC ATTRN
-syn keyword sasFunction        BAND BETAINV BLSHIFT BNOT BOR BRSHIFT BXOR
-syn keyword sasFunction        BYTE CDF CEIL CEXIST CINV CLOSE CNONCT COLLATE
-syn keyword sasFunction        COMPBL COMPOUND COMPRESS COS COSH CSS CUROBS
-syn keyword sasFunction        CV DACCDB DACCDBSL DACCSL DACCSYD DACCTAB
-syn keyword sasFunction        DAIRY DATE DATEJUL DATEPART DATETIME DAY
-syn keyword sasFunction        DCLOSE DEPDB DEPDBSL DEPDBSL DEPSL DEPSL
-syn keyword sasFunction        DEPSYD DEPSYD DEPTAB DEPTAB DEQUOTE DHMS
-syn keyword sasFunction        DIF DIGAMMA DIM DINFO DNUM DOPEN DOPTNAME
-syn keyword sasFunction        DOPTNUM DREAD DROPNOTE DSNAME ERF ERFC EXIST
-syn keyword sasFunction        EXP FAPPEND FCLOSE FCOL FDELETE FETCH FETCHOBS
-syn keyword sasFunction        FEXIST FGET FILEEXIST FILENAME FILEREF FINFO
-syn keyword sasFunction        FINV FIPNAME FIPNAMEL FIPSTATE FLOOR FNONCT
-syn keyword sasFunction        FNOTE FOPEN FOPTNAME FOPTNUM FPOINT FPOS
-syn keyword sasFunction        FPUT FREAD FREWIND FRLEN FSEP FUZZ FWRITE
-syn keyword sasFunction        GAMINV GAMMA GETOPTION GETVARC GETVARN HBOUND
-syn keyword sasFunction        HMS HOSTHELP HOUR IBESSEL INDEX INDEXC
-syn keyword sasFunction        INDEXW INPUT INPUTC INPUTN INT INTCK INTNX
-syn keyword sasFunction        INTRR IRR JBESSEL JULDATE KURTOSIS LAG LBOUND
-syn keyword sasFunction        LEFT LENGTH LGAMMA LIBNAME LIBREF LOG LOG10
-syn keyword sasFunction        LOG2 LOGPDF LOGPMF LOGSDF LOWCASE MAX MDY
-syn keyword sasFunction        MEAN MIN MINUTE MOD MONTH MOPEN MORT N
-syn keyword sasFunction        NETPV NMISS NORMAL NOTE NPV OPEN ORDINAL
-syn keyword sasFunction        PATHNAME PDF PEEK PEEKC PMF POINT POISSON POKE
-syn keyword sasFunction        PROBBETA PROBBNML PROBCHI PROBF PROBGAM
-syn keyword sasFunction        PROBHYPR PROBIT PROBNEGB PROBNORM PROBT PUT
-syn keyword sasFunction        PUTC PUTN QTR QUOTE RANBIN RANCAU RANEXP
-syn keyword sasFunction        RANGAM RANGE RANK RANNOR RANPOI RANTBL RANTRI
-syn keyword sasFunction        RANUNI REPEAT RESOLVE REVERSE REWIND RIGHT
-syn keyword sasFunction        ROUND SAVING SCAN SDF SECOND SIGN SIN SINH
-syn keyword sasFunction        SKEWNESS SOUNDEX SPEDIS SQRT STD STDERR STFIPS
-syn keyword sasFunction        STNAME STNAMEL SUBSTR SUM SYMGET SYSGET SYSMSG
-syn keyword sasFunction        SYSPROD SYSRC SYSTEM TAN TANH TIME TIMEPART
-syn keyword sasFunction        TINV TNONCT TODAY TRANSLATE TRANWRD TRIGAMMA
-syn keyword sasFunction        TRIM TRIMN TRUNC UNIFORM UPCASE USS VAR
-syn keyword sasFunction        VARFMT VARINFMT VARLABEL VARLEN VARNAME
-syn keyword sasFunction        VARNUM VARRAY VARRAYX VARTYPE VERIFY VFORMAT
-syn keyword sasFunction        VFORMATD VFORMATDX VFORMATN VFORMATNX VFORMATW
-syn keyword sasFunction        VFORMATWX VFORMATX VINARRAY VINARRAYX VINFORMAT
-syn keyword sasFunction        VINFORMATD VINFORMATDX VINFORMATN VINFORMATNX
-syn keyword sasFunction        VINFORMATW VINFORMATWX VINFORMATX VLABEL
-syn keyword sasFunction        VLABELX VLENGTH VLENGTHX VNAME VNAMEX VTYPE
-syn keyword sasFunction        VTYPEX WEEKDAY YEAR YYQ ZIPFIPS ZIPNAME ZIPNAMEL
-syn keyword sasFunction        ZIPSTATE
-
-" Handy settings for using vim with log files
-syn keyword sasLogMsg  NOTE
-syn keyword sasWarnMsg WARNING
-syn keyword sasErrMsg  ERROR
-
-" Always contained in a comment (Bob Heckel)
-syn keyword sasTodo    TODO TBD FIXME contained
-
-" These don't fit anywhere else (Bob Heckel).
-" Added others that were missing.
-syn keyword sasUnderscore      _ALL_ _AUTOMATIC_ _CHARACTER_ _INFILE_ _N_ _NAME_ _NULL_ _NUMERIC_ _USER_ _WEBOUT_
-
-" End of SAS Functions
-
-"  Define the default highlighting.
-"  Only when an item doesn't have highlighting yet
-
-
-" Default sas enhanced editor color syntax
-hi sComment    term=bold cterm=NONE ctermfg=Green ctermbg=Black gui=NONE guifg=DarkGreen guibg=White
-hi sCard       term=bold cterm=NONE ctermfg=Black ctermbg=Yellow gui=NONE guifg=Black guibg=LightYellow
-hi sDate_Time  term=NONE cterm=bold ctermfg=Green ctermbg=Black gui=bold guifg=SeaGreen guibg=White
-hi sKeyword    term=NONE cterm=NONE ctermfg=Blue  ctermbg=Black gui=NONE guifg=Blue guibg=White
-hi sFmtInfmt   term=NONE cterm=NONE ctermfg=LightGreen ctermbg=Black gui=NONE guifg=SeaGreen guibg=White
-hi sString     term=NONE cterm=NONE ctermfg=Magenta ctermbg=Black gui=NONE guifg=Purple guibg=White
-hi sText       term=NONE cterm=NONE ctermfg=White ctermbg=Black gui=bold guifg=Black guibg=White
-hi sNumber     term=NONE cterm=bold ctermfg=Green ctermbg=Black gui=bold guifg=SeaGreen guibg=White
-hi sProc       term=NONE cterm=bold ctermfg=Blue ctermbg=Black gui=bold guifg=Navy guibg=White
-hi sSection    term=NONE cterm=bold ctermfg=Blue ctermbg=Black gui=bold guifg=Navy guibg=White
-hi mDefine     term=NONE cterm=bold ctermfg=White ctermbg=Black gui=bold guifg=Black guibg=White
-hi mKeyword    term=NONE cterm=NONE ctermfg=Blue ctermbg=Black gui=NONE guifg=Blue guibg=White
-hi mReference  term=NONE cterm=bold ctermfg=White ctermbg=Black gui=bold guifg=Blue guibg=White
-hi mSection    term=NONE cterm=NONE ctermfg=Blue ctermbg=Black gui=bold guifg=Navy guibg=White
-hi mText       term=NONE cterm=NONE ctermfg=White ctermbg=Black gui=bold guifg=Black guibg=White
-
-" Colors that closely match SAS log colors for default color scheme
-hi lError      term=NONE cterm=NONE ctermfg=Red ctermbg=Black gui=none guifg=Red guibg=White
-hi lWarning    term=NONE cterm=NONE ctermfg=Green ctermbg=Black gui=none guifg=Green guibg=White
-hi lNote       term=NONE cterm=NONE ctermfg=Cyan ctermbg=Black gui=none guifg=Blue guibg=White
-
-
-" Special hilighting for the SAS proc section
+syn case ignore
 
-hi def link sasComment sComment
-hi def link sasConditional     sKeyword
-hi def link sasStep            sSection
-hi def link sasFunction        sKeyword
-hi def link sasMacro   mKeyword
-hi def link sasMacroVar        NonText
-hi def link sasNumber  sNumber
-hi def link sasStatement       sKeyword
-hi def link sasString  sString
-hi def link sasProc            sProc
-" (Bob Heckel)
-hi def link sasTodo            Todo
-hi def link sasErrMsg  lError
-hi def link sasWarnMsg lWarning
-hi def link sasLogMsg  lNote
-hi def link sasCards   sCard
-" (Bob Heckel)
-hi def link sasUnderscore      PreProc
+" Basic SAS syntaxes
+syn keyword sasOperator and eq ge gt in le lt ne not of or
+syn keyword sasReserved _all_ _automatic_ _char_ _character_ _data_ _infile_ _last_ _n_ _name_ _null_ _num_ _numeric_ _temporary_ _user_ _webout_
+" Strings
+syn region sasString start=+'+ skip=+''+ end=+'+ contains=@Spell
+syn region sasString start=+"+ skip=+""+ end=+"+ contains=sasMacroVariable,@Spell
+" Constants
+syn match sasNumber /\v<\d+%(\.\d+)=%(>|e[\-+]=\d+>)/ display
+syn match sasDateTime /\v(['"])\d{2}%(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d{2}%(\d{2})=:\d{2}:\d{2}%(:\d{2})=%(am|pm)\1dt>/ display
+syn match sasDateTime /\v(['"])\d{2}%(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d{2}%(\d{2})=\1d>/ display
+syn match sasDateTime /\v(['"])\d{2}:\d{2}%(:\d{2})=%(am|pm)\1t>/ display
+" Comments
+syn keyword sasTodo todo tbd fixme contained
+syn region sasComment start='/\*' end='\*/' contains=sasTodo
+syn region sasComment start='\v%(^|;)\s*\zs\%=\*' end=';'me=s-1 contains=sasTodo
+syn region sasSectLbl matchgroup=sasSectLblEnds start='/\*\*\s*' end='\s*\*\*/' concealends
+" Macros
+syn match sasMacroVariable '\v\&+\w+%(\.\w+)=' display
+syn match sasMacroReserved '\v\%%(abort|by|copy|display|do|else|end|global|goto|if|include|input|let|list|local|macro|mend|put|return|run|symdel|syscall|sysexec|syslput|sysrput|then|to|until|window|while)>' display
+syn region sasMacroFunction matchgroup=sasMacroFunctionName start='\v\%\w+\ze\(' end=')'he=s-1 contains=@sasBasicSyntax,sasMacroFunction
+syn region sasMacroFunction matchgroup=sasMacroFunctionName start='\v\%q=sysfunc\ze\(' end=')'he=s-1 contains=@sasBasicSyntax,sasMacroFunction,sasDataStepFunction
+" Syntax cluster for basic SAS syntaxes
+syn cluster sasBasicSyntax contains=sasOperator,sasReserved,sasNumber,sasDateTime,sasString,sasComment,sasMacroReserved,sasMacroFunction,sasMacroVariable,sasSectLbl
+
+" Formats
+syn match sasFormat '\v\$\w+\.' display contained
+syn match sasFormat '\v<\w+\.%(\d+>)=' display contained
+syn region sasFormatContext start='.' end=';'me=s-1 contained contains=@sasBasicSyntax,sasFormat
+
+" Define global statements that can be accessed out of data step or procedures
+syn keyword sasGlobalStatementKeyword catname dm endsas filename footnote footnote1 footnote2 footnote3 footnote4 footnote5 footnote6 footnote7 footnote8 footnote9 footnote10 missing libname lock ods options page quit resetline run sasfile skip sysecho title title1 title2 title3 title4 title5 title6 title7 title8 title9 title10 contained
+syn keyword sasGlobalStatementODSKeyword chtml csvall docbook document escapechar epub epub2 epub3 exclude excel graphics html html3 html5 htmlcss imode listing markup output package path pcl pdf preferences phtml powerpoint printer proclabel proctitle ps results rtf select show tagsets trace usegopt verify wml contained
+syn match sasGlobalStatement '\v%(^|;)\s*\zs\h\w*>' display transparent contains=sasGlobalStatementKeyword
+syn match sasGlobalStatement '\v%(^|;)\s*\zsods>' display transparent contains=sasGlobalStatementKeyword nextgroup=sasGlobalStatementODSKeyword skipwhite skipnl skipempty
+
+" Data step statements, 9.4
+syn keyword sasDataStepFunctionName abs addr addrlong airy allcomb allperm anyalnum anyalpha anycntrl anydigit anyfirst anygraph anylower anyname anyprint anypunct anyspace anyupper anyxdigit arcos arcosh arsin arsinh artanh atan atan2 attrc attrn band beta betainv blackclprc blackptprc blkshclprc blkshptprc blshift bnot bor brshift bxor byte cat catq cats catt catx cdf ceil ceilz cexist char choosec choosen cinv close cmiss cnonct coalesce coalescec collate comb compare compbl compfuzz compged complev compound compress constant convx convxp cos cosh cot count countc countw csc css cumipmt cumprinc curobs cv daccdb daccdbsl daccsl daccsyd dacctab dairy datdif date datejul datepart datetime day dclose dcreate depdb depdbsl depsl depsyd deptab dequote deviance dhms dif digamma dim dinfo divide dnum dopen doptname doptnum dosubl dread dropnote dsname dsncatlgd dur durp effrate envlen erf erfc euclid exist exp fact fappend fclose fcol fcopy fdelete fetch fetchobs fexist fget fileexist filename fileref finance find findc findw finfo finv fipname fipnamel fipstate first floor floorz fmtinfo fnonct fnote fopen foptname foptnum fpoint fpos fput fread frewind frlen fsep fuzz fwrite gaminv gamma garkhclprc garkhptprc gcd geodist geomean geomeanz getoption getvarc getvarn graycode harmean harmeanz hbound hms holiday holidayck holidaycount holidayname holidaynx holidayny holidaytest hour htmldecode htmlencode ibessel ifc ifn index indexc indexw input inputc inputn int intcindex intck intcycle intfit intfmt intget intindex intnx intrr intseas intshift inttest intz iorcmsg ipmt iqr irr jbessel juldate juldate7 kurtosis lag largest lbound lcm lcomb left length lengthc lengthm lengthn lexcomb lexcombi lexperk lexperm lfact lgamma libname libref log log1px log10 log2 logbeta logcdf logistic logpdf logsdf lowcase lperm lpnorm mad margrclprc margrptprc max md5 mdy mean median min minute missing mod modexist module modulec modulen modz month mopen mort msplint mvalid contained
+syn keyword sasDataStepFunctionName n netpv nliteral nmiss nomrate normal notalnum notalpha notcntrl notdigit note notfirst notgraph notlower notname notprint notpunct notspace notupper notxdigit npv nvalid nwkdom open ordinal pathname pctl pdf peek peekc peekclong peeklong perm pmt point poisson ppmt probbeta probbnml probbnrm probchi probf probgam probhypr probit probmc probnegb probnorm probt propcase prxchange prxmatch prxparen prxparse prxposn ptrlongadd put putc putn pvp qtr quantile quote ranbin rancau rand ranexp rangam range rank rannor ranpoi rantbl rantri ranuni rename repeat resolve reverse rewind right rms round rounde roundz saving savings scan sdf sec second sha256 sha256hex sha256hmachex sign sin sinh skewness sleep smallest soapweb soapwebmeta soapwipservice soapwipsrs soapws soapwsmeta soundex spedis sqrt squantile std stderr stfips stname stnamel strip subpad substr substrn sum sumabs symexist symget symglobl symlocal sysexist sysget sysmsg sysparm sysprocessid sysprocessname sysprod sysrc system tan tanh time timepart timevalue tinv tnonct today translate transtrn tranwrd trigamma trim trimn trunc tso typeof tzoneid tzonename tzoneoff tzones2u tzoneu2s uniform upcase urldecode urlencode uss uuidgen var varfmt varinfmt varlabel varlen varname varnum varray varrayx vartype verify vformat vformatd vformatdx vformatn vformatnx vformatw vformatwx vformatx vinarray vinarrayx vinformat vinformatd vinformatdx vinformatn vinformatnx vinformatw vinformatwx vinformatx vlabel vlabelx vlength vlengthx vname vnamex vtype vtypex vvalue vvaluex week weekday whichc whichn wto year yieldp yrdif yyq zipcity zipcitydistance zipfips zipname zipnamel zipstate contained
+syn keyword sasDataStepCallRoutineName allcomb allcombi allperm cats catt catx compcost execute graycode is8601_convert label lexcomb lexcombi lexperk lexperm logistic missing module poke pokelong prxchange prxdebug prxfree prxnext prxposn prxsubstr ranbin rancau rancomb ranexp rangam rannor ranperk ranperm ranpoi rantbl rantri ranuni scan set sleep softmax sortc sortn stdize streaminit symput symputx system tanh tso vname vnext wto contained
+syn region sasDataStepFunctionContext start='(' end=')' contained contains=@sasBasicSyntax,sasDataStepFunction
+syn region sasDataStepFunctionFormatContext start='(' end=')' contained contains=@sasBasicSyntax,sasDataStepFunction,sasFormat
+syn match sasDataStepFunction '\v<\w+\ze\(' contained contains=sasDataStepFunctionName,sasDataStepCallRoutineName nextgroup=sasDataStepFunctionContext
+syn match sasDataStepFunction '\v%(input|put)\ze\(' contained contains=sasDataStepFunctionName nextgroup=sasDataStepFunctionFormatContext
+syn keyword sasDataStepHashMethodName add check clear definedata definedone definekey delete do_over equals find find_next find_prev first has_next has_prev last next output prev ref remove removedup replace replacedup reset_dup setcur sum sumdup contained
+syn region sasDataStepHashMethodContext start='(' end=')' contained contains=@sasBasicSyntax,sasDataStepFunction
+syn match sasDataStepHashMethod '\v\.\w+\ze\(' contained contains=sasDataStepHashMethodName nextgroup=sasDataStepHashMethodContext
+syn keyword sasDataStepHashAttributeName item_size num_items contained
+syn match sasDataStepHashAttribute '\v\.\w+>\ze\_[^(]' display contained contains=sasDataStepHashAttributeName
+syn keyword sasDataStepControl continue do end go goto if leave link otherwise over return select to until when while contained
+syn keyword sasDataStepControl else then contained nextgroup=sasDataStepStatementKeyword skipwhite skipnl skipempty
+syn keyword sasDataStepHashOperator _new_ contained
+syn keyword sasDataStepStatementKeyword abort array attrib by call cards cards4 datalines datalines4 dcl declare delete describe display drop error execute file format infile informat input keep label length lines lines4 list lostcard merge modify output put putlog redirect remove rename replace retain set stop update where window contained
+syn keyword sasDataStepStatementHashKeyword hash hiter javaobj contained
+syn match sasDataStepStatement '\v%(^|;)\s*\zs\h\w*>' display contained contains=sasDataStepStatementKeyword,sasGlobalStatementKeyword
+syn match sasDataStepStatement '\v%(^|;)\s*\zs%(dcl|declare)>' display contained contains=sasDataStepStatementKeyword nextgroup=sasDataStepStatementHashKeyword skipwhite skipnl skipempty
+syn match sasDataStepStatement '\v%(^|;)\s*\zsods>' display contained contains=sasGlobalStatementKeyword nextgroup=sasGlobalStatementODSKeyword skipwhite skipnl skipempty
+syn match sasDataStepStatement '\v%(^|;)\s*\zs%(format|informat|input|put)>' display contained contains=sasDataStepStatementKeyword nextgroup=sasFormatContext skipwhite skipnl skipempty
+syn match sasDataStepStatement '\v%(^|;)\s*\zs%(cards|datalines|lines)4=\s*;' display contained contains=sasDataStepStatementKeyword nextgroup=sasDataLine skipwhite skipnl skipempty
+syn region sasDataLine start='^' end='^;'me=s-1 contained
+syn region sasDataStep matchgroup=sasSectionKeyword start='\v%(^|;)\s*\zsdata>' end='\v%(^|;)\s*%(run|data|proc|endsas)>'me=s-1 fold contains=@sasBasicSyntax,@sasDataStepSyntax
+syn cluster sasDataStepSyntax contains=sasDataStepFunction,sasDataStepHashOperator,sasDataStepHashAttribute,sasDataStepHashMethod,sasDataStepControl,sasDataStepStatement
+
+" Procedures, base SAS, 9.4
+syn keyword sasProcStatementKeyword abort age append array attrib audit block break by calid cdfplot change checkbox class classlev column compute contents copy create datarow dbencoding define delete deletefunc deletesubr delimiter device dialog dur endcomp exact exchange exclude explore fin fmtlib fontfile fontpath format formats freq function getnames guessingrows hbar hdfs histogram holidur holifin holistart holivar id idlabel informat inset invalue item key keylabel keyword label line link listfunc listsubr mapmiss mapreduce mean menu messages meta modify opentype outargs outdur outfin output outstart pageby partial picture pie pig plot ppplot printer probplot profile prompter qqplot radiobox ranks rbreak rbutton rebuild record remove rename repair report roptions save select selection separator source star start statistics struct submenu subroutine sum sumby table tables test text trantab truetype type1 types value var vbar ways weight where with write contained
+syn match sasProcStatement '\v%(^|;)\s*\zs\h\w*>' display contained contains=sasProcStatementKeyword,sasGlobalStatementKeyword
+syn match sasProcStatement '\v%(^|;)\s*\zsods>' display contained contains=sasGlobalStatementKeyword nextgroup=sasGlobalStatementODSKeyword skipwhite skipnl skipempty
+syn match sasProcStatement '\v%(^|;)\s*\zs%(format|informat)>' display contained contains=sasProcStatementKeyword nextgroup=sasFormatContext skipwhite skipnl skipempty
+syn region sasProc matchgroup=sasSectionKeyword start='\v%(^|;)\s*\zsproc%(\s+\h\w*)=>' end='\v%(^|;)\s*%(run|data|proc|endsas)>'me=s-1 fold contains=@sasBasicSyntax,sasDataStepFunction,sasProcStatement
+syn region sasProc matchgroup=sasSectionKeyword start='\v%(^|;)\s*\zsproc\s+%(catalog|chart|datasets|document|plot)>' end='\v%(^|;)\s*%(quit|data|proc|endsas)>'me=s-1 fold contains=@sasBasicSyntax,sasDataStepFunction,sasProcStatement
+
+" Procedures, SAS/GRAPH, 9.4
+syn keyword sasGraphProcStatementKeyword add area axis bar block bubble2 byline cc ccopy cdef cdelete chart cmap choro copy delete device dial donut exclude flow format fs goptions gout grid group hbar hbar3d hbullet hslider htrafficlight id igout label legend list modify move nobyline note pattern pie pie3d plot plot2 preview prism quit rename replay select scatter speedometer star surface symbol tc tcopy tdef tdelete template tile toggle treplay vbar vbar3d vtrafficlight vbullet vslider where contained
+syn match sasGraphProcStatement '\v%(^|;)\s*\zs\h\w*>' display contained contains=sasGraphProcStatementKeyword,sasGlobalStatementKeyword
+syn match sasGraphProcStatement '\v%(^|;)\s*\zsformat>' display contained contains=sasGraphProcStatementKeyword nextgroup=sasFormatContext skipwhite skipnl skipempty
+syn region sasGraphProc matchgroup=sasSectionKeyword start='\v%(^|;)\s*\zsproc\s+%(g3d|g3grid|ganno|gcontour|gdevice|geocode|gfont|ginside|goptions|gproject|greduce|gremove|mapimport)>' end='\v%(^|;)\s*%(run|data|proc|endsas)>'me=s-1 fold contains=@sasBasicSyntax,sasDataStepFunction,sasGraphProcStatement
+syn region sasGraphProc matchgroup=sasSectionKeyword start='\v%(^|;)\s*\zsproc\s+%(gareabar|gbarline|gchart|gkpi|gmap|gplot|gradar|greplay|gslide|gtile)>' end='\v%(^|;)\s*%(quit|data|proc|endsas)>'me=s-1 fold contains=@sasBasicSyntax,sasDataStepFunction,sasGraphProcStatement
+
+" Procedures, SAS/STAT, 14.1
+syn keyword sasAnalyticalProcStatementKeyword absorb add array assess baseline bayes beginnodata bivar bootstrap bounds by cdfplot cells class cluster code compute condition contrast control coordinates copy cosan cov covtest coxreg der design determ deviance direct directions domain effect effectplot effpart em endnodata equality estimate exact exactoptions factor factors fcs filter fitindex format freq fwdlink gender grid group grow hazardratio height hyperprior id impjoint inset insetgroup invar invlink ippplot lincon lineqs lismod lmtests location logistic loglin lpredplot lsmeans lsmestimate manova matings matrix mcmc mean means missmodel mnar model modelaverage modeleffects monotone mstruct mtest multreg name nlincon nloptions oddsratio onecorr onesamplefreq onesamplemeans onewayanova outfiles output paired pairedfreq pairedmeans parameters parent parms partial partition path pathdiagram pcov performance plot population poststrata power preddist predict predpplot priors process probmodel profile prune pvar ram random ratio reference refit refmodel renameparm repeated replicate repweights response restore restrict retain reweight ridge rmsstd roc roccontrast rules samplesize samplingunit seed size scale score selection show simtests simulate slice std stderr store strata structeq supplementary table tables test testclass testfreq testfunc testid time transform treatments trend twosamplefreq twosamplemeans towsamplesurvival twosamplewilcoxon uds units univar var variance varnames weight where with zeromodel contained
+syn match sasAnalyticalProcStatement '\v%(^|;)\s*\zs\h\w*>' display contained contains=sasAnalyticalProcStatementKeyword,sasGlobalStatementKeyword
+syn match sasAnalyticalProcStatement '\v%(^|;)\s*\zsods>' display contained contains=sasGlobalStatementKeyword nextgroup=sasGlobalStatementODSKeyword skipwhite skipnl skipempty
+syn match sasAnalyticalProcStatement '\v%(^|;)\s*\zsformat>' display contained contains=sasAnalyticalProcStatementKeyword nextgroup=sasFormatContext skipwhite skipnl skipempty
+syn region sasAnalyticalProc matchgroup=sasSectionKeyword start='\v%(^|;)\s*\zsproc\s+%(aceclus|adaptivereg|bchoice|boxplot|calis|cancorr|candisc|cluster|corresp|discrim|distance|factor|fastclus|fmm|freq|gam|gampl|gee|genmod|glimmix|glmmod|glmpower|glmselect|hpcandisc|hpfmm|hpgenselect|hplmixed|hplogistic|hpmixed|hpnlmod|hppls|hpprincomp|hpquantselect|hpreg|hpsplit|iclifetest|icphreg|inbreed|irt|kde|krige2d|lattice|lifereg|lifetest|loess|logistic|mcmc|mds|mi|mianalyze|mixed|modeclus|multtest|nested|nlin|nlmixed|npar1way|orthoreg|phreg|plm|pls|power|princomp|prinqual|probit|quantlife|quantreg|quantselect|robustreg|rsreg|score|seqdesign|seqtest|sim2d|simnormal|spp|stdize|stdrate|stepdisc|surveyfreq|surveyimpute|surveylogistic|surveymeans|surveyphreg|surveyreg|surveyselect|tpspline|transreg|tree|ttest|varclus|varcomp|variogram)>' end='\v%(^|;)\s*%(run|data|proc|endsas)>'me=s-1 fold contains=@sasBasicSyntax,sasDataStepControl,sasDataStepFunction,sasAnalyticalProcStatement
+syn region sasAnalyticalProc matchgroup=sasSectionKeyword start='\v%(^|;)\s*\zsproc\s+%(anova|arima|catmod|factex|glm|model|optex|plan|reg)>' end='\v%(^|;)\s*%(quit|data|proc|endsas)>'me=s-1 fold contains=@sasBasicSyntax,sasDataStepControl,sasDataStepFunction,sasAnalyticalProcStatement
+
+" Procedures, ODS graphics, 9.4
+syn keyword sasODSGraphicsProcStatementKeyword band block bubble by colaxis compare dattrvar density dot dropline dynamic ellipse ellipseparm format fringe gradlegend hbar hbarbasic hbarparm hbox heatmap heatmapparm highlow histogram hline inset keylegend label lineparm loess matrix needle parent panelby pbspline plot polygon refline reg rowaxis scatter series spline step style styleattrs symbolchar symbolimage text vbar vbarbasic vbarparm vbox vector vline waterfall where xaxis x2axis yaxis y2axis yaxistable contained
+syn match sasODSGraphicsProcStatement '\v%(^|;)\s*\zs\h\w*>' display contained contains=sasODSGraphicsProcStatementKeyword,sasGlobalStatementKeyword
+syn match sasODSGraphicsProcStatement '\v%(^|;)\s*\zsods>' display contained contains=sasGlobalStatementKeyword nextgroup=sasGlobalStatementODSKeyword skipwhite skipnl skipempty
+syn match sasODSGraphicsProcStatement '\v%(^|;)\s*\zsformat>' display contained contains=sasODSGraphicsProcStatementKeyword nextgroup=sasFormatContext skipwhite skipnl skipempty
+syn region sasODSGraphicsProc matchgroup=sasSectionKeyword start='\v%(^|;)\s*\zsproc\s+%(sgdesign|sgpanel|sgplot|sgrender|sgscatter)>' end='\v%(^|;)\s*%(run|data|proc|endsas)>'me=s-1 fold contains=@sasBasicSyntax,sasDataStepFunction,sasODSGraphicsProcStatement
+
+" Proc TEMPLATE, 9.4
+syn keyword sasProcTemplateClause as into
+syn keyword sasProcTemplateStatementKeyword block break cellstyle class close column compute continue define delete delstream do done dynamic edit else end eval flush footer header import iterate link list mvar ndent next nmvar notes open path put putl putlog putq putstream putvars replace set source stop style test text text2 text3 translate trigger unblock unset xdent contained
+syn keyword sasProcTemplateStatementComplexKeyword cellvalue column crosstabs event footer header statgraph style table tagset contained
+syn keyword sasProcTemplateGTLStatementKeyword axislegend axistable bandplot barchart barchartparm begingraph beginpolygon beginpolyline bihistogram3dparm blockplot boxplot boxplotparm bubbleplot continuouslegend contourplotparm dendrogram discretelegend drawarrow drawimage drawline drawoval drawrectangle drawtext dropline ellipse ellipseparm endgraph endinnermargin endlayout endpolygon endpolyline endsidebar entry entryfootnote entrytitle fringeplot heatmap heatmapparm highlowplot histogram histogramparm innermargin layout legenditem legendtextitems linechart lineparm loessplot mergedlegend modelband needleplot pbsplineplot polygonplot referenceline regressionplot scatterplot seriesplot sidebar stepplot surfaceplotparm symbolchar symbolimage textplot vectorplot waterfallchart contained
+syn keyword sasProcTemplateGTLComplexKeyword datalattice datapanel globallegend gridded lattice overlay overlayequated overlay3d region contained
+syn match sasProcTemplateStatement '\v%(^|;)\s*\zs\h\w*>' display contained contains=sasProcTemplateStatementKeyword,sasProcTemplateGTLStatementKeyword,sasGlobalStatementKeyword
+syn match sasProcTemplateStatement '\v%(^|;)\s*\zsdefine>' display contained contains=sasProcTemplateStatementKeyword nextgroup=sasProcTemplateStatementComplexKeyword skipwhite skipnl skipempty
+syn match sasProcTemplateStatement '\v%(^|;)\s*\zslayout>' display contained contains=sasProcTemplateGTLStatementKeyword nextgroup=sasProcTemplateGTLComplexKeyword skipwhite skipnl skipempty
+syn match sasProcTemplateStatement '\v%(^|;)\s*\zsods>' display contained contains=sasGlobalStatementKeyword nextgroup=sasGlobalStatementODSKeyword skipwhite skipnl skipempty
+syn region sasProcTemplate matchgroup=sasSectionKeyword start='\v%(^|;)\s*\zsproc\s+template>' end='\v%(^|;)\s*%(run|data|proc|endsas)>'me=s-1 fold contains=@sasBasicSyntax,sasProcTemplateClause,sasProcTemplateStatement
+
+" Proc SQL, 9.4
+syn keyword sasProcSQLFunctionName avg count css cv freq max mean median min n nmiss prt range std stderr sum sumwgt t uss var contained
+syn region sasProcSQLFunctionContext start='(' end=')' contained contains=@sasBasicSyntax,sasProcSQLFunction
+syn match sasProcSQLFunction '\v<\w+\ze\(' contained contains=sasProcSQLFunctionName,sasDataStepFunctionName nextgroup=sasProcSQLFunctionContext
+syn keyword sasProcSQLClause add asc between by calculated cascade case check connection constraint cross desc distinct drop else end escape except exists foreign from full group having in inner intersect into is join key left libname like modify natural newline notrim null on order outer primary references restrict right separated set then to trimmed union unique user using values when where contained
+syn keyword sasProcSQLClause as contained nextgroup=sasProcSQLStatementKeyword skipwhite skipnl skipempty
+syn keyword sasProcSQLStatementKeyword connect delete disconnect execute insert reset select update validate contained
+syn keyword sasProcSQLStatementComplexKeyword alter create describe drop contained nextgroup=sasProcSQLStatementNextKeyword skipwhite skipnl skipempty
+syn keyword sasProcSQLStatementNextKeyword index table view contained
+syn match sasProcSQLStatement '\v%(^|;)\s*\zs\h\w*>' display contained contains=sasProcSQLStatementKeyword,sasGlobalStatementKeyword
+syn match sasProcSQLStatement '\v%(^|;)\s*\zs%(alter|create|describe|drop)>' display contained contains=sasProcSQLStatementComplexKeyword nextgroup=sasProcSQLStatementNextKeyword skipwhite skipnl skipempty
+syn match sasProcSQLStatement '\v%(^|;)\s*\zsvalidate>' display contained contains=sasProcSQLStatementKeyword nextgroup=sasProcSQLStatementKeyword,sasProcSQLStatementComplexKeyword skipwhite skipnl skipempty
+syn match sasProcSQLStatement '\v%(^|;)\s*\zsods>' display contained contains=sasGlobalStatementKeyword nextgroup=sasGlobalStatementODSKeyword skipwhite skipnl skipempty 
+syn region sasProcSQL matchgroup=sasSectionKeyword start='\v%(^|;)\s*\zsproc\s+sql>' end='\v%(^|;)\s*%(quit|data|proc|endsas)>'me=s-1 fold contains=@sasBasicSyntax,sasProcSQLFunction,sasProcSQLClause,sasProcSQLStatement
+
+" SAS/DS2, 9.4
+syn keyword sasDS2FunctionName abs anyalnum anyalpha anycntrl anydigit anyfirst anygraph anylower anyname anyprint anypunct anyspace anyupper anyxdigit arcos arcosh arsin arsinh artanh atan atan2 band beta betainv blackclprc blackptprc blkshclprc blkshptprc blshift bnot bor brshift bxor byte cat cats catt catx ceil ceilz choosec choosen cmp cmpt coalesce coalescec comb compare compbl compfuzz compound compress constant convx convxp cos cosh count countc countw css cumipmt cumprinc cv datdif date datejul datepart datetime day dequote deviance dhms dif digamma dim divide dur durp effrate erf erfc exp fact find findc findw floor floorz fmtinfo fuzz gaminv gamma garkhclprc garkhptprc gcd geodist geomean geomeanz harmean harmeanz hbound hms holiday hour index indexc indexw inputc inputn int intcindex intck intcycle intdt intfit intget intindex intnest intnx intrr intseas intshift inttest intts intz ipmt iqr irr juldate juldate7 kcount kstrcat kstrip kupdate kupdates kurtosis lag largest lbound lcm left length lengthc lengthm lengthn lgamma log logbeta log10 log1px log2 lowcase mad margrclprc margrptprc max md5 mdy mean median min minute missing mod modz month mort n ndims netpv nmiss nomrate notalnum notalpha notcntrl notdigit notfirst notgraph notlower notname notprint notpunct notspace notupper notxdigit npv null nwkdom ordinal pctl perm pmt poisson power ppmt probbeta probbnml probbnrm probchi probdf probf probgam probhypr probit probmc probmed probnegb probnorm probt prxchange prxmatch prxparse prxposn put pvp qtr quote ranbin rancau rand ranexp rangam range rank rannor ranpoi rantbl rantri ranuni repeat reverse right rms round rounde roundz savings scan sec second sha256hex sha256hmachex sign sin sinh skewness sleep smallest sqlexec sqrt std stderr streaminit strip substr substrn sum sumabs tan tanh time timepart timevalue tinv to_date to_double to_time to_timestamp today translate transtrn tranwrd trigamma trim trimn trunc uniform upcase uss uuidgen var verify vformat vinarray vinformat vlabel vlength vname vtype week weekday whichc whichn year yieldp yrdif yyq contained
+syn region sasDS2FunctionContext start='(' end=')' contained contains=@sasBasicSyntax,sasDS2Function
+syn match sasDS2Function '\v<\w+\ze\(' contained contains=sasDS2FunctionName nextgroup=sasDS2FunctionContext
+syn keyword sasDS2Control continue data dcl declare do drop else end enddata endpackage endthread from go goto if leave method otherwise package point return select then thread to until when while contained
+syn keyword sasDS2StatementKeyword array by forward keep merge output put rename retain set stop vararray varlist contained
+syn keyword sasDS2StatementComplexKeyword package thread contained
+syn match sasDS2Statement '\v%(^|;)\s*\zs\h\w*>' display contained contains=sasDS2StatementKeyword,sasGlobalStatementKeyword
+syn match sasDS2Statement '\v%(^|;)\s*\zs%(dcl|declare|drop)>' display contained contains=sasDS2StatementKeyword nextgroup=sasDS2StatementComplexKeyword skipwhite skipnl skipempty
+syn match sasDS2Statement '\v%(^|;)\s*\zsods>' display contained contains=sasGlobalStatementKeyword nextgroup=sasGlobalStatementODSKeyword skipwhite skipnl skipempty
+syn region sasDS2 matchgroup=sasSectionKeyword start='\v%(^|;)\s*\zsproc\s+ds2>' end='\v%(^|;)\s*%(quit|data|proc|endsas)>'me=s-1 fold contains=@sasBasicSyntax,sasDS2Function,sasDS2Control,sasDS2Statement
+
+" SAS/IML, 14.1
+syn keyword sasIMLFunctionName abs all allcomb allperm any apply armasim bin blankstr block branks bspline btran byte char choose col colvec concat contents convexit corr corr2cov countmiss countn countunique cov cov2corr covlag cshape cusum cuprod cv cvexhull datasets design designf det diag dif dimension distance do duration echelon eigval eigvec element exp expmatrix expandgrid fft forward froot full gasetup geomean ginv hadamard half hankel harmean hdir hermite homogen i ifft insert int inv invupdt isempty isskipped j jroot kurtosis lag length loc log logabsdet mad magic mahalanobis max mean median min mod moduleic modulein name ncol ndx2sub nleng norm normal nrow num opscal orpol parentname palette polyroot prod product pv quartile rancomb randdirichlet randfun randmultinomial randmvt randnormal randwishart ranperk ranperm range rank ranktie rates ratio remove repeat root row rowcat rowcatc rowvec rsubstr sample setdif shape shapecol skewness solve sparse splinev spot sqrsym sqrt sqrvech ssq standard std storage sub2ndx substr sum sweep symsqr t toeplitz trace trisolv type uniform union unique uniqueby value var vecdiag vech xmult xsect yield contained
+syn keyword sasIMLCallRoutineName appcort armacov armalik bar box change comport delete eigen execute exportdatasettor exportmatrixtor farmacov farmafit farmalik farmasim fdif gaend gagetmem gagetval gainit gareeval garegen gasetcro gasetmut gasetobj gasetsel gblkvp gblkvpd gclose gdelete gdraw gdrawl geneig ggrid ginclude gopen gpie gpiexy gpoint gpoly gport gportpop gportstk gscale gscript gset gshow gsorth gstart gstop gstrlen gtext gvtext gwindow gxaxis gyaxis heatmapcont heatmapdisc histogram importdatasetfromr importmatrixfromr ipf itsolver kalcvf kalcvs kaldff kaldfs lav lcp lms lp lpsolve lts lupdt marg maxqform mcd milpsolve modulei mve nlpcg nlpdd nlpfdd nlpfea nlphqn nlplm nlpnms nlpnra nlpnrr nlpqn nlpqua nlptr ode odsgraph ortvec pgraf push qntl qr quad queue randgen randseed rdodt rupdt rename rupdt rzlind scatter seq seqscale seqshift seqscale seqshift series solvelin sort sortndx sound spline splinec svd tabulate tpspline tpsplnev tsbaysea tsdecomp tsmlocar tsmlomar tsmulmar tspears tspred tsroot tstvcar tsunimar valset varmacov varmalik varmasim vnormal vtsroot wavft wavget wavift wavprint wavthrsh contained
+syn region sasIMLFunctionContext start='(' end=')' contained contains=@sasBasicSyntax,sasIMLFunction
+syn match sasIMLFunction '\v<\w+\ze\(' contained contains=sasIMLFunctionName,sasDataStepFunction nextgroup=sasIMLFunctionContext
+syn keyword sasIMLControl abort by do else end finish goto if link pause quit resume return run start stop then to until while contained
+syn keyword sasIMLStatementKeyword append call close closefile create delete display edit file find force free index infile input list load mattrib print purge read remove replace reset save setin setout show sort store summary use window contained
+syn match sasIMLStatement '\v%(^|;)\s*\zs\h\w*>' display contained contains=sasIMLStatementKeyword,sasGlobalStatementKeyword
+syn match sasIMLStatement '\v%(^|;)\s*\zsods>' display contained contains=sasGlobalStatementKeyword nextgroup=sasGlobalStatementODSKeyword skipwhite skipnl skipempty
+syn region sasIML matchgroup=sasSectionKeyword start='\v%(^|;)\s*\zsproc\s+iml>' end='\v%(^|;)\s*%(quit|data|proc|endsas)>'me=s-1 fold contains=@sasBasicSyntax,sasIMLFunction,sasIMLControl,sasIMLStatement
+
+" Macro definition
+syn region sasMacro start='\v\%macro>' end='\v\%mend>' fold keepend contains=@sasBasicSyntax,@sasDataStepSyntax,sasDataStep,sasProc,sasODSGraphicsProc,sasGraphProc,sasAnalyticalProc,sasProcTemplate,sasProcSQL,sasDS2,sasIML
+
+" Define default highlighting
+hi def link sasComment Comment
+hi def link sasTodo Delimiter
+hi def link sasSectLbl Title
+hi def link sasSectLblEnds Comment
+hi def link sasNumber Number
+hi def link sasDateTime Constant
+hi def link sasString String
+hi def link sasDataStepControl Keyword
+hi def link sasProcTemplateClause Keyword
+hi def link sasProcSQLClause Keyword
+hi def link sasDS2Control Keyword
+hi def link sasIMLControl Keyword
+hi def link sasOperator Operator
+hi def link sasGlobalStatementKeyword Statement
+hi def link sasGlobalStatementODSKeyword Statement
+hi def link sasSectionKeyword Statement
+hi def link sasDataStepFunctionName Function
+hi def link sasDataStepCallRoutineName Function
+hi def link sasDataStepStatementKeyword Statement
+hi def link sasDataStepStatementHashKeyword Statement
+hi def link sasDataStepHashOperator Operator
+hi def link sasDataStepHashMethodName Function
+hi def link sasDataStepHashAttributeName Identifier
+hi def link sasProcStatementKeyword Statement
+hi def link sasODSGraphicsProcStatementKeyword Statement
+hi def link sasGraphProcStatementKeyword Statement
+hi def link sasAnalyticalProcStatementKeyword Statement
+hi def link sasProcTemplateStatementKeyword Statement
+hi def link sasProcTemplateStatementComplexKeyword Statement
+hi def link sasProcTemplateGTLStatementKeyword Statement
+hi def link sasProcTemplateGTLComplexKeyword Statement
+hi def link sasProcSQLFunctionName Function
+hi def link sasProcSQLStatementKeyword Statement
+hi def link sasProcSQLStatementComplexKeyword Statement
+hi def link sasProcSQLStatementNextKeyword Statement
+hi def link sasDS2FunctionName Function
+hi def link sasDS2StatementKeyword Statement
+hi def link sasIMLFunctionName Function
+hi def link sasIMLCallRoutineName Function
+hi def link sasIMLStatementKeyword Statement
+hi def link sasMacroReserved PreProc
+hi def link sasMacroVariable Define
+hi def link sasMacroFunctionName Define
+hi def link sasDataLine SpecialChar
+hi def link sasFormat SpecialChar
+hi def link sasReserved Special
 
 " Syncronize from beginning to keep large blocks from losing
 " syntax coloring while moving through code.
@@ -264,4 +261,5 @@ syn sync fromstart
 
 let b:current_syntax = "sas"
 
-" vim: ts=8
+let &cpo = s:cpo_save
+unlet s:cpo_save
index 7779c43..c5a175f 100644 (file)
@@ -71,6 +71,8 @@ hi link scalaUnicodeChar Special
 
 syn match scalaOperator "||"
 syn match scalaOperator "&&"
+syn match scalaOperator "|"
+syn match scalaOperator "&"
 hi link scalaOperator Special
 
 syn match scalaNameDefinition /\<[_A-Za-z0-9$]\+\>/ contained nextgroup=scalaPostNameDefinition,scalaVariableDeclarationList
@@ -142,7 +144,7 @@ hi link scalaString String
 hi link scalaStringEmbeddedQuote String
 
 syn region scalaIString matchgroup=scalaInterpolationBrackets start=/\<[a-zA-Z][a-zA-Z0-9_]*"/ skip=/\\"/ end=/"/ contains=scalaInterpolation,scalaInterpolationB,scalaEscapedChar,scalaUnicodeChar
-syn region scalaTripleIString matchgroup=scalaInterpolationBrackets start=/\<[a-zA-Z][a-zA-Z0-9_]*"""/ end=/"""\%([^"]\|$\)/ contains=scalaInterpolation,scalaInterpolationB,scalaEscapedChar,scalaUnicodeChar
+syn region scalaTripleIString matchgroup=scalaInterpolationBrackets start=/\<[a-zA-Z][a-zA-Z0-9_]*"""/ end=/"""\ze\%([^"]\|$\)/ contains=scalaInterpolation,scalaInterpolationB,scalaEscapedChar,scalaUnicodeChar
 hi link scalaIString String
 hi link scalaTripleIString String
 
index 63cecec..f8bc4c6 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         sensors.conf(5) - libsensors configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             sensors.conf(5) - libsensors configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index 661f57a..94e39ae 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         services(5) - Internet network services list
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             services(5) - Internet network services list
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index cdd309d..967fa5f 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         setserial(8) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             setserial(8) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index 2f880bb..f97299c 100644 (file)
@@ -2,8 +2,8 @@
 " Language:            shell (sh) Korn shell (ksh) bash (sh)
 " Maintainer:          Charles E. Campbell  <NdrOchipS@PcampbellAfamily.Mbiz>
 " Previous Maintainer: Lennart Schultz <Lennart.Schultz@ecmwf.int>
-" Last Change:         Sep 22, 2016
-" Version:             165
+" Last Change:         Jan 30, 2017
+" Version:             168
 " URL:         http://www.drchip.org/astronaut/vim/index.html#SYNTAX_SH
 " For options and settings, please use:      :help ft-sh-syntax
 " This file includes many ideas from Eric Brunet (eric.brunet@ens.fr)
@@ -305,7 +305,7 @@ if exists("b:is_bash")
  syn cluster shCommandSubList add=bashSpecialVariables,bashStatement
  syn cluster shCaseList add=bashAdminStatement,bashStatement
  syn keyword bashSpecialVariables contained auto_resume BASH BASH_ALIASES BASH_ALIASES BASH_ARGC BASH_ARGC BASH_ARGV BASH_ARGV BASH_CMDS BASH_CMDS BASH_COMMAND BASH_COMMAND BASH_ENV BASH_EXECUTION_STRING BASH_EXECUTION_STRING BASH_LINENO BASH_LINENO BASHOPTS BASHOPTS BASHPID BASHPID BASH_REMATCH BASH_REMATCH BASH_SOURCE BASH_SOURCE BASH_SUBSHELL BASH_SUBSHELL BASH_VERSINFO BASH_VERSION BASH_XTRACEFD BASH_XTRACEFD CDPATH COLUMNS COLUMNS COMP_CWORD COMP_CWORD COMP_KEY COMP_KEY COMP_LINE COMP_LINE COMP_POINT COMP_POINT COMPREPLY COMPREPLY COMP_TYPE COMP_TYPE COMP_WORDBREAKS COMP_WORDBREAKS COMP_WORDS COMP_WORDS COPROC COPROC DIRSTACK EMACS EMACS ENV ENV EUID FCEDIT FIGNORE FUNCNAME FUNCNAME FUNCNEST FUNCNEST GLOBIGNORE GROUPS histchars HISTCMD HISTCONTROL HISTFILE HISTFILESIZE HISTIGNORE HISTSIZE HISTTIMEFORMAT HISTTIMEFORMAT HOME HOSTFILE HOSTNAME HOSTTYPE IFS IGNOREEOF INPUTRC LANG LC_ALL LC_COLLATE LC_CTYPE LC_CTYPE LC_MESSAGES LC_NUMERIC LC_NUMERIC LINENO LINES LINES MACHTYPE MAIL MAILCHECK MAILPATH MAPFILE MAPFILE OLDPWD OPTARG OPTERR OPTIND OSTYPE PATH PIPESTATUS POSIXLY_CORRECT POSIXLY_CORRECT PPID PROMPT_COMMAND PS1 PS2 PS3 PS4 PWD RANDOM READLINE_LINE READLINE_LINE READLINE_POINT READLINE_POINT REPLY SECONDS SHELL SHELL SHELLOPTS SHLVL TIMEFORMAT TIMEOUT TMPDIR TMPDIR UID
- syn keyword bashStatement chmod clear complete du egrep expr fgrep find gnufind gnugrep grep less ls mkdir mv rm rmdir rpm sed sleep sort strip tail 
+ syn keyword bashStatement chmod clear complete du egrep expr fgrep find gnufind gnugrep grep less ls mkdir mv rm rmdir rpm sed sleep sort strip tail
  syn keyword bashAdminStatement daemon killall killproc nice reload restart start status stop
  syn keyword bashStatement     command compgen
 endif
@@ -346,7 +346,7 @@ syn region  shSingleQuote   matchgroup=shQuote start=+'+ end=+'+            contains=@Spell
 syn region  shDoubleQuote      matchgroup=shQuote start=+\%(\%(\\\\\)*\\\)\@<!"+ skip=+\\"+ end=+"+    contains=@shDblQuoteList,shStringSpecial,@Spell
 syn match   shStringSpecial    "[^[:print:] \t]"                       contained
 syn match   shStringSpecial    "[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]"
-syn match   shSpecial  "[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]"               nextgroup=shBkslshSnglQuote,shBkslshDblQuote
+syn match   shSpecial  "[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]"
 syn match   shSpecial  "^\%(\\\\\)*\\[\\"'`$()#]"
 syn match   shSpecialNxt       contained       "\\[\\"'`$()#]"
 syn region  shBkslshSnglQuote  contained       matchgroup=shQuote start=+'+ end=+'+    contains=@Spell
@@ -376,8 +376,8 @@ ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc06 start="<<-\s*\"\z([^ \
 ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc07 start="<<\s*\\\_$\_s*\z([^ \t|>]\+\)"                matchgroup=shHereDoc07 end="^\z1\s*$"           contains=@shDblQuoteList
 ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc08 start="<<\s*\\\_$\_s*'\z([^ \t|>]\+\)'"      matchgroup=shHereDoc08 end="^\z1\s*$"
 ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc09 start="<<\s*\\\_$\_s*\"\z([^ \t|>]\+\)\""    matchgroup=shHereDoc09 end="^\z1\s*$"
-ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc10 start="<<-\s*\\\_$\_s*\z([^ \t|>]\+\)"       matchgroup=shHereDoc10 end="^\s*\z1\s*$"        
-ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc11 start="<<-\s*\\\_$\_s*\\\z([^ \t|>]\+\)"     matchgroup=shHereDoc11 end="^\s*\z1\s*$"        
+ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc10 start="<<-\s*\\\_$\_s*\z([^ \t|>]\+\)"       matchgroup=shHereDoc10 end="^\s*\z1\s*$"
+ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc11 start="<<-\s*\\\_$\_s*\\\z([^ \t|>]\+\)"     matchgroup=shHereDoc11 end="^\s*\z1\s*$"
 ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc12 start="<<-\s*\\\_$\_s*'\z([^ \t|>]\+\)'"     matchgroup=shHereDoc12 end="^\s*\z1\s*$"
 ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc13 start="<<-\s*\\\_$\_s*\"\z([^ \t|>]\+\)\""   matchgroup=shHereDoc13 end="^\s*\z1\s*$"
 ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc14 start="<<\\\z([^ \t|>]\+\)"          matchgroup=shHereDoc14 end="^\z1\s*$"
@@ -386,7 +386,7 @@ ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc15 start="<<-\s*\\\z([^ \
 " Here Strings: {{{1
 " =============
 " available for: bash; ksh (really should be ksh93 only) but not if its a posix
-if exists("b:is_bash") || (exists("b:is_kornshell") && !exists("g:is_posix"))
+if exists("b:is_bash") || (exists("b:is_kornshell") && !exists("b:is_posix"))
  syn match shHereString "<<<"  skipwhite       nextgroup=shCmdParenRegion
 endif
 
@@ -407,7 +407,7 @@ else
 endif
 
 " Functions: {{{1
-if !exists("g:is_posix")
+if !exists("b:is_posix")
  syn keyword shFunctionKey function    skipwhite skipnl nextgroup=shFunctionTwo
 endif
 
@@ -533,7 +533,7 @@ endif
 " ====================
 if exists("b:is_kornshell") || exists("b:is_bash")
  syn keyword shStatement autoload bg false fc fg functions getopts hash history integer jobs let nohup printf r stop suspend times true type unalias whence
- if exists("g:is_posix")
+ if exists("b:is_posix")
   syn keyword shStatement command
  else
   syn keyword shStatement time
@@ -542,7 +542,7 @@ if exists("b:is_kornshell") || exists("b:is_bash")
 " Useful bash Keywords: {{{1
 " =====================
  if exists("b:is_bash")
-  syn keyword shStatement bind builtin dirs disown enable help local logout popd pushd shopt source
+  syn keyword shStatement bind builtin dirs disown enable help logout popd pushd shopt source
  else
   syn keyword shStatement login newgrp
  endif
index 4bb4417..35b4dfb 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         Sieve filtering language input file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2007-10-25
+" Language:             Sieve filtering language input file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2007-10-25
 
 if exists("b:current_syntax")
   finish
index 9fe4503..712ba90 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         RFC 2614 - An API for Service Location configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             RFC 2614 - An API for Service Location configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index f3c8a7f..a177b06 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         RFC 2614 - An API for Service Location registration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             RFC 2614 - An API for Service Location registration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index 8507e3d..eaeb02a 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         RFC 2614 - An API for Service Location SPI file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             RFC 2614 - An API for Service Location SPI file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index 8401923..755d08e 100644 (file)
@@ -5,8 +5,8 @@
 " Contributor:  Leonard Ehrenfried <leonard.ehrenfried@web.de>
 " Contributor:  Karsten Hopp <karsten@redhat.com>
 " Contributor:  Dean, Adam Kenneth <adam.ken.dean@hpe.com>
-" Last Change: 2016 Aug 11
-" SSH Version: 7.3p1
+" Last Change: 2016 Dec 28
+" SSH Version: 7.4p1
 "
 
 " Setup
@@ -181,6 +181,7 @@ syn keyword sshconfigKeyword IPQoS
 syn keyword sshconfigKeyword IdentitiesOnly
 syn keyword sshconfigKeyword IdentityFile
 syn keyword sshconfigKeyword IgnoreUnknown
+syn keyword sshconfigKeyword Include
 syn keyword sshconfigKeyword IPQoS
 syn keyword sshconfigKeyword KbdInteractiveAuthentication
 syn keyword sshconfigKeyword KbdInteractiveDevices
index 1556258..c3abfff 100644 (file)
@@ -6,8 +6,8 @@
 " Contributor:  Leonard Ehrenfried <leonard.ehrenfried@web.de> 
 " Contributor:  Karsten Hopp <karsten@redhat.com>
 " Originally:  2009-07-09
-" Last Change: 2016 Mar 1
-" SSH Version: 7.2
+" Last Change: 2016 Dec 28
+" SSH Version: 7.4p1
 "
 
 " Setup
@@ -161,6 +161,7 @@ syn keyword sshdconfigKeyword Compression
 syn keyword sshdconfigKeyword DebianBanner
 syn keyword sshdconfigKeyword DenyGroups
 syn keyword sshdconfigKeyword DenyUsers
+syn keyword sshdconfigKeyword DisableForwarding
 syn keyword sshdconfigKeyword ForceCommand
 syn keyword sshdconfigKeyword GSSAPIAuthentication
 syn keyword sshdconfigKeyword GSSAPICleanupCredentials
index fffc1cf..df1eb99 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         sudoers(5) configuration files
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2011-02-24
+" Language:             sudoers(5) configuration files
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2011-02-24
 
 if exists("b:current_syntax")
   finish
index 748054f..d99ac01 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         sysctl.conf(5) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2011-05-02
+" Language:             sysctl.conf(5) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2011-05-02
 
 if exists("b:current_syntax")
   finish
index 0ea112a..2b0ab08 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         terminfo(5) definition
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             terminfo(5) definition
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index dd66902..ab19da3 100644 (file)
@@ -1,8 +1,8 @@
 " Vim syntax file
 " Language:    TeX
 " Maintainer:  Charles E. Campbell <NdrchipO@ScampbellPfamily.AbizM>
-" Last Change: Sep 20, 2016
-" Version:     101
+" Last Change: Jan 31, 2017
+" Version:     103
 " URL:         http://www.drchip.org/astronaut/vim/index.html#SYNTAX_TEX
 "
 " Notes: {{{1
@@ -494,13 +494,11 @@ if !exists("g:tex_no_math")
      \ ['\\backslash'  , '\'] ,
      \ ['\\downarrow'  , '↓'] ,
      \ ['\\Downarrow'  , '⇓'] ,
-     \ ['\\langle'     , '<'] ,
      \ ['\\lbrace'     , '['] ,
      \ ['\\lceil'      , '⌈'] ,
      \ ['\\lfloor'     , '⌊'] ,
      \ ['\\lgroup'     , '⌊'] ,
      \ ['\\lmoustache' , '⎛'] ,
-     \ ['\\rangle'     , '>'] ,
      \ ['\\rbrace'     , ']'] ,
      \ ['\\rceil'      , '⌉'] ,
      \ ['\\rfloor'     , '⌋'] ,
@@ -510,6 +508,15 @@ if !exists("g:tex_no_math")
      \ ['\\Uparrow'    , '↑'] ,
      \ ['\\updownarrow', '↕'] ,
      \ ['\\Updownarrow', '⇕']]
+  if &ambw == "double" || exists("g:tex_usedblwidth")
+    let s:texMathDelimList= s:texMathDelimList + [
+     \ ['\\langle'     , '〈'] ,
+     \ ['\\rangle'     , '〉']]
+  else
+    let s:texMathDelimList= s:texMathDelimList + [
+     \ ['\\langle'     , '<'] ,
+     \ ['\\rangle'     , '>']]
+  endif
   syn match texMathDelim       '\\[bB]igg\=[lr]' contained nextgroup=texMathDelimBad
   for texmath in s:texMathDelimList
    exe "syn match texMathDelim '\\\\[bB]igg\\=[lr]\\=".texmath[0]."'   contained conceal cchar=".texmath[1]
@@ -587,8 +594,6 @@ endif
 if s:tex_fast =~# 'v'
   if exists("g:tex_verbspell") && g:tex_verbspell
    syn region texZone          start="\\begin{[vV]erbatim}"            end="\\end{[vV]erbatim}\|%stopzone\>"   contains=@Spell
-   " listings package:
-   syn region texZone          start="\\begin{lstlisting}"             end="\\end{lstlisting}\|%stopzone\>"    contains=@Spell
    if b:tex_stylish
     syn region texZone         start="\\verb\*\=\z([^\ta-zA-Z@]\)"     end="\z1\|%stopzone\>"                  contains=@Spell
    else
@@ -680,6 +685,7 @@ if has("conceal") && &enc == 'utf-8'
     \ ['backslash'     , '∖'],
     \ ['barwedge'      , '⊼'],
     \ ['because'       , '∵'],
+    \ ['beth'           , 'ܒ'],
     \ ['between'       , '≬'],
     \ ['bigcap'                , '∩'],
     \ ['bigcirc'       , '○'],
@@ -699,6 +705,7 @@ if has("conceal") && &enc == 'utf-8'
     \ ['boxminus'      , '⊟'],
     \ ['boxplus'       , '⊞'],
     \ ['boxtimes'      , '⊠'],
+    \ ['Box'            , '☐'],
     \ ['bullet'                , '•'],
     \ ['bumpeq'                , '≏'],
     \ ['Bumpeq'                , '≎'],
@@ -748,6 +755,7 @@ if has("conceal") && &enc == 'utf-8'
     \ ['eqslantgtr'    , '⪖'],
     \ ['eqslantless'   , '⪕'],
     \ ['equiv'         , '≡'],
+    \ ['eth'            , 'ð'],
     \ ['exists'                , '∃'],
     \ ['fallingdotseq' , '≒'],
     \ ['flat'          , '♭'],
@@ -757,6 +765,7 @@ if has("conceal") && &enc == 'utf-8'
     \ ['geq'           , '≥'],
     \ ['geqq'          , '≧'],
     \ ['gets'          , '←'],
+    \ ['gimel'          , 'ℷ'],
     \ ['gg'            , '⟫'],
     \ ['gneqq'         , '≩'],
     \ ['gtrdot'                , '⋗'],
@@ -767,13 +776,17 @@ if has("conceal") && &enc == 'utf-8'
     \ ['heartsuit'     , '♡'],
     \ ['hookleftarrow' , '↩'],
     \ ['hookrightarrow'        , '↪'],
+    \ ['iff'            , '⇔'],
     \ ['iiint'         , '∭'],
     \ ['iint'          , '∬'],
     \ ['Im'            , 'ℑ'],
     \ ['imath'         , 'ɩ'],
+    \ ['implies'       , '⇒'],
     \ ['in'            , '∈'],
     \ ['infty'         , '∞'],
     \ ['int'           , '∫'],
+    \ ['jmath'         , '𝚥'],
+    \ ['land'          , '∧'],
     \ ['lceil'         , '⌈'],
     \ ['ldots'         , '…'],
     \ ['le'            , '≤'],
@@ -800,6 +813,7 @@ if has("conceal") && &enc == 'utf-8'
     \ ['ll'            , '≪'],
     \ ['lmoustache'     , '╭'],
     \ ['lneqq'         , '≨'],
+    \ ['lor'           , '∨'],
     \ ['ltimes'                , '⋉'],
     \ ['mapsto'                , '↦'],
     \ ['measuredangle' , '∡'],
@@ -826,6 +840,7 @@ if has("conceal") && &enc == 'utf-8'
     \ ['nless'         , '≮'],
     \ ['nmid'          , '∤'],
     \ ['notin'         , '∉'],
+    \ ['nparallel'      , '∦'],
     \ ['nprec'         , '⊀'],
     \ ['nrightarrow'   , '↛'],
     \ ['nRightarrow'   , '⇏'],
@@ -927,10 +942,12 @@ if has("conceal") && &enc == 'utf-8'
     \ ['trianglerighteq', '⊵'],
     \ ['twoheadleftarrow', '↞'],
     \ ['twoheadrightarrow', '↠'],
+    \ ['ulcorner'       , '⌜'],
     \ ['uparrow'       , '↑'],
     \ ['Uparrow'       , '⇑'],
     \ ['updownarrow'   , '↕'],
     \ ['Updownarrow'   , '⇕'],
+    \ ['urcorner'       , '⌝'],
     \ ['varnothing'    , '∅'],
     \ ['vartriangle'   , '∆'],
     \ ['vdash'         , '⊢'],
@@ -946,6 +963,15 @@ if has("conceal") && &enc == 'utf-8'
 "    \ ['jmath'                , 'X']
 "    \ ['uminus'       , 'X']
 "    \ ['uplus'                , 'X']
+  if &ambw == "double" || exists("g:tex_usedblwidth")
+    let s:texMathList= s:texMathList + [
+    \ ['right\\rangle' , '〉'],
+    \ ['left\\langle'  , '〈']]
+  else
+    let s:texMathList= s:texMathList + [
+    \ ['right\\rangle' , '>'],
+    \ ['left\\langle'  , '<']]
+  endif
   for texmath in s:texMathList
    if texmath[0] =~# '\w$'
     exe "syn match texMathSymbol '\\\\".texmath[0]."\\>' contained conceal cchar=".texmath[1]
diff --git a/runtime/syntax/tmux.vim b/runtime/syntax/tmux.vim
new file mode 100644 (file)
index 0000000..1ba5f67
--- /dev/null
@@ -0,0 +1,124 @@
+" Language: tmux(1) configuration file
+" Version: 2.3 (git-14dc2ac)
+" 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)
+
+if exists("b:current_syntax")
+    finish
+endif
+
+" Explicitly change compatiblity options to Vim's defaults because this file
+" uses line continuations.
+let s:original_cpo = &cpo
+set cpo&vim
+
+let b:current_syntax = "tmux"
+setlocal iskeyword+=-
+syntax case match
+
+syn keyword tmuxAction  none any current other
+syn keyword tmuxBoolean off on
+
+syn keyword tmuxTodo FIXME NOTE TODO XXX contained
+
+syn match tmuxColour            /\<colour[0-9]\+/      display
+syn match tmuxKey               /\(C-\|M-\|\^\)\+\S\+/ display
+syn match tmuxNumber            /\d\+/                 display
+syn match tmuxFlags             /\s-\a\+/              display
+syn match tmuxVariable          /\w\+=/                display
+syn match tmuxVariableExpansion /\${\=\w\+}\=/         display
+
+syn region tmuxComment start=/#/ skip=/\\\@<!\\$/ end=/$/ contains=tmuxTodo
+
+syn region tmuxString start=+"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=tmuxFormatString
+syn region tmuxString start=+'+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end='$' contains=tmuxFormatString
+
+" 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=/)/ contained keepend
+
+hi def link tmuxFormatString      Identifier
+hi def link tmuxAction            Boolean
+hi def link tmuxBoolean           Boolean
+hi def link tmuxCommands          Keyword
+hi def link tmuxComment           Comment
+hi def link tmuxKey               Special
+hi def link tmuxNumber            Number
+hi def link tmuxFlags             Identifier
+hi def link tmuxOptions           Function
+hi def link tmuxString            String
+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.
+" 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
+
+syn keyword tmuxOptions
+\ buffer-limit command-alias default-terminal escape-time exit-unattached
+\ focus-events history-file message-limit set-clipboard terminal-overrides
+\ assume-paste-time base-index bell-action bell-on-alert default-command
+\ default-shell destroy-unattached detach-on-destroy
+\ display-panes-active-colour display-panes-colour display-panes-time
+\ display-time history-limit key-table lock-after-time lock-command
+\ message-attr message-bg message-command-attr message-command-bg
+\ message-command-fg message-command-style message-fg message-style mouse
+\ prefix prefix2 renumber-windows repeat-time set-titles set-titles-string
+\ status status-attr status-bg status-fg status-interval status-justify
+\ status-keys status-left status-left-attr status-left-bg status-left-fg
+\ status-left-length status-left-style status-position status-right
+\ status-right-attr status-right-bg status-right-fg status-right-length
+\ status-right-style status-style update-environment visual-activity
+\ visual-bell visual-silence word-separators aggressive-resize allow-rename
+\ alternate-screen automatic-rename automatic-rename-format
+\ clock-mode-colour clock-mode-style force-height force-width
+\ main-pane-height main-pane-width mode-attr mode-bg mode-fg mode-keys
+\ mode-style monitor-activity monitor-silence other-pane-height
+\ other-pane-width pane-active-border-bg pane-active-border-fg
+\ pane-active-border-style pane-base-index pane-border-bg pane-border-fg
+\ pane-border-format pane-border-status pane-border-style remain-on-exit
+\ synchronize-panes window-active-style window-style
+\ window-status-activity-attr window-status-activity-bg
+\ window-status-activity-fg window-status-activity-style window-status-attr
+\ window-status-bell-attr window-status-bell-bg window-status-bell-fg
+\ window-status-bell-style window-status-bg window-status-current-attr
+\ window-status-current-bg window-status-current-fg
+\ window-status-current-format window-status-current-style window-status-fg
+\ window-status-format window-status-last-attr window-status-last-bg
+\ window-status-last-fg window-status-last-style window-status-separator
+\ window-status-style wrap-search xterm-keys
+
+syn keyword tmuxCommands
+\ attach-session attach bind-key bind break-pane breakp capture-pane
+\ capturep clear-history clearhist choose-buffer choose-client choose-tree
+\ choose-session choose-window command-prompt confirm-before confirm
+\ copy-mode clock-mode detach-client detach suspend-client suspendc
+\ display-message display display-panes displayp find-window findw if-shell
+\ if join-pane joinp move-pane movep kill-pane killp kill-server
+\ start-server start kill-session kill-window killw unlink-window unlinkw
+\ list-buffers lsb list-clients lsc list-keys lsk list-commands lscm
+\ list-panes lsp list-sessions ls list-windows lsw load-buffer loadb
+\ lock-server lock lock-session locks lock-client lockc move-window movew
+\ link-window linkw new-session new has-session has new-window neww
+\ paste-buffer pasteb pipe-pane pipep refresh-client refresh rename-session
+\ rename rename-window renamew resize-pane resizep respawn-pane respawnp
+\ respawn-window respawnw rotate-window rotatew run-shell run save-buffer
+\ saveb show-buffer showb select-layout selectl next-layout nextl
+\ previous-layout prevl select-pane selectp last-pane lastp select-window
+\ selectw next-window next previous-window prev last-window last send-keys
+\ send send-prefix set-buffer setb delete-buffer deleteb set-environment
+\ setenv set-hook show-hooks set-option set set-window-option setw
+\ show-environment showenv show-messages showmsgs show-options show
+\ show-window-options showw source-file source split-window splitw swap-pane
+\ swapp swap-window swapw switch-client switchc unbind-key unbind wait-for
+\ wait
+
+let &cpo = s:original_cpo
+unlet! s:original_cpo s:bg s:i
index 921c5be..60bbf26 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         Treetop
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2011-03-14
+" Language:             Treetop
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2011-03-14
 
 if exists("b:current_syntax")
   finish
index a294604..82fd81d 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         udev(8) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             udev(8) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index 9d3af09..abda0b6 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         udev(8) permissions file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             udev(8) permissions file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index b04d728..ce156cc 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         udev(8) rules file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-12-18
+" Language:             udev(8) rules file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-12-18
 
 if exists("b:current_syntax")
   finish
index 7c082d6..224a7dd 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         updatedb.conf(5) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2009-05-25
+" Language:             updatedb.conf(5) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2009-05-25
 
 if exists("b:current_syntax")
   finish
index 4e9ce1b..52df919 100644 (file)
@@ -1,8 +1,8 @@
 " Vim syntax file
 " Language:    Vim 8.0 script
 " Maintainer:  Charles E. Campbell <NdrOchipS@PcampbellAfamily.Mbiz>
-" Last Change: September 29, 2016
-" Version:     8.0-01
+" Last Change: Jan 19, 2017
+" Version:     8.0-02
 " URL: http://www.drchip.org/astronaut/vim/index.html#SYNTAX_VIM
 " Automatically generated keyword lists: {{{1
 
@@ -164,6 +164,7 @@ endif
 syn match vimNumber    "\<\d\+\%(\.\d\+\%([eE][+-]\=\d\+\)\=\)\=" skipwhite nextgroup=vimGlobal,vimSubst,vimCommand
 syn match vimNumber    "-\d\+\%(\.\d\+\%([eE][+-]\=\d\+\)\=\)\="  skipwhite nextgroup=vimGlobal,vimSubst,vimCommand
 syn match vimNumber    "\<0[xX]\x\+"
+syn match vimNumber    "\<0[bB][01]\+"
 syn match vimNumber    "\%(^\|[^a-zA-Z]\)\zs#\x\{6}"
 
 " All vimCommands are contained by vimIsCommands. {{{2
@@ -225,7 +226,7 @@ endif
 " Functions : Tag is provided for those who wish to highlight tagged functions {{{2
 " =========
 syn cluster    vimFuncList     contains=vimCommand,vimFunctionError,vimFuncKey,Tag,vimFuncSID
-syn cluster    vimFuncBodyList contains=vimAbb,vimAddress,vimAugroupKey,vimAutoCmd,vimCmplxRepeat,vimComment,vimComment,vimContinue,vimCtrlChar,vimEcho,vimEchoHL,vimExecute,vimIf,vimIsCommand,vimFBVar,vimFunc,vimFunction,vimFuncVar,vimGlobal,vimHighlight,vimIsCommand,vimLet,vimLineComment,vimMap,vimMark,vimNorm,vimNotation,vimNotFunc,vimNumber,vimOper,vimOperParen,vimRegion,vimRegister,vimSet,vimSpecFile,vimString,vimSubst,vimSynLine,vimUnmap,vimUserCommand
+syn cluster    vimFuncBodyList contains=vimAbb,vimAddress,vimAugroupKey,vimAutoCmd,vimCmplxRepeat,vimComment,vimContinue,vimCtrlChar,vimEcho,vimEchoHL,vimExecute,vimIf,vimIsCommand,vimFBVar,vimFunc,vimFunction,vimFuncVar,vimGlobal,vimHighlight,vimIsCommand,vimLet,vimLineComment,vimMap,vimMark,vimNorm,vimNotation,vimNotFunc,vimNumber,vimOper,vimOperParen,vimRegion,vimRegister,vimSet,vimSpecFile,vimString,vimSubst,vimSynLine,vimUnmap,vimUserCommand
 syn match      vimFunction     "\<fu\%[nction]!\=\s\+\%(<[sS][iI][dD]>\|[sSgGbBwWtTlL]:\)\=\%(\i\|[#.]\|{.\{-1,}}\)*\ze\s*("   contains=@vimFuncList nextgroup=vimFuncBody
 
 if exists("g:vimsyn_folding") && g:vimsyn_folding =~# 'f'
index 9010a48..fab3a91 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         xinetd.conf(5) configuration file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             xinetd.conf(5) configuration file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index 69c70c5..28cae3e 100644 (file)
@@ -1,7 +1,7 @@
 " Vim syntax file
-" Language:         xmodmap(1) definition file
-" Maintainer:       Nikolai Weibull <now@bitwi.se>
-" Latest Revision:  2006-04-19
+" Language:             xmodmap(1) definition file
+" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
+" Latest Revision:      2006-04-19
 
 if exists("b:current_syntax")
   finish
index 2021c3a..0667ca2 100644 (file)
@@ -1,8 +1,9 @@
 " Vim syntax file
 " Language:    X Pixmap
 " Maintainer:  Ronald Schild <rs@scutum.de>
-" Last Change: 2008 May 28
+" Last Change: 2017 Feb 01
 " Version:     5.4n.1
+"               Jemma Nelson added termguicolors support
 
 " quit when a syntax file was already loaded
 if exists("b:current_syntax")
@@ -15,7 +16,7 @@ syn keyword xpmTodo           TODO FIXME XXX  contained
 syn region  xpmComment         start="/\*"  end="\*/"  contains=xpmTodo
 syn region  xpmPixelString     start=+"+  skip=+\\\\\|\\"+  end=+"+  contains=@xpmColors
 
-if has("gui_running")
+if has("gui_running") || has("termguicolors") && &termguicolors
 
 let color  = ""
 let chars  = ""
@@ -120,7 +121,7 @@ endwhile
 
 unlet color chars colors cpp n i s
 
-endif          " has("gui_running")
+endif          " has("gui_running") || has("termguicolors") && &termguicolors
 
 " Define the default highlighting.
 " Only when an item doesn't have highlighting yet
index 1d0eb57..dfa6945 100644 (file)
@@ -1,9 +1,10 @@
 " Vim syntax file
 " Language:    X Pixmap v2
 " Maintainer:  Steve Wall (hitched97@velnet.com)
-" Last Change: 2012 Jun 01
+" Last Change: 2017 Feb 01
 "              (Dominique Pelle added @Spell)
 " Version:     5.8
+"               Jemma Nelson added termguicolors support
 "
 " Made from xpm.vim by Ronald Schild <rs@scutum.de>
 
@@ -22,7 +23,7 @@ syn match   xpm2Comment               "\!.*$"  contains=@Spell,xpm2Todo
 
 command -nargs=+ Hi hi def <args>
 
-if has("gui_running")
+if has("gui_running") || has("termguicolors") && &termguicolors
 
   let color  = ""
   let chars  = ""
@@ -132,7 +133,7 @@ if has("gui_running")
 
   unlet color chars colors cpp n i s
 
-endif          " has("gui_running")
+endif          " has("gui_running") || has("termguicolors") && &termguicolors
 
 " Define the default highlighting.
 " Only when an item doesn't have highlighting yet
index 0d385a3..c69ef15 100644 (file)
@@ -2,9 +2,9 @@
 " Language:             Zsh shell script
 " Maintainer:           Christian Brabandt <cb@256bit.org>
 " Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
-" Latest Revision:      2016-02-15
+" Latest Revision:      2017-04-10
 " License:              Vim (see :h license)
-" Repository:          https://github.com/chrisbra/vim-zsh
+" Repository:           https://github.com/chrisbra/vim-zsh
 
 if exists("b:current_syntax")
   finish
@@ -24,7 +24,7 @@ endif
 
 syn keyword zshTodo             contained TODO FIXME XXX NOTE
 
-syn region  zshComment          oneline start='\%(^\|\s*\)#' end='$'
+syn region  zshComment          oneline start='\%(^\|\s\+\)#' end='$'
                                 \ contains=zshTodo,@Spell fold
 
 syn region  zshComment          start='^\s*#' end='^\%(\s*#\)\@!'
@@ -88,33 +88,20 @@ syn match   zshVariable         '\<\h\w*' contained
 syn match   zshVariableDef      '\<\h\w*\ze+\=='
 " XXX: how safe is this?
 syn region  zshVariableDef      oneline
-                                \ start='\$\@<!\<\h\w*\[' end='\]\ze+\=='
+                                \ start='\$\@<!\<\h\w*\[' end='\]\ze+\?=\?'
                                 \ contains=@zshSubst
 
-syn cluster zshDerefs           contains=zshShortDeref,zshLongDeref,zshDeref
+syn cluster zshDerefs           contains=zshShortDeref,zshLongDeref,zshDeref,zshDollarVar
 
-if !exists("g:zsh_syntax_variables")
-  let s:zsh_syntax_variables = 'all'
-else
-  let s:zsh_syntax_variables = g:zsh_syntax_variables
-endif
+syn match zshShortDeref       '\$[!#$*@?_-]\w\@!'
+syn match zshShortDeref       '\$[=^~]*[#+]*\d\+\>'
 
-if s:zsh_syntax_variables =~ 'short\|all'
-  syn match zshShortDeref       '\$[!#$*@?_-]\w\@!'
-  syn match zshShortDeref       '\$[=^~]*[#+]*\d\+\>'
-endif
+syn match zshLongDeref        '\$\%(ARGC\|argv\|status\|pipestatus\|CPUTYPE\|EGID\|EUID\|ERRNO\|GID\|HOST\|LINENO\|LOGNAME\)'
+syn match zshLongDeref        '\$\%(MACHTYPE\|OLDPWD OPTARG\|OPTIND\|OSTYPE\|PPID\|PWD\|RANDOM\|SECONDS\|SHLVL\|signals\)'
+syn match zshLongDeref        '\$\%(TRY_BLOCK_ERROR\|TTY\|TTYIDLE\|UID\|USERNAME\|VENDOR\|ZSH_NAME\|ZSH_VERSION\|REPLY\|reply\|TERM\)'
 
-if s:zsh_syntax_variables =~ 'long\|all'
-  syn match zshLongDeref        '\$\%(ARGC\|argv\|status\|pipestatus\|CPUTYPE\|EGID\|EUID\|ERRNO\|GID\|HOST\|LINENO\|LOGNAME\)'
-  syn match zshLongDeref        '\$\%(MACHTYPE\|OLDPWD OPTARG\|OPTIND\|OSTYPE\|PPID\|PWD\|RANDOM\|SECONDS\|SHLVL\|signals\)'
-  syn match zshLongDeref        '\$\%(TRY_BLOCK_ERROR\|TTY\|TTYIDLE\|UID\|USERNAME\|VENDOR\|ZSH_NAME\|ZSH_VERSION\|REPLY\|reply\|TERM\)'
-endif
-
-if s:zsh_syntax_variables =~ 'all'
-  syn match zshDeref            '\$[=^~]*[#+]*\h\w*\>'
-else
-  syn match zshDeref            transparent contains=NONE '\$[=^~]*[#+]*\h\w*\>'
-endif
+syn match zshDollarVar        '\$\h\w*'
+syn match zshDeref            '\$[=^~]*[#+]*\h\w*\>'
 
 syn match   zshCommands         '\%(^\|\s\)[.:]\ze\s'
 syn keyword zshCommands         alias autoload bg bindkey break bye cap cd
@@ -126,10 +113,10 @@ syn keyword zshCommands         alias autoload bg bindkey break bye cap cd
                                 \ functions getcap getln getopts hash history
                                 \ jobs kill let limit log logout popd print
                                 \ printf pushd pushln pwd r read readonly
-                                \ rehash return sched set setcap setopt shift
+                                \ rehash return sched set setcap shift
                                 \ source stat suspend test times trap true
                                 \ ttyctl type ulimit umask unalias unfunction
-                                \ unhash unlimit unset unsetopt vared wait
+                                \ unhash unlimit unset  vared wait
                                 \ whence where which zcompile zformat zftp zle
                                 \ zmodload zparseopts zprof zpty zregexparse
                                 \ zsocket zstyle ztcp
@@ -145,163 +132,9 @@ syn keyword zshCommands         alias autoload bg bindkey break bye cap cd
 "    done
 
 syn case ignore
-syn keyword zshOptions          aliases allexport all_export alwayslastprompt
-                                \ always_last_prompt always_lastprompt alwaystoend always_to_end appendcreate
-                                \ append_create appendhistory append_history autocd auto_cd autocontinue
-                                \ auto_continue autolist auto_list
-                                \ automenu auto_menu autonamedirs auto_name_dirs
-                                \ autoparamkeys auto_param_keys autoparamslash
-                                \ auto_param_slash autopushd auto_pushd autoremoveslash
-                                \ auto_remove_slash autoresume auto_resume badpattern bad_pattern
-                                \ banghist bang_hist bareglobqual bare_glob_qual
-                                \ bashautolist bash_auto_list bashrematch bash_rematch
-                                \ beep bgnice bg_nice braceccl brace_ccl braceexpand brace_expand
-                                \ bsdecho bsd_echo caseglob case_glob casematch case_match
-                                \ cbases c_bases cdablevars cdable_vars cd_able_vars chasedots chase_dots
-                                \ chaselinks chase_links checkjobs check_jobs
-                                \ clobber combiningchars combining_chars completealiases
-                                \ complete_aliases completeinword complete_in_word
-                                \ continueonerror continue_on_error correct
-                                \ correctall correct_all cprecedences c_precedences
-                                \ cshjunkiehistory csh_junkie_history cshjunkieloops
-                                \ csh_junkie_loops cshjunkiequotes csh_junkie_quotes
-                                \ csh_nullcmd csh_null_cmd cshnullcmd csh_null_cmd cshnullglob csh_null_glob
-                                \ debugbeforecmd debug_before_cmd dotglob dot_glob dvorak
-                                \ emacs equals errexit err_exit errreturn err_return evallineno
-                                \ eval_lineno exec extendedglob extended_glob extendedhistory
-                                \ extended_history flowcontrol flow_control forcefloat
-                                \ force_float functionargzero function_argzero function_arg_zero glob globalexport
-                                \ global_export globalrcs global_rcs globassign glob_assign
-                                \ globcomplete glob_complete globdots glob_dots glob_subst
-                                \ globsubst globstarshort glob_star_short hashall hash_all hashcmds
-                                \ hash_cmds hashdirs hash_dirs hashexecutablesonly hash_executables_only
-                                \ hashlistall hash_list_all histallowclobber hist_allow_clobber histappend
-                                \ hist_append histbeep hist_beep hist_expand hist_expire_dups_first
-                                \ histexpand histexpiredupsfirst histfcntllock hist_fcntl_lock
-                                \ histfindnodups hist_find_no_dups histignorealldups
-                                \ hist_ignore_all_dups histignoredups hist_ignore_dups
-                                \ histignorespace hist_ignore_space histlexwords hist_lex_words
-                                \ histnofunctions hist_no_functions histnostore hist_no_store
-                                \ histreduceblanks hist_reduce_blanks histsavebycopy
-                                \ hist_save_by_copy histsavenodups hist_save_no_dups
-                                \ histsubstpattern hist_subst_pattern histverify hist_verify
-                                \ hup ignorebraces ignore_braces ignoreclosebraces ignore_close_braces
-                                \ ignoreeof ignore_eof incappendhistory inc_append_history
-                                \ incappendhistorytime inc_append_history_time interactive
-                                \ interactivecomments interactive_comments ksharrays ksh_arrays
-                                \ kshautoload ksh_autoload kshglob ksh_glob kshoptionprint
-                                \ ksh_option_print kshtypeset ksh_typeset kshzerosubscript
-                                \ ksh_zero_subscript listambiguous list_ambiguous listbeep
-                                \ list_beep listpacked list_packed listrowsfirst list_rows_first
-                                \ listtypes list_types localloops local_loops localoptions
-                                \ local_options localpatterns local_patterns localtraps
-                                \ local_traps log login longlistjobs long_list_jobs magicequalsubst
-                                \ magic_equal_subst mailwarn mail_warn mail_warning mark_dirs
-                                \ mailwarning markdirs menucomplete menu_complete monitor
-                                \ multibyte multi_byte multifuncdef multi_func_def multios
-                                \ multi_os nomatch no_match notify nullglob null_glob numericglobsort
-                                \ numeric_glob_sort octalzeroes octal_zeroes onecmd one_cmd
-                                \ overstrike over_strike pathdirs path_dirs pathscript
-                                \ path_script physical pipefail pipe_fail posixaliases
-                                \ posix_aliases posixargzero posix_arg_zero posix_argzero posixbuiltins 
-                                \ posix_builtins posixcd posix_cd posixidentifiers posix_identifiers
-                                \ posixjobs posix_jobs posixstrings posix_strings posixtraps
-                                \ posix_traps printeightbit print_eight_bit printexitvalue
-                                \ print_exit_value privileged promptbang prompt_bang promptcr
-                                \ prompt_cr promptpercent prompt_percent promptsp prompt_sp
-                                \ promptsubst prompt_subst promptvars prompt_vars pushdignoredups
-                                \ pushd_ignore_dups pushdminus pushd_minus pushdsilent pushd_silent
-                                \ pushdtohome pushd_to_home rcexpandparam rc_expandparam rc_expand_param rcquotes
-                                \ rc_quotes rcs recexact rec_exact rematchpcre re_match_pcre rematch_pcre
-                                \ restricted rmstarsilent rm_star_silent rmstarwait rm_star_wait
-                                \ sharehistory share_history shfileexpansion sh_file_expansion
-                                \ shglob sh_glob shinstdin shin_stdin shnullcmd sh_nullcmd
-                                \ shoptionletters sh_option_letters shortloops short_loops shwordsplit
-                                \ sh_word_split singlecommand single_command singlelinezle single_line_zle
-                                \ sourcetrace source_trace stdin sunkeyboardhack sun_keyboard_hack
-                                \ trackall track_all transientrprompt transient_rprompt
-                                \ trapsasync traps_async typesetsilent type_set_silent typeset_silent unset verbose vi
-                                \ warncreateglobal warn_create_global xtrace zle
-
-syn keyword zshOptions          noaliases no_aliases noallexport no_allexport noall_export no_all_export noalwayslastprompt no_alwayslastprompt
-                                \ noalways_lastprompt no_always_lastprompt no_always_last_prompt noalwaystoend no_alwaystoend noalways_to_end no_always_to_end
-                                \ noappendcreate no_appendcreate no_append_create noappendhistory no_appendhistory noappend_history no_append_history noautocd
-                                \ no_autocd no_auto_cd noautocontinue no_autocontinue noauto_continue no_auto_continue noautolist no_autolist noauto_list
-                                \ no_auto_list noautomenu no_automenu noauto_menu no_auto_menu noautonamedirs no_autonamedirs noauto_name_dirs
-                                \ no_auto_name_dirs noautoparamkeys no_autoparamkeys noauto_param_keys no_auto_param_keys noautoparamslash no_autoparamslash
-                                \ noauto_param_slash no_auto_param_slash noautopushd no_autopushd noauto_pushd no_auto_pushd noautoremoveslash no_autoremoveslash
-                                \ noauto_remove_slash no_auto_remove_slash noautoresume no_autoresume noauto_resume no_auto_resume nobadpattern no_badpattern no_bad_pattern
-                                \ nobanghist no_banghist nobang_hist no_bang_hist nobareglobqual no_bareglobqual nobare_glob_qual no_bare_glob_qual
-                                \ nobashautolist no_bashautolist nobash_auto_list no_bash_auto_list nobashrematch no_bashrematch nobash_rematch no_bash_rematch
-                                \ nobeep no_beep nobgnice no_bgnice no_bg_nice nobraceccl no_braceccl nobrace_ccl no_brace_ccl nobraceexpand no_braceexpand nobrace_expand no_brace_expand
-                                \ nobsdecho no_bsdecho nobsd_echo no_bsd_echo nocaseglob no_caseglob nocase_glob no_case_glob nocasematch no_casematch nocase_match no_case_match
-                                \ nocbases no_cbases no_c_bases nocdablevars no_cdablevars no_cdable_vars nocd_able_vars no_cd_able_vars nochasedots no_chasedots nochase_dots no_chase_dots
-                                \ nochaselinks no_chaselinks nochase_links no_chase_links nocheckjobs no_checkjobs nocheck_jobs no_check_jobs
-                                \ noclobber no_clobber nocombiningchars no_combiningchars nocombining_chars no_combining_chars nocompletealiases no_completealiases
-                                \ nocomplete_aliases no_complete_aliases nocompleteinword no_completeinword nocomplete_in_word no_complete_in_word
-                                \ nocontinueonerror no_continueonerror nocontinue_on_error no_continue_on_error nocorrect no_correct
-                                \ nocorrectall no_correctall nocorrect_all no_correct_all nocprecedences no_cprecedences noc_precedences no_c_precedences
-                                \ nocshjunkiehistory no_cshjunkiehistory nocsh_junkie_history no_csh_junkie_history nocshjunkieloops no_cshjunkieloops
-                                \ nocsh_junkie_loops no_csh_junkie_loops nocshjunkiequotes no_cshjunkiequotes nocsh_junkie_quotes no_csh_junkie_quotes
-                                \ nocshnullcmd no_cshnullcmd no_csh_nullcmd nocsh_null_cmd no_csh_null_cmd nocshnullglob no_cshnullglob nocsh_null_glob no_csh_null_glob
-                                \ nodebugbeforecmd no_debugbeforecmd nodebug_before_cmd no_debug_before_cmd nodotglob no_dotglob nodot_glob no_dot_glob nodvorak no_dvorak
-                                \ noemacs no_emacs noequals no_equals noerrexit no_errexit noerr_exit no_err_exit noerrreturn no_errreturn noerr_return no_err_return noevallineno no_evallineno
-                                \ noeval_lineno no_eval_lineno noexec no_exec noextendedglob no_extendedglob noextended_glob no_extended_glob noextendedhistory no_extendedhistory
-                                \ noextended_history no_extended_history noflowcontrol no_flowcontrol noflow_control no_flow_control noforcefloat no_forcefloat
-                                \ noforce_float no_force_float nofunctionargzero no_functionargzero nofunction_arg_zero no_function_argzero no_function_arg_zero noglob no_glob noglobalexport no_globalexport
-                                \ noglobal_export no_global_export noglobalrcs no_globalrcs noglobal_rcs no_global_rcs noglobassign no_globassign noglob_assign no_glob_assign
-                                \ noglobcomplete no_globcomplete noglob_complete no_glob_complete noglobdots no_globdots noglob_dots no_glob_dots
-                                \ noglobstarshort no_glob_star_short noglob_subst no_glob_subst
-                                \ noglobsubst no_globsubst nohashall no_hashall nohash_all no_hash_all nohashcmds no_hashcmds nohash_cmds no_hash_cmds nohashdirs no_hashdirs
-                                \ nohash_dirs no_hash_dirs nohashexecutablesonly no_hashexecutablesonly nohash_executables_only no_hash_executables_only nohashlistall no_hashlistall
-                                \ nohash_list_all no_hash_list_all nohistallowclobber no_histallowclobber nohist_allow_clobber no_hist_allow_clobber nohistappend no_histappend
-                                \ nohist_append no_hist_append nohistbeep no_histbeep nohist_beep no_hist_beep nohist_expand no_hist_expand nohist_expire_dups_first no_hist_expire_dups_first
-                                \ nohistexpand no_histexpand nohistexpiredupsfirst no_histexpiredupsfirst nohistfcntllock no_histfcntllock nohist_fcntl_lock no_hist_fcntl_lock
-                                \ nohistfindnodups no_histfindnodups nohist_find_no_dups no_hist_find_no_dups nohistignorealldups no_histignorealldups
-                                \ nohist_ignore_all_dups no_hist_ignore_all_dups nohistignoredups no_histignoredups nohist_ignore_dups no_hist_ignore_dups
-                                \ nohistignorespace no_histignorespace nohist_ignore_space no_hist_ignore_space nohistlexwords no_histlexwords nohist_lex_words no_hist_lex_words
-                                \ nohistnofunctions no_histnofunctions nohist_no_functions no_hist_no_functions nohistnostore no_histnostore nohist_no_store no_hist_no_store
-                                \ nohistreduceblanks no_histreduceblanks nohist_reduce_blanks no_hist_reduce_blanks nohistsavebycopy no_histsavebycopy
-                                \ nohist_save_by_copy no_hist_save_by_copy nohistsavenodups no_histsavenodups nohist_save_no_dups no_hist_save_no_dups
-                                \ nohistsubstpattern no_histsubstpattern nohist_subst_pattern no_hist_subst_pattern nohistverify no_histverify nohist_verify no_hist_verify
-                                \ nohup no_hup noignorebraces no_ignorebraces noignore_braces no_ignore_braces noignoreclosebraces no_ignoreclosebraces noignore_close_braces no_ignore_close_braces
-                                \ noignoreeof no_ignoreeof noignore_eof no_ignore_eof noincappendhistory no_incappendhistory noinc_append_history no_inc_append_history
-                                \ noincappendhistorytime no_incappendhistorytime noinc_append_history_time no_inc_append_history_time nointeractive no_interactive
-                                \ nointeractivecomments no_interactivecomments nointeractive_comments no_interactive_comments noksharrays no_ksharrays noksh_arrays no_ksh_arrays
-                                \ nokshautoload no_kshautoload noksh_autoload no_ksh_autoload nokshglob no_kshglob noksh_glob no_ksh_glob nokshoptionprint no_kshoptionprint
-                                \ noksh_option_print no_ksh_option_print nokshtypeset no_kshtypeset noksh_typeset no_ksh_typeset nokshzerosubscript no_kshzerosubscript
-                                \ noksh_zero_subscript no_ksh_zero_subscript nolistambiguous no_listambiguous nolist_ambiguous no_list_ambiguous nolistbeep no_listbeep
-                                \ nolist_beep no_list_beep nolistpacked no_listpacked nolist_packed no_list_packed nolistrowsfirst no_listrowsfirst nolist_rows_first no_list_rows_first
-                                \ nolisttypes no_listtypes nolist_types no_list_types nolocalloops no_localloops nolocal_loops no_local_loops nolocaloptions no_localoptions
-                                \ nolocal_options no_local_options nolocalpatterns no_localpatterns nolocal_patterns no_local_patterns nolocaltraps no_localtraps
-                                \ nolocal_traps no_local_traps nolog no_log nologin no_login nolonglistjobs no_longlistjobs nolong_list_jobs no_long_list_jobs nomagicequalsubst no_magicequalsubst
-                                \ nomagic_equal_subst no_magic_equal_subst nomailwarn no_mailwarn nomail_warn no_mail_warn nomail_warning no_mail_warning nomark_dirs no_mark_dirs
-                                \ nomailwarning no_mailwarning nomarkdirs no_markdirs nomenucomplete no_menucomplete nomenu_complete no_menu_complete nomonitor no_monitor
-                                \ nomultibyte no_multibyte nomulti_byte no_multi_byte nomultifuncdef no_multifuncdef nomulti_func_def no_multi_func_def nomultios no_multios
-                                \ nomulti_os no_multi_os nonomatch no_nomatch nono_match no_no_match nonotify no_notify nonullglob no_nullglob nonull_glob no_null_glob nonumericglobsort no_numericglobsort
-                                \ nonumeric_glob_sort no_numeric_glob_sort nooctalzeroes no_octalzeroes nooctal_zeroes no_octal_zeroes noonecmd no_onecmd noone_cmd no_one_cmd
-                                \ nooverstrike no_overstrike noover_strike no_over_strike nopathdirs no_pathdirs nopath_dirs no_path_dirs nopathscript no_pathscript
-                                \ nopath_script no_path_script nophysical no_physical nopipefail no_pipefail nopipe_fail no_pipe_fail noposixaliases no_posixaliases
-                                \ noposix_aliases no_posix_aliases noposixargzero no_posixargzero no_posix_argzero noposix_arg_zero no_posix_arg_zero noposixbuiltins no_posixbuiltins 
-                                \ noposix_builtins no_posix_builtins noposixcd no_posixcd noposix_cd no_posix_cd noposixidentifiers no_posixidentifiers noposix_identifiers no_posix_identifiers
-                                \ noposixjobs no_posixjobs noposix_jobs no_posix_jobs noposixstrings no_posixstrings noposix_strings no_posix_strings noposixtraps no_posixtraps
-                                \ noposix_traps no_posix_traps noprinteightbit no_printeightbit noprint_eight_bit no_print_eight_bit noprintexitvalue no_printexitvalue
-                                \ noprint_exit_value no_print_exit_value noprivileged no_privileged nopromptbang no_promptbang noprompt_bang no_prompt_bang nopromptcr no_promptcr
-                                \ noprompt_cr no_prompt_cr nopromptpercent no_promptpercent noprompt_percent no_prompt_percent nopromptsp no_promptsp noprompt_sp no_prompt_sp
-                                \ nopromptsubst no_promptsubst noprompt_subst no_prompt_subst nopromptvars no_promptvars noprompt_vars no_prompt_vars nopushdignoredups no_pushdignoredups
-                                \ nopushd_ignore_dups no_pushd_ignore_dups nopushdminus no_pushdminus nopushd_minus no_pushd_minus nopushdsilent no_pushdsilent nopushd_silent no_pushd_silent
-                                \ nopushdtohome no_pushdtohome nopushd_to_home no_pushd_to_home norcexpandparam no_rcexpandparam norc_expandparam no_rc_expandparam no_rc_expand_param norcquotes no_rcquotes
-                                \ norc_quotes no_rc_quotes norcs no_rcs norecexact no_recexact norec_exact no_rec_exact norematchpcre no_rematchpcre nore_match_pcre no_re_match_pcre no_rematch_pcre
-                                \ norestricted no_restricted normstarsilent no_rmstarsilent norm_star_silent no_rm_star_silent normstarwait no_rmstarwait norm_star_wait no_rm_star_wait
-                                \ nosharehistory no_sharehistory noshare_history no_share_history noshfileexpansion no_shfileexpansion nosh_file_expansion no_sh_file_expansion
-                                \ noshglob no_shglob nosh_glob no_sh_glob noshinstdin no_shinstdin noshin_stdin no_shin_stdin noshnullcmd no_shnullcmd nosh_nullcmd no_sh_nullcmd
-                                \ noshoptionletters no_shoptionletters nosh_option_letters no_sh_option_letters noshortloops no_shortloops noshort_loops no_short_loops noshwordsplit no_shwordsplit
-                                \ nosh_word_split no_sh_word_split nosinglecommand no_singlecommand nosingle_command no_single_command nosinglelinezle no_singlelinezle nosingle_line_zle no_single_line_zle
-                                \ nosourcetrace no_sourcetrace nosource_trace no_source_trace nostdin no_stdin nosunkeyboardhack no_sunkeyboardhack nosun_keyboard_hack no_sun_keyboard_hack
-                                \ notrackall no_trackall notrack_all no_track_all notransientrprompt no_transientrprompt notransient_rprompt no_transient_rprompt
-                                \ notrapsasync no_trapsasync notrapasync no_trapasync no_traps_async notypesetsilent no_typesetsilent notype_set_silent no_type_set_silent no_typeset_silent \nounset no_unset
-                                \ noverbose no_verbose novi no_vi nowarncreateglobal no_warncreateglobal nowarn_create_global no_warn_create_global noxtrace no_xtrace nozle no_zle
-syn case match
+
+syn match   zshOptStart /^\s*\%(\%(\%(un\)\?setopt\)\|set\s+[-+]o\)/ nextgroup=zshOption skipwhite
+syn match   zshOption /\%(\%(no_\?\)\?aliases\)\|\%(\%(no_\?\)\?allexport\)\|\%(\%(no_\?\)\?all_export\)\|\%(\%(no_\?\)\?alwayslastprompt\)\|\%(\%(no_\?\)\?always_last_prompt\)\|\%(\%(no_\?\)\?always_lastprompt\)\|\%(\%(no_\?\)\?alwaystoend\)\|\%(\%(no_\?\)\?always_to_end\)\|\%(\%(no_\?\)\?appendcreate\)\|\%(\%(no_\?\)\?append_create\)\|\%(\%(no_\?\)\?appendhistory\)\|\%(\%(no_\?\)\?append_history\)\|\%(\%(no_\?\)\?autocd\)\|\%(\%(no_\?\)\?auto_cd\)\|\%(\%(no_\?\)\?autocontinue\)\|\%(\%(no_\?\)\?auto_continue\)\|\%(\%(no_\?\)\?autolist\)\|\%(\%(no_\?\)\?auto_list\)\|\%(\%(no_\?\)\?automenu\)\|\%(\%(no_\?\)\?auto_menu\)\|\%(\%(no_\?\)\?autonamedirs\)\|\%(\%(no_\?\)\?auto_name_dirs\)\|\%(\%(no_\?\)\?autoparamkeys\)\|\%(\%(no_\?\)\?auto_param_keys\)\|\%(\%(no_\?\)\?autoparamslash\)\|\%(\%(no_\?\)\?auto_param_slash\)\|\%(\%(no_\?\)\?autopushd\)\|\%(\%(no_\?\)\?auto_pushd\)\|\%(\%(no_\?\)\?autoremoveslash\)\|\%(\%(no_\?\)\?auto_remove_slash\)\|\%(\%(no_\?\)\?autoresume\)\|\%(\%(no_\?\)\?auto_resume\)\|\%(\%(no_\?\)\?badpattern\)\|\%(\%(no_\?\)\?bad_pattern\)\|\%(\%(no_\?\)\?banghist\)\|\%(\%(no_\?\)\?bang_hist\)\|\%(\%(no_\?\)\?bareglobqual\)\|\%(\%(no_\?\)\?bare_glob_qual\)\|\%(\%(no_\?\)\?bashautolist\)\|\%(\%(no_\?\)\?bash_auto_list\)\|\%(\%(no_\?\)\?bashrematch\)\|\%(\%(no_\?\)\?bash_rematch\)\|\%(\%(no_\?\)\?beep\)\|\%(\%(no_\?\)\?bgnice\)\|\%(\%(no_\?\)\?bg_nice\)\|\%(\%(no_\?\)\?braceccl\)\|\%(\%(no_\?\)\?brace_ccl\)\|\%(\%(no_\?\)\?braceexpand\)\|\%(\%(no_\?\)\?brace_expand\)\|\%(\%(no_\?\)\?bsdecho\)\|\%(\%(no_\?\)\?bsd_echo\)\|\%(\%(no_\?\)\?caseglob\)\|\%(\%(no_\?\)\?case_glob\)\|\%(\%(no_\?\)\?casematch\)\|\%(\%(no_\?\)\?case_match\)\|\%(\%(no_\?\)\?cbases\)\|\%(\%(no_\?\)\?c_bases\)\|\%(\%(no_\?\)\?cdablevars\)\|\%(\%(no_\?\)\?cdable_vars\)\|\%(\%(no_\?\)\?cd_able_vars\)\|\%(\%(no_\?\)\?chasedots\)\|\%(\%(no_\?\)\?chase_dots\)\|\%(\%(no_\?\)\?chaselinks\)\|\%(\%(no_\?\)\?chase_links\)\|\%(\%(no_\?\)\?checkjobs\)\|\%(\%(no_\?\)\?check_jobs\)\|\%(\%(no_\?\)\?clobber\)\|\%(\%(no_\?\)\?combiningchars\)\|\%(\%(no_\?\)\?combining_chars\)\|\%(\%(no_\?\)\?completealiases\)\|\%(\%(no_\?\)\?complete_aliases\)\|\%(\%(no_\?\)\?completeinword\)\|\%(\%(no_\?\)\?complete_in_word\)\|\%(\%(no_\?\)\?continueonerror\)\|\%(\%(no_\?\)\?continue_on_error\)\|\%(\%(no_\?\)\?correct\)\|\%(\%(no_\?\)\?correctall\)\|\%(\%(no_\?\)\?correct_all\)\|\%(\%(no_\?\)\?cprecedences\)\|\%(\%(no_\?\)\?c_precedences\)\|\%(\%(no_\?\)\?cshjunkiehistory\)\|\%(\%(no_\?\)\?csh_junkie_history\)\|\%(\%(no_\?\)\?cshjunkieloops\)\|\%(\%(no_\?\)\?csh_junkie_loops\)\|\%(\%(no_\?\)\?cshjunkiequotes\)\|\%(\%(no_\?\)\?csh_junkie_quotes\)\|\%(\%(no_\?\)\?csh_nullcmd\)\|\%(\%(no_\?\)\?csh_null_cmd\)\|\%(\%(no_\?\)\?cshnullcmd\)\|\%(\%(no_\?\)\?csh_null_cmd\)\|\%(\%(no_\?\)\?cshnullglob\)\|\%(\%(no_\?\)\?csh_null_glob\)\|\%(\%(no_\?\)\?debugbeforecmd\)\|\%(\%(no_\?\)\?debug_before_cmd\)\|\%(\%(no_\?\)\?dotglob\)\|\%(\%(no_\?\)\?dot_glob\)\|\%(\%(no_\?\)\?dvorak\)\|\%(\%(no_\?\)\?emacs\)\|\%(\%(no_\?\)\?equals\)\|\%(\%(no_\?\)\?errexit\)\|\%(\%(no_\?\)\?err_exit\)\|\%(\%(no_\?\)\?errreturn\)\|\%(\%(no_\?\)\?err_return\)\|\%(\%(no_\?\)\?evallineno\)\|\%(\%(no_\?\)\?eval_lineno\)\|\%(\%(no_\?\)\?exec\)\|\%(\%(no_\?\)\?extendedglob\)\|\%(\%(no_\?\)\?extended_glob\)\|\%(\%(no_\?\)\?extendedhistory\)\|\%(\%(no_\?\)\?extended_history\)\|\%(\%(no_\?\)\?flowcontrol\)\|\%(\%(no_\?\)\?flow_control\)\|\%(\%(no_\?\)\?forcefloat\)\|\%(\%(no_\?\)\?force_float\)\|\%(\%(no_\?\)\?functionargzero\)\|\%(\%(no_\?\)\?function_argzero\)\|\%(\%(no_\?\)\?function_arg_zero\)\|\%(\%(no_\?\)\?glob\)\|\%(\%(no_\?\)\?globalexport\)\|\%(\%(no_\?\)\?global_export\)\|\%(\%(no_\?\)\?globalrcs\)\|\%(\%(no_\?\)\?global_rcs\)\|\%(\%(no_\?\)\?globassign\)\|\%(\%(no_\?\)\?glob_assign\)\|\%(\%(no_\?\)\?globcomplete\)\|\%(\%(no_\?\)\?glob_complete\)\|\%(\%(no_\?\)\?globdots\)\|\%(\%(no_\?\)\?glob_dots\)\|\%(\%(no_\?\)\?glob_subst\)\|\%(\%(no_\?\)\?globsubst\)\|\%(\%(no_\?\)\?globstarshort\)\|\%(\%(no_\?\)\?glob_star_short\)\|\%(\%(no_\?\)\?hashall\)\|\%(\%(no_\?\)\?hash_all\)\|\%(\%(no_\?\)\?hashcmds\)\|\%(\%(no_\?\)\?hash_cmds\)\|\%(\%(no_\?\)\?hashdirs\)\|\%(\%(no_\?\)\?hash_dirs\)\|\%(\%(no_\?\)\?hashexecutablesonly\)\|\%(\%(no_\?\)\?hash_executables_only\)\|\%(\%(no_\?\)\?hashlistall\)\|\%(\%(no_\?\)\?hash_list_all\)\|\%(\%(no_\?\)\?histallowclobber\)\|\%(\%(no_\?\)\?hist_allow_clobber\)\|\%(\%(no_\?\)\?histappend\)\|\%(\%(no_\?\)\?hist_append\)\|\%(\%(no_\?\)\?histbeep\)\|\%(\%(no_\?\)\?hist_beep\)\|\%(\%(no_\?\)\?hist_expand\)\|\%(\%(no_\?\)\?hist_expire_dups_first\)\|\%(\%(no_\?\)\?histexpand\)\|\%(\%(no_\?\)\?histexpiredupsfirst\)\|\%(\%(no_\?\)\?histfcntllock\)\|\%(\%(no_\?\)\?hist_fcntl_lock\)\|\%(\%(no_\?\)\?histfindnodups\)\|\%(\%(no_\?\)\?hist_find_no_dups\)\|\%(\%(no_\?\)\?histignorealldups\)\|\%(\%(no_\?\)\?hist_ignore_all_dups\)\|\%(\%(no_\?\)\?histignoredups\)\|\%(\%(no_\?\)\?hist_ignore_dups\)\|\%(\%(no_\?\)\?histignorespace\)\|\%(\%(no_\?\)\?hist_ignore_space\)\|\%(\%(no_\?\)\?histlexwords\)\|\%(\%(no_\?\)\?hist_lex_words\)\|\%(\%(no_\?\)\?histnofunctions\)\|\%(\%(no_\?\)\?hist_no_functions\)\|\%(\%(no_\?\)\?histnostore\)\|\%(\%(no_\?\)\?hist_no_store\)\|\%(\%(no_\?\)\?histreduceblanks\)\|\%(\%(no_\?\)\?hist_reduce_blanks\)\|\%(\%(no_\?\)\?histsavebycopy\)\|\%(\%(no_\?\)\?hist_save_by_copy\)\|\%(\%(no_\?\)\?histsavenodups\)\|\%(\%(no_\?\)\?hist_save_no_dups\)\|\%(\%(no_\?\)\?histsubstpattern\)\|\%(\%(no_\?\)\?hist_subst_pattern\)\|\%(\%(no_\?\)\?histverify\)\|\%(\%(no_\?\)\?hist_verify\)\|\%(\%(no_\?\)\?hup\)\|\%(\%(no_\?\)\?ignorebraces\)\|\%(\%(no_\?\)\?ignore_braces\)\|\%(\%(no_\?\)\?ignoreclosebraces\)\|\%(\%(no_\?\)\?ignore_close_braces\)\|\%(\%(no_\?\)\?ignoreeof\)\|\%(\%(no_\?\)\?ignore_eof\)\|\%(\%(no_\?\)\?incappendhistory\)\|\%(\%(no_\?\)\?inc_append_history\)\|\%(\%(no_\?\)\?incappendhistorytime\)\|\%(\%(no_\?\)\?inc_append_history_time\)\|\%(\%(no_\?\)\?interactive\)\|\%(\%(no_\?\)\?interactivecomments\)\|\%(\%(no_\?\)\?interactive_comments\)\|\%(\%(no_\?\)\?ksharrays\)\|\%(\%(no_\?\)\?ksh_arrays\)\|\%(\%(no_\?\)\?kshautoload\)\|\%(\%(no_\?\)\?ksh_autoload\)\|\%(\%(no_\?\)\?kshglob\)\|\%(\%(no_\?\)\?ksh_glob\)\|\%(\%(no_\?\)\?kshoptionprint\)\|\%(\%(no_\?\)\?ksh_option_print\)\|\%(\%(no_\?\)\?kshtypeset\)\|\%(\%(no_\?\)\?ksh_typeset\)\|\%(\%(no_\?\)\?kshzerosubscript\)\|\%(\%(no_\?\)\?ksh_zero_subscript\)\|\%(\%(no_\?\)\?listambiguous\)\|\%(\%(no_\?\)\?list_ambiguous\)\|\%(\%(no_\?\)\?listbeep\)\|\%(\%(no_\?\)\?list_beep\)\|\%(\%(no_\?\)\?listpacked\)\|\%(\%(no_\?\)\?list_packed\)\|\%(\%(no_\?\)\?listrowsfirst\)\|\%(\%(no_\?\)\?list_rows_first\)\|\%(\%(no_\?\)\?listtypes\)\|\%(\%(no_\?\)\?list_types\)\|\%(\%(no_\?\)\?localloops\)\|\%(\%(no_\?\)\?local_loops\)\|\%(\%(no_\?\)\?localoptions\)\|\%(\%(no_\?\)\?local_options\)\|\%(\%(no_\?\)\?localpatterns\)\|\%(\%(no_\?\)\?local_patterns\)\|\%(\%(no_\?\)\?localtraps\)\|\%(\%(no_\?\)\?local_traps\)\|\%(\%(no_\?\)\?log\)\|\%(\%(no_\?\)\?login\)\|\%(\%(no_\?\)\?longlistjobs\)\|\%(\%(no_\?\)\?long_list_jobs\)\|\%(\%(no_\?\)\?magicequalsubst\)\|\%(\%(no_\?\)\?magic_equal_subst\)\|\%(\%(no_\?\)\?mailwarn\)\|\%(\%(no_\?\)\?mail_warn\)\|\%(\%(no_\?\)\?mail_warning\)\|\%(\%(no_\?\)\?mark_dirs\)\|\%(\%(no_\?\)\?mailwarning\)\|\%(\%(no_\?\)\?markdirs\)\|\%(\%(no_\?\)\?menucomplete\)\|\%(\%(no_\?\)\?menu_complete\)\|\%(\%(no_\?\)\?monitor\)\|\%(\%(no_\?\)\?multibyte\)\|\%(\%(no_\?\)\?multi_byte\)\|\%(\%(no_\?\)\?multifuncdef\)\|\%(\%(no_\?\)\?multi_func_def\)\|\%(\%(no_\?\)\?multios\)\|\%(\%(no_\?\)\?multi_os\)\|\%(\%(no_\?\)\?nomatch\)\|\%(\%(no_\?\)\?no_match\)\|\%(\%(no_\?\)\?notify\)\|\%(\%(no_\?\)\?nullglob\)\|\%(\%(no_\?\)\?null_glob\)\|\%(\%(no_\?\)\?numericglobsort\)\|\%(\%(no_\?\)\?numeric_glob_sort\)\|\%(\%(no_\?\)\?octalzeroes\)\|\%(\%(no_\?\)\?octal_zeroes\)\|\%(\%(no_\?\)\?onecmd\)\|\%(\%(no_\?\)\?one_cmd\)\|\%(\%(no_\?\)\?overstrike\)\|\%(\%(no_\?\)\?over_strike\)\|\%(\%(no_\?\)\?pathdirs\)\|\%(\%(no_\?\)\?path_dirs\)\|\%(\%(no_\?\)\?pathscript\)\|\%(\%(no_\?\)\?path_script\)\|\%(\%(no_\?\)\?physical\)\|\%(\%(no_\?\)\?pipefail\)\|\%(\%(no_\?\)\?pipe_fail\)\|\%(\%(no_\?\)\?posixaliases\)\|\%(\%(no_\?\)\?posix_aliases\)\|\%(\%(no_\?\)\?posixargzero\)\|\%(\%(no_\?\)\?posix_arg_zero\)\|\%(\%(no_\?\)\?posix_argzero\)\|\%(\%(no_\?\)\?posixbuiltins\)\|\%(\%(no_\?\)\?posix_builtins\)\|\%(\%(no_\?\)\?posixcd\)\|\%(\%(no_\?\)\?posix_cd\)\|\%(\%(no_\?\)\?posixidentifiers\)\|\%(\%(no_\?\)\?posix_identifiers\)\|\%(\%(no_\?\)\?posixjobs\)\|\%(\%(no_\?\)\?posix_jobs\)\|\%(\%(no_\?\)\?posixstrings\)\|\%(\%(no_\?\)\?posix_strings\)\|\%(\%(no_\?\)\?posixtraps\)\|\%(\%(no_\?\)\?posix_traps\)\|\%(\%(no_\?\)\?printeightbit\)\|\%(\%(no_\?\)\?print_eight_bit\)\|\%(\%(no_\?\)\?printexitvalue\)\|\%(\%(no_\?\)\?print_exit_value\)\|\%(\%(no_\?\)\?privileged\)\|\%(\%(no_\?\)\?promptbang\)\|\%(\%(no_\?\)\?prompt_bang\)\|\%(\%(no_\?\)\?promptcr\)\|\%(\%(no_\?\)\?prompt_cr\)\|\%(\%(no_\?\)\?promptpercent\)\|\%(\%(no_\?\)\?prompt_percent\)\|\%(\%(no_\?\)\?promptsp\)\|\%(\%(no_\?\)\?prompt_sp\)\|\%(\%(no_\?\)\?promptsubst\)\|\%(\%(no_\?\)\?prompt_subst\)\|\%(\%(no_\?\)\?promptvars\)\|\%(\%(no_\?\)\?prompt_vars\)\|\%(\%(no_\?\)\?pushdignoredups\)\|\%(\%(no_\?\)\?pushd_ignore_dups\)\|\%(\%(no_\?\)\?pushdminus\)\|\%(\%(no_\?\)\?pushd_minus\)\|\%(\%(no_\?\)\?pushdsilent\)\|\%(\%(no_\?\)\?pushd_silent\)\|\%(\%(no_\?\)\?pushdtohome\)\|\%(\%(no_\?\)\?pushd_to_home\)\|\%(\%(no_\?\)\?rcexpandparam\)\|\%(\%(no_\?\)\?rc_expandparam\)\|\%(\%(no_\?\)\?rc_expand_param\)\|\%(\%(no_\?\)\?rcquotes\)\|\%(\%(no_\?\)\?rc_quotes\)\|\%(\%(no_\?\)\?rcs\)\|\%(\%(no_\?\)\?recexact\)\|\%(\%(no_\?\)\?rec_exact\)\|\%(\%(no_\?\)\?rematchpcre\)\|\%(\%(no_\?\)\?re_match_pcre\)\|\%(\%(no_\?\)\?rematch_pcre\)\|\%(\%(no_\?\)\?restricted\)\|\%(\%(no_\?\)\?rmstarsilent\)\|\%(\%(no_\?\)\?rm_star_silent\)\|\%(\%(no_\?\)\?rmstarwait\)\|\%(\%(no_\?\)\?rm_star_wait\)\|\%(\%(no_\?\)\?sharehistory\)\|\%(\%(no_\?\)\?share_history\)\|\%(\%(no_\?\)\?shfileexpansion\)\|\%(\%(no_\?\)\?sh_file_expansion\)\|\%(\%(no_\?\)\?shglob\)\|\%(\%(no_\?\)\?sh_glob\)\|\%(\%(no_\?\)\?shinstdin\)\|\%(\%(no_\?\)\?shin_stdin\)\|\%(\%(no_\?\)\?shnullcmd\)\|\%(\%(no_\?\)\?sh_nullcmd\)\|\%(\%(no_\?\)\?shoptionletters\)\|\%(\%(no_\?\)\?sh_option_letters\)\|\%(\%(no_\?\)\?shortloops\)\|\%(\%(no_\?\)\?short_loops\)\|\%(\%(no_\?\)\?shwordsplit\)\|\%(\%(no_\?\)\?sh_word_split\)\|\%(\%(no_\?\)\?singlecommand\)\|\%(\%(no_\?\)\?single_command\)\|\%(\%(no_\?\)\?singlelinezle\)\|\%(\%(no_\?\)\?single_line_zle\)\|\%(\%(no_\?\)\?sourcetrace\)\|\%(\%(no_\?\)\?source_trace\)\|\%(\%(no_\?\)\?stdin\)\|\%(\%(no_\?\)\?sunkeyboardhack\)\|\%(\%(no_\?\)\?sun_keyboard_hack\)\|\%(\%(no_\?\)\?trackall\)\|\%(\%(no_\?\)\?track_all\)\|\%(\%(no_\?\)\?transientrprompt\)\|\%(\%(no_\?\)\?transient_rprompt\)\|\%(\%(no_\?\)\?trapsasync\)\|\%(\%(no_\?\)\?traps_async\)\|\%(\%(no_\?\)\?typesetsilent\)\|\%(\%(no_\?\)\?type_set_silent\)\|\%(\%(no_\?\)\?typeset_silent\)\|\%(\%(no_\?\)\?unset\)\|\%(\%(no_\?\)\?verbose\)\|\%(\%(no_\?\)\?vi\)\|\%(\%(no_\?\)\?warncreateglobal\)\|\%(\%(no_\?\)\?warn_create_global\)\|\%(\%(no_\?\)\?xtrace\)\|\%(\%(no_\?\)\?zle\)/ nextgroup=zshOption skipwhite contained
 
 syn keyword zshTypes            float integer local typeset declare private
 
@@ -319,9 +152,9 @@ syn cluster zshSubst            contains=zshSubst,zshOldSubst,zshMathSubst
 syn region  zshSubst            matchgroup=zshSubstDelim transparent
                                 \ start='\$(' skip='\\)' end=')' contains=TOP fold
 syn region  zshParentheses      transparent start='(' skip='\\)' end=')' fold
+syn region  zshGlob             start='(#' end=')'
 syn region  zshMathSubst        matchgroup=zshSubstDelim transparent
-                                \ start='\$((' skip='\\)'
-                                \ matchgroup=zshSubstDelim end='))'
+                                \ start='\$((' skip='\\)' end='))'
                                 \ contains=zshParentheses,@zshSubst,zshNumber,
                                 \ @zshDerefs,zshString keepend fold
 syn region  zshBrackets         contained transparent start='{' skip='\\}'
@@ -359,23 +192,13 @@ hi def link zshRedir            Operator
 hi def link zshVariable         None
 hi def link zshVariableDef      zshVariable
 hi def link zshDereferencing    PreProc
-if s:zsh_syntax_variables =~ 'short\|all'
-  hi def link zshShortDeref     zshDereferencing
-else
-  hi def link zshShortDeref     None
-endif
-if s:zsh_syntax_variables =~ 'long\|all'
-  hi def link zshLongDeref      zshDereferencing
-else
-  hi def link zshLongDeref      None
-endif
-if s:zsh_syntax_variables =~ 'all'
-  hi def link zshDeref          zshDereferencing
-else
-  hi def link zshDeref          None
-endif
+hi def link zshShortDeref       zshDereferencing
+hi def link zshLongDeref        zshDereferencing
+hi def link zshDeref            zshDereferencing
+hi def link zshDollarVar        zshDereferencing
 hi def link zshCommands         Keyword
-hi def link zshOptions          Constant
+hi def link zshOptStart         Keyword
+hi def link zshOption           Constant
 hi def link zshTypes            Type
 hi def link zshSwitches         Special
 hi def link zshNumber           Number
@@ -383,6 +206,7 @@ hi def link zshSubst            PreProc
 hi def link zshMathSubst        zshSubst
 hi def link zshOldSubst         zshSubst
 hi def link zshSubstDelim       zshSubst
+hi def link zshGlob             zshSubst
 
 let b:current_syntax = "zsh"
 
index 832ad04..268c40c 100644 (file)
@@ -542,7 +542,7 @@ Nota: 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
               Lección 5.3: UN MANDATO DE ESCRITURA SELECTIVO
 
-   ** Para guardar parte del fuchero escriba   :#,# NOMBRE_DEL_FICHERO **
+   ** Para guardar parte del fichero escriba   :#,# NOMBRE_DEL_FICHERO **
 
 
   1. Escriba de nuevo, una vez más,  :!dir  o  :!ls  para obtener una lista
index e5a6c45..cdfdcd6 100644 (file)
@@ -61,8 +61,8 @@ NOTE : Les touches fl
      Ceci quitte l'éditeur SANS enregistrer les changements que vous avez
      faits.
 
-  3. Lorsque l'invite du shell vous sera présentée, tapez la commande qui
-     vous a mené dans ce tutoriel. Cela pourrait être :    vimtutor <Entrée>
+  3. Revenez ici en tapant la commande qui vous a mené à ce tutoriel.
+     Cela pourrait être :    vimtutor <Entrée>
 
   4. Si vous avez mémorisé ces étapes et êtes confiant, effectuez les étapes
      1 à 3 pour sortir puis rentrer dans l'éditeur.
@@ -123,7 +123,7 @@ NOTE : En avan
                      Leçon 1.5 : ÉDITION DE TEXTE - AJOUTER
 
 
-                    ** Appuyez  A  pour ajouter du text. **
+                    ** Appuyez  A  pour ajouter du texte. **
 
   1. Déplacez le curseur sur la première ligne ci-dessous marquée --->.
      Peu importe sur quel caractère se trouve le curseur sur cette ligne.
@@ -154,7 +154,7 @@ NOTE : En avan
 !! NOTE : Lisez toute la leçon avant d'exécuter les instructions ci-dessous !!
 
   1. Sortez de ce tutoriel comme vous l'avez fait dans la Leçon 1.2 :  :q!
-     Ou, si vous avez accès à un autre terminal, exécutez y les actions
+     Ou, si vous avez accès à un autre terminal, exécutez-y les actions
      qui suivent.
 
   2. À l'invite du shell, tapez cette commande :  vim tutor <Entrée>
@@ -574,7 +574,7 @@ NOTE : Quand la recherche atteint la fin du fichier, elle reprend au d
 
   2. Puis tapez le caractère  % .
 
-  3. Le curseur se déplacera sur la parenthèse out crochet correspondant.
+  3. Le curseur se déplacera sur la parenthèse ou crochet correspondant.
 
   4. Tapez  %  pour replacer le curseur sur la parenthèse ou crochet
      correspondant.
@@ -704,7 +704,7 @@ NOTE : Si vous quittez Vim et le red
   3. Appuyez  :  . En bas de l'écran  :'<,'> va apparaître.
 
   4. Tapez   w TEST  , où TEST est un nom de fichier qui n'existe pas.
-     Vérifiez que vous voyez  :'<,'>w TEST  avant de d'appuyer sur <Entrée>.
+     Vérifiez que vous voyez  :'<,'>w TEST  avant d'appuyer sur <Entrée>.
 
   5. Vim va enregistrer les lignes sélectionnées dans le fichier TEST.
      Utilisez  :!dir  ou  :!ls pour le voir. Ne l'effacez pas encore !
@@ -854,17 +854,17 @@ NOTE : Le mode Remplacement est comme le mode Insertion, mais tous les
   5. Tapez  p  pour coller le texte. Puis tapez :  un second <Échap> .
 
   6. Utilisez le mode Visuel pour sélectionner "élément", copiez-le avec  y  ,
-     déplacez-vous à la fin de la ligne suivant avec  j$  et collez le texte
+     déplacez-vous à la fin de la ligne suivante avec  j$  et collez le texte
      à cet endroit avec  p .
 
 --->  a) ceci est le premier élément.
       b)
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                       Leçon 6.4 : RÉGLAGE DES OPTIONS
+                       Leçon 6.5 : RÉGLAGE DES OPTIONS
 
 
-    ** Réglons une option afin que la recherche et la substitution ignore la
+    ** Réglons une option afin que la recherche et la substitution ignorent la
        casse des caractères. **
 
   1. Recherchez 'ignore' en tapant :   /ignore <Entrée>
@@ -1034,5 +1034,5 @@ NOTE : Le compl
   Dernières mises à jour par Dominique Pellé.
 
   E-mail :      dominique.pelle@gmail.com
-  Last Change : 2016 Jul 02
+  Last Change : 2017 Jan 16
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index 9c44db1..0ec3287 100644 (file)
@@ -61,8 +61,8 @@ NOTE : Les touches fléchées devraient également fonctionner. Mais en utilisan
      Ceci quitte l'éditeur SANS enregistrer les changements que vous avez
      faits.
 
-  3. Lorsque l'invite du shell vous sera présentée, tapez la commande qui
-     vous a mené dans ce tutoriel. Cela pourrait être :    vimtutor <Entrée>
+  3. Revenez ici en tapant la commande qui vous a mené à ce tutoriel.
+     Cela pourrait être :    vimtutor <Entrée>
 
   4. Si vous avez mémorisé ces étapes et êtes confiant, effectuez les étapes
      1 à 3 pour sortir puis rentrer dans l'éditeur.
@@ -123,7 +123,7 @@ NOTE : En avançant dans ce cours, n'essayez pas de mémoriser, apprenez par
                      Leçon 1.5 : ÉDITION DE TEXTE - AJOUTER
 
 
-                    ** Appuyez  A  pour ajouter du text. **
+                    ** Appuyez  A  pour ajouter du texte. **
 
   1. Déplacez le curseur sur la première ligne ci-dessous marquée --->.
      Peu importe sur quel caractère se trouve le curseur sur cette ligne.
@@ -154,7 +154,7 @@ NOTE : En avançant dans ce cours, n'essayez pas de mémoriser, apprenez par
 !! NOTE : Lisez toute la leçon avant d'exécuter les instructions ci-dessous !!
 
   1. Sortez de ce tutoriel comme vous l'avez fait dans la Leçon 1.2 :  :q!
-     Ou, si vous avez accès à un autre terminal, exécutez y les actions
+     Ou, si vous avez accès à un autre terminal, exécutez-y les actions
      qui suivent.
 
   2. À l'invite du shell, tapez cette commande :  vim tutor <Entrée>
@@ -574,7 +574,7 @@ NOTE : Quand la recherche atteint la fin du fichier, elle reprend au début
 
   2. Puis tapez le caractère  % .
 
-  3. Le curseur se déplacera sur la parenthèse out crochet correspondant.
+  3. Le curseur se déplacera sur la parenthèse ou crochet correspondant.
 
   4. Tapez  %  pour replacer le curseur sur la parenthèse ou crochet
      correspondant.
@@ -704,7 +704,7 @@ NOTE : Si vous quittez Vim et le redémarrez de nouveau avec le fichier TEST,
   3. Appuyez  :  . En bas de l'écran  :'<,'> va apparaître.
 
   4. Tapez   w TEST  , où TEST est un nom de fichier qui n'existe pas.
-     Vérifiez que vous voyez  :'<,'>w TEST  avant de d'appuyer sur <Entrée>.
+     Vérifiez que vous voyez  :'<,'>w TEST  avant d'appuyer sur <Entrée>.
 
   5. Vim va enregistrer les lignes sélectionnées dans le fichier TEST.
      Utilisez  :!dir  ou  :!ls pour le voir. Ne l'effacez pas encore !
@@ -854,17 +854,17 @@ NOTE : Le mode Remplacement est comme le mode Insertion, mais tous les
   5. Tapez  p  pour coller le texte. Puis tapez :  un second <Échap> .
 
   6. Utilisez le mode Visuel pour sélectionner "élément", copiez-le avec  y  ,
-     déplacez-vous à la fin de la ligne suivant avec  j$  et collez le texte
+     déplacez-vous à la fin de la ligne suivante avec  j$  et collez le texte
      à cet endroit avec  p .
 
 --->  a) ceci est le premier élément.
       b)
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                       Leçon 6.4 : RÉGLAGE DES OPTIONS
+                       Leçon 6.5 : RÉGLAGE DES OPTIONS
 
 
-    ** Réglons une option afin que la recherche et la substitution ignore la
+    ** Réglons une option afin que la recherche et la substitution ignorent la
        casse des caractères. **
 
   1. Recherchez 'ignore' en tapant :   /ignore <Entrée>
@@ -1034,5 +1034,5 @@ NOTE : Le complètement fonctionne pour de nombreuses commandes. Essayez
   Dernières mises à jour par Dominique Pellé.
 
   E-mail :      dominique.pelle@gmail.com
-  Last Change : 2016 Jul 02
+  Last Change : 2017 Jan 16
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index 8fd1326..57d578f 100644 (file)
@@ -523,7 +523,7 @@ NOTA: La posizione del cursore si vede nell'angolo in basso a destra dello
      schiacciato mentre premi la lettera o).  Ripeti  CTRL-O  per andare ancora
      indietro. Puoi usare  CTRL-I  per tornare in avanti.
 
-NOTA: "errroore" non è il modo giusto di digitare errore; errroore è un errore.
+---> "errroore" non è il modo giusto di digitare errore; errroore è un errore.
 NOTA: Quando la ricerca arriva a fine file, ricomincia dall'inizio del file,
       a meno che l'opzione 'wrapscan' sia stata disattivata.
 
@@ -730,7 +730,7 @@ NOTA:  Puoi anche leggere l'output prodotto da un comando esterno. Ad es.
 
   4. Per aprire una linea SOPRA il cursore, batti una   O  maiuscola, invece
      che una   o   minuscola. Prova sulla linea qui sotto.
-Apri una linea SOPRA questa battendo  O  mentre il cursore è su questa linea.
+---> Apri una linea SOPRA questa battendo  O  mentre il cursore è su questa linea.
 
 
 
index 076aac3..74c8120 100644 (file)
@@ -523,7 +523,7 @@ NOTA: La posizione del cursore si vede nell'angolo in basso a destra dello
      schiacciato mentre premi la lettera o).  Ripeti  CTRL-O  per andare ancora
      indietro. Puoi usare  CTRL-I  per tornare in avanti.
 
-NOTA: "errroore" non è il modo giusto di digitare errore; errroore è un errore.
+---> "errroore" non è il modo giusto di digitare errore; errroore è un errore.
 NOTA: Quando la ricerca arriva a fine file, ricomincia dall'inizio del file,
       a meno che l'opzione 'wrapscan' sia stata disattivata.
 
@@ -730,7 +730,7 @@ NOTA:  Puoi anche leggere l'output prodotto da un comando esterno. Ad es.
 
   4. Per aprire una linea SOPRA il cursore, batti una   O  maiuscola, invece
      che una   o   minuscola. Prova sulla linea qui sotto.
-Apri una linea SOPRA questa battendo  O  mentre il cursore è su questa linea.
+---> Apri una linea SOPRA questa battendo  O  mentre il cursore è su questa linea.
 
 
 
index b7c74f5..38c5929 100644 (file)
@@ -1,36 +1,36 @@
 ===============================================================================
-=      B e m   V i n d o   a o   V I M   T u t o r   -   Versão 1.7 pt_BR     =
+=    B e m - v i n d o  ao  t u t o r i a l  do  V I M  -  Versão 1.8 pt_BR   =
 ===============================================================================
 
      Vim é um poderoso editor que possui muitos comandos, tantos que seria
-     impossível ensinar num tutorial como este. Este tutorial é planejado para
-     apresentar os comandos suficientes para você ficar habilitado a usar
-     facilmente o Vim como um editor de textos genérico.
+     impossível ensiná-los num tutorial como este, que é concebido para
+     apresentar os comandos suficientes para permiti-lo usar facilmente o
+     Vim como um editor de textos genérico.
 
-     O tempo aproximado requerido para completar o tutorial é de 25-30 minutos,
+     O tempo necessário para completar o tutorial é de cerca de 25-30 minutos,
      dependendo de quanto tempo é gasto praticando os comandos.
 
      ATENÇÃO:
-     Os comandos nas lições vão modificar o texto. Utilize uma cópia deste
-     arquivo para praticar os comandos (se você iniciou o "vimtutor", esta já
+     Os comandos nas lições modificam este texto. Faça uma cópia deste
+     arquivo para praticar os comandos (se usou o "vimtutor", esta já
      é uma cópia).
 
-     É importante lembrar que este tutorial é planejado para ensinar através da
+     É importante lembrar que este tutorial é concebido para ensinar pela
      prática. Isso significa que você precisa executar os comandos para 
      aprendê-los adequadamente. Se você somente ler o texto, esquecerá os
      comandos!
 
      Agora, certifique-se de que sua tecla Shift-Lock (ou Caps Lock) não esteja
      ativada e pressione a tecla  j  o bastante para mover o cursor até que a
-     Lição 1.1 esteja completamente na tela.
+     Lição 1.1 apareça inteiramente na tela.
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                        Lição 1.1:  MOVENDO O CURSOR
+                        Lição 1.1:  MOVER O CURSOR
 
 
   ** Para mover o cursor, pressione as teclas h,j,k,l conforme indicado. **
              ^
-             k          Dica: A tecla h está à esquerda e move para a esquerda.
-       < h       l >          A tecla l está à direita e move para a direita.
+             k          Dica: A tecla h está à esquerda e move à esquerda.
+       < h       l >          A tecla l está à direita e move à direita.
              j                A tecla j se parece com uma seta para baixo.
              v
   1. Mova o cursor pela tela até que você se sinta confortável.
   2. Segure pressionada a tecla (j) até haver repetição.
      Agora você já sabe como ir para a próxima lição.
 
-  3. Usando a tecla j, mova até a lição 1.2.
+  3. Usando a tecla j, vá para a Lição 1.2.
 
-NOTA: Se você está inseguro sobre o que digitou, pressione <ESC> para 
-      colocá-lo no modo Normal. Então redigite o comando que você queria.
+NOTA: Se está inseguro sobre o que digitou, pressione <ESC> para 
+      colocá-lo no modo Normal. Então redigite o comando que queria.
 
-NOTA: As teclas de cursor devem funcionar também. Mas usando hjkl, tão logo
+NOTA: As teclas de cursor funcionam também. Mas usando hjkl, tão logo
       esteja acostumado, você poderá se mover muito mais rapidamente.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                          Lição 1.2: SAINDO DO VIM
+                          Lição 1.2: SAIR DO VIM
 
 
- !! NOTA: Antes de executar qualquer dos passos abaixo, leia a lição inteira !!
+ !! NOTA: Antes de executar quaisquer dos passos abaixo, leia a lição inteira !!
 
   1. Pressione <ESC> (para ter certeza de que está no modo Normal).
 
-  2. Digite    :q! <ENTER>.
-     Isso sai do editor SEM salvar qualquer mudança que tenha sido feita.
-     Se quiser salvar as alterações e sair, digite     :wq <ENTER>
+  2. Digite:    :q! <ENTER>.
+     Assim, sai do editor SEM salvar qualquer mudança feita.
 
-  3. Repita o procedimento que lhe trouxe a este tutorial. O procedimento pode
+  3. Repita o procedimento que o trouxe a este tutorial. O procedimento pode
      ter sido a digitação de:  vimtutor <ENTER>.
 
-  4. Se você memorizou estes passos e está confiante, execute os passos de
+  4. Se memorizou estes passos e está confiante, execute os passos de
      1 a 3 para sair e reentrar no editor.
 
 NOTA:  :q! <ENTER>  descarta qualquer mudança. Em uma próxima lição será
@@ -70,9 +69,9 @@ NOTA:  :q! <ENTER>  descarta qualquer mudan
   5. Desça o cursor até a Lição 1.3.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                    Lição 1.3: EDITANDO TEXTOS - DELEÇÃO
+                    Lição 1.3: EDITAR TEXTOS - REMOÇÃO
 
-  ** No modo Normal, pressione  x  para deletar o caractere sob o cursor. **
+  ** Pressione  x  para deletar o caractere sob o cursor. **
 
 
   1. Mova o cursor para a linha abaixo marcada com --->.
@@ -80,47 +79,47 @@ NOTA:  :q! <ENTER>  descarta qualquer mudan
   2. Para corrigir os erros, mova o cursor até que ele esteja sobre o 
      caractere a ser deletado.
 
-  3. Pressione a tecla  x  para deletar o caractere indesejado.
+  3. Pressione a tecla  x  para remover o caractere incorreto.
 
-  4. Repita os passos 2 até 4 até que a sentença esteja correta.
+  4. Repita os passos 2 até 4 até que a frase esteja correta.
 
 ---> A vvaca pullouu por ccimaa dda luuua.
 
-  5. Agora que a sentença está correta, vá para a Lição 1.4.
+  5. Agora que a frase está correta, prossiga para a Lição 1.4.
 
 NOTA: Enquanto segue este tutorial, não tente memorizar, aprenda pelo uso.
 
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                   Lição 1.4: EDITANDO TEXTOS - INSERÇÃO
+                   Lição 1.4: EDITAR TEXTOS - INSERÇÃO
 
                   ** Pressione  i  para inserir texto. **
 
 
   1. Mova o cursor até a primeira linha abaixo marcada com --->.
 
-  2. Para fazer a primeira linha ficar igual à segunda, mova o cursor para
+  2. Para deixar a primeira linha igual à segunda, mova o cursor para
      o primeiro caractere DEPOIS de onde o texto deverá ser inserido.
 
   3. Pressione  i  e digite as adições necessárias.
 
   4. Assim que cada erro for corrigido pressione <ESC> para retornar ao modo
-     Normal. Repita os passos 2 até 4 para corrigir a sentença.
+     Normal. Repita os passos 2 até 4 para corrigir a frase.
 
----> Tem text fatado desta .
----> Tem algum texto faltando desta linha.
+---> Tem text fatado nesta .
+---> Tem algum texto faltando nesta linha.
 
-  5. Quando se sentir confortável com a inserção de texto, mova o cursor para
-     a lição 1.5.
+  5. Quando se sentir à vontade com a inserção de texto, mova o cursor para
+     a Lição 1.5.
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                  Lição 1.5: EDITANDO TEXTO - ADICIONANDO
+                  Lição 1.5: EDITAR TEXTO - ADICIONAR
 
                  ** Pressione  A  para adicionar texto. **
 
-  1. Mova o curso para a primeira linha abaixo marcada com --->.
+  1. Mova o cursor para a primeira linha abaixo marcada com --->.
      Não importa sobre qual caractere o cursor estará na linha.
 
   2. Pressione  A  e digite as adições necessárias.
@@ -128,41 +127,41 @@ NOTA: Enquanto segue este tutorial, n
   3. Quando adicionar o texto, pressione <ESC> para retornar ao modo Normal.
 
   4. Mova o cursor para a segunda linha marcada ---> e repita os passos 2 e 3
-     para corrigir o texto.
+     para corrigir a frase.
 
----> Há algum texto faltando des
-     Há algum texto faltando desta linha.
+---> Há algum texto faltando nes
+     Há algum texto faltando nesta linha.
      Há algum texto faltan
 ---> Há algum texto faltando aqui.
 
-  5. Quando se sentir confortável adicionando texto, mova para a lição 1.6.
+  5. Quando se sentir confortável adicionando texto, vá para a Lição 1.6.
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                       Lição 1.6: EDITANDO UM ARQUIVO
+                       Lição 1.6: EDITAR UM ARQUIVO
+
                ** Use  :wq  para salvar um arquivo e sair. **
 
-         !! NOTA: Antes de executar qualquer um dos passos abaixo,
-                      leia esta lição completamente!!
+  !! NOTA: Leia toda a lição antes de executar as instruções!!
 
   1. Saia deste tutorial como o fez na lição 1.2:  :q!
      Ou, se tiver acesso a outro terminal, faça o seguinte nele.
 
   2. No prompt do shell, digite esse comando:  vim tutor <ENTER>
-     'vim' is é comando para iniciar o editor Vim e 'tutor' é o nome do
-     arquivo que você deseja editar.  Use um arquivo que possa ser modificado.
+     'vim' é o comando para iniciar o editor Vim e 'tutor' é o nome do
+     arquivo que você quer editar.  Use um arquivo que possa ser modificado.
 
-  3. Insira e delete texto tal como aprendeu com as lições anteriores.
+  3. Insira e apague texto tal como aprendeu nas lições anteriores.
 
   4. Salve o arquivo com as mudanças e saia do Vim com:  :wq <ENTER>
 
-  5. Se você tiver saído do vimtutor no passo 1, reinicie o vimtutor e vá para
-     o sumário seguinte.
+  5. Se tiver saído do vimtutor no passo 1, reinicie o vimtutor e vá para
+     o resumo seguinte.
 
   6. Após ler os passos acima e compreendê-los, execute-os.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                             SUMÁRIO DA LIÇÃO 1
+                             RESUMO DA LIÇÃO 1
 
   1. O cursor é movido usando tanto as teclas de seta quanto as teclas hjkl.
        h (esquerda)    j (para baixo)  k (para cima)   l (direita)
@@ -185,9 +184,9 @@ NOTA: Pressionando <ESC> voc
 Agora continue com a Lição 2.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                       Lição 2.1: COMANDOS DE DELEÇÃO
+                       Lição 2.1: COMANDOS DE REMOÇÃO 
 
-         ** Digite  dw  para deletar até o final de uma palavra. **
+                 ** Digite  dw  para apagar uma palavra. **
 
 
   1. Pressione  <ESC>  para ter certeza de que está no modo Normal.
@@ -198,19 +197,19 @@ Agora continue com a Li
 
   4. Digite  dw  para fazer a palavra desaparecer.
 
-  NOTA: A letra  d  vai aparece na última linha da tela enquanto você a
-       digita. O Vim está lhe esperando digitar um  w . Se você digitou
+  NOTA: A letra  d  vai aparecer na última linha da tela enquanto você a
+       digita. O Vim o está esperando digitar um  w . Se digitou
        alguma coisa errada, pressione <ESC> e comece de novo.
 
----> Tem a algumas oi palavras diversão que não pertencem papel a esta sentença.
+---> Tem a algumas oi palavras diversão que não pertencem papel a esta frase.
 
-  5. Repita os passos 3 ao 4 até que a sentença esteja correta e vá para a
+  5. Repita os passos 3 ao 4 até que a frase esteja correta e vá para a
      Lição 2.2.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                     Lição 2.2: MAIS COMANDOS DE DELEÇÃO
+                     Lição 2.2: MAIS COMANDOS DE REMOÇÃO
 
-          ** Digite  d$  para deletar até o final da linha. **
+             ** Digite  d$  para deletar até o fim da linha. **
 
 
 
@@ -218,13 +217,13 @@ Agora continue com a Li
 
   2. Mova o cursor até a linha abaixo marcada com --->.
 
-  3. Mova o cursor até o fim da linha correta (DEPOIS do primeiro  .).
+  3. Mova o cursor até o fim da linha correta (DEPOIS do primeiro  . ).
 
-  4. Digite  d$  para deletar até o final da linha.
+  4. Digite  d$  para apagar até o fim da linha.
 
----> Alguém digitou o final desta linha duas vezes. desta linha duas vezes.
+---> Alguém digitou o fim desta linha duas vezes. desta linha duas vezes.
 
-  5. Vá para a lição 2.3 para entender o que está acontecendo.
+  5. Vá para a lição 2.3 para entender o funcionamento deste comando.
 
 
 
@@ -233,30 +232,31 @@ Agora continue com a Li
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   Lição 2.3: SOBRE OPERADORES E MOVIMENTOS 
 
-  Muitos comandos que mudam texto são feitos de um operador e um movimento.
-  O formato para um comando deletar com o operador de deleção  d  tem a
+  Muitos comandos que mudam texto são feitos de um operador e de um movimento.
+  O formato para um comando apagar com o operador de remoção  d  tem a
   seguinte forma:
 
          d   movimento
+
   Onde:
-    d - é o operador deletar.
-    movimento - é como o operador vai operar (listado abaixo).
+    d - é o operador apagar.
+    movimento - é o movimento sobre o qual o operador age (listado abaixo).
 
   Uma pequena lista de teclas de movimento:
-    w - do cursor até o fim da palavra, incluindo o espaço.
-    e - do cursor até o fim da palavra, NÃO incluindo o espaço.
-    $ - do cursor até o fim da linha.
+    w - até o início da próxima palavra, excluindo seu primeiro caractere.
+    e - até o fim da palavra atual, incluindo seu último caractere.
+    $ - até o fim da linha, incluindo seu último caractere.
 
-  Portanto, digitando  de  irá deletar do cursor ao fim da palavra.
+  Portanto, digitar  de  apaga do cursor ao fim da palavra.
 
-NOTA: Pressionando apenas a tecla de movimento enquanto em modo Normal, sem o
-operador, irá mover o cursor como especificado na lista de teclas de
+NOTA: Pressionar apenas a tecla de movimento em modo Normal, sem o
+operador, faz o cursor se mover como especificado na lista de teclas de
 movimento.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-              Lição 2.4: USANDO UM CONTADOR PARA UM MOVIMENTO
+              Lição 2.4: USAR UM CONTADOR PARA UM MOVIMENTO
 
-    ** Digitando um número antes de um movimento repete-o muitas vezes. **
+   ** Digitar um número antes de um movimento repete-o o tanto de vezes. **
 
 
    1. Mova o cursor para o começo da linha marcada com ---> abaixo.
@@ -269,7 +269,7 @@ movimento.
 
    5. Repita os passos 2 e 3 com diferentes números.
 
----> Esta é uma linha com algumas palavras para lhe permitir fazer movimentos.
+---> Esta é uma linha com algumas palavras para permiti-lo fazer movimentos.
 
    6. Vá para a Lição 2.5.
 
@@ -277,22 +277,22 @@ movimento.
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-              Lição 2.5: USANDO UM CONTADOR PARA DELETAR MAIS
+              Lição 2.5: USAR UM CONTADOR PARA APAGAR MAIS
 
-   ** Digitando um número com um operador repete-o esse número de vezes. **
+   ** Digitar um número com um operador repete-o esse número de vezes. **
 
 
-   Você deve inserir um contador entre o operador de deleção e o movimento
-   mencionados acima para para deletar mais:
+   Você deve inserir um contador entre o operador de remoção e o de movimento
+   mencionados acima para apagar mais:
        d   número   movimento
 
-   1. Movimente o cursor para a primeira palavra com LETRAS MAIÚSCULAS na
+   1. Movimente o cursor para a primeira palavra em LETRAS MAIÚSCULAS na
       linha marcada com --->.
 
-   2. Digite  d2w  para deletar as duas palavras com LETRAS MAIÚSCULAS.
+   2. Digite  d2w  para deletar as duas palavras em LETRAS MAIÚSCULAS.
 
    3. Repita os passos 1 e 2 com diferentes contadores para deletar as
-      palavras de LETRAS MAIÚSCULAS com um comando.
+      palavras em LETRAS MAIÚSCULAS com um comando.
 
 --->  esta ABC DE linha FGHI JK LMN OP de palavras está Q RS TUV limpa.
 
@@ -300,17 +300,17 @@ movimento.
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                      Lição 2.6: OPERANDO SOBRE LINHAS
+                      Lição 2.6: TRABALHAR COM LINHAS
 
-             ** Digite  dd  para deletar uma linha inteira. **
+             ** Digite  dd  para apagar uma linha inteira. **
 
-  Em virtude da frequência em deletar uma linha inteira, os projetistas do Vi
-  decidiram que seria mais simples digitar dois d's numa linha para deletá-la.
+  Em virtude da frequência em deletar uma linha inteira, os desenvolvedores 
+  do Vi decidiram que seria mais simples digitar dois d para apagar uma linha.
 
-  1. Mova o cursor até a segunda linha na lista a baixo.
-  2. Digite  dd  para deletar a linha.
+  1. Mova o cursor até a segunda linha da frase abaixo.
+  2. Digite  dd  para apagar a linha.
   3. Agora mova até a quarta linha.
-  4. Digite  2dd  para deletar duas linhas.
+  4. Digite  2dd  para apagar duas linhas.
 
 --->  1)  Rosas são vermelhas,
 --->  2)  Lama é divertida,
@@ -318,92 +318,94 @@ movimento.
 --->  4)  Eu tenho um carro,
 --->  5)  Relógios dizem as horas,
 --->  6)  Açúcar é doce,
---->  7)  E assim é você.
+--->  7)  Assim como você.
 
 Notas do tradutor: Lama (mud) em inglês pode significar fofoca, difamação.
                    Há rima no texto original.
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                     Lição 2.7: O COMANDO UNDO (DESFAZER)
 
-** Pressione u para desfazer os últimos comandos, U restaura linha inteira.**
+** Pressione u para desfazer os últimos comandos, U recupera a linha inteira.**
 
 
   1. Mova o cursor para a linha abaixo marcada com ---> e posicione-o sobre o
      primeiro erro.
-  2. Digite  x  para deletar o primeiro caractere indesejado.
+  2. Digite  x  para deletar o primeiro caractere errado.
   3. Agora, digite  u  para desfazer o último comando executado.
   4. Desta vez, corrija todos os erros na linha usando o comando  x .
   5. Agora, digite um U maiúsculo para retornar a linha ao seu estado original.
   6. Digite  u  algumas vezes para desfazer o  U  e os comandos anteriores.
   7. Digite CTRL-R (segurando a tecla CTRL enquanto digita R) algumas vezes
-     para refazer os comandos (desfazer os undo's).
+     para refazer os comandos (desfazer os undos).
 
 ---> Corriija os erros nnesta linha e reetorne-os com undo.
 
-  8. Esses comandos são muito úteis. Agora vá para o sumário da Lição 2.
+  8. Esses comandos são muito úteis. Agora vá para o resumo da Lição 2.
 
 
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                             SUMÁRIO DA LIÇÃO 2
+                             RESUMO DA LIÇÃO 2
 
 
-  1. Para deletar do cursor até o fim de uma palavra digite:   dw
-  2. Para deletar do cursor até o fim de uma linha digite:   d$
-  3. Para deletar uma linha inteira digite:   dd
-  4. Para repetir um movimento adicione antes um número:   2w
+  1. Para apagar do cursor até a próxima palavra, digite:   dw
+  2. Para apagar do cursor até o fim de uma linha, digite:  d$
+  3. Para apagar uma linha inteira, digite:   dd
+  4. Para repetir um movimento, adicione antes um número:   2w
   5. O formato para um comando no modo Normal é:
            operador   [número]   movimento
    onde:
-      operador  - é o que será feito, como  d  para deletar
-      número    - é quantas vezes o comando será repetido
-      movimento - movimento sobre o texto que sofrerá a operação, como
-                  w (palavra), $ (até o final da linha), etc.
+      operador  - é o que será feito, como  d  para apagar
+      [número]  - quantas vezes o comando será repetido
+      movimento - movimento sobre o texto que receberá a operação, como
+                  w (palavra), $ (até o fim da linha), etc.
+
+  6. Para ir ao início da linha, use um zero:  0
 
-  5. Para desfazer um ação anterior, digite:                  u  (minúsculo)
-     Para desfazer todas as modificações em uma linha digite: U (maiúsculo)
-     Para desfazer o que foi desfeito digite:                 CTRL-R
+  7. Para desfazer uma ação anterior, digite:                  u (minúsculo)
+     Para desfazer todas as alterações em uma linha, digite:   U (maiúsculo)
+     Para desfazer o que foi desfeito, digite:                 CTRL-R
 
 
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                       Lição 3.1: O COMANDO PUT (PÔR)
+                       Lição 3.1: O COMANDO COLAR
 
-       ** Digite  p  para colocar a última deleção após o cursor. **
+       ** Digite  p  para colar após o cursor o que acabou de apagar. **
 
 
-  1. Mova o cursor até a primeira linha na lista abaixo.
+  1. Mova o cursor até a primeira linha marcada com --->.
 
-  2. Digite  dd  para deletar a linha e guardá-la no buffer do Vim.
+  2. Digite  dd  para apagar a linha e guardá-la num registro do Vim.
 
-  3. Mova o cursor até a linha ACIMA de onde a linha deletada deve ficar.
+  3. Mova o cursor até a linha c) ACIMA de onde a linha apagada deveria estar.
 
   4. No modo Normal, digite  p  para inserir a linha.
 
   5. Repita os passos 2 ao 4 para pôr todas as linhas na ordem correta.
 
-     d) Você pode aprender também?
-     b) Violetas são azuis,
-     c) Inteligência se aprende,
-     a) Rosas são vermelhas,
+---> d) Você pode aprender também?
+---> b) Violetas são azuis,
+---> c) Inteligência se aprende,
+---> a) Rosas são vermelhas,
 
 Nota do tradutor: Há rima no original.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                 Lição 3.2: O COMANDO REPLACE (SUBSTITUIR)
+                      Lição 3.2: O COMANDO SUBSTITUIR
 
      ** Digite  rx  para substituir o caractere sob o cursor por  x . ** 
 
 
   1. Mova o cursor até a primeira linha abaixo marcada com --->.
 
-  2. Mova o cursor até que ele esteja sobre o primeiro erro.
+  2. Mova o cursor até que esteja sobre o primeiro erro.
 
   3. Digite  r  e então o caractere que deveria estar lá.
 
-  4. Repita os passos 2 e 3 até que a primeira linha esteja correta.
+  4. Repita os passos 2 e 3 até que a primeira linha esteja igual à segunda.
 
 ---> Quendo este limha foi dugitada, alguem pressioniu algumas teclas erradzs!
 ---> Quando esta linha foi digitada, alguém pressionou algumas teclas erradas!
@@ -417,42 +419,43 @@ NOTA: Lembre-se que voc
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                     Lição 3.3: O OPERADOR CHANGE (MUDAR)
 
-       ** Para mudar toda uma palavra ou parte dela, digite  cw . **
+       ** Para alterar até o fim de uma palavra, digite  ce . **
 
 
   1. Mova o cursor até a primeira linha abaixo marcada com --->.
   
   2. Posicione o cursor sobre o u em lunba.
 
-  3. Digite  cw  e a palavra correta (nesse caso, digite 'inha'.)
+  3. Digite  ce  e a palavra correta (nesse caso, digite 'inha'.)
 
   4. Pressione <ESC> e mova para o próximo caractere a ser alterado.
 
-  5. Repita os passos 3 e 4 até que a primeira sentença esteja igual à segunda.
+  5. Repita os passos 3 e 4 até que a primeira frase esteja igual à segunda.
 
 ---> Essa lunba tem pwlesmfr que ocrimmm  soi alteradas cup o comando change.
 ---> Essa linha tem palavras que precisam ser alteradas com o comando change. 
 
-Note que  cw  não somente substitui a palavra, mas também lhe coloca no modo
-de inserção.
+Note que  ce  não somente substitui a palavra, mas também o coloca no modo
+de Inserção.
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                      Lição 3.4: MAIS MUDANÇAS USANDO c
 
-      ** O operador change é usado com os mesmos objetos que delete. **
+     ** O operador change é usado com os mesmos movimentos que o delete. **
+
 
   1. O operador change trabalha da mesma maneira que o delete. O formato é:
 
           c    [número]    movimento
 
-  2. Os movimentos também são os mesmos: w (palavra), $ (fim da linha), etc.
+  2. Os movimentos também são os mesmos: w (palavra) e $ (fim da linha).
 
   3. Mova até a primeira linha abaixo marcada com --->.
 
   4. Mova o cursor até o primeiro erro.
 
-  5. Digite  c$  para fazer o resto da linha ficar igual à segunda e pressione
+  5. Digite  c$  para tornar o resto da linha igual à segunda e pressione
      <ESC>.
 
 ---> O fim desta linha precisa de ajuda para ficar igual à segunda.
@@ -461,18 +464,18 @@ de inser
 NOTA: Você pode usar a tecla Backspace para corrigir erros enquanto digita.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                             SUMÁRIO DA LIÇÃO 3
+                             RESUMO DA LIÇÃO 3
 
 
-  1. Para inserir um texto que já foi deletado, digite  p . Isso coloca o texto
+  1. Para reinserir um texto que já foi apagado, digite  p . Isso coloca o texto
      deletado APÓS o cursor (se uma linha é deletada ela será inserida na linha
      abaixo do cursor).
 
   2. Para substituir o caractere sob o cursor, digite  r  e então o caractere
-     que irá substituir o original.
+     que substituirá o original.
 
   3. O comando change possibilita mudar do cursor até onde o movimento for.
-     Ex: Digite  cw  para mudar do cursor até o fim de uma palavra, c$ para
+     Ex: Digite  ce  para mudar do cursor até o fim de uma palavra, c$ para
      mudar até o fim da linha.
 
   4. O formato para uma operação change é:
@@ -484,14 +487,14 @@ Agora v
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-            Lição 4.1: LOCALIZAÇÃO DO CURSOR E STATUS DO ARQUIVO
+            Lição 4.1: LOCALIZAÇÃO DO CURSOR E ESTADO DO ARQUIVO
 
-    ** Digite CTRL-G para mostrar sua localização no arquivo e seu status.
+    ** Digite CTRL-G para mostrar sua localização no arquivo e seu estado.
        Digite  G  para mover para uma linha do arquivo.  **
 
   Nota: Leia esta lição inteira antes de executar qualquer um dos passos!!
 
-  1. Segure pressionada a tecla Ctrl e pressione  g . Nós chamamos isso de
+  1. Segure pressionada a tecla Ctrl e pressione  g . Chamamos isso de
      CTRL-G. Uma mensagem aparecerá no rodapé da página com o nome do arquivo
      e a sua posição no arquivo. Lembre-se do número da linha para o Passo 3.
 
@@ -499,54 +502,55 @@ NOTA:  A posi
        tela. Isso acontece quando a opção 'ruler' está ativa
        (veja  :help 'ruler' ).
 
-  2. Pressione  G  para mover para o final do arquivo.
-     Digite  gg  para mover para o início do arquivo.
+  2. Pressione  G  para se mover até o fim do arquivo.
+     Digite  gg  para se mover até o início do arquivo.
 
-  3. Digite o número da linha em que você estava e então G . Isto
-     retornará o cursor à linha em que você estava quando pressionou CTRL-G.
+  3. Digite o número da linha em que estava e então G . Assim o cursor retornará
+     à linha em que estava quando pressionou CTRL-G.
 
-  4. Se você estiver confiante para fazer isto, execute os passos 1 ao 3.
+  4. Se estiver seguro para fazê-los, execute os passos 1 a 3.
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                       Lição 4.2: O COMANDO SEARCH (PROCURA)
+                       Lição 4.2: O COMANDO BUSCAR
 
-      ** Digite  /  seguido por uma string para procurar pela string. **
+      ** Digite  /  seguido por uma frase para procurar por ela. **
 
   1. No modo Normal digite o caractere  / . Note que ele e o cursor aparecem
      no rodapé da tela, como ocorre com o comando  : .
 
-  2. Agora digite 'errroo' <ENTER>. Esta é a palavra que você quer procurar.
+  2. Agora digite 'errroo' <ENTER>. Esta é a palavra que quer procurar.
 
-  3. Para procurar pela mesma palavra de novo, simplesmente tecle  n .
-     Para procurar pela mesma palavra na direção oposta, tecle  N .
+  3. Para buscar a mesma palavra de novo, simplesmente tecle  n .
+     Para buscar a mesma palavra na direção oposta, tecle  N .
 
-  4. Se você quer procurar por uma string no sentido de frente para trás, use
-     ?  em vez de  / .
+  4. Se quer procurar por uma frase de trás para frente, use  ?  em vez de  /  .
 
-  5. Para voltar para onde estava, pressione CTRL-O (mantenha a tecla Ctrl
-     pressionada e pressione a tecla o). Repita para voltar outras posições.
+  5. Para voltar aonde estava, pressione CTRL-O (mantenha a tecla Ctrl
+     pressionada e pressione a tecla o). Repita para voltar outras posições.
      CTRL-I segue para posições mais recentes.
 
 --->  "errroo" não é uma maneira de escrever erro;  errroo é um erro.
-NOTA: Quando a busca atinge o final do arquivo ela continuará do começo, a
+
+NOTA: Quando a busca atinge o fim do arquivo ela continuará do começo, a
       menos que a opção 'wrapscan' esteja desativada.
+
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-               Lição 4.3: PROCURA POR CASAMENTO DE PARÊNTESES
+               Lição 4.3: BUSCA DE PARÊNTESES CORRESPONDENTES
 
-          ** Digite  %  para achar um casamento de ),], ou } . **
+         ** Digite  %  para encontrar um ),], ou } correspondente. **
 
 
   1. Posicione o cursor em qualquer (, [, ou { na linha abaixo marcada com --->.
   
   2. Agora digite o caractere  % .
   
-  3. O cursor deve estar no parênteses ou colchetes que casa com o primeiro.
+  3. O cursor deve estar no parêntese ou colchete que casa com o primeiro.
 
-  4. Digite  %  para mover o cursor de volta ao primeiro colchete ou parênteses
+  4. Digite  %  para mover o cursor de volta ao primeiro colchete ou parêntese
      (por casamento).
 
----> Isto ( é uma linha de teste contendo ('s, ['s ] e {'s }. ))
+---> Isto ( é uma linha de teste contendo (, [ ] e { }. ))
 
-Nota: Isso é muito útil para corrigir um programa com parênteses não-casados!
+Nota: Isso é muito útil para corrigir um programa com parêntese não-casado!
 
 
 
@@ -572,14 +576,17 @@ Nota: Isso 
      digite  :#,#s/velho/novo/g   onde #,# são os números das duas linhas.
      Digite  :%s/velho/novo/g     para mudar todas as ocorrências no arquivo
                                   inteiro.
-     Digite  :%s/velho/novo/gc    para mudar todas as ocorrência no arquivo
+     Digite  :%s/velho/novo/gc    para mudar todas as ocorrências no arquivo
                                   inteiro, com a opção de confirmar cada
                                  substituição.
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                              SUMÁRIO DA LIÇÃO 4
-  1.    CTRL-G  mostra a sua localização no arquivo e o status do mesmo.
-             G  move para o final do arquivo.
-     número  G  move para esta linha com esse número.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                              RESUMO DA LIÇÃO 4
+
+
+  1.    CTRL-G  mostra em que ponto do arquivo está e o estado dele.
+             G  move para o fim do arquivo.
+     número  G  move para a linha com esse número.
             gg  move para a primeira linha.
 
   2. Digitando  /  seguido por uma expressão procura À FRENTE por ela.
@@ -594,31 +601,32 @@ Nota: Isso 
 
   4. Para substituir:
        o primeiro 'velho' de uma linha por 'novo' digite   :s/velho/novo
-       todos os 'velho's em uma linha por 'novo' digite    :s/velho/novo/g
+       todos os 'velho' em uma linha por 'novo' digite     :s/velho/novo/g
        expressões entre dois números (#) de linhas digite  :#,#s/velho/novo
        todas as ocorrências no arquivo digite              :%s/velho/novo/g
      Para confirmar cada substituição adicione 'c'         :%s/velho/novo/gc
+
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                 Lição 5.1: COMO EXECUTAR UM COMANDO EXTERNO
 
 
** Digite  :!  seguido por um comando externo para executar esse comando. **
      ** Digite  :!  seguido por um comando externo para executá-lo. **
 
   1. Digite o familiar comando  :  para levar o cursor ao rodapé da tela. Isso
-     lhe permite entrar um comando.
+     o permite entrar um comando.
 
-  2. Agora digite o caractere  !  (ponto de exclamação). Isso lhe permite
+  2. Agora digite o caractere  !  (ponto de exclamação). Isso o permite
      executar qualquer comando do shell.
 
   3. Como um exemplo digite  ls  seguindo o  !  e então tecle <ENTER>. Isto
-     irá mostrar uma listagem do seu diretório, como se você estivesse no
+     mostrará uma listagem do seu diretório, como se você estivesse no
      prompt do shell. Ou use  :!dir se ls não funcionar.
 
 NOTA:  É possível executar qualquer comando externo dessa maneira, inclusive
        com argumentos.
 
 NOTA:  Todos os comandos  :  devem ser finalizados teclando-se <ENTER>
-       Daqui em diante não iremos mencionar isso sempre.
+       Daqui em diante não mencionaremos isso todas as vezes.
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -635,19 +643,19 @@ NOTA:  Todos os comandos  :  devem ser finalizados teclando-se <ENTER>
   3. Agora digite:   :w TESTE  (onde TESTE é o nome que você escolheu.)
 
   4. Isto salva o arquivo inteiro  (o Vim Tutor) com o nome TESTE.
-     Para verificar isso, digite  :!ls de novo para ver seu diretório
+     Para verificar isso, digite  :!ls de novo para ver seu diretório.
 
-NOTA: Se você sair do Vim e entrar de novo com o nome do arquivo TESTE,
-      o arquivo deve ser uma cópia exata do tutor quando você o salvou.
+NOTA: Se sair do Vim e entrar de novo com o nome do arquivo TESTE,
+      o arquivo deve ser uma cópia exata do tutorial quando você o salvou.
 
   5. Agora remova o arquivo digitando (MS-DOS):     :!del TESTE
                                    ou (Unix):       :!rm TESTE
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                Lição 5.3: SELECIONANDO O TEXTO A SER SALVO
+                Lição 5.3: SELECIONAR O TEXTO A SER SALVO
 
-  ** Para salvar parte de um arquivo, digite  v  movimento NOMEDOARQUIVO **
+  ** Para salvar parte de um arquivo, digite  v  movimento  :w NOMEDOARQUIVO **
 
   1. Mova o cursor para esta linha.
 
@@ -658,24 +666,24 @@ NOTA: Se voc
      da tela.
 
   4. Digite  w TESTE , sendo TESTE um nome de arquivo que não existe ainda.
-     Você deverá ver  :'<,'>w TESTE  antes de pressionar <ENTER>.
+     Certifique-se de ver  :'<,'>w TESTE  antes de pressionar <ENTER>.
 
   5. O Vim salvará as linhas selecionadas no arquivo TESTE. Use  :!dir  ou
-     !:ls para vê-lo. Não o apague agora! Nós o usaremos na próxima lição.
+     !:ls para vê-lo. Não o apague ainda! Nós o usaremos na próxima lição.
 
-NOTA:  Pressionando  v  inicia o modo Visual de seleção.  Você pode mover o
+NOTA:  Pressionar  v  inicia o modo Visual de seleção.  Você pode mover o
 cursor pela tela para tornar a seleção maior ou menor. Pode, então, usar um
-operador para executar alguma ação. Por exemplo,  d  deleta o texto.
+operador para executar alguma ação. Por exemplo,  d  apaga o texto.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                 Lição 5.4: RECUPERANDO E JUNTANDO ARQUIVOS
+                 Lição 5.4: RECUPERAR E UNIR ARQUIVOS
 
     ** Para inserir o conteúdo de um arquivo, digite  :r NOMEDOARQUIVO **
 
 
   1. Posicione o cursor logo acima desta linha.
 
-NOTA:  Depois de executar o Passo 2 você verá a lição 5.3. Então DESÇA o
+NOTA:  Depois de executar o Passo 2 você verá a Lição 5.3. Então DESÇA o
        cursor para ver esta lição novamente.
 
   2. Agora recupere o arquivo TESTE usando o comando  :r TESTE  onde TESTE é o
@@ -691,7 +699,7 @@ NOTA: Voc
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                             SUMÁRIO DA LIÇÃO 5 
+                             RESUMO DA LIÇÃO 5 
 
 
   1.  :!comando  executa um comando externo.
@@ -714,15 +722,15 @@ NOTA: Voc
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                        Lição 6.1: O COMANDO OPEN (ABRIR)
+                        Lição 6.1: O COMANDO ABRIR
 
-   ** Digite  o  para abrir uma linha embaixo do cursor e ir para o modo de
-      Inserção (INSERT). **
+   ** Digite  o  para abrir uma linha em baixo do cursor e ir para o modo de
+      Inserção. ** 
 
   1. Mova o cursor para a linha abaixo marcada com --->.
 
-  2. Digite  o (minúsculo) para abrir uma linha ABAIXO do cursor e ir para o
-     modo de Inserção (INSERT).
+  2. Digite  o  (minúsculo) para abrir uma linha ABAIXO do cursor e ir para o
+     modo de Inserção
 
   3. Agora digite algum texto e pressione <ESC> para sair do modo de
      Inserção.
@@ -737,7 +745,7 @@ NOTA: Voc
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                        Lição 6.2: O COMANDO APPEND
+                              Lição 6.2: O COMANDO ADICIONAR
 
            ** Digite  a  para inserir texto DEPOIS do cursor. **
 
@@ -754,13 +762,13 @@ NOTA: Voc
   5. Use  e  para mover para a próxima palavra incompleta  repita os passos 3
      e 4.
 
----> Esta lin lhe permite pratic a adiç de texto a uma linha.
----> Esta linha lhe permite praticar a adição de texto a uma linha.
+---> Esta lin o permite pratic a adiç de texto a uma linha.
+---> Esta linha o permite praticar a adição de texto a uma linha.
 
 NOTA: a, i e A levam ao mesmo modo de Inserção, a única diferença é onde os
       caracteres são inseridos.
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-            Lição 6.3: UMA OUTRA VERSÃO DO REPLACE (SUBSTITUIR)
+                Lição 6.3: UMA OUTRA VERSÃO DO SUBSTITUIR
 
       ** Digite um R maiúsculo para substituir mais de um caractere. **
 
@@ -772,7 +780,7 @@ NOTA: a, i e A levam ao mesmo modo de Inser
      linha, para substituir o  xxx .
 
   3. Pressione <ESC> para sair do modo de Substituição. Note que o resto da
-     linha permanece inalterada.
+     linha permanece inalterado.
 
   4. Repita os passos para substituir os  xxx  restantes.
 
@@ -780,48 +788,53 @@ NOTA: a, i e A levam ao mesmo modo de Inser
 --->  Adicionando 123 a 456 resulta em 579.
 
 NOTA:  O modo de Substituição é como o modo de Inserção, mas cada caractere
-       digitado deleta um caractere existente.
+       digitado apaga um caractere existente.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                       Lição 6.4: COPIAR E COLAR TEXTO
 
        ** Use o operador  y  para copiar texto e  p  para colá-lo. **
 
-   1. Vá para a linha marcada com ---> abaixo e posicione o cursor após "a)".
+   1. Vá à linha marcada com ---> abaixo e posicione o cursor após "a)".
 
    2. Inicie o modo Visual com  v  e mova o cursor para logo antes de
       "primeiro".
 
    3. Digite  y  para copiar o texto selecionado.
 
-   4. Mova o cursor para o final da próxima linha:  j$
+   4. Mova o cursor para o fim da próxima linha:  j$
 
-   5. Digite  p  par pôr (colar) o texto. Então, digite:  o segundo <ESC> .
+   5. Digite  p  para colar o texto. Então, digite:  o segundo <ESC> .
 
    6. Use o modo Visual para selecionar  " item.", copie-o com  y , mova para
-      o fina da próxima linha com  j$  e ponha (cole) o texto com  p .
+      o fim da próxima linha com  j$  e cole o texto com  p .
 
 --->  a) esse é o primeiro item.
       b)
+
 NOTA:  Você também pode usar  y  como um operador; por exemplo, yw copia uma
        palavra.
+
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                      Lição 6.5: CONFIGURAR PREFERÊNCIAS
 
-      ** Configurar uma preferência de modo que um search ou substitute
-        ignora se as letras estão em maiúsculas ou minúsculas. **
+      ** Configure uma preferência de modo que uma busca ou substituição
+        ignore se as letras são maiúsculas ou minúsculas. **
 
-  1. Procure por 'ignore' entrando:  /ignore <ENTER>
+  1. Procure por 'ignore' entrando:   /ignore <ENTER>
      Repita várias vezes teclando  n .
-  2. Configure a opção 'ic' (Ignore case) digitando:
-     :set ic
+
+  2. Configure a opção 'ic' (Ignore case) digitando:  :set ic
+  
   3. Agora procure por 'ignore' de novo teclando: n
      Repita várias vezes.
-  4. Configure as opções 'hlsearch' e 'incsearch':
-     :set hls is
-  5. Agora entre com o comando search de novo, e veja o que acontece:
+  
+  4. Configure as opções 'hlsearch' e 'incsearch':  :set hls is
+  
+  5. Agora entre com o comando buscar de novo, e veja o que acontece:
      /ignore
-  6. Para desabilitar a desconsideração de maiúsculas e minúsculas:
+  
+  6. Para desabilitar a diferenciação entre maiúsculas e minúsculas:
      :set noic
 
 NOTA:  Para remover o realce dos termos localizados entre:  :nohlsearch
@@ -829,32 +842,35 @@ NOTA:  Se quiser ignorar a diferen
        uma pesquisa, use  \c  no comando:  /ignore\c <ENTER>
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                             SUMÁRIO DA LIÇÃO 6
+                             RESUMO DA LIÇÃO 6
 
   1. Digite  o  para abrir uma linha ABAIXO do cursor e iniciar o modo de
      Inserção.
      Digite  O  para abrir uma linha ACIMA da linha onde o cursor está.
 
   2. Digite  a  para adicionar texto DEPOIS do caractere onde está o cursor.
-     Digite  A  para adicionar texto ao final da linha.
+     Digite  A  para adicionar texto ao fim da linha.
 
-  3. O comando  e  move o cursor para o final de uma palavra.
+  3. O comando  e  move o cursor para o fim de uma palavra.
 
-  4. O operador  y  copia texto,  p  põe (cola) o texto copiado.
+  4. O operador  y  copia texto,  p  cola o texto copiado.
 
   5. Digitando  R  entra-se no modo de Substituição até que <ESC> seja
      pressionado.
 
   6. Digitando  ":set xxx" modifica-se a opção "xxx". Algumas opções são:
-         'ic' 'ignorecase'     ignora diferença entre maiúsculas/minúsculas
-        'is' 'incsearch'      realiza a busca enquanto se digita
+         'ic'  'ignorecase'    ignora diferença entre maiúsculas/minúsculas
+        'is'  'incsearch'     realiza a busca enquanto se digita
         'hls' 'hlsearch'      realça todos os trechos localizados
      Você tanto pode usar o nome curto quanto o nome longo da opção.
+
   7. Adicione o prefixo "no" para desabilitar uma opção:  :set noic
+
+
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                           LIÇÃO 7.1: OBTENDO AJUDA
 
-                ** Usar o sistema de ajuda do próprio Vim **
+                ** Use o sistema de ajuda do próprio Vim **
 
   O Vim possui sistema de ajuda abrangente. Para começar, tente algum
   desses três:
@@ -863,11 +879,11 @@ NOTA:  Se quiser ignorar a diferen
         - digite      :help <ENTER>
 
   Leia o texto da ajuda para aprender como o sistema de ajuda funciona.
-  Digite  CTRL-W CTRL-W  para pular de uma janela para outra.
-  Digite  :q <ENTER> para fechar a janela da ajuda.
+  Digite  CTRL-W CTRL-W  para pular de uma janela a outra.
+  Digite  :q <ENTER>     para fechar a janela da ajuda.
 
-  Você pode achar ajuda sobre qualquer assunto, fornecendo um argumento para
-  o comando ":help". Tente isto (não esqueça de pressionar <ENTER>):
+  Você pode encontrar ajuda sobre qualquer assunto, fornecendo um argumento 
+  para o comando ":help". Tente isto (não se esqueça de pressionar <ENTER>):
 
        :help w
        :help c_CTRL-D
@@ -877,7 +893,7 @@ NOTA:  Se quiser ignorar a diferen
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                 Lição 7.2: CRIAR UM SCRIPT DE INICIALIZAÇÃO
 
-                      ** Habilitar recursos do Vim **
+                      ** Habilite recursos do Vim **
 
   O Vim tem muito mais recursos do que o Vi, mas na sua maioria eles são
   desabilitados por padrão.  Para usar mais recursos, você tem que criar um
@@ -893,7 +909,7 @@ NOTA:  Se quiser ignorar a diferen
   3. Salve o arquivo com:
          :w
 
-  Da próxima vez que o Vim for iniciado, ele irá usar realce de sintaxe. Você
+  Da próxima vez que o Vim for iniciado, ele usará realce de sintaxe. Você
   pode adicionar suas configurações preferidas para esse arquivo "vimrc". Para
   maiores informações, digite:  :help vimrc-intro
 
@@ -904,39 +920,40 @@ NOTA:  Se quiser ignorar a diferen
 
    1. Certifique-se de que o Vim não está no modo compatível:  :set nocp
 
-   2. Olhe quais arquivos existem no diretório:  :!ls  ou  :!dir
+   2. Veja quais arquivos existem no diretório:  :!ls  ou  :!dir
 
    3. Digite o início de um comando:  :e
 
-   4. Pressione  CTRL-D  e o Vim irá mostrar a lista dos comandos iniciados
+   4. Pressione  CTRL-D  e o Vim mostrará a lista dos comandos iniciados
       com "e".
 
-   5. Pressione  <TAB>  e o Vim irá completar o nome do comando para ":edit".
+   5. Pressione  <TAB>  e o Vim completará o nome do comando para ":edit".
 
    6. Agora, adicione um espaço e o início do nome de um arquivo existente:
       :edit ARQ
 
-   7. Pressione <TAB>.  O Vim irá completar o nome (se ele for único).
+   7. Pressione <TAB>.  O Vim completará o nome (se ele for único).
 
 NOTA:  A completação funciona com muitos comandos. Basta pressionar CTRL-D e
 <TAB>. Isso é especialmente útil para  :help .
+
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                             SUMÁRIO DA LIÇÃO 7
+                             RESUMO DA LIÇÃO 7
 
 
   1. Digite  :help ou pressione <F1> ou <Help>  para abrir a janela de ajuda.
 
   2. Digite  :help cmd  para achar a ajuda sobre  cmd .
 
-  3. Digite  CTRL-W CTRL-W  para pular de uma janela para outra.
+  3. Digite  CTRL-W CTRL-W  para pular de uma janela a outra.
 
   4. Digite  :q  para fechar a janela de ajuda.
 
   5. Crie um script de inicialização vimrc para ativar automaticamente as suas
      configurações preferidas.
 
-  6. Quando pressionando um comando  : , pressione CTRL-D para ver as
-     possibilidade de completação.
+  6. Quando pressionar um comando  : , pressione CTRL-D para ver as possibilidades 
+  de completação. Pressione <TAB> para usá-la.
 
 
 
@@ -944,8 +961,8 @@ NOTA:  A completa
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-  Isto conclui o Vim tutor. Ele pretendeu dar uma breve apresentação do editor
-  Vim, somente o bastante para que você possa usar o editor com facilidade.
+  Isto conclui o tutorial do Vim, uma breve apresentação do editor Vim,
+  somente o bastante para que você possa usar o editor com facilidade.
   Ele está longe de ser completo, uma vez que o Vim possui muitos, muitos mais
   comandos. O próximo passo é ler o manual:  ":help user-manual".
 
@@ -979,6 +996,9 @@ NOTA:  A completa
   Revisão e atualização da tradução para a versão 1.7 por Jakson Aquino,
   Universidade Federal do Ceará: E-mail: jalvesaq@gmail.com
 
-  Last Change: 2010 Jul 27
+  Nova revisão e atualização para a versão 1.8 por Roní Gonçalves,
+  Universidade Federal de Uberlândia.
+
+  Last Change: 2017 Feb 11
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index 1309404..4756861 100644 (file)
@@ -1,36 +1,36 @@
 ===============================================================================
-=      B e m   V i n d o   a o   V I M   T u t o r   -   Versão 1.7 pt_BR     =
+=    B e m - v i n d o  ao  t u t o r i a l  do  V I M  -  Versão 1.8 pt_BR   =
 ===============================================================================
 
      Vim é um poderoso editor que possui muitos comandos, tantos que seria
-     impossível ensinar num tutorial como este. Este tutorial é planejado para
-     apresentar os comandos suficientes para você ficar habilitado a usar
-     facilmente o Vim como um editor de textos genérico.
+     impossível ensiná-los num tutorial como este, que é concebido para
+     apresentar os comandos suficientes para permiti-lo usar facilmente o
+     Vim como um editor de textos genérico.
 
-     O tempo aproximado requerido para completar o tutorial é de 25-30 minutos,
+     O tempo necessário para completar o tutorial é de cerca de 25-30 minutos,
      dependendo de quanto tempo é gasto praticando os comandos.
 
      ATENÇÃO:
-     Os comandos nas lições vão modificar o texto. Utilize uma cópia deste
-     arquivo para praticar os comandos (se você iniciou o "vimtutor", esta já
+     Os comandos nas lições modificam este texto. Faça uma cópia deste
+     arquivo para praticar os comandos (se usou o "vimtutor", esta já
      é uma cópia).
 
-     É importante lembrar que este tutorial é planejado para ensinar através da
+     É importante lembrar que este tutorial é concebido para ensinar pela
      prática. Isso significa que você precisa executar os comandos para 
      aprendê-los adequadamente. Se você somente ler o texto, esquecerá os
      comandos!
 
      Agora, certifique-se de que sua tecla Shift-Lock (ou Caps Lock) não esteja
      ativada e pressione a tecla  j  o bastante para mover o cursor até que a
-     Lição 1.1 esteja completamente na tela.
+     Lição 1.1 apareça inteiramente na tela.
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                        Lição 1.1:  MOVENDO O CURSOR
+                        Lição 1.1:  MOVER O CURSOR
 
 
   ** Para mover o cursor, pressione as teclas h,j,k,l conforme indicado. **
              ^
-             k          Dica: A tecla h está à esquerda e move para a esquerda.
-       < h       l >          A tecla l está à direita e move para a direita.
+             k          Dica: A tecla h está à esquerda e move à esquerda.
+       < h       l >          A tecla l está à direita e move à direita.
              j                A tecla j se parece com uma seta para baixo.
              v
   1. Mova o cursor pela tela até que você se sinta confortável.
   2. Segure pressionada a tecla (j) até haver repetição.
      Agora você já sabe como ir para a próxima lição.
 
-  3. Usando a tecla j, mova até a lição 1.2.
+  3. Usando a tecla j, vá para a Lição 1.2.
 
-NOTA: Se você está inseguro sobre o que digitou, pressione <ESC> para 
-      colocá-lo no modo Normal. Então redigite o comando que você queria.
+NOTA: Se está inseguro sobre o que digitou, pressione <ESC> para 
+      colocá-lo no modo Normal. Então redigite o comando que queria.
 
-NOTA: As teclas de cursor devem funcionar também. Mas usando hjkl, tão logo
+NOTA: As teclas de cursor funcionam também. Mas usando hjkl, tão logo
       esteja acostumado, você poderá se mover muito mais rapidamente.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                          Lição 1.2: SAINDO DO VIM
+                          Lição 1.2: SAIR DO VIM
 
 
- !! NOTA: Antes de executar qualquer dos passos abaixo, leia a lição inteira !!
+ !! NOTA: Antes de executar quaisquer dos passos abaixo, leia a lição inteira !!
 
   1. Pressione <ESC> (para ter certeza de que está no modo Normal).
 
-  2. Digite    :q! <ENTER>.
-     Isso sai do editor SEM salvar qualquer mudança que tenha sido feita.
-     Se quiser salvar as alterações e sair, digite     :wq <ENTER>
+  2. Digite:    :q! <ENTER>.
+     Assim, sai do editor SEM salvar qualquer mudança feita.
 
-  3. Repita o procedimento que lhe trouxe a este tutorial. O procedimento pode
+  3. Repita o procedimento que o trouxe a este tutorial. O procedimento pode
      ter sido a digitação de:  vimtutor <ENTER>.
 
-  4. Se você memorizou estes passos e está confiante, execute os passos de
+  4. Se memorizou estes passos e está confiante, execute os passos de
      1 a 3 para sair e reentrar no editor.
 
 NOTA:  :q! <ENTER>  descarta qualquer mudança. Em uma próxima lição será
@@ -70,9 +69,9 @@ NOTA:  :q! <ENTER>  descarta qualquer mudança. Em uma próxima lição será
   5. Desça o cursor até a Lição 1.3.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                    Lição 1.3: EDITANDO TEXTOS - DELEÇÃO
+                    Lição 1.3: EDITAR TEXTOS - REMOÇÃO
 
-  ** No modo Normal, pressione  x  para deletar o caractere sob o cursor. **
+  ** Pressione  x  para deletar o caractere sob o cursor. **
 
 
   1. Mova o cursor para a linha abaixo marcada com --->.
@@ -80,47 +79,47 @@ NOTA:  :q! <ENTER>  descarta qualquer mudança. Em uma próxima lição será
   2. Para corrigir os erros, mova o cursor até que ele esteja sobre o 
      caractere a ser deletado.
 
-  3. Pressione a tecla  x  para deletar o caractere indesejado.
+  3. Pressione a tecla  x  para remover o caractere incorreto.
 
-  4. Repita os passos 2 até 4 até que a sentença esteja correta.
+  4. Repita os passos 2 até 4 até que a frase esteja correta.
 
 ---> A vvaca pullouu por ccimaa dda luuua.
 
-  5. Agora que a sentença está correta, vá para a Lição 1.4.
+  5. Agora que a frase está correta, prossiga para a Lição 1.4.
 
 NOTA: Enquanto segue este tutorial, não tente memorizar, aprenda pelo uso.
 
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                   Lição 1.4: EDITANDO TEXTOS - INSERÇÃO
+                   Lição 1.4: EDITAR TEXTOS - INSERÇÃO
 
                   ** Pressione  i  para inserir texto. **
 
 
   1. Mova o cursor até a primeira linha abaixo marcada com --->.
 
-  2. Para fazer a primeira linha ficar igual à segunda, mova o cursor para
+  2. Para deixar a primeira linha igual à segunda, mova o cursor para
      o primeiro caractere DEPOIS de onde o texto deverá ser inserido.
 
   3. Pressione  i  e digite as adições necessárias.
 
   4. Assim que cada erro for corrigido pressione <ESC> para retornar ao modo
-     Normal. Repita os passos 2 até 4 para corrigir a sentença.
+     Normal. Repita os passos 2 até 4 para corrigir a frase.
 
----> Tem text fatado desta .
----> Tem algum texto faltando desta linha.
+---> Tem text fatado nesta .
+---> Tem algum texto faltando nesta linha.
 
-  5. Quando se sentir confortável com a inserção de texto, mova o cursor para
-     a lição 1.5.
+  5. Quando se sentir à vontade com a inserção de texto, mova o cursor para
+     a Lição 1.5.
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                  Lição 1.5: EDITANDO TEXTO - ADICIONANDO
+                  Lição 1.5: EDITAR TEXTO - ADICIONAR
 
                  ** Pressione  A  para adicionar texto. **
 
-  1. Mova o curso para a primeira linha abaixo marcada com --->.
+  1. Mova o cursor para a primeira linha abaixo marcada com --->.
      Não importa sobre qual caractere o cursor estará na linha.
 
   2. Pressione  A  e digite as adições necessárias.
@@ -128,41 +127,41 @@ NOTA: Enquanto segue este tutorial, não tente memorizar, aprenda pelo uso.
   3. Quando adicionar o texto, pressione <ESC> para retornar ao modo Normal.
 
   4. Mova o cursor para a segunda linha marcada ---> e repita os passos 2 e 3
-     para corrigir o texto.
+     para corrigir a frase.
 
----> Há algum texto faltando des
-     Há algum texto faltando desta linha.
+---> Há algum texto faltando nes
+     Há algum texto faltando nesta linha.
      Há algum texto faltan
 ---> Há algum texto faltando aqui.
 
-  5. Quando se sentir confortável adicionando texto, mova para a lição 1.6.
+  5. Quando se sentir confortável adicionando texto, vá para a Lição 1.6.
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                       Lição 1.6: EDITANDO UM ARQUIVO
+                       Lição 1.6: EDITAR UM ARQUIVO
+
                ** Use  :wq  para salvar um arquivo e sair. **
 
-         !! NOTA: Antes de executar qualquer um dos passos abaixo,
-                      leia esta lição completamente!!
+  !! NOTA: Leia toda a lição antes de executar as instruções!!
 
   1. Saia deste tutorial como o fez na lição 1.2:  :q!
      Ou, se tiver acesso a outro terminal, faça o seguinte nele.
 
   2. No prompt do shell, digite esse comando:  vim tutor <ENTER>
-     'vim' is é comando para iniciar o editor Vim e 'tutor' é o nome do
-     arquivo que você deseja editar.  Use um arquivo que possa ser modificado.
+     'vim' é o comando para iniciar o editor Vim e 'tutor' é o nome do
+     arquivo que você quer editar.  Use um arquivo que possa ser modificado.
 
-  3. Insira e delete texto tal como aprendeu com as lições anteriores.
+  3. Insira e apague texto tal como aprendeu nas lições anteriores.
 
   4. Salve o arquivo com as mudanças e saia do Vim com:  :wq <ENTER>
 
-  5. Se você tiver saído do vimtutor no passo 1, reinicie o vimtutor e vá para
-     o sumário seguinte.
+  5. Se tiver saído do vimtutor no passo 1, reinicie o vimtutor e vá para
+     o resumo seguinte.
 
   6. Após ler os passos acima e compreendê-los, execute-os.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                             SUMÁRIO DA LIÇÃO 1
+                             RESUMO DA LIÇÃO 1
 
   1. O cursor é movido usando tanto as teclas de seta quanto as teclas hjkl.
        h (esquerda)    j (para baixo)  k (para cima)   l (direita)
@@ -185,9 +184,9 @@ NOTA: Pressionando <ESC> você irá para o modo Normal ou cancelará um comando
 Agora continue com a Lição 2.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                       Lição 2.1: COMANDOS DE DELEÇÃO
+                       Lição 2.1: COMANDOS DE REMOÇÃO 
 
-         ** Digite  dw  para deletar até o final de uma palavra. **
+                 ** Digite  dw  para apagar uma palavra. **
 
 
   1. Pressione  <ESC>  para ter certeza de que está no modo Normal.
@@ -198,19 +197,19 @@ Agora continue com a Lição 2.
 
   4. Digite  dw  para fazer a palavra desaparecer.
 
-  NOTA: A letra  d  vai aparece na última linha da tela enquanto você a
-       digita. O Vim está lhe esperando digitar um  w . Se você digitou
+  NOTA: A letra  d  vai aparecer na última linha da tela enquanto você a
+       digita. O Vim o está esperando digitar um  w . Se digitou
        alguma coisa errada, pressione <ESC> e comece de novo.
 
----> Tem a algumas oi palavras diversão que não pertencem papel a esta sentença.
+---> Tem a algumas oi palavras diversão que não pertencem papel a esta frase.
 
-  5. Repita os passos 3 ao 4 até que a sentença esteja correta e vá para a
+  5. Repita os passos 3 ao 4 até que a frase esteja correta e vá para a
      Lição 2.2.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                     Lição 2.2: MAIS COMANDOS DE DELEÇÃO
+                     Lição 2.2: MAIS COMANDOS DE REMOÇÃO
 
-          ** Digite  d$  para deletar até o final da linha. **
+             ** Digite  d$  para deletar até o fim da linha. **
 
 
 
@@ -218,13 +217,13 @@ Agora continue com a Lição 2.
 
   2. Mova o cursor até a linha abaixo marcada com --->.
 
-  3. Mova o cursor até o fim da linha correta (DEPOIS do primeiro  .).
+  3. Mova o cursor até o fim da linha correta (DEPOIS do primeiro  . ).
 
-  4. Digite  d$  para deletar até o final da linha.
+  4. Digite  d$  para apagar até o fim da linha.
 
----> Alguém digitou o final desta linha duas vezes. desta linha duas vezes.
+---> Alguém digitou o fim desta linha duas vezes. desta linha duas vezes.
 
-  5. Vá para a lição 2.3 para entender o que está acontecendo.
+  5. Vá para a lição 2.3 para entender o funcionamento deste comando.
 
 
 
@@ -233,30 +232,31 @@ Agora continue com a Lição 2.
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   Lição 2.3: SOBRE OPERADORES E MOVIMENTOS 
 
-  Muitos comandos que mudam texto são feitos de um operador e um movimento.
-  O formato para um comando deletar com o operador de deleção  d  tem a
+  Muitos comandos que mudam texto são feitos de um operador e de um movimento.
+  O formato para um comando apagar com o operador de remoção  d  tem a
   seguinte forma:
 
          d   movimento
+
   Onde:
-    d - é o operador deletar.
-    movimento - é como o operador vai operar (listado abaixo).
+    d - é o operador apagar.
+    movimento - é o movimento sobre o qual o operador age (listado abaixo).
 
   Uma pequena lista de teclas de movimento:
-    w - do cursor até o fim da palavra, incluindo o espaço.
-    e - do cursor até o fim da palavra, NÃO incluindo o espaço.
-    $ - do cursor até o fim da linha.
+    w - até o início da próxima palavra, excluindo seu primeiro caractere.
+    e - até o fim da palavra atual, incluindo seu último caractere.
+    $ - até o fim da linha, incluindo seu último caractere.
 
-  Portanto, digitando  de  irá deletar do cursor ao fim da palavra.
+  Portanto, digitar  de  apaga do cursor ao fim da palavra.
 
-NOTA: Pressionando apenas a tecla de movimento enquanto em modo Normal, sem o
-operador, irá mover o cursor como especificado na lista de teclas de
+NOTA: Pressionar apenas a tecla de movimento em modo Normal, sem o
+operador, faz o cursor se mover como especificado na lista de teclas de
 movimento.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-              Lição 2.4: USANDO UM CONTADOR PARA UM MOVIMENTO
+              Lição 2.4: USAR UM CONTADOR PARA UM MOVIMENTO
 
-    ** Digitando um número antes de um movimento repete-o muitas vezes. **
+   ** Digitar um número antes de um movimento repete-o o tanto de vezes. **
 
 
    1. Mova o cursor para o começo da linha marcada com ---> abaixo.
@@ -269,7 +269,7 @@ movimento.
 
    5. Repita os passos 2 e 3 com diferentes números.
 
----> Esta é uma linha com algumas palavras para lhe permitir fazer movimentos.
+---> Esta é uma linha com algumas palavras para permiti-lo fazer movimentos.
 
    6. Vá para a Lição 2.5.
 
@@ -277,22 +277,22 @@ movimento.
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-              Lição 2.5: USANDO UM CONTADOR PARA DELETAR MAIS
+              Lição 2.5: USAR UM CONTADOR PARA APAGAR MAIS
 
-   ** Digitando um número com um operador repete-o esse número de vezes. **
+   ** Digitar um número com um operador repete-o esse número de vezes. **
 
 
-   Você deve inserir um contador entre o operador de deleção e o movimento
-   mencionados acima para para deletar mais:
+   Você deve inserir um contador entre o operador de remoção e o de movimento
+   mencionados acima para apagar mais:
        d   número   movimento
 
-   1. Movimente o cursor para a primeira palavra com LETRAS MAIÚSCULAS na
+   1. Movimente o cursor para a primeira palavra em LETRAS MAIÚSCULAS na
       linha marcada com --->.
 
-   2. Digite  d2w  para deletar as duas palavras com LETRAS MAIÚSCULAS.
+   2. Digite  d2w  para deletar as duas palavras em LETRAS MAIÚSCULAS.
 
    3. Repita os passos 1 e 2 com diferentes contadores para deletar as
-      palavras de LETRAS MAIÚSCULAS com um comando.
+      palavras em LETRAS MAIÚSCULAS com um comando.
 
 --->  esta ABC DE linha FGHI JK LMN OP de palavras está Q RS TUV limpa.
 
@@ -300,17 +300,17 @@ movimento.
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                      Lição 2.6: OPERANDO SOBRE LINHAS
+                      Lição 2.6: TRABALHAR COM LINHAS
 
-             ** Digite  dd  para deletar uma linha inteira. **
+             ** Digite  dd  para apagar uma linha inteira. **
 
-  Em virtude da frequência em deletar uma linha inteira, os projetistas do Vi
-  decidiram que seria mais simples digitar dois d's numa linha para deletá-la.
+  Em virtude da frequência em deletar uma linha inteira, os desenvolvedores 
+  do Vi decidiram que seria mais simples digitar dois d para apagar uma linha.
 
-  1. Mova o cursor até a segunda linha na lista a baixo.
-  2. Digite  dd  para deletar a linha.
+  1. Mova o cursor até a segunda linha da frase abaixo.
+  2. Digite  dd  para apagar a linha.
   3. Agora mova até a quarta linha.
-  4. Digite  2dd  para deletar duas linhas.
+  4. Digite  2dd  para apagar duas linhas.
 
 --->  1)  Rosas são vermelhas,
 --->  2)  Lama é divertida,
@@ -318,92 +318,94 @@ movimento.
 --->  4)  Eu tenho um carro,
 --->  5)  Relógios dizem as horas,
 --->  6)  Açúcar é doce,
---->  7)  E assim é você.
+--->  7)  Assim como você.
 
 Notas do tradutor: Lama (mud) em inglês pode significar fofoca, difamação.
                    Há rima no texto original.
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                     Lição 2.7: O COMANDO UNDO (DESFAZER)
 
-** Pressione u para desfazer os últimos comandos, U restaura linha inteira.**
+** Pressione u para desfazer os últimos comandos, U recupera a linha inteira.**
 
 
   1. Mova o cursor para a linha abaixo marcada com ---> e posicione-o sobre o
      primeiro erro.
-  2. Digite  x  para deletar o primeiro caractere indesejado.
+  2. Digite  x  para deletar o primeiro caractere errado.
   3. Agora, digite  u  para desfazer o último comando executado.
   4. Desta vez, corrija todos os erros na linha usando o comando  x .
   5. Agora, digite um U maiúsculo para retornar a linha ao seu estado original.
   6. Digite  u  algumas vezes para desfazer o  U  e os comandos anteriores.
   7. Digite CTRL-R (segurando a tecla CTRL enquanto digita R) algumas vezes
-     para refazer os comandos (desfazer os undo's).
+     para refazer os comandos (desfazer os undos).
 
 ---> Corriija os erros nnesta linha e reetorne-os com undo.
 
-  8. Esses comandos são muito úteis. Agora vá para o sumário da Lição 2.
+  8. Esses comandos são muito úteis. Agora vá para o resumo da Lição 2.
 
 
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                             SUMÁRIO DA LIÇÃO 2
+                             RESUMO DA LIÇÃO 2
 
 
-  1. Para deletar do cursor até o fim de uma palavra digite:   dw
-  2. Para deletar do cursor até o fim de uma linha digite:   d$
-  3. Para deletar uma linha inteira digite:   dd
-  4. Para repetir um movimento adicione antes um número:   2w
+  1. Para apagar do cursor até a próxima palavra, digite:   dw
+  2. Para apagar do cursor até o fim de uma linha, digite:  d$
+  3. Para apagar uma linha inteira, digite:   dd
+  4. Para repetir um movimento, adicione antes um número:   2w
   5. O formato para um comando no modo Normal é:
            operador   [número]   movimento
    onde:
-      operador  - é o que será feito, como  d  para deletar
-      número    - é quantas vezes o comando será repetido
-      movimento - movimento sobre o texto que sofrerá a operação, como
-                  w (palavra), $ (até o final da linha), etc.
+      operador  - é o que será feito, como  d  para apagar
+      [número]  - quantas vezes o comando será repetido
+      movimento - movimento sobre o texto que receberá a operação, como
+                  w (palavra), $ (até o fim da linha), etc.
+
+  6. Para ir ao início da linha, use um zero:  0
 
-  5. Para desfazer um ação anterior, digite:                  u  (minúsculo)
-     Para desfazer todas as modificações em uma linha digite: U (maiúsculo)
-     Para desfazer o que foi desfeito digite:                 CTRL-R
+  7. Para desfazer uma ação anterior, digite:                  u (minúsculo)
+     Para desfazer todas as alterações em uma linha, digite:   U (maiúsculo)
+     Para desfazer o que foi desfeito, digite:                 CTRL-R
 
 
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                       Lição 3.1: O COMANDO PUT (PÔR)
+                       Lição 3.1: O COMANDO COLAR
 
-       ** Digite  p  para colocar a última deleção após o cursor. **
+       ** Digite  p  para colar após o cursor o que acabou de apagar. **
 
 
-  1. Mova o cursor até a primeira linha na lista abaixo.
+  1. Mova o cursor até a primeira linha marcada com --->.
 
-  2. Digite  dd  para deletar a linha e guardá-la no buffer do Vim.
+  2. Digite  dd  para apagar a linha e guardá-la num registro do Vim.
 
-  3. Mova o cursor até a linha ACIMA de onde a linha deletada deve ficar.
+  3. Mova o cursor até a linha c) ACIMA de onde a linha apagada deveria estar.
 
   4. No modo Normal, digite  p  para inserir a linha.
 
   5. Repita os passos 2 ao 4 para pôr todas as linhas na ordem correta.
 
-     d) Você pode aprender também?
-     b) Violetas são azuis,
-     c) Inteligência se aprende,
-     a) Rosas são vermelhas,
+---> d) Você pode aprender também?
+---> b) Violetas são azuis,
+---> c) Inteligência se aprende,
+---> a) Rosas são vermelhas,
 
 Nota do tradutor: Há rima no original.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                 Lição 3.2: O COMANDO REPLACE (SUBSTITUIR)
+                      Lição 3.2: O COMANDO SUBSTITUIR
 
      ** Digite  rx  para substituir o caractere sob o cursor por  x . ** 
 
 
   1. Mova o cursor até a primeira linha abaixo marcada com --->.
 
-  2. Mova o cursor até que ele esteja sobre o primeiro erro.
+  2. Mova o cursor até que esteja sobre o primeiro erro.
 
   3. Digite  r  e então o caractere que deveria estar lá.
 
-  4. Repita os passos 2 e 3 até que a primeira linha esteja correta.
+  4. Repita os passos 2 e 3 até que a primeira linha esteja igual à segunda.
 
 ---> Quendo este limha foi dugitada, alguem pressioniu algumas teclas erradzs!
 ---> Quando esta linha foi digitada, alguém pressionou algumas teclas erradas!
@@ -417,42 +419,43 @@ NOTA: Lembre-se que você deve aprender pelo uso, não pela memorização.
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                     Lição 3.3: O OPERADOR CHANGE (MUDAR)
 
-       ** Para mudar toda uma palavra ou parte dela, digite  cw . **
+       ** Para alterar até o fim de uma palavra, digite  ce . **
 
 
   1. Mova o cursor até a primeira linha abaixo marcada com --->.
   
   2. Posicione o cursor sobre o u em lunba.
 
-  3. Digite  cw  e a palavra correta (nesse caso, digite 'inha'.)
+  3. Digite  ce  e a palavra correta (nesse caso, digite 'inha'.)
 
   4. Pressione <ESC> e mova para o próximo caractere a ser alterado.
 
-  5. Repita os passos 3 e 4 até que a primeira sentença esteja igual à segunda.
+  5. Repita os passos 3 e 4 até que a primeira frase esteja igual à segunda.
 
 ---> Essa lunba tem pwlesmfr que ocrimmm  soi alteradas cup o comando change.
 ---> Essa linha tem palavras que precisam ser alteradas com o comando change. 
 
-Note que  cw  não somente substitui a palavra, mas também lhe coloca no modo
-de inserção.
+Note que  ce  não somente substitui a palavra, mas também o coloca no modo
+de Inserção.
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                      Lição 3.4: MAIS MUDANÇAS USANDO c
 
-      ** O operador change é usado com os mesmos objetos que delete. **
+     ** O operador change é usado com os mesmos movimentos que o delete. **
+
 
   1. O operador change trabalha da mesma maneira que o delete. O formato é:
 
           c    [número]    movimento
 
-  2. Os movimentos também são os mesmos: w (palavra), $ (fim da linha), etc.
+  2. Os movimentos também são os mesmos: w (palavra) e $ (fim da linha).
 
   3. Mova até a primeira linha abaixo marcada com --->.
 
   4. Mova o cursor até o primeiro erro.
 
-  5. Digite  c$  para fazer o resto da linha ficar igual à segunda e pressione
+  5. Digite  c$  para tornar o resto da linha igual à segunda e pressione
      <ESC>.
 
 ---> O fim desta linha precisa de ajuda para ficar igual à segunda.
@@ -461,18 +464,18 @@ de inserção.
 NOTA: Você pode usar a tecla Backspace para corrigir erros enquanto digita.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                             SUMÁRIO DA LIÇÃO 3
+                             RESUMO DA LIÇÃO 3
 
 
-  1. Para inserir um texto que já foi deletado, digite  p . Isso coloca o texto
+  1. Para reinserir um texto que já foi apagado, digite  p . Isso coloca o texto
      deletado APÓS o cursor (se uma linha é deletada ela será inserida na linha
      abaixo do cursor).
 
   2. Para substituir o caractere sob o cursor, digite  r  e então o caractere
-     que irá substituir o original.
+     que substituirá o original.
 
   3. O comando change possibilita mudar do cursor até onde o movimento for.
-     Ex: Digite  cw  para mudar do cursor até o fim de uma palavra, c$ para
+     Ex: Digite  ce  para mudar do cursor até o fim de uma palavra, c$ para
      mudar até o fim da linha.
 
   4. O formato para uma operação change é:
@@ -484,14 +487,14 @@ Agora vá para a próxima lição.
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-            Lição 4.1: LOCALIZAÇÃO DO CURSOR E STATUS DO ARQUIVO
+            Lição 4.1: LOCALIZAÇÃO DO CURSOR E ESTADO DO ARQUIVO
 
-    ** Digite CTRL-G para mostrar sua localização no arquivo e seu status.
+    ** Digite CTRL-G para mostrar sua localização no arquivo e seu estado.
        Digite  G  para mover para uma linha do arquivo.  **
 
   Nota: Leia esta lição inteira antes de executar qualquer um dos passos!!
 
-  1. Segure pressionada a tecla Ctrl e pressione  g . Nós chamamos isso de
+  1. Segure pressionada a tecla Ctrl e pressione  g . Chamamos isso de
      CTRL-G. Uma mensagem aparecerá no rodapé da página com o nome do arquivo
      e a sua posição no arquivo. Lembre-se do número da linha para o Passo 3.
 
@@ -499,54 +502,55 @@ NOTA:  A posição do cursor pode estar visível no canto direito inferior da
        tela. Isso acontece quando a opção 'ruler' está ativa
        (veja  :help 'ruler' ).
 
-  2. Pressione  G  para mover para o final do arquivo.
-     Digite  gg  para mover para o início do arquivo.
+  2. Pressione  G  para se mover até o fim do arquivo.
+     Digite  gg  para se mover até o início do arquivo.
 
-  3. Digite o número da linha em que você estava e então G . Isto
-     retornará o cursor à linha em que você estava quando pressionou CTRL-G.
+  3. Digite o número da linha em que estava e então G . Assim o cursor retornará
+     à linha em que estava quando pressionou CTRL-G.
 
-  4. Se você estiver confiante para fazer isto, execute os passos 1 ao 3.
+  4. Se estiver seguro para fazê-los, execute os passos 1 a 3.
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                       Lição 4.2: O COMANDO SEARCH (PROCURA)
+                       Lição 4.2: O COMANDO BUSCAR
 
-      ** Digite  /  seguido por uma string para procurar pela string. **
+      ** Digite  /  seguido por uma frase para procurar por ela. **
 
   1. No modo Normal digite o caractere  / . Note que ele e o cursor aparecem
      no rodapé da tela, como ocorre com o comando  : .
 
-  2. Agora digite 'errroo' <ENTER>. Esta é a palavra que você quer procurar.
+  2. Agora digite 'errroo' <ENTER>. Esta é a palavra que quer procurar.
 
-  3. Para procurar pela mesma palavra de novo, simplesmente tecle  n .
-     Para procurar pela mesma palavra na direção oposta, tecle  N .
+  3. Para buscar a mesma palavra de novo, simplesmente tecle  n .
+     Para buscar a mesma palavra na direção oposta, tecle  N .
 
-  4. Se você quer procurar por uma string no sentido de frente para trás, use
-     ?  em vez de  / .
+  4. Se quer procurar por uma frase de trás para frente, use  ?  em vez de  /  .
 
-  5. Para voltar para onde estava, pressione CTRL-O (mantenha a tecla Ctrl
-     pressionada e pressione a tecla o). Repita para voltar outras posições.
+  5. Para voltar aonde estava, pressione CTRL-O (mantenha a tecla Ctrl
+     pressionada e pressione a tecla o). Repita para voltar outras posições.
      CTRL-I segue para posições mais recentes.
 
 --->  "errroo" não é uma maneira de escrever erro;  errroo é um erro.
-NOTA: Quando a busca atinge o final do arquivo ela continuará do começo, a
+
+NOTA: Quando a busca atinge o fim do arquivo ela continuará do começo, a
       menos que a opção 'wrapscan' esteja desativada.
+
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-               Lição 4.3: PROCURA POR CASAMENTO DE PARÊNTESES
+               Lição 4.3: BUSCA DE PARÊNTESES CORRESPONDENTES
 
-          ** Digite  %  para achar um casamento de ),], ou } . **
+         ** Digite  %  para encontrar um ),], ou } correspondente. **
 
 
   1. Posicione o cursor em qualquer (, [, ou { na linha abaixo marcada com --->.
   
   2. Agora digite o caractere  % .
   
-  3. O cursor deve estar no parênteses ou colchetes que casa com o primeiro.
+  3. O cursor deve estar no parêntese ou colchete que casa com o primeiro.
 
-  4. Digite  %  para mover o cursor de volta ao primeiro colchete ou parênteses
+  4. Digite  %  para mover o cursor de volta ao primeiro colchete ou parêntese
      (por casamento).
 
----> Isto ( é uma linha de teste contendo ('s, ['s ] e {'s }. ))
+---> Isto ( é uma linha de teste contendo (, [ ] e { }. ))
 
-Nota: Isso é muito útil para corrigir um programa com parênteses não-casados!
+Nota: Isso é muito útil para corrigir um programa com parêntese não-casado!
 
 
 
@@ -572,14 +576,17 @@ Nota: Isso é muito útil para corrigir um programa com parênteses não-casados
      digite  :#,#s/velho/novo/g   onde #,# são os números das duas linhas.
      Digite  :%s/velho/novo/g     para mudar todas as ocorrências no arquivo
                                   inteiro.
-     Digite  :%s/velho/novo/gc    para mudar todas as ocorrência no arquivo
+     Digite  :%s/velho/novo/gc    para mudar todas as ocorrências no arquivo
                                   inteiro, com a opção de confirmar cada
                                  substituição.
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                              SUMÁRIO DA LIÇÃO 4
-  1.    CTRL-G  mostra a sua localização no arquivo e o status do mesmo.
-             G  move para o final do arquivo.
-     número  G  move para esta linha com esse número.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                              RESUMO DA LIÇÃO 4
+
+
+  1.    CTRL-G  mostra em que ponto do arquivo está e o estado dele.
+             G  move para o fim do arquivo.
+     número  G  move para a linha com esse número.
             gg  move para a primeira linha.
 
   2. Digitando  /  seguido por uma expressão procura À FRENTE por ela.
@@ -594,31 +601,32 @@ Nota: Isso é muito útil para corrigir um programa com parênteses não-casados
 
   4. Para substituir:
        o primeiro 'velho' de uma linha por 'novo' digite   :s/velho/novo
-       todos os 'velho's em uma linha por 'novo' digite    :s/velho/novo/g
+       todos os 'velho' em uma linha por 'novo' digite     :s/velho/novo/g
        expressões entre dois números (#) de linhas digite  :#,#s/velho/novo
        todas as ocorrências no arquivo digite              :%s/velho/novo/g
      Para confirmar cada substituição adicione 'c'         :%s/velho/novo/gc
+
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                 Lição 5.1: COMO EXECUTAR UM COMANDO EXTERNO
 
 
** Digite  :!  seguido por um comando externo para executar esse comando. **
      ** Digite  :!  seguido por um comando externo para executá-lo. **
 
   1. Digite o familiar comando  :  para levar o cursor ao rodapé da tela. Isso
-     lhe permite entrar um comando.
+     o permite entrar um comando.
 
-  2. Agora digite o caractere  !  (ponto de exclamação). Isso lhe permite
+  2. Agora digite o caractere  !  (ponto de exclamação). Isso o permite
      executar qualquer comando do shell.
 
   3. Como um exemplo digite  ls  seguindo o  !  e então tecle <ENTER>. Isto
-     irá mostrar uma listagem do seu diretório, como se você estivesse no
+     mostrará uma listagem do seu diretório, como se você estivesse no
      prompt do shell. Ou use  :!dir se ls não funcionar.
 
 NOTA:  É possível executar qualquer comando externo dessa maneira, inclusive
        com argumentos.
 
 NOTA:  Todos os comandos  :  devem ser finalizados teclando-se <ENTER>
-       Daqui em diante não iremos mencionar isso sempre.
+       Daqui em diante não mencionaremos isso todas as vezes.
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -635,19 +643,19 @@ NOTA:  Todos os comandos  :  devem ser finalizados teclando-se <ENTER>
   3. Agora digite:   :w TESTE  (onde TESTE é o nome que você escolheu.)
 
   4. Isto salva o arquivo inteiro  (o Vim Tutor) com o nome TESTE.
-     Para verificar isso, digite  :!ls de novo para ver seu diretório
+     Para verificar isso, digite  :!ls de novo para ver seu diretório.
 
-NOTA: Se você sair do Vim e entrar de novo com o nome do arquivo TESTE,
-      o arquivo deve ser uma cópia exata do tutor quando você o salvou.
+NOTA: Se sair do Vim e entrar de novo com o nome do arquivo TESTE,
+      o arquivo deve ser uma cópia exata do tutorial quando você o salvou.
 
   5. Agora remova o arquivo digitando (MS-DOS):     :!del TESTE
                                    ou (Unix):       :!rm TESTE
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                Lição 5.3: SELECIONANDO O TEXTO A SER SALVO
+                Lição 5.3: SELECIONAR O TEXTO A SER SALVO
 
-  ** Para salvar parte de um arquivo, digite  v  movimento NOMEDOARQUIVO **
+  ** Para salvar parte de um arquivo, digite  v  movimento  :w NOMEDOARQUIVO **
 
   1. Mova o cursor para esta linha.
 
@@ -658,24 +666,24 @@ NOTA: Se você sair do Vim e entrar de novo com o nome do arquivo TESTE,
      da tela.
 
   4. Digite  w TESTE , sendo TESTE um nome de arquivo que não existe ainda.
-     Você deverá ver  :'<,'>w TESTE  antes de pressionar <ENTER>.
+     Certifique-se de ver  :'<,'>w TESTE  antes de pressionar <ENTER>.
 
   5. O Vim salvará as linhas selecionadas no arquivo TESTE. Use  :!dir  ou
-     !:ls para vê-lo. Não o apague agora! Nós o usaremos na próxima lição.
+     !:ls para vê-lo. Não o apague ainda! Nós o usaremos na próxima lição.
 
-NOTA:  Pressionando  v  inicia o modo Visual de seleção.  Você pode mover o
+NOTA:  Pressionar  v  inicia o modo Visual de seleção.  Você pode mover o
 cursor pela tela para tornar a seleção maior ou menor. Pode, então, usar um
-operador para executar alguma ação. Por exemplo,  d  deleta o texto.
+operador para executar alguma ação. Por exemplo,  d  apaga o texto.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                 Lição 5.4: RECUPERANDO E JUNTANDO ARQUIVOS
+                 Lição 5.4: RECUPERAR E UNIR ARQUIVOS
 
     ** Para inserir o conteúdo de um arquivo, digite  :r NOMEDOARQUIVO **
 
 
   1. Posicione o cursor logo acima desta linha.
 
-NOTA:  Depois de executar o Passo 2 você verá a lição 5.3. Então DESÇA o
+NOTA:  Depois de executar o Passo 2 você verá a Lição 5.3. Então DESÇA o
        cursor para ver esta lição novamente.
 
   2. Agora recupere o arquivo TESTE usando o comando  :r TESTE  onde TESTE é o
@@ -691,7 +699,7 @@ NOTA: Você também pode ler a saída de um comando externo. Por exemplo,  :r !l
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                             SUMÁRIO DA LIÇÃO 5 
+                             RESUMO DA LIÇÃO 5 
 
 
   1.  :!comando  executa um comando externo.
@@ -714,15 +722,15 @@ NOTA: Você também pode ler a saída de um comando externo. Por exemplo,  :r !l
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                        Lição 6.1: O COMANDO OPEN (ABRIR)
+                        Lição 6.1: O COMANDO ABRIR
 
-   ** Digite  o  para abrir uma linha embaixo do cursor e ir para o modo de
-      Inserção (INSERT). **
+   ** Digite  o  para abrir uma linha em baixo do cursor e ir para o modo de
+      Inserção. ** 
 
   1. Mova o cursor para a linha abaixo marcada com --->.
 
-  2. Digite  o (minúsculo) para abrir uma linha ABAIXO do cursor e ir para o
-     modo de Inserção (INSERT).
+  2. Digite  o  (minúsculo) para abrir uma linha ABAIXO do cursor e ir para o
+     modo de Inserção
 
   3. Agora digite algum texto e pressione <ESC> para sair do modo de
      Inserção.
@@ -737,7 +745,7 @@ NOTA: Você também pode ler a saída de um comando externo. Por exemplo,  :r !l
 
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                        Lição 6.2: O COMANDO APPEND
+                              Lição 6.2: O COMANDO ADICIONAR
 
            ** Digite  a  para inserir texto DEPOIS do cursor. **
 
@@ -754,13 +762,13 @@ NOTA: Você também pode ler a saída de um comando externo. Por exemplo,  :r !l
   5. Use  e  para mover para a próxima palavra incompleta  repita os passos 3
      e 4.
 
----> Esta lin lhe permite pratic a adiç de texto a uma linha.
----> Esta linha lhe permite praticar a adição de texto a uma linha.
+---> Esta lin o permite pratic a adiç de texto a uma linha.
+---> Esta linha o permite praticar a adição de texto a uma linha.
 
 NOTA: a, i e A levam ao mesmo modo de Inserção, a única diferença é onde os
       caracteres são inseridos.
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-            Lição 6.3: UMA OUTRA VERSÃO DO REPLACE (SUBSTITUIR)
+                Lição 6.3: UMA OUTRA VERSÃO DO SUBSTITUIR
 
       ** Digite um R maiúsculo para substituir mais de um caractere. **
 
@@ -772,7 +780,7 @@ NOTA: a, i e A levam ao mesmo modo de Inserção, a única diferença é onde os
      linha, para substituir o  xxx .
 
   3. Pressione <ESC> para sair do modo de Substituição. Note que o resto da
-     linha permanece inalterada.
+     linha permanece inalterado.
 
   4. Repita os passos para substituir os  xxx  restantes.
 
@@ -780,48 +788,53 @@ NOTA: a, i e A levam ao mesmo modo de Inserção, a única diferença é onde os
 --->  Adicionando 123 a 456 resulta em 579.
 
 NOTA:  O modo de Substituição é como o modo de Inserção, mas cada caractere
-       digitado deleta um caractere existente.
+       digitado apaga um caractere existente.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                       Lição 6.4: COPIAR E COLAR TEXTO
 
        ** Use o operador  y  para copiar texto e  p  para colá-lo. **
 
-   1. Vá para a linha marcada com ---> abaixo e posicione o cursor após "a)".
+   1. Vá à linha marcada com ---> abaixo e posicione o cursor após "a)".
 
    2. Inicie o modo Visual com  v  e mova o cursor para logo antes de
       "primeiro".
 
    3. Digite  y  para copiar o texto selecionado.
 
-   4. Mova o cursor para o final da próxima linha:  j$
+   4. Mova o cursor para o fim da próxima linha:  j$
 
-   5. Digite  p  par pôr (colar) o texto. Então, digite:  o segundo <ESC> .
+   5. Digite  p  para colar o texto. Então, digite:  o segundo <ESC> .
 
    6. Use o modo Visual para selecionar  " item.", copie-o com  y , mova para
-      o fina da próxima linha com  j$  e ponha (cole) o texto com  p .
+      o fim da próxima linha com  j$  e cole o texto com  p .
 
 --->  a) esse é o primeiro item.
       b)
+
 NOTA:  Você também pode usar  y  como um operador; por exemplo, yw copia uma
        palavra.
+
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                      Lição 6.5: CONFIGURAR PREFERÊNCIAS
 
-      ** Configurar uma preferência de modo que um search ou substitute
-        ignora se as letras estão em maiúsculas ou minúsculas. **
+      ** Configure uma preferência de modo que uma busca ou substituição
+        ignore se as letras são maiúsculas ou minúsculas. **
 
-  1. Procure por 'ignore' entrando:  /ignore <ENTER>
+  1. Procure por 'ignore' entrando:   /ignore <ENTER>
      Repita várias vezes teclando  n .
-  2. Configure a opção 'ic' (Ignore case) digitando:
-     :set ic
+
+  2. Configure a opção 'ic' (Ignore case) digitando:  :set ic
+  
   3. Agora procure por 'ignore' de novo teclando: n
      Repita várias vezes.
-  4. Configure as opções 'hlsearch' e 'incsearch':
-     :set hls is
-  5. Agora entre com o comando search de novo, e veja o que acontece:
+  
+  4. Configure as opções 'hlsearch' e 'incsearch':  :set hls is
+  
+  5. Agora entre com o comando buscar de novo, e veja o que acontece:
      /ignore
-  6. Para desabilitar a desconsideração de maiúsculas e minúsculas:
+  
+  6. Para desabilitar a diferenciação entre maiúsculas e minúsculas:
      :set noic
 
 NOTA:  Para remover o realce dos termos localizados entre:  :nohlsearch
@@ -829,32 +842,35 @@ NOTA:  Se quiser ignorar a diferença entre maiúsculas e minúsculas em apenas
        uma pesquisa, use  \c  no comando:  /ignore\c <ENTER>
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                             SUMÁRIO DA LIÇÃO 6
+                             RESUMO DA LIÇÃO 6
 
   1. Digite  o  para abrir uma linha ABAIXO do cursor e iniciar o modo de
      Inserção.
      Digite  O  para abrir uma linha ACIMA da linha onde o cursor está.
 
   2. Digite  a  para adicionar texto DEPOIS do caractere onde está o cursor.
-     Digite  A  para adicionar texto ao final da linha.
+     Digite  A  para adicionar texto ao fim da linha.
 
-  3. O comando  e  move o cursor para o final de uma palavra.
+  3. O comando  e  move o cursor para o fim de uma palavra.
 
-  4. O operador  y  copia texto,  p  põe (cola) o texto copiado.
+  4. O operador  y  copia texto,  p  cola o texto copiado.
 
   5. Digitando  R  entra-se no modo de Substituição até que <ESC> seja
      pressionado.
 
   6. Digitando  ":set xxx" modifica-se a opção "xxx". Algumas opções são:
-         'ic' 'ignorecase'     ignora diferença entre maiúsculas/minúsculas
-        'is' 'incsearch'      realiza a busca enquanto se digita
+         'ic'  'ignorecase'    ignora diferença entre maiúsculas/minúsculas
+        'is'  'incsearch'     realiza a busca enquanto se digita
         'hls' 'hlsearch'      realça todos os trechos localizados
      Você tanto pode usar o nome curto quanto o nome longo da opção.
+
   7. Adicione o prefixo "no" para desabilitar uma opção:  :set noic
+
+
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                           LIÇÃO 7.1: OBTENDO AJUDA
 
-                ** Usar o sistema de ajuda do próprio Vim **
+                ** Use o sistema de ajuda do próprio Vim **
 
   O Vim possui sistema de ajuda abrangente. Para começar, tente algum
   desses três:
@@ -863,11 +879,11 @@ NOTA:  Se quiser ignorar a diferença entre maiúsculas e minúsculas em apenas
         - digite      :help <ENTER>
 
   Leia o texto da ajuda para aprender como o sistema de ajuda funciona.
-  Digite  CTRL-W CTRL-W  para pular de uma janela para outra.
-  Digite  :q <ENTER> para fechar a janela da ajuda.
+  Digite  CTRL-W CTRL-W  para pular de uma janela a outra.
+  Digite  :q <ENTER>     para fechar a janela da ajuda.
 
-  Você pode achar ajuda sobre qualquer assunto, fornecendo um argumento para
-  o comando ":help". Tente isto (não esqueça de pressionar <ENTER>):
+  Você pode encontrar ajuda sobre qualquer assunto, fornecendo um argumento 
+  para o comando ":help". Tente isto (não se esqueça de pressionar <ENTER>):
 
        :help w
        :help c_CTRL-D
@@ -877,7 +893,7 @@ NOTA:  Se quiser ignorar a diferença entre maiúsculas e minúsculas em apenas
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                 Lição 7.2: CRIAR UM SCRIPT DE INICIALIZAÇÃO
 
-                      ** Habilitar recursos do Vim **
+                      ** Habilite recursos do Vim **
 
   O Vim tem muito mais recursos do que o Vi, mas na sua maioria eles são
   desabilitados por padrão.  Para usar mais recursos, você tem que criar um
@@ -893,7 +909,7 @@ NOTA:  Se quiser ignorar a diferença entre maiúsculas e minúsculas em apenas
   3. Salve o arquivo com:
          :w
 
-  Da próxima vez que o Vim for iniciado, ele irá usar realce de sintaxe. Você
+  Da próxima vez que o Vim for iniciado, ele usará realce de sintaxe. Você
   pode adicionar suas configurações preferidas para esse arquivo "vimrc". Para
   maiores informações, digite:  :help vimrc-intro
 
@@ -904,39 +920,40 @@ NOTA:  Se quiser ignorar a diferença entre maiúsculas e minúsculas em apenas
 
    1. Certifique-se de que o Vim não está no modo compatível:  :set nocp
 
-   2. Olhe quais arquivos existem no diretório:  :!ls  ou  :!dir
+   2. Veja quais arquivos existem no diretório:  :!ls  ou  :!dir
 
    3. Digite o início de um comando:  :e
 
-   4. Pressione  CTRL-D  e o Vim irá mostrar a lista dos comandos iniciados
+   4. Pressione  CTRL-D  e o Vim mostrará a lista dos comandos iniciados
       com "e".
 
-   5. Pressione  <TAB>  e o Vim irá completar o nome do comando para ":edit".
+   5. Pressione  <TAB>  e o Vim completará o nome do comando para ":edit".
 
    6. Agora, adicione um espaço e o início do nome de um arquivo existente:
       :edit ARQ
 
-   7. Pressione <TAB>.  O Vim irá completar o nome (se ele for único).
+   7. Pressione <TAB>.  O Vim completará o nome (se ele for único).
 
 NOTA:  A completação funciona com muitos comandos. Basta pressionar CTRL-D e
 <TAB>. Isso é especialmente útil para  :help .
+
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                             SUMÁRIO DA LIÇÃO 7
+                             RESUMO DA LIÇÃO 7
 
 
   1. Digite  :help ou pressione <F1> ou <Help>  para abrir a janela de ajuda.
 
   2. Digite  :help cmd  para achar a ajuda sobre  cmd .
 
-  3. Digite  CTRL-W CTRL-W  para pular de uma janela para outra.
+  3. Digite  CTRL-W CTRL-W  para pular de uma janela a outra.
 
   4. Digite  :q  para fechar a janela de ajuda.
 
   5. Crie um script de inicialização vimrc para ativar automaticamente as suas
      configurações preferidas.
 
-  6. Quando pressionando um comando  : , pressione CTRL-D para ver as
-     possibilidade de completação.
+  6. Quando pressionar um comando  : , pressione CTRL-D para ver as possibilidades 
+  de completação. Pressione <TAB> para usá-la.
 
 
 
@@ -944,8 +961,8 @@ NOTA:  A completação funciona com muitos comandos. Basta pressionar CTRL-D e
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-  Isto conclui o Vim tutor. Ele pretendeu dar uma breve apresentação do editor
-  Vim, somente o bastante para que você possa usar o editor com facilidade.
+  Isto conclui o tutorial do Vim, uma breve apresentação do editor Vim,
+  somente o bastante para que você possa usar o editor com facilidade.
   Ele está longe de ser completo, uma vez que o Vim possui muitos, muitos mais
   comandos. O próximo passo é ler o manual:  ":help user-manual".
 
@@ -979,6 +996,9 @@ NOTA:  A completação funciona com muitos comandos. Basta pressionar CTRL-D e
   Revisão e atualização da tradução para a versão 1.7 por Jakson Aquino,
   Universidade Federal do Ceará: E-mail: jalvesaq@gmail.com
 
-  Last Change: 2010 Jul 27
+  Nova revisão e atualização para a versão 1.8 por Roní Gonçalves,
+  Universidade Federal de Uberlândia.
+
+  Last Change: 2017 Feb 11
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index a827fa1..99f1047 100644 (file)
@@ -221,8 +221,8 @@ diffs or instructions to the address given in the `README' so they can
 be considered for the next release.  If at some point `config.cache'
 contains results you don't want to keep, you may remove or edit it.
 
-   The file `configure.in' is used to create `configure' by a program
-called `autoconf'.  You only need `configure.in' if you want to change
+   The file `configure.ac' is used to create `configure' by a program
+called `autoconf'.  You only need `configure.ac' if you want to change
 it or regenerate `configure' using a newer version of `autoconf'.
 
 The simplest way to compile this package is:
index 63f7fa9..b292720 100644 (file)
@@ -81,6 +81,13 @@ ifndef STATIC_STDCPLUS
 STATIC_STDCPLUS=no
 endif
 
+
+# Link against the shared version of libwinpthread by default.  Set
+# STATIC_WINPTHREAD to "yes" to link against static version instead.
+ifndef STATIC_WINPTHREAD
+STATIC_WINPTHREAD=$(STATIC_STDCPLUS)
+endif
+
 # If the user doesn't want gettext, undefine it.
 ifeq (no, $(GETTEXT))
 GETTEXT=
@@ -817,6 +824,10 @@ LIB += -lstdc++
 endif
 endif
 
+ifeq (yes, $(STATIC_WINPTHREAD))
+LIB += -Wl,-Bstatic -lwinpthread -Wl,-Bdynamic
+endif
+
 all: $(TARGET) vimrun.exe xxd/xxd.exe install.exe uninstal.exe GvimExt/gvimext.dll
 
 vimrun.exe: vimrun.c
index 435f56d..1638fd9 100644 (file)
@@ -285,8 +285,10 @@ MSVCRT_VER = ($(MSVCVER) / 10 - 50)
 # Base name of the msvcrXX.dll
 !if $(MSVCRT_VER) <= 60
 MSVCRT_NAME = msvcrt
-!else
+!elseif $(MSVCRT_VER) <= 130
 MSVCRT_NAME = msvcr$(MSVCRT_VER)
+!else
+MSVCRT_NAME = vcruntime$(MSVCRT_VER)
 !endif
 
 !if $(MSVC_MAJOR) == 6
@@ -297,6 +299,9 @@ CPU = ix86
 # Flag to turn on Win64 compatibility warnings for VC7.x and VC8.
 WP64CHECK = /Wp64
 
+# Use multiprocess build
+USE_MP = yes
+
 #>>>>> path of the compiler and linker; name of include and lib directories
 # PATH = c:\msvc20\bin;$(PATH)
 # INCLUDE = c:\msvc20\include
@@ -473,6 +478,14 @@ NODEFAULTLIB =
 NODEFAULTLIB = /nodefaultlib
 !endif
 
+# Use multiprocess build on MSVC 10
+!if "$(USE_MP)"=="yes"
+!if $(MSVC_MAJOR) >= 10
+CFLAGS = $(CFLAGS) /MP
+!endif
+!endif
+
+
 !ifdef NODEBUG
 VIM = vim
 !if "$(OPTIMIZE)" == "SPACE"
@@ -1112,9 +1125,6 @@ clean:
        cd GvimExt
        $(MAKE) /NOLOGO -f Makefile clean
        cd ..
-       cd GvimExt
-       $(MAKE) /NOLOGO -f Makefile clean
-       cd ..
        - if exist testdir\*.out del testdir\*.out
 
 test:
index fd07946..b8f440e 100644 (file)
 #SunOS 4.1.x                        +X11 -GUI          5.1b (J) Bram Moolenaar
 #SunOS 4.1.3_U1 (sun4c) gcc         +X11 +GUI Athena   5.0w (J) Darren Hiebert
 #SUPER-UX 6.2 (NEC SX-4) cc         +X11R6 Motif,Athena4.6b (P) Lennart Schultz
-#Tandem/NSK                                                  (c) Matthew Woehlke
+#Tandem/NSK                                                 (c) Matthew Woehlke
 #Unisys 6035         cc             +X11 Motif         5.3  (8) Glauber Ribeiro
 #ESIX V4.2           cc             +X11               6.0  (a) Reinhard Wobst
 #Mac OS X 10.[23]     gcc           Carbon             6.2  (x) Bram Moolenaar
@@ -403,6 +403,7 @@ CClink = $(CC)
 # First one is for static linking, second one for dynamic loading.
 # Use --with-luajit if you want to use LuaJIT instead of Lua.
 # Set PATH environment variable to find lua or luajit executable.
+# This requires at least "normal" features, "tiny" and "small" don't work.
 #CONF_OPT_LUA = --enable-luainterp
 #CONF_OPT_LUA = --enable-luainterp=dynamic
 #CONF_OPT_LUA = --enable-luainterp --with-luajit
@@ -429,45 +430,45 @@ CClink = $(CC)
 # the next line.
 # When you get an error for a missing "perl.exp" file, try creating an empty
 # one: "touch perl.exp".
-# This requires at least "small" features, "tiny" doesn't work.
-#CONF_OPT_PERL = --enable-perlinterp
+# This requires at least "normal" features, "tiny" and "small" don't work.
+CONF_OPT_PERL = --enable-perlinterp
 #CONF_OPT_PERL = --enable-perlinterp=dynamic
 
 # PYTHON
-# Uncomment this when you want to include the Python interface.
-# Requires small features or better, fails with tiny features.
+# Uncomment lines here when you want to include the Python interface.
+# This requires at least "normal" features, "tiny" and "small" don't work.
 # NOTE: This may cause threading to be enabled, which has side effects (such
 # as using different libraries and debugging becomes more difficult).
-# NOTE: Using this together with Perl may cause a crash in initialization.
 # For Python3 support make a symbolic link in /usr/local/bin:
 #      ln -s python3 python3.1
 # If both python2.x and python3.x are enabled then the linking will be via
 # dlopen(), dlsym(), dlclose(), i.e. pythonX.Y.so must be available
 # However, this may still cause problems, such as "import termios" failing.
 # Build two separate versions of Vim in that case.
-#CONF_OPT_PYTHON = --enable-pythoninterp
+CONF_OPT_PYTHON = --enable-pythoninterp
 #CONF_OPT_PYTHON = --enable-pythoninterp=dynamic
-#CONF_OPT_PYTHON3 = --enable-python3interp
+CONF_OPT_PYTHON3 = --enable-python3interp
 #CONF_OPT_PYTHON3 = --enable-python3interp=dynamic
 
 # RUBY
 # Uncomment this when you want to include the Ruby interface.
 # First one for static linking, second one for loading when used.
 # Note: you need the development package (e.g., ruby1.9.1-dev on Ubuntu).
-#CONF_OPT_RUBY = --enable-rubyinterp
+# This requires at least "normal" features, "tiny" and "small" don't work.
+CONF_OPT_RUBY = --enable-rubyinterp
 #CONF_OPT_RUBY = --enable-rubyinterp=dynamic
 #CONF_OPT_RUBY = --enable-rubyinterp --with-ruby-command=ruby1.9.1
 
 # TCL
 # Uncomment this when you want to include the Tcl interface.
 # First one is for static linking, second one for dynamic loading.
-#CONF_OPT_TCL = --enable-tclinterp
+CONF_OPT_TCL = --enable-tclinterp
 #CONF_OPT_TCL = --enable-tclinterp=dynamic
 #CONF_OPT_TCL = --enable-tclinterp --with-tclsh=tclsh8.4
 
 # CSCOPE
 # Uncomment this when you want to include the Cscope interface.
-#CONF_OPT_CSCOPE = --enable-cscope
+CONF_OPT_CSCOPE = --enable-cscope
 
 # WORKSHOP - Sun Visual Workshop interface.  Only works with Motif!
 #CONF_OPT_WORKSHOP = --enable-workshop
@@ -527,7 +528,7 @@ CClink = $(CC)
 #CONF_OPT_FEAT = --with-features=small
 #CONF_OPT_FEAT = --with-features=normal
 #CONF_OPT_FEAT = --with-features=big
-#CONF_OPT_FEAT = --with-features=huge
+CONF_OPT_FEAT = --with-features=huge
 
 # COMPILED BY - For including a specific e-mail address for ":version".
 #CONF_OPT_COMPBY = "--with-compiledby=John Doe <JohnDoe@yahoo.com>"
@@ -596,7 +597,7 @@ CClink = $(CC)
 #CFLAGS = -g -O2 '-DSTARTUPTIME="vimstartup"' -fno-strength-reduce -Wall -Wmissing-prototypes
 
 # Use this with GCC to check for mistakes, unused arguments, etc.
-#CFLAGS = -g -Wall -Wextra -Wshadow -Wmissing-prototypes -Wunreachable-code -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
+CFLAGS = -g -Wall -Wextra -Wshadow -Wmissing-prototypes -Wunreachable-code -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
 #CFLAGS = -g -O2 -Wall -Wextra -Wmissing-prototypes -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -DU_DEBUG
 #PYTHON_CFLAGS_EXTRA = -Wno-missing-field-initializers
 #MZSCHEME_CFLAGS_EXTRA = -Wno-unreachable-code -Wno-unused-parameter
@@ -617,7 +618,7 @@ AUTOCONF = autoconf
 #PURIFY = purify
 
 # VALGRIND - remove the # to use valgrind for memory leaks and access errors.
-#            Used for the unittest targets.
+#           Used for the unittest targets.
 # VALGRIND = valgrind --tool=memcheck --leak-check=yes --num-callers=25 --log-file=valgrind.$@
 
 # NBDEBUG - debugging the netbeans interface.
@@ -649,15 +650,15 @@ LINT_OPTIONS = -beprxzF
 # coverage information. (provided by Yegappan Lakshmanan)
 # 1. make clean, run configure and build Vim as usual.
 # 2. Generate the baseline code coverage information:
-#        $ lcov -c -i -b . -d objects -o objects/coverage_base.info
+#      $ lcov -c -i -b . -d objects -o objects/coverage_base.info
 # 3. Run "make test" to run the unit tests.  The code coverage information will
 #    be generated in the src/objects directory.
 # 4. Generate the code coverage information from the tests:
-#        $ lcov -c -b . -d objects/ -o objects/coverage_test.info
+#      $ lcov -c -b . -d objects/ -o objects/coverage_test.info
 # 5. Combine the baseline and test code coverage data:
-#        $ lcov -a objects/coverage_base.info -a objects/coverage_test.info -o objects/coverage_total.info
+#      $ lcov -a objects/coverage_base.info -a objects/coverage_test.info -o objects/coverage_total.info
 # 6. Process the test coverage data and generate a report in html:
-#        $ genhtml objects/coverage_total.info -o objects
+#      $ genhtml objects/coverage_total.info -o objects
 # 7. Open the objects/index.html file in a web browser to view the coverage
 #    information.
 #
@@ -678,16 +679,20 @@ SANITIZER_LIBS = $(SANITIZER_CFLAGS)
 # Configuration is in the .ccmalloc or ~/.ccmalloc file.
 # Doesn't work very well, since memory linked to from global variables
 # (in libraries) is also marked as leaked memory.
-#LEAK_CFLAGS = -DEXITFREE
+LEAK_CFLAGS = -DEXITFREE
 #LEAK_LIBS = -lccmalloc
 
+# Uncomment this line to have Vim call abort() when an internal error is
+# detected.  Useful when using a tool to find errors.
+#ABORT_CLFAGS = -DABORT_ON_INTERNAL_ERROR
+
 #####################################################
 ###  Specific systems, check if yours is listed!  ### {{{
 #####################################################
 
 ### Uncomment things here only if the values chosen by configure are wrong.
-### It's better to adjust configure.in and "make autoconf", if you can!
-### Then send the required changes to configure.in to the bugs list.
+### It's better to adjust configure.ac and "make autoconf", if you can!
+### Then send the required changes to configure.ac to the bugs list.
 
 ### (1) BSD/OS 2.0.1, 2.1 or 3.0 using shared libraries
 ###
@@ -1403,13 +1408,18 @@ PROTO_FLAGS = -d -E"$(CPP)" $(NO_ATTR)
 
 SHELL = /bin/sh
 
+# We would normally use "mkdir -p" but it doesn't work properly everywhere.
+# Using AC_PROG_MKDIR_P in configure.ac has a problem with the "auto"
+# directory.  Always use the install-sh script, it's slower but reliable.
+MKDIR_P = $(SHELL) install-sh -c -d
+
 .SUFFIXES:
 .SUFFIXES: .c .o .pro
 
 PRE_DEFS = -Iproto $(DEFS) $(GUI_DEFS) $(GUI_IPATH) $(CPPFLAGS) $(EXTRA_IPATHS)
 POST_DEFS = $(X_CFLAGS) $(MZSCHEME_CFLAGS) $(EXTRA_DEFS)
 
-ALL_CFLAGS = $(PRE_DEFS) $(CFLAGS) $(PROFILE_CFLAGS) $(SANITIZER_CFLAGS) $(LEAK_CFLAGS) $(POST_DEFS)
+ALL_CFLAGS = $(PRE_DEFS) $(CFLAGS) $(PROFILE_CFLAGS) $(SANITIZER_CFLAGS) $(LEAK_CFLAGS) $(ABORT_CLFAGS) $(POST_DEFS)
 
 # Exclude $CFLAGS for osdef.sh, for Mac 10.4 some flags don't work together
 # with "-E".
@@ -1580,14 +1590,16 @@ EXTRA_SRC = hangulin.c if_lua.c if_mzsch.c auto/if_perl.c if_perlsfio.c \
 # Unittest files
 JSON_TEST_SRC = json_test.c
 JSON_TEST_TARGET = json_test$(EXEEXT)
+KWORD_TEST_SRC = kword_test.c
+KWORD_TEST_TARGET = kword_test$(EXEEXT)
 MEMFILE_TEST_SRC = memfile_test.c
 MEMFILE_TEST_TARGET = memfile_test$(EXEEXT)
 MESSAGE_TEST_SRC = message_test.c
 MESSAGE_TEST_TARGET = message_test$(EXEEXT)
 
-UNITTEST_SRC = $(JSON_TEST_SRC) $(MEMFILE_TEST_SRC) $(MESSAGE_TEST_SRC)
-UNITTEST_TARGETS = $(JSON_TEST_TARGET) $(MEMFILE_TEST_TARGET) $(MESSAGE_TEST_TARGET)
-RUN_UNITTESTS = run_json_test run_memfile_test run_message_test
+UNITTEST_SRC = $(JSON_TEST_SRC) $(KWORD_TEST_SRC) $(MEMFILE_TEST_SRC) $(MESSAGE_TEST_SRC)
+UNITTEST_TARGETS = $(JSON_TEST_TARGET) $(KWORD_TEST_TARGET) $(MEMFILE_TEST_TARGET) $(MESSAGE_TEST_TARGET)
+RUN_UNITTESTS = run_json_test run_kword_test run_memfile_test run_message_test
 
 # All sources, also the ones that are not configured
 ALL_SRC = $(BASIC_SRC) $(ALL_GUI_SRC) $(UNITTEST_SRC) $(EXTRA_SRC)
@@ -1607,7 +1619,6 @@ OBJ_COMMON = \
        objects/arabic.o \
        objects/buffer.o \
        objects/blowfish.o \
-       objects/charset.o \
        objects/crypt.o \
        objects/crypt_zip.o \
        objects/dict.o \
@@ -1674,27 +1685,55 @@ OBJ_COMMON = \
        $(WSDEBUG_OBJ)
 
 # The files included by tests are not in OBJ_COMMON.
-OBJ = $(OBJ_COMMON) \
+OBJ_MAIN = \
+       objects/charset.o \
        objects/json.o \
        objects/main.o \
        objects/memfile.o \
        objects/message.o
 
-JSON_TEST_OBJ = $(OBJ_COMMON) \
+OBJ = $(OBJ_COMMON) $(OBJ_MAIN)
+
+OBJ_JSON_TEST = \
+       objects/charset.o \
        objects/memfile.o \
        objects/message.o \
        objects/json_test.o
 
-MEMFILE_TEST_OBJ = $(OBJ_COMMON) \
+JSON_TEST_OBJ = $(OBJ_COMMON) $(OBJ_JSON_TEST)
+
+OBJ_KWORD_TEST = \
+       objects/json.o \
+       objects/memfile.o \
+       objects/message.o \
+       objects/kword_test.o
+
+KWORD_TEST_OBJ = $(OBJ_COMMON) $(OBJ_KWORD_TEST)
+
+OBJ_MEMFILE_TEST = \
+       objects/charset.o \
        objects/json.o \
        objects/message.o \
        objects/memfile_test.o
 
-MESSAGE_TEST_OBJ = $(OBJ_COMMON) \
+MEMFILE_TEST_OBJ = $(OBJ_COMMON) $(OBJ_MEMFILE_TEST)
+
+OBJ_MESSAGE_TEST = \
+       objects/charset.o \
        objects/json.o \
        objects/memfile.o \
        objects/message_test.o
 
+MESSAGE_TEST_OBJ = $(OBJ_COMMON) $(OBJ_MESSAGE_TEST)
+
+ALL_OBJ = $(OBJ_COMMON) \
+         $(OBJ_MAIN) \
+         $(OBJ_JSON_TEST) \
+         $(OBJ_KWORD_TEST) \
+         $(OBJ_MEMFILE_TEST) \
+         $(OBJ_MESSAGE_TEST)
+
+
 PRO_AUTO = \
        arabic.pro \
        blowfish.pro \
@@ -1828,7 +1867,7 @@ reconfig: scratch clean
 # - DO NOT RUN autoconf MANUALLY!  It will overwrite ./configure instead of
 #   producing auto/configure.
 # - autoconf is not run automatically, because a patch usually changes both
-#   configure.in and auto/configure but can't update the timestamps.  People
+#   configure.ac and auto/configure but can't update the timestamps.  People
 #   who do not have (the correct version of) autoconf would run into trouble.
 #
 # Two tricks are required to make autoconf put its output in the "auto" dir:
@@ -1851,14 +1890,18 @@ autoconf:
        -rm -rf autom4te.cache
        -rm -f auto/config.status auto/config.cache
 
-# Re-execute this Makefile to include the new auto/config.mk produced by
-# configure Only used when typing "make" with a fresh auto/config.mk.
-myself:
-       $(MAKE) -f Makefile all
+# Run vim script to generate the Ex command lookup table.
+# This only needs to be run when a command name has been added or changed.
+# If this fails because you don't have Vim yet, first build and install Vim
+# without changes.
+cmdidxs: ex_cmds.h
+       vim -u NONE -i NONE -X -S create_cmdidxs.vim
 
 
 # The normal command to compile a .c file to its .o file.
-CCC = $(CC) -c -I$(srcdir) $(ALL_CFLAGS)
+# Without or with ALL_CFLAGS.
+CCC_NF = $(CC) -c -I$(srcdir)
+CCC = $(CCC_NF) $(ALL_CFLAGS)
 
 
 # Link the target for normal use or debugging.
@@ -1998,7 +2041,6 @@ scripttests:
        fi
        cd testdir; $(MAKE) -f Makefile $(GUI_TESTTARGET) VIMPROG=../$(VIMTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE)
 
-
 # Run the tests with the GUI.  Assumes vim/gvim was already built
 testgui:
        cd testdir; $(MAKE) -f Makefile $(GUI_TESTTARGET) VIMPROG=../$(VIMTARGET) GUI_FLAG=-g $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE)
@@ -2015,6 +2057,9 @@ unittest unittests: $(RUN_UNITTESTS)
 run_json_test: $(JSON_TEST_TARGET)
        $(VALGRIND) ./$(JSON_TEST_TARGET) || exit 1; echo $* passed;
 
+run_kword_test: $(KWORD_TEST_TARGET)
+       $(VALGRIND) ./$(KWORD_TEST_TARGET) || exit 1; echo $* passed;
+
 run_memfile_test: $(MEMFILE_TEST_TARGET)
        $(VALGRIND) ./$(MEMFILE_TEST_TARGET) || exit 1; echo $* passed;
 
@@ -2025,7 +2070,6 @@ run_message_test: $(MESSAGE_TEST_TARGET)
 test1 \
        test_autocmd_option \
        test_autoformat_join \
-       test_breakindent \
        test_changelist \
        test_close_count \
        test_comparators \
@@ -2035,10 +2079,7 @@ test1 \
        test_getcwd \
        test_insertcount \
        test_listchars \
-       test_listlbr \
-       test_listlbr_utf8 \
        test_search_mbyte \
-       test_utf8 \
        test_wordcount \
        test3 test4 test5 test6 test7 test8 test9 \
        test11 test12 test14 test15 test17 test18 test19 \
@@ -2048,22 +2089,29 @@ test1 \
        test50 test51 test52 test53 test54 test55 test56 test57 test58 test59 \
        test60 test64 test65 test66 test67 test68 test69 \
        test70 test72 test73 test74 test75 test77 test78 test79 \
-       test80 test82 test83 test84 test85 test86 test87 test88 test89 \
-       test90 test91 test92 test93 test94 test95 test97 test98 test99 \
+       test80 test82 test83 test84 test85 test86 test87 test88 \
+       test90 test91 test94 test95 test97 test98 test99 \
        test100 test101 test103 test104 test107 test108:
        cd testdir; rm -f $@.out; $(MAKE) -f Makefile $@.out VIMPROG=../$(VIMTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE)
 
 # Run individual NEW style test, assuming that Vim was already compiled.
 test_arglist \
+       test_arabic \
        test_assert \
        test_assign \
        test_autochdir \
        test_autocmd \
        test_backspace_opt \
+       test_breakindent \
        test_bufwintabinfo \
+       test_cd \
        test_cdo \
+       test_changedtick \
        test_channel \
        test_charsearch \
+       test_charsearch_utf8 \
+       test_cindent \
+       test_clientserver \
        test_cmdline \
        test_command_count \
        test_crypt \
@@ -2072,7 +2120,10 @@ test_arglist \
        test_delete \
        test_diffmode \
        test_digraph \
+       test_display \
+       test_edit \
        test_ex_undo \
+       test_ex_z \
        test_execute_func \
        test_expand \
        test_expand_dllpath \
@@ -2084,15 +2135,24 @@ test_arglist \
        test_fileformat \
        test_filter_cmd \
        test_filter_map \
+       test_findfile \
+       test_float_func \
        test_fnameescape \
        test_fnamemodify \
-       test_glob2regpat \
+       test_fold \
+       test_functions \
+       test_ga \
        test_gf \
+       test_glob2regpat \
+       test_global \
        test_gn \
        test_goto \
        test_gui \
+       test_gui_init \
        test_hardcopy \
+       test_help \
        test_help_tagjump \
+       test_hide \
        test_history \
        test_hlsearch \
        test_increment \
@@ -2105,6 +2165,10 @@ test_arglist \
        test_langmap \
        test_largefile \
        test_lispwords \
+       test_listlbr \
+       test_listlbr_utf8 \
+       test_lua \
+       test_makeencoding \
        test_man \
        test_mapping \
        test_marks \
@@ -2113,26 +2177,40 @@ test_arglist \
        test_matchadd_conceal_utf8 \
        test_menu \
        test_messages \
+       test_mksession \
+       test_mksession_utf8 \
        test_nested_function \
        test_netbeans \
        test_normal \
+       test_number \
        test_options \
        test_packadd \
        test_partial \
+       test_paste \
        test_perl \
        test_popup \
+       test_profile \
+       test_put \
+       test_python2 \
+       test_python3 \
+       test_pyx2 \
+       test_pyx3 \
        test_quickfix \
+       test_quotestar \
+       test_recover \
        test_regexp_latin \
        test_regexp_utf8 \
        test_reltime \
+       test_retab \
        test_ruby \
        test_search \
        test_searchpos \
        test_set \
        test_signs \
+       test_smartindent \
        test_sort \
        test_source_utf8 \
-       test_smartindent \
+       test_spell \
        test_startup \
        test_startup_utf8 \
        test_stat \
@@ -2140,18 +2218,22 @@ test_arglist \
        test_substitute \
        test_syn_attr \
        test_syntax \
+       test_system \
        test_tabline \
        test_tabpage \
        test_tagcase \
        test_tagjump \
+       test_taglist \
+       test_tcl \
        test_textobjects \
        test_timers \
        test_true_false \
        test_undo \
        test_unlet \
        test_usercommands \
+       test_utf8 \
        test_viminfo \
-       test_viml \
+       test_vimscript \
        test_visual \
        test_window_cmd \
        test_window_id \
@@ -2187,6 +2269,13 @@ $(JSON_TEST_TARGET): auto/config.mk objects $(JSON_TEST_OBJ)
                MAKE="$(MAKE)" LINK_AS_NEEDED=$(LINK_AS_NEEDED) \
                sh $(srcdir)/link.sh
 
+$(KWORD_TEST_TARGET): auto/config.mk objects $(KWORD_TEST_OBJ)
+       $(CCC) version.c -o objects/version.o
+       @LINK="$(PURIFY) $(SHRPENV) $(CClink) $(ALL_LIB_DIRS) $(LDFLAGS) \
+               -o $(KWORD_TEST_TARGET) $(KWORD_TEST_OBJ) $(ALL_LIBS)" \
+               MAKE="$(MAKE)" LINK_AS_NEEDED=$(LINK_AS_NEEDED) \
+               sh $(srcdir)/link.sh
+
 $(MEMFILE_TEST_TARGET): auto/config.mk objects $(MEMFILE_TEST_OBJ)
        $(CCC) version.c -o objects/version.o
        @LINK="$(PURIFY) $(SHRPENV) $(CClink) $(ALL_LIB_DIRS) $(LDFLAGS) \
@@ -2475,7 +2564,7 @@ DESKTOPPATH = $(DESTDIR)$(DATADIR)/applications
 KDEPATH = $(HOME)/.kde/share/icons
 install-icons:
        if test -n "$(DESTDIR)"; then \
-               $(SHELL) ./mkinstalldirs $(ICON48PATH) $(ICON32PATH) \
+               $(MKDIR_P) $(ICON48PATH) $(ICON32PATH) \
                $(ICON16PATH) $(DESKTOPPATH); \
        fi
 
@@ -2516,7 +2605,7 @@ $(DESTDIR)$(exec_prefix) $(DEST_BIN) \
                $(DEST_LANG) $(DEST_KMAP) $(DEST_COMP) $(DEST_MACRO) \
                $(DEST_PACK) $(DEST_TOOLS) $(DEST_TUTOR) $(DEST_SPELL) \
                $(DEST_AUTO) $(DEST_AUTO)/xml $(DEST_PLUG):
-       -$(SHELL) ./mkinstalldirs $@
+       $(MKDIR_P) $@
        -chmod $(DIRMOD) $@
 
 # create links from various names to vim.  This is only done when the links
@@ -2679,9 +2768,11 @@ uninstall_runtime:
 # Clean up all the files that have been produced, except configure's.
 # We support common typing mistakes for Juergen! :-)
 clean celan: testclean
-       -rm -f *.o objects/* core $(VIMTARGET).core $(VIMTARGET) vim xxd/*.o
+       -rm -f *.o core $(VIMTARGET).core $(VIMTARGET) vim xxd/*.o
+       -rm -rf objects
        -rm -f $(TOOLS) auto/osdef.h auto/pathdef.c auto/if_perl.c auto/gui_gtk_gresources.c auto/gui_gtk_gresources.h
        -rm -f conftest* *~ auto/link.sed
+       -rm -f testdir/opt_test.vim
        -rm -f $(UNITTEST_TARGETS)
        -rm -f runtime pixmaps
        -rm -rf $(APPDIR)
@@ -2695,25 +2786,25 @@ clean celan: testclean
 SHADOWDIR = shadow
 
 shadow:        runtime pixmaps
-       mkdir $(SHADOWDIR)
-       cd $(SHADOWDIR); ln -s ../*.[ch] ../*.in ../*.sh ../*.xs ../*.xbm ../gui_gtk_res.xml ../toolcheck ../proto ../vimtutor ../gvimtutor ../mkinstalldirs .
+       $(MKDIR_P) $(SHADOWDIR)
+       cd $(SHADOWDIR); ln -s ../*.[chm] ../*.in ../*.sh ../*.xs ../*.xbm ../gui_gtk_res.xml ../toolcheck ../proto ../vimtutor ../gvimtutor ../install-sh .
        mkdir $(SHADOWDIR)/auto
        cd $(SHADOWDIR)/auto; ln -s ../../auto/configure .
-       mkdir $(SHADOWDIR)/po
+       $(MKDIR_P) $(SHADOWDIR)/po
        cd $(SHADOWDIR)/po; ln -s ../../po/*.po ../../po/*.mak ../../po/*.vim ../../po/Makefile .
        cd $(SHADOWDIR); rm -f auto/link.sed
        cp Makefile configure $(SHADOWDIR)
        rm -f $(SHADOWDIR)/auto/config.mk $(SHADOWDIR)/config.mk.dist
        cp config.mk.dist $(SHADOWDIR)/auto/config.mk
        cp config.mk.dist $(SHADOWDIR)
-       mkdir $(SHADOWDIR)/xxd
+       $(MKDIR_P) $(SHADOWDIR)/xxd
        cd $(SHADOWDIR)/xxd; ln -s ../../xxd/*.[ch] ../../xxd/Make* .
        if test -d $(RSRC_DIR); then \
                cd $(SHADOWDIR); \
                ln -s ../infplist.xml .; \
                ln -s ../$(RSRC_DIR) ../os_mac.rsr.hqx ../dehqx.py .; \
        fi
-       mkdir $(SHADOWDIR)/testdir
+       $(MKDIR_P) $(SHADOWDIR)/testdir
        cd $(SHADOWDIR)/testdir; ln -s ../../testdir/Makefile \
                                 ../../testdir/Make_all.mak \
                                 ../../testdir/README.txt \
@@ -2721,6 +2812,7 @@ shadow:   runtime pixmaps
                                 ../../testdir/*.vim \
                                 ../../testdir/*.py \
                                 ../../testdir/python* \
+                                ../../testdir/pyxfile \
                                 ../../testdir/sautest \
                                 ../../testdir/samples \
                                 ../../testdir/test83-tags? \
@@ -2846,8 +2938,16 @@ auto/gui_gtk_gresources.h: gui_gtk_res.xml $(GUI_GTK_RES_INPUTS)
 # commands understand putting object files in another directory, it must be
 # specified for each file separately.
 
-objects:
-       mkdir objects
+objects: objects/.dirstamp
+
+objects/.dirstamp:
+       $(MKDIR_P) objects
+       touch objects/.dirstamp
+
+# All object files depend on the objects directory, so that parallel make
+# works.  Can't depend on the directory itself, its timestamp changes all the
+# time.
+$(ALL_OBJ): objects/.dirstamp
 
 objects/arabic.o: arabic.c
        $(CCC) -o $@ arabic.c
@@ -2940,7 +3040,7 @@ objects/gui_gtk_f.o: gui_gtk_f.c
        $(CCC) -o $@ gui_gtk_f.c
 
 objects/gui_gtk_gresources.o: auto/gui_gtk_gresources.c
-       $(CCC) $(PERL_CFLAGS) -o $@ auto/gui_gtk_gresources.c
+       $(CCC_NF) $(PERL_CFLAGS) $(ALL_CFLAGS) -o $@ auto/gui_gtk_gresources.c
 
 objects/gui_gtk_x11.o: gui_gtk_x11.c
        $(CCC) -o $@ gui_gtk_x11.c
@@ -2973,7 +3073,7 @@ objects/if_xcmdsrv.o: if_xcmdsrv.c
        $(CCC) -o $@ if_xcmdsrv.c
 
 objects/if_lua.o: if_lua.c
-       $(CCC) $(LUA_CFLAGS) -o $@ if_lua.c
+       $(CCC_NF) $(LUA_CFLAGS) $(ALL_CFLAGS) -o $@ if_lua.c
 
 objects/if_mzsch.o: if_mzsch.c $(MZSCHEME_EXTRA)
        $(CCC) -o $@ $(MZSCHEME_CFLAGS_EXTRA) if_mzsch.c
@@ -2982,27 +3082,28 @@ mzscheme_base.c:
        $(MZSCHEME_MZC) --c-mods mzscheme_base.c ++lib scheme/base
 
 objects/if_perl.o: auto/if_perl.c
-       $(CCC) $(PERL_CFLAGS) -o $@ auto/if_perl.c
+       $(CCC_NF) $(PERL_CFLAGS) $(ALL_CFLAGS) -o $@ auto/if_perl.c
 
 objects/if_perlsfio.o: if_perlsfio.c
-       $(CCC) $(PERL_CFLAGS) -o $@ if_perlsfio.c
+       $(CCC_NF) $(PERL_CFLAGS) $(ALL_CFLAGS) -o $@ if_perlsfio.c
 
 objects/py_getpath.o: $(PYTHON_CONFDIR)/getpath.c
-       $(CCC) $(PYTHON_CFLAGS) -o $@ $(PYTHON_CONFDIR)/getpath.c \
+       $(CCC_NF) $(PYTHON_CFLAGS) $(ALL_CFLAGS) -o $@ \
+               $(PYTHON_CONFDIR)/getpath.c \
                -I$(PYTHON_CONFDIR) -DHAVE_CONFIG_H -DNO_MAIN \
                $(PYTHON_GETPATH_CFLAGS)
 
 objects/if_python.o: if_python.c if_py_both.h
-       $(CCC) $(PYTHON_CFLAGS) $(PYTHON_CFLAGS_EXTRA) -o $@ if_python.c
+       $(CCC_NF) $(PYTHON_CFLAGS) $(PYTHON_CFLAGS_EXTRA) $(ALL_CFLAGS) -o $@ if_python.c
 
 objects/if_python3.o: if_python3.c if_py_both.h
-       $(CCC) $(PYTHON3_CFLAGS) $(PYTHON3_CFLAGS_EXTRA) -o $@ if_python3.c
+       $(CCC_NF) $(PYTHON3_CFLAGS) $(PYTHON3_CFLAGS_EXTRA) $(ALL_CFLAGS) -o $@ if_python3.c
 
 objects/if_ruby.o: if_ruby.c
-       $(CCC) $(RUBY_CFLAGS) -o $@ if_ruby.c
+       $(CCC_NF) $(RUBY_CFLAGS) $(ALL_CFLAGS) -o $@ if_ruby.c
 
 objects/if_tcl.o: if_tcl.c
-       $(CCC) $(TCL_CFLAGS) -o $@ if_tcl.c
+       $(CCC_NF) $(TCL_CFLAGS) $(ALL_CFLAGS) -o $@ if_tcl.c
 
 objects/integration.o: integration.c
        $(CCC) -o $@ integration.c
@@ -3013,6 +3114,9 @@ objects/json.o: json.c
 objects/json_test.o: json_test.c
        $(CCC) -o $@ json_test.c
 
+objects/kword_test.o: kword_test.c
+       $(CCC) -o $@ kword_test.c
+
 objects/list.o: list.c
        $(CCC) -o $@ list.c
 
@@ -3059,7 +3163,7 @@ objects/ops.o: ops.c
        $(CCC) -o $@ ops.c
 
 objects/option.o: option.c
-       $(CCC) $(LUA_CFLAGS) $(PERL_CFLAGS) $(PYTHON_CFLAGS) $(PYTHON3_CFLAGS) $(RUBY_CFLAGS) $(TCL_CFLAGS) -o $@ option.c
+       $(CCC_NF) $(LUA_CFLAGS) $(PERL_CFLAGS) $(PYTHON_CFLAGS) $(PYTHON3_CFLAGS) $(RUBY_CFLAGS) $(TCL_CFLAGS) $(ALL_CFLAGS) -o $@ option.c
 
 objects/os_beos.o: os_beos.c
        $(CCC) -o $@ os_beos.c
@@ -3168,8 +3272,7 @@ install_macosx: gui_bundle
 # Generate the help tags file now, it won't work with "make installruntime".
        -@srcdir=`pwd`; cd $(HELPSOURCE); $(MAKE) VIMEXE=$$srcdir/$(VIMTARGET) vimtags
 # Install the runtime files.  Recursive!
-       -mkdir -p $(DESTDIR)$(prefix)/$(RESDIR)/vim/runtime
-#      -mkdir $(DESTDIR)$(prefix)/$(APPDIR)/bin
+       $(MKDIR_P) $(DESTDIR)$(prefix)/$(RESDIR)/vim/runtime
        srcdir=`pwd`; $(MAKE) -f Makefile installruntime \
                VIMEXE=$$srcdir/$(VIMTARGET) \
                prefix=$(DESTDIR)$(prefix)/$(RESDIR)$(VIMDIR) \
@@ -3187,16 +3290,16 @@ gui_bundle: $(RESDIR) bundle-dir bundle-executable bundle-info bundle-resource \
        bundle-language
 
 $(RESDIR):
-       mkdir -p $@
+       $(MKDIR_P) $@
 
 bundle-dir: $(APPDIR)/Contents $(VIMTARGET)
 # Make a link to the runtime directory, so that we can try out the executable
 # without installing it.
-       mkdir -p $(RESDIR)/vim
+       $(MKDIR_P) $(RESDIR)/vim
        -ln -s `pwd`/../runtime $(RESDIR)/vim
 
 bundle-executable: $(VIMTARGET)
-       mkdir -p $(APPDIR)/Contents/MacOS
+       $(MKDIR_P) $(APPDIR)/Contents/MacOS
        cp $(VIMTARGET) $(APPDIR)/Contents/MacOS/$(VIMTARGET)
 
 bundle-info:  bundle-dir
@@ -3227,8 +3330,8 @@ bundle-rsrc: os_mac.rsr.hqx
 bundle-language: bundle-dir
 
 $(APPDIR)/Contents:
-       -$(SHELL) ./mkinstalldirs $(APPDIR)/Contents/MacOS
-       -$(SHELL) ./mkinstalldirs $(RESDIR)/English.lproj
+       $(MKDIR_P) $(APPDIR)/Contents/MacOS
+       $(MKDIR_P) $(RESDIR)/English.lproj
 
 
 ###############################################################################
@@ -3552,6 +3655,10 @@ objects/json_test.o: json_test.c main.c vim.h auto/config.h feature.h os_unix.h
  auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
  regexp.h gui.h gui_beval.h proto/gui_beval.pro alloc.h ex_cmds.h spell.h \
  proto.h globals.h farsi.h arabic.h json.c
+objects/kword_test.o: kword_test.c main.c vim.h auto/config.h feature.h os_unix.h \
+ auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
+ regexp.h gui.h gui_beval.h proto/gui_beval.pro alloc.h ex_cmds.h spell.h \
+ proto.h globals.h farsi.h arabic.h charset.c mbyte.c
 objects/memfile_test.o: memfile_test.c main.c vim.h auto/config.h feature.h \
  os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h \
  structs.h regexp.h gui.h gui_beval.h proto/gui_beval.pro alloc.h \
index fa5e940..9bc1669 100644 (file)
@@ -24,7 +24,9 @@ static int  chg_c_a2s(int cur_c);
 static int  chg_c_a2i(int cur_c);
 static int  chg_c_a2m(int cur_c);
 static int  chg_c_a2f(int cur_c);
+#if 0
 static int  chg_c_i2m(int cur_c);
+#endif
 static int  chg_c_f2m(int cur_c);
 static int  chg_c_laa2i(int hid_c);
 static int  chg_c_laa2f(int hid_c);
@@ -200,126 +202,47 @@ A_is_f(int cur_c)
     static int
 chg_c_a2s(int cur_c)
 {
-    int tempc;
-
     switch (cur_c)
     {
-       case a_HAMZA:
-           tempc = a_s_HAMZA;
-           break;
-       case a_ALEF_MADDA:
-           tempc = a_s_ALEF_MADDA;
-           break;
-       case a_ALEF_HAMZA_ABOVE:
-           tempc = a_s_ALEF_HAMZA_ABOVE;
-           break;
-       case a_WAW_HAMZA:
-           tempc = a_s_WAW_HAMZA;
-           break;
-       case a_ALEF_HAMZA_BELOW:
-           tempc = a_s_ALEF_HAMZA_BELOW;
-           break;
-       case a_YEH_HAMZA:
-           tempc = a_s_YEH_HAMZA;
-           break;
-       case a_ALEF:
-           tempc = a_s_ALEF;
-           break;
-       case a_TEH_MARBUTA:
-           tempc = a_s_TEH_MARBUTA;
-           break;
-       case a_DAL:
-           tempc = a_s_DAL;
-           break;
-       case a_THAL:
-           tempc = a_s_THAL;
-           break;
-       case a_REH:
-           tempc = a_s_REH;
-           break;
-       case a_ZAIN:
-           tempc = a_s_ZAIN;
-           break;
-       case a_TATWEEL:                 /* exceptions */
-           tempc = cur_c;
-           break;
-       case a_WAW:
-           tempc = a_s_WAW;
-           break;
-       case a_ALEF_MAKSURA:
-           tempc = a_s_ALEF_MAKSURA;
-           break;
-       case a_BEH:
-           tempc = a_s_BEH;
-           break;
-       case a_TEH:
-           tempc = a_s_TEH;
-           break;
-       case a_THEH:
-           tempc = a_s_THEH;
-           break;
-       case a_JEEM:
-           tempc = a_s_JEEM;
-           break;
-       case a_HAH:
-           tempc = a_s_HAH;
-           break;
-       case a_KHAH:
-           tempc = a_s_KHAH;
-           break;
-       case a_SEEN:
-           tempc = a_s_SEEN;
-           break;
-       case a_SHEEN:
-           tempc = a_s_SHEEN;
-           break;
-       case a_SAD:
-           tempc = a_s_SAD;
-           break;
-       case a_DAD:
-           tempc = a_s_DAD;
-           break;
-       case a_TAH:
-           tempc = a_s_TAH;
-           break;
-       case a_ZAH:
-           tempc = a_s_ZAH;
-           break;
-       case a_AIN:
-           tempc = a_s_AIN;
-           break;
-       case a_GHAIN:
-           tempc = a_s_GHAIN;
-           break;
-       case a_FEH:
-           tempc = a_s_FEH;
-           break;
-       case a_QAF:
-           tempc = a_s_QAF;
-           break;
-       case a_KAF:
-           tempc = a_s_KAF;
-           break;
-       case a_LAM:
-           tempc = a_s_LAM;
-           break;
-       case a_MEEM:
-           tempc = a_s_MEEM;
-           break;
-       case a_NOON:
-           tempc = a_s_NOON;
-           break;
-       case a_HEH:
-           tempc = a_s_HEH;
-           break;
-       case a_YEH:
-           tempc = a_s_YEH;
-           break;
-       default:
-           tempc = 0;
+       case a_HAMZA: return a_s_HAMZA;
+       case a_ALEF_MADDA: return a_s_ALEF_MADDA;
+       case a_ALEF_HAMZA_ABOVE: return a_s_ALEF_HAMZA_ABOVE;
+       case a_WAW_HAMZA: return a_s_WAW_HAMZA;
+       case a_ALEF_HAMZA_BELOW: return a_s_ALEF_HAMZA_BELOW;
+       case a_YEH_HAMZA: return a_s_YEH_HAMZA;
+       case a_ALEF: return a_s_ALEF;
+       case a_TEH_MARBUTA: return a_s_TEH_MARBUTA;
+       case a_DAL: return a_s_DAL;
+       case a_THAL: return a_s_THAL;
+       case a_REH: return a_s_REH;
+       case a_ZAIN: return a_s_ZAIN;
+       case a_TATWEEL: return cur_c;   /* exceptions */
+       case a_WAW: return a_s_WAW;
+       case a_ALEF_MAKSURA: return a_s_ALEF_MAKSURA;
+       case a_BEH: return a_s_BEH;
+       case a_TEH: return a_s_TEH;
+       case a_THEH: return a_s_THEH;
+       case a_JEEM: return a_s_JEEM;
+       case a_HAH: return a_s_HAH;
+       case a_KHAH: return a_s_KHAH;
+       case a_SEEN: return a_s_SEEN;
+       case a_SHEEN: return a_s_SHEEN;
+       case a_SAD: return a_s_SAD;
+       case a_DAD: return a_s_DAD;
+       case a_TAH: return a_s_TAH;
+       case a_ZAH: return a_s_ZAH;
+       case a_AIN: return a_s_AIN;
+       case a_GHAIN: return a_s_GHAIN;
+       case a_FEH: return a_s_FEH;
+       case a_QAF: return a_s_QAF;
+       case a_KAF: return a_s_KAF;
+       case a_LAM: return a_s_LAM;
+       case a_MEEM: return a_s_MEEM;
+       case a_NOON: return a_s_NOON;
+       case a_HEH: return a_s_HEH;
+       case a_YEH: return a_s_YEH;
     }
-
-    return tempc;
+    return 0;
 }
 
 
@@ -329,126 +252,61 @@ chg_c_a2s(int cur_c)
     static int
 chg_c_a2i(int cur_c)
 {
-    int tempc;
-
     switch (cur_c)
     {
-       case a_YEH_HAMZA:
-           tempc = a_i_YEH_HAMZA;
-           break;
+       case a_YEH_HAMZA: return a_i_YEH_HAMZA;
        case a_HAMZA:                   /* exceptions */
-           tempc = a_s_HAMZA;
-           break;
+           return a_s_HAMZA;
        case a_ALEF_MADDA:              /* exceptions */
-           tempc = a_s_ALEF_MADDA;
-           break;
+           return a_s_ALEF_MADDA;
        case a_ALEF_HAMZA_ABOVE:        /* exceptions */
-           tempc = a_s_ALEF_HAMZA_ABOVE;
-           break;
+           return a_s_ALEF_HAMZA_ABOVE;
        case a_WAW_HAMZA:               /* exceptions */
-           tempc = a_s_WAW_HAMZA;
-           break;
+           return a_s_WAW_HAMZA;
        case a_ALEF_HAMZA_BELOW:        /* exceptions */
-           tempc = a_s_ALEF_HAMZA_BELOW;
-           break;
+           return a_s_ALEF_HAMZA_BELOW;
        case a_ALEF:                    /* exceptions */
-           tempc = a_s_ALEF;
-           break;
+           return a_s_ALEF;
        case a_TEH_MARBUTA:             /* exceptions */
-           tempc = a_s_TEH_MARBUTA;
-           break;
+           return a_s_TEH_MARBUTA;
        case a_DAL:                     /* exceptions */
-           tempc = a_s_DAL;
-           break;
+           return a_s_DAL;
        case a_THAL:                    /* exceptions */
-           tempc = a_s_THAL;
-           break;
+           return a_s_THAL;
        case a_REH:                     /* exceptions */
-           tempc = a_s_REH;
-           break;
+           return a_s_REH;
        case a_ZAIN:                    /* exceptions */
-           tempc = a_s_ZAIN;
-           break;
+           return a_s_ZAIN;
        case a_TATWEEL:                 /* exceptions */
-           tempc = cur_c;
-           break;
+           return cur_c;
        case a_WAW:                     /* exceptions */
-           tempc = a_s_WAW;
-           break;
+           return a_s_WAW;
        case a_ALEF_MAKSURA:            /* exceptions */
-           tempc = a_s_ALEF_MAKSURA;
-           break;
-       case a_BEH:
-           tempc = a_i_BEH;
-           break;
-       case a_TEH:
-           tempc = a_i_TEH;
-           break;
-       case a_THEH:
-           tempc = a_i_THEH;
-           break;
-       case a_JEEM:
-           tempc = a_i_JEEM;
-           break;
-       case a_HAH:
-           tempc = a_i_HAH;
-           break;
-       case a_KHAH:
-           tempc = a_i_KHAH;
-           break;
-       case a_SEEN:
-           tempc = a_i_SEEN;
-           break;
-       case a_SHEEN:
-           tempc = a_i_SHEEN;
-           break;
-       case a_SAD:
-           tempc = a_i_SAD;
-           break;
-       case a_DAD:
-           tempc = a_i_DAD;
-           break;
-       case a_TAH:
-           tempc = a_i_TAH;
-           break;
-       case a_ZAH:
-           tempc = a_i_ZAH;
-           break;
-       case a_AIN:
-           tempc = a_i_AIN;
-           break;
-       case a_GHAIN:
-           tempc = a_i_GHAIN;
-           break;
-       case a_FEH:
-           tempc = a_i_FEH;
-           break;
-       case a_QAF:
-           tempc = a_i_QAF;
-           break;
-       case a_KAF:
-           tempc = a_i_KAF;
-           break;
-       case a_LAM:
-           tempc = a_i_LAM;
-           break;
-       case a_MEEM:
-           tempc = a_i_MEEM;
-           break;
-       case a_NOON:
-           tempc = a_i_NOON;
-           break;
-       case a_HEH:
-           tempc = a_i_HEH;
-           break;
-       case a_YEH:
-           tempc = a_i_YEH;
-           break;
-       default:
-           tempc = 0;
+           return a_s_ALEF_MAKSURA;
+       case a_BEH: return a_i_BEH;
+       case a_TEH: return a_i_TEH;
+       case a_THEH: return a_i_THEH;
+       case a_JEEM: return a_i_JEEM;
+       case a_HAH: return a_i_HAH;
+       case a_KHAH: return a_i_KHAH;
+       case a_SEEN: return a_i_SEEN;
+       case a_SHEEN: return a_i_SHEEN;
+       case a_SAD: return a_i_SAD;
+       case a_DAD: return a_i_DAD;
+       case a_TAH: return a_i_TAH;
+       case a_ZAH: return a_i_ZAH;
+       case a_AIN: return a_i_AIN;
+       case a_GHAIN: return a_i_GHAIN;
+       case a_FEH: return a_i_FEH;
+       case a_QAF: return a_i_QAF;
+       case a_KAF: return a_i_KAF;
+       case a_LAM: return a_i_LAM;
+       case a_MEEM: return a_i_MEEM;
+       case a_NOON: return a_i_NOON;
+       case a_HEH: return a_i_HEH;
+       case a_YEH: return a_i_YEH;
     }
-
-    return tempc;
+    return 0;
 }
 
 
@@ -458,126 +316,47 @@ chg_c_a2i(int cur_c)
     static int
 chg_c_a2m(int cur_c)
 {
-    int tempc;
-
     switch (cur_c)
     {
-       case a_HAMZA:                   /* exception */
-           tempc = a_s_HAMZA;
-           break;
-       case a_ALEF_MADDA:              /* exception */
-           tempc = a_f_ALEF_MADDA;
-           break;
-       case a_ALEF_HAMZA_ABOVE:        /* exception */
-           tempc = a_f_ALEF_HAMZA_ABOVE;
-           break;
-       case a_WAW_HAMZA:               /* exception */
-           tempc = a_f_WAW_HAMZA;
-           break;
-       case a_ALEF_HAMZA_BELOW:        /* exception */
-           tempc = a_f_ALEF_HAMZA_BELOW;
-           break;
-       case a_YEH_HAMZA:
-           tempc = a_m_YEH_HAMZA;
-           break;
-       case a_ALEF:                    /* exception */
-           tempc = a_f_ALEF;
-           break;
-       case a_BEH:
-           tempc = a_m_BEH;
-           break;
-       case a_TEH_MARBUTA:             /* exception */
-           tempc = a_f_TEH_MARBUTA;
-           break;
-       case a_TEH:
-           tempc = a_m_TEH;
-           break;
-       case a_THEH:
-           tempc = a_m_THEH;
-           break;
-       case a_JEEM:
-           tempc = a_m_JEEM;
-           break;
-       case a_HAH:
-           tempc = a_m_HAH;
-           break;
-       case a_KHAH:
-           tempc = a_m_KHAH;
-           break;
-       case a_DAL:                     /* exception */
-           tempc = a_f_DAL;
-           break;
-       case a_THAL:                    /* exception */
-           tempc = a_f_THAL;
-           break;
-       case a_REH:                     /* exception */
-           tempc = a_f_REH;
-           break;
-       case a_ZAIN:                    /* exception */
-           tempc = a_f_ZAIN;
-           break;
-       case a_SEEN:
-           tempc = a_m_SEEN;
-           break;
-       case a_SHEEN:
-           tempc = a_m_SHEEN;
-           break;
-       case a_SAD:
-           tempc = a_m_SAD;
-           break;
-       case a_DAD:
-           tempc = a_m_DAD;
-           break;
-       case a_TAH:
-           tempc = a_m_TAH;
-           break;
-       case a_ZAH:
-           tempc = a_m_ZAH;
-           break;
-       case a_AIN:
-           tempc = a_m_AIN;
-           break;
-       case a_GHAIN:
-           tempc = a_m_GHAIN;
-           break;
-       case a_TATWEEL:                 /* exception */
-           tempc = cur_c;
-           break;
-       case a_FEH:
-           tempc = a_m_FEH;
-           break;
-       case a_QAF:
-           tempc = a_m_QAF;
-           break;
-       case a_KAF:
-           tempc = a_m_KAF;
-           break;
-       case a_LAM:
-           tempc = a_m_LAM;
-           break;
-       case a_MEEM:
-           tempc = a_m_MEEM;
-           break;
-       case a_NOON:
-           tempc = a_m_NOON;
-           break;
-       case a_HEH:
-           tempc = a_m_HEH;
-           break;
-       case a_WAW:                     /* exception */
-           tempc = a_f_WAW;
-           break;
-       case a_ALEF_MAKSURA:            /* exception */
-           tempc = a_f_ALEF_MAKSURA;
-           break;
-       case a_YEH:
-           tempc = a_m_YEH;
-           break;
-       default:
-           tempc = 0;
+       case a_HAMZA: return a_s_HAMZA; /* exception */
+       case a_ALEF_MADDA: return a_f_ALEF_MADDA;       /* exception */
+       case a_ALEF_HAMZA_ABOVE: return a_f_ALEF_HAMZA_ABOVE;   /* exception */
+       case a_WAW_HAMZA: return a_f_WAW_HAMZA; /* exception */
+       case a_ALEF_HAMZA_BELOW: return a_f_ALEF_HAMZA_BELOW;   /* exception */
+       case a_YEH_HAMZA: return a_m_YEH_HAMZA;
+       case a_ALEF: return a_f_ALEF;   /* exception */
+       case a_BEH: return a_m_BEH;
+       case a_TEH_MARBUTA: return a_f_TEH_MARBUTA;     /* exception */
+       case a_TEH: return a_m_TEH;
+       case a_THEH: return a_m_THEH;
+       case a_JEEM: return a_m_JEEM;
+       case a_HAH: return a_m_HAH;
+       case a_KHAH: return a_m_KHAH;
+       case a_DAL: return a_f_DAL;     /* exception */
+       case a_THAL: return a_f_THAL;   /* exception */
+       case a_REH: return a_f_REH;     /* exception */
+       case a_ZAIN: return a_f_ZAIN;   /* exception */
+       case a_SEEN: return a_m_SEEN;
+       case a_SHEEN: return a_m_SHEEN;
+       case a_SAD: return a_m_SAD;
+       case a_DAD: return a_m_DAD;
+       case a_TAH: return a_m_TAH;
+       case a_ZAH: return a_m_ZAH;
+       case a_AIN: return a_m_AIN;
+       case a_GHAIN: return a_m_GHAIN;
+       case a_TATWEEL: return cur_c;   /* exception */
+       case a_FEH: return a_m_FEH;
+       case a_QAF: return a_m_QAF;
+       case a_KAF: return a_m_KAF;
+       case a_LAM: return a_m_LAM;
+       case a_MEEM: return a_m_MEEM;
+       case a_NOON: return a_m_NOON;
+       case a_HEH: return a_m_HEH;
+       case a_WAW: return a_f_WAW;     /* exception */
+       case a_ALEF_MAKSURA: return a_f_ALEF_MAKSURA;   /* exception */
+       case a_YEH: return a_m_YEH;
     }
-
-    return tempc;
+    return 0;
 }
 
 
@@ -587,224 +366,96 @@ chg_c_a2m(int cur_c)
     static int
 chg_c_a2f(int cur_c)
 {
-    int tempc;
-
     /* NOTE: these encodings need to be accounted for
-
-       a_f_ALEF_MADDA;
-       a_f_ALEF_HAMZA_ABOVE;
-       a_f_ALEF_HAMZA_BELOW;
-       a_f_LAM_ALEF_MADDA_ABOVE;
-       a_f_LAM_ALEF_HAMZA_ABOVE;
-       a_f_LAM_ALEF_HAMZA_BELOW;
-       */
-
+     * a_f_ALEF_MADDA;
+     * a_f_ALEF_HAMZA_ABOVE;
+     * a_f_ALEF_HAMZA_BELOW;
+     * a_f_LAM_ALEF_MADDA_ABOVE;
+     * a_f_LAM_ALEF_HAMZA_ABOVE;
+     * a_f_LAM_ALEF_HAMZA_BELOW;
+     */
     switch (cur_c)
     {
-       case a_HAMZA:                   /* exception */
-           tempc = a_s_HAMZA;
-           break;
-       case a_ALEF_MADDA:
-           tempc = a_f_ALEF_MADDA;
-           break;
-       case a_ALEF_HAMZA_ABOVE:
-           tempc = a_f_ALEF_HAMZA_ABOVE;
-           break;
-       case a_WAW_HAMZA:
-           tempc = a_f_WAW_HAMZA;
-           break;
-       case a_ALEF_HAMZA_BELOW:
-           tempc = a_f_ALEF_HAMZA_BELOW;
-           break;
-       case a_YEH_HAMZA:
-           tempc = a_f_YEH_HAMZA;
-           break;
-       case a_ALEF:
-           tempc = a_f_ALEF;
-           break;
-       case a_BEH:
-           tempc = a_f_BEH;
-           break;
-       case a_TEH_MARBUTA:
-           tempc = a_f_TEH_MARBUTA;
-           break;
-       case a_TEH:
-           tempc = a_f_TEH;
-           break;
-       case a_THEH:
-           tempc = a_f_THEH;
-           break;
-       case a_JEEM:
-           tempc = a_f_JEEM;
-           break;
-       case a_HAH:
-           tempc = a_f_HAH;
-           break;
-       case a_KHAH:
-           tempc = a_f_KHAH;
-           break;
-       case a_DAL:
-           tempc = a_f_DAL;
-           break;
-       case a_THAL:
-           tempc = a_f_THAL;
-           break;
-       case a_REH:
-           tempc = a_f_REH;
-           break;
-       case a_ZAIN:
-           tempc = a_f_ZAIN;
-           break;
-       case a_SEEN:
-           tempc = a_f_SEEN;
-           break;
-       case a_SHEEN:
-           tempc = a_f_SHEEN;
-           break;
-       case a_SAD:
-           tempc = a_f_SAD;
-           break;
-       case a_DAD:
-           tempc = a_f_DAD;
-           break;
-       case a_TAH:
-           tempc = a_f_TAH;
-           break;
-       case a_ZAH:
-           tempc = a_f_ZAH;
-           break;
-       case a_AIN:
-           tempc = a_f_AIN;
-           break;
-       case a_GHAIN:
-           tempc = a_f_GHAIN;
-           break;
-       case a_TATWEEL:                 /* exception */
-           tempc = cur_c;
-           break;
-       case a_FEH:
-           tempc = a_f_FEH;
-           break;
-       case a_QAF:
-           tempc = a_f_QAF;
-           break;
-       case a_KAF:
-           tempc = a_f_KAF;
-           break;
-       case a_LAM:
-           tempc = a_f_LAM;
-           break;
-       case a_MEEM:
-           tempc = a_f_MEEM;
-           break;
-       case a_NOON:
-           tempc = a_f_NOON;
-           break;
-       case a_HEH:
-           tempc = a_f_HEH;
-           break;
-       case a_WAW:
-           tempc = a_f_WAW;
-           break;
-       case a_ALEF_MAKSURA:
-           tempc = a_f_ALEF_MAKSURA;
-           break;
-       case a_YEH:
-           tempc = a_f_YEH;
-           break;
-       default:
-           tempc = 0;
+       case a_HAMZA: return a_s_HAMZA; /* exception */
+       case a_ALEF_MADDA: return a_f_ALEF_MADDA;
+       case a_ALEF_HAMZA_ABOVE: return a_f_ALEF_HAMZA_ABOVE;
+       case a_WAW_HAMZA: return a_f_WAW_HAMZA;
+       case a_ALEF_HAMZA_BELOW: return a_f_ALEF_HAMZA_BELOW;
+       case a_YEH_HAMZA: return a_f_YEH_HAMZA;
+       case a_ALEF: return a_f_ALEF;
+       case a_BEH: return a_f_BEH;
+       case a_TEH_MARBUTA: return a_f_TEH_MARBUTA;
+       case a_TEH: return a_f_TEH;
+       case a_THEH: return a_f_THEH;
+       case a_JEEM: return a_f_JEEM;
+       case a_HAH: return a_f_HAH;
+       case a_KHAH: return a_f_KHAH;
+       case a_DAL: return a_f_DAL;
+       case a_THAL: return a_f_THAL;
+       case a_REH: return a_f_REH;
+       case a_ZAIN: return a_f_ZAIN;
+       case a_SEEN: return a_f_SEEN;
+       case a_SHEEN: return a_f_SHEEN;
+       case a_SAD: return a_f_SAD;
+       case a_DAD: return a_f_DAD;
+       case a_TAH: return a_f_TAH;
+       case a_ZAH: return a_f_ZAH;
+       case a_AIN: return a_f_AIN;
+       case a_GHAIN: return a_f_GHAIN;
+       case a_TATWEEL: return cur_c;   /* exception */
+       case a_FEH: return a_f_FEH;
+       case a_QAF: return a_f_QAF;
+       case a_KAF: return a_f_KAF;
+       case a_LAM: return a_f_LAM;
+       case a_MEEM: return a_f_MEEM;
+       case a_NOON: return a_f_NOON;
+       case a_HEH: return a_f_HEH;
+       case a_WAW: return a_f_WAW;
+       case a_ALEF_MAKSURA: return a_f_ALEF_MAKSURA;
+       case a_YEH: return a_f_YEH;
     }
-
-    return tempc;
+    return 0;
 }
 
 
 /*
  * Change shape - from Initial to Medial
+ * This code is unreachable, because for the relevant characters ARABIC_CHAR()
+ * is FALSE;
  */
+#if 0
     static int
 chg_c_i2m(int cur_c)
 {
-    int tempc;
-
     switch (cur_c)
     {
-       case a_i_YEH_HAMZA:
-           tempc = a_m_YEH_HAMZA;
-           break;
-       case a_i_BEH:
-           tempc = a_m_BEH;
-           break;
-       case a_i_TEH:
-           tempc = a_m_TEH;
-           break;
-       case a_i_THEH:
-           tempc = a_m_THEH;
-           break;
-       case a_i_JEEM:
-           tempc = a_m_JEEM;
-           break;
-       case a_i_HAH:
-           tempc = a_m_HAH;
-           break;
-       case a_i_KHAH:
-           tempc = a_m_KHAH;
-           break;
-       case a_i_SEEN:
-           tempc = a_m_SEEN;
-           break;
-       case a_i_SHEEN:
-           tempc = a_m_SHEEN;
-           break;
-       case a_i_SAD:
-           tempc = a_m_SAD;
-           break;
-       case a_i_DAD:
-           tempc = a_m_DAD;
-           break;
-       case a_i_TAH:
-           tempc = a_m_TAH;
-           break;
-       case a_i_ZAH:
-           tempc = a_m_ZAH;
-           break;
-       case a_i_AIN:
-           tempc = a_m_AIN;
-           break;
-       case a_i_GHAIN:
-           tempc = a_m_GHAIN;
-           break;
-       case a_i_FEH:
-           tempc = a_m_FEH;
-           break;
-       case a_i_QAF:
-           tempc = a_m_QAF;
-           break;
-       case a_i_KAF:
-           tempc = a_m_KAF;
-           break;
-       case a_i_LAM:
-           tempc = a_m_LAM;
-           break;
-       case a_i_MEEM:
-           tempc = a_m_MEEM;
-           break;
-       case a_i_NOON:
-           tempc = a_m_NOON;
-           break;
-       case a_i_HEH:
-           tempc = a_m_HEH;
-           break;
-       case a_i_YEH:
-           tempc = a_m_YEH;
-           break;
-       default:
-           tempc = 0;
+       case a_i_YEH_HAMZA: return a_m_YEH_HAMZA;
+       case a_i_BEH: return a_m_BEH;
+       case a_i_TEH: return a_m_TEH;
+       case a_i_THEH: return a_m_THEH;
+       case a_i_JEEM: return a_m_JEEM;
+       case a_i_HAH: return a_m_HAH;
+       case a_i_KHAH: return a_m_KHAH;
+       case a_i_SEEN: return a_m_SEEN;
+       case a_i_SHEEN: return a_m_SHEEN;
+       case a_i_SAD: return a_m_SAD;
+       case a_i_DAD: return a_m_DAD;
+       case a_i_TAH: return a_m_TAH;
+       case a_i_ZAH: return a_m_ZAH;
+       case a_i_AIN: return a_m_AIN;
+       case a_i_GHAIN: return a_m_GHAIN;
+       case a_i_FEH: return a_m_FEH;
+       case a_i_QAF: return a_m_QAF;
+       case a_i_KAF: return a_m_KAF;
+       case a_i_LAM: return a_m_LAM;
+       case a_i_MEEM: return a_m_MEEM;
+       case a_i_NOON: return a_m_NOON;
+       case a_i_HEH: return a_m_HEH;
+       case a_i_YEH: return a_m_YEH;
     }
-
-    return tempc;
+    return 0;
 }
+#endif
 
 
 /*
@@ -813,18 +464,14 @@ chg_c_i2m(int cur_c)
     static int
 chg_c_f2m(int cur_c)
 {
-    int tempc;
-
     switch (cur_c)
     {
        /* NOTE: these encodings are multi-positional, no ?
-          case a_f_ALEF_MADDA:
-          case a_f_ALEF_HAMZA_ABOVE:
-          case a_f_ALEF_HAMZA_BELOW:
-          */
-       case a_f_YEH_HAMZA:
-           tempc = a_m_YEH_HAMZA;
-           break;
+        * case a_f_ALEF_MADDA:
+        * case a_f_ALEF_HAMZA_ABOVE:
+        * case a_f_ALEF_HAMZA_BELOW:
+        */
+       case a_f_YEH_HAMZA: return a_m_YEH_HAMZA;
        case a_f_WAW_HAMZA:             /* exceptions */
        case a_f_ALEF:
        case a_f_TEH_MARBUTA:
@@ -834,85 +481,38 @@ chg_c_f2m(int cur_c)
        case a_f_ZAIN:
        case a_f_WAW:
        case a_f_ALEF_MAKSURA:
-           tempc = cur_c;
-           break;
-       case a_f_BEH:
-           tempc = a_m_BEH;
-           break;
-       case a_f_TEH:
-           tempc = a_m_TEH;
-           break;
-       case a_f_THEH:
-           tempc = a_m_THEH;
-           break;
-       case a_f_JEEM:
-           tempc = a_m_JEEM;
-           break;
-       case a_f_HAH:
-           tempc = a_m_HAH;
-           break;
-       case a_f_KHAH:
-           tempc = a_m_KHAH;
-           break;
-       case a_f_SEEN:
-           tempc = a_m_SEEN;
-           break;
-       case a_f_SHEEN:
-           tempc = a_m_SHEEN;
-           break;
-       case a_f_SAD:
-           tempc = a_m_SAD;
-           break;
-       case a_f_DAD:
-           tempc = a_m_DAD;
-           break;
-       case a_f_TAH:
-           tempc = a_m_TAH;
-           break;
-       case a_f_ZAH:
-           tempc = a_m_ZAH;
-           break;
-       case a_f_AIN:
-           tempc = a_m_AIN;
-           break;
-       case a_f_GHAIN:
-           tempc = a_m_GHAIN;
-           break;
-       case a_f_FEH:
-           tempc = a_m_FEH;
-           break;
-       case a_f_QAF:
-           tempc = a_m_QAF;
-           break;
-       case a_f_KAF:
-           tempc = a_m_KAF;
-           break;
-       case a_f_LAM:
-           tempc = a_m_LAM;
-           break;
-       case a_f_MEEM:
-           tempc = a_m_MEEM;
-           break;
-       case a_f_NOON:
-           tempc = a_m_NOON;
-           break;
-       case a_f_HEH:
-           tempc = a_m_HEH;
-           break;
-       case a_f_YEH:
-           tempc = a_m_YEH;
-           break;
-           /* NOTE: these encodings are multi-positional, no ?
-               case a_f_LAM_ALEF_MADDA_ABOVE:
-               case a_f_LAM_ALEF_HAMZA_ABOVE:
-               case a_f_LAM_ALEF_HAMZA_BELOW:
-               case a_f_LAM_ALEF:
-               */
-       default:
-           tempc = 0;
-    }
+               return cur_c;
+       case a_f_BEH: return a_m_BEH;
+       case a_f_TEH: return a_m_TEH;
+       case a_f_THEH: return a_m_THEH;
+       case a_f_JEEM: return a_m_JEEM;
+       case a_f_HAH: return a_m_HAH;
+       case a_f_KHAH: return a_m_KHAH;
+       case a_f_SEEN: return a_m_SEEN;
+       case a_f_SHEEN: return a_m_SHEEN;
+       case a_f_SAD: return a_m_SAD;
+       case a_f_DAD: return a_m_DAD;
+       case a_f_TAH: return a_m_TAH;
+       case a_f_ZAH: return a_m_ZAH;
+       case a_f_AIN: return a_m_AIN;
+       case a_f_GHAIN: return a_m_GHAIN;
+       case a_f_FEH: return a_m_FEH;
+       case a_f_QAF: return a_m_QAF;
+       case a_f_KAF: return a_m_KAF;
+       case a_f_LAM: return a_m_LAM;
+       case a_f_MEEM: return a_m_MEEM;
+       case a_f_NOON: return a_m_NOON;
+       case a_f_HEH: return a_m_HEH;
+       case a_f_YEH: return a_m_YEH;
 
-    return tempc;
+       /* NOTE: these encodings are multi-positional, no ?
+        * case a_f_LAM_ALEF_MADDA_ABOVE:
+        * case a_f_LAM_ALEF_HAMZA_ABOVE:
+        * case a_f_LAM_ALEF_HAMZA_BELOW:
+        * case a_f_LAM_ALEF:
+        */
+    }
+    return 0;
 }
 
 
@@ -922,27 +522,14 @@ chg_c_f2m(int cur_c)
     static int
 chg_c_laa2i(int hid_c)
 {
-    int tempc;
-
     switch (hid_c)
     {
-       case a_ALEF_MADDA:
-           tempc = a_s_LAM_ALEF_MADDA_ABOVE;
-           break;
-       case a_ALEF_HAMZA_ABOVE:
-           tempc = a_s_LAM_ALEF_HAMZA_ABOVE;
-           break;
-       case a_ALEF_HAMZA_BELOW:
-           tempc = a_s_LAM_ALEF_HAMZA_BELOW;
-           break;
-       case a_ALEF:
-           tempc = a_s_LAM_ALEF;
-           break;
-       default:
-           tempc = 0;
+       case a_ALEF_MADDA: return a_s_LAM_ALEF_MADDA_ABOVE;
+       case a_ALEF_HAMZA_ABOVE: return a_s_LAM_ALEF_HAMZA_ABOVE;
+       case a_ALEF_HAMZA_BELOW: return a_s_LAM_ALEF_HAMZA_BELOW;
+       case a_ALEF: return a_s_LAM_ALEF;
     }
-
-    return tempc;
+    return 0;
 }
 
 
@@ -952,27 +539,14 @@ chg_c_laa2i(int hid_c)
     static int
 chg_c_laa2f(int hid_c)
 {
-    int tempc;
-
     switch (hid_c)
     {
-       case a_ALEF_MADDA:
-           tempc = a_f_LAM_ALEF_MADDA_ABOVE;
-           break;
-       case a_ALEF_HAMZA_ABOVE:
-           tempc = a_f_LAM_ALEF_HAMZA_ABOVE;
-           break;
-       case a_ALEF_HAMZA_BELOW:
-           tempc = a_f_LAM_ALEF_HAMZA_BELOW;
-           break;
-       case a_ALEF:
-           tempc = a_f_LAM_ALEF;
-           break;
-       default:
-           tempc = 0;
+       case a_ALEF_MADDA: return a_f_LAM_ALEF_MADDA_ABOVE;
+       case a_ALEF_HAMZA_ABOVE: return a_f_LAM_ALEF_HAMZA_ABOVE;
+       case a_ALEF_HAMZA_BELOW: return a_f_LAM_ALEF_HAMZA_BELOW;
+       case a_ALEF: return a_f_LAM_ALEF;
     }
-
-    return tempc;
+    return 0;
 }
 
 /*
@@ -1040,7 +614,11 @@ arabic_shape(
     else if (!shape_c || A_is_f(shape_c) || A_is_s(shape_c) || prev_laa)
        curr_c = A_is_valid(next_c) ? chg_c_a2i(c) : chg_c_a2s(c);
     else if (A_is_valid(next_c))
+#if 0
        curr_c = A_is_iso(c) ? chg_c_a2m(c) : chg_c_i2m(c);
+#else
+       curr_c = A_is_iso(c) ? chg_c_a2m(c) : 0;
+#endif
     else if (A_is_valid(prev_c))
        curr_c = chg_c_a2f(c);
     else
index fa7c108..8a584c2 100644 (file)
@@ -1,4 +1,4 @@
-the first targets to make vim are: scratch config myself
+the first target to make vim is: reconfig
 srcdir = .
 VIMNAME = vim
 EXNAME = ex
index 27aea9c..e9c2c34 100755 (executable)
@@ -3446,7 +3446,7 @@ ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
-       ac_ext=c
+               ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
@@ -3723,7 +3723,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
 
 fi
 rm -f conftest*
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
 $as_echo_n "checking for fgrep... " >&6; }
 if ${ac_cv_path_FGREP+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -3789,7 +3789,7 @@ fi
 $as_echo "$ac_cv_path_FGREP" >&6; }
  FGREP="$ac_cv_path_FGREP"
 
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing strerror" >&5
+               { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing strerror" >&5
 $as_echo_n "checking for library containing strerror... " >&6; }
 if ${ac_cv_search_strerror+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -3844,7 +3844,7 @@ if test "$ac_res" != no; then :
   test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
 
 fi
-       for ac_prog in gawk mawk nawk awk
+               for ac_prog in gawk mawk nawk awk
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
@@ -4114,9 +4114,9 @@ if test "$GCC" = yes; then
   fi
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for recent clang version" >&5
-$as_echo_n "checking for recent clang version... " >&6; }
-CLANG_VERSION_STRING=`$CC --version 2>/dev/null | sed  -n -e 's/^.*clang.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*$/\1/p'`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for clang version" >&5
+$as_echo_n "checking for clang version... " >&6; }
+CLANG_VERSION_STRING=`$CC --version 2>/dev/null | sed  -n -e 's/^.*clang[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*$/\1/p'`
 if test x"$CLANG_VERSION_STRING" != x"" ; then
   CLANG_MAJOR=`echo "$CLANG_VERSION_STRING" | sed -n -e 's/\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*/\1/p'`
   CLANG_MINOR=`echo "$CLANG_VERSION_STRING" | sed -n -e 's/[0-9][0-9]*\.\([0-9][0-9]*\)\.[0-9][0-9]*/\1/p'`
@@ -4124,12 +4124,19 @@ if test x"$CLANG_VERSION_STRING" != x"" ; then
   CLANG_VERSION=`expr $CLANG_MAJOR '*' 1000000 '+' $CLANG_MINOR '*' 1000 '+' $CLANG_REVISION`
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CLANG_VERSION" >&5
 $as_echo "$CLANG_VERSION" >&6; }
-          if test "$CLANG_VERSION" -ge 500002075 ; then
-    CFLAGS=`echo "$CFLAGS" | sed -n -e 's/-fno-strength-reduce/ /p'`
+          { $as_echo "$as_me:${as_lineno-$LINENO}: checking if clang supports -fno-strength-reduce" >&5
+$as_echo_n "checking if clang supports -fno-strength-reduce... " >&6; }
+  if test "$CLANG_VERSION" -ge 500002075 ; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    CFLAGS=`echo "$CFLAGS" | sed -e 's/-fno-strength-reduce/ /'`
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
   fi
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: N/A" >&5
+$as_echo "N/A" >&6; }
 fi
 
 CROSS_COMPILING=
@@ -7411,7 +7418,7 @@ $as_echo_n "checking whether compiling with process communication is possible...
        /* Check bitfields */
        struct nbbuf {
        unsigned int  initDone:1;
-       ushort signmaplen;
+       unsigned short signmaplen;
        };
 
 int
 
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for /proc link to executable" >&5
+$as_echo_n "checking for /proc link to executable... " >&6; }
+if test -L "/proc/self/exe"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: /proc/self/exe" >&5
+$as_echo "/proc/self/exe" >&6; }
+  $as_echo "#define PROC_EXE_LINK \"/proc/self/exe\"" >>confdefs.h
+
+elif test -L "/proc/self/path/a.out"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: /proc/self/path/a.out" >&5
+$as_echo "/proc/self/path/a.out" >&6; }
+  $as_echo "#define PROC_EXE_LINK \"/proc/self/path/a.out\"" >>confdefs.h
+
+elif test -L "/proc/curproc/file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: /proc/curproc/file" >&5
+$as_echo "/proc/curproc/file" >&6; }
+  $as_echo "#define PROC_EXE_LINK \"/proc/curproc/file\"" >>confdefs.h
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CYGWIN or MSYS environment" >&5
 $as_echo_n "checking for CYGWIN or MSYS environment... " >&6; }
 case `uname` in
@@ -12000,10 +12029,10 @@ if test "x$vim_cv_getcwd_broken" = "xyes" ; then
 
 fi
 
-for ac_func in bcmp fchdir fchown fsync getcwd getpseudotty \
-       getpwent getpwnam getpwuid getrlimit gettimeofday getwd lstat memcmp \
+for ac_func in fchdir fchown fsync getcwd getpseudotty \
+       getpwent getpwnam getpwuid getrlimit gettimeofday getwd lstat \
        memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \
-       setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \
+       getpgid setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \
        sigprocmask sigvec strcasecmp strerror strftime stricmp strncasecmp \
        strnicmp strpbrk strtol tgetent towlower towupper iswupper \
        usleep utime utimes
index d3f5cff..eaf0b9e 100644 (file)
@@ -38,7 +38,7 @@ typedef union {
   /* MS-Windows is always little endian */
 #else
 # ifdef HAVE_CONFIG_H
-   /* in configure.in AC_C_BIGENDIAN() defines WORDS_BIGENDIAN when needed */
+   /* in configure.ac AC_C_BIGENDIAN() defines WORDS_BIGENDIAN when needed */
 # else
    error!
    Please change this code to define WORDS_BIGENDIAN for big-endian machines.
@@ -426,7 +426,7 @@ bf_key_init(
     keylen = (int)STRLEN(key) / 2;
     if (keylen == 0)
     {
-       EMSG(_("E831: bf_key_init() called with empty password"));
+       IEMSG(_("E831: bf_key_init() called with empty password"));
        return;
     }
     for (i = 0; i < keylen; i++)
index 8b1bceb..ac0f1e6 100644 (file)
@@ -111,18 +111,21 @@ read_buffer(
     {
        /* Set or reset 'modified' before executing autocommands, so that
         * it can be changed there. */
-       if (!readonlymode && !bufempty())
+       if (!readonlymode && !BUFEMPTY())
            changed();
-       else if (retval != FAIL)
+       else if (retval == OK)
            unchanged(curbuf, FALSE);
 
 #ifdef FEAT_AUTOCMD
+       if (retval == OK)
+       {
 # ifdef FEAT_EVAL
-       apply_autocmds_retval(EVENT_STDINREADPOST, NULL, NULL, FALSE,
+           apply_autocmds_retval(EVENT_STDINREADPOST, NULL, NULL, FALSE,
                                                        curbuf, &retval);
 # else
-       apply_autocmds(EVENT_STDINREADPOST, NULL, NULL, FALSE, curbuf);
+           apply_autocmds(EVENT_STDINREADPOST, NULL, NULL, FALSE, curbuf);
 # endif
+       }
 #endif
     }
     return retval;
@@ -294,7 +297,7 @@ open_buffer(
 #endif
        )
        changed();
-    else if (retval != FAIL && !read_stdin && !read_fifo)
+    else if (retval == OK && !read_stdin && !read_fifo)
        unchanged(curbuf, FALSE);
     save_file_ff(curbuf);              /* keep this fileformat */
 
@@ -328,7 +331,7 @@ open_buffer(
 # endif
 #endif
 
-    if (retval != FAIL)
+    if (retval == OK)
     {
 #ifdef FEAT_AUTOCMD
        /*
@@ -870,6 +873,25 @@ free_buffer(buf_T *buf)
 }
 
 /*
+ * Initializes b:changedtick.
+ */
+    static void
+init_changedtick(buf_T *buf)
+{
+    dictitem_T *di = (dictitem_T *)&buf->b_ct_di;
+
+    di->di_flags = DI_FLAGS_FIX | DI_FLAGS_RO;
+    di->di_tv.v_type = VAR_NUMBER;
+    di->di_tv.v_lock = VAR_FIXED;
+    di->di_tv.vval.v_number = 0;
+
+#ifdef FEAT_EVAL
+    STRCPY(buf->b_ct_di.di_key, "changedtick");
+    (void)dict_add(buf->b_vars, di);
+#endif
+}
+
+/*
  * Free stuff in the buffer for ":bdel" and when wiping out the buffer.
  */
     static void
@@ -886,8 +908,14 @@ free_buffer_stuff(
 #endif
     }
 #ifdef FEAT_EVAL
-    vars_clear(&buf->b_vars->dv_hashtab); /* free all internal variables */
-    hash_init(&buf->b_vars->dv_hashtab);
+    {
+       varnumber_T tick = CHANGEDTICK(buf);
+
+       vars_clear(&buf->b_vars->dv_hashtab); /* free all buffer variables */
+       hash_init(&buf->b_vars->dv_hashtab);
+       init_changedtick(buf);
+       CHANGEDTICK(buf) = tick;
+    }
 #endif
 #ifdef FEAT_USR_CMDS
     uc_clear(&buf->b_ucmds);           /* clear local user commands */
@@ -1412,7 +1440,7 @@ do_buffer(
 # ifdef FEAT_AUTOCMD
                   && !(curwin->w_closing || curwin->w_buffer->b_locked > 0)
 # endif
-                  && (firstwin != lastwin || first_tabpage->tp_next != NULL))
+                  && (!ONE_WINDOW || first_tabpage->tp_next != NULL))
        {
            if (win_close(curwin, FALSE) == FAIL)
                break;
@@ -1931,7 +1959,7 @@ buflist_new(
            && curbuf != NULL
            && curbuf->b_ffname == NULL
            && curbuf->b_nwindows <= 1
-           && (curbuf->b_ml.ml_mfp == NULL || bufempty()))
+           && (curbuf->b_ml.ml_mfp == NULL || BUFEMPTY()))
     {
        buf = curbuf;
 #ifdef FEAT_AUTOCMD
@@ -1976,6 +2004,7 @@ buflist_new(
        }
        init_var_dict(buf->b_vars, &buf->b_bufvar, VAR_SCOPE);
 #endif
+       init_changedtick(buf);
     }
 
     if (ffname != NULL)
@@ -2150,6 +2179,7 @@ free_buf_options(
 #if defined(FEAT_CRYPT)
     clear_string_option(&buf->b_p_cm);
 #endif
+    clear_string_option(&buf->b_p_fp);
 #if defined(FEAT_EVAL)
     clear_string_option(&buf->b_p_fex);
 #endif
@@ -2225,6 +2255,9 @@ free_buf_options(
     clear_string_option(&buf->b_p_lw);
 #endif
     clear_string_option(&buf->b_p_bkc);
+#ifdef FEAT_MBYTE
+    clear_string_option(&buf->b_p_menc);
+#endif
 }
 
 /*
@@ -2301,7 +2334,7 @@ buflist_getfile(
        /* If 'switchbuf' contains "split", "vsplit" or "newtab" and the
         * current buffer isn't empty: open new tab or window */
        if (wp == NULL && (swb_flags & (SWB_VSPLIT | SWB_SPLIT | SWB_NEWTAB))
-                                                              && !bufempty())
+                                                              && !BUFEMPTY())
        {
            if (swb_flags & SWB_NEWTAB)
                tabpage_new();
@@ -2966,7 +2999,7 @@ buflist_findlnum(buf_T *buf)
 
 #if defined(FEAT_LISTCMDS) || defined(PROTO)
 /*
- * List all know file names (for :files and :buffers command).
+ * List all known file names (for :files and :buffers command).
  */
     void
 buflist_list(exarg_T *eap)
@@ -4858,8 +4891,8 @@ do_arg_all(
            wpnext = wp->w_next;
            buf = wp->w_buffer;
            if (buf->b_ffname == NULL
-                   || (!keep_tabs && buf->b_nwindows > 1)
-                   || wp->w_width != Columns)
+                   || (!keep_tabs && (buf->b_nwindows > 1
+                           || wp->w_width != Columns)))
                i = opened_len;
            else
            {
@@ -4984,7 +5017,7 @@ do_arg_all(
 #ifdef FEAT_WINDOWS
     /* ":drop all" should re-use an empty window to avoid "--remote-tab"
      * leaving an empty tab page when executed locally. */
-    if (keep_tabs && bufempty() && curbuf->b_nwindows == 1
+    if (keep_tabs && BUFEMPTY() && curbuf->b_nwindows == 1
                            && curbuf->b_ffname == NULL && !curbuf->b_changed)
        use_firstwin = TRUE;
 #endif
@@ -5140,7 +5173,7 @@ ex_buffer_all(exarg_T *eap)
                        : wp->w_width != Columns)
                    || (had_tab > 0 && wp != firstwin)
 #endif
-                   ) && firstwin != lastwin
+                   ) && !ONE_WINDOW
 #ifdef FEAT_AUTOCMD
                    && !(wp->w_closing || wp->w_buffer->b_locked > 0)
 #endif
@@ -5988,7 +6021,7 @@ sign_list_placed(buf_T *rbuf)
        if (buf->b_signlist != NULL)
        {
            vim_snprintf(lbuf, BUFSIZ, _("Signs for %s:"), buf->b_fname);
-           MSG_PUTS_ATTR(lbuf, hl_attr(HLF_D));
+           MSG_PUTS_ATTR(lbuf, HL_ATTR(HLF_D));
            msg_putchar('\n');
        }
        for (p = buf->b_signlist; p != NULL && !got_int; p = p->next)
index 16156ce..54a141c 100644 (file)
@@ -19,7 +19,7 @@
 # define CH_HAS_GUI (gui.in_use || gui.starting)
 #endif
 
-/* Note: when making changes here also adjust configure.in. */
+/* Note: when making changes here also adjust configure.ac. */
 #ifdef WIN32
 /* WinSock API is separated from C API, thus we can't use read(), write(),
  * errno... */
@@ -710,7 +710,14 @@ channel_open(
        channel_free(channel);
        return NULL;
     }
-    memcpy((char *)&server.sin_addr, host->h_addr, host->h_length);
+    {
+       char            *p;
+
+       /* When using host->h_addr directly ubsan warns for it to not be
+        * aligned.  First copy the pointer to aviod that. */
+       memcpy(&p, &host->h_addr, sizeof(p));
+       memcpy((char *)&server.sin_addr, p, host->h_length);
+    }
 
     /* On Mac and Solaris a zero timeout almost never works.  At least wait
      * one millisecond. Let's do it for all systems, because we don't know why
@@ -1195,6 +1202,7 @@ channel_set_options(channel_T *channel, jobopt_T *opt)
     if (opt->jo_set & JO_CLOSE_CALLBACK)
        set_callback(&channel->ch_close_cb, &channel->ch_close_partial,
                opt->jo_close_cb, opt->jo_close_partial);
+    channel->ch_drop_never = opt->jo_drop_never;
 
     if ((opt->jo_set & JO_OUT_IO) && opt->jo_io[PART_OUT] == JIO_BUFFER)
     {
@@ -1341,7 +1349,7 @@ write_buf_line(buf_T *buf, linenr_T lnum, channel_T *channel)
 
     p[len] = NL;
     p[len + 1] = NUL;
-    channel_send(channel, PART_IN, p, len + 1, "write_buf_line()");
+    channel_send(channel, PART_IN, p, len + 1, "write_buf_line");
     vim_free(p);
 }
 
@@ -1566,7 +1574,7 @@ invoke_callback(channel_T *channel, char_u *callback, partial_T *partial,
     int                dummy;
 
     if (safe_to_invoke_callback == 0)
-       EMSG("INTERNAL: Invoking callback when it is not safe");
+       IEMSG("INTERNAL: Invoking callback when it is not safe");
 
     argv[0].v_type = VAR_CHANNEL;
     argv[0].vval.v_channel = channel;
@@ -1832,39 +1840,42 @@ channel_save(channel_T *channel, ch_part_T part, char_u *buf, int len,
     return OK;
 }
 
+/*
+ * Try to fill the buffer of "reader".
+ * Returns FALSE when nothing was added.
+ */
     static int
 channel_fill(js_read_T *reader)
 {
     channel_T  *channel = (channel_T *)reader->js_cookie;
     ch_part_T  part = reader->js_cookie_arg;
     char_u     *next = channel_get(channel, part);
-    int                unused;
-    int                len;
+    int                keeplen;
+    int                addlen;
     char_u     *p;
 
     if (next == NULL)
        return FALSE;
 
-    unused = reader->js_end - reader->js_buf - reader->js_used;
-    if (unused > 0)
+    keeplen = reader->js_end - reader->js_buf;
+    if (keeplen > 0)
     {
        /* Prepend unused text. */
-       len = (int)STRLEN(next);
-       p = alloc(unused + len + 1);
+       addlen = (int)STRLEN(next);
+       p = alloc(keeplen + addlen + 1);
        if (p == NULL)
        {
            vim_free(next);
            return FALSE;
        }
-       mch_memmove(p, reader->js_buf + reader->js_used, unused);
-       mch_memmove(p + unused, next, len + 1);
+       mch_memmove(p, reader->js_buf, keeplen);
+       mch_memmove(p + keeplen, next, addlen + 1);
        vim_free(next);
        next = p;
     }
 
     vim_free(reader->js_buf);
     reader->js_buf = next;
-    reader->js_used = 0;
     return TRUE;
 }
 
@@ -1895,9 +1906,12 @@ channel_parse_json(channel_T *channel, ch_part_T part)
 
     /* When a message is incomplete we wait for a short while for more to
      * arrive.  After the delay drop the input, otherwise a truncated string
-     * or list will make us hang.  */
+     * or list will make us hang.
+     * Do not generate error messages, they will be written in a channel log. */
+    ++emsg_silent;
     status = json_decode(&reader, &listtv,
                                  chanpart->ch_mode == MODE_JS ? JSON_JS : 0);
+    --emsg_silent;
     if (status == OK)
     {
        /* Only accept the response when it is a list with at least two
@@ -1918,6 +1932,7 @@ channel_parse_json(channel_T *channel, ch_part_T part)
                clear_tv(&listtv);
            else
            {
+               item->jq_no_callback = FALSE;
                item->jq_value = alloc_tv();
                if (item->jq_value == NULL)
                {
@@ -1940,16 +1955,20 @@ channel_parse_json(channel_T *channel, ch_part_T part)
     }
 
     if (status == OK)
-       chanpart->ch_waiting = FALSE;
+       chanpart->ch_wait_len = 0;
     else if (status == MAYBE)
     {
-       if (!chanpart->ch_waiting)
+       size_t buflen = STRLEN(reader.js_buf);
+
+       if (chanpart->ch_wait_len < buflen)
        {
-           /* First time encountering incomplete message, set a deadline of
-            * 100 msec. */
-           ch_log(channel, "Incomplete message - wait for more");
+           /* First time encountering incomplete message or after receiving
+            * more (but still incomplete): set a deadline of 100 msec. */
+           ch_logn(channel,
+                   "Incomplete message (%d bytes) - wait 100 msec for more",
+                   (int)buflen);
            reader.js_used = 0;
-           chanpart->ch_waiting = TRUE;
+           chanpart->ch_wait_len = buflen;
 #ifdef WIN32
            chanpart->ch_deadline = GetTickCount() + 100L;
 #else
@@ -1980,7 +1999,8 @@ channel_parse_json(channel_T *channel, ch_part_T part)
            if (timeout)
            {
                status = FAIL;
-               chanpart->ch_waiting = FALSE;
+               chanpart->ch_wait_len = 0;
+               ch_log(channel, "timed out");
            }
            else
            {
@@ -1994,7 +2014,7 @@ channel_parse_json(channel_T *channel, ch_part_T part)
     {
        ch_error(channel, "Decoding failed - discarding input");
        ret = FALSE;
-       chanpart->ch_waiting = FALSE;
+       chanpart->ch_wait_len = 0;
     }
     else if (reader.js_buf[reader.js_used] != NUL)
     {
@@ -2050,11 +2070,17 @@ remove_json_node(jsonq_T *head, jsonq_T *node)
  * When "id" is positive it must match the first number in the list.
  * When "id" is zero or negative jut get the first message.  But not the one
  * with id ch_block_id.
+ * When "without_callback" is TRUE also get messages that were pushed back.
  * Return OK when found and return the value in "rettv".
  * Return FAIL otherwise.
  */
     static int
-channel_get_json(channel_T *channel, ch_part_T part, int id, typval_T **rettv)
+channel_get_json(
+       channel_T   *channel,
+       ch_part_T   part,
+       int         id,
+       int         without_callback,
+       typval_T    **rettv)
 {
     jsonq_T   *head = &channel->ch_part[part].ch_json_head;
     jsonq_T   *item = head->jq_next;
@@ -2064,10 +2090,11 @@ channel_get_json(channel_T *channel, ch_part_T part, int id, typval_T **rettv)
        list_T      *l = item->jq_value->vval.v_list;
        typval_T    *tv = &l->lv_first->li_tv;
 
-       if ((id > 0 && tv->v_type == VAR_NUMBER && tv->vval.v_number == id)
+       if ((without_callback || !item->jq_no_callback)
+           && ((id > 0 && tv->v_type == VAR_NUMBER && tv->vval.v_number == id)
              || (id <= 0 && (tv->v_type != VAR_NUMBER
                 || tv->vval.v_number == 0
-                || tv->vval.v_number != channel->ch_part[part].ch_block_id)))
+                || tv->vval.v_number != channel->ch_part[part].ch_block_id))))
        {
            *rettv = item->jq_value;
            if (tv->v_type == VAR_NUMBER)
@@ -2080,6 +2107,65 @@ channel_get_json(channel_T *channel, ch_part_T part, int id, typval_T **rettv)
     return FAIL;
 }
 
+/*
+ * Put back "rettv" into the JSON queue, there was no callback for it.
+ * Takes over the values in "rettv".
+ */
+    static void
+channel_push_json(channel_T *channel, ch_part_T part, typval_T *rettv)
+{
+    jsonq_T   *head = &channel->ch_part[part].ch_json_head;
+    jsonq_T   *item = head->jq_next;
+    jsonq_T   *newitem;
+
+    if (head->jq_prev != NULL && head->jq_prev->jq_no_callback)
+       /* last item was pushed back, append to the end */
+       item = NULL;
+    else while (item != NULL && item->jq_no_callback)
+       /* append after the last item that was pushed back */
+       item = item->jq_next;
+
+    newitem = (jsonq_T *)alloc((unsigned)sizeof(jsonq_T));
+    if (newitem == NULL)
+       clear_tv(rettv);
+    else
+    {
+       newitem->jq_value = alloc_tv();
+       if (newitem->jq_value == NULL)
+       {
+           vim_free(newitem);
+           clear_tv(rettv);
+       }
+       else
+       {
+           newitem->jq_no_callback = FALSE;
+           *newitem->jq_value = *rettv;
+           if (item == NULL)
+           {
+               /* append to the end */
+               newitem->jq_prev = head->jq_prev;
+               head->jq_prev = newitem;
+               newitem->jq_next = NULL;
+               if (newitem->jq_prev == NULL)
+                   head->jq_next = newitem;
+               else
+                   newitem->jq_prev->jq_next = newitem;
+           }
+           else
+           {
+               /* append after "item" */
+               newitem->jq_prev = item;
+               newitem->jq_next = item->jq_next;
+               item->jq_next = newitem;
+               if (newitem->jq_next == NULL)
+                   head->jq_prev = newitem;
+               else
+                   newitem->jq_next->jq_prev = newitem;
+           }
+       }
+    }
+}
+
 #define CH_JSON_MAX_ARGS 4
 
 /*
@@ -2410,11 +2496,11 @@ may_invoke_callback(channel_T *channel, ch_part_T part)
        int             argc = 0;
 
        /* Get any json message in the queue. */
-       if (channel_get_json(channel, part, -1, &listtv) == FAIL)
+       if (channel_get_json(channel, part, -1, FALSE, &listtv) == FAIL)
        {
            /* Parse readahead, return when there is still no message. */
            channel_parse_json(channel, part);
-           if (channel_get_json(channel, part, -1, &listtv) == FAIL)
+           if (channel_get_json(channel, part, -1, FALSE, &listtv) == FAIL)
                return FALSE;
        }
 
@@ -2454,7 +2540,7 @@ may_invoke_callback(channel_T *channel, ch_part_T part)
        {
            /* If there is a close callback it may use ch_read() to get the
             * messages. */
-           if (channel->ch_close_cb == NULL)
+           if (channel->ch_close_cb == NULL && !channel->ch_drop_never)
                drop_messages(channel, part);
            return FALSE;
        }
@@ -2485,9 +2571,14 @@ may_invoke_callback(channel_T *channel, ch_part_T part)
            if (nl == NULL)
            {
                /* Flush remaining message that is missing a NL. */
-               buf = vim_realloc(buf, node->rq_buflen + 1);
-               if (buf == NULL)
+               char_u  *new_buf;
+
+               new_buf = vim_realloc(buf, node->rq_buflen + 1);
+               if (new_buf == NULL)
+                   /* This might fail over and over again, should the message
+                    * be dropped? */
                    return FALSE;
+               buf = new_buf;
                node->rq_buffer = buf;
                nl = buf + node->rq_buflen++;
                *nl = NUL;
@@ -2531,7 +2622,7 @@ may_invoke_callback(channel_T *channel, ch_part_T part)
     {
        int     done = FALSE;
 
-       /* invoke the one-time callback with the matching nr */
+       /* JSON or JS mode: invoke the one-time callback with the matching nr */
        for (cbitem = cbhead->cq_next; cbitem != NULL; cbitem = cbitem->cq_next)
            if (cbitem->cq_seq_nr == seq_nr)
            {
@@ -2540,7 +2631,17 @@ may_invoke_callback(channel_T *channel, ch_part_T part)
                break;
            }
        if (!done)
-           ch_logn(channel, "Dropping message %d without callback", seq_nr);
+       {
+           if (channel->ch_drop_never)
+           {
+               /* message must be read with ch_read() */
+               channel_push_json(channel, part, listtv);
+               listtv = NULL;
+           }
+           else
+               ch_logn(channel, "Dropping message %d without callback",
+                                                                      seq_nr);
+       }
     }
     else if (callback != NULL || buffer != NULL)
     {
@@ -2567,7 +2668,7 @@ may_invoke_callback(channel_T *channel, ch_part_T part)
        }
     }
     else
-       ch_log(channel, "Dropping message");
+       ch_logn(channel, "Dropping message %d", seq_nr);
 
     if (listtv != NULL)
        free_tv(listtv);
@@ -2603,7 +2704,7 @@ channel_is_open(channel_T *channel)
 /*
  * Return TRUE if "channel" has JSON or other typeahead.
  */
-    static int
+    int
 channel_has_readahead(channel_T *channel, ch_part_T part)
 {
     ch_mode_T  ch_mode = channel->ch_part[part].ch_mode;
@@ -2792,9 +2893,10 @@ channel_close(channel_T *channel, int invoke_close_cb)
              redraw_after_callback();
          }
 
-         /* any remaining messages are useless now */
-         for (part = PART_SOCK; part < PART_IN; ++part)
-             drop_messages(channel, part);
+         if (!channel->ch_drop_never)
+             /* any remaining messages are useless now */
+             for (part = PART_SOCK; part < PART_IN; ++part)
+                 drop_messages(channel, part);
     }
 
     channel->ch_nb_close_cb = NULL;
@@ -3091,9 +3193,9 @@ ch_close_part_on_error(
 channel_close_now(channel_T *channel)
 {
     ch_log(channel, "Closing channel because all readable fds are closed");
-    channel_close(channel, TRUE);
     if (channel->ch_nb_close_cb != NULL)
        (*channel->ch_nb_close_cb)();
+    channel_close(channel, TRUE);
 }
 
 /*
@@ -3202,6 +3304,7 @@ channel_read_block(channel_T *channel, ch_part_T part, int timeout)
        channel_read(channel, part, "channel_read_block");
     }
 
+    /* We have a complete message now. */
     if (mode == MODE_RAW)
     {
        msg = channel_get_all(channel, part);
@@ -3243,7 +3346,7 @@ channel_read_block(channel_T *channel, ch_part_T part, int timeout)
  * When "id" is -1 accept any message;
  * Blocks until the message is received or the timeout is reached.
  */
-    int
+    static int
 channel_read_json_block(
        channel_T   *channel,
        ch_part_T   part,
@@ -3264,7 +3367,7 @@ channel_read_json_block(
        more = channel_parse_json(channel, part);
 
        /* search for message "id" */
-       if (channel_get_json(channel, part, id, rettv) == OK)
+       if (channel_get_json(channel, part, id, TRUE, rettv) == OK)
        {
            chanpart->ch_block_id = 0;
            return OK;
@@ -3280,7 +3383,7 @@ channel_read_json_block(
            /* Wait for up to the timeout.  If there was an incomplete message
             * use the deadline for that. */
            timeout = timeout_arg;
-           if (chanpart->ch_waiting)
+           if (chanpart->ch_wait_len > 0)
            {
 #ifdef WIN32
                timeout = chanpart->ch_deadline - GetTickCount() + 1;
@@ -3300,7 +3403,7 @@ channel_read_json_block(
                {
                    /* Something went wrong, channel_parse_json() didn't
                     * discard message.  Cancel waiting. */
-                   chanpart->ch_waiting = FALSE;
+                   chanpart->ch_wait_len = 0;
                    timeout = timeout_arg;
                }
                else if (timeout > timeout_arg)
@@ -3450,7 +3553,12 @@ channel_handle_events(void)
  * Return FAIL or OK.
  */
     int
-channel_send(channel_T *channel, ch_part_T part, char_u *buf, int len, char *fun)
+channel_send(
+       channel_T *channel,
+       ch_part_T part,
+       char_u    *buf,
+       int       len,
+       char      *fun)
 {
     int                res;
     sock_T     fd;
@@ -3810,6 +3918,11 @@ channel_parse_messages(void)
     int                ret = FALSE;
     int                r;
     ch_part_T  part = PART_SOCK;
+#ifdef ELAPSED_FUNC
+    ELAPSED_TYPE  start_tv;
+
+    ELAPSED_INIT(start_tv);
+#endif
 
     ++safe_to_invoke_callback;
 
@@ -3854,7 +3967,14 @@ channel_parse_messages(void)
            r = may_invoke_callback(channel, part);
            if (r == OK)
                ret = TRUE;
-           if (channel_unref(channel) || r == OK)
+           if (channel_unref(channel) || (r == OK
+#ifdef ELAPSED_FUNC
+                       /* Limit the time we loop here to 100 msec, otherwise
+                        * Vim becomes unresponsive when the callback takes
+                        * more than a bit of time. */
+                       && ELAPSED_FUNC(start_tv) < 100L
+#endif
+                       ))
            {
                /* channel was freed or something was done, start over */
                channel = first_channel;
@@ -3883,6 +4003,31 @@ channel_parse_messages(void)
 }
 
 /*
+ * Return TRUE if any channel has readahead.  That means we should not block on
+ * waiting for input.
+ */
+    int
+channel_any_readahead(void)
+{
+    channel_T  *channel = first_channel;
+    ch_part_T  part = PART_SOCK;
+
+    while (channel != NULL)
+    {
+       if (channel_has_readahead(channel, part))
+           return TRUE;
+       if (part < PART_ERR)
+           ++part;
+       else
+       {
+           channel = channel->ch_next;
+           part = PART_SOCK;
+       }
+    }
+    return FALSE;
+}
+
+/*
  * Mark references to lists used in channels.
  */
     int
@@ -4248,6 +4393,20 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported)
                    return FAIL;
                }
            }
+           else if (STRCMP(hi->hi_key, "drop") == 0)
+           {
+               int never = FALSE;
+               val = get_tv_string(item);
+
+               if (STRCMP(val, "never") == 0)
+                   never = TRUE;
+               else if (STRCMP(val, "auto") != 0)
+               {
+                   EMSG2(_(e_invarg2), "drop");
+                   return FAIL;
+               }
+               opt->jo_drop_never = never;
+           }
            else if (STRCMP(hi->hi_key, "exit_cb") == 0)
            {
                if (!(supported & JO_EXIT_CB))
@@ -4428,19 +4587,66 @@ job_free(job_T *job)
     }
 }
 
+#if defined(EXITFREE) || defined(PROTO)
+    void
+job_free_all(void)
+{
+    while (first_job != NULL)
+       job_free(first_job);
+}
+#endif
+
+/*
+ * Return TRUE if we need to check if the process of "job" has ended.
+ */
+    static int
+job_need_end_check(job_T *job)
+{
+    return job->jv_status == JOB_STARTED
+                  && (job->jv_stoponexit != NULL || job->jv_exit_cb != NULL);
+}
+
+/*
+ * Return TRUE if the channel of "job" is still useful.
+ */
+    static int
+job_channel_still_useful(job_T *job)
+{
+    return job->jv_channel != NULL && channel_still_useful(job->jv_channel);
+}
+
+/*
+ * Return TRUE if the job should not be freed yet.  Do not free the job when
+ * it has not ended yet and there is a "stoponexit" flag, an exit callback
+ * or when the associated channel will do something with the job output.
+ */
+    static int
+job_still_useful(job_T *job)
+{
+    return job_need_end_check(job) || job_channel_still_useful(job);
+}
+
+/*
+ * NOTE: Must call job_cleanup() only once right after the status of "job"
+ * changed to JOB_ENDED (i.e. after job_status() returned "dead" first or
+ * mch_detect_ended_job() returned non-NULL).
+ */
     static void
 job_cleanup(job_T *job)
 {
     if (job->jv_status != JOB_ENDED)
        return;
 
+    /* Ready to cleanup the job. */
+    job->jv_status = JOB_FINISHED;
+
     if (job->jv_exit_cb != NULL)
     {
        typval_T        argv[3];
        typval_T        rettv;
        int             dummy;
 
-       /* invoke the exit callback; make sure the refcount is > 0 */
+       /* Invoke the exit callback. Make sure the refcount is > 0. */
        ++job->jv_refcount;
        argv[0].v_type = VAR_JOB;
        argv[0].vval.v_job = job;
@@ -4453,42 +4659,18 @@ job_cleanup(job_T *job)
        --job->jv_refcount;
        channel_need_redraw = TRUE;
     }
-    if (job->jv_refcount == 0)
+
+    /* Do not free the job in case the close callback of the associated channel
+     * isn't invoked yet and may get information by job_info(). */
+    if (job->jv_refcount == 0 && !job_channel_still_useful(job))
     {
-       /* The job was already unreferenced, now that it ended it can be
-        * freed. Careful: caller must not use "job" after this! */
+       /* The job was already unreferenced and the associated channel was
+        * detached, now that it ended it can be freed. Careful: caller must
+        * not use "job" after this! */
        job_free(job);
     }
 }
 
-#if defined(EXITFREE) || defined(PROTO)
-    void
-job_free_all(void)
-{
-    while (first_job != NULL)
-       job_free(first_job);
-}
-#endif
-
-/*
- * Return TRUE if the job should not be freed yet.  Do not free the job when
- * it has not ended yet and there is a "stoponexit" flag, an exit callback
- * or when the associated channel will do something with the job output.
- */
-    static int
-job_still_useful(job_T *job)
-{
-    return (job->jv_stoponexit != NULL || job->jv_exit_cb != NULL
-           || (job->jv_channel != NULL
-               && channel_still_useful(job->jv_channel)));
-}
-
-    static int
-job_still_alive(job_T *job)
-{
-    return (job->jv_status == JOB_STARTED) && job_still_useful(job);
-}
-
 /*
  * Mark references in jobs that are still useful.
  */
@@ -4500,7 +4682,7 @@ set_ref_in_job(int copyID)
     typval_T   tv;
 
     for (job = first_job; job != NULL; job = job->jv_next)
-       if (job_still_alive(job))
+       if (job_still_useful(job))
        {
            tv.v_type = VAR_JOB;
            tv.vval.v_job = job;
@@ -4509,26 +4691,33 @@ set_ref_in_job(int copyID)
     return abort;
 }
 
+/*
+ * Dereference "job".  Note that after this "job" may have been freed.
+ */
     void
 job_unref(job_T *job)
 {
     if (job != NULL && --job->jv_refcount <= 0)
     {
-       /* Do not free the job when it has not ended yet and there is a
-        * "stoponexit" flag or an exit callback. */
-       if (!job_still_alive(job))
+       /* Do not free the job if there is a channel where the close callback
+        * may get the job info. */
+       if (!job_channel_still_useful(job))
        {
-           job_free(job);
-       }
-       else if (job->jv_channel != NULL
-                                   && !channel_still_useful(job->jv_channel))
-       {
-           /* Do remove the link to the channel, otherwise it hangs
-            * around until Vim exits. See job_free() for refcount. */
-           ch_log(job->jv_channel, "detaching channel from job");
-           job->jv_channel->ch_job = NULL;
-           channel_unref(job->jv_channel);
-           job->jv_channel = NULL;
+           /* Do not free the job when it has not ended yet and there is a
+            * "stoponexit" flag or an exit callback. */
+           if (!job_need_end_check(job))
+           {
+               job_free(job);
+           }
+           else if (job->jv_channel != NULL)
+           {
+               /* Do remove the link to the channel, otherwise it hangs
+                * around until Vim exits. See job_free() for refcount. */
+               ch_log(job->jv_channel, "detaching channel from job");
+               job->jv_channel->ch_job = NULL;
+               channel_unref(job->jv_channel);
+               job->jv_channel = NULL;
+           }
        }
     }
 }
@@ -4541,7 +4730,7 @@ free_unused_jobs_contents(int copyID, int mask)
 
     for (job = first_job; job != NULL; job = job->jv_next)
        if ((job->jv_copyID & mask) != (copyID & mask)
-                                                    && !job_still_alive(job))
+                                                   && !job_still_useful(job))
        {
            /* Free the channel and ordinary items it contains, but don't
             * recurse into Lists, Dictionaries etc. */
@@ -4561,7 +4750,7 @@ free_unused_jobs(int copyID, int mask)
     {
        job_next = job->jv_next;
        if ((job->jv_copyID & mask) != (copyID & mask)
-                                                    && !job_still_alive(job))
+                                                   && !job_still_useful(job))
        {
            /* Free the job struct itself. */
            job_free_job(job);
@@ -4655,8 +4844,7 @@ has_pending_job(void)
        /* Only should check if the channel has been closed, if the channel is
         * open the job won't exit. */
        if (job->jv_status == JOB_STARTED && job->jv_exit_cb != NULL
-               && (job->jv_channel == NULL
-                   || !channel_still_useful(job->jv_channel)))
+                                           && !job_channel_still_useful(job))
            return TRUE;
     return FALSE;
 }
@@ -4671,14 +4859,18 @@ job_check_ended(void)
 {
     int                i;
 
+    if (first_job == NULL)
+       return;
+
     for (i = 0; i < MAX_CHECK_ENDED; ++i)
     {
+       /* NOTE: mch_detect_ended_job() must only return a job of which the
+        * status was just set to JOB_ENDED. */
        job_T   *job = mch_detect_ended_job(first_job);
 
        if (job == NULL)
            break;
-       if (job_still_useful(job))
-           job_cleanup(job); /* may free "job" */
+       job_cleanup(job); /* may free "job" */
     }
 
     if (channel_need_redraw)
@@ -4892,7 +5084,7 @@ job_status(job_T *job)
 {
     char       *result;
 
-    if (job->jv_status == JOB_ENDED)
+    if (job->jv_status >= JOB_ENDED)
        /* No need to check, dead is dead. */
        result = "dead";
     else if (job->jv_status == JOB_FAILED)
index 134cd09..d649179 100644 (file)
@@ -870,7 +870,7 @@ win_linetabsize(win_T *wp, char_u *line, colnr_T len)
     char_u     *s;
 
     for (s = line; *s != NUL && (len == MAXCOL || s < line + len);
-                                                               mb_ptr_adv(s))
+                                                               MB_PTR_ADV(s))
        col += win_lbr_chartabsize(wp, line, s, col, NULL);
     return (int)col;
 }
@@ -887,7 +887,7 @@ vim_isIDc(int c)
 
 /*
  * return TRUE if 'c' is a keyword character: Letters and characters from
- * 'iskeyword' option for current buffer.
+ * 'iskeyword' option for the current buffer.
  * For multi-byte characters mb_get_class() is used (builtin rules).
  */
     int
@@ -899,16 +899,17 @@ vim_iswordc(int c)
     int
 vim_iswordc_buf(int c, buf_T *buf)
 {
-#ifdef FEAT_MBYTE
     if (c >= 0x100)
     {
+#ifdef FEAT_MBYTE
        if (enc_dbcs != 0)
            return dbcs_class((unsigned)c >> 8, (unsigned)(c & 0xff)) >= 2;
        if (enc_utf8)
-           return utf_class(c) >= 2;
-    }
+           return utf_class_buf(c, buf) >= 2;
 #endif
-    return (c > 0 && c < 0x100 && GET_CHARTAB(buf, c) != 0);
+       return FALSE;
+    }
+    return (c > 0 && GET_CHARTAB(buf, c) != 0);
 }
 
 /*
@@ -917,21 +918,19 @@ vim_iswordc_buf(int c, buf_T *buf)
     int
 vim_iswordp(char_u *p)
 {
-#ifdef FEAT_MBYTE
-    if (has_mbyte && MB_BYTE2LEN(*p) > 1)
-       return mb_get_class(p) >= 2;
-#endif
-    return GET_CHARTAB(curbuf, *p) != 0;
+    return vim_iswordp_buf(p, curbuf);
 }
 
     int
 vim_iswordp_buf(char_u *p, buf_T *buf)
 {
+    int        c = *p;
+
 #ifdef FEAT_MBYTE
-    if (has_mbyte && MB_BYTE2LEN(*p) > 1)
-       return mb_get_class(p) >= 2;
+    if (has_mbyte && MB_BYTE2LEN(c) > 1)
+       c = (*mb_ptr2char)(p);
 #endif
-    return (GET_CHARTAB(buf, *p) != 0);
+    return vim_iswordc_buf(c, buf);
 }
 
 /*
@@ -961,7 +960,7 @@ vim_isfilec_or_wc(int c)
 }
 
 /*
- * return TRUE if 'c' is a printable character
+ * Return TRUE if 'c' is a printable character.
  * Assume characters above 0x100 are printable (multi-byte), except for
  * Unicode.
  */
@@ -1027,7 +1026,7 @@ lbr_chartabsize_adv(
     int                retval;
 
     retval = lbr_chartabsize(line, *s, col);
-    mb_ptr_adv(*s);
+    MB_PTR_ADV(*s);
     return retval;
 }
 
@@ -1090,8 +1089,8 @@ win_lbr_chartabsize(
      * needs a break here
      */
     if (wp->w_p_lbr
-           && vim_isbreak(c)
-           && !vim_isbreak(s[1])
+           && VIM_ISBREAK(c)
+           && !VIM_ISBREAK((int)s[1])
            && wp->w_p_wrap
 # ifdef FEAT_WINDOWS
            && wp->w_width != 0
@@ -1116,12 +1115,12 @@ win_lbr_chartabsize(
        for (;;)
        {
            ps = s;
-           mb_ptr_adv(s);
+           MB_PTR_ADV(s);
            c = *s;
            if (!(c != NUL
-                   && (vim_isbreak(c)
-                       || (!vim_isbreak(c)
-                           && (col2 == col || !vim_isbreak(*ps))))))
+                   && (VIM_ISBREAK(c)
+                       || (!VIM_ISBREAK(c)
+                           && (col2 == col || !VIM_ISBREAK((int)*ps))))))
                break;
 
            col2 += win_chartabsize(wp, s, col2);
@@ -1296,7 +1295,18 @@ getvcol(
     if (pos->col == MAXCOL)
        posptr = NULL;  /* continue until the NUL */
     else
+    {
+       /* Special check for an empty line, which can happen on exit, when
+        * ml_get_buf() always returns an empty string. */
+       if (*ptr == NUL)
+           pos->col = 0;
        posptr = ptr + pos->col;
+#ifdef FEAT_MBYTE
+       if (has_mbyte)
+           /* always start on the first byte */
+           posptr -= (*mb_head_off)(line, posptr);
+#endif
+    }
 
     /*
      * This function is used very often, do some speed optimizations.
@@ -1359,7 +1369,7 @@ getvcol(
                break;
 
            vcol += incr;
-           mb_ptr_adv(ptr);
+           MB_PTR_ADV(ptr);
        }
     }
     else
@@ -1380,7 +1390,7 @@ getvcol(
                break;
 
            vcol += incr;
-           mb_ptr_adv(ptr);
+           MB_PTR_ADV(ptr);
        }
     }
     if (start != NULL)
@@ -1393,7 +1403,8 @@ getvcol(
                && (State & NORMAL)
                && !wp->w_p_list
                && !virtual_active()
-               && !(VIsual_active && (*p_sel == 'e' || ltoreq(*pos, VIsual)))
+               && !(VIsual_active
+                               && (*p_sel == 'e' || LTOREQ_POS(*pos, VIsual)))
                )
            *cursor = vcol + incr - 1;      /* cursor at end */
        else
@@ -1486,7 +1497,7 @@ getvcols(
 {
     colnr_T    from1, from2, to1, to2;
 
-    if (ltp(pos1, pos2))
+    if (LT_POSP(pos1, pos2))
     {
        getvvcol(wp, pos1, &from1, NULL, &to1);
        getvvcol(wp, pos2, &from2, NULL, &to2);
@@ -1519,7 +1530,7 @@ skipwhite(char_u *q)
 {
     char_u     *p = q;
 
-    while (vim_iswhite(*p)) /* skip to next non-white */
+    while (VIM_ISWHITE(*p)) /* skip to next non-white */
        ++p;
     return p;
 }
@@ -1706,7 +1717,7 @@ vim_toupper(int c)
 {
     if (c <= '@')
        return c;
-    if (c >= 0x80)
+    if (c >= 0x80 || !(cmp_flags & CMP_KEEPASCII))
     {
        if (enc_utf8)
            return utf_toupper(c);
@@ -1722,6 +1733,8 @@ vim_toupper(int c)
        if (enc_latin1like)
            return latin1upper[c];
     }
+    if (c < 0x80 && (cmp_flags & CMP_KEEPASCII))
+       return TOUPPER_ASC(c);
     return TOUPPER_LOC(c);
 }
 
@@ -1730,7 +1743,7 @@ vim_tolower(int c)
 {
     if (c <= '@')
        return c;
-    if (c >= 0x80)
+    if (c >= 0x80 || !(cmp_flags & CMP_KEEPASCII))
     {
        if (enc_utf8)
            return utf_tolower(c);
@@ -1746,6 +1759,8 @@ vim_tolower(int c)
        if (enc_latin1like)
            return latin1lower[c];
     }
+    if (c < 0x80 && (cmp_flags & CMP_KEEPASCII))
+       return TOLOWER_ASC(c);
     return TOLOWER_LOC(c);
 }
 #endif
@@ -1901,7 +1916,11 @@ vim_str2nr(
            n += 2;         /* skip over "0b" */
        while ('0' <= *ptr && *ptr <= '1')
        {
-           un = 2 * un + (unsigned long)(*ptr - '0');
+           /* avoid ubsan error for overflow */
+           if (un < UVARNUM_MAX / 2)
+               un = 2 * un + (unsigned long)(*ptr - '0');
+           else
+               un = UVARNUM_MAX;
            ++ptr;
            if (n++ == maxlen)
                break;
@@ -1912,7 +1931,11 @@ vim_str2nr(
        /* octal */
        while ('0' <= *ptr && *ptr <= '7')
        {
-           un = 8 * un + (uvarnumber_T)(*ptr - '0');
+           /* avoid ubsan error for overflow */
+           if (un < UVARNUM_MAX / 8)
+               un = 8 * un + (uvarnumber_T)(*ptr - '0');
+           else
+               un = UVARNUM_MAX;
            ++ptr;
            if (n++ == maxlen)
                break;
@@ -1925,7 +1948,11 @@ vim_str2nr(
            n += 2;         /* skip over "0x" */
        while (vim_isxdigit(*ptr))
        {
-           un = 16 * un + (uvarnumber_T)hex2nr(*ptr);
+           /* avoid ubsan error for overflow */
+           if (un < UVARNUM_MAX / 16)
+               un = 16 * un + (uvarnumber_T)hex2nr(*ptr);
+           else
+               un = UVARNUM_MAX;
            ++ptr;
            if (n++ == maxlen)
                break;
@@ -1936,7 +1963,11 @@ vim_str2nr(
        /* decimal */
        while (VIM_ISDIGIT(*ptr))
        {
-           un = 10 * un + (uvarnumber_T)(*ptr - '0');
+           /* avoid ubsan error for overflow */
+           if (un < UVARNUM_MAX / 10)
+               un = 10 * un + (uvarnumber_T)(*ptr - '0');
+           else
+               un = UVARNUM_MAX;
            ++ptr;
            if (n++ == maxlen)
                break;
@@ -1950,9 +1981,19 @@ vim_str2nr(
     if (nptr != NULL)
     {
        if (negative)   /* account for leading '-' for decimal numbers */
-           *nptr = -(varnumber_T)un;
+       {
+           /* avoid ubsan error for overflow */
+           if (un > VARNUM_MAX)
+               *nptr = VARNUM_MIN;
+           else
+               *nptr = -(varnumber_T)un;
+       }
        else
+       {
+           if (un > VARNUM_MAX)
+               un = VARNUM_MAX;
            *nptr = (varnumber_T)un;
+       }
     }
     if (unptr != NULL)
        *unptr = un;
index 62427e2..f8a23ed 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * config.h.in.  Generated automatically from configure.in by autoheader, and
- * manually changed after that.
+ * config.h.in.  Originally generated automatically from configure.ac by
+ * autoheader and manually changed after that.
  */
 
 /* Define if we have EBCDIC code */
 #undef BAD_GETCWD
 
 /* Define if you the function: */
-#undef HAVE_BCMP
 #undef HAVE_FCHDIR
 #undef HAVE_FCHOWN
 #undef HAVE_FSEEKO
 #undef HAVE_FSYNC
+#undef HAVE_FLOAT_FUNCS
 #undef HAVE_GETCWD
+#undef HAVE_GETPGID
 #undef HAVE_GETPSEUDOTTY
 #undef HAVE_GETPWENT
 #undef HAVE_GETPWNAM
 #undef HAVE_GETTIMEOFDAY
 #undef HAVE_GETWD
 #undef HAVE_ICONV
-#undef HAVE_NL_LANGINFO_CODESET
 #undef HAVE_LSTAT
-#undef HAVE_MEMCMP
 #undef HAVE_MEMSET
 #undef HAVE_MKDTEMP
 #undef HAVE_NANOSLEEP
+#undef HAVE_NL_LANGINFO_CODESET
 #undef HAVE_OPENDIR
-#undef HAVE_FLOAT_FUNCS
 #undef HAVE_PUTENV
 #undef HAVE_QSORT
 #undef HAVE_READLINK
 /* Define if fcntl()'s F_SETFD command knows about FD_CLOEXEC */
 #undef HAVE_FD_CLOEXEC
 
+/* Define if /proc/self/exe or similar can be read */
+#undef PROC_EXE_LINK
+
 /* Define if you want Cygwin to use the WIN32 clipboard, not compatible with X11*/
 #undef FEAT_CYGWIN_WIN32_CLIPBOARD
 
index fa7c108..8a584c2 100644 (file)
@@ -1,4 +1,4 @@
-the first targets to make vim are: scratch config myself
+the first target to make vim is: reconfig
 srcdir = .
 VIMNAME = vim
 EXNAME = ex
similarity index 99%
rename from src/configure.in
rename to src/configure.ac
index 43bf9ad..cdf39b3 100644 (file)
@@ -1,4 +1,4 @@
-dnl configure.in: autoconf script for Vim
+dnl configure.ac: autoconf script for Vim
 
 dnl Process this file with autoconf 2.12 or 2.13 to produce "configure".
 dnl Should also work with autoconf 2.54 and later.
@@ -11,12 +11,12 @@ AC_DEFINE(UNIX)
 AC_PROG_MAKE_SET
 
 dnl Checks for programs.
-AC_PROG_CC     dnl required by almost everything
-AC_PROG_CPP    dnl required by header file checks
-AC_PROGRAM_EGREP dnl required by AC_EGREP_CPP
-AC_PROG_FGREP  dnl finds working grep -F
-AC_ISC_POSIX   dnl required by AC_C_CROSS
-AC_PROG_AWK    dnl required for "make html" in ../doc
+AC_PROG_CC             dnl required by almost everything
+AC_PROG_CPP            dnl required by header file checks
+AC_PROGRAM_EGREP       dnl required by AC_EGREP_CPP
+AC_PROG_FGREP          dnl finds working grep -F
+AC_ISC_POSIX           dnl required by AC_C_CROSS
+AC_PROG_AWK            dnl required for "make html" in ../doc
 
 dnl Don't strip if we don't have it
 AC_CHECK_PROG(STRIP, strip, strip, :)
@@ -67,8 +67,8 @@ dnl clang-500.2.75 or around has abandoned -f[no-]strength-reduce and issues a
 dnl warning when that flag is passed to.  Accordingly, adjust CFLAGS based on
 dnl the version number of the clang in use.
 dnl Note that this does not work to get the version of clang 3.1 or 3.2.
-AC_MSG_CHECKING(for recent clang version)
-CLANG_VERSION_STRING=`$CC --version 2>/dev/null | sed  -n -e 's/^.*clang.*\([[0-9]][[0-9]]*\.[[0-9]][[0-9]]*\.[[0-9]][[0-9]]*\).*$/\1/p'`
+AC_MSG_CHECKING(for clang version)
+CLANG_VERSION_STRING=`$CC --version 2>/dev/null | sed  -n -e 's/^.*clang[[^0-9]]*\([[0-9]][[0-9]]*\.[[0-9]][[0-9]]*\.[[0-9]][[0-9]]*\).*$/\1/p'`
 if test x"$CLANG_VERSION_STRING" != x"" ; then
   CLANG_MAJOR=`echo "$CLANG_VERSION_STRING" | sed -n -e 's/\([[0-9]][[0-9]]*\)\.[[0-9]][[0-9]]*\.[[0-9]][[0-9]]*/\1/p'`
   CLANG_MINOR=`echo "$CLANG_VERSION_STRING" | sed -n -e 's/[[0-9]][[0-9]]*\.\([[0-9]][[0-9]]*\)\.[[0-9]][[0-9]]*/\1/p'`
@@ -79,11 +79,15 @@ if test x"$CLANG_VERSION_STRING" != x"" ; then
   dnl change the constant 500002075 below appropriately.  To get the
   dnl integer corresponding to a version number, refer to the
   dnl definition of CLANG_VERSION above.
+  AC_MSG_CHECKING(if clang supports -fno-strength-reduce)
   if test "$CLANG_VERSION" -ge 500002075 ; then
-    CFLAGS=`echo "$CFLAGS" | sed -n -e 's/-fno-strength-reduce/ /p'`
+    AC_MSG_RESULT(no)
+    CFLAGS=`echo "$CFLAGS" | sed -e 's/-fno-strength-reduce/ /'`
+  else
+    AC_MSG_RESULT(yes)
   fi
 else
-  AC_MSG_RESULT(no)
+  AC_MSG_RESULT(N/A)
 fi
 
 dnl If configure thinks we are cross compiling, there might be something
@@ -1995,7 +1999,7 @@ if test "$enable_channel" = "yes"; then
        /* Check bitfields */
        struct nbbuf {
        unsigned int  initDone:1;
-       ushort signmaplen;
+       unsigned short signmaplen;
        };
            ], [
                /* Check creating a socket. */
@@ -3016,6 +3020,23 @@ dnl ---------------------------------------------------------------------------
 dnl end of GUI-checking
 dnl ---------------------------------------------------------------------------
 
+AC_MSG_CHECKING([for /proc link to executable])
+if test -L "/proc/self/exe"; then
+  dnl Linux
+  AC_MSG_RESULT([/proc/self/exe])
+  AC_DEFINE(PROC_EXE_LINK, "/proc/self/exe")
+elif test -L "/proc/self/path/a.out"; then
+  dnl Solaris
+  AC_MSG_RESULT([/proc/self/path/a.out])
+  AC_DEFINE(PROC_EXE_LINK, "/proc/self/path/a.out")
+elif test -L "/proc/curproc/file"; then
+  dnl FreeBSD
+  AC_MSG_RESULT([/proc/curproc/file])
+  AC_DEFINE(PROC_EXE_LINK, "/proc/curproc/file")
+else
+  AC_MSG_RESULT(no)
+fi
+
 dnl Check for Cygwin, which needs an extra source file if not using X11
 AC_MSG_CHECKING(for CYGWIN or MSYS environment)
 case `uname` in
@@ -3594,10 +3615,10 @@ fi
 
 dnl Check for functions in one big call, to reduce the size of configure.
 dnl Can only be used for functions that do not require any include.
-AC_CHECK_FUNCS(bcmp fchdir fchown fsync getcwd getpseudotty \
-       getpwent getpwnam getpwuid getrlimit gettimeofday getwd lstat memcmp \
+AC_CHECK_FUNCS(fchdir fchown fsync getcwd getpseudotty \
+       getpwent getpwnam getpwuid getrlimit gettimeofday getwd lstat \
        memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \
-       setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \
+       getpgid setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \
        sigprocmask sigvec strcasecmp strerror strftime stricmp strncasecmp \
        strnicmp strpbrk strtol tgetent towlower towupper iswupper \
        usleep utime utimes)
diff --git a/src/create_cmdidxs.vim b/src/create_cmdidxs.vim
new file mode 100644 (file)
index 0000000..c306ccb
--- /dev/null
@@ -0,0 +1,81 @@
+" This script generates the tables cmdidxs1[] and cmdidxs2[][] which,
+" given a Ex command, determine the first value to probe to find
+" a matching command in cmdnames[] based on the first character
+" and the first 2 characters of the command.
+" This is used to speed up lookup in cmdnames[].
+"
+" Script should be run every time new Ex commands are added in Vim,
+" from the src/vim directory, since it reads commands from "ex_cmds.h".
+
+let cmds = []
+let skipped_cmds = 0
+
+for line in readfile('ex_cmds.h')
+  if line =~ '^EX(CMD_'
+    let m = matchlist(line, '^EX(CMD_\S*,\s*"\([a-z][^"]*\)"')
+    if len(m) >= 2
+      let cmds += [ m[1] ]
+    else
+      let skipped_cmds += 1
+    endif
+  endif
+endfor
+
+let cmdidxs1 = {}
+let cmdidxs2 = {}
+
+for i in range(len(cmds) - 1, 0, -1)
+  let cmd = cmds[i]
+  let c1 = cmd[0] " First character of command
+  let c2 = cmd[1] " Second character of command (if any)
+
+  let cmdidxs1{c1} = i
+  if c2 >= 'a' && c2 <= 'z'
+    let cmdidxs2{c1}{c2} = i
+  endif
+endfor
+
+let output =  [ '/* Automatically generated code by create_cmdidxs.vim' ]
+let output += [ ' *' ]
+let output += [ ' * Table giving the index of the first command in cmdnames[] to lookup' ]
+let output += [ ' * based on the first letter of a command.' ]
+let output += [ ' */' ]
+let output += [ 'static const unsigned short cmdidxs1[26] =' ]
+let output += [ '{' ]
+
+let a_to_z = map(range(char2nr('a'), char2nr('z')), 'nr2char(v:val)')
+for c1 in a_to_z
+  let line = '  /* ' . c1 . ' */ ' . cmdidxs1{c1} . ((c1 == 'z') ? '' : ',')
+  let output += [ line ]
+endfor
+let output += [ '};' ]
+let output += [ '' ]
+let output += [ '/*' ]
+let output += [ ' * Table giving the index of the first command in cmdnames[] to lookup' ]
+let output += [ ' * based on the first 2 letters of a command.' ]
+let output += [ ' * Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they' ]
+let output += [ ' * fit in a byte.' ]
+let output += [ ' */' ]
+let output += [ 'static const unsigned char cmdidxs2[26][26] =' ]
+let output += [ '{ /*         a   b   c   d   e   f   g   h   i   j   k   l   m   n   o   p   q   r   s   t   u   v   w   x   y   z */' ]
+
+for c1 in a_to_z
+  let line = '  /* ' . c1 . ' */ {'
+  for c2 in a_to_z
+    if exists('cmdidxs2{c1}{c2}')
+      let line .= printf('%3d', cmdidxs2{c1}{c2} - cmdidxs1{c1})
+    else
+      let line .= '  0'
+    endif
+    let line .= (c2 == 'z') ? '' : ','
+  endfor
+  let line .= ' }' . ((c1 == 'z') ? '' : ',')
+  let output += [ line ]
+endfor
+
+let output += [ '};' ]
+let output += [ '' ]
+let output += [ 'static const int command_count = ' . (len(cmds) + skipped_cmds) . ';' ]
+
+call writefile(output, "ex_cmdidxs.h")
+quit
index 8175906..930bbd7 100644 (file)
@@ -118,6 +118,9 @@ static cryptmethod_T cryptmethods[CRYPT_M_COUNT] = {
        NULL, NULL,
        crypt_blowfish_encode, crypt_blowfish_decode,
     },
+
+    /* NOTE: when adding a new method, use some random bytes for the magic key,
+     * to avoid that a text file is recognized as encrypted. */
 };
 
 #define CRYPT_MAGIC_LEN        12      /* cannot change */
index 136348b..a26419b 100644 (file)
@@ -88,8 +88,7 @@ dict_free_contents(dict_T *d)
             * something recursive causing trouble. */
            di = HI2DI(hi);
            hash_remove(&d->dv_hashtab, hi);
-           clear_tv(&di->di_tv);
-           vim_free(di);
+           dictitem_free(di);
            --todo;
        }
     }
@@ -214,7 +213,7 @@ dictitem_remove(dict_T *dict, dictitem_T *item)
 
     hi = hash_find(&dict->dv_hashtab, item->di_key);
     if (HASHITEM_EMPTY(hi))
-       EMSG2(_(e_intern2), "dictitem_remove()");
+       internal_error("dictitem_remove()");
     else
        hash_remove(&dict->dv_hashtab, hi);
     dictitem_free(item);
@@ -357,12 +356,12 @@ dict_add_list(dict_T *d, char *key, list_T *list)
     item->di_tv.v_lock = 0;
     item->di_tv.v_type = VAR_LIST;
     item->di_tv.vval.v_list = list;
+    ++list->lv_refcount;
     if (dict_add(d, item) == FAIL)
     {
        dictitem_free(item);
        return FAIL;
     }
-    ++list->lv_refcount;
     return OK;
 }
 
@@ -381,12 +380,12 @@ dict_add_dict(dict_T *d, char *key, dict_T *dict)
     item->di_tv.v_lock = 0;
     item->di_tv.v_type = VAR_DICT;
     item->di_tv.vval.v_dict = dict;
+    ++dict->dv_refcount;
     if (dict_add(d, item) == FAIL)
     {
        dictitem_free(item);
        return FAIL;
     }
-    ++dict->dv_refcount;
     return OK;
 }
 
index a4a2acb..246c4e0 100644 (file)
@@ -139,6 +139,23 @@ diff_buf_add(buf_T *buf)
 }
 
 /*
+ * Remove all buffers to make diffs for.
+ */
+    static void
+diff_buf_clear(void)
+{
+    int                i;
+
+    for (i = 0; i < DB_COUNT; ++i)
+       if (curtab->tp_diffbuf[i] != NULL)
+       {
+           curtab->tp_diffbuf[i] = NULL;
+           curtab->tp_diff_invalid = TRUE;
+           diff_redraw(TRUE);
+       }
+}
+
+/*
  * Find buffer "buf" in the list of diff buffers for the current tab page.
  * Return its index or DB_COUNT if not found.
  */
@@ -889,6 +906,7 @@ ex_diffpatch(exarg_T *eap)
     int                browse_flag = cmdmod.browse;
 #endif
     stat_T     st;
+    char_u     *esc_name = NULL;
 
 #ifdef FEAT_BROWSE
     if (cmdmod.browse)
@@ -918,11 +936,14 @@ ex_diffpatch(exarg_T *eap)
     /* Get the absolute path of the patchfile, changing directory below. */
     fullname = FullName_save(eap->arg, FALSE);
 #endif
-    buflen = STRLEN(tmp_orig) + (
+    esc_name = vim_strsave_shellescape(
 # ifdef UNIX
-                   fullname != NULL ? STRLEN(fullname) :
+                   fullname != NULL ? fullname :
 # endif
-                   STRLEN(eap->arg)) + STRLEN(tmp_new) + 16;
+                   eap->arg, TRUE, TRUE);
+    if (esc_name == NULL)
+       goto theend;
+    buflen = STRLEN(tmp_orig) + STRLEN(esc_name) + STRLEN(tmp_new) + 16;
     buf = alloc((unsigned)buflen);
     if (buf == NULL)
        goto theend;
@@ -960,12 +981,8 @@ ex_diffpatch(exarg_T *eap)
     {
        /* Build the patch command and execute it.  Ignore errors.  Switch to
         * cooked mode to allow the user to respond to prompts. */
-       vim_snprintf((char *)buf, buflen, "patch -o %s %s < \"%s\"",
-               tmp_new, tmp_orig,
-# ifdef UNIX
-               fullname != NULL ? fullname :
-# endif
-               eap->arg);
+       vim_snprintf((char *)buf, buflen, "patch -o %s %s < %s",
+                                                 tmp_new, tmp_orig, esc_name);
 #ifdef FEAT_AUTOCMD
        block_autocmds();       /* Avoid ShellCmdPost stuff */
 #endif
@@ -1056,6 +1073,7 @@ theend:
 #ifdef UNIX
     vim_free(fullname);
 #endif
+    vim_free(esc_name);
 #ifdef FEAT_BROWSE
     vim_free(browseFile);
     cmdmod.browse = browse_flag;
@@ -1257,6 +1275,10 @@ ex_diffoff(exarg_T *eap)
 #endif
     }
 
+    /* Also remove hidden buffers from the list. */
+    if (eap->forceit)
+       diff_buf_clear();
+
 #ifdef FEAT_SCROLLBIND
     /* Remove "hor" from from 'scrollopt' if there are no diff windows left. */
     if (!diffwin && vim_strchr(p_sbo, 'h') != NULL)
@@ -1645,7 +1667,7 @@ diff_cmp(char_u *s1, char_u *s2)
     p2 = s2;
     while (*p1 != NUL && *p2 != NUL)
     {
-       if (vim_iswhite(*p1) && vim_iswhite(*p2))
+       if (VIM_ISWHITE(*p1) && VIM_ISWHITE(*p2))
        {
            p1 = skipwhite(p1);
            p2 = skipwhite(p2);
@@ -1972,8 +1994,8 @@ diff_find_change(
            while (line_org[si_org] != NUL)
            {
                if ((diff_flags & DIFF_IWHITE)
-                       && vim_iswhite(line_org[si_org])
-                       && vim_iswhite(line_new[si_new]))
+                       && VIM_ISWHITE(line_org[si_org])
+                       && VIM_ISWHITE(line_new[si_new]))
                {
                    si_org = (int)(skipwhite(line_org + si_org) - line_org);
                    si_new = (int)(skipwhite(line_new + si_new) - line_new);
@@ -2007,14 +2029,14 @@ diff_find_change(
                                                && ei_org >= 0 && ei_new >= 0)
                {
                    if ((diff_flags & DIFF_IWHITE)
-                           && vim_iswhite(line_org[ei_org])
-                           && vim_iswhite(line_new[ei_new]))
+                           && VIM_ISWHITE(line_org[ei_org])
+                           && VIM_ISWHITE(line_new[ei_new]))
                    {
                        while (ei_org >= *startp
-                                            && vim_iswhite(line_org[ei_org]))
+                                            && VIM_ISWHITE(line_org[ei_org]))
                            --ei_org;
                        while (ei_new >= si_new
-                                            && vim_iswhite(line_new[ei_new]))
+                                            && VIM_ISWHITE(line_new[ei_new]))
                            --ei_new;
                    }
                    else
@@ -2180,7 +2202,7 @@ ex_diffgetput(exarg_T *eap)
     {
        /* Buffer number or pattern given.  Ignore trailing white space. */
        p = eap->arg + STRLEN(eap->arg);
-       while (p > eap->arg && vim_iswhite(p[-1]))
+       while (p > eap->arg && VIM_ISWHITE(p[-1]))
            --p;
        for (i = 0; vim_isdigit(eap->arg[i]) && eap->arg + i < p; ++i)
            ;
@@ -2311,7 +2333,7 @@ ex_diffgetput(exarg_T *eap)
                    end_skip = 0;
            }
 
-           buf_empty = bufempty();
+           buf_empty = BUFEMPTY();
            added = 0;
            for (i = 0; i < count; ++i)
            {
@@ -2595,7 +2617,6 @@ diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1)
     return lnum;
 }
 
-#if defined(FEAT_FOLDING) || defined(PROTO)
 /*
  * For line "lnum" in the current window find the equivalent lnum in window
  * "wp", compensating for inserted/deleted lines.
@@ -2635,6 +2656,5 @@ diff_lnum_win(linenr_T lnum, win_T *wp)
        n = dp->df_lnum[i] + dp->df_count[i];
     return n;
 }
-#endif
 
 #endif /* FEAT_DIFF */
index 3a0e188..0153f3b 100644 (file)
@@ -186,7 +186,7 @@ static int  ins_compl_pum_key(int c);
 static int  ins_compl_key2count(int c);
 static int  ins_compl_use_match(int c);
 static int  ins_complete(int c, int enable_pum);
-static void show_pum(int save_w_wrow);
+static void show_pum(int prev_w_wrow, int prev_w_leftcol);
 static unsigned  quote_meta(char_u *dest, char_u *str, int len);
 #endif /* FEAT_INS_EXPAND */
 
@@ -309,6 +309,7 @@ static int  dont_sync_undo = FALSE; /* CTRL-G U prevents syncing undo for
  * "cmdchar" can be:
  * 'i' normal insert command
  * 'a' normal append command
+ * K_PS bracketed paste
  * 'R' replace command
  * 'r' "r<CR>" command: insert one <CR>.  Note: count can be > 1, for redo,
  *     but still only one <CR> is inserted.  The <Esc> is not used for redo.
@@ -407,7 +408,7 @@ edit(
         * the "A" command, thus set State to avoid that. Also check that the
         * line number is still valid (lines may have been deleted).
         * Do not restore if v:char was set to a non-empty string. */
-       if (!equalpos(curwin->w_cursor, save_cursor)
+       if (!EQUAL_POS(curwin->w_cursor, save_cursor)
 # ifdef FEAT_EVAL
                && *get_vim_var_str(VV_CHAR) == NUL
 # endif
@@ -462,7 +463,10 @@ edit(
        else
 #endif
        {
-           AppendCharToRedobuff(cmdchar);
+           if (cmdchar == K_PS)
+               AppendCharToRedobuff('a');
+           else
+               AppendCharToRedobuff(cmdchar);
            if (cmdchar == 'g')             /* "gI" command */
                AppendCharToRedobuff('I');
            else if (cmdchar == 'r')        /* "r<CR>" command */
@@ -530,11 +534,15 @@ edit(
     revins_legal = 0;
     revins_scol = -1;
 #endif
+    if (!p_ek)
+       /* Disable bracketed paste mode, we won't recognize the escape
+        * sequences. */
+       out_str(T_BD);
 
     /*
      * Handle restarting Insert mode.
-     * Don't do this for "CTRL-O ." (repeat an insert): we get here with
-     * restart_edit non-zero, and something in the stuff buffer.
+     * Don't do this for "CTRL-O ." (repeat an insert): In that case we get
+     * here with something in the stuff buffer.
      */
     if (restart_edit != 0 && stuff_empty())
     {
@@ -782,10 +790,14 @@ edit(
            dont_sync_undo = TRUE;
        else
            dont_sync_undo = FALSE;
-       do
-       {
-           c = safe_vgetc();
-       } while (c == K_IGNORE);
+       if (cmdchar == K_PS)
+           /* Got here from normal mode when bracketed paste started. */
+           c = K_PS;
+       else
+           do
+           {
+               c = safe_vgetc();
+           } while (c == K_IGNORE);
 
 #ifdef FEAT_AUTOCMD
        /* Don't want K_CURSORHOLD for the second key, e.g., after CTRL-V. */
@@ -845,7 +857,7 @@ edit(
 
                    if (str != NULL)
                    {
-                       for (p = str; *p != NUL; mb_ptr_adv(p))
+                       for (p = str; *p != NUL; MB_PTR_ADV(p))
                            ins_compl_addleader(PTR2CHAR(p));
                        vim_free(str);
                    }
@@ -1025,9 +1037,11 @@ doESCkey:
        case Ctrl_Z:    /* suspend when 'insertmode' set */
            if (!p_im)
                goto normalchar;        /* insert CTRL-Z as normal char */
-           stuffReadbuff((char_u *)":st\r");
-           c = Ctrl_O;
-           /*FALLTHROUGH*/
+           do_cmdline_cmd((char_u *)"stop");
+#ifdef CURSOR_SHAPE
+           ui_cursor_shape();          /* may need to update cursor shape */
+#endif
+           continue;
 
        case Ctrl_O:    /* execute one command */
 #ifdef FEAT_COMPL_FUNC
@@ -1193,6 +1207,16 @@ doESCkey:
            ins_mousescroll(MSCR_RIGHT);
            break;
 #endif
+       case K_PS:
+           bracketed_paste(PASTE_INSERT, FALSE, NULL);
+           if (cmdchar == K_PS)
+               /* invoked from normal mode, bail out */
+               goto doESCkey;
+           break;
+       case K_PE:
+           /* Got K_PE without K_PS, ignore. */
+           break;
+
 #ifdef FEAT_GUI_TABLINE
        case K_TABLINE:
        case K_TABMENU:
@@ -1429,10 +1453,14 @@ doESCkey:
 
 docomplete:
            compl_busy = TRUE;
+#ifdef FEAT_FOLDING
            disable_fold_update++;  /* don't redraw folds here */
+#endif
            if (ins_complete(c, TRUE) == FAIL)
                compl_cont_status = 0;
+#ifdef FEAT_FOLDING
            disable_fold_update--;
+#endif
            compl_busy = FALSE;
            break;
 #endif /* FEAT_INS_EXPAND */
@@ -1464,7 +1492,7 @@ normalchar:
                    if (*str != NUL && stop_arrow() != FAIL)
                    {
                        /* Insert the new value of v:char literally. */
-                       for (p = str; *p != NUL; mb_ptr_adv(p))
+                       for (p = str; *p != NUL; MB_PTR_ADV(p))
                        {
                            c = PTR2CHAR(p);
                            if (c == CAR || c == K_KENTER || c == NL)
@@ -1603,7 +1631,7 @@ ins_redraw(
 # endif
                )
 # ifdef FEAT_AUTOCMD
-       && !equalpos(last_cursormoved, curwin->w_cursor)
+       && !EQUAL_POS(last_cursormoved, curwin->w_cursor)
 # endif
 # ifdef FEAT_INS_EXPAND
        && !pum_visible()
@@ -1646,7 +1674,7 @@ ins_redraw(
 #ifdef FEAT_AUTOCMD
     /* Trigger TextChangedI if b_changedtick differs. */
     if (ready && has_textchangedI()
-           && last_changedtick != curbuf->b_changedtick
+           && last_changedtick != CHANGEDTICK(curbuf)
 # ifdef FEAT_INS_EXPAND
            && !pum_visible()
 # endif
@@ -1655,7 +1683,7 @@ ins_redraw(
        if (last_changedtick_buf == curbuf)
            apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf);
        last_changedtick_buf = curbuf;
-       last_changedtick = curbuf->b_changedtick;
+       last_changedtick = CHANGEDTICK(curbuf);
     }
 #endif
 
@@ -1743,7 +1771,7 @@ edit_putchar(int c, int highlight)
        update_topline();       /* just in case w_topline isn't valid */
        validate_cursor();
        if (highlight)
-           attr = hl_attr(HLF_8);
+           attr = HL_ATTR(HLF_8);
        else
            attr = 0;
        pc_row = W_WINROW(curwin) + curwin->w_wrow;
@@ -2121,7 +2149,7 @@ truncate_spaces(char_u *line)
     int            i;
 
     /* find start of trailing white space */
-    for (i = (int)STRLEN(line) - 1; i >= 0 && vim_iswhite(line[i]); i--)
+    for (i = (int)STRLEN(line) - 1; i >= 0 && VIM_ISWHITE(line[i]); i--)
     {
        if (State & REPLACE_FLAG)
            replace_join(0);        /* remove a NUL from the replace stack */
@@ -2228,13 +2256,16 @@ has_compl_option(int dict_opt)
        edit_submode = NULL;
        msg_attr(dict_opt ? (char_u *)_("'dictionary' option is empty")
                          : (char_u *)_("'thesaurus' option is empty"),
-                                                             hl_attr(HLF_E));
+                                                             HL_ATTR(HLF_E));
        if (emsg_silent == 0)
        {
            vim_beep(BO_COMPL);
            setcursor();
            out_flush();
-           ui_delay(2000L, FALSE);
+#ifdef FEAT_EVAL
+           if (!get_vim_var_nr(VV_TESTING))
+#endif
+               ui_delay(2000L, FALSE);
        }
        return FALSE;
     }
@@ -2299,7 +2330,7 @@ vim_is_ctrl_x_key(int c)
        case CTRL_X_EVAL:
            return (c == Ctrl_P || c == Ctrl_N);
     }
-    EMSG(_(e_internal));
+    internal_error("vim_is_ctrl_x_key()");
     return FALSE;
 }
 
@@ -2327,7 +2358,7 @@ ins_compl_accept_char(int c)
        case CTRL_X_OMNI:
            /* Command line and Omni completion can work with just about any
             * printable character, but do stop at white space. */
-           return vim_isprintc(c) && !vim_iswhite(c);
+           return vim_isprintc(c) && !VIM_ISWHITE(c);
 
        case CTRL_X_WHOLE_LINE:
            /* For while line completion a space can be part of the line. */
@@ -2372,7 +2403,7 @@ ins_compl_add_infercase(
            actual_len = 0;
            while (*p != NUL)
            {
-               mb_ptr_adv(p);
+               MB_PTR_ADV(p);
                ++actual_len;
            }
        }
@@ -2388,7 +2419,7 @@ ins_compl_add_infercase(
            actual_compl_length = 0;
            while (*p != NUL)
            {
-               mb_ptr_adv(p);
+               MB_PTR_ADV(p);
                ++actual_compl_length;
            }
        }
@@ -2691,8 +2722,8 @@ ins_compl_longest_match(compl_T *match)
 #ifdef FEAT_MBYTE
            if (has_mbyte)
            {
-               mb_ptr_adv(p);
-               mb_ptr_adv(s);
+               MB_PTR_ADV(p);
+               MB_PTR_ADV(s);
            }
            else
 #endif
@@ -2794,11 +2825,13 @@ completeopt_was_set(void)
 set_completion(colnr_T startcol, list_T *list)
 {
     int save_w_wrow = curwin->w_wrow;
+    int save_w_leftcol = curwin->w_leftcol;
 
     /* If already doing completions stop it. */
     if (ctrl_x_mode != 0)
        ins_compl_prep(' ');
     ins_compl_clear();
+    ins_compl_free();
 
     compl_direction = FORWARD;
     if (startcol > curwin->w_cursor.col)
@@ -2833,7 +2866,7 @@ set_completion(colnr_T startcol, list_T *list)
 
     /* Lazily show the popup menu, unless we got interrupted. */
     if (!compl_interrupted)
-       show_pum(save_w_wrow);
+       show_pum(save_w_wrow, save_w_leftcol);
     out_flush();
 }
 
@@ -3219,7 +3252,7 @@ ins_compl_files(
        {
            vim_snprintf((char *)IObuff, IOSIZE,
                              _("Scanning dictionary: %s"), (char *)files[i]);
-           (void)msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
+           (void)msg_trunc_attr(IObuff, TRUE, HL_ATTR(HLF_R));
        }
 
        if (fp != NULL)
@@ -3441,13 +3474,16 @@ ins_compl_bs(void)
 
     line = ml_get_curline();
     p = line + curwin->w_cursor.col;
-    mb_ptr_back(line, p);
+    MB_PTR_BACK(line, p);
 
     /* Stop completion when the whole word was deleted.  For Omni completion
-     * allow the word to be deleted, we won't match everything. */
+     * allow the word to be deleted, we won't match everything.
+     * Respect the 'backspace' option. */
     if ((int)(p - line) - (int)compl_col < 0
            || ((int)(p - line) - (int)compl_col == 0
-               && ctrl_x_mode != CTRL_X_OMNI) || ctrl_x_mode == CTRL_X_EVAL)
+               && ctrl_x_mode != CTRL_X_OMNI) || ctrl_x_mode == CTRL_X_EVAL
+           || (!can_bs(BS_START) && (int)(p - line) - (int)compl_col
+                                                       - compl_length < 0))
        return K_BS;
 
     /* Deleted more than what was used to find matches or didn't finish
@@ -3557,7 +3593,11 @@ ins_compl_addleader(int c)
 {
 #ifdef FEAT_MBYTE
     int                cc;
+#endif
 
+    if (stop_arrow() == FAIL)
+       return;
+#ifdef FEAT_MBYTE
     if (has_mbyte && (cc = (*mb_char2len)(c)) > 1)
     {
        char_u  buf[MB_MAXBYTES + 1];
@@ -3875,7 +3915,7 @@ ins_compl_prep(int c)
                if (prev_col > 0)
                    dec_cursor();
                /* only format when something was inserted */
-               if (!arrow_used && !ins_need_undo)
+               if (!arrow_used && !ins_need_undo && c != Ctrl_E)
                    insertchar(NUL, 0, -1);
                if (prev_col > 0
                             && ml_get_curline()[curwin->w_cursor.col] != NUL)
@@ -3983,7 +4023,7 @@ ins_compl_fixRedoBufForLeader(char_u *ptr_arg)
        if (len > 0)
            len -= (*mb_head_off)(p, p + len);
 #endif
-       for (p += len; *p != NUL; mb_ptr_adv(p))
+       for (p += len; *p != NUL; MB_PTR_ADV(p))
            AppendCharToRedobuff(K_BS);
     }
     else
@@ -4090,7 +4130,7 @@ expand_by_function(
     }
     curwin->w_cursor = pos;    /* restore the cursor position */
     validate_cursor();
-    if (!equalpos(curwin->w_cursor, pos))
+    if (!EQUAL_POS(curwin->w_cursor, pos))
     {
        EMSG(_(e_compldel));
        goto theend;
@@ -4304,7 +4344,7 @@ ins_compl_get_exp(pos_T *ini)
                            : ins_buf->b_sfname == NULL
                                ? ins_buf->b_fname
                                : ins_buf->b_sfname);
-               (void)msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
+               (void)msg_trunc_attr(IObuff, TRUE, HL_ATTR(HLF_R));
            }
            else if (*e_cpt == NUL)
                break;
@@ -4334,7 +4374,7 @@ ins_compl_get_exp(pos_T *ini)
                {
                    type = CTRL_X_TAGS;
                    vim_snprintf((char *)IObuff, IOSIZE, _("Scanning tags."));
-                   (void)msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
+                   (void)msg_trunc_attr(IObuff, TRUE, HL_ATTR(HLF_R));
                }
                else
                    type = -1;
@@ -4716,7 +4756,6 @@ ins_compl_next(
     int            in_compl_func)      /* called from complete_check() */
 {
     int            num_matches = -1;
-    int            i;
     int            todo = count;
     compl_T *found_compl = NULL;
     int            found_end = FALSE;
@@ -4908,15 +4947,30 @@ ins_compl_next(
      */
     if (compl_shown_match->cp_fname != NULL)
     {
-       STRCPY(IObuff, "match in file ");
-       i = (vim_strsize(compl_shown_match->cp_fname) + 16) - sc_col;
-       if (i <= 0)
-           i = 0;
-       else
-           STRCAT(IObuff, "<");
-       STRCAT(IObuff, compl_shown_match->cp_fname + i);
-       msg(IObuff);
-       redraw_cmdline = FALSE;     /* don't overwrite! */
+       char    *lead = _("match in file");
+       int     space = sc_col - vim_strsize((char_u *)lead) - 2;
+       char_u  *s;
+       char_u  *e;
+
+       if (space > 0)
+       {
+           /* We need the tail that fits.  With double-byte encoding going
+            * back from the end is very slow, thus go from the start and keep
+            * the text that fits in "space" between "s" and "e". */
+           for (s = e = compl_shown_match->cp_fname; *e != NUL; MB_PTR_ADV(e))
+           {
+               space -= ptr2cells(e);
+               while (space < 0)
+               {
+                   space += ptr2cells(s);
+                   MB_PTR_ADV(s);
+               }
+           }
+           vim_snprintf((char *)IObuff, IOSIZE, "%s %s%s", lead,
+                               s > compl_shown_match->cp_fname ? "<" : "", s);
+           msg(IObuff);
+           redraw_cmdline = FALSE;         /* don't overwrite! */
+       }
     }
 
     return num_matches;
@@ -5064,7 +5118,9 @@ ins_complete(int c, int enable_pum)
     colnr_T    curs_col;           /* cursor column */
     int                n;
     int                save_w_wrow;
+    int                save_w_leftcol;
     int                insert_match;
+    int                save_did_ai = did_ai;
 
     compl_direction = ins_compl_key2dir(c);
     insert_match = ins_compl_use_match(c);
@@ -5294,9 +5350,9 @@ ins_complete(int c, int enable_pum)
            {
                char_u  *p = line + startcol;
 
-               mb_ptr_back(line, p);
+               MB_PTR_BACK(line, p);
                while (p > line && vim_isfilec(PTR2CHAR(p)))
-                   mb_ptr_back(line, p);
+                   MB_PTR_BACK(line, p);
                if (p == line && vim_isfilec(PTR2CHAR(p)))
                    startcol = 0;
                else
@@ -5348,6 +5404,8 @@ ins_complete(int c, int enable_pum)
            {
                EMSG2(_(e_notset), ctrl_x_mode == CTRL_X_FUNCTION
                                             ? "completefunc" : "omnifunc");
+               /* restore did_ai, so that adding comment leader works */
+               did_ai = save_did_ai;
                return FAIL;
            }
 
@@ -5364,7 +5422,7 @@ ins_complete(int c, int enable_pum)
            }
            curwin->w_cursor = pos;     /* restore the cursor position */
            validate_cursor();
-           if (!equalpos(curwin->w_cursor, pos))
+           if (!EQUAL_POS(curwin->w_cursor, pos))
            {
                EMSG(_(e_compldel));
                return FAIL;
@@ -5431,7 +5489,7 @@ ins_complete(int c, int enable_pum)
        }
        else
        {
-           EMSG2(_(e_intern2), "ins_complete()");
+           internal_error("ins_complete()");
            return FAIL;
        }
 
@@ -5504,6 +5562,7 @@ ins_complete(int c, int enable_pum)
      * Find next match (and following matches).
      */
     save_w_wrow = curwin->w_wrow;
+    save_w_leftcol = curwin->w_leftcol;
     n = ins_compl_next(TRUE, ins_compl_key2count(c), insert_match, FALSE);
 
     /* may undisplay the popup menu */
@@ -5648,7 +5707,7 @@ ins_complete(int c, int enable_pum)
            if (!p_smd)
                msg_attr(edit_submode_extra,
                        edit_submode_highl < HLF_COUNT
-                       ? hl_attr(edit_submode_highl) : 0);
+                       ? HL_ATTR(edit_submode_highl) : 0);
        }
        else
            msg_clr_cmdline();  /* necessary for "noshowmode" */
@@ -5656,9 +5715,8 @@ ins_complete(int c, int enable_pum)
 
     /* Show the popup menu, unless we got interrupted. */
     if (enable_pum && !compl_interrupted)
-    {
-       show_pum(save_w_wrow);
-    }
+       show_pum(save_w_wrow, save_w_leftcol);
+
     compl_was_interrupted = compl_interrupted;
     compl_interrupted = FALSE;
 
@@ -5666,21 +5724,22 @@ ins_complete(int c, int enable_pum)
 }
 
     static void
-show_pum(int save_w_wrow)
+show_pum(int prev_w_wrow, int prev_w_leftcol)
 {
-  /* RedrawingDisabled may be set when invoked through complete(). */
-  int n = RedrawingDisabled;
+    /* RedrawingDisabled may be set when invoked through complete(). */
+    int n = RedrawingDisabled;
 
-  RedrawingDisabled = 0;
+    RedrawingDisabled = 0;
 
-  /* If the cursor moved we need to remove the pum first. */
-  setcursor();
-  if (save_w_wrow != curwin->w_wrow)
-      ins_compl_del_pum();
+    /* If the cursor moved or the display scrolled we need to remove the pum
+     * first. */
+    setcursor();
+    if (prev_w_wrow != curwin->w_wrow || prev_w_leftcol != curwin->w_leftcol)
+       ins_compl_del_pum();
 
-  ins_compl_show_pum();
-  setcursor();
-  RedrawingDisabled = n;
+    ins_compl_show_pum();
+    setcursor();
+    RedrawingDisabled = n;
 }
 
 /*
@@ -5944,9 +6003,9 @@ insert_special(
 #endif
 
 #ifdef FEAT_MBYTE
-# define WHITECHAR(cc) (vim_iswhite(cc) && (!enc_utf8 || !utf_iscomposing(utf_ptr2char(ml_get_cursor() + 1))))
+# define WHITECHAR(cc) (VIM_ISWHITE(cc) && (!enc_utf8 || !utf_iscomposing(utf_ptr2char(ml_get_cursor() + 1))))
 #else
-# define WHITECHAR(cc) vim_iswhite(cc)
+# define WHITECHAR(cc) VIM_ISWHITE(cc)
 #endif
 
 /*
@@ -5992,7 +6051,7 @@ insertchar(
      */
     if (textwidth > 0
            && (force_format
-               || (!vim_iswhite(c)
+               || (!VIM_ISWHITE(c)
                    && !((State & REPLACE_FLAG)
 #ifdef FEAT_VREPLACE
                        && !(State & VREPLACE_FLAG)
@@ -6049,7 +6108,7 @@ insertchar(
                ++p;
            middle_len = copy_option_part(&p, lead_end, COM_MAX_LEN, ",");
            /* Don't count trailing white space for middle_len */
-           while (middle_len > 0 && vim_iswhite(lead_end[middle_len - 1]))
+           while (middle_len > 0 && VIM_ISWHITE(lead_end[middle_len - 1]))
                --middle_len;
 
            /* Find the end-comment string */
@@ -6059,7 +6118,7 @@ insertchar(
 
            /* Skip white space before the cursor */
            i = curwin->w_cursor.col;
-           while (--i >= 0 && vim_iswhite(line[i]))
+           while (--i >= 0 && VIM_ISWHITE(line[i]))
                ;
            i++;
 
@@ -6143,6 +6202,9 @@ insertchar(
                && (!has_mbyte || MB_BYTE2LEN_CHECK(c) == 1)
 #endif
                && i < INPUT_BUFLEN
+# ifdef FEAT_FKMAP
+               && !(p_fkmap && KeyTyped) /* Farsi mode mapping moves cursor */
+# endif
                && (textwidth == 0
                    || (virtcol += byte2cells(buf[i - 1])) < (colnr_T)textwidth)
                && !(!no_abbr && !vim_iswordc(c) && vim_iswordc(buf[i - 1])))
@@ -6151,10 +6213,6 @@ insertchar(
            c = vgetc();
            if (p_hkmap && KeyTyped)
                c = hkmap(c);               /* Hebrew mode mapping */
-# ifdef FEAT_FKMAP
-           if (p_fkmap && KeyTyped)
-               c = fkmap(c);               /* Farsi mode mapping */
-# endif
            buf[i++] = c;
 #else
            buf[i++] = vgetc();
@@ -6249,7 +6307,7 @@ internal_format(
            )
     {
        cc = gchar_cursor();
-       if (vim_iswhite(cc))
+       if (VIM_ISWHITE(cc))
        {
            save_char = cc;
            pchar_cursor('x');
@@ -6987,13 +7045,13 @@ stop_insert(
            {
                dec_cursor();
                cc = gchar_cursor();
-               if (!vim_iswhite(cc))
+               if (!VIM_ISWHITE(cc))
                    curwin->w_cursor = tpos;
            }
 
            auto_format(TRUE, FALSE);
 
-           if (vim_iswhite(cc))
+           if (VIM_ISWHITE(cc))
            {
                if (gchar_cursor() != NUL)
                    inc_cursor();
@@ -7029,7 +7087,7 @@ stop_insert(
                if (gchar_cursor() == NUL && curwin->w_cursor.col > 0)
                    --curwin->w_cursor.col;
                cc = gchar_cursor();
-               if (!vim_iswhite(cc))
+               if (!VIM_ISWHITE(cc))
                    break;
                if (del_char(TRUE) == FAIL)
                    break;  /* should not happen */
@@ -7179,7 +7237,7 @@ beginline(int flags)
        {
            char_u  *ptr;
 
-           for (ptr = ml_get_curline(); vim_iswhite(*ptr)
+           for (ptr = ml_get_curline(); VIM_ISWHITE(*ptr)
                               && !((flags & BL_FIX) && ptr[1] == NUL); ++ptr)
                ++curwin->w_cursor.col;
        }
@@ -8149,7 +8207,8 @@ in_cinkeys(
        {
            if (try_match && *look == keytyped)
                return TRUE;
-           ++look;
+           if (*look != NUL)
+               ++look;
        }
 
        /*
@@ -8605,6 +8664,9 @@ ins_esc(
 #ifdef CURSOR_SHAPE
     ui_cursor_shape();         /* may show different cursor shape */
 #endif
+    if (!p_ek)
+       /* Re-enable bracketed paste mode. */
+       out_str(T_BE);
 
     /*
      * When recording or for CTRL-O, need to display the new mode.
@@ -8899,7 +8961,7 @@ ins_bs(
      * can't backup past starting point unless 'backspace' > 1
      * can backup to a previous line if 'backspace' == 0
      */
-    if (       bufempty()
+    if (       BUFEMPTY()
            || (
 #ifdef FEAT_RIGHTLEFT
                !revins_on &&
@@ -8955,7 +9017,7 @@ ins_bs(
 #endif
 
     /*
-     * delete newline!
+     * Delete newline!
      */
     if (curwin->w_cursor.col == 0)
     {
@@ -8970,7 +9032,7 @@ ins_bs(
                               (linenr_T)(curwin->w_cursor.lnum + 1)) == FAIL)
                return FALSE;
            --Insstart.lnum;
-           Insstart.col = MAXCOL;
+           Insstart.col = (colnr_T)STRLEN(ml_get(Insstart.lnum));
        }
        /*
         * In replace mode:
@@ -9121,7 +9183,7 @@ ins_bs(
 
            /* delete characters until we are at or before want_vcol */
            while (vcol > want_vcol
-                   && (cc = *(ml_get_cursor() - 1), vim_iswhite(cc)))
+                   && (cc = *(ml_get_cursor() - 1), VIM_ISWHITE(cc)))
                ins_bs_one(&vcol);
 
            /* insert extra spaces until we are at want_vcol */
@@ -9414,7 +9476,7 @@ ins_mousescroll(int dir)
     }
 # endif
 
-    if (!equalpos(curwin->w_cursor, tpos))
+    if (!EQUAL_POS(curwin->w_cursor, tpos))
     {
        start_arrow(&tpos);
 # ifdef FEAT_CINDENT
@@ -9424,6 +9486,105 @@ ins_mousescroll(int dir)
 }
 #endif
 
+/*
+ * Handle receiving P_PS: start paste mode.  Inserts the following text up to
+ * P_PE literally.
+ * When "drop" is TRUE then consume the text and drop it.
+ */
+    int
+bracketed_paste(paste_mode_T mode, int drop, garray_T *gap)
+{
+    int                c;
+    char_u     buf[NUMBUFLEN + MB_MAXBYTES];
+    int                idx = 0;
+    char_u     *end = find_termcode((char_u *)"PE");
+    int                ret_char = -1;
+    int                save_allow_keys = allow_keys;
+    int                save_paste = p_paste;
+    int                save_ai = curbuf->b_p_ai;
+
+    /* If the end code is too long we can't detect it, read everything. */
+    if (STRLEN(end) >= NUMBUFLEN)
+       end = NULL;
+    ++no_mapping;
+    allow_keys = 0;
+    p_paste = TRUE;
+    curbuf->b_p_ai = FALSE;
+
+    for (;;)
+    {
+       /* When the end is not defined read everything. */
+       if (end == NULL && vpeekc() == NUL)
+           break;
+       c = plain_vgetc();
+#ifdef FEAT_MBYTE
+       if (has_mbyte)
+           idx += (*mb_char2bytes)(c, buf + idx);
+       else
+#endif
+           buf[idx++] = c;
+       buf[idx] = NUL;
+       if (end != NULL && STRNCMP(buf, end, idx) == 0)
+       {
+           if (end[idx] == NUL)
+               break; /* Found the end of paste code. */
+           continue;
+       }
+       if (!drop)
+       {
+           switch (mode)
+           {
+               case PASTE_CMDLINE:
+                   put_on_cmdline(buf, idx, TRUE);
+                   break;
+
+               case PASTE_EX:
+                   if (gap != NULL && ga_grow(gap, idx) == OK)
+                   {
+                       mch_memmove((char *)gap->ga_data + gap->ga_len,
+                                                            buf, (size_t)idx);
+                       gap->ga_len += idx;
+                   }
+                   break;
+
+               case PASTE_INSERT:
+                   if (stop_arrow() == OK)
+                   {
+                       c = buf[0];
+                       if (idx == 1 && (c == CAR || c == K_KENTER || c == NL))
+                           ins_eol(c);
+                       else
+                       {
+                           ins_char_bytes(buf, idx);
+                           AppendToRedobuffLit(buf, idx);
+                       }
+                   }
+                   break;
+
+               case PASTE_ONE_CHAR:
+                   if (ret_char == -1)
+                   {
+#ifdef FEAT_MBYTE
+                       if (has_mbyte)
+                           ret_char = (*mb_ptr2char)(buf);
+                       else
+#endif
+                           ret_char = buf[0];
+                   }
+                   break;
+           }
+       }
+       idx = 0;
+    }
+
+    --no_mapping;
+    allow_keys = save_allow_keys;
+    p_paste = save_paste;
+    curbuf->b_p_ai = save_ai;
+
+    return ret_char;
+}
+
 #if defined(FEAT_GUI_TABLINE) || defined(PROTO)
     static void
 ins_tabline(int c)
@@ -9909,7 +10070,7 @@ ins_tab(void)
 
        /* Find first white before the cursor */
        fpos = curwin->w_cursor;
-       while (fpos.col > 0 && vim_iswhite(ptr[-1]))
+       while (fpos.col > 0 && VIM_ISWHITE(ptr[-1]))
        {
            --fpos.col;
            --ptr;
@@ -9930,7 +10091,7 @@ ins_tab(void)
 
        /* Use as many TABs as possible.  Beware of 'breakindent', 'showbreak'
         * and 'linebreak' adding extra virtual columns. */
-       while (vim_iswhite(*ptr))
+       while (VIM_ISWHITE(*ptr))
        {
            i = lbr_chartabsize(NULL, (char_u *)"\t", vcol);
            if (vcol + i > want_vcol)
@@ -10309,7 +10470,7 @@ ins_try_si(int c)
            ptr = ml_get(pos->lnum);
            i = pos->col;
            if (i > 0)          /* skip blanks before '{' */
-               while (--i > 0 && vim_iswhite(ptr[i]))
+               while (--i > 0 && VIM_ISWHITE(ptr[i]))
                    ;
            curwin->w_cursor.lnum = pos->lnum;
            curwin->w_cursor.col = i;
index 18eb879..5f589eb 100644 (file)
@@ -242,14 +242,38 @@ static void list_one_var(dictitem_T *v, char_u *prefix, int *first);
 static void list_one_var_a(char_u *prefix, char_u *name, int type, char_u *string, int *first);
 static char_u *find_option_end(char_u **arg, int *opt_flags);
 
-#ifdef EBCDIC
-static int compare_func_name(const void *s1, const void *s2);
-static void sortFunctions();
-#endif
-
 /* for VIM_VERSION_ defines */
 #include "version.h"
 
+
+#if defined(EBCDIC) || defined(PROTO)
+/*
+ * Compare struct fst by function name.
+ */
+    static int
+compare_func_name(const void *s1, const void *s2)
+{
+    struct fst *p1 = (struct fst *)s1;
+    struct fst *p2 = (struct fst *)s2;
+
+    return STRCMP(p1->f_name, p2->f_name);
+}
+
+/*
+ * Sort the function table by function name.
+ * The sorting of the table above is ASCII dependant.
+ * On machines using EBCDIC we have to sort it.
+ */
+    static void
+sortFunctions(void)
+{
+    int                funcCnt = (int)(sizeof(functions) / sizeof(struct fst)) - 1;
+
+    qsort(functions, (size_t)funcCnt, sizeof(struct fst), compare_func_name);
+}
+#endif
+
+
 /*
  * Initialize the global and v: variables.
  */
@@ -270,7 +294,7 @@ eval_init(void)
        p = &vimvars[i];
        if (STRLEN(p->vv_name) > 16)
        {
-           EMSG("INTERNAL: name too long, increase size of dictitem16_T");
+           IEMSG("INTERNAL: name too long, increase size of dictitem16_T");
            getout(1);
        }
        STRCPY(p->vv_di.di_key, p->vv_name);
@@ -839,7 +863,7 @@ restore_vimvar(int idx, typval_T *save_tv)
     {
        hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key);
        if (HASHITEM_EMPTY(hi))
-           EMSG2(_(e_intern2), "restore_vimvar()");
+           internal_error("restore_vimvar()");
        else
            hash_remove(&vimvarht, hi);
     }
@@ -926,7 +950,7 @@ eval_expr(char_u *arg, char_u **nextcmd)
 
 
 /*
- * Call some vimL function and return the result in "*rettv".
+ * Call some Vim script function and return the result in "*rettv".
  * Uses argv[argc] for the function arguments.  Only Number and String
  * arguments are currently supported.
  * Returns OK or FAIL.
@@ -1003,7 +1027,7 @@ call_vim_function(
 }
 
 /*
- * Call vimL function "func" and return the result as a number.
+ * Call Vim script function "func" and return the result as a number.
  * Returns -1 when calling the function fails.
  * Uses argv[argc] for the function arguments.
  */
@@ -1031,7 +1055,7 @@ call_func_retnr(
 
 # if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO)
 /*
- * Call vimL function "func" and return the result as a string.
+ * Call Vim script function "func" and return the result as a string.
  * Returns NULL when calling the function fails.
  * Uses argv[argc] for the function arguments.
  */
@@ -1056,7 +1080,7 @@ call_func_retstr(
 # endif
 
 /*
- * Call vimL function "func" and return the result as a List.
+ * Call Vim script function "func" and return the result as a List.
  * Uses argv[argc] for the function arguments.
  * Returns NULL when there is something wrong.
  */
@@ -1308,7 +1332,7 @@ ex_let_vars(
        }
        else if (*arg != ',' && *arg != ']')
        {
-           EMSG2(_(e_intern2), "ex_let_vars()");
+           internal_error("ex_let_vars()");
            return FAIL;
        }
     }
@@ -1427,14 +1451,8 @@ list_glob_vars(int *first)
     static void
 list_buf_vars(int *first)
 {
-    char_u     numbuf[NUMBUFLEN];
-
     list_hashtable_vars(&curbuf->b_vars->dv_hashtab, (char_u *)"b:",
                                                                 TRUE, first);
-
-    sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick);
-    list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER,
-                                                              numbuf, first);
 }
 
 /*
@@ -1498,7 +1516,7 @@ list_arg_vars(exarg_T *eap, char_u *arg, int *first)
        if (error || eap->skip)
        {
            arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START);
-           if (!vim_iswhite(*arg) && !ends_excmd(*arg))
+           if (!VIM_ISWHITE(*arg) && !ends_excmd(*arg))
            {
                emsg_severe = TRUE;
                EMSG(_(e_trailing));
@@ -1782,20 +1800,6 @@ ex_let_one(
 }
 
 /*
- * If "arg" is equal to "b:changedtick" give an error and return TRUE.
- */
-    int
-check_changedtick(char_u *arg)
-{
-    if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13]))
-    {
-       EMSG2(_(e_readonlyvar), arg);
-       return TRUE;
-    }
-    return FALSE;
-}
-
-/*
  * Get an lval: variable, Dict item or List item that can be assigned a value
  * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]",
  * "name.key", "name.key[expr]" etc.
@@ -1807,6 +1811,7 @@ check_changedtick(char_u *arg)
  *
  * flags:
  *  GLV_QUIET:       do not give error messages
+ *  GLV_READ_ONLY:   will not change the variable
  *  GLV_NO_AUTOLOAD: do not use script autoloading
  *
  * Returns a pointer to just after the name, including indexes.
@@ -1851,7 +1856,7 @@ get_lval(
     if (expr_start != NULL)
     {
        /* Don't expand the name when we already know there is an error. */
-       if (unlet && !vim_iswhite(*p) && !ends_excmd(*p)
+       if (unlet && !VIM_ISWHITE(*p) && !ends_excmd(*p)
                                                    && *p != '[' && *p != '.')
        {
            EMSG(_(e_trailing));
@@ -1893,6 +1898,8 @@ get_lval(
      * Loop until no more [idx] or .key is following.
      */
     lp->ll_tv = &v->di_tv;
+    var1.v_type = VAR_UNKNOWN;
+    var2.v_type = VAR_UNKNOWN;
     while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT))
     {
        if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL)
@@ -1950,8 +1957,7 @@ get_lval(
                {
                    if (!quiet)
                        EMSG(_(e_dictrange));
-                   if (!empty1)
-                       clear_tv(&var1);
+                   clear_tv(&var1);
                    return NULL;
                }
                if (rettv != NULL && (rettv->v_type != VAR_LIST
@@ -1959,8 +1965,7 @@ get_lval(
                {
                    if (!quiet)
                        EMSG(_("E709: [:] requires a List value"));
-                   if (!empty1)
-                       clear_tv(&var1);
+                   clear_tv(&var1);
                    return NULL;
                }
                p = skipwhite(p + 1);
@@ -1971,15 +1976,13 @@ get_lval(
                    lp->ll_empty2 = FALSE;
                    if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */
                    {
-                       if (!empty1)
-                           clear_tv(&var1);
+                       clear_tv(&var1);
                        return NULL;
                    }
                    if (get_tv_string_chk(&var2) == NULL)
                    {
                        /* not a number or string */
-                       if (!empty1)
-                           clear_tv(&var1);
+                       clear_tv(&var1);
                        clear_tv(&var2);
                        return NULL;
                    }
@@ -1993,10 +1996,8 @@ get_lval(
            {
                if (!quiet)
                    EMSG(_(e_missbrac));
-               if (!empty1)
-                   clear_tv(&var1);
-               if (lp->ll_range && !lp->ll_empty2)
-                   clear_tv(&var2);
+               clear_tv(&var1);
+               clear_tv(&var2);
                return NULL;
            }
 
@@ -2059,26 +2060,27 @@ get_lval(
                {
                    if (!quiet)
                        EMSG2(_(e_dictkey), key);
-                   if (len == -1)
-                       clear_tv(&var1);
+                   clear_tv(&var1);
                    return NULL;
                }
                if (len == -1)
                    lp->ll_newkey = vim_strsave(key);
                else
                    lp->ll_newkey = vim_strnsave(key, len);
-               if (len == -1)
-                   clear_tv(&var1);
+               clear_tv(&var1);
                if (lp->ll_newkey == NULL)
                    p = NULL;
                break;
            }
            /* existing variable, need to check if it can be changed */
-           else if (var_check_ro(lp->ll_di->di_flags, name, FALSE))
+           else if ((flags & GLV_READ_ONLY) == 0
+                            && var_check_ro(lp->ll_di->di_flags, name, FALSE))
+           {
+               clear_tv(&var1);
                return NULL;
+           }
 
-           if (len == -1)
-               clear_tv(&var1);
+           clear_tv(&var1);
            lp->ll_tv = &lp->ll_di->di_tv;
        }
        else
@@ -2089,11 +2091,10 @@ get_lval(
            if (empty1)
                lp->ll_n1 = 0;
            else
-           {
+               /* is number or string */
                lp->ll_n1 = (long)get_tv_number(&var1);
-                                                   /* is number or string */
-               clear_tv(&var1);
-           }
+           clear_tv(&var1);
+
            lp->ll_dict = NULL;
            lp->ll_list = lp->ll_tv->vval.v_list;
            lp->ll_li = list_find(lp->ll_list, lp->ll_n1);
@@ -2107,8 +2108,7 @@ get_lval(
            }
            if (lp->ll_li == NULL)
            {
-               if (lp->ll_range && !lp->ll_empty2)
-                   clear_tv(&var2);
+               clear_tv(&var2);
                if (!quiet)
                    EMSGN(_(e_listidx), lp->ll_n1);
                return NULL;
@@ -2152,6 +2152,7 @@ get_lval(
        }
     }
 
+    clear_tv(&var1);
     return p;
 }
 
@@ -2184,32 +2185,29 @@ set_var_lval(
 
     if (lp->ll_tv == NULL)
     {
-       if (!check_changedtick(lp->ll_name))
+       cc = *endp;
+       *endp = NUL;
+       if (op != NULL && *op != '=')
        {
-           cc = *endp;
-           *endp = NUL;
-           if (op != NULL && *op != '=')
-           {
-               typval_T tv;
+           typval_T tv;
 
-               /* handle +=, -= and .= */
-               di = NULL;
-               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, FALSE)
-                             && !tv_check_lock(di->di_tv.v_lock, lp->ll_name,
-                                                                     FALSE)))
-                           && tv_op(&tv, rettv, op) == OK)
-                       set_var(lp->ll_name, &tv, FALSE);
-                   clear_tv(&tv);
-               }
+           /* handle +=, -= and .= */
+           di = NULL;
+           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, FALSE)
+                         && !tv_check_lock(di->di_tv.v_lock, lp->ll_name,
+                                                                 FALSE)))
+                       && tv_op(&tv, rettv, op) == OK)
+                   set_var(lp->ll_name, &tv, FALSE);
+               clear_tv(&tv);
            }
-           else
-               set_var(lp->ll_name, rettv, copy);
-           *endp = cc;
        }
+       else
+           set_var(lp->ll_name, rettv, copy);
+       *endp = cc;
     }
     else if (tv_check_lock(lp->ll_newkey == NULL
                ? lp->ll_tv->v_lock
@@ -2451,7 +2449,7 @@ eval_for_line(
        return fi;
 
     expr = skipwhite(expr);
-    if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2]))
+    if (expr[0] != 'i' || expr[1] != 'n' || !VIM_ISWHITE(expr[2]))
     {
        EMSG(_("E690: Missing \"in\" after :for"));
        return fi;
@@ -2553,8 +2551,8 @@ set_context_for_expression(
            for (p = arg + STRLEN(arg); p >= arg; )
            {
                xp->xp_pattern = p;
-               mb_ptr_back(arg, p);
-               if (vim_iswhite(*p))
+               MB_PTR_BACK(arg, p);
+               if (VIM_ISWHITE(*p))
                    break;
            }
            return;
@@ -2700,7 +2698,7 @@ ex_unletlock(
                                                             FNE_CHECK_START);
        if (lv.ll_name == NULL)
            error = TRUE;           /* error but continue parsing */
-       if (name_end == NULL || (!vim_iswhite(*name_end)
+       if (name_end == NULL || (!VIM_ISWHITE(*name_end)
                                                   && !ends_excmd(*name_end)))
        {
            if (name_end != NULL)
@@ -2752,9 +2750,7 @@ do_unlet_var(
        *name_end = NUL;
 
        /* Normal name or expanded name. */
-       if (check_changedtick(lp->ll_name))
-           ret = FAIL;
-       else if (do_unlet(lp->ll_name, forceit) == FAIL)
+       if (do_unlet(lp->ll_name, forceit) == FAIL)
            ret = FAIL;
        *name_end = cc;
     }
@@ -2830,7 +2826,7 @@ do_unlet(char_u *name, int forceit)
            }
            if (d == NULL)
            {
-               EMSG2(_(e_intern2), "do_unlet()");
+               internal_error("do_unlet()");
                return FAIL;
            }
        }
@@ -2880,21 +2876,22 @@ do_lock_var(
        *name_end = NUL;
 
        /* Normal name or expanded name. */
-       if (check_changedtick(lp->ll_name))
+       di = find_var(lp->ll_name, NULL, TRUE);
+       if (di == NULL)
            ret = FAIL;
+       else if ((di->di_flags & DI_FLAGS_FIX)
+                       && di->di_tv.v_type != VAR_DICT
+                       && di->di_tv.v_type != VAR_LIST)
+           /* For historic reasons this error is not given for a list or dict.
+            * E.g., the b: dict could be locked/unlocked. */
+           EMSG2(_("E940: Cannot lock or unlock variable %s"), lp->ll_name);
        else
        {
-           di = find_var(lp->ll_name, NULL, TRUE);
-           if (di == NULL)
-               ret = FAIL;
+           if (lock)
+               di->di_flags |= DI_FLAGS_LOCK;
            else
-           {
-               if (lock)
-                   di->di_flags |= DI_FLAGS_LOCK;
-               else
-                   di->di_flags &= ~DI_FLAGS_LOCK;
-               item_lock(&di->di_tv, deep, lock);
-           }
+               di->di_flags &= ~DI_FLAGS_LOCK;
+           item_lock(&di->di_tv, deep, lock);
        }
        *name_end = cc;
     }
@@ -3115,11 +3112,6 @@ get_user_var_name(expand_T *xp, int idx)
            ++hi;
        return cat_prefix_varname('b', hi->hi_key);
     }
-    if (bdone == ht->ht_used)
-    {
-       ++bdone;
-       return (char_u *)"b:changedtick";
-    }
 
     /* w: variables */
     ht = &curwin->w_vars->dv_hashtab;
@@ -4085,21 +4077,12 @@ eval6(
                {
                    if (n2 == 0)        /* give an error message? */
                    {
-#ifdef FEAT_NUM64
-                       if (n1 == 0)
-                           n1 = -0x7fffffffffffffffLL - 1; /* similar to NaN */
-                       else if (n1 < 0)
-                           n1 = -0x7fffffffffffffffLL;
-                       else
-                           n1 = 0x7fffffffffffffffLL;
-#else
                        if (n1 == 0)
-                           n1 = -0x7fffffffL - 1L;     /* similar to NaN */
+                           n1 = VARNUM_MIN; /* similar to NaN */
                        else if (n1 < 0)
-                           n1 = -0x7fffffffL;
+                           n1 = -VARNUM_MAX;
                        else
-                           n1 = 0x7fffffffL;
-#endif
+                           n1 = VARNUM_MAX;
                    }
                    else
                        n1 = n1 / n2;
@@ -4339,10 +4322,17 @@ eval7(
                 * use its contents. */
                s = deref_func_name(s, &len, &partial, !evaluate);
 
-               /* Invoke the function. */
-               ret = get_func_tv(s, len, rettv, arg,
-                         curwin->w_cursor.lnum, curwin->w_cursor.lnum,
-                         &len, evaluate, partial, NULL);
+               /* Need to make a copy, in case evaluating the arguments makes
+                * the name invalid. */
+               s = vim_strsave(s);
+               if (s == NULL)
+                   ret = FAIL;
+               else
+                   /* Invoke the function. */
+                   ret = get_func_tv(s, len, rettv, arg,
+                             curwin->w_cursor.lnum, curwin->w_cursor.lnum,
+                             &len, evaluate, partial, NULL);
+               vim_free(s);
 
                /* If evaluate is FALSE rettv->v_type was not set in
                 * get_func_tv, but it's needed in handle_subscript() to parse
@@ -4824,7 +4814,7 @@ get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
     /*
      * Find the end of the string, skipping backslashed characters.
      */
-    for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p))
+    for (p = *arg + 1; *p != NUL && *p != '"'; MB_PTR_ADV(p))
     {
        if (*p == '\\' && p[1] != NUL)
        {
@@ -4962,7 +4952,7 @@ get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate)
     /*
      * Find the end of the string, skipping ''.
      */
-    for (p = *arg + 1; *p != NUL; mb_ptr_adv(p))
+    for (p = *arg + 1; *p != NUL; MB_PTR_ADV(p))
     {
        if (*p == '\'')
        {
@@ -5678,7 +5668,7 @@ get_var_special_name(int nr)
        case VVAL_NONE:  return "v:none";
        case VVAL_NULL:  return "v:null";
     }
-    EMSG2(_(e_intern2), "get_var_special_name()");
+    internal_error("get_var_special_name()");
     return "42";
 }
 
@@ -5920,7 +5910,7 @@ string_quote(char_u *str, int function)
     if (str != NULL)
     {
        len += (unsigned)STRLEN(str);
-       for (p = str; *p != NUL; mb_ptr_adv(p))
+       for (p = str; *p != NUL; MB_PTR_ADV(p))
            if (*p == '\'')
                ++len;
     }
@@ -5964,6 +5954,22 @@ string2float(
     char       *s = (char *)text;
     float_T    f;
 
+    /* MS-Windows does not deal with "inf" and "nan" properly. */
+    if (STRNICMP(text, "inf", 3) == 0)
+    {
+       *value = INFINITY;
+       return 3;
+    }
+    if (STRNICMP(text, "-inf", 3) == 0)
+    {
+       *value = -INFINITY;
+       return 4;
+    }
+    if (STRNICMP(text, "nan", 3) == 0)
+    {
+       *value = NAN;
+       return 3;
+    }
     f = strtod(s, &s);
     *value = f;
     return (int)((char_u *)s - text);
@@ -6114,13 +6120,16 @@ var2fpos(
        if (name[1] == '0')             /* "w0": first visible line */
        {
            update_topline();
-           pos.lnum = curwin->w_topline;
+           /* In silent Ex mode topline is zero, but that's not a valid line
+            * number; use one instead. */
+           pos.lnum = curwin->w_topline > 0 ? curwin->w_topline : 1;
            return &pos;
        }
        else if (name[1] == '$')        /* "w$": last visible line */
        {
            validate_botline();
-           pos.lnum = curwin->w_botline - 1;
+           /* In silent Ex mode botline is zero, return zero then. */
+           pos.lnum = curwin->w_botline > 0 ? curwin->w_botline - 1 : 0;
            return &pos;
        }
     }
@@ -6363,12 +6372,12 @@ find_name_end(
                        || *p == '{'
                        || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.'))
                        || mb_nest != 0
-                       || br_nest != 0); mb_ptr_adv(p))
+                       || br_nest != 0); MB_PTR_ADV(p))
     {
        if (*p == '\'')
        {
            /* skip over 'string' to avoid counting [ and ] inside it. */
-           for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p))
+           for (p = p + 1; *p != NUL && *p != '\''; MB_PTR_ADV(p))
                ;
            if (*p == NUL)
                break;
@@ -6376,7 +6385,7 @@ find_name_end(
        else if (*p == '"')
        {
            /* skip over "str\"ing" to avoid counting [ and ] inside it. */
-           for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p))
+           for (p = p + 1; *p != NUL && *p != '"'; MB_PTR_ADV(p))
                if (*p == '\\' && p[1] != NUL)
                    ++p;
            if (*p == NUL)
@@ -6634,7 +6643,7 @@ set_vim_var_dict(int idx, dict_T *val)
            if (HASHITEM_EMPTY(hi))
                continue;
            --todo;
-           HI2DI(hi)->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
+           HI2DI(hi)->di_flags |= DI_FLAGS_RO | DI_FLAGS_FIX;
        }
     }
 }
@@ -6777,7 +6786,6 @@ get_var_tv(
 {
     int                ret = OK;
     typval_T   *tv = NULL;
-    typval_T   atv;
     dictitem_T *v;
     int                cc;
 
@@ -6786,27 +6794,14 @@ get_var_tv(
     name[len] = NUL;
 
     /*
-     * Check for "b:changedtick".
-     */
-    if (STRCMP(name, "b:changedtick") == 0)
-    {
-       atv.v_type = VAR_NUMBER;
-       atv.vval.v_number = curbuf->b_changedtick;
-       tv = &atv;
-    }
-
-    /*
      * Check for user-defined variables.
      */
-    else
+    v = find_var(name, NULL, no_autoload);
+    if (v != NULL)
     {
-       v = find_var(name, NULL, no_autoload);
-       if (v != NULL)
-       {
-           tv = &v->di_tv;
-           if (dip != NULL)
-               *dip = v;
-       }
+       tv = &v->di_tv;
+       if (dip != NULL)
+           *dip = v;
     }
 
     if (tv == NULL)
@@ -6874,7 +6869,7 @@ handle_subscript(
                || (**arg == '.' && rettv->v_type == VAR_DICT)
                || (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC
                                            || rettv->v_type == VAR_PARTIAL)))
-           && !vim_iswhite(*(*arg - 1)))
+           && !VIM_ISWHITE(*(*arg - 1)))
     {
        if (**arg == '(')
        {
@@ -7152,7 +7147,7 @@ get_tv_number_chk(typval_T *varp, int *denote)
            break;
 #endif
        case VAR_UNKNOWN:
-           EMSG2(_(e_intern2), "get_tv_number(UNKNOWN)");
+           internal_error("get_tv_number(UNKNOWN)");
            break;
     }
     if (denote == NULL)                /* useful for values that must be unsigned */
@@ -7199,7 +7194,7 @@ get_tv_float(typval_T *varp)
            break;
 # endif
        case VAR_UNKNOWN:
-           EMSG2(_(e_intern2), "get_tv_float(UNKNOWN)");
+           internal_error("get_tv_float(UNKNOWN)");
            break;
     }
     return 0;
@@ -7283,7 +7278,7 @@ get_tv_string_buf_chk(typval_T *varp, char_u *buf)
                if (job == NULL)
                    return (char_u *)"no process";
                status = job->jv_status == JOB_FAILED ? "fail"
-                               : job->jv_status == JOB_ENDED ? "dead"
+                               : job->jv_status >= JOB_ENDED ? "dead"
                                : "run";
 # ifdef UNIX
                vim_snprintf((char *)buf, NUMBUFLEN,
@@ -7733,7 +7728,7 @@ set_var(
                return;
            }
            else if (v->di_tv.v_type != tv->v_type)
-               EMSG2(_(e_intern2), "set_var()");
+               internal_error("set_var()");
        }
 
        clear_tv(&v->di_tv);
@@ -7962,7 +7957,7 @@ copy_tv(typval_T *from, typval_T *to)
            }
            break;
        case VAR_UNKNOWN:
-           EMSG2(_(e_intern2), "copy_tv(UNKNOWN)");
+           internal_error("copy_tv(UNKNOWN)");
            break;
     }
 }
@@ -8036,7 +8031,7 @@ item_copy(
                ret = FAIL;
            break;
        case VAR_UNKNOWN:
-           EMSG2(_(e_intern2), "item_copy(UNKNOWN)");
+           internal_error("item_copy(UNKNOWN)");
            ret = FAIL;
     }
     --recurse;
@@ -8327,6 +8322,14 @@ ex_execute(exarg_T *eap)
 
     if (ret != FAIL && ga.ga_data != NULL)
     {
+       if (eap->cmdidx == CMD_echomsg || eap->cmdidx == CMD_echoerr)
+       {
+           /* Mark the already saved text as finishing the line, so that what
+            * follows is displayed on a new line when scrolling back at the
+            * more prompt. */
+           msg_sb_eol();
+       }
+
        if (eap->cmdidx == CMD_echomsg)
        {
            MSG_ATTR(ga.ga_data, echo_attr);
@@ -9083,6 +9086,17 @@ assert_bool(typval_T *argvars, int isTrue)
 }
 
     void
+assert_report(typval_T *argvars)
+{
+    garray_T   ga;
+
+    prepare_assert_error(&ga);
+    ga_concat(&ga, get_tv_string(&argvars[0]));
+    assert_error(&ga);
+    ga_clear(&ga);
+}
+
+    void
 assert_exception(typval_T *argvars)
 {
     garray_T   ga;
@@ -9202,28 +9216,30 @@ fill_assert_error(
 
     if (opt_msg_tv->v_type != VAR_UNKNOWN)
     {
-       ga_concat(gap, tv2string(opt_msg_tv, &tofree, numbuf, 0));
+       ga_concat(gap, echo_string(opt_msg_tv, &tofree, numbuf, 0));
        vim_free(tofree);
+       ga_concat(gap, (char_u *)": ");
     }
+
+    if (atype == ASSERT_MATCH || atype == ASSERT_NOTMATCH)
+       ga_concat(gap, (char_u *)"Pattern ");
+    else if (atype == ASSERT_NOTEQUAL)
+       ga_concat(gap, (char_u *)"Expected not equal to ");
     else
+       ga_concat(gap, (char_u *)"Expected ");
+    if (exp_str == NULL)
+    {
+       ga_concat_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0));
+       vim_free(tofree);
+    }
+    else
+       ga_concat_esc(gap, exp_str);
+    if (atype != ASSERT_NOTEQUAL)
     {
-       if (atype == ASSERT_MATCH || atype == ASSERT_NOTMATCH)
-           ga_concat(gap, (char_u *)"Pattern ");
-       else
-           ga_concat(gap, (char_u *)"Expected ");
-       if (exp_str == NULL)
-       {
-           ga_concat_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0));
-           vim_free(tofree);
-       }
-       else
-           ga_concat_esc(gap, exp_str);
        if (atype == ASSERT_MATCH)
            ga_concat(gap, (char_u *)" does not match ");
        else if (atype == ASSERT_NOTMATCH)
            ga_concat(gap, (char_u *)" does match ");
-       else if (atype == ASSERT_NOTEQUAL)
-           ga_concat(gap, (char_u *)" differs from ");
        else
            ga_concat(gap, (char_u *)" but got ");
        ga_concat_esc(gap, tv2string(got_tv, &tofree, numbuf, 0));
@@ -9416,7 +9432,7 @@ shortpath_for_partial(
     /* Count up the path separators from the RHS.. so we know which part
      * of the path to return. */
     sepcount = 0;
-    for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p))
+    for (p = *fnamep; p < *fnamep + *fnamelen; MB_PTR_ADV(p))
        if (vim_ispathsep(*p))
            ++sepcount;
 
@@ -9534,7 +9550,7 @@ repeat:
        }
 
        /* When "/." or "/.." is used: force expansion to get rid of it. */
-       for (p = *fnamep; *p != NUL; mb_ptr_adv(p))
+       for (p = *fnamep; *p != NUL; MB_PTR_ADV(p))
        {
            if (vim_ispathsep(*p)
                    && p[1] == '.'
@@ -9664,7 +9680,7 @@ repeat:
        *usedlen += 2;
        s = get_past_head(*fnamep);
        while (tail > s && after_pathsep(s, tail))
-           mb_ptr_back(*fnamep, tail);
+           MB_PTR_BACK(*fnamep, tail);
        *fnamelen = (int)(tail - *fnamep);
 #ifdef VMS
        if (*fnamelen > 0)
@@ -9683,7 +9699,7 @@ repeat:
        else
        {
            while (tail > s && !after_pathsep(s, tail))
-               mb_ptr_back(*fnamep, tail);
+               MB_PTR_BACK(*fnamep, tail);
        }
     }
 
index f643329..45c43f6 100644 (file)
@@ -52,12 +52,16 @@ static void f_assert_inrange(typval_T *argvars, typval_T *rettv);
 static void f_assert_match(typval_T *argvars, typval_T *rettv);
 static void f_assert_notequal(typval_T *argvars, typval_T *rettv);
 static void f_assert_notmatch(typval_T *argvars, typval_T *rettv);
+static void f_assert_report(typval_T *argvars, typval_T *rettv);
 static void f_assert_true(typval_T *argvars, typval_T *rettv);
 #ifdef FEAT_FLOAT
 static void f_asin(typval_T *argvars, typval_T *rettv);
 static void f_atan(typval_T *argvars, typval_T *rettv);
 static void f_atan2(typval_T *argvars, typval_T *rettv);
 #endif
+#ifdef FEAT_BEVAL
+static void f_balloon_show(typval_T *argvars, typval_T *rettv);
+#endif
 static void f_browse(typval_T *argvars, typval_T *rettv);
 static void f_browsedir(typval_T *argvars, typval_T *rettv);
 static void f_bufexists(typval_T *argvars, typval_T *rettv);
@@ -76,6 +80,7 @@ static void f_call(typval_T *argvars, typval_T *rettv);
 static void f_ceil(typval_T *argvars, typval_T *rettv);
 #endif
 #ifdef FEAT_JOB_CHANNEL
+static void f_ch_canread(typval_T *argvars, typval_T *rettv);
 static void f_ch_close(typval_T *argvars, typval_T *rettv);
 static void f_ch_close_in(typval_T *argvars, typval_T *rettv);
 static void f_ch_evalexpr(typval_T *argvars, typval_T *rettv);
@@ -288,6 +293,9 @@ static void f_py3eval(typval_T *argvars, typval_T *rettv);
 #ifdef FEAT_PYTHON
 static void f_pyeval(typval_T *argvars, typval_T *rettv);
 #endif
+#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
+static void f_pyxeval(typval_T *argvars, typval_T *rettv);
+#endif
 static void f_range(typval_T *argvars, typval_T *rettv);
 static void f_readfile(typval_T *argvars, typval_T *rettv);
 static void f_reltime(typval_T *argvars, typval_T *rettv);
@@ -300,6 +308,7 @@ static void f_remote_foreground(typval_T *argvars, typval_T *rettv);
 static void f_remote_peek(typval_T *argvars, typval_T *rettv);
 static void f_remote_read(typval_T *argvars, typval_T *rettv);
 static void f_remote_send(typval_T *argvars, typval_T *rettv);
+static void f_remote_startserver(typval_T *argvars, typval_T *rettv);
 static void f_remove(typval_T *argvars, typval_T *rettv);
 static void f_rename(typval_T *argvars, typval_T *rettv);
 static void f_repeat(typval_T *argvars, typval_T *rettv);
@@ -383,8 +392,9 @@ static void f_tagfiles(typval_T *argvars, typval_T *rettv);
 static void f_tempname(typval_T *argvars, typval_T *rettv);
 static void f_test_alloc_fail(typval_T *argvars, typval_T *rettv);
 static void f_test_autochdir(typval_T *argvars, typval_T *rettv);
-static void f_test_disable_char_avail(typval_T *argvars, typval_T *rettv);
+static void f_test_override(typval_T *argvars, typval_T *rettv);
 static void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv);
+static void f_test_ignore_error(typval_T *argvars, typval_T *rettv);
 #ifdef FEAT_JOB_CHANNEL
 static void f_test_null_channel(typval_T *argvars, typval_T *rettv);
 #endif
@@ -470,15 +480,19 @@ static struct fst
     {"assert_exception", 1, 2, f_assert_exception},
     {"assert_fails",   1, 2, f_assert_fails},
     {"assert_false",   1, 2, f_assert_false},
-    {"assert_inrange", 2, 3, f_assert_inrange},
+    {"assert_inrange", 3, 4, f_assert_inrange},
     {"assert_match",   2, 3, f_assert_match},
     {"assert_notequal",        2, 3, f_assert_notequal},
     {"assert_notmatch",        2, 3, f_assert_notmatch},
+    {"assert_report",  1, 1, f_assert_report},
     {"assert_true",    1, 2, f_assert_true},
 #ifdef FEAT_FLOAT
     {"atan",           1, 1, f_atan},
     {"atan2",          2, 2, f_atan2},
 #endif
+#ifdef FEAT_BEVAL
+    {"balloon_show",   1, 1, f_balloon_show},
+#endif
     {"browse",         4, 4, f_browse},
     {"browsedir",      2, 2, f_browsedir},
     {"bufexists",      1, 1, f_bufexists},
@@ -499,6 +513,7 @@ static struct fst
     {"ceil",           1, 1, f_ceil},
 #endif
 #ifdef FEAT_JOB_CHANNEL
+    {"ch_canread",     1, 1, f_ch_canread},
     {"ch_close",       1, 1, f_ch_close},
     {"ch_close_in",    1, 1, f_ch_close_in},
     {"ch_evalexpr",    2, 3, f_ch_evalexpr},
@@ -714,6 +729,9 @@ static struct fst
 #ifdef FEAT_PYTHON
     {"pyeval",         1, 1, f_pyeval},
 #endif
+#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
+    {"pyxeval",                1, 1, f_pyxeval},
+#endif
     {"range",          1, 3, f_range},
     {"readfile",       1, 3, f_readfile},
     {"reltime",                0, 2, f_reltime},
@@ -721,11 +739,12 @@ static struct fst
     {"reltimefloat",   1, 1, f_reltimefloat},
 #endif
     {"reltimestr",     1, 1, f_reltimestr},
-    {"remote_expr",    2, 3, f_remote_expr},
+    {"remote_expr",    2, 4, f_remote_expr},
     {"remote_foreground", 1, 1, f_remote_foreground},
     {"remote_peek",    1, 2, f_remote_peek},
-    {"remote_read",    1, 1, f_remote_read},
+    {"remote_read",    1, 2, f_remote_read},
     {"remote_send",    2, 3, f_remote_send},
+    {"remote_startserver", 1, 1, f_remote_startserver},
     {"remove",         2, 3, f_remove},
     {"rename",         2, 2, f_rename},
     {"repeat",         2, 2, f_repeat},
@@ -805,7 +824,7 @@ static struct fst
     {"tabpagenr",      0, 1, f_tabpagenr},
     {"tabpagewinnr",   1, 2, f_tabpagewinnr},
     {"tagfiles",       0, 0, f_tagfiles},
-    {"taglist",                1, 1, f_taglist},
+    {"taglist",                1, 2, f_taglist},
 #ifdef FEAT_FLOAT
     {"tan",            1, 1, f_tan},
     {"tanh",           1, 1, f_tanh},
@@ -813,8 +832,8 @@ static struct fst
     {"tempname",       0, 0, f_tempname},
     {"test_alloc_fail",        3, 3, f_test_alloc_fail},
     {"test_autochdir", 0, 0, f_test_autochdir},
-    {"test_disable_char_avail", 1, 1, f_test_disable_char_avail},
     {"test_garbagecollect_now",        0, 0, f_test_garbagecollect_now},
+    {"test_ignore_error",      1, 1, f_test_ignore_error},
 #ifdef FEAT_JOB_CHANNEL
     {"test_null_channel", 0, 0, f_test_null_channel},
 #endif
@@ -825,6 +844,7 @@ static struct fst
     {"test_null_list", 0, 0, f_test_null_list},
     {"test_null_partial", 0, 0, f_test_null_partial},
     {"test_null_string", 0, 0, f_test_null_string},
+    {"test_override",    2, 2, f_test_override},
     {"test_settime",   1, 1, f_test_settime},
 #ifdef FEAT_TIMERS
     {"timer_info",     0, 1, f_timer_info},
@@ -921,34 +941,6 @@ get_expr_name(expand_T *xp, int idx)
 
 #endif /* FEAT_CMDL_COMPL */
 
-#if defined(EBCDIC) || defined(PROTO)
-/*
- * Compare struct fst by function name.
- */
-    static int
-compare_func_name(const void *s1, const void *s2)
-{
-    struct fst *p1 = (struct fst *)s1;
-    struct fst *p2 = (struct fst *)s2;
-
-    return STRCMP(p1->f_name, p2->f_name);
-}
-
-/*
- * Sort the function table by function name.
- * The sorting of the table above is ASCII dependant.
- * On machines using EBCDIC we have to sort it.
- */
-    static void
-sortFunctions(void)
-{
-    int                funcCnt = (int)(sizeof(functions) / sizeof(struct fst)) - 1;
-
-    qsort(functions, (size_t)funcCnt, sizeof(struct fst), compare_func_name);
-}
-#endif
-
-
 /*
  * Find internal function in table above.
  * Return index, or -1 if not found
@@ -1324,6 +1316,15 @@ f_assert_notmatch(typval_T *argvars, typval_T *rettv UNUSED)
 }
 
 /*
+ * "assert_report(msg)" function
+ */
+    static void
+f_assert_report(typval_T *argvars, typval_T *rettv UNUSED)
+{
+    assert_report(argvars);
+}
+
+/*
  * "assert_true(actual[, msg])" function
  */
     static void
@@ -1381,6 +1382,18 @@ f_atan2(typval_T *argvars, typval_T *rettv)
 #endif
 
 /*
+ * "balloon_show()" function
+ */
+#ifdef FEAT_BEVAL
+    static void
+f_balloon_show(typval_T *argvars, typval_T *rettv UNUSED)
+{
+    if (balloonEval != NULL)
+       gui_mch_post_balloon(balloonEval, get_tv_string_chk(&argvars[0]));
+}
+#endif
+
+/*
  * "browse(save, title, initdir, default)" function
  */
     static void
@@ -1779,6 +1792,21 @@ f_ceil(typval_T *argvars, typval_T *rettv)
 
 #ifdef FEAT_JOB_CHANNEL
 /*
+ * "ch_canread()" function
+ */
+    static void
+f_ch_canread(typval_T *argvars, typval_T *rettv)
+{
+    channel_T *channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0);
+
+    rettv->vval.v_number = 0;
+    if (channel != NULL)
+       rettv->vval.v_number = channel_has_readahead(channel, PART_SOCK)
+                           || channel_has_readahead(channel, PART_OUT)
+                           || channel_has_readahead(channel, PART_ERR);
+}
+
+/*
  * "ch_close()" function
  */
     static void
@@ -2544,7 +2572,7 @@ f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
 #ifdef FEAT_DIFF
     linenr_T           lnum = get_tv_lnum(argvars);
     static linenr_T    prev_lnum = 0;
-    static int         changedtick = 0;
+    static varnumber_T changedtick = 0;
     static int         fnum = 0;
     static int         change_start = 0;
     static int         change_end = 0;
@@ -2555,7 +2583,7 @@ f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
     if (lnum < 0)      /* ignore type error in {lnum} arg */
        lnum = 0;
     if (lnum != prev_lnum
-           || changedtick != curbuf->b_changedtick
+           || changedtick != CHANGEDTICK(curbuf)
            || fnum != curbuf->b_fnum)
     {
        /* New line, buffer, change: need to get the values. */
@@ -2577,7 +2605,7 @@ f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
        else
            hlID = (hlf_T)0;
        prev_lnum = lnum;
-       changedtick = curbuf->b_changedtick;
+       changedtick = CHANGEDTICK(curbuf);
        fnum = curbuf->b_fnum;
     }
 
@@ -2644,7 +2672,7 @@ f_empty(typval_T *argvars, typval_T *rettv)
            break;
 #endif
        case VAR_UNKNOWN:
-           EMSG2(_(e_intern2), "f_empty(UNKNOWN)");
+           internal_error("f_empty(UNKNOWN)");
            n = TRUE;
            break;
     }
@@ -2824,7 +2852,17 @@ f_execute(typval_T *argvars, typval_T *rettv)
        --list->lv_refcount;
     }
 
-    rettv->vval.v_string = redir_execute_ga.ga_data;
+    /* Need to append a NUL to the result. */
+    if (ga_grow(&redir_execute_ga, 1) == OK)
+    {
+       ((char *)redir_execute_ga.ga_data)[redir_execute_ga.ga_len] = NUL;
+       rettv->vval.v_string = redir_execute_ga.ga_data;
+    }
+    else
+    {
+       ga_clear(&redir_execute_ga);
+       rettv->vval.v_string = NULL;
+    }
     msg_silent = save_msg_silent;
     emsg_silent = save_emsg_silent;
     emsg_noredir = save_emsg_noredir;
@@ -3315,21 +3353,12 @@ f_float2nr(typval_T *argvars, typval_T *rettv)
 
     if (get_float_arg(argvars, &f) == OK)
     {
-# ifdef FEAT_NUM64
-       if (f < -0x7fffffffffffffffLL)
-           rettv->vval.v_number = -0x7fffffffffffffffLL;
-       else if (f > 0x7fffffffffffffffLL)
-           rettv->vval.v_number = 0x7fffffffffffffffLL;
-       else
-           rettv->vval.v_number = (varnumber_T)f;
-# else
-       if (f < -0x7fffffff)
-           rettv->vval.v_number = -0x7fffffff;
-       else if (f > 0x7fffffff)
-           rettv->vval.v_number = 0x7fffffff;
+       if (f < -VARNUM_MAX)
+           rettv->vval.v_number = -VARNUM_MAX;
+       else if (f > VARNUM_MAX)
+           rettv->vval.v_number = VARNUM_MAX;
        else
            rettv->vval.v_number = (varnumber_T)f;
-# endif
     }
 }
 
@@ -3518,7 +3547,7 @@ f_foldtext(typval_T *argvars UNUSED, typval_T *rettv)
            }
        }
        count = (long)(foldend - foldstart + 1);
-       txt = ngettext("+-%s%3ld line: ", "+-%s%3ld lines: ", count);
+       txt = NGETTEXT("+-%s%3ld line: ", "+-%s%3ld lines: ", count);
        r = alloc((unsigned)(STRLEN(txt)
                    + STRLEN(dashes)        /* for %s */
                    + 20                    /* for %3ld */
@@ -3560,7 +3589,8 @@ f_foldtextresult(typval_T *argvars UNUSED, typval_T *rettv)
     fold_count = foldedCount(curwin, lnum, &foldinfo);
     if (fold_count > 0)
     {
-       text = get_foldtext(curwin, lnum, lnum + fold_count - 1, &foldinfo, buf);
+       text = get_foldtext(curwin, lnum, lnum + fold_count - 1,
+                                                              &foldinfo, buf);
        if (text == buf)
            text = vim_strsave(text);
        rettv->vval.v_string = text;
@@ -3956,11 +3986,12 @@ get_buffer_info(buf_T *buf)
     dict_add_nr_str(dict, "bufnr", buf->b_fnum, NULL);
     dict_add_nr_str(dict, "name", 0L,
            buf->b_ffname != NULL ? buf->b_ffname : (char_u *)"");
-    dict_add_nr_str(dict, "lnum", buflist_findlnum(buf), NULL);
+    dict_add_nr_str(dict, "lnum", buf == curbuf ? curwin->w_cursor.lnum
+                                               : buflist_findlnum(buf), NULL);
     dict_add_nr_str(dict, "loaded", buf->b_ml.ml_mfp != NULL, NULL);
     dict_add_nr_str(dict, "listed", buf->b_p_bl, NULL);
     dict_add_nr_str(dict, "changed", bufIsChanged(buf), NULL);
-    dict_add_nr_str(dict, "changedtick", buf->b_changedtick, NULL);
+    dict_add_nr_str(dict, "changedtick", CHANGEDTICK(buf), NULL);
     dict_add_nr_str(dict, "hidden",
                    buf->b_ml.ml_mfp != NULL && buf->b_nwindows == 0,
                    NULL);
@@ -4193,12 +4224,6 @@ f_getbufvar(typval_T *argvars, typval_T *rettv)
                /* buffer-local-option */
                done = TRUE;
        }
-       else if (STRCMP(varname, "changedtick") == 0)
-       {
-           rettv->v_type = VAR_NUMBER;
-           rettv->vval.v_number = curbuf->b_changedtick;
-           done = TRUE;
-       }
        else
        {
            /* Look up the variable. */
@@ -4241,7 +4266,7 @@ f_getchar(typval_T *argvars, typval_T *rettv)
     {
        if (argvars[0].v_type == VAR_UNKNOWN)
            /* getchar(): blocking wait. */
-           n = safe_vgetc();
+           n = plain_vgetc();
        else if (get_tv_number_chk(&argvars[0], &error) == 1)
            /* getchar(1): only check if char avail */
            n = vpeekc_any();
@@ -4250,7 +4275,7 @@ f_getchar(typval_T *argvars, typval_T *rettv)
            n = 0;
        else
            /* getchar(0) and char avail: return char */
-           n = safe_vgetc();
+           n = plain_vgetc();
 
        if (n == K_IGNORE)
            continue;
@@ -5217,24 +5242,6 @@ f_getwininfo(typval_T *argvars, typval_T *rettv)
 }
 
 /*
- * "getwinposx()" function
- */
-    static void
-f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv)
-{
-    rettv->vval.v_number = -1;
-#ifdef FEAT_GUI
-    if (gui.in_use)
-    {
-       int         x, y;
-
-       if (gui_mch_get_winpos(&x, &y) == OK)
-           rettv->vval.v_number = x;
-    }
-#endif
-}
-
-/*
  * "win_findbuf()" function
  */
     static void
@@ -5282,6 +5289,33 @@ f_win_id2win(typval_T *argvars, typval_T *rettv)
 }
 
 /*
+ * "getwinposx()" function
+ */
+    static void
+f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv)
+{
+    rettv->vval.v_number = -1;
+#ifdef FEAT_GUI
+    if (gui.in_use)
+    {
+       int         x, y;
+
+       if (gui_mch_get_winpos(&x, &y) == OK)
+           rettv->vval.v_number = x;
+       return;
+    }
+#endif
+#if defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)
+    {
+       int         x, y;
+
+       if (term_get_winpos(&x, &y) == OK)
+           rettv->vval.v_number = x;
+    }
+#endif
+}
+
+/*
  * "getwinposy()" function
  */
     static void
@@ -5295,6 +5329,15 @@ f_getwinposy(typval_T *argvars UNUSED, typval_T *rettv)
 
        if (gui_mch_get_winpos(&x, &y) == OK)
            rettv->vval.v_number = y;
+       return;
+    }
+#endif
+#if defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)
+    {
+       int         x, y;
+
+       if (term_get_winpos(&x, &y) == OK)
+           rettv->vval.v_number = y;
     }
 #endif
 }
@@ -5753,15 +5796,13 @@ f_has(typval_T *argvars, typval_T *rettv)
 #ifdef FEAT_PERSISTENT_UNDO
        "persistent_undo",
 #endif
-#ifdef FEAT_PYTHON
-#ifndef DYNAMIC_PYTHON
+#if defined(FEAT_PYTHON) && !defined(DYNAMIC_PYTHON)
        "python",
+       "pythonx",
 #endif
-#endif
-#ifdef FEAT_PYTHON3
-#ifndef DYNAMIC_PYTHON3
+#if defined(FEAT_PYTHON3) && !defined(DYNAMIC_PYTHON3)
        "python3",
-#endif
+       "pythonx",
 #endif
 #ifdef FEAT_POSTSCRIPT
        "postscript",
@@ -5959,6 +6000,10 @@ f_has(typval_T *argvars, typval_T *rettv)
        }
        else if (STRICMP(name, "vim_starting") == 0)
            n = (starting != 0);
+       else if (STRICMP(name, "ttyin") == 0)
+           n = mch_input_isatty();
+       else if (STRICMP(name, "ttyout") == 0)
+           n = stdout_isatty;
 #ifdef FEAT_MBYTE
        else if (STRICMP(name, "multi_byte_encoding") == 0)
            n = has_mbyte;
@@ -5987,17 +6032,30 @@ f_has(typval_T *argvars, typval_T *rettv)
        else if (STRICMP(name, "ruby") == 0)
            n = ruby_enabled(FALSE);
 #endif
-#ifdef FEAT_PYTHON
 #ifdef DYNAMIC_PYTHON
        else if (STRICMP(name, "python") == 0)
            n = python_enabled(FALSE);
 #endif
-#endif
-#ifdef FEAT_PYTHON3
 #ifdef DYNAMIC_PYTHON3
        else if (STRICMP(name, "python3") == 0)
            n = python3_enabled(FALSE);
 #endif
+#if defined(DYNAMIC_PYTHON) || defined(DYNAMIC_PYTHON3)
+       else if (STRICMP(name, "pythonx") == 0)
+       {
+# if defined(DYNAMIC_PYTHON) && defined(DYNAMIC_PYTHON3)
+           if (p_pyx == 0)
+               n = python3_enabled(FALSE) || python_enabled(FALSE);
+           else if (p_pyx == 3)
+               n = python3_enabled(FALSE);
+           else if (p_pyx == 2)
+               n = python_enabled(FALSE);
+# elif defined(DYNAMIC_PYTHON)
+           n = python_enabled(FALSE);
+# elif defined(DYNAMIC_PYTHON3)
+           n = python3_enabled(FALSE);
+# endif
+       }
 #endif
 #ifdef DYNAMIC_PERL
        else if (STRICMP(name, "perl") == 0)
@@ -6555,7 +6613,7 @@ f_islocked(typval_T *argvars, typval_T *rettv)
 
     rettv->vval.v_number = -1;
     end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE,
-                                       GLV_NO_AUTOLOAD, FNE_CHECK_START);
+                            GLV_NO_AUTOLOAD | GLV_READ_ONLY, FNE_CHECK_START);
     if (end != NULL && lv.ll_name != NULL)
     {
        if (*end != NUL)
@@ -6564,21 +6622,16 @@ f_islocked(typval_T *argvars, typval_T *rettv)
        {
            if (lv.ll_tv == NULL)
            {
-               if (check_changedtick(lv.ll_name))
-                   rettv->vval.v_number = 1;       /* always locked */
-               else
+               di = find_var(lv.ll_name, NULL, TRUE);
+               if (di != NULL)
                {
-                   di = find_var(lv.ll_name, NULL, TRUE);
-                   if (di != NULL)
-                   {
-                       /* Consider a variable locked when:
-                        * 1. the variable itself is locked
-                        * 2. the value of the variable is locked.
-                        * 3. the List or Dict value is locked.
-                        */
-                       rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK)
-                                                 || tv_islocked(&di->di_tv));
-                   }
+                   /* Consider a variable locked when:
+                    * 1. the variable itself is locked
+                    * 2. the value of the variable is locked.
+                    * 3. the List or Dict value is locked.
+                    */
+                   rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK)
+                                                  || tv_islocked(&di->di_tv));
                }
            }
            else if (lv.ll_range)
@@ -6796,8 +6849,7 @@ f_json_decode(typval_T *argvars, typval_T *rettv)
     reader.js_buf = get_tv_string(&argvars[0]);
     reader.js_fill = NULL;
     reader.js_used = 0;
-    if (json_decode_all(&reader, rettv, 0) != OK)
-       EMSG(_(e_invarg));
+    json_decode_all(&reader, rettv, 0);
 }
 
 /*
@@ -6866,10 +6918,8 @@ f_len(typval_T *argvars, typval_T *rettv)
     }
 }
 
-static void libcall_common(typval_T *argvars, typval_T *rettv, int type);
-
     static void
-libcall_common(typval_T *argvars, typval_T *rettv, int type)
+libcall_common(typval_T *argvars UNUSED, typval_T *rettv, int type)
 {
 #ifdef FEAT_LIBCALL
     char_u             *string_in;
@@ -7667,6 +7717,7 @@ static int mkdir_recurse(char_u *dir, int prot);
 /*
  * Create the directory in which "dir" is located, and higher levels when
  * needed.
+ * Return OK or FAIL.
  */
     static int
 mkdir_recurse(char_u *dir, int prot)
@@ -7774,21 +7825,26 @@ f_mode(typval_T *argvars, typval_T *rettv)
        }
        else
 #endif
-       if (State & REPLACE_FLAG)
-           buf[0] = 'R';
-       else
-           buf[0] = 'i';
+       {
+           if (State & REPLACE_FLAG)
+               buf[0] = 'R';
+           else
+               buf[0] = 'i';
+#ifdef FEAT_INS_EXPAND
+           if (ins_compl_active())
+               buf[1] = 'c';
+           else if (ctrl_x_mode == 1)
+               buf[1] = 'x';
+#endif
+       }
     }
-    else if (State & CMDLINE)
+    else if ((State & CMDLINE) || exmode_active)
     {
        buf[0] = 'c';
-       if (exmode_active)
+       if (exmode_active == EXMODE_VIM)
            buf[1] = 'v';
-    }
-    else if (exmode_active)
-    {
-       buf[0] = 'c';
-       buf[1] = 'e';
+       else if (exmode_active == EXMODE_NORMAL)
+           buf[1] = 'e';
     }
     else
     {
@@ -8025,6 +8081,9 @@ f_py3eval(typval_T *argvars, typval_T *rettv)
     char_u     *str;
     char_u     buf[NUMBUFLEN];
 
+    if (p_pyx == 0)
+       p_pyx = 3;
+
     str = get_tv_string_buf(&argvars[0], buf);
     do_py3eval(str, rettv);
 }
@@ -8040,11 +8099,35 @@ f_pyeval(typval_T *argvars, typval_T *rettv)
     char_u     *str;
     char_u     buf[NUMBUFLEN];
 
+    if (p_pyx == 0)
+       p_pyx = 2;
+
     str = get_tv_string_buf(&argvars[0], buf);
     do_pyeval(str, rettv);
 }
 #endif
 
+#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
+/*
+ * "pyxeval()" function
+ */
+    static void
+f_pyxeval(typval_T *argvars, typval_T *rettv)
+{
+# if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
+    init_pyxversion();
+    if (p_pyx == 2)
+       f_pyeval(argvars, rettv);
+    else
+       f_py3eval(argvars, rettv);
+# elif defined(FEAT_PYTHON)
+    f_pyeval(argvars, rettv);
+# elif defined(FEAT_PYTHON3)
+    f_py3eval(argvars, rettv);
+# endif
+}
+#endif
+
 /*
  * "range()" function
  */
@@ -8437,7 +8520,7 @@ check_connection(void)
     make_connection();
     if (X_DISPLAY == NULL)
     {
-       EMSG(_("E240: No connection to Vim server"));
+       EMSG(_("E240: No connection to the X server"));
        return FAIL;
     }
     return OK;
@@ -8452,6 +8535,7 @@ remote_common(typval_T *argvars, typval_T *rettv, int expr)
     char_u     *keys;
     char_u     *r = NULL;
     char_u     buf[NUMBUFLEN];
+    int                timeout = 0;
 # ifdef WIN32
     HWND       w;
 # else
@@ -8465,16 +8549,19 @@ remote_common(typval_T *argvars, typval_T *rettv, int expr)
     if (check_connection() == FAIL)
        return;
 # endif
+    if (argvars[2].v_type != VAR_UNKNOWN
+           && argvars[3].v_type != VAR_UNKNOWN)
+       timeout = get_tv_number(&argvars[3]);
 
     server_name = get_tv_string_chk(&argvars[0]);
     if (server_name == NULL)
        return;         /* type error; errmsg already given */
     keys = get_tv_string_buf(&argvars[1], buf);
 # ifdef WIN32
-    if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0)
+    if (serverSendToVim(server_name, keys, &r, &w, expr, timeout, TRUE) < 0)
 # else
-    if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE)
-                                                                         < 0)
+    if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, timeout,
+                                                                 0, TRUE) < 0)
 # endif
     {
        if (r != NULL)
@@ -8492,13 +8579,15 @@ remote_common(typval_T *argvars, typval_T *rettv, int expr)
        char_u          str[30];
        char_u          *idvar;
 
-       sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w);
-       v.di_tv.v_type = VAR_STRING;
-       v.di_tv.vval.v_string = vim_strsave(str);
        idvar = get_tv_string_chk(&argvars[2]);
-       if (idvar != NULL)
+       if (idvar != NULL && *idvar != NUL)
+       {
+           sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w);
+           v.di_tv.v_type = VAR_STRING;
+           v.di_tv.vval.v_string = vim_strsave(str);
            set_var(idvar, &v.di_tv, FALSE);
-       vim_free(v.di_tv.vval.v_string);
+           vim_free(v.di_tv.vval.v_string);
+       }
     }
 }
 #endif
@@ -8570,7 +8659,7 @@ f_remote_peek(typval_T *argvars UNUSED, typval_T *rettv)
        rettv->vval.v_number = -1;
     else
     {
-       s = serverGetReply((HWND)n, FALSE, FALSE, FALSE);
+       s = serverGetReply((HWND)n, FALSE, FALSE, FALSE, 0);
        rettv->vval.v_number = (s != NULL);
     }
 # else
@@ -8607,17 +8696,24 @@ f_remote_read(typval_T *argvars UNUSED, typval_T *rettv)
 
     if (serverid != NULL && !check_restricted() && !check_secure())
     {
+       int timeout = 0;
 # ifdef WIN32
        /* The server's HWND is encoded in the 'id' parameter */
        long_u          n = 0;
+# endif
+
+       if (argvars[1].v_type != VAR_UNKNOWN)
+           timeout = get_tv_number(&argvars[1]);
 
+# ifdef WIN32
        sscanf((char *)serverid, SCANF_HEX_LONG_U, &n);
        if (n != 0)
-           r = serverGetReply((HWND)n, FALSE, TRUE, TRUE);
+           r = serverGetReply((HWND)n, FALSE, TRUE, TRUE, timeout);
        if (r == NULL)
 # else
-       if (check_connection() == FAIL || serverReadReply(X_DISPLAY,
-               serverStrToWin(serverid), &r, FALSE) < 0)
+       if (check_connection() == FAIL
+               || serverReadReply(X_DISPLAY, serverStrToWin(serverid),
+                                                      &r, FALSE, timeout) < 0)
 # endif
            EMSG(_("E277: Unable to read a server reply"));
     }
@@ -8640,6 +8736,33 @@ f_remote_send(typval_T *argvars UNUSED, typval_T *rettv)
 }
 
 /*
+ * "remote_startserver()" function
+ */
+    static void
+f_remote_startserver(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
+{
+#ifdef FEAT_CLIENTSERVER
+    char_u     *server = get_tv_string_chk(&argvars[0]);
+
+    if (server == NULL)
+       return;         /* type error; errmsg already given */
+    if (serverName != NULL)
+       EMSG(_("E941: already started a server"));
+    else
+    {
+# ifdef FEAT_X11
+       if (check_connection() == OK)
+           serverRegisterName(X_DISPLAY, server);
+# else
+       serverSetName(server);
+# endif
+    }
+#else
+    EMSG(_("E942: +clientserver feature not available"));
+#endif
+}
+
+/*
  * "remove()" function
  */
     static void
@@ -9487,35 +9610,35 @@ do_searchpair(
 
     /* Make two search patterns: start/end (pat2, for in nested pairs) and
      * start/middle/end (pat3, for the top pair). */
-    pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15));
-    pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23));
+    pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 17));
+    pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 25));
     if (pat2 == NULL || pat3 == NULL)
        goto theend;
-    sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
+    sprintf((char *)pat2, "\\m\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
     if (*mpat == NUL)
        STRCPY(pat3, pat2);
     else
-       sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)",
+       sprintf((char *)pat3, "\\m\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)",
                                                            spat, epat, mpat);
     if (flags & SP_START)
        options |= SEARCH_START;
 
     save_cursor = curwin->w_cursor;
     pos = curwin->w_cursor;
-    clearpos(&firstpos);
-    clearpos(&foundpos);
+    CLEAR_POS(&firstpos);
+    CLEAR_POS(&foundpos);
     pat = pat3;
     for (;;)
     {
        n = searchit(curwin, curbuf, &pos, dir, pat, 1L,
                                           options, RE_SEARCH, lnum_stop, &tm);
-       if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos)))
+       if (n == FAIL || (firstpos.lnum != 0 && EQUAL_POS(pos, firstpos)))
            /* didn't find it or found the first match again: FAIL */
            break;
 
        if (firstpos.lnum == 0)
            firstpos = pos;
-       if (equalpos(pos, foundpos))
+       if (EQUAL_POS(pos, foundpos))
        {
            /* Found the same position again.  Can happen with a pattern that
             * has "\zs" at the end and searching backwards.  Advance one
@@ -9934,7 +10057,8 @@ set_qf_ll_list(
            act = get_tv_string_chk(action_arg);
            if (act == NULL)
                return;         /* type error; errmsg already given */
-           if ((*act == 'a' || *act == 'r' || *act == ' ') && act[1] == NUL)
+           if ((*act == 'a' || *act == 'r' || *act == ' ' || *act == 'f') &&
+                   act[1] == NUL)
                action = *act;
            else
                EMSG2(_(e_invact), act);
@@ -10110,20 +10234,15 @@ f_setpos(typval_T *argvars, typval_T *rettv)
                pos.col = 0;
            if (name[0] == '.' && name[1] == NUL)
            {
-               /* set cursor */
-               if (fnum == curbuf->b_fnum)
+               /* set cursor; "fnum" is ignored */
+               curwin->w_cursor = pos;
+               if (curswant >= 0)
                {
-                   curwin->w_cursor = pos;
-                   if (curswant >= 0)
-                   {
-                       curwin->w_curswant = curswant - 1;
-                       curwin->w_set_curswant = FALSE;
-                   }
-                   check_cursor();
-                   rettv->vval.v_number = 0;
+                   curwin->w_curswant = curswant - 1;
+                   curwin->w_set_curswant = FALSE;
                }
-               else
-                   EMSG(_(e_invarg));
+               check_cursor();
+               rettv->vval.v_number = 0;
            }
            else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL)
            {
@@ -11045,10 +11164,13 @@ f_sqrt(typval_T *argvars, typval_T *rettv)
 f_str2float(typval_T *argvars, typval_T *rettv)
 {
     char_u *p = skipwhite(get_tv_string(&argvars[0]));
+    int     isneg = (*p == '-');
 
-    if (*p == '+')
+    if (*p == '+' || *p == '-')
        p = skipwhite(p + 1);
     (void)string2float(p, &rettv->vval.v_float);
+    if (isneg)
+       rettv->vval.v_float *= -1;
     rettv->v_type = VAR_FLOAT;
 }
 #endif
@@ -11063,6 +11185,7 @@ f_str2nr(typval_T *argvars, typval_T *rettv)
     char_u     *p;
     varnumber_T        n;
     int                what;
+    int                isneg;
 
     if (argvars[1].v_type != VAR_UNKNOWN)
     {
@@ -11075,7 +11198,8 @@ f_str2nr(typval_T *argvars, typval_T *rettv)
     }
 
     p = skipwhite(get_tv_string(&argvars[0]));
-    if (*p == '+')
+    isneg = (*p == '-');
+    if (*p == '+' || *p == '-')
        p = skipwhite(p + 1);
     switch (base)
     {
@@ -11085,7 +11209,11 @@ f_str2nr(typval_T *argvars, typval_T *rettv)
        default: what = 0;
     }
     vim_str2nr(p, NULL, NULL, what, &n, NULL, 0);
-    rettv->vval.v_number = n;
+    if (isneg)
+       rettv->vval.v_number = -n;
+    else
+       rettv->vval.v_number = n;
+
 }
 
 #ifdef HAVE_STRFTIME
@@ -11506,8 +11634,8 @@ f_submatch(typval_T *argvars, typval_T *rettv)
        return;
     if (no < 0 || no >= NSUBEXP)
     {
-        EMSGN(_("E935: invalid submatch number: %d"), no);
-        return;
+       EMSGN(_("E935: invalid submatch number: %d"), no);
+       return;
     }
     if (argvars[1].v_type != VAR_UNKNOWN)
        retList = (int)get_tv_number_chk(&argvars[1], &error);
@@ -11638,7 +11766,7 @@ f_synIDattr(typval_T *argvars UNUSED, typval_T *rettv)
                break;
 
        case 'n':                                       /* name */
-               p = get_highlight_name(NULL, id - 1);
+               p = get_highlight_name_ext(NULL, id - 1, FALSE);
                break;
 
        case 'r':                                       /* reverse */
@@ -11795,7 +11923,6 @@ get_cmd_output_as_rettv(
     char_u     *res = NULL;
     char_u     *p;
     char_u     *infile = NULL;
-    char_u     buf[NUMBUFLEN];
     int                err = FALSE;
     FILE       *fd;
     list_T     *list = NULL;
@@ -11809,7 +11936,7 @@ get_cmd_output_as_rettv(
     if (argvars[1].v_type != VAR_UNKNOWN)
     {
        /*
-        * Write the string to a temp file, to be used for input of the shell
+        * Write the text to a temp file, to be used for input of the shell
         * command.
         */
        if ((infile = vim_tempname('i', TRUE)) == NULL)
@@ -11824,14 +11951,43 @@ get_cmd_output_as_rettv(
            EMSG2(_(e_notopen), infile);
            goto errret;
        }
-       if (argvars[1].v_type == VAR_LIST)
+       if (argvars[1].v_type == VAR_NUMBER)
+       {
+           linenr_T    lnum;
+           buf_T       *buf;
+
+           buf = buflist_findnr(argvars[1].vval.v_number);
+           if (buf == NULL)
+           {
+               EMSGN(_(e_nobufnr), argvars[1].vval.v_number);
+               fclose(fd);
+               goto errret;
+           }
+
+           for (lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++)
+           {
+               for (p = ml_get_buf(buf, lnum, FALSE); *p != NUL; ++p)
+                   if (putc(*p == '\n' ? NUL : *p, fd) == EOF)
+                   {
+                       err = TRUE;
+                       break;
+                   }
+               if (putc(NL, fd) == EOF)
+               {
+                   err = TRUE;
+                   break;
+               }
+           }
+       }
+       else if (argvars[1].v_type == VAR_LIST)
        {
            if (write_list(fd, argvars[1].vval.v_list, TRUE) == FAIL)
                err = TRUE;
        }
        else
        {
-           size_t len;
+           size_t      len;
+           char_u      buf[NUMBUFLEN];
 
            p = get_tv_string_buf_chk(&argvars[1], buf);
            if (p == NULL)
@@ -12132,6 +12288,7 @@ f_tagfiles(typval_T *argvars UNUSED, typval_T *rettv)
     static void
 f_taglist(typval_T *argvars, typval_T *rettv)
 {
+    char_u  *fname = NULL;
     char_u  *tag_pattern;
 
     tag_pattern = get_tv_string(&argvars[0]);
@@ -12140,8 +12297,10 @@ f_taglist(typval_T *argvars, typval_T *rettv)
     if (*tag_pattern == NUL)
        return;
 
+    if (argvars[1].v_type != VAR_UNKNOWN)
+       fname = get_tv_string(&argvars[1]);
     if (rettv_list_alloc(rettv) == OK)
-       (void)get_tags(rettv->vval.v_list, tag_pattern);
+       (void)get_tags(rettv->vval.v_list, tag_pattern, fname);
 }
 
 /*
@@ -12244,12 +12403,34 @@ f_test_autochdir(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
 }
 
 /*
- * "test_disable_char_avail({expr})" function
+ * "test_disable({name}, {val})" function
  */
     static void
-f_test_disable_char_avail(typval_T *argvars, typval_T *rettv UNUSED)
+f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
 {
-    disable_char_avail_for_testing = (int)get_tv_number(&argvars[0]);
+    char_u *name = (char_u *)"";
+    int     val;
+
+    if (argvars[0].v_type != VAR_STRING
+           || (argvars[1].v_type) != VAR_NUMBER)
+       EMSG(_(e_invarg));
+    else
+    {
+       name = get_tv_string_chk(&argvars[0]);
+       val = (int)get_tv_number(&argvars[1]);
+
+       if (STRCMP(name, (char_u *)"redraw") == 0)
+           disable_redraw_for_testing = val;
+       else if (STRCMP(name, (char_u *)"char_avail") == 0)
+           disable_char_avail_for_testing = val;
+       else if (STRCMP(name, (char_u *)"ALL") == 0)
+       {
+           disable_char_avail_for_testing = FALSE;
+           disable_redraw_for_testing = FALSE;
+       }
+       else
+           EMSG2(_(e_invarg2), name);
+    }
 }
 
 /*
@@ -12263,6 +12444,15 @@ f_test_garbagecollect_now(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
     garbage_collect(TRUE);
 }
 
+/*
+ * "test_ignore_error()" function
+ */
+    static void
+f_test_ignore_error(typval_T *argvars, typval_T *rettv UNUSED)
+{
+     ignore_error_for_testing(get_tv_string(&argvars[0]));
+}
+
 #ifdef FEAT_JOB_CHANNEL
     static void
 f_test_null_channel(typval_T *argvars UNUSED, typval_T *rettv)
@@ -12484,39 +12674,8 @@ f_timer_stopall(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
     static void
 f_tolower(typval_T *argvars, typval_T *rettv)
 {
-    char_u     *p;
-
-    p = vim_strsave(get_tv_string(&argvars[0]));
     rettv->v_type = VAR_STRING;
-    rettv->vval.v_string = p;
-
-    if (p != NULL)
-       while (*p != NUL)
-       {
-#ifdef FEAT_MBYTE
-           int         l;
-
-           if (enc_utf8)
-           {
-               int c, lc;
-
-               c = utf_ptr2char(p);
-               lc = utf_tolower(c);
-               l = utf_ptr2len(p);
-               /* TODO: reallocate string when byte count changes. */
-               if (utf_char2len(lc) == l)
-                   utf_char2bytes(lc, p);
-               p += l;
-           }
-           else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
-               p += l;         /* skip multi-byte character */
-           else
-#endif
-           {
-               *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */
-               ++p;
-           }
-       }
+    rettv->vval.v_string = strlow_save(get_tv_string(&argvars[0]));
 }
 
 /*
@@ -12695,7 +12854,7 @@ f_type(typval_T *argvars, typval_T *rettv)
        case VAR_JOB:     n = VAR_TYPE_JOB; break;
        case VAR_CHANNEL: n = VAR_TYPE_CHANNEL; break;
        case VAR_UNKNOWN:
-            EMSG2(_(e_intern2), "f_type(UNKNOWN)");
+            internal_error("f_type(UNKNOWN)");
             n = -1;
             break;
     }
diff --git a/src/ex_cmdidxs.h b/src/ex_cmdidxs.h
new file mode 100644 (file)
index 0000000..3b6120e
--- /dev/null
@@ -0,0 +1,72 @@
+/* Automatically generated code by create_cmdidxs.vim
+ *
+ * Table giving the index of the first command in cmdnames[] to lookup
+ * based on the first letter of a command.
+ */
+static const unsigned short cmdidxs1[26] =
+{
+  /* a */ 0,
+  /* b */ 19,
+  /* c */ 42,
+  /* d */ 103,
+  /* e */ 125,
+  /* f */ 145,
+  /* g */ 161,
+  /* h */ 167,
+  /* i */ 176,
+  /* j */ 194,
+  /* k */ 196,
+  /* l */ 201,
+  /* m */ 259,
+  /* n */ 277,
+  /* o */ 297,
+  /* p */ 309,
+  /* q */ 348,
+  /* r */ 351,
+  /* s */ 370,
+  /* t */ 437,
+  /* u */ 472,
+  /* v */ 483,
+  /* w */ 501,
+  /* x */ 516,
+  /* y */ 525,
+  /* z */ 526
+};
+
+/*
+ * Table giving the index of the first command in cmdnames[] to lookup
+ * based on the first 2 letters of a command.
+ * Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they
+ * fit in a byte.
+ */
+static const unsigned char cmdidxs2[26][26] =
+{ /*         a   b   c   d   e   f   g   h   i   j   k   l   m   n   o   p   q   r   s   t   u   v   w   x   y   z */
+  /* a */ {  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  5,  6,  0,  0,  0,  7, 15,  0, 16,  0,  0,  0,  0,  0 },
+  /* b */ {  2,  0,  0,  4,  5,  7,  0,  0,  0,  0,  0,  8,  9, 10, 11, 12,  0, 13,  0,  0,  0,  0, 22,  0,  0,  0 },
+  /* c */ {  3, 10, 12, 14, 16, 18, 21,  0,  0,  0,  0, 29, 33, 36, 42, 51, 53, 54, 55,  0, 57,  0, 60,  0,  0,  0 },
+  /* d */ {  0,  0,  0,  0,  0,  0,  0,  0,  6, 15,  0, 16,  0,  0, 17,  0,  0, 19, 20,  0,  0,  0,  0,  0,  0,  0 },
+  /* e */ {  1,  0,  2,  0,  0,  0,  0,  0,  0,  0,  0,  7,  9, 10,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16,  0,  0 },
+  /* f */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  9,  0,  0,  0,  0,  0, 15,  0,  0,  0,  0,  0 },
+  /* g */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  2,  0,  0,  4,  5,  0,  0,  0,  0 },
+  /* h */ {  5,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },
+  /* i */ {  1,  0,  0,  0,  0,  3,  0,  0,  0,  4,  0,  5,  6,  0,  0,  0,  0,  0, 13,  0, 15,  0,  0,  0,  0,  0 },
+  /* j */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0 },
+  /* k */ {  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },
+  /* l */ {  3,  9, 11, 15, 16, 20, 23, 28,  0,  0,  0, 30, 33, 36, 40, 46,  0, 48, 57, 49, 50, 54, 56,  0,  0,  0 },
+  /* m */ {  1,  0,  0,  0,  7,  0,  0,  0,  0,  0, 10,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16 },
+  /* n */ {  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  8, 10,  0,  0,  0,  0,  0, 17,  0,  0,  0,  0,  0 },
+  /* o */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  5,  0,  0,  0,  0,  0,  0,  9,  0, 11,  0,  0,  0 },
+  /* p */ {  1,  0,  3,  0,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,  9,  0,  0, 16, 17, 26,  0, 27,  0, 28,  0 },
+  /* q */ {  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },
+  /* r */ {  0,  0,  0,  0,  0,  0,  0,  0, 11,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 13, 18,  0,  0,  0,  0 },
+  /* s */ {  2,  6, 15,  0, 18, 22,  0, 24, 25,  0,  0, 28, 30, 34, 38, 40,  0, 48,  0, 49,  0, 61, 62,  0, 63,  0 },
+  /* t */ {  2,  0, 19,  0, 22, 23,  0, 24,  0, 25,  0, 26, 27, 28, 29, 30,  0, 31, 33,  0, 34,  0,  0,  0,  0,  0 },
+  /* u */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 10,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },
+  /* v */ {  0,  0,  0,  0,  1,  0,  0,  0,  4,  0,  0,  0,  9, 12,  0,  0,  0,  0, 15,  0, 16,  0,  0,  0,  0,  0 },
+  /* w */ {  2,  0,  0,  0,  0,  0,  0,  3,  4,  0,  0,  0,  0,  8,  0,  9, 10,  0, 12,  0, 13, 14,  0,  0,  0,  0 },
+  /* x */ {  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  5,  0,  0,  0,  0,  0,  0,  7,  0,  0,  0,  0,  0 },
+  /* y */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },
+  /* z */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }
+};
+
+static const int command_count = 539;
index cb58f24..309474c 100644 (file)
@@ -256,7 +256,7 @@ linelen(int *has_tab)
 
     /* find the character after the last non-blank character */
     for (last = first + STRLEN(first);
-                               last > first && vim_iswhite(last[-1]); --last)
+                               last > first && VIM_ISWHITE(last[-1]); --last)
        ;
     save = *last;
     *last = NUL;
@@ -400,7 +400,7 @@ ex_sort(exarg_T *eap)
 
     for (p = eap->arg; *p != NUL; ++p)
     {
-       if (vim_iswhite(*p))
+       if (VIM_ISWHITE(*p))
            ;
        else if (*p == 'i')
            sort_ic = TRUE;
@@ -683,7 +683,7 @@ ex_retab(exarg_T *eap)
        did_undo = FALSE;
        for (;;)
        {
-           if (vim_iswhite(ptr[col]))
+           if (VIM_ISWHITE(ptr[col]))
            {
                if (!got_tab && num_spaces == 0)
                {
@@ -799,14 +799,8 @@ do_move(linenr_T line1, linenr_T line2, linenr_T dest)
     linenr_T   num_lines;  /* Num lines moved */
     linenr_T   last_line;  /* Last line in file after adding new text */
 #ifdef FEAT_FOLDING
-    int                isFolded;
-
-    /* Moving lines seems to corrupt the folds, delete folding info now
-     * and recreate it when finished.  Don't do this for manual folding, it
-     * would delete all folds. */
-    isFolded = hasAnyFolding(curwin) && !foldmethodIsManual(curwin);
-    if (isFolded)
-       deleteFoldRecurse(&curwin->w_folds);
+    win_T      *win;
+    tabpage_T  *tp;
 #endif
 
     if (dest >= line1 && dest < line2)
@@ -851,24 +845,34 @@ do_move(linenr_T line1, linenr_T line2, linenr_T dest)
      * their final destination at the new text position -- webb
      */
     last_line = curbuf->b_ml.ml_line_count;
-    mark_adjust(line1, line2, last_line - line2, 0L);
-    changed_lines(last_line - num_lines + 1, 0, last_line + 1, num_lines);
+    mark_adjust_nofold(line1, line2, last_line - line2, 0L);
     if (dest >= line2)
     {
-       mark_adjust(line2 + 1, dest, -num_lines, 0L);
+       mark_adjust_nofold(line2 + 1, dest, -num_lines, 0L);
+#ifdef FEAT_FOLDING
+       FOR_ALL_TAB_WINDOWS(tp, win) {
+           if (win->w_buffer == curbuf)
+               foldMoveRange(&win->w_folds, line1, line2, dest);
+       }
+#endif
        curbuf->b_op_start.lnum = dest - num_lines + 1;
        curbuf->b_op_end.lnum = dest;
     }
     else
     {
-       mark_adjust(dest + 1, line1 - 1, num_lines, 0L);
+       mark_adjust_nofold(dest + 1, line1 - 1, num_lines, 0L);
+#ifdef FEAT_FOLDING
+       FOR_ALL_TAB_WINDOWS(tp, win) {
+           if (win->w_buffer == curbuf)
+               foldMoveRange(&win->w_folds, dest + 1, line1 - 1, line2);
+       }
+#endif
        curbuf->b_op_start.lnum = dest + 1;
        curbuf->b_op_end.lnum = dest + num_lines;
     }
     curbuf->b_op_start.col = curbuf->b_op_end.col = 0;
-    mark_adjust(last_line - num_lines + 1, last_line,
+    mark_adjust_nofold(last_line - num_lines + 1, last_line,
                                             -(last_line - dest - extra), 0L);
-    changed_lines(last_line - num_lines + 1, 0, last_line + 1, -extra);
 
     /*
      * Now we delete the original text -- webb
@@ -906,12 +910,6 @@ do_move(linenr_T line1, linenr_T line2, linenr_T dest)
     else
        changed_lines(dest + 1, 0, line1 + num_lines, 0L);
 
-#ifdef FEAT_FOLDING
-       /* recreate folds */
-       if (isFolded)
-           foldUpdateAll(curwin);
-#endif
-
     return OK;
 }
 
@@ -1313,7 +1311,7 @@ do_filter(
        if (otmp != NULL)
        {
            if (readfile(otmp, NULL, line2, (linenr_T)0, (linenr_T)MAXLNUM,
-                                                   eap, READ_FILTER) == FAIL)
+                                                   eap, READ_FILTER) != OK)
            {
 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
                if (!aborting())
@@ -2891,7 +2889,7 @@ print_line_no_prefix(
     {
        vim_snprintf((char *)numbuf, sizeof(numbuf),
                                   "%*ld ", number_width(curwin), (long)lnum);
-       msg_puts_attr(numbuf, hl_attr(HLF_N));  /* Highlight line nrs */
+       msg_puts_attr(numbuf, HL_ATTR(HLF_N));  /* Highlight line nrs */
     }
     msg_prt_line(ml_get(lnum), list);
 }
@@ -3967,7 +3965,8 @@ do_ecmd(
                     * <VN> We could instead free the synblock
                     * and re-attach to buffer, perhaps.
                     */
-                   if (curwin->w_s == &(curwin->w_buffer->b_s))
+                   if (curwin->w_buffer != NULL
+                           && curwin->w_s == &(curwin->w_buffer->b_s))
                        curwin->w_s = &(buf->b_s);
 #endif
                    curwin->w_buffer = buf;
@@ -4210,7 +4209,7 @@ do_ecmd(
 
        /* If autocommands change the cursor position or topline, we should
         * keep it.  Also when it moves within a line. */
-       if (!equalpos(curwin->w_cursor, orig_pos))
+       if (!EQUAL_POS(curwin->w_cursor, orig_pos))
        {
            newlnum = curwin->w_cursor.lnum;
            newcol = curwin->w_cursor.col;
@@ -4565,7 +4564,7 @@ ex_change(exarg_T *eap)
 ex_z(exarg_T *eap)
 {
     char_u     *x;
-    int                bigness;
+    long       bigness;
     char_u     *kind;
     int                minus = 0;
     linenr_T   start, end, curs, i;
@@ -4577,7 +4576,7 @@ ex_z(exarg_T *eap)
     if (eap->forceit)
        bigness = curwin->w_height;
 #ifdef FEAT_WINDOWS
-    else if (firstwin != lastwin)
+    else if (!ONE_WINDOW)
        bigness = curwin->w_height - 3;
 #endif
     else
@@ -4602,7 +4601,12 @@ ex_z(exarg_T *eap)
        }
        else
        {
-           bigness = atoi((char *)x);
+           bigness = atol((char *)x);
+
+           /* bigness could be < 0 if atol(x) overflows. */
+           if (bigness > 2 * curbuf->b_ml.ml_line_count || bigness < 0)
+               bigness = 2 * curbuf->b_ml.ml_line_count;
+
            p_window = bigness;
            if (*kind == '=')
                bigness += 2;
@@ -4660,6 +4664,8 @@ ex_z(exarg_T *eap)
 
     if (curs > curbuf->b_ml.ml_line_count)
        curs = curbuf->b_ml.ml_line_count;
+    else if (curs < 1)
+       curs = 1;
 
     for (i = start; i <= end; i++)
     {
@@ -4682,7 +4688,11 @@ ex_z(exarg_T *eap)
        }
     }
 
-    curwin->w_cursor.lnum = curs;
+    if (curwin->w_cursor.lnum != curs)
+    {
+       curwin->w_cursor.lnum = curs;
+       curwin->w_cursor.col = 0;
+    }
     ex_no_reprint = TRUE;
 }
 
@@ -4806,7 +4816,7 @@ do_sub(exarg_T *eap)
        which_pat = RE_SUBST;   /* use last substitute regexp */
 
                                /* new pattern and substitution */
-    if (eap->cmd[0] == 's' && *cmd != NUL && !vim_iswhite(*cmd)
+    if (eap->cmd[0] == 's' && *cmd != NUL && !VIM_ISWHITE(*cmd)
                && vim_strchr((char_u *)"0123456789cegriIp|\"", *cmd) == NULL)
     {
                                /* don't accept alphanumeric for separator */
@@ -4862,7 +4872,7 @@ do_sub(exarg_T *eap)
            }
            if (cmd[0] == '\\' && cmd[1] != 0)  /* skip escaped characters */
                ++cmd;
-           mb_ptr_adv(cmd);
+           MB_PTR_ADV(cmd);
        }
 
        if (!eap->skip)
@@ -5262,6 +5272,10 @@ do_sub(exarg_T *eap)
                    setmouse();         /* disable mouse in xterm */
 #endif
                    curwin->w_cursor.col = regmatch.startpos[0].col;
+#ifdef FEAT_CURSORBIND
+                   if (curwin->w_p_crb)
+                       do_check_cursorbind();
+#endif
 
                    /* When 'cpoptions' contains "u" don't sync undo when
                     * asking for confirmation. */
@@ -5283,6 +5297,8 @@ do_sub(exarg_T *eap)
 
                            getvcol(curwin, &curwin->w_cursor, &sc, NULL, NULL);
                            curwin->w_cursor.col = regmatch.endpos[0].col - 1;
+                           if (curwin->w_cursor.col < 0)
+                               curwin->w_cursor.col = 0;
                            getvcol(curwin, &curwin->w_cursor, NULL, NULL, &ec);
                            if (subflags.do_number || curwin->w_p_nu)
                            {
@@ -5374,7 +5390,7 @@ do_sub(exarg_T *eap)
                            msg_no_more = TRUE;
                            /* write message same highlighting as for
                             * wait_return */
-                           smsg_attr(hl_attr(HLF_R),
+                           smsg_attr(HL_ATTR(HLF_R),
                                    (char_u *)_("replace with %s (y/n/a/q/l/^E/^Y)?"), sub);
                            msg_no_more = FALSE;
                            msg_scroll = i;
@@ -6218,7 +6234,7 @@ ex_help(exarg_T *eap)
 
     /* remove trailing blanks */
     p = arg + STRLEN(arg) - 1;
-    while (p > arg && vim_iswhite(*p) && p[-1] != '\\')
+    while (p > arg && VIM_ISWHITE(*p) && p[-1] != '\\')
        *p-- = NUL;
 
 #ifdef FEAT_MULTI_LANG
@@ -6498,18 +6514,20 @@ find_help_tags(
     static char *(mtable[]) = {"*", "g*", "[*", "]*", ":*",
                               "/*", "/\\*", "\"*", "**",
                               "cpo-*", "/\\(\\)", "/\\%(\\)",
-                              "?", ":?", "?<CR>", "g?", "g?g?", "g??", "z?",
+                              "?", ":?", "?<CR>", "g?", "g?g?", "g??",
                               "/\\?", "/\\z(\\)", "\\=", ":s\\=",
-                              "[count]", "[quotex]", "[range]",
+                              "[count]", "[quotex]",
+                              "[range]", ":[range]",
                               "[pattern]", "\\|", "\\%$",
                               "s/\\~", "s/\\U", "s/\\L",
                               "s/\\1", "s/\\2", "s/\\3", "s/\\9"};
     static char *(rtable[]) = {"star", "gstar", "[star", "]star", ":star",
                               "/star", "/\\\\star", "quotestar", "starstar",
                               "cpo-star", "/\\\\(\\\\)", "/\\\\%(\\\\)",
-                              "?", ":?", "?<CR>", "g?", "g?g?", "g??", "z?",
+                              "?", ":?", "?<CR>", "g?", "g?g?", "g??",
                               "/\\\\?", "/\\\\z(\\\\)", "\\\\=", ":s\\\\=",
-                              "\\[count]", "\\[quotex]", "\\[range]",
+                              "\\[count]", "\\[quotex]",
+                              "\\[range]", ":\\[range]",
                               "\\[pattern]", "\\\\bar", "/\\\\%\\$",
                               "s/\\\\\\~", "s/\\\\U", "s/\\\\L",
                               "s/\\\\1", "s/\\\\2", "s/\\\\3", "s/\\\\9"};
@@ -6800,7 +6818,7 @@ fix_help_buffer(void)
        {
            line = ml_get_buf(curbuf, lnum, FALSE);
            len = (int)STRLEN(line);
-           if (in_example && len > 0 && !vim_iswhite(line[0]))
+           if (in_example && len > 0 && !VIM_ISWHITE(line[0]))
            {
                /* End of example: non-white or '<' in first column. */
                if (line[0] == '<')
@@ -7412,7 +7430,7 @@ ex_helptags(exarg_T *eap)
     int                add_help_tags = FALSE;
 
     /* Check for ":helptags ++t {dir}". */
-    if (STRNCMP(eap->arg, "++t", 3) == 0 && vim_iswhite(eap->arg[3]))
+    if (STRNCMP(eap->arg, "++t", 3) == 0 && VIM_ISWHITE(eap->arg[3]))
     {
        add_help_tags = TRUE;
        eap->arg = skipwhite(eap->arg + 3);
@@ -7745,7 +7763,7 @@ ex_sign(exarg_T *eap)
        if (VIM_ISDIGIT(*arg))
        {
            id = getdigits(&arg);
-           if (!vim_iswhite(*arg) && *arg != NUL)
+           if (!VIM_ISWHITE(*arg) && *arg != NUL)
            {
                id = -1;
                arg = arg1;
@@ -7955,7 +7973,7 @@ sign_list_defined(sign_T *sp)
     if (sp->sn_line_hl > 0)
     {
        MSG_PUTS(" linehl=");
-       p = get_highlight_name(NULL, sp->sn_line_hl - 1);
+       p = get_highlight_name_ext(NULL, sp->sn_line_hl - 1, FALSE);
        if (p == NULL)
            MSG_PUTS("NONE");
        else
@@ -7964,7 +7982,7 @@ sign_list_defined(sign_T *sp)
     if (sp->sn_text_hl > 0)
     {
        MSG_PUTS(" texthl=");
-       p = get_highlight_name(NULL, sp->sn_text_hl - 1);
+       p = get_highlight_name_ext(NULL, sp->sn_text_hl - 1, FALSE);
        if (p == NULL)
            MSG_PUTS("NONE");
        else
@@ -8277,7 +8295,7 @@ ex_smile(exarg_T *eap UNUSED)
            else
                for (n = *p++; n > 0; --n)
                    if (*p == 'o' || *p == '$')
-                       msg_putchar_attr(*p, hl_attr(HLF_L));
+                       msg_putchar_attr(*p, HL_ATTR(HLF_L));
                    else
                        msg_putchar(*p);
     msg_clr_eos();
index 01126ba..531bd0e 100644 (file)
@@ -65,7 +65,8 @@
 #define ADDR_LOADED_BUFFERS    3
 #define ADDR_BUFFERS           4
 #define ADDR_TABS              5
-#define ADDR_QUICKFIX          6
+#define ADDR_TABS_RELATIVE     6   /* Tab page that only relative */
+#define ADDR_QUICKFIX          7
 #define ADDR_OTHER             99
 
 #ifndef DO_DECLARE_EXCMD
@@ -391,10 +392,10 @@ EX(CMD_cquit,             "cquit",        ex_cquit,
 EX(CMD_crewind,                "crewind",      ex_cc,
                        RANGE|NOTADR|COUNT|TRLBAR|BANG,
                        ADDR_LINES),
-EX(CMD_cscope,         "cscope",       do_cscope,
+EX(CMD_cscope,         "cscope",       ex_cscope,
                        EXTRA|NOTRLCOM|XFILE,
                        ADDR_LINES),
-EX(CMD_cstag,          "cstag",        do_cstag,
+EX(CMD_cstag,          "cstag",        ex_cstag,
                        BANG|TRLBAR|WORD1,
                        ADDR_LINES),
 EX(CMD_cunmap,         "cunmap",       ex_unmap,
@@ -623,7 +624,7 @@ EX(CMD_highlight,   "highlight",    ex_highlight,
                        BANG|EXTRA|TRLBAR|SBOXOK|CMDWIN,
                        ADDR_LINES),
 EX(CMD_hide,           "hide",         ex_hide,
-                       BANG|RANGE|NOTADR|COUNT|EXTRA|NOTRLCOM,
+                       BANG|RANGE|NOTADR|COUNT|EXTRA|TRLBAR,
                        ADDR_WINDOWS),
 EX(CMD_history,                "history",      ex_history,
                        EXTRA|TRLBAR|CMDWIN,
@@ -745,7 +746,7 @@ EX(CMD_lchdir,              "lchdir",       ex_cd,
 EX(CMD_lclose,         "lclose",       ex_cclose,
                        RANGE|NOTADR|COUNT|TRLBAR,
                        ADDR_LINES),
-EX(CMD_lcscope,                "lcscope",      do_cscope,
+EX(CMD_lcscope,                "lcscope",      ex_cscope,
                        EXTRA|NOTRLCOM|XFILE,
                        ADDR_LINES),
 EX(CMD_ldo,            "ldo",          ex_listdo,
@@ -1132,6 +1133,18 @@ EX(CMD_python3,          "python3",      ex_py3,
 EX(CMD_py3file,                "py3file",      ex_py3file,
                        RANGE|FILE1|NEEDARG|CMDWIN,
                        ADDR_LINES),
+EX(CMD_pyx,            "pyx",          ex_pyx,
+                       RANGE|EXTRA|NEEDARG|CMDWIN,
+                       ADDR_LINES),
+EX(CMD_pyxdo,          "pyxdo",        ex_pyxdo,
+                       RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN,
+                       ADDR_LINES),
+EX(CMD_pythonx,                "pythonx",      ex_pyx,
+                       RANGE|EXTRA|NEEDARG|CMDWIN,
+                       ADDR_LINES),
+EX(CMD_pyxfile,                "pyxfile",      ex_pyxfile,
+                       RANGE|FILE1|NEEDARG|CMDWIN,
+                       ADDR_LINES),
 EX(CMD_quit,           "quit",         ex_quit,
                        BANG|RANGE|COUNT|NOTADR|TRLBAR|CMDWIN,
                        ADDR_WINDOWS),
@@ -1249,7 +1262,7 @@ EX(CMD_scriptnames,       "scriptnames",  ex_scriptnames,
 EX(CMD_scriptencoding, "scriptencoding", ex_scriptencoding,
                        WORD1|TRLBAR|CMDWIN,
                        ADDR_LINES),
-EX(CMD_scscope,                "scscope",      do_scscope,
+EX(CMD_scscope,                "scscope",      ex_scscope,
                        EXTRA|NOTRLCOM,
                        ADDR_LINES),
 EX(CMD_set,            "set",          ex_set,
@@ -1413,9 +1426,9 @@ EX(CMD_tags,              "tags",         do_tags,
                        ADDR_LINES),
 EX(CMD_tab,            "tab",          ex_wrongmodifier,
                        NEEDARG|EXTRA|NOTRLCOM,
-                       ADDR_LINES),
+                       ADDR_TABS),
 EX(CMD_tabclose,       "tabclose",     ex_tabclose,
-                       RANGE|NOTADR|COUNT|BANG|TRLBAR|CMDWIN,
+                       BANG|RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR|CMDWIN,
                        ADDR_TABS),
 EX(CMD_tabdo,          "tabdo",        ex_listdo,
                        NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL,
@@ -1428,34 +1441,34 @@ EX(CMD_tabfind,         "tabfind",      ex_splitview,
                        ADDR_TABS),
 EX(CMD_tabfirst,       "tabfirst",     ex_tabnext,
                        TRLBAR,
-                       ADDR_LINES),
+                       ADDR_TABS),
 EX(CMD_tabmove,                "tabmove",      ex_tabmove,
                        RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR,
                        ADDR_TABS),
 EX(CMD_tablast,                "tablast",      ex_tabnext,
                        TRLBAR,
-                       ADDR_LINES),
+                       ADDR_TABS),
 EX(CMD_tabnext,                "tabnext",      ex_tabnext,
-                       RANGE|NOTADR|COUNT|TRLBAR,
-                       ADDR_LINES),
+                       RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR,
+                       ADDR_TABS),
 EX(CMD_tabnew,         "tabnew",       ex_splitview,
                        BANG|FILE1|RANGE|NOTADR|ZEROR|EDITCMD|ARGOPT|TRLBAR,
                        ADDR_TABS),
 EX(CMD_tabonly,                "tabonly",      ex_tabonly,
-                       BANG|RANGE|NOTADR|TRLBAR|CMDWIN,
+                       BANG|RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR|CMDWIN,
                        ADDR_TABS),
 EX(CMD_tabprevious,    "tabprevious",  ex_tabnext,
-                       RANGE|NOTADR|COUNT|TRLBAR,
-                       ADDR_LINES),
+                       RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR,
+                       ADDR_TABS_RELATIVE),
 EX(CMD_tabNext,                "tabNext",      ex_tabnext,
-                       RANGE|NOTADR|COUNT|TRLBAR,
-                       ADDR_LINES),
+                       RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR,
+                       ADDR_TABS_RELATIVE),
 EX(CMD_tabrewind,      "tabrewind",    ex_tabnext,
                        TRLBAR,
-                       ADDR_LINES),
+                       ADDR_TABS),
 EX(CMD_tabs,           "tabs",         ex_tabs,
                        TRLBAR|CMDWIN,
-                       ADDR_LINES),
+                       ADDR_TABS),
 EX(CMD_tcl,            "tcl",          ex_tcl,
                        RANGE|EXTRA|NEEDARG|CMDWIN,
                        ADDR_LINES),
@@ -1610,7 +1623,7 @@ EX(CMD_wincmd,            "wincmd",       ex_wincmd,
                        NEEDARG|WORD1|RANGE|NOTADR,
                        ADDR_WINDOWS),
 EX(CMD_windo,          "windo",        ex_listdo,
-                       BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL,
+                       NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL,
                        ADDR_WINDOWS),
 EX(CMD_winpos,         "winpos",       ex_winpos,
                        EXTRA|TRLBAR|CMDWIN,
index bee4670..36ee57e 100644 (file)
@@ -2230,7 +2230,7 @@ buf_write_all(buf_T *buf, int forceit)
 #ifdef FEAT_AUTOCMD
     if (curbuf != old_curbuf)
     {
-       msg_source(hl_attr(HLF_W));
+       msg_source(HL_ATTR(HLF_W));
        MSG(_("Warning: Entered other buffer unexpectedly (check autocommands)"));
     }
 #endif
@@ -2832,8 +2832,15 @@ ex_argdelete(exarg_T *eap)
        if (eap->line2 > ARGCOUNT)
            eap->line2 = ARGCOUNT;
        n = eap->line2 - eap->line1 + 1;
-       if (*eap->arg != NUL || n <= 0)
+       if (*eap->arg != NUL)
+           /* Can't have both a range and an argument. */
            EMSG(_(e_invarg));
+       else if (n <= 0)
+       {
+           /* Don't give an error for ":%argdel" if the list is empty. */
+           if (eap->line1 != 1 || eap->line2 != 0)
+               EMSG(_(e_invrange));
+       }
        else
        {
            for (i = eap->line1; i <= eap->line2; ++i)
@@ -3509,6 +3516,9 @@ add_pack_plugin(char_u *fname, void *cookie)
     size_t  afterlen = 0;
     char_u  *ffname = fix_fname(fname);
     size_t  fname_len;
+    char_u  *buf = NULL;
+    char_u  *rtp_ffname;
+    int            match;
 
     if (ffname == NULL)
        return;
@@ -3516,7 +3526,7 @@ add_pack_plugin(char_u *fname, void *cookie)
     {
        /* directory is not yet in 'runtimepath', add it */
        p4 = p3 = p2 = p1 = get_past_head(ffname);
-       for (p = p1; *p; mb_ptr_adv(p))
+       for (p = p1; *p; MB_PTR_ADV(p))
            if (vim_ispathsep_nocolon(*p))
            {
                p4 = p3; p3 = p2; p2 = p1; p1 = p;
@@ -3533,26 +3543,28 @@ add_pack_plugin(char_u *fname, void *cookie)
        /* Find "ffname" in "p_rtp", ignoring '/' vs '\' differences. */
        fname_len = STRLEN(ffname);
        insp = p_rtp;
-       for (;;)
+       buf = alloc(MAXPATHL);
+       if (buf == NULL)
+           goto theend;
+       while (*insp != NUL)
        {
-           if (vim_fnamencmp(insp, ffname, fname_len) == 0)
+           copy_option_part(&insp, buf, MAXPATHL, ",");
+           add_pathsep(buf);
+           rtp_ffname = fix_fname(buf);
+           if (rtp_ffname == NULL)
+               goto theend;
+           match = vim_fnamencmp(rtp_ffname, ffname, fname_len) == 0;
+           vim_free(rtp_ffname);
+           if (match)
                break;
-           insp = vim_strchr(insp, ',');
-           if (insp == NULL)
-               break;
-           ++insp;
        }
 
-       if (insp == NULL)
+       if (*insp == NUL)
            /* not found, append at the end */
            insp = p_rtp + STRLEN(p_rtp);
        else
-       {
            /* append after the matching directory. */
-           insp += STRLEN(ffname);
-           while (*insp != NUL && *insp != ',')
-               ++insp;
-       }
+           --insp;
        *p4 = c;
 
        /* check if rtp/pack/name/start/name/after exists */
@@ -3562,7 +3574,8 @@ add_pack_plugin(char_u *fname, void *cookie)
 
        oldlen = STRLEN(p_rtp);
        addlen = STRLEN(ffname) + 1; /* add one for comma */
-       new_rtp = alloc((int)(oldlen + addlen + afterlen + 1)); /* add one for NUL */
+       new_rtp = alloc((int)(oldlen + addlen + afterlen + 1));
+                                                         /* add one for NUL */
        if (new_rtp == NULL)
            goto theend;
        keep = (int)(insp - p_rtp);
@@ -3616,6 +3629,7 @@ add_pack_plugin(char_u *fname, void *cookie)
     }
 
 theend:
+    vim_free(buf);
     vim_free(ffname);
 }
 
@@ -3675,6 +3689,194 @@ ex_options(
 }
 #endif
 
+#if defined(FEAT_PYTHON3) || defined(FEAT_PYTHON) || defined(PROTO)
+
+# if (defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)) || defined(PROTO)
+/*
+ * Detect Python 3 or 2, and initialize 'pyxversion'.
+ */
+    void
+init_pyxversion(void)
+{
+    if (p_pyx == 0)
+    {
+       if (python3_enabled(FALSE))
+           p_pyx = 3;
+       else if (python_enabled(FALSE))
+           p_pyx = 2;
+    }
+}
+# endif
+
+/*
+ * Does a file contain one of the following strings at the beginning of any
+ * line?
+ * "#!(any string)python2"  => returns 2
+ * "#!(any string)python3"  => returns 3
+ * "# requires python 2.x"  => returns 2
+ * "# requires python 3.x"  => returns 3
+ * otherwise return 0.
+ */
+    static int
+requires_py_version(char_u *filename)
+{
+    FILE    *file;
+    int            requires_py_version = 0;
+    int            i, lines;
+
+    lines = (int)p_mls;
+    if (lines < 0)
+       lines = 5;
+
+    file = mch_fopen((char *)filename, "r");
+    if (file != NULL)
+    {
+       for (i = 0; i < lines; i++)
+       {
+           if (vim_fgets(IObuff, IOSIZE, file))
+               break;
+           if (i == 0 && IObuff[0] == '#' && IObuff[1] == '!')
+           {
+               /* Check shebang. */
+               if (strstr((char *)IObuff + 2, "python2") != NULL)
+               {
+                   requires_py_version = 2;
+                   break;
+               }
+               if (strstr((char *)IObuff + 2, "python3") != NULL)
+               {
+                   requires_py_version = 3;
+                   break;
+               }
+           }
+           IObuff[21] = '\0';
+           if (STRCMP("# requires python 2.x", IObuff) == 0)
+           {
+               requires_py_version = 2;
+               break;
+           }
+           if (STRCMP("# requires python 3.x", IObuff) == 0)
+           {
+               requires_py_version = 3;
+               break;
+           }
+       }
+       fclose(file);
+    }
+    return requires_py_version;
+}
+
+
+/*
+ * Source a python file using the requested python version.
+ */
+    static void
+source_pyx_file(exarg_T *eap, char_u *fname)
+{
+    exarg_T ex;
+    int            v = requires_py_version(fname);
+
+# if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
+    init_pyxversion();
+# endif
+    if (v == 0)
+    {
+# if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
+       /* user didn't choose a preference, 'pyx' is used */
+       v = p_pyx;
+# elif defined(FEAT_PYTHON)
+       v = 2;
+# elif defined(FEAT_PYTHON3)
+       v = 3;
+# endif
+    }
+
+    /*
+     * now source, if required python version is not supported show
+     * unobtrusive message.
+     */
+    if (eap == NULL)
+       vim_memset(&ex, 0, sizeof(ex));
+    else
+       ex = *eap;
+    ex.arg = fname;
+    ex.cmd = (char_u *)(v == 2 ? "pyfile" : "pyfile3");
+
+    if (v == 2)
+    {
+# ifdef FEAT_PYTHON
+       ex_pyfile(&ex);
+# else
+       vim_snprintf((char *)IObuff, IOSIZE,
+               _("W20: Required python version 2.x not supported, ignoring file: %s"),
+               fname);
+       MSG(IObuff);
+# endif
+       return;
+    }
+    else
+    {
+# ifdef FEAT_PYTHON3
+       ex_py3file(&ex);
+# else
+       vim_snprintf((char *)IObuff, IOSIZE,
+               _("W21: Required python version 3.x not supported, ignoring file: %s"),
+               fname);
+       MSG(IObuff);
+# endif
+       return;
+    }
+}
+
+/*
+ * ":pyxfile {fname}"
+ */
+    void
+ex_pyxfile(exarg_T *eap)
+{
+    source_pyx_file(eap, eap->arg);
+}
+
+/*
+ * ":pyx"
+ */
+    void
+ex_pyx(exarg_T *eap)
+{
+# if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
+    init_pyxversion();
+    if (p_pyx == 2)
+       ex_python(eap);
+    else
+       ex_py3(eap);
+# elif defined(FEAT_PYTHON)
+    ex_python(eap);
+# elif defined(FEAT_PYTHON3)
+    ex_py3(eap);
+# endif
+}
+
+/*
+ * ":pyxdo"
+ */
+    void
+ex_pyxdo(exarg_T *eap)
+{
+# if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
+    init_pyxversion();
+    if (p_pyx == 2)
+       ex_pydo(eap);
+    else
+       ex_py3do(eap);
+# elif defined(FEAT_PYTHON)
+    ex_pydo(eap);
+# elif defined(FEAT_PYTHON3)
+    ex_py3do(eap);
+# endif
+}
+
+#endif
+
 /*
  * ":source {fname}"
  */
@@ -4531,7 +4733,7 @@ get_one_sourceline(struct source_cookie *sp)
                {
                    if (!sp->error)
                    {
-                       msg_source(hl_attr(HLF_W));
+                       msg_source(HL_ATTR(HLF_W));
                        EMSG(_("W15: Warning: Wrong line separator, ^M may be missing"));
                    }
                    sp->error = TRUE;
@@ -4981,7 +5183,7 @@ ex_language(exarg_T *eap)
      * Allow abbreviation, but require at least 3 characters to avoid
      * confusion with a two letter language name "me" or "ct". */
     p = skiptowhite(eap->arg);
-    if ((*p == NUL || vim_iswhite(*p)) && p - eap->arg >= 3)
+    if ((*p == NUL || VIM_ISWHITE(*p)) && p - eap->arg >= 3)
     {
        if (STRNICMP(eap->arg, "messages", p - eap->arg) == 0)
        {
@@ -5091,23 +5293,9 @@ ex_language(exarg_T *eap)
 # if defined(FEAT_CMDL_COMPL) || defined(PROTO)
 
 static char_u  **locales = NULL;       /* Array of all available locales */
-static int     did_init_locales = FALSE;
 
-static void init_locales(void);
-static char_u **find_locales(void);
-
-/*
- * Lazy initialization of all available locales.
- */
-    static void
-init_locales(void)
-{
-    if (!did_init_locales)
-    {
-       did_init_locales = TRUE;
-       locales = find_locales();
-    }
-}
+#  ifndef WIN32
+static int     did_init_locales = FALSE;
 
 /* Return an array of strings for all available locales + NULL for the
  * last element.  Return NULL in case of error. */
@@ -5149,6 +5337,22 @@ find_locales(void)
     ((char_u **)locales_ga.ga_data)[locales_ga.ga_len] = NULL;
     return (char_u **)locales_ga.ga_data;
 }
+#  endif
+
+/*
+ * Lazy initialization of all available locales.
+ */
+    static void
+init_locales(void)
+{
+#  ifndef WIN32
+    if (!did_init_locales)
+    {
+       did_init_locales = TRUE;
+       locales = find_locales();
+    }
+#  endif
+}
 
 #  if defined(EXITFREE) || defined(PROTO)
     void
index dcb5cfe..d0df1fd 100644 (file)
@@ -137,7 +137,7 @@ static int  getargopt(exarg_T *eap);
 #endif
 
 static int     check_more(int, int);
-static linenr_T get_address(exarg_T *, char_u **, int addr_type, int skip, int to_other_file);
+static linenr_T get_address(exarg_T *, char_u **, int addr_type, int skip, int to_other_file, int address_count);
 static void    get_flags(exarg_T *eap);
 #if !defined(FEAT_PERL) \
        || !defined(FEAT_PYTHON) || !defined(FEAT_PYTHON3) \
@@ -243,9 +243,9 @@ static void ex_popup(exarg_T *eap);
 # define ex_helpfind           ex_ni
 #endif
 #ifndef FEAT_CSCOPE
-# define do_cscope             ex_ni
-# define do_scscope            ex_ni
-# define do_cstag              ex_ni
+# define ex_cscope             ex_ni
+# define ex_scscope            ex_ni
+# define ex_cstag              ex_ni
 #endif
 #ifndef FEAT_SYN_HL
 # define ex_syntax             ex_ni
@@ -288,6 +288,11 @@ static void        ex_popup(exarg_T *eap);
 # define ex_py3do              ex_ni
 # define ex_py3file            ex_ni
 #endif
+#if !defined(FEAT_PYTHON) && !defined(FEAT_PYTHON3)
+# define ex_pyx                        ex_script_ni
+# define ex_pyxdo              ex_ni
+# define ex_pyxfile            ex_ni
+#endif
 #ifndef FEAT_TCL
 # define ex_tcl                        ex_script_ni
 # define ex_tcldo              ex_ni
@@ -489,40 +494,7 @@ static void        ex_folddo(exarg_T *eap);
  */
 #define DO_DECLARE_EXCMD
 #include "ex_cmds.h"
-
-/*
- * Table used to quickly search for a command, based on its first character.
- */
-static cmdidx_T cmdidxs[27] =
-{
-       CMD_append,
-       CMD_buffer,
-       CMD_change,
-       CMD_delete,
-       CMD_edit,
-       CMD_file,
-       CMD_global,
-       CMD_help,
-       CMD_insert,
-       CMD_join,
-       CMD_k,
-       CMD_list,
-       CMD_move,
-       CMD_next,
-       CMD_open,
-       CMD_print,
-       CMD_quit,
-       CMD_read,
-       CMD_substitute,
-       CMD_t,
-       CMD_undo,
-       CMD_vglobal,
-       CMD_write,
-       CMD_xit,
-       CMD_yank,
-       CMD_z,
-       CMD_bang
-};
+#include "ex_cmdidxs.h"
 
 static char_u dollar_command[2] = {'$', 0};
 
@@ -609,7 +581,6 @@ restore_dbg_stuff(struct dbg_stuff *dsp)
 }
 #endif
 
-
 /*
  * do_exmode(): Repeatedly get commands for the "Ex" mode, until the ":vi"
  * command is given.
@@ -621,7 +592,7 @@ do_exmode(
     int                save_msg_scroll;
     int                prev_msg_row;
     linenr_T   prev_line;
-    int                changedtick;
+    varnumber_T        changedtick;
 
     if (improved)
        exmode_active = EXMODE_VIM;
@@ -655,7 +626,7 @@ do_exmode(
        need_wait_return = FALSE;
        ex_pressedreturn = FALSE;
        ex_no_reprint = FALSE;
-       changedtick = curbuf->b_changedtick;
+       changedtick = CHANGEDTICK(curbuf);
        prev_msg_row = msg_row;
        prev_line = curwin->w_cursor.lnum;
        if (improved)
@@ -668,7 +639,7 @@ do_exmode(
        lines_left = Rows - 1;
 
        if ((prev_line != curwin->w_cursor.lnum
-                   || changedtick != curbuf->b_changedtick) && !ex_no_reprint)
+                  || changedtick != CHANGEDTICK(curbuf)) && !ex_no_reprint)
        {
            if (curbuf->b_ml.ml_flags & ML_EMPTY)
                EMSG(_(e_emptybuf));
@@ -787,8 +758,13 @@ do_cmdline(
 #endif
 
     /* It's possible to create an endless loop with ":execute", catch that
-     * here.  The value of 200 allows nested function calls, ":source", etc. */
-    if (call_depth == 200)
+     * here.  The value of 200 allows nested function calls, ":source", etc.
+     * Allow 200 or 'maxfuncdepth', whatever is larger. */
+    if (call_depth >= 200
+#ifdef FEAT_EVAL
+           && call_depth >= p_mfd
+#endif
+           )
     {
        EMSG(_("E169: Command too recursive"));
 #ifdef FEAT_EVAL
@@ -1388,8 +1364,6 @@ do_cmdline(
                    break;
                case ET_INTERRUPT:
                    break;
-               default:
-                   p = vim_strsave((char_u *)_(e_internal));
            }
 
            saved_sourcing_name = sourcing_name;
@@ -1793,6 +1767,7 @@ do_one_cmd(
     cmdmod_T           save_cmdmod;
     int                        ni;                     /* set when Not Implemented */
     char_u             *cmd;
+    int                        address_count = 1;
 
     vim_memset(&ea, 0, sizeof(ea));
     ea.line1 = 1;
@@ -2004,7 +1979,7 @@ do_one_cmd(
                        if (save_msg_silent == -1)
                            save_msg_silent = msg_silent;
                        ++msg_silent;
-                       if (*ea.cmd == '!' && !vim_iswhite(ea.cmd[-1]))
+                       if (*ea.cmd == '!' && !VIM_ISWHITE(ea.cmd[-1]))
                        {
                            /* ":silent!", but not "silent !cmd" */
                            ea.cmd = skipwhite(ea.cmd + 1);
@@ -2017,7 +1992,7 @@ do_one_cmd(
                        {
 #ifdef FEAT_WINDOWS
                            long tabnr = get_address(&ea, &ea.cmd, ADDR_TABS,
-                                                               ea.skip, FALSE);
+                                                           ea.skip, FALSE, 1);
                            if (tabnr == MAXLNUM)
                                cmdmod.tab = tabpage_index(curtab) + 1;
                            else
@@ -2153,8 +2128,7 @@ do_one_cmd(
                ea.line2 = curwin->w_cursor.lnum;
                break;
            case ADDR_WINDOWS:
-               lnum = CURRENT_WIN_NR;
-               ea.line2 = lnum;
+               ea.line2 = CURRENT_WIN_NR;
                break;
            case ADDR_ARGUMENTS:
                ea.line2 = curwin->w_arg_idx + 1;
@@ -2166,8 +2140,10 @@ do_one_cmd(
                ea.line2 = curbuf->b_fnum;
                break;
            case ADDR_TABS:
-               lnum = CURRENT_TAB_NR;
-               ea.line2 = lnum;
+               ea.line2 = CURRENT_TAB_NR;
+               break;
+           case ADDR_TABS_RELATIVE:
+               ea.line2 = 1;
                break;
 #ifdef FEAT_QUICKFIX
            case ADDR_QUICKFIX:
@@ -2177,7 +2153,7 @@ do_one_cmd(
        }
        ea.cmd = skipwhite(ea.cmd);
        lnum = get_address(&ea, &ea.cmd, ea.addr_type, ea.skip,
-                                                         ea.addr_count == 0);
+                                         ea.addr_count == 0, address_count++);
        if (ea.cmd == NULL)                 /* error detected */
            goto doend;
        if (lnum == MAXLNUM)
@@ -2226,6 +2202,10 @@ do_one_cmd(
                            goto doend;
                        }
                        break;
+                   case ADDR_TABS_RELATIVE:
+                       errormsg = (char_u *)_(e_invrange);
+                       goto doend;
+                       break;
                    case ADDR_ARGUMENTS:
                        if (ARGCOUNT == 0)
                            ea.line1 = ea.line2 = 0;
@@ -2279,7 +2259,11 @@ do_one_cmd(
        if (*ea.cmd == ';')
        {
            if (!ea.skip)
+           {
                curwin->w_cursor.lnum = ea.line2;
+               /* don't leave the cursor on an illegal line or column */
+               check_cursor();
+           }
        }
        else if (*ea.cmd != ',')
            break;
@@ -2295,9 +2279,6 @@ do_one_cmd(
            ea.addr_count = 0;
     }
 
-    /* Don't leave the cursor on an illegal line (caused by ';') */
-    check_cursor_lnum();
-
 /*
  * 5. Parse the command.
  */
@@ -2475,7 +2456,7 @@ do_one_cmd(
                && !IS_USER_CMDIDX(ea.cmdidx))
        {
            /* Command not allowed when editing the command line. */
-           errormsg = get_text_locked_msg();
+           errormsg = (char_u *)_(get_text_locked_msg());
            goto doend;
        }
 #ifdef FEAT_AUTOCMD
@@ -2700,6 +2681,9 @@ do_one_cmd(
            case ADDR_TABS:
                ea.line2 = LAST_TAB_NR;
                break;
+           case ADDR_TABS_RELATIVE:
+               ea.line2 = 1;
+               break;
            case ADDR_ARGUMENTS:
                if (ARGCOUNT == 0)
                    ea.line1 = ea.line2 = 0;
@@ -2753,7 +2737,7 @@ do_one_cmd(
      */
     if ((ea.argt & COUNT) && VIM_ISDIGIT(*ea.arg)
            && (!(ea.argt & BUFNAME) || *(p = skipdigits(ea.arg)) == NUL
-                                                         || vim_iswhite(*p)))
+                                                         || VIM_ISWHITE(*p)))
     {
        n = getdigits(&ea.arg);
        ea.arg = skipwhite(ea.arg);
@@ -2776,7 +2760,8 @@ do_one_cmd(
            /*
             * Be vi compatible: no error message for out of range.
             */
-           if (ea.line2 > curbuf->b_ml.ml_line_count)
+           if (ea.addr_type == ADDR_LINES
+                   && ea.line2 > curbuf->b_ml.ml_line_count)
                ea.line2 = curbuf->b_ml.ml_line_count;
        }
     }
@@ -2920,7 +2905,7 @@ do_one_cmd(
        else
        {
            p = ea.arg + STRLEN(ea.arg);
-           while (p > ea.arg && vim_iswhite(p[-1]))
+           while (p > ea.arg && VIM_ISWHITE(p[-1]))
                --p;
        }
        ea.line2 = buflist_findpat(ea.arg, p, (ea.argt & BUFUNL) != 0,
@@ -2987,7 +2972,10 @@ do_one_cmd(
 
 doend:
     if (curwin->w_cursor.lnum == 0)    /* can happen with zero line number */
+    {
        curwin->w_cursor.lnum = 1;
+       curwin->w_cursor.col = 0;
+    }
 
     if (errormsg != NULL && *errormsg != NUL && !did_emsg)
     {
@@ -3189,10 +3177,25 @@ find_command(exarg_T *eap, int *full UNUSED)
            }
        }
 
-       if (ASCII_ISLOWER(*eap->cmd))
-           eap->cmdidx = cmdidxs[CharOrdLow(*eap->cmd)];
+       if (ASCII_ISLOWER(eap->cmd[0]))
+       {
+           int c1 = eap->cmd[0];
+           int c2 = eap->cmd[1];
+
+           if (command_count != (int)CMD_SIZE)
+           {
+               iemsg((char_u *)_("E943: Command table needs to be updated, run 'make cmdidxs'"));
+               getout(1);
+           }
+
+           /* Use a precomputed index for fast look-up in cmdnames[]
+            * taking into account the first 2 letters of eap->cmd. */
+           eap->cmdidx = cmdidxs1[CharOrdLow(c1)];
+           if (ASCII_ISLOWER(c2))
+               eap->cmdidx += cmdidxs2[CharOrdLow(c1)][CharOrdLow(c2)];
+       }
        else
-           eap->cmdidx = cmdidxs[26];
+           eap->cmdidx = CMD_bang;
 
        for ( ; (int)eap->cmdidx < (int)CMD_SIZE;
                               eap->cmdidx = (cmdidx_T)((int)eap->cmdidx + 1))
@@ -3677,7 +3680,7 @@ set_one_cmd_context(
                    return NULL;    /* It's a comment */
                }
            }
-           mb_ptr_adv(p);
+           MB_PTR_ADV(p);
        }
     }
 
@@ -3701,7 +3704,7 @@ set_one_cmd_context(
        {
            if (*p == '\\' && *(p + 1) != NUL)
                ++p; /* skip over escaped character */
-           mb_ptr_adv(p);
+           MB_PTR_ADV(p);
        }
     }
 
@@ -3738,7 +3741,7 @@ set_one_cmd_context(
            }
            /* An argument can contain just about everything, except
             * characters that end the command and white space. */
-           else if (c == '|' || c == '\n' || c == '"' || (vim_iswhite(c)
+           else if (c == '|' || c == '\n' || c == '"' || (VIM_ISWHITE(c)
 #ifdef SPACE_IN_FILENAME
                                         && (!(ea.argt & NOSPC) || usefilter)
 #endif
@@ -3761,7 +3764,7 @@ set_one_cmd_context(
                    else
 #endif
                        len = 1;
-                   mb_ptr_adv(p);
+                   MB_PTR_ADV(p);
                }
                if (in_quote)
                    bow = p;
@@ -3769,7 +3772,7 @@ set_one_cmd_context(
                    xp->xp_pattern = p;
                p -= len;
            }
-           mb_ptr_adv(p);
+           MB_PTR_ADV(p);
        }
 
        /*
@@ -3866,7 +3869,6 @@ set_one_cmd_context(
        case CMD_cfdo:
        case CMD_confirm:
        case CMD_debug:
-       case CMD_filter:
        case CMD_folddoclosed:
        case CMD_folddoopen:
        case CMD_hide:
@@ -3891,6 +3893,16 @@ set_one_cmd_context(
        case CMD_windo:
            return arg;
 
+       case CMD_filter:
+           if (*arg != NUL)
+               arg = skip_vimgrep_pat(arg, NULL, NULL);
+           if (arg == NULL || *arg == NUL)
+           {
+               xp->xp_context = EXPAND_NOTHING;
+               return NULL;
+           }
+           return skipwhite(arg);
+
 #ifdef FEAT_CMDL_COMPL
 # ifdef FEAT_SEARCH_EXTRA
        case CMD_match:
@@ -4095,6 +4107,12 @@ set_one_cmd_context(
        case CMD_echoerr:
        case CMD_call:
        case CMD_return:
+       case CMD_cexpr:
+       case CMD_caddexpr:
+       case CMD_cgetexpr:
+       case CMD_lexpr:
+       case CMD_laddexpr:
+       case CMD_lgetexpr:
            set_context_for_expression(xp, arg, ea.cmdidx);
            break;
 
@@ -4170,7 +4188,7 @@ set_one_cmd_context(
                            arg = p + 1;
                        else if (*p == '\\' && *(p + 1) != NUL)
                            ++p; /* skip over escaped character */
-                       mb_ptr_adv(p);
+                       MB_PTR_ADV(p);
                    }
                    xp->xp_pattern = arg;
                }
@@ -4323,9 +4341,16 @@ skip_range(
 {
     unsigned   delim;
 
-    while (vim_strchr((char_u *)" \t0123456789.$%'/?-+,;", *cmd) != NULL)
+    while (vim_strchr((char_u *)" \t0123456789.$%'/?-+,;\\", *cmd) != NULL)
     {
-       if (*cmd == '\'')
+       if (*cmd == '\\')
+       {
+           if (cmd[1] == '?' || cmd[1] == '/' || cmd[1] == '&')
+               ++cmd;
+           else
+               break;
+       }
+       else if (*cmd == '\'')
        {
            if (*++cmd == NUL && ctx != NULL)
                *ctx = EXPAND_NOTHING;
@@ -4364,7 +4389,8 @@ get_address(
     char_u     **ptr,
     int                addr_type,  /* flag: one of ADDR_LINES, ... */
     int                skip,       /* only skip the address, don't use it */
-    int                to_other_file)  /* flag: may jump to other file */
+    int                to_other_file,  /* flag: may jump to other file */
+    int                address_count UNUSED) /* 1 for first address, >1 after comma */
 {
     int                c;
     int                i;
@@ -4401,6 +4427,11 @@ get_address(
                    case ADDR_TABS:
                        lnum = CURRENT_TAB_NR;
                        break;
+                   case ADDR_TABS_RELATIVE:
+                       EMSG(_(e_invrange));
+                       cmd = NULL;
+                       goto error;
+                       break;
 #ifdef FEAT_QUICKFIX
                    case ADDR_QUICKFIX:
                        lnum = qf_get_cur_valid_idx(eap);
@@ -4438,6 +4469,11 @@ get_address(
                    case ADDR_TABS:
                        lnum = LAST_TAB_NR;
                        break;
+                   case ADDR_TABS_RELATIVE:
+                       EMSG(_(e_invrange));
+                       cmd = NULL;
+                       goto error;
+                       break;
 #ifdef FEAT_QUICKFIX
                    case ADDR_QUICKFIX:
                        lnum = qf_get_size(eap);
@@ -4620,6 +4656,9 @@ get_address(
                    case ADDR_TABS:
                        lnum = CURRENT_TAB_NR;
                        break;
+                   case ADDR_TABS_RELATIVE:
+                       lnum = 1;
+                       break;
 #ifdef FEAT_QUICKFIX
                    case ADDR_QUICKFIX:
                        lnum = qf_get_cur_valid_idx(eap);
@@ -4636,14 +4675,31 @@ get_address(
                n = 1;
            else
                n = getdigits(&cmd);
-           if (addr_type == ADDR_LOADED_BUFFERS
+
+           if (addr_type == ADDR_TABS_RELATIVE)
+           {
+               EMSG(_(e_invrange));
+               cmd = NULL;
+               goto error;
+           }
+           else if (addr_type == ADDR_LOADED_BUFFERS
                    || addr_type == ADDR_BUFFERS)
                lnum = compute_buffer_local_count(
                                    addr_type, lnum, (i == '-') ? -1 * n : n);
-           else if (i == '-')
-               lnum -= n;
            else
-               lnum += n;
+           {
+#ifdef FEAT_FOLDING
+               /* Relative line addressing, need to adjust for folded lines
+                * now, but only do it after the first address. */
+               if (addr_type == ADDR_LINES && (i == '-' || i == '+')
+                       && address_count >= 2)
+                   (void)hasFolding(lnum, NULL, &lnum);
+#endif
+               if (i == '-')
+                   lnum -= n;
+               else
+                   lnum += n;
+           }
        }
     } while (*cmd == '/' || *cmd == '?');
 
@@ -4759,6 +4815,9 @@ invalid_range(exarg_T *eap)
                if (eap->line2 > LAST_TAB_NR)
                    return (char_u *)_(e_invrange);
                break;
+           case ADDR_TABS_RELATIVE:
+               /* Do nothing */
+               break;
 #ifdef FEAT_QUICKFIX
            case ADDR_QUICKFIX:
                if (eap->line2 != 1 && eap->line2 > qf_get_size(eap))
@@ -5061,7 +5120,7 @@ expand_filename(
                        /* skip escaped characters */
                        if (p[1] && (*p == '\\' || *p == Ctrl_V))
                            ++p;
-                       else if (vim_iswhite(*p))
+                       else if (VIM_ISWHITE(*p))
                        {
                            *errormsgp = (char_u *)_("E172: Only one file name allowed");
                            return FAIL;
@@ -5205,7 +5264,7 @@ separate_nextcmd(exarg_T *eap)
     p = eap->arg;
 #endif
 
-    for ( ; *p; mb_ptr_adv(p))
+    for ( ; *p; MB_PTR_ADV(p))
     {
        if (*p == Ctrl_V)
        {
@@ -5305,7 +5364,7 @@ skip_cmd_arg(
            else
                ++p;
        }
-       mb_ptr_adv(p);
+       MB_PTR_ADV(p);
     }
     return p;
 }
@@ -5634,15 +5693,16 @@ find_nextcmd(char_u *p)
 #endif
 
 /*
- * Check if *p is a separator between Ex commands.
- * Return NULL if it isn't, (p + 1) if it is.
+ * Check if *p is a separator between Ex commands, skipping over white space.
+ * Return NULL if it isn't, the following character if it is.
  */
     char_u *
 check_nextcmd(char_u *p)
 {
-    p = skipwhite(p);
-    if (*p == '|' || *p == '\n')
-       return (p + 1);
+    char_u *s = skipwhite(p);
+
+    if (*s == '|' || *s == '\n')
+       return (s + 1);
     else
        return NULL;
 }
@@ -5956,7 +6016,7 @@ uc_list(char_u *name, size_t name_len)
            msg_putchar(gap != &ucmds ? 'b' : ' ');
            msg_putchar(' ');
 
-           msg_outtrans_attr(cmd->uc_name, hl_attr(HLF_D));
+           msg_outtrans_attr(cmd->uc_name, HL_ATTR(HLF_D));
            len = (int)STRLEN(cmd->uc_name) + 4;
 
            do {
@@ -6260,7 +6320,7 @@ ex_command(exarg_T *eap)
     if (ASCII_ISALPHA(*p))
        while (ASCII_ISALNUM(*p))
            ++p;
-    if (!ends_excmd(*p) && !vim_iswhite(*p))
+    if (!ends_excmd(*p) && !VIM_ISWHITE(*p))
     {
        EMSG(_("E182: Invalid command name"));
        return;
@@ -6388,7 +6448,7 @@ uc_split_args(char_u *arg, size_t *lenp)
            len += 2;
            p += 2;
        }
-       else if (p[0] == '\\' && vim_iswhite(p[1]))
+       else if (p[0] == '\\' && VIM_ISWHITE(p[1]))
        {
            len += 1;
            p += 2;
@@ -6398,7 +6458,7 @@ uc_split_args(char_u *arg, size_t *lenp)
            len += 2;
            p += 1;
        }
-       else if (vim_iswhite(*p))
+       else if (VIM_ISWHITE(*p))
        {
            p = skipwhite(p);
            if (*p == NUL)
@@ -6436,7 +6496,7 @@ uc_split_args(char_u *arg, size_t *lenp)
            *q++ = '\\';
            p += 2;
        }
-       else if (p[0] == '\\' && vim_iswhite(p[1]))
+       else if (p[0] == '\\' && VIM_ISWHITE(p[1]))
        {
            *q++ = p[1];
            p += 2;
@@ -6446,7 +6506,7 @@ uc_split_args(char_u *arg, size_t *lenp)
            *q++ = '\\';
            *q++ = *p++;
        }
-       else if (vim_iswhite(*p))
+       else if (VIM_ISWHITE(*p))
        {
            p = skipwhite(p);
            if (*p == NUL)
@@ -7002,7 +7062,7 @@ parse_addr_type_arg(
     {
        char_u  *err = value;
 
-       for (i = 0; err[i] != NUL && !vim_iswhite(err[i]); i++)
+       for (i = 0; err[i] != NUL && !VIM_ISWHITE(err[i]); i++)
            ;
        err[i] = NUL;
        EMSG2(_("E180: Invalid address type value: %s"), err);
@@ -7400,6 +7460,107 @@ ex_win_close(
 }
 
 /*
+ * Handle the argument for a tabpage related ex command.
+ * Returns a tabpage number.
+ * When an error is encountered then eap->errmsg is set.
+ */
+    static int
+get_tabpage_arg(exarg_T *eap)
+{
+    int tab_number;
+    int unaccept_arg0 = (eap->cmdidx == CMD_tabmove) ? 0 : 1;
+
+    if (eap->arg && *eap->arg != NUL)
+    {
+       char_u *p = eap->arg;
+       char_u *p_save;
+       int    relative = 0; /* argument +N/-N means: go to N places to the
+                             * right/left relative to the current position. */
+
+       if (*p == '-')
+       {
+           relative = -1;
+           p++;
+       }
+       else if (*p == '+')
+       {
+           relative = 1;
+           p++;
+       }
+
+       p_save = p;
+       tab_number = getdigits(&p);
+
+       if (relative == 0)
+       {
+           if (STRCMP(p, "$") == 0)
+               tab_number = LAST_TAB_NR;
+           else if (p == p_save || *p_save == '-' || *p != NUL
+                   || tab_number > LAST_TAB_NR)
+           {
+               /* No numbers as argument. */
+               eap->errmsg = e_invarg;
+               goto theend;
+           }
+       }
+       else
+       {
+           if (*p_save == NUL)
+               tab_number = 1;
+           else if (p == p_save || *p_save == '-' || *p != NUL
+                   || tab_number == 0)
+           {
+               /* No numbers as argument. */
+               eap->errmsg = e_invarg;
+               goto theend;
+           }
+           tab_number = tab_number * relative + tabpage_index(curtab);
+           if (!unaccept_arg0 && relative == -1)
+               --tab_number;
+       }
+       if (tab_number < unaccept_arg0 || tab_number > LAST_TAB_NR)
+           eap->errmsg = e_invarg;
+    }
+    else if (eap->addr_count > 0)
+    {
+       if (unaccept_arg0 && eap->line2 == 0)
+       {
+           eap->errmsg = e_invrange;
+           tab_number = 0;
+       }
+       else
+       {
+           tab_number = eap->line2;
+           if (!unaccept_arg0 && **eap->cmdlinep == '-')
+           {
+               --tab_number;
+               if (tab_number < unaccept_arg0)
+                   eap->errmsg = e_invarg;
+           }
+       }
+    }
+    else
+    {
+       switch (eap->cmdidx)
+       {
+       case CMD_tabnext:
+           tab_number = tabpage_index(curtab) + 1;
+           if (tab_number > LAST_TAB_NR)
+               tab_number = 1;
+           break;
+       case CMD_tabmove:
+           tab_number = LAST_TAB_NR;
+           break;
+       default:
+           tab_number = tabpage_index(curtab);
+       }
+    }
+
+theend:
+    return tab_number;
+}
+
+/*
  * ":tabclose": close current tab page, unless it is the last one.
  * ":tabclose N": close tab page N.
  */
@@ -7407,6 +7568,7 @@ ex_win_close(
 ex_tabclose(exarg_T *eap)
 {
     tabpage_T  *tp;
+    int                tab_number;
 
 # ifdef FEAT_CMDWIN
     if (cmdwin_type != 0)
@@ -7417,9 +7579,10 @@ ex_tabclose(exarg_T *eap)
            EMSG(_("E784: Cannot close last tab page"));
        else
        {
-           if (eap->addr_count > 0)
+           tab_number = get_tabpage_arg(eap);
+           if (eap->errmsg == NULL)
            {
-               tp = find_tabpage((int)eap->line2);
+               tp = find_tabpage(tab_number);
                if (tp == NULL)
                {
                    beep_flush();
@@ -7430,13 +7593,13 @@ ex_tabclose(exarg_T *eap)
                    tabpage_close_other(tp, eap->forceit);
                    return;
                }
-           }
-           if (!text_locked()
+               else if (!text_locked()
 #ifdef FEAT_AUTOCMD
-                   && !curbuf_locked()
+                       && !curbuf_locked()
 #endif
-              )
-               tabpage_close(eap->forceit);
+               )
+                   tabpage_close(eap->forceit);
+           }
        }
 }
 
@@ -7448,6 +7611,7 @@ ex_tabonly(exarg_T *eap)
 {
     tabpage_T  *tp;
     int                done;
+    int                tab_number;
 
 # ifdef FEAT_CMDWIN
     if (cmdwin_type != 0)
@@ -7458,24 +7622,27 @@ ex_tabonly(exarg_T *eap)
            MSG(_("Already only one tab page"));
        else
        {
-           if (eap->addr_count > 0)
-               goto_tabpage(eap->line2);
-           /* Repeat this up to a 1000 times, because autocommands may mess
-            * up the lists. */
-           for (done = 0; done < 1000; ++done)
+           tab_number = get_tabpage_arg(eap);
+           if (eap->errmsg == NULL)
            {
-               FOR_ALL_TABPAGES(tp)
-                   if (tp->tp_topframe != topframe)
-                   {
-                       tabpage_close_other(tp, eap->forceit);
-                       /* if we failed to close it quit */
-                       if (valid_tabpage(tp))
-                           done = 1000;
-                       /* start over, "tp" is now invalid */
+               goto_tabpage(tab_number);
+               /* Repeat this up to a 1000 times, because autocommands may
+                * mess up the lists. */
+               for (done = 0; done < 1000; ++done)
+               {
+                   FOR_ALL_TABPAGES(tp)
+                       if (tp->tp_topframe != topframe)
+                       {
+                           tabpage_close_other(tp, eap->forceit);
+                           /* if we failed to close it quit */
+                           if (valid_tabpage(tp))
+                               done = 1000;
+                           /* start over, "tp" is now invalid */
+                           break;
+                       }
+                   if (first_tabpage->tp_next == NULL)
                        break;
-                   }
-               if (first_tabpage->tp_next == NULL)
-                   break;
+               }
            }
        }
 }
@@ -7488,9 +7655,9 @@ tabpage_close(int forceit)
 {
     /* First close all the windows but the current one.  If that worked then
      * close the last window in this tab, that will close it. */
-    if (lastwin != firstwin)
+    if (!ONE_WINDOW)
        close_others(TRUE, forceit);
-    if (lastwin == firstwin)
+    if (ONE_WINDOW)
        ex_win_close(forceit, curwin, NULL);
 # ifdef FEAT_GUI
     need_mouse_correct = TRUE;
@@ -7572,40 +7739,34 @@ ex_all(exarg_T *eap)
 #endif /* FEAT_WINDOWS */
 
     static void
-ex_hide(exarg_T *eap)
+ex_hide(exarg_T *eap UNUSED)
 {
-    if (*eap->arg != NUL && check_nextcmd(eap->arg) == NULL)
-       eap->errmsg = e_invarg;
-    else
-    {
-       /* ":hide" or ":hide | cmd": hide current window */
-       eap->nextcmd = check_nextcmd(eap->arg);
+    /* ":hide" or ":hide | cmd": hide current window */
 #ifdef FEAT_WINDOWS
-       if (!eap->skip)
-       {
+    if (!eap->skip)
+    {
 # ifdef FEAT_GUI
-           need_mouse_correct = TRUE;
+       need_mouse_correct = TRUE;
 # endif
-           if (eap->addr_count == 0)
-               win_close(curwin, FALSE);       /* don't free buffer */
-           else
-           {
-               int     winnr = 0;
-               win_T   *win;
+       if (eap->addr_count == 0)
+           win_close(curwin, FALSE);   /* don't free buffer */
+       else
+       {
+           int winnr = 0;
+           win_T       *win;
 
-               FOR_ALL_WINDOWS(win)
-               {
-                   winnr++;
-                   if (winnr == eap->line2)
-                       break;
-               }
-               if (win == NULL)
-                   win = lastwin;
-               win_close(win, FALSE);
+           FOR_ALL_WINDOWS(win)
+           {
+               winnr++;
+               if (winnr == eap->line2)
+                   break;
            }
+           if (win == NULL)
+               win = lastwin;
+           win_close(win, FALSE);
        }
-#endif
     }
+#endif
 }
 
 /*
@@ -8223,6 +8384,8 @@ tabpage_new(void)
     static void
 ex_tabnext(exarg_T *eap)
 {
+    int tab_number;
+
     switch (eap->cmdidx)
     {
        case CMD_tabfirst:
@@ -8234,10 +8397,40 @@ ex_tabnext(exarg_T *eap)
            break;
        case CMD_tabprevious:
        case CMD_tabNext:
-           goto_tabpage(eap->addr_count == 0 ? -1 : -(int)eap->line2);
+           if (eap->arg && *eap->arg != NUL)
+           {
+               char_u *p = eap->arg;
+               char_u *p_save = p;
+
+               tab_number = getdigits(&p);
+               if (p == p_save || *p_save == '-' || *p != NUL
+                           || tab_number == 0)
+               {
+                   /* No numbers as argument. */
+                   eap->errmsg = e_invarg;
+                   return;
+               }
+           }
+           else
+           {
+               if (eap->addr_count == 0)
+                   tab_number = 1;
+               else
+               {
+                   tab_number = eap->line2;
+                   if (tab_number < 1)
+                   {
+                       eap->errmsg = e_invrange;
+                       return;
+                   }
+               }
+           }
+           goto_tabpage(-tab_number);
            break;
        default: /* CMD_tabnext */
-           goto_tabpage(eap->addr_count == 0 ? 0 : (int)eap->line2);
+           tab_number = get_tabpage_arg(eap);
+           if (eap->errmsg == NULL)
+               goto_tabpage(tab_number);
            break;
     }
 }
@@ -8250,59 +8443,9 @@ ex_tabmove(exarg_T *eap)
 {
     int tab_number;
 
-    if (eap->arg && *eap->arg != NUL)
-    {
-       char_u *p = eap->arg;
-       int    relative = 0; /* argument +N/-N means: move N places to the
-                             * right/left relative to the current position. */
-
-       if (*eap->arg == '-')
-       {
-           relative = -1;
-           p = eap->arg + 1;
-       }
-       else if (*eap->arg == '+')
-       {
-           relative = 1;
-           p = eap->arg + 1;
-       }
-       else
-           p = eap->arg;
-
-       if (relative == 0)
-       {
-           if (STRCMP(p, "$") == 0)
-               tab_number = LAST_TAB_NR;
-           else if (p == skipdigits(p))
-           {
-               /* No numbers as argument. */
-               eap->errmsg = e_invarg;
-               return;
-           }
-           else
-               tab_number = getdigits(&p);
-       }
-       else
-       {
-           if (*p != NUL)
-               tab_number = getdigits(&p);
-           else
-               tab_number = 1;
-           tab_number = tab_number * relative + tabpage_index(curtab);
-           if (relative == -1)
-               --tab_number;
-       }
-    }
-    else if (eap->addr_count != 0)
-    {
-       tab_number = eap->line2;
-       if (**eap->cmdlinep == '-')
-           --tab_number;
-    }
-    else
-       tab_number = LAST_TAB_NR;
-
-    tabpage_move(tab_number);
+    tab_number = get_tabpage_arg(eap);
+    if (eap->errmsg == NULL)
+       tabpage_move(tab_number);
 }
 
 /*
@@ -8321,7 +8464,7 @@ ex_tabs(exarg_T *eap UNUSED)
     {
        msg_putchar('\n');
        vim_snprintf((char *)IObuff, IOSIZE, _("Tab page %d"), tabcount++);
-       msg_outtrans_attr(IObuff, hl_attr(HLF_T));
+       msg_outtrans_attr(IObuff, HL_ATTR(HLF_T));
        out_flush();        /* output one line at a time */
        ui_breakcheck();
 
@@ -8837,7 +8980,7 @@ ex_read(exarg_T *eap)
                          eap->line2, (linenr_T)0, (linenr_T)MAXLNUM, eap, 0);
 
        }
-       if (i == FAIL)
+       if (i != OK)
        {
 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
            if (!aborting())
@@ -9307,7 +9450,7 @@ ex_copymove(exarg_T *eap)
 {
     long       n;
 
-    n = get_address(eap, &eap->arg, eap->addr_type, FALSE, FALSE);
+    n = get_address(eap, &eap->arg, eap->addr_type, FALSE, FALSE, 1);
     if (eap->arg == NULL)          /* error detected */
     {
        eap->nextcmd = NULL;
@@ -9653,6 +9796,7 @@ ex_redraw(exarg_T *eap)
 
     RedrawingDisabled = 0;
     p_lz = FALSE;
+    validate_cursor();
     update_topline();
     update_screen(eap->forceit ? CLEAR : VIsual_active ? INVERTED : 0);
 #ifdef FEAT_TITLE
@@ -10146,6 +10290,7 @@ ex_normal(exarg_T *eap)
            {
                curwin->w_cursor.lnum = eap->line1++;
                curwin->w_cursor.col = 0;
+               check_cursor_moved(curwin);
            }
 
            exec_normal_cmd(
@@ -10429,7 +10574,7 @@ ex_tag_cmd(exarg_T *eap, char_u *name)
 #ifdef FEAT_CSCOPE
                  if (p_cst && *eap->arg != NUL)
                  {
-                     do_cstag(eap);
+                     ex_cstag(eap);
                      return;
                  }
 #endif
@@ -11166,8 +11311,10 @@ makeopens(
         * resized when moving between windows.
         * Do this before restoring the view, so that the topline and the
         * cursor can be set.  This is done again below.
+        * winminheight and winminwidth need to be set to avoid an error if the
+        * user has set winheight or winwidth.
         */
-       if (put_line(fd, "set winheight=1 winwidth=1") == FAIL)
+       if (put_line(fd, "set winminheight=1 winheight=1 winminwidth=1 winwidth=1") == FAIL)
            return FAIL;
        if (nr > 1 && ses_winsizes(fd, restore_size, tab_firstwin) == FAIL)
            return FAIL;
@@ -11237,6 +11384,10 @@ makeopens(
     if (fprintf(fd, "set winheight=%ld winwidth=%ld shortmess=%s",
                               p_wh, p_wiw, p_shm) < 0 || put_eol(fd) == FAIL)
        return FAIL;
+    /* Re-apply 'winminheight' and 'winminwidth'. */
+    if (fprintf(fd, "set winminheight=%ld winminwidth=%ld",
+                                     p_wmh, p_wmw) < 0 || put_eol(fd) == FAIL)
+       return FAIL;
 
     /*
      * Lastly, execute the x.vim file if it exists.
@@ -11632,7 +11783,7 @@ ses_arglist(
                    s = buf;
                }
            }
-           if (fputs("argadd ", fd) < 0
+           if (fputs("$argadd ", fd) < 0
                    || ses_put_fname(fd, s, flagp) == FAIL
                    || put_eol(fd) == FAIL)
            {
@@ -11695,7 +11846,7 @@ ses_put_fname(FILE *fd, char_u *name, unsigned *flagp)
     if (*flagp & SSOP_SLASH)
     {
        /* change all backslashes to forward slashes */
-       for (p = sname; *p != NUL; mb_ptr_adv(p))
+       for (p = sname; *p != NUL; MB_PTR_ADV(p))
            if (*p == '\\')
                *p = '/';
     }
@@ -12098,7 +12249,7 @@ ex_match(exarg_T *eap)
     if (ends_excmd(*eap->arg))
        end = eap->arg;
     else if ((STRNICMP(eap->arg, "none", 4) == 0
-               && (vim_iswhite(eap->arg[4]) || ends_excmd(eap->arg[4]))))
+               && (VIM_ISWHITE(eap->arg[4]) || ends_excmd(eap->arg[4]))))
        end = eap->arg + 4;
     else
     {
index daccfc8..17e0fdb 100644 (file)
@@ -16,7 +16,7 @@
 #if defined(FEAT_EVAL) || defined(PROTO)
 
 static void    free_msglist(struct msglist *l);
-static int     throw_exception(void *, int, char_u *);
+static int     throw_exception(void *, except_type_T, char_u *);
 static char_u  *get_end_emsg(struct condstack *cstack);
 
 /*
@@ -422,7 +422,7 @@ do_intthrow(struct condstack *cstack)
     char_u *
 get_exception_string(
     void       *value,
-    int                type,
+    except_type_T type,
     char_u     *cmdname,
     int                *should_free)
 {
@@ -503,7 +503,7 @@ get_exception_string(
  * error exception.
  */
     static int
-throw_exception(void *value, int type, char_u *cmdname)
+throw_exception(void *value, except_type_T type, char_u *cmdname)
 {
     except_T   *excp;
     int                should_free;
@@ -595,7 +595,7 @@ discard_exception(except_T *excp, int was_finished)
 
     if (excp == NULL)
     {
-       EMSG(_(e_internal));
+       internal_error("discard_exception()");
        return;
     }
 
@@ -700,7 +700,7 @@ catch_exception(except_T *excp)
 finish_exception(except_T *excp)
 {
     if (excp != caught_stack)
-       EMSG(_(e_internal));
+       internal_error("finish_exception()");
     caught_stack = caught_stack->caught;
     if (caught_stack != NULL)
     {
@@ -1603,7 +1603,7 @@ ex_catch(exarg_T *eap)
             * ":break", ":return", ":finish", error, interrupt, or another
             * exception. */
            if (cstack->cs_exception[cstack->cs_idx] != current_exception)
-               EMSG(_(e_internal));
+               internal_error("ex_catch()");
        }
        else
        {
@@ -1737,7 +1737,7 @@ ex_finally(exarg_T *eap)
                 * exception will be discarded. */
                if (did_throw && cstack->cs_exception[cstack->cs_idx]
                                                         != current_exception)
-                   EMSG(_(e_internal));
+                   internal_error("ex_finally()");
            }
 
            /*
index 5d098cc..c42abe9 100644 (file)
@@ -127,7 +127,7 @@ static void clear_hist_entry(histentry_T *hisptr);
 #endif
 
 #ifdef FEAT_CMDWIN
-static int     ex_window(void);
+static int     open_cmdwin(void);
 #endif
 
 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
@@ -234,7 +234,7 @@ getcmdline(
 
     ccline.overstrike = FALSE;             /* always start in insert mode */
 #ifdef FEAT_SEARCH_EXTRA
-    clearpos(&match_end);
+    CLEAR_POS(&match_end);
     save_cursor = curwin->w_cursor;        /* may be restored later */
     search_start = curwin->w_cursor;
     old_curswant = curwin->w_curswant;
@@ -258,6 +258,7 @@ getcmdline(
        return NULL;                        /* out of memory */
     ccline.cmdlen = ccline.cmdpos = 0;
     ccline.cmdbuff[0] = NUL;
+    sb_text_start_cmdline();
 
     /* autoindent for :insert and :append */
     if (firstc <= 0)
@@ -772,7 +773,7 @@ getcmdline(
                /*
                 * Open a window to edit the command line (and history).
                 */
-               c = ex_window();
+               c = open_cmdwin();
                some_key_typed = TRUE;
            }
        }
@@ -1291,7 +1292,7 @@ getcmdline(
                goto cmdline_not_changed;
 
        case K_IGNORE:
-               /* Ignore mouse event or ex_window() result. */
+               /* Ignore mouse event or open_cmdwin() result. */
                goto cmdline_not_changed;
 
 #ifdef FEAT_GUI_W32
@@ -1479,7 +1480,7 @@ getcmdline(
                    if (did_incsearch)
                    {
                        curwin->w_cursor = match_end;
-                       if (!equalpos(curwin->w_cursor, search_start))
+                       if (!EQUAL_POS(curwin->w_cursor, search_start))
                        {
                            c = gchar_cursor();
                            /* If 'ignorecase' and 'smartcase' are set and the
@@ -1707,7 +1708,7 @@ getcmdline(
                            search_start = t;
                            (void)decl(&search_start);
                        }
-                       if (lt(t, search_start) && c == Ctrl_G)
+                       if (LT_POS(t, search_start) && c == Ctrl_G)
                        {
                            /* wrap around */
                            search_start = t;
@@ -1793,6 +1794,10 @@ getcmdline(
                goto cmdline_not_changed;
 #endif
 
+       case K_PS:
+               bracketed_paste(PASTE_CMDLINE, FALSE, NULL);
+               goto cmdline_changed;
+
        default:
 #ifdef UNIX
                if (c == intr_char)
@@ -2003,7 +2008,7 @@ returncmd:
            curwin->w_cursor = save_cursor;
        else
        {
-           if (!equalpos(save_cursor, search_start))
+           if (!EQUAL_POS(save_cursor, search_start))
            {
                /* put the '" mark at the original position */
                curwin->w_cursor = save_cursor;
@@ -2079,6 +2084,7 @@ returncmd:
 #ifdef CURSOR_SHAPE
     ui_cursor_shape();         /* may show different cursor shape */
 #endif
+    sb_text_end_cmdline();
 
     {
        char_u *p = ccline.cmdbuff;
@@ -2365,10 +2371,16 @@ getexmodeline(
        if (ga_grow(&line_ga, 40) == FAIL)
            break;
 
-       /* Get one character at a time.  Don't use inchar(), it can't handle
-        * special characters. */
+       /*
+        * Get one character at a time.
+        */
        prev_char = c1;
-       c1 = vgetc();
+
+       /* Check for a ":normal" command and no more characters left. */
+       if (ex_normal_busy > 0 && typebuf.tb_len == 0)
+           c1 = '\n';
+       else
+           c1 = vgetc();
 
        /*
         * Handle line editing.
@@ -2381,6 +2393,12 @@ getexmodeline(
            break;
        }
 
+       if (c1 == K_PS)
+       {
+           bracketed_paste(PASTE_EX, FALSE, &line_ga);
+           goto redraw;
+       }
+
        if (!escaped)
        {
            /* CR typed means "enter", which is NL */
@@ -4129,7 +4147,7 @@ showmatches(expand_T *xp, int wildmenu UNUSED)
        got_int = FALSE;        /* only int. the completion, not the cmd line */
 #ifdef FEAT_WILDMENU
     else if (wildmenu)
-       win_redr_status_matches(xp, num_files, files_found, 0, showtail);
+       win_redr_status_matches(xp, num_files, files_found, -1, showtail);
 #endif
     else
     {
@@ -4162,14 +4180,14 @@ showmatches(expand_T *xp, int wildmenu UNUSED)
            lines = (num_files + columns - 1) / columns;
        }
 
-       attr = hl_attr(HLF_D);  /* find out highlighting for directories */
+       attr = HL_ATTR(HLF_D);  /* find out highlighting for directories */
 
        if (xp->xp_context == EXPAND_TAGS_LISTFILES)
        {
-           MSG_PUTS_ATTR(_("tagname"), hl_attr(HLF_T));
+           MSG_PUTS_ATTR(_("tagname"), HL_ATTR(HLF_T));
            msg_clr_eos();
            msg_advance(maxlen - 3);
-           MSG_PUTS_ATTR(_(" kind file\n"), hl_attr(HLF_T));
+           MSG_PUTS_ATTR(_(" kind file\n"), HL_ATTR(HLF_T));
        }
 
        /* list the files line by line */
@@ -4180,12 +4198,12 @@ showmatches(expand_T *xp, int wildmenu UNUSED)
            {
                if (xp->xp_context == EXPAND_TAGS_LISTFILES)
                {
-                   msg_outtrans_attr(files_found[k], hl_attr(HLF_D));
+                   msg_outtrans_attr(files_found[k], HL_ATTR(HLF_D));
                    p = files_found[k] + STRLEN(files_found[k]) + 1;
                    msg_advance(maxlen + 1);
                    msg_puts(p);
                    msg_advance(maxlen + 3);
-                   msg_puts_long_attr(p + 2, hl_attr(HLF_D));
+                   msg_puts_long_attr(p + 2, HL_ATTR(HLF_D));
                    break;
                }
                for (j = maxlen - lastlen; --j >= 0; )
@@ -4280,7 +4298,7 @@ sm_gettail(char_u *s)
            t = p;
            had_sep = FALSE;
        }
-       mb_ptr_adv(p);
+       MB_PTR_ADV(p);
     }
     return t;
 }
@@ -4356,7 +4374,9 @@ addstar(
                || context == EXPAND_OWNSYNTAX
                || context == EXPAND_FILETYPE
                || context == EXPAND_PACKADD
-               || (context == EXPAND_TAGS && fname[0] == '/'))
+               || ((context == EXPAND_TAGS_LISTFILES
+                       || context == EXPAND_TAGS)
+                   && fname[0] == '/'))
            retval = vim_strnsave(fname, len);
        else
        {
@@ -5129,8 +5149,8 @@ expand_shellcmd(
 static void * call_user_expand_func(void *(*user_expand_func)(char_u *, int, char_u **, int), expand_T *xp, int *num_file, char_u ***file);
 
 /*
- * Call "user_expand_func()" to invoke a user defined VimL function and return
- * the result (either a string or a List).
+ * Call "user_expand_func()" to invoke a user defined Vim script function and
+ * return the result (either a string or a List).
  */
     static void *
 call_user_expand_func(
@@ -5352,7 +5372,7 @@ ExpandRTDir(
        if (e - 4 > s && STRNICMP(e - 4, ".vim", 4) == 0)
        {
            e -= 4;
-           for (s = e; s > match; mb_ptr_back(match, s))
+           for (s = e; s > match; MB_PTR_BACK(match, s))
                if (s < match || vim_ispathsep(*s))
                    break;
            ++s;
@@ -6009,7 +6029,7 @@ remove_key_from_history(void)
                if (p == NULL)
                    break;
                ++p;
-               for (i = 0; p[i] && !vim_iswhite(p[i]); ++i)
+               for (i = 0; p[i] && !VIM_ISWHITE(p[i]); ++i)
                    if (p[i] == '\\' && p[i + 1])
                        ++i;
                STRMOVE(p, p + i);
@@ -6776,7 +6796,7 @@ cmd_gchar(int offset)
  *     K_IGNORE if editing continues
  */
     static int
-ex_window(void)
+open_cmdwin(void)
 {
     struct cmdline_info        save_ccline;
     bufref_T           old_curbuf;
@@ -6821,6 +6841,7 @@ ex_window(void)
 # endif
     /* don't use a new tab page */
     cmdmod.tab = 0;
+    cmdmod.noswapfile = 1;
 
     /* Create a window for the command-line buffer. */
     if (win_split((int)p_cwh, WSP_BOT) == FAIL)
@@ -6837,7 +6858,6 @@ ex_window(void)
     (void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL);
     (void)setfname(curbuf, (char_u *)"[Command Line]", NULL, TRUE);
     set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL);
-    set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
     curbuf->b_p_ma = TRUE;
 #ifdef FEAT_FOLDING
     curwin->w_p_fen = FALSE;
@@ -6901,9 +6921,7 @@ ex_window(void)
     redraw_later(SOME_VALID);
 
     /* Save the command line info, can be used recursively. */
-    save_ccline = ccline;
-    ccline.cmdbuff = NULL;
-    ccline.cmdprompt = NULL;
+    save_cmdline(&save_ccline);
 
     /* No Ex mode here! */
     exmode_active = 0;
@@ -6950,7 +6968,7 @@ ex_window(void)
 # endif
 
     /* Restore the command line info. */
-    ccline = save_ccline;
+    restore_cmdline(&save_ccline);
     cmdwin_type = 0;
 
     exmode_active = save_exmode;
index 1c5d2fd..ebed47e 100644 (file)
 
 #if defined(FEAT_FKMAP) || defined(PROTO)
 
-static int toF_Xor_X_(int c);
-static int F_is_TyE(int c);
-static int F_is_TyC_TyD(int c);
 static int F_is_TyB_TyC_TyD(int src, int offset);
-static int toF_TyB(int c);
-static void put_curr_and_l_to_X(int c);
-static void put_and_redo(int c);
-static void chg_c_toX_orX(void);
-static void chg_c_to_X_orX_(void);
-static void chg_c_to_X_or_X(void);
-static void chg_l_to_X_orX_(void);
-static void chg_l_toXor_X(void);
-static void chg_r_to_Xor_X_(void);
-static int toF_leading(int c);
-static int toF_Rjoin(int c);
-static int canF_Ljoin(int c);
-static int canF_Rjoin(int c);
-static int F_isterm(int c);
-static int toF_ending(int c);
-static void lrswapbuf(char_u *buf, int len);
 
 /*
  * Convert the given Farsi character into a _X or _X_ type
-*/
+ */
     static int
 toF_Xor_X_(int c)
 {
@@ -105,7 +86,7 @@ toF_Xor_X_(int c)
 
 /*
  * Convert the given Farsi character into Farsi capital character.
-*/
+ */
     static int
 toF_TyA(int c)
 {
@@ -156,7 +137,7 @@ toF_TyA(int c)
  * Is the character under the cursor+offset in the given buffer a join type.
  * That is a character that is combined with the others.
  * Note: the offset is used only for command line buffer.
-*/
+ */
     static int
 F_is_TyB_TyC_TyD(int src, int offset)
 {
@@ -207,7 +188,7 @@ F_is_TyB_TyC_TyD(int src, int offset)
 
 /*
  * Is the Farsi character one of the terminating only type.
-*/
+ */
     static int
 F_is_TyE(int c)
 {
@@ -230,7 +211,7 @@ F_is_TyE(int c)
 
 /*
  * Is the Farsi character one of the none leading type.
-*/
+ */
     static int
 F_is_TyC_TyD(int c)
 {
@@ -254,7 +235,7 @@ F_is_TyC_TyD(int c)
 
 /*
  * Convert a none leading Farsi char into a leading type.
-*/
+ */
     static int
 toF_TyB(int c)
 {
@@ -275,9 +256,18 @@ toF_TyB(int c)
     return c;
 }
 
+
+    static void
+put_and_redo(int c)
+{
+    pchar_cursor(c);
+    AppendCharToRedobuff(K_BS);
+    AppendCharToRedobuff(c);
+}
+
 /*
  * Overwrite the current redo and cursor characters + left adjust.
-*/
+ */
     static void
 put_curr_and_l_to_X(int c)
 {
@@ -312,17 +302,9 @@ put_curr_and_l_to_X(int c)
     put_and_redo(c);
 }
 
-    static void
-put_and_redo(int c)
-{
-    pchar_cursor(c);
-    AppendCharToRedobuff(K_BS);
-    AppendCharToRedobuff(c);
-}
-
 /*
  * Change the char. under the cursor to a X_ or X type
-*/
+ */
     static void
 chg_c_toX_orX(void)
 {
@@ -446,8 +428,7 @@ chg_c_toX_orX(void)
 
 /*
  * Change the char. under the cursor to a _X_ or X_ type
-*/
-
+ */
     static void
 chg_c_to_X_orX_(void)
 {
@@ -498,9 +479,9 @@ chg_c_to_X_orX_(void)
 
 /*
  * Change the char. under the cursor to a _X_ or _X type
-*/
+ */
     static void
-chg_c_to_X_or_X (void)
+chg_c_to_X_or_X(void)
 {
     int        tempc;
 
@@ -529,7 +510,7 @@ chg_c_to_X_or_X (void)
 
 /*
  * Change the character left to the cursor to a _X_ or X_ type
-*/
+ */
     static void
 chg_l_to_X_orX_(void)
 {
@@ -597,10 +578,9 @@ chg_l_to_X_orX_(void)
 
 /*
  * Change the character left to the cursor to a X or _X type
-*/
-
+ */
     static void
-chg_l_toXor_X (void)
+chg_l_toXor_X(void)
 {
     int        tempc;
 
@@ -666,8 +646,7 @@ chg_l_toXor_X (void)
 
 /*
  * Change the character right to the cursor to a _X or _X_ type
-*/
-
+ */
     static void
 chg_r_to_Xor_X_(void)
 {
@@ -691,48 +670,50 @@ chg_r_to_Xor_X_(void)
 
 /*
  * Map Farsi keyboard when in fkmap mode.
-*/
-
+ */
     int
 fkmap(int c)
 {
     int                tempc;
-    static int revins;
+    int                insert_mode = (State & INSERT);
+    static int revins = 0;
 
     if (IS_SPECIAL(c))
        return c;
 
-    if (VIM_ISDIGIT(c) || ((c == '.' || c == '+' || c == '-' ||
-       c == '^' || c == '%' || c == '#' || c == '=')  && revins))
+    if (insert_mode)
     {
-       if (!revins)
+       if (VIM_ISDIGIT(c) || ((c == '.' || c == '+' || c == '-' ||
+           c == '^' || c == '%' || c == '#' || c == '=') && revins))
        {
-           if (curwin->w_cursor.col)
+           /* Numbers are entered left-to-right. */
+           if (!revins)
            {
-               if (!p_ri)
-                   dec_cursor();
+               if (curwin->w_cursor.col)
+               {
+                   if (!p_ri)
+                       dec_cursor();
 
-               chg_c_toX_orX ();
-               chg_l_toXor_X ();
+                   chg_c_toX_orX ();
+                   chg_l_toXor_X ();
 
-               if (!p_ri)
-                   inc_cursor();
+                   if (!p_ri)
+                       inc_cursor();
+               }
            }
-       }
 
-       arrow_used = TRUE;
-       (void)stop_arrow();
+           arrow_used = TRUE;
+           (void)stop_arrow();
 
-       if (!curwin->w_p_rl && revins)
-           inc_cursor();
+           if (!curwin->w_p_rl && revins)
+               inc_cursor();
 
-       ++revins;
-       p_ri=1;
-    }
-    else
-    {
-       if (revins)
+           ++revins;
+           p_ri = 1;
+       }
+       else if (revins)
        {
+           /* Stop entering number. */
            arrow_used = TRUE;
            (void)stop_arrow();
 
@@ -773,14 +754,14 @@ fkmap(int c)
     if (!revins)
     {
        if (curwin->w_p_rl)
-           p_ri=0;
+           p_ri = 0;
        if (!curwin->w_p_rl)
-           p_ri=1;
+           p_ri = 1;
     }
 
-    if ((c < 0x100) && (isalpha(c) || c == '&' ||   c == '^' ||        c == ';' ||
+    if ((c < 0x100) && (isalpha(c) || c == '&' || c == '^' ||  c == ';' ||
                            c == '\''|| c == ',' || c == '[' ||
-                           c == ']' || c == '{' || c == '}'    ))
+                           c == ']' || c == '{' || c == '}'))
        chg_r_to_Xor_X_();
 
     tempc = 0;
@@ -844,13 +825,12 @@ fkmap(int c)
        case  NL:
        case  TAB:
 
-           if (p_ri && c == NL && curwin->w_cursor.col)
+           if (p_ri && c == NL && curwin->w_cursor.col && insert_mode)
            {
                /*
                 * If the char before the cursor is _X_ or X_ do not change
                 * the one under the cursor with X type.
-               */
-
+                */
                dec_cursor();
 
                if (F_isalpha(gchar_cursor()))
@@ -920,215 +900,219 @@ fkmap(int c)
                }
                break;
            }
-           if (!p_ri)
-               dec_cursor();
 
-           switch ((tempc = gchar_cursor()))
+           if (insert_mode)
            {
-               case _BE:
-               case _PE:
-               case _TE:
-               case _SE:
-               case _JIM:
-               case _CHE:
-               case _HE_J:
-               case _XE:
-               case _SIN:
-               case _SHIN:
-               case _SAD:
-               case _ZAD:
-               case _FE:
-               case _GHAF:
-               case _KAF:
-               case _KAF_H:
-               case _GAF:
-               case _LAM:
-               case _MIM:
-               case _NOON:
-               case _HE:
-               case _HE_:
-               case _TA:
-               case _ZA:
-                       put_curr_and_l_to_X(toF_TyA(tempc));
-                       break;
-               case _AYN:
-               case _AYN_:
-
-                       if (!p_ri)
-                           if (!curwin->w_cursor.col)
-                           {
-                               put_curr_and_l_to_X(AYN);
-                               break;
-                           }
-
-                       if (p_ri)
-                           inc_cursor();
-                       else
-                           dec_cursor();
-
-                       if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
-                           tempc = AYN_;
-                       else
-                           tempc = AYN;
-
-                       if (p_ri)
-                           dec_cursor();
-                       else
-                           inc_cursor();
-
-                       put_curr_and_l_to_X(tempc);
-
-                       break;
-               case _GHAYN:
-               case _GHAYN_:
-
-                       if (!p_ri)
-                           if (!curwin->w_cursor.col)
-                           {
-                               put_curr_and_l_to_X(GHAYN);
-                               break;
-                           }
-
-                       if (p_ri)
-                           inc_cursor();
-                       else
-                           dec_cursor();
-
-                       if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
-                           tempc = GHAYN_;
-                       else
-                           tempc = GHAYN;
-
-                       if (p_ri)
-                           dec_cursor();
-                       else
-                           inc_cursor();
-
-                       put_curr_and_l_to_X(tempc);
-                       break;
-               case _YE:
-               case _IE:
-               case _YEE:
-                       if (!p_ri)
-                           if (!curwin->w_cursor.col)
-                           {
-                               put_curr_and_l_to_X((tempc == _YE ? YE :
-                                           (tempc == _IE ? IE : YEE)));
-                               break;
-                           }
-
-                       if (p_ri)
-                           inc_cursor();
-                       else
-                           dec_cursor();
-
-                       if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
-                               tempc = (tempc == _YE ? YE_ :
-                                   (tempc == _IE ? IE_ : YEE_));
-                       else
-                               tempc = (tempc == _YE ? YE :
-                                   (tempc == _IE ? IE : YEE));
-
-                       if (p_ri)
-                           dec_cursor();
-                       else
-                           inc_cursor();
+               if (!p_ri)
+                   dec_cursor();
 
-                       put_curr_and_l_to_X(tempc);
-                       break;
+               switch ((tempc = gchar_cursor()))
+               {
+                   case _BE:
+                   case _PE:
+                   case _TE:
+                   case _SE:
+                   case _JIM:
+                   case _CHE:
+                   case _HE_J:
+                   case _XE:
+                   case _SIN:
+                   case _SHIN:
+                   case _SAD:
+                   case _ZAD:
+                   case _FE:
+                   case _GHAF:
+                   case _KAF:
+                   case _KAF_H:
+                   case _GAF:
+                   case _LAM:
+                   case _MIM:
+                   case _NOON:
+                   case _HE:
+                   case _HE_:
+                   case _TA:
+                   case _ZA:
+                           put_curr_and_l_to_X(toF_TyA(tempc));
+                           break;
+                   case _AYN:
+                   case _AYN_:
+
+                           if (!p_ri)
+                               if (!curwin->w_cursor.col)
+                               {
+                                   put_curr_and_l_to_X(AYN);
+                                   break;
+                               }
+
+                           if (p_ri)
+                               inc_cursor();
+                           else
+                               dec_cursor();
+
+                           if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+                               tempc = AYN_;
+                           else
+                               tempc = AYN;
+
+                           if (p_ri)
+                               dec_cursor();
+                           else
+                               inc_cursor();
+
+                           put_curr_and_l_to_X(tempc);
+
+                           break;
+                   case _GHAYN:
+                   case _GHAYN_:
+
+                           if (!p_ri)
+                               if (!curwin->w_cursor.col)
+                               {
+                                   put_curr_and_l_to_X(GHAYN);
+                                   break;
+                               }
+
+                           if (p_ri)
+                               inc_cursor();
+                           else
+                               dec_cursor();
+
+                           if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+                               tempc = GHAYN_;
+                           else
+                               tempc = GHAYN;
+
+                           if (p_ri)
+                               dec_cursor();
+                           else
+                               inc_cursor();
+
+                           put_curr_and_l_to_X(tempc);
+                           break;
+                   case _YE:
+                   case _IE:
+                   case _YEE:
+                           if (!p_ri)
+                               if (!curwin->w_cursor.col)
+                               {
+                                   put_curr_and_l_to_X((tempc == _YE ? YE :
+                                               (tempc == _IE ? IE : YEE)));
+                                   break;
+                               }
+
+                           if (p_ri)
+                               inc_cursor();
+                           else
+                               dec_cursor();
+
+                           if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+                                   tempc = (tempc == _YE ? YE_ :
+                                       (tempc == _IE ? IE_ : YEE_));
+                           else
+                                   tempc = (tempc == _YE ? YE :
+                                       (tempc == _IE ? IE : YEE));
+
+                           if (p_ri)
+                               dec_cursor();
+                           else
+                               inc_cursor();
+
+                           put_curr_and_l_to_X(tempc);
+                           break;
                }
 
                if (!p_ri)
                    inc_cursor();
+           }
 
-               tempc = 0;
+           tempc = 0;
 
-               switch (c)
-               {
-                   case '0':   return FARSI_0;
-                   case '1':   return FARSI_1;
-                   case '2':   return FARSI_2;
-                   case '3':   return FARSI_3;
-                   case '4':   return FARSI_4;
-                   case '5':   return FARSI_5;
-                   case '6':   return FARSI_6;
-                   case '7':   return FARSI_7;
-                   case '8':   return FARSI_8;
-                   case '9':   return FARSI_9;
-                   case 'B':   return F_PSP;
-                   case 'E':   return JAZR_N;
-                   case 'F':   return ALEF_D_H;
-                   case 'H':   return ALEF_A;
-                   case 'I':   return TASH;
-                   case 'K':   return F_LQUOT;
-                   case 'L':   return F_RQUOT;
-                   case 'M':   return HAMZE;
-                   case 'O':   return '[';
-                   case 'P':   return ']';
-                   case 'Q':   return OO;
-                   case 'R':   return MAD_N;
-                   case 'T':   return OW;
-                   case 'U':   return MAD;
-                   case 'W':   return OW_OW;
-                   case 'Y':   return JAZR;
-                   case '`':   return F_PCN;
-                   case '!':   return F_EXCL;
-                   case '@':   return F_COMMA;
-                   case '#':   return F_DIVIDE;
-                   case '$':   return F_CURRENCY;
-                   case '%':   return F_PERCENT;
-                   case '^':   return F_MUL;
-                   case '&':   return F_BCOMMA;
-                   case '*':   return F_STAR;
-                   case '(':   return F_LPARENT;
-                   case ')':   return F_RPARENT;
-                   case '-':   return F_MINUS;
-                   case '_':   return F_UNDERLINE;
-                   case '=':   return F_EQUALS;
-                   case '+':   return F_PLUS;
-                   case '\\':  return F_BSLASH;
-                   case '|':   return F_PIPE;
-                   case ':':   return F_DCOLON;
-                   case '"':   return F_SEMICOLON;
-                   case '.':   return F_PERIOD;
-                   case '/':   return F_SLASH;
-                   case '<':   return F_LESS;
-                   case '>':   return F_GREATER;
-                   case '?':   return F_QUESTION;
-                   case ' ':   return F_BLANK;
-               }
-               break;
+           switch (c)
+           {
+               case '0':       return FARSI_0;
+               case '1':       return FARSI_1;
+               case '2':       return FARSI_2;
+               case '3':       return FARSI_3;
+               case '4':       return FARSI_4;
+               case '5':       return FARSI_5;
+               case '6':       return FARSI_6;
+               case '7':       return FARSI_7;
+               case '8':       return FARSI_8;
+               case '9':       return FARSI_9;
+               case 'B':       return F_PSP;
+               case 'E':       return JAZR_N;
+               case 'F':       return ALEF_D_H;
+               case 'H':       return ALEF_A;
+               case 'I':       return TASH;
+               case 'K':       return F_LQUOT;
+               case 'L':       return F_RQUOT;
+               case 'M':       return HAMZE;
+               case 'O':       return '[';
+               case 'P':       return ']';
+               case 'Q':       return OO;
+               case 'R':       return MAD_N;
+               case 'T':       return OW;
+               case 'U':       return MAD;
+               case 'W':       return OW_OW;
+               case 'Y':       return JAZR;
+               case '`':       return F_PCN;
+               case '!':       return F_EXCL;
+               case '@':       return F_COMMA;
+               case '#':       return F_DIVIDE;
+               case '$':       return F_CURRENCY;
+               case '%':       return F_PERCENT;
+               case '^':       return F_MUL;
+               case '&':       return F_BCOMMA;
+               case '*':       return F_STAR;
+               case '(':       return F_LPARENT;
+               case ')':       return F_RPARENT;
+               case '-':       return F_MINUS;
+               case '_':       return F_UNDERLINE;
+               case '=':       return F_EQUALS;
+               case '+':       return F_PLUS;
+               case '\\':      return F_BSLASH;
+               case '|':       return F_PIPE;
+               case ':':       return F_DCOLON;
+               case '"':       return F_SEMICOLON;
+               case '.':       return F_PERIOD;
+               case '/':       return F_SLASH;
+               case '<':       return F_LESS;
+               case '>':       return F_GREATER;
+               case '?':       return F_QUESTION;
+               case ' ':       return F_BLANK;
+           }
+           break;
 
        case 'a':
-               tempc = _SHIN;
-               break;
+           tempc = _SHIN;
+           break;
        case 'A':
-               tempc = WAW_H;
-               break;
+           tempc = WAW_H;
+           break;
        case 'b':
-               tempc = ZAL;
-               break;
+           tempc = ZAL;
+           break;
        case 'c':
-               tempc = ZE;
-               break;
+           tempc = ZE;
+           break;
        case 'C':
-               tempc = JE;
-               break;
+           tempc = JE;
+           break;
        case 'd':
-               tempc = _YE;
-               break;
+           tempc = _YE;
+           break;
        case 'D':
-               tempc = _YEE;
-               break;
+           tempc = _YEE;
+           break;
        case 'e':
-               tempc = _SE;
-               break;
+           tempc = _SE;
+           break;
        case 'f':
-               tempc = _BE;
-               break;
+           tempc = _BE;
+           break;
        case 'g':
-               tempc = _LAM;
-               break;
+           tempc = _LAM;
+           break;
        case 'G':
            if (!curwin->w_cursor.col  &&  STRLEN(ml_get_curline()))
            {
@@ -1230,7 +1214,7 @@ fkmap(int c)
                inc_cursor();
            break;
        case 'j':
-               tempc = _TE;
+           tempc = _TE;
            break;
        case 'J':
            if (!curwin->w_cursor.col  &&  STRLEN(ml_get_curline()))
@@ -1260,73 +1244,73 @@ fkmap(int c)
 
            return tempc;
        case 'k':
-               tempc = _NOON;
+           tempc = _NOON;
            break;
        case 'l':
-               tempc = _MIM;
+           tempc = _MIM;
            break;
        case 'm':
-               tempc = _PE;
+           tempc = _PE;
            break;
        case 'n':
        case 'N':
-               tempc = DAL;
+           tempc = DAL;
            break;
        case 'o':
-               tempc = _XE;
+           tempc = _XE;
            break;
        case 'p':
-               tempc = _HE_J;
+           tempc = _HE_J;
            break;
        case 'q':
-               tempc = _ZAD;
+           tempc = _ZAD;
            break;
        case 'r':
-               tempc = _GHAF;
+           tempc = _GHAF;
            break;
        case 's':
-               tempc = _SIN;
+           tempc = _SIN;
            break;
        case 'S':
-               tempc = _IE;
+           tempc = _IE;
            break;
        case 't':
-               tempc = _FE;
+           tempc = _FE;
            break;
        case 'u':
-               if (!curwin->w_cursor.col  &&  STRLEN(ml_get_curline()))
-               {
-                   if (!p_ri && !F_is_TyE(tempc))
-                       chg_c_to_X_orX_ ();
-                   if (p_ri)
-                       chg_c_to_X_or_X ();
+           if (!curwin->w_cursor.col  &&  STRLEN(ml_get_curline()))
+           {
+               if (!p_ri && !F_is_TyE(tempc))
+                   chg_c_to_X_orX_ ();
+               if (p_ri)
+                   chg_c_to_X_or_X ();
 
-               }
+           }
 
-               if (!p_ri && !curwin->w_cursor.col)
-                   return _AYN;
+           if (!p_ri && !curwin->w_cursor.col)
+               return _AYN;
 
-               if (!p_ri)
-                   dec_cursor();
+           if (!p_ri)
+               dec_cursor();
 
-               if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
-                   tempc = _AYN_;
-               else
-                   tempc = _AYN;
+           if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+               tempc = _AYN_;
+           else
+               tempc = _AYN;
 
-               if (!p_ri)
-                   inc_cursor();
+           if (!p_ri)
+               inc_cursor();
            break;
        case 'v':
        case 'V':
-               tempc = RE;
+           tempc = RE;
            break;
        case 'w':
-               tempc = _SAD;
+           tempc = _SAD;
            break;
        case 'x':
        case 'X':
-               tempc = _TA;
+           tempc = _TA;
            break;
        case 'y':
            if (!curwin->w_cursor.col  &&  STRLEN(ml_get_curline()))
@@ -1354,36 +1338,36 @@ fkmap(int c)
 
            break;
        case 'z':
-               tempc = _ZA;
+           tempc = _ZA;
            break;
        case 'Z':
-               tempc = _KAF_H;
+           tempc = _KAF_H;
            break;
        case ';':
-               tempc = _KAF;
+           tempc = _KAF;
            break;
        case '\'':
-               tempc = _GAF;
+           tempc = _GAF;
            break;
        case ',':
-               tempc = WAW;
+           tempc = WAW;
            break;
        case '[':
-               tempc = _JIM;
+           tempc = _JIM;
            break;
        case ']':
-               tempc = _CHE;
+           tempc = _CHE;
            break;
     }
 
-    if ((F_isalpha(tempc) || F_isdigit(tempc)))
+    if (F_isalpha(tempc) || F_isdigit(tempc))
     {
-       if (!curwin->w_cursor.col  &&  STRLEN(ml_get_curline()))
+       if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
        {
            if (!p_ri && !F_is_TyE(tempc))
-               chg_c_to_X_orX_ ();
+               chg_c_to_X_orX_();
            if (p_ri)
-               chg_c_to_X_or_X ();
+               chg_c_to_X_or_X();
        }
 
        if (curwin->w_cursor.col)
@@ -1392,9 +1376,9 @@ fkmap(int c)
                dec_cursor();
 
            if (F_is_TyE(tempc))
-               chg_l_toXor_X ();
+               chg_l_toXor_X();
            else
-               chg_l_to_X_orX_ ();
+               chg_l_to_X_orX_();
 
            if (!p_ri)
                inc_cursor();
@@ -1407,7 +1391,7 @@ fkmap(int c)
 
 /*
  * Convert a none leading Farsi char into a leading type.
-*/
+ */
     static int
 toF_leading(int c)
 {
@@ -1461,7 +1445,7 @@ toF_leading(int c)
 
 /*
  * Convert a given Farsi char into right joining type.
-*/
+ */
     static int
 toF_Rjoin(int c)
 {
@@ -1517,7 +1501,7 @@ toF_Rjoin(int c)
 
 /*
  * Can a given Farsi character join via its left edj.
-*/
+ */
     static int
 canF_Ljoin(int c)
 {
@@ -1591,7 +1575,7 @@ canF_Ljoin(int c)
 
 /*
  * Can a given Farsi character join via its right edj.
-*/
+ */
     static int
 canF_Rjoin(int c)
 {
@@ -1619,7 +1603,7 @@ canF_Rjoin(int c)
 
 /*
  * is a given Farsi character a terminating type.
-*/
+ */
     static int
 F_isterm(int c)
 {
@@ -1646,7 +1630,7 @@ F_isterm(int c)
 
 /*
  * Convert the given Farsi character into a ending type .
-*/
+ */
     static int
 toF_ending(int c)
 {
@@ -1691,7 +1675,7 @@ toF_ending(int c)
 
 /*
  * Convert the Farsi 3342 standard into Farsi VIM.
-*/
+ */
     static void
 conv_to_pvim(void)
 {
@@ -1711,7 +1695,7 @@ conv_to_pvim(void)
                ptr[i] = toF_leading(ptr[i]);
                ++i;
 
-               while (canF_Rjoin(ptr[i]) && i < llen)
+               while (i < llen && canF_Rjoin(ptr[i]))
                {
                    ptr[i] = toF_Rjoin(ptr[i]);
                    if (F_isterm(ptr[i]) || !F_isalpha(ptr[i]))
@@ -1735,7 +1719,7 @@ conv_to_pvim(void)
 
     /* Assume the screen has been messed up: clear it and redraw. */
     redraw_later(CLEAR);
-    MSG_ATTR(farsi_text_1, hl_attr(HLF_S));
+    MSG_ATTR(farsi_text_1, HL_ATTR(HLF_S));
 }
 
 /*
@@ -1763,7 +1747,7 @@ conv_to_pstd(void)
 
     /* Assume the screen has been messed up: clear it and redraw. */
     redraw_later(CLEAR);
-    MSG_ATTR(farsi_text_2, hl_attr(HLF_S));
+    MSG_ATTR(farsi_text_2, HL_ATTR(HLF_S));
 }
 
 /*
@@ -1936,56 +1920,56 @@ cmdl_fkmap(int c)
        case  NL:
        case  TAB:
 
-              switch ((tempc = cmd_gchar(AT_CURSOR)))
-              {
-           case _BE:
-           case _PE:
-           case _TE:
-           case _SE:
-           case _JIM:
-           case _CHE:
-           case _HE_J:
-           case _XE:
-           case _SIN:
-           case _SHIN:
-           case _SAD:
-           case _ZAD:
-           case _AYN:
-           case _GHAYN:
-           case _FE:
-           case _GHAF:
-           case _KAF:
-           case _GAF:
-           case _LAM:
-           case _MIM:
-           case _NOON:
-           case _HE:
-           case _HE_:
-                       cmd_pchar(toF_TyA(tempc), AT_CURSOR);
-               break;
-           case _AYN_:
-                       cmd_pchar(AYN_, AT_CURSOR);
-               break;
-           case _GHAYN_:
-                       cmd_pchar(GHAYN_, AT_CURSOR);
-               break;
-           case _IE:
-               if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
-                           cmd_pchar(IE_, AT_CURSOR);
-               else
-                           cmd_pchar(IE, AT_CURSOR);
-               break;
-           case _YEE:
-               if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
-                           cmd_pchar(YEE_, AT_CURSOR);
-                       else
-                           cmd_pchar(YEE, AT_CURSOR);
-               break;
-           case _YE:
-               if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
-                           cmd_pchar(YE_, AT_CURSOR);
-                       else
-                           cmd_pchar(YE, AT_CURSOR);
+           switch ((tempc = cmd_gchar(AT_CURSOR)))
+           {
+               case _BE:
+               case _PE:
+               case _TE:
+               case _SE:
+               case _JIM:
+               case _CHE:
+               case _HE_J:
+               case _XE:
+               case _SIN:
+               case _SHIN:
+               case _SAD:
+               case _ZAD:
+               case _AYN:
+               case _GHAYN:
+               case _FE:
+               case _GHAF:
+               case _KAF:
+               case _GAF:
+               case _LAM:
+               case _MIM:
+               case _NOON:
+               case _HE:
+               case _HE_:
+                   cmd_pchar(toF_TyA(tempc), AT_CURSOR);
+                   break;
+               case _AYN_:
+                   cmd_pchar(AYN_, AT_CURSOR);
+                   break;
+               case _GHAYN_:
+                   cmd_pchar(GHAYN_, AT_CURSOR);
+                   break;
+               case _IE:
+                   if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
+                       cmd_pchar(IE_, AT_CURSOR);
+                   else
+                       cmd_pchar(IE, AT_CURSOR);
+                   break;
+               case _YEE:
+                   if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
+                       cmd_pchar(YEE_, AT_CURSOR);
+                   else
+                       cmd_pchar(YEE, AT_CURSOR);
+                   break;
+               case _YE:
+                   if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
+                       cmd_pchar(YE_, AT_CURSOR);
+                   else
+                       cmd_pchar(YE, AT_CURSOR);
            }
 
            switch (c)
index bcb8fef..b41df3e 100644 (file)
@@ -210,7 +210,7 @@ filemess(
  * READ_KEEP_UNDO  don't clear undo info or read it from a file
  * READ_FIFO   read from fifo/socket instead of a file
  *
- * return FAIL for failure, OK otherwise
+ * return FAIL for failure, NOTDONE for directory (failure), or OK
  */
     int
 readfile(
@@ -274,9 +274,9 @@ readfile(
     int                msg_save = msg_scroll;
     linenr_T   read_no_eol_lnum = 0;   /* non-zero lnum when last line of
                                         * last read was missing the eol */
-    int                try_mac = (vim_strchr(p_ffs, 'm') != NULL);
-    int                try_dos = (vim_strchr(p_ffs, 'd') != NULL);
-    int                try_unix = (vim_strchr(p_ffs, 'x') != NULL);
+    int                try_mac;
+    int                try_dos;
+    int                try_unix;
     int                file_rewind = FALSE;
 #ifdef FEAT_MBYTE
     int                can_retry;
@@ -450,13 +450,18 @@ readfile(
 # endif
                                                )
        {
+           int retval = FAIL;
+
            if (S_ISDIR(perm))
+           {
                filemess(curbuf, fname, (char_u *)_("is a directory"), 0);
+               retval = NOTDONE;
+           }
            else
                filemess(curbuf, fname, (char_u *)_("is not a file"), 0);
            msg_end();
            msg_scroll = msg_save;
-           return FAIL;
+           return retval;
        }
 #endif
 #if defined(MSWIN)
@@ -733,6 +738,10 @@ readfile(
     curbuf->b_op_start.lnum = ((from == 0) ? 1 : from);
     curbuf->b_op_start.col = 0;
 
+    try_mac = (vim_strchr(p_ffs, 'm') != NULL);
+    try_dos = (vim_strchr(p_ffs, 'd') != NULL);
+    try_unix = (vim_strchr(p_ffs, 'x') != NULL);
+
 #ifdef FEAT_AUTOCMD
     if (!read_buffer)
     {
@@ -764,6 +773,11 @@ readfile(
        else
            apply_autocmds_exarg(EVENT_FILEREADPRE, sfname, sfname,
                                                            FALSE, NULL, eap);
+       /* autocommands may have changed it */
+       try_mac = (vim_strchr(p_ffs, 'm') != NULL);
+       try_dos = (vim_strchr(p_ffs, 'd') != NULL);
+       try_unix = (vim_strchr(p_ffs, 'x') != NULL);
+
        if (msg_scrolled == n)
            msg_scroll = m;
 
@@ -2237,8 +2251,9 @@ rewind_retry:
                        len = (colnr_T)(ptr - line_start + 1);
                        if (fileformat == EOL_DOS)
                        {
-                           if (ptr[-1] == CAR) /* remove CR */
+                           if (ptr > line_start && ptr[-1] == CAR)
                            {
+                               /* remove CR before NL */
                                ptr[-1] = NUL;
                                --len;
                            }
@@ -4909,11 +4924,11 @@ restore_backup:
     {
        unchanged(buf, TRUE);
 #ifdef FEAT_AUTOCMD
-       /* buf->b_changedtick is always incremented in unchanged() but that
+       /* b:changedtick is always incremented in unchanged() but that
         * should not trigger a TextChanged event. */
-       if (last_changedtick + 1 == buf->b_changedtick
+       if (last_changedtick + 1 == CHANGEDTICK(buf)
                                               && last_changedtick_buf == buf)
-           last_changedtick = buf->b_changedtick;
+           last_changedtick = CHANGEDTICK(buf);
 #endif
        u_unchanged(buf);
        u_update_save_nr(buf);
@@ -5029,7 +5044,7 @@ nofail:
     {
        int numlen = errnum != NULL ? (int)STRLEN(errnum) : 0;
 
-       attr = hl_attr(HLF_E);  /* set highlight for error messages */
+       attr = HL_ATTR(HLF_E);  /* set highlight for error messages */
        msg_add_fname(buf,
 #ifndef UNIX
                sfname
@@ -5285,7 +5300,7 @@ check_mtime(buf_T *buf, stat_T *st)
        msg_silent = 0;             /* must give this prompt */
        /* don't use emsg() here, don't want to flush the buffers */
        MSG_ATTR(_("WARNING: The file has been changed since reading it!!!"),
-                                                      hl_attr(HLF_E));
+                                                      HL_ATTR(HLF_E));
        if (ask_yesno((char_u *)_("Do you really want to write to it"),
                                                                 TRUE) == 'n')
            return FAIL;
@@ -6232,7 +6247,7 @@ buf_modname(
      * Then truncate what is after the '/', '\' or ':' to 8 characters for
      * MSDOS and 26 characters for AMIGA, a lot more for UNIX.
      */
-    for (ptr = retval + fnamelen; ptr > retval; mb_ptr_back(retval, ptr))
+    for (ptr = retval + fnamelen; ptr > retval; MB_PTR_BACK(retval, ptr))
     {
        if (*ext == '.'
 #ifdef USE_LONG_FNAME
@@ -6996,10 +7011,10 @@ buf_check_timestamp(
 # endif
                {
                    msg_start();
-                   msg_puts_attr(tbuf, hl_attr(HLF_E) + MSG_HIST);
+                   msg_puts_attr(tbuf, HL_ATTR(HLF_E) + MSG_HIST);
                    if (*mesg2 != NUL)
                        msg_puts_attr((char_u *)mesg2,
-                                                  hl_attr(HLF_W) + MSG_HIST);
+                                                  HL_ATTR(HLF_W) + MSG_HIST);
                    msg_clr_eos();
                    (void)msg_end();
                    if (emsg_silent == 0)
@@ -7103,7 +7118,7 @@ buf_reload(buf_T *buf, int orig_mode)
         * the old contents.  Can't use memory only, the file might be
         * too big.  Use a hidden buffer to move the buffer contents to.
         */
-       if (bufempty() || saved == FAIL)
+       if (BUFEMPTY() || saved == FAIL)
            savebuf = NULL;
        else
        {
@@ -7136,7 +7151,7 @@ buf_reload(buf_T *buf, int orig_mode)
 #endif
            if (readfile(buf->b_ffname, buf->b_fname, (linenr_T)0,
                        (linenr_T)0,
-                       (linenr_T)MAXLNUM, &ea, flags) == FAIL)
+                       (linenr_T)MAXLNUM, &ea, flags) != OK)
            {
 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
                if (!aborting())
@@ -7146,7 +7161,7 @@ buf_reload(buf_T *buf, int orig_mode)
                {
                    /* Put the text back from the save buffer.  First
                     * delete any lines that readfile() added. */
-                   while (!bufempty())
+                   while (!BUFEMPTY())
                        if (ml_delete(buf->b_ml.ml_line_count, FALSE) == FAIL)
                            break;
                    (void)move_lines(savebuf, buf);
@@ -7825,12 +7840,12 @@ show_autocmd(AutoPat *ap, event_T event)
        if (ap->group != AUGROUP_DEFAULT)
        {
            if (AUGROUP_NAME(ap->group) == NULL)
-               msg_puts_attr(get_deleted_augroup(), hl_attr(HLF_E));
+               msg_puts_attr(get_deleted_augroup(), HL_ATTR(HLF_E));
            else
-               msg_puts_attr(AUGROUP_NAME(ap->group), hl_attr(HLF_T));
+               msg_puts_attr(AUGROUP_NAME(ap->group), HL_ATTR(HLF_T));
            msg_puts((char_u *)"  ");
        }
-       msg_puts_attr(event_nr2name(event), hl_attr(HLF_T));
+       msg_puts_attr(event_nr2name(event), HL_ATTR(HLF_T));
        last_event = event;
        last_group = ap->group;
        msg_putchar('\n');
@@ -8148,7 +8163,7 @@ event_name2nr(char_u *start, char_u **end)
     int                len;
 
     /* the event name ends with end of line, '|', a blank or a comma */
-    for (p = start; *p && !vim_iswhite(*p) && *p != ',' && *p != '|'; ++p)
+    for (p = start; *p && !VIM_ISWHITE(*p) && *p != ',' && *p != '|'; ++p)
        ;
     for (i = 0; event_names[i].name != NULL; ++i)
     {
@@ -8191,7 +8206,7 @@ find_end_event(
 
     if (*arg == '*')
     {
-       if (arg[1] && !vim_iswhite(arg[1]))
+       if (arg[1] && !VIM_ISWHITE(arg[1]))
        {
            EMSG2(_("E215: Illegal character after *: %s"), arg);
            return NULL;
@@ -8200,7 +8215,7 @@ find_end_event(
     }
     else
     {
-       for (pat = arg; *pat && *pat != '|' && !vim_iswhite(*pat); pat = p)
+       for (pat = arg; *pat && *pat != '|' && !VIM_ISWHITE(*pat); pat = p)
        {
            if ((int)event_name2nr(pat, &p) >= (int)NUM_EVENTS)
            {
@@ -8379,7 +8394,7 @@ do_autocmd(char_u *arg_in, int forceit)
         * Scan over the pattern.  Put a NUL at the end.
         */
        cmd = pat;
-       while (*cmd && (!vim_iswhite(*cmd) || cmd[-1] == '\\'))
+       while (*cmd && (!VIM_ISWHITE(*cmd) || cmd[-1] == '\\'))
            cmd++;
        if (*cmd)
            *cmd++ = NUL;
@@ -8405,7 +8420,7 @@ do_autocmd(char_u *arg_in, int forceit)
         * Check for "nested" flag.
         */
        cmd = skipwhite(cmd);
-       if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0 && vim_iswhite(cmd[6]))
+       if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0 && VIM_ISWHITE(cmd[6]))
        {
            nested = TRUE;
            cmd = skipwhite(cmd + 6);
@@ -8448,7 +8463,7 @@ do_autocmd(char_u *arg_in, int forceit)
     }
     else
     {
-       while (*arg && *arg != '|' && !vim_iswhite(*arg))
+       while (*arg && *arg != '|' && !VIM_ISWHITE(*arg))
            if (do_autocmd_event(event_name2nr(arg, &arg), pat,
                                        nested, cmd, forceit, group) == FAIL)
                break;
@@ -8473,7 +8488,7 @@ au_get_grouparg(char_u **argp)
     char_u     *arg = *argp;
     int                group = AUGROUP_ALL;
 
-    for (p = arg; *p && !vim_iswhite(*p) && *p != '|'; ++p)
+    for (p = arg; *p && !VIM_ISWHITE(*p) && *p != '|'; ++p)
        ;
     if (p > arg)
     {
@@ -8785,7 +8800,7 @@ do_doautocmd(
     /*
      * Loop over the events.
      */
-    while (*arg && !vim_iswhite(*arg))
+    while (*arg && !VIM_ISWHITE(*arg))
        if (apply_autocmds_group(event_name2nr(arg, &arg),
                                      fname, NULL, TRUE, group, curbuf, NULL))
            nothing_done = FALSE;
@@ -9018,6 +9033,11 @@ win_found:
        win_remove(curwin, NULL);
        aucmd_win_used = FALSE;
        last_status(FALSE);         /* may need to remove last status line */
+
+       if (!valid_tabpage_win(curtab))
+           /* no valid window in current tabpage */
+           close_tabpage(curtab);
+
        restore_snapshot(SNAP_AUCMD_IDX, FALSE);
        (void)win_comp_pos();   /* recompute window positions */
        unblock_autocmds();
@@ -9296,6 +9316,7 @@ apply_autocmds_group(
     proftime_T wait_time;
 #endif
     int                did_save_redobuff = FALSE;
+    save_redo_T        save_redo;
 
     /*
      * Quickly return if there are no autocommands for this event or
@@ -9501,7 +9522,7 @@ apply_autocmds_group(
        if (!ins_compl_active())
 #endif
        {
-           saveRedobuff();
+           saveRedobuff(&save_redo);
            did_save_redobuff = TRUE;
        }
        did_filetype = keep_filetype;
@@ -9604,7 +9625,7 @@ apply_autocmds_group(
     {
        restore_search_patterns();
        if (did_save_redobuff)
-           restoreRedobuff();
+           restoreRedobuff(&save_redo);
        did_filetype = FALSE;
        while (au_pending_free_buf != NULL)
        {
@@ -9901,14 +9922,14 @@ set_context_in_autocmd(
     if (group == AUGROUP_ERROR)
        return NULL;
     /* If there only is a group name that's what we expand. */
-    if (*arg == NUL && group != AUGROUP_ALL && !vim_iswhite(arg[-1]))
+    if (*arg == NUL && group != AUGROUP_ALL && !VIM_ISWHITE(arg[-1]))
     {
        arg = p;
        group = AUGROUP_ALL;
     }
 
     /* skip over event name */
-    for (p = arg; *p != NUL && !vim_iswhite(*p); ++p)
+    for (p = arg; *p != NUL && !VIM_ISWHITE(*p); ++p)
        if (*p == ',')
            arg = p + 1;
     if (*p == NUL)
@@ -9922,7 +9943,7 @@ set_context_in_autocmd(
 
     /* skip over pattern */
     arg = skipwhite(p);
-    while (*arg && (!vim_iswhite(*arg) || arg[-1] == '\\'))
+    while (*arg && (!VIM_ISWHITE(*arg) || arg[-1] == '\\'))
        arg++;
     if (*arg)
        return arg;                         /* expand (next) command */
index d3635a6..f8abe22 100644 (file)
@@ -1039,7 +1039,7 @@ foldAdjustVisual(void)
     if (!VIsual_active || !hasAnyFolding(curwin))
        return;
 
-    if (ltoreq(VIsual, curwin->w_cursor))
+    if (LTOREQ_POS(VIsual, curwin->w_cursor))
     {
        start = &VIsual;
        end = &curwin->w_cursor;
@@ -1576,16 +1576,23 @@ foldMarkAdjustRecurse(
                {
                    /* 5. fold is below line1 and contains line2; need to
                     * correct nested folds too */
-                   foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top,
-                                 line2 - fp->fd_top, amount,
-                                 amount_after + (fp->fd_top - top));
                    if (amount == MAXLNUM)
                    {
+                       foldMarkAdjustRecurse(&fp->fd_nested,
+                                 line1 - fp->fd_top,
+                                 line2 - fp->fd_top,
+                                 amount,
+                                 amount_after + (fp->fd_top - top));
                        fp->fd_len -= line2 - fp->fd_top + 1;
                        fp->fd_top = line1;
                    }
                    else
                    {
+                       foldMarkAdjustRecurse(&fp->fd_nested,
+                                 line1 - fp->fd_top,
+                                 line2 - fp->fd_top,
+                                 amount,
+                                 amount_after - amount);
                        fp->fd_len += amount_after - amount;
                        fp->fd_top += amount;
                    }
@@ -1753,6 +1760,7 @@ foldAddMarker(linenr_T lnum, char_u *marker, int markerlen)
     int                line_len;
     char_u     *newline;
     char_u     *p = (char_u *)strstr((char *)curbuf->b_p_cms, "%s");
+    int                line_is_comment = FALSE;
 
     /* Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end */
     line = ml_get(lnum);
@@ -1760,11 +1768,16 @@ foldAddMarker(linenr_T lnum, char_u *marker, int markerlen)
 
     if (u_save(lnum - 1, lnum + 1) == OK)
     {
+#if defined(FEAT_COMMENTS)
+       /* Check if the line ends with an unclosed comment */
+       (void)skip_comment(line, FALSE, FALSE, &line_is_comment);
+#endif
        newline = alloc((unsigned)(line_len + markerlen + STRLEN(cms) + 1));
        if (newline == NULL)
            return;
        STRCPY(newline, line);
-       if (p == NULL)
+       /* Append the marker to the end of the line */
+       if (p == NULL || line_is_comment)
            vim_strncpy(newline + line_len, marker, markerlen);
        else
        {
@@ -1963,7 +1976,7 @@ get_foldtext(
        long count = (long)(lnume - lnum + 1);
 
        vim_snprintf((char *)buf, FOLD_TEXT_LEN,
-                    ngettext("+--%3ld line folded ",
+                    NGETTEXT("+--%3ld line folded ",
                                               "+--%3ld lines folded ", count),
                     count);
        text = buf;
@@ -1991,7 +2004,7 @@ foldtext_cleanup(char_u *str)
     /* Ignore leading and trailing white space in 'commentstring'. */
     cms_start = skipwhite(curbuf->b_p_cms);
     cms_slen = (int)STRLEN(cms_start);
-    while (cms_slen > 0 && vim_iswhite(cms_start[cms_slen - 1]))
+    while (cms_slen > 0 && VIM_ISWHITE(cms_start[cms_slen - 1]))
        --cms_slen;
 
     /* locate "%s" in 'commentstring', use the part before and after it. */
@@ -2002,7 +2015,7 @@ foldtext_cleanup(char_u *str)
        cms_slen = (int)(cms_end - cms_start);
 
        /* exclude white space before "%s" */
-       while (cms_slen > 0 && vim_iswhite(cms_start[cms_slen - 1]))
+       while (cms_slen > 0 && VIM_ISWHITE(cms_start[cms_slen - 1]))
            --cms_slen;
 
        /* skip "%s" and white space after it */
@@ -2026,7 +2039,7 @@ foldtext_cleanup(char_u *str)
 
            /* May remove 'commentstring' start.  Useful when it's a double
             * quote and we already removed a double quote. */
-           for (p = s; p > str && vim_iswhite(p[-1]); --p)
+           for (p = s; p > str && VIM_ISWHITE(p[-1]); --p)
                ;
            if (p >= str + cms_slen
                           && STRNCMP(p - cms_slen, cms_start, cms_slen) == 0)
@@ -2051,13 +2064,13 @@ foldtext_cleanup(char_u *str)
        }
        if (len != 0)
        {
-           while (vim_iswhite(s[len]))
+           while (VIM_ISWHITE(s[len]))
                ++len;
            STRMOVE(s, s + len);
        }
        else
        {
-           mb_ptr_adv(s);
+           MB_PTR_ADV(s);
        }
     }
 }
@@ -2498,7 +2511,11 @@ foldUpdateIEMSRecurse(
                         * 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 >= startlnum && fp->fd_top != firstlnum)
+                       if (fp->fd_top == firstlnum)
+                       {
+                           /* have found a fold beginning where we want */
+                       }
+                       else if (fp->fd_top >= startlnum)
                        {
                            if (fp->fd_top > firstlnum)
                                /* like lines are inserted */
@@ -2516,18 +2533,44 @@ foldUpdateIEMSRecurse(
                            fp->fd_top = firstlnum;
                            fold_changed = TRUE;
                        }
-                       else if (flp->start != 0 && lvl == level
-                                                  && fp->fd_top != firstlnum)
+                       else if ((flp->start != 0 && lvl == level)
+                                                    || firstlnum != startlnum)
                        {
-                           /* Existing fold that includes startlnum must stop
-                            * if we find the start of a new fold at the same
-                            * level.  Split it.  Delete contained folds at
-                            * this point to split them too. */
-                           foldRemove(&fp->fd_nested, flp->lnum - fp->fd_top,
-                                                     flp->lnum - fp->fd_top);
+                           linenr_T breakstart;
+                           linenr_T breakend;
+
+                           /*
+                            * Before there was a fold spanning from above
+                            * startlnum to below firstlnum. This fold is valid
+                            * above startlnum (because we are not updating
+                            * that range), but there should now be a break in
+                            * it.
+                            * If the break is because we are now forced to
+                            * start a new fold at the level "level" at line
+                            * fline->lnum, then we need to split the fold at
+                            * fline->lnum.
+                            * If the break is because the range
+                            * [startlnum, firstlnum) is now at a lower indent
+                            * than "level", we need to split the fold in this
+                            * range.
+                            * Any splits have to be done recursively.
+                            */
+                           if (firstlnum != startlnum)
+                           {
+                               breakstart = startlnum;
+                               breakend = firstlnum;
+                           }
+                           else
+                           {
+                               breakstart = flp->lnum;
+                               breakend = flp->lnum;
+                           }
+                           foldRemove(&fp->fd_nested, breakstart - fp->fd_top,
+                                                     breakend - fp->fd_top);
                            i = (int)(fp - (fold_T *)gap->ga_data);
-                           foldSplit(gap, i, flp->lnum, flp->lnum - 1);
+                           foldSplit(gap, i, breakstart, breakend - 1);
                            fp = (fold_T *)gap->ga_data + i + 1;
+
                            /* If using the "marker" or "syntax" method, we
                             * need to continue until the end of the fold is
                             * found. */
@@ -2536,6 +2579,20 @@ foldUpdateIEMSRecurse(
                                    || getlevel == foldlevelSyntax)
                                finish = TRUE;
                        }
+
+                       if (fp->fd_top == startlnum && concat)
+                       {
+                           i = (int)(fp - (fold_T *)gap->ga_data);
+                           if (i != 0)
+                           {
+                               fp2 = fp - 1;
+                               if (fp2->fd_top + fp2->fd_len == fp->fd_top)
+                               {
+                                   foldMerge(fp2, gap, fp);
+                                   fp = fp2;
+                               }
+                           }
+                       }
                        break;
                    }
                    if (fp->fd_top >= startlnum)
@@ -2698,7 +2755,7 @@ foldUpdateIEMSRecurse(
        /* End of fold found, update the length when it got shorter. */
        if (fp->fd_len != flp->lnum - fp->fd_top)
        {
-           if (fp->fd_top + fp->fd_len > bot + 1)
+           if (fp->fd_top + fp->fd_len - 1 > bot)
            {
                /* fold continued below bot */
                if (getlevel == foldlevelMarker
@@ -2871,7 +2928,7 @@ foldRemove(garray_T *gap, linenr_T top, linenr_T bot)
        {
            /* 2: or 3: need to delete nested folds */
            foldRemove(&fp->fd_nested, top - fp->fd_top, bot - fp->fd_top);
-           if (fp->fd_top + fp->fd_len > bot + 1)
+           if (fp->fd_top + fp->fd_len - 1 > bot)
            {
                /* 3: need to split it. */
                foldSplit(gap, (int)(fp - (fold_T *)gap->ga_data), top, bot);
@@ -2911,6 +2968,191 @@ foldRemove(garray_T *gap, linenr_T top, linenr_T bot)
     }
 }
 
+/* foldReverseOrder() {{{2 */
+    static void
+foldReverseOrder(garray_T *gap, linenr_T start_arg, linenr_T end_arg)
+{
+    fold_T *left, *right;
+    fold_T tmp;
+    linenr_T start = start_arg;
+    linenr_T end = end_arg;
+
+    for (; start < end; start++, end--)
+    {
+       left = (fold_T *)gap->ga_data + start;
+       right = (fold_T *)gap->ga_data + end;
+       tmp  = *left;
+       *left = *right;
+       *right = tmp;
+    }
+}
+
+/* foldMoveRange() {{{2 */
+/*
+ * Move folds within the inclusive range "line1" to "line2" to after "dest"
+ * requires "line1" <= "line2" <= "dest"
+ *
+ * There are the following situations for the first fold at or below line1 - 1.
+ *       1  2  3  4
+ *       1  2  3  4
+ * line1    2  3  4
+ *          2  3  4  5  6  7
+ * line2       3  4  5  6  7
+ *             3  4     6  7  8  9
+ * dest           4        7  8  9
+ *                4        7  8    10
+ *                4        7  8    10
+ *
+ * In the following descriptions, "moved" means moving in the buffer, *and* in
+ * the fold array.
+ * Meanwhile, "shifted" just means moving in the buffer.
+ * 1. not changed
+ * 2. truncated above line1
+ * 3. length reduced by  line2 - line1, folds starting between the end of 3 and
+ *    dest are truncated and shifted up
+ * 4. internal folds moved (from [line1, line2] to dest)
+ * 5. moved to dest.
+ * 6. truncated below line2 and moved.
+ * 7. length reduced by line2 - dest, folds starting between line2 and dest are
+ *    removed, top is moved down by move_len.
+ * 8. truncated below dest and shifted up.
+ * 9. shifted up
+ * 10. not changed
+ */
+
+    static void
+truncate_fold(fold_T *fp, linenr_T end)
+{
+    end += 1;
+    foldRemove(&fp->fd_nested, end - fp->fd_top, MAXLNUM);
+    fp->fd_len = end - fp->fd_top;
+}
+
+#define fold_end(fp) ((fp)->fd_top + (fp)->fd_len - 1)
+#define valid_fold(fp, gap) ((fp) < ((fold_T *)(gap)->ga_data + (gap)->ga_len))
+#define fold_index(fp, gap) ((size_t)(fp - ((fold_T *)(gap)->ga_data)))
+
+    void
+foldMoveRange(garray_T *gap, linenr_T line1, linenr_T line2, linenr_T dest)
+{
+    fold_T *fp;
+    linenr_T range_len = line2 - line1 + 1;
+    linenr_T move_len = dest - line2;
+    int at_start = foldFind(gap, line1 - 1, &fp);
+    size_t move_start = 0, move_end = 0, dest_index = 0;
+
+    if (at_start)
+    {
+       if (fold_end(fp) > dest)
+       {
+           /* Case 4
+           * don't have to change this fold, but have to move nested folds.
+           */
+           foldMoveRange(&fp->fd_nested, line1 - fp->fd_top, line2 -
+                   fp->fd_top, dest - fp->fd_top);
+           return;
+       }
+       else if (fold_end(fp) > line2)
+       {
+           /* Case 3
+            * Remove nested folds between line1 and line2 & reduce the
+            * length of fold by "range_len".
+            * Folds after this one must be dealt with.
+            */
+           foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top, line2 -
+                   fp->fd_top, MAXLNUM, -range_len);
+           fp->fd_len -= range_len;
+       }
+       else
+           /* Case 2 truncate fold, folds after this one must be dealt with. */
+           truncate_fold(fp, line1 - 1);
+
+       /* Look at the next fold, and treat that one as if it were the first
+        * after  "line1" (because now it is). */
+       fp = fp + 1;
+    }
+
+    if (!valid_fold(fp, gap) || fp->fd_top > dest)
+    {
+       /* Case 10
+        * No folds after "line1" and before "dest"
+        */
+       return;
+    }
+    else if (fp->fd_top > line2)
+    {
+       for (; valid_fold(fp, gap) && fold_end(fp) <= dest; fp++)
+       /* Case 9. (for all case 9's) -- shift up. */
+           fp->fd_top -= range_len;
+
+       if (valid_fold(fp, gap) && fp->fd_top <= dest)
+       {
+           /* Case 8. -- ensure truncated at dest, shift up */
+           truncate_fold(fp, dest);
+           fp->fd_top -= range_len;
+       }
+       return;
+    }
+    else if (fold_end(fp) > dest)
+    {
+       /* Case 7 -- remove nested folds and shrink */
+       foldMarkAdjustRecurse(&fp->fd_nested, line2 + 1 - fp->fd_top, dest -
+               fp->fd_top, MAXLNUM, -move_len);
+       fp->fd_len -= move_len;
+       fp->fd_top += move_len;
+       return;
+    }
+
+    /* Case 5 or 6
+     * changes rely on whether there are folds between the end of
+     * this fold and "dest".
+     */
+    move_start = fold_index(fp, gap);
+
+    for (; valid_fold(fp, gap) && fp->fd_top <= dest; fp++)
+    {
+       if (fp->fd_top <= line2)
+       {
+           /* 1. 2. or 3. */
+           if (fold_end(fp) > line2)
+               /* 2. or 3., truncate before moving */
+               truncate_fold(fp, line2);
+
+           fp->fd_top += move_len;
+           continue;
+       }
+
+       /* Record index of the first fold after the moved range. */
+       if (move_end == 0)
+           move_end = fold_index(fp, gap);
+
+       if (fold_end(fp) > dest)
+           truncate_fold(fp, dest);
+
+       fp->fd_top -= range_len;
+    }
+
+    dest_index = fold_index(fp, gap);
+
+    /*
+     * All folds are now correct, but not necessarily in the correct order.  We
+     * must swap folds in the range [move_end, dest_index) with those in the
+     * range [move_start, move_end).
+     */
+    if (move_end == 0)
+       /* There are no folds after those moved, hence no folds have been moved
+        * out of order. */
+       return;
+    foldReverseOrder(gap, (linenr_T)move_start, (linenr_T)dest_index - 1);
+    foldReverseOrder(gap, (linenr_T)move_start,
+                          (linenr_T)(move_start + dest_index - move_end - 1));
+    foldReverseOrder(gap, (linenr_T)(move_start + dest_index - move_end),
+                                                  (linenr_T)(dest_index - 1));
+}
+#undef fold_end
+#undef valid_fold
+#undef fold_index
+
 /* foldMerge() {{{2 */
 /*
  * Merge two adjacent folds (and the nested ones in them).
@@ -3198,7 +3440,7 @@ foldlevelMarker(fline_T *flp)
                --flp->lvl_next;
        }
        else
-           mb_ptr_adv(s);
+           MB_PTR_ADV(s);
     }
 
     /* The level can't go negative, must be missing a start marker. */
index 55db537..18af2a3 100644 (file)
 
 static buffheader_T redobuff = {{NULL, {NUL}}, NULL, 0, 0};
 static buffheader_T old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
-#if defined(FEAT_AUTOCMD) || defined(FEAT_EVAL) || defined(PROTO)
-static buffheader_T save_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
-static buffheader_T save_old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
-#endif
 static buffheader_T recordbuff = {{NULL, {NUL}}, NULL, 0, 0};
 
 static int typeahead_char = 0;         /* typeahead char that's not flushed */
@@ -250,7 +246,7 @@ add_buff(
     }
     else if (buf->bh_curr == NULL)     /* buffer has already been read */
     {
-       EMSG(_("E222: Add to read buffer"));
+       IEMSG(_("E222: Add to read buffer"));
        return;
     }
     else if (buf->bh_index != 0)
@@ -521,27 +517,22 @@ CancelRedo(void)
  * Save redobuff and old_redobuff to save_redobuff and save_old_redobuff.
  * Used before executing autocommands and user functions.
  */
-static int save_level = 0;
-
     void
-saveRedobuff(void)
+saveRedobuff(save_redo_T *save_redo)
 {
     char_u     *s;
 
-    if (save_level++ == 0)
-    {
-       save_redobuff = redobuff;
-       redobuff.bh_first.b_next = NULL;
-       save_old_redobuff = old_redobuff;
-       old_redobuff.bh_first.b_next = NULL;
+    save_redo->sr_redobuff = redobuff;
+    redobuff.bh_first.b_next = NULL;
+    save_redo->sr_old_redobuff = old_redobuff;
+    old_redobuff.bh_first.b_next = NULL;
 
-       /* Make a copy, so that ":normal ." in a function works. */
-       s = get_buffcont(&save_redobuff, FALSE);
-       if (s != NULL)
-       {
-           add_buff(&redobuff, s, -1L);
-           vim_free(s);
-       }
+    /* Make a copy, so that ":normal ." in a function works. */
+    s = get_buffcont(&save_redo->sr_redobuff, FALSE);
+    if (s != NULL)
+    {
+       add_buff(&redobuff, s, -1L);
+       vim_free(s);
     }
 }
 
@@ -550,15 +541,12 @@ saveRedobuff(void)
  * Used after executing autocommands and user functions.
  */
     void
-restoreRedobuff(void)
+restoreRedobuff(save_redo_T *save_redo)
 {
-    if (--save_level == 0)
-    {
-       free_buff(&redobuff);
-       redobuff = save_redobuff;
-       free_buff(&old_redobuff);
-       old_redobuff = save_old_redobuff;
-    }
+    free_buff(&redobuff);
+    redobuff = save_redo->sr_redobuff;
+    free_buff(&old_redobuff);
+    old_redobuff = save_redo->sr_old_redobuff;
 }
 #endif
 
@@ -932,7 +920,7 @@ init_typebuf(void)
        typebuf.tb_noremap = noremapbuf_init;
        typebuf.tb_buflen = TYPELEN_INIT;
        typebuf.tb_len = 0;
-       typebuf.tb_off = 0;
+       typebuf.tb_off = MAXMAPLEN + 4;
        typebuf.tb_change_cnt = 1;
     }
 }
@@ -978,23 +966,32 @@ ins_typebuf(
 
     addlen = (int)STRLEN(str);
 
-    /*
-     * Easy case: there is room in front of typebuf.tb_buf[typebuf.tb_off]
-     */
     if (offset == 0 && addlen <= typebuf.tb_off)
     {
+       /*
+        * Easy case: there is room in front of typebuf.tb_buf[typebuf.tb_off]
+        */
        typebuf.tb_off -= addlen;
        mch_memmove(typebuf.tb_buf + typebuf.tb_off, str, (size_t)addlen);
     }
-
-    /*
-     * Need to allocate a new buffer.
-     * In typebuf.tb_buf there must always be room for 3 * MAXMAPLEN + 4
-     * characters.  We add some extra room to avoid having to allocate too
-     * often.
-     */
+    else if (typebuf.tb_len == 0 && typebuf.tb_buflen
+                                              >= addlen + 3 * (MAXMAPLEN + 4))
+    {
+       /*
+        * Buffer is empty and string fits in the existing buffer.
+        * Leave some space before and after, if possible.
+        */
+       typebuf.tb_off = (typebuf.tb_buflen - addlen - 3 * (MAXMAPLEN + 4)) / 2;
+       mch_memmove(typebuf.tb_buf + typebuf.tb_off, str, (size_t)addlen);
+    }
     else
     {
+       /*
+        * Need to allocate a new buffer.
+        * In typebuf.tb_buf there must always be room for 3 * (MAXMAPLEN + 4)
+        * characters.  We add some extra room to avoid having to allocate too
+        * often.
+        */
        newoff = MAXMAPLEN + 4;
        newlen = typebuf.tb_len + addlen + newoff + 4 * (MAXMAPLEN + 4);
        if (newlen < 0)             /* string is getting too long */
@@ -1304,7 +1301,7 @@ alloc_typebuf(void)
        return FAIL;
     }
     typebuf.tb_buflen = TYPELEN_INIT;
-    typebuf.tb_off = 0;
+    typebuf.tb_off = MAXMAPLEN + 4;  /* can insert without realloc */
     typebuf.tb_len = 0;
     typebuf.tb_maplen = 0;
     typebuf.tb_silent = 0;
@@ -1321,11 +1318,11 @@ alloc_typebuf(void)
 free_typebuf(void)
 {
     if (typebuf.tb_buf == typebuf_init)
-       EMSG2(_(e_intern2), "Free typebuf 1");
+       internal_error("Free typebuf 1");
     else
        vim_free(typebuf.tb_buf);
     if (typebuf.tb_noremap == noremapbuf_init)
-       EMSG2(_(e_intern2), "Free typebuf 2");
+       internal_error("Free typebuf 2");
     else
        vim_free(typebuf.tb_noremap);
 }
@@ -1818,6 +1815,12 @@ plain_vgetc(void)
     {
        c = safe_vgetc();
     } while (c == K_IGNORE || c == K_VER_SCROLLBAR || c == K_HOR_SCROLLBAR);
+
+    if (c == K_PS)
+       /* Only handle the first pasted character.  Drop the rest, since we
+        * don't know what to do with it. */
+       c = bracketed_paste(PASTE_ONE_CHAR, FALSE, NULL);
+
     return c;
 }
 
@@ -1907,7 +1910,7 @@ vungetc(int c)
 }
 
 /*
- * get a character:
+ * Get a character:
  * 1. from the stuffbuffer
  *     This is used for abbreviated commands like "D" -> "d$".
  *     Also used to redo a command for ".".
@@ -2009,7 +2012,7 @@ vgetorpeek(int advance)
            {
                /* KeyTyped = FALSE;  When the command that stuffed something
                 * was typed, behave like the stuffed command was typed.
-                * needed for CTRL-W CTRl-] to open a fold, for example. */
+                * needed for CTRL-W CTRL-] to open a fold, for example. */
                KeyStuffed = TRUE;
            }
            if (typebuf.tb_no_abbr_cnt == 0)
@@ -2646,7 +2649,7 @@ vgetorpeek(int advance)
                                ptr = ml_get_curline();
                                while (col < curwin->w_cursor.col)
                                {
-                                   if (!vim_iswhite(ptr[col]))
+                                   if (!VIM_ISWHITE(ptr[col]))
                                        curwin->w_wcol = vcol;
                                    vcol += lbr_chartabsize(ptr, ptr + col,
                                                               (colnr_T)vcol);
@@ -3319,7 +3322,7 @@ do_map(
      */
     p = keys;
     do_backslash = (vim_strchr(p_cpo, CPO_BSLASH) == NULL);
-    while (*p && (maptype == 1 || !vim_iswhite(*p)))
+    while (*p && (maptype == 1 || !VIM_ISWHITE(*p)))
     {
        if ((p[0] == Ctrl_V || (do_backslash && p[0] == '\\')) &&
                                                                  p[1] != NUL)
@@ -3424,7 +3427,7 @@ do_map(
                        }
            /* An abbreviation cannot contain white space. */
            for (n = 0; n < len; ++n)
-               if (vim_iswhite(keys[n]))
+               if (VIM_ISWHITE(keys[n]))
                {
                    retval = 1;
                    goto theend;
@@ -4017,9 +4020,9 @@ showmap(
     } while (len < 12);
 
     if (mp->m_noremap == REMAP_NONE)
-       msg_puts_attr((char_u *)"*", hl_attr(HLF_8));
+       msg_puts_attr((char_u *)"*", HL_ATTR(HLF_8));
     else if (mp->m_noremap == REMAP_SCRIPT)
-       msg_puts_attr((char_u *)"&", hl_attr(HLF_8));
+       msg_puts_attr((char_u *)"&", HL_ATTR(HLF_8));
     else
        msg_putchar(' ');
 
@@ -4031,7 +4034,7 @@ showmap(
     /* 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 */
     if (*mp->m_str == NUL)
-       msg_puts_attr((char_u *)"<Nop>", hl_attr(HLF_8));
+       msg_puts_attr((char_u *)"<Nop>", HL_ATTR(HLF_8));
     else
     {
        /* Remove escaping of CSI, because "m_str" is in a format to be used
@@ -4211,6 +4214,11 @@ set_context_in_map_cmd(
                arg = skipwhite(arg + 8);
                continue;
            }
+           if (STRNCMP(arg, "<special>", 9) == 0)
+           {
+               arg = skipwhite(arg + 9);
+               continue;
+           }
 #ifdef FEAT_EVAL
            if (STRNCMP(arg, "<script>", 8) == 0)
            {
@@ -4262,7 +4270,7 @@ ExpandMappings(
     {
        count = 0;
 
-       for (i = 0; i < 6; ++i)
+       for (i = 0; i < 7; ++i)
        {
            if (i == 0)
                p = (char_u *)"<silent>";
@@ -4280,6 +4288,8 @@ ExpandMappings(
 #endif
            else if (i == 5)
                p = (char_u *)"<nowait>";
+           else if (i == 6)
+               p = (char_u *)"<special>";
            else
                continue;
 
@@ -4868,7 +4878,7 @@ makemap(
                        c1 = 'l';
                        break;
                    default:
-                       EMSG(_("E228: makemap: Illegal mode"));
+                       IEMSG(_("E228: makemap: Illegal mode"));
                        return FAIL;
                }
                do      /* do this twice if c2 is set, 3 times with c3 */
@@ -5031,7 +5041,7 @@ put_escstr(FILE *fd, char_u *strstart, int what)
         * interpreted as the start of a special key name.
         * A space in the lhs of a :map needs a CTRL-V.
         */
-       if (what == 2 && (vim_iswhite(c) || c == '"' || c == '\\'))
+       if (what == 2 && (VIM_ISWHITE(c) || c == '"' || c == '\\'))
        {
            if (putc('\\', fd) < 0)
                return FAIL;
index fea9543..28b71ac 100644 (file)
@@ -532,7 +532,6 @@ EXTERN int  clip_autoselect_plus INIT(= FALSE);
 EXTERN int     clip_autoselectml INIT(= FALSE);
 EXTERN int     clip_html INIT(= FALSE);
 EXTERN regprog_T *clip_exclude_prog INIT(= NULL);
-EXTERN int     clip_did_set_selection INIT(= TRUE);
 EXTERN int     clip_unnamed_saved INIT(= 0);
 #endif
 
@@ -643,6 +642,8 @@ EXTERN int  exiting INIT(= FALSE);
 EXTERN int     really_exiting INIT(= FALSE);
                                /* TRUE when we are sure to exit, e.g., after
                                 * a deadly signal */
+EXTERN int     stdout_isatty INIT(= TRUE);     /* is stdout a terminal? */
+
 #if defined(FEAT_AUTOCHDIR)
 EXTERN int     test_autochdir INIT(= FALSE);
 #endif
@@ -930,10 +931,10 @@ EXTERN int        State INIT(= NORMAL);   /* This is the current state of the
                                         * command interpreter. */
 
 EXTERN int     finish_op INIT(= FALSE);/* TRUE while an operator is pending */
-EXTERN int     opcount INIT(= 0);      /* count for pending operator */
+EXTERN long    opcount INIT(= 0);      /* count for pending operator */
 
 /*
- * ex mode (Q) state
+ * Ex mode (Q) state
  */
 EXTERN int exmode_active INIT(= 0);    /* zero, EXMODE_NORMAL or EXMODE_VIM */
 EXTERN int ex_no_reprint INIT(= FALSE); /* no need to print after z or p */
@@ -1086,7 +1087,7 @@ EXTERN pos_T      last_cursormoved              /* for CursorMoved event */
                        = INIT_POS_T(0, 0, 0)
 # endif
                        ;
-EXTERN int     last_changedtick INIT(= 0);   /* for TextChanged event */
+EXTERN varnumber_T last_changedtick INIT(= 0);   /* for TextChanged event */
 EXTERN buf_T   *last_changedtick_buf INIT(= NULL);
 #endif
 
@@ -1440,6 +1441,7 @@ EXTERN char_u e_font[]            INIT(= N_("E235: Unknown font: %s"));
 EXTERN char_u e_fontwidth[]    INIT(= N_("E236: Font \"%s\" is not fixed-width"));
 #endif
 EXTERN char_u e_internal[]     INIT(= N_("E473: Internal error"));
+EXTERN char_u e_intern2[]      INIT(= N_("E685: Internal error: %s"));
 EXTERN char_u e_interr[]       INIT(= N_("Interrupted"));
 EXTERN char_u e_invaddr[]      INIT(= N_("E14: Invalid address"));
 EXTERN char_u e_invarg[]       INIT(= N_("E474: Invalid argument"));
@@ -1578,7 +1580,7 @@ EXTERN char_u e_winheight[]       INIT(= N_("E591: 'winheight' cannot be smaller than
 EXTERN char_u e_winwidth[]     INIT(= N_("E592: 'winwidth' cannot be smaller than 'winminwidth'"));
 #endif
 EXTERN char_u e_write[]                INIT(= N_("E80: Error while writing"));
-EXTERN char_u e_zerocount[]    INIT(= N_("Zero count"));
+EXTERN char_u e_zerocount[]    INIT(= N_("E939: Positive count required"));
 #ifdef FEAT_EVAL
 EXTERN char_u e_usingsid[]     INIT(= N_("E81: Using <SID> not in a script context"));
 #endif
@@ -1589,7 +1591,6 @@ EXTERN char_u e_invexprmsg[]      INIT(= N_("E449: Invalid expression received"));
 EXTERN char_u e_guarded[]      INIT(= N_("E463: Region is guarded, cannot modify"));
 EXTERN char_u e_nbreadonly[]   INIT(= N_("E744: NetBeans does not allow changes in read-only files"));
 #endif
-EXTERN char_u e_intern2[]      INIT(= N_("E685: Internal error: %s"));
 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 %ld does not exist"));
@@ -1646,7 +1647,9 @@ EXTERN int  alloc_fail_countdown INIT(= -1);
 /* set by alloc_fail(), number of times alloc() returns NULL */
 EXTERN int  alloc_fail_repeat INIT(= 0);
 
+/* flags set by test_override() */
 EXTERN int  disable_char_avail_for_testing INIT(= 0);
+EXTERN int  disable_redraw_for_testing INIT(= 0);
 
 EXTERN int  in_free_unref_items INIT(= FALSE);
 #endif
index 87b0839..7d44db1 100644 (file)
--- a/src/gui.c
+++ b/src/gui.c
@@ -630,7 +630,7 @@ gui_init(void)
      * where Vim was started. */
     emsg_on_display = FALSE;
     msg_scrolled = 0;
-    clear_sb_text();
+    clear_sb_text(TRUE);
     need_wait_return = FALSE;
     msg_didany = FALSE;
 
@@ -1459,6 +1459,8 @@ gui_resize_shell(int pixel_width, int pixel_height)
     }
 
 again:
+    new_pixel_width = 0;
+    new_pixel_height = 0;
     busy = TRUE;
 
     /* Flush pending output before redrawing */
@@ -1468,8 +1470,8 @@ again:
     gui.num_rows = (pixel_height - gui_get_base_height()) / gui.char_height;
 
     gui_position_components(pixel_width);
-
     gui_reset_scroll_region();
+
     /*
      * At the "more" and ":confirm" prompt there is no redraw, put the cursor
      * at the last line here (why does it have to be one row too low?).
@@ -1491,17 +1493,22 @@ again:
 
     busy = FALSE;
 
-    /*
-     * We could have been called again while redrawing the screen.
-     * Need to do it all again with the latest size then.
-     */
+    /* We may have been called again while redrawing the screen.
+     * Need to do it all again with the latest size then.  But only if the size
+     * actually changed. */
     if (new_pixel_height)
     {
-       pixel_width = new_pixel_width;
-       pixel_height = new_pixel_height;
-       new_pixel_width = 0;
-       new_pixel_height = 0;
-       goto again;
+       if (pixel_width == new_pixel_width && pixel_height == new_pixel_height)
+       {
+           new_pixel_width = 0;
+           new_pixel_height = 0;
+       }
+       else
+       {
+           pixel_width = new_pixel_width;
+           pixel_height = new_pixel_height;
+           goto again;
+       }
     }
 }
 
@@ -1511,18 +1518,10 @@ again:
     void
 gui_may_resize_shell(void)
 {
-    int                h, w;
-
     if (new_pixel_height)
-    {
        /* careful: gui_resize_shell() may postpone the resize again if we
         * were called indirectly by it */
-       w = new_pixel_width;
-       h = new_pixel_height;
-       new_pixel_width = 0;
-       new_pixel_height = 0;
-       gui_resize_shell(w, h);
-    }
+       gui_resize_shell(new_pixel_width, new_pixel_height);
 }
 
     int
@@ -4477,7 +4476,7 @@ gui_do_scroll(void)
        pum_redraw();
 #endif
 
-    return (wp == curwin && !equalpos(curwin->w_cursor, old_cursor));
+    return (wp == curwin && !EQUAL_POS(curwin->w_cursor, old_cursor));
 }
 
 
@@ -4501,7 +4500,7 @@ scroll_line_len(linenr_T lnum)
        for (;;)
        {
            w = chartabsize(p, col);
-           mb_ptr_adv(p);
+           MB_PTR_ADV(p);
            if (*p == NUL)              /* don't count the last character */
                break;
            col += w;
@@ -4968,7 +4967,7 @@ ex_gui(exarg_T *eap)
      */
     if (arg[0] == '-'
            && (arg[1] == 'f' || arg[1] == 'b')
-           && (arg[2] == NUL || vim_iswhite(arg[2])))
+           && (arg[2] == NUL || VIM_ISWHITE(arg[2])))
     {
        gui.dofork = (arg[1] == 'b');
        eap->arg = skipwhite(eap->arg + 2);
@@ -5119,7 +5118,7 @@ gui_update_screen(void)
                curwin->w_p_cole > 0
 # endif
                )
-                    && !equalpos(last_cursormoved, curwin->w_cursor))
+                    && !EQUAL_POS(last_cursormoved, curwin->w_cursor))
     {
 # ifdef FEAT_AUTOCMD
        if (has_cursormoved())
index bfdf6b6..659e934 100644 (file)
@@ -60,11 +60,12 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 /* created by weissman, Mon Jul  7 13:20:03 1986 */
 /* converted by swick, Thu Aug 27 1987 */
 
+#include "vim.h"
+
 #include <X11/IntrinsicP.h>
 #include <X11/StringDefs.h>
 
 #include <X11/Xaw/XawInit.h>
-#include "vim.h"
 #include "gui_at_sb.h"
 
 #include <X11/Xmu/Drawing.h>
index 3d78287..18e3a8b 100644 (file)
@@ -9,6 +9,8 @@
  * See README.txt for an overview of the Vim source code.
  */
 
+#include "vim.h"
+
 #include <X11/StringDefs.h>
 #include <X11/Intrinsic.h>
 #ifdef FEAT_GUI_NEXTAW
@@ -34,7 +36,6 @@
 # include <X11/Xaw/AsciiText.h>
 #endif /* FEAT_GUI_NEXTAW */
 
-#include "vim.h"
 #ifndef FEAT_GUI_NEXTAW
 # include "gui_at_sb.h"
 #endif
index 4a7c06e..818a50b 100644 (file)
@@ -84,7 +84,7 @@ general_beval_cb(BalloonEval *beval, int state UNUSED)
            result = eval_to_string(bexpr, NULL, TRUE);
 
            /* Remove one trailing newline, it is added when the result was a
-            * list and it's hardly every useful.  If the user really wants a
+            * list and it's hardly ever useful.  If the user really wants a
             * trailing newline he can add two and one remains. */
            if (result != NULL)
            {
@@ -218,7 +218,7 @@ gui_mch_create_beval_area(
 
     if (mesg != NULL && mesgCB != NULL)
     {
-       EMSG(_("E232: Cannot create BalloonEval with both message and callback"));
+       IEMSG(_("E232: Cannot create BalloonEval with both message and callback"));
        return NULL;
     }
 
@@ -366,7 +366,7 @@ get_beval_info(
 
                    if (VIsual_active)
                    {
-                       if (lt(VIsual, curwin->w_cursor))
+                       if (LT_POS(VIsual, curwin->w_cursor))
                        {
                            spos = &VIsual;
                            epos = &curwin->w_cursor;
@@ -1054,7 +1054,7 @@ set_printable_label_text(GtkLabel *label, char_u *text)
 #endif
 
        /* Look up the RGB values of the SpecialKey foreground color. */
-       aep = syn_gui_attr2entry(hl_attr(HLF_8));
+       aep = syn_gui_attr2entry(HL_ATTR(HLF_8));
        pixel = (aep != NULL) ? aep->ae_u.gui.fg_color : INVALCOLOR;
        if (pixel != INVALCOLOR)
 # if GTK_CHECK_VERSION(3,0,0)
@@ -1178,12 +1178,23 @@ drawBalloon(BalloonEval *beval)
        int             y_offset = EVAL_OFFSET_Y;
        PangoLayout     *layout;
 # ifdef HAVE_GTK_MULTIHEAD
+#  if GTK_CHECK_VERSION(3,22,2)
+       GdkRectangle rect;
+       GdkMonitor * const mon = gdk_display_get_monitor_at_window(
+               gtk_widget_get_display(beval->balloonShell),
+               gtk_widget_get_window(beval->balloonShell));
+       gdk_monitor_get_geometry(mon, &rect);
+
+       screen_w = rect.width;
+       screen_h = rect.height;
+#  else
        GdkScreen       *screen;
 
        screen = gtk_widget_get_screen(beval->target);
        gtk_window_set_screen(GTK_WINDOW(beval->balloonShell), screen);
        screen_w = gdk_screen_get_width(screen);
        screen_h = gdk_screen_get_height(screen);
+#  endif
 # else
        screen_w = gdk_screen_width();
        screen_h = gdk_screen_height();
index 25a53eb..c175dd3 100644 (file)
@@ -1519,7 +1519,7 @@ split_button_string(char_u *button_string, int *n_buttons)
            else if (*p == DLG_HOTKEY_CHAR)
                *p++ = '_';
            else
-               mb_ptr_adv(p);
+               MB_PTR_ADV(p);
        }
        array[count] = NULL; /* currently not relied upon, but doesn't hurt */
     }
@@ -1881,10 +1881,36 @@ gui_mch_show_popupmenu(vimmenu_T *menu)
 #  endif
 # endif /* FEAT_XIM */
 
+# if GTK_CHECK_VERSION(3,22,2)
+    {
+       GdkEventButton trigger;
+
+       /* A pseudo event to have gtk_menu_popup_at_pointer() work. Since the
+        * function calculates the popup menu position on the basis of the
+        * actual pointer position when it is invoked, the fields x, y, x_root
+        * and y_root are set to zero for convenience. */
+       trigger.type       = GDK_BUTTON_PRESS;
+       trigger.window     = gtk_widget_get_window(gui.drawarea);
+       trigger.send_event = FALSE;
+       trigger.time       = gui.event_time;
+       trigger.x          = 0.0;
+       trigger.y          = 0.0;
+       trigger.axes       = NULL;
+       trigger.state      = 0;
+       trigger.button     = 3;
+       trigger.device     = NULL;
+       trigger.x_root     = 0.0;
+       trigger.y_root     = 0.0;
+
+       gtk_menu_popup_at_pointer(GTK_MENU(menu->submenu_id),
+                                 (GdkEvent *)&trigger);
+    }
+#else
     gtk_menu_popup(GTK_MENU(menu->submenu_id),
                   NULL, NULL,
                   (GtkMenuPositionFunc)NULL, NULL,
                   3U, gui.event_time);
+#endif
 }
 
 /* Ugly global variable to pass "mouse_pos" flag from gui_make_popup() to
@@ -1942,10 +1968,55 @@ gui_make_popup(char_u *path_name, int mouse_pos)
 
     if (menu != NULL && menu->submenu_id != NULL)
     {
+# if GTK_CHECK_VERSION(3,22,2)
+       GdkWindow * const win = gtk_widget_get_window(gui.drawarea);
+       GdkEventButton trigger;
+
+       /* A pseudo event to have gtk_menu_popup_at_*() functions work. Since
+        * the position where the menu pops up is automatically adjusted by
+        * the functions, none of the fields x, y, x_root and y_root has to be
+        * set to a specific value here; therefore, they are set to zero for
+        * convenience.*/
+       trigger.type       = GDK_BUTTON_PRESS;
+       trigger.window     = win;
+       trigger.send_event = FALSE;
+       trigger.time       = GDK_CURRENT_TIME;
+       trigger.x          = 0.0;
+       trigger.y          = 0.0;
+       trigger.axes       = NULL;
+       trigger.state      = 0;
+       trigger.button     = 0;
+       trigger.device     = NULL;
+       trigger.x_root     = 0.0;
+       trigger.y_root     = 0.0;
+
+       if (mouse_pos)
+           gtk_menu_popup_at_pointer(GTK_MENU(menu->submenu_id),
+                                     (GdkEvent *)&trigger);
+       else
+       {
+           gint origin_x, origin_y;
+           GdkRectangle rect = { 0, 0, 0, 0 };
+
+           gdk_window_get_origin(win, &origin_x, &origin_y);
+           popup_menu_position_func(NULL, &rect.x, &rect.y, NULL, NULL);
+
+           rect.x -= origin_x;
+           rect.y -= origin_y;
+
+           gtk_menu_popup_at_rect(GTK_MENU(menu->submenu_id),
+                                  win,
+                                  &rect,
+                                  GDK_GRAVITY_SOUTH_EAST,
+                                  GDK_GRAVITY_NORTH_WEST,
+                                  (GdkEvent *)&trigger);
+       }
+# else
        gtk_menu_popup(GTK_MENU(menu->submenu_id),
                       NULL, NULL,
                       &popup_menu_position_func, NULL,
                       0U, (guint32)GDK_CURRENT_TIME);
+# endif
     }
 }
 
index 182fe82..bb4c632 100644 (file)
@@ -92,19 +92,6 @@ static void gtk_form_position_child(GtkForm *form,
                                    gboolean force_allocate);
 static void gtk_form_position_children(GtkForm *form);
 
-#if !GTK_CHECK_VERSION(3,0,0)
-static GdkFilterReturn gtk_form_filter(GdkXEvent *gdk_xevent,
-                                      GdkEvent *event,
-                                      gpointer data);
-static GdkFilterReturn gtk_form_main_filter(GdkXEvent *gdk_xevent,
-                                           GdkEvent *event,
-                                           gpointer data);
-#endif
-#if !GTK_CHECK_VERSION(3,16,0)
-static void gtk_form_set_static_gravity(GdkWindow *window,
-                                       gboolean use_static);
-#endif
-
 static void gtk_form_send_configure(GtkForm *form);
 
 static void gtk_form_child_map(GtkWidget *widget, gpointer user_data);
@@ -171,9 +158,6 @@ gtk_form_put(GtkForm        *form,
        gtk_form_attach_child_window(form, child);
 
     gtk_widget_set_parent(child_widget, GTK_WIDGET(form));
-#if !GTK_CHECK_VERSION(3,0,0)
-    gtk_widget_size_request(child->widget, NULL);
-#endif
 
 #if GTK_CHECK_VERSION(3,0,0)
     if (gtk_widget_get_realized(GTK_WIDGET(form))
@@ -301,19 +285,7 @@ gtk_form_init(GtkForm *form)
     gtk_widget_set_has_window(GTK_WIDGET(form), TRUE);
 #endif
     form->children = NULL;
-
-#if !GTK_CHECK_VERSION(3,0,0)
-    form->width = 1;
-    form->height = 1;
-#endif
-
     form->bin_window = NULL;
-
-#if !GTK_CHECK_VERSION(3,0,0)
-    form->configure_serial = 0;
-    form->visibility = GDK_VISIBILITY_PARTIAL;
-#endif
-
     form->freeze_count = 0;
 }
 
@@ -393,10 +365,6 @@ gtk_form_realize(GtkWidget *widget)
 #endif
     gdk_window_set_user_data(form->bin_window, widget);
 
-#if !GTK_CHECK_VERSION(3,16,0)
-    gtk_form_set_static_gravity(form->bin_window, TRUE);
-#endif
-
 #if GTK_CHECK_VERSION(3,0,0)
     {
        GtkStyleContext * const sctx = gtk_widget_get_style_context(widget);
@@ -414,11 +382,6 @@ gtk_form_realize(GtkWidget *widget)
     gtk_style_set_background(widget->style, form->bin_window, GTK_STATE_NORMAL);
 #endif
 
-#if !GTK_CHECK_VERSION(3,0,0)
-    gdk_window_add_filter(widget->window, gtk_form_main_filter, form);
-    gdk_window_add_filter(form->bin_window, gtk_form_filter, form);
-#endif
-
     for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
     {
        GtkFormChild *child = tmp_list->data;
@@ -540,33 +503,11 @@ gtk_form_unrealize(GtkWidget *widget)
     static void
 gtk_form_size_request(GtkWidget *widget, GtkRequisition *requisition)
 {
-#if !GTK_CHECK_VERSION(3,0,0)
-    GList *tmp_list;
-    GtkForm *form;
-#endif
-
     g_return_if_fail(GTK_IS_FORM(widget));
+    g_return_if_fail(requisition != NULL);
 
-#if !GTK_CHECK_VERSION(3,0,0)
-    form = GTK_FORM(widget);
-#endif
-
-#if GTK_CHECK_VERSION(3,0,0)
     requisition->width = 1;
     requisition->height = 1;
-#else
-    requisition->width = form->width;
-    requisition->height = form->height;
-
-    tmp_list = form->children;
-
-    while (tmp_list)
-    {
-       GtkFormChild *child = tmp_list->data;
-       gtk_widget_size_request(child->widget, NULL);
-       tmp_list = tmp_list->next;
-    }
-#endif
 }
 
 #if GTK_CHECK_VERSION(3,0,0)
@@ -735,28 +676,9 @@ gtk_form_expose(GtkWidget *widget, GdkEventExpose *event)
        return FALSE;
 
     for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
-    {
-       GtkFormChild    *formchild = tmp_list->data;
-       GtkWidget       *child     = formchild->widget;
-       /*
-        * The following chunk of code is taken from gtkcontainer.c.  The
-        * gtk1.x code synthesized expose events directly on the child widgets,
-        * which can't be done in gtk2
-        */
-       if (GTK_WIDGET_DRAWABLE(child) && GTK_WIDGET_NO_WINDOW(child)
-               && child->window == event->window)
-       {
-           GdkEventExpose child_event;
-           child_event = *event;
-
-           child_event.region = gtk_widget_region_intersect(child, event->region);
-           if (!gdk_region_empty(child_event.region))
-           {
-               gdk_region_get_clipbox(child_event.region, &child_event.area);
-               gtk_widget_send_expose(child, (GdkEvent *)&child_event);
-           }
-       }
-    }
+       gtk_container_propagate_expose(GTK_CONTAINER(widget),
+               GTK_WIDGET(((GtkFormChild *)tmp_list->data)->widget),
+               event);
 
     return FALSE;
 }
@@ -914,9 +836,6 @@ gtk_form_attach_child_window(GtkForm *form, GtkFormChild *child)
 #endif
 
        gtk_widget_set_parent_window(child->widget, child->window);
-#if !GTK_CHECK_VERSION(3,16,0)
-       gtk_form_set_static_gravity(child->window, TRUE);
-#endif
        /*
         * Install signal handlers to map/unmap child->window
         * alongside with the actual widget.
@@ -948,15 +867,6 @@ gtk_form_realize_child(GtkForm *form, GtkFormChild *child)
 {
     gtk_form_attach_child_window(form, child);
     gtk_widget_realize(child->widget);
-
-#if !GTK_CHECK_VERSION(3,16,0)
-    if (child->window == NULL) /* might be already set, see above */
-# if GTK_CHECK_VERSION(3,0,0)
-       gtk_form_set_static_gravity(gtk_widget_get_window(child->widget), TRUE);
-# else
-       gtk_form_set_static_gravity(child->widget->window, TRUE);
-# endif
-#endif
 }
 
     static void
@@ -1068,96 +978,6 @@ gtk_form_position_children(GtkForm *form)
        gtk_form_position_child(form, tmp_list->data, FALSE);
 }
 
-/* Callbacks */
-
-/* The main event filter. Actually, we probably don't really need
- * to install this as a filter at all, since we are calling it
- * directly above in the expose-handling hack.
- *
- * This routine identifies expose events that are generated when
- * we've temporarily moved the bin_window_origin, and translates
- * them or discards them, depending on whether we are obscured
- * or not.
- */
-#if !GTK_CHECK_VERSION(3,0,0)
-    static GdkFilterReturn
-gtk_form_filter(GdkXEvent *gdk_xevent, GdkEvent *event UNUSED, gpointer data)
-{
-    XEvent *xevent;
-    GtkForm *form;
-
-    xevent = (XEvent *) gdk_xevent;
-    form = GTK_FORM(data);
-
-    switch (xevent->type)
-    {
-    case Expose:
-       if (xevent->xexpose.serial == form->configure_serial)
-       {
-           if (form->visibility == GDK_VISIBILITY_UNOBSCURED)
-               return GDK_FILTER_REMOVE;
-           else
-               break;
-       }
-       break;
-
-    case ConfigureNotify:
-       if ((xevent->xconfigure.x != 0) || (xevent->xconfigure.y != 0))
-           form->configure_serial = xevent->xconfigure.serial;
-       break;
-    }
-
-    return GDK_FILTER_CONTINUE;
-}
-
-/* Although GDK does have a GDK_VISIBILITY_NOTIFY event,
- * there is no corresponding event in GTK, so we have
- * to get the events from a filter
- */
-    static GdkFilterReturn
-gtk_form_main_filter(GdkXEvent *gdk_xevent,
-                    GdkEvent *event UNUSED,
-                    gpointer data)
-{
-    XEvent *xevent;
-    GtkForm *form;
-
-    xevent = (XEvent *) gdk_xevent;
-    form = GTK_FORM(data);
-
-    if (xevent->type == VisibilityNotify)
-    {
-       switch (xevent->xvisibility.state)
-       {
-       case VisibilityFullyObscured:
-           form->visibility = GDK_VISIBILITY_FULLY_OBSCURED;
-           break;
-
-       case VisibilityPartiallyObscured:
-           form->visibility = GDK_VISIBILITY_PARTIAL;
-           break;
-
-       case VisibilityUnobscured:
-           form->visibility = GDK_VISIBILITY_UNOBSCURED;
-           break;
-       }
-
-       return GDK_FILTER_REMOVE;
-    }
-    return GDK_FILTER_CONTINUE;
-}
-#endif /* !GTK_CHECK_VERSION(3,0,0) */
-
-#if !GTK_CHECK_VERSION(3,16,0)
-    static void
-gtk_form_set_static_gravity(GdkWindow *window, gboolean use_static)
-{
-    /* We don't check if static gravity is actually supported, because it
-     * results in an annoying assertion error message. */
-    gdk_window_set_static_gravities(window, use_static);
-}
-#endif /* !GTK_CHECK_VERSION(3,16,0) */
-
     void
 gtk_form_move_resize(GtkForm *form, GtkWidget *widget,
                     gint x, gint y, gint w, gint h)
index 7bcf48b..be7693a 100644 (file)
@@ -43,19 +43,7 @@ struct _GtkForm
     GtkContainer container;
 
     GList *children;
-
-#ifndef USE_GTK3
-    guint width;
-    guint height;
-#endif
-
     GdkWindow *bin_window;
-
-#ifndef USE_GTK3
-    GdkVisibilityState visibility;
-    gulong configure_serial;
-#endif
-
     gint freeze_count;
 };
 
index 3884642..8824e5f 100644 (file)
@@ -627,6 +627,7 @@ static void gui_gtk_window_clear(GdkWindow *win);
     static void
 gui_gtk3_redraw(int x, int y, int width, int height)
 {
+    /* Range checks are left to gui_redraw_block() */
     gui_redraw_block(Y_2_ROW(y), X_2_COL(x),
            Y_2_ROW(y + height - 1), X_2_COL(x + width - 1),
            GUI_MON_NOCLEAR);
@@ -681,12 +682,20 @@ draw_event(GtkWidget *widget UNUSED,
        if (list->status != CAIRO_STATUS_CLIP_NOT_REPRESENTABLE)
        {
            int i;
+
+           /* First clear all the blocks and then redraw them.  Just in case
+            * some blocks overlap. */
            for (i = 0; i < list->num_rectangles; i++)
            {
                const cairo_rectangle_t rect = list->rectangles[i];
 
-               gui_mch_clear_block(Y_2_ROW(rect.y), 1,
-                       Y_2_ROW(rect.y + rect.height - 1), Columns);
+               gui_mch_clear_block(Y_2_ROW((int)rect.y), 0,
+                       Y_2_ROW((int)(rect.y + rect.height)) - 1, Columns - 1);
+           }
+
+           for (i = 0; i < list->num_rectangles; i++)
+           {
+               const cairo_rectangle_t rect = list->rectangles[i];
 
                if (blink_mode)
                    gui_gtk3_redraw(rect.x, rect.y, rect.width, rect.height);
@@ -2837,7 +2846,7 @@ mainwin_realize(GtkWidget *widget UNUSED, gpointer data UNUSED)
        /*
         * Cannot handle "XLib-only" windows with gtk event routines, we'll
         * have to change the "server" registration to that of the main window
-        * If we have not registered a name yet, remember the window
+        * If we have not registered a name yet, remember the window.
         */
 # if GTK_CHECK_VERSION(3,0,0)
        serverChangeRegisteredWindow(GDK_WINDOW_XDISPLAY(mainwin_win),
@@ -3076,10 +3085,16 @@ drawarea_unrealize_cb(GtkWidget *widget UNUSED, gpointer data UNUSED)
     gui.blank_pointer = NULL;
 }
 
+#if GTK_CHECK_VERSION(3,22,2)
+    static void
+drawarea_style_updated_cb(GtkWidget *widget UNUSED,
+                        gpointer data UNUSED)
+#else
     static void
 drawarea_style_set_cb(GtkWidget        *widget UNUSED,
                      GtkStyle  *previous_style UNUSED,
                      gpointer  data UNUSED)
+#endif
 {
     gui_mch_new_colors();
 }
@@ -3096,6 +3111,35 @@ drawarea_configure_event_cb(GtkWidget          *widget,
     g_return_val_if_fail(event
            && event->width >= 1 && event->height >= 1, TRUE);
 
+# if GTK_CHECK_VERSION(3,22,2) && !GTK_CHECK_VERSION(3,22,4)
+    /* As of 3.22.2, GdkWindows have started distributing configure events to
+     * their "native" children (https://git.gnome.org/browse/gtk+/commit/?h=gtk-3-22&id=12579fe71b3b8f79eb9c1b80e429443bcc437dd0).
+     *
+     * As can be seen from the implementation of move_native_children() and
+     * configure_native_child() in gdkwindow.c, those functions actually
+     * propagate configure events to every child, failing to distinguish
+     * "native" one from non-native one.
+     *
+     * Naturally, configure events propagated to here like that are fallacious
+     * and, as a matter of fact, they trigger a geometric collapse of
+     * gui.drawarea in fullscreen and miximized modes.
+     *
+     * To filter out such nuisance events, we are making use of the fact that
+     * the field send_event of such GdkEventConfigures is set to FALSE in
+     * configure_native_child().
+     *
+     * Obviously, this is a terrible hack making GVim depend on GTK's
+     * implementation details.  Therefore, watch out any relevant internal
+     * changes happening in GTK in the feature (sigh).
+     */
+    /* Follow-up
+     * After a few weeks later, the GdkWindow change mentioned above was
+     * reverted (https://git.gnome.org/browse/gtk+/commit/?h=gtk-3-22&id=f70039cb9603a02d2369fec4038abf40a1711155).
+     * The corresponding official release is 3.22.4. */
+    if (event->send_event == FALSE)
+       return TRUE;
+# endif
+
     if (event->width == cur_width && event->height == cur_height)
        return TRUE;
 
@@ -3133,9 +3177,9 @@ delete_event_cb(GtkWidget *widget UNUSED,
     static int
 get_item_dimensions(GtkWidget *widget, GtkOrientation orientation)
 {
+# ifdef FEAT_GUI_GNOME
     GtkOrientation item_orientation = GTK_ORIENTATION_HORIZONTAL;
 
-# ifdef FEAT_GUI_GNOME
     if (using_gnome && widget != NULL)
     {
        GtkWidget *parent;
@@ -3154,7 +3198,10 @@ get_item_dimensions(GtkWidget *widget, GtkOrientation orientation)
            item_orientation = bonobo_dock_item_get_orientation(dockitem);
        }
     }
+# else
+#  define item_orientation GTK_ORIENTATION_HORIZONTAL
 # endif
+
 # if GTK_CHECK_VERSION(3,0,0)
     if (widget != NULL
            && item_orientation == orientation
@@ -3171,16 +3218,16 @@ get_item_dimensions(GtkWidget *widget, GtkOrientation orientation)
        GtkAllocation allocation;
 
        gtk_widget_get_allocation(widget, &allocation);
-
-       if (orientation == GTK_ORIENTATION_HORIZONTAL)
-           return allocation.height;
-       else
-           return allocation.width;
+       return allocation.height;
 # else
+#  ifdef FEAT_GUI_GNOME
        if (orientation == GTK_ORIENTATION_HORIZONTAL)
            return widget->allocation.height;
        else
            return widget->allocation.width;
+#  else
+       return widget->allocation.height;
+#  endif
 # endif
     }
     return 0;
@@ -3519,8 +3566,12 @@ on_tabline_menu(GtkWidget *widget, GdkEvent *event)
        /* If the event was generated for 3rd button popup the menu. */
        if (bevent->button == 3)
        {
+# if GTK_CHECK_VERSION(3,22,2)
+           gtk_menu_popup_at_pointer(GTK_MENU(widget), event);
+# else
            gtk_menu_popup(GTK_MENU(widget), NULL, NULL, NULL, NULL,
                                                bevent->button, bevent->time);
+# endif
            /* We handled the event. */
            return TRUE;
        }
@@ -4116,6 +4167,9 @@ gui_mch_init(void)
 #endif
 
     gui.drawarea = gtk_drawing_area_new();
+#if GTK_CHECK_VERSION(3,22,2)
+    gtk_widget_set_name(gui.drawarea, "vim-gui-drawarea");
+#endif
 #if GTK_CHECK_VERSION(3,0,0)
     gui.surface = NULL;
     gui.by_signal = FALSE;
@@ -4167,8 +4221,13 @@ gui_mch_init(void)
                     G_CALLBACK(drawarea_unrealize_cb), NULL);
     g_signal_connect(G_OBJECT(gui.drawarea), "configure-event",
            G_CALLBACK(drawarea_configure_event_cb), NULL);
+# if GTK_CHECK_VERSION(3,22,2)
+    g_signal_connect_after(G_OBJECT(gui.drawarea), "style-updated",
+                          G_CALLBACK(&drawarea_style_updated_cb), NULL);
+# else
     g_signal_connect_after(G_OBJECT(gui.drawarea), "style-set",
                           G_CALLBACK(&drawarea_style_set_cb), NULL);
+# endif
 #else
     gtk_signal_connect(GTK_OBJECT(gui.drawarea), "realize",
                       GTK_SIGNAL_FUNC(drawarea_realize_cb), NULL);
@@ -4384,14 +4443,34 @@ set_cairo_source_rgba_from_color(cairo_t *cr, guicolor_T color)
 gui_mch_new_colors(void)
 {
 #if GTK_CHECK_VERSION(3,0,0)
+# if !GTK_CHECK_VERSION(3,22,2)
     GdkWindow * const da_win = gtk_widget_get_window(gui.drawarea);
+# endif
 
     if (gui.drawarea != NULL && gtk_widget_get_window(gui.drawarea) != NULL)
 #else
     if (gui.drawarea != NULL && gui.drawarea->window != NULL)
 #endif
     {
-#if GTK_CHECK_VERSION(3,4,0)
+#if GTK_CHECK_VERSION(3,22,2)
+       GtkStyleContext * const context
+           = gtk_widget_get_style_context(gui.drawarea);
+       GtkCssProvider * const provider = gtk_css_provider_new();
+       gchar * const css = g_strdup_printf(
+               "widget#vim-gui-drawarea {\n"
+               "  background-color: #%.2lx%.2lx%.2lx;\n"
+               "}\n",
+                (gui.back_pixel >> 16) & 0xff,
+                (gui.back_pixel >> 8) & 0xff,
+                gui.back_pixel & 0xff);
+
+       gtk_css_provider_load_from_data(provider, css, -1, NULL);
+       gtk_style_context_add_provider(context,
+               GTK_STYLE_PROVIDER(provider), G_MAXUINT);
+
+       g_free(css);
+       g_object_unref(provider);
+#elif GTK_CHECK_VERSION(3,4,0) /* !GTK_CHECK_VERSION(3,22,2) */
        GdkRGBA rgba;
 
        rgba = color_to_rgba(gui.back_pixel);
@@ -4415,7 +4494,7 @@ gui_mch_new_colors(void)
 # else
        gdk_window_set_background(gui.drawarea->window, &color);
 # endif
-#endif /* !GTK_CHECK_VERSION(3,4,0) */
+#endif /* !GTK_CHECK_VERSION(3,22,2) */
     }
 }
 
@@ -4429,6 +4508,30 @@ form_configure_event(GtkWidget *widget UNUSED,
 {
     int usable_height = event->height;
 
+#if GTK_CHECK_VERSION(3,22,2) && !GTK_CHECK_VERSION(3,22,4)
+    /* As of 3.22.2, GdkWindows have started distributing configure events to
+     * their "native" children (https://git.gnome.org/browse/gtk+/commit/?h=gtk-3-22&id=12579fe71b3b8f79eb9c1b80e429443bcc437dd0).
+     *
+     * As can be seen from the implementation of move_native_children() and
+     * configure_native_child() in gdkwindow.c, those functions actually
+     * propagate configure events to every child, failing to distinguish
+     * "native" one from non-native one.
+     *
+     * Naturally, configure events propagated to here like that are fallacious
+     * and, as a matter of fact, they trigger a geometric collapse of
+     * gui.formwin.
+     *
+     * To filter out such fallacious events, check if the given event is the
+     * one that was sent out to the right place. Ignore it if not.
+     */
+    /* Follow-up
+     * After a few weeks later, the GdkWindow change mentioned above was
+     * reverted (https://git.gnome.org/browse/gtk+/commit/?h=gtk-3-22&id=f70039cb9603a02d2369fec4038abf40a1711155).
+     * The corresponding official release is 3.22.4. */
+    if (event->window != gtk_widget_get_window(gui.formwin))
+       return TRUE;
+#endif
+
     /* When in a GtkPlug, we can't guarantee valid heights (as a round
      * no. of char-heights), so we have to manually sanitise them.
      * Widths seem to sort themselves out, don't ask me why.
@@ -4890,6 +4993,16 @@ gui_mch_set_shellsize(int width, int height,
 gui_mch_get_screen_dimensions(int *screen_w, int *screen_h)
 {
 #ifdef HAVE_GTK_MULTIHEAD
+# if GTK_CHECK_VERSION(3,22,2)
+    GdkRectangle rect;
+    GdkMonitor * const mon = gdk_display_get_monitor_at_window(
+           gtk_widget_get_display(gui.mainwin),
+           gtk_widget_get_window(gui.mainwin));
+    gdk_monitor_get_geometry(mon, &rect);
+
+    *screen_w = rect.width;
+    *screen_h = rect.height - p_ghr;
+# else
     GdkScreen* screen;
 
     if (gui.mainwin != NULL && gtk_widget_has_screen(gui.mainwin))
@@ -4899,6 +5012,7 @@ gui_mch_get_screen_dimensions(int *screen_w, int *screen_h)
 
     *screen_w = gdk_screen_get_width(screen);
     *screen_h = gdk_screen_get_height(screen) - p_ghr;
+# endif
 #else
     *screen_w = gdk_screen_width();
     /* Subtract 'guiheadroom' from the height to allow some room for the
@@ -6601,8 +6715,14 @@ gui_mch_flush(void)
  * (row2, col2) inclusive.
  */
     void
-gui_mch_clear_block(int row1, int col1, int row2, int col2)
+gui_mch_clear_block(int row1arg, int col1arg, int row2arg, int col2arg)
 {
+
+    int col1 = check_col(col1arg);
+    int col2 = check_col(col2arg);
+    int row1 = check_row(row1arg);
+    int row2 = check_row(row2arg);
+
 #if GTK_CHECK_VERSION(3,0,0)
     if (gtk_widget_get_window(gui.drawarea) == NULL)
        return;
@@ -6626,11 +6746,15 @@ gui_mch_clear_block(int row1, int col1, int row2, int col2)
        };
        GdkWindow * const win = gtk_widget_get_window(gui.drawarea);
        cairo_t * const cr = cairo_create(gui.surface);
+# if GTK_CHECK_VERSION(3,22,2)
+       set_cairo_source_rgba_from_color(cr, gui.back_pixel);
+# else
        cairo_pattern_t * const pat = gdk_window_get_background_pattern(win);
        if (pat != NULL)
            cairo_set_source(cr, pat);
        else
            set_cairo_source_rgba_from_color(cr, gui.back_pixel);
+# endif
        gdk_cairo_rectangle(cr, &rect);
        cairo_fill(cr);
        cairo_destroy(cr);
@@ -6659,11 +6783,15 @@ gui_gtk_window_clear(GdkWindow *win)
        0, 0, gdk_window_get_width(win), gdk_window_get_height(win)
     };
     cairo_t * const cr = cairo_create(gui.surface);
+# if GTK_CHECK_VERSION(3,22,2)
+    set_cairo_source_rgba_from_color(cr, gui.back_pixel);
+# else
     cairo_pattern_t * const pat = gdk_window_get_background_pattern(win);
     if (pat != NULL)
        cairo_set_source(cr, pat);
     else
        set_cairo_source_rgba_from_color(cr, gui.back_pixel);
+# endif
     gdk_cairo_rectangle(cr, &rect);
     cairo_fill(cr);
     cairo_destroy(cr);
index 5a9dd92..4e4dffa 100644 (file)
@@ -8,6 +8,8 @@
  * See README.txt for an overview of the Vim source code.
  */
 
+#include "vim.h"
+
 #include <Xm/Form.h>
 #include <Xm/RowColumn.h>
 #include <Xm/PushB.h>
@@ -33,8 +35,6 @@
 #include <X11/StringDefs.h>
 #include <X11/Intrinsic.h>
 
-#include "vim.h"
-
 #ifdef HAVE_X11_XPM_H
 # include <X11/xpm.h>
 #else
index be2158d..52db8f4 100644 (file)
@@ -558,13 +558,12 @@ gui_mch_set_blinking(long wait, long on, long off)
     blink_offtime = off;
 }
 
-/* ARGSUSED */
     static VOID CALLBACK
 _OnBlinkTimer(
     HWND hwnd,
-    UINT uMsg,
+    UINT uMsg UNUSED,
     UINT idEvent,
-    DWORD dwTime)
+    DWORD dwTime UNUSED)
 {
     MSG msg;
 
@@ -590,7 +589,7 @@ _OnBlinkTimer(
        gui_update_cursor(TRUE, FALSE);
        blink_state = BLINK_ON;
        blink_timer = (UINT) SetTimer(NULL, 0, (UINT)blink_ontime,
-                                                        (TIMERPROC)_OnBlinkTimer);
+                                                   (TIMERPROC)_OnBlinkTimer);
     }
 }
 
@@ -644,13 +643,12 @@ gui_mch_start_blink(void)
  * Call-back routines.
  */
 
-/*ARGSUSED*/
     static VOID CALLBACK
 _OnTimer(
     HWND hwnd,
-    UINT uMsg,
+    UINT uMsg UNUSED,
     UINT idEvent,
-    DWORD dwTime)
+    DWORD dwTime UNUSED)
 {
     MSG msg;
 
@@ -667,12 +665,11 @@ _OnTimer(
        s_wait_timer = 0;
 }
 
-/*ARGSUSED*/
     static void
 _OnDeadChar(
-    HWND hwnd,
-    UINT ch,
-    int cRepeat)
+    HWND hwnd UNUSED,
+    UINT ch UNUSED,
+    int cRepeat UNUSED)
 {
     dead_key = 1;
 }
@@ -752,12 +749,11 @@ char_to_string(int ch, char_u *string, int slen, int had_alt)
 /*
  * Key hit, add it to the input buffer.
  */
-/*ARGSUSED*/
     static void
 _OnChar(
-    HWND hwnd,
+    HWND hwnd UNUSED,
     UINT ch,
-    int cRepeat)
+    int cRepeat UNUSED)
 {
     char_u     string[40];
     int                len = 0;
@@ -777,12 +773,11 @@ _OnChar(
 /*
  * Alt-Key hit, add it to the input buffer.
  */
-/*ARGSUSED*/
     static void
 _OnSysChar(
-    HWND hwnd,
+    HWND hwnd UNUSED,
     UINT cch,
-    int cRepeat)
+    int cRepeat UNUSED)
 {
     char_u     string[40]; /* Enough for multibyte character */
     int                len;
@@ -861,11 +856,10 @@ _OnMouseEvent(
     gui_send_mouse_event(button, x, y, repeated_click, vim_modifiers);
 }
 
-/*ARGSUSED*/
     static void
 _OnMouseButtonDown(
-    HWND hwnd,
-    BOOL fDoubleClick,
+    HWND hwnd UNUSED,
+    BOOL fDoubleClick UNUSED,
     int x,
     int y,
     UINT keyFlags)
@@ -960,10 +954,9 @@ _OnMouseButtonDown(
     }
 }
 
-/*ARGSUSED*/
     static void
 _OnMouseMoveOrRelease(
-    HWND hwnd,
+    HWND hwnd UNUSED,
     int x,
     int y,
     UINT keyFlags)
@@ -1038,13 +1031,12 @@ gui_mswin_find_menu(
     return pMenu;
 }
 
-/*ARGSUSED*/
     static void
 _OnMenu(
-    HWND       hwnd,
+    HWND       hwnd UNUSED,
     int                id,
-    HWND       hwndCtl,
-    UINT       codeNotify)
+    HWND       hwndCtl UNUSED,
+    UINT       codeNotify UNUSED)
 {
     vimmenu_T  *pMenu;
 
@@ -1527,9 +1519,8 @@ gui_mch_get_font(
  * Return the name of font "font" in allocated memory.
  * Don't know how to get the actual name, thus use the provided name.
  */
-/*ARGSUSED*/
     char_u *
-gui_mch_get_fontname(GuiFont font, char_u *name)
+gui_mch_get_fontname(GuiFont font UNUSED, char_u *name)
 {
     if (name == NULL)
        return NULL;
@@ -2175,13 +2166,12 @@ gui_mch_enable_menu(int flag)
 #endif
 }
 
-/*ARGSUSED*/
     void
 gui_mch_set_menu_pos(
-    int            x,
-    int            y,
-    int            w,
-    int            h)
+    int            x UNUSED,
+    int            y UNUSED,
+    int            w UNUSED,
+    int            h UNUSED)
 {
     /* It will be in the right place anyway */
 }
@@ -2297,19 +2287,24 @@ GetTextWidthEnc(HDC hdc, char_u *str, int len)
 # define GetTextWidthEnc(h, s, l) GetTextWidth((h), (s), (l))
 #endif
 
+static void get_work_area(RECT *spi_rect);
+
 /*
  * A quick little routine that will center one window over another, handy for
- * dialog boxes.  Taken from the Win32SDK samples.
+ * dialog boxes.  Taken from the Win32SDK samples and modified for multiple
+ * monitors.
  */
     static BOOL
 CenterWindow(
     HWND hwndChild,
     HWND hwndParent)
 {
-    RECT    rChild, rParent;
-    int     wChild, hChild, wParent, hParent;
-    int     wScreen, hScreen, xNew, yNew;
-    HDC     hdc;
+    HMONITOR       mon;
+    MONITORINFO            moninfo;
+    RECT           rChild, rParent, rScreen;
+    int                    wChild, hChild, wParent, hParent;
+    int                    xNew, yNew;
+    HDC                    hdc;
 
     GetWindowRect(hwndChild, &rChild);
     wChild = rChild.right - rChild.left;
@@ -2317,32 +2312,39 @@ CenterWindow(
 
     /* If Vim is minimized put the window in the middle of the screen. */
     if (hwndParent == NULL || IsMinimized(hwndParent))
-       SystemParametersInfo(SPI_GETWORKAREA, 0, &rParent, 0);
+       get_work_area(&rParent);
     else
        GetWindowRect(hwndParent, &rParent);
     wParent = rParent.right - rParent.left;
     hParent = rParent.bottom - rParent.top;
 
-    hdc = GetDC(hwndChild);
-    wScreen = GetDeviceCaps (hdc, HORZRES);
-    hScreen = GetDeviceCaps (hdc, VERTRES);
-    ReleaseDC(hwndChild, hdc);
-
-    xNew = rParent.left + ((wParent - wChild) /2);
-    if (xNew < 0)
+    moninfo.cbSize = sizeof(MONITORINFO);
+    mon = MonitorFromWindow(hwndChild, MONITOR_DEFAULTTOPRIMARY);
+    if (mon != NULL && GetMonitorInfo(mon, &moninfo))
     {
-       xNew = 0;
+       rScreen = moninfo.rcWork;
     }
-    else if ((xNew+wChild) > wScreen)
+    else
     {
-       xNew = wScreen - wChild;
+       hdc = GetDC(hwndChild);
+       rScreen.left = 0;
+       rScreen.top = 0;
+       rScreen.right = GetDeviceCaps(hdc, HORZRES);
+       rScreen.bottom = GetDeviceCaps(hdc, VERTRES);
+       ReleaseDC(hwndChild, hdc);
     }
 
-    yNew = rParent.top + ((hParent - hChild) /2);
-    if (yNew < 0)
-       yNew = 0;
-    else if ((yNew+hChild) > hScreen)
-       yNew = hScreen - hChild;
+    xNew = rParent.left + ((wParent - wChild) / 2);
+    if (xNew < rScreen.left)
+       xNew = rScreen.left;
+    else if ((xNew + wChild) > rScreen.right)
+       xNew = rScreen.right - wChild;
+
+    yNew = rParent.top + ((hParent - hChild) / 2);
+    if (yNew < rScreen.top)
+       yNew = rScreen.top;
+    else if ((yNew + hChild) > rScreen.bottom)
+       yNew = rScreen.bottom - hChild;
 
     return SetWindowPos(hwndChild, NULL, xNew, yNew, 0, 0,
                                                   SWP_NOSIZE | SWP_NOZORDER);
@@ -2625,7 +2627,9 @@ gui_mch_set_curtab(int nr)
     void
 ex_simalt(exarg_T *eap)
 {
-    char_u *keys = eap->arg;
+    char_u     *keys = eap->arg;
+    int                fill_typebuf = FALSE;
+    char_u     key_name[4];
 
     PostMessage(s_hwnd, WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, (LPARAM)0);
     while (*keys)
@@ -2634,6 +2638,18 @@ ex_simalt(exarg_T *eap)
            *keys = ' ';            /* for showing system menu */
        PostMessage(s_hwnd, WM_CHAR, (WPARAM)*keys, (LPARAM)0);
        keys++;
+       fill_typebuf = TRUE;
+    }
+    if (fill_typebuf)
+    {
+       /* Put something in the typeahead buffer so that the message will get
+        * processed. */
+       key_name[0] = K_SPECIAL;
+       key_name[1] = KS_EXTRA;
+       key_name[2] = KE_IGNORE;
+       key_name[3] = NUL;
+       typebuf_was_filled = TRUE;
+       (void)ins_typebuf(key_name, REMAP_NONE, 0, TRUE, FALSE);
     }
 }
 
@@ -2805,10 +2821,8 @@ _OnEndSession(void)
  * Get this message when the user clicks on the cross in the top right corner
  * of a Windows95 window.
  */
-/*ARGSUSED*/
     static void
-_OnClose(
-    HWND hwnd)
+_OnClose(HWND hwnd UNUSED)
 {
     gui_shell_closed();
 }
@@ -2817,8 +2831,7 @@ _OnClose(
  * Get a message when the window is being destroyed.
  */
     static void
-_OnDestroy(
-    HWND hwnd)
+_OnDestroy(HWND hwnd)
 {
     if (!destroying)
        _OnClose(hwnd);
@@ -2871,11 +2884,10 @@ _OnPaint(
     }
 }
 
-/*ARGSUSED*/
     static void
 _OnSize(
     HWND hwnd,
-    UINT state,
+    UINT state UNUSED,
     int cx,
     int cy)
 {
@@ -3112,9 +3124,8 @@ gui_mch_insert_lines(
 }
 
 
-/*ARGSUSED*/
     void
-gui_mch_exit(int rc)
+gui_mch_exit(int rc UNUSED)
 {
 #if defined(FEAT_DIRECTX)
     DWriteContext_Close(s_dwc);
@@ -3273,9 +3284,8 @@ gui_mch_wide_font_changed(void)
  * Initialise vim to use the font with the given name.
  * Return FAIL if the font could not be loaded, OK otherwise.
  */
-/*ARGSUSED*/
     int
-gui_mch_init_font(char_u *font_name, int fontset)
+gui_mch_init_font(char_u *font_name, int fontset UNUSED)
 {
     LOGFONT    lf;
     GuiFont    font = NOFONT;
@@ -3404,11 +3414,10 @@ gui_mch_newfont(void)
 /*
  * Set the window title
  */
-/*ARGSUSED*/
     void
 gui_mch_settitle(
     char_u  *title,
-    char_u  *icon)
+    char_u  *icon UNUSED)
 {
     set_window_title(s_hwnd, (title == NULL ? "VIM" : (char *)title));
 }
@@ -3539,12 +3548,12 @@ gui_mch_browseW(
     filterp = convert_filterW(filter);
 
     vim_memset(&fileStruct, 0, sizeof(OPENFILENAMEW));
-#ifdef OPENFILENAME_SIZE_VERSION_400W
+#  ifdef OPENFILENAME_SIZE_VERSION_400W
     /* be compatible with Windows NT 4.0 */
     fileStruct.lStructSize = OPENFILENAME_SIZE_VERSION_400W;
-#else
+#  else
     fileStruct.lStructSize = sizeof(fileStruct);
-#endif
+#  endif
 
     if (title != NULL)
        titlep = enc_to_utf16(title, NULL);
@@ -3581,10 +3590,10 @@ gui_mch_browseW(
      * Don't use OFN_OVERWRITEPROMPT, Vim has its own ":confirm" dialog.
      */
     fileStruct.Flags = (OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY);
-#ifdef FEAT_SHORTCUT
+#  ifdef FEAT_SHORTCUT
     if (curbuf->b_p_bin)
        fileStruct.Flags |= OFN_NODEREFERENCELINKS;
-#endif
+#  endif
     if (saving)
     {
        if (!GetSaveFileNameW(&fileStruct))
@@ -3760,10 +3769,9 @@ gui_mch_browse(
 }
 #endif /* FEAT_BROWSE */
 
-/*ARGSUSED*/
     static void
 _OnDropFiles(
-    HWND hwnd,
+    HWND hwnd UNUSED,
     HDROP hDrop)
 {
 #ifdef FEAT_WINDOWS
@@ -3821,10 +3829,9 @@ _OnDropFiles(
 #endif
 }
 
-/*ARGSUSED*/
     static int
 _OnScroll(
-    HWND hwnd,
+    HWND hwnd UNUSED,
     HWND hwndCtl,
     UINT code,
     int pos)
@@ -3942,7 +3949,6 @@ _OnScroll(
  * Return pointer to buffer in "tofree".
  * Returns zero when out of memory.
  */
-/*ARGSUSED*/
     int
 get_cmd_args(char *prog, char *cmdline, char ***argvp, char **tofree)
 {
@@ -5559,7 +5565,7 @@ get_work_area(RECT *spi_rect)
     MONITORINFO            moninfo;
 
     /* work out which monitor the window is on, and get *it's* work area */
-    mon = MonitorFromWindow(s_hwnd, 1 /*MONITOR_DEFAULTTOPRIMARY*/);
+    mon = MonitorFromWindow(s_hwnd, MONITOR_DEFAULTTOPRIMARY);
     if (mon != NULL)
     {
        moninfo.cbSize = sizeof(MONITORINFO);
@@ -5576,10 +5582,14 @@ get_work_area(RECT *spi_rect)
 /*
  * Set the size of the window to the given width and height in pixels.
  */
-/*ARGSUSED*/
     void
-gui_mch_set_shellsize(int width, int height,
-       int min_width, int min_height, int base_width, int base_height,
+gui_mch_set_shellsize(
+       int width,
+       int height,
+       int min_width UNUSED,
+       int min_height UNUSED,
+       int base_width UNUSED,
+       int base_height UNUSED,
        int direction)
 {
     RECT       workarea_rect;
@@ -5740,9 +5750,8 @@ gui_mch_set_sp_color(guicolor_T color)
 /*
  * handle WM_IME_NOTIFY message
  */
-/*ARGSUSED*/
     static LRESULT
-_OnImeNotify(HWND hWnd, DWORD dwCommand, DWORD dwData)
+_OnImeNotify(HWND hWnd, DWORD dwCommand, DWORD dwData UNUSED)
 {
     LRESULT lResult = 0;
     HIMC hImc;
@@ -5790,9 +5799,8 @@ _OnImeNotify(HWND hWnd, DWORD dwCommand, DWORD dwData)
     return lResult;
 }
 
-/*ARGSUSED*/
     static LRESULT
-_OnImeComposition(HWND hwnd, WPARAM dbcs, LPARAM param)
+_OnImeComposition(HWND hwnd, WPARAM dbcs UNUSED, LPARAM param)
 {
     char_u     *ret;
     int                len;
@@ -6832,13 +6840,12 @@ gui_mch_menu_grey(
  * pressed, return that button's ID - IDCANCEL (2), which is the button's
  * number.
  */
-/*ARGSUSED*/
     static LRESULT CALLBACK
 dialog_callback(
     HWND hwnd,
     UINT message,
     WPARAM wParam,
-    LPARAM lParam)
+    LPARAM lParam UNUSED)
 {
     if (message == WM_INITDIALOG)
     {
@@ -7119,7 +7126,7 @@ gui_mch_dialog(
 #else
            l = 1;
 #endif
-           if (l == 1 && vim_iswhite(*pend)
+           if (l == 1 && VIM_ISWHITE(*pend)
                                        && textWidth > maxDialogWidth * 3 / 4)
                last_white = pend;
            textWidth += GetTextWidthEnc(hdc, pend, l);
@@ -8524,13 +8531,12 @@ delete_tooltip(BalloonEval *beval)
     PostMessage(beval->balloon, WM_CLOSE, 0, 0);
 }
 
-/*ARGSUSED*/
     static VOID CALLBACK
 BevalTimerProc(
-    HWND    hwnd,
-    UINT    uMsg,
-    UINT_PTR    idEvent,
-    DWORD   dwTime)
+    HWND       hwnd UNUSED,
+    UINT       uMsg UNUSED,
+    UINT_PTR    idEvent UNUSED,
+    DWORD      dwTime)
 {
     POINT      pt;
     RECT       rect;
@@ -8566,16 +8572,14 @@ BevalTimerProc(
     }
 }
 
-/*ARGSUSED*/
     void
-gui_mch_disable_beval_area(BalloonEval *beval)
+gui_mch_disable_beval_area(BalloonEval *beval UNUSED)
 {
     // TRACE0("gui_mch_disable_beval_area {{{");
     KillTimer(s_textArea, BevalTimerId);
     // TRACE0("gui_mch_disable_beval_area }}}");
 }
 
-/*ARGSUSED*/
     void
 gui_mch_enable_beval_area(BalloonEval *beval)
 {
@@ -8591,6 +8595,7 @@ gui_mch_enable_beval_area(BalloonEval *beval)
 gui_mch_post_balloon(BalloonEval *beval, char_u *mesg)
 {
     POINT   pt;
+
     // TRACE0("gui_mch_post_balloon {{{");
     if (beval->showState == ShS_SHOWING)
        return;
@@ -8598,8 +8603,8 @@ gui_mch_post_balloon(BalloonEval *beval, char_u *mesg)
     ScreenToClient(s_textArea, &pt);
 
     if (abs(beval->x - pt.x) < 3 && abs(beval->y - pt.y) < 3)
-       /* cursor is still here */
     {
+       /* cursor is still here */
        gui_mch_disable_beval_area(cur_beval);
        beval->showState = ShS_SHOWING;
        make_tooltip(beval, (char *)mesg, pt);
@@ -8607,7 +8612,6 @@ gui_mch_post_balloon(BalloonEval *beval, char_u *mesg)
     // TRACE0("gui_mch_post_balloon }}}");
 }
 
-/*ARGSUSED*/
     BalloonEval *
 gui_mch_create_beval_area(
     void       *target,        /* ignored, always use s_textArea */
@@ -8620,7 +8624,7 @@ gui_mch_create_beval_area(
 
     if (mesg != NULL && mesgCB != NULL)
     {
-       EMSG(_("E232: Cannot create BalloonEval with both message and callback"));
+       IEMSG(_("E232: Cannot create BalloonEval with both message and callback"));
        return NULL;
     }
 
@@ -8647,9 +8651,8 @@ gui_mch_create_beval_area(
     return beval;
 }
 
-/*ARGSUSED*/
     static void
-Handle_WM_Notify(HWND hwnd, LPNMHDR pnmh)
+Handle_WM_Notify(HWND hwnd UNUSED, LPNMHDR pnmh)
 {
     if (pnmh->idFrom != ID_BEVAL_TOOLTIP) /* it is not our tooltip */
        return;
index 05bd028..2226e89 100644 (file)
@@ -12,6 +12,8 @@
  * Not used for GTK.
  */
 
+#include "vim.h"
+
 #include <X11/keysym.h>
 #include <X11/Xatom.h>
 #include <X11/StringDefs.h>
@@ -19,8 +21,6 @@
 #include <X11/Shell.h>
 #include <X11/cursorfont.h>
 
-#include "vim.h"
-
 /*
  * For Workshop XpmP.h is preferred, because it makes the signs drawn with a
  * transparent background instead of black.
@@ -1992,14 +1992,40 @@ gui_mch_get_font(char_u *name, int giveErrorIfMissing)
 #if defined(FEAT_EVAL) || defined(PROTO)
 /*
  * Return the name of font "font" in allocated memory.
- * Don't know how to get the actual name, thus use the provided name.
  */
     char_u *
-gui_mch_get_fontname(GuiFont font UNUSED, char_u *name)
+gui_mch_get_fontname(GuiFont font, char_u *name)
 {
-    if (name == NULL)
-       return NULL;
-    return vim_strsave(name);
+    char_u *ret = NULL;
+
+    if (name != NULL && font == NULL)
+    {
+       /* In this case, there's no way other than doing this. */
+       ret = vim_strsave(name);
+    }
+    else if (font != NULL)
+    {
+       /* In this case, try to retrieve the XLFD corresponding to 'font'->fid;
+        * if failed, use 'name' unless it's NULL. */
+       unsigned long value = 0L;
+
+       if (XGetFontProperty(font, XA_FONT, &value))
+       {
+           char *xa_font_name = NULL;
+
+           xa_font_name = XGetAtomName(gui.dpy, value);
+           if (xa_font_name != NULL)
+           {
+               ret = vim_strsave((char_u *)xa_font_name);
+               XFree(xa_font_name);
+           }
+           else if (name != NULL)
+               ret = vim_strsave(name);
+       }
+       else if (name != NULL)
+           ret = vim_strsave(name);
+    }
+    return ret;
 }
 #endif
 
index f957e31..01e536c 100644 (file)
@@ -16,6 +16,8 @@
  * when using a dynamic scrollbar policy.
  */
 
+#include "vim.h"
+
 #include <Xm/Form.h>
 #include <Xm/PushBG.h>
 #include <Xm/Text.h>
@@ -36,8 +38,6 @@
 #include <X11/StringDefs.h>
 #include <X11/Intrinsic.h>
 
-#include "vim.h"
-
 extern Widget vimShell;
 
 #ifdef FEAT_MENU
index 1b5604b..60b3577 100644 (file)
@@ -590,7 +590,7 @@ hangul_automata2(char_u *buf, int_u *c)
            return AUTOMATA_CORRECT_NEW;
 
        default:
-           EMSG(_("E256: Hangul automata ERROR"));
+           IEMSG(_("E256: Hangul automata ERROR"));
            break;
     }
     return AUTOMATA_ERROR; /* RrEeAaLlLlYy EeRrRrOoRr */
index 449bfbd..4a0910d 100644 (file)
@@ -569,7 +569,7 @@ prt_header(
 prt_message(char_u *s)
 {
     screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
-    screen_puts(s, (int)Rows - 1, 0, hl_attr(HLF_R));
+    screen_puts(s, (int)Rows - 1, 0, HL_ATTR(HLF_R));
     out_flush();
 }
 
index d8d3aed..4bf41e0 100644 (file)
@@ -70,7 +70,6 @@ hash_init(hashtab_T *ht)
     ht->ht_mask = HT_INIT_SIZE - 1;
 }
 
-#if defined(FEAT_EVAL) || defined(FEAT_SYN_HL) || defined(PROTO)
 /*
  * Free the array of a hash table.  Does not free the items it contains!
  * If "ht" is not freed then you should call hash_init() next!
@@ -104,7 +103,6 @@ hash_clear_all(hashtab_T *ht, int off)
     }
     hash_clear(ht);
 }
-#endif
 
 /*
  * Find "key" in hashtable "ht".  "key" must not be NULL.
@@ -210,7 +208,7 @@ hash_add(hashtab_T *ht, char_u *key)
     hi = hash_lookup(ht, key, hash);
     if (!HASHITEM_EMPTY(hi))
     {
-       EMSG2(_(e_intern2), "hash_add()");
+       internal_error("hash_add()");
        return FAIL;
     }
     return hash_add_item(ht, hi, key, hash);
index 9e7a362..2c4f229 100644 (file)
@@ -201,15 +201,13 @@ set_context_in_cscope_cmd(
 #endif /* FEAT_CMDL_COMPL */
 
 /*
- * PRIVATE: do_cscope_general
- *
  * 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 */
+    int                make_split UNUSED) /* whether to split window */
 {
     cscmd_T *cmdp;
 
@@ -242,31 +240,28 @@ do_cscope_general(
 }
 
 /*
- * PUBLIC: do_cscope
+ * Implementation of ":cscope" and ":lcscope"
  */
     void
-do_cscope(exarg_T *eap)
+ex_cscope(exarg_T *eap)
 {
     do_cscope_general(eap, FALSE);
 }
 
 /*
- * PUBLIC: do_scscope
- *
- * same as do_cscope, but splits window, too.
+ * Implementation of ":scscope". Same as ex_cscope(), but splits window, too.
  */
     void
-do_scscope(exarg_T *eap)
+ex_scscope(exarg_T *eap)
 {
     do_cscope_general(eap, TRUE);
 }
 
 /*
- * PUBLIC: do_cstag
- *
+ * Implementation of ":cstag"
  */
     void
-do_cstag(exarg_T *eap)
+ex_cstag(exarg_T *eap)
 {
     int ret = FALSE;
 
@@ -336,13 +331,11 @@ do_cstag(exarg_T *eap)
 #endif
     }
 
-} /* do_cscope */
+}
 
 
 /*
- * PUBLIC: cs_find
- *
- * this simulates a vim_fgets(), but for cscope, returns the next line
+ * This simulates a vim_fgets(), but for cscope, returns the next line
  * from the cscope output.  should only be called from find_tags()
  *
  * returns TRUE if eof, FALSE otherwise
@@ -361,9 +354,7 @@ cs_fgets(char_u *buf, int size)
 
 
 /*
- * PUBLIC: cs_free_tags
- *
- * called only from do_tag(), when popping the tag stack
+ * Called only from do_tag(), when popping the tag stack.
  */
     void
 cs_free_tags(void)
@@ -373,9 +364,7 @@ cs_free_tags(void)
 
 
 /*
- * PUBLIC: cs_print_tags
- *
- * called from do_tag()
+ * Called from do_tag().
  */
     void
 cs_print_tags(void)
@@ -467,12 +456,8 @@ cs_connection(int num, char_u *dbpath, char_u *ppath)
  ****************************************************************************/
 
 /*
- * PRIVATE: cs_add
- *
- * add cscope database or a directory name (to look for cscope.out)
- * to the cscope connection list
- *
- * MAXPATHL 256
+ * Add cscope database or a directory name (to look for cscope.out)
+ * to the cscope connection list.
  */
     static int
 cs_add(exarg_T *eap UNUSED)
@@ -508,10 +493,8 @@ cs_stat_emsg(char *fname)
 
 
 /*
- * PRIVATE: cs_add_common
- *
- * 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
+ * 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
@@ -632,7 +615,7 @@ staterr:
        if (p_csverbose)
        {
            msg_clr_eos();
-           (void)smsg_attr(hl_attr(HLF_R),
+           (void)smsg_attr(HL_ATTR(HLF_R),
                            (char_u *)_("Added cscope database %s"),
                            csinfo[i].fname);
        }
@@ -666,9 +649,7 @@ cs_check_for_tags(void)
 
 
 /*
- * PRIVATE: cs_cnt_connections
- *
- * count the number of cscope connections
+ * Count the number of cscope connections.
  */
     static int
 cs_cnt_connections(void)
@@ -693,9 +674,7 @@ cs_reading_emsg(
 
 #define        CSREAD_BUFSIZE  2048
 /*
- * PRIVATE: cs_cnt_matches
- *
- * count the number of matches for a given cscope connection.
+ * Count the number of matches for a given cscope connection.
  */
     static int
 cs_cnt_matches(int idx)
@@ -754,8 +733,6 @@ cs_cnt_matches(int idx)
 
 
 /*
- * PRIVATE: cs_create_cmd
- *
  * Creates the actual cscope command query from what the user entered.
  */
     static char *
@@ -804,7 +781,7 @@ cs_create_cmd(char *csoption, char *pattern)
      * they may want to use the leading white space. */
     pat = pattern;
     if (search != 4 && search != 6)
-       while vim_iswhite(*pat)
+       while VIM_ISWHITE(*pat)
            ++pat;
 
     if ((cmd = (char *)alloc((unsigned)(strlen(pat) + 2))) == NULL)
@@ -817,8 +794,6 @@ cs_create_cmd(char *csoption, char *pattern)
 
 
 /*
- * PRIVATE: cs_create_connection
- *
  * This piece of code was taken/adapted from nvi.  do we need to add
  * the BSD license notice?
  */
@@ -1056,8 +1031,6 @@ err_closing:
 
 
 /*
- * PRIVATE: cs_find
- *
  * Query cscope using command line interface.  Parse the output and use tselect
  * to allow choices.  Like Nvi, creates a pipe to send to/from query/cscope.
  *
@@ -1102,9 +1075,7 @@ cs_find(exarg_T *eap)
 
 
 /*
- * PRIVATE: cs_find_common
- *
- * common code for cscope find, shared by cs_find() and do_cstag()
+ * Common code for cscope find, shared by cs_find() and ex_cstag().
  */
     static int
 cs_find_common(
@@ -1271,7 +1242,7 @@ cs_find_common(
                wp = curwin;
            /* '-' starts a new error list */
            if (qf_init(wp, tmp, (char_u *)"%f%*\\t%l%*\\t%m",
-                                                 *qfpos == '-', cmdline) > 0)
+                                         *qfpos == '-', cmdline, NULL) > 0)
            {
 # ifdef FEAT_WINDOWS
                if (postponed_split != 0)
@@ -1323,9 +1294,7 @@ cs_find_common(
 } /* cs_find_common */
 
 /*
- * PRIVATE: cs_help
- *
- * print help
+ * Print help.
  */
     static int
 cs_help(exarg_T *eap UNUSED)
@@ -1408,9 +1377,7 @@ GetWin32Error(void)
 #endif
 
 /*
- * PRIVATE: cs_insert_filelist
- *
- * insert a new cscope database filename into the filelist
+ * Insert a new cscope database filename into the filelist.
  */
     static int
 cs_insert_filelist(
@@ -1551,9 +1518,7 @@ cs_insert_filelist(
 
 
 /*
- * PRIVATE: cs_lookup_cmd
- *
- * find cscope command in command table
+ * Find cscope command in command table.
  */
     static cscmd_T *
 cs_lookup_cmd(exarg_T *eap)
@@ -1582,9 +1547,7 @@ cs_lookup_cmd(exarg_T *eap)
 
 
 /*
- * PRIVATE: cs_kill
- *
- * nuke em
+ * Nuke em.
  */
     static int
 cs_kill(exarg_T *eap UNUSED)
@@ -1639,8 +1602,6 @@ cs_kill(exarg_T *eap UNUSED)
 
 
 /*
- * PRIVATE: cs_kill_execute
- *
  * Actually kills a specific cscope connection.
  */
     static void
@@ -1651,7 +1612,7 @@ cs_kill_execute(
     if (p_csverbose)
     {
        msg_clr_eos();
-       (void)smsg_attr(hl_attr(HLF_R) | MSG_HIST,
+       (void)smsg_attr(HL_ATTR(HLF_R) | MSG_HIST,
                (char_u *)_("cscope connection %s closed"), cname);
     }
     cs_release_csp(i, TRUE);
@@ -1659,22 +1620,20 @@ cs_kill_execute(
 
 
 /*
- * PRIVATE: cs_make_vim_style_matches
- *
- * convert the cscope output into a ctags style entry (as might be found
+ * Convert the cscope output into a ctags style entry (as might be found
  * in a ctags tags file).  there's one catch though: cscope doesn't tell you
  * the type of the tag you are looking for.  for example, in Darren Hiebert's
  * ctags (the one that comes with vim), #define's use a line number to find the
  * tag in a file while function definitions use a regexp search pattern.
  *
- * i'm going to always use the line number because cscope does something
+ * I'm going to always use the line number because cscope does something
  * quirky (and probably other things i don't know about):
  *
  *     if you have "#  define" in your source file, which is
  *     perfectly legal, cscope thinks you have "#define".  this
  *     will result in a failed regexp search. :(
  *
- * besides, even if this particular case didn't happen, the search pattern
+ * 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.
  */
@@ -1721,9 +1680,7 @@ cs_make_vim_style_matches(
 
 
 /*
- * PRIVATE: cs_manage_matches
- *
- * this is kind of hokey, but i don't see an easy way round this..
+ * This is kind of hokey, but i don't see an easy way round this.
  *
  * Store: keep a ptr to the (malloc'd) memory of matches originally
  * generated from cs_find().  the matches are originally lines directly
@@ -1792,7 +1749,7 @@ cs_manage_matches(
        cs_print_tags_priv(mp, cp, cnt);
        break;
     default:   /* should not reach here */
-       (void)EMSG(_("E570: fatal error in cs_manage_matches"));
+       IEMSG(_("E570: fatal error in cs_manage_matches"));
        return NULL;
     }
 
@@ -1801,9 +1758,7 @@ cs_manage_matches(
 
 
 /*
- * PRIVATE: cs_parse_results
- *
- * parse cscope output
+ * Parse cscope output.
  */
     static char *
 cs_parse_results(
@@ -1864,9 +1819,7 @@ cs_parse_results(
 
 #ifdef FEAT_QUICKFIX
 /*
- * PRIVATE: cs_file_results
- *
- * write cscope find results to file
+ * Write cscope find results to file.
  */
     static void
 cs_file_results(FILE *f, int *nummatches_a)
@@ -1919,10 +1872,8 @@ cs_file_results(FILE *f, int *nummatches_a)
 #endif
 
 /*
- * PRIVATE: cs_fill_results
- *
- * get parsed cscope output and calls cs_make_vim_style_matches to convert
- * into ctags format
+ * 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
@@ -2032,9 +1983,7 @@ cs_pathcomponents(char *path)
 }
 
 /*
- * PRIVATE: cs_print_tags_priv
- *
- * called from cs_manage_matches()
+ * Called from cs_manage_matches().
  */
     static void
 cs_print_tags_priv(char **matches, char **cntxts, int num_matches)
@@ -2052,7 +2001,7 @@ cs_print_tags_priv(char **matches, char **cntxts, int num_matches)
     char       *cstag_msg = _("Cscope tag: %s");
     char       *csfmt_str = "%4d %6s  ";
 
-    assert (num_matches > 0);
+    assert(num_matches > 0);
 
     if ((tbuf = (char *)alloc((unsigned)strlen(matches[0]) + 1)) == NULL)
        return;
@@ -2071,14 +2020,14 @@ cs_print_tags_priv(char **matches, char **cntxts, int num_matches)
     {
        bufsize = newsize;
        (void)sprintf(buf, cstag_msg, ptag);
-       MSG_PUTS_ATTR(buf, hl_attr(HLF_T));
+       MSG_PUTS_ATTR(buf, HL_ATTR(HLF_T));
     }
 
     vim_free(tbuf);
 
-    MSG_PUTS_ATTR(_("\n   #   line"), hl_attr(HLF_T));    /* strlen is 7 */
+    MSG_PUTS_ATTR(_("\n   #   line"), HL_ATTR(HLF_T));    /* strlen is 7 */
     msg_advance(msg_col + 2);
-    MSG_PUTS_ATTR(_("filename / context / line\n"), hl_attr(HLF_T));
+    MSG_PUTS_ATTR(_("filename / context / line\n"), HL_ATTR(HLF_T));
 
     num = 1;
     for (i = 0; i < num_matches; i++)
@@ -2122,9 +2071,9 @@ cs_print_tags_priv(char **matches, char **cntxts, int num_matches)
        {
            /* csfmt_str = "%4d %6s  "; */
            (void)sprintf(buf, csfmt_str, num, lno);
-           MSG_PUTS_ATTR(buf, hl_attr(HLF_CM));
+           MSG_PUTS_ATTR(buf, HL_ATTR(HLF_CM));
        }
-       MSG_PUTS_LONG_ATTR(cs_pathcomponents(fname), hl_attr(HLF_CM));
+       MSG_PUTS_LONG_ATTR(cs_pathcomponents(fname), HL_ATTR(HLF_CM));
 
        /* compute the required space for the context */
        if (cntxts[idx] != NULL)
@@ -2182,9 +2131,7 @@ cs_print_tags_priv(char **matches, char **cntxts, int num_matches)
 
 
 /*
- * PRIVATE: cs_read_prompt
- *
- * read a cscope prompt (basically, skip over the ">> ")
+ * Read a cscope prompt (basically, skip over the ">> ").
  */
     static int
 cs_read_prompt(int i)
@@ -2280,8 +2227,6 @@ sig_handler SIGDEFARG(sigarg)
 #endif
 
 /*
- * PRIVATE: cs_release_csp
- *
  * Does the actual free'ing for the cs ptr with an optional flag of whether
  * or not to free the filename.  Called by cs_kill and cs_reset.
  */
@@ -2408,9 +2353,7 @@ cs_release_csp(int i, int freefnpp)
 
 
 /*
- * PRIVATE: cs_reset
- *
- * calls cs_kill on all cscope connections then reinits
+ * Calls cs_kill on all cscope connections then reinits.
  */
     static int
 cs_reset(exarg_T *eap UNUSED)
@@ -2456,7 +2399,7 @@ cs_reset(exarg_T *eap UNUSED)
                 * "Added cscope database..."
                 */
                sprintf(buf, " (#%d)", i);
-               MSG_PUTS_ATTR(buf, hl_attr(HLF_R));
+               MSG_PUTS_ATTR(buf, HL_ATTR(HLF_R));
            }
        }
        vim_free(dblist[i]);
@@ -2468,14 +2411,12 @@ cs_reset(exarg_T *eap UNUSED)
     vim_free(fllist);
 
     if (p_csverbose)
-       MSG_ATTR(_("All cscope databases reset"), hl_attr(HLF_R) | MSG_HIST);
+       MSG_ATTR(_("All cscope databases reset"), HL_ATTR(HLF_R) | MSG_HIST);
     return CSCOPE_SUCCESS;
 } /* cs_reset */
 
 
 /*
- * PRIVATE: cs_resolve_file
- *
  * Construct the full pathname to a file found in the cscope database.
  * (Prepends ppath, if there is one and if it's not already prepended,
  * otherwise just uses the name found.)
@@ -2544,9 +2485,7 @@ cs_resolve_file(int i, char *name)
 
 
 /*
- * PRIVATE: cs_show
- *
- * show all cscope connections
+ * Show all cscope connections.
  */
     static int
 cs_show(exarg_T *eap UNUSED)
@@ -2558,7 +2497,7 @@ cs_show(exarg_T *eap UNUSED)
     {
        MSG_PUTS_ATTR(
            _(" # pid    database name                       prepend path\n"),
-           hl_attr(HLF_T));
+           HL_ATTR(HLF_T));
        for (i = 0; i < csinfo_size; i++)
        {
            if (csinfo[i].fname == NULL)
@@ -2579,8 +2518,6 @@ cs_show(exarg_T *eap UNUSED)
 
 
 /*
- * PUBLIC: cs_end
- *
  * Only called when VIM exits to quit any cscope sessions.
  */
     void
index b77a3cd..ad8ee1b 100644 (file)
@@ -1716,6 +1716,8 @@ ex_luado(exarg_T *eap)
     const char *s = (const char *) eap->arg;
     luaL_Buffer b;
     size_t len;
+    buf_T *was_curbuf = curbuf;
+
     if (lua_init() == FAIL) return;
     if (u_save(eap->line1 - 1, eap->line2 + 1) == FAIL)
     {
@@ -1739,6 +1741,10 @@ ex_luado(exarg_T *eap)
     lua_replace(L, -2); /* function -> body */
     for (l = eap->line1; l <= eap->line2; l++)
     {
+       /* Check the line number, the command my have deleted lines. */
+       if (l > curbuf->b_ml.ml_line_count)
+           break;
+
        lua_pushvalue(L, -1); /* function */
        luaV_pushline(L, curbuf, l); /* current line as arg */
        lua_pushinteger(L, l); /* current line number as arg */
@@ -1747,6 +1753,9 @@ ex_luado(exarg_T *eap)
            luaV_emsg(L);
            break;
        }
+       /* Catch the command switching to another buffer. */
+       if (curbuf != was_curbuf)
+           break;
        if (lua_isstring(L, -1)) /* update line? */
        {
 #ifdef HAVE_SANDBOX
index 5a29c1b..076c5c6 100644 (file)
@@ -1286,8 +1286,9 @@ ex_perldo(exarg_T *eap)
     SV         *sv;
     char       *str;
     linenr_T   i;
+    buf_T      *was_curbuf = curbuf;
 
-    if (bufempty())
+    if (BUFEMPTY())
        return;
 
     if (perl_interp == NULL)
@@ -1321,11 +1322,14 @@ ex_perldo(exarg_T *eap)
     SAVETMPS;
     for (i = eap->line1; i <= eap->line2; i++)
     {
+       /* Check the line number, the command my have deleted lines. */
+       if (i > curbuf->b_ml.ml_line_count)
+           break;
        sv_setpv(GvSV(PL_defgv), (char *)ml_get(i));
        PUSHMARK(sp);
        perl_call_pv("VIM::perldo", G_SCALAR | G_EVAL);
        str = SvPV(GvSV(PL_errgv), length);
-       if (length)
+       if (length || curbuf != was_curbuf)
            break;
        SPAGAIN;
        if (SvTRUEx(POPs))
index c44fc93..78c70e7 100644 (file)
@@ -582,9 +582,9 @@ VimTryStart(void)
 VimTryEnd(void)
 {
     --trylevel;
-    /* Without this it stops processing all subsequent VimL commands and
-     * generates strange error messages if I e.g. try calling Test() in a
-     * cycle */
+    /* Without this it stops processing all subsequent Vim script commands and
+     * generates strange error messages if I e.g. try calling Test() in a cycle
+     */
     did_emsg = FALSE;
     /* Keyboard interrupt should be preferred over anything else */
     if (got_int)
@@ -625,7 +625,7 @@ VimTryEnd(void)
        discard_current_exception();
        return -1;
     }
-    /* Finally transform VimL exception to python one */
+    /* Finally transform Vim script exception to python one */
     else
     {
        PyErr_SetVim((char *)current_exception->value);
@@ -5619,6 +5619,7 @@ run_do(const char *cmd, void *arg UNUSED
     int                status;
     PyObject   *pyfunc, *pymain;
     PyObject   *run_ret;
+    buf_T      *was_curbuf = curbuf;
 
     if (u_save((linenr_T)RangeStart - 1, (linenr_T)RangeEnd + 1) != OK)
     {
@@ -5671,7 +5672,9 @@ run_do(const char *cmd, void *arg UNUSED
 #ifdef PY_CAN_RECURSE
        *pygilstate = PyGILState_Ensure();
 #endif
-       if (!(line = GetBufferLine(curbuf, lnum)))
+       /* Check the line number, the command my have deleted lines. */
+       if (lnum > curbuf->b_ml.ml_line_count
+               || !(line = GetBufferLine(curbuf, lnum)))
            goto err;
        if (!(linenr = PyInt_FromLong((long) lnum)))
        {
@@ -5684,9 +5687,19 @@ run_do(const char *cmd, void *arg UNUSED
        if (!ret)
            goto err;
 
+       /* Check that the command didn't switch to another buffer. */
+       if (curbuf != was_curbuf)
+       {
+           Py_XDECREF(ret);
+           goto err;
+       }
+
        if (ret != Py_None)
            if (SetBufferLine(curbuf, lnum, ret, NULL) == FAIL)
+           {
+               Py_XDECREF(ret);
                goto err;
+           }
 
        Py_XDECREF(ret);
        PythonIO_Flush();
index 622634d..6b2ce56 100644 (file)
@@ -1114,6 +1114,9 @@ ex_python(exarg_T *eap)
 {
     char_u *script;
 
+    if (p_pyx == 0)
+       p_pyx = 2;
+
     script = script_get(eap, eap->arg);
     if (!eap->skip)
     {
@@ -1137,6 +1140,9 @@ ex_pyfile(exarg_T *eap)
     const char *file = (char *)eap->arg;
     char *p;
 
+    if (p_pyx == 0)
+       p_pyx = 2;
+
     /* Have to do it like this. PyRun_SimpleFile requires you to pass a
      * stdio file pointer, but Vim and the Python DLL are compiled with
      * different options under Windows, meaning that stdio pointers aren't
@@ -1175,6 +1181,9 @@ ex_pyfile(exarg_T *eap)
     void
 ex_pydo(exarg_T *eap)
 {
+    if (p_pyx == 0)
+       p_pyx = 2;
+
     DoPyCommand((char *)eap->arg,
            (rangeinitializer) init_range_cmd,
            (runner)run_do,
index 53a1313..d68ab85 100644 (file)
@@ -1004,6 +1004,9 @@ ex_py3(exarg_T *eap)
 {
     char_u *script;
 
+    if (p_pyx == 0)
+       p_pyx = 3;
+
     script = script_get(eap, eap->arg);
     if (!eap->skip)
     {
@@ -1028,6 +1031,9 @@ ex_py3file(exarg_T *eap)
     char *p;
     int i;
 
+    if (p_pyx == 0)
+       p_pyx = 3;
+
     /* Have to do it like this. PyRun_SimpleFile requires you to pass a
      * stdio file pointer, but Vim and the Python DLL are compiled with
      * different options under Windows, meaning that stdio pointers aren't
@@ -1080,6 +1086,9 @@ ex_py3file(exarg_T *eap)
     void
 ex_py3do(exarg_T *eap)
 {
+    if (p_pyx == 0)
+       p_pyx = 3;
+
     DoPyCommand((char *)eap->arg,
            (rangeinitializer)init_range_cmd,
            (runner)run_do,
index fc72d33..02b59dd 100644 (file)
@@ -303,6 +303,7 @@ static void ruby_vim_init(void);
 # define ruby_init_loadpath            dll_ruby_init_loadpath
 # ifdef WIN3264
 #  define NtInitialize                 dll_NtInitialize
+#  define ruby_sysinit                 dll_ruby_sysinit
 #  if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
 #   define rb_w32_snprintf             dll_rb_w32_snprintf
 #  endif
@@ -405,6 +406,7 @@ static void (*dll_ruby_init) (void);
 static void (*dll_ruby_init_loadpath) (void);
 # ifdef WIN3264
 static void (*dll_NtInitialize) (int*, char***);
+static void (*dll_ruby_sysinit) (int*, char***);
 #  if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
 static int (*dll_rb_w32_snprintf)(char*, size_t, const char*, ...);
 #  endif
@@ -514,9 +516,10 @@ static struct
 {
     {"rb_assoc_new", (RUBY_PROC*)&dll_rb_assoc_new},
     {"rb_cFalseClass", (RUBY_PROC*)&dll_rb_cFalseClass},
-    {"rb_cFixnum", (RUBY_PROC*)&dll_rb_cFixnum},
 # if defined(USE_RUBY_INTEGER)
     {"rb_cInteger", (RUBY_PROC*)&dll_rb_cInteger},
+# else
+    {"rb_cFixnum", (RUBY_PROC*)&dll_rb_cFixnum},
 # endif
 # if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 20
     {"rb_cFloat", (RUBY_PROC*)&dll_rb_cFloat},
@@ -593,13 +596,11 @@ static struct
     {"ruby_init", (RUBY_PROC*)&dll_ruby_init},
     {"ruby_init_loadpath", (RUBY_PROC*)&dll_ruby_init_loadpath},
 # ifdef WIN3264
-    {
 #  if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER < 19
-    "NtInitialize",
+    {"NtInitialize", (RUBY_PROC*)&dll_NtInitialize},
 #  else
-    "ruby_sysinit",
+    {"ruby_sysinit", (RUBY_PROC*)&dll_ruby_sysinit},
 #  endif
-                       (RUBY_PROC*)&dll_NtInitialize},
 #  if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
     {"rb_w32_snprintf", (RUBY_PROC*)&dll_rb_w32_snprintf},
 #  endif
@@ -782,6 +783,7 @@ void ex_rubydo(exarg_T *eap)
 {
     int state;
     linenr_T i;
+    buf_T   *was_curbuf = curbuf;
 
     if (ensure_ruby_initialized())
     {
@@ -791,6 +793,8 @@ void ex_rubydo(exarg_T *eap)
        {
            VALUE line;
 
+           if (i > curbuf->b_ml.ml_line_count)
+               break;
            line = vim_str2rb_enc_str((char *)ml_get(i));
            rb_lastline_set(line);
            eval_enc_string_protect((char *) eap->arg, &state);
@@ -799,6 +803,8 @@ void ex_rubydo(exarg_T *eap)
                error_print(state);
                break;
            }
+           if (was_curbuf != curbuf)
+               break;
            line = rb_lastline_get();
            if (!NIL_P(line))
            {
@@ -861,7 +867,11 @@ static int ensure_ruby_initialized(void)
            int argc = 1;
            char *argv[] = {"gvim.exe"};
            char **argvp = argv;
+# ifdef RUBY19_OR_LATER
+           ruby_sysinit(&argc, &argvp);
+# else
            NtInitialize(&argc, &argvp);
+# endif
 #endif
            {
 #if defined(RUBY19_OR_LATER) || defined(RUBY_INIT_STACK)
index 1e856c7..9b47f1b 100644 (file)
@@ -1958,6 +1958,7 @@ ex_tcldo(exarg_T *eap)
     char       var_line[VARNAME_SIZE];
     linenr_T   first_line = 0;
     linenr_T   last_line = 0;
+    buf_T      *was_curbuf = curbuf;
 
     rs = eap->line1;
     re = eap->line2;
@@ -1979,6 +1980,8 @@ ex_tcldo(exarg_T *eap)
     }
     while (err == TCL_OK  &&  rs <= re)
     {
+       if ((linenr_T)rs > curbuf->b_ml.ml_line_count)
+           break;
        line = (char *)ml_get_buf(curbuf, (linenr_T)rs, FALSE);
        if (!line)
        {
@@ -1994,7 +1997,7 @@ ex_tcldo(exarg_T *eap)
 #if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 5) || TCL_MAJOR_VERSION > 8
            || Tcl_LimitExceeded(tclinfo.interp)
 #endif
-          )
+           || curbuf != was_curbuf)
            break;
        line = (char *)Tcl_GetVar(tclinfo.interp, var_line, 0);
        if (line)
index d597154..4c3c012 100644 (file)
@@ -231,7 +231,7 @@ serverRegisterName(
            if (res < -1 || i >= 1000)
            {
                MSG_ATTR(_("Unable to register a command server name"),
-                                                             hl_attr(HLF_W));
+                                                             HL_ATTR(HLF_W));
                return FAIL;
            }
            if (p == NULL)
@@ -373,6 +373,7 @@ serverSendToVim(
     char_u     **result,               /* Result of eval'ed expression */
     Window     *server,                /* Actual ID of receiving app */
     Bool       asExpr,                 /* Interpret as keystrokes or expr ? */
+    int                timeout,                /* seconds to wait or zero */
     Bool       localLoop,              /* Throw away everything but result */
     int                silent)                 /* don't complain about no server */
 {
@@ -399,27 +400,7 @@ serverSendToVim(
 
     /* Execute locally if no display or target is ourselves */
     if (dpy == NULL || (serverName != NULL && STRICMP(name, serverName) == 0))
-    {
-       if (asExpr)
-       {
-           char_u *ret;
-
-           ret = eval_client_expr_to_string(cmd);
-           if (result != NULL)
-           {
-               if (ret == NULL)
-                   *result = vim_strsave((char_u *)_(e_invexprmsg));
-               else
-                   *result = ret;
-           }
-           else
-               vim_free(ret);
-           return ret == NULL ? -1 : 0;
-       }
-       else
-           server_to_input_buf(cmd);
-       return 0;
-    }
+       return sendToLocalVim(cmd, asExpr, result);
 
     /*
      * Bind the server name to a communication window.
@@ -505,7 +486,8 @@ serverSendToVim(
     pending.nextPtr = pendingCommands;
     pendingCommands = &pending;
 
-    ServerWait(dpy, w, WaitForPend, &pending, localLoop, 600);
+    ServerWait(dpy, w, WaitForPend, &pending, localLoop,
+                                                 timeout > 0 ? timeout : 600);
 
     /*
      * Unregister the information about the pending command
@@ -616,6 +598,10 @@ ServerWait(
        if (seconds >= 0 && (now - start) >= seconds)
            break;
 
+#ifdef FEAT_TIMERS
+       check_due_timer();
+#endif
+
        /* Just look out for the answer without calling back into Vim */
        if (localLoop)
        {
@@ -800,11 +786,13 @@ serverSendReply(char_u *name, char_u *str)
 WaitForReply(void *p)
 {
     Window  *w = (Window *) p;
+
     return ServerReplyFind(*w, SROP_Find) != NULL;
 }
 
 /*
  * Wait for replies from id (win)
+ * When "timeout" is non-zero wait up to this many seconds.
  * Return 0 and the malloc'ed string when a reply is available.
  * Return -1 if the window becomes invalid while waiting.
  */
@@ -813,13 +801,15 @@ serverReadReply(
     Display    *dpy,
     Window     win,
     char_u     **str,
-    int                localLoop)
+    int                localLoop,
+    int                timeout)
 {
     int                len;
     char_u     *s;
     struct     ServerReply *p;
 
-    ServerWait(dpy, win, WaitForReply, &win, localLoop, -1);
+    ServerWait(dpy, win, WaitForReply, &win, localLoop,
+                                                  timeout > 0 ? timeout : -1);
 
     if ((p = ServerReplyFind(win, SROP_Find)) != NULL && p->strings.ga_len > 0)
     {
@@ -1449,8 +1439,8 @@ server_parse_message(
            char_u      *enc;
 
            /*
-            * This is a (n)otification.  Sent with serverreply_send in VimL.
-            * Execute any autocommand and save it for later retrieval
+            * This is a (n)otification.  Sent with serverreply_send in Vim
+            * script.  Execute any autocommand and save it for later retrieval
             */
            p += 2;
            gotWindow = 0;
diff --git a/src/install-sh b/src/install-sh
new file mode 100755 (executable)
index 0000000..0b0fdcb
--- /dev/null
@@ -0,0 +1,501 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2013-12-25.23; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# 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
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# 'make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+tab='  '
+nl='
+'
+IFS=" $tab$nl"
+
+# Set DOITPROG to "echo" to test this script.
+
+doit=${DOITPROG-}
+doit_exec=${doit:-exec}
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+is_target_a_directory=possibly
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+        shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+        case $mode in
+          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
+            echo "$0: invalid mode: $mode" >&2
+            exit 1;;
+        esac
+        shift;;
+
+    -o) chowncmd="$chownprog $2"
+        shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -t)
+        is_target_a_directory=always
+        dst_arg=$2
+        # Protect names problematic for 'test' and other utilities.
+        case $dst_arg in
+          -* | [=\(\)!]) dst_arg=./$dst_arg;;
+        esac
+        shift;;
+
+    -T) is_target_a_directory=never;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --) shift
+        break;;
+
+    -*) echo "$0: invalid option: $1" >&2
+        exit 1;;
+
+    *)  break;;
+  esac
+  shift
+done
+
+# We allow the use of options -d and -T together, by making -d
+# take the precedence; this is for compatibility with GNU install.
+
+if test -n "$dir_arg"; then
+  if test -n "$dst_arg"; then
+    echo "$0: target directory not allowed when installing a directory." >&2
+    exit 1
+  fi
+fi
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+    # Protect names problematic for 'test' and other utilities.
+    case $dst_arg in
+      -* | [=\(\)!]) dst_arg=./$dst_arg;;
+    esac
+  done
+fi
+
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call 'install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  if test $# -gt 1 || test "$is_target_a_directory" = always; then
+    if test ! -d "$dst_arg"; then
+      echo "$0: $dst_arg: Is not a directory." >&2
+      exit 1
+    fi
+  fi
+fi
+
+if test -z "$dir_arg"; then
+  do_exit='(exit $ret); exit $ret'
+  trap "ret=129; $do_exit" 1
+  trap "ret=130; $do_exit" 2
+  trap "ret=141; $do_exit" 13
+  trap "ret=143; $do_exit" 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+        u_plus_rw=
+      else
+        u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+        u_plus_rw=
+      else
+        u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names problematic for 'test' and other utilities.
+  case $src in
+    -* | [=\(\)!]) src=./$src;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+    dst=$dst_arg
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test "$is_target_a_directory" = never; then
+        echo "$0: $dst_arg: Is a directory" >&2
+        exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      dstdir=`dirname "$dst"`
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+        # Create intermediate dirs using mode 755 as modified by the umask.
+        # This is like FreeBSD 'install' as of 1997-10-28.
+        umask=`umask`
+        case $stripcmd.$umask in
+          # Optimize common cases.
+          *[2367][2367]) mkdir_umask=$umask;;
+          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+          *[0-7])
+            mkdir_umask=`expr $umask + 22 \
+              - $umask % 100 % 40 + $umask % 20 \
+              - $umask % 10 % 4 + $umask % 2
+            `;;
+          *) mkdir_umask=$umask,go-w;;
+        esac
+
+        # With -d, create the new directory with the user-specified mode.
+        # Otherwise, rely on $mkdir_umask.
+        if test -n "$dir_arg"; then
+          mkdir_mode=-m$mode
+        else
+          mkdir_mode=
+        fi
+
+        posix_mkdir=false
+        case $umask in
+          *[123567][0-7][0-7])
+            # POSIX mkdir -p sets u+wx bits regardless of umask, which
+            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+            ;;
+          *)
+            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+            trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+            if (umask $mkdir_umask &&
+                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+            then
+              if test -z "$dir_arg" || {
+                   # Check for POSIX incompatibilities with -m.
+                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+                   # other-writable bit of parent directory when it shouldn't.
+                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+                   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+                   case $ls_ld_tmpdir in
+                     d????-?r-*) different_mode=700;;
+                     d????-?--*) different_mode=755;;
+                     *) false;;
+                   esac &&
+                   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+                     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+                   }
+                 }
+              then posix_mkdir=:
+              fi
+              rmdir "$tmpdir/d" "$tmpdir"
+            else
+              # Remove any dirs left behind by ancient mkdir implementations.
+              rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+            fi
+            trap '' 0;;
+        esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+        umask $mkdir_umask &&
+        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+        /*) prefix='/';;
+        [-=\(\)!]*) prefix='./';;
+        *)  prefix='';;
+      esac
+
+      oIFS=$IFS
+      IFS=/
+      set -f
+      set fnord $dstdir
+      shift
+      set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+        test X"$d" = X && continue
+
+        prefix=$prefix$d
+        if test -d "$prefix"; then
+          prefixes=
+        else
+          if $posix_mkdir; then
+            (umask=$mkdir_umask &&
+             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+            # Don't fail if two instances are running concurrently.
+            test -d "$prefix" || exit 1
+          else
+            case $prefix in
+              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+              *) qprefix=$prefix;;
+            esac
+            prefixes="$prefixes '$qprefix'"
+          fi
+        fi
+        prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+        # Don't fail if two instances are running concurrently.
+        (umask $mkdir_umask &&
+         eval "\$doit_exec \$mkdirprog $prefixes") ||
+          test -d "$dstdir" || exit 1
+        obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
+       set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       set +f &&
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+        # Now remove or move aside any old file at destination location.
+        # We try this two ways since rm can't unlink itself on some
+        # systems and the destination file might be busy for other
+        # reasons.  In this case, the final cleanup might fail but the new
+        # file should still install successfully.
+        {
+          test ! -f "$dst" ||
+          $doit $rmcmd -f "$dst" 2>/dev/null ||
+          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+          } ||
+          { echo "$0: cannot unlink or rename $dst" >&2
+            (exit 1); exit 1
+          }
+        } &&
+
+        # Now rename the file to the real destination.
+        $doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
index 0ac6c46..a2f09ad 100755 (executable)
@@ -39,7 +39,7 @@ tutorsubloc=$scriptloc/tutor
 if test $what = "install" -o $what = "xxd"; then
    if test ! -d $destdir; then
       echo creating $destdir
-      ./mkinstalldirs $destdir
+      /bin/sh install-sh -c -d $destdir
    fi
 fi
 
index e6dc3d8..8649c6f 100755 (executable)
@@ -49,7 +49,7 @@ eviewname=$9
 if test $what = "install" -a \( -f $destdir/$vimname.1 -o -f $destdir/$vimdiffname.1 -o -f $destdir/$eviewname.1 \); then
    if test ! -d $destdir; then
       echo creating $destdir
-      ./mkinstalldirs $destdir
+      /bin/sh install-sh -c -d $destdir
    fi
 
    # ex
index 36d47aa..e5e85eb 100644 (file)
@@ -328,7 +328,7 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options)
            break;
 #endif
        case VAR_UNKNOWN:
-           EMSG2(_(e_intern2), "json_encode_item()");
+           internal_error("json_encode_item()");
            return FAIL;
     }
     return OK;
@@ -378,176 +378,7 @@ json_skip_white(js_read_T *reader)
 }
 
     static int
-json_decode_array(js_read_T *reader, typval_T *res, int options)
-{
-    char_u     *p;
-    typval_T   item;
-    listitem_T *li;
-    int                ret;
-
-    if (res != NULL && rettv_list_alloc(res) == FAIL)
-    {
-       res->v_type = VAR_SPECIAL;
-       res->vval.v_number = VVAL_NONE;
-       return FAIL;
-    }
-    ++reader->js_used; /* consume the '[' */
-
-    while (TRUE)
-    {
-       json_skip_white(reader);
-       p = reader->js_buf + reader->js_used;
-       if (*p == NUL)
-           return MAYBE;
-       if (*p == ']')
-       {
-           ++reader->js_used; /* consume the ']' */
-           break;
-       }
-
-       ret = json_decode_item(reader, res == NULL ? NULL : &item, options);
-       if (ret != OK)
-           return ret;
-       if (res != NULL)
-       {
-           li = listitem_alloc();
-           if (li == NULL)
-           {
-               clear_tv(&item);
-               return FAIL;
-           }
-           li->li_tv = item;
-           list_append(res->vval.v_list, li);
-       }
-
-       json_skip_white(reader);
-       p = reader->js_buf + reader->js_used;
-       if (*p == ',')
-           ++reader->js_used;
-       else if (*p != ']')
-       {
-           if (*p == NUL)
-               return MAYBE;
-           return FAIL;
-       }
-    }
-    return OK;
-}
-
-    static int
-json_decode_object(js_read_T *reader, typval_T *res, int options)
-{
-    char_u     *p;
-    typval_T   tvkey;
-    typval_T   item;
-    dictitem_T *di;
-    char_u     buf[NUMBUFLEN];
-    char_u     *key = NULL;
-    int                ret;
-
-    if (res != NULL && rettv_dict_alloc(res) == FAIL)
-    {
-       res->v_type = VAR_SPECIAL;
-       res->vval.v_number = VVAL_NONE;
-       return FAIL;
-    }
-    ++reader->js_used; /* consume the '{' */
-
-    while (TRUE)
-    {
-       json_skip_white(reader);
-       p = reader->js_buf + reader->js_used;
-       if (*p == NUL)
-           return MAYBE;
-       if (*p == '}')
-       {
-           ++reader->js_used; /* consume the '}' */
-           break;
-       }
-
-       if ((options & JSON_JS) && reader->js_buf[reader->js_used] != '"')
-       {
-           /* accept a key that is not in quotes */
-           key = p = reader->js_buf + reader->js_used;
-           while (*p != NUL && *p != ':' && *p > ' ')
-               ++p;
-           tvkey.v_type = VAR_STRING;
-           tvkey.vval.v_string = vim_strnsave(key, (int)(p - key));
-           reader->js_used += (int)(p - key);
-           key = tvkey.vval.v_string;
-       }
-       else
-       {
-           ret = json_decode_item(reader, res == NULL ? NULL : &tvkey,
-                                                                    options);
-           if (ret != OK)
-               return ret;
-           if (res != NULL)
-           {
-               key = get_tv_string_buf_chk(&tvkey, buf);
-               if (key == NULL || *key == NUL)
-               {
-                   clear_tv(&tvkey);
-                   return FAIL;
-               }
-           }
-       }
-
-       json_skip_white(reader);
-       p = reader->js_buf + reader->js_used;
-       if (*p != ':')
-       {
-           if (res != NULL)
-               clear_tv(&tvkey);
-           if (*p == NUL)
-               return MAYBE;
-           return FAIL;
-       }
-       ++reader->js_used;
-       json_skip_white(reader);
-
-       ret = json_decode_item(reader, res == NULL ? NULL : &item, options);
-       if (ret != OK)
-       {
-           if (res != NULL)
-               clear_tv(&tvkey);
-           return ret;
-       }
-
-       if (res != NULL)
-       {
-           di = dictitem_alloc(key);
-           clear_tv(&tvkey);
-           if (di == NULL)
-           {
-               clear_tv(&item);
-               return FAIL;
-           }
-           di->di_tv = item;
-           di->di_tv.v_lock = 0;
-           if (dict_add(res->vval.v_dict, di) == FAIL)
-           {
-               dictitem_free(di);
-               return FAIL;
-           }
-       }
-
-       json_skip_white(reader);
-       p = reader->js_buf + reader->js_used;
-       if (*p == ',')
-           ++reader->js_used;
-       else if (*p != '}')
-       {
-           if (*p == NUL)
-               return MAYBE;
-           return FAIL;
-       }
-    }
-    return OK;
-}
-
-    static int
-json_decode_string(js_read_T *reader, typval_T *res)
+json_decode_string(js_read_T *reader, typval_T *res, int quote)
 {
     garray_T    ga;
     int                len;
@@ -558,8 +389,8 @@ json_decode_string(js_read_T *reader, typval_T *res)
     if (res != NULL)
        ga_init2(&ga, 1, 200);
 
-    p = reader->js_buf + reader->js_used + 1; /* skip over " */
-    while (*p != '"')
+    p = reader->js_buf + reader->js_used + 1; /* skip over " or ' */
+    while (*p != quote)
     {
        /* The JSON is always expected to be utf-8, thus use utf functions
         * here. The string is converted below if needed. */
@@ -673,7 +504,7 @@ json_decode_string(js_read_T *reader, typval_T *res)
     }
 
     reader->js_used = (int)(p - reader->js_buf);
-    if (*p == '"')
+    if (*p == quote)
     {
        ++reader->js_used;
        if (res != NULL)
@@ -711,11 +542,24 @@ json_decode_string(js_read_T *reader, typval_T *res)
     return MAYBE;
 }
 
+typedef enum {
+    JSON_ARRAY,                /* parsing items in an array */
+    JSON_OBJECT_KEY,   /* parsing key of an object */
+    JSON_OBJECT                /* parsing item in an object, after the key */
+} json_decode_T;
+
+typedef struct {
+    json_decode_T jd_type;
+    typval_T     jd_tv;        /* the list or dict */
+    typval_T     jd_key_tv;
+    char_u       *jd_key;
+} json_dec_item_T;
+
 /*
  * Decode one item and put it in "res".  If "res" is NULL only advance.
  * Must already have skipped white space.
  *
- * Return FAIL for a decoding error.
+ * Return FAIL for a decoding error (and give an error).
  * Return MAYBE for an incomplete message.
  */
     static int
@@ -723,150 +567,441 @@ json_decode_item(js_read_T *reader, typval_T *res, int options)
 {
     char_u     *p;
     int                len;
+    int                retval;
+    garray_T   stack;
+    typval_T   item;
+    typval_T   *cur_item;
+    json_dec_item_T *top_item;
+    char_u     key_buf[NUMBUFLEN];
+
+    ga_init2(&stack, sizeof(json_dec_item_T), 100);
+    cur_item = res;
+    init_tv(&item);
+    if (res != NULL)
+    init_tv(res);
 
     fill_numbuflen(reader);
     p = reader->js_buf + reader->js_used;
-    switch (*p)
+    for (;;)
     {
-       case '[': /* array */
-           return json_decode_array(reader, res, options);
-
-       case '{': /* object */
-           return json_decode_object(reader, res, options);
+       top_item = NULL;
+       if (stack.ga_len > 0)
+       {
+           top_item = ((json_dec_item_T *)stack.ga_data) + stack.ga_len - 1;
+           json_skip_white(reader);
+           p = reader->js_buf + reader->js_used;
+           if (*p == NUL)
+           {
+               retval = MAYBE;
+               if (top_item->jd_type == JSON_OBJECT)
+                   /* did get the key, clear it */
+                   clear_tv(&top_item->jd_key_tv);
+               goto theend;
+           }
+           if (top_item->jd_type == JSON_OBJECT_KEY
+                                           || top_item->jd_type == JSON_ARRAY)
+           {
+               /* Check for end of object or array. */
+               if (*p == (top_item->jd_type == JSON_ARRAY ? ']' : '}'))
+               {
+                   ++reader->js_used; /* consume the ']' or '}' */
+                   --stack.ga_len;
+                   if (stack.ga_len == 0)
+                   {
+                       retval = OK;
+                       goto theend;
+                   }
+                   if (cur_item != NULL)
+                       cur_item = &top_item->jd_tv;
+                   goto item_end;
+               }
+           }
+       }
 
-       case '"': /* string */
-           return json_decode_string(reader, res);
+       if (top_item != NULL && top_item->jd_type == JSON_OBJECT_KEY
+               && (options & JSON_JS)
+               && reader->js_buf[reader->js_used] != '"'
+               && reader->js_buf[reader->js_used] != '\'')
+       {
+           char_u *key;
 
-       case ',': /* comma: empty item */
-           if ((options & JSON_JS) == 0)
-               return FAIL;
-           /* FALLTHROUGH */
-       case NUL: /* empty */
-           if (res != NULL)
+           /* accept an object key that is not in quotes */
+           key = p = reader->js_buf + reader->js_used;
+           while (*p != NUL && *p != ':' && *p > ' ')
+               ++p;
+           if (cur_item != NULL)
            {
-               res->v_type = VAR_SPECIAL;
-               res->vval.v_number = VVAL_NONE;
+               cur_item->v_type = VAR_STRING;
+               cur_item->vval.v_string = vim_strnsave(key, (int)(p - key));
+               top_item->jd_key = cur_item->vval.v_string;
            }
-           return OK;
-
-       default:
-           if (VIM_ISDIGIT(*p) || *p == '-')
+           reader->js_used += (int)(p - key);
+       }
+       else
+       {
+           switch (*p)
            {
-#ifdef FEAT_FLOAT
-               char_u  *sp = p;
+               case '[': /* start of array */
+                   if (ga_grow(&stack, 1) == FAIL)
+                   {
+                       retval = FAIL;
+                       break;
+                   }
+                   if (cur_item != NULL && rettv_list_alloc(cur_item) == FAIL)
+                   {
+                       cur_item->v_type = VAR_SPECIAL;
+                       cur_item->vval.v_number = VVAL_NONE;
+                       retval = FAIL;
+                       break;
+                   }
 
-               if (*sp == '-')
-               {
-                   ++sp;
-                   if (*sp == NUL)
-                       return MAYBE;
-                   if (!VIM_ISDIGIT(*sp))
-                       return FAIL;
-               }
-               sp = skipdigits(sp);
-               if (*sp == '.' || *sp == 'e' || *sp == 'E')
-               {
-                   if (res == NULL)
+                   ++reader->js_used; /* consume the '[' */
+                   top_item = ((json_dec_item_T *)stack.ga_data)
+                                                               + stack.ga_len;
+                   top_item->jd_type = JSON_ARRAY;
+                   ++stack.ga_len;
+                   if (cur_item != NULL)
+                   {
+                       top_item->jd_tv = *cur_item;
+                       cur_item = &item;
+                   }
+                   continue;
+
+               case '{': /* start of object */
+                   if (ga_grow(&stack, 1) == FAIL)
+                   {
+                       retval = FAIL;
+                       break;
+                   }
+                   if (cur_item != NULL && rettv_dict_alloc(cur_item) == FAIL)
                    {
-                       float_T f;
+                       cur_item->v_type = VAR_SPECIAL;
+                       cur_item->vval.v_number = VVAL_NONE;
+                       retval = FAIL;
+                       break;
+                   }
 
-                       len = string2float(p, &f);
+                   ++reader->js_used; /* consume the '{' */
+                   top_item = ((json_dec_item_T *)stack.ga_data)
+                                                               + stack.ga_len;
+                   top_item->jd_type = JSON_OBJECT_KEY;
+                   ++stack.ga_len;
+                   if (cur_item != NULL)
+                   {
+                       top_item->jd_tv = *cur_item;
+                       cur_item = &top_item->jd_key_tv;
                    }
+                   continue;
+
+               case '"': /* string */
+                   retval = json_decode_string(reader, cur_item, *p);
+                   break;
+
+               case '\'':
+                   if (options & JSON_JS)
+                       retval = json_decode_string(reader, cur_item, *p);
                    else
                    {
-                       res->v_type = VAR_FLOAT;
-                       len = string2float(p, &res->vval.v_float);
+                       EMSG(_(e_invarg));
+                       retval = FAIL;
                    }
-               }
-               else
-#endif
-               {
-                   varnumber_T nr;
+                   break;
 
-                   vim_str2nr(reader->js_buf + reader->js_used,
-                           NULL, &len, 0, /* what */
-                           &nr, NULL, 0);
-                   if (res != NULL)
+               case ',': /* comma: empty item */
+                   if ((options & JSON_JS) == 0)
                    {
-                       res->v_type = VAR_NUMBER;
-                       res->vval.v_number = nr;
+                       EMSG(_(e_invarg));
+                       retval = FAIL;
+                       break;
                    }
-               }
-               reader->js_used += len;
-               return OK;
+                   /* FALLTHROUGH */
+               case NUL: /* empty */
+                   if (cur_item != NULL)
+                   {
+                       cur_item->v_type = VAR_SPECIAL;
+                       cur_item->vval.v_number = VVAL_NONE;
+                   }
+                   retval = OK;
+                   break;
+
+               default:
+                   if (VIM_ISDIGIT(*p) || *p == '-')
+                   {
+#ifdef FEAT_FLOAT
+                       char_u  *sp = p;
+
+                       if (*sp == '-')
+                       {
+                           ++sp;
+                           if (*sp == NUL)
+                           {
+                               retval = MAYBE;
+                               break;
+                           }
+                           if (!VIM_ISDIGIT(*sp))
+                           {
+                               EMSG(_(e_invarg));
+                               retval = FAIL;
+                               break;
+                           }
+                       }
+                       sp = skipdigits(sp);
+                       if (*sp == '.' || *sp == 'e' || *sp == 'E')
+                       {
+                           if (cur_item == NULL)
+                           {
+                               float_T f;
+
+                               len = string2float(p, &f);
+                           }
+                           else
+                           {
+                               cur_item->v_type = VAR_FLOAT;
+                               len = string2float(p, &cur_item->vval.v_float);
+                           }
+                       }
+                       else
+#endif
+                       {
+                           varnumber_T nr;
+
+                           vim_str2nr(reader->js_buf + reader->js_used,
+                                   NULL, &len, 0, /* what */
+                                   &nr, NULL, 0);
+                           if (cur_item != NULL)
+                           {
+                               cur_item->v_type = VAR_NUMBER;
+                               cur_item->vval.v_number = nr;
+                           }
+                       }
+                       reader->js_used += len;
+                       retval = OK;
+                       break;
+                   }
+                   if (STRNICMP((char *)p, "false", 5) == 0)
+                   {
+                       reader->js_used += 5;
+                       if (cur_item != NULL)
+                       {
+                           cur_item->v_type = VAR_SPECIAL;
+                           cur_item->vval.v_number = VVAL_FALSE;
+                       }
+                       retval = OK;
+                       break;
+                   }
+                   if (STRNICMP((char *)p, "true", 4) == 0)
+                   {
+                       reader->js_used += 4;
+                       if (cur_item != NULL)
+                       {
+                           cur_item->v_type = VAR_SPECIAL;
+                           cur_item->vval.v_number = VVAL_TRUE;
+                       }
+                       retval = OK;
+                       break;
+                   }
+                   if (STRNICMP((char *)p, "null", 4) == 0)
+                   {
+                       reader->js_used += 4;
+                       if (cur_item != NULL)
+                       {
+                           cur_item->v_type = VAR_SPECIAL;
+                           cur_item->vval.v_number = VVAL_NULL;
+                       }
+                       retval = OK;
+                       break;
+                   }
+#ifdef FEAT_FLOAT
+                   if (STRNICMP((char *)p, "NaN", 3) == 0)
+                   {
+                       reader->js_used += 3;
+                       if (cur_item != NULL)
+                       {
+                           cur_item->v_type = VAR_FLOAT;
+                           cur_item->vval.v_float = NAN;
+                       }
+                       retval = OK;
+                       break;
+                   }
+                   if (STRNICMP((char *)p, "Infinity", 8) == 0)
+                   {
+                       reader->js_used += 8;
+                       if (cur_item != NULL)
+                       {
+                           cur_item->v_type = VAR_FLOAT;
+                           cur_item->vval.v_float = INFINITY;
+                       }
+                       retval = OK;
+                       break;
+                   }
+#endif
+                   /* check for truncated name */
+                   len = (int)(reader->js_end - (reader->js_buf + reader->js_used));
+                   if (
+                           (len < 5 && STRNICMP((char *)p, "false", len) == 0)
+#ifdef FEAT_FLOAT
+                           || (len < 8 && STRNICMP((char *)p, "Infinity", len) == 0)
+                           || (len < 3 && STRNICMP((char *)p, "NaN", len) == 0)
+#endif
+                           || (len < 4 && (STRNICMP((char *)p, "true", len) == 0
+                                      ||  STRNICMP((char *)p, "null", len) == 0)))
+
+                       retval = MAYBE;
+                   else
+                       retval = FAIL;
+                   break;
            }
-           if (STRNICMP((char *)p, "false", 5) == 0)
+
+           /* We are finished when retval is FAIL or MAYBE and when at the
+            * toplevel. */
+           if (retval == FAIL)
+               break;
+           if (retval == MAYBE || stack.ga_len == 0)
+               goto theend;
+
+           if (top_item != NULL && top_item->jd_type == JSON_OBJECT_KEY
+                   && cur_item != NULL)
            {
-               reader->js_used += 5;
-               if (res != NULL)
+               top_item->jd_key = get_tv_string_buf_chk(cur_item, key_buf);
+               if (top_item->jd_key == NULL)
                {
-                   res->v_type = VAR_SPECIAL;
-                   res->vval.v_number = VVAL_FALSE;
+                   clear_tv(cur_item);
+                   EMSG(_(e_invarg));
+                   retval = FAIL;
+                   goto theend;
                }
-               return OK;
            }
-           if (STRNICMP((char *)p, "true", 4) == 0)
-           {
-               reader->js_used += 4;
+       }
+
+item_end:
+       top_item = ((json_dec_item_T *)stack.ga_data) + stack.ga_len - 1;
+       switch (top_item->jd_type)
+       {
+           case JSON_ARRAY:
                if (res != NULL)
                {
-                   res->v_type = VAR_SPECIAL;
-                   res->vval.v_number = VVAL_TRUE;
+                   listitem_T  *li = listitem_alloc();
+
+                   if (li == NULL)
+                   {
+                       clear_tv(cur_item);
+                       retval = FAIL;
+                       goto theend;
+                   }
+                   li->li_tv = *cur_item;
+                   list_append(top_item->jd_tv.vval.v_list, li);
                }
-               return OK;
-           }
-           if (STRNICMP((char *)p, "null", 4) == 0)
-           {
-               reader->js_used += 4;
-               if (res != NULL)
+               if (cur_item != NULL)
+                   cur_item = &item;
+
+               json_skip_white(reader);
+               p = reader->js_buf + reader->js_used;
+               if (*p == ',')
+                   ++reader->js_used;
+               else if (*p != ']')
                {
-                   res->v_type = VAR_SPECIAL;
-                   res->vval.v_number = VVAL_NULL;
+                   if (*p == NUL)
+                       retval = MAYBE;
+                   else
+                   {
+                       EMSG(_(e_invarg));
+                       retval = FAIL;
+                   }
+                   goto theend;
                }
-               return OK;
-           }
-#ifdef FEAT_FLOAT
-           if (STRNICMP((char *)p, "NaN", 3) == 0)
-           {
-               reader->js_used += 3;
-               if (res != NULL)
+               break;
+
+           case JSON_OBJECT_KEY:
+               json_skip_white(reader);
+               p = reader->js_buf + reader->js_used;
+               if (*p != ':')
                {
-                   res->v_type = VAR_FLOAT;
-                   res->vval.v_float = NAN;
+                   if (cur_item != NULL)
+                       clear_tv(cur_item);
+                   if (*p == NUL)
+                       retval = MAYBE;
+                   else
+                   {
+                       EMSG(_(e_invarg));
+                       retval = FAIL;
+                   }
+                   goto theend;
                }
-               return OK;
-           }
-           if (STRNICMP((char *)p, "Infinity", 8) == 0)
-           {
-               reader->js_used += 8;
-               if (res != NULL)
+               ++reader->js_used;
+               json_skip_white(reader);
+               top_item->jd_type = JSON_OBJECT;
+               if (cur_item != NULL)
+                   cur_item = &item;
+               break;
+
+           case JSON_OBJECT:
+               if (cur_item != NULL
+                       && dict_find(top_item->jd_tv.vval.v_dict,
+                                                top_item->jd_key, -1) != NULL)
                {
-                   res->v_type = VAR_FLOAT;
-                   res->vval.v_float = INFINITY;
+                   EMSG2(_("E938: Duplicate key in JSON: \"%s\""),
+                                                            top_item->jd_key);
+                   clear_tv(&top_item->jd_key_tv);
+                   clear_tv(cur_item);
+                   retval = FAIL;
+                   goto theend;
                }
-               return OK;
-           }
-#endif
-           /* check for truncated name */
-           len = (int)(reader->js_end - (reader->js_buf + reader->js_used));
-           if (
-                   (len < 5 && STRNICMP((char *)p, "false", len) == 0)
-#ifdef FEAT_FLOAT
-                   || (len < 8 && STRNICMP((char *)p, "Infinity", len) == 0)
-                   || (len < 3 && STRNICMP((char *)p, "NaN", len) == 0)
-#endif
-                   || (len < 4 && (STRNICMP((char *)p, "true", len) == 0
-                              ||  STRNICMP((char *)p, "null", len) == 0)))
-               return MAYBE;
-           break;
+
+               if (cur_item != NULL)
+               {
+                   dictitem_T *di = dictitem_alloc(top_item->jd_key);
+
+                   clear_tv(&top_item->jd_key_tv);
+                   if (di == NULL)
+                   {
+                       clear_tv(cur_item);
+                       retval = FAIL;
+                       goto theend;
+                   }
+                   di->di_tv = *cur_item;
+                   di->di_tv.v_lock = 0;
+                   if (dict_add(top_item->jd_tv.vval.v_dict, di) == FAIL)
+                   {
+                       dictitem_free(di);
+                       retval = FAIL;
+                       goto theend;
+                   }
+               }
+
+               json_skip_white(reader);
+               p = reader->js_buf + reader->js_used;
+               if (*p == ',')
+                   ++reader->js_used;
+               else if (*p != '}')
+               {
+                   if (*p == NUL)
+                       retval = MAYBE;
+                   else
+                   {
+                       EMSG(_(e_invarg));
+                       retval = FAIL;
+                   }
+                   goto theend;
+               }
+               top_item->jd_type = JSON_OBJECT_KEY;
+               if (cur_item != NULL)
+                   cur_item = &top_item->jd_key_tv;
+               break;
+       }
     }
 
+    /* Get here when parsing failed. */
     if (res != NULL)
     {
+       clear_tv(res);
        res->v_type = VAR_SPECIAL;
        res->vval.v_number = VVAL_NONE;
     }
-    return FAIL;
+    EMSG(_(e_invarg));
+
+theend:
+    ga_clear(&stack);
+    return retval;
 }
 
 /*
@@ -884,10 +1019,17 @@ json_decode_all(js_read_T *reader, typval_T *res, int options)
     json_skip_white(reader);
     ret = json_decode_item(reader, res, options);
     if (ret != OK)
+    {
+       if (ret == MAYBE)
+           EMSG(_(e_invarg));
        return FAIL;
+    }
     json_skip_white(reader);
     if (reader->js_buf[reader->js_used] != NUL)
+    {
+       EMSG(_(e_trailing));
        return FAIL;
+    }
     return OK;
 }
 
@@ -914,7 +1056,8 @@ json_decode(js_read_T *reader, typval_T *res, int options)
 
 /*
  * Decode the JSON from "reader" to find the end of the message.
- * "options" can be JSON_JS or zero;
+ * "options" can be JSON_JS or zero.
+ * This is only used for testing.
  * Return FAIL if the message has a decoding error.
  * Return MAYBE if the message is truncated, need to read more.
  * This only works reliable if the message contains an object, array or
index 1a1fdcb..c7779b2 100644 (file)
@@ -107,6 +107,12 @@ test_decode_find_end(void)
     reader.js_buf = (char_u *)"  {   ";
     assert(json_find_end(&reader, 0) == MAYBE);
 
+    /* JS object with white space */
+    reader.js_buf = (char_u *)"  {  a  :  123  }  ";
+    assert(json_find_end(&reader, JSON_JS) == OK);
+    reader.js_buf = (char_u *)"  {  a  :   ";
+    assert(json_find_end(&reader, JSON_JS) == MAYBE);
+
     /* array without white space */
     reader.js_buf = (char_u *)"[\"a\",123]";
     assert(json_find_end(&reader, 0) == OK);
@@ -181,7 +187,7 @@ test_fill_called_on_string(void)
     reader.js_buf = (char_u *)" \"foo";
     reader.js_end = reader.js_buf + STRLEN(reader.js_buf);
     reader.js_cookie =        " \"foobar\"  ";
-    assert(json_decode_string(&reader, NULL) == OK);
+    assert(json_decode_string(&reader, NULL, '"') == OK);
 }
 #endif
 
index 1957e98..776a532 100644 (file)
@@ -391,6 +391,8 @@ enum key_extra
 #define K_KMULTIPLY    TERMCAP2KEY('K', '9')   /* keypad * */
 #define K_KENTER       TERMCAP2KEY('K', 'A')   /* keypad Enter */
 #define K_KPOINT       TERMCAP2KEY('K', 'B')   /* keypad . or ,*/
+#define K_PS           TERMCAP2KEY('P', 'S')   /* paste start */
+#define K_PE           TERMCAP2KEY('P', 'E')   /* paste end */
 
 #define K_K0           TERMCAP2KEY('K', 'C')   /* keypad 0 */
 #define K_K1           TERMCAP2KEY('K', 'D')   /* keypad 1 */
@@ -480,9 +482,10 @@ enum key_extra
 
 /*
  * The length of the longest special key name, including modifiers.
- * Current longest is <M-C-S-T-4-MiddleRelease> (length includes '<' and '>').
+ * Current longest is <M-C-S-T-D-A-4-ScrollWheelRight> (length includes '<' and
+ * '>').
  */
-#define MAX_KEY_NAME_LEN    25
+#define MAX_KEY_NAME_LEN    32
 
 /* Maximum length of a special key event as tokens.  This includes modifiers.
  * The longest event is something like <M-C-S-T-4-LeftDrag> which would be the
diff --git a/src/kword_test.c b/src/kword_test.c
new file mode 100644 (file)
index 0000000..2e6640b
--- /dev/null
@@ -0,0 +1,85 @@
+/* vi:set ts=8 sts=4 sw=4 noet:
+ *
+ * VIM - Vi IMproved   by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * kword_test.c: Unittests for vim_iswordc() and vim_iswordp().
+ */
+
+#undef NDEBUG
+#include <assert.h>
+
+/* Must include main.c because it contains much more than just main() */
+#define NO_VIM_MAIN
+#include "main.c"
+
+/* This file has to be included because the tested functions are static */
+#include "charset.c"
+
+#ifdef FEAT_MBYTE
+/*
+ * Test the results of vim_iswordc() and vim_iswordp() are matched.
+ */
+    static void
+test_isword_funcs_utf8(void)
+{
+    buf_T buf;
+    int c;
+
+    vim_memset(&buf, 0, sizeof(buf));
+    p_enc = (char_u *)"utf-8";
+    p_isi = (char_u *)"";
+    p_isp = (char_u *)"";
+    p_isf = (char_u *)"";
+    buf.b_p_isk = (char_u *)"@,48-57,_,128-167,224-235";
+
+    curbuf = &buf;
+    mb_init(); /* calls init_chartab() */
+
+    for (c = 0; c < 0x10000; ++c)
+    {
+       char_u p[4] = {0};
+       int c1;
+       int retc;
+       int retp;
+
+       utf_char2bytes(c, p);
+       c1 = utf_ptr2char(p);
+       if (c != c1)
+       {
+           fprintf(stderr, "Failed: ");
+           fprintf(stderr,
+                   "[c = %#04x, p = {%#02x, %#02x, %#02x}] ",
+                   c, p[0], p[1], p[2]);
+           fprintf(stderr, "c != utf_ptr2char(p) (=%#04x)\n", c1);
+           abort();
+       }
+       retc = vim_iswordc_buf(c, &buf);
+       retp = vim_iswordp_buf(p, &buf);
+       if (retc != retp)
+       {
+           fprintf(stderr, "Failed: ");
+           fprintf(stderr,
+                   "[c = %#04x, p = {%#02x, %#02x, %#02x}] ",
+                   c, p[0], p[1], p[2]);
+           fprintf(stderr, "vim_iswordc(c) (=%d) != vim_iswordp(p) (=%d)\n",
+                   retc, retp);
+           abort();
+       }
+    }
+}
+#endif
+
+    int
+main(void)
+{
+#ifdef FEAT_MBYTE
+    test_isword_funcs_utf8();
+#endif
+    return 0;
+}
index 83caed6..50d38ff 100644 (file)
@@ -885,7 +885,7 @@ failret:
 }
 
 /*
- * Write list of strings to file
+ * Write "list" of strings to file "fd".
  */
     int
 write_list(FILE *fd, list_T *list, int binary)
index faa8ccc..8ebc8ce 100644 (file)
@@ -8,49 +8,58 @@
 
 /*
  * macros.h: macro definitions for often used code
+ *
+ * Macros should be ALL_CAPS.  An exception is for where a function is
+ * replaced and an argument is not used more than once.
  */
 
 /*
- * pchar(lp, c) - put character 'c' at position 'lp'
+ * PCHAR(lp, c) - put character 'c' at position 'lp'
  */
-#define pchar(lp, c) (*(ml_get_buf(curbuf, (lp).lnum, TRUE) + (lp).col) = (c))
+#define PCHAR(lp, c) (*(ml_get_buf(curbuf, (lp).lnum, TRUE) + (lp).col) = (c))
 
 /*
  * Position comparisons
  */
 #ifdef FEAT_VIRTUALEDIT
-# define lt(a, b) (((a).lnum != (b).lnum) \
+# define LT_POS(a, b) (((a).lnum != (b).lnum) \
                   ? (a).lnum < (b).lnum \
                   : (a).col != (b).col \
                       ? (a).col < (b).col \
                       : (a).coladd < (b).coladd)
-# define ltp(a, b) (((a)->lnum != (b)->lnum) \
+# define LT_POSP(a, b) (((a)->lnum != (b)->lnum) \
                   ? (a)->lnum < (b)->lnum \
                   : (a)->col != (b)->col \
                       ? (a)->col < (b)->col \
                       : (a)->coladd < (b)->coladd)
-# define equalpos(a, b) (((a).lnum == (b).lnum) && ((a).col == (b).col) && ((a).coladd == (b).coladd))
-# define clearpos(a) {(a)->lnum = 0; (a)->col = 0; (a)->coladd = 0;}
+# define EQUAL_POS(a, b) (((a).lnum == (b).lnum) && ((a).col == (b).col) && ((a).coladd == (b).coladd))
+# define CLEAR_POS(a) {(a)->lnum = 0; (a)->col = 0; (a)->coladd = 0;}
 #else
-# define lt(a, b) (((a).lnum != (b).lnum) \
+# define LT_POS(a, b) (((a).lnum != (b).lnum) \
                   ? ((a).lnum < (b).lnum) : ((a).col < (b).col))
-# define ltp(a, b) (((a)->lnum != (b)->lnum) \
+# define LT_POSP(a, b) (((a)->lnum != (b)->lnum) \
                   ? ((a)->lnum < (b)->lnum) : ((a)->col < (b)->col))
-# define equalpos(a, b) (((a).lnum == (b).lnum) && ((a).col == (b).col))
-# define clearpos(a) {(a)->lnum = 0; (a)->col = 0;}
+# define EQUAL_POS(a, b) (((a).lnum == (b).lnum) && ((a).col == (b).col))
+# define CLEAR_POS(a) {(a)->lnum = 0; (a)->col = 0;}
 #endif
 
-#define ltoreq(a, b) (lt(a, b) || equalpos(a, b))
+#define LTOREQ_POS(a, b) (LT_POS(a, b) || EQUAL_POS(a, b))
+
+/*
+ * VIM_ISWHITE() is used for "^" and the like. It differs from isspace()
+ * because it doesn't include <CR> and <LF> and the like.
+ */
+#define VIM_ISWHITE(x) ((x) == ' ' || (x) == '\t')
 
 /*
- * lineempty() - return TRUE if the line is empty
+ * LINEEMPTY() - return TRUE if the line is empty
  */
-#define lineempty(p) (*ml_get(p) == NUL)
+#define LINEEMPTY(p) (*ml_get(p) == NUL)
 
 /*
- * bufempty() - return TRUE if the current buffer is empty
+ * BUFEMPTY() - return TRUE if the current buffer is empty
  */
-#define bufempty() (curbuf->b_ml.ml_line_count == 1 && *ml_get((linenr_T)1) == NUL)
+#define BUFEMPTY() (curbuf->b_ml.ml_line_count == 1 && *ml_get((linenr_T)1) == NUL)
 
 /*
  * toupper() and tolower() that use the current locale.
 #endif
 
 /*
- * vim_isbreak() is used very often if 'linebreak' is set, use a macro to make
- * it work fast.
+ * VIM_ISBREAK() is used very often if 'linebreak' is set, use a macro to make
+ * it work fast.  Only works for single byte characters!
  */
-#define vim_isbreak(c) (breakat_flags[(char_u)(c)])
+#define VIM_ISBREAK(c) ((c) < 256 && breakat_flags[(char_u)(c)])
 
 /*
  * On VMS file names are different and require a translation.
 #  define mch_stat(n, p)       vim_stat((n), (p))
 # else
 #  ifdef STAT_IGNORES_SLASH
-    /* On Solaris stat() accepts "file/" as if it was "file".  Return -1 if
-     * the name ends in "/" and it's not a directory. */
-#   define mch_stat(n, p)      (illegal_slash(n) ? -1 : stat((n), (p)))
+#   define mch_stat(n, p)      vim_stat((n), (p))
 #  else
 #   define mch_stat(n, p)      stat((n), (p))
 #  endif
 #endif
 
 /*
- * mb_ptr_adv(): advance a pointer to the next character, taking care of
+ * MB_PTR_ADV(): advance a pointer to the next character, taking care of
  * multi-byte characters if needed.
- * mb_ptr_back(): backup a pointer to the previous character, taking care of
+ * MB_PTR_BACK(): backup a pointer to the previous character, taking care of
  * multi-byte characters if needed.
  * MB_COPY_CHAR(f, t): copy one char from "f" to "t" and advance the pointers.
  * PTR2CHAR(): get character from pointer.
  */
 #ifdef FEAT_MBYTE
 /* Get the length of the character p points to */
-# define MB_PTR2LEN(p)         (has_mbyte ? (*mb_ptr2len)(p) : 1)
+# define MB_PTR2LEN(p)     (has_mbyte ? (*mb_ptr2len)(p) : 1)
 /* Advance multi-byte pointer, skip over composing chars. */
-# define mb_ptr_adv(p)     p += has_mbyte ? (*mb_ptr2len)(p) : 1
+# define MB_PTR_ADV(p)     p += has_mbyte ? (*mb_ptr2len)(p) : 1
 /* Advance multi-byte pointer, do not skip over composing chars. */
-# define mb_cptr_adv(p)            p += enc_utf8 ? utf_ptr2len(p) : has_mbyte ? (*mb_ptr2len)(p) : 1
+# define MB_CPTR_ADV(p)            p += enc_utf8 ? utf_ptr2len(p) : has_mbyte ? (*mb_ptr2len)(p) : 1
 /* Backup multi-byte pointer. Only use with "p" > "s" ! */
-# define mb_ptr_back(s, p)  p -= has_mbyte ? ((*mb_head_off)(s, p - 1) + 1) : 1
+# define MB_PTR_BACK(s, p)  p -= has_mbyte ? ((*mb_head_off)(s, p - 1) + 1) : 1
 /* get length of multi-byte char, not including composing chars */
 # define MB_CPTR2LEN(p)            (enc_utf8 ? utf_ptr2len(p) : (*mb_ptr2len)(p))
 
 #else
 # define MB_PTR2LEN(p)         1
 # define MB_CPTR2LEN(p)                1
-# define mb_ptr_adv(p)         ++p
-# define mb_cptr_adv(p)                ++p
-# define mb_ptr_back(s, p)     --p
+# define MB_PTR_ADV(p)         ++p
+# define MB_CPTR_ADV(p)                ++p
+# define MB_PTR_BACK(s, p)     --p
 # define MB_COPY_CHAR(f, t)    *t++ = *f++
 # define MB_CHARLEN(p)         STRLEN(p)
 # define MB_CHAR2LEN(c)                1
index bedbbb5..19bc97d 100644 (file)
     # A U T O C O N F
     #
 
-    # Run autoconf when configure.in has been changed since it was last run.
+    # Run autoconf when configure.ac has been changed since it was last run.
     # This is skipped when the signatures in "mysign" are up-to-date.  When
     # there is no autoconf program skip this (the signature is often the only
     # thing that's outdated)
-    auto/configure {signfile = mysign} : configure.in
+    auto/configure {signfile = mysign} : configure.ac
         @if not program_path("autoconf"):
             :print Can't find autoconf, using existing configure script.
         @else:
index acc51f1..883c9cc 100644 (file)
@@ -57,6 +57,9 @@ static void main_start_gui(void);
 # if defined(HAS_SWAP_EXISTS_ACTION)
 static void check_swap_exists_action(void);
 # endif
+# ifdef FEAT_EVAL
+static void set_progpath(char_u *argv0);
+# endif
 # if defined(FEAT_CLIENTSERVER) || defined(PROTO)
 static void exec_on_server(mparm_T *parmp);
 static void prepare_server(mparm_T *parmp);
@@ -86,15 +89,16 @@ static char *(main_errors[]) =
 };
 
 #ifndef PROTO          /* don't want a prototype for main() */
+
+/* Various parameters passed between main() and other functions. */
+static mparm_T params;
+
 #ifndef NO_VIM_MAIN    /* skip this for unittests */
 
 static char_u *start_dir = NULL;       /* current working dir on startup */
 
 static int has_dash_c_arg = FALSE;
 
-/* Various parameters passed between main() and other functions. */
-static mparm_T params;
-
     int
 # ifdef VIMDLL
 _export
@@ -556,11 +560,16 @@ vim_main2(void)
      */
     if (params.edit_type == EDIT_QF)
     {
+       char_u  *enc = NULL;
+
+# ifdef FEAT_MBYTE
+       enc = p_menc;
+# endif
        if (params.use_ef != NULL)
            set_string_option_direct((char_u *)"ef", -1,
                                           params.use_ef, OPT_FREE, SID_CARG);
        vim_snprintf((char *)IObuff, IOSIZE, "cfile %s", p_ef);
-       if (qf_init(NULL, p_ef, p_efm, TRUE, IObuff) < 0)
+       if (qf_init(NULL, p_ef, p_efm, TRUE, IObuff, enc) < 0)
        {
            out_char('\n');
            mch_exit(3);
@@ -657,12 +666,6 @@ vim_main2(void)
 
     starttermcap();        /* start termcap if not done by wait_return() */
     TIME_MSG("start termcap");
-#if defined(FEAT_TERMRESPONSE)
-# if defined(FEAT_MBYTE)
-    may_req_ambiguous_char_width();
-# endif
-    may_req_bg_color();
-#endif
 
 #ifdef FEAT_MOUSE
     setmouse();                                /* may start using the mouse */
@@ -792,6 +795,11 @@ vim_main2(void)
     /* Requesting the termresponse is postponed until here, so that a "-c q"
      * argument doesn't make it appear in the shell Vim was started from. */
     may_req_termresponse();
+
+# if defined(FEAT_MBYTE)
+    may_req_ambiguous_char_width();
+# endif
+    may_req_bg_color();
 #endif
 
     /* start in insert mode */
@@ -973,7 +981,7 @@ common_init(mparm_T *paramp)
      * (needed for :! to * work). mch_check_win() will also handle the -d or
      * -dev argument.
      */
-    paramp->stdout_isatty = (mch_check_win(paramp->argc, paramp->argv) != FAIL);
+    stdout_isatty = (mch_check_win(paramp->argc, paramp->argv) != FAIL);
     TIME_MSG("window checked");
 
     /*
@@ -1005,6 +1013,15 @@ common_init(mparm_T *paramp)
 }
 
 /*
+ * Return TRUE when the --not-a-term argument was found.
+ */
+    int
+is_not_a_term()
+{
+    return params.not_a_term;
+}
+
+/*
  * Main loop: Execute Normal mode commands until exiting Vim.
  * Also used to handle commands in the command-line window, until the window
  * is closed.
@@ -1118,6 +1135,10 @@ main_loop(
            skip_redraw = FALSE;
        else if (do_redraw || stuff_empty())
        {
+# ifdef FEAT_GUI
+           /* If ui_breakcheck() was used a resize may have been postponed. */
+           gui_may_resize_shell();
+# endif
 #if defined(FEAT_AUTOCMD) || defined(FEAT_CONCEAL)
            /* Trigger CursorMoved if the cursor moved. */
            if (!finish_op && (
@@ -1132,7 +1153,7 @@ main_loop(
 # endif
                        )
 # ifdef FEAT_AUTOCMD
-                && !equalpos(last_cursormoved, curwin->w_cursor)
+                && !EQUAL_POS(last_cursormoved, curwin->w_cursor)
 # endif
                 )
            {
@@ -1158,15 +1179,15 @@ main_loop(
 #endif
 
 #ifdef FEAT_AUTOCMD
-           /* Trigger TextChanged if b_changedtick differs. */
+           /* Trigger TextChanged if b:changedtick differs. */
            if (!finish_op && has_textchanged()
-                   && last_changedtick != curbuf->b_changedtick)
+                   && last_changedtick != CHANGEDTICK(curbuf))
            {
                if (last_changedtick_buf == curbuf)
                    apply_autocmds(EVENT_TEXTCHANGED, NULL, NULL,
                                                               FALSE, curbuf);
                last_changedtick_buf = curbuf;
-               last_changedtick = curbuf->b_changedtick;
+               last_changedtick = CHANGEDTICK(curbuf);
            }
 #endif
 
@@ -1384,11 +1405,11 @@ getout(int exitval)
                    /* Autocmd must have close the buffer already, skip. */
                    continue;
                buf = wp->w_buffer;
-               if (buf->b_changedtick != -1)
+               if (CHANGEDTICK(buf) != -1)
                {
                    apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname,
                                                    buf->b_fname, FALSE, buf);
-                   buf->b_changedtick = -1;  /* note that we did it already */
+                   CHANGEDTICK(buf) = -1;  /* note that we did it already */
                    /* start all over, autocommands may mess up the lists */
                    next_tp = first_tabpage;
                    break;
@@ -1690,7 +1711,7 @@ parse_command_name(mparm_T *parmp)
 
 #ifdef FEAT_EVAL
     set_vim_var_string(VV_PROGNAME, initstr, -1);
-    set_vim_var_string(VV_PROGPATH, (char_u *)parmp->argv[0], -1);
+    set_progpath((char_u *)parmp->argv[0]);
 #endif
 
     if (TOLOWER_ASC(initstr[0]) == 'r')
@@ -1828,6 +1849,7 @@ command_line_scan(mparm_T *parmp)
                                /* "--literal" take files literally */
                                /* "--nofork" don't fork */
                                /* "--not-a-term" don't warn for not a term */
+                               /* "--ttyfail" exit if not a term */
                                /* "--noplugin[s]" skip plugins */
                                /* "--cmd <cmd>" execute cmd before vimrc */
                if (STRICMP(argv[0] + argv_idx, "help") == 0)
@@ -1857,6 +1879,8 @@ command_line_scan(mparm_T *parmp)
                    p_lpl = FALSE;
                else if (STRNICMP(argv[0] + argv_idx, "not-a-term", 10) == 0)
                    parmp->not_a_term = TRUE;
+               else if (STRNICMP(argv[0] + argv_idx, "ttyfail", 7) == 0)
+                   parmp->tty_fail = TRUE;
                else if (STRNICMP(argv[0] + argv_idx, "cmd", 3) == 0)
                {
                    want_argument = TRUE;
@@ -2489,7 +2513,7 @@ check_tty(mparm_T *parmp)
        if (!input_isatty)
            silent_mode = TRUE;
     }
-    else if (parmp->want_full_screen && (!parmp->stdout_isatty || !input_isatty)
+    else if (parmp->want_full_screen && (!stdout_isatty || !input_isatty)
 #ifdef FEAT_GUI
            /* don't want the delay when started from the desktop */
            && !gui.starting
@@ -2504,7 +2528,7 @@ check_tty(mparm_T *parmp)
         * input buffer so fast I can't even kill the process in under 2
         * minutes (and it beeps continuously the whole time :-)
         */
-       if (netbeans_active() && (!parmp->stdout_isatty || !input_isatty))
+       if (netbeans_active() && (!stdout_isatty || !input_isatty))
        {
            mch_errmsg(_("Vim: Error: Failure to start gvim from NetBeans\n"));
            exit(1);
@@ -2517,11 +2541,13 @@ check_tty(mparm_T *parmp)
            exit(1);
        }
 #endif
-       if (!parmp->stdout_isatty)
+       if (!stdout_isatty)
            mch_errmsg(_("Vim: Warning: Output is not to a terminal\n"));
        if (!input_isatty)
            mch_errmsg(_("Vim: Warning: Input is not from a terminal\n"));
        out_flush();
+       if (parmp->tty_fail && (!stdout_isatty || !input_isatty))
+           exit(1);
        if (scriptin[0] == NULL)
            ui_delay(2000L, TRUE);
        TIME_MSG("Warning delay");
@@ -3287,6 +3313,7 @@ usage(void)
 #endif
     main_msg(_("-T <terminal>\tSet terminal type to <terminal>"));
     main_msg(_("--not-a-term\t\tSkip warning for input/output not being a terminal"));
+    main_msg(_("--ttyfail\t\tExit if input or output is not a terminal"));
     main_msg(_("-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"));
 #ifdef FEAT_GUI
     main_msg(_("-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"));
@@ -3407,7 +3434,7 @@ check_swap_exists_action(void)
 }
 #endif
 
-#endif
+#endif /* NO_VIM_MAIN */
 
 #if defined(STARTUPTIME) || defined(PROTO)
 static void time_diff(struct timeval *then, struct timeval *now);
@@ -3515,6 +3542,53 @@ time_msg(
 
 #endif
 
+#if !defined(NO_VIM_MAIN) && defined(FEAT_EVAL)
+    static void
+set_progpath(char_u *argv0)
+{
+    char_u *val = argv0;
+
+# ifdef PROC_EXE_LINK
+    char    buf[PATH_MAX + 1];
+    ssize_t len;
+
+    len = readlink(PROC_EXE_LINK, buf, PATH_MAX);
+    if (len > 0)
+    {
+       buf[len] = NUL;
+       val = (char_u *)buf;
+    }
+# else
+    /* A relative path containing a "/" will become invalid when using ":cd",
+     * turn it into a full path.
+     * On MS-Windows "vim" should be expanded to "vim.exe", thus always do
+     * this. */
+#  ifdef WIN32
+    char_u *path = NULL;
+
+    if (mch_can_exe(argv0, &path, FALSE) && path != NULL)
+       val = path;
+#  else
+    char_u buf[MAXPATHL];
+
+    if (!mch_isFullName(argv0))
+    {
+       if (gettail(argv0) != argv0
+                          && vim_FullName(argv0, buf, MAXPATHL, TRUE) != FAIL)
+           val = buf;
+    }
+#  endif
+# endif
+
+    set_vim_var_string(VV_PROGPATH, val, -1);
+
+# ifdef WIN32
+    vim_free(path);
+# endif
+}
+
+#endif /* NO_VIM_MAIN */
+
 #if (defined(FEAT_CLIENTSERVER) && !defined(NO_VIM_MAIN)) || defined(PROTO)
 
 /*
@@ -3726,10 +3800,10 @@ cmdsrv_main(
            }
            else
                ret = serverSendToVim(xterm_dpy, sname, *serverStr,
-                                                   NULL, &srv, 0, 0, silent);
+                                                 NULL, &srv, 0, 0, 0, silent);
 # else
            /* Win32 always works? */
-           ret = serverSendToVim(sname, *serverStr, NULL, &srv, 0, silent);
+           ret = serverSendToVim(sname, *serverStr, NULL, &srv, 0, 0, silent);
 # endif
            if (ret < 0)
            {
@@ -3789,11 +3863,11 @@ cmdsrv_main(
                while (memchr(done, 0, numFiles) != NULL)
                {
 # ifdef WIN32
-                   p = serverGetReply(srv, NULL, TRUE, TRUE);
+                   p = serverGetReply(srv, NULL, TRUE, TRUE, 0);
                    if (p == NULL)
                        break;
 # else
-                   if (serverReadReply(xterm_dpy, srv, &p, TRUE) < 0)
+                   if (serverReadReply(xterm_dpy, srv, &p, TRUE, -1) < 0)
                        break;
 # endif
                    j = atoi((char *)p);
@@ -3820,12 +3894,12 @@ cmdsrv_main(
 # ifdef WIN32
            /* Win32 always works? */
            if (serverSendToVim(sname, (char_u *)argv[i + 1],
-                                                   &res, NULL, 1, FALSE) < 0)
+                                                 &res, NULL, 1, 0, FALSE) < 0)
 # else
            if (xterm_dpy == NULL)
                mch_errmsg(_("No display: Send expression failed.\n"));
            else if (serverSendToVim(xterm_dpy, sname, (char_u *)argv[i + 1],
-                                                &res, NULL, 1, 1, FALSE) < 0)
+                                              &res, NULL, 1, 0, 1, FALSE) < 0)
 # endif
            {
                if (res != NULL && *res != NUL)
@@ -4075,6 +4149,11 @@ eval_client_expr_to_string(char_u *expr)
     char_u     *res;
     int                save_dbl = debug_break_level;
     int                save_ro = redir_off;
+    void       *fc;
+
+    /* Evaluate the expression at the toplevel, don't use variables local to
+     * the calling function. */
+    fc = clear_current_funccal();
 
      /* Disable debugging, otherwise Vim hangs, waiting for "cont" to be
       * typed. */
@@ -4091,6 +4170,7 @@ eval_client_expr_to_string(char_u *expr)
     --emsg_silent;
     if (emsg_silent < 0)
        emsg_silent = 0;
+    restore_current_funccal(fc);
 
     /* A client can tell us to redraw, but not to display the cursor, so do
      * that here. */
@@ -4105,6 +4185,41 @@ eval_client_expr_to_string(char_u *expr)
 }
 
 /*
+ * Evaluate a command or expression sent to ourselves.
+ */
+    int
+sendToLocalVim(char_u *cmd, int asExpr, char_u **result)
+{
+    if (asExpr)
+    {
+       char_u *ret;
+
+       ret = eval_client_expr_to_string(cmd);
+       if (result != NULL)
+       {
+           if (ret == NULL)
+           {
+               char    *err = _(e_invexprmsg);
+               size_t  len = STRLEN(cmd) + STRLEN(err) + 5;
+               char_u  *msg;
+
+               msg = alloc((unsigned)len);
+               if (msg != NULL)
+                   vim_snprintf((char *)msg, len, "%s: \"%s\"", err, cmd);
+               *result = msg;
+           }
+           else
+               *result = ret;
+       }
+       else
+           vim_free(ret);
+       return ret == NULL ? -1 : 0;
+    }
+    server_to_input_buf(cmd);
+    return 0;
+}
+
+/*
  * If conversion is needed, convert "data" from "client_enc" to 'encoding' and
  * return an allocated string.  Otherwise return "data".
  * "*tofree" is set to the result when it needs to be freed later.
index 9c84bc4..d93dfac 100644 (file)
@@ -37,6 +37,8 @@ static void cleanup_jumplist(void);
 #ifdef FEAT_VIMINFO
 static void write_one_filemark(FILE *fp, xfmark_T *fm, int c1, int c2);
 #endif
+static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount,
+    long amount_after, int adjust_folds);
 
 /*
  * Set named mark "c" at current cursor position.
@@ -57,6 +59,7 @@ setmark(int c)
 setmark_pos(int c, pos_T *pos, int fnum)
 {
     int                i;
+    buf_T      *buf;
 
     /* Check for a special key (may cause islower() to crash). */
     if (c < 0)
@@ -75,9 +78,13 @@ setmark_pos(int c, pos_T *pos, int fnum)
        return OK;
     }
 
+    buf = buflist_findnr(fnum);
+    if (buf == NULL)
+       return FAIL;
+
     if (c == '"')
     {
-       curbuf->b_last_cursor = *pos;
+       buf->b_last_cursor = *pos;
        return OK;
     }
 
@@ -85,31 +92,31 @@ setmark_pos(int c, pos_T *pos, int fnum)
      * file. */
     if (c == '[')
     {
-       curbuf->b_op_start = *pos;
+       buf->b_op_start = *pos;
        return OK;
     }
     if (c == ']')
     {
-       curbuf->b_op_end = *pos;
+       buf->b_op_end = *pos;
        return OK;
     }
 
     if (c == '<' || c == '>')
     {
        if (c == '<')
-           curbuf->b_visual.vi_start = *pos;
+           buf->b_visual.vi_start = *pos;
        else
-           curbuf->b_visual.vi_end = *pos;
-       if (curbuf->b_visual.vi_mode == NUL)
+           buf->b_visual.vi_end = *pos;
+       if (buf->b_visual.vi_mode == NUL)
            /* Visual_mode has not yet been set, use a sane default. */
-           curbuf->b_visual.vi_mode = 'v';
+           buf->b_visual.vi_mode = 'v';
        return OK;
     }
 
     if (ASCII_ISLOWER(c))
     {
        i = c - 'a';
-       curbuf->b_namedm[i] = *pos;
+       buf->b_namedm[i] = *pos;
        return OK;
     }
     if (ASCII_ISUPPER(c) || VIM_ISDIGIT(c))
@@ -201,7 +208,7 @@ setpcmark(void)
 checkpcmark(void)
 {
     if (curwin->w_prev_pcmark.lnum != 0
-           && (equalpos(curwin->w_pcmark, curwin->w_cursor)
+           && (EQUAL_POS(curwin->w_pcmark, curwin->w_cursor)
                || curwin->w_pcmark.lnum == 0))
     {
        curwin->w_pcmark = curwin->w_prev_pcmark;
@@ -396,7 +403,8 @@ getmark_buf_fnum(
     {
        startp = &buf->b_visual.vi_start;
        endp = &buf->b_visual.vi_end;
-       if ((c == '<') == lt(*startp, *endp))
+       if (((c == '<') == LT_POS(*startp, *endp) || endp->lnum == 0)
+                                                         && startp->lnum != 0)
            posp = startp;
        else
            posp = endp;
@@ -491,14 +499,14 @@ getnextmark(
        {
            if (dir == FORWARD)
            {
-               if ((result == NULL || lt(curbuf->b_namedm[i], *result))
-                       && lt(pos, curbuf->b_namedm[i]))
+               if ((result == NULL || LT_POS(curbuf->b_namedm[i], *result))
+                       && LT_POS(pos, curbuf->b_namedm[i]))
                    result = &curbuf->b_namedm[i];
            }
            else
            {
-               if ((result == NULL || lt(*result, curbuf->b_namedm[i]))
-                       && lt(curbuf->b_namedm[i], pos))
+               if ((result == NULL || LT_POS(*result, curbuf->b_namedm[i]))
+                       && LT_POS(curbuf->b_namedm[i], pos))
                    result = &curbuf->b_namedm[i];
            }
        }
@@ -689,7 +697,7 @@ mark_line(pos_T *mp, int lead_len)
        return NULL;
     /* Truncate the line to fit it in the window */
     len = 0;
-    for (p = s; *p != NUL; mb_ptr_adv(p))
+    for (p = s; *p != NUL; MB_PTR_ADV(p))
     {
        len += ptr2cells(p);
        if (len >= Columns - lead_len)
@@ -786,7 +794,7 @@ show_one_mark(
            }
            if (name != NULL)
            {
-               msg_outtrans_attr(name, current ? hl_attr(HLF_D) : 0);
+               msg_outtrans_attr(name, current ? HL_ATTR(HLF_D) : 0);
                if (mustfree)
                    vim_free(name);
            }
@@ -918,7 +926,7 @@ ex_jumps(exarg_T *eap UNUSED)
            msg_outtrans(IObuff);
            msg_outtrans_attr(name,
                            curwin->w_jumplist[i].fmark.fnum == curbuf->b_fnum
-                                                       ? hl_attr(HLF_D) : 0);
+                                                       ? HL_ATTR(HLF_D) : 0);
            vim_free(name);
            ui_breakcheck();
        }
@@ -965,7 +973,7 @@ ex_changes(exarg_T *eap UNUSED)
            name = mark_line(&curbuf->b_changelist[i], 17);
            if (name == NULL)
                break;
-           msg_outtrans_attr(name, hl_attr(HLF_D));
+           msg_outtrans_attr(name, HL_ATTR(HLF_D));
            vim_free(name);
            ui_breakcheck();
        }
@@ -1023,6 +1031,27 @@ mark_adjust(
     long       amount,
     long       amount_after)
 {
+    mark_adjust_internal(line1, line2, amount, amount_after, TRUE);
+}
+
+    void
+mark_adjust_nofold(
+    linenr_T line1,
+    linenr_T line2,
+    long amount,
+    long amount_after)
+{
+    mark_adjust_internal(line1, line2, amount, amount_after, FALSE);
+}
+
+    static void
+mark_adjust_internal(
+    linenr_T line1,
+    linenr_T line2,
+    long amount,
+    long amount_after,
+    int adjust_folds UNUSED)
+{
     int                i;
     int                fnum = curbuf->b_fnum;
     linenr_T   *lp;
@@ -1057,7 +1086,7 @@ mark_adjust(
        one_adjust(&(curbuf->b_last_change.lnum));
 
        /* last cursor position, if it was set */
-       if (!equalpos(curbuf->b_last_cursor, initpos))
+       if (!EQUAL_POS(curbuf->b_last_cursor, initpos))
            one_adjust(&(curbuf->b_last_cursor.lnum));
 
 
@@ -1168,7 +1197,8 @@ mark_adjust(
 
 #ifdef FEAT_FOLDING
            /* adjust folds */
-           foldMarkAdjust(win, line1, line2, amount, amount_after);
+           if (adjust_folds)
+               foldMarkAdjust(win, line1, line2, amount, amount_after);
 #endif
        }
     }
@@ -1832,7 +1862,8 @@ write_buffer_marks(buf_T *buf, FILE *fp_out)
     for (i = 0; i < buf->b_changelistlen; ++i)
     {
        /* skip duplicates */
-       if (i == 0 || !equalpos(buf->b_changelist[i - 1], buf->b_changelist[i]))
+       if (i == 0 || !EQUAL_POS(buf->b_changelist[i - 1],
+                                                        buf->b_changelist[i]))
            write_one_mark(fp_out, '+', &buf->b_changelist[i]);
     }
 #endif
index 646235f..7396a7c 100644 (file)
@@ -886,7 +886,7 @@ mb_get_class_buf(char_u *p, buf_T *buf)
 {
     if (MB_BYTE2LEN(p[0]) == 1)
     {
-       if (p[0] == NUL || vim_iswhite(p[0]))
+       if (p[0] == NUL || VIM_ISWHITE(p[0]))
            return 0;
        if (vim_iswordc_buf(p[0], buf))
            return 2;
@@ -895,7 +895,7 @@ mb_get_class_buf(char_u *p, buf_T *buf)
     if (enc_dbcs != 0 && p[0] != NUL && p[1] != NUL)
        return dbcs_class(p[0], p[1]);
     if (enc_utf8)
-       return utf_class(utf_ptr2char(p));
+       return utf_class_buf(utf_ptr2char(p), buf);
     return 0;
 }
 
@@ -2694,6 +2694,12 @@ static struct interval emoji_all[] =
     int
 utf_class(int c)
 {
+    return utf_class_buf(c, curbuf);
+}
+
+    int
+utf_class_buf(int c, buf_T *buf)
+{
     /* sorted list of non-overlapping intervals */
     static struct clinterval
     {
@@ -2780,7 +2786,7 @@ utf_class(int c)
     {
        if (c == ' ' || c == '\t' || c == NUL || c == 0xa0)
            return 0;       /* blank */
-       if (vim_iswordc(c))
+       if (vim_iswordc_buf(c, buf))
            return 2;       /* word character */
        return 1;           /* punctuation */
     }
@@ -4041,7 +4047,7 @@ mb_prevptr(
     char_u *p)
 {
     if (p > line)
-       mb_ptr_back(line, p);
+       MB_PTR_BACK(line, p);
     return p;
 }
 
@@ -4584,47 +4590,6 @@ static HINSTANCE hMsvcrtDLL = 0;
 #   endif
 
 /*
- * Get the address of 'funcname' which is imported by 'hInst' DLL.
- */
-    static void *
-get_iconv_import_func(HINSTANCE hInst, const char *funcname)
-{
-    PBYTE                      pImage = (PBYTE)hInst;
-    PIMAGE_DOS_HEADER          pDOS = (PIMAGE_DOS_HEADER)hInst;
-    PIMAGE_NT_HEADERS          pPE;
-    PIMAGE_IMPORT_DESCRIPTOR   pImpDesc;
-    PIMAGE_THUNK_DATA          pIAT;       /* Import Address Table */
-    PIMAGE_THUNK_DATA          pINT;       /* Import Name Table */
-    PIMAGE_IMPORT_BY_NAME      pImpName;
-
-    if (pDOS->e_magic != IMAGE_DOS_SIGNATURE)
-       return NULL;
-    pPE = (PIMAGE_NT_HEADERS)(pImage + pDOS->e_lfanew);
-    if (pPE->Signature != IMAGE_NT_SIGNATURE)
-       return NULL;
-    pImpDesc = (PIMAGE_IMPORT_DESCRIPTOR)(pImage
-           + pPE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
-                                                           .VirtualAddress);
-    for (; pImpDesc->FirstThunk; ++pImpDesc)
-    {
-       if (!pImpDesc->OriginalFirstThunk)
-           continue;
-       pIAT = (PIMAGE_THUNK_DATA)(pImage + pImpDesc->FirstThunk);
-       pINT = (PIMAGE_THUNK_DATA)(pImage + pImpDesc->OriginalFirstThunk);
-       for (; pIAT->u1.Function; ++pIAT, ++pINT)
-       {
-           if (IMAGE_SNAP_BY_ORDINAL(pINT->u1.Ordinal))
-               continue;
-           pImpName = (PIMAGE_IMPORT_BY_NAME)(pImage
-                                       + (UINT_PTR)(pINT->u1.AddressOfData));
-           if (strcmp((char *)pImpName->Name, funcname) == 0)
-               return (void *)pIAT->u1.Function;
-       }
-    }
-    return NULL;
-}
-
-/*
  * Try opening the iconv.dll and return TRUE if iconv() can be used.
  */
     int
@@ -4671,7 +4636,7 @@ iconv_enabled(int verbose)
     iconv_open = (void *)GetProcAddress(hIconvDLL, "libiconv_open");
     iconv_close        = (void *)GetProcAddress(hIconvDLL, "libiconv_close");
     iconvctl   = (void *)GetProcAddress(hIconvDLL, "libiconvctl");
-    iconv_errno        = get_iconv_import_func(hIconvDLL, "_errno");
+    iconv_errno        = get_dll_import_func(hIconvDLL, "_errno");
     if (iconv_errno == NULL)
        iconv_errno = (void *)GetProcAddress(hMsvcrtDLL, "_errno");
     if (iconv == NULL || iconv_open == NULL || iconv_close == NULL
@@ -5735,7 +5700,7 @@ static char e_xim[] = N_("E285: Failed to create input context");
 #endif
 
 #if defined(FEAT_GUI_X11) || defined(PROTO)
-# if defined(XtSpecificationRelease) && XtSpecificationRelease >= 6 && !defined(sun)
+# if defined(XtSpecificationRelease) && XtSpecificationRelease >= 6 && !defined(SUN_SYSTEM)
 #  define USE_X11R6_XIM
 # endif
 
@@ -5743,7 +5708,6 @@ static int xim_real_init(Window x11_window, Display *x11_display);
 
 
 #ifdef USE_X11R6_XIM
-static void xim_instantiate_cb(Display *display, XPointer client_data, XPointer        call_data);
 static void xim_destroy_cb(XIM im, XPointer client_data, XPointer call_data);
 
     static void
index 2f75201..0fb2787 100644 (file)
@@ -482,7 +482,7 @@ mf_put(
     flags = hp->bh_flags;
 
     if ((flags & BH_LOCKED) == 0)
-       EMSG(_("E293: block was not locked"));
+       IEMSG(_("E293: block was not locked"));
     flags &= ~BH_LOCKED;
     if (dirty)
     {
index 37555e6..458b545 100644 (file)
@@ -333,7 +333,7 @@ ml_open(buf_T *buf)
        goto error;
     if (hp->bh_bnum != 0)
     {
-       EMSG(_("E298: Didn't get block nr 0?"));
+       IEMSG(_("E298: Didn't get block nr 0?"));
        goto error;
     }
     b0p = (ZERO_BL *)(hp->bh_data);
@@ -383,7 +383,7 @@ ml_open(buf_T *buf)
        goto error;
     if (hp->bh_bnum != 1)
     {
-       EMSG(_("E298: Didn't get block nr 1?"));
+       IEMSG(_("E298: Didn't get block nr 1?"));
        goto error;
     }
     pp = (PTR_BL *)(hp->bh_data);
@@ -401,7 +401,7 @@ ml_open(buf_T *buf)
        goto error;
     if (hp->bh_bnum != 2)
     {
-       EMSG(_("E298: Didn't get block nr 2?"));
+       IEMSG(_("E298: Didn't get block nr 2?"));
        goto error;
     }
 
@@ -950,7 +950,7 @@ ml_upd_block0(buf_T *buf, upd_block0_T what)
 
     b0p = (ZERO_BL *)(hp->bh_data);
     if (ml_check_b0_id(b0p) == FAIL)
-       EMSG(_("E304: ml_upd_block0(): Didn't get block 0??"));
+       IEMSG(_("E304: ml_upd_block0(): Didn't get block 0??"));
     else
     {
        if (what == UB_FNAME)
@@ -1136,7 +1136,7 @@ ml_recover(void)
 
     recoverymode = TRUE;
     called_from_main = (curbuf->b_ml.ml_mfp == NULL);
-    attr = hl_attr(HLF_E);
+    attr = HL_ATTR(HLF_E);
 
     /*
      * If the file name ends in ".s[uvw][a-z]" we assume this is the swap file.
@@ -1148,11 +1148,11 @@ ml_recover(void)
     len = (int)STRLEN(fname);
     if (len >= 4 &&
 #if defined(VMS)
-           STRNICMP(fname + len - 4, "_s" , 2)
+           STRNICMP(fname + len - 4, "_s", 2)
 #else
-           STRNICMP(fname + len - 4, ".s" , 2)
+           STRNICMP(fname + len - 4, ".s", 2)
 #endif
-               == 0
+                                               == 0
                && vim_strchr((char_u *)"UVWuvw", fname[len - 2]) != NULL
                && ASCII_ISALPHA(fname[len - 1]))
     {
@@ -1519,7 +1519,7 @@ ml_recover(void)
                            line_count = pp->pb_pointer[idx].pe_line_count;
                            if (readfile(curbuf->b_ffname, NULL, lnum,
                                        pp->pb_pointer[idx].pe_old_lnum - 1,
-                                       line_count, NULL, 0) == FAIL)
+                                       line_count, NULL, 0) != OK)
                                cannot_open = TRUE;
                            else
                                lnum += line_count;
@@ -1649,7 +1649,7 @@ ml_recover(void)
        if (!(curbuf->b_ml.ml_line_count == 2 && *ml_get(1) == NUL))
        {
            changed_int();
-           ++curbuf->b_changedtick;
+           ++CHANGEDTICK(curbuf);
        }
     }
     else
@@ -1663,7 +1663,7 @@ ml_recover(void)
            if (i != 0)
            {
                changed_int();
-               ++curbuf->b_changedtick;
+               ++CHANGEDTICK(curbuf);
                break;
            }
        }
@@ -1863,8 +1863,10 @@ recover_names(
            else
            {
 #if defined(UNIX) || defined(WIN3264)
-               p = dir_name + STRLEN(dir_name);
-               if (after_pathsep(dir_name, p) && p[-1] == p[-2])
+               int     len = (int)STRLEN(dir_name);
+
+               p = dir_name + len;
+               if (after_pathsep(dir_name, p) && len > 1 && p[-1] == p[-2])
                {
                    /* Ends with '//', Use Full path for swap name */
                    tail = make_percent_swname(dir_name, fname_res);
@@ -2026,7 +2028,7 @@ make_percent_swname(char_u *dir, char_u *name)
        if (s != NULL)
        {
            STRCPY(s, f);
-           for (d = s; *d != NUL; mb_ptr_adv(d))
+           for (d = s; *d != NUL; MB_PTR_ADV(d))
                if (vim_ispathsep(*d))
                    *d = '%';
            d = concat_fnames(dir, s, TRUE);
@@ -2450,7 +2452,7 @@ ml_get_buf(
            /* Avoid giving this message for a recursive call, may happen when
             * the GUI redraws part of the text. */
            ++recursive;
-           EMSGN(_("E315: ml_get: invalid lnum: %ld"), lnum);
+           IEMSGN(_("E315: ml_get: invalid lnum: %ld"), lnum);
            --recursive;
        }
 errorret:
@@ -2485,7 +2487,7 @@ errorret:
                /* Avoid giving this message for a recursive call, may happen
                 * when the GUI redraws part of the text. */
                ++recursive;
-               EMSGN(_("E316: ml_get: cannot find line %ld"), lnum);
+               IEMSGN(_("E316: ml_get: cannot find line %ld"), lnum);
                --recursive;
            }
            goto errorret;
@@ -2900,7 +2902,7 @@ ml_append_int(
            pp = (PTR_BL *)(hp->bh_data);   /* must be pointer block */
            if (pp->pb_id != PTR_ID)
            {
-               EMSG(_("E317: pointer block id wrong 3"));
+               IEMSG(_("E317: pointer block id wrong 3"));
                mf_put(mfp, hp, FALSE, FALSE);
                return FAIL;
            }
@@ -3042,7 +3044,7 @@ ml_append_int(
         */
        if (stack_idx < 0)
        {
-           EMSG(_("E318: Updated too many blocks?"));
+           IEMSG(_("E318: Updated too many blocks?"));
            buf->b_ml.ml_stack_top = 0; /* invalidate stack */
        }
     }
@@ -3220,7 +3222,7 @@ ml_delete_int(buf_T *buf, linenr_T lnum, int message)
            pp = (PTR_BL *)(hp->bh_data);   /* must be pointer block */
            if (pp->pb_id != PTR_ID)
            {
-               EMSG(_("E317: pointer block id wrong 4"));
+               IEMSG(_("E317: pointer block id wrong 4"));
                mf_put(mfp, hp, FALSE, FALSE);
                return FAIL;
            }
@@ -3432,7 +3434,7 @@ ml_flush_line(buf_T *buf)
 
        hp = ml_find_line(buf, lnum, ML_FIND);
        if (hp == NULL)
-           EMSGN(_("E320: Cannot find line %ld"), lnum);
+           IEMSGN(_("E320: Cannot find line %ld"), lnum);
        else
        {
            dp = (DATA_BL *)(hp->bh_data);
@@ -3674,7 +3676,7 @@ ml_find_line(buf_T *buf, linenr_T lnum, int action)
        pp = (PTR_BL *)(dp);            /* must be pointer block */
        if (pp->pb_id != PTR_ID)
        {
-           EMSG(_("E317: pointer block id wrong"));
+           IEMSG(_("E317: pointer block id wrong"));
            goto error_block;
        }
 
@@ -3719,11 +3721,11 @@ ml_find_line(buf_T *buf, linenr_T lnum, int action)
        if (idx >= (int)pp->pb_count)       /* past the end: something wrong! */
        {
            if (lnum > buf->b_ml.ml_line_count)
-               EMSGN(_("E322: line number out of range: %ld past the end"),
+               IEMSGN(_("E322: line number out of range: %ld past the end"),
                                              lnum - buf->b_ml.ml_line_count);
 
            else
-               EMSGN(_("E323: line count wrong in block %ld"), bnum);
+               IEMSGN(_("E323: line count wrong in block %ld"), bnum);
            goto error_block;
        }
        if (action == ML_DELETE)
@@ -3817,7 +3819,7 @@ ml_lineadd(buf_T *buf, int count)
        if (pp->pb_id != PTR_ID)
        {
            mf_put(mfp, hp, FALSE, FALSE);
-           EMSG(_("E317: pointer block id wrong 2"));
+           IEMSG(_("E317: pointer block id wrong 2"));
            break;
        }
        pp->pb_pointer[ip->ip_index].pe_line_count += count;
@@ -3922,8 +3924,10 @@ makeswapname(
 #endif
 
 #if defined(UNIX) || defined(WIN3264)  /* Need _very_ long file names */
-    s = dir_name + STRLEN(dir_name);
-    if (after_pathsep(dir_name, s) && s[-1] == s[-2])
+    int                len = (int)STRLEN(dir_name);
+
+    s = dir_name + len;
+    if (after_pathsep(dir_name, s) && len > 1 && s[-1] == s[-2])
     {                         /* Ends with '//', Use Full path */
        r = NULL;
        if ((s = make_percent_swname(dir_name, fname)) != NULL)
@@ -4011,7 +4015,7 @@ get_file_in_dir(
 
 #ifdef WIN3264
     if (retval != NULL)
-       for (t = gettail(retval); *t != NUL; mb_ptr_adv(t))
+       for (t = gettail(retval); *t != NUL; MB_PTR_ADV(t))
            if (*t == ':')
                *t = '%';
 #endif
@@ -4150,7 +4154,7 @@ findswapname(
        if (buf_fname == NULL)
            buf_fname = buf->b_fname;
        else
-           for (t = gettail(buf_fname); *t != NUL; mb_ptr_adv(t))
+           for (t = gettail(buf_fname); *t != NUL; MB_PTR_ADV(t))
                if (*t == ':')
                    *t = '%';
     }
index d4ee45b..343a1b8 100644 (file)
@@ -152,7 +152,7 @@ ex_menu(
        {
            if (*arg == '\\')
                STRMOVE(arg, arg + 1);
-           mb_ptr_adv(arg);
+           MB_PTR_ADV(arg);
        }
        if (*arg != NUL)
        {
@@ -167,9 +167,9 @@ ex_menu(
     for (p = arg; *p; ++p)
        if (!VIM_ISDIGIT(*p) && *p != '.')
            break;
-    if (vim_iswhite(*p))
+    if (VIM_ISWHITE(*p))
     {
-       for (i = 0; i < MENUDEPTH && !vim_iswhite(*arg); ++i)
+       for (i = 0; i < MENUDEPTH && !VIM_ISWHITE(*arg); ++i)
        {
            pri_tab[i] = getdigits(&arg);
            if (pri_tab[i] == 0)
@@ -193,12 +193,12 @@ ex_menu(
     /*
      * Check for "disable" or "enable" argument.
      */
-    if (STRNCMP(arg, "enable", 6) == 0 && vim_iswhite(arg[6]))
+    if (STRNCMP(arg, "enable", 6) == 0 && VIM_ISWHITE(arg[6]))
     {
        enable = TRUE;
        arg = skipwhite(arg + 6);
     }
-    else if (STRNCMP(arg, "disable", 7) == 0 && vim_iswhite(arg[7]))
+    else if (STRNCMP(arg, "disable", 7) == 0 && VIM_ISWHITE(arg[7]))
     {
        enable = FALSE;
        arg = skipwhite(arg + 7);
@@ -661,7 +661,7 @@ add_menu_path(
 
                    STRCPY(tearpath, menu_path);
                    idx = (int)(next_name - path_name - 1);
-                   for (s = tearpath; *s && s < tearpath + idx; mb_ptr_adv(s))
+                   for (s = tearpath; *s && s < tearpath + idx; MB_PTR_ADV(s))
                    {
                        if ((*s == '\\' || *s == Ctrl_V) && s[1])
                        {
@@ -1132,7 +1132,7 @@ show_menus_recursive(vimmenu_T *menu, int modes, int depth)
            MSG_PUTS(" ");
        }
                                /* Same highlighting as for directories!? */
-       msg_outtrans_attr(menu->name, hl_attr(HLF_D));
+       msg_outtrans_attr(menu->name, HL_ATTR(HLF_D));
     }
 
     if (menu != NULL && menu->children == NULL)
@@ -1162,7 +1162,7 @@ show_menus_recursive(vimmenu_T *menu, int modes, int depth)
                    msg_putchar(' ');
                MSG_PUTS(" ");
                if (*menu->strings[bit] == NUL)
-                   msg_puts_attr((char_u *)"<Nop>", hl_attr(HLF_8));
+                   msg_puts_attr((char_u *)"<Nop>", HL_ATTR(HLF_8));
                else
                    msg_outtrans_special(menu->strings[bit], FALSE);
            }
@@ -1219,24 +1219,24 @@ set_context_in_menu_cmd(
        if (!VIM_ISDIGIT(*p) && *p != '.')
            break;
 
-    if (!vim_iswhite(*p))
+    if (!VIM_ISWHITE(*p))
     {
        if (STRNCMP(arg, "enable", 6) == 0
-               && (arg[6] == NUL ||  vim_iswhite(arg[6])))
+               && (arg[6] == NUL ||  VIM_ISWHITE(arg[6])))
            p = arg + 6;
        else if (STRNCMP(arg, "disable", 7) == 0
-               && (arg[7] == NUL || vim_iswhite(arg[7])))
+               && (arg[7] == NUL || VIM_ISWHITE(arg[7])))
            p = arg + 7;
        else
            p = arg;
     }
 
-    while (*p != NUL && vim_iswhite(*p))
+    while (*p != NUL && VIM_ISWHITE(*p))
        ++p;
 
     arg = after_dot = p;
 
-    for (; *p && !vim_iswhite(*p); ++p)
+    for (; *p && !VIM_ISWHITE(*p); ++p)
     {
        if ((*p == '\\' || *p == Ctrl_V) && p[1] != NUL)
            p++;
@@ -1247,7 +1247,7 @@ set_context_in_menu_cmd(
     /* ":tearoff" and ":popup" only use menus, not entries */
     expand_menus = !((*cmd == 't' && cmd[1] == 'e') || *cmd == 'p');
     expand_emenu = (*cmd == 'e');
-    if (expand_menus && vim_iswhite(*p))
+    if (expand_menus && VIM_ISWHITE(*p))
        return NULL;    /* TODO: check for next command? */
     if (*p == NUL)             /* Complete the menu name */
     {
@@ -1472,7 +1472,7 @@ menu_name_skip(char_u *name)
 {
     char_u  *p;
 
-    for (p = name; *p && *p != '.'; mb_ptr_adv(p))
+    for (p = name; *p && *p != '.'; MB_PTR_ADV(p))
     {
        if (*p == '\\' || *p == Ctrl_V)
        {
@@ -2432,7 +2432,7 @@ ex_menutranslate(exarg_T *eap UNUSED)
     static char_u *
 menu_skip_part(char_u *p)
 {
-    while (*p != NUL && *p != '.' && !vim_iswhite(*p))
+    while (*p != NUL && *p != '.' && !VIM_ISWHITE(*p))
     {
        if ((*p == '\\' || *p == Ctrl_V) && p[1] != NUL)
            ++p;
@@ -2455,7 +2455,7 @@ menutrans_lookup(char_u *name, int len)
     char_u             *dname;
 
     for (i = 0; i < menutrans_ga.ga_len; ++i)
-       if (STRNCMP(name, tp[i].from, len) == 0 && tp[i].from[len] == NUL)
+       if (STRNICMP(name, tp[i].from, len) == 0 && tp[i].from[len] == NUL)
            return tp[i].to;
 
     /* Now try again while ignoring '&' characters. */
@@ -2466,7 +2466,7 @@ menutrans_lookup(char_u *name, int len)
     if (dname != NULL)
     {
        for (i = 0; i < menutrans_ga.ga_len; ++i)
-           if (STRCMP(dname, tp[i].from_noamp) == 0)
+           if (STRICMP(dname, tp[i].from_noamp) == 0)
            {
                vim_free(dname);
                return tp[i].to;
@@ -2485,7 +2485,7 @@ menu_unescape_name(char_u *name)
 {
     char_u  *p;
 
-    for (p = name; *p && *p != '.'; mb_ptr_adv(p))
+    for (p = name; *p && *p != '.'; MB_PTR_ADV(p))
        if (*p == '\\')
            STRMOVE(p, p + 1);
 }
@@ -2500,7 +2500,7 @@ menu_translate_tab_and_shift(char_u *arg_start)
 {
     char_u     *arg = arg_start;
 
-    while (*arg && !vim_iswhite(*arg))
+    while (*arg && !VIM_ISWHITE(*arg))
     {
        if ((*arg == '\\' || *arg == Ctrl_V) && arg[1] != NUL)
            arg++;
index f8152a7..a9a6669 100644 (file)
@@ -42,6 +42,9 @@ static int    confirm_msg_used = FALSE;       /* displaying confirm_msg */
 static char_u  *confirm_msg = NULL;            /* ":confirm" message */
 static char_u  *confirm_msg_tail;              /* tail of confirm_msg */
 #endif
+#ifdef FEAT_JOB_CHANNEL
+static int emsg_to_channel_log = FALSE;
+#endif
 
 struct msg_hist
 {
@@ -166,6 +169,14 @@ msg_attr_keep(
                && STRCMP(s, last_msg_hist->msg)))
        add_msg_hist(s, -1, attr);
 
+#ifdef FEAT_JOB_CHANNEL
+    if (emsg_to_channel_log)
+    {
+       /* Write message in the channel log. */
+       ch_logs(NULL, "ERROR: %s", (char *)s);
+    }
+#endif
+
     /* When displaying keep_msg, don't let msg_start() free it, caller must do
      * that. */
     if (s == keep_msg)
@@ -304,7 +315,7 @@ trunc_string(
        for (;;)
        {
            do
-               half = half - (*mb_head_off)(s, s + half - 1) - 1;
+               half = half - utf_head_off(s, s + half - 1) - 1;
            while (half > 0 && utf_iscomposing(utf_ptr2char(s + half)));
            n = ptr2cells(s + half);
            if (len + n > room || half == 0)
@@ -492,7 +503,7 @@ msg_source(int attr)
     p = get_emsg_lnum();
     if (p != NULL)
     {
-       msg_attr(p, hl_attr(HLF_N));
+       msg_attr(p, HL_ATTR(HLF_N));
        vim_free(p);
        last_sourcing_lnum = sourcing_lnum;  /* only once for each line */
     }
@@ -528,6 +539,31 @@ emsg_not_now(void)
     return FALSE;
 }
 
+#if defined(FEAT_EVAL) || defined(PROTO)
+static garray_T ignore_error_list = GA_EMPTY;
+
+    void
+ignore_error_for_testing(char_u *error)
+{
+    if (ignore_error_list.ga_itemsize == 0)
+       ga_init2(&ignore_error_list, sizeof(char_u *), 1);
+
+    ga_add_string(&ignore_error_list, error);
+}
+
+    static int
+ignore_error(char_u *msg)
+{
+    int i;
+
+    for (i = 0; i < ignore_error_list.ga_len; ++i)
+       if (strstr((char *)msg,
+                 (char *)((char_u **)(ignore_error_list.ga_data))[i]) != NULL)
+           return TRUE;
+    return FALSE;
+}
+#endif
+
 #if !defined(HAVE_STRERROR) || defined(PROTO)
 /*
  * Replacement for perror() that behaves more or less like emsg() was called.
@@ -556,6 +592,7 @@ emsg(char_u *s)
 {
     int                attr;
     char_u     *p;
+    int                r;
 #ifdef FEAT_EVAL
     int                ignore = FALSE;
     int                severe;
@@ -565,9 +602,14 @@ emsg(char_u *s)
     if (emsg_not_now())
        return TRUE;
 
+#ifdef FEAT_EVAL
+    /* When testing some errors are turned into a normal message. */
+    if (ignore_error(s))
+       /* don't call msg() if it results in a dialog */
+       return msg_use_printf() ? FALSE : msg(s);
+#endif
+
     called_emsg = TRUE;
-    if (emsg_silent == 0)
-       ex_exitval = 1;
 
     /*
      * If "emsg_severe" is TRUE: When an error exception is to be thrown,
@@ -624,9 +666,14 @@ emsg(char_u *s)
                }
                redir_write(s, -1);
            }
+#ifdef FEAT_JOB_CHANNEL
+           ch_logs(NULL, "ERROR: %s", (char *)s);
+#endif
            return TRUE;
        }
 
+       ex_exitval = 1;
+
        /* Reset msg_silent, an error causes messages to be switched back on. */
        msg_silent = 0;
        cmd_silent = FALSE;
@@ -643,13 +690,16 @@ emsg(char_u *s)
 
     emsg_on_display = TRUE;    /* remember there is an error message */
     ++msg_scroll;              /* don't overwrite a previous message */
-    attr = hl_attr(HLF_E);     /* set highlight mode for error messages */
+    attr = HL_ATTR(HLF_E);     /* set highlight mode for error messages */
     if (msg_scrolled != 0)
        need_wait_return = TRUE;    /* needed in case emsg() is called after
                                     * wait_return has reset need_wait_return
                                     * and a redraw is expected because
                                     * msg_scrolled is non-zero */
 
+#ifdef FEAT_JOB_CHANNEL
+    emsg_to_channel_log = TRUE;
+#endif
     /*
      * Display name and line number for the source of the error.
      */
@@ -659,9 +709,15 @@ emsg(char_u *s)
      * Display the error message itself.
      */
     msg_nowait = FALSE;                        /* wait for this msg */
-    return msg_attr(s, attr);
+    r = msg_attr(s, attr);
+
+#ifdef FEAT_JOB_CHANNEL
+    emsg_to_channel_log = FALSE;
+#endif
+    return r;
 }
 
+
 /*
  * Print an error message with one "%s" and one string argument.
  */
@@ -671,6 +727,84 @@ emsg2(char_u *s, char_u *a1)
     return emsg3(s, a1, NULL);
 }
 
+/*
+ * Print an error message with one or two "%s" and one or two string arguments.
+ * This is not in message.c to avoid a warning for prototypes.
+ */
+    int
+emsg3(char_u *s, char_u *a1, char_u *a2)
+{
+    if (emsg_not_now())
+       return TRUE;            /* no error messages at the moment */
+    vim_snprintf((char *)IObuff, IOSIZE, (char *)s, a1, a2);
+    return emsg(IObuff);
+}
+
+/*
+ * Print an error message with one "%ld" and one long int argument.
+ * This is not in message.c to avoid a warning for prototypes.
+ */
+    int
+emsgn(char_u *s, long n)
+{
+    if (emsg_not_now())
+       return TRUE;            /* no error messages at the moment */
+    vim_snprintf((char *)IObuff, IOSIZE, (char *)s, n);
+    return emsg(IObuff);
+}
+
+/*
+ * Same as emsg(...), but abort on error when ABORT_ON_INTERNAL_ERROR is
+ * defined. It is used for internal errors only, so that they can be
+ * detected when fuzzing vim.
+ */
+    void
+iemsg(char_u *s)
+{
+    msg(s);
+#ifdef ABORT_ON_INTERNAL_ERROR
+    abort();
+#endif
+}
+
+
+/*
+ * Same as emsg2(...) but abort on error when ABORT_ON_INTERNAL_ERROR is
+ * defined. It is used for internal errors only, so that they can be
+ * detected when fuzzing vim.
+ */
+    void
+iemsg2(char_u *s, char_u *a1)
+{
+    emsg2(s, a1);
+#ifdef ABORT_ON_INTERNAL_ERROR
+    abort();
+#endif
+}
+
+/*
+ * Same as emsgn(...) but abort on error when ABORT_ON_INTERNAL_ERROR is
+ * defined. It is used for internal errors only, so that they can be
+ * detected when fuzzing vim.
+ */
+    void
+iemsgn(char_u *s, long n)
+{
+    emsgn(s, n);
+#ifdef ABORT_ON_INTERNAL_ERROR
+    abort();
+#endif
+}
+
+/*
+ * Give an "Internal error" message.
+ */
+    void
+internal_error(char *where)
+{
+    IEMSG2(_(e_intern2), where);
+}
+
 /* emsg3() and emsgn() are in misc2.c to avoid warnings for the prototypes. */
 
     void
@@ -851,7 +985,7 @@ ex_messages(exarg_T *eap)
        if (s != NULL && *s != NUL)
            msg_attr((char_u *)
                    _("Messages maintainer: Bram Moolenaar <Bram@vim.org>"),
-                   hl_attr(HLF_T));
+                   HL_ATTR(HLF_T));
     }
 
     /* Display what was not skipped. */
@@ -1146,7 +1280,7 @@ hit_return_msg(void)
     if (got_int)
        MSG_PUTS(_("Interrupt: "));
 
-    MSG_PUTS_ATTR(_("Press ENTER or type command to continue"), hl_attr(HLF_R));
+    MSG_PUTS_ATTR(_("Press ENTER or type command to continue"), HL_ATTR(HLF_R));
     if (!msg_use_printf())
        msg_clr_eos();
     p_more = save_p_more;
@@ -1297,7 +1431,7 @@ msg_home_replace(char_u *fname)
     void
 msg_home_replace_hl(char_u *fname)
 {
-    msg_home_replace_attr(fname, hl_attr(HLF_D));
+    msg_home_replace_attr(fname, HL_ATTR(HLF_D));
 }
 #endif
 
@@ -1410,7 +1544,7 @@ msg_outtrans_len_attr(char_u *msgstr, int len, int attr)
                    msg_puts_attr_len(plain_start, (int)(str - plain_start),
                                                                        attr);
                plain_start = str + mb_l;
-               msg_puts_attr(transchar(c), attr == 0 ? hl_attr(HLF_8) : attr);
+               msg_puts_attr(transchar(c), attr == 0 ? HL_ATTR(HLF_8) : attr);
                retval += char2cells(c);
            }
            len -= mb_l - 1;
@@ -1428,7 +1562,7 @@ msg_outtrans_len_attr(char_u *msgstr, int len, int attr)
                    msg_puts_attr_len(plain_start, (int)(str - plain_start),
                                                                        attr);
                plain_start = str + 1;
-               msg_puts_attr(s, attr == 0 ? hl_attr(HLF_8) : attr);
+               msg_puts_attr(s, attr == 0 ? HL_ATTR(HLF_8) : attr);
                retval += (int)STRLEN(s);
            }
            else
@@ -1489,7 +1623,7 @@ msg_outtrans_special(
     int                attr;
     int                len;
 
-    attr = hl_attr(HLF_8);
+    attr = HL_ATTR(HLF_8);
     while (*str != NUL)
     {
        /* Leading and trailing spaces need to be displayed in <> form. */
@@ -1655,7 +1789,7 @@ msg_prt_line(char_u *s, int list)
     if (list && lcs_trail)
     {
        trail = s + STRLEN(s);
-       while (trail > s && vim_iswhite(trail[-1]))
+       while (trail > s && VIM_ISWHITE(trail[-1]))
            --trail;
     }
 
@@ -1712,13 +1846,13 @@ msg_prt_line(char_u *s, int list)
                {
                    c = lcs_tab1;
                    c_extra = lcs_tab2;
-                   attr = hl_attr(HLF_8);
+                   attr = HL_ATTR(HLF_8);
                }
            }
            else if (c == 160 && list && lcs_nbsp != NUL)
            {
                c = lcs_nbsp;
-               attr = hl_attr(HLF_8);
+               attr = HL_ATTR(HLF_8);
            }
            else if (c == NUL && list && lcs_eol != NUL)
            {
@@ -1726,7 +1860,7 @@ msg_prt_line(char_u *s, int list)
                c_extra = NUL;
                n_extra = 1;
                c = lcs_eol;
-               attr = hl_attr(HLF_AT);
+               attr = HL_ATTR(HLF_AT);
                --s;
            }
            else if (c != NUL && (n = byte2cells(c)) > 1)
@@ -1737,17 +1871,17 @@ msg_prt_line(char_u *s, int list)
                c = *p_extra++;
                /* Use special coloring to be able to distinguish <hex> from
                 * the same in plain text. */
-               attr = hl_attr(HLF_8);
+               attr = HL_ATTR(HLF_8);
            }
            else if (c == ' ' && trail != NULL && s > trail)
            {
                c = lcs_trail;
-               attr = hl_attr(HLF_8);
+               attr = HL_ATTR(HLF_8);
            }
            else if (c == ' ' && list && lcs_space != NUL)
            {
                c = lcs_space;
-               attr = hl_attr(HLF_8);
+               attr = HL_ATTR(HLF_8);
            }
        }
 
@@ -1779,7 +1913,7 @@ screen_puts_mbyte(char_u *s, int l, int attr)
                msg_col == Columns - 1))
     {
        /* Doesn't fit, print a highlighted '>' to fill it up. */
-       msg_screen_putchar('>', hl_attr(HLF_AT));
+       msg_screen_putchar('>', HL_ATTR(HLF_AT));
        return s;
     }
 
@@ -1822,7 +1956,7 @@ msg_puts(char_u *s)
 msg_puts_title(
     char_u     *s)
 {
-    msg_puts_attr(s, hl_attr(HLF_T));
+    msg_puts_attr(s, HL_ATTR(HLF_T));
 }
 
 /*
@@ -1847,7 +1981,7 @@ msg_puts_long_len_attr(char_u *longstr, int len, int attr)
     {
        slen = (room - 3) / 2;
        msg_outtrans_len_attr(longstr, slen, attr);
-       msg_puts_attr((char_u *)"...", hl_attr(HLF_8));
+       msg_puts_attr((char_u *)"...", HL_ATTR(HLF_8));
     }
     msg_outtrans_len_attr(longstr + len - slen, slen, attr);
 }
@@ -2012,8 +2146,6 @@ msg_puts_display(
 
            inc_msg_scrolled();
            need_wait_return = TRUE; /* may need wait_return in main() */
-           if (must_redraw < VALID)
-               must_redraw = VALID;
            redraw_cmdline = TRUE;
            if (cmdline_row > 0 && !exmode_active)
                --cmdline_row;
@@ -2233,6 +2365,8 @@ inc_msg_scrolled(void)
     }
 #endif
     ++msg_scrolled;
+    if (must_redraw < VALID)
+       must_redraw = VALID;
 }
 
 /*
@@ -2255,7 +2389,15 @@ static msgchunk_T *last_msgchunk = NULL; /* last displayed text */
 static msgchunk_T *msg_sb_start(msgchunk_T *mps);
 static msgchunk_T *disp_sb_line(int row, msgchunk_T *smp);
 
-static int do_clear_sb_text = FALSE;   /* clear text on next msg */
+typedef enum {
+    SB_CLEAR_NONE = 0,
+    SB_CLEAR_ALL,
+    SB_CLEAR_CMDLINE_BUSY,
+    SB_CLEAR_CMDLINE_DONE
+} sb_clear_T;
+
+/* When to clear text on next msg. */
+static sb_clear_T do_clear_sb_text = SB_CLEAR_NONE;
 
 /*
  * Store part of a printed message for displaying when scrolling back.
@@ -2270,10 +2412,11 @@ store_sb_text(
 {
     msgchunk_T *mp;
 
-    if (do_clear_sb_text)
+    if (do_clear_sb_text == SB_CLEAR_ALL
+           || do_clear_sb_text == SB_CLEAR_CMDLINE_DONE)
     {
-       clear_sb_text();
-       do_clear_sb_text = FALSE;
+       clear_sb_text(do_clear_sb_text == SB_CLEAR_ALL);
+       do_clear_sb_text = SB_CLEAR_NONE;
     }
 
     if (s > *sb_str)
@@ -2313,23 +2456,53 @@ store_sb_text(
     void
 may_clear_sb_text(void)
 {
-    do_clear_sb_text = TRUE;
+    do_clear_sb_text = SB_CLEAR_ALL;
+}
+
+/*
+ * Starting to edit the command line, do not clear messages now.
+ */
+    void
+sb_text_start_cmdline(void)
+{
+    do_clear_sb_text = SB_CLEAR_CMDLINE_BUSY;
+    msg_sb_eol();
+}
+
+/*
+ * Ending to edit the command line.  Clear old lines but the last one later.
+ */
+    void
+sb_text_end_cmdline(void)
+{
+    do_clear_sb_text = SB_CLEAR_CMDLINE_DONE;
 }
 
 /*
  * Clear any text remembered for scrolling back.
+ * When "all" is FALSE keep the last line.
  * Called when redrawing the screen.
  */
     void
-clear_sb_text(void)
+clear_sb_text(int all)
 {
     msgchunk_T *mp;
+    msgchunk_T **lastp;
+
+    if (all)
+       lastp = &last_msgchunk;
+    else
+    {
+       if (last_msgchunk == NULL)
+           return;
+       lastp = &last_msgchunk->sb_prev;
+    }
 
-    while (last_msgchunk != NULL)
+    while (*lastp != NULL)
     {
-       mp = last_msgchunk->sb_prev;
-       vim_free(last_msgchunk);
-       last_msgchunk = mp;
+       mp = (*lastp)->sb_prev;
+       vim_free(*lastp);
+       *lastp = mp;
     }
 }
 
@@ -2933,7 +3106,7 @@ msg_moremsg(int full)
     int                attr;
     char_u     *s = (char_u *)_("-- More --");
 
-    attr = hl_attr(HLF_M);
+    attr = HL_ATTR(HLF_M);
     screen_puts(s, (int)Rows - 1, 0, attr);
     if (full)
        screen_puts((char_u *)
@@ -3286,7 +3459,7 @@ give_warning(char_u *message, int hl)
     vim_free(keep_msg);
     keep_msg = NULL;
     if (hl)
-       keep_msg_attr = hl_attr(HLF_W);
+       keep_msg_attr = HL_ATTR(HLF_W);
     else
        keep_msg_attr = 0;
     if (msg_attr(message, keep_msg_attr) && msg_scrolled == 0)
@@ -3612,7 +3785,7 @@ msg_show_console_dialog(
            }
 
            /* advance to the next character */
-           mb_ptr_adv(r);
+           MB_PTR_ADV(r);
        }
 
        if (copy)
@@ -3678,7 +3851,7 @@ display_confirm_msg(void)
     /* avoid that 'q' at the more prompt truncates the message here */
     ++confirm_msg_used;
     if (confirm_msg != NULL)
-       msg_puts_attr(confirm_msg, hl_attr(HLF_M));
+       msg_puts_attr(confirm_msg, HL_ATTR(HLF_M));
     --confirm_msg_used;
 }
 
index e5ecf26..55ca814 100644 (file)
@@ -96,8 +96,6 @@ test_trunc_string(void)
     int
 main(int argc, char **argv)
 {
-    mparm_T params;
-
     vim_memset(&params, 0, sizeof(params));
     params.argc = argc;
     params.argv = argv;
index 6bf7d75..bc927b1 100644 (file)
@@ -139,7 +139,7 @@ set_indent(
            ind_done = 0;
 
            /* count as many characters as we can use */
-           while (todo > 0 && vim_iswhite(*p))
+           while (todo > 0 && VIM_ISWHITE(*p))
            {
                if (*p == TAB)
                {
@@ -202,7 +202,7 @@ set_indent(
     }
 
     /* Return if the indent is OK already. */
-    if (!doit && !vim_iswhite(*p) && !(flags & SIN_INSERT))
+    if (!doit && !VIM_ISWHITE(*p) && !(flags & SIN_INSERT))
        return FALSE;
 
     /* Allocate memory for the new line. */
@@ -234,7 +234,7 @@ set_indent(
 
        /* Skip over any additional white space (useful when newindent is less
         * than old) */
-       while (vim_iswhite(*p))
+       while (VIM_ISWHITE(*p))
            ++p;
 
     }
@@ -258,7 +258,7 @@ set_indent(
            p = oldline;
            ind_done = 0;
 
-           while (todo > 0 && vim_iswhite(*p))
+           while (todo > 0 && VIM_ISWHITE(*p))
            {
                if (*p == TAB)
                {
@@ -357,7 +357,7 @@ copy_indent(int size, char_u *src)
        s = src;
 
        /* Count/copy the usable portion of the source line */
-       while (todo > 0 && vim_iswhite(*s))
+       while (todo > 0 && VIM_ISWHITE(*s))
        {
            if (*s == TAB)
            {
@@ -492,7 +492,7 @@ get_breakindent_win(
     static int     prev_indent = 0;  /* cached indent value */
     static long            prev_ts     = 0L; /* cached tabstop value */
     static char_u   *prev_line = NULL; /* cached pointer to line */
-    static int     prev_tick = 0;   /* changedtick of cached value */
+    static varnumber_T prev_tick = 0;   /* changedtick of cached value */
     int                    bri = 0;
     /* window width minus window margin space, i.e. what rests for text */
     const int      eff_wwidth = W_WIDTH(wp)
@@ -502,11 +502,11 @@ get_breakindent_win(
 
     /* used cached indent, unless pointer or 'tabstop' changed */
     if (prev_line != line || prev_ts != wp->w_buffer->b_p_ts
-                                 || prev_tick != wp->w_buffer->b_changedtick)
+                                 || prev_tick != CHANGEDTICK(wp->w_buffer))
     {
        prev_line = line;
        prev_ts = wp->w_buffer->b_p_ts;
-       prev_tick = wp->w_buffer->b_changedtick;
+       prev_tick = CHANGEDTICK(wp->w_buffer);
        prev_indent = get_indent_str(line,
                                     (int)wp->w_buffer->b_p_ts, wp->w_p_list);
     }
@@ -820,7 +820,7 @@ open_line(
                {
                    /* Find last non-blank in line */
                    p = ptr + STRLEN(ptr) - 1;
-                   while (p > ptr && vim_iswhite(*p))
+                   while (p > ptr && VIM_ISWHITE(*p))
                        --p;
                    last_char = *p;
 
@@ -831,7 +831,7 @@ open_line(
                    {
                        if (p > ptr)
                            --p;
-                       while (p > ptr && vim_iswhite(*p))
+                       while (p > ptr && VIM_ISWHITE(*p))
                            --p;
                    }
                    /*
@@ -1020,7 +1020,7 @@ open_line(
                     * comment leader, then put a space after the middle
                     * comment leader on the next line.
                     */
-                   if (!vim_iswhite(saved_line[lead_len - 1])
+                   if (!VIM_ISWHITE(saved_line[lead_len - 1])
                            && ((p_extra != NULL
                                    && (int)curwin->w_cursor.col == lead_len)
                                || (p_extra == NULL
@@ -1124,7 +1124,7 @@ open_line(
                    {
                        /* find last non-white in the leader to line up with */
                        for (p = leader + lead_len - 1; p > leader
-                                                     && vim_iswhite(*p); --p)
+                                                     && VIM_ISWHITE(*p); --p)
                            ;
                        ++p;
 
@@ -1140,7 +1140,7 @@ open_line(
 
                            while (old_size < repl_size && p > leader)
                            {
-                               mb_ptr_back(leader, p);
+                               MB_PTR_BACK(leader, p);
                                old_size += ptr2cells(p);
                            }
                            l = lead_repl_len - (int)(endp - p);
@@ -1180,7 +1180,7 @@ open_line(
                            }
                            else
 #endif
-                           if (!vim_iswhite(*p))
+                           if (!VIM_ISWHITE(*p))
                                *p = ' ';
                        }
                    }
@@ -1217,7 +1217,7 @@ open_line(
                         * leader by spaces.  Keep Tabs, the indent must
                         * remain the same. */
                        for (p += lead_repl_len; p < leader + lead_len; ++p)
-                           if (!vim_iswhite(*p))
+                           if (!VIM_ISWHITE(*p))
                            {
                                /* Don't put a space before a TAB. */
                                if (p + 1 < leader + lead_len && p[1] == TAB)
@@ -1282,7 +1282,7 @@ open_line(
 
                    /* If the leader ends in white space, don't add an
                     * extra space */
-                   if (lead_len > 0 && vim_iswhite(leader[lead_len - 1]))
+                   if (lead_len > 0 && VIM_ISWHITE(leader[lead_len - 1]))
                        extra_space = FALSE;
                    leader[lead_len] = NUL;
                }
@@ -1305,7 +1305,7 @@ open_line(
 #endif
                                           )
                {
-                   while (lead_len && vim_iswhite(*leader))
+                   while (lead_len && VIM_ISWHITE(*leader))
                    {
                        --lead_len;
                        --newcol;
@@ -1427,8 +1427,12 @@ open_line(
        /* Postpone calling changed_lines(), because it would mess up folding
         * with markers.
         * Skip mark_adjust when adding a line after the last one, there can't
-        * be marks there. */
-       if (curwin->w_cursor.lnum + 1 < curbuf->b_ml.ml_line_count)
+        * be marks there. But still needed in diff mode. */
+       if (curwin->w_cursor.lnum + 1 < curbuf->b_ml.ml_line_count
+#ifdef FEAT_DIFF
+               || curwin->w_p_diff
+#endif
+           )
            mark_adjust(curwin->w_cursor.lnum + 1, (linenr_T)MAXLNUM, 1L, 0L);
        did_append = TRUE;
     }
@@ -1676,7 +1680,7 @@ get_leader_len(
     char_u     *saved_flags = NULL;
 
     result = i = 0;
-    while (vim_iswhite(line[i]))    /* leading white space is ignored */
+    while (VIM_ISWHITE(line[i]))    /* leading white space is ignored */
        ++i;
 
     /*
@@ -1721,11 +1725,11 @@ get_leader_len(
             * 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 (vim_iswhite(string[0]))
+           if (VIM_ISWHITE(string[0]))
            {
-               if (i == 0 || !vim_iswhite(line[i - 1]))
+               if (i == 0 || !VIM_ISWHITE(line[i - 1]))
                    continue;  /* missing white space */
-               while (vim_iswhite(string[0]))
+               while (VIM_ISWHITE(string[0]))
                    ++string;
            }
            for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j)
@@ -1736,7 +1740,7 @@ get_leader_len(
            /* 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
-                          && !vim_iswhite(line[i + j]) && line[i + j] != NUL)
+                          && !VIM_ISWHITE(line[i + j]) && line[i + j] != NUL)
                continue;
 
            /* We have found a match, stop searching unless this is a middle
@@ -1781,7 +1785,7 @@ get_leader_len(
        result = i;
 
        /* Include any trailing white space. */
-       while (vim_iswhite(line[i]))
+       while (VIM_ISWHITE(line[i]))
            ++i;
 
        if (include_space)
@@ -1849,11 +1853,11 @@ get_last_leader_offset(char_u *line, char_u **flags)
             * (but the amount does not need to match, there might be a mix of
             * TABs and spaces).
             */
-           if (vim_iswhite(string[0]))
+           if (VIM_ISWHITE(string[0]))
            {
-               if (i == 0 || !vim_iswhite(line[i - 1]))
+               if (i == 0 || !VIM_ISWHITE(line[i - 1]))
                    continue;
-               while (vim_iswhite(string[0]))
+               while (VIM_ISWHITE(string[0]))
                    ++string;
            }
            for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j)
@@ -1866,7 +1870,7 @@ get_last_leader_offset(char_u *line, char_u **flags)
             * end-of-line after the string in the line.
             */
            if (vim_strchr(part_buf, COM_BLANK) != NULL
-                   && !vim_iswhite(line[i + j]) && line[i + j] != NUL)
+                   && !VIM_ISWHITE(line[i + j]) && line[i + j] != NUL)
            {
                continue;
            }
@@ -1903,7 +1907,7 @@ get_last_leader_offset(char_u *line, char_u **flags)
             * the comment leader correctly.
             */
 
-           while (vim_iswhite(*com_leader))
+           while (VIM_ISWHITE(*com_leader))
                ++com_leader;
            len1 = (int)STRLEN(com_leader);
 
@@ -1916,7 +1920,7 @@ get_last_leader_offset(char_u *line, char_u **flags)
                    continue;
                string = vim_strchr(part_buf2, ':');
                ++string;
-               while (vim_iswhite(*string))
+               while (VIM_ISWHITE(*string))
                    ++string;
                len2 = (int)STRLEN(string);
                if (len2 == 0)
@@ -2066,7 +2070,7 @@ plines_win_col(win_T *wp, linenr_T lnum, long column)
     while (*s != NUL && --column >= 0)
     {
        col += win_lbr_chartabsize(wp, line, s, (colnr_T)col, NULL);
-       mb_ptr_adv(s);
+       MB_PTR_ADV(s);
     }
 
     /*
@@ -2177,16 +2181,19 @@ ins_bytes_len(char_u *p, int len)
     void
 ins_char(int c)
 {
-#if defined(FEAT_MBYTE) || defined(PROTO)
     char_u     buf[MB_MAXBYTES + 1];
-    int                n;
+    int                n = 1;
 
+#ifdef FEAT_MBYTE
     n = (*mb_char2bytes)(c, buf);
 
     /* When "c" is 0x100, 0x200, etc. we don't want to insert a NUL byte.
      * Happens for CTRL-Vu9900. */
     if (buf[0] == 0)
        buf[0] = '\n';
+#else
+    buf[0] = c;
+#endif
 
     ins_char_bytes(buf, n);
 }
@@ -2195,7 +2202,6 @@ ins_char(int c)
 ins_char_bytes(char_u *buf, int charlen)
 {
     int                c = buf[0];
-#endif
     int                newlen;         /* nr of bytes inserted */
     int                oldlen;         /* nr of bytes deleted (0 when not replacing) */
     char_u     *p;
@@ -2218,11 +2224,7 @@ ins_char_bytes(char_u *buf, int charlen)
 
     /* The lengths default to the values for when not replacing. */
     oldlen = 0;
-#ifdef FEAT_MBYTE
     newlen = charlen;
-#else
-    newlen = 1;
-#endif
 
     if (State & REPLACE_FLAG)
     {
@@ -2692,7 +2694,7 @@ inindent(int extra)
     char_u     *ptr;
     colnr_T    col;
 
-    for (col = 0, ptr = ml_get_curline(); vim_iswhite(*ptr); ++col)
+    for (col = 0, ptr = ml_get_curline(); VIM_ISWHITE(*ptr); ++col)
        ++ptr;
     if (col >= curwin->w_cursor.col + extra)
        return TRUE;
@@ -2770,7 +2772,7 @@ changed(void)
        }
        changed_int();
     }
-    ++curbuf->b_changedtick;
+    ++CHANGEDTICK(curbuf);
 }
 
 /*
@@ -2865,8 +2867,12 @@ appended_lines(linenr_T lnum, long count)
 appended_lines_mark(linenr_T lnum, long count)
 {
     /* Skip mark_adjust when adding a line after the last one, there can't
-     * be marks there. */
-    if (lnum + count < curbuf->b_ml.ml_line_count)
+     * be marks there. But it's still needed in diff mode. */
+    if (lnum + count < curbuf->b_ml.ml_line_count
+#ifdef FEAT_DIFF
+           || curwin->w_p_diff
+#endif
+       )
        mark_adjust(lnum + 1, (linenr_T)MAXLNUM, count, 0L);
     changed_lines(lnum + 1, 0, lnum + 1, count);
 }
@@ -3197,7 +3203,7 @@ unchanged(
        need_maketitle = TRUE;      /* set window title later */
 #endif
     }
-    ++buf->b_changedtick;
+    ++CHANGEDTICK(buf);
 #ifdef FEAT_NETBEANS_INTG
     netbeans_unmodified(buf);
 #endif
@@ -3259,14 +3265,18 @@ change_warning(
        msg_start();
        if (msg_row == Rows - 1)
            msg_col = col;
-       msg_source(hl_attr(HLF_W));
-       MSG_PUTS_ATTR(_(w_readonly), hl_attr(HLF_W) | MSG_HIST);
+       msg_source(HL_ATTR(HLF_W));
+       MSG_PUTS_ATTR(_(w_readonly), HL_ATTR(HLF_W) | MSG_HIST);
 #ifdef FEAT_EVAL
        set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_readonly), -1);
 #endif
        msg_clr_eos();
        (void)msg_end();
-       if (msg_silent == 0 && !silent_mode)
+       if (msg_silent == 0 && !silent_mode
+#ifdef FEAT_EVAL
+               && time_for_testing != 1
+#endif
+               )
        {
            out_flush();
            ui_delay(1000L, TRUE); /* give the user time to think about it */
@@ -3309,7 +3319,7 @@ ask_yesno(char_u *str, int direct)
     while (r != 'y' && r != 'n')
     {
        /* same highlighting as for wait_return */
-       smsg_attr(hl_attr(HLF_R), (char_u *)"%s (y/n)?", str);
+       smsg_attr(HL_ATTR(HLF_R), (char_u *)"%s (y/n)?", str);
        if (direct)
            r = get_keystroke();
        else
@@ -3691,8 +3701,8 @@ vim_beep(
         * function give the user a hint where the beep comes from. */
        if (vim_strchr(p_debug, 'e') != NULL)
        {
-           msg_source(hl_attr(HLF_W));
-           msg_attr((char_u *)_("Beep!"), hl_attr(HLF_W));
+           msg_source(HL_ATTR(HLF_W));
+           msg_attr((char_u *)_("Beep!"), HL_ATTR(HLF_W));
        }
     }
 }
@@ -4026,15 +4036,12 @@ expand_env_esc(
                 */
 #  if defined(HAVE_GETPWNAM) && defined(HAVE_PWD_H)
                {
-                   struct passwd *pw;
-
                    /* Note: memory allocated by getpwnam() is never freed.
                     * Calling endpwent() apparently doesn't help. */
-                   pw = getpwnam((char *)dst + 1);
-                   if (pw != NULL)
-                       var = (char_u *)pw->pw_dir;
-                   else
-                       var = NULL;
+                   struct passwd *pw = (*dst == NUL)
+                                       ? NULL : getpwnam((char *)dst + 1);
+
+                   var = (pw == NULL) ? NULL : (char_u *)pw->pw_dir;
                }
                if (var == NULL)
 #  endif
@@ -4830,7 +4837,7 @@ gettail(char_u *fname)
     {
        if (vim_ispathsep_nocolon(*p2))
            p1 = p2 + 1;
-       mb_ptr_adv(p2);
+       MB_PTR_ADV(p2);
     }
     return p1;
 }
@@ -4868,7 +4875,7 @@ gettail_dir(char_u *fname)
                dir_end = next_dir_end;
            look_for_sep = TRUE;
        }
-       mb_ptr_adv(p);
+       MB_PTR_ADV(p);
     }
     return dir_end;
 }
@@ -4903,7 +4910,7 @@ gettail_sep(char_u *fname)
 getnextcomp(char_u *fname)
 {
     while (*fname && !vim_ispathsep(*fname))
-       mb_ptr_adv(fname);
+       MB_PTR_ADV(fname);
     if (*fname)
        ++fname;
     return fname;
@@ -5265,7 +5272,8 @@ ind_find_start_CORS(void)     /* XXX */
 
     /* If comment_pos is before rs_pos the raw string is inside the comment.
      * If rs_pos is before comment_pos the comment is inside the raw string. */
-    if (comment_pos == NULL || (rs_pos != NULL && lt(*rs_pos, *comment_pos)))
+    if (comment_pos == NULL || (rs_pos != NULL
+                                            && LT_POS(*rs_pos, *comment_pos)))
        return rs_pos;
     return comment_pos;
 }
@@ -5422,7 +5430,6 @@ static int        skip_label(linenr_T, char_u **pp);
 static int     cin_first_id_amount(void);
 static int     cin_get_equal_amount(linenr_T lnum);
 static int     cin_ispreproc(char_u *);
-static int     cin_ispreproc_cont(char_u **pp, linenr_T *lnump);
 static int     cin_iscomment(char_u *);
 static int     cin_islinecomment(char_u *);
 static int     cin_isterminated(char_u *, int, int);
@@ -5762,6 +5769,7 @@ cin_is_cpp_namespace(char_u *s)
 {
     char_u     *p;
     int                has_name = FALSE;
+    int                has_name_start = FALSE;
 
     s = cin_skipcomment(s);
     if (STRNCMP(s, "namespace", 9) == 0 && (s[9] == NUL || !vim_iswordc(s[9])))
@@ -5769,7 +5777,7 @@ cin_is_cpp_namespace(char_u *s)
        p = cin_skipcomment(skipwhite(s + 9));
        while (*p != NUL)
        {
-           if (vim_iswhite(*p))
+           if (VIM_ISWHITE(*p))
            {
                has_name = TRUE; /* found end of a name */
                p = cin_skipcomment(skipwhite(p));
@@ -5780,10 +5788,18 @@ cin_is_cpp_namespace(char_u *s)
            }
            else if (vim_iswordc(*p))
            {
+               has_name_start = TRUE;
                if (has_name)
                    return FALSE; /* word character after skipping past name */
                ++p;
            }
+           else if (p[0] == ':' && p[1] == ':' && vim_iswordc(p[2]))
+           {
+               if (!has_name_start || has_name)
+                   return FALSE;
+               /* C++ 17 nested namespace */
+               p += 3;
+           }
            else
            {
                return FALSE;
@@ -5795,6 +5811,54 @@ cin_is_cpp_namespace(char_u *s)
 }
 
 /*
+ * Recognize a `extern "C"` or `extern "C++"` linkage specifications.
+ */
+    static int
+cin_is_cpp_extern_c(char_u *s)
+{
+    char_u     *p;
+    int                has_string_literal = FALSE;
+
+    s = cin_skipcomment(s);
+    if (STRNCMP(s, "extern", 6) == 0 && (s[6] == NUL || !vim_iswordc(s[6])))
+    {
+       p = cin_skipcomment(skipwhite(s + 6));
+       while (*p != NUL)
+       {
+           if (VIM_ISWHITE(*p))
+           {
+               p = cin_skipcomment(skipwhite(p));
+           }
+           else if (*p == '{')
+           {
+               break;
+           }
+           else if (p[0] == '"' && p[1] == 'C' && p[2] == '"')
+           {
+               if (has_string_literal)
+                   return FALSE;
+               has_string_literal = TRUE;
+               p += 3;
+           }
+           else if (p[0] == '"' && p[1] == 'C' && p[2] == '+' && p[3] == '+'
+                   && p[4] == '"')
+           {
+               if (has_string_literal)
+                   return FALSE;
+               has_string_literal = TRUE;
+               p += 5;
+           }
+           else
+           {
+               return FALSE;
+           }
+       }
+       return has_string_literal ? TRUE : FALSE;
+    }
+    return FALSE;
+}
+
+/*
  * Return a pointer to the first non-empty non-comment character after a ':'.
  * Return NULL if not found.
  *       case 234:    a = b;
@@ -5912,15 +5976,15 @@ cin_first_id_amount(void)
            || (len == 6 && STRNCMP(p, "signed", 6) == 0))
     {
        s = skipwhite(p + len);
-       if ((STRNCMP(s, "int", 3) == 0 && vim_iswhite(s[3]))
-               || (STRNCMP(s, "long", 4) == 0 && vim_iswhite(s[4]))
-               || (STRNCMP(s, "short", 5) == 0 && vim_iswhite(s[5]))
-               || (STRNCMP(s, "char", 4) == 0 && vim_iswhite(s[4])))
+       if ((STRNCMP(s, "int", 3) == 0 && VIM_ISWHITE(s[3]))
+               || (STRNCMP(s, "long", 4) == 0 && VIM_ISWHITE(s[4]))
+               || (STRNCMP(s, "short", 5) == 0 && VIM_ISWHITE(s[5]))
+               || (STRNCMP(s, "char", 4) == 0 && VIM_ISWHITE(s[4])))
            p = s;
     }
     for (len = 0; vim_isIDc(p[len]); ++len)
        ;
-    if (len == 0 || !vim_iswhite(p[len]) || cin_nocode(p))
+    if (len == 0 || !VIM_ISWHITE(p[len]) || cin_nocode(p))
        return 0;
 
     p = skipwhite(p + len);
@@ -5993,13 +6057,18 @@ cin_ispreproc(char_u *s)
  * Return TRUE if line "*pp" at "*lnump" is a preprocessor statement or a
  * continuation line of a preprocessor statement.  Decrease "*lnump" to the
  * start and return the line in "*pp".
+ * Put the amount of indent in "*amount".
  */
     static int
-cin_ispreproc_cont(char_u **pp, linenr_T *lnump)
+cin_ispreproc_cont(char_u **pp, linenr_T *lnump, int *amount)
 {
     char_u     *line = *pp;
     linenr_T   lnum = *lnump;
     int                retval = FALSE;
+    int                candidate_amount = *amount;
+
+    if (*line != NUL && line[STRLEN(line) - 1] == '\\')
+       candidate_amount = get_indent_lnum(lnum);
 
     for (;;)
     {
@@ -6018,6 +6087,8 @@ cin_ispreproc_cont(char_u **pp, linenr_T *lnump)
 
     if (lnum != *lnump)
        *pp = ml_get(*lnump);
+    if (retval)
+       *amount = candidate_amount;
     return retval;
 }
 
@@ -6285,7 +6356,7 @@ cin_is_if_for_while_before_offset(char_u *line, int *poffset)
 
     if (offset-- < 2)
        return 0;
-    while (offset > 2 && vim_iswhite(line[offset]))
+    while (offset > 2 && VIM_ISWHITE(line[offset]))
        --offset;
 
     offset -= 1;
@@ -6630,6 +6701,7 @@ cin_skip2pos(pos_T *trypos)
 {
     char_u     *line;
     char_u     *p;
+    char_u     *new_p;
 
     p = line = ml_get(trypos->lnum);
     while (*p && (colnr_T)(p - line) < trypos->col)
@@ -6638,8 +6710,11 @@ cin_skip2pos(pos_T *trypos)
            p = cin_skipcomment(p);
        else
        {
-           p = skip_string(p);
-           ++p;
+           new_p = skip_string(p);
+           if (new_p == p)
+               ++p;
+           else
+               p = new_p;
        }
     }
     return (int)(p - line);
@@ -6952,6 +7027,12 @@ parse_cino(buf_T *buf)
      * while(). */
     buf->b_ind_if_for_while = 0;
 
+    /* indentation for # comments */
+    buf->b_ind_hash_comment = 0;
+
+    /* Handle C++ extern "C" or "C++" */
+    buf->b_ind_cpp_extern_c = 0;
+
     for (p = buf->b_p_cino; *p; )
     {
        l = p++;
@@ -7026,6 +7107,7 @@ parse_cino(buf_T *buf)
            case '#': buf->b_ind_hash_comment = n; break;
            case 'N': buf->b_ind_cpp_namespace = n; break;
            case 'k': buf->b_ind_if_for_while = n; break;
+           case 'E': buf->b_ind_cpp_extern_c = n; break;
        }
        if (*p == ',')
            ++p;
@@ -7136,7 +7218,8 @@ get_c_indent(void)
        comment_pos = &tryposCopy;
     }
     trypos = find_start_rawstring(curbuf->b_ind_maxcomment);
-    if (trypos != NULL && (comment_pos == NULL || lt(*trypos, *comment_pos)))
+    if (trypos != NULL && (comment_pos == NULL
+                                            || LT_POS(*trypos, *comment_pos)))
     {
        amount = -1;
        goto laterend;
@@ -7381,7 +7464,7 @@ get_c_indent(void)
                l = skipwhite(ml_get(lnum));
                if (cin_nocode(l))              /* skip comment lines */
                    continue;
-               if (cin_ispreproc_cont(&l, &lnum))
+               if (cin_ispreproc_cont(&l, &lnum, &amount))
                    continue;                   /* ignore #define, #if, etc. */
                curwin->w_cursor.lnum = lnum;
 
@@ -7519,7 +7602,7 @@ get_c_indent(void)
                    else
                    {
                        col = our_paren_pos.col + 1;
-                       while (vim_iswhite(l[col]))
+                       while (VIM_ISWHITE(l[col]))
                            col++;
                        if (l[col] != NUL)      /* In case of trailing space */
                            our_paren_pos.col = col;
@@ -7739,6 +7822,8 @@ get_c_indent(void)
                    l = skipwhite(ml_get_curline());
                    if (cin_is_cpp_namespace(l))
                        amount += curbuf->b_ind_cpp_namespace;
+                   else if (cin_is_cpp_extern_c(l))
+                       amount += curbuf->b_ind_cpp_extern_c;
                }
                else
                {
@@ -7794,10 +7879,10 @@ get_c_indent(void)
                 */
                if (curwin->w_cursor.lnum <= ourscope)
                {
-                   /* we reached end of scope:
-                    * if looking for a enum or structure initialization
+                   /* We reached end of scope:
+                    * If looking for a enum or structure initialization
                     * go further back:
-                    * if it is an initializer (enum xxx or xxx =), then
+                    * If it is an initializer (enum xxx or xxx =), then
                     * don't add ind_continuation, otherwise it is a variable
                     * declaration:
                     * int x,
@@ -7836,7 +7921,8 @@ get_c_indent(void)
                        /*
                         * Skip preprocessor directives and blank lines.
                         */
-                       if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum))
+                       if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum,
+                                                                   &amount))
                            continue;
 
                        if (cin_nocode(l))
@@ -7953,7 +8039,8 @@ get_c_indent(void)
                            }
 
                            /* Skip preprocessor directives and blank lines. */
-                           if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum))
+                           if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum,
+                                                                   &amount))
                                continue;
 
                            /* Finally the actual check for "namespace". */
@@ -7963,6 +8050,12 @@ get_c_indent(void)
                                                            - added_to_amount;
                                break;
                            }
+                           else if (cin_is_cpp_extern_c(l))
+                           {
+                               amount += curbuf->b_ind_cpp_extern_c
+                                                           - added_to_amount;
+                               break;
+                           }
 
                            if (cin_nocode(l))
                                continue;
@@ -8129,7 +8222,7 @@ get_c_indent(void)
                 * unlocked it)
                 */
                l = ml_get_curline();
-               if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum)
+               if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount)
                                                             || cin_nocode(l))
                    continue;
 
@@ -8850,7 +8943,7 @@ term_again:
        /*
         * Skip preprocessor directives and blank lines.
         */
-       if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum))
+       if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount))
            continue;
 
        if (cin_nocode(l))
@@ -8951,7 +9044,7 @@ term_again:
            {
                look = ml_get(--curwin->w_cursor.lnum);
                if (!(cin_nocode(look) || cin_ispreproc_cont(
-                                     &look, &curwin->w_cursor.lnum)))
+                                     &look, &curwin->w_cursor.lnum, &amount)))
                    break;
            }
            if (curwin->w_cursor.lnum > 0
@@ -9158,7 +9251,8 @@ find_match(int lookfor, linenr_T ourscope)
     int
 get_expr_indent(void)
 {
-    int                indent;
+    int                indent = -1;
+    char_u     *inde_copy;
     pos_T      save_pos;
     colnr_T    save_curswant;
     int                save_set_curswant;
@@ -9175,7 +9269,16 @@ get_expr_indent(void)
     if (use_sandbox)
        ++sandbox;
     ++textlock;
-    indent = (int)eval_to_number(curbuf->b_p_inde);
+
+    /* Need to make a copy, the 'indentexpr' option could be changed while
+     * evaluating it. */
+    inde_copy = vim_strsave(curbuf->b_p_inde);
+    if (inde_copy != NULL)
+    {
+       indent = (int)eval_to_number(inde_copy);
+       vim_free(inde_copy);
+    }
+
     if (use_sandbox)
        --sandbox;
     --textlock;
@@ -9261,7 +9364,7 @@ get_lisp_indent(void)
     {
        paren = *pos;
        pos = findmatch(NULL, '[');
-       if (pos == NULL || ltp(pos, &paren))
+       if (pos == NULL || LT_POSP(pos, &paren))
            pos = &paren;
     }
     if (pos != NULL)
@@ -9356,7 +9459,7 @@ get_lisp_indent(void)
                    amount++;
                    firsttry = amount;
 
-                   while (vim_iswhite(*that))
+                   while (VIM_ISWHITE(*that))
                    {
                        amount += lbr_chartabsize(line, that, (colnr_T)amount);
                        ++that;
@@ -9379,7 +9482,7 @@ get_lisp_indent(void)
                                    && (*that < '0' || *that > '9')))
                        {
                            while (*that
-                                   && (!vim_iswhite(*that)
+                                   && (!VIM_ISWHITE(*that)
                                        || quotecount
                                        || parencount)
                                    && (!((*that == '(' || *that == '[')
@@ -9402,7 +9505,7 @@ get_lisp_indent(void)
                                                line, &that, (colnr_T)amount);
                            }
                        }
-                       while (vim_iswhite(*that))
+                       while (VIM_ISWHITE(*that))
                        {
                            amount += lbr_chartabsize(
                                                 line, that, (colnr_T)amount);
@@ -9633,7 +9736,7 @@ expand_wildcards(
 # endif
            if (match_file_list(p_wig, (*files)[i], ffname))
            {
-               /* remove this matching files from the list */
+               /* remove this matching file from the list */
                vim_free((*files)[i]);
                for (j = i; j + 1 < *num_files; ++j)
                    (*files)[j] = (*files)[j + 1];
@@ -10285,7 +10388,7 @@ find_previous_pathsep(char_u *path, char_u **psep)
     {
        if (vim_ispathsep(**psep))
            return OK;
-       mb_ptr_back(path, *psep);
+       MB_PTR_BACK(path, *psep);
     }
 
     return FAIL;
@@ -10440,7 +10543,7 @@ get_path_cutoff(char_u *fname, garray_T *gap)
     /* skip to the file or directory name */
     if (cutoff != NULL)
        while (vim_ispathsep(*cutoff))
-           mb_ptr_adv(cutoff);
+           MB_PTR_ADV(cutoff);
 
     return cutoff;
 }
@@ -10697,7 +10800,7 @@ static int has_env_var(char_u *p);
     static int
 has_env_var(char_u *p)
 {
-    for ( ; *p; mb_ptr_adv(p))
+    for ( ; *p; MB_PTR_ADV(p))
     {
        if (*p == '\\' && p[1] != NUL)
            ++p;
@@ -10717,14 +10820,15 @@ has_env_var(char_u *p)
 static int has_special_wildchar(char_u *p);
 
 /*
- * Return TRUE if "p" contains a special wildcard character.
- * Allowing for escaping.
+ * Return TRUE if "p" contains a special wildcard character, one that Vim
+ * cannot expand, requires using a shell.
  */
     static int
 has_special_wildchar(char_u *p)
 {
-    for ( ; *p; mb_ptr_adv(p))
+    for ( ; *p; MB_PTR_ADV(p))
     {
+       /* Allow for escaping. */
        if (*p == '\\' && p[1] != NUL)
            ++p;
        else if (vim_strchr((char_u *)SPECIAL_WILDCHAR, *p) != NULL)
@@ -11199,7 +11303,7 @@ get_isolated_shell_name(void)
 
        /* Find the last path separator before the space. */
        p1 = p_sh;
-       for (p2 = p_sh; p2 < p; mb_ptr_adv(p2))
+       for (p2 = p_sh; p2 < p; MB_PTR_ADV(p2))
            if (vim_ispathsep(*p2))
                p1 = p2 + 1;
        p = vim_strnsave(p1, (int)(p - p1));
index 3803249..fa06e47 100644 (file)
@@ -196,7 +196,7 @@ coladvance2(
            /* Count a tab for what it's worth (if list mode not on) */
 #ifdef FEAT_LINEBREAK
            csize = win_lbr_chartabsize(curwin, line, ptr, col, &head);
-           mb_ptr_adv(ptr);
+           MB_PTR_ADV(ptr);
 #else
            csize = lbr_chartabsize_adv(line, &ptr, col);
 #endif
@@ -403,7 +403,7 @@ incl(pos_T *lp)
     int
 dec_cursor(void)
 {
- return dec(&curwin->w_cursor);
   return dec(&curwin->w_cursor);
 }
 
     int
@@ -918,7 +918,7 @@ lalloc(long_u size, int message)
     {
        /* Don't hide this message */
        emsg_silent = 0;
-       EMSGN(_("E341: Internal error: lalloc(%ld, )"), size);
+       IEMSGN(_("E341: Internal error: lalloc(%ld, )"), size);
        return NULL;
     }
 
@@ -970,7 +970,7 @@ lalloc(long_u size, int message)
            break;
        releasing = TRUE;
 
-       clear_sb_text();              /* free any scrollback text */
+       clear_sb_text(TRUE);          /* free any scrollback text */
        try_again = mf_release_all(); /* release as many blocks as possible */
 
        releasing = FALSE;
@@ -1075,7 +1075,7 @@ free_all_mem(void)
     p_ea = FALSE;
     if (first_tabpage->tp_next != NULL)
        do_cmdline_cmd((char_u *)"tabonly!");
-    if (firstwin != lastwin)
+    if (!ONE_WINDOW)
        do_cmdline_cmd((char_u *)"only!");
 # endif
 
@@ -1148,7 +1148,7 @@ free_all_mem(void)
 # ifdef FEAT_DIFF
     diff_clear(curtab);
 # endif
-    clear_sb_text();         /* free any scrollback text */
+    clear_sb_text(TRUE);             /* free any scrollback text */
 
     /* Free some global vars. */
     vim_free(username);
@@ -1418,7 +1418,7 @@ vim_strsave_shellescape(char_u *string, int do_special, int do_newline)
 
     /* First count the number of extra bytes required. */
     length = (unsigned)STRLEN(string) + 3;  /* two quotes and a trailing NUL */
-    for (p = string; *p != NUL; mb_ptr_adv(p))
+    for (p = string; *p != NUL; MB_PTR_ADV(p))
     {
 # ifdef WIN32
        if (!p_ssl)
@@ -1602,7 +1602,10 @@ strup_save(char_u *orig)
                {
                    s = alloc((unsigned)STRLEN(res) + 1 + newl - l);
                    if (s == NULL)
-                       break;
+                   {
+                       vim_free(res);
+                       return NULL;
+                   }
                    mch_memmove(s, res, p - res);
                    STRCPY(s + (p - res) + newl, p + l);
                    p = s + (p - res);
@@ -1625,6 +1628,69 @@ strup_save(char_u *orig)
 
     return res;
 }
+
+/*
+ * Make string "s" all lower-case and return it in allocated memory.
+ * Handles multi-byte characters as well as possible.
+ * Returns NULL when out of memory.
+ */
+    char_u *
+strlow_save(char_u *orig)
+{
+    char_u     *p;
+    char_u     *res;
+
+    res = p = vim_strsave(orig);
+
+    if (res != NULL)
+       while (*p != NUL)
+       {
+# ifdef FEAT_MBYTE
+           int         l;
+
+           if (enc_utf8)
+           {
+               int     c, lc;
+               int     newl;
+               char_u  *s;
+
+               c = utf_ptr2char(p);
+               lc = utf_tolower(c);
+
+               /* Reallocate string when byte count changes.  This is rare,
+                * thus it's OK to do another malloc()/free(). */
+               l = utf_ptr2len(p);
+               newl = utf_char2len(lc);
+               if (newl != l)
+               {
+                   s = alloc((unsigned)STRLEN(res) + 1 + newl - l);
+                   if (s == NULL)
+                   {
+                       vim_free(res);
+                       return NULL;
+                   }
+                   mch_memmove(s, res, p - res);
+                   STRCPY(s + (p - res) + newl, p + l);
+                   p = s + (p - res);
+                   vim_free(res);
+                   res = s;
+               }
+
+               utf_char2bytes(lc, p);
+               p += newl;
+           }
+           else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
+               p += l;         /* skip multi-byte character */
+           else
+# endif
+           {
+               *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */
+               p++;
+           }
+       }
+
+    return res;
+}
 #endif
 
 /*
@@ -1636,7 +1702,7 @@ del_trailing_spaces(char_u *ptr)
     char_u     *q;
 
     q = ptr + STRLEN(ptr);
-    while (--q > ptr && vim_iswhite(q[0]) && q[-1] != '\\' && q[-1] != Ctrl_V)
+    while (--q > ptr && VIM_ISWHITE(q[0]) && q[-1] != '\\' && q[-1] != Ctrl_V)
        *q = NUL;
 }
 
@@ -1653,7 +1719,7 @@ vim_strncpy(char_u *to, char_u *from, size_t len)
 
 /*
  * Like strcat(), but make sure the result fits in "tosize" bytes and is
- * always NUL terminated.
+ * always NUL terminated. "from" and "to" may overlap.
  */
     void
 vim_strcat(char_u *to, char_u *from, size_t tosize)
@@ -1667,7 +1733,7 @@ vim_strcat(char_u *to, char_u *from, size_t tosize)
        to[tosize - 1] = NUL;
     }
     else
-       STRCPY(to + tolen, from);
+       mch_memmove(to + tolen, from, fromlen + 1);
 }
 
 /*
@@ -1740,55 +1806,6 @@ vim_memset(void *ptr, int c, size_t size)
 }
 #endif
 
-#ifdef VIM_MEMCMP
-/*
- * Return zero when "b1" and "b2" are the same for "len" bytes.
- * Return non-zero otherwise.
- */
-    int
-vim_memcmp(void *b1, void *b2, size_t len)
-{
-    char_u  *p1 = (char_u *)b1, *p2 = (char_u *)b2;
-
-    for ( ; len > 0; --len)
-    {
-       if (*p1 != *p2)
-           return 1;
-       ++p1;
-       ++p2;
-    }
-    return 0;
-}
-#endif
-
-/* skipped when generating prototypes, the prototype is in vim.h */
-#ifdef VIM_MEMMOVE
-/*
- * Version of memmove() that handles overlapping source and destination.
- * For systems that don't have a function that is guaranteed to do that (SYSV).
- */
-    void
-mch_memmove(void *src_arg, void *dst_arg, size_t len)
-{
-    /*
-     * A void doesn't have a size, we use char pointers.
-     */
-    char *dst = dst_arg, *src = src_arg;
-
-                                       /* overlap, copy backwards */
-    if (dst > src && dst < src + len)
-    {
-       src += len;
-       dst += len;
-       while (len-- > 0)
-           *--dst = *--src;
-    }
-    else                               /* copy forwards */
-       while (len-- > 0)
-           *dst++ = *src++;
-}
-#endif
-
 #if (!defined(HAVE_STRCASECMP) && !defined(HAVE_STRICMP)) || defined(PROTO)
 /*
  * Compare two strings, ignoring case, using current locale.
@@ -1857,7 +1874,7 @@ vim_strchr(char_u *string, int c)
     {
        while (*p != NUL)
        {
-           int l = (*mb_ptr2len)(p);
+           int l = utfc_ptr2len(p);
 
            /* Avoid matching an illegal byte here. */
            if (utf_ptr2char(p) == c && l > 1)
@@ -1933,7 +1950,7 @@ vim_strrchr(char_u *string, int c)
     {
        if (*p == c)
            retval = p;
-       mb_ptr_adv(p);
+       MB_PTR_ADV(p);
     }
     return retval;
 }
@@ -1954,7 +1971,7 @@ vim_strpbrk(char_u *s, char_u *charset)
     {
        if (vim_strchr(charset, *s) != NULL)
            return s;
-       mb_ptr_adv(s);
+       MB_PTR_ADV(s);
     }
     return NULL;
 }
@@ -2082,7 +2099,7 @@ ga_concat_strings(garray_T *gap, char *sep)
     return s;
 }
 
-#if defined(FEAT_VIMINFO) || defined(PROTO)
+#if defined(FEAT_VIMINFO) || defined(FEAT_EVAL) || defined(PROTO)
 /*
  * Make a copy of string "p" and add it to "gap".
  * When out of memory nothing changes.
@@ -2112,7 +2129,7 @@ ga_concat(garray_T *gap, char_u *s)
 {
     int    len;
 
-    if (s == NULL)
+    if (s == NULL || *s == NUL)
        return;
     len = (int)STRLEN(s);
     if (ga_grow(gap, len) == OK)
@@ -2183,6 +2200,7 @@ static struct modmasktable
     /* 'A' must be the last one */
     {MOD_MASK_ALT,             MOD_MASK_ALT,           (char_u)'A'},
     {0, 0, NUL}
+    /* NOTE: when adding an entry, update MAX_KEY_NAME_LEN! */
 };
 
 /*
@@ -2315,6 +2333,8 @@ static struct key_name_entry
     {K_XDOWN,          (char_u *)"xDown"},
     {K_XLEFT,          (char_u *)"xLeft"},
     {K_XRIGHT,         (char_u *)"xRight"},
+    {K_PS,             (char_u *)"PasteStart"},
+    {K_PE,             (char_u *)"PasteEnd"},
 
     {K_F1,             (char_u *)"F1"},
     {K_F2,             (char_u *)"F2"},
@@ -2450,6 +2470,7 @@ static struct key_name_entry
     {K_PLUG,           (char_u *)"Plug"},
     {K_CURSORHOLD,     (char_u *)"CursorHold"},
     {0,                        NULL}
+    /* NOTE: When adding a long name update MAX_KEY_NAME_LEN. */
 };
 
 #define KEY_NAMES_TABLE_LEN (sizeof(key_names_table) / sizeof(struct key_name_entry))
@@ -2678,8 +2699,13 @@ get_special_key_name(int c, int modifiers)
     }
     else               /* use name of special key */
     {
-       STRCPY(string + idx, key_names_table[table_idx].name);
-       idx = (int)STRLEN(string);
+       size_t len = STRLEN(key_names_table[table_idx].name);
+
+       if (len + idx + 2 <= MAX_KEY_NAME_LEN)
+       {
+           STRCPY(string + idx, key_names_table[table_idx].name);
+           idx += (int)len;
+       }
     }
     string[idx++] = '>';
     string[idx] = NUL;
@@ -3338,8 +3364,8 @@ vim_chdirfile(char_u *fname)
  * Used for systems where stat() ignores a trailing slash on a file name.
  * The Vim code assumes a trailing slash is only ignored for a directory.
  */
-    int
-illegal_slash(char *name)
+    static int
+illegal_slash(const char *name)
 {
     if (name[0] == NUL)
        return FALSE;       /* no file name is not illegal */
@@ -3349,6 +3375,17 @@ illegal_slash(char *name)
        return FALSE;       /* trailing slash for a directory */
     return TRUE;
 }
+
+/*
+ * Special implementation of mch_stat() for Solaris.
+ */
+    int
+vim_stat(const char *name, stat_T *stp)
+{
+    /* On Solaris stat() accepts "file/" as if it was "file".  Return -1 if
+     * the name ends in "/" and it's not a directory. */
+    return illegal_slash(name) ? -1 : stat(name, stp);
+}
 #endif
 
 #if defined(CURSOR_SHAPE) || defined(PROTO)
@@ -3446,11 +3483,12 @@ parse_shape_opt(int what)
        while (*modep != NUL)
        {
            colonp = vim_strchr(modep, ':');
-           if (colonp == NULL)
+           commap = vim_strchr(modep, ',');
+
+           if (colonp == NULL || (commap != NULL && commap < colonp))
                return (char_u *)N_("E545: Missing colon");
            if (colonp == modep)
                return (char_u *)N_("E546: Illegal mode");
-           commap = vim_strchr(modep, ',');
 
            /*
             * Repeat for all mode's before the colon.
@@ -4599,13 +4637,23 @@ vim_findfile(void *search_ctx_arg)
                if (!vim_isAbsName(stackp->ffs_fix_path)
                                                && search_ctx->ffsc_start_dir)
                {
-                   STRCPY(file_path, search_ctx->ffsc_start_dir);
-                   add_pathsep(file_path);
+                   if (STRLEN(search_ctx->ffsc_start_dir) + 1 < MAXPATHL)
+                   {
+                       STRCPY(file_path, search_ctx->ffsc_start_dir);
+                       add_pathsep(file_path);
+                   }
+                   else
+                       goto fail;
                }
 
                /* append the fix part of the search path */
-               STRCAT(file_path, stackp->ffs_fix_path);
-               add_pathsep(file_path);
+               if (STRLEN(file_path) + STRLEN(stackp->ffs_fix_path) + 1 < MAXPATHL)
+               {
+                   STRCAT(file_path, stackp->ffs_fix_path);
+                   add_pathsep(file_path);
+               }
+               else
+                   goto fail;
 
 #ifdef FEAT_PATH_EXTRA
                rest_of_wildcards = stackp->ffs_wc_path;
@@ -4622,7 +4670,10 @@ vim_findfile(void *search_ctx_arg)
                        if (*p > 0)
                        {
                            (*p)--;
-                           file_path[len++] = '*';
+                           if (len + 1 < MAXPATHL)
+                               file_path[len++] = '*';
+                           else
+                               goto fail;
                        }
 
                        if (*p == 0)
@@ -4650,7 +4701,10 @@ vim_findfile(void *search_ctx_arg)
                     */
                    while (*rest_of_wildcards
                            && !vim_ispathsep(*rest_of_wildcards))
-                       file_path[len++] = *rest_of_wildcards++;
+                       if (len + 1 < MAXPATHL)
+                           file_path[len++] = *rest_of_wildcards++;
+                       else
+                           goto fail;
 
                    file_path[len] = NUL;
                    if (vim_ispathsep(*rest_of_wildcards))
@@ -4711,9 +4765,15 @@ vim_findfile(void *search_ctx_arg)
 
                        /* prepare the filename to be checked for existence
                         * below */
-                       STRCPY(file_path, stackp->ffs_filearray[i]);
-                       add_pathsep(file_path);
-                       STRCAT(file_path, search_ctx->ffsc_file_to_search);
+                       if (STRLEN(stackp->ffs_filearray[i]) + 1
+                               + STRLEN(search_ctx->ffsc_file_to_search) < MAXPATHL)
+                       {
+                           STRCPY(file_path, stackp->ffs_filearray[i]);
+                           add_pathsep(file_path);
+                           STRCAT(file_path, search_ctx->ffsc_file_to_search);
+                       }
+                       else
+                           goto fail;
 
                        /*
                         * Try without extra suffix and then with suffixes
@@ -4886,9 +4946,15 @@ vim_findfile(void *search_ctx_arg)
            if (*search_ctx->ffsc_start_dir == 0)
                break;
 
-           STRCPY(file_path, search_ctx->ffsc_start_dir);
-           add_pathsep(file_path);
-           STRCAT(file_path, search_ctx->ffsc_fix_path);
+           if (STRLEN(search_ctx->ffsc_start_dir) + 1
+                   + STRLEN(search_ctx->ffsc_fix_path) < MAXPATHL)
+           {
+               STRCPY(file_path, search_ctx->ffsc_start_dir);
+               add_pathsep(file_path);
+               STRCAT(file_path, search_ctx->ffsc_fix_path);
+           }
+           else
+               goto fail;
 
            /* create a new stack entry */
            sptr = ff_create_stack_element(file_path,
@@ -4902,6 +4968,7 @@ vim_findfile(void *search_ctx_arg)
     }
 #endif
 
+fail:
     vim_free(file_path);
     return NULL;
 }
@@ -6040,32 +6107,6 @@ filewritable(char_u *fname)
 }
 #endif
 
-/*
- * Print an error message with one or two "%s" and one or two string arguments.
- * This is not in message.c to avoid a warning for prototypes.
- */
-    int
-emsg3(char_u *s, char_u *a1, char_u *a2)
-{
-    if (emsg_not_now())
-       return TRUE;            /* no error messages at the moment */
-    vim_snprintf((char *)IObuff, IOSIZE, (char *)s, a1, a2);
-    return emsg(IObuff);
-}
-
-/*
- * Print an error message with one "%ld" and one long int argument.
- * This is not in message.c to avoid a warning for prototypes.
- */
-    int
-emsgn(char_u *s, long n)
-{
-    if (emsg_not_now())
-       return TRUE;            /* no error messages at the moment */
-    vim_snprintf((char *)IObuff, IOSIZE, (char *)s, n);
-    return emsg(IObuff);
-}
-
 #if defined(FEAT_SPELL) || defined(FEAT_PERSISTENT_UNDO) || defined(PROTO)
 /*
  * Read 2 bytes from "fd" and turn them into an int, MSB first.
@@ -6289,3 +6330,33 @@ parse_queued_messages(void)
 # endif
 }
 #endif
+
+#ifndef PROTO  /* proto is defined in vim.h */
+# ifdef ELAPSED_TIMEVAL
+/*
+ * Return time in msec since "start_tv".
+ */
+    long
+elapsed(struct timeval *start_tv)
+{
+    struct timeval  now_tv;
+
+    gettimeofday(&now_tv, NULL);
+    return (now_tv.tv_sec - start_tv->tv_sec) * 1000L
+        + (now_tv.tv_usec - start_tv->tv_usec) / 1000L;
+}
+# endif
+
+# ifdef ELAPSED_TICKCOUNT
+/*
+ * Return time in msec since "start_tick".
+ */
+    long
+elapsed(DWORD start_tick)
+{
+    DWORD      now = GetTickCount();
+
+    return (long)now - (long)start_tick;
+}
+# endif
+#endif
diff --git a/src/mkinstalldirs b/src/mkinstalldirs
deleted file mode 100755 (executable)
index 68c4e73..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-#! /bin/sh
-# mkinstalldirs --- make directory hierarchy
-# Author: Noah Friedman <friedman@prep.ai.mit.edu>
-# Created: 1993-05-16
-# Public domain
-
-errstatus=0
-
-for file
-do
-   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
-   shift
-
-   pathcomp=
-   for d
-   do
-     pathcomp="$pathcomp$d"
-     case "$pathcomp" in
-       -* ) pathcomp=./$pathcomp ;;
-     esac
-
-     if test ! -d "$pathcomp"; then
-       echo "mkdir $pathcomp" 1>&2
-
-       mkdir "$pathcomp" || lasterr=$?
-
-       if test ! -d "$pathcomp"; then
-         errstatus=$lasterr
-       fi
-     fi
-
-     pathcomp="$pathcomp/"
-   done
-done
-
-exit $errstatus
-
-# mkinstalldirs ends here
index 912e51c..f058b73 100644 (file)
@@ -177,11 +177,9 @@ update_topline(void)
     int                save_so = p_so;
 #endif
 
-    if (!screen_valid(TRUE))
-       return;
-
-    /* If the window height is zero just use the cursor line. */
-    if (curwin->w_height == 0)
+    /* If there is no valid screen and when the window height is zero just use
+     * the cursor line. */
+    if (!screen_valid(TRUE) || curwin->w_height == 0)
     {
        curwin->w_topline = curwin->w_cursor.lnum;
        curwin->w_botline = curwin->w_topline;
@@ -210,7 +208,7 @@ update_topline(void)
     /*
      * If the buffer is empty, always set topline to 1.
      */
-    if (bufempty())            /* special case - file is empty */
+    if (BUFEMPTY())            /* special case - file is empty */
     {
        if (curwin->w_topline != 1)
            redraw_later(NOT_VALID);
@@ -2592,6 +2590,7 @@ halfpage(int flag, linenr_T Prenum)
     n = (curwin->w_p_scr <= curwin->w_height) ?
                                    curwin->w_p_scr : curwin->w_height;
 
+    update_topline();
     validate_botline();
     room = curwin->w_empty_rows;
 #ifdef FEAT_DIFF
@@ -2841,6 +2840,10 @@ do_check_cursorbind(void)
            restart_edit_save = restart_edit;
            restart_edit = TRUE;
            check_cursor();
+# ifdef FEAT_SYN_HL
+           if (curwin->w_p_cul || curwin->w_p_cuc)
+               validate_cursor();
+# endif
            restart_edit = restart_edit_save;
 # ifdef FEAT_MBYTE
            /* Correct cursor for multi-byte character. */
index 42b6cbb..fc751c0 100644 (file)
@@ -1 +1 @@
-=auto/configure\e-lastupdate=1178970549.78\e-@buildcheck=dfc15c059b7ce88a951584995c49a201\e=configure.in@md5=e0d6e9a7d7b986d63ce4e8e7362fd0b9\e
+=auto/configure\e-lastupdate=1178970549.78\e-@buildcheck=dfc15c059b7ce88a951584995c49a201\e=configure.ac@md5=e0d6e9a7d7b986d63ce4e8e7362fd0b9\e
index cc55604..fb4cb76 100644 (file)
@@ -2332,7 +2332,8 @@ special_keys(char_u *args)
     char *save_str = nb_unquote(args, NULL);
     char *tok = strtok(save_str, " ");
     char *sep;
-    char keybuf[64];
+#define KEYBUFLEN 64
+    char keybuf[KEYBUFLEN];
     char cmdbuf[256];
 
     while (tok != NULL)
@@ -2359,10 +2360,13 @@ special_keys(char_u *args)
            tok++;
        }
 
-       strcpy(&keybuf[i], tok);
-       vim_snprintf(cmdbuf, sizeof(cmdbuf),
-                               "<silent><%s> :nbkey %s<CR>", keybuf, keybuf);
-       do_map(0, (char_u *)cmdbuf, NORMAL, FALSE);
+       if (strlen(tok) + i < KEYBUFLEN)
+       {
+           strcpy(&keybuf[i], tok);
+           vim_snprintf(cmdbuf, sizeof(cmdbuf),
+                                "<silent><%s> :nbkey %s<CR>", keybuf, keybuf);
+           do_map(0, (char_u *)cmdbuf, NORMAL, FALSE);
+       }
        tok = strtok(NULL, " ");
     }
     vim_free(save_str);
index 5d0796f..25c0986 100644 (file)
@@ -426,6 +426,7 @@ static const struct nv_cmd
 #ifdef FEAT_AUTOCMD
     {K_CURSORHOLD, nv_cursorhold, NV_KEEPREG,          0},
 #endif
+    {K_PS,     nv_edit,        0,                      0},
 };
 
 /* Number of commands in nv_cmds[]. */
@@ -1539,7 +1540,7 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
            if (VIsual_select && VIsual_mode == 'V'
                                            && cap->oap->op_type != OP_DELETE)
            {
-               if (lt(VIsual, curwin->w_cursor))
+               if (LT_POS(VIsual, curwin->w_cursor))
                {
                    VIsual.col = 0;
                    curwin->w_cursor.col =
@@ -1571,7 +1572,7 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
         * Set oap->start to the first position of the operated text, oap->end
         * to the end of the operated text.  w_cursor is equal to oap->start.
         */
-       if (lt(oap->start, curwin->w_cursor))
+       if (LT_POS(oap->start, curwin->w_cursor))
        {
 #ifdef FEAT_FOLDING
            /* Include folded lines completely. */
@@ -1775,7 +1776,7 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
                    && (!oap->inclusive
                        || (oap->op_type == OP_YANK
                            && gchar_pos(&oap->end) == NUL))
-                   && equalpos(oap->start, oap->end)
+                   && EQUAL_POS(oap->start, oap->end)
 #ifdef FEAT_VIRTUALEDIT
                    && !(virtual_op && oap->start.coladd != oap->end.coladd)
 #endif
@@ -1984,7 +1985,7 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
                op_formatexpr(oap);     /* use expression */
            else
 #endif
-               if (*p_fp != NUL)
+               if (*p_fp != NUL || *curbuf->b_p_fp != NUL)
                op_colon(oap);          /* use external command */
            else
                op_format(oap, FALSE);  /* use internal function */
@@ -2040,6 +2041,8 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
 
                if (restart_edit == 0)
                    restart_edit = restart_edit_save;
+               else
+                   cap->retval |= CA_COMMAND_BUSY;
            }
 #else
            vim_beep(BO_OPER);
@@ -2197,10 +2200,12 @@ op_colon(oparg_T *oap)
     }
     else if (oap->op_type == OP_FORMAT)
     {
-       if (*p_fp == NUL)
-           stuffReadbuff((char_u *)"fmt");
-       else
+       if (*curbuf->b_p_fp != NUL)
+           stuffReadbuff(curbuf->b_p_fp);
+       else if (*p_fp != NUL)
            stuffReadbuff(p_fp);
+       else
+           stuffReadbuff((char_u *)"fmt");
        stuffReadbuff((char_u *)"\n']");
     }
 
@@ -2678,12 +2683,12 @@ do_mouse(
                            jump_flags = MOUSE_MAY_STOP_VIS;
                        else
                        {
-                           if ((lt(curwin->w_cursor, VIsual)
-                                       && (lt(m_pos, curwin->w_cursor)
-                                           || lt(VIsual, m_pos)))
-                                   || (lt(VIsual, curwin->w_cursor)
-                                       && (lt(m_pos, VIsual)
-                                           || lt(curwin->w_cursor, m_pos))))
+                           if ((LT_POS(curwin->w_cursor, VIsual)
+                                       && (LT_POS(m_pos, curwin->w_cursor)
+                                           || LT_POS(VIsual, m_pos)))
+                                   || (LT_POS(VIsual, curwin->w_cursor)
+                                       && (LT_POS(m_pos, VIsual)
+                                         || LT_POS(curwin->w_cursor, m_pos))))
                            {
                                jump_flags = MOUSE_MAY_STOP_VIS;
                            }
@@ -2749,7 +2754,7 @@ do_mouse(
                 * Remember the start and end of visual before moving the
                 * cursor.
                 */
-               if (lt(curwin->w_cursor, VIsual))
+               if (LT_POS(curwin->w_cursor, VIsual))
                {
                    start_visual = curwin->w_cursor;
                    end_visual = VIsual;
@@ -2886,9 +2891,9 @@ do_mouse(
             * If the click is after the end of visual, change the end.  If
             * the click is inside the visual, change the closest side.
             */
-           if (lt(curwin->w_cursor, start_visual))
+           if (LT_POS(curwin->w_cursor, start_visual))
                VIsual = end_visual;
-           else if (lt(end_visual, curwin->w_cursor))
+           else if (LT_POS(end_visual, curwin->w_cursor))
                VIsual = start_visual;
            else
            {
@@ -2977,12 +2982,10 @@ do_mouse(
                || (mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)
            && bt_quickfix(curbuf))
     {
-       if (State & INSERT)
-           stuffcharReadbuff(Ctrl_O);
        if (curwin->w_llist_ref == NULL)        /* quickfix window */
-           stuffReadbuff((char_u *)":.cc\n");
+           do_cmdline_cmd((char_u *)".cc");
        else                                    /* location list window */
-           stuffReadbuff((char_u *)":.ll\n");
+           do_cmdline_cmd((char_u *)".ll");
        got_click = FALSE;              /* ignore drag&release now */
     }
 #endif
@@ -3087,14 +3090,14 @@ do_mouse(
                 * not a word character, try finding a match and select a (),
                 * {}, [], #if/#endif, etc. block. */
                end_visual = curwin->w_cursor;
-               while (gc = gchar_pos(&end_visual), vim_iswhite(gc))
+               while (gc = gchar_pos(&end_visual), VIM_ISWHITE(gc))
                    inc(&end_visual);
                if (oap != NULL)
                    oap->motion_type = MCHAR;
                if (oap != NULL
                        && VIsual_mode == 'v'
                        && !vim_iswordc(gchar_pos(&end_visual))
-                       && equalpos(curwin->w_cursor, VIsual)
+                       && EQUAL_POS(curwin->w_cursor, VIsual)
                        && (pos = findmatch(oap, NUL)) != NULL)
                {
                    curwin->w_cursor = *pos;
@@ -3102,7 +3105,7 @@ do_mouse(
                        VIsual_mode = 'V';
                    else if (*p_sel == 'e')
                    {
-                       if (lt(curwin->w_cursor, VIsual))
+                       if (LT_POS(curwin->w_cursor, VIsual))
                            ++VIsual.col;
                        else
                            ++curwin->w_cursor.col;
@@ -3114,7 +3117,7 @@ do_mouse(
            {
                /* When not found a match or when dragging: extend to include
                 * a word. */
-               if (lt(curwin->w_cursor, orig_cursor))
+               if (LT_POS(curwin->w_cursor, orig_cursor))
                {
                    find_start_of_word(&curwin->w_cursor);
                    find_end_of_word(&VIsual);
@@ -3263,7 +3266,7 @@ check_visual_highlight(void)
 
     if (full_screen)
     {
-       if (!did_check && hl_attr(HLF_V) == 0)
+       if (!did_check && HL_ATTR(HLF_V) == 0)
            MSG(_("Warning: terminal cannot highlight"));
        did_check = TRUE;
     }
@@ -3464,7 +3467,7 @@ find_ident_at_pos(
        else
 #endif
            while (ptr[col] != NUL
-                   && (i == 0 ? !vim_iswordc(ptr[col]) : vim_iswhite(ptr[col]))
+                   && (i == 0 ? !vim_iswordc(ptr[col]) : VIM_ISWHITE(ptr[col]))
 # if defined(FEAT_BEVAL)
                    && (!(find_type & FIND_EVAL) || ptr[col] != ']')
 # endif
@@ -3521,7 +3524,7 @@ find_ident_at_pos(
            while (col > 0
                    && ((i == 0
                            ? vim_iswordc(ptr[col - 1])
-                           : (!vim_iswhite(ptr[col - 1])
+                           : (!VIM_ISWHITE(ptr[col - 1])
                                && (!(find_type & FIND_IDENT)
                                    || !vim_iswordc(ptr[col - 1]))))
 #if defined(FEAT_BEVAL)
@@ -3585,7 +3588,7 @@ find_ident_at_pos(
     else
 #endif
        while ((i == 0 ? vim_iswordc(ptr[col])
-                      : (ptr[col] != NUL && !vim_iswhite(ptr[col])))
+                      : (ptr[col] != NUL && !VIM_ISWHITE(ptr[col])))
 # if defined(FEAT_BEVAL)
                    || ((find_type & FIND_EVAL)
                        && col <= (int)startcol
@@ -3742,7 +3745,7 @@ clear_showcmd(void)
 
     if (VIsual_active && !char_avail())
     {
-       int             cursor_bot = lt(VIsual, curwin->w_cursor);
+       int             cursor_bot = LT_POS(VIsual, curwin->w_cursor);
        long            lines;
        colnr_T         leftcol, rightcol;
        linenr_T        top, bot;
@@ -3856,7 +3859,7 @@ add_to_showcmd(int c)
        K_VER_SCROLLBAR, K_HOR_SCROLLBAR,
        K_LEFTMOUSE_NM, K_LEFTRELEASE_NM,
 # endif
-       K_IGNORE,
+       K_IGNORE, K_PS,
        K_LEFTMOUSE, K_LEFTDRAG, K_LEFTRELEASE,
        K_MIDDLEMOUSE, K_MIDDLEDRAG, K_MIDDLERELEASE,
        K_RIGHTMOUSE, K_RIGHTDRAG, K_RIGHTRELEASE,
@@ -4350,7 +4353,7 @@ find_decl(
     curwin->w_cursor.col = 0;
 
     /* Search forward for the identifier, ignore comment lines. */
-    clearpos(&found_pos);
+    CLEAR_POS(&found_pos);
     for (;;)
     {
        valid = FALSE;
@@ -4368,7 +4371,12 @@ find_decl(
            if ((pos = findmatchlimit(NULL, '}', FM_FORWARD,
                     (int)(old_pos.lnum - curwin->w_cursor.lnum + 1))) != NULL
                    && pos->lnum < old_pos.lnum)
+           {
+               /* There can't be a useful match before the end of this block.
+                * Skip to the end. */
+               curwin->w_cursor = *pos;
                continue;
+           }
        }
 
        if (t == FAIL)
@@ -4416,13 +4424,10 @@ find_decl(
         * declarations this skips the function header without types. */
        if (!valid)
        {
-           /* Braces needed due to macro expansion of clearpos. */
-           clearpos(&found_pos);
+           CLEAR_POS(&found_pos);
        }
        else
-       {
            found_pos = curwin->w_cursor;
-       }
        /* Remove SEARCH_START from flags to avoid getting stuck at one
         * position. */
        searchflags &= ~SEARCH_START;
@@ -5831,7 +5836,7 @@ get_visual_text(
     }
     else
     {
-       if (lt(curwin->w_cursor, VIsual))
+       if (LT_POS(curwin->w_cursor, VIsual))
        {
            *pp = ml_get_pos(&curwin->w_cursor);
            *lenp = VIsual.col - curwin->w_cursor.col + 1;
@@ -6017,7 +6022,7 @@ nv_right(cmdarg_T *cap)
                 * included, move to next line after that */
                if (       cap->oap->op_type != OP_NOP
                        && !cap->oap->inclusive
-                       && !lineempty(curwin->w_cursor.lnum))
+                       && !LINEEMPTY(curwin->w_cursor.lnum))
                    cap->oap->inclusive = TRUE;
                else
                {
@@ -6039,7 +6044,7 @@ nv_right(cmdarg_T *cap)
            }
            else
            {
-               if (!lineempty(curwin->w_cursor.lnum))
+               if (!LINEEMPTY(curwin->w_cursor.lnum))
                    cap->oap->inclusive = TRUE;
            }
            break;
@@ -6118,7 +6123,7 @@ nv_left(cmdarg_T *cap)
                 * Don't adjust op_end now, otherwise it won't work. */
                if (       (cap->oap->op_type == OP_DELETE
                            || cap->oap->op_type == OP_CHANGE)
-                       && !lineempty(curwin->w_cursor.lnum))
+                       && !LINEEMPTY(curwin->w_cursor.lnum))
                {
                    char_u *cp = ml_get_cursor();
 
@@ -6188,10 +6193,12 @@ nv_down(cmdarg_T *cap)
 #if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
     /* In a quickfix window a <CR> jumps to the error under the cursor. */
     if (bt_quickfix(curbuf) && cap->cmdchar == CAR)
+    {
        if (curwin->w_llist_ref == NULL)
            do_cmdline_cmd((char_u *)".cc");    /* quickfix window */
        else
            do_cmdline_cmd((char_u *)".ll");    /* location list window */
+    }
     else
 #endif
     {
@@ -6328,7 +6335,7 @@ nv_search(cmdarg_T *cap)
     }
 
     (void)normal_search(cap, cap->cmdchar, cap->searchbuf,
-                       (cap->arg || !equalpos(save_cursor, curwin->w_cursor))
+                       (cap->arg || !EQUAL_POS(save_cursor, curwin->w_cursor))
                                                           ? 0 : SEARCH_MARK);
 }
 
@@ -6342,7 +6349,7 @@ nv_next(cmdarg_T *cap)
     pos_T old = curwin->w_cursor;
     int   i = normal_search(cap, 0, NULL, SEARCH_MARK | cap->arg);
 
-    if (i == 1 && equalpos(old, curwin->w_cursor))
+    if (i == 1 && EQUAL_POS(old, curwin->w_cursor))
     {
        /* Avoid getting stuck on the current cursor position, which can
         * happen when an offset is given and the cursor is on the last char
@@ -6684,9 +6691,9 @@ nv_brackets(cmdarg_T *cap)
 
            if (VIsual_active)
            {
-               start = ltoreq(VIsual, curwin->w_cursor)
+               start = LTOREQ_POS(VIsual, curwin->w_cursor)
                                                  ? VIsual : curwin->w_cursor;
-               end =  equalpos(start,VIsual) ? curwin->w_cursor : VIsual;
+               end =  EQUAL_POS(start,VIsual) ? curwin->w_cursor : VIsual;
                curwin->w_cursor = (dir == BACKWARD ? start : end);
            }
 # ifdef FEAT_CLIPBOARD
@@ -7310,7 +7317,7 @@ n_swapchar(cmdarg_T *cap)
     if (checkclearopq(cap->oap))
        return;
 
-    if (lineempty(curwin->w_cursor.lnum) && vim_strchr(p_ww, '~') == NULL)
+    if (LINEEMPTY(curwin->w_cursor.lnum) && vim_strchr(p_ww, '~') == NULL)
     {
        clearopbeep(cap->oap);
        return;
@@ -7554,7 +7561,7 @@ nv_gomark(cmdarg_T *cap)
 #ifdef FEAT_FOLDING
     if (cap->oap->op_type == OP_NOP
            && pos != NULL
-           && (pos == (pos_T *)-1 || !equalpos(old_cursor, *pos))
+           && (pos == (pos_T *)-1 || !EQUAL_POS(old_cursor, *pos))
            && (fdo_flags & FDO_MARK)
            && old_KeyTyped)
        foldOpenCursor();
@@ -8107,7 +8114,7 @@ nv_g_cmd(cmdarg_T *cap)
        {
            do
                i = gchar_cursor();
-           while (vim_iswhite(i) && oneright() == OK);
+           while (VIM_ISWHITE(i) && oneright() == OK);
        }
        curwin->w_set_curswant = TRUE;
        break;
@@ -8131,7 +8138,7 @@ nv_g_cmd(cmdarg_T *cap)
 
            /* Decrease the cursor column until it's on a non-blank. */
            while (curwin->w_cursor.col > 0
-                                   && vim_iswhite(ptr[curwin->w_cursor.col]))
+                                   && VIM_ISWHITE(ptr[curwin->w_cursor.col]))
                --curwin->w_cursor.col;
            curwin->w_set_curswant = TRUE;
            adjust_for_sel(cap);
@@ -8309,6 +8316,7 @@ nv_g_cmd(cmdarg_T *cap)
        break;
 #endif
 
+    /* "g<": show scrollback text */
     case '<':
        show_sb_text();
        break;
@@ -8714,7 +8722,7 @@ nv_wordcmd(cmdarg_T *cap)
        n = gchar_cursor();
        if (n != NUL)                   /* not an empty line */
        {
-           if (vim_iswhite(n))
+           if (VIM_ISWHITE(n))
            {
                /*
                 * Reproduce a funny Vi behaviour: "cw" on a blank only
@@ -8758,7 +8766,7 @@ nv_wordcmd(cmdarg_T *cap)
 
     /* Don't leave the cursor on the NUL past the end of line. Unless we
      * didn't move it forward. */
-    if (lt(startpos, curwin->w_cursor))
+    if (LT_POS(startpos, curwin->w_cursor))
        adjust_cursor(cap->oap);
 
     if (n == FAIL && cap->oap->op_type == OP_NOP)
@@ -8828,7 +8836,7 @@ nv_beginline(cmdarg_T *cap)
 adjust_for_sel(cmdarg_T *cap)
 {
     if (VIsual_active && cap->oap->inclusive && *p_sel == 'e'
-           && gchar_cursor() != NUL && lt(VIsual, curwin->w_cursor))
+           && gchar_cursor() != NUL && LT_POS(VIsual, curwin->w_cursor))
     {
 #ifdef FEAT_MBYTE
        if (has_mbyte)
@@ -8850,9 +8858,9 @@ unadjust_for_sel(void)
 {
     pos_T      *pp;
 
-    if (*p_sel == 'e' && !equalpos(VIsual, curwin->w_cursor))
+    if (*p_sel == 'e' && !EQUAL_POS(VIsual, curwin->w_cursor))
     {
-       if (lt(VIsual, curwin->w_cursor))
+       if (LT_POS(VIsual, curwin->w_cursor))
            pp = &curwin->w_cursor;
        else
            pp = &VIsual;
@@ -9013,6 +9021,7 @@ nv_esc(cmdarg_T *cap)
 
 /*
  * Handle "A", "a", "I", "i" and <Insert> commands.
+ * Also handle K_PS, start bracketed paste.
  */
     static void
 nv_edit(cmdarg_T *cap)
@@ -9040,6 +9049,37 @@ nv_edit(cmdarg_T *cap)
        /* Only give this error when 'insertmode' is off. */
        EMSG(_(e_modifiable));
        clearop(cap->oap);
+       if (cap->cmdchar == K_PS)
+           /* drop the pasted text */
+           bracketed_paste(PASTE_INSERT, TRUE, NULL);
+    }
+    else if (cap->cmdchar == K_PS && VIsual_active)
+    {
+       pos_T old_pos = curwin->w_cursor;
+       pos_T old_visual = VIsual;
+
+       /* In Visual mode the selected text is deleted. */
+       if (VIsual_mode == 'V' || curwin->w_cursor.lnum != VIsual.lnum)
+       {
+           shift_delete_registers();
+           cap->oap->regname = '1';
+       }
+       else
+           cap->oap->regname = '-';
+       cap->cmdchar = 'd';
+       cap->nchar = NUL;
+       nv_operator(cap);
+       do_pending_operator(cap, 0, FALSE);
+       cap->cmdchar = K_PS;
+
+       /* When the last char in the line was deleted then append. Detect this
+        * by checking if the cursor moved to before the Visual area. */
+       if (*ml_get_cursor() != NUL && LT_POS(curwin->w_cursor, old_pos)
+                                      && LT_POS(curwin->w_cursor, old_visual))
+           inc_cursor();
+
+       /* Insert to replace the deleted text with the pasted text. */
+       invoke_edit(cap, FALSE, cap->cmdchar, FALSE);
     }
     else if (!checkclearopq(cap->oap))
     {
@@ -9070,6 +9110,13 @@ nv_edit(cmdarg_T *cap)
                    beginline(BL_WHITE|BL_FIX);
                break;
 
+           case K_PS:
+               /* Bracketed paste works like "a"ppend, unless the cursor is in
+                * the first column, then it inserts. */
+               if (curwin->w_cursor.col == 0)
+                   break;
+               /*FALLTHROUGH*/
+
            case 'a':   /* "a"ppend is like "i"nsert on the next character. */
 #ifdef FEAT_VIRTUALEDIT
                /* increment coladd when in virtual space, increment the
@@ -9101,6 +9148,9 @@ nv_edit(cmdarg_T *cap)
 
        invoke_edit(cap, FALSE, cap->cmdchar, FALSE);
     }
+    else if (cap->cmdchar == K_PS)
+       /* drop the pasted text */
+       bracketed_paste(PASTE_INSERT, TRUE, NULL);
 }
 
 /*
index 4bef6c5..7cbc0c2 100644 (file)
--- a/src/ops.c
+++ b/src/ops.c
@@ -113,9 +113,6 @@ static void copy_yank_reg(yankreg_T *reg);
 static void    may_set_selection(void);
 #endif
 static void    dis_msg(char_u *p, int skip_esc);
-#if defined(FEAT_COMMENTS) || defined(PROTO)
-static char_u  *skip_comment(char_u *line, int process, int include_space, int *is_comment);
-#endif
 static void    block_prep(oparg_T *oap, struct block_def *, linenr_T, int);
 static int     do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1);
 #if defined(FEAT_CLIPBOARD) || defined(FEAT_EVAL)
@@ -259,11 +256,6 @@ op_shift(oparg_T *oap, int curs_top, int amount)
     }
 
     changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L);
-#ifdef FEAT_FOLDING
-    /* The cursor line is not in a closed fold */
-    foldOpenCursor();
-#endif
-
     if (oap->block_mode)
     {
        curwin->w_cursor.lnum = oap->start.lnum;
@@ -277,6 +269,12 @@ op_shift(oparg_T *oap, int curs_top, int amount)
     else
        --curwin->w_cursor.lnum;        /* put cursor on last line, for ":>" */
 
+#ifdef FEAT_FOLDING
+    /* The cursor line is not in a closed fold */
+    foldOpenCursor();
+#endif
+
+
     if (oap->line_count > p_report)
     {
        if (oap->op_type == OP_RSHIFT)
@@ -428,7 +426,7 @@ shift_block(oparg_T *oap, int amount)
 #endif
                ++bd.textstart;
        }
-       for ( ; vim_iswhite(*bd.textstart); )
+       for ( ; VIM_ISWHITE(*bd.textstart); )
        {
            /* TODO: is passing bd.textstart for start of the line OK? */
            incr = lbr_chartabsize_adv(bd.textstart, &bd.textstart,
@@ -485,12 +483,12 @@ shift_block(oparg_T *oap, int amount)
         * 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);
+           MB_PTR_ADV(non_white);
 
        /* The character's column is in "bd.start_vcol".  */
        non_white_col = bd.start_vcol;
 
-       while (vim_iswhite(*non_white))
+       while (VIM_ISWHITE(*non_white))
        {
            incr = lbr_chartabsize_adv(bd.textstart, &non_white, non_white_col);
            non_white_col += incr;
@@ -525,7 +523,7 @@ shift_block(oparg_T *oap, int amount)
            if (verbatim_copy_width + incr > destination_col)
                break;
            verbatim_copy_width += incr;
-           mb_ptr_adv(verbatim_copy_end);
+           MB_PTR_ADV(verbatim_copy_end);
        }
 
        /* If "destination_col" is different from the width of the initial
@@ -1627,6 +1625,22 @@ adjust_clip_reg(int *rp)
 #endif
 
 /*
+ * Shift the delete registers: "9 is cleared, "8 becomes "9, etc.
+ */
+    void
+shift_delete_registers()
+{
+    int                n;
+
+    y_current = &y_regs[9];
+    free_yank_all();                   /* free register nine */
+    for (n = 9; n > 1; --n)
+       y_regs[n] = y_regs[n - 1];
+    y_previous = y_current = &y_regs[1];
+    y_regs[1].y_array = NULL;          /* set register one to empty */
+}
+
+/*
  * Handle a delete operation.
  *
  * Return FAIL if undo failed, OK otherwise.
@@ -1738,12 +1752,7 @@ op_delete(oparg_T *oap)
        if (orig_regname != 0 || oap->motion_type == MLINE
                                   || oap->line_count > 1 || oap->use_reg_one)
        {
-           y_current = &y_regs[9];
-           free_yank_all();                    /* free register nine */
-           for (n = 9; n > 1; --n)
-               y_regs[n] = y_regs[n - 1];
-           y_previous = y_current = &y_regs[1];
-           y_regs[1].y_array = NULL;           /* set register one to empty */
+           shift_delete_registers();
            if (op_yank(oap, TRUE, FALSE) == OK)
                did_yank = TRUE;
        }
@@ -2178,7 +2187,7 @@ op_replace(oparg_T *oap, int c)
        else if (!oap->inclusive)
            dec(&(oap->end));
 
-       while (ltoreq(curwin->w_cursor, oap->end))
+       while (LTOREQ_POS(curwin->w_cursor, oap->end))
        {
            n = gchar_cursor();
            if (n != NUL)
@@ -2217,7 +2226,7 @@ op_replace(oparg_T *oap, int c)
                            getvpos(&oap->end, end_vcol);
                    }
 #endif
-                   pchar(curwin->w_cursor, c);
+                   PCHAR(curwin->w_cursor, c);
                }
            }
 #ifdef FEAT_VIRTUALEDIT
@@ -2236,7 +2245,7 @@ op_replace(oparg_T *oap, int c)
                curwin->w_cursor.col -= (virtcols + 1);
                for (; virtcols >= 0; virtcols--)
                {
-                   pchar(curwin->w_cursor, c);
+                   PCHAR(curwin->w_cursor, c);
                    if (inc(&curwin->w_cursor) == -1)
                        break;
                }
@@ -2326,7 +2335,7 @@ op_tilde(oparg_T *oap)
                did_change |= swapchars(oap->op_type, &pos,
                                pos.lnum == oap->end.lnum ? oap->end.col + 1:
                                           (int)STRLEN(ml_get_pos(&pos)));
-               if (ltoreq(oap->end, pos) || inc(&pos) == -1)
+               if (LTOREQ_POS(oap->end, pos) || inc(&pos) == -1)
                    break;
            }
        if (did_change)
@@ -2478,7 +2487,7 @@ swapchar(int op_type, pos_T *pos)
        }
        else
 #endif
-           pchar(*pos, nc);
+           PCHAR(*pos, nc);
        return TRUE;
     }
     return FALSE;
@@ -2563,20 +2572,20 @@ op_insert(oparg_T *oap, long count1)
            check_cursor_col();
 
            /* Works just like an 'i'nsert on the next character. */
-           if (!lineempty(curwin->w_cursor.lnum)
+           if (!LINEEMPTY(curwin->w_cursor.lnum)
                    && oap->start_vcol != oap->end_vcol)
                inc_cursor();
        }
     }
 
     t1 = oap->start;
-    edit(NUL, FALSE, (linenr_T)count1);
+    (void)edit(NUL, FALSE, (linenr_T)count1);
 
     /* When a tab was inserted, and the characters in front of the tab
      * have been converted to a tab as well, the column of the cursor
      * might have actually been reduced, so need to adjust here. */
     if (t1.lnum == curbuf->b_op_start_orig.lnum
-           && lt(curbuf->b_op_start_orig, t1))
+           && LT_POS(curbuf->b_op_start_orig, t1))
        oap->start = curbuf->b_op_start_orig;
 
     /* If user has moved off this line, we don't know what to do, so do
@@ -2723,7 +2732,7 @@ op_change(oparg_T *oap)
     else if (op_delete(oap) == FAIL)
        return FALSE;
 
-    if ((l > curwin->w_cursor.col) && !lineempty(curwin->w_cursor.lnum)
+    if ((l > curwin->w_cursor.col) && !LINEEMPTY(curwin->w_cursor.lnum)
                                                         && !virtual_op)
        inc_cursor();
 
@@ -3350,6 +3359,8 @@ do_put(
      */
     if (regname == '.')
     {
+       if (VIsual_active)
+           stuffcharReadbuff(VIsual_mode);
        (void)stuff_inserted((dir == FORWARD ? (count == -1 ? 'o' : 'a') :
                                    (count == -1 ? 'O' : 'i')), count, FALSE);
        /* Putting the text is done later, so can't really move the cursor to
@@ -3444,7 +3455,7 @@ do_put(
                goto end;
            p = ml_get_cursor();
            if (dir == FORWARD && *p != NUL)
-               mb_ptr_adv(p);
+               MB_PTR_ADV(p);
            ptr = vim_strsave(p);
            if (ptr == NULL)
                goto end;
@@ -3454,7 +3465,7 @@ do_put(
            oldp = ml_get_curline();
            p = oldp + curwin->w_cursor.col;
            if (dir == FORWARD && *p != NUL)
-               mb_ptr_adv(p);
+               MB_PTR_ADV(p);
            ptr = vim_strnsave(oldp, p - oldp);
            if (ptr == NULL)
                goto end;
@@ -3505,7 +3516,7 @@ do_put(
            ++lnum;
        /* In an empty buffer the empty line is going to be replaced, include
         * it in the saved lines. */
-       if ((bufempty() ? u_save(0, 2) : u_save(lnum - 1, lnum)) == FAIL)
+       if ((BUFEMPTY() ? u_save(0, 2) : u_save(lnum - 1, lnum)) == FAIL)
            goto end;
 #ifdef FEAT_FOLDING
        if (dir == FORWARD)
@@ -3547,7 +3558,7 @@ do_put(
      */
     if (y_type == MBLOCK)
     {
-       char    c = gchar_cursor();
+       int     c = gchar_cursor();
        colnr_T endcol2 = 0;
 
        if (dir == FORWARD && c != NUL)
@@ -3771,11 +3782,25 @@ do_put(
         */
        if (y_type == MCHAR && y_size == 1)
        {
+           linenr_T end_lnum = 0; /* init for gcc */
+
+           if (VIsual_active)
+           {
+               end_lnum = curbuf->b_visual.vi_end.lnum;
+               if (end_lnum < curbuf->b_visual.vi_start.lnum)
+                   end_lnum = curbuf->b_visual.vi_start.lnum;
+           }
+
            do {
                totlen = count * yanklen;
                if (totlen > 0)
                {
                    oldp = ml_get(lnum);
+                   if (VIsual_active && col > (int)STRLEN(oldp))
+                   {
+                       lnum++;
+                       continue;
+                   }
                    newp = alloc_check((unsigned)(STRLEN(oldp) + totlen + 1));
                    if (newp == NULL)
                        goto end;       /* alloc() gave an error message */
@@ -3798,7 +3823,7 @@ do_put(
                }
                if (VIsual_active)
                    lnum++;
-           } while (VIsual_active && lnum <= curbuf->b_visual.vi_end.lnum);
+           } while (VIsual_active && lnum <= end_lnum);
 
            if (VIsual_active) /* reset lnum to the last visual line */
                lnum--;
@@ -3899,9 +3924,13 @@ error:
                    curbuf->b_op_start.lnum++;
            }
            /* Skip mark_adjust when adding lines after the last one, there
-            * can't be marks there. */
+            * can't be marks there. But still needed in diff mode. */
            if (curbuf->b_op_start.lnum + (y_type == MCHAR) - 1 + nr_lines
-                                                < curbuf->b_ml.ml_line_count)
+                                                < curbuf->b_ml.ml_line_count
+#ifdef FEAT_DIFF
+                                                || curwin->w_p_diff
+#endif
+                                                )
                mark_adjust(curbuf->b_op_start.lnum + (y_type == MCHAR),
                                             (linenr_T)MAXLNUM, nr_lines, 0L);
 
@@ -4083,7 +4112,7 @@ ex_display(exarg_T *eap)
 
     if (arg != NULL && *arg == NUL)
        arg = NULL;
-    attr = hl_attr(HLF_8);
+    attr = HL_ATTR(HLF_8);
 
     /* Highlight title */
     MSG_PUTS_TITLE(_("\n--- Registers ---"));
@@ -4269,7 +4298,7 @@ dis_msg(
  * is_comment - will indicate whether the current line ends with an unclosed
  *             comment.
  */
-    static char_u *
+    char_u *
 skip_comment(
     char_u   *line,
     int      process,
@@ -4457,11 +4486,11 @@ do_join(
            if (has_mbyte)
            {
                cend = curr + currsize;
-               mb_ptr_back(curr, cend);
+               MB_PTR_BACK(curr, cend);
                endcurr1 = (*mb_ptr2char)(cend);
                if (cend > curr)
                {
-                   mb_ptr_back(curr, cend);
+                   MB_PTR_BACK(curr, cend);
                    endcurr2 = (*mb_ptr2char)(cend);
                }
            }
@@ -4623,18 +4652,18 @@ same_leader(
     line1 = vim_strsave(ml_get(lnum));
     if (line1 != NULL)
     {
-       for (idx1 = 0; vim_iswhite(line1[idx1]); ++idx1)
+       for (idx1 = 0; VIM_ISWHITE(line1[idx1]); ++idx1)
            ;
        line2 = ml_get(lnum + 1);
        for (idx2 = 0; idx2 < leader2_len; ++idx2)
        {
-           if (!vim_iswhite(line2[idx2]))
+           if (!VIM_ISWHITE(line2[idx2]))
            {
                if (line1[idx1++] != line2[idx2])
                    break;
            }
            else
-               while (vim_iswhite(line1[idx1]))
+               while (VIM_ISWHITE(line1[idx1]))
                    ++idx1;
        }
        vim_free(line1);
@@ -4904,7 +4933,7 @@ format_lines(
                    && prev_is_end_par
                    && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
            {
-               if (do_second_indent && !lineempty(curwin->w_cursor.lnum + 1))
+               if (do_second_indent && !LINEEMPTY(curwin->w_cursor.lnum + 1))
                {
 #ifdef FEAT_COMMENTS
                    if (leader_len == 0 && next_leader_len == 0)
@@ -5060,10 +5089,10 @@ ends_in_white(linenr_T lnum)
 
     if (*s == NUL)
        return FALSE;
-    /* Don't use STRLEN() inside vim_iswhite(), SAS/C complains: "macro
+    /* Don't use STRLEN() inside VIM_ISWHITE(), SAS/C complains: "macro
      * invocation may call function multiple times". */
     l = STRLEN(s) - 1;
-    return vim_iswhite(s[l]);
+    return VIM_ISWHITE(s[l]);
 }
 
 /*
@@ -5218,7 +5247,7 @@ block_prep(
        incr = lbr_chartabsize(line, pstart, (colnr_T)bdp->start_vcol);
        bdp->start_vcol += incr;
 #ifdef FEAT_VISUALEXTRA
-       if (vim_iswhite(*pstart))
+       if (VIM_ISWHITE(*pstart))
        {
            bdp->pre_whitesp += incr;
            bdp->pre_whitesp_c++;
@@ -5230,7 +5259,7 @@ block_prep(
        }
 #endif
        prev_pstart = pstart;
-       mb_ptr_adv(pstart);
+       MB_PTR_ADV(pstart);
     }
     bdp->start_char_vcols = incr;
     if (bdp->start_vcol < oap->start_vcol)     /* line too short */
@@ -6283,7 +6312,7 @@ write_viminfo_registers(FILE *fp)
 
 /*
  * Routine to export any final X selection we had to the environment
- * so that the text is still available after vim has exited. X selections
+ * so that the text is still available after Vim has exited. X selections
  * only exist while the owning application exists, so we write to the
  * permanent (while X runs) store CUT_BUFFER0.
  * Dump the CLIPBOARD selection if we own it (it's logically the more
@@ -6437,7 +6466,7 @@ clip_get_selection(VimClipboard *cbd)
        VIsual = old_visual;
        VIsual_mode = old_visual_mode;
     }
-    else
+    else if (!is_clipboard_needs_update())
     {
        clip_free_selection(cbd);
 
@@ -7205,7 +7234,7 @@ cursor_pos_info(dict_T *dict)
 
        if (VIsual_active)
        {
-           if (lt(VIsual, curwin->w_cursor))
+           if (LT_POS(VIsual, curwin->w_cursor))
            {
                min_pos = VIsual;
                max_pos = curwin->w_cursor;
index c32a2a4..f9d2734 100644 (file)
 #if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
 # define PV_BEXPR      OPT_BOTH(OPT_BUF(BV_BEXPR))
 #endif
+#define PV_FP          OPT_BOTH(OPT_BUF(BV_FP))
 #ifdef FEAT_EVAL
 # define PV_FEX                OPT_BUF(BV_FEX)
 #endif
 # define PV_LISP       OPT_BUF(BV_LISP)
 # define PV_LW         OPT_BOTH(OPT_BUF(BV_LW))
 #endif
+#ifdef FEAT_MBYTE
+# define PV_MENC       OPT_BOTH(OPT_BUF(BV_MENC))
+#endif
 #define PV_MA          OPT_BUF(BV_MA)
 #define PV_ML          OPT_BUF(BV_ML)
 #define PV_MOD         OPT_BUF(BV_MOD)
@@ -435,8 +439,8 @@ struct vimoption
 
                                /* when option changed, what to display: */
 #define P_RSTAT                0x1000  /* redraw status lines */
-#define P_RWIN         0x2000  /* redraw current window */
-#define P_RBUF         0x4000  /* redraw current buffer */
+#define P_RWIN         0x2000  /* redraw current window and recompute text */
+#define P_RBUF         0x4000  /* redraw current buffer and recompute text */
 #define P_RALL         0x6000  /* redraw all windows */
 #define P_RCLR         0x7000  /* clear and redraw all */
 
@@ -452,10 +456,12 @@ struct vimoption
 #define P_NFNAME       0x400000L /* only normal file name chars allowed */
 #define P_INSECURE     0x800000L /* option was set from a modeline */
 #define P_PRI_MKRC    0x1000000L /* priority for :mkvimrc (setting option has
-                                  side effects) */
+                                   side effects) */
 #define P_NO_ML       0x2000000L /* not allowed in modeline */
 #define P_CURSWANT    0x4000000L /* update curswant required; not needed when
                                  * there is a redraw flag */
+#define P_NDNAME      0x8000000L /* only normal dir name chars allowed */
+#define P_RWINONLY   0x10000000L /* only redraw current window */
 
 #define ISK_LATIN1  (char_u *)"@,48-57,_,192-255"
 
@@ -476,6 +482,17 @@ struct vimoption
 # define HIGHLIGHT_INIT "8:SpecialKey,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,N:CursorLineNr,r:Question,s:StatusLine,S:StatusLineNC,t:Title,v:Visual,w:WarningMsg,W:WildMenu,>:SignColumn,*:TabLine,#:TabLineSel,_:TabLineFill"
 #endif
 
+/* Default python version for pyx* commands */
+#if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
+# define DEFAULT_PYTHON_VER    0
+#elif defined(FEAT_PYTHON3)
+# define DEFAULT_PYTHON_VER    3
+#elif defined(FEAT_PYTHON)
+# define DEFAULT_PYTHON_VER    2
+#else
+# define DEFAULT_PYTHON_VER    0
+#endif
+
 /*
  * options[] is initialized here.
  * The order of the options MUST be alphabetic for ":set all" and findoption().
@@ -545,11 +562,15 @@ static struct vimoption options[] =
                            {(char_u *)0L, (char_u *)0L}
 #endif
                            SCRIPTID_INIT},
-#ifdef FEAT_AUTOCHDIR
     {"autochdir",  "acd",   P_BOOL|P_VI_DEF,
+#ifdef FEAT_AUTOCHDIR
                            (char_u *)&p_acd, PV_NONE,
-                           {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+                           {(char_u *)FALSE, (char_u *)0L}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)0L, (char_u *)0L}
 #endif
+                           SCRIPTID_INIT},
     {"autoindent",  "ai",   P_BOOL|P_VI_DEF,
                            (char_u *)&p_ai, PV_AI,
                            {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
@@ -610,19 +631,33 @@ static struct vimoption options[] =
                            {(char_u *)0L, (char_u *)0L}
 #endif
                            SCRIPTID_INIT},
-#ifdef FEAT_BEVAL
     {"balloondelay","bdlay",P_NUM|P_VI_DEF,
+#ifdef FEAT_BEVAL
                            (char_u *)&p_bdlay, PV_NONE,
-                           {(char_u *)600L, (char_u *)0L} SCRIPTID_INIT},
+                           {(char_u *)600L, (char_u *)0L}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)0L, (char_u *)0L}
+#endif
+                           SCRIPTID_INIT},
     {"ballooneval", "beval",P_BOOL|P_VI_DEF|P_NO_MKRC,
+#ifdef FEAT_BEVAL
                            (char_u *)&p_beval, PV_NONE,
-                           {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
-# ifdef FEAT_EVAL
+                           {(char_u *)FALSE, (char_u *)0L}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)0L, (char_u *)0L}
+#endif
+                           SCRIPTID_INIT},
     {"balloonexpr", "bexpr", P_STRING|P_ALLOCED|P_VI_DEF|P_VIM,
+#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
                            (char_u *)&p_bexpr, PV_BEXPR,
-                           {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
-# endif
+                           {(char_u *)"", (char_u *)0L}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)0L, (char_u *)0L}
 #endif
+                           SCRIPTID_INIT},
     {"beautify",    "bf",   P_BOOL|P_VI_DEF,
                            (char_u *)NULL, PV_NONE,
                            {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
@@ -966,7 +1001,7 @@ static struct vimoption options[] =
                            (char_u *)NULL, PV_NONE,
 #endif
                            {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
-    {"cursorline",   "cul", P_BOOL|P_VI_DEF|P_RWIN,
+    {"cursorline",   "cul", P_BOOL|P_VI_DEF|P_RWINONLY,
 #ifdef FEAT_SYN_HL
                            (char_u *)VAR_WIN, PV_CUL,
 #else
@@ -992,7 +1027,7 @@ static struct vimoption options[] =
                            (char_u *)NULL, PV_NONE,
 #endif
                            {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
-    {"dictionary",  "dict", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA|P_NODUP,
+    {"dictionary",  "dict", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA|P_NODUP|P_NDNAME,
 #ifdef FEAT_INS_EXPAND
                            (char_u *)&p_dict, PV_DICT,
 #else
@@ -1182,62 +1217,125 @@ static struct vimoption options[] =
     {"flash",      "fl",   P_BOOL|P_VI_DEF,
                            (char_u *)NULL, PV_NONE,
                            {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
-#ifdef FEAT_FOLDING
     {"foldclose",   "fcl",  P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP|P_RWIN,
+#ifdef FEAT_FOLDING
                            (char_u *)&p_fcl, PV_NONE,
-                           {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+                           {(char_u *)"", (char_u *)0L}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)NULL, (char_u *)0L}
+#endif
+                           SCRIPTID_INIT},
     {"foldcolumn",  "fdc",  P_NUM|P_VI_DEF|P_RWIN,
+#ifdef FEAT_FOLDING
                            (char_u *)VAR_WIN, PV_FDC,
-                           {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+                           {(char_u *)FALSE, (char_u *)0L}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)NULL, (char_u *)0L}
+#endif
+                           SCRIPTID_INIT},
     {"foldenable",  "fen",  P_BOOL|P_VI_DEF|P_RWIN,
+#ifdef FEAT_FOLDING
                            (char_u *)VAR_WIN, PV_FEN,
-                           {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+                           {(char_u *)TRUE, (char_u *)0L}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)NULL, (char_u *)0L}
+#endif
+                           SCRIPTID_INIT},
     {"foldexpr",    "fde",  P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN,
-# ifdef FEAT_EVAL
+#if defined(FEAT_FOLDING) && defined(FEAT_EVAL)
                            (char_u *)VAR_WIN, PV_FDE,
                            {(char_u *)"0", (char_u *)NULL}
-# else
+#else
                            (char_u *)NULL, PV_NONE,
                            {(char_u *)NULL, (char_u *)0L}
-# endif
+#endif
                            SCRIPTID_INIT},
     {"foldignore",  "fdi",  P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN,
+#ifdef FEAT_FOLDING
                            (char_u *)VAR_WIN, PV_FDI,
-                           {(char_u *)"#", (char_u *)NULL} SCRIPTID_INIT},
+                           {(char_u *)"#", (char_u *)NULL}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)NULL, (char_u *)0L}
+#endif
+                           SCRIPTID_INIT},
     {"foldlevel",   "fdl",  P_NUM|P_VI_DEF|P_RWIN,
+#ifdef FEAT_FOLDING
                            (char_u *)VAR_WIN, PV_FDL,
-                           {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+                           {(char_u *)0L, (char_u *)0L}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)NULL, (char_u *)0L}
+#endif
+                           SCRIPTID_INIT},
     {"foldlevelstart","fdls", P_NUM|P_VI_DEF|P_CURSWANT,
+#ifdef FEAT_FOLDING
                            (char_u *)&p_fdls, PV_NONE,
-                           {(char_u *)-1L, (char_u *)0L} SCRIPTID_INIT},
+                           {(char_u *)-1L, (char_u *)0L}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)NULL, (char_u *)0L}
+#endif
+                           SCRIPTID_INIT},
     {"foldmarker",  "fmr",  P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|
                                                    P_RWIN|P_ONECOMMA|P_NODUP,
+#ifdef FEAT_FOLDING
                            (char_u *)VAR_WIN, PV_FMR,
                            {(char_u *)"{{{,}}}", (char_u *)NULL}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)NULL, (char_u *)0L}
+#endif
                            SCRIPTID_INIT},
     {"foldmethod",  "fdm",  P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN,
+#ifdef FEAT_FOLDING
                            (char_u *)VAR_WIN, PV_FDM,
-                           {(char_u *)"manual", (char_u *)NULL} SCRIPTID_INIT},
+                           {(char_u *)"manual", (char_u *)NULL}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)NULL, (char_u *)0L}
+#endif
+                           SCRIPTID_INIT},
     {"foldminlines","fml",  P_NUM|P_VI_DEF|P_RWIN,
+#ifdef FEAT_FOLDING
                            (char_u *)VAR_WIN, PV_FML,
-                           {(char_u *)1L, (char_u *)0L} SCRIPTID_INIT},
+                           {(char_u *)1L, (char_u *)0L}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)NULL, (char_u *)0L}
+#endif
+                           SCRIPTID_INIT},
     {"foldnestmax", "fdn",  P_NUM|P_VI_DEF|P_RWIN,
+#ifdef FEAT_FOLDING
                            (char_u *)VAR_WIN, PV_FDN,
-                           {(char_u *)20L, (char_u *)0L} SCRIPTID_INIT},
+                           {(char_u *)20L, (char_u *)0L}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)NULL, (char_u *)0L}
+#endif
+                           SCRIPTID_INIT},
     {"foldopen",    "fdo",  P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP|P_CURSWANT,
+#ifdef FEAT_FOLDING
                            (char_u *)&p_fdo, PV_NONE,
                 {(char_u *)"block,hor,mark,percent,quickfix,search,tag,undo",
-                                                (char_u *)0L} SCRIPTID_INIT},
+                                                (char_u *)0L}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)NULL, (char_u *)0L}
+#endif
+                           SCRIPTID_INIT},
     {"foldtext",    "fdt",  P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN,
-# ifdef FEAT_EVAL
+#if defined(FEAT_FOLDING) && defined(FEAT_EVAL)
                            (char_u *)VAR_WIN, PV_FDT,
                            {(char_u *)"foldtext()", (char_u *)NULL}
-# else
+#else
                            (char_u *)NULL, PV_NONE,
                            {(char_u *)NULL, (char_u *)0L}
-# endif
-                           SCRIPTID_INIT},
 #endif
+                           SCRIPTID_INIT},
     {"formatexpr", "fex",   P_STRING|P_ALLOCED|P_VI_DEF|P_VIM,
 #ifdef FEAT_EVAL
                            (char_u *)&p_fex, PV_FEX,
@@ -1256,7 +1354,7 @@ static struct vimoption options[] =
                            {(char_u *)"^\\s*\\d\\+[\\]:.)}\\t ]\\s*",
                                                 (char_u *)0L} SCRIPTID_INIT},
     {"formatprg",   "fp",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
-                           (char_u *)&p_fp, PV_NONE,
+                           (char_u *)&p_fp, PV_FP,
                            {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
     {"fsync",       "fs",   P_BOOL|P_SECURE|P_VI_DEF,
 #ifdef HAVE_FSYNC
@@ -1775,17 +1873,24 @@ static struct vimoption options[] =
     {"loadplugins", "lpl",  P_BOOL|P_VI_DEF,
                            (char_u *)&p_lpl, PV_NONE,
                            {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
-#if defined(DYNAMIC_LUA)
     {"luadll",      NULL,   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+#if defined(DYNAMIC_LUA)
                            (char_u *)&p_luadll, PV_NONE,
                            {(char_u *)DYNAMIC_LUA_DLL, (char_u *)0L}
-                           SCRIPTID_INIT},
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)"", (char_u *)0L}
 #endif
-#ifdef FEAT_GUI_MAC
+                           SCRIPTID_INIT},
     {"macatsui",    NULL,   P_BOOL|P_VI_DEF|P_RCLR,
+#ifdef FEAT_GUI_MAC
                            (char_u *)&p_macatsui, PV_NONE,
-                           {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+                           {(char_u *)TRUE, (char_u *)0L}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)"", (char_u *)0L}
 #endif
+                           SCRIPTID_INIT},
     {"magic",      NULL,   P_BOOL|P_VI_DEF,
                            (char_u *)&p_magic, PV_NONE,
                            {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
@@ -1798,6 +1903,15 @@ static struct vimoption options[] =
                            {(char_u *)NULL, (char_u *)0L}
 #endif
                            SCRIPTID_INIT},
+    {"makeencoding","menc", P_STRING|P_VI_DEF,
+#ifdef FEAT_MBYTE
+                           (char_u *)&p_menc, PV_MENC,
+                           {(char_u *)"", (char_u *)0L}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)0L, (char_u *)0L}
+#endif
+                           SCRIPTID_INIT},
     {"makeprg",            "mp",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
 #ifdef FEAT_QUICKFIX
                            (char_u *)&p_mp, PV_MP,
@@ -2017,12 +2131,15 @@ static struct vimoption options[] =
                            (char_u *)".,/usr/include,,",
 #endif
                                (char_u *)0L} SCRIPTID_INIT},
-#if defined(DYNAMIC_PERL)
     {"perldll",     NULL,   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+#if defined(DYNAMIC_PERL)
                            (char_u *)&p_perldll, PV_NONE,
                            {(char_u *)DYNAMIC_PERL_DLL, (char_u *)0L}
-                           SCRIPTID_INIT},
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)0L, (char_u *)0L}
 #endif
+                           SCRIPTID_INIT},
     {"preserveindent", "pi", P_BOOL|P_VI_DEF|P_VIM,
                            (char_u *)&p_pi, PV_PI,
                            {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
@@ -2058,7 +2175,7 @@ static struct vimoption options[] =
                            {(char_u *)NULL, (char_u *)0L}
 #endif
                            SCRIPTID_INIT},
-    {"printexpr", "pexpr",  P_STRING|P_VI_DEF,
+    {"printexpr", "pexpr",  P_STRING|P_VI_DEF|P_SECURE,
 #ifdef FEAT_POSTSCRIPT
                            (char_u *)&p_pexpr, PV_NONE,
                            {(char_u *)"", (char_u *)0L}
@@ -2128,18 +2245,32 @@ static struct vimoption options[] =
                            (char_u *)NULL, PV_NONE,
 #endif
                            {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
-#if defined(DYNAMIC_PYTHON3)
     {"pythonthreedll",  NULL,   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+#if defined(DYNAMIC_PYTHON3)
                            (char_u *)&p_py3dll, PV_NONE,
                            {(char_u *)DYNAMIC_PYTHON3_DLL, (char_u *)0L}
-                           SCRIPTID_INIT},
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)NULL, (char_u *)0L}
 #endif
-#if defined(DYNAMIC_PYTHON)
+                           SCRIPTID_INIT},
     {"pythondll",   NULL,   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+#if defined(DYNAMIC_PYTHON)
                            (char_u *)&p_pydll, PV_NONE,
                            {(char_u *)DYNAMIC_PYTHON_DLL, (char_u *)0L}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)NULL, (char_u *)0L}
+#endif
                            SCRIPTID_INIT},
+    {"pyxversion", "pyx",   P_NUM|P_VI_DEF|P_SECURE,
+#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
+                           (char_u *)&p_pyx, PV_NONE,
+#else
+                           (char_u *)NULL, PV_NONE,
 #endif
+                           {(char_u *)DEFAULT_PYTHON_VER, (char_u *)0L}
+                           SCRIPTID_INIT},
     {"quoteescape", "qe",   P_STRING|P_ALLOCED|P_VI_DEF,
 #ifdef FEAT_TEXTOBJ
                            (char_u *)&p_qe, PV_QE,
@@ -2213,12 +2344,15 @@ static struct vimoption options[] =
                            {(char_u *)NULL, (char_u *)0L}
 #endif
                            SCRIPTID_INIT},
-#if defined(DYNAMIC_RUBY)
     {"rubydll",     NULL,   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+#if defined(DYNAMIC_RUBY)
                            (char_u *)&p_rubydll, PV_NONE,
                            {(char_u *)DYNAMIC_RUBY_DLL, (char_u *)0L}
-                           SCRIPTID_INIT},
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)NULL, (char_u *)0L}
 #endif
+                           SCRIPTID_INIT},
     {"ruler",      "ru",   P_BOOL|P_VI_DEF|P_VIM|P_RSTAT,
 #ifdef FEAT_CMDL_INFO
                            (char_u *)&p_ru, PV_NONE,
@@ -2606,12 +2740,15 @@ static struct vimoption options[] =
     {"tagstack",    "tgst", P_BOOL|P_VI_DEF,
                            (char_u *)&p_tgst, PV_NONE,
                            {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
-#if defined(DYNAMIC_TCL)
     {"tcldll",      NULL,   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+#if defined(DYNAMIC_TCL)
                            (char_u *)&p_tcldll, PV_NONE,
                            {(char_u *)DYNAMIC_TCL_DLL, (char_u *)0L}
-                           SCRIPTID_INIT},
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)0L, (char_u *)0L}
 #endif
+                           SCRIPTID_INIT},
     {"term",       NULL,   P_STRING|P_EXPAND|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RALL,
                            (char_u *)&T_NAME, PV_NONE,
                            {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
@@ -2659,7 +2796,7 @@ static struct vimoption options[] =
     {"textwidth",   "tw",   P_NUM|P_VI_DEF|P_VIM|P_RBUF,
                            (char_u *)&p_tw, PV_TW,
                            {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
-    {"thesaurus",   "tsr",  P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA|P_NODUP,
+    {"thesaurus",   "tsr",  P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA|P_NODUP|P_NDNAME,
 #ifdef FEAT_INS_EXPAND
                            (char_u *)&p_tsr, PV_TSR,
 #else
@@ -2706,17 +2843,24 @@ static struct vimoption options[] =
                            (char_u *)NULL, PV_NONE,
 #endif
                            {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
-#if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32)
     {"toolbar",     "tb",   P_STRING|P_ONECOMMA|P_VI_DEF|P_NODUP,
+#if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32)
                            (char_u *)&p_toolbar, PV_NONE,
                            {(char_u *)"icons,tooltips", (char_u *)0L}
-                           SCRIPTID_INIT},
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)0L, (char_u *)0L}
 #endif
-#if defined(FEAT_TOOLBAR) && defined(FEAT_GUI_GTK)
+                           SCRIPTID_INIT},
     {"toolbariconsize",        "tbis", P_STRING|P_VI_DEF,
+#if defined(FEAT_TOOLBAR) && defined(FEAT_GUI_GTK)
                            (char_u *)&p_tbis, PV_NONE,
-                           {(char_u *)"small", (char_u *)0L} SCRIPTID_INIT},
+                           {(char_u *)"small", (char_u *)0L}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)0L, (char_u *)0L}
 #endif
+                           SCRIPTID_INIT},
     {"ttimeout",    NULL,   P_BOOL|P_VI_DEF|P_VIM,
                            (char_u *)&p_ttimeout, PV_NONE,
                            {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
@@ -3030,6 +3174,7 @@ static struct vimoption options[] =
     p_term("t_vi", T_VI)
     p_term("t_vs", T_VS)
     p_term("t_WP", T_CWP)
+    p_term("t_GP", T_CGP)
     p_term("t_WS", T_CWS)
     p_term("t_xn", T_XN)
     p_term("t_xs", T_XS)
@@ -3037,6 +3182,8 @@ static struct vimoption options[] =
     p_term("t_ZR", T_CZR)
     p_term("t_8f", T_8F)
     p_term("t_8b", T_8B)
+    p_term("t_BE", T_BE)
+    p_term("t_BD", T_BD)
 
 /* terminal key codes are not in here */
 
@@ -3751,7 +3898,7 @@ free_all_options(void)
        if (options[i].indir == PV_NONE)
        {
            /* global option: free value and default value. */
-           if (options[i].flags & P_ALLOCED && options[i].var != NULL)
+           if ((options[i].flags & P_ALLOCED) && options[i].var != NULL)
                free_string_option(*(char_u **)options[i].var);
            if (options[i].flags & P_DEF_ALLOCED)
                free_string_option(options[i].def_val[VI_DEFAULT]);
@@ -3983,7 +4130,6 @@ set_init_3(void)
            options[idx3].def_val[VI_DEFAULT] = p_shcf;
        }
 
-# ifdef WIN3264
        /* Somehow Win32 requires the quotes around the redirection too */
        idx3 = findoption((char_u *)"sxq");
        if (idx3 >= 0 && !(options[idx3].flags & P_WAS_SET))
@@ -3991,14 +4137,6 @@ set_init_3(void)
            p_sxq = (char_u *)"\"";
            options[idx3].def_val[VI_DEFAULT] = p_sxq;
        }
-# else
-       idx3 = findoption((char_u *)"shq");
-       if (idx3 >= 0 && !(options[idx3].flags & P_WAS_SET))
-       {
-           p_shq = (char_u *)"\"";
-           options[idx3].def_val[VI_DEFAULT] = p_shq;
-       }
-# endif
     }
     else if (strstr((char *)gettail(p_sh), "cmd.exe") != NULL)
     {
@@ -4033,7 +4171,7 @@ set_init_3(void)
     }
 #endif
 
-    if (bufempty())
+    if (BUFEMPTY())
     {
        int idx_ffs = findoption((char_u *)"ffs");
 
@@ -4301,7 +4439,7 @@ do_set(
            afterchar = arg[len];
 
            /* skip white space, allow ":set ai  ?" */
-           while (vim_iswhite(arg[len]))
+           while (VIM_ISWHITE(arg[len]))
                ++len;
 
            adding = FALSE;
@@ -4389,8 +4527,11 @@ do_set(
                 * "wrap" gets set. */
                if (curwin->w_p_diff
                        && opt_idx >= 0  /* shut up coverity warning */
-                       && (options[opt_idx].indir == PV_FDM
-                           || options[opt_idx].indir == PV_WRAP))
+                       && (
+#ifdef FEAT_FOLDING
+                           options[opt_idx].indir == PV_FDM ||
+#endif
+                           options[opt_idx].indir == PV_WRAP))
                    goto skip;
 #endif
            }
@@ -4422,7 +4563,7 @@ do_set(
                    }
                }
                if (vim_strchr((char_u *)"?!&<", nextchar) != NULL
-                       && arg[1] != NUL && !vim_iswhite(arg[1]))
+                       && arg[1] != NUL && !VIM_ISWHITE(arg[1]))
                {
                    errmsg = e_trailing;
                    goto skip;
@@ -4480,7 +4621,7 @@ do_set(
                        (void)show_one_termcode(key_name, p, TRUE);
                }
                if (nextchar != '?'
-                       && nextchar != NUL && !vim_iswhite(afterchar))
+                       && nextchar != NUL && !VIM_ISWHITE(afterchar))
                    errmsg = e_trailing;
            }
            else
@@ -4520,7 +4661,7 @@ do_set(
                         * ":set invopt": invert
                         * ":set opt" or ":set noopt": set or reset
                         */
-                       if (nextchar != NUL && !vim_iswhite(afterchar))
+                       if (nextchar != NUL && !VIM_ISWHITE(afterchar))
                        {
                            errmsg = e_trailing;
                            goto skip;
@@ -4574,7 +4715,8 @@ do_set(
                                    || (long *)varp == &p_wcm)
                                && (*arg == '<'
                                    || *arg == '^'
-                                   || ((!arg[1] || vim_iswhite(arg[1]))
+                                   || (*arg != NUL
+                                       && (!arg[1] || VIM_ISWHITE(arg[1]))
                                        && !VIM_ISDIGIT(*arg))))
                        {
                            value = string_to_key(arg);
@@ -4590,7 +4732,7 @@ do_set(
                             * hex numbers. */
                            vim_str2nr(arg, NULL, &i, STR2NR_ALL,
                                                             &value, NULL, 0);
-                           if (arg[i] != NUL && !vim_iswhite(arg[i]))
+                           if (arg[i] != NUL && !VIM_ISWHITE(arg[i]))
                            {
                                errmsg = e_invarg;
                                goto skip;
@@ -4782,7 +4924,7 @@ do_set(
                             * do remove it for "\\\\machine\\path".
                             * The reverse is found in ExpandOldSetting().
                             */
-                           while (*arg && !vim_iswhite(*arg))
+                           while (*arg && !VIM_ISWHITE(*arg))
                            {
                                if (*arg == '\\' && arg[1] != NUL
 #ifdef BACKSLASH_IN_FILENAME
@@ -4930,7 +5072,7 @@ do_set(
                            if (flags & P_FLAGLIST)
                            {
                                /* Remove flags that appear twice. */
-                               for (s = newval; *s; ++s)
+                               for (s = newval; *s;)
                                {
                                    /* if options have P_FLAGLIST and
                                     * P_ONECOMMA such as 'whichwrap' */
@@ -4942,7 +5084,7 @@ do_set(
                                            /* Remove the duplicated value and
                                             * the next comma. */
                                            STRMOVE(s, s + 2);
-                                           s -= 2;
+                                           continue;
                                        }
                                    }
                                    else
@@ -4951,9 +5093,10 @@ do_set(
                                              && vim_strchr(s + 1, *s) != NULL)
                                        {
                                            STRMOVE(s, s + 1);
-                                           --s;
+                                           continue;
                                        }
                                    }
+                                   ++s;
                                }
                            }
 
@@ -5021,7 +5164,7 @@ do_set(
                        else
                        {
                            ++arg; /* jump to after the '=' or ':' */
-                           for (p = arg; *p && !vim_iswhite(*p); ++p)
+                           for (p = arg; *p && !VIM_ISWHITE(*p); ++p)
                                if (*p == '\\' && p[1] != NUL)
                                    ++p;
                            nextchar = *p;
@@ -5049,7 +5192,7 @@ skip:
             */
            for (i = 0; i < 2 ; ++i)
            {
-               while (*arg != NUL && !vim_iswhite(*arg))
+               while (*arg != NUL && !VIM_ISWHITE(*arg))
                    if (*arg++ == '\\' && *arg != NUL)
                        ++arg;
                arg = skipwhite(arg);
@@ -5479,6 +5622,7 @@ check_buf_options(buf_T *buf)
 #if defined(FEAT_CRYPT)
     check_string_option(&buf->b_p_cm);
 #endif
+    check_string_option(&buf->b_p_fp);
 #if defined(FEAT_EVAL)
     check_string_option(&buf->b_p_fex);
 #endif
@@ -5550,6 +5694,9 @@ check_buf_options(buf_T *buf)
     check_string_option(&buf->b_p_lw);
 #endif
     check_string_option(&buf->b_p_bkc);
+#ifdef FEAT_MBYTE
+    check_string_option(&buf->b_p_menc);
+#endif
 }
 
 /*
@@ -5615,7 +5762,7 @@ was_set_insecurely(char_u *opt, int opt_flags)
        flagp = insecure_flag(idx, opt_flags);
        return (*flagp & P_INSECURE) != 0;
     }
-    EMSG2(_(e_intern2), "was_set_insecurely()");
+    internal_error("was_set_insecurely()");
     return -1;
 }
 
@@ -5696,7 +5843,7 @@ set_string_option_direct(
        if (idx < 0)    /* not found (should not happen) */
        {
            EMSG2(_(e_intern2), "set_string_option_direct()");
-           EMSG2(_("For option %s"), name);
+           IEMSG2(_("For option %s"), name);
            return;
        }
     }
@@ -5803,7 +5950,7 @@ set_string_option(
                                                           opt_flags)) == NULL)
            did_set_option(opt_idx, opt_flags, TRUE);
 
-       /* call autocomamnd after handling side effects */
+       /* call autocommand after handling side effects */
 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
        if (saved_oldval != NULL)
        {
@@ -5876,11 +6023,15 @@ did_set_string_option(
        errmsg = e_secure;
     }
 
-    /* Check for a "normal" file name in some options.  Disallow a path
-     * separator (slash and/or backslash), wildcards and characters that are
-     * often illegal in a file name. */
-    else if ((options[opt_idx].flags & P_NFNAME)
-                        && vim_strpbrk(*varp, (char_u *)"/\\*?[|<>") != NULL)
+    /* Check for a "normal" directory or file name in some options.  Disallow a
+     * path separator (slash and/or backslash), wildcards and characters that
+     * are often illegal in a file name. Be more permissive if "secure" is off.
+     */
+    else if (((options[opt_idx].flags & P_NFNAME)
+                   && vim_strpbrk(*varp, (char_u *)(secure
+                           ? "/\\*?[|;&<>\r\n" : "/\\*?[<>\r\n")) != NULL)
+         || ((options[opt_idx].flags & P_NDNAME)
+                   && vim_strpbrk(*varp, (char_u *)"*?[|;&<>\r\n") != NULL))
     {
        errmsg = e_invarg;
     }
@@ -5899,8 +6050,15 @@ did_set_string_option(
        else if (set_termname(T_NAME) == FAIL)
            errmsg = (char_u *)N_("E522: Not found in termcap");
        else
+       {
            /* Screen colors may have changed. */
            redraw_later_clear();
+
+           /* Both 'term' and 'ttytype' point to T_NAME, only set the
+            * P_ALLOCED flag on 'term'. */
+           opt_idx = findoption((char_u *)"term");
+           free_oldval = (options[opt_idx].flags & P_ALLOCED);
+       }
     }
 
     /* 'backupcopy' */
@@ -6142,8 +6300,9 @@ did_set_string_option(
 #endif
 
 #ifdef FEAT_MBYTE
-    /* 'encoding' and 'fileencoding' */
-    else if (varp == &p_enc || gvarp == &p_fenc || varp == &p_tenc)
+    /* 'encoding', 'fileencoding', 'termencoding' and 'makeencoding' */
+    else if (varp == &p_enc || gvarp == &p_fenc || varp == &p_tenc
+                                                          || gvarp == &p_menc)
     {
        if (gvarp == &p_fenc)
        {
@@ -6244,7 +6403,7 @@ did_set_string_option(
 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
     else if (varp == &p_imak)
     {
-       if (gui.in_use && !im_xim_isvalid_imactivate())
+       if (!im_xim_isvalid_imactivate())
            errmsg = e_invarg;
     }
 #endif
@@ -6609,6 +6768,15 @@ did_set_string_option(
            mch_set_normal_colors();
 #endif
        }
+       if (varp == &T_BE && termcap_active)
+       {
+           if (*T_BE == NUL)
+               /* When clearing t_BE we assume the user no longer wants
+                * bracketed paste, thus disable it by writing t_BD. */
+               out_str(T_BD);
+           else
+               out_str(T_BE);
+       }
     }
 
 #ifdef FEAT_LINEBREAK
@@ -6619,7 +6787,7 @@ did_set_string_option(
        {
            if (ptr2cells(s) != 1)
                errmsg = (char_u *)N_("E595: contains unprintable or wide character");
-           mb_ptr_adv(s);
+           MB_PTR_ADV(s);
        }
     }
 #endif
@@ -6978,7 +7146,7 @@ did_set_string_option(
                    /* skip optional filename after 'k' and 's' */
                    while (*s && *s != ',' && *s != ' ')
                    {
-                       if (*s == '\\')
+                       if (*s == '\\' && s[1] != NUL)
                            ++s;
                        ++s;
                    }
@@ -7021,6 +7189,7 @@ did_set_string_option(
 
 
 #if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32)
+    /* 'toolbar' */
     else if (varp == &p_toolbar)
     {
        if (opt_strings_flags(p_toolbar, p_toolbar_values,
@@ -7235,6 +7404,7 @@ did_set_string_option(
 #endif
 
 #if defined(FEAT_RENDER_OPTIONS)
+    /* 'renderoptions' */
     else if (varp == &p_rop && gui.in_use)
     {
        if (!gui_mch_set_rendering_options(p_rop))
@@ -7262,19 +7432,19 @@ did_set_string_option(
     else
     {
        p = NULL;
-       if (varp == &p_ww)
+       if (varp == &p_ww) /* 'whichwrap' */
            p = (char_u *)WW_ALL;
-       if (varp == &p_shm)
+       if (varp == &p_shm) /* 'shortmess' */
            p = (char_u *)SHM_ALL;
-       else if (varp == &(p_cpo))
+       else if (varp == &(p_cpo)) /* 'cpoptions' */
            p = (char_u *)CPO_ALL;
-       else if (varp == &(curbuf->b_p_fo))
+       else if (varp == &(curbuf->b_p_fo)) /* 'formatoptions' */
            p = (char_u *)FO_ALL;
 #ifdef FEAT_CONCEAL
-       else if (varp == &curwin->w_p_cocu)
+       else if (varp == &curwin->w_p_cocu) /* 'concealcursor' */
            p = (char_u *)COCU_ALL;
 #endif
-       else if (varp == &p_mouse)
+       else if (varp == &p_mouse) /* 'mouse' */
        {
 #ifdef FEAT_MOUSE
            p = (char_u *)MOUSE_ALL;
@@ -7284,7 +7454,7 @@ did_set_string_option(
 #endif
        }
 #if defined(FEAT_GUI)
-       else if (varp == &p_go)
+       else if (varp == &p_go) /* 'guioptions' */
            p = (char_u *)GO_ALL;
 #endif
        if (p != NULL)
@@ -8387,8 +8557,8 @@ set_bool_option(
            {
                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));
+               msg_source(HL_ATTR(HLF_W));
+               MSG_ATTR(_(w_arabic), HL_ATTR(HLF_W));
 #ifdef FEAT_EVAL
                set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_arabic), -1);
 #endif
@@ -8551,7 +8721,7 @@ set_num_option(
        }
 
        /* Change window height NOW */
-       if (lastwin != firstwin)
+       if (!ONE_WINDOW)
        {
            if (pp == &p_wh && curwin->w_height < p_wh)
                win_setheight((int)p_wh);
@@ -8591,7 +8761,7 @@ set_num_option(
        }
 
        /* Change window width NOW */
-       if (lastwin != firstwin && curwin->w_width < p_wiw)
+       if (!ONE_WINDOW && curwin->w_width < p_wiw)
            win_setwidth((int)p_wiw);
     }
 
@@ -8805,6 +8975,15 @@ set_num_option(
        mzvim_reset_timer();
 #endif
 
+#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
+    /* 'pyxversion' */
+    else if (pp == &p_pyx)
+    {
+       if (p_pyx != 0 && p_pyx != 2 && p_pyx != 3)
+           errmsg = e_invarg;
+    }
+#endif
+
     /* sync undo before 'undolevels' changes */
     else if (pp == &p_ul)
     {
@@ -9048,6 +9227,8 @@ check_redraw(long_u flags)
        changed_window_setting();
     if (flags & P_RBUF)
        redraw_curbuf_later(NOT_VALID);
+    if (flags & P_RWINONLY)
+       redraw_later(NOT_VALID);
     if (doclear)
        redraw_all_later(CLEAR);
     else if (all)
@@ -9146,7 +9327,35 @@ get_option_value(
 
     opt_idx = findoption(name);
     if (opt_idx < 0)               /* unknown option */
+    {
+       int key;
+
+       if (STRLEN(name) == 4 && name[0] == 't' && name[1] == '_'
+               && (key = find_key_option(name)) != 0)
+       {
+           char_u key_name[2];
+           char_u *p;
+
+           if (key < 0)
+           {
+               key_name[0] = KEY2TERMCAP0(key);
+               key_name[1] = KEY2TERMCAP1(key);
+           }
+           else
+           {
+               key_name[0] = KS_KEY;
+               key_name[1] = (key & 0xff);
+           }
+           p = find_termcode(key_name);
+           if (p != NULL)
+           {
+               if (stringval != NULL)
+                   *stringval = vim_strsave(p);
+               return 0;
+           }
+       }
        return -3;
+    }
 
     varp = get_varp_scope(&(options[opt_idx]), opt_flags);
 
@@ -9375,7 +9584,7 @@ option_iter_next(void **option, int opt_type)
                    ret = NULL;
                break;
            default:
-               EMSG2(_(e_intern2), "option_iter_next()");
+               internal_error("option_iter_next()");
                return NULL;
        }
     }
@@ -9404,7 +9613,33 @@ set_option_value(
 
     opt_idx = findoption(name);
     if (opt_idx < 0)
+    {
+       int key;
+
+       if (STRLEN(name) == 4 && name[0] == 't' && name[1] == '_'
+               && (key = find_key_option(name)) != 0)
+       {
+           char_u key_name[2];
+
+           if (key < 0)
+           {
+               key_name[0] = KEY2TERMCAP0(key);
+               key_name[1] = KEY2TERMCAP1(key);
+           }
+           else
+           {
+               key_name[0] = KS_KEY;
+               key_name[1] = (key & 0xff);
+           }
+           add_termcode(key_name, string, FALSE);
+           if (full_screen)
+               ttest(FALSE);
+           redraw_all_later(CLEAR);
+           return NULL;
+       }
+
        EMSG2(_("E355: Unknown option: %s"), name);
+    }
     else
     {
        flags = options[opt_idx].flags;
@@ -10075,7 +10310,7 @@ istermoption(struct vimoption *p)
 comp_col(void)
 {
 #if defined(FEAT_CMDL_INFO) && defined(FEAT_WINDOWS)
-    int last_has_status = (p_ls == 2 || (p_ls == 1 && firstwin != lastwin));
+    int last_has_status = (p_ls == 2 || (p_ls == 1 && !ONE_WINDOW));
 
     sc_col = 0;
     ru_col = 0;
@@ -10165,6 +10400,9 @@ unset_global_local_option(char_u *name, void *from)
            clear_string_option(&buf->b_p_tsr);
            break;
 #endif
+       case PV_FP:
+           clear_string_option(&buf->b_p_fp);
+           break;
 #ifdef FEAT_QUICKFIX
        case PV_EFM:
            clear_string_option(&buf->b_p_efm);
@@ -10199,6 +10437,11 @@ unset_global_local_option(char_u *name, void *from)
            clear_string_option(&buf->b_p_lw);
            break;
 #endif
+#ifdef FEAT_MBYTE
+       case PV_MENC:
+           clear_string_option(&buf->b_p_menc);
+           break;
+#endif
     }
 }
 
@@ -10218,6 +10461,7 @@ get_varp_scope(struct vimoption *p, int opt_flags)
     {
        switch ((int)p->indir)
        {
+           case PV_FP:   return (char_u *)&(curbuf->b_p_fp);
 #ifdef FEAT_QUICKFIX
            case PV_EFM:  return (char_u *)&(curbuf->b_p_efm);
            case PV_GP:   return (char_u *)&(curbuf->b_p_gp);
@@ -10251,6 +10495,9 @@ get_varp_scope(struct vimoption *p, int opt_flags)
            case PV_LW:   return (char_u *)&(curbuf->b_p_lw);
 #endif
            case PV_BKC:  return (char_u *)&(curbuf->b_p_bkc);
+#ifdef FEAT_MBYTE
+           case PV_MENC: return (char_u *)&(curbuf->b_p_menc);
+#endif
        }
        return NULL; /* "cannot happen" */
     }
@@ -10298,6 +10545,8 @@ get_varp(struct vimoption *p)
        case PV_TSR:    return *curbuf->b_p_tsr != NUL
                                    ? (char_u *)&(curbuf->b_p_tsr) : p->var;
 #endif
+       case PV_FP:     return *curbuf->b_p_fp != NUL
+                                   ? (char_u *)&(curbuf->b_p_fp) : p->var;
 #ifdef FEAT_QUICKFIX
        case PV_EFM:    return *curbuf->b_p_efm != NUL
                                    ? (char_u *)&(curbuf->b_p_efm) : p->var;
@@ -10324,6 +10573,10 @@ get_varp(struct vimoption *p)
        case PV_LW:     return *curbuf->b_p_lw != NUL
                                    ? (char_u *)&(curbuf->b_p_lw) : p->var;
 #endif
+#ifdef FEAT_MBYTE
+       case PV_MENC:   return *curbuf->b_p_menc != NUL
+                                   ? (char_u *)&(curbuf->b_p_menc) : p->var;
+#endif
 
 #ifdef FEAT_ARABIC
        case PV_ARAB:   return (char_u *)&(curwin->w_p_arab);
@@ -10496,7 +10749,7 @@ get_varp(struct vimoption *p)
 #ifdef FEAT_SIGNS
        case PV_SCL:    return (char_u *)&(curwin->w_p_scl);
 #endif
-       default:        EMSG(_("E356: get_varp ERROR"));
+       default:        IEMSG(_("E356: get_varp ERROR"));
     }
     /* always return a valid pointer to avoid a crash! */
     return (char_u *)&(curbuf->b_p_wm);
@@ -10806,7 +11059,7 @@ buf_copy_options(buf_T *buf, int flags)
            buf->b_p_ml = p_ml;
            buf->b_p_ml_nobin = p_ml_nobin;
            buf->b_p_inf = p_inf;
-           buf->b_p_swf = p_swf;
+           buf->b_p_swf = cmdmod.noswapfile ? FALSE : p_swf;
 #ifdef FEAT_INS_EXPAND
            buf->b_p_cpt = vim_strsave(p_cpt);
 #endif
@@ -10863,6 +11116,7 @@ buf_copy_options(buf_T *buf, int flags)
            buf->b_p_inde = vim_strsave(p_inde);
            buf->b_p_indk = vim_strsave(p_indk);
 #endif
+           buf->b_p_fp = empty_option;
 #if defined(FEAT_EVAL)
            buf->b_p_fex = vim_strsave(p_fex);
 #endif
@@ -10924,6 +11178,9 @@ buf_copy_options(buf_T *buf, int flags)
 #ifdef FEAT_LISP
            buf->b_p_lw = empty_option;
 #endif
+#ifdef FEAT_MBYTE
+           buf->b_p_menc = empty_option;
+#endif
 
            /*
             * Don't copy the options set by ex_help(), use the saved values,
@@ -11411,7 +11668,7 @@ ExpandOldSetting(int *num_file, char_u ***file)
 #ifdef BACKSLASH_IN_FILENAME
     /* 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))
+    for (var = buf; *var != NUL; MB_PTR_ADV(var))
        if (var[0] == '\\' && var[1] == '\\'
                && expand_option_idx >= 0
                && (options[expand_option_idx].flags & P_EXPAND)
@@ -11611,7 +11868,7 @@ langmap_set(void)
     for (p = p_langmap; p[0] != NUL; )
     {
        for (p2 = p; p2[0] != NUL && p2[0] != ',' && p2[0] != ';';
-                                                              mb_ptr_adv(p2))
+                                                              MB_PTR_ADV(p2))
        {
            if (p2[0] == '\\' && p2[1] != NUL)
                ++p2;
@@ -11637,7 +11894,7 @@ langmap_set(void)
            to = NUL;
            if (p2 == NULL)
            {
-               mb_ptr_adv(p);
+               MB_PTR_ADV(p);
                if (p[0] != ',')
                {
                    if (p[0] == '\\')
@@ -11677,10 +11934,10 @@ langmap_set(void)
                langmap_mapchar[from & 255] = to;
 
            /* Advance to next pair */
-           mb_ptr_adv(p);
+           MB_PTR_ADV(p);
            if (p2 != NULL)
            {
-               mb_ptr_adv(p2);
+               MB_PTR_ADV(p2);
                if (*p == ';')
                {
                    p = p2;
index 13acabf..2c6aeef 100644 (file)
@@ -630,6 +630,9 @@ EXTERN char_u       *p_luadll;      /* 'luadll' */
 EXTERN int     p_macatsui;     /* 'macatsui' */
 #endif
 EXTERN int     p_magic;        /* 'magic' */
+#ifdef FEAT_MBYTE
+EXTERN char_u  *p_menc;        /* 'makeencoding' */
+#endif
 #ifdef FEAT_QUICKFIX
 EXTERN char_u  *p_mef;         /* 'makeef' */
 EXTERN char_u  *p_mp;          /* 'makeprg' */
@@ -694,6 +697,9 @@ EXTERN char_u       *p_py3dll;      /* 'pythonthreedll' */
 #if defined(DYNAMIC_PYTHON)
 EXTERN char_u  *p_pydll;       /* 'pythondll' */
 #endif
+#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
+EXTERN long    p_pyx;          /* 'pyxversion' */
+#endif
 #ifdef FEAT_RELTIME
 EXTERN long    p_rdt;          /* 'redrawtime' */
 #endif
@@ -1029,6 +1035,7 @@ enum
     , BV_EP
     , BV_ET
     , BV_FENC
+    , BV_FP
 #ifdef FEAT_EVAL
     , BV_BEXPR
     , BV_FEX
@@ -1061,6 +1068,9 @@ enum
     , BV_LISP
     , BV_LW
 #endif
+#ifdef FEAT_MBYTE
+    , BV_MENC
+#endif
     , BV_MA
     , BV_ML
     , BV_MOD
index 9266380..85e0c4e 100644 (file)
@@ -889,6 +889,8 @@ mch_early_init(void)
     void
 mch_exit(int r)
 {
+    exiting = TRUE;
+
     if (raw_in)                            /* put terminal in 'normal' mode */
     {
        settmode(TMODE_COOK);
@@ -1565,7 +1567,7 @@ sortcmp(const void *a, const void *b)
     int
 mch_has_exp_wildcard(char_u *p)
 {
-    for ( ; *p; mb_ptr_adv(p))
+    for ( ; *p; MB_PTR_ADV(p))
     {
        if (*p == '\\' && p[1] != NUL)
            ++p;
@@ -1578,7 +1580,7 @@ mch_has_exp_wildcard(char_u *p)
     int
 mch_has_wildcard(char_u *p)
 {
-    for ( ; *p; mb_ptr_adv(p))
+    for ( ; *p; MB_PTR_ADV(p))
     {
        if (*p == '\\' && p[1] != NUL)
            ++p;
index 625fdcc..696847e 100644 (file)
@@ -40,7 +40,7 @@
 #  include <dlgs.h>
 #  include <winspool.h>
 #  include <commdlg.h>
-#endif
+# endif
 
 #endif /* PROTO */
 
@@ -201,6 +201,8 @@ int _stricoll(char *a, char *b)
     void
 mch_exit(int r)
 {
+    exiting = TRUE;
+
     display_errors();
 
     ml_close_all(TRUE);                /* remove all memfiles */
@@ -306,10 +308,8 @@ mch_settitle(
  *  2: Just restore icon (which we don't have)
  *  3: Restore title and icon (which we don't have)
  */
-/*ARGSUSED*/
     void
-mch_restore_title(
-    int which)
+mch_restore_title(int which UNUSED)
 {
 #ifndef FEAT_GUI_MSWIN
     SetConsoleTitle(g_szOrigTitle);
@@ -345,13 +345,12 @@ mch_can_restore_icon(void)
  * When 'shellslash' set do it the other way around.
  * Return OK or FAIL.
  */
-/*ARGSUSED*/
     int
 mch_FullName(
     char_u     *fname,
     char_u     *buf,
     int                len,
-    int                force)
+    int                force UNUSED)
 {
     int                nResult = FAIL;
 
@@ -455,7 +454,7 @@ slash_adjust(char_u *p)
     {
        if (*p == psepcN)
            *p = psepc;
-       mb_ptr_adv(p);
+       MB_PTR_ADV(p);
     }
 }
 
@@ -601,7 +600,7 @@ vim_stat(const char *name, stat_T *stp)
     vim_strncpy((char_u *)buf, (char_u *)name, sizeof(buf) - 1);
     p = buf + STRLEN(buf);
     if (p > buf)
-       mb_ptr_back(buf, p);
+       MB_PTR_BACK(buf, p);
 
     /* Remove trailing '\\' except root path. */
     if (p > buf && (*p == '\\' || *p == '/') && p[-1] != ':')
@@ -636,9 +635,8 @@ vim_stat(const char *name, stat_T *stp)
 }
 
 #if defined(FEAT_GUI_MSWIN) || defined(PROTO)
-/*ARGSUSED*/
     void
-mch_settmode(int tmode)
+mch_settmode(int tmode UNUSED)
 {
     /* nothing to do */
 }
@@ -722,7 +720,7 @@ display_errors(void)
     int
 mch_has_exp_wildcard(char_u *p)
 {
-    for ( ; *p; mb_ptr_adv(p))
+    for ( ; *p; MB_PTR_ADV(p))
     {
        if (vim_strchr((char_u *)"?*[", *p) != NULL
                || (*p == '~' && p[1] != NUL))
@@ -738,7 +736,7 @@ mch_has_exp_wildcard(char_u *p)
     int
 mch_has_wildcard(char_u *p)
 {
-    for ( ; *p; mb_ptr_adv(p))
+    for ( ; *p; MB_PTR_ADV(p))
     {
        if (vim_strchr((char_u *)
 #  ifdef VIM_BACKTICK
@@ -817,10 +815,8 @@ mch_char_avail(void)
 /*
  * set screen mode, always fails.
  */
-/*ARGSUSED*/
     int
-mch_screenmode(
-    char_u *arg)
+mch_screenmode(char_u *arg UNUSED)
 {
     EMSG(_(e_screenmode));
     return FAIL;
@@ -996,10 +992,8 @@ mch_libcall(
 /*
  * Debugging helper: expose the MCH_WRITE_DUMP stuff to other modules
  */
-/*ARGSUSED*/
     void
-DumpPutS(
-    const char *psz)
+DumpPutS(const char *psz UNUSED)
 {
 # ifdef MCH_WRITE_DUMP
     if (fdDump)
@@ -1173,9 +1167,12 @@ swap_me(COLORREF colorref)
 # define PDP_RETVAL INT_PTR
 #endif
 
-/*ARGSUSED*/
     static PDP_RETVAL CALLBACK
-PrintDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+PrintDlgProc(
+       HWND hDlg,
+       UINT message,
+       WPARAM wParam UNUSED,
+       LPARAM lParam UNUSED)
 {
 #ifdef FEAT_GETTEXT
     NONCLIENTMETRICS nm;
@@ -1236,9 +1233,8 @@ PrintDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     return FALSE;
 }
 
-/*ARGSUSED*/
     static BOOL CALLBACK
-AbortProc(HDC hdcPrn, int iCode)
+AbortProc(HDC hdcPrn UNUSED, int iCode UNUSED)
 {
     MSG msg;
 
@@ -1619,7 +1615,9 @@ mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
 
        if (psettings->n_uncollated_copies == 0)
            psettings->n_uncollated_copies = 1;
-    } else {
+    }
+    else
+    {
        psettings->n_collated_copies = 1;
        psettings->n_uncollated_copies = 1;
     }
@@ -1681,9 +1679,8 @@ mch_print_begin(prt_settings_T *psettings)
     return (ret > 0);
 }
 
-/*ARGSUSED*/
     void
-mch_print_end(prt_settings_T *psettings)
+mch_print_end(prt_settings_T *psettings UNUSED)
 {
     EndDoc(prt_dlg.hDC);
     if (!*bUserAbort)
@@ -2108,11 +2105,15 @@ Messaging_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
            str = serverConvert(client_enc, (char_u *)data->lpData, &tofree);
            res = eval_client_expr_to_string(str);
-           vim_free(tofree);
 
            if (res == NULL)
            {
-               res = vim_strsave((char_u *)_(e_invexprmsg));
+               char    *err = _(e_invexprmsg);
+               size_t  len = STRLEN(str) + STRLEN(err) + 5;
+
+               res = alloc((unsigned)len);
+               if (res != NULL)
+                   vim_snprintf((char *)res, len, "%s: \"%s\"", err, str);
                reply.dwData = COPYDATA_ERROR_RESULT;
            }
            else
@@ -2123,6 +2124,7 @@ Messaging_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
            serverSendEnc(sender);
            retval = (int)SendMessage(sender, WM_COPYDATA,
                                    (WPARAM)message_window, (LPARAM)(&reply));
+           vim_free(tofree);
            vim_free(res);
            return retval;
 
@@ -2399,6 +2401,7 @@ serverSendToVim(
     char_u      **result,              /* Result of eval'ed expression */
     void        *ptarget,              /* HWND of server */
     int                 asExpr,                /* Expression or keys? */
+    int                 timeout,               /* timeout in seconds or zero */
     int                 silent)                /* don't complain about no server */
 {
     HWND       target;
@@ -2407,6 +2410,10 @@ serverSendToVim(
     int                retcode = 0;
     char_u     altname_buf[MAX_PATH];
 
+    /* Execute locally if no display or target is ourselves */
+    if (serverName != NULL && STRICMP(name, serverName) == 0)
+       return sendToLocalVim(cmd, asExpr, result);
+
     /* If the server name does not end in a digit then we look for an
      * alternate name.  e.g. when "name" is GVIM the we may find GVIM2. */
     if (STRLEN(name) > 1 && !vim_isdigit(name[STRLEN(name) - 1]))
@@ -2438,7 +2445,7 @@ serverSendToVim(
        return -1;
 
     if (asExpr)
-       retval = serverGetReply(target, &retcode, TRUE, TRUE);
+       retval = serverGetReply(target, &retcode, TRUE, TRUE, timeout);
 
     if (result == NULL)
        vim_free(retval);
@@ -2515,13 +2522,17 @@ save_reply(HWND server, char_u *reply, int expr)
  * if "wait" is TRUE block until a message arrives (or the server exits).
  */
     char_u *
-serverGetReply(HWND server, int *expr_res, int remove, int wait)
+serverGetReply(HWND server, int *expr_res, int remove, int wait, int timeout)
 {
     int                i;
     char_u     *reply;
     reply_T    *rep;
+    int                did_process = FALSE;
+    time_t     start;
+    time_t     now;
 
     /* When waiting, loop until the message waiting for is received. */
+    time(&start);
     for (;;)
     {
        /* Reset this here, in case a message arrives while we are going
@@ -2556,7 +2567,17 @@ serverGetReply(HWND server, int *expr_res, int remove, int wait)
        /* If we got here, we didn't find a reply. Return immediately if the
         * "wait" parameter isn't set.  */
        if (!wait)
+       {
+           /* Process pending messages once. Without this, looping on
+            * remote_peek() would never get the reply. */
+           if (!did_process)
+           {
+               did_process = TRUE;
+               serverProcessPendingMessages();
+               continue;
+           }
            break;
+       }
 
        /* We need to wait for a reply. Enter a message loop until the
         * "reply_received" flag gets set. */
@@ -2564,6 +2585,13 @@ serverGetReply(HWND server, int *expr_res, int remove, int wait)
        /* Loop until we receive a reply */
        while (reply_received == 0)
        {
+#ifdef FEAT_TIMERS
+           check_due_timer();
+#endif
+           time(&now);
+           if (timeout > 0 && (now - start) >= timeout)
+               break;
+
            /* Wait for a SendMessage() call to us.  This could be the reply
             * we are waiting for.  Use a timeout of a second, to catch the
             * situation that the server died unexpectedly. */
@@ -2762,12 +2790,11 @@ points_to_pixels(char_u *str, char_u **end, int vertical, long_i pprinter_dc)
     return pixels;
 }
 
-/*ARGSUSED*/
     static int CALLBACK
 font_enumproc(
     ENUMLOGFONT            *elf,
-    NEWTEXTMETRIC   *ntm,
-    int                    type,
+    NEWTEXTMETRIC   *ntm UNUSED,
+    int                    type UNUSED,
     LPARAM         lparam)
 {
     /* Return value:
@@ -2893,7 +2920,7 @@ get_logfont(
      */
     for (p = name; *p && *p != ':'; p++)
     {
-       if (p - name + 1 > LF_FACESIZE)
+       if (p - name + 1 >= LF_FACESIZE)
            goto theend;                        /* Name too long */
        lf->lfFaceName[p - name] = *p;
     }
index c6beba2..8ed3a67 100644 (file)
@@ -238,6 +238,10 @@ static volatile int deadly_signal = 0;         /* The signal we caught */
 /* volatile because it is used in signal handler deathtrap(). */
 static volatile int in_mch_delay = FALSE;    /* sleeping in mch_delay() */
 
+#if defined(FEAT_JOB_CHANNEL) && !defined(USE_SYSTEM)
+static int dont_check_job_ended = 0;
+#endif
+
 static int curr_tmode = TMODE_COOK;    /* contains current terminal mode */
 
 #ifdef USE_XSMP
@@ -261,7 +265,7 @@ static xsmp_config_T xsmp;
  * that describe the signals. That is nearly what we want here.  But
  * autoconf does only check for sys_siglist (without the underscore), I
  * do not want to change everything today.... jw.
- * This is why AC_DECL_SYS_SIGLIST is commented out in configure.in
+ * This is why AC_DECL_SYS_SIGLIST is commented out in configure.ac.
  */
 #endif
 
@@ -372,21 +376,6 @@ mch_write(char_u *s, int len)
        RealWaitForChar(read_cmd_fd, p_wd, NULL, NULL);
 }
 
-#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
-/*
- * Return time in msec since "start_tv".
- */
-    static long
-elapsed(struct timeval *start_tv)
-{
-    struct timeval  now_tv;
-
-    gettimeofday(&now_tv, NULL);
-    return (now_tv.tv_sec - start_tv->tv_sec) * 1000L
-        + (now_tv.tv_usec - start_tv->tv_usec) / 1000L;
-}
-#endif
-
 /*
  * mch_inchar(): low level input function.
  * Get a characters from the keyboard.
@@ -407,10 +396,10 @@ mch_inchar(
     int                did_start_blocking = FALSE;
     long       wait_time;
     long       elapsed_time = 0;
-#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
-    struct timeval  start_tv;
+#ifdef ELAPSED_FUNC
+    ELAPSED_TYPE start_tv;
 
-    gettimeofday(&start_tv, NULL);
+    ELAPSED_INIT(start_tv);
 #endif
 
     /* repeat until we got a character or waited long enough */
@@ -434,8 +423,8 @@ mch_inchar(
            else
                /* going to block after p_ut */
                wait_time = p_ut;
-#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
-           elapsed_time = elapsed(&start_tv);
+#ifdef ELAPSED_FUNC
+           elapsed_time = ELAPSED_FUNC(start_tv);
 #endif
            wait_time -= elapsed_time;
            if (wait_time < 0)
@@ -473,6 +462,16 @@ mch_inchar(
        /* Checking if a job ended requires polling.  Do this every 100 msec. */
        if (has_pending_job() && (wait_time < 0 || wait_time > 100L))
            wait_time = 100L;
+       /* If there is readahead then parse_queued_messages() timed out and we
+        * should call it again soon. */
+       if ((wait_time < 0 || wait_time > 100L) && channel_any_readahead())
+           wait_time = 10L;
+#endif
+#ifdef FEAT_BEVAL
+       if (p_beval && wait_time > 100L)
+           /* The 'balloonexpr' may indirectly invoke a callback while waiting
+            * for a character, need to check often. */
+           wait_time = 100L;
 #endif
 
        /*
@@ -512,7 +511,7 @@ mch_inchar(
                || interrupted
 #endif
                || wait_time > 0
-               || !did_start_blocking)
+               || (wtime < 0 && !did_start_blocking))
            continue;
 
        /* no character available or interrupted */
@@ -1550,18 +1549,16 @@ mch_input_isatty(void)
 
 #ifdef FEAT_X11
 
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) \
+# if defined(ELAPSED_TIMEVAL) \
        && (defined(FEAT_XCLIPBOARD) || defined(FEAT_TITLE))
 
-static void xopen_message(struct timeval *start_tv);
-
 /*
  * Give a message about the elapsed time for opening the X window.
  */
     static void
-xopen_message(struct timeval *start_tv)
+xopen_message(long elapsed_msec)
 {
-    smsg((char_u *)_("Opening the X display took %ld msec"), elapsed(start_tv));
+    smsg((char_u *)_("Opening the X display took %ld msec"), elapsed_msec);
 }
 # endif
 #endif
@@ -1860,11 +1857,11 @@ get_x11_windis(void)
 #endif
        if (x11_display != NULL)
        {
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+# ifdef ELAPSED_FUNC
            if (p_verbose > 0)
            {
                verbose_enter();
-               xopen_message(&start_tv);
+               xopen_message(ELAPSED_FUNC(start_tv));
                verbose_leave();
            }
 # endif
@@ -3084,7 +3081,7 @@ executable_file(char_u *name)
 }
 
 /*
- * Return 1 if "name" can be found in $PATH and executed, 0 if not.
+ * Return TRUE if "name" can be found in $PATH and executed, FALSE if not.
  * If "use_path" is FALSE only check if "name" is executable.
  * Return -1 if unknown.
  */
@@ -3106,7 +3103,7 @@ mch_can_exe(char_u *name, char_u **path, int use_path)
        {
            if (path != NULL)
            {
-               if (name[0] == '.')
+               if (name[0] != '/')
                    *path = FullName_save(name, TRUE);
                else
                    *path = vim_strsave(name);
@@ -3145,7 +3142,7 @@ mch_can_exe(char_u *name, char_u **path, int use_path)
        {
            if (path != NULL)
            {
-               if (buf[0] == '.')
+               if (buf[0] != '/')
                    *path = FullName_save(buf, TRUE);
                else
                    *path = vim_strsave(buf);
@@ -4485,7 +4482,9 @@ mch_call_shell(
            catch_signals(SIG_IGN, SIG_ERR);
            catch_int_signal();
            UNBLOCK_SIGNALS(&curset);
-
+# ifdef FEAT_JOB_CHANNEL
+           ++dont_check_job_ended;
+# endif
            /*
             * For the GUI we redirect stdin, stdout and stderr to our window.
             * This is also used to pipe stdin/stdout to/from the external
@@ -4624,8 +4623,8 @@ mch_call_shell(
                    ga_init2(&ga, 1, BUFLEN);
 
                noread_cnt = 0;
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
-               gettimeofday(&start_tv, NULL);
+# ifdef ELAPSED_FUNC
+               ELAPSED_INIT(start_tv);
 # endif
                for (;;)
                {
@@ -4660,8 +4659,8 @@ mch_call_shell(
                          /* Get extra characters when we don't have any.
                           * Reset the counter and timer. */
                          noread_cnt = 0;
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
-                         gettimeofday(&start_tv, NULL);
+# ifdef ELAPSED_FUNC
+                         ELAPSED_INIT(start_tv);
 # endif
                          len = ui_inchar(ta_buf, BUFLEN, 10L, 0);
                      }
@@ -4880,10 +4879,10 @@ mch_call_shell(
                        if (got_int)
                            break;
 
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+# ifdef ELAPSED_FUNC
                        if (wait_pid == 0)
                        {
-                           long            msec = elapsed(&start_tv);
+                           long        msec = ELAPSED_FUNC(start_tv);
 
                            /* Avoid that we keep looping here without
                             * checking for a CTRL-C for a long time.  Don't
@@ -5030,6 +5029,10 @@ finished:
                wait4pid(wpid, NULL);
            }
 
+# ifdef FEAT_JOB_CHANNEL
+           --dont_check_job_ended;
+# endif
+
            /*
             * Set to raw mode right now, otherwise a CTRL-C after
             * catch_signals() will kill Vim.
@@ -5344,7 +5347,7 @@ mch_job_status(job_T *job)
     return "run";
 
 return_dead:
-    if (job->jv_status != JOB_ENDED)
+    if (job->jv_status < JOB_ENDED)
     {
        ch_log(job->jv_channel, "Job ended");
        job->jv_status = JOB_ENDED;
@@ -5363,6 +5366,14 @@ mch_detect_ended_job(job_T *job_list)
     pid_t      wait_pid = 0;
     job_T      *job;
 
+# ifndef USE_SYSTEM
+    /* Do not do this when waiting for a shell command to finish, we would get
+     * the exit value here (and discard it), the exit value obtained there
+     * would then be wrong.  */
+    if (dont_check_job_ended > 0)
+       return NULL;
+# endif
+
 # ifdef __NeXT__
     wait_pid = wait4(-1, &status, WNOHANG, (struct rusage *)0);
 # else
@@ -5380,7 +5391,7 @@ mch_detect_ended_job(job_T *job_list)
                job->jv_exitval = WEXITSTATUS(status);
            else if (WIFSIGNALED(status))
                job->jv_exitval = -1;
-           if (job->jv_status != JOB_ENDED)
+           if (job->jv_status < JOB_ENDED)
            {
                ch_log(job->jv_channel, "Job ended");
                job->jv_status = JOB_ENDED;
@@ -5418,8 +5429,10 @@ mch_stop_job(job_T *job, char_u *how)
 
     /* TODO: have an option to only kill the process, not the group? */
     job_pid = job->jv_pid;
+#ifdef HAVE_GETPGID
     if (job_pid == getpgid(job_pid))
        job_pid = -job_pid;
+#endif
 
     kill(job_pid, sig);
 
@@ -5614,15 +5627,14 @@ RealWaitForChar(int fd, long msec, int *check_for_gpm UNUSED, int *interrupted)
     /* May retry getting characters after an event was handled. */
 # define MAY_LOOP
 
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+# ifdef ELAPSED_FUNC
     /* Remember at what time we started, so that we know how much longer we
      * should wait after being interrupted. */
-#  define USE_START_TV
     long           start_msec = msec;
-    struct timeval  start_tv;
+    ELAPSED_TYPE  start_tv;
 
     if (msec > 0)
-       gettimeofday(&start_tv, NULL);
+       ELAPSED_INIT(start_tv);
 # endif
 
     /* Handle being called recursively.  This may happen for the session
@@ -5929,9 +5941,9 @@ select_eintr:
        /* We're going to loop around again, find out for how long */
        if (msec > 0)
        {
-# ifdef USE_START_TV
+# ifdef ELAPSED_FUNC
            /* Compute remaining wait time. */
-           msec = start_msec - elapsed(&start_tv);
+           msec = start_msec - ELAPSED_FUNC(start_tv);
 # else
            /* Guess we got interrupted halfway. */
            msec = msec / 2;
@@ -5994,6 +6006,7 @@ mch_expand_wildcards(
 {
     int                i;
     size_t     len;
+    long       llen;
     char_u     *p;
     int                dir;
 
@@ -6127,7 +6140,7 @@ mch_expand_wildcards(
        STRCAT(command, pat[0] + 1);            /* exclude first backtick */
        p = command + STRLEN(command) - 1;
        *p-- = ')';                             /* remove last backtick */
-       while (p > command && vim_iswhite(*p))
+       while (p > command && VIM_ISWHITE(*p))
            --p;
        if (*p == '&')                          /* remove trailing '&' */
        {
@@ -6280,9 +6293,13 @@ mch_expand_wildcards(
        goto notfound;
     }
     fseek(fd, 0L, SEEK_END);
-    len = ftell(fd);                   /* get size of temp file */
+    llen = ftell(fd);                  /* get size of temp file */
     fseek(fd, 0L, SEEK_SET);
-    buffer = alloc(len + 1);
+    if (llen < 0)
+       /* just in case ftell() would fail */
+       buffer = NULL;
+    else
+       buffer = alloc(llen + 1);
     if (buffer == NULL)
     {
        /* out of memory */
@@ -6291,6 +6308,7 @@ mch_expand_wildcards(
        fclose(fd);
        return FAIL;
     }
+    len = llen;
     i = fread((char *)buffer, 1, len, fd);
     fclose(fd);
     mch_remove(tempname);
@@ -6510,7 +6528,7 @@ save_patterns(
     int
 mch_has_exp_wildcard(char_u *p)
 {
-    for ( ; *p; mb_ptr_adv(p))
+    for ( ; *p; MB_PTR_ADV(p))
     {
        if (*p == '\\' && p[1] != NUL)
            ++p;
@@ -6534,7 +6552,7 @@ mch_has_exp_wildcard(char_u *p)
     int
 mch_has_wildcard(char_u *p)
 {
-    for ( ; *p; mb_ptr_adv(p))
+    for ( ; *p; MB_PTR_ADV(p))
     {
        if (*p == '\\' && p[1] != NUL)
            ++p;
@@ -6914,7 +6932,7 @@ mch_libcall(
            if (argstring != NULL)
            {
 # if defined(USE_DLOPEN)
-               ProcAdd = (STRPROCSTR)dlsym(hinstLib, (const char *)funcname);
+               *(void **)(&ProcAdd) = dlsym(hinstLib, (const char *)funcname);
                dlerr = (char *)dlerror();
 # else
                if (shl_findsym(&hinstLib, (const char *)funcname,
@@ -6936,7 +6954,7 @@ mch_libcall(
            else
            {
 # if defined(USE_DLOPEN)
-               ProcAddI = (INTPROCSTR)dlsym(hinstLib, (const char *)funcname);
+               *(void **)(&ProcAddI) = dlsym(hinstLib, (const char *)funcname);
                dlerr = (char *)dlerror();
 # else
                if (shl_findsym(&hinstLib, (const char *)funcname,
@@ -7028,11 +7046,11 @@ setup_term_clip(void)
 #if defined(HAVE_SETJMP_H)
        int (*oldIOhandler)();
 #endif
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
-       struct timeval  start_tv;
+# ifdef ELAPSED_FUNC
+       ELAPSED_TYPE  start_tv;
 
        if (p_verbose > 0)
-           gettimeofday(&start_tv, NULL);
+           ELAPSED_INIT(start_tv);
 # endif
 
        /* Ignore X errors while opening the display */
@@ -7074,11 +7092,11 @@ setup_term_clip(void)
        /* Catch terminating error of the X server connection. */
        (void)XSetIOErrorHandler(x_IOerror_handler);
 
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+# ifdef ELAPSED_FUNC
        if (p_verbose > 0)
        {
            verbose_enter();
-           xopen_message(&start_tv);
+           xopen_message(ELAPSED_FUNC(start_tv));
            verbose_leave();
        }
 # endif
index d28aa4d..695affa 100644 (file)
@@ -423,21 +423,17 @@ typedef struct dsc$descriptor   DESC;
 # endif
 #endif
 
-/* memmove is not present on all systems, use memmove, bcopy, memcpy or our
- * own version */
-/* Some systems have (void *) arguments, some (char *). If we use (char *) it
+/* memmove() is not present on all systems, use memmove, bcopy or memcpy.
+ * Some systems have (void *) arguments, some (char *). If we use (char *) it
  * works for all */
-#ifdef USEMEMMOVE
+#if defined(USEMEMMOVE) || (!defined(USEBCOPY) && !defined(USEMEMCPY))
 # define mch_memmove(to, from, len) memmove((char *)(to), (char *)(from), len)
 #else
 # ifdef USEBCOPY
 #  define mch_memmove(to, from, len) bcopy((char *)(from), (char *)(to), len)
 # else
-#  ifdef USEMEMCPY
+    /* ifdef USEMEMCPY */
 #   define mch_memmove(to, from, len) memcpy((char *)(to), (char *)(from), len)
-#  else
-#   define VIM_MEMMOVE     /* found in misc2.c */
-#  endif
 # endif
 #endif
 
index 8ed52d1..edf7914 100644 (file)
@@ -17,8 +17,8 @@
 # define signal sigset
 #endif
 
-   /* sun's sys/ioctl.h redefines symbols from termio world */
-#if defined(HAVE_SYS_IOCTL_H) && !defined(sun)
+   /* Sun's sys/ioctl.h redefines symbols from termio world */
+#if defined(HAVE_SYS_IOCTL_H) && !defined(SUN_SYSTEM)
 # include <sys/ioctl.h>
 #endif
 
 #endif
 
 #ifdef HAVE_SYS_SYSTEMINFO_H
-/*
- * foolish Sinix <sys/systeminfo.h> uses SYS_NMLN but doesn't include
- * <limits.h>, where it is defined. Perhaps other systems have the same
- * problem? Include it here. -- Slootman
- */
-# if defined(HAVE_LIMITS_H) && !defined(_LIMITS_H)
-#  include <limits.h>          /* for SYS_NMLN (Sinix 5.41 / Unix SysV.4) */
-# endif
-
-/* Define SYS_NMLN ourselves if it still isn't defined (for CrayT3E). */
+/* <sys/systeminfo.h> uses SYS_NMLN but it may not be defined (CrayT3E). */
 # ifndef SYS_NMLN
 #  define SYS_NMLN 32
 # endif
 
 /* shared library access */
 #if defined(HAVE_DLFCN_H) && defined(USE_DLOPEN)
-# ifdef __MVS__
+# if defined(__MVS__) && !defined (__SUSV3)
     /* needed to define RTLD_LAZY (Anthony Giorgio) */
 #  define __SUSV3
 # endif
index 5c110f2..9aa7526 100644 (file)
 #define HAVE_STRTOL
 #define HAVE_TGETENT
 #define HAVE_MEMSET
-#define HAVE_MEMCMP
 #define HAVE_STRERROR
 #define HAVE_FCHOWN
 #define HAVE_RENAME
index d7fd2a7..3beca19 100644 (file)
@@ -38,13 +38,12 @@ void _cdecl SaveInst(HINSTANCE hInst);
 static void (_cdecl *pSaveInst)(HINSTANCE);
 #endif
 
-/*ARGSUSED*/
     int WINAPI
 WinMain(
-    HINSTANCE  hInstance,
-    HINSTANCE  hPrevInst,
+    HINSTANCE  hInstance UNUSED,
+    HINSTANCE  hPrevInst UNUSED,
     LPSTR      lpszCmdLine,
-    int                nCmdShow)
+    int                nCmdShow UNUSED)
 {
     int                argc = 0;
     char       **argv;
index 9fcb054..f2fd808 100644 (file)
@@ -425,6 +425,84 @@ vimLoadLib(char *name)
     return dll;
 }
 
+#if defined(DYNAMIC_ICONV) || defined(DYNAMIC_GETTEXT) || defined(PROTO)
+/*
+ * Get related information about 'funcname' which is imported by 'hInst'.
+ * If 'info' is 0, return the function address.
+ * If 'info' is 1, return the module name which the function is imported from.
+ */
+    static void *
+get_imported_func_info(HINSTANCE hInst, const char *funcname, int info)
+{
+    PBYTE                      pImage = (PBYTE)hInst;
+    PIMAGE_DOS_HEADER          pDOS = (PIMAGE_DOS_HEADER)hInst;
+    PIMAGE_NT_HEADERS          pPE;
+    PIMAGE_IMPORT_DESCRIPTOR   pImpDesc;
+    PIMAGE_THUNK_DATA          pIAT;       /* Import Address Table */
+    PIMAGE_THUNK_DATA          pINT;       /* Import Name Table */
+    PIMAGE_IMPORT_BY_NAME      pImpName;
+
+    if (pDOS->e_magic != IMAGE_DOS_SIGNATURE)
+       return NULL;
+    pPE = (PIMAGE_NT_HEADERS)(pImage + pDOS->e_lfanew);
+    if (pPE->Signature != IMAGE_NT_SIGNATURE)
+       return NULL;
+    pImpDesc = (PIMAGE_IMPORT_DESCRIPTOR)(pImage
+           + pPE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
+                                                           .VirtualAddress);
+    for (; pImpDesc->FirstThunk; ++pImpDesc)
+    {
+       if (!pImpDesc->OriginalFirstThunk)
+           continue;
+       pIAT = (PIMAGE_THUNK_DATA)(pImage + pImpDesc->FirstThunk);
+       pINT = (PIMAGE_THUNK_DATA)(pImage + pImpDesc->OriginalFirstThunk);
+       for (; pIAT->u1.Function; ++pIAT, ++pINT)
+       {
+           if (IMAGE_SNAP_BY_ORDINAL(pINT->u1.Ordinal))
+               continue;
+           pImpName = (PIMAGE_IMPORT_BY_NAME)(pImage
+                                       + (UINT_PTR)(pINT->u1.AddressOfData));
+           if (strcmp((char *)pImpName->Name, funcname) == 0)
+           {
+               switch (info)
+               {
+                   case 0:
+                       return (void *)pIAT->u1.Function;
+                   case 1:
+                       return (void *)(pImage + pImpDesc->Name);
+                   default:
+                       return NULL;
+               }
+           }
+       }
+    }
+    return NULL;
+}
+
+/*
+ * Get the module handle which 'funcname' in 'hInst' is imported from.
+ */
+    HINSTANCE
+find_imported_module_by_funcname(HINSTANCE hInst, const char *funcname)
+{
+    char    *modulename;
+
+    modulename = (char *)get_imported_func_info(hInst, funcname, 1);
+    if (modulename != NULL)
+       return GetModuleHandleA(modulename);
+    return NULL;
+}
+
+/*
+ * Get the address of 'funcname' which is imported by 'hInst' DLL.
+ */
+    void *
+get_dll_import_func(HINSTANCE hInst, const char *funcname)
+{
+    return get_imported_func_info(hInst, funcname, 0);
+}
+#endif
+
 #if defined(DYNAMIC_GETTEXT) || defined(PROTO)
 # ifndef GETTEXT_DLL
 #  define GETTEXT_DLL "libintl.dll"
@@ -436,6 +514,8 @@ static char *null_libintl_ngettext(const char *, const char *, unsigned long n);
 static char *null_libintl_textdomain(const char *);
 static char *null_libintl_bindtextdomain(const char *, const char *);
 static char *null_libintl_bind_textdomain_codeset(const char *, const char *);
+static int null_libintl_putenv(const char *);
+static int null_libintl_wputenv(const wchar_t *);
 
 static HINSTANCE hLibintlDLL = NULL;
 char *(*dyn_libintl_gettext)(const char *) = null_libintl_gettext;
@@ -446,6 +526,8 @@ char *(*dyn_libintl_bindtextdomain)(const char *, const char *)
                                                = null_libintl_bindtextdomain;
 char *(*dyn_libintl_bind_textdomain_codeset)(const char *, const char *)
                                       = null_libintl_bind_textdomain_codeset;
+int (*dyn_libintl_putenv)(const char *) = null_libintl_putenv;
+int (*dyn_libintl_wputenv)(const wchar_t *) = null_libintl_wputenv;
 
     int
 dyn_libintl_init(void)
@@ -463,6 +545,7 @@ dyn_libintl_init(void)
        {"bindtextdomain", (FARPROC*)&dyn_libintl_bindtextdomain},
        {NULL, NULL}
     };
+    HINSTANCE hmsvcrt;
 
     /* No need to initialize twice. */
     if (hLibintlDLL)
@@ -507,6 +590,18 @@ dyn_libintl_init(void)
        dyn_libintl_bind_textdomain_codeset =
                                         null_libintl_bind_textdomain_codeset;
 
+    /* _putenv() function for the libintl.dll is optional. */
+    hmsvcrt = find_imported_module_by_funcname(hLibintlDLL, "getenv");
+    if (hmsvcrt != NULL)
+    {
+       dyn_libintl_putenv = (void *)GetProcAddress(hmsvcrt, "_putenv");
+       dyn_libintl_wputenv = (void *)GetProcAddress(hmsvcrt, "_wputenv");
+    }
+    if (dyn_libintl_putenv == NULL || dyn_libintl_putenv == _putenv)
+       dyn_libintl_putenv = null_libintl_putenv;
+    if (dyn_libintl_wputenv == NULL || dyn_libintl_wputenv == _wputenv)
+       dyn_libintl_wputenv = null_libintl_wputenv;
+
     return 1;
 }
 
@@ -521,16 +616,16 @@ dyn_libintl_end(void)
     dyn_libintl_textdomain     = null_libintl_textdomain;
     dyn_libintl_bindtextdomain = null_libintl_bindtextdomain;
     dyn_libintl_bind_textdomain_codeset = null_libintl_bind_textdomain_codeset;
+    dyn_libintl_putenv         = null_libintl_putenv;
+    dyn_libintl_wputenv                = null_libintl_wputenv;
 }
 
-/*ARGSUSED*/
     static char *
 null_libintl_gettext(const char *msgid)
 {
     return (char*)msgid;
 }
 
-/*ARGSUSED*/
     static char *
 null_libintl_ngettext(
        const char *msgid,
@@ -540,28 +635,40 @@ null_libintl_ngettext(
     return (char *)(n == 1 ? msgid : msgid_plural);
 }
 
-/*ARGSUSED*/
     static char *
-null_libintl_bindtextdomain(const char *domainname, const char *dirname)
+null_libintl_bindtextdomain(
+       const char *domainname UNUSED,
+       const char *dirname UNUSED)
 {
     return NULL;
 }
 
-/*ARGSUSED*/
     static char *
-null_libintl_bind_textdomain_codeset(const char *domainname,
-                                                         const char *codeset)
+null_libintl_bind_textdomain_codeset(
+       const char *domainname UNUSED,
+       const char *codeset UNUSED)
 {
     return NULL;
 }
 
-/*ARGSUSED*/
     static char *
-null_libintl_textdomain(const char *domainname)
+null_libintl_textdomain(const char *domainname UNUSED)
 {
     return NULL;
 }
 
+    int
+null_libintl_putenv(const char *envstring UNUSED)
+{
+    return 0;
+}
+
+    int
+null_libintl_wputenv(const wchar_t *envstring UNUSED)
+{
+    return 0;
+}
+
 #endif /* DYNAMIC_GETTEXT */
 
 /* This symbol is not defined in older versions of the SDK or Visual C++ */
@@ -949,9 +1056,8 @@ decode_key_event(
  * For the GUI the mouse handling is in gui_w32.c.
  */
 # ifdef FEAT_GUI_W32
-/*ARGSUSED*/
     void
-mch_setmouse(int on)
+mch_setmouse(int on UNUSED)
 {
 }
 # else
@@ -1351,8 +1457,20 @@ WaitForChar(long msec)
            DWORD dwWaitTime = dwEndTime - dwNow;
 
 #ifdef FEAT_JOB_CHANNEL
-           /* Check channel while waiting input. */
+           /* Check channel while waiting for input. */
            if (dwWaitTime > 100)
+           {
+               dwWaitTime = 100;
+               /* If there is readahead then parse_queued_messages() timed out
+                * and we should call it again soon. */
+               if (channel_any_readahead())
+                   dwWaitTime = 10;
+           }
+#endif
+#ifdef FEAT_BEVAL
+           if (p_beval && dwWaitTime > 100)
+               /* The 'balloonexpr' may indirectly invoke a callback while
+                * waiting for a character, need to check often. */
                dwWaitTime = 100;
 #endif
 #ifdef FEAT_MZSCHEME
@@ -1541,13 +1659,12 @@ tgetch(int *pmodifiers, WCHAR *pch2)
  * If time == -1, wait forever for characters.
  * Returns the number of characters read into buf.
  */
-/*ARGSUSED*/
     int
 mch_inchar(
-    char_u     *buf,
-    int                maxlen,
-    long       time,
-    int                tb_change_cnt)
+    char_u     *buf UNUSED,
+    int                maxlen UNUSED,
+    long       time UNUSED,
+    int                tb_change_cnt UNUSED)
 {
 #ifndef FEAT_GUI_W32       /* this isn't used for the GUI */
 
@@ -1785,17 +1902,36 @@ theend:
 #endif
 
 /*
- * Return TRUE if "name" is in $PATH.
+ * If "use_path" is TRUE: Return TRUE if "name" is in $PATH.
+ * If "use_path" is FALSE: Return TRUE if "name" exists.
+ * When returning TRUE and "path" is not NULL save the path and set "*path" to
+ * the allocated memory.
  * TODO: Should somehow check if it's really executable.
  */
     static int
-executable_exists(char *name, char_u **path)
+executable_exists(char *name, char_u **path, int use_path)
 {
     char       *dum;
     char       fname[_MAX_PATH];
     char       *curpath, *newpath;
     long       n;
 
+    if (!use_path)
+    {
+       if (mch_getperm((char_u *)name) != -1 && !mch_isdir((char_u *)name))
+       {
+           if (path != NULL)
+           {
+               if (mch_isFullName((char_u *)name))
+                   *path = vim_strsave((char_u *)name);
+               else
+                   *path = FullName_save((char_u *)name, FALSE);
+           }
+           return TRUE;
+       }
+       return FALSE;
+    }
+
 #ifdef FEAT_MBYTE
     if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
     {
@@ -1921,7 +2057,7 @@ mch_init(void)
            vimrun_path = (char *)vim_strsave(vimrun_location);
            s_dont_use_vimrun = FALSE;
        }
-       else if (executable_exists("vimrun.exe", NULL))
+       else if (executable_exists("vimrun.exe", NULL, TRUE))
            s_dont_use_vimrun = FALSE;
 
        /* Don't give the warning for a missing vimrun.exe right now, but only
@@ -1935,7 +2071,7 @@ mch_init(void)
      * If "finstr.exe" doesn't exist, use "grep -n" for 'grepprg'.
      * Otherwise the default "findstr /n" is used.
      */
-    if (!executable_exists("findstr.exe", NULL))
+    if (!executable_exists("findstr.exe", NULL, TRUE))
        set_option_value((char_u *)"grepprg", 0, (char_u *)"grep -n", 0);
 
 #ifdef FEAT_CLIPBOARD
@@ -2427,8 +2563,9 @@ mch_init(void)
     void
 mch_exit(int r)
 {
-    stoptermcap();
+    exiting = TRUE;
 
+    stoptermcap();
     if (g_fWindInitCalled)
        settmode(TMODE_COOK);
 
@@ -2475,11 +2612,10 @@ mch_exit(int r)
 /*
  * Do we have an interactive window?
  */
-/*ARGSUSED*/
     int
 mch_check_win(
-    int argc,
-    char **argv)
+    int argc UNUSED,
+    char **argv UNUSED)
 {
     get_exe_name();
 
@@ -3241,9 +3377,10 @@ mch_writable(char_u *name)
 }
 
 /*
- * Return 1 if "name" can be executed, 0 if not.
+ * Return TRUE if "name" can be executed, FALSE if not.
  * If "use_path" is FALSE only check if "name" is executable.
- * Return -1 if unknown.
+ * When returning TRUE and "path" is not NULL save the path and set "*path" to
+ * the allocated memory.
  */
     int
 mch_can_exe(char_u *name, char_u **path, int use_path)
@@ -3254,17 +3391,12 @@ mch_can_exe(char_u *name, char_u **path, int use_path)
 
     if (len >= _MAX_PATH)      /* safety check */
        return FALSE;
-    if (!use_path)
-    {
-       /* TODO: check if file is really executable. */
-       return mch_getperm(name) != -1 && !mch_isdir(name);
-    }
 
     /* If there already is an extension try using the name directly.  Also do
      * this with a Unix-shell like 'shell'. */
     if (vim_strchr(gettail(name), '.') != NULL
                               || strstr((char *)gettail(p_sh), "sh") != NULL)
-       if (executable_exists((char *)name, path))
+       if (executable_exists((char *)name, path, use_path))
            return TRUE;
 
     /*
@@ -3286,7 +3418,7 @@ mch_can_exe(char_u *name, char_u **path, int use_path)
        }
        else
            copy_option_part(&p, buf + len, _MAX_PATH - len, ";");
-       if (executable_exists((char *)buf, path))
+       if (executable_exists((char *)buf, path, use_path))
            return TRUE;
     }
     return FALSE;
@@ -3876,6 +4008,28 @@ vim_create_process(
 }
 
 
+    static HINSTANCE
+vim_shell_execute(
+    char *cmd,
+    INT         n_show_cmd)
+{
+#ifdef FEAT_MBYTE
+    if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+    {
+       WCHAR *wcmd = enc_to_utf16((char_u *)cmd, NULL);
+       if (wcmd != NULL)
+       {
+           HINSTANCE ret;
+           ret = ShellExecuteW(NULL, NULL, wcmd, NULL, NULL, n_show_cmd);
+           vim_free(wcmd);
+           return ret;
+       }
+    }
+#endif
+    return ShellExecute(NULL, NULL, cmd, NULL, NULL, n_show_cmd);
+}
+
+
 #if defined(FEAT_GUI_W32) || defined(PROTO)
 
 /*
@@ -4287,9 +4441,6 @@ mch_system_piped(char *cmd, int options)
                    /* Get extra characters when we don't have any.  Reset the
                     * counter and timer. */
                    noread_cnt = 0;
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
-                   gettimeofday(&start_tv, NULL);
-# endif
                    len = ui_inchar(ta_buf, BUFLEN, 10L, 0);
                }
                if (ta_len > 0 || len > 0)
@@ -4577,11 +4728,12 @@ mch_call_shell(
        if (*cmdbase == '(')
            ++cmdbase;
 
-       if ((STRNICMP(cmdbase, "start", 5) == 0) && vim_iswhite(cmdbase[5]))
+       if ((STRNICMP(cmdbase, "start", 5) == 0) && VIM_ISWHITE(cmdbase[5]))
        {
            STARTUPINFO         si;
            PROCESS_INFORMATION pi;
            DWORD               flags = CREATE_NEW_CONSOLE;
+           INT                 n_show_cmd = SW_SHOWNORMAL;
            char_u              *p;
 
            ZeroMemory(&si, sizeof(si));
@@ -4595,14 +4747,15 @@ mch_call_shell(
 
            cmdbase = skipwhite(cmdbase + 5);
            if ((STRNICMP(cmdbase, "/min", 4) == 0)
-                   && vim_iswhite(cmdbase[4]))
+                   && VIM_ISWHITE(cmdbase[4]))
            {
                cmdbase = skipwhite(cmdbase + 4);
                si.dwFlags = STARTF_USESHOWWINDOW;
                si.wShowWindow = SW_SHOWMINNOACTIVE;
+               n_show_cmd = SW_SHOWMINNOACTIVE;
            }
            else if ((STRNICMP(cmdbase, "/b", 2) == 0)
-                   && vim_iswhite(cmdbase[2]))
+                   && VIM_ISWHITE(cmdbase[2]))
            {
                cmdbase = skipwhite(cmdbase + 2);
                flags = CREATE_NO_WINDOW;
@@ -4671,6 +4824,9 @@ mch_call_shell(
             */
            if (vim_create_process((char *)newcmd, FALSE, flags, &si, &pi))
                x = 0;
+           else if (vim_shell_execute((char *)newcmd, n_show_cmd)
+                                                              > (HINSTANCE)32)
+               x = 0;
            else
            {
                x = -1;
@@ -4705,12 +4861,24 @@ mch_call_shell(
 #if defined(FEAT_GUI_W32)
                if (need_vimrun_warning)
                {
-                   MessageBox(NULL,
-                           _("VIMRUN.EXE not found in your $PATH.\n"
-                               "External commands will not pause after completion.\n"
-                               "See  :help win32-vimrun  for more information."),
-                           _("Vim Warning"),
-                           MB_ICONWARNING);
+                   char *msg = _("VIMRUN.EXE not found in your $PATH.\n"
+                       "External commands will not pause after completion.\n"
+                       "See  :help win32-vimrun  for more information.");
+                   char *title = _("Vim Warning");
+# ifdef FEAT_MBYTE
+                   if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+                   {
+                       WCHAR *wmsg = enc_to_utf16((char_u *)msg, NULL);
+                       WCHAR *wtitle = enc_to_utf16((char_u *)title, NULL);
+
+                       if (wmsg != NULL && wtitle != NULL)
+                           MessageBoxW(NULL, wmsg, wtitle, MB_ICONWARNING);
+                       vim_free(wmsg);
+                       vim_free(wtitle);
+                   }
+                   else
+# endif
+                       MessageBox(NULL, msg, title, MB_ICONWARNING);
                    need_vimrun_warning = FALSE;
                }
                if (!s_dont_use_vimrun && p_stmp)
@@ -4766,32 +4934,32 @@ mch_call_shell(
 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
     static HANDLE
 job_io_file_open(
-        char_u *fname,
-        DWORD dwDesiredAccess,
-        DWORD dwShareMode,
-        LPSECURITY_ATTRIBUTES lpSecurityAttributes,
-        DWORD dwCreationDisposition,
-        DWORD dwFlagsAndAttributes)
+       char_u *fname,
+       DWORD dwDesiredAccess,
+       DWORD dwShareMode,
+       LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+       DWORD dwCreationDisposition,
+       DWORD dwFlagsAndAttributes)
 {
     HANDLE h;
 # ifdef FEAT_MBYTE
     WCHAR *wn = NULL;
     if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
     {
-        wn = enc_to_utf16(fname, NULL);
-        if (wn != NULL)
-        {
-            h = CreateFileW(wn, dwDesiredAccess, dwShareMode,
-                     lpSecurityAttributes, dwCreationDisposition,
-                     dwFlagsAndAttributes, NULL);
-            vim_free(wn);
-        }
+       wn = enc_to_utf16(fname, NULL);
+       if (wn != NULL)
+       {
+           h = CreateFileW(wn, dwDesiredAccess, dwShareMode,
+                   lpSecurityAttributes, dwCreationDisposition,
+                   dwFlagsAndAttributes, NULL);
+           vim_free(wn);
+       }
     }
     if (wn == NULL)
 # endif
-        h = CreateFile((LPCSTR)fname, dwDesiredAccess, dwShareMode,
-                     lpSecurityAttributes, dwCreationDisposition,
-                     dwFlagsAndAttributes, NULL);
+       h = CreateFile((LPCSTR)fname, dwDesiredAccess, dwShareMode,
+               lpSecurityAttributes, dwCreationDisposition,
+               dwFlagsAndAttributes, NULL);
     return h;
 }
 
@@ -4978,7 +5146,7 @@ mch_job_status(job_T *job)
            || dwExitCode != STILL_ACTIVE)
     {
        job->jv_exitval = (int)dwExitCode;
-       if (job->jv_status != JOB_ENDED)
+       if (job->jv_status < JOB_ENDED)
        {
            ch_log(job->jv_channel, "Job ended");
            job->jv_status = JOB_ENDED;
@@ -5222,11 +5390,10 @@ termcap_mode_end(void)
 
 
 #ifdef FEAT_GUI_W32
-/*ARGSUSED*/
     void
 mch_write(
-    char_u  *s,
-    int            len)
+    char_u  *s UNUSED,
+    int            len UNUSED)
 {
     /* never used */
 }
@@ -5601,7 +5768,7 @@ write_chars(
        {
            char_u *p = pchBuf;
            for (n = 0; n < cchwritten; n++)
-               mb_cptr_adv(p);
+               MB_CPTR_ADV(p);
            written = p - pchBuf;
            g_coord.X += (SHORT)mb_string2cells(pchBuf, written);
        }
@@ -5924,11 +6091,10 @@ mch_write(
 /*
  * Delay for "msec" milliseconds.
  */
-/*ARGSUSED*/
     void
 mch_delay(
     long    msec,
-    int            ignoreinput)
+    int            ignoreinput UNUSED)
 {
 #ifdef FEAT_GUI_W32
     Sleep((int)msec);      /* never wait for input */
@@ -6017,9 +6183,8 @@ mch_breakcheck(int force)
 /*
  * How much main memory in KiB that can be used by VIM.
  */
-/*ARGSUSED*/
     long_u
-mch_total_mem(int special)
+mch_total_mem(int special UNUSED)
 {
     MEMORYSTATUSEX  ms;
 
@@ -6874,3 +7039,43 @@ fix_arg_enc(void)
     set_alist_count();
 }
 #endif
+
+    int
+mch_setenv(char *var, char *value, int x)
+{
+    char_u     *envbuf;
+
+    envbuf = alloc((unsigned)(STRLEN(var) + STRLEN(value) + 2));
+    if (envbuf == NULL)
+       return -1;
+
+    sprintf((char *)envbuf, "%s=%s", var, value);
+
+#ifdef FEAT_MBYTE
+    if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+    {
+       WCHAR       *p = enc_to_utf16(envbuf, NULL);
+
+       vim_free(envbuf);
+       if (p == NULL)
+           return -1;
+       _wputenv(p);
+# ifdef libintl_wputenv
+       libintl_wputenv(p);
+# endif
+       /* Unlike Un*x systems, we can free the string for _wputenv(). */
+       vim_free(p);
+    }
+    else
+#endif
+    {
+       _putenv((char *)envbuf);
+# ifdef libintl_putenv
+       libintl_putenv((char *)envbuf);
+# endif
+       /* Unlike Un*x systems, we can free the string for _putenv(). */
+       vim_free(envbuf);
+    }
+
+    return 0;
+}
index f620d74..5017f53 100644 (file)
@@ -202,7 +202,9 @@ Trace(char *pszFormat, ...);
 #define ASSERT_NULL_OR_POINTER(p, type) \
     ASSERT(((p) == NULL)  ||  IsValidAddress((p), sizeof(type), FALSE))
 
-#define mch_setenv(name, val, x) setenv(name, val, x)
+#ifndef HAVE_SETENV
+# define HAVE_SETENV
+#endif
 #define mch_getenv(x) (char_u *)getenv((char *)(x))
 #ifdef __BORLANDC__
 # define vim_mkdir(x, y) mkdir(x)
index a11e6ea..5519104 100644 (file)
@@ -50,12 +50,7 @@ extern int   poll(struct pollfd *, long, int);
 #ifdef HAVE_MEMSET
 extern void    *memset(void *, int, size_t);
 #endif
-#ifdef HAVE_BCMP
-extern int     bcmp(void *, void *, size_t);
-#endif
-#ifdef HAVE_MEMCMP
 extern int     memcmp(const void *, const void *, size_t);
-#endif
 #ifdef HAVE_STRPBRK
 extern char    *strpbrk(const char *, const char *);
 #endif
index d9aa834..5e43fff 100644 (file)
@@ -232,12 +232,13 @@ sk.cp1250.po: sk.po
        iconv -f iso-8859-2 -t cp1250 sk.po | \
                sed -e 's/charset=ISO-8859-2/charset=cp1250/' -e 's/# Original translations/# Generated from sk.po, DO NOT EDIT/' > sk.cp1250.po
 
-# Convert zh_CN.po to create zh_CN.cp936.po.
-# set 'charset' to gbk to avoid that msfmt generates a warning
-zh_CN.cp936.po: zh_CN.po
+# Convert zh_CN.UTF-8.po to create zh_CN.cp936.po.
+# Set 'charset' to gbk to avoid that msfmt generates a warning.
+# This used to convert from zh_CN.po, but that results in a conversion error.
+zh_CN.cp936.po: zh_CN.UTF-8.po
        rm -f zh_CN.cp936.po
-       iconv -f gb2312 -t cp936 zh_CN.po | \
-               sed -e 's/charset=gb2312/charset=gbk/' -e 's/# Original translations/# Generated from zh_CN.po, DO NOT EDIT/' > zh_CN.cp936.po
+       iconv -f UTF-8 -t cp936 zh_CN.UTF-8.po | \
+               sed -e 's/charset=utf-8/charset=gbk/' -e 's/# Original translations/# Generated from zh_CN.po, DO NOT EDIT/' > zh_CN.cp936.po
 
 # Convert ko.UTF-8.po to create ko.po.
 ko.po: ko.UTF-8.po
index c891527..3fb300c 100644 (file)
@@ -5,7 +5,7 @@
 #
 # UNUA TRADUKISTO Dominique PELLE   <dominique.pelle ĉe gmail.com>
 # PROVLEGANTO(J)  Felipe CASTRO     <fefcas ĉe gmail.com>
-#                 Antono MECHELYNCK <antoine.mechelynck ĉe skynet.be>
+#                 Antono MECHELYNCK <antoine.mechelynck ĉe gmail.com>
 #                 Yves NEVELSTEEN
 #
 # Uzitaj vortaroj kaj fakvortaroj:
@@ -23,8 +23,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Vim(Esperanto)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-08-26 20:54+0200\n"
-"PO-Revision-Date: 2016-08-26 20:30+0200\n"
+"POT-Creation-Date: 2017-01-16 00:30+0100\n"
+"PO-Revision-Date: 2017-01-16 01:14+0100\n"
 "Last-Translator: Dominique PELLÉ <dominique.pelle@gmail.com>\n"
 "Language-Team: \n"
 "Language: eo\n"
@@ -66,6 +66,9 @@ msgstr "E83: Ne eblas disponigi bufron, nun uzas alian..."
 msgid "E931: Buffer cannot be registered"
 msgstr "E931: Bufro ne povas esti registrita"
 
+msgid "E937: Attempt to delete a buffer that is in use"
+msgstr "E937: Provo de forviŝo de bufro, kiu estas uzanta"
+
 msgid "E515: No buffers were unloaded"
 msgstr "E515: Neniu bufro estis malŝargita"
 
@@ -269,7 +272,7 @@ msgid "E918: buffer must be loaded: %s"
 msgstr "E918: bufro devas esti ŝargita: %s"
 
 msgid "E821: File is encrypted with unknown method"
-msgstr "E821: Dosiero estas ĉifrata per nekonata metodo"
+msgstr "E821: Dosiero estas ĉifrita per nekonata metodo"
 
 msgid "Warning: Using a weak encryption method; see :help 'cm'"
 msgstr "Averto: uzo de malfortika ĉifrada metodo; vidu :help 'cm'"
@@ -1963,6 +1966,9 @@ msgstr "E462: Ne eblis prepari por reŝargi \"%s\""
 msgid "E321: Could not reload \"%s\""
 msgstr "E321: Ne eblis reŝargi \"%s\""
 
+msgid "--Deleted--"
+msgstr "--Forviŝita--"
+
 #, c-format
 msgid "auto-removing autocommand: %s <buffer=%d>"
 msgstr "aŭto-forviŝas aŭtokomandon: %s <bufro=%d>"
@@ -1972,12 +1978,12 @@ msgstr "aŭto-forviŝas aŭtokomandon: %s <bufro=%d>"
 msgid "E367: No such group: \"%s\""
 msgstr "E367: Ne ekzistas tia grupo: \"%s\""
 
+msgid "E936: Cannot delete the current group"
+msgstr "E936: Ne eblas forviŝi la aktualan grupon"
+
 msgid "W19: Deleting augroup that is still in use"
 msgstr "W19: Forviŝo de augroup kiu estas ankoraŭ uzata"
 
-msgid "--Deleted--"
-msgstr "--Forviŝita--"
-
 #, c-format
 msgid "E215: Illegal character after *: %s"
 msgstr "E215: Nevalida signo post *: %s"
@@ -2835,6 +2841,10 @@ msgstr ""
 "E251: Ecoj de registro de apero de VIM estas nevalide formata. Forviŝita!"
 
 #, c-format
+msgid "E938: Duplicate key in JSON: \"%s\""
+msgstr "E938: Ripetita ŝlosilo en JSON: \"%s\""
+
+#, c-format
 msgid "E696: Missing comma in List: %s"
 msgstr "E696: Mankas komo en Listo: %s"
 
@@ -3058,6 +3068,10 @@ msgid "--not-a-term\t\tSkip warning for input/output not being a terminal"
 msgstr ""
 "--not-a-term\t\tPreterpasi averton por enigo/eligo, kiu ne estas terminalo"
 
+msgid "--ttyfail\t\tExit if input or output is not a terminal"
+msgstr ""
+"--ttyfail\t\tEliri se le eniro aŭ eliro ne estas terminalo"
+
 msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
 msgstr "-u <vimrc>\t\tUzi <vimrc> anstataŭ iun ajn .vimrc"
 
@@ -4454,9 +4468,6 @@ msgstr "ERARO DE ENIGO/ELIGO"
 msgid "Message"
 msgstr "Mesaĝo"
 
-msgid "'columns' is not 80, cannot execute external commands"
-msgstr "'columns' ne estas 80, ne eblas plenumi eksterajn komandojn"
-
 msgid "E237: Printer selection failed"
 msgstr "E237: Elekto de presilo malsukcesis"
 
@@ -5998,14 +6009,6 @@ msgstr "E133: \":return\" ekster funkcio"
 msgid "E107: Missing parentheses: %s"
 msgstr "E107: Mankas krampoj: %s"
 
-#. Only MS VC 4.1 and earlier can do Win32s
-msgid ""
-"\n"
-"MS-Windows 16/32-bit GUI version"
-msgstr ""
-"\n"
-"Grafika versio MS-Vindozo 16/32-bitoj"
-
 msgid ""
 "\n"
 "MS-Windows 64-bit GUI version"
@@ -6305,13 +6308,6 @@ msgstr "tajpu  :help register<Enenklavo>  por pliaj informoj   "
 msgid "menu  Help->Sponsor/Register  for information    "
 msgstr "menuo Helpo->Subteni/Registri     por pliaj informoj   "
 
-msgid "WARNING: Windows 95/98/ME detected"
-msgstr "AVERTO: Trovis Vindozon 95/98/ME"
-
-# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-msgid "type  :help windows95<Enter>  for info on this"
-msgstr "tajpu  :help windows95<Enenklavo> por pliaj informoj   "
-
 msgid "Already only one window"
 msgstr "Jam nur unu fenestro"
 
@@ -6465,6 +6461,10 @@ msgstr "E236: La tiparo \"%s\" ne estas egallarĝa"
 msgid "E473: Internal error"
 msgstr "E473: Interna eraro"
 
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Interna eraro: %s"
+
 msgid "Interrupted"
 msgstr "Interrompita"
 
@@ -6745,10 +6745,6 @@ msgstr "E463: Regiono estas gardita, ne eblas ŝanĝi"
 msgid "E744: NetBeans does not allow changes in read-only files"
 msgstr "E744: NetBeans ne permesas ŝanĝojn en nurlegeblaj dosieroj"
 
-#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: Interna eraro: %s"
-
 msgid "E363: pattern uses more memory than 'maxmempattern'"
 msgstr "E363: ŝablono uzas pli da memoro ol 'maxmempattern'"
 
index 171a907..05b2fa0 100644 (file)
@@ -6,7 +6,7 @@
 #  FIRST AUTHOR  DindinX         <David.Odin@bigfoot.com>     2000.
 # SECOND AUTHOR  Adrien Beau     <version.francaise@free.fr>  2002, 2003.
 #  THIRD AUTHOR  David Blanchet  <david.blanchet@free.fr>     2006, 2008.
-# FOURTH AUTHOR  Dominique Pellé <dominique.pelle@gmail.com>  2008, 2016.
+# FOURTH AUTHOR  Dominique Pellé <dominique.pelle@gmail.com>  2008, 2017.
 #
 # Latest translation available at:
 #   http://dominique.pelle.free.fr/vim-fr.php
@@ -15,8 +15,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Vim(Français)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-08-26 20:54+0200\n"
-"PO-Revision-Date: 2016-08-26 20:34+0200\n"
+"POT-Creation-Date: 2017-01-16 00:30+0100\n"
+"PO-Revision-Date: 2017-01-16 00:51+0100\n"
 "Last-Translator: Dominique Pellé <dominique.pelle@gmail.com>\n"
 "Language-Team: \n"
 "Language: fr\n"
@@ -63,6 +63,9 @@ msgstr ""
 msgid "E931: Buffer cannot be registered"
 msgstr "E931: Le tampon ne peut pas être enregistré"
 
+msgid "E937: Attempt to delete a buffer that is in use"
+msgstr "E937: Tentative de suppression d'un tampon en cours d'utilisation"
+
 msgid "E515: No buffers were unloaded"
 msgstr "E515: Aucun tampon n'a été déchargé"
 
@@ -242,7 +245,7 @@ msgid "E898: socket() in channel_open()"
 msgstr "E898: socket() dans channel_open()"
 
 msgid "E903: received command with non-string argument"
-msgstr "E903: commande reçue avec une argument qui n'est pas une chaîne"
+msgstr "E903: commande reçue avec un argument qui n'est pas une chaîne"
 
 msgid "E904: last argument for expr/call must be a number"
 msgstr "E904: le dernier argument de expr/call doit être un nombre"
@@ -2150,6 +2153,9 @@ msgstr "E462: Impossible de pr
 msgid "E321: Could not reload \"%s\""
 msgstr "E321: Impossible de recharger \"%s\""
 
+msgid "--Deleted--"
+msgstr "--Effacé--"
+
 #, c-format
 msgid "auto-removing autocommand: %s <buffer=%d>"
 msgstr "Autocommandes marquées pour auto-suppression : %s <tampon=%d>"
@@ -2159,12 +2165,12 @@ msgstr "Autocommandes marqu
 msgid "E367: No such group: \"%s\""
 msgstr "E367: Aucun groupe \"%s\""
 
+msgid "E936: Cannot delete the current group"
+msgstr "E936: Impossible de supprimer le groupe courant"
+
 msgid "W19: Deleting augroup that is still in use"
 msgstr "W19: Effacement d'augroup toujours en usage"
 
-msgid "--Deleted--"
-msgstr "--Effacé--"
-
 #, c-format
 msgid "E215: Illegal character after *: %s"
 msgstr "E215: Caractère non valide après * : %s"
@@ -2854,7 +2860,7 @@ msgid "invalid expression"
 msgstr "expression invalide"
 
 msgid "expressions disabled at compile time"
-msgstr "expressions désactivée lors de la compilation"
+msgstr "expressions désactivées lors de la compilation"
 
 msgid "hidden option"
 msgstr "option cachée"
@@ -3042,6 +3048,10 @@ msgid "E251: VIM instance registry property is badly formed.  Deleted!"
 msgstr "E251: Entrée registre de l'instance de Vim mal formatée. Suppression !"
 
 #, c-format
+msgid "E938: Duplicate key in JSON: \"%s\""
+msgstr "E938: Clé dupliquée dans le document JSON : \"%s\""
+
+#, c-format
 msgid "E696: Missing comma in List: %s"
 msgstr "E696: Il manque une virgule dans la Liste %s"
 
@@ -3269,6 +3279,10 @@ msgid "--not-a-term\t\tSkip warning for input/output not being a terminal"
 msgstr ""
 "--no-a-term\t\tAucun avertissement si l'entrée/sortie n'est pas un terminal"
 
+msgid "--ttyfail\t\tExit if input or output is not a terminal"
+msgstr ""
+"--ttyfail\t\tQuitte si l'entrée ou la sortie ne sont pas un terminal"
+
 msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
 msgstr "-u <vimrc>\tUtiliser <vimrc> au lieu du vimrc habituel"
 
@@ -4682,9 +4696,6 @@ msgstr "ERREUR d'E/S"
 msgid "Message"
 msgstr "Message"
 
-msgid "'columns' is not 80, cannot execute external commands"
-msgstr "'columns' ne vaut pas 80, impossible d'exécuter des commandes externes"
-
 msgid "E237: Printer selection failed"
 msgstr "E237: La sélection de l'imprimante a échoué"
 
@@ -5625,7 +5636,7 @@ msgstr ""
 #. This should have been checked when generating the .spl
 #. * file.
 msgid "E783: duplicate char in MAP entry"
-msgstr "E783: caractères dupliqué dans l'entrée MAP"
+msgstr "E783: caractère dupliqué dans l'entrée MAP"
 
 msgid "No Syntax items defined for this buffer"
 msgstr "Aucun élément de syntaxe défini pour ce tampon"
@@ -6264,14 +6275,6 @@ msgstr "E133: :return en dehors d'une fonction"
 msgid "E107: Missing parentheses: %s"
 msgstr "E107: Parenthèses manquantes : %s"
 
-#. Only MS VC 4.1 and earlier can do Win32s
-msgid ""
-"\n"
-"MS-Windows 16/32-bit GUI version"
-msgstr ""
-"\n"
-"Version graphique MS-Windows 16/32 bits"
-
 msgid ""
 "\n"
 "MS-Windows 64-bit GUI version"
@@ -6561,12 +6564,6 @@ msgstr "tapez  :help register<Entr
 msgid "menu  Help->Sponsor/Register  for information    "
 msgstr "menu  Aide->Sponsor/Enregistrement pour plus d'info"
 
-msgid "WARNING: Windows 95/98/ME detected"
-msgstr "ALERTE: Windows 95/98/ME détecté"
-
-msgid "type  :help windows95<Enter>  for info on this"
-msgstr "tapez  :help windows95<Entrée>  pour plus d'information"
-
 msgid "Already only one window"
 msgstr "Il n'y a déjà plus qu'une fenêtre"
 
@@ -6727,6 +6724,10 @@ msgstr "E236: La police \"%s\" n'a pas une chasse (largeur) fixe"
 msgid "E473: Internal error"
 msgstr "E473: Erreur interne"
 
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Erreur interne : %s"
+
 msgid "Interrupted"
 msgstr "Interrompu"
 
@@ -7011,10 +7012,6 @@ msgid "E744: NetBeans does not allow changes in read-only files"
 msgstr ""
 "E744: NetBeans n'autorise pas la modification des fichiers en lecture seule"
 
-#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: Erreur interne : %s"
-
 msgid "E363: pattern uses more memory than 'maxmempattern'"
 msgstr "E363: le motif utilise plus de mémoire que 'maxmempattern'"
 
index 82228ca..2aa5f77 100644 (file)
@@ -2894,7 +2894,8 @@ msgstr "-X\t\t\t不连接到 X Server"
 msgid "--remote <files>\tEdit <files> in a Vim server if possible"
 msgstr "--remote <files>\t如有可能,在 Vim 服务器上编辑文件 <files>"
 
-msgid "--remote-silent <files>  Same, don't complain if there is no server"
+msgid ""
+"--remote-silent <files>  Same, don't complain if there is no server"
 msgstr "--remote-silent <files>  同上,找不到服务器时不抱怨"
 
 msgid ""
index 36c7b97..13a1891 100644 (file)
@@ -241,9 +241,8 @@ msgstr " 
 msgid " Tag completion (^]^N^P)"
 msgstr " Tag ²¹È« (^]^N^P)"
 
-#, fuzzy
-#~ msgid " Path pattern completion (^N^P)"
-#~ msgstr " Â·¾¶Ä£Ê½²¹È« (^N^P)"
+msgid " Path pattern completion (^N^P)"
+msgstr " Í·Îļþģʽ²¹È« (^N^P)"
 
 msgid " Definition completion (^D^N^P)"
 msgstr " ¶¨Ò岹ȫ (^D^N^P)"
@@ -2896,7 +2895,7 @@ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
 msgstr "--remote <files>\tÈçÓпÉÄÜ£¬ÔÚ Vim ·þÎñÆ÷Éϱ༭Îļþ <files>"
 
 msgid "--remote-silent <files>  Same, don't complain if there is no server"
-msgstr "--remote-silent <files>  Í¬ÉÏ£¬ÕÒ²»µ½·þÎñÆ÷ʱ»±§Ô¹"
+msgstr "--remote-silent <files>  Í¬ÉÏ£¬ÕÒ²»µ½·þÎñÆ÷ʱ²»±§Ô¹"
 
 msgid ""
 "--remote-wait <files>  As --remote but wait for files to have been edited"
@@ -5284,7 +5283,7 @@ msgstr "Vim: 
 
 #. must display the prompt
 msgid "No undo possible; continue anyway"
-msgstr "ÎÞ·¨³·Ïú£»Çë¼ÌÐø"
+msgstr "ÎÞ·¨³·Ïú£»ÈÔÈ»¼ÌÐø"
 
 msgid "Already at oldest change"
 msgstr "ÒÑλÓÚ×î¾ÉµÄ¸Ä±ä"
@@ -5601,13 +5600,13 @@ msgid "type  :help cp-default<Enter> for info on this"
 msgstr "ÊäÈë  :help cp-default<Enter> ²é¿´Ïà¹Ø˵Ã÷    "
 
 msgid "menu  Help->Orphans           for information    "
-msgstr "²Ëµ¥  Help->Orphans           ²é¿´ËµÃ÷           "
+msgstr "²Ëµ¥  °ïÖú->¹Â¶ù           ²é¿´ËµÃ÷           "
 
 msgid "Running modeless, typed text is inserted"
 msgstr "ÎÞģʽÔËÐУ¬ÊäÈëÎÄ×Ö¼´²åÈë"
 
 msgid "menu  Edit->Global Settings->Toggle Insert Mode  "
-msgstr "²Ëµ¥  Edit->Global Settings->Toggle Insert Mode  "
+msgstr "²Ëµ¥  ±à¼­->È«¾ÖÉ趨->¿ª/¹Ø²åÈëģʽ  "
 
 #, fuzzy
 #~ msgid "                              for two modes      "
index 19d215b..58e3817 100644 (file)
@@ -105,7 +105,8 @@ redo:
 
     /* Put the pum below "row" if possible.  If there are few lines decide on
      * where there is more room. */
-    if (row - above_row >= below_row - row)
+    if (row + 2 >= below_row - pum_height
+                           && row - above_row > (below_row - above_row) / 2)
     {
        /* pum above "row" */
 
@@ -334,7 +335,7 @@ pum_redraw(void)
                case 3: p = pum_array[idx].pum_extra; break;
            }
            if (p != NULL)
-               for ( ; ; mb_ptr_adv(p))
+               for ( ; ; MB_PTR_ADV(p))
                {
                    if (s == NULL)
                        s = p;
@@ -368,7 +369,7 @@ pum_redraw(void)
                                        {
                                            size -= has_mbyte
                                                    ? (*mb_ptr2cells)(rt) : 1;
-                                           mb_ptr_adv(rt);
+                                           MB_PTR_ADV(rt);
                                        } while (size > pum_width);
 
                                        if (size < pum_width)
@@ -589,7 +590,7 @@ pum_set_selected(int n, int repeat)
                        && curbuf->b_p_bh[0] == 'w')
                {
                    /* Already a "wipeout" buffer, make it empty. */
-                   while (!bufempty())
+                   while (!BUFEMPTY())
                        ml_delete((linenr_T)1, FALSE);
                }
                else
index 6a52d8b..a54d387 100644 (file)
@@ -25,6 +25,7 @@ void channel_consume(channel_T *channel, ch_part_T part, int len);
 int channel_collapse(channel_T *channel, ch_part_T part, int want_nl);
 int channel_can_write_to(channel_T *channel);
 int channel_is_open(channel_T *channel);
+int channel_has_readahead(channel_T *channel, ch_part_T part);
 char *channel_status(channel_T *channel, int req_part);
 void channel_info(channel_T *channel, dict_T *dict);
 void channel_close(channel_T *channel, int invoke_close_cb);
@@ -32,7 +33,6 @@ void channel_close_in(channel_T *channel);
 void channel_clear(channel_T *channel);
 void channel_free_all(void);
 char_u *channel_read_block(channel_T *channel, ch_part_T part, int timeout);
-int channel_read_json_block(channel_T *channel, ch_part_T part, int timeout_arg, int id, typval_T **rettv);
 void common_channel_read(typval_T *argvars, typval_T *rettv, int raw);
 channel_T *channel_fd2channel(sock_T fd, ch_part_T *partp);
 void channel_handle_events(void);
@@ -44,6 +44,7 @@ int channel_poll_check(int ret_in, void *fds_in);
 int channel_select_setup(int maxfd_in, void *rfds_in, void *wfds_in);
 int channel_select_check(int ret_in, void *rfds_in, void *wfds_in);
 int channel_parse_messages(void);
+int channel_any_readahead(void);
 int set_ref_in_channel(int copyID);
 ch_part_T channel_part_send(channel_T *channel);
 ch_part_T channel_part_read(channel_T *channel);
index 7a399c0..f6d645c 100644 (file)
@@ -38,6 +38,7 @@ void fixthisline(int (*get_the_indent)(void));
 void fix_indent(void);
 int in_cinkeys(int keytyped, int when, int line_is_empty);
 int hkmap(int c);
+int bracketed_paste(paste_mode_T mode, int drop, garray_T *gap);
 void ins_scroll(void);
 void ins_horscroll(void);
 int ins_copychar(linenr_T lnum);
index edca43e..5fc6260 100644 (file)
@@ -25,7 +25,6 @@ void *call_func_retlist(char_u *func, int argc, char_u **argv, int safe);
 int eval_foldexpr(char_u *arg, int *cp);
 void ex_let(exarg_T *eap);
 void list_hashtable_vars(hashtab_T *ht, char_u *prefix, int empty, int *first);
-int check_changedtick(char_u *arg);
 char_u *get_lval(char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int flags, int fne_flags);
 void clear_lval(lval_T *lp);
 void *eval_for_line(char_u *arg, int *errp, char_u **nextcmdp, int skip);
@@ -124,6 +123,7 @@ void assert_equal_common(typval_T *argvars, assert_type_T atype);
 void assert_match_common(typval_T *argvars, assert_type_T atype);
 void assert_inrange(typval_T *argvars);
 void assert_bool(typval_T *argvars, int isTrue);
+void assert_report(typval_T *argvars);
 void assert_exception(typval_T *argvars);
 void assert_fails(typval_T *argvars);
 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);
index c1325a4..4a40f0a 100644 (file)
@@ -75,6 +75,10 @@ int do_in_runtimepath(char_u *name, int flags, void (*callback)(char_u *fname, v
 void ex_packloadall(exarg_T *eap);
 void ex_packadd(exarg_T *eap);
 void ex_options(exarg_T *eap);
+void init_pyxversion(void);
+void ex_pyxfile(exarg_T *eap);
+void ex_pyx(exarg_T *eap);
+void ex_pyxdo(exarg_T *eap);
 void ex_source(exarg_T *eap);
 linenr_T *source_breakpoint(void *cookie);
 int *source_dbg_tick(void *cookie);
index 908b785..9274bce 100644 (file)
@@ -7,7 +7,7 @@ int cause_errthrow(char_u *mesg, int severe, int *ignore);
 void free_global_msglist(void);
 void do_errthrow(struct condstack *cstack, char_u *cmdname);
 int do_intthrow(struct condstack *cstack);
-char_u *get_exception_string(void *value, int type, char_u *cmdname, int *should_free);
+char_u *get_exception_string(void *value, except_type_T type, char_u *cmdname, int *should_free);
 void discard_current_exception(void);
 void report_make_pending(int pending, void *value);
 void report_resume_pending(int pending, void *value);
index dce1803..cda536b 100644 (file)
@@ -31,6 +31,7 @@ void foldInitWin(win_T *new_win);
 int find_wl_entry(win_T *win, linenr_T lnum);
 void foldAdjustVisual(void);
 void foldAdjustCursor(void);
+void foldMoveRange(garray_T *gap, linenr_T line1, linenr_T line2, linenr_T dest);
 void cloneFoldGrowArray(garray_T *from, garray_T *to);
 void deleteFoldRecurse(garray_T *gap);
 void foldMarkAdjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long amount_after);
index de33bfd..aac522f 100644 (file)
@@ -8,8 +8,8 @@ void typeahead_noflush(int c);
 void flush_buffers(int flush_typeahead);
 void ResetRedobuff(void);
 void CancelRedo(void);
-void saveRedobuff(void);
-void restoreRedobuff(void);
+void saveRedobuff(save_redo_T *save_redo);
+void restoreRedobuff(save_redo_T *save_redo);
 void AppendToRedobuff(char_u *s);
 void AppendToRedobuffLit(char_u *str, int len);
 void AppendCharToRedobuff(int c);
index 3a3b392..f9919c4 100644 (file)
@@ -1,9 +1,9 @@
 /* if_cscope.c */
 char_u *get_cscope_name(expand_T *xp, int idx);
 void set_context_in_cscope_cmd(expand_T *xp, char_u *arg, cmdidx_T cmdidx);
-void do_cscope(exarg_T *eap);
-void do_scscope(exarg_T *eap);
-void do_cstag(exarg_T *eap);
+void ex_cscope(exarg_T *eap);
+void ex_scscope(exarg_T *eap);
+void ex_cstag(exarg_T *eap);
 int cs_fgets(char_u *buf, int size);
 void cs_free_tags(void);
 void cs_print_tags(void);
index 137020e..801dc00 100644 (file)
@@ -1,11 +1,11 @@
 /* if_xcmdsrv.c */
 int serverRegisterName(Display *dpy, char_u *name);
 void serverChangeRegisteredWindow(Display *dpy, Window newwin);
-int serverSendToVim(Display *dpy, char_u *name, char_u *cmd, char_u **result, Window *server, int asExpr, int localLoop, int silent);
+int serverSendToVim(Display *dpy, char_u *name, char_u *cmd, char_u **result, Window *server, int asExpr, int timeout, int localLoop, int silent);
 char_u *serverGetVimNames(Display *dpy);
 Window serverStrToWin(char_u *str);
 int serverSendReply(char_u *name, char_u *str);
-int serverReadReply(Display *dpy, Window win, char_u **str, int localLoop);
+int serverReadReply(Display *dpy, Window win, char_u **str, int localLoop, int timeout);
 int serverPeekReply(Display *dpy, Window win, char_u **str);
 void serverEventProc(Display *dpy, XEvent *eventPtr, int immediate);
 void server_parse_messages(void);
index 958e1f3..278d1ad 100644 (file)
@@ -1,6 +1,7 @@
 /* main.c */
 int vim_main2(void);
 void common_init(mparm_T *paramp);
+int is_not_a_term(void);
 void main_loop(int cmdwin, int noexmode);
 void getout_preserve_modified(int exitval);
 void getout(int exitval);
@@ -11,5 +12,6 @@ void time_pop(void *tp);
 void time_msg(char *mesg, void *tv_start);
 void server_to_input_buf(char_u *str);
 char_u *eval_client_expr_to_string(char_u *expr);
+int sendToLocalVim(char_u *cmd, int asExpr, char_u **result);
 char_u *serverConvert(char_u *client_enc, char_u *data, char_u **tofree);
 /* vim: set ft=c : */
index 90be1a5..ff1f441 100644 (file)
@@ -19,6 +19,7 @@ void ex_jumps(exarg_T *eap);
 void ex_clearjumps(exarg_T *eap);
 void ex_changes(exarg_T *eap);
 void mark_adjust(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);
 void mark_col_adjust(linenr_T lnum, colnr_T mincol, long lnum_amount, long col_amount);
 void copy_jumplist(win_T *from, win_T *to);
 void free_jumplist(win_T *wp);
index 806a6c6..83bcadc 100644 (file)
@@ -40,6 +40,7 @@ int utf_char2bytes(int c, char_u *buf);
 int utf_iscomposing(int c);
 int utf_printable(int c);
 int utf_class(int c);
+int utf_class_buf(int c, buf_T *buf);
 int utf_ambiguous_width(int c);
 int utf_fold(int a);
 int utf_toupper(int a);
index 7112b09..8d9ac71 100644 (file)
@@ -8,9 +8,16 @@ void trunc_string(char_u *s, char_u *buf, int room_in, int buflen);
 void reset_last_sourcing(void);
 void msg_source(int attr);
 int emsg_not_now(void);
+void ignore_error_for_testing(char_u *error);
 void do_perror(char *msg);
 int emsg(char_u *s);
 int emsg2(char_u *s, char_u *a1);
+int emsg3(char_u *s, char_u *a1, char_u *a2);
+int emsgn(char_u *s, long n);
+void iemsg(char_u *s);
+void iemsg2(char_u *s, char_u *a1);
+void iemsgn(char_u *s, long n);
+void internal_error(char *where);
 void emsg_invreg(int name);
 char_u *msg_trunc_attr(char_u *s, int force, int attr);
 char_u *msg_may_trunc(int force, char_u *s);
@@ -45,7 +52,9 @@ void msg_puts_long_len_attr(char_u *longstr, int len, int attr);
 void msg_puts_attr(char_u *s, int attr);
 int message_filtered(char_u *msg);
 void may_clear_sb_text(void);
-void clear_sb_text(void);
+void sb_text_start_cmdline(void);
+void sb_text_end_cmdline(void);
+void clear_sb_text(int all);
 void show_sb_text(void);
 void msg_sb_eol(void);
 int msg_use_printf(void);
index d18ae20..68c40da 100644 (file)
@@ -40,6 +40,7 @@ char_u *vim_strsave_up(char_u *string);
 char_u *vim_strnsave_up(char_u *string, int len);
 void vim_strup(char_u *p);
 char_u *strup_save(char_u *orig);
+char_u *strlow_save(char_u *orig);
 void del_trailing_spaces(char_u *ptr);
 void vim_strncpy(char_u *to, char_u *from, size_t len);
 void vim_strcat(char_u *to, char_u *from, size_t tosize);
@@ -82,7 +83,7 @@ int get_real_state(void);
 int after_pathsep(char_u *b, char_u *p);
 int same_directory(char_u *f1, char_u *f2);
 int vim_chdirfile(char_u *fname);
-int illegal_slash(char *name);
+int vim_stat(const char *name, stat_T *stp);
 char_u *parse_shape_opt(int what);
 int get_shape_idx(int mouse);
 void update_mouseshape(int shape_idx);
@@ -99,8 +100,6 @@ int get_user_name(char_u *buf, int len);
 void sort_strings(char_u **files, int count);
 int pathcmp(const char *p, const char *q, int maxlen);
 int filewritable(char_u *fname);
-int emsg3(char_u *s, char_u *a1, char_u *a2);
-int emsgn(char_u *s, long n);
 int get2c(FILE *fd);
 int get3c(FILE *fd);
 int get4c(FILE *fd);
index de4ae73..0740dda 100644 (file)
@@ -23,6 +23,7 @@ int insert_reg(int regname, int literally);
 int get_spec_reg(int regname, char_u **argp, int *allocated, int errmsg);
 int cmdline_paste_reg(int regname, int literally, int remcr);
 void adjust_clip_reg(int *rp);
+void shift_delete_registers(void);
 int op_delete(oparg_T *oap);
 int op_replace(oparg_T *oap, int c);
 void op_tilde(oparg_T *oap);
@@ -37,6 +38,7 @@ void adjust_cursor_eol(void);
 int preprocs_left(void);
 int get_register_name(int num);
 void ex_display(exarg_T *eap);
+char_u *skip_comment(char_u *line, int process, int include_space, int *is_comment);
 int do_join(long count, int insert_space, int save_undo, int use_formatoptions, int setmark);
 void op_format(oparg_T *oap, int keep_cursor);
 void op_formatexpr(oparg_T *oap);
index 8cfcb43..cc660a6 100644 (file)
@@ -43,9 +43,9 @@ void serverInitMessaging(void);
 void serverSetName(char_u *name);
 char_u *serverGetVimNames(void);
 int serverSendReply(char_u *name, char_u *reply);
-int serverSendToVim(char_u *name, char_u *cmd, char_u **result, void *ptarget, int asExpr, int silent);
+int serverSendToVim(char_u *name, char_u *cmd, char_u **result, void *ptarget, int asExpr, int timeout, int silent);
 void serverForeground(char_u *name);
-char_u *serverGetReply(HWND server, int *expr_res, int remove, int wait);
+char_u *serverGetReply(HWND server, int *expr_res, int remove, int wait, int timeout);
 void serverProcessPendingMessages(void);
 char *charset_id2name(int id);
 char *quality_id2name(DWORD id);
index b21a7ba..ca67146 100644 (file)
@@ -1,5 +1,7 @@
 /* os_win32.c */
 HINSTANCE vimLoadLib(char *name);
+HINSTANCE find_imported_module_by_funcname(HINSTANCE hInst, const char *funcname);
+void *get_dll_import_func(HINSTANCE hInst, const char *funcname);
 int dyn_libintl_init(void);
 void dyn_libintl_end(void);
 void PlatformId(void);
@@ -63,4 +65,5 @@ void free_cmd_argsW(void);
 void used_file_arg(char *name, int literal, int full_path, int diff_mode);
 void set_alist_count(void);
 void fix_arg_enc(void);
+int mch_setenv(char *var, char *value, int x);
 /* vim: set ft=c : */
index d48eb25..995f41f 100644 (file)
@@ -1,5 +1,5 @@
 /* quickfix.c */
-int qf_init(win_T *wp, char_u *efile, char_u *errorformat, int newlist, char_u *qf_title);
+int qf_init(win_T *wp, char_u *efile, char_u *errorformat, int newlist, char_u *qf_title, char_u *enc);
 void qf_free_all(win_T *wp);
 void copy_loclist(win_T *from, win_T *to);
 void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit);
index 64235b0..aae187f 100644 (file)
@@ -52,5 +52,6 @@ void highlight_gui_started(void);
 int highlight_changed(void);
 void set_context_in_highlight_cmd(expand_T *xp, char_u *arg);
 char_u *get_highlight_name(expand_T *xp, int idx);
+char_u *get_highlight_name_ext(expand_T *xp, int idx, int skip_cleared);
 void free_highlight_fonts(void);
 /* vim: set ft=c : */
index 55f579d..497a76e 100644 (file)
@@ -8,5 +8,5 @@ int get_tagfname(tagname_T *tnp, int first, char_u *buf);
 void tagname_free(tagname_T *tnp);
 void simplify_filename(char_u *filename);
 int expand_tags(int tagnames, char_u *pat, int *num_file, char_u ***file);
-int get_tags(list_T *list, char_u *pat);
+int get_tags(list_T *list, char_u *pat, char_u *buf_fname);
 /* vim: set ft=c : */
index 0c238d3..7d9fc6a 100644 (file)
@@ -22,6 +22,7 @@ void term_cursor_right(int i);
 void term_append_lines(int line_count);
 void term_delete_lines(int line_count);
 void term_set_winpos(int x, int y);
+int term_get_winpos(int *x, int *y);
 void term_set_winsize(int width, int height);
 void term_fg_color(int n);
 void term_bg_color(int n);
index dbb7213..47c0fef 100644 (file)
@@ -16,6 +16,7 @@ void clip_update_selection(VimClipboard *clip);
 void clip_own_selection(VimClipboard *cbd);
 void clip_lose_selection(VimClipboard *cbd);
 void start_global_changes(void);
+int is_clipboard_needs_update(void);
 void end_global_changes(void);
 void clip_auto_select(void);
 int clip_isautosel_star(void);
index 8b649db..e53123c 100644 (file)
@@ -26,6 +26,8 @@ int win_new_tabpage(int after);
 int may_open_tabpage(void);
 int make_tabpages(int maxcount);
 int valid_tabpage(tabpage_T *tpc);
+int valid_tabpage_win(tabpage_T *tpc);
+void close_tabpage(tabpage_T *tpc);
 tabpage_T *find_tabpage(int n);
 int tabpage_index(tabpage_T *ftp);
 void goto_tabpage(int n);
index c07256f..20ab65b 100644 (file)
--- a/src/pty.c
+++ b/src/pty.c
@@ -62,7 +62,7 @@
 #ifdef sinix
 #undef buf_T
 #endif
-# ifdef sun
+# ifdef SUN_SYSTEM
 #  include <sys/conf.h>
 # endif
 #endif
 # include <sys/ptem.h>
 #endif
 
-#if !defined(sun) && !defined(VMS) && !defined(MACOS)
+#if !defined(SUN_SYSTEM) && !defined(VMS) && !defined(MACOS)
 # include <sys/ioctl.h>
 #endif
 
-#if defined(sun) && defined(LOCKPTY) && !defined(TIOCEXCL)
+#if defined(SUN_SYSTEM) && defined(LOCKPTY) && !defined(TIOCEXCL)
 # include <sys/ttold.h>
 #endif
 
@@ -166,7 +166,7 @@ SetupSlavePTY(int fd)
 # endif
     if (ioctl(fd, I_PUSH, "ldterm") != 0)
        return -1;
-# ifdef sun
+# ifdef SUN_SYSTEM
     if (ioctl(fd, I_PUSH, "ttcompat") != 0)
        return -1;
 # endif
@@ -391,7 +391,7 @@ OpenPTY(char **ttyn)
                continue;
            }
 #endif
-#if defined(sun) && defined(TIOCGPGRP) && !defined(SUNOS3)
+#if defined(SUN_SYSTEM) && defined(TIOCGPGRP) && !defined(SUNOS3)
            /* Hack to ensure that the slave side of the pty is
             * unused. May not work in anything other than SunOS4.1
             */
index a45faea..e65e431 100644 (file)
@@ -114,7 +114,9 @@ struct efm_S
     int                    conthere;   /* %> used */
 };
 
-static int     qf_init_ext(qf_info_T *qi, char_u *efile, buf_T *buf, typval_T *tv, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast, char_u *qf_title);
+static efm_T   *fmt_start = NULL; /* cached across qf_parse_line() calls */
+
+static int     qf_init_ext(qf_info_T *qi, char_u *efile, buf_T *buf, typval_T *tv, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast, char_u *qf_title, char_u *enc);
 static void    qf_store_title(qf_info_T *qi, char_u *title);
 static void    qf_new_list(qf_info_T *qi, char_u *qf_title);
 static void    ll_free_all(qf_info_T **pqi);
@@ -165,7 +167,8 @@ qf_init(
     char_u         *efile,
     char_u         *errorformat,
     int                    newlist,            /* TRUE: start a new error list */
-    char_u         *qf_title)
+    char_u         *qf_title,
+    char_u         *enc)
 {
     qf_info_T      *qi = &ql_info;
 
@@ -178,7 +181,7 @@ qf_init(
 
     return qf_init_ext(qi, efile, curbuf, NULL, errorformat, newlist,
                                                    (linenr_T)0, (linenr_T)0,
-                                                   qf_title);
+                                                   qf_title, enc);
 }
 
 /*
@@ -389,6 +392,7 @@ free_efm_list(efm_T **efm_first)
        vim_regfree(efm_ptr->prog);
        vim_free(efm_ptr);
     }
+    fmt_start = NULL;
 }
 
 /* Parse 'errorformat' option */
@@ -495,6 +499,7 @@ typedef struct {
     buf_T      *buf;
     linenr_T   buflnum;
     linenr_T   lnumlast;
+    vimconv_T  vc;
 } qfstate_T;
 
     static char_u *
@@ -710,6 +715,31 @@ qf_get_next_file_line(qfstate_T *state)
     else
        state->linebuf = IObuff;
 
+#ifdef FEAT_MBYTE
+    /* Convert a line if it contains a non-ASCII character. */
+    if (state->vc.vc_type != CONV_NONE && has_non_ascii(state->linebuf))
+    {
+       char_u  *line;
+
+       line = string_convert(&state->vc, state->linebuf, &state->linelen);
+       if (line != NULL)
+       {
+           if (state->linelen < IOSIZE)
+           {
+               STRCPY(state->linebuf, line);
+               vim_free(line);
+           }
+           else
+           {
+               vim_free(state->growbuf);
+               state->linebuf = state->growbuf = line;
+               state->growbufsiz = state->linelen < LINE_MAXLEN
+                                               ? state->linelen : LINE_MAXLEN;
+           }
+       }
+    }
+#endif
+
     return QF_OK;
 }
 
@@ -786,7 +816,6 @@ qf_parse_line(
        qffields_T      *fields)
 {
     efm_T              *fmt_ptr;
-    static efm_T       *fmt_start = NULL; /* cached across calls */
     char_u             *ptr;
     int                        len;
     int                        i;
@@ -889,7 +918,8 @@ restofline:
            }
            if (fmt_ptr->flags == '+' && !qi->qf_multiscan)     /* %+ */
            {
-               if (linelen > fields->errmsglen) {
+               if (linelen > fields->errmsglen)
+               {
                    /* linelen + null terminator */
                    if ((fields->errmsg = vim_realloc(fields->errmsg,
                                    linelen + 1)) == NULL)
@@ -903,7 +933,8 @@ restofline:
                if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL)
                    continue;
                len = (int)(regmatch.endp[i] - regmatch.startp[i]);
-               if (len > fields->errmsglen) {
+               if (len > fields->errmsglen)
+               {
                    /* len + null terminator */
                    if ((fields->errmsg = vim_realloc(fields->errmsg, len + 1))
                            == NULL)
@@ -985,7 +1016,8 @@ restofline:
        fields->namebuf[0] = NUL;       /* no match found, remove file name */
        fields->lnum = 0;                       /* don't jump to this line */
        fields->valid = FALSE;
-       if (linelen > fields->errmsglen) {
+       if (linelen > fields->errmsglen)
+       {
            /* linelen + null terminator */
            if ((fields->errmsg = vim_realloc(fields->errmsg,
                            linelen + 1)) == NULL)
@@ -1103,13 +1135,14 @@ qf_init_ext(
     int                    newlist,            /* TRUE: start a new error list */
     linenr_T       lnumfirst,          /* first line number to use */
     linenr_T       lnumlast,           /* last line number to use */
-    char_u         *qf_title)
+    char_u         *qf_title,
+    char_u         *enc)
 {
-    qfstate_T      state = {NULL, 0, NULL, 0, NULL, NULL, NULL, NULL,
-                            NULL, 0, 0};
-    qffields_T     fields = {NULL, NULL, 0, 0L, 0, FALSE, NULL, 0, 0, 0};
+    qfstate_T      state;
+    qffields_T     fields;
 #ifdef FEAT_WINDOWS
     qfline_T       *old_last = NULL;
+    int                    adding = FALSE;
 #endif
     static efm_T    *fmt_first = NULL;
     char_u         *efm;
@@ -1117,6 +1150,13 @@ qf_init_ext(
     int                    retval = -1;        /* default: return error flag */
     int                    status;
 
+    vim_memset(&state, 0, sizeof(state));
+    vim_memset(&fields, 0, sizeof(fields));
+#ifdef FEAT_MBYTE
+    state.vc.vc_type = CONV_NONE;
+    if (enc != NULL && *enc != NUL)
+       convert_setup(&state.vc, enc, p_enc);
+#endif
     fields.namebuf = alloc_id(CMDBUFFSIZE + 1, aid_qf_namebuf);
     fields.errmsglen = CMDBUFFSIZE + 1;
     fields.errmsg = alloc_id(fields.errmsglen, aid_qf_errmsg);
@@ -1138,6 +1178,7 @@ qf_init_ext(
     else if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
     {
        /* Adding to existing list, use last entry. */
+       adding = TRUE;
        old_last = qi->qf_lists[qi->qf_curlist].qf_last;
     }
 #endif
@@ -1264,10 +1305,13 @@ qf_init_ext(
     }
     EMSG(_(e_readerrf));
 error2:
-    qf_free(qi, qi->qf_curlist);
-    qi->qf_listcount--;
-    if (qi->qf_curlist > 0)
-       --qi->qf_curlist;
+    if (!adding)
+    {
+       qf_free(qi, qi->qf_curlist);
+       qi->qf_listcount--;
+       if (qi->qf_curlist > 0)
+           --qi->qf_curlist;
+    }
 qf_init_end:
     if (state.fd != NULL)
        fclose(state.fd);
@@ -1279,6 +1323,10 @@ qf_init_end:
 #ifdef FEAT_WINDOWS
     qf_update_buffer(qi, old_last);
 #endif
+#ifdef FEAT_MBYTE
+    if (state.vc.vc_type != CONV_NONE)
+       convert_setup(&state.vc, NULL, NULL);
+#endif
 
     return retval;
 }
@@ -1610,7 +1658,7 @@ static char_u *qf_last_bufname = NULL;
 static bufref_T  qf_last_bufref = {NULL, 0};
 
 /*
- * Get buffer number for file "directory.fname".
+ * Get buffer number for file "directory/fname".
  * Also sets the b_has_qf_entry flag.
  */
     static int
@@ -2511,7 +2559,7 @@ qf_list(exarg_T *eap)
                vim_snprintf((char *)IObuff, IOSIZE, "%2d %s",
                                                            i, (char *)fname);
            msg_outtrans_attr(IObuff, i == qi->qf_lists[qi->qf_curlist].qf_index
-                                          ? hl_attr(HLF_L) : hl_attr(HLF_D));
+                                          ? HL_ATTR(HLF_L) : HL_ATTR(HLF_D));
            if (qfp->qf_lnum == 0)
                IObuff[0] = NUL;
            else if (qfp->qf_col == 0)
@@ -2521,7 +2569,7 @@ qf_list(exarg_T *eap)
                                                   qfp->qf_lnum, qfp->qf_col);
            sprintf((char *)IObuff + STRLEN(IObuff), "%s:",
                                  (char *)qf_types(qfp->qf_type, qfp->qf_nr));
-           msg_puts_attr(IObuff, hl_attr(HLF_N));
+           msg_puts_attr(IObuff, HL_ATTR(HLF_N));
            if (qfp->qf_pattern != NULL)
            {
                qf_fmt_text(qfp->qf_pattern, IObuff, IOSIZE);
@@ -2564,7 +2612,7 @@ qf_fmt_text(char_u *text, char_u *buf, int bufsize)
        {
            buf[i] = ' ';
            while (*++p != NUL)
-               if (!vim_iswhite(*p) && *p != '\n')
+               if (!VIM_ISWHITE(*p) && *p != '\n')
                    break;
        }
        else
@@ -2702,9 +2750,18 @@ qf_free(qf_info_T *qi, int idx)
     vim_free(qi->qf_lists[idx].qf_title);
     qi->qf_lists[idx].qf_title = NULL;
     qi->qf_lists[idx].qf_index = 0;
+    qi->qf_lists[idx].qf_start = NULL;
+    qi->qf_lists[idx].qf_last = NULL;
+    qi->qf_lists[idx].qf_ptr = NULL;
+    qi->qf_lists[idx].qf_nonevalid = TRUE;
 
     qf_clean_dir_stack(&qi->qf_dir_stack);
+    qi->qf_directory = NULL;
     qf_clean_dir_stack(&qi->qf_file_stack);
+    qi->qf_currfile = NULL;
+    qi->qf_multiline = FALSE;
+    qi->qf_multiignore = FALSE;
+    qi->qf_multiscan = FALSE;
 }
 
 /*
@@ -3231,7 +3288,7 @@ qf_fill_buffer(qf_info_T *qi, buf_T *buf, qfline_T *old_last)
     {
        if (buf != curbuf)
        {
-           EMSG2(_(e_intern2), "qf_fill_buffer()");
+           internal_error("qf_fill_buffer()");
            return;
        }
 
@@ -3422,6 +3479,7 @@ ex_make(exarg_T *eap)
 {
     char_u     *fname;
     char_u     *cmd;
+    char_u     *enc = NULL;
     unsigned   len;
     win_T      *wp = NULL;
     qf_info_T  *qi = &ql_info;
@@ -3455,6 +3513,9 @@ ex_make(exarg_T *eap)
 # endif
     }
 #endif
+#ifdef FEAT_MBYTE
+    enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc;
+#endif
 
     if (eap->cmdidx == CMD_lmake || eap->cmdidx == CMD_lgrep
        || eap->cmdidx == CMD_lgrepadd)
@@ -3502,7 +3563,7 @@ ex_make(exarg_T *eap)
                            && eap->cmdidx != CMD_lmake) ? p_gefm : p_efm,
                                           (eap->cmdidx != CMD_grepadd
                                            && eap->cmdidx != CMD_lgrepadd),
-                                          *eap->cmdlinep);
+                                          *eap->cmdlinep, enc);
     if (wp != NULL)
        qi = GET_LOC_LIST(wp);
 #ifdef FEAT_AUTOCMD
@@ -3841,6 +3902,7 @@ ex_cnext(exarg_T *eap)
     void
 ex_cfile(exarg_T *eap)
 {
+    char_u     *enc = NULL;
     win_T      *wp = NULL;
     qf_info_T  *qi = &ql_info;
 #ifdef FEAT_AUTOCMD
@@ -3865,6 +3927,9 @@ ex_cfile(exarg_T *eap)
     if (au_name != NULL)
        apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name, NULL, FALSE, curbuf);
 #endif
+#ifdef FEAT_MBYTE
+    enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc;
+#endif
 #ifdef FEAT_BROWSE
     if (cmdmod.browse)
     {
@@ -3892,7 +3957,7 @@ ex_cfile(exarg_T *eap)
      */
     if (qf_init(wp, p_ef, p_efm, (eap->cmdidx != CMD_caddfile
                                  && eap->cmdidx != CMD_laddfile),
-                                                          *eap->cmdlinep) > 0
+                                                      *eap->cmdlinep, enc) > 0
                                  && (eap->cmdidx == CMD_cfile
                                             || eap->cmdidx == CMD_lfile))
     {
@@ -4714,6 +4779,10 @@ qf_add_entries(
            bufnum = 0;
        }
 
+       /* If the 'valid' field is present it overrules the detected value. */
+       if ((dict_find(d, (char_u *)"valid", -1)) != NULL)
+           valid = (int)get_dict_number(d, (char_u *)"valid");
+
        status =  qf_add_entry(qi,
                               NULL,        /* dir */
                               filename,
@@ -4744,7 +4813,8 @@ qf_add_entries(
        qi->qf_lists[qi->qf_curlist].qf_nonevalid = TRUE;
     else
        qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE;
-    if (action != 'a') {
+    if (action != 'a')
+    {
        qi->qf_lists[qi->qf_curlist].qf_ptr =
            qi->qf_lists[qi->qf_curlist].qf_start;
        if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
@@ -4808,6 +4878,75 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action)
 }
 
 /*
+ * Find the non-location list window with the specified location list.
+ */
+    static win_T *
+find_win_with_ll(qf_info_T *qi)
+{
+    win_T      *wp = NULL;
+
+    FOR_ALL_WINDOWS(wp)
+       if ((wp->w_llist == qi) && !bt_quickfix(wp->w_buffer))
+           return wp;
+
+    return NULL;
+}
+
+/*
+ * Free the entire quickfix/location list stack.
+ * If the quickfix/location list window is open, then clear it.
+ */
+    static void
+qf_free_stack(win_T *wp, qf_info_T *qi)
+{
+    win_T      *qfwin = qf_find_win(qi);
+    win_T      *llwin = NULL;
+    win_T      *orig_wp = wp;
+
+    if (qfwin != NULL)
+    {
+       /* If the quickfix/location list window is open, then clear it */
+       if (qi->qf_curlist < qi->qf_listcount)
+           qf_free(qi, qi->qf_curlist);
+       qf_update_buffer(qi, NULL);
+    }
+
+    if (wp != NULL && IS_LL_WINDOW(wp))
+    {
+       /* If in the location list window, then use the non-location list
+        * window with this location list (if present)
+        */
+       llwin = find_win_with_ll(qi);
+       if (llwin != NULL)
+           wp = llwin;
+    }
+
+    qf_free_all(wp);
+    if (wp == NULL)
+    {
+       /* quickfix list */
+       qi->qf_curlist = 0;
+       qi->qf_listcount = 0;
+    }
+    else if (IS_LL_WINDOW(orig_wp))
+    {
+       /* If the location list window is open, then create a new empty
+        * location list */
+       qf_info_T *new_ll = ll_new_list();
+
+       /* first free the list reference in the location list window */
+       ll_free_all(&orig_wp->w_llist_ref);
+
+       orig_wp->w_llist_ref = new_ll;
+       if (llwin != NULL)
+       {
+           llwin->w_llist = new_ll;
+           new_ll->qf_refcount++;
+       }
+    }
+}
+
+/*
  * Populate the quickfix list with the items supplied in the list
  * of dictionaries. "title" will be copied to w:quickfix_title.
  * "action" is 'a' for add, 'r' for replace.  Otherwise create a new list.
@@ -4830,7 +4969,12 @@ set_errorlist(
            return FAIL;
     }
 
-    if (what != NULL)
+    if (action == 'f')
+    {
+       /* Free the entire quickfix or location list stack */
+       qf_free_stack(wp, qi);
+    }
+    else if (what != NULL)
        retval = qf_set_properties(qi, what, action);
     else
        retval = qf_add_entries(qi, list, title, action);
@@ -4918,7 +5062,7 @@ ex_cbuffer(exarg_T *eap)
                            (eap->cmdidx != CMD_caddbuffer
                             && eap->cmdidx != CMD_laddbuffer),
                                                   eap->line1, eap->line2,
-                                                  qf_title) > 0)
+                                                  qf_title, NULL) > 0)
            {
 #ifdef FEAT_AUTOCMD
                if (au_name != NULL)
@@ -4986,7 +5130,8 @@ ex_cexpr(exarg_T *eap)
            if (qf_init_ext(qi, NULL, NULL, tv, p_efm,
                            (eap->cmdidx != CMD_caddexpr
                             && eap->cmdidx != CMD_laddexpr),
-                                (linenr_T)0, (linenr_T)0, *eap->cmdlinep) > 0)
+                                (linenr_T)0, (linenr_T)0, *eap->cmdlinep,
+                                NULL) > 0)
            {
 #ifdef FEAT_AUTOCMD
                if (au_name != NULL)
@@ -5022,6 +5167,7 @@ ex_helpgrep(exarg_T *eap)
     char_u     *lang;
 #endif
     qf_info_T  *qi = &ql_info;
+    qf_info_T  *save_qi;
     int                new_qi = FALSE;
     win_T      *wp;
 #ifdef FEAT_AUTOCMD
@@ -5075,6 +5221,9 @@ ex_helpgrep(exarg_T *eap)
        }
     }
 
+    /* Autocommands may change the list. Save it for later comparison */
+    save_qi = qi;
+
     regmatch.regprog = vim_regcomp(eap->arg, RE_MAGIC + RE_STRING);
     regmatch.rm_ic = FALSE;
     if (regmatch.regprog != NULL)
@@ -5128,7 +5277,8 @@ ex_helpgrep(exarg_T *eap)
                            /* Convert a line if 'encoding' is not utf-8 and
                             * the line contains a non-ASCII character. */
                            if (vc.vc_type != CONV_NONE
-                                                  && has_non_ascii(IObuff)) {
+                                                  && has_non_ascii(IObuff))
+                           {
                                line = string_convert(&vc, IObuff, NULL);
                                if (line == NULL)
                                    line = IObuff;
@@ -5207,7 +5357,7 @@ ex_helpgrep(exarg_T *eap)
     {
        apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
                                               curbuf->b_fname, TRUE, curbuf);
-       if (!new_qi && qi != &ql_info && qf_find_buf(qi) == NULL)
+       if (!new_qi && qi != save_qi && qf_find_buf(qi) == NULL)
            /* autocommands made "qi" invalid */
            return;
     }
index 8d63d5a..e1f6484 100644 (file)
@@ -335,11 +335,13 @@ toggle_Magic(int x)
 /* Used for an error (down from) vim_regcomp(): give the error message, set
  * rc_did_emsg and return NULL */
 #define EMSG_RET_NULL(m) return (EMSG(m), rc_did_emsg = TRUE, (void *)NULL)
+#define IEMSG_RET_NULL(m) return (IEMSG(m), rc_did_emsg = TRUE, (void *)NULL)
 #define EMSG_RET_FAIL(m) return (EMSG(m), rc_did_emsg = TRUE, FAIL)
 #define EMSG2_RET_NULL(m, c) return (EMSG2((m), (c) ? "" : "\\"), rc_did_emsg = TRUE, (void *)NULL)
 #define EMSG2_RET_FAIL(m, c) return (EMSG2((m), (c) ? "" : "\\"), rc_did_emsg = TRUE, FAIL)
 #define EMSG_ONE_RET_NULL EMSG2_RET_NULL(_("E369: invalid item in %s%%[]"), reg_magic == MAGIC_ALL)
 
+
 #define MAX_LIMIT      (32767L << 16L)
 
 static int re_multi_type(int);
@@ -1203,7 +1205,7 @@ skip_anyof(char_u *p)
            {
                ++p;
                if (*p != ']' && *p != NUL)
-                   mb_ptr_adv(p);
+                   MB_PTR_ADV(p);
            }
        else if (*p == '\\'
                && !reg_cpo_bsl
@@ -1250,7 +1252,7 @@ skip_regexp(
        mymagic = MAGIC_OFF;
     get_cpo_flags();
 
-    for (; p[0] != NUL; mb_ptr_adv(p))
+    for (; p[0] != NUL; MB_PTR_ADV(p))
     {
        if (p[0] == dirc)       /* found end of regexp */
            break;
@@ -2043,7 +2045,7 @@ regatom(int *flagp)
       case Magic(')'):
        if (one_exactly)
            EMSG_ONE_RET_NULL;
-       EMSG_RET_NULL(_(e_internal));   /* Supposed to be caught earlier. */
+       IEMSG_RET_NULL(_(e_internal));  /* Supposed to be caught earlier. */
        /* NOTREACHED */
 
       case Magic('='):
@@ -2553,17 +2555,17 @@ collection:
                                regc('\t');
                                break;
                            case CLASS_CNTRL:
-                               for (cu = 1; cu <= 255; cu++)
+                               for (cu = 1; cu <= 127; cu++)
                                    if (iscntrl(cu))
                                        regmbc(cu);
                                break;
                            case CLASS_DIGIT:
-                               for (cu = 1; cu <= 255; cu++)
+                               for (cu = 1; cu <= 127; cu++)
                                    if (VIM_ISDIGIT(cu))
                                        regmbc(cu);
                                break;
                            case CLASS_GRAPH:
-                               for (cu = 1; cu <= 255; cu++)
+                               for (cu = 1; cu <= 127; cu++)
                                    if (isgraph(cu))
                                        regmbc(cu);
                                break;
@@ -3862,7 +3864,7 @@ bt_regexec_both(
            {
                if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0)
                    break;              /* Found it. */
-               mb_ptr_adv(s);
+               MB_PTR_ADV(s);
            }
 #endif
        else
@@ -3870,7 +3872,7 @@ bt_regexec_both(
            {
                if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0)
                    break;              /* Found it. */
-               mb_ptr_adv(s);
+               MB_PTR_ADV(s);
            }
        if (s == NULL)          /* Not present. */
            goto theend;
@@ -4148,7 +4150,7 @@ reg_match_visual(void)
 
     if (VIsual_active)
     {
-       if (lt(VIsual, wp->w_cursor))
+       if (LT_POS(VIsual, wp->w_cursor))
        {
            top = VIsual;
            bot = wp->w_cursor;
@@ -4162,7 +4164,7 @@ reg_match_visual(void)
     }
     else
     {
-       if (lt(curbuf->b_visual.vi_start, curbuf->b_visual.vi_end))
+       if (LT_POS(curbuf->b_visual.vi_start, curbuf->b_visual.vi_end))
        {
            top = curbuf->b_visual.vi_start;
            bot = curbuf->b_visual.vi_end;
@@ -4202,7 +4204,7 @@ reg_match_visual(void)
     return TRUE;
 }
 
-#define ADVANCE_REGINPUT() mb_ptr_adv(reginput)
+#define ADVANCE_REGINPUT() MB_PTR_ADV(reginput)
 
 /*
  * The arguments from BRACE_LIMITS are stored here.  They are actually local
@@ -4521,14 +4523,14 @@ regmatch(
            break;
 
          case WHITE:
-           if (!vim_iswhite(c))
+           if (!VIM_ISWHITE(c))
                status = RA_NOMATCH;
            else
                ADVANCE_REGINPUT();
            break;
 
          case NWHITE:
-           if (c == NUL || vim_iswhite(c))
+           if (c == NUL || VIM_ISWHITE(c))
                status = RA_NOMATCH;
            else
                ADVANCE_REGINPUT();
@@ -4730,7 +4732,7 @@ regmatch(
                    break;
                }
                if (enc_utf8)
-                   opndc = mb_ptr2char(opnd);
+                   opndc = utf_ptr2char(opnd);
                if (enc_utf8 && utf_iscomposing(opndc))
                {
                    /* When only a composing char is given match at any
@@ -4739,7 +4741,7 @@ regmatch(
                    for (i = 0; reginput[i] != NUL;
                                                i += utf_ptr2len(reginput + i))
                    {
-                       inpc = mb_ptr2char(reginput + i);
+                       inpc = utf_ptr2char(reginput + i);
                        if (!utf_iscomposing(inpc))
                        {
                            if (i > 0)
@@ -4748,7 +4750,7 @@ regmatch(
                        else if (opndc == inpc)
                        {
                            /* Include all following composing chars. */
-                           len = i + mb_ptr2len(reginput + i);
+                           len = i + utfc_ptr2len(reginput + i);
                            status = RA_MATCH;
                            break;
                        }
@@ -4773,7 +4775,7 @@ regmatch(
            {
                /* Skip composing characters. */
                while (utf_iscomposing(utf_ptr2char(reginput)))
-                   mb_cptr_adv(reginput);
+                   MB_CPTR_ADV(reginput);
            }
 #endif
            break;
@@ -5070,7 +5072,7 @@ regmatch(
                }
                else
                {
-                   EMSG(_(e_internal));            /* Shouldn't happen */
+                   internal_error("BRACE_LIMITS");
                    status = RA_FAIL;
                }
            }
@@ -5555,7 +5557,7 @@ regmatch(
                        no = FAIL;
                    else
                    {
-                       mb_ptr_back(regline, rp->rs_un.regsave.rs_u.ptr);
+                       MB_PTR_BACK(regline, rp->rs_un.regsave.rs_u.ptr);
                        if (limit > 0 && (long)(behind_pos.rs_u.ptr
                                     - rp->rs_un.regsave.rs_u.ptr) > limit)
                            no = FAIL;
@@ -5642,7 +5644,7 @@ regmatch(
                                fast_breakcheck();
                            }
                            else
-                               mb_ptr_back(regline, reginput);
+                               MB_PTR_BACK(regline, reginput);
                        }
                        else
                        {
@@ -5786,7 +5788,7 @@ regrepeat(
            while (*scan != NUL && count < maxcount)
            {
                ++count;
-               mb_ptr_adv(scan);
+               MB_PTR_ADV(scan);
            }
            if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline
                                      || rex.reg_line_lbr || count == maxcount)
@@ -5809,7 +5811,7 @@ regrepeat(
        {
            if (vim_isIDc(PTR2CHAR(scan)) && (testval || !VIM_ISDIGIT(*scan)))
            {
-               mb_ptr_adv(scan);
+               MB_PTR_ADV(scan);
            }
            else if (*scan == NUL)
            {
@@ -5840,7 +5842,7 @@ regrepeat(
            if (vim_iswordp_buf(scan, rex.reg_buf)
                                          && (testval || !VIM_ISDIGIT(*scan)))
            {
-               mb_ptr_adv(scan);
+               MB_PTR_ADV(scan);
            }
            else if (*scan == NUL)
            {
@@ -5870,7 +5872,7 @@ regrepeat(
        {
            if (vim_isfilec(PTR2CHAR(scan)) && (testval || !VIM_ISDIGIT(*scan)))
            {
-               mb_ptr_adv(scan);
+               MB_PTR_ADV(scan);
            }
            else if (*scan == NUL)
            {
@@ -5911,7 +5913,7 @@ regrepeat(
            else if (vim_isprintc(PTR2CHAR(scan)) == 1
                                          && (testval || !VIM_ISDIGIT(*scan)))
            {
-               mb_ptr_adv(scan);
+               MB_PTR_ADV(scan);
            }
            else if (rex.reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
                ++scan;
@@ -7544,7 +7546,7 @@ vim_regsub_both(
            {
                int had_backslash = FALSE;
 
-               for (s = eval_result; *s != NUL; mb_ptr_adv(s))
+               for (s = eval_result; *s != NUL; MB_PTR_ADV(s))
                {
                    /* Change NL to CR, so that it becomes a line break,
                     * unless called from vim_regexec_nl().
index fcca818..d6e81d7 100644 (file)
@@ -50,7 +50,7 @@ enum
     NFA_CONCAT,                            /* concatenate two previous items (postfix
                                     * only) */
     NFA_OR,                        /* \| (postfix only) */
-    NFA_STAR,                      /* greedy * (posfix only) */
+    NFA_STAR,                      /* greedy * (postfix only) */
     NFA_STAR_NONGREEDY,                    /* non-greedy * (postfix only) */
     NFA_QUEST,                     /* greedy \? (postfix only) */
     NFA_QUEST_NONGREEDY,           /* non-greedy \? (postfix only) */
@@ -1359,7 +1359,7 @@ nfa_regatom(void)
                    rc_did_emsg = TRUE;
                    return FAIL;
                }
-               EMSGN("INTERNAL: Unknown character class char: %ld", c);
+               IEMSGN("INTERNAL: Unknown character class char: %ld", c);
                return FAIL;
            }
 #ifdef FEAT_MBYTE
@@ -1425,7 +1425,7 @@ nfa_regatom(void)
                    EMSG(_(e_nopresub));
                    return FAIL;
                }
-               for (lp = reg_prev_sub; *lp != NUL; mb_cptr_adv(lp))
+               for (lp = reg_prev_sub; *lp != NUL; MB_CPTR_ADV(lp))
                {
                    EMIT(PTR2CHAR(lp));
                    if (lp != reg_prev_sub)
@@ -1672,7 +1672,7 @@ collection:
                    else
                        EMIT(result);
                    regparse = endp;
-                   mb_ptr_adv(regparse);
+                   MB_PTR_ADV(regparse);
                    return OK;
                }
                /*
@@ -1684,7 +1684,7 @@ collection:
                if (*regparse == '^')                   /* negated range */
                {
                    negated = TRUE;
-                   mb_ptr_adv(regparse);
+                   MB_PTR_ADV(regparse);
                    EMIT(NFA_START_NEG_COLL);
                }
                else
@@ -1694,7 +1694,7 @@ collection:
                    startc = '-';
                    EMIT(startc);
                    EMIT(NFA_CONCAT);
-                   mb_ptr_adv(regparse);
+                   MB_PTR_ADV(regparse);
                }
                /* Emit the OR branches for each character in the [] */
                emit_range = FALSE;
@@ -1797,7 +1797,7 @@ collection:
                    {
                        emit_range = TRUE;
                        startc = oldstartc;
-                       mb_ptr_adv(regparse);
+                       MB_PTR_ADV(regparse);
                        continue;           /* reading the end of the range */
                    }
 
@@ -1817,7 +1817,7 @@ collection:
                            )
                        )
                    {
-                       mb_ptr_adv(regparse);
+                       MB_PTR_ADV(regparse);
 
                        if (*regparse == 'n')
                            startc = reg_string ? NL : NFA_NEWL;
@@ -1832,7 +1832,7 @@ collection:
                                /* TODO(RE) This needs more testing */
                                startc = coll_get_char();
                                got_coll_char = TRUE;
-                               mb_ptr_back(old_regparse, regparse);
+                               MB_PTR_BACK(old_regparse, regparse);
                            }
                            else
                            {
@@ -1932,10 +1932,10 @@ collection:
                        }
                    }
 
-                   mb_ptr_adv(regparse);
+                   MB_PTR_ADV(regparse);
                } /* while (p < endp) */
 
-               mb_ptr_back(old_regparse, regparse);
+               MB_PTR_BACK(old_regparse, regparse);
                if (*regparse == '-')       /* if last, '-' is just a char */
                {
                    EMIT('-');
@@ -1944,7 +1944,7 @@ collection:
 
                /* skip the trailing ] */
                regparse = endp;
-               mb_ptr_adv(regparse);
+               MB_PTR_ADV(regparse);
 
                /* Mark end of the collection. */
                if (negated == TRUE)
@@ -1974,7 +1974,7 @@ collection:
 nfa_do_multibyte:
                /* plen is length of current char with composing chars */
                if (enc_utf8 && ((*mb_char2len)(c)
-                           != (plen = (*mb_ptr2len)(old_regparse))
+                           != (plen = utfc_ptr2len(old_regparse))
                                                       || utf_iscomposing(c)))
                {
                    int i = 0;
@@ -2169,7 +2169,7 @@ nfa_regpiece(void)
             * maximum is much larger than the minimum and when the maximum is
             * large.  Bail out if we can use the other engine. */
            if ((nfa_re_flags & RE_AUTO)
-                                  && (maxval > minval + 200 || maxval > 500))
+                                  && (maxval > 500 || maxval > minval + 200))
                return FAIL;
 
            /* Ignore previous call to nfa_regatom() */
@@ -4871,7 +4871,7 @@ check_char_class(int class, int c)
                return OK;
            break;
        case NFA_CLASS_CNTRL:
-           if (c >= 1 && c <= 255 && iscntrl(c))
+           if (c >= 1 && c <= 127 && iscntrl(c))
                return OK;
            break;
        case NFA_CLASS_DIGIT:
@@ -4879,7 +4879,7 @@ check_char_class(int class, int c)
                return OK;
            break;
        case NFA_CLASS_GRAPH:
-           if (c >= 1 && c <= 255 && isgraph(c))
+           if (c >= 1 && c <= 127 && isgraph(c))
                return OK;
            break;
        case NFA_CLASS_LOWER:
@@ -4925,7 +4925,7 @@ check_char_class(int class, int c)
 
        default:
            /* should not be here :P */
-           EMSGN(_(e_ill_char_class), class);
+           IEMSGN(_(e_ill_char_class), class);
            return FAIL;
     }
     return FAIL;
@@ -5799,6 +5799,9 @@ nfa_regmatch(
                }
 #ifdef ENABLE_LOG
                fprintf(log_fd, "Match found:\n");
+               /* TODO: this avoids a crash but is not right */
+               if (t->state->c == NFA_END_INVISIBLE_NEG)
+                   m->norm.in_use = 0;
                log_subsexpr(m);
 #endif
                nfa_match = TRUE;
@@ -6351,12 +6354,12 @@ nfa_regmatch(
                break;
 
            case NFA_WHITE:     /*  \s  */
-               result = vim_iswhite(curc);
+               result = VIM_ISWHITE(curc);
                ADD_STATE_IF_MATCH(t->state);
                break;
 
            case NFA_NWHITE:    /*  \S  */
-               result = curc != NUL && !vim_iswhite(curc);
+               result = curc != NUL && !VIM_ISWHITE(curc);
                ADD_STATE_IF_MATCH(t->state);
                break;
 
@@ -6688,7 +6691,7 @@ nfa_regmatch(
 
 #ifdef DEBUG
                if (c < 0)
-                   EMSGN("INTERNAL: Negative state char: %ld", c);
+                   IEMSGN("INTERNAL: Negative state char: %ld", c);
 #endif
                result = (c == curc);
 
@@ -7216,7 +7219,7 @@ nfa_regcomp(char_u *expr, int re_flags)
     {
        /* TODO: only give this error for debugging? */
        if (post_ptr >= post_end)
-           EMSGN("Internal error: estimated max number of states insufficient: %ld", post_end - post_start);
+           IEMSGN("Internal error: estimated max number of states insufficient: %ld", post_end - post_start);
        goto fail;          /* Cascaded (syntax?) error */
     }
 
index 621f25c..fbfded1 100644 (file)
@@ -777,6 +777,57 @@ update_screen(int type)
 #endif
 }
 
+#if defined(FEAT_SIGNS) || defined(FEAT_GUI) || defined(FEAT_CONCEAL)
+/*
+ * Prepare for updating one or more windows.
+ * Caller must check for "updating_screen" already set to avoid recursiveness.
+ */
+    static void
+update_prepare(void)
+{
+    cursor_off();
+    updating_screen = TRUE;
+#ifdef FEAT_GUI
+    /* Remove the cursor before starting to do anything, because scrolling may
+     * make it difficult to redraw the text under it. */
+    if (gui.in_use)
+       gui_undraw_cursor();
+#endif
+#ifdef FEAT_SEARCH_EXTRA
+    start_search_hl();
+#endif
+}
+
+/*
+ * Finish updating one or more windows.
+ */
+    static void
+update_finish(void)
+{
+    if (redraw_cmdline)
+       showmode();
+
+# ifdef FEAT_SEARCH_EXTRA
+    end_search_hl();
+# endif
+
+    updating_screen = FALSE;
+
+# ifdef FEAT_GUI
+    gui_may_resize_shell();
+
+    /* Redraw the cursor and update the scrollbars when all screen updating is
+     * done. */
+    if (gui.in_use)
+    {
+       out_flush();    /* required before updating the cursor */
+       gui_update_cursor(FALSE, FALSE);
+       gui_update_scrollbars(FALSE);
+    }
+# endif
+}
+#endif
+
 #if defined(FEAT_CONCEAL) || defined(PROTO)
 /*
  * Return TRUE if the cursor line in window "wp" may be concealed, according
@@ -824,18 +875,14 @@ update_single_line(win_T *wp, linenr_T lnum)
     int                j;
 
     /* Don't do anything if the screen structures are (not yet) valid. */
-    if (!screen_valid(TRUE))
+    if (!screen_valid(TRUE) || updating_screen)
        return;
 
     if (lnum >= wp->w_topline && lnum < wp->w_botline
                                 && foldedCount(wp, lnum, &win_foldinfo) == 0)
     {
-# ifdef FEAT_GUI
-       /* Remove the cursor before starting to do anything, because scrolling
-        * may make it difficult to redraw the text under it. */
-       if (gui.in_use)
-           gui_undraw_cursor();
-# endif
+       update_prepare();
+
        row = 0;
        for (j = 0; j < wp->w_lines_valid; ++j)
        {
@@ -855,70 +902,10 @@ update_single_line(win_T *wp, linenr_T lnum)
            }
            row += wp->w_lines[j].wl_size;
        }
-# ifdef FEAT_GUI
-       /* Redraw the cursor */
-       if (gui.in_use)
-       {
-           out_flush();        /* required before updating the cursor */
-           gui_update_cursor(FALSE, FALSE);
-       }
-# endif
-    }
-    need_cursor_line_redraw = FALSE;
-}
-#endif
-
-#if defined(FEAT_SIGNS) || defined(FEAT_GUI)
-static void update_prepare(void);
-static void update_finish(void);
-
-/*
- * Prepare for updating one or more windows.
- * Caller must check for "updating_screen" already set to avoid recursiveness.
- */
-    static void
-update_prepare(void)
-{
-    cursor_off();
-    updating_screen = TRUE;
-#ifdef FEAT_GUI
-    /* Remove the cursor before starting to do anything, because scrolling may
-     * make it difficult to redraw the text under it. */
-    if (gui.in_use)
-       gui_undraw_cursor();
-#endif
-#ifdef FEAT_SEARCH_EXTRA
-    start_search_hl();
-#endif
-}
 
-/*
- * Finish updating one or more windows.
- */
-    static void
-update_finish(void)
-{
-    if (redraw_cmdline)
-       showmode();
-
-# ifdef FEAT_SEARCH_EXTRA
-    end_search_hl();
-# endif
-
-    updating_screen = FALSE;
-
-# ifdef FEAT_GUI
-    gui_may_resize_shell();
-
-    /* Redraw the cursor and update the scrollbars when all screen updating is
-     * done. */
-    if (gui.in_use)
-    {
-       out_flush();    /* required before updating the cursor */
-       gui_update_cursor(FALSE, FALSE);
-       gui_update_scrollbars(FALSE);
+       update_finish();
     }
-# endif
+    need_cursor_line_redraw = FALSE;
 }
 #endif
 
@@ -2152,10 +2139,10 @@ win_update(win_T *wp)
             * Last line isn't finished: Display "@@@" in the last screen line.
             */
            screen_puts_len((char_u *)"@@", 2, scr_row, W_WINCOL(wp),
-                                                             hl_attr(HLF_AT));
+                                                             HL_ATTR(HLF_AT));
            screen_fill(scr_row, scr_row + 1,
                    (int)W_WINCOL(wp) + 2, (int)W_ENDCOL(wp),
-                   '@', ' ', hl_attr(HLF_AT));
+                   '@', ' ', HL_ATTR(HLF_AT));
            set_empty_rows(wp, srow);
            wp->w_botline = lnum;
        }
@@ -2167,7 +2154,7 @@ win_update(win_T *wp)
            screen_fill(W_WINROW(wp) + wp->w_height - 1,
                    W_WINROW(wp) + wp->w_height,
                    (int)W_ENDCOL(wp) - 3, (int)W_ENDCOL(wp),
-                   '@', '@', hl_attr(HLF_AT));
+                   '@', '@', HL_ATTR(HLF_AT));
            set_empty_rows(wp, srow);
            wp->w_botline = lnum;
        }
@@ -2295,7 +2282,7 @@ win_draw_end(
                n = W_WIDTH(wp);
            screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
                    W_ENDCOL(wp) - n, (int)W_ENDCOL(wp),
-                   ' ', ' ', hl_attr(HLF_FC));
+                   ' ', ' ', HL_ATTR(HLF_FC));
        }
 # endif
 # ifdef FEAT_SIGNS
@@ -2308,16 +2295,16 @@ win_draw_end(
                nn = W_WIDTH(wp);
            screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
                    W_ENDCOL(wp) - nn, (int)W_ENDCOL(wp) - n,
-                   ' ', ' ', hl_attr(HLF_SC));
+                   ' ', ' ', HL_ATTR(HLF_SC));
            n = nn;
        }
 # endif
        screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
                W_WINCOL(wp), W_ENDCOL(wp) - 1 - FDC_OFF,
-               c2, c2, hl_attr(hl));
+               c2, c2, HL_ATTR(hl));
        screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
                W_ENDCOL(wp) - 1 - FDC_OFF, W_ENDCOL(wp) - FDC_OFF,
-               c1, c2, hl_attr(hl));
+               c1, c2, HL_ATTR(hl));
     }
     else
 #endif
@@ -2331,7 +2318,7 @@ win_draw_end(
                n = wp->w_width;
            screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
                    W_WINCOL(wp), (int)W_WINCOL(wp) + n,
-                   cmdwin_type, ' ', hl_attr(HLF_AT));
+                   cmdwin_type, ' ', HL_ATTR(HLF_AT));
        }
 #endif
 #ifdef FEAT_FOLDING
@@ -2344,7 +2331,7 @@ win_draw_end(
                nn = W_WIDTH(wp);
            screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
                    W_WINCOL(wp) + n, (int)W_WINCOL(wp) + nn,
-                   ' ', ' ', hl_attr(HLF_FC));
+                   ' ', ' ', HL_ATTR(HLF_FC));
            n = nn;
        }
 #endif
@@ -2358,13 +2345,13 @@ win_draw_end(
                nn = W_WIDTH(wp);
            screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
                    W_WINCOL(wp) + n, (int)W_WINCOL(wp) + nn,
-                   ' ', ' ', hl_attr(HLF_SC));
+                   ' ', ' ', HL_ATTR(HLF_SC));
            n = nn;
        }
 #endif
        screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
                W_WINCOL(wp) + FDC_OFF, (int)W_ENDCOL(wp),
-               c1, c2, hl_attr(hl));
+               c1, c2, HL_ATTR(hl));
     }
     set_empty_rows(wp, row);
 }
@@ -2441,7 +2428,7 @@ fold_line(
     if (cmdwin_type != 0 && wp == curwin)
     {
        ScreenLines[off] = cmdwin_type;
-       ScreenAttrs[off] = hl_attr(HLF_AT);
+       ScreenAttrs[off] = HL_ATTR(HLF_AT);
 #ifdef FEAT_MBYTE
        if (enc_utf8)
            ScreenLinesUC[off] = 0;
@@ -2464,14 +2451,14 @@ fold_line(
            int         i;
 
            copy_text_attr(off + W_WIDTH(wp) - fdc - col, buf, fdc,
-                                                            hl_attr(HLF_FC));
+                                                            HL_ATTR(HLF_FC));
            /* reverse the fold column */
            for (i = 0; i < fdc; ++i)
                ScreenLines[off + W_WIDTH(wp) - i - 1 - col] = buf[i];
        }
        else
 #endif
-           copy_text_attr(off + col, buf, fdc, hl_attr(HLF_FC));
+           copy_text_attr(off + col, buf, fdc, HL_ATTR(HLF_FC));
        col += fdc;
     }
 
@@ -2489,7 +2476,7 @@ fold_line(
 
     /* Set all attributes of the 'number' or 'relativenumber' column and the
      * text */
-    RL_MEMSET(col, hl_attr(HLF_FL), W_WIDTH(wp) - col);
+    RL_MEMSET(col, HL_ATTR(HLF_FL), W_WIDTH(wp) - col);
 
 #ifdef FEAT_SIGNS
     /* If signs are being displayed, add two spaces. */
@@ -2504,10 +2491,10 @@ fold_line(
            if (wp->w_p_rl)
                /* the line number isn't reversed */
                copy_text_attr(off + W_WIDTH(wp) - len - col,
-                                       (char_u *)"  ", len, hl_attr(HLF_FL));
+                                       (char_u *)"  ", len, HL_ATTR(HLF_FL));
            else
 # endif
-               copy_text_attr(off + col, (char_u *)"  ", len, hl_attr(HLF_FL));
+               copy_text_attr(off + col, (char_u *)"  ", len, HL_ATTR(HLF_FL));
            col += len;
        }
     }
@@ -2549,10 +2536,10 @@ fold_line(
            if (wp->w_p_rl)
                /* the line number isn't reversed */
                copy_text_attr(off + W_WIDTH(wp) - len - col, buf, len,
-                                                            hl_attr(HLF_FL));
+                                                            HL_ATTR(HLF_FL));
            else
 #endif
-               copy_text_attr(off + col, buf, len, hl_attr(HLF_FL));
+               copy_text_attr(off + col, buf, len, HL_ATTR(HLF_FL));
            col += len;
        }
     }
@@ -2710,12 +2697,18 @@ fold_line(
            {
                ScreenLinesUC[off + col] = fill_fold;
                ScreenLinesC[0][off + col] = 0;
+                ScreenLines[off + col] = 0x80; /* avoid storing zero */
            }
            else
+           {
                ScreenLinesUC[off + col] = 0;
+               ScreenLines[off + col] = fill_fold;
+           }
+           col++;
        }
+       else
 #endif
-       ScreenLines[off + col++] = fill_fold;
+           ScreenLines[off + col++] = fill_fold;
     }
 
     if (text != buf)
@@ -2727,7 +2720,7 @@ fold_line(
      */
     if (VIsual_active && wp->w_buffer == curwin->w_buffer)
     {
-       if (ltoreq(curwin->w_cursor, VIsual))
+       if (LTOREQ_POS(curwin->w_cursor, VIsual))
        {
            /* Visual is after curwin->w_cursor */
            top = &curwin->w_cursor;
@@ -2761,14 +2754,14 @@ fold_line(
                        len = wp->w_old_cursor_lcol;
                    else
                        len = W_WIDTH(wp) - txtcol;
-                   RL_MEMSET(wp->w_old_cursor_fcol + txtcol, hl_attr(HLF_V),
+                   RL_MEMSET(wp->w_old_cursor_fcol + txtcol, HL_ATTR(HLF_V),
                                            len - (int)wp->w_old_cursor_fcol);
                }
            }
            else
            {
                /* Set all attributes of the text */
-               RL_MEMSET(txtcol, hl_attr(HLF_V), W_WIDTH(wp) - txtcol);
+               RL_MEMSET(txtcol, HL_ATTR(HLF_V), W_WIDTH(wp) - txtcol);
            }
        }
     }
@@ -2790,7 +2783,7 @@ fold_line(
                txtcol -= wp->w_leftcol;
            if (txtcol >= 0 && txtcol < W_WIDTH(wp))
                ScreenAttrs[off + txtcol] = hl_combine_attr(
-                                   ScreenAttrs[off + txtcol], hl_attr(HLF_MC));
+                                   ScreenAttrs[off + txtcol], HL_ATTR(HLF_MC));
            txtcol = old_txtcol;
            j = wp->w_p_cc_cols[++i];
        }
@@ -2806,7 +2799,7 @@ fold_line(
            txtcol -= wp->w_leftcol;
        if (txtcol >= 0 && txtcol < W_WIDTH(wp))
            ScreenAttrs[off + txtcol] = hl_combine_attr(
-                                ScreenAttrs[off + txtcol], hl_attr(HLF_CUC));
+                                ScreenAttrs[off + txtcol], HL_ATTR(HLF_CUC));
     }
 #endif
 
@@ -2916,7 +2909,7 @@ win_line(
     int                endrow,
     int                nochange UNUSED)        /* not updating for changed text */
 {
-    int                col;                    /* visual column on screen */
+    int                col = 0;                /* visual column on screen */
     unsigned   off;                    /* offset in ScreenLines/ScreenAttrs */
     int                c = 0;                  /* init for GCC */
     long       vcol = 0;               /* virtual column (for tabs) */
@@ -3010,7 +3003,8 @@ win_line(
 #endif
     colnr_T    trailcol = MAXCOL;      /* start of trailing spaces */
 #ifdef FEAT_LINEBREAK
-    int                need_showbreak = FALSE;
+    int                need_showbreak = FALSE; /* overlong line, skipping first x
+                                          chars */
 #endif
 #if defined(FEAT_SIGNS) || (defined(FEAT_QUICKFIX) && defined(FEAT_WINDOWS)) \
        || defined(FEAT_SYN_HL) || defined(FEAT_DIFF)
@@ -3075,7 +3069,7 @@ win_line(
     int                syntax_flags    = 0;
     int                syntax_seqnr    = 0;
     int                prev_syntax_id  = 0;
-    int                conceal_attr    = hl_attr(HLF_CONCEAL);
+    int                conceal_attr    = HL_ATTR(HLF_CONCEAL);
     int                is_concealing   = FALSE;
     int                boguscols       = 0;    /* nonexistent columns added to force
                                           wrapping */
@@ -3182,7 +3176,7 @@ win_line(
     if (VIsual_active && wp->w_buffer == curwin->w_buffer)
     {
                                        /* Visual is after curwin->w_cursor */
-       if (ltoreq(curwin->w_cursor, VIsual))
+       if (LTOREQ_POS(curwin->w_cursor, VIsual))
        {
            top = &curwin->w_cursor;
            bot = &VIsual;
@@ -3255,13 +3249,13 @@ win_line(
        if (fromcol >= 0)
        {
            area_highlighting = TRUE;
-           attr = hl_attr(HLF_V);
+           attr = HL_ATTR(HLF_V);
 #if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
            if ((clip_star.available && !clip_star.owned
                                                     && clip_isautosel_star())
                    || (clip_plus.available && !clip_plus.owned
                                                    && clip_isautosel_plus()))
-               attr = hl_attr(HLF_VNC);
+               attr = HL_ATTR(HLF_VNC);
 #endif
        }
     }
@@ -3291,7 +3285,7 @@ win_line(
        if (fromcol == tocol)
            tocol = fromcol + 1;
        area_highlighting = TRUE;
-       attr = hl_attr(HLF_I);
+       attr = HL_ATTR(HLF_I);
     }
 
 #ifdef FEAT_DIFF
@@ -3327,7 +3321,7 @@ win_line(
 # if defined(FEAT_QUICKFIX) && defined(FEAT_WINDOWS)
     /* Highlight the current line in the quickfix window. */
     if (bt_quickfix(wp->w_buffer) && qf_current_entry(wp) == lnum)
-       line_attr = hl_attr(HLF_L);
+       line_attr = HL_ATTR(HLF_L);
 # endif
     if (line_attr != 0)
        area_highlighting = TRUE;
@@ -3383,7 +3377,7 @@ win_line(
        if (lcs_trail)
        {
            trailcol = (colnr_T)STRLEN(ptr);
-           while (trailcol > (colnr_T)0 && vim_iswhite(ptr[trailcol - 1]))
+           while (trailcol > (colnr_T)0 && VIM_ISWHITE(ptr[trailcol - 1]))
                --trailcol;
            trailcol += (colnr_T) (ptr - line);
        }
@@ -3409,7 +3403,7 @@ win_line(
 #ifdef FEAT_MBYTE
            prev_ptr = ptr;
 #endif
-           mb_ptr_adv(ptr);
+           MB_PTR_ADV(ptr);
        }
 
        /* When:
@@ -3441,7 +3435,14 @@ win_line(
 #else
            --ptr;
 #endif
-           n_skip = v - vcol;
+           /* If the character fits on the screen, don't need to skip it.
+            * Except for a TAB. */
+           if ((
+#ifdef FEAT_MBYTE
+                       (*mb_ptr2cells)(ptr) >= c ||
+#endif
+                      *ptr == TAB) && col == 0)
+              n_skip = v - vcol;
        }
 
        /*
@@ -3597,7 +3598,7 @@ win_line(
     if (wp->w_p_cul && lnum == wp->w_cursor.lnum
                                         && !(wp == curwin && VIsual_active))
     {
-       line_attr = hl_attr(HLF_CUL);
+       line_attr = HL_ATTR(HLF_CUL);
        area_highlighting = TRUE;
     }
 #endif
@@ -3635,7 +3636,7 @@ win_line(
                    /* Draw the cmdline character. */
                    n_extra = 1;
                    c_extra = cmdwin_type;
-                   char_attr = hl_attr(HLF_AT);
+                   char_attr = HL_ATTR(HLF_AT);
                }
            }
 #endif
@@ -3648,13 +3649,20 @@ win_line(
                draw_state = WL_FOLD;
                if (fdc > 0)
                {
-                   /* Draw the 'foldcolumn'. */
-                   fill_foldcolumn(extra, wp, FALSE, lnum);
-                   n_extra = fdc;
-                   p_extra = extra;
-                   p_extra[n_extra] = NUL;
-                   c_extra = NUL;
-                   char_attr = hl_attr(HLF_FC);
+                   /* Draw the 'foldcolumn'.  Allocate a buffer, "extra" may
+                    * already be in use. */
+                   vim_free(p_extra_free);
+                   p_extra_free = alloc(12 + 1);
+
+                   if (p_extra_free != NULL)
+                   {
+                       fill_foldcolumn(p_extra_free, wp, FALSE, lnum);
+                       n_extra = fdc;
+                       p_extra_free[n_extra] = NUL;
+                       p_extra = p_extra_free;
+                       c_extra = NUL;
+                       char_attr = HL_ATTR(HLF_FC);
+                   }
                }
            }
 #endif
@@ -3674,7 +3682,7 @@ win_line(
 
                    /* Draw two cells with the sign value or blank. */
                    c_extra = ' ';
-                   char_attr = hl_attr(HLF_SC);
+                   char_attr = HL_ATTR(HLF_SC);
                    n_extra = 2;
 
                    if (row == startrow
@@ -3767,7 +3775,7 @@ win_line(
                    else
                        c_extra = ' ';
                    n_extra = number_width(wp) + 1;
-                   char_attr = hl_attr(HLF_N);
+                   char_attr = HL_ATTR(HLF_N);
 #ifdef FEAT_SYN_HL
                    /* When 'cursorline' is set highlight the line number of
                     * the current line differently.
@@ -3775,7 +3783,7 @@ win_line(
                     * when CursorLineNr isn't set? */
                    if ((wp->w_p_cul || wp->w_p_rnu)
                                                 && lnum == wp->w_cursor.lnum)
-                       char_attr = hl_attr(HLF_CLN);
+                       char_attr = HL_ATTR(HLF_CLN);
 #endif
                }
            }
@@ -3793,21 +3801,23 @@ win_line(
            if (draw_state == WL_BRI - 1 && n_extra == 0)
            {
                draw_state = WL_BRI;
-               if (wp->w_p_bri && n_extra == 0 && row != startrow
+               /* if need_showbreak is set, breakindent also applies */
+               if (wp->w_p_bri && n_extra == 0
+                                        && (row != startrow || need_showbreak)
 # ifdef FEAT_DIFF
                        && filler_lines == 0
 # endif
                   )
                {
-                   char_attr = 0; /* was: hl_attr(HLF_AT); */
+                   char_attr = 0;
 # ifdef FEAT_DIFF
                    if (diff_hlf != (hlf_T)0)
                    {
-                       char_attr = hl_attr(diff_hlf);
+                       char_attr = HL_ATTR(diff_hlf);
 #  ifdef FEAT_SYN_HL
                        if (wp->w_p_cul && lnum == wp->w_cursor.lnum)
                            char_attr = hl_combine_attr(char_attr,
-                                                           hl_attr(HLF_CUL));
+                                                           HL_ATTR(HLF_CUL));
 #  endif
                    }
 # endif
@@ -3841,7 +3851,7 @@ win_line(
                    else
 #  endif
                        n_extra = W_WIDTH(wp) - col;
-                   char_attr = hl_attr(HLF_DED);
+                   char_attr = HL_ATTR(HLF_DED);
                }
 # endif
 # ifdef FEAT_LINEBREAK
@@ -3851,7 +3861,7 @@ win_line(
                    p_extra = p_sbr;
                    c_extra = NUL;
                    n_extra = (int)STRLEN(p_sbr);
-                   char_attr = hl_attr(HLF_AT);
+                   char_attr = HL_ATTR(HLF_AT);
                    need_showbreak = FALSE;
                    vcol_sbr = vcol + MB_CHARLEN(p_sbr);
                    /* Correct end of highlighted area for 'showbreak',
@@ -3862,7 +3872,7 @@ win_line(
                    /* combine 'showbreak' with 'cursorline' */
                    if (wp->w_p_cul && lnum == wp->w_cursor.lnum)
                        char_attr = hl_combine_attr(char_attr,
-                                                           hl_attr(HLF_CUL));
+                                                           HL_ATTR(HLF_CUL));
 #endif
                }
 # endif
@@ -4057,9 +4067,9 @@ win_line(
                if (diff_hlf == HLF_TXD && ptr - line > change_end
                                                              && n_extra == 0)
                    diff_hlf = HLF_CHD;         /* changed line */
-               line_attr = hl_attr(diff_hlf);
+               line_attr = HL_ATTR(diff_hlf);
                if (wp->w_p_cul && lnum == wp->w_cursor.lnum)
-                   line_attr = hl_combine_attr(line_attr, hl_attr(HLF_CUL));
+                   line_attr = hl_combine_attr(line_attr, HL_ATTR(HLF_CUL));
            }
 #endif
 
@@ -4112,7 +4122,7 @@ win_line(
                c = c_extra;
 #ifdef FEAT_MBYTE
                mb_c = c;       /* doesn't handle non-utf-8 multi-byte! */
-               if (enc_utf8 && (*mb_char2len)(c) > 1)
+               if (enc_utf8 && utf_char2len(c) > 1)
                {
                    mb_utf8 = TRUE;
                    u8cc[0] = 0;
@@ -4133,7 +4143,7 @@ win_line(
                    {
                        /* If the UTF-8 character is more than one byte:
                         * Decode it into "mb_c". */
-                       mb_l = (*mb_ptr2len)(p_extra);
+                       mb_l = utfc_ptr2len(p_extra);
                        mb_utf8 = FALSE;
                        if (mb_l > n_extra)
                            mb_l = 1;
@@ -4169,7 +4179,7 @@ win_line(
                        mb_c = c;
                        mb_l = 1;
                        mb_utf8 = FALSE;
-                       multi_attr = hl_attr(HLF_AT);
+                       multi_attr = HL_ATTR(HLF_AT);
                        /* put the pointer back to output the double-width
                         * character at the start of the next line. */
                        ++n_extra;
@@ -4188,6 +4198,10 @@ win_line(
        }
        else
        {
+#ifdef FEAT_LINEBREAK
+           int c0;
+#endif
+
            if (p_extra_free != NULL)
            {
                vim_free(p_extra_free);
@@ -4197,6 +4211,9 @@ win_line(
             * Get a character from the line itself.
             */
            c = *ptr;
+#ifdef FEAT_LINEBREAK
+           c0 = *ptr;
+#endif
 #ifdef FEAT_MBYTE
            if (has_mbyte)
            {
@@ -4205,7 +4222,7 @@ win_line(
                {
                    /* If the UTF-8 character is more than one byte: Decode it
                     * into "mb_c". */
-                   mb_l = (*mb_ptr2len)(ptr);
+                   mb_l = utfc_ptr2len(ptr);
                    mb_utf8 = FALSE;
                    if (mb_l > 1)
                    {
@@ -4213,7 +4230,12 @@ win_line(
                        /* Overlong encoded ASCII or ASCII with composing char
                         * is displayed normally, except a NUL. */
                        if (mb_c < 0x80)
+                       {
                            c = mb_c;
+# ifdef FEAT_LINEBREAK
+                           c0 = mb_c;
+# endif
+                       }
                        mb_utf8 = TRUE;
 
                        /* At start of the line we can have a composing char.
@@ -4268,7 +4290,7 @@ win_line(
                        if (area_attr == 0 && search_attr == 0)
                        {
                            n_attr = n_extra + 1;
-                           extra_attr = hl_attr(HLF_8);
+                           extra_attr = HL_ATTR(HLF_8);
                            saved_attr2 = char_attr; /* save current attr */
                        }
                    }
@@ -4337,7 +4359,7 @@ win_line(
                            if (area_attr == 0 && search_attr == 0)
                            {
                                n_attr = n_extra + 1;
-                               extra_attr = hl_attr(HLF_8);
+                               extra_attr = HL_ATTR(HLF_8);
                                saved_attr2 = char_attr; /* save current attr */
                            }
                            mb_c = c;
@@ -4358,7 +4380,7 @@ win_line(
                    mb_c = c;
                    mb_utf8 = FALSE;
                    mb_l = 1;
-                   multi_attr = hl_attr(HLF_AT);
+                   multi_attr = HL_ATTR(HLF_AT);
                    /* Put pointer back so that the character will be
                     * displayed at the start of the next line. */
                    --ptr;
@@ -4377,7 +4399,7 @@ win_line(
                    if (area_attr == 0 && search_attr == 0)
                    {
                        n_attr = n_extra + 1;
-                       extra_attr = hl_attr(HLF_AT);
+                       extra_attr = HL_ATTR(HLF_AT);
                        saved_attr2 = char_attr; /* save current attr */
                    }
                    mb_c = c;
@@ -4537,7 +4559,8 @@ win_line(
                /*
                 * Found last space before word: check for line break.
                 */
-               if (wp->w_p_lbr && vim_isbreak(c) && !vim_isbreak(*ptr))
+               if (wp->w_p_lbr && c0 == c
+                                 && VIM_ISBREAK(c) && !VIM_ISBREAK((int)*ptr))
                {
 # ifdef FEAT_MBYTE
                    int mb_off = has_mbyte ? (*mb_head_off)(line, ptr - 1) : 0;
@@ -4560,7 +4583,7 @@ win_line(
 # else
                    c_extra = ' ';
 # endif
-                   if (vim_iswhite(c))
+                   if (VIM_ISWHITE(c))
                    {
 #ifdef FEAT_CONCEAL
                        if (c == TAB)
@@ -4587,12 +4610,12 @@ win_line(
                    if (area_attr == 0 && search_attr == 0)
                    {
                        n_attr = 1;
-                       extra_attr = hl_attr(HLF_8);
+                       extra_attr = HL_ATTR(HLF_8);
                        saved_attr2 = char_attr; /* save current attr */
                    }
 #ifdef FEAT_MBYTE
                    mb_c = c;
-                   if (enc_utf8 && (*mb_char2len)(c) > 1)
+                   if (enc_utf8 && utf_char2len(c) > 1)
                    {
                        mb_utf8 = TRUE;
                        u8cc[0] = 0;
@@ -4609,12 +4632,12 @@ win_line(
                    if (!attr_pri)
                    {
                        n_attr = 1;
-                       extra_attr = hl_attr(HLF_8);
+                       extra_attr = HL_ATTR(HLF_8);
                        saved_attr2 = char_attr; /* save current attr */
                    }
 #ifdef FEAT_MBYTE
                    mb_c = c;
-                   if (enc_utf8 && (*mb_char2len)(c) > 1)
+                   if (enc_utf8 && utf_char2len(c) > 1)
                    {
                        mb_utf8 = TRUE;
                        u8cc[0] = 0;
@@ -4686,6 +4709,7 @@ win_line(
                        p = alloc((unsigned)(len + 1));
                        vim_memset(p, ' ', len);
                        p[len] = NUL;
+                       vim_free(p_extra_free);
                        p_extra_free = p;
                        for (i = 0; i < tab_len; i++)
                        {
@@ -4740,11 +4764,11 @@ win_line(
 #endif
                            c_extra = lcs_tab2;
                        n_attr = tab_len + 1;
-                       extra_attr = hl_attr(HLF_8);
+                       extra_attr = HL_ATTR(HLF_8);
                        saved_attr2 = char_attr; /* save current attr */
 #ifdef FEAT_MBYTE
                        mb_c = c;
-                       if (enc_utf8 && (*mb_char2len)(c) > 1)
+                       if (enc_utf8 && utf_char2len(c) > 1)
                        {
                            mb_utf8 = TRUE;
                            u8cc[0] = 0;
@@ -4813,12 +4837,12 @@ win_line(
                    --ptr;          /* put it back at the NUL */
                    if (!attr_pri)
                    {
-                       extra_attr = hl_attr(HLF_AT);
+                       extra_attr = HL_ATTR(HLF_AT);
                        n_attr = 1;
                    }
 #ifdef FEAT_MBYTE
                    mb_c = c;
-                   if (enc_utf8 && (*mb_char2len)(c) > 1)
+                   if (enc_utf8 && utf_char2len(c) > 1)
                    {
                        mb_utf8 = TRUE;
                        u8cc[0] = 0;
@@ -4848,6 +4872,7 @@ win_line(
                        vim_memset(p, ' ', n_extra);
                        STRNCPY(p, p_extra + 1, STRLEN(p_extra) - 1);
                        p[n_extra] = NUL;
+                       vim_free(p_extra_free);
                        p_extra_free = p_extra = p;
                    }
                    else
@@ -4859,7 +4884,7 @@ win_line(
                    if (!attr_pri)
                    {
                        n_attr = n_extra + 1;
-                       extra_attr = hl_attr(HLF_8);
+                       extra_attr = HL_ATTR(HLF_8);
                        saved_attr2 = char_attr; /* save current attr */
                    }
 #ifdef FEAT_MBYTE
@@ -4915,10 +4940,10 @@ win_line(
                        diff_hlf = HLF_CHD;
                        if (attr == 0 || char_attr != attr)
                        {
-                           char_attr = hl_attr(diff_hlf);
+                           char_attr = HL_ATTR(diff_hlf);
                            if (wp->w_p_cul && lnum == wp->w_cursor.lnum)
                                char_attr = hl_combine_attr(char_attr,
-                                                           hl_attr(HLF_CUL));
+                                                           HL_ATTR(HLF_CUL));
                        }
                    }
 # endif
@@ -4981,7 +5006,7 @@ win_line(
                }
 # ifdef FEAT_MBYTE
                mb_c = c;
-               if (enc_utf8 && (*mb_char2len)(c) > 1)
+               if (enc_utf8 && utf_char2len(c) > 1)
                {
                    mb_utf8 = TRUE;
                    u8cc[0] = 0;
@@ -5085,10 +5110,10 @@ win_line(
                c_extra = MB_FILLER_CHAR;
                n_extra = 1;
                n_attr = 2;
-               extra_attr = hl_attr(HLF_AT);
+               extra_attr = HL_ATTR(HLF_AT);
            }
            mb_c = c;
-           if (enc_utf8 && (*mb_char2len)(c) > 1)
+           if (enc_utf8 && utf_char2len(c) > 1)
            {
                mb_utf8 = TRUE;
                u8cc[0] = 0;
@@ -5100,7 +5125,7 @@ win_line(
            if (!attr_pri)
            {
                saved_attr3 = char_attr; /* save current attr */
-               char_attr = hl_attr(HLF_AT); /* later copied to char_attr */
+               char_attr = HL_ATTR(HLF_AT); /* later copied to char_attr */
                n_attr3 = 1;
            }
        }
@@ -5307,9 +5332,9 @@ win_line(
                                                                 &color_cols);
 
                    if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol)
-                       ScreenAttrs[off++] = hl_attr(HLF_CUC);
+                       ScreenAttrs[off++] = HL_ATTR(HLF_CUC);
                    else if (draw_color_col && VCOL_HLC == *color_cols)
-                       ScreenAttrs[off++] = hl_attr(HLF_MC);
+                       ScreenAttrs[off++] = HL_ATTR(HLF_MC);
                    else
                        ScreenAttrs[off++] = 0;
 
@@ -5358,10 +5383,10 @@ win_line(
                    || (n_extra && (c_extra != NUL || *p_extra != NUL))))
        {
            c = lcs_ext;
-           char_attr = hl_attr(HLF_AT);
+           char_attr = HL_ATTR(HLF_AT);
 #ifdef FEAT_MBYTE
            mb_c = c;
-           if (enc_utf8 && (*mb_char2len)(c) > 1)
+           if (enc_utf8 && utf_char2len(c) > 1)
            {
                mb_utf8 = TRUE;
                u8cc[0] = 0;
@@ -5388,12 +5413,12 @@ win_line(
                                                 && lnum != wp->w_cursor.lnum)
            {
                vcol_save_attr = char_attr;
-               char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUC));
+               char_attr = hl_combine_attr(char_attr, HL_ATTR(HLF_CUC));
            }
            else if (draw_color_col && VCOL_HLC == *color_cols)
            {
                vcol_save_attr = char_attr;
-               char_attr = hl_combine_attr(char_attr, hl_attr(HLF_MC));
+               char_attr = hl_combine_attr(char_attr, HL_ATTR(HLF_MC));
            }
        }
 #endif
@@ -5775,6 +5800,7 @@ win_line(
     }
 #endif
 
+    vim_free(p_extra_free);
     return row;
 }
 
@@ -6388,7 +6414,7 @@ status_match_len(expand_T *xp, char_u *s)
     {
        s += skip_status_match_char(xp, s);
        len += ptr2cells(s);
-       mb_ptr_adv(s);
+       MB_PTR_ADV(s);
     }
 
     return len;
@@ -6629,7 +6655,7 @@ win_redr_status_matches(
        if (selstart != NULL && highlight)
        {
            *selend = NUL;
-           screen_puts(selstart, row, selstart_col, hl_attr(HLF_WM));
+           screen_puts(selstart, row, selstart_col, HL_ATTR(HLF_WM));
        }
 
        screen_fill(row, row + 1, clen, (int)Columns, fillchar, fillchar, attr);
@@ -6726,7 +6752,7 @@ win_redr_status(win_T *wp)
        if (wp->w_buffer->b_p_ro)
        {
            STRCPY(p + len, _("[RO]"));
-           len += 4;
+           len += (int)STRLEN(p + len);
        }
 
        this_ru_col = ru_col - (Columns - W_WIDTH(wp));
@@ -6955,7 +6981,7 @@ win_redr_custom(
        stl = p_tal;
        row = 0;
        fillchar = ' ';
-       attr = hl_attr(HLF_TPF);
+       attr = HL_ATTR(HLF_TPF);
        maxwidth = Columns;
 # ifdef FEAT_EVAL
        use_sandbox = was_set_insecurely((char_u *)"tabline", 0);
@@ -7302,7 +7328,7 @@ screen_puts_len(
                {
                    u8c = (mbyte_cells == 2) ? 0xff1f : (int)'?';
                    if (attr == 0)
-                       attr = hl_attr(HLF_8);
+                       attr = HL_ATTR(HLF_8);
                }
 # endif
 # ifdef FEAT_ARABIC
@@ -7505,7 +7531,7 @@ start_search_hl(void)
     if (p_hls && !no_hlsearch)
     {
        last_pat_prog(&search_hl.rm);
-       search_hl.attr = hl_attr(HLF_L);
+       search_hl.attr = HL_ATTR(HLF_L);
 # ifdef FEAT_RELTIME
        /* Set the time limit to 'redrawtime'. */
        profile_setlimit(p_rdt, &search_hl.tm);
@@ -10075,7 +10101,7 @@ showmode(void)
        /* Position on the last line in the window, column 0 */
        msg_pos_mode();
        cursor_off();
-       attr = hl_attr(HLF_CM);                 /* Highlight mode */
+       attr = HL_ATTR(HLF_CM);                 /* Highlight mode */
        if (do_mode)
        {
            MSG_PUTS_ATTR("--", attr);
@@ -10129,7 +10155,7 @@ showmode(void)
                    {
                        MSG_PUTS_ATTR(" ", attr);  /* add a space in between */
                        if ((int)edit_submode_highl < (int)HLF_COUNT)
-                           sub_attr = hl_attr(edit_submode_highl);
+                           sub_attr = HL_ATTR(edit_submode_highl);
                        else
                            sub_attr = attr;
                        msg_puts_attr(edit_submode_extra, sub_attr);
@@ -10286,7 +10312,7 @@ clearmode(void)
 {
     msg_pos_mode();
     if (Recording)
-       recording_mode(hl_attr(HLF_CM));
+       recording_mode(HL_ATTR(HLF_CM));
     msg_clr_eos();
 }
 
@@ -10321,9 +10347,9 @@ draw_tabline(void)
     int                modified;
     int                c;
     int                len;
-    int                attr_sel = hl_attr(HLF_TPS);
-    int                attr_nosel = hl_attr(HLF_TP);
-    int                attr_fill = hl_attr(HLF_TPF);
+    int                attr_sel = HL_ATTR(HLF_TPS);
+    int                attr_nosel = HL_ATTR(HLF_TP);
+    int                attr_fill = HL_ATTR(HLF_TPF);
     char_u     *p;
     int                room;
     int                use_sep_chars = (t_colors < 8
@@ -10335,6 +10361,8 @@ draw_tabline(void)
 #endif
                                            );
 
+    if (ScreenLines == NULL)
+       return;
     redraw_tabline = FALSE;
 
 #ifdef FEAT_GUI_TABLINE
@@ -10422,7 +10450,7 @@ draw_tabline(void)
                        break;
                    screen_puts_len(NameBuff, len, 0, col,
 #if defined(FEAT_SYN_HL)
-                                        hl_combine_attr(attr, hl_attr(HLF_T))
+                                        hl_combine_attr(attr, HL_ATTR(HLF_T))
 #else
                                         attr
 #endif
@@ -10447,7 +10475,7 @@ draw_tabline(void)
                    while (len > room)
                    {
                        len -= ptr2cells(p);
-                       mb_ptr_adv(p);
+                       MB_PTR_ADV(p);
                    }
                else
 #endif
@@ -10515,18 +10543,18 @@ fillchar_status(int *attr, int is_curwin)
     int fill;
     if (is_curwin)
     {
-       *attr = hl_attr(HLF_S);
+       *attr = HL_ATTR(HLF_S);
        fill = fill_stl;
     }
     else
     {
-       *attr = hl_attr(HLF_SNC);
+       *attr = HL_ATTR(HLF_SNC);
        fill = fill_stlnc;
     }
     /* Use fill when there is highlighting, and highlighting of current
      * window differs, or the fillchars differ, or this is not the
      * current window */
-    if (*attr != 0 && ((hl_attr(HLF_S) != hl_attr(HLF_SNC)
+    if (*attr != 0 && ((HL_ATTR(HLF_S) != HL_ATTR(HLF_SNC)
                        || !is_curwin || ONE_WINDOW)
                    || (fill_stl != fill_stlnc)))
        return fill;
@@ -10544,7 +10572,7 @@ fillchar_status(int *attr, int is_curwin)
     static int
 fillchar_vsep(int *attr)
 {
-    *attr = hl_attr(HLF_C);
+    *attr = HL_ATTR(HLF_C);
     if (*attr == 0 && fill_vert == ' ')
        return '|';
     else
@@ -10558,7 +10586,12 @@ fillchar_vsep(int *attr)
     int
 redrawing(void)
 {
-    return (!RedrawingDisabled
+#ifdef FEAT_EVAL
+    if (disable_redraw_for_testing)
+       return 0;
+    else
+#endif
+       return (!RedrawingDisabled
                       && !(p_lz && char_avail() && !KeyTyped && !do_redraw));
 }
 
index cedcad9..3145e9a 100644 (file)
@@ -1643,7 +1643,11 @@ searchc(cmdarg_T *cap, int t_cmd)
     }
     else               /* repeat previous search */
     {
-       if (*lastc == NUL)
+       if (*lastc == NUL
+#ifdef FEAT_MBYTE
+               && lastc_bytelen == 1
+#endif
+               )
            return FAIL;
        if (dir)        /* repeat in opposite direction */
            dir = -lastcdir;
@@ -1693,11 +1697,9 @@ searchc(cmdarg_T *cap, int t_cmd)
                    if (p[col] == c && stop)
                        break;
                }
-               else
-               {
-                   if (vim_memcmp(p + col, lastc_bytes, lastc_bytelen) == 0 && stop)
-                       break;
-               }
+               else if (STRNCMP(p + col, lastc_bytes, lastc_bytelen) == 0
+                                                                      && stop)
+                   break;
                stop = TRUE;
            }
        }
@@ -2098,7 +2100,7 @@ findmatchlimit(
 
     do_quotes = -1;
     start_in_quotes = MAYBE;
-    clearpos(&match_pos);
+    CLEAR_POS(&match_pos);
 
     /* backward search: Check if this line contains a single-line comment */
     if ((backwards && comment_dir)
@@ -2718,7 +2720,7 @@ findsent(int dir, long count)
            if (decl(&pos) == -1)
                break;
            /* when going forward: Stop in front of empty line */
-           if (lineempty(pos.lnum) && dir == FORWARD)
+           if (LINEEMPTY(pos.lnum) && dir == FORWARD)
            {
                incl(&pos);
                goto found;
@@ -2849,9 +2851,17 @@ findpar(
     curwin->w_cursor.lnum = curr;
     if (curr == curbuf->b_ml.ml_line_count && what != '}')
     {
-       if ((curwin->w_cursor.col = (colnr_T)STRLEN(ml_get(curr))) != 0)
+       char_u *line = ml_get(curr);
+
+       /* Put the cursor on the last character in the last line and make the
+        * motion inclusive. */
+       if ((curwin->w_cursor.col = (colnr_T)STRLEN(line)) != 0)
        {
            --curwin->w_cursor.col;
+#ifdef FEAT_MBYTE
+           curwin->w_cursor.col -=
+                            (*mb_head_off)(line, line + curwin->w_cursor.col);
+#endif
            *pincl = TRUE;
        }
     }
@@ -3080,7 +3090,7 @@ bck_word(long count, int bigword, int stop)
            while (cls() == 0)
            {
                if (curwin->w_cursor.col == 0
-                                     && lineempty(curwin->w_cursor.lnum))
+                                     && LINEEMPTY(curwin->w_cursor.lnum))
                    goto finished;
                if (dec_cursor() == -1) /* hit start of file, stop here */
                    return OK;
@@ -3161,7 +3171,7 @@ end_word(
            while (cls() == 0)
            {
                if (empty && curwin->w_cursor.col == 0
-                                         && lineempty(curwin->w_cursor.lnum))
+                                         && LINEEMPTY(curwin->w_cursor.lnum))
                    goto finished;
                if (inc_cursor() == -1)     /* hit end of file, stop here */
                    return FAIL;
@@ -3221,7 +3231,7 @@ bckend_word(
         */
        while (cls() == 0)
        {
-           if (curwin->w_cursor.col == 0 && lineempty(curwin->w_cursor.lnum))
+           if (curwin->w_cursor.col == 0 && LINEEMPTY(curwin->w_cursor.lnum))
                break;
            if ((i = dec_cursor()) == -1 || (eol && i == 1))
                return OK;
@@ -3274,7 +3284,7 @@ find_first_blank(pos_T *posp)
     while (decl(posp) != -1)
     {
        c = gchar_pos(posp);
-       if (!vim_iswhite(c))
+       if (!VIM_ISWHITE(c))
        {
            incl(posp);
            break;
@@ -3318,17 +3328,17 @@ current_word(
     int                include_white = FALSE;
 
     cls_bigword = bigword;
-    clearpos(&start_pos);
+    CLEAR_POS(&start_pos);
 
     /* Correct cursor when 'selection' is exclusive */
-    if (VIsual_active && *p_sel == 'e' && lt(VIsual, curwin->w_cursor))
+    if (VIsual_active && *p_sel == 'e' && LT_POS(VIsual, curwin->w_cursor))
        dec_cursor();
 
     /*
      * When Visual mode is not active, or when the VIsual area is only one
      * character, select the word and/or white space under the cursor.
      */
-    if (!VIsual_active || equalpos(curwin->w_cursor, VIsual))
+    if (!VIsual_active || EQUAL_POS(curwin->w_cursor, VIsual))
     {
        /*
         * Go to start of current word or white space.
@@ -3385,7 +3395,7 @@ current_word(
     while (count > 0)
     {
        inclusive = TRUE;
-       if (VIsual_active && lt(curwin->w_cursor, VIsual))
+       if (VIsual_active && LT_POS(curwin->w_cursor, VIsual))
        {
            /*
             * In Visual mode, with cursor at start: move cursor back.
@@ -3461,7 +3471,7 @@ current_word(
 
     if (VIsual_active)
     {
-       if (*p_sel == 'e' && inclusive && ltoreq(VIsual, curwin->w_cursor))
+       if (*p_sel == 'e' && inclusive && LTOREQ_POS(VIsual, curwin->w_cursor))
            inc_cursor();
        if (VIsual_mode == 'V')
        {
@@ -3496,10 +3506,10 @@ current_sent(oparg_T *oap, long count, int include)
     /*
      * When the Visual area is bigger than one character: Extend it.
      */
-    if (VIsual_active && !equalpos(start_pos, VIsual))
+    if (VIsual_active && !EQUAL_POS(start_pos, VIsual))
     {
 extend:
-       if (lt(start_pos, VIsual))
+       if (LT_POS(start_pos, VIsual))
        {
            /*
             * Cursor at start of Visual area.
@@ -3510,10 +3520,10 @@ extend:
             */
            at_start_sent = TRUE;
            decl(&pos);
-           while (lt(pos, curwin->w_cursor))
+           while (LT_POS(pos, curwin->w_cursor))
            {
                c = gchar_pos(&pos);
-               if (!vim_iswhite(c))
+               if (!VIM_ISWHITE(c))
                {
                    at_start_sent = FALSE;
                    break;
@@ -3523,7 +3533,7 @@ extend:
            if (!at_start_sent)
            {
                findsent(BACKWARD, 1L);
-               if (equalpos(curwin->w_cursor, start_pos))
+               if (EQUAL_POS(curwin->w_cursor, start_pos))
                    at_start_sent = TRUE;  /* exactly at start of sentence */
                else
                    /* inside a sentence, go to its end (start of next) */
@@ -3536,7 +3546,7 @@ extend:
                if (at_start_sent)
                    find_first_blank(&curwin->w_cursor);
                c = gchar_cursor();
-               if (!at_start_sent || (!include && !vim_iswhite(c)))
+               if (!at_start_sent || (!include && !VIM_ISWHITE(c)))
                    findsent(BACKWARD, 1L);
                at_start_sent = !at_start_sent;
            }
@@ -3552,13 +3562,14 @@ extend:
             */
            incl(&pos);
            at_start_sent = TRUE;
-           if (!equalpos(pos, curwin->w_cursor)) /* not just before a sentence */
+           /* not just before a sentence */
+           if (!EQUAL_POS(pos, curwin->w_cursor))
            {
                at_start_sent = FALSE;
-               while (lt(pos, curwin->w_cursor))
+               while (LT_POS(pos, curwin->w_cursor))
                {
                    c = gchar_pos(&pos);
-                   if (!vim_iswhite(c))
+                   if (!VIM_ISWHITE(c))
                    {
                        at_start_sent = TRUE;
                        break;
@@ -3584,9 +3595,9 @@ extend:
      * If the cursor started on a blank, check if it is just before the start
      * of the next sentence.
      */
-    while (c = gchar_pos(&pos), vim_iswhite(c))        /* vim_iswhite() is a macro */
+    while (c = gchar_pos(&pos), VIM_ISWHITE(c))        /* VIM_ISWHITE() is a macro */
        incl(&pos);
-    if (equalpos(pos, curwin->w_cursor))
+    if (EQUAL_POS(pos, curwin->w_cursor))
     {
        start_blank = TRUE;
        find_first_blank(&start_pos);   /* go back to first blank */
@@ -3620,18 +3631,18 @@ extend:
        if (start_blank)
        {
            find_first_blank(&curwin->w_cursor);
-           c = gchar_pos(&curwin->w_cursor);   /* vim_iswhite() is a macro */
-           if (vim_iswhite(c))
+           c = gchar_pos(&curwin->w_cursor);   /* VIM_ISWHITE() is a macro */
+           if (VIM_ISWHITE(c))
                decl(&curwin->w_cursor);
        }
-       else if (c = gchar_cursor(), !vim_iswhite(c))
+       else if (c = gchar_cursor(), !VIM_ISWHITE(c))
            find_first_blank(&start_pos);
     }
 
     if (VIsual_active)
     {
        /* Avoid getting stuck with "is" on a single space before a sentence. */
-       if (equalpos(start_pos, curwin->w_cursor))
+       if (EQUAL_POS(start_pos, curwin->w_cursor))
            goto extend;
        if (*p_sel == 'e')
            ++curwin->w_cursor.col;
@@ -3680,7 +3691,7 @@ current_block(
     /*
      * If we start on '(', '{', ')', '}', etc., use the whole block inclusive.
      */
-    if (!VIsual_active || equalpos(VIsual, curwin->w_cursor))
+    if (!VIsual_active || EQUAL_POS(VIsual, curwin->w_cursor))
     {
        setpcmark();
        if (what == '{')                /* ignore indent */
@@ -3691,7 +3702,7 @@ current_block(
            /* cursor on '(' or '{', move cursor just after it */
            ++curwin->w_cursor.col;
     }
-    else if (lt(VIsual, curwin->w_cursor))
+    else if (LT_POS(VIsual, curwin->w_cursor))
     {
        old_start = VIsual;
        curwin->w_cursor = VIsual;          /* cursor at low end of Visual */
@@ -3749,7 +3760,7 @@ current_block(
         * In Visual mode, when the resulting area is not bigger than what we
         * started with, extend it to the next block, and then exclude again.
         */
-       if (!lt(start_pos, old_start) && !lt(old_end, curwin->w_cursor)
+       if (!LT_POS(start_pos, old_start) && !LT_POS(old_end, curwin->w_cursor)
                && VIsual_active)
        {
            curwin->w_cursor = old_start;
@@ -3790,7 +3801,7 @@ current_block(
        oap->inclusive = FALSE;
        if (sol)
            incl(&curwin->w_cursor);
-       else if (ltoreq(start_pos, curwin->w_cursor))
+       else if (LTOREQ_POS(start_pos, curwin->w_cursor))
            /* Include the character under the cursor. */
            oap->inclusive = TRUE;
        else
@@ -3825,7 +3836,7 @@ in_html_tag(
 
        /* We search forward until the cursor, because searching backwards is
         * very slow for DBCS encodings. */
-       for (p = line; p < line + curwin->w_cursor.col; mb_ptr_adv(p))
+       for (p = line; p < line + curwin->w_cursor.col; MB_PTR_ADV(p))
            if (*p == '>' || *p == '<')
            {
                lc = *p;
@@ -3845,7 +3856,7 @@ in_html_tag(
        {
            if (*p == '<')      /* find '<' under/before cursor */
                break;
-           mb_ptr_back(line, p);
+           MB_PTR_BACK(line, p);
            if (*p == '>')      /* find '>' before cursor */
                break;
        }
@@ -3856,7 +3867,7 @@ in_html_tag(
     pos.lnum = curwin->w_cursor.lnum;
     pos.col = (colnr_T)(p - line);
 
-    mb_ptr_adv(p);
+    MB_PTR_ADV(p);
     if (end_tag)
        /* check that there is a '/' after the '<' */
        return *p == '/';
@@ -3914,7 +3925,7 @@ current_tagblock(
     /*
      * If we start on "<aaa>" select that block.
      */
-    if (!VIsual_active || equalpos(VIsual, curwin->w_cursor))
+    if (!VIsual_active || EQUAL_POS(VIsual, curwin->w_cursor))
     {
        setpcmark();
 
@@ -3940,7 +3951,7 @@ current_tagblock(
            old_end = curwin->w_cursor;
        }
     }
-    else if (lt(VIsual, curwin->w_cursor))
+    else if (LT_POS(VIsual, curwin->w_cursor))
     {
        old_start = VIsual;
        curwin->w_cursor = VIsual;          /* cursor at low end of Visual */
@@ -3971,7 +3982,7 @@ again:
      */
     inc_cursor();
     p = ml_get_cursor();
-    for (cp = p; *cp != NUL && *cp != '>' && !vim_iswhite(*cp); mb_ptr_adv(cp))
+    for (cp = p; *cp != NUL && *cp != '>' && !VIM_ISWHITE(*cp); MB_PTR_ADV(cp))
        ;
     len = (int)(cp - p);
     if (len == 0)
@@ -3997,7 +4008,7 @@ again:
     vim_free(spat);
     vim_free(epat);
 
-    if (r < 1 || lt(curwin->w_cursor, old_end))
+    if (r < 1 || LT_POS(curwin->w_cursor, old_end))
     {
        /* Can't find other end or it's before the previous end.  Could be a
         * HTML tag that doesn't have a matching end.  Search backwards for
@@ -4044,7 +4055,7 @@ again:
 
        /* If we now have the same text as before reset "do_include" and try
         * again. */
-       if (equalpos(start_pos, old_start) && equalpos(end_pos, old_end))
+       if (EQUAL_POS(start_pos, old_start) && EQUAL_POS(end_pos, old_end))
        {
            do_include = TRUE;
            curwin->w_cursor = old_start;
@@ -4057,7 +4068,7 @@ again:
     {
        /* If the end is before the start there is no text between tags, select
         * the char under the cursor. */
-       if (lt(end_pos, start_pos))
+       if (LT_POS(end_pos, start_pos))
            curwin->w_cursor = start_pos;
        else if (*p_sel == 'e')
            inc_cursor();
@@ -4070,7 +4081,7 @@ again:
     {
        oap->start = start_pos;
        oap->motion_type = MCHAR;
-       if (lt(end_pos, start_pos))
+       if (LT_POS(end_pos, start_pos))
        {
            /* End is before the start: there is no text between tags; operate
             * on an empty area. */
@@ -4240,7 +4251,11 @@ extend:
         * line, we get stuck there.  Trap this here. */
        if (VIsual_mode == 'V' && start_lnum == curwin->w_cursor.lnum)
            goto extend;
-       VIsual.lnum = start_lnum;
+       if (VIsual.lnum != start_lnum)
+       {
+           VIsual.lnum = start_lnum;
+           VIsual.col = 0;
+       }
        VIsual_mode = 'V';
        redraw_curbuf_later(INVERTED);  /* update the inversion */
        showmode();
@@ -4352,10 +4367,14 @@ current_quote(
     /* Correct cursor when 'selection' is exclusive */
     if (VIsual_active)
     {
-       vis_bef_curs = lt(VIsual, curwin->w_cursor);
+       /* this only works within one line */
+       if (VIsual.lnum != curwin->w_cursor.lnum)
+           return FALSE;
+
+       vis_bef_curs = LT_POS(VIsual, curwin->w_cursor);
        if (*p_sel == 'e' && vis_bef_curs)
            dec_cursor();
-       vis_empty = equalpos(VIsual, curwin->w_cursor);
+       vis_empty = EQUAL_POS(VIsual, curwin->w_cursor);
     }
 
     if (!vis_empty)
@@ -4485,11 +4504,11 @@ current_quote(
      * the starting quote. */
     if (include)
     {
-       if (vim_iswhite(line[col_end + 1]))
-           while (vim_iswhite(line[col_end + 1]))
+       if (VIM_ISWHITE(line[col_end + 1]))
+           while (VIM_ISWHITE(line[col_end + 1]))
                ++col_end;
        else
-           while (col_start > 0 && vim_iswhite(line[col_start - 1]))
+           while (col_start > 0 && VIM_ISWHITE(line[col_start - 1]))
                --col_start;
     }
 
@@ -4595,7 +4614,7 @@ current_search(
     p_ws = FALSE;
 
     /* Correct cursor when 'selection' is exclusive */
-    if (VIsual_active && *p_sel == 'e' && lt(VIsual, curwin->w_cursor))
+    if (VIsual_active && *p_sel == 'e' && LT_POS(VIsual, curwin->w_cursor))
        dec_cursor();
 
     if (VIsual_active)
@@ -4658,12 +4677,14 @@ current_search(
        }
        else if (!i && !result)
        {
-           if (forward) /* try again from start of buffer */
+           if (forward)
            {
-               clearpos(&pos);
+               /* try again from start of buffer */
+               CLEAR_POS(&pos);
            }
-           else /* try again from end of buffer */
+           else
            {
+               /* try again from end of buffer */
                /* searching backwards, so set pos to last line and col */
                pos.lnum = curwin->w_buffer->b_ml.ml_line_count;
                pos.col  = (colnr_T)STRLEN(
@@ -4699,9 +4720,9 @@ current_search(
        if (*p_sel == 'e')
        {
            /* Correction for exclusive selection depends on the direction. */
-           if (forward && ltoreq(VIsual, curwin->w_cursor))
+           if (forward && LTOREQ_POS(VIsual, curwin->w_cursor))
                inc_cursor();
-           else if (!forward && ltoreq(curwin->w_cursor, VIsual))
+           else if (!forward && LTOREQ_POS(curwin->w_cursor, VIsual))
                inc(&VIsual);
        }
 
@@ -4754,7 +4775,9 @@ is_one_char(char_u *pattern, int move)
     regmatch.startpos[0].col = -1;
     /* move to match */
     if (move)
-       clearpos(&pos)
+    {
+       CLEAR_POS(&pos);
+    }
     else
     {
        pos = curwin->w_cursor;
@@ -4998,7 +5021,7 @@ find_pattern_in_path(
                    {
                        /* using "new_fname" is more reliable, e.g., when
                         * 'includeexpr' is set. */
-                       msg_outtrans_attr(new_fname, hl_attr(HLF_D));
+                       msg_outtrans_attr(new_fname, HL_ATTR(HLF_D));
                    }
                    else
                    {
@@ -5044,7 +5067,7 @@ find_pattern_in_path(
                        }
                        save_char = p[i];
                        p[i] = NUL;
-                       msg_outtrans_attr(p, hl_attr(HLF_D));
+                       msg_outtrans_attr(p, HL_ATTR(HLF_D));
                        p[i] = save_char;
                    }
 
@@ -5109,7 +5132,7 @@ find_pattern_in_path(
                        vim_snprintf((char*)IObuff, IOSIZE,
                                _("Scanning included file: %s"),
                                (char *)new_fname);
-                       msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
+                       msg_trunc_attr(IObuff, TRUE, HL_ATTR(HLF_R));
                    }
                    else
 #endif
@@ -5557,7 +5580,7 @@ show_pat_in_path(
            msg_puts(IObuff);
            sprintf((char *)IObuff, "%4ld", *lnum);     /* show line nr */
                                                /* Highlight line numbers */
-           msg_puts_attr(IObuff, hl_attr(HLF_N));
+           msg_puts_attr(IObuff, HL_ATTR(HLF_N));
            MSG_PUTS(" ");
        }
        msg_prt_line(line, FALSE);
index eb81ad2..118e78b 100644 (file)
@@ -468,7 +468,7 @@ spell_check(
     {
        do
        {
-           mb_ptr_adv(mi.mi_fend);
+           MB_PTR_ADV(mi.mi_fend);
        } while (*mi.mi_fend != NUL && spell_iswordp(mi.mi_fend, wp));
 
        if (capcol != NULL && *capcol == 0 && wp->w_s->b_cap_prog != NULL)
@@ -494,7 +494,7 @@ spell_check(
     /* case-fold the word with one non-word character, so that we can check
      * for the word end. */
     if (*mi.mi_fend != NUL)
-       mb_ptr_adv(mi.mi_fend);
+       MB_PTR_ADV(mi.mi_fend);
 
     (void)spell_casefold(ptr, (int)(mi.mi_fend - ptr), mi.mi_fword,
                                                             MAXWLEN + 1);
@@ -582,7 +582,7 @@ spell_check(
        else if (mi.mi_end == ptr)
            /* Always include at least one character.  Required for when there
             * is a mixup in "midword". */
-           mb_ptr_adv(mi.mi_end);
+           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)
        {
@@ -598,8 +598,8 @@ spell_check(
                fp = mi.mi_fword;
                for (;;)
                {
-                   mb_ptr_adv(p);
-                   mb_ptr_adv(fp);
+                   MB_PTR_ADV(p);
+                   MB_PTR_ADV(fp);
                    if (p >= mi.mi_end)
                        break;
                    mi.mi_compoff = (int)(fp - mi.mi_fword);
@@ -827,8 +827,8 @@ find_word(matchinf_T *mip, int mode)
            p = mip->mi_word;
            if (STRNCMP(ptr, p, wlen) != 0)
            {
-               for (s = ptr; s < ptr + wlen; mb_ptr_adv(s))
-                   mb_ptr_adv(p);
+               for (s = ptr; s < ptr + wlen; MB_PTR_ADV(s))
+                   MB_PTR_ADV(p);
                wlen = (int)(p - mip->mi_word);
            }
        }
@@ -952,8 +952,8 @@ find_word(matchinf_T *mip, int mode)
                    {
                        /* case folding may have changed the length */
                        p = mip->mi_word;
-                       for (s = ptr; s < ptr + mip->mi_compoff; mb_ptr_adv(s))
-                           mb_ptr_adv(p);
+                       for (s = ptr; s < ptr + mip->mi_compoff; MB_PTR_ADV(s))
+                           MB_PTR_ADV(p);
                    }
                    else
 #endif
@@ -969,7 +969,7 @@ find_word(matchinf_T *mip, int mode)
                         * character we do not accept a Onecap word.  We do
                         * accept a no-caps word, even when the dictionary
                         * word specifies ONECAP. */
-                       mb_ptr_back(mip->mi_word, p);
+                       MB_PTR_BACK(mip->mi_word, p);
                        if (spell_iswordp_nmw(p, mip->mi_win)
                                ? capflags == WF_ONECAP
                                : (flags & WF_ONECAP) != 0
@@ -1038,8 +1038,8 @@ find_word(matchinf_T *mip, int mode)
                    p = mip->mi_fword;
                    if (STRNCMP(ptr, p, wlen) != 0)
                    {
-                       for (s = ptr; s < ptr + wlen; mb_ptr_adv(s))
-                           mb_ptr_adv(p);
+                       for (s = ptr; s < ptr + wlen; MB_PTR_ADV(s))
+                           MB_PTR_ADV(p);
                        mip->mi_compoff = (int)(p - mip->mi_fword);
                    }
                }
@@ -1208,7 +1208,7 @@ can_compound(slang_T *slang, char_u *word, char_u *flags)
        /* Need to convert the single byte flags to utf8 characters. */
        p = uflags;
        for (i = 0; flags[i] != NUL; ++i)
-           p += mb_char2bytes(flags[i], p);
+           p += utf_char2bytes(flags[i], p);
        *p = NUL;
        p = uflags;
     }
@@ -1506,12 +1506,12 @@ fold_more(matchinf_T *mip)
     p = mip->mi_fend;
     do
     {
-       mb_ptr_adv(mip->mi_fend);
+       MB_PTR_ADV(mip->mi_fend);
     } while (*mip->mi_fend != NUL && spell_iswordp(mip->mi_fend, mip->mi_win));
 
     /* Include the non-word character so that we can check for the word end. */
     if (*mip->mi_fend != NUL)
-       mb_ptr_adv(mip->mi_fend);
+       MB_PTR_ADV(mip->mi_fend);
 
     (void)spell_casefold(p, (int)(mip->mi_fend - p),
                             mip->mi_fword + mip->mi_fwordlen,
@@ -1603,7 +1603,7 @@ spell_move_to(
      * though...
      */
     lnum = wp->w_cursor.lnum;
-    clearpos(&found_pos);
+    CLEAR_POS(&found_pos);
 
     while (!got_int)
     {
@@ -1734,14 +1734,14 @@ spell_move_to(
        if (curline)
            break;      /* only check cursor line */
 
+       /* If we are back at the starting line and searched it again there
+        * is no match, give up. */
+       if (lnum == wp->w_cursor.lnum && wrapped)
+           break;
+
        /* Advance to next line. */
        if (dir == BACKWARD)
        {
-           /* If we are back at the starting line and searched it again there
-            * is no match, give up. */
-           if (lnum == wp->w_cursor.lnum && wrapped)
-               break;
-
            if (lnum > 1)
                --lnum;
            else if (!p_ws)
@@ -1775,7 +1775,7 @@ spell_move_to(
 
            /* If we are back at the starting line and there is no match then
             * give up. */
-           if (lnum == wp->w_cursor.lnum && (!found_one || wrapped))
+           if (lnum == wp->w_cursor.lnum && !found_one)
                break;
 
            /* Skip the characters at the start of the next line that were
@@ -2760,7 +2760,7 @@ captype(
     int                past_second = FALSE;    /* past second word char */
 
     /* find first letter */
-    for (p = word; !spell_iswordp_nmw(p, curwin); mb_ptr_adv(p))
+    for (p = word; !spell_iswordp_nmw(p, curwin); MB_PTR_ADV(p))
        if (end == NULL ? *p == NUL : p >= end)
            return 0;       /* only non-word characters, illegal word */
 #ifdef FEAT_MBYTE
@@ -2775,7 +2775,7 @@ captype(
      * Need to check all letters to find a word with mixed upper/lower.
      * But a word with an upper char only at start is a ONECAP.
      */
-    for ( ; end == NULL ? *p != NUL : p < end; mb_ptr_adv(p))
+    for ( ; end == NULL ? *p != NUL : p < end; MB_PTR_ADV(p))
        if (spell_iswordp_nmw(p, curwin))
        {
            c = PTR2CHAR(p);
@@ -2818,7 +2818,7 @@ badword_captype(char_u *word, char_u *end)
        /* Count the number of UPPER and lower case letters. */
        l = u = 0;
        first = FALSE;
-       for (p = word; p < end; mb_ptr_adv(p))
+       for (p = word; p < end; MB_PTR_ADV(p))
        {
            c = PTR2CHAR(p);
            if (SPELL_ISUPPER(c))
@@ -3123,7 +3123,7 @@ spell_iswordp(
 
     if (has_mbyte)
     {
-       l = MB_BYTE2LEN(*p);
+       l = MB_PTR2LEN(p);
        s = p;
        if (l == 1)
        {
@@ -3385,10 +3385,10 @@ spell_suggest(int count)
        p = line + curwin->w_cursor.col;
        /* Backup to before start of word. */
        while (p > line && spell_iswordp_nmw(p, curwin))
-           mb_ptr_back(line, p);
+           MB_PTR_BACK(line, p);
        /* Forward to start of word. */
        while (*p != NUL && !spell_iswordp_nmw(p, curwin))
-           mb_ptr_adv(p);
+           MB_PTR_ADV(p);
 
        if (!spell_iswordp_nmw(p, curwin))              /* No word found. */
        {
@@ -3624,7 +3624,7 @@ check_need_cap(linenr_T lnum, colnr_T col)
        p = line + endcol;
        for (;;)
        {
-           mb_ptr_back(line, p);
+           MB_PTR_BACK(line, p);
            if (p == line || spell_iswordp_nmw(p, curwin))
                break;
            if (vim_regexec(&regmatch, p, 0)
@@ -3808,6 +3808,10 @@ spell_find_suggest(
     vim_strncpy(su->su_badword, su->su_badptr, su->su_badlen);
     (void)spell_casefold(su->su_badptr, su->su_badlen,
                                                    su->su_fbadword, MAXWLEN);
+    /* TODO: make this work if the case-folded text is longer than the original
+     * text. Currently an illegal byte causes wrong pointer computations. */
+    su->su_fbadword[su->su_badlen] = NUL;
+
     /* get caps flags for bad word */
     su->su_badflags = badword_captype(su->su_badptr,
                                               su->su_badptr + su->su_badlen);
@@ -4528,7 +4532,7 @@ suggest_trie_walk(
 
            fword_ends = (fword[sp->ts_fidx] == NUL
                           || (soundfold
-                              ? vim_iswhite(fword[sp->ts_fidx])
+                              ? VIM_ISWHITE(fword[sp->ts_fidx])
                               : !spell_iswordp(fword + sp->ts_fidx, curwin)));
            tword[sp->ts_twordlen] = NUL;
 
@@ -4644,7 +4648,7 @@ suggest_trie_walk(
 
                    /* Get pointer to last char of previous word. */
                    p = preword + sp->ts_prewordlen;
-                   mb_ptr_back(preword, p);
+                   MB_PTR_BACK(preword, p);
                }
            }
 
@@ -4746,11 +4750,11 @@ suggest_trie_walk(
                    /* Give a penalty when changing non-word char to word
                     * char, e.g., "thes," -> "these". */
                    p = fword + sp->ts_fidx;
-                   mb_ptr_back(fword, p);
+                   MB_PTR_BACK(fword, p);
                    if (!spell_iswordp(p, curwin))
                    {
                        p = preword + STRLEN(preword);
-                       mb_ptr_back(preword, p);
+                       MB_PTR_BACK(preword, p);
                        if (spell_iswordp(p, curwin))
                            newscore += SCORE_NONWORD;
                    }
@@ -4937,12 +4941,7 @@ suggest_trie_walk(
                        {
                            int     l;
 
-#ifdef FEAT_MBYTE
-                           if (has_mbyte)
-                               l = MB_BYTE2LEN(fword[sp->ts_fidx]);
-                           else
-#endif
-                               l = 1;
+                           l = MB_PTR2LEN(fword + sp->ts_fidx);
                            if (fword_ends)
                            {
                                /* Copy the skipped character to preword. */
@@ -5109,19 +5108,18 @@ suggest_trie_walk(
                                /* Correct ts_fidx for the byte length of the
                                 * character (we didn't check that before). */
                                sp->ts_fidx = sp->ts_fcharstart
-                                           + MB_BYTE2LEN(
-                                                   fword[sp->ts_fcharstart]);
-
+                                           + MB_PTR2LEN(
+                                                   fword + sp->ts_fcharstart);
                                /* For changing a composing character adjust
                                 * the score from SCORE_SUBST to
                                 * SCORE_SUBCOMP. */
                                if (enc_utf8
                                        && utf_iscomposing(
-                                           mb_ptr2char(tword
+                                           utf_ptr2char(tword
                                                + sp->ts_twordlen
                                                           - sp->ts_tcharlen))
                                        && utf_iscomposing(
-                                           mb_ptr2char(fword
+                                           utf_ptr2char(fword
                                                        + sp->ts_fcharstart)))
                                    sp->ts_score -=
                                                  SCORE_SUBST - SCORE_SUBCOMP;
@@ -5157,7 +5155,7 @@ suggest_trie_walk(
                                     * to the score.  Also for the soundfold
                                     * tree (might seem illogical but does
                                     * give better scores). */
-                                   mb_ptr_back(tword, p);
+                                   MB_PTR_BACK(tword, p);
                                    if (c == mb_ptr2char(p))
                                        sp->ts_score -= SCORE_INS
                                                               - SCORE_INSDUP;
@@ -5232,7 +5230,7 @@ suggest_trie_walk(
                if (has_mbyte)
                {
                    c = mb_ptr2char(fword + sp->ts_fidx);
-                   stack[depth].ts_fidx += MB_BYTE2LEN(fword[sp->ts_fidx]);
+                   stack[depth].ts_fidx += MB_PTR2LEN(fword + sp->ts_fidx);
                    if (enc_utf8 && utf_iscomposing(c))
                        stack[depth].ts_score -= SCORE_DEL - SCORE_DELCOMP;
                    else if (c == mb_ptr2char(fword + stack[depth].ts_fidx))
@@ -5456,9 +5454,9 @@ suggest_trie_walk(
 #ifdef FEAT_MBYTE
            if (has_mbyte)
            {
-               n = MB_BYTE2LEN(*p);
+               n = MB_PTR2LEN(p);
                c = mb_ptr2char(p + n);
-               mch_memmove(p + MB_BYTE2LEN(p[n]), p, n);
+               mch_memmove(p + MB_PTR2LEN(p + n), p, n);
                mb_char2bytes(c, p);
            }
            else
@@ -5550,11 +5548,11 @@ suggest_trie_walk(
 #ifdef FEAT_MBYTE
            if (has_mbyte)
            {
-               n = MB_BYTE2LEN(*p);
+               n = MB_PTR2LEN(p);
                c2 = mb_ptr2char(p + n);
-               fl = MB_BYTE2LEN(p[n]);
+               fl = MB_PTR2LEN(p + n);
                c = mb_ptr2char(p + n + fl);
-               tl = MB_BYTE2LEN(p[n + fl]);
+               tl = MB_PTR2LEN(p + n + fl);
                mch_memmove(p + fl + tl, p, n);
                mb_char2bytes(c, p);
                mb_char2bytes(c2, p + tl);
@@ -5627,10 +5625,10 @@ suggest_trie_walk(
 #ifdef FEAT_MBYTE
            if (has_mbyte)
            {
-               n = MB_BYTE2LEN(*p);
-               n += MB_BYTE2LEN(p[n]);
+               n = MB_PTR2LEN(p);
+               n += MB_PTR2LEN(p + n);
                c = mb_ptr2char(p + n);
-               tl = MB_BYTE2LEN(p[n]);
+               tl = MB_PTR2LEN(p + n);
                mch_memmove(p + tl, p, n);
                mb_char2bytes(c, p);
            }
@@ -5693,9 +5691,9 @@ suggest_trie_walk(
            if (has_mbyte)
            {
                c = mb_ptr2char(p);
-               tl = MB_BYTE2LEN(*p);
-               n = MB_BYTE2LEN(p[tl]);
-               n += MB_BYTE2LEN(p[tl + n]);
+               tl = MB_PTR2LEN(p);
+               n = MB_PTR2LEN(p + tl);
+               n += MB_PTR2LEN(p + tl + n);
                mch_memmove(p, p + tl, n);
                mb_char2bytes(c, p + n);
            }
@@ -5867,9 +5865,9 @@ nofold_len(char_u *fword, int flen, char_u *word)
     char_u     *p;
     int                i = 0;
 
-    for (p = fword; p < fword + flen; mb_ptr_adv(p))
+    for (p = fword; p < fword + flen; MB_PTR_ADV(p))
        ++i;
-    for (p = word; i > 0; mb_ptr_adv(p))
+    for (p = word; i > 0; MB_PTR_ADV(p))
        --i;
     return (int)(p - word);
 }
@@ -6231,7 +6229,7 @@ stp_sal_score(
         * sounds like "t h" while "the" sounds like "@".  Avoid that by
         * removing the space.  Don't do it when the good word also contains a
         * space. */
-       if (vim_iswhite(su->su_badptr[su->su_badlen])
+       if (VIM_ISWHITE(su->su_badptr[su->su_badlen])
                                         && *skiptowhite(stp->st_word) == NUL)
            for (p = fword; *(p = skiptowhite(p)) != NUL; )
                STRMOVE(p, p + 1);
@@ -6428,7 +6426,7 @@ add_sound_suggest(
     sfwordnr = soundfold_find(slang, goodword);
     if (sfwordnr < 0)
     {
-       EMSG2(_(e_intern2), "add_sound_suggest()");
+       internal_error("add_sound_suggest()");
        return;
     }
 
@@ -6745,8 +6743,8 @@ add_suggestion(
        badlen = (int)(pbad - su->su_badptr);
        if (goodlen <= 0 || badlen <= 0)
            break;
-       mb_ptr_back(goodword, pgood);
-       mb_ptr_back(su->su_badptr, pbad);
+       MB_PTR_BACK(goodword, pgood);
+       MB_PTR_BACK(su->su_badptr, pbad);
 #ifdef FEAT_MBYTE
        if (has_mbyte)
        {
@@ -7106,7 +7104,7 @@ spell_soundfold_sofo(slang_T *slang, char_u *inword, char_u *res)
        for (s = inword; *s != NUL; )
        {
            c = mb_cptr2char_adv(&s);
-           if (enc_utf8 ? utf_class(c) == 0 : vim_iswhite(c))
+           if (enc_utf8 ? utf_class(c) == 0 : VIM_ISWHITE(c))
                c = ' ';
            else if (c < 256)
                c = slang->sl_sal_first[c];
@@ -7147,7 +7145,7 @@ spell_soundfold_sofo(slang_T *slang, char_u *inword, char_u *res)
        /* The sl_sal_first[] table contains the translation. */
        for (s = inword; (c = *s) != NUL; ++s)
        {
-           if (vim_iswhite(c))
+           if (VIM_ISWHITE(c))
                c = ' ';
            else
                c = slang->sl_sal_first[c];
@@ -7185,7 +7183,7 @@ spell_soundfold_sal(slang_T *slang, char_u *inword, char_u *res)
        t = word;
        while (*s != NUL)
        {
-           if (vim_iswhite(*s))
+           if (VIM_ISWHITE(*s))
            {
                *t++ = ' ';
                s = skipwhite(s);
@@ -7409,7 +7407,7 @@ spell_soundfold_sal(slang_T *slang, char_u *inword, char_u *res)
                }
            }
        }
-       else if (vim_iswhite(c))
+       else if (VIM_ISWHITE(c))
        {
            c = ' ';
            k = 1;
@@ -7474,7 +7472,7 @@ spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
        c = mb_cptr2char_adv(&s);
        if (slang->sl_rem_accents)
        {
-           if (enc_utf8 ? utf_class(c) == 0 : vim_iswhite(c))
+           if (enc_utf8 ? utf_class(c) == 0 : VIM_ISWHITE(c))
            {
                if (did_white)
                    continue;
@@ -7715,7 +7713,7 @@ spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
                }
            }
        }
-       else if (vim_iswhite(c))
+       else if (VIM_ISWHITE(c))
        {
            c = ' ';
            k = 1;
@@ -8545,7 +8543,7 @@ ex_spelldump(exarg_T *eap)
     set_option_value((char_u*)"spl",  dummy, spl, OPT_LOCAL);
     vim_free(spl);
 
-    if (!bufempty())
+    if (!BUFEMPTY())
        return;
 
     spell_dump_compl(NULL, 0, NULL, eap->forceit ? DUMPFLAG_COUNT : 0);
@@ -8976,7 +8974,7 @@ spell_to_word_end(char_u *start, win_T *win)
     char_u  *p = start;
 
     while (*p != NUL && spell_iswordp(p, win))
-       mb_ptr_adv(p);
+       MB_PTR_ADV(p);
     return p;
 }
 
@@ -9002,7 +9000,7 @@ spell_word_start(int startcol)
     line = ml_get_curline();
     for (p = line + startcol; p > line; )
     {
-       mb_ptr_back(line, p);
+       MB_PTR_BACK(line, p);
        if (spell_iswordp_nmw(p, curwin))
            break;
     }
@@ -9011,7 +9009,7 @@ spell_word_start(int startcol)
     while (p > line)
     {
        col = (int)(p - line);
-       mb_ptr_back(line, p);
+       MB_PTR_BACK(line, p);
        if (!spell_iswordp(p, curwin))
            break;
        col = 0;
index c7d87c6..6188aaf 100644 (file)
@@ -1429,7 +1429,7 @@ set_sofo(slang_T *lp, char_u *from, char_u *to)
        for (p = from, s = to; *p != NUL && *s != NUL; )
        {
            c = mb_cptr2char_adv(&p);
-           mb_cptr_adv(s);
+           MB_CPTR_ADV(s);
            if (c >= 256)
                ++lp->sl_sal_first[c & 0xff];
        }
@@ -1585,7 +1585,7 @@ spell_read_tree(
     int                prefixtree,     /* TRUE for the prefix tree */
     int                prefixcnt)      /* when "prefixtree" is TRUE: prefix count */
 {
-    int                len;
+    long       len;
     int                idx;
     char_u     *bp;
     idx_T      *ip;
@@ -1595,6 +1595,9 @@ spell_read_tree(
     len = get4c(fd);
     if (len < 0)
        return SP_TRUNCERROR;
+    if (len >= LONG_MAX / (long)sizeof(int))
+       /* Invalid length, multiply with sizeof(int) would overflow. */
+       return SP_FORMERROR;
     if (len > 0)
     {
        /* Allocate the byte array. */
@@ -2799,7 +2802,7 @@ spell_read_aff(spellinfo_T *spin, char_u *fname)
                            {
                                p = aff_entry->ae_add
                                                  + STRLEN(aff_entry->ae_add);
-                               mb_ptr_back(aff_entry->ae_add, p);
+                               MB_PTR_BACK(aff_entry->ae_add, p);
                                if (PTR2CHAR(p) == c_up)
                                {
                                    upper = TRUE;
@@ -2927,10 +2930,10 @@ spell_read_aff(spellinfo_T *spin, char_u *fname)
                {
                    /* Replace underscore with space (can't include a space
                     * directly). */
-                   for (p = items[1]; *p != NUL; mb_ptr_adv(p))
+                   for (p = items[1]; *p != NUL; MB_PTR_ADV(p))
                        if (*p == '_')
                            *p = ' ';
-                   for (p = items[2]; *p != NUL; mb_ptr_adv(p))
+                   for (p = items[2]; *p != NUL; MB_PTR_ADV(p))
                        if (*p == '_')
                            *p = ' ';
                    add_fromto(spin, items[0][3] == 'S'
@@ -3621,7 +3624,7 @@ spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile)
        /* Truncate the word at the "/", set "afflist" to what follows.
         * Replace "\/" by "/" and "\\" by "\". */
        afflist = NULL;
-       for (p = w; *p != NUL; mb_ptr_adv(p))
+       for (p = w; *p != NUL; MB_PTR_ADV(p))
        {
            if (*p == '\\' && (p[1] == '\\' || p[1] == '/'))
                STRMOVE(p, p + 1);
@@ -3944,7 +3947,7 @@ store_aff_word(
                                {
                                    i = mb_charlen(ae->ae_chop);
                                    for ( ; i > 0; --i)
-                                       mb_ptr_adv(p);
+                                       MB_PTR_ADV(p);
                                }
                                else
 #endif
@@ -3962,7 +3965,7 @@ store_aff_word(
                                p = newword + STRLEN(newword);
                                i = (int)MB_CHARLEN(ae->ae_chop);
                                for ( ; i > 0; --i)
-                                   mb_ptr_back(newword, p);
+                                   MB_PTR_BACK(newword, p);
                                *p = NUL;
                            }
                            if (ae->ae_add != NULL)
index 7a4d7fb..0175017 100644 (file)
@@ -515,6 +515,12 @@ struct buffheader
     int                bh_space;       /* space in bh_curr for appending */
 };
 
+typedef struct
+{
+    buffheader_T sr_redobuff;
+    buffheader_T sr_old_redobuff;
+} save_redo_T;
+
 /*
  * used for completion on the command line
  */
@@ -815,13 +821,23 @@ struct msglist
 };
 
 /*
+ * The exception types.
+ */
+typedef enum
+{
+    ET_USER,           /* exception caused by ":throw" command */
+    ET_ERROR,          /* error exception */
+    ET_INTERRUPT       /* interrupt exception triggered by Ctrl-C */
+} except_type_T;
+
+/*
  * Structure describing an exception.
  * (don't use "struct exception", it's used by the math library).
  */
 typedef struct vim_exception except_T;
 struct vim_exception
 {
-    int                        type;           /* exception type */
+    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 */
@@ -830,13 +846,6 @@ struct vim_exception
 };
 
 /*
- * The exception types.
- */
-#define ET_USER                0       /* exception caused by ":throw" command */
-#define ET_ERROR       1       /* error exception */
-#define ET_INTERRUPT   2       /* interrupt exception triggered by Ctrl-C */
-
-/*
  * Structure to save the error/interrupt/exception state between calls to
  * enter_cleanup() and leave_cleanup().  Must be allocated as an automatic
  * variable by the (common) caller of these functions.
@@ -1130,25 +1139,43 @@ typedef long_u hash_T;          /* Type for hi_hash */
 #  ifdef PROTO
 typedef long               varnumber_T;
 typedef unsigned long      uvarnumber_T;
+#define VARNUM_MIN         LONG_MIN
+#define VARNUM_MAX         LONG_MAX
+#define UVARNUM_MAX        ULONG_MAX
 #  else
 typedef __int64                    varnumber_T;
 typedef unsigned __int64    uvarnumber_T;
+#define VARNUM_MIN         _I64_MIN
+#define VARNUM_MAX         _I64_MAX
+#define UVARNUM_MAX        _UI64_MAX
 #  endif
 # elif defined(HAVE_STDINT_H)
 typedef int64_t                    varnumber_T;
 typedef uint64_t           uvarnumber_T;
+#define VARNUM_MIN         INT64_MIN
+#define VARNUM_MAX         INT64_MAX
+#define UVARNUM_MAX        UINT64_MAX
 # else
 typedef long               varnumber_T;
 typedef unsigned long      uvarnumber_T;
+#define VARNUM_MIN         LONG_MIN
+#define VARNUM_MAX         LONG_MAX
+#define UVARNUM_MAX        ULONG_MAX
 # endif
 #else
 /* Use 32-bit Number. */
 # if VIM_SIZEOF_INT <= 3       /* use long if int is smaller than 32 bits */
 typedef long               varnumber_T;
 typedef unsigned long      uvarnumber_T;
+#define VARNUM_MIN         LONG_MIN
+#define VARNUM_MAX         LONG_MAX
+#define UVARNUM_MAX        ULONG_MAX
 # else
 typedef int                varnumber_T;
 typedef unsigned int       uvarnumber_T;
+#define VARNUM_MIN         INT_MIN
+#define VARNUM_MAX         INT_MAX
+#define UVARNUM_MAX        UINT_MAX
 # endif
 #endif
 
@@ -1316,6 +1343,7 @@ typedef struct
     int                uf_varargs;     /* variable nr of arguments */
     int                uf_flags;
     int                uf_calls;       /* nr of active calls */
+    int                uf_cleared;     /* func_clear() was already called */
     garray_T   uf_args;        /* arguments */
     garray_T   uf_lines;       /* function lines */
 #ifdef FEAT_PROFILE
@@ -1418,11 +1446,13 @@ struct partial_S
     dict_T     *pt_dict;       /* dict for "self" */
 };
 
+/* Status of a job.  Order matters! */
 typedef enum
 {
     JOB_FAILED,
     JOB_STARTED,
-    JOB_ENDED
+    JOB_ENDED,     /* detected job done */
+    JOB_FINISHED    /* job done and cleanup done */
 } jobstatus_T;
 
 /*
@@ -1469,6 +1499,7 @@ struct jsonq_S
     typval_T   *jq_value;
     jsonq_T    *jq_next;
     jsonq_T    *jq_prev;
+    int                jq_no_callback; /* TRUE when no callback was found */
 };
 
 struct cbq_S
@@ -1538,9 +1569,11 @@ typedef struct {
     jsonq_T    ch_json_head;   /* header for circular json read queue */
     int                ch_block_id;    /* ID that channel_read_json_block() is
                                   waiting for */
-    /* When ch_waiting is TRUE use ch_deadline to wait for incomplete message
-     * to be complete. */
-    int                ch_waiting;
+    /* When ch_wait_len is non-zero use ch_deadline to wait for incomplete
+     * message to be complete. The value is the length of the incomplete
+     * message when the deadline was set.  If it gets longer (something was
+     * received) the deadline is reset. */
+    size_t     ch_wait_len;
 #ifdef WIN32
     DWORD      ch_deadline;
 #else
@@ -1592,6 +1625,7 @@ struct channel_S {
     partial_T  *ch_partial;
     char_u     *ch_close_cb;   /* call when channel is closed */
     partial_T  *ch_close_partial;
+    int                ch_drop_never;
 
     job_T      *ch_job;        /* Job that uses this channel; this does not
                                 * count as a reference to avoid a circular
@@ -1679,6 +1713,7 @@ typedef struct
     partial_T  *jo_close_partial; /* not referenced! */
     char_u     *jo_exit_cb;    /* not allocated! */
     partial_T  *jo_exit_partial; /* not referenced! */
+    int                jo_drop_never;
     int                jo_waittime;
     int                jo_timeout;
     int                jo_out_timeout;
@@ -1887,7 +1922,10 @@ struct file_buffer
 
     int                b_changed;      /* 'modified': Set to TRUE if something in the
                                   file has been changed and not written out. */
-    int                b_changedtick;  /* incremented for each change, also for undo */
+    dictitem16_T b_ct_di;      /* holds the b:changedtick value in
+                                  b_ct_di.di_tv.vval.v_number;
+                                  incremented for each change, also for undo */
+#define CHANGEDTICK(buf) ((buf)->b_ct_di.di_tv.vval.v_number)
 
     int                b_saving;       /* Set to TRUE if we are in the middle of
                                   saving the buffer. */
@@ -2089,6 +2127,7 @@ struct file_buffer
     long_u     b_p_inde_flags; /* flags for 'indentexpr' */
     char_u     *b_p_indk;      /* 'indentkeys' */
 #endif
+    char_u     *b_p_fp;        /* 'formatprg' */
 #if defined(FEAT_EVAL)
     char_u     *b_p_fex;       /* 'formatexpr' */
     long_u     b_p_fex_flags;  /* flags for 'formatexpr' */
@@ -2100,6 +2139,9 @@ struct file_buffer
 #ifdef FEAT_LISP
     int                b_p_lisp;       /* 'lisp' */
 #endif
+#ifdef FEAT_MBYTE
+    char_u     *b_p_menc;      /* 'makeencoding' */
+#endif
     char_u     *b_p_mps;       /* 'matchpairs' */
     int                b_p_ml;         /* 'modeline' */
     int                b_p_ml_nobin;   /* b_p_ml saved for binary mode */
@@ -2200,6 +2242,7 @@ struct file_buffer
     int                b_ind_hash_comment;
     int                b_ind_cpp_namespace;
     int                b_ind_if_for_while;
+    int                b_ind_cpp_extern_c;
 #endif
 
     linenr_T   b_no_eol_lnum;  /* non-zero lnum when last line of next binary
@@ -3220,8 +3263,8 @@ typedef struct
 #endif
 
     int                want_full_screen;
-    int                stdout_isatty;          /* is stdout a terminal? */
     int                not_a_term;             /* no warning for missing term? */
+    int                tty_fail;               /* exit if not a tty */
     char_u     *term;                  /* specified terminal name */
 #ifdef FEAT_CRYPT
     int                ask_for_key;            /* -x argument */
diff --git a/src/swis.s b/src/swis.s
deleted file mode 100644 (file)
index 562747a..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-; Thomas Leonard
-; 24/5/98
-
-ar0    rn      0
-ar1    rn      1
-ar2    rn      2
-ar3    rn      3
-ar4    rn      4
-ar5    rn      5
-ar6    rn      6
-ar7    rn      7
-ar10   rn      10
-ar11   rn      11
-lk     rn      14
-ar15   rn      15
-
-       AREA    DATA
-       align   4
-
-       export  |r0|
-r0:    dcd     0
-
-       export  |r1|
-r1:    dcd     0
-
-       export  |r2|
-r2:    dcd     0
-
-       export  |r3|
-r3:    dcd     0
-
-       export  |r4|
-r4:    dcd     0
-
-       export  |r5|
-r5:    dcd     0
-
-       export  |r6|
-r6:    dcd     0
-
-       export  |r7|
-r7:    dcd     0
-
-       export  |time_of_last_poll|
-time_of_last_poll:  dcd        0
-
-       AREA    CODE, READONLY
-       align 4
-       import  |r0|
-       export  |swi|
-       =       "swi"
-       align 4
-swi:
-       ; r0 = swi number
-       stmfd   sp!,{ar4-ar10,lk}
-       orr     ar10,ar0,#1<<17         ;always use the X form
-       mov     ar0,ar1
-       mov     ar1,ar2
-       mov     ar2,ar3
-       add     ar3,sp,#4*8
-       ldmia   ar3,{ar3-ar7}
-       swi     0x6f            ; OS_CallASWI
-       ldr     ar10,regs_addr
-       stmia   ar10,{ar0-ar7}
-       ldmvcfd sp!,{ar4-ar10,pc}^
-       ; report the error and quit on Cancel
-       mov     r1,#0x17
-       adr     r2,s_title
-       swi     0x400df         ; Wimp_ReportError
-       cmp     r1,#1                   ;OK selected?
-       ldmeqfd sp!,{ar4-ar10,pc}^      ;yes - try to continue
-       swi     0x11                    ;no  - die (OS_Exit)
-s_title:
-       = "Nasty error - Cancel to quit"
-       = 0
-
-       align 4
-       export  |xswi|
-       =       "xswi"
-       align 4
-xswi:
-       ; r0 = swi number
-       stmfd   sp!,{ar4-ar10,lk}
-       orr     ar10,ar0,#1<<17         ;always use the X form
-       mov     ar0,ar1
-       mov     ar1,ar2
-       mov     ar2,ar3
-       add     ar3,sp,#4*8
-       ldmia   ar3,{ar3-ar7}
-       swi     0x6f            ; OS_CallASWI
-       ldr     ar10,regs_addr
-       stmia   ar10,{ar0-ar7}
-       mov     ar0,#0
-       orr     ar0,ar0,ar15
-       ldmfd   sp!,{ar4-ar10,pc}^
-
-regs_addr:
-       dcd     r0
-
-       ; The Wimp_Poll swis have to be done specially because,
-       ; for some reason, r13 sometimes gets corrupted by Wimp_Poll
-       ; (eg when running FileFind)
-       AREA    CODE, READONLY
-       align 4
-       import  |time_of_last_poll|
-       export  |wimp_poll|
-       =       "wimp_poll"
-       align 4
-wimp_poll:
-       mov     ar3,sp
-       swi     0x400c7         ; Wimp_Poll
-       mov     sp,ar3
-
-       mov     ar3,ar0
-       swi     0x42            ; OS_ReadMonotonicTime
-       ldr     ar2,addr_time
-       str     ar0,[ar2]
-       mov     ar0,ar3
-
-       mov     ar2,#0
-       wfs     ar2             ; Write floating point status. Needed?
-       movs    pc,lk
-
-       align 4
-       export  |wimp_pollidle|
-       =       "wimp_pollidle"
-       align 4
-wimp_pollidle:
-       mov     ar3,sp
-       swi     0x400e1         ; Wimp_PollIdle
-       mov     sp,ar3
-
-       mov     ar3,ar0
-       swi     0x42            ; OS_ReadMonotonicTime
-       ldr     ar2,addr_time
-       str     ar0,[ar2]
-       mov     ar0,ar3
-
-       mov     ar2,#0
-       wfs     ar2             ; Write floating point status. Needed?
-       movs    pc,lk
-
-addr_time: dcd time_of_last_poll
index 75ede36..42a0bdc 100644 (file)
@@ -22,6 +22,7 @@ struct hl_group
 {
     char_u     *sg_name;       /* highlight group name */
     char_u     *sg_name_u;     /* uppercase of sg_name */
+    int                sg_cleared;     /* "hi clear" was used */
 /* for normal terminals */
     int                sg_term;        /* "term=" highlighting attributes */
     char_u     *sg_start;      /* terminal string for start highl */
@@ -462,7 +463,7 @@ static void syn_clear_keyword(int id, hashtab_T *ht);
 static void clear_keywtab(hashtab_T *ht);
 static void add_keyword(char_u *name, int id, int flags, short *cont_in_list, short *next_list, int conceal_char);
 static char_u *get_group_name(char_u *arg, char_u **name_end);
-static char_u *get_syn_options(char_u *arg, syn_opt_arg_T *opt, int *conceal_char);
+static char_u *get_syn_options(char_u *arg, syn_opt_arg_T *opt, int *conceal_char, int skip);
 static void syn_cmd_include(exarg_T *eap, int syncing);
 static void syn_cmd_iskeyword(exarg_T *eap, int syncing);
 static void syn_cmd_keyword(exarg_T *eap, int syncing);
@@ -481,7 +482,7 @@ static int syn_add_cluster(char_u *name);
 static void init_syn_patterns(void);
 static char_u *get_syn_pattern(char_u *arg, synpat_T *ci);
 static void syn_cmd_sync(exarg_T *eap, int syncing);
-static int get_id_list(char_u **arg, int keylen, short **list);
+static int get_id_list(char_u **arg, int keylen, short **list, int skip);
 static void syn_combine_list(short **clstr1, short **clstr2, int list_op);
 static void syn_incl_toplevel(int id, int *flagsp);
 
@@ -502,7 +503,7 @@ syntax_start(win_T *wp, linenr_T lnum)
     linenr_T   parsed_lnum;
     linenr_T   first_stored;
     int                dist;
-    static int changedtick = 0;        /* remember the last change ID */
+    static varnumber_T changedtick = 0;        /* remember the last change ID */
 
 #ifdef FEAT_CONCEAL
     current_sub_char = NUL;
@@ -515,13 +516,13 @@ syntax_start(win_T *wp, linenr_T lnum)
      */
     if (syn_block != wp->w_s
            || syn_buf != wp->w_buffer
-           || changedtick != syn_buf->b_changedtick)
+           || changedtick != CHANGEDTICK(syn_buf))
     {
        invalidate_current_state();
        syn_buf = wp->w_buffer;
        syn_block = wp->w_s;
     }
-    changedtick = syn_buf->b_changedtick;
+    changedtick = CHANGEDTICK(syn_buf);
     syn_win = wp;
 
     /*
@@ -1182,11 +1183,12 @@ syn_stack_free_block(synblock_T *block)
     void
 syn_stack_free_all(synblock_T *block)
 {
+#ifdef FEAT_FOLDING
     win_T      *wp;
+#endif
 
     syn_stack_free_block(block);
 
-
 #ifdef FEAT_FOLDING
     /* When using "syntax" fold method, must update all folds. */
     FOR_ALL_WINDOWS(wp)
@@ -1780,36 +1782,33 @@ syn_finish_line(
     stateitem_T        *cur_si;
     colnr_T    prev_current_col;
 
-    if (!current_finished)
+    while (!current_finished)
     {
-       while (!current_finished)
+       (void)syn_current_attr(syncing, FALSE, NULL, FALSE);
+       /*
+        * When syncing, and found some item, need to check the item.
+        */
+       if (syncing && current_state.ga_len)
        {
-           (void)syn_current_attr(syncing, FALSE, NULL, FALSE);
            /*
-            * When syncing, and found some item, need to check the item.
+            * Check for match with sync item.
             */
-           if (syncing && current_state.ga_len)
-           {
-               /*
-                * Check for match with sync item.
-                */
-               cur_si = &CUR_STATE(current_state.ga_len - 1);
-               if (cur_si->si_idx >= 0
-                       && (SYN_ITEMS(syn_block)[cur_si->si_idx].sp_flags
-                                             & (HL_SYNC_HERE|HL_SYNC_THERE)))
-                   return TRUE;
-
-               /* 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;
-               check_state_ends();
-               current_col = prev_current_col;
-           }
-           ++current_col;
+           cur_si = &CUR_STATE(current_state.ga_len - 1);
+           if (cur_si->si_idx >= 0
+                   && (SYN_ITEMS(syn_block)[cur_si->si_idx].sp_flags
+                                         & (HL_SYNC_HERE|HL_SYNC_THERE)))
+               return TRUE;
+
+           /* 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;
+           check_state_ends();
+           current_col = prev_current_col;
        }
+       ++current_col;
     }
     return FALSE;
 }
@@ -2306,7 +2305,7 @@ syn_current_attr(
            {
                line = syn_getcurline();
                if (((current_next_flags & HL_SKIPWHITE)
-                           && vim_iswhite(line[current_col]))
+                           && VIM_ISWHITE(line[current_col]))
                        || ((current_next_flags & HL_SKIPEMPTY)
                            && *line == NUL))
                    break;
@@ -3209,12 +3208,12 @@ syn_add_end_off(
        if (off > 0)
        {
            while (off-- > 0 && *p != NUL)
-               mb_ptr_adv(p);
+               MB_PTR_ADV(p);
        }
        else if (off < 0)
        {
            while (off++ < 0 && base < p)
-               mb_ptr_back(base, p);
+               MB_PTR_BACK(base, p);
        }
        col = (int)(p - base);
     }
@@ -3263,12 +3262,12 @@ syn_add_start_off(
        if (off > 0)
        {
            while (off-- && *p != NUL)
-               mb_ptr_adv(p);
+               MB_PTR_ADV(p);
        }
        else if (off < 0)
        {
            while (off++ && base < p)
-               mb_ptr_back(base, p);
+               MB_PTR_BACK(base, p);
        }
        col = (int)(p - base);
     }
@@ -3331,7 +3330,7 @@ syn_regexec(
 /*
  * Check one position in a line for a matching keyword.
  * The caller must check if a keyword can start at startcol.
- * Return it's ID if found, 0 otherwise.
+ * Return its ID if found, 0 otherwise.
  */
     static int
 check_keyword_id(
@@ -3434,7 +3433,14 @@ syn_cmd_conceal(exarg_T *eap UNUSED, int syncing UNUSED)
        return;
 
     next = skiptowhite(arg);
-    if (STRNICMP(arg, "on", 2) == 0 && next - arg == 2)
+    if (*arg == NUL)
+    {
+       if (curwin->w_s->b_syn_conceal)
+           MSG(_("syn conceal on"));
+       else
+           MSG(_("syn conceal off"));
+    }
+    else if (STRNICMP(arg, "on", 2) == 0 && next - arg == 2)
        curwin->w_s->b_syn_conceal = TRUE;
     else if (STRNICMP(arg, "off", 3) == 0 && next - arg == 3)
        curwin->w_s->b_syn_conceal = FALSE;
@@ -3457,7 +3463,14 @@ syn_cmd_case(exarg_T *eap, int syncing UNUSED)
        return;
 
     next = skiptowhite(arg);
-    if (STRNICMP(arg, "match", 5) == 0 && next - arg == 5)
+    if (*arg == NUL)
+    {
+       if (curwin->w_s->b_syn_ic)
+           MSG(_("syntax case ignore"));
+       else
+           MSG(_("syntax case match"));
+    }
+    else if (STRNICMP(arg, "match", 5) == 0 && next - arg == 5)
        curwin->w_s->b_syn_ic = FALSE;
     else if (STRNICMP(arg, "ignore", 6) == 0 && next - arg == 6)
        curwin->w_s->b_syn_ic = TRUE;
@@ -3479,7 +3492,16 @@ syn_cmd_spell(exarg_T *eap, int syncing UNUSED)
        return;
 
     next = skiptowhite(arg);
-    if (STRNICMP(arg, "toplevel", 8) == 0 && next - arg == 8)
+    if (*arg == NUL)
+    {
+       if (curwin->w_s->b_syn_spell == SYNSPL_TOP)
+           MSG(_("syntax spell toplevel"));
+       else if (curwin->w_s->b_syn_spell == SYNSPL_NOTOP)
+           MSG(_("syntax spell notoplevel"));
+       else
+           MSG(_("syntax spell default"));
+    }
+    else if (STRNICMP(arg, "toplevel", 8) == 0 && next - arg == 8)
        curwin->w_s->b_syn_spell = SYNSPL_TOP;
     else if (STRNICMP(arg, "notoplevel", 10) == 0 && next - arg == 10)
        curwin->w_s->b_syn_spell = SYNSPL_NOTOP;
@@ -3556,6 +3578,9 @@ syntax_clear(synblock_T *block)
     block->b_syn_ic = FALSE;       /* Use case, by default */
     block->b_syn_spell = SYNSPL_DEFAULT; /* default spell checking */
     block->b_syn_containedin = FALSE;
+#ifdef FEAT_CONCEAL
+    block->b_syn_conceal = FALSE;
+#endif
 
     /* free the keywords */
     clear_keywtab(&block->b_keywtab);
@@ -4042,7 +4067,7 @@ syn_list_one(
                    {0, NULL}
                };
 
-    attr = hl_attr(HLF_D);             /* highlight like directories */
+    attr = HL_ATTR(HLF_D);             /* highlight like directories */
 
     /* list the keywords for "id" */
     if (!syncing)
@@ -4153,11 +4178,11 @@ syn_list_cluster(int id)
     if (SYN_CLSTR(curwin->w_s)[id].scl_list != NULL)
     {
        put_id_list((char_u *)"cluster", SYN_CLSTR(curwin->w_s)[id].scl_list,
-                   hl_attr(HLF_D));
+                   HL_ATTR(HLF_D));
     }
     else
     {
-       msg_puts_attr((char_u *)"cluster", hl_attr(HLF_D));
+       msg_puts_attr((char_u *)"cluster", HL_ATTR(HLF_D));
        msg_puts((char_u *)"=NONE");
     }
 }
@@ -4543,7 +4568,8 @@ get_group_name(
 get_syn_options(
     char_u         *arg,               /* next argument to be checked */
     syn_opt_arg_T   *opt,              /* various things */
-    int                    *conceal_char UNUSED)
+    int                    *conceal_char UNUSED,
+    int                    skip)               /* TRUE if skipping over command */
 {
     char_u     *gname_start, *gname;
     int                syn_id;
@@ -4602,7 +4628,7 @@ get_syn_options(
            for (i = 0, len = 0; p[i] != NUL; i += 2, ++len)
                if (arg[len] != p[i] && arg[len] != p[i + 1])
                    break;
-           if (p[i] == NUL && (vim_iswhite(arg[len])
+           if (p[i] == NUL && (VIM_ISWHITE(arg[len])
                                    || (flagtab[fidx].argtype > 0
                                         ? arg[len] == '='
                                         : ends_excmd(arg[len]))))
@@ -4626,17 +4652,17 @@ get_syn_options(
                EMSG(_("E395: contains argument not accepted here"));
                return NULL;
            }
-           if (get_id_list(&arg, 8, &opt->cont_list) == FAIL)
+           if (get_id_list(&arg, 8, &opt->cont_list, skip) == FAIL)
                return NULL;
        }
        else if (flagtab[fidx].argtype == 2)
        {
-           if (get_id_list(&arg, 11, &opt->cont_in_list) == FAIL)
+           if (get_id_list(&arg, 11, &opt->cont_in_list, skip) == FAIL)
                return NULL;
        }
        else if (flagtab[fidx].argtype == 3)
        {
-           if (get_id_list(&arg, 9, &opt->next_list) == FAIL)
+           if (get_id_list(&arg, 9, &opt->next_list, skip) == FAIL)
                return NULL;
        }
        else if (flagtab[fidx].argtype == 11 && arg[5] == '=')
@@ -4846,7 +4872,10 @@ syn_cmd_keyword(exarg_T *eap, int syncing UNUSED)
 
     if (rest != NULL)
     {
-       syn_id = syn_check_group(arg, (int)(group_name_end - arg));
+       if (eap->skip)
+           syn_id = -1;
+       else
+           syn_id = syn_check_group(arg, (int)(group_name_end - arg));
        if (syn_id != 0)
            /* allocate a buffer, for removing backslashes in the keyword */
            keyword_copy = alloc((unsigned)STRLEN(rest) + 1);
@@ -4868,11 +4897,12 @@ syn_cmd_keyword(exarg_T *eap, int syncing UNUSED)
            p = keyword_copy;
            for ( ; rest != NULL && !ends_excmd(*rest); rest = skipwhite(rest))
            {
-               rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
+               rest = get_syn_options(rest, &syn_opt_arg, &conceal_char,
+                                                                   eap->skip);
                if (rest == NULL || ends_excmd(*rest))
                    break;
                /* Copy the keyword, removing backslashes, and add a NUL. */
-               while (*rest != NUL && !vim_iswhite(*rest))
+               while (*rest != NUL && !VIM_ISWHITE(*rest))
                {
                    if (*rest == '\\' && rest[1] != NUL)
                        ++rest;
@@ -4981,7 +5011,7 @@ syn_cmd_match(
     syn_opt_arg.cont_list = NULL;
     syn_opt_arg.cont_in_list = NULL;
     syn_opt_arg.next_list = NULL;
-    rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
+    rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip);
 
     /* get the pattern. */
     init_syn_patterns();
@@ -4991,7 +5021,7 @@ syn_cmd_match(
        syn_opt_arg.flags |= HL_HAS_EOL;
 
     /* Get options after the pattern */
-    rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
+    rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip);
 
     if (rest != NULL)          /* all arguments are valid */
     {
@@ -5117,13 +5147,13 @@ syn_cmd_region(
     while (rest != NULL && !ends_excmd(*rest))
     {
        /* Check for option arguments */
-       rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
+       rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip);
        if (rest == NULL || ends_excmd(*rest))
            break;
 
        /* must be a pattern or matchgroup then */
        key_end = rest;
-       while (*key_end && !vim_iswhite(*key_end) && *key_end != '=')
+       while (*key_end && !VIM_ISWHITE(*key_end) && *key_end != '=')
            ++key_end;
        vim_free(key);
        key = vim_strnsave_up(rest, (int)(key_end - rest));
@@ -5462,7 +5492,7 @@ syn_combine_list(short **clstr1, short **clstr2, int list_op)
 }
 
 /*
- * Lookup a syntax cluster name and return it's ID.
+ * Lookup a syntax cluster name and return its ID.
  * If it is not found, 0 is returned.
  */
     static int
@@ -5502,7 +5532,7 @@ syn_scl_namen2id(char_u *linep, int len)
 }
 
 /*
- * Find syntax cluster name in the table and return it's ID.
+ * Find syntax cluster name in the table and return its ID.
  * The argument is a pointer to the name and the length of the name.
  * If it doesn't exist yet, a new entry is created.
  * Return 0 for failure.
@@ -5526,7 +5556,7 @@ syn_check_cluster(char_u *pp, int len)
 }
 
 /*
- * Add new syntax cluster and return it's ID.
+ * Add new syntax cluster and return its ID.
  * "name" must be an allocated string, it will be consumed.
  * Return 0 for failure.
  */
@@ -5607,19 +5637,19 @@ syn_cmd_cluster(exarg_T *eap, int syncing UNUSED)
        for (;;)
        {
            if (STRNICMP(rest, "add", 3) == 0
-                   && (vim_iswhite(rest[3]) || rest[3] == '='))
+                   && (VIM_ISWHITE(rest[3]) || rest[3] == '='))
            {
                opt_len = 3;
                list_op = CLUSTER_ADD;
            }
            else if (STRNICMP(rest, "remove", 6) == 0
-                   && (vim_iswhite(rest[6]) || rest[6] == '='))
+                   && (VIM_ISWHITE(rest[6]) || rest[6] == '='))
            {
                opt_len = 6;
                list_op = CLUSTER_SUBTRACT;
            }
            else if (STRNICMP(rest, "contains", 8) == 0
-                       && (vim_iswhite(rest[8]) || rest[8] == '='))
+                       && (VIM_ISWHITE(rest[8]) || rest[8] == '='))
            {
                opt_len = 8;
                list_op = CLUSTER_REPLACE;
@@ -5628,13 +5658,16 @@ syn_cmd_cluster(exarg_T *eap, int syncing UNUSED)
                break;
 
            clstr_list = NULL;
-           if (get_id_list(&rest, opt_len, &clstr_list) == FAIL)
+           if (get_id_list(&rest, opt_len, &clstr_list, eap->skip) == FAIL)
            {
                EMSG2(_(e_invarg2), rest);
                break;
            }
-           syn_combine_list(&SYN_CLSTR(curwin->w_s)[scl_id].scl_list,
+           if (scl_id >= 0)
+               syn_combine_list(&SYN_CLSTR(curwin->w_s)[scl_id].scl_list,
                             &clstr_list, list_op);
+           else
+               vim_free(clstr_list);
            got_clstr = TRUE;
        }
 
@@ -5757,7 +5790,7 @@ get_syn_pattern(char_u *arg, synpat_T *ci)
        }
     } while (idx >= 0);
 
-    if (!ends_excmd(*end) && !vim_iswhite(*end))
+    if (!ends_excmd(*end) && !VIM_ISWHITE(*end))
     {
        EMSG2(_("E402: Garbage after pattern: %s"), arg);
        return NULL;
@@ -5931,8 +5964,9 @@ syn_cmd_sync(exarg_T *eap, int syncing UNUSED)
 get_id_list(
     char_u     **arg,
     int                keylen,         /* length of keyword */
-    short      **list)         /* where to store the resulting list, if not
+    short      **list,         /* where to store the resulting list, if not
                                   NULL, the list is silently skipped! */
+    int                skip)
 {
     char_u     *p = NULL;
     char_u     *end;
@@ -5977,7 +6011,7 @@ get_id_list(
        count = 0;
        while (!ends_excmd(*p))
        {
-           for (end = p; *end && !vim_iswhite(*end) && *end != ','; ++end)
+           for (end = p; *end && !VIM_ISWHITE(*end) && *end != ','; ++end)
                ;
            name = alloc((int)(end - p + 3));       /* leave room for "^$" */
            if (name == NULL)
@@ -6000,7 +6034,8 @@ get_id_list(
                }
                if (count != 0)
                {
-                   EMSG2(_("E408: %s must be first in contains list"), name + 1);
+                   EMSG2(_("E408: %s must be first in contains list"),
+                                                                    name + 1);
                    failed = TRUE;
                    vim_free(name);
                    break;
@@ -6015,7 +6050,10 @@ get_id_list(
            }
            else if (name[1] == '@')
            {
-               id = syn_check_cluster(name + 2, (int)(end - p - 1));
+               if (skip)
+                   id = -1;
+               else
+                   id = syn_check_cluster(name + 2, (int)(end - p - 1));
            }
            else
            {
@@ -6383,7 +6421,9 @@ syntax_present(win_T *win)
 static enum
 {
     EXP_SUBCMD,            /* expand ":syn" sub-commands */
-    EXP_CASE       /* expand ":syn case" arguments */
+    EXP_CASE,      /* expand ":syn case" arguments */
+    EXP_SPELL,     /* expand ":syn spell" arguments */
+    EXP_SYNC       /* expand ":syn sync" arguments */
 } expand_what;
 
 /*
@@ -6434,6 +6474,10 @@ set_context_in_syntax_cmd(expand_T *xp, char_u *arg)
                xp->xp_context = EXPAND_NOTHING;
            else if (STRNICMP(arg, "case", p - arg) == 0)
                expand_what = EXP_CASE;
+           else if (STRNICMP(arg, "spell", p - arg) == 0)
+               expand_what = EXP_SPELL;
+           else if (STRNICMP(arg, "sync", p - arg) == 0)
+               expand_what = EXP_SYNC;
            else if (  STRNICMP(arg, "keyword", p - arg) == 0
                    || STRNICMP(arg, "region", p - arg) == 0
                    || STRNICMP(arg, "match", p - arg) == 0
@@ -6445,8 +6489,6 @@ set_context_in_syntax_cmd(expand_T *xp, char_u *arg)
     }
 }
 
-static char *(case_args[]) = {"match", "ignore", NULL};
-
 /*
  * Function given to ExpandGeneric() to obtain the list syntax names for
  * expansion.
@@ -6454,9 +6496,31 @@ static char *(case_args[]) = {"match", "ignore", NULL};
     char_u *
 get_syntax_name(expand_T *xp UNUSED, int idx)
 {
-    if (expand_what == EXP_SUBCMD)
-       return (char_u *)subcommands[idx].name;
-    return (char_u *)case_args[idx];
+    switch (expand_what)
+    {
+       case EXP_SUBCMD:
+           return (char_u *)subcommands[idx].name;
+       case EXP_CASE:
+       {
+           static char *case_args[] = {"match", "ignore", NULL};
+           return (char_u *)case_args[idx];
+       }
+       case EXP_SPELL:
+       {
+           static char *spell_args[] =
+               {"toplevel", "notoplevel", "default", NULL};
+           return (char_u *)spell_args[idx];
+       }
+       case EXP_SYNC:
+       {
+           static char *sync_args[] =
+               {"ccomment", "clear", "fromstart",
+                "linebreaks=", "linecont", "lines=", "match",
+                "maxlines=", "minlines=", "region", NULL};
+           return (char_u *)sync_args[idx];
+       }
+    }
+    return NULL;
 }
 
 #endif /* FEAT_CMDL_COMPL */
@@ -6704,8 +6768,10 @@ syntime_report(void)
        }
     }
 
-    /* sort on total time */
-    qsort(ga.ga_data, (size_t)ga.ga_len, sizeof(time_entry_T),
+    /* Sort on total time. Skip if there are no items to avoid passing NULL
+     * pointer to qsort(). */
+    if (ga.ga_len > 1)
+       qsort(ga.ga_data, (size_t)ga.ga_len, sizeof(time_entry_T),
                                                         syn_compare_syntime);
 
     MSG_PUTS_TITLE(_("  TOTAL      COUNT  MATCH   SLOWEST     AVERAGE   NAME               PATTERN"));
@@ -7265,6 +7331,7 @@ do_highlight(
 #ifdef FEAT_EVAL
                HL_TABLE()[from_id - 1].sg_scriptID = current_SID;
 #endif
+               HL_TABLE()[from_id - 1].sg_cleared = FALSE;
                redraw_all_later(SOME_VALID);
            }
        }
@@ -7396,7 +7463,7 @@ do_highlight(
         * Isolate the key ("term", "ctermfg", "ctermbg", "font", "guifg" or
         * "guibg").
         */
-       while (*linep && !vim_iswhite(*linep) && *linep != '=')
+       while (*linep && !VIM_ISWHITE(*linep) && *linep != '=')
            ++linep;
        vim_free(key);
        key = vim_strnsave_up(key_start, (int)(linep - key_start));
@@ -7682,7 +7749,7 @@ do_highlight(
                    break;
                }
 
-               /* Use the _16 table to check if its a valid color name. */
+               /* Use the _16 table to check if it's a valid color name. */
                color = color_numbers_16[i];
                if (color >= 0)
                {
@@ -7972,6 +8039,7 @@ do_highlight(
            error = TRUE;
            break;
        }
+       HL_TABLE()[idx].sg_cleared = FALSE;
 
        /*
         * When highlighting has been given for a group, don't link it.
@@ -8098,7 +8166,7 @@ hl_has_settings(int idx, int check_link)
            || HL_TABLE()[idx].sg_gui_fg_name != NULL
            || HL_TABLE()[idx].sg_gui_bg_name != NULL
            || HL_TABLE()[idx].sg_gui_sp_name != NULL
-           || HL_TABLE()[idx].sg_font_name != NUL
+           || HL_TABLE()[idx].sg_font_name != NULL
 #endif
            || (check_link && (HL_TABLE()[idx].sg_set & SG_LINK)));
 }
@@ -8109,6 +8177,8 @@ hl_has_settings(int idx, int check_link)
     static void
 highlight_clear(int idx)
 {
+    HL_TABLE()[idx].sg_cleared = TRUE;
+
     HL_TABLE()[idx].sg_term = 0;
     vim_free(HL_TABLE()[idx].sg_start);
     HL_TABLE()[idx].sg_start = NULL;
@@ -8765,6 +8835,10 @@ hl_combine_attr(int char_attr, int prim_attr)
        else
        {
            vim_memset(&new_en, 0, sizeof(new_en));
+#ifdef FEAT_TERMGUICOLORS
+           new_en.ae_u.cterm.bg_rgb = INVALCOLOR;
+           new_en.ae_u.cterm.fg_rgb = INVALCOLOR;
+#endif
            if (char_attr <= HL_ALL)
                new_en.ae_attr = char_attr;
        }
@@ -8922,7 +8996,7 @@ highlight_list_one(int id)
     {
        (void)syn_list_header(didh, 9999, id);
        didh = TRUE;
-       msg_puts_attr((char_u *)"links to", hl_attr(HLF_D));
+       msg_puts_attr((char_u *)"links to", HL_ATTR(HLF_D));
        msg_putchar(' ');
        msg_outtrans(HL_TABLE()[HL_TABLE()[id - 1].sg_link - 1].sg_name);
     }
@@ -8979,8 +9053,8 @@ highlight_list_arg(
        {
            if (*name != NUL)
            {
-               MSG_PUTS_ATTR(name, hl_attr(HLF_D));
-               MSG_PUTS_ATTR("=", hl_attr(HLF_D));
+               MSG_PUTS_ATTR(name, HL_ATTR(HLF_D));
+               MSG_PUTS_ATTR("=", HL_ATTR(HLF_D));
            }
            msg_outtrans(ts);
        }
@@ -9269,7 +9343,7 @@ set_hl_attr(
 }
 
 /*
- * Lookup a highlight group name and return it's ID.
+ * Lookup a highlight group name and return its ID.
  * If it is not found, 0 is returned.
  */
     int
@@ -9334,7 +9408,7 @@ syn_namen2id(char_u *linep, int len)
 }
 
 /*
- * Find highlight group name in the table and return it's ID.
+ * Find highlight group name in the table and return its ID.
  * The argument is a pointer to the name and the length of the name.
  * If it doesn't exist yet, a new entry is created.
  * Return 0 for failure.
@@ -9358,7 +9432,7 @@ syn_check_group(char_u *pp, int len)
 }
 
 /*
- * Add new highlight group and return it's ID.
+ * Add new highlight group and return its ID.
  * "name" must be an allocated string, it will be consumed.
  * Return 0 for failure.
  */
@@ -9380,7 +9454,7 @@ syn_add_group(char_u *name)
        {
            /* This is an error, but since there previously was no check only
             * give a warning. */
-           msg_source(hl_attr(HLF_W));
+           msg_source(HL_ATTR(HLF_W));
            MSG(_("W18: Invalid character in group name"));
            break;
        }
@@ -9644,7 +9718,7 @@ highlight_changed(void)
            attr = 0;
            for ( ; *p && *p != ','; ++p)           /* parse upto comma */
            {
-               if (vim_iswhite(*p))                /* ignore white space */
+               if (VIM_ISWHITE(*p))                /* ignore white space */
                    continue;
 
                if (attr > HL_ALL)  /* Combination with ':' is not allowed. */
@@ -9855,7 +9929,7 @@ highlight_list(void)
     int                i;
 
     for (i = 10; --i >= 0; )
-       highlight_list_two(i, hl_attr(HLF_D));
+       highlight_list_two(i, HL_ATTR(HLF_D));
     for (i = 40; --i >= 0; )
        highlight_list_two(99, 0);
 }
@@ -9875,11 +9949,28 @@ highlight_list_two(int cnt, int attr)
     || defined(FEAT_SIGNS) || defined(PROTO)
 /*
  * Function given to ExpandGeneric() to obtain the list of group names.
- * Also used for synIDattr() function.
  */
     char_u *
 get_highlight_name(expand_T *xp UNUSED, int idx)
 {
+    return get_highlight_name_ext(xp, idx, TRUE);
+}
+
+/*
+ * Obtain a highlight group name.
+ * When "skip_cleared" is TRUE don't return a cleared entry.
+ */
+    char_u *
+get_highlight_name_ext(expand_T *xp UNUSED, int idx, int skip_cleared)
+{
+    if (idx < 0)
+       return NULL;
+
+    /* Items are never removed from the table, skip the ones that were
+     * cleared. */
+    if (skip_cleared && idx < highlight_ga.ga_len && HL_TABLE()[idx].sg_cleared)
+       return (char_u *)"";
+
 #ifdef FEAT_CMDL_COMPL
     if (idx == highlight_ga.ga_len && include_none != 0)
        return (char_u *)"none";
@@ -9892,7 +9983,7 @@ get_highlight_name(expand_T *xp UNUSED, int idx)
                                                         && include_link != 0)
        return (char_u *)"clear";
 #endif
-    if (idx < 0 || idx >= highlight_ga.ga_len)
+    if (idx >= highlight_ga.ga_len)
        return NULL;
     return HL_TABLE()[idx].sg_name;
 }
index 14fdcf8..d6d1df2 100644 (file)
--- a/src/tag.c
+++ b/src/tag.c
@@ -35,19 +35,16 @@ typedef struct tag_pointers
 } tagptrs_T;
 
 /*
- * The matching tags are first stored in ga_match[].  In which one depends on
- * the priority of the match.
- * At the end, the matches from ga_match[] are concatenated, to make a list
+ * The matching tags are first stored in one of the hash tables.  In
+ * which one depends on the priority of the match.
+ * ht_match[] is used to find duplicates, ga_match[] to keep them in sequence.
+ * At the end, all the matches from ga_match[] are concatenated, to make a list
  * sorted on priority.
  */
 #define MT_ST_CUR      0               /* static match in current file */
 #define MT_GL_CUR      1               /* global match in current file */
 #define MT_GL_OTH      2               /* global match in other file */
 #define MT_ST_OTH      3               /* static match in other file */
-#define MT_IC_ST_CUR   4               /* icase static match in current file */
-#define MT_IC_GL_CUR   5               /* icase global match in current file */
-#define MT_IC_GL_OTH   6               /* icase global match in other file */
-#define MT_IC_ST_OTH   7               /* icase static match in other file */
 #define MT_IC_OFF      4               /* add for icase match */
 #define MT_RE_OFF      8               /* add for regexp match */
 #define MT_MASK                7               /* mask for printing priority */
@@ -181,7 +178,7 @@ do_tag(
     free_string_option(nofile_fname);
     nofile_fname = NULL;
 
-    clearpos(&saved_fmark.mark);       /* shutup gcc 4.0 */
+    CLEAR_POS(&saved_fmark.mark);      /* shutup gcc 4.0 */
     saved_fmark.fnum = 0;
 
     /*
@@ -608,10 +605,10 @@ do_tag(
                if (msg_col == 0)
                    msg_didout = FALSE; /* overwrite previous message */
                msg_start();
-               MSG_PUTS_ATTR(_("  # pri kind tag"), hl_attr(HLF_T));
+               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));
+               MSG_PUTS_ATTR(_("file\n"), HL_ATTR(HLF_T));
 
                for (i = 0; i < num_matches && !got_int; ++i)
                {
@@ -636,7 +633,7 @@ do_tag(
                    msg_advance(13);
                    msg_outtrans_len_attr(tagp.tagname,
                                       (int)(tagp.tagname_end - tagp.tagname),
-                                                             hl_attr(HLF_T));
+                                                             HL_ATTR(HLF_T));
                    msg_putchar(' ');
                    taglen_advance(taglen);
 
@@ -645,7 +642,7 @@ do_tag(
                    p = tag_full_fname(&tagp);
                    if (p != NULL)
                    {
-                       msg_puts_long_attr(p, hl_attr(HLF_D));
+                       msg_puts_long_attr(p, HL_ATTR(HLF_D));
                        vim_free(p);
                    }
                    if (msg_col > 0)
@@ -680,7 +677,7 @@ do_tag(
                                continue;
                            }
                            /* print all other extra fields */
-                           attr = hl_attr(HLF_CM);
+                           attr = HL_ATTR(HLF_CM);
                            while (*p && *p != '\r' && *p != '\n')
                            {
                                if (msg_col + ptr2cells(p) >= Columns)
@@ -742,7 +739,7 @@ do_tag(
                        /* skip backslash used for escaping a command char or
                         * a backslash */
                        if (*p == '\\' && (*(p + 1) == *tagp.command
-                                       || *(p + 1) == '\\'))
+                                       || *(p + 1) == '\\'))
                            ++p;
 
                        if (*p == TAB)
@@ -1006,7 +1003,7 @@ do_tag(
                                                           && num_matches > 1)
                {
                    if (ic)
-                       msg_attr(IObuff, hl_attr(HLF_W));
+                       msg_attr(IObuff, HL_ATTR(HLF_W));
                    else
                        msg(IObuff);
                    msg_scroll = TRUE;  /* don't overwrite this message */
@@ -1143,7 +1140,7 @@ do_tags(exarg_T *eap UNUSED)
                tagstack[i].fmark.mark.lnum);
            msg_outtrans(IObuff);
            msg_outtrans_attr(name, tagstack[i].fmark.fnum == curbuf->b_fnum
-                                                       ? hl_attr(HLF_D) : 0);
+                                                       ? HL_ATTR(HLF_D) : 0);
            vim_free(name);
        }
        out_flush();                /* show one line at a time */
@@ -1260,6 +1257,7 @@ prepare_pats(pat_T *pats, int has_re)
  * 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
  */
     int
 find_tags(
@@ -1341,12 +1339,10 @@ find_tags(
     int                is_etag;                /* current file is emaces style */
 #endif
 
-    struct match_found
-    {
-       int     len;            /* nr of chars of match[] to be compared */
-       char_u  match[1];       /* actually longer */
-    } *mfp, *mfp2;
-    garray_T   ga_match[MT_COUNT];
+    char_u     *mfp;
+    garray_T   ga_match[MT_COUNT];     /* stores matches in sequence */
+    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;
     int                mtt;
@@ -1356,6 +1352,7 @@ find_tags(
     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[] */
+    int                is_txt = FALSE;                 /* flag of file extension */
 #endif
 
     pat_T      orgpat;                 /* holds unconverted pattern info */
@@ -1388,7 +1385,7 @@ find_tags(
      */
     switch (curbuf->b_tc_flags ? curbuf->b_tc_flags : tc_flags)
     {
-       case TC_FOLLOWIC:                break;
+       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;
@@ -1401,16 +1398,19 @@ find_tags(
     vimconv.vc_type = CONV_NONE;
 #endif
 
-/*
- * Allocate memory for the buffers that are used
- */
+    /*
    * Allocate memory for the buffers that are used
    */
     lbuf = alloc(lbuf_size);
     tag_fname = alloc(MAXPATHL + 1);
 #ifdef FEAT_EMACS_TAGS
     ebuf = alloc(LSIZE);
 #endif
     for (mtt = 0; mtt < MT_COUNT; ++mtt)
-       ga_init2(&ga_match[mtt], (int)sizeof(struct match_found *), 100);
+    {
+       ga_init2(&ga_match[mtt], (int)sizeof(char_u *), 100);
+       hash_init(&ht_match[mtt]);
+    }
 
     /* check for out of memory situation */
     if (lbuf == NULL || tag_fname == NULL
@@ -1429,6 +1429,14 @@ find_tags(
      */
     if (help_only)                             /* want tags from help file */
        curbuf->b_help = TRUE;                  /* will be restored later */
+#ifdef FEAT_CSCOPE
+    else if (use_cscope)
+    {
+       /* Make sure we don't mix help and cscope, confuses Coverity. */
+       help_only = FALSE;
+       curbuf->b_help = FALSE;
+    }
+#endif
 
     orgpat.len = (int)STRLEN(pat);
 #ifdef FEAT_MULTI_LANG
@@ -1476,6 +1484,15 @@ find_tags(
      * When the tag file is case-fold sorted, it is either one or the other.
      * Only ignore case when TAG_NOIC not used or 'ignorecase' set.
      */
+#ifdef FEAT_MULTI_LANG
+    /* Set a flag if the file extension is .txt */
+    if ((flags & TAG_KEEP_LANG)
+           && help_lang_find == NULL
+           && curbuf->b_fname != NULL
+           && (i = (int)STRLEN(curbuf->b_fname)) > 4
+           && STRICMP(curbuf->b_fname + i - 4, ".txt") == 0)
+       is_txt = TRUE;
+#endif
 #ifdef FEAT_TAG_BINS
     orgpat.regmatch.rm_ic = ((p_ic || !noic)
                                && (findall || orgpat.headlen == 0 || !p_tbs));
@@ -1509,14 +1526,19 @@ find_tags(
 #ifdef FEAT_MULTI_LANG
            if (curbuf->b_help)
            {
-               /* Prefer help tags according to 'helplang'.  Put the
-                * two-letter language name in help_lang[]. */
-               i = (int)STRLEN(tag_fname);
-               if (i > 3 && tag_fname[i - 3] == '-')
-                   STRCPY(help_lang, tag_fname + i - 2);
-               else
+               /* Keep en if the file extension is .txt*/
+               if (is_txt)
                    STRCPY(help_lang, "en");
-
+               else
+               {
+                   /* Prefer help tags according to 'helplang'.  Put the
+                    * two-letter language name in help_lang[]. */
+                   i = (int)STRLEN(tag_fname);
+                   if (i > 3 && tag_fname[i - 3] == '-')
+                       STRCPY(help_lang, tag_fname + i - 2);
+                   else
+                       STRCPY(help_lang, "en");
+               }
                /* When searching for a specific language skip tags files
                 * for other languages. */
                if (help_lang_find != NULL
@@ -1744,8 +1766,13 @@ line_read_in:
            /*
             * Emacs tags line with CTRL-L: New file name on next line.
             * The file name is followed by a ','.
+            * Remember etag file name in ebuf.
             */
-           if (*lbuf == Ctrl_L)        /* remember etag file name in ebuf */
+           if (*lbuf == Ctrl_L
+# ifdef FEAT_CSCOPE
+                               && !use_cscope
+# endif
+                               )
            {
                is_etag = 1;            /* in case at the start */
                state = TS_LINEAR;
@@ -1978,7 +2005,7 @@ parse_line:
 #endif
                        if (       fnamencmp(lbuf, tagp.fname, p - lbuf) == 0
 #ifdef FEAT_TAG_ANYWHITE
-                               && vim_iswhite(tagp.fname[p - lbuf])
+                               && VIM_ISWHITE(tagp.fname[p - lbuf])
 #else
                                && tagp.fname[p - lbuf] == TAB
 #endif
@@ -2191,10 +2218,12 @@ parse_line:
            }
 
            /*
-            * If a match is found, add it to ga_match[].
+            * If a match is found, add it to ht_match[] and ga_match[].
             */
            if (match)
            {
+               int len = 0;
+
 #ifdef FEAT_CSCOPE
                if (use_cscope)
                {
@@ -2247,179 +2276,177 @@ parse_line:
                }
 
                /*
-                * Add the found match in ga_match[mtt], avoiding duplicates.
+                * 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 (ga_grow(&ga_match[mtt], 1) == OK)
+               if (help_only)
                {
-                   int len;
-                   int heuristic;
-
-                   if (help_only)
-                   {
 #ifdef FEAT_MULTI_LANG
 # define ML_EXTRA 3
 #else
 # define ML_EXTRA 0
 #endif
-                       /*
-                        * Append the help-heuristic number after the
-                        * tagname, for sorting it later.
-                        */
-                       *tagp.tagname_end = NUL;
-                       len = (int)(tagp.tagname_end - tagp.tagname);
-                       mfp = (struct match_found *)
-                                alloc((int)sizeof(struct match_found) + len
-                                                            + 10 + ML_EXTRA);
-                       if (mfp != NULL)
-                       {
-                           /* "len" includes the language and the NUL, but
-                            * not the priority. */
-                           mfp->len = len + ML_EXTRA + 1;
-#define ML_HELP_LEN 6
-                           p = mfp->match;
-                           STRCPY(p, tagp.tagname);
+                   /*
+                    * Append the help-heuristic number after the tagname, for
+                    * sorting it later.  The heuristic is ignored for
+                    * detecting duplicates.
+                    * The format is {tagname}@{lang}NUL{heuristic}NUL
+                    */
+                   *tagp.tagname_end = NUL;
+                   len = (int)(tagp.tagname_end - tagp.tagname);
+                   mfp = (char_u *)alloc((int)sizeof(char_u)
+                                                   + len + 10 + ML_EXTRA + 1);
+                   if (mfp != NULL)
+                   {
+                       int heuristic;
+
+                       p = mfp;
+                       STRCPY(p, tagp.tagname);
 #ifdef FEAT_MULTI_LANG
-                           p[len] = '@';
-                           STRCPY(p + len + 1, help_lang);
+                       p[len] = '@';
+                       STRCPY(p + len + 1, help_lang);
 #endif
 
-                           heuristic = help_heuristic(tagp.tagname,
-                                       match_re ? matchoff : 0, !match_no_ic);
+                       heuristic = help_heuristic(tagp.tagname,
+                                   match_re ? matchoff : 0, !match_no_ic);
 #ifdef FEAT_MULTI_LANG
-                           heuristic += help_pri;
+                       heuristic += help_pri;
 #endif
-                           sprintf((char *)p + len + 1 + ML_EXTRA, "%06d",
-                                                                  heuristic);
-                       }
-                       *tagp.tagname_end = TAB;
+                       sprintf((char *)p + len + 1 + ML_EXTRA, "%06d",
+                                                              heuristic);
                    }
-                   else if (name_only)
+                   *tagp.tagname_end = TAB;
+               }
+               else if (name_only)
+               {
+                   if (get_it_again)
                    {
-                       if (get_it_again)
-                       {
-                           char_u *temp_end = tagp.command;
+                       char_u *temp_end = tagp.command;
 
-                           if (*temp_end == '/')
-                               while (*temp_end && *temp_end != '\r'
-                                       && *temp_end != '\n'
-                                       && *temp_end != '$')
-                                   temp_end++;
+                       if (*temp_end == '/')
+                           while (*temp_end && *temp_end != '\r'
+                                   && *temp_end != '\n'
+                                   && *temp_end != '$')
+                               temp_end++;
 
-                           if (tagp.command + 2 < temp_end)
-                           {
-                               len = (int)(temp_end - tagp.command - 2);
-                               mfp = (struct match_found *)alloc(
-                                       (int)sizeof(struct match_found) + len);
-                               if (mfp != NULL)
-                               {
-                                   mfp->len = len + 1; /* include the NUL */
-                                   p = mfp->match;
-                                   vim_strncpy(p, tagp.command + 2, len);
-                               }
-                           }
-                           else
-                               mfp = NULL;
-                           get_it_again = FALSE;
-                       }
-                       else
+                       if (tagp.command + 2 < temp_end)
                        {
-                           len = (int)(tagp.tagname_end - tagp.tagname);
-                           mfp = (struct match_found *)alloc(
-                                      (int)sizeof(struct match_found) + len);
+                           len = (int)(temp_end - tagp.command - 2);
+                           mfp = (char_u *)alloc(len + 2);
                            if (mfp != NULL)
-                           {
-                               mfp->len = len + 1; /* include the NUL */
-                               p = mfp->match;
-                               vim_strncpy(p, tagp.tagname, len);
-                           }
-
-                           /* if wanted, re-read line to get long form too */
-                           if (State & INSERT)
-                               get_it_again = p_sft;
+                               vim_strncpy(mfp, tagp.command + 2, len);
                        }
+                       else
+                           mfp = NULL;
+                       get_it_again = FALSE;
                    }
                    else
                    {
-                       /* Save the tag in a buffer.
-                        * 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>
-                        */
-                       len = (int)STRLEN(tag_fname)
-                                                + (int)STRLEN(lbuf) + 3;
+                       len = (int)(tagp.tagname_end - tagp.tagname);
+                       mfp = (char_u *)alloc((int)sizeof(char_u) + len + 1);
+                       if (mfp != NULL)
+                           vim_strncpy(mfp, tagp.tagname, len);
+
+                       /* if wanted, re-read line to get long form too */
+                       if (State & INSERT)
+                           get_it_again = p_sft;
+                   }
+               }
+               else
+               {
+#define TAG_SEP 0x02
+                   size_t tag_fname_len = STRLEN(tag_fname);
 #ifdef FEAT_EMACS_TAGS
-                       if (is_etag)
-                           len += (int)STRLEN(ebuf) + 1;
-                       else
-                           ++len;
+                   size_t ebuf_len = 0;
 #endif
-                       mfp = (struct match_found *)alloc(
-                                      (int)sizeof(struct match_found) + len);
-                       if (mfp != NULL)
-                       {
-                           mfp->len = len;
-                           p = mfp->match;
-                           p[0] = mtt;
-                           STRCPY(p + 1, tag_fname);
+
+                   /* Save the tag in a buffer.
+                    * Use 0x02 to separate fields (Can't use NUL because the
+                    * hash key is terminated by NUL, or Ctrl_A because that is
+                    * part of some Emacs tag files -- see parse_tag_line).
+                    * Emacs tag: <mtt><tag_fname><0x02><ebuf><0x02><lbuf><NUL>
+                    * other tag: <mtt><tag_fname><0x02><0x02><lbuf><NUL>
+                    * without Emacs tags: <mtt><tag_fname><0x02><lbuf><NUL>
+                    * Here <mtt> is the "mtt" value plus 1 to avoid NUL.
+                    */
+                   len = (int)tag_fname_len + (int)STRLEN(lbuf) + 3;
+#ifdef FEAT_EMACS_TAGS
+                   if (is_etag)
+                   {
+                       ebuf_len = STRLEN(ebuf);
+                       len += (int)ebuf_len + 1;
+                   }
+                   else
+                       ++len;
+#endif
+                   mfp = (char_u *)alloc((int)sizeof(char_u) + len + 1);
+                   if (mfp != NULL)
+                   {
+                       p = mfp;
+                       p[0] = mtt + 1;
+                       STRCPY(p + 1, tag_fname);
 #ifdef BACKSLASH_IN_FILENAME
-                           /* Ignore differences in slashes, avoid adding
-                            * both path/file and path\file. */
-                           slash_adjust(p + 1);
+                       /* Ignore differences in slashes, avoid adding
+                        * both path/file and path\file. */
+                       slash_adjust(p + 1);
 #endif
-                           s = p + 1 + STRLEN(tag_fname) + 1;
+                       p[tag_fname_len + 1] = TAG_SEP;
+                       s = p + 1 + tag_fname_len + 1;
 #ifdef FEAT_EMACS_TAGS
-                           if (is_etag)
-                           {
-                               STRCPY(s, ebuf);
-                               s += STRLEN(ebuf) + 1;
-                           }
-                           else
-                               *s++ = NUL;
-#endif
-                           STRCPY(s, lbuf);
+                       if (is_etag)
+                       {
+                           STRCPY(s, ebuf);
+                           s[ebuf_len] = TAG_SEP;
+                           s += ebuf_len + 1;
                        }
+                       else
+                           *s++ = TAG_SEP;
+#endif
+                       STRCPY(s, lbuf);
                    }
+               }
 
-                   if (mfp != NULL)
-                   {
-                       /*
-                        * Don't add identical matches.
-                        * This can take a lot of time when finding many
-                        * matches, check for CTRL-C now and then.
-                        * Add all cscope tags, because they are all listed.
-                        */
+               if (mfp != NULL)
+               {
+                   hashitem_T  *hi;
+
+                   /*
+                    * Don't add identical matches.
+                    * Add all cscope tags, because they are all listed.
+                    * "mfp" is used as a hash key, there is a NUL byte to end
+                    * the part matters for comparing, more bytes may follow
+                    * after it.  E.g. help tags store the priority after the
+                    * NUL.
+                    */
 #ifdef FEAT_CSCOPE
-                       if (use_cscope)
-                           i = -1;
-                       else
+                   if (use_cscope)
+                       hash++;
+                   else
 #endif
-                         for (i = ga_match[mtt].ga_len; --i >= 0 && !got_int; )
-                         {
-                             mfp2 = ((struct match_found **)
-                                                 (ga_match[mtt].ga_data))[i];
-                             if (mfp2->len == mfp->len
-                                     && vim_memcmp(mfp2->match, mfp->match,
-                                                      (size_t)mfp->len) == 0)
-                                 break;
-                             fast_breakcheck();
-                         }
-                       if (i < 0)
+                       hash = hash_hash(mfp);
+                   hi = hash_lookup(&ht_match[mtt], mfp, hash);
+                   if (HASHITEM_EMPTY(hi))
+                   {
+                       if (hash_add_item(&ht_match[mtt], hi, mfp, hash)
+                                                                      == FAIL
+                                      || ga_grow(&ga_match[mtt], 1) != OK)
                        {
-                           ((struct match_found **)(ga_match[mtt].ga_data))
-                                              [ga_match[mtt].ga_len++] = mfp;
-                           ++match_count;
+                           /* Out of memory! Just forget about the rest. */
+                           retval = OK;
+                           stop_searching = TRUE;
+                           break;
                        }
                        else
-                           vim_free(mfp);
+                       {
+                           ((char_u **)(ga_match[mtt].ga_data))
+                                               [ga_match[mtt].ga_len++] = mfp;
+                           ++match_count;
+                       }
                    }
-               }
-               else    /* Out of memory! Just forget about the rest. */
-               {
-                   retval = OK;
-                   stop_searching = TRUE;
-                   break;
+                   else
+                       /* duplicate tag, drop it */
+                       vim_free(mfp);
                }
            }
 #ifdef FEAT_CSCOPE
@@ -2533,20 +2560,27 @@ findtag_end:
     {
        for (i = 0; i < ga_match[mtt].ga_len; ++i)
        {
-           mfp = ((struct match_found **)(ga_match[mtt].ga_data))[i];
+           mfp = ((char_u **)(ga_match[mtt].ga_data))[i];
            if (matches == NULL)
                vim_free(mfp);
            else
            {
-               /* To avoid allocating memory again we turn the struct
-                * match_found into a string.  For help the priority was not
-                * included in the length. */
-               mch_memmove(mfp, mfp->match,
-                        (size_t)(mfp->len + (help_only ? ML_HELP_LEN : 0)));
+               if (!name_only)
+               {
+                   /* Change mtt back to zero-based. */
+                   *mfp = *mfp - 1;
+
+                   /* change the TAG_SEP back to NUL */
+                   for (p = mfp + 1; *p != NUL; ++p)
+                       if (*p == TAG_SEP)
+                           *p = NUL;
+               }
                matches[match_count++] = (char_u *)mfp;
            }
        }
+
        ga_clear(&ga_match[mtt]);
+       hash_clear(&ht_match[mtt]);
     }
 
     *matchesp = matches;
@@ -3170,8 +3204,12 @@ jumpto_tag(
      * open a new tab page. */
     if (postponed_split || cmdmod.tab != 0)
     {
-       win_split(postponed_split > 0 ? postponed_split : 0,
-                                                      postponed_split_flags);
+       if (win_split(postponed_split > 0 ? postponed_split : 0,
+                                               postponed_split_flags) == FAIL)
+       {
+           --RedrawingDisabled;
+           goto erret;
+       }
        RESET_BINDING(curwin);
     }
 #endif
@@ -3511,7 +3549,7 @@ simplify_filename(char_u *filename)
                tail = p + 1;
                if (p[1] != NUL)
                    while (vim_ispathsep(*tail))
-                       mb_ptr_adv(tail);
+                       MB_PTR_ADV(tail);
                else if (p > start)
                    --p;                /* strip preceding path separator */
                STRMOVE(p, tail);
@@ -3523,7 +3561,7 @@ simplify_filename(char_u *filename)
            /* Skip to after ".." or "../" or "..///". */
            tail = p + 2;
            while (vim_ispathsep(*tail))
-               mb_ptr_adv(tail);
+               MB_PTR_ADV(tail);
 
            if (components > 0)         /* strip one preceding component */
            {
@@ -3550,7 +3588,7 @@ simplify_filename(char_u *filename)
                    --p;
                    /* Skip back to after previous '/'. */
                    while (p > start && !after_pathsep(start, p))
-                       mb_ptr_back(start, p);
+                       MB_PTR_BACK(start, p);
 
                    if (!do_strip)
                    {
@@ -3843,11 +3881,11 @@ add_tag_field(
 }
 
 /*
- * Add the tags matching the specified pattern to the list "list"
- * as a dictionary
+ * Add the tags matching the specified pattern "pat" to the list "list"
+ * as a dictionary. Use "buf_fname" for priority, unless NULL.
  */
     int
-get_tags(list_T *list, char_u *pat)
+get_tags(list_T *list, char_u *pat, char_u *buf_fname)
 {
     int                num_matches, i, ret;
     char_u     **matches, *p;
@@ -3857,7 +3895,7 @@ get_tags(list_T *list, char_u *pat)
     long       is_static;
 
     ret = find_tags(pat, &num_matches, &matches,
-                                   TAG_REGEXP | TAG_NOIC, (int)MAXCOL, NULL);
+                               TAG_REGEXP | TAG_NOIC, (int)MAXCOL, buf_fname);
     if (ret == OK && num_matches > 0)
     {
        for (i = 0; i < num_matches; ++i)
@@ -3899,7 +3937,7 @@ get_tags(list_T *list, char_u *pat)
                    else if (STRNCMP(p, "file:", 5) == 0)
                        /* skip "file:" (static tag) */
                        p += 4;
-                   else if (!vim_iswhite(*p))
+                   else if (!VIM_ISWHITE(*p))
                    {
                        char_u  *s, *n;
                        int     len;
index a9c2c57..d23d8cb 100644 (file)
@@ -845,9 +845,11 @@ static struct builtin_term builtin_termcaps[] =
                                                  ESC_STR "[8;%p1%d;%p2%dt")},
     {(int)KS_CWP,      IF_EB("\033[3;%p1%d;%p2%dt",
                                                  ESC_STR "[3;%p1%d;%p2%dt")},
+    {(int)KS_CGP,      IF_EB("\033[13t", ESC_STR "[13t")},
 #  else
     {(int)KS_CWS,      IF_EB("\033[8;%d;%dt", ESC_STR "[8;%d;%dt")},
     {(int)KS_CWP,      IF_EB("\033[3;%d;%dt", ESC_STR "[3;%d;%dt")},
+    {(int)KS_CGP,      IF_EB("\033[13t", ESC_STR "[13t")},
 #  endif
     {(int)KS_CRV,      IF_EB("\033[>c", ESC_STR "[>c")},
     {(int)KS_RBG,      IF_EB("\033]11;?\007", ESC_STR "]11;?\007")},
@@ -857,6 +859,8 @@ static struct builtin_term builtin_termcaps[] =
     {(int)KS_8F,       IF_EB("\033[38;2;%lu;%lu;%lum", ESC_STR "[38;2;%lu;%lu;%lum")},
     {(int)KS_8B,       IF_EB("\033[48;2;%lu;%lu;%lum", ESC_STR "[48;2;%lu;%lu;%lum")},
 #  endif
+    {(int)KS_CBE,      IF_EB("\033[?2004h", ESC_STR "[?2004h")},
+    {(int)KS_CBD,      IF_EB("\033[?2004l", ESC_STR "[?2004l")},
 
     {K_UP,             IF_EB("\033O*A", ESC_STR "O*A")},
     {K_DOWN,           IF_EB("\033O*B", ESC_STR "O*B")},
@@ -902,13 +906,15 @@ static struct builtin_term builtin_termcaps[] =
     {K_ZEND,           IF_EB("\033[8;*~", ESC_STR "[8;*~")},
     {K_PAGEUP,         IF_EB("\033[5;*~", ESC_STR "[5;*~")},
     {K_PAGEDOWN,       IF_EB("\033[6;*~", ESC_STR "[6;*~")},
-    {K_KPLUS,          IF_EB("\033O*k", ESC_STR "O*k")},       /* keypad plus */
-    {K_KMINUS,         IF_EB("\033O*m", ESC_STR "O*m")},       /* keypad minus */
-    {K_KDIVIDE,                IF_EB("\033O*o", ESC_STR "O*o")},       /* keypad / */
-    {K_KMULTIPLY,      IF_EB("\033O*j", ESC_STR "O*j")},       /* keypad * */
-    {K_KENTER,         IF_EB("\033O*M", ESC_STR "O*M")},       /* keypad Enter */
-    {K_KPOINT,         IF_EB("\033O*n", ESC_STR "O*n")},       /* keypad . */
-    {K_KDEL,           IF_EB("\033[3;*~", ESC_STR "[3;*~")},   /* keypad Del */
+    {K_KPLUS,          IF_EB("\033O*k", ESC_STR "O*k")},     /* keypad plus */
+    {K_KMINUS,         IF_EB("\033O*m", ESC_STR "O*m")},     /* keypad minus */
+    {K_KDIVIDE,                IF_EB("\033O*o", ESC_STR "O*o")},     /* keypad / */
+    {K_KMULTIPLY,      IF_EB("\033O*j", ESC_STR "O*j")},     /* keypad * */
+    {K_KENTER,         IF_EB("\033O*M", ESC_STR "O*M")},     /* keypad Enter */
+    {K_KPOINT,         IF_EB("\033O*n", ESC_STR "O*n")},     /* keypad . */
+    {K_KDEL,           IF_EB("\033[3;*~", ESC_STR "[3;*~")}, /* keypad Del */
+    {K_PS,             IF_EB("\033[200~", ESC_STR "[200~")}, /* paste start */
+    {K_PE,             IF_EB("\033[201~", ESC_STR "[201~")}, /* paste end */
 
     {BT_EXTRA_KEYS,   ""},
     {TERMCAP2KEY('k', '0'), IF_EB("\033[10;*~", ESC_STR "[10;*~")}, /* F0 */
@@ -1224,6 +1230,8 @@ static struct builtin_term builtin_termcaps[] =
     {K_KMULTIPLY,      "[KMULTIPLY]"},
     {K_KENTER,         "[KENTER]"},
     {K_KPOINT,         "[KPOINT]"},
+    {K_PS,             "[PASTE-START]"},
+    {K_PE,             "[PASTE-END]"},
     {K_K0,             "[K0]"},
     {K_K1,             "[K1]"},
     {K_K2,             "[K2]"},
@@ -1538,6 +1546,8 @@ set_termname(char_u *term)
                                {KS_CSI, "SI"}, {KS_CEI, "EI"},
                                {KS_U7, "u7"}, {KS_RBG, "RB"},
                                {KS_8F, "8f"}, {KS_8B, "8b"},
+                               {KS_CBE, "BE"}, {KS_CBD, "BD"},
+                               {KS_CPS, "PS"}, {KS_CPE, "PE"},
                                {(enum SpecialKey)0, NULL}
                            };
 
@@ -1557,9 +1567,9 @@ set_termname(char_u *term)
            /* get output strings */
                for (i = 0; string_names[i].name != NULL; ++i)
                {
-                   if (term_str(string_names[i].dest) == NULL
-                           || term_str(string_names[i].dest) == empty_option)
-                       term_str(string_names[i].dest) =
+                   if (TERM_STR(string_names[i].dest) == NULL
+                           || TERM_STR(string_names[i].dest) == empty_option)
+                       TERM_STR(string_names[i].dest) =
                                           TGETSTR(string_names[i].name, &tp);
                }
 
@@ -1611,8 +1621,8 @@ set_termname(char_u *term)
                /*
                 * Get number of colors (if not done already).
                 */
-               if (term_str(KS_CCO) == NULL
-                       || term_str(KS_CCO) == empty_option)
+               if (TERM_STR(KS_CCO) == NULL
+                       || TERM_STR(KS_CCO) == empty_option)
                    set_color_count(tgetnum("Co"));
 
 # ifndef hpux
@@ -1697,7 +1707,8 @@ set_termname(char_u *term)
                {
                    screen_start();     /* don't know where cursor is now */
                    out_flush();
-                   ui_delay(2000L, TRUE);
+                   if (!is_not_a_term())
+                       ui_delay(2000L, TRUE);
                }
                set_string_option_direct((char_u *)"term", -1, term,
                                                                 OPT_FREE, 0);
@@ -2572,6 +2583,60 @@ term_set_winpos(int x, int y)
     OUT_STR(tgoto((char *)T_CWP, y, x));
 }
 
+# if defined(FEAT_TERMRESPONSE) || defined(PROTO)
+/*
+ * Return TRUE if we can request the terminal for a response.
+ */
+    static int
+can_get_termresponse()
+{
+    return cur_tmode == TMODE_RAW
+           && termcap_active
+# ifdef UNIX
+           && (is_not_a_term() || (isatty(1) && isatty(read_cmd_fd)))
+# endif
+           && p_ek;
+}
+
+static int winpos_x;
+static int winpos_y;
+static int waiting_for_winpos = FALSE;
+
+/*
+ * Try getting the Vim window position from the terminal.
+ * Returns OK or FAIL.
+ */
+    int
+term_get_winpos(int *x, int *y)
+{
+    int count = 0;
+
+    if (*T_CGP == NUL || !can_get_termresponse())
+       return FAIL;
+    winpos_x = -1;
+    winpos_y = -1;
+    waiting_for_winpos = TRUE;
+    OUT_STR(T_CGP);
+    out_flush();
+
+    /* Try reading the result for 100 msec. */
+    while (count++ < 10)
+    {
+       (void)vpeekc_nomap();
+       if (winpos_x >= 0 && winpos_y >= 0)
+       {
+           *x = winpos_x;
+           *y = winpos_y;
+           waiting_for_winpos = FALSE;
+           return OK;
+       }
+       ui_delay(10, FALSE);
+    }
+    waiting_for_winpos = FALSE;
+    return FALSE;
+}
+# endif
+
     void
 term_set_winsize(int width, int height)
 {
@@ -3116,15 +3181,19 @@ settmode(int tmode)
 #endif
 #ifdef FEAT_MOUSE_TTY
            if (tmode != TMODE_RAW)
-               mch_setmouse(FALSE);            /* switch mouse off */
+               mch_setmouse(FALSE);    /* switch mouse off */
 #endif
+           if (tmode != TMODE_RAW)
+               out_str(T_BD);          /* disable bracketed paste mode */
            out_flush();
-           mch_settmode(tmode);    /* machine specific function */
+           mch_settmode(tmode);        /* machine specific function */
            cur_tmode = tmode;
 #ifdef FEAT_MOUSE
            if (tmode == TMODE_RAW)
-               setmouse();                     /* may switch mouse on */
+               setmouse();             /* may switch mouse on */
 #endif
+           if (tmode == TMODE_RAW)
+               out_str(T_BE);          /* enable bracketed paste mode */
            out_flush();
        }
 #ifdef FEAT_TERMRESPONSE
@@ -3140,6 +3209,7 @@ starttermcap(void)
     {
        out_str(T_TI);                  /* start termcap mode */
        out_str(T_KS);                  /* start "keypad transmit" mode */
+       out_str(T_BE);                  /* enable bracketed paste mode */
        out_flush();
        termcap_active = TRUE;
        screen_start();                 /* don't know where cursor is now */
@@ -3189,6 +3259,7 @@ stoptermcap(void)
            check_for_codes_from_term();
        }
 #endif
+       out_str(T_BD);                  /* disable bracketed paste mode */
        out_str(T_KE);                  /* stop "keypad transmit" mode */
        out_flush();
        termcap_active = FALSE;
@@ -3218,14 +3289,8 @@ stoptermcap(void)
 may_req_termresponse(void)
 {
     if (crv_status == CRV_GET
-           && cur_tmode == TMODE_RAW
+           && can_get_termresponse()
            && starting == 0
-           && termcap_active
-           && p_ek
-# ifdef UNIX
-           && isatty(1)
-           && isatty(read_cmd_fd)
-# endif
            && *T_CRV != NUL)
     {
        LOG_TR("Sending CRV");
@@ -3252,13 +3317,8 @@ may_req_termresponse(void)
 may_req_ambiguous_char_width(void)
 {
     if (u7_status == U7_GET
-           && cur_tmode == TMODE_RAW
-           && termcap_active
-           && p_ek
-#  ifdef UNIX
-           && isatty(1)
-           && isatty(read_cmd_fd)
-#  endif
+           && can_get_termresponse()
+           && starting == 0
            && *T_U7 != NUL
            && !option_was_set((char_u *)"ambiwidth"))
     {
@@ -3284,7 +3344,6 @@ may_req_ambiguous_char_width(void)
 }
 # endif
 
-#if defined(FEAT_TERMRESPONSE) || defined(PROTO)
 /*
  * Similar to requesting the version string: Request the terminal background
  * color when it is the right moment.
@@ -3293,13 +3352,8 @@ may_req_ambiguous_char_width(void)
 may_req_bg_color(void)
 {
     if (rbg_status == RBG_GET
-           && cur_tmode == TMODE_RAW
-           && termcap_active
-           && p_ek
-#  ifdef UNIX
-           && isatty(1)
-           && isatty(read_cmd_fd)
-#  endif
+           && can_get_termresponse()
+           && starting == 0
            && *T_RBG != NUL
            && !option_was_set((char_u *)"bg"))
     {
@@ -3312,7 +3366,6 @@ may_req_bg_color(void)
        (void)vpeekc_nomap();
     }
 }
-# endif
 
 # ifdef DEBUG_TERMRESPONSE
     static void
@@ -4125,10 +4178,12 @@ check_termcode(
             * - Cursor position report: <Esc>[{row};{col}R
             *   The final byte must be 'R'. It is used for checking the
             *   ambiguous-width character state.
+            *
+            * - window position reply: <Esc>[3;{x};{y}t
             */
            char_u *argp = tp[0] == ESC ? tp + 2 : tp + 1;
 
-           if ((*T_CRV != NUL || *T_U7 != NUL)
+           if ((*T_CRV != NUL || *T_U7 != NUL || waiting_for_winpos)
                        && ((tp[0] == ESC && len >= 3 && tp[1] == '[')
                            || (tp[0] == CSI && len >= 2))
                        && (VIM_ISDIGIT(*argp) || *argp == '>' || *argp == '?'))
@@ -4267,6 +4322,41 @@ check_termcode(
                    key_name[1] = (int)KE_IGNORE;
                    slen = i + 1;
                }
+
+               /*
+                * Check for a window position response from the terminal:
+                *       {lead}3;{x}:{y}t
+                */
+               else if (waiting_for_winpos
+                           && ((len >= 4 && tp[0] == ESC && tp[1] == '[')
+                               || (len >= 3 && tp[0] == CSI))
+                           && tp[(j = 1 + (tp[0] == ESC))] == '3'
+                           && tp[j + 1] == ';')
+               {
+                   j += 2;
+                   for (i = j; i < len && vim_isdigit(tp[i]); ++i)
+                       ;
+                   if (i < len && tp[i] == ';')
+                   {
+                       winpos_x = atoi((char *)tp + j);
+                       j = i + 1;
+                       for (i = j; i < len && vim_isdigit(tp[i]); ++i)
+                           ;
+                       if (i < len && tp[i] == 't')
+                       {
+                           winpos_y = atoi((char *)tp + j);
+                           /* got finished code: consume it */
+                           key_name[0] = (int)KS_EXTRA;
+                           key_name[1] = (int)KE_IGNORE;
+                           slen = i + 1;
+                       }
+                   }
+                   if (i == len)
+                   {
+                       LOG_TR("not enough characters for winpos");
+                       return -1;
+                   }
+               }
            }
 
            /* Check for background color response from the terminal:
@@ -6069,8 +6159,12 @@ hex_digit(int c)
     guicolor_T
 gui_get_color_cmn(char_u *name)
 {
-    /* On MS-Windows an RGB macro is available and it's different from ours,
-     * but does what is needed. */
+    /* On MS-Windows an RGB macro is available and it produces 0x00bbggrr color
+     * values as used by the MS-Windows GDI api.  It should be used only for
+     * MS-Windows GDI builds. */
+# if defined(RGB) && defined(WIN32) && !defined(FEAT_GUI)
+#  undef RGB
+# endif
 # ifndef RGB
 #  define RGB(r, g, b) ((r<<16) | (g<<8) | (b))
 # endif
index 3064cef..be01cb5 100644 (file)
@@ -77,6 +77,7 @@ enum SpecialKey
     KS_TS,     /* set window title start (to status line)*/
     KS_FS,     /* set window title end (from status line) */
     KS_CWP,    /* set window position in pixels */
+    KS_CGP,    /* get window position */
     KS_CWS,    /* set window size in characters */
     KS_CRV,    /* request version string */
     KS_RBG,    /* request background color */
@@ -89,10 +90,14 @@ enum SpecialKey
     KS_OP,     /* original color pair */
     KS_U7,     /* request cursor position */
     KS_8F,     /* set foreground color (RGB) */
-    KS_8B      /* set background color (RGB) */
+    KS_8B,     /* set background color (RGB) */
+    KS_CBE,    /* enable bracketed paste mode */
+    KS_CBD,    /* disable bracketed paste mode */
+    KS_CPS,    /* start of bracketed paste */
+    KS_CPE     /* end of bracketed paste */
 };
 
-#define KS_LAST            KS_8B
+#define KS_LAST            KS_CPE
 
 /*
  * the terminal capabilities are stored in this array
@@ -107,69 +112,74 @@ extern char_u *(term_strings[]);    /* current terminal strings */
 /*
  * strings used for terminal
  */
-#define T_NAME (term_str(KS_NAME))     /* terminal name */
-#define T_CE   (term_str(KS_CE))       /* clear to end of line */
-#define T_AL   (term_str(KS_AL))       /* add new blank line */
-#define T_CAL  (term_str(KS_CAL))      /* add number of blank lines */
-#define T_DL   (term_str(KS_DL))       /* delete line */
-#define T_CDL  (term_str(KS_CDL))      /* delete number of lines */
-#define T_CS   (term_str(KS_CS))       /* scroll region */
-#define T_CSV  (term_str(KS_CSV))      /* scroll region vertical */
-#define T_CL   (term_str(KS_CL))       /* clear screen */
-#define T_CD   (term_str(KS_CD))       /* clear to end of display */
-#define T_UT   (term_str(KS_UT))       /* clearing uses background color */
-#define T_DA   (term_str(KS_DA))       /* text may be scrolled down from up */
-#define T_DB   (term_str(KS_DB))       /* text may be scrolled up from down */
-#define T_VI   (term_str(KS_VI))       /* cursor invisible */
-#define T_VE   (term_str(KS_VE))       /* cursor visible */
-#define T_VS   (term_str(KS_VS))       /* cursor very visible */
-#define T_ME   (term_str(KS_ME))       /* normal mode */
-#define T_MR   (term_str(KS_MR))       /* reverse mode */
-#define T_MD   (term_str(KS_MD))       /* bold mode */
-#define T_SE   (term_str(KS_SE))       /* normal mode */
-#define T_SO   (term_str(KS_SO))       /* standout mode */
-#define T_CZH  (term_str(KS_CZH))      /* italic mode start */
-#define T_CZR  (term_str(KS_CZR))      /* italic mode end */
-#define T_UE   (term_str(KS_UE))       /* exit underscore (underline) mode */
-#define T_US   (term_str(KS_US))       /* underscore (underline) mode */
-#define T_UCE  (term_str(KS_UCE))      /* exit undercurl mode */
-#define T_UCS  (term_str(KS_UCS))      /* undercurl mode */
-#define T_MS   (term_str(KS_MS))       /* save to move cur in reverse mode */
-#define T_CM   (term_str(KS_CM))       /* cursor motion */
-#define T_SR   (term_str(KS_SR))       /* scroll reverse (backward) */
-#define T_CRI  (term_str(KS_CRI))      /* cursor number of chars right */
-#define T_VB   (term_str(KS_VB))       /* visual bell */
-#define T_KS   (term_str(KS_KS))       /* put term in "keypad transmit" mode */
-#define T_KE   (term_str(KS_KE))       /* out of "keypad transmit" mode */
-#define T_TI   (term_str(KS_TI))       /* put terminal in termcap mode */
-#define T_TE   (term_str(KS_TE))       /* out of termcap mode */
-#define T_BC   (term_str(KS_BC))       /* backspace character */
-#define T_CCS  (term_str(KS_CCS))      /* cur is relative to scroll region */
-#define T_CCO  (term_str(KS_CCO))      /* number of colors */
-#define T_CSF  (term_str(KS_CSF))      /* set foreground color */
-#define T_CSB  (term_str(KS_CSB))      /* set background color */
-#define T_XS   (term_str(KS_XS))       /* standout not erased by overwriting */
-#define T_XN   (term_str(KS_XN))       /* newline glitch */
-#define T_MB   (term_str(KS_MB))       /* blink mode */
-#define T_CAF  (term_str(KS_CAF))      /* set foreground color (ANSI) */
-#define T_CAB  (term_str(KS_CAB))      /* set background color (ANSI) */
-#define T_LE   (term_str(KS_LE))       /* cursor left */
-#define T_ND   (term_str(KS_ND))       /* cursor right */
-#define T_CIS  (term_str(KS_CIS))      /* set icon text start */
-#define T_CIE  (term_str(KS_CIE))      /* set icon text end */
-#define T_TS   (term_str(KS_TS))       /* set window title start */
-#define T_FS   (term_str(KS_FS))       /* set window title end */
-#define T_CWP  (term_str(KS_CWP))      /* window position */
-#define T_CWS  (term_str(KS_CWS))      /* window size */
-#define T_CSI  (term_str(KS_CSI))      /* start insert mode */
-#define T_CEI  (term_str(KS_CEI))      /* end insert mode */
-#define T_CSR  (term_str(KS_CSR))      /* start replace mode */
-#define T_CRV  (term_str(KS_CRV))      /* request version string */
-#define T_RBG  (term_str(KS_RBG))      /* request background RGB */
-#define T_OP   (term_str(KS_OP))       /* original color pair */
-#define T_U7   (term_str(KS_U7))       /* request cursor position */
-#define T_8F   (term_str(KS_8F))       /* set foreground color (RGB) */
-#define T_8B   (term_str(KS_8B))       /* set background color (RGB) */
+#define T_NAME (TERM_STR(KS_NAME))     /* terminal name */
+#define T_CE   (TERM_STR(KS_CE))       /* clear to end of line */
+#define T_AL   (TERM_STR(KS_AL))       /* add new blank line */
+#define T_CAL  (TERM_STR(KS_CAL))      /* add number of blank lines */
+#define T_DL   (TERM_STR(KS_DL))       /* delete line */
+#define T_CDL  (TERM_STR(KS_CDL))      /* delete number of lines */
+#define T_CS   (TERM_STR(KS_CS))       /* scroll region */
+#define T_CSV  (TERM_STR(KS_CSV))      /* scroll region vertical */
+#define T_CL   (TERM_STR(KS_CL))       /* clear screen */
+#define T_CD   (TERM_STR(KS_CD))       /* clear to end of display */
+#define T_UT   (TERM_STR(KS_UT))       /* clearing uses background color */
+#define T_DA   (TERM_STR(KS_DA))       /* text may be scrolled down from up */
+#define T_DB   (TERM_STR(KS_DB))       /* text may be scrolled up from down */
+#define T_VI   (TERM_STR(KS_VI))       /* cursor invisible */
+#define T_VE   (TERM_STR(KS_VE))       /* cursor visible */
+#define T_VS   (TERM_STR(KS_VS))       /* cursor very visible */
+#define T_ME   (TERM_STR(KS_ME))       /* normal mode */
+#define T_MR   (TERM_STR(KS_MR))       /* reverse mode */
+#define T_MD   (TERM_STR(KS_MD))       /* bold mode */
+#define T_SE   (TERM_STR(KS_SE))       /* normal mode */
+#define T_SO   (TERM_STR(KS_SO))       /* standout mode */
+#define T_CZH  (TERM_STR(KS_CZH))      /* italic mode start */
+#define T_CZR  (TERM_STR(KS_CZR))      /* italic mode end */
+#define T_UE   (TERM_STR(KS_UE))       /* exit underscore (underline) mode */
+#define T_US   (TERM_STR(KS_US))       /* underscore (underline) mode */
+#define T_UCE  (TERM_STR(KS_UCE))      /* exit undercurl mode */
+#define T_UCS  (TERM_STR(KS_UCS))      /* undercurl mode */
+#define T_MS   (TERM_STR(KS_MS))       /* save to move cur in reverse mode */
+#define T_CM   (TERM_STR(KS_CM))       /* cursor motion */
+#define T_SR   (TERM_STR(KS_SR))       /* scroll reverse (backward) */
+#define T_CRI  (TERM_STR(KS_CRI))      /* cursor number of chars right */
+#define T_VB   (TERM_STR(KS_VB))       /* visual bell */
+#define T_KS   (TERM_STR(KS_KS))       /* put term in "keypad transmit" mode */
+#define T_KE   (TERM_STR(KS_KE))       /* out of "keypad transmit" mode */
+#define T_TI   (TERM_STR(KS_TI))       /* put terminal in termcap mode */
+#define T_TE   (TERM_STR(KS_TE))       /* out of termcap mode */
+#define T_BC   (TERM_STR(KS_BC))       /* backspace character */
+#define T_CCS  (TERM_STR(KS_CCS))      /* cur is relative to scroll region */
+#define T_CCO  (TERM_STR(KS_CCO))      /* number of colors */
+#define T_CSF  (TERM_STR(KS_CSF))      /* set foreground color */
+#define T_CSB  (TERM_STR(KS_CSB))      /* set background color */
+#define T_XS   (TERM_STR(KS_XS))       /* standout not erased by overwriting */
+#define T_XN   (TERM_STR(KS_XN))       /* newline glitch */
+#define T_MB   (TERM_STR(KS_MB))       /* blink mode */
+#define T_CAF  (TERM_STR(KS_CAF))      /* set foreground color (ANSI) */
+#define T_CAB  (TERM_STR(KS_CAB))      /* set background color (ANSI) */
+#define T_LE   (TERM_STR(KS_LE))       /* cursor left */
+#define T_ND   (TERM_STR(KS_ND))       /* cursor right */
+#define T_CIS  (TERM_STR(KS_CIS))      /* set icon text start */
+#define T_CIE  (TERM_STR(KS_CIE))      /* set icon text end */
+#define T_TS   (TERM_STR(KS_TS))       /* set window title start */
+#define T_FS   (TERM_STR(KS_FS))       /* set window title end */
+#define T_CWP  (TERM_STR(KS_CWP))      /* set window position */
+#define T_CGP  (TERM_STR(KS_CGP))      /* get window position */
+#define T_CWS  (TERM_STR(KS_CWS))      /* window size */
+#define T_CSI  (TERM_STR(KS_CSI))      /* start insert mode */
+#define T_CEI  (TERM_STR(KS_CEI))      /* end insert mode */
+#define T_CSR  (TERM_STR(KS_CSR))      /* start replace mode */
+#define T_CRV  (TERM_STR(KS_CRV))      /* request version string */
+#define T_RBG  (TERM_STR(KS_RBG))      /* request background RGB */
+#define T_OP   (TERM_STR(KS_OP))       /* original color pair */
+#define T_U7   (TERM_STR(KS_U7))       /* request cursor position */
+#define T_8F   (TERM_STR(KS_8F))       /* set foreground color (RGB) */
+#define T_8B   (TERM_STR(KS_8B))       /* set background color (RGB) */
+#define T_BE   (TERM_STR(KS_CBE))      /* enable bracketed paste mode */
+#define T_BD   (TERM_STR(KS_CBD))      /* disable bracketed paste mode */
+#define T_PS   (TERM_STR(KS_CPS))      /* start of bracketed paste */
+#define T_PE   (TERM_STR(KS_CPE))      /* end of bracketed paste */
 
 #define TMODE_COOK  0  /* terminal mode for external cmds and Ex mode */
 #define TMODE_SLEEP 1  /* terminal mode for sleeping (cooked but no echo) */
index a8ea543..ce39367 100644 (file)
@@ -2,7 +2,10 @@
 # Common Makefile, defines the list of tests to run.
 #
 
-NO_PLUGIN = -U NONE --noplugin --not-a-term
+# Options for protecting the tests against undesirable interaction with the
+# environment
+NO_PLUGINS = --noplugin --not-a-term
+NO_INITS = -U NONE $(NO_PLUGINS)
 
 # The first script creates small.vim.
 SCRIPTS_FIRST = \
@@ -63,8 +66,6 @@ SCRIPTS_ALL = \
        test88.out \
        test90.out \
        test91.out \
-       test92.out \
-       test93.out \
        test94.out \
        test95.out \
        test98.out \
@@ -75,7 +76,6 @@ SCRIPTS_ALL = \
        test108.out \
        test_autocmd_option.out \
        test_autoformat_join.out \
-       test_breakindent.out \
        test_changelist.out \
        test_close_count.out \
        test_comparators.out \
@@ -85,9 +85,7 @@ SCRIPTS_ALL = \
        test_getcwd.out \
        test_insertcount.out \
        test_listchars.out \
-       test_listlbr.out \
        test_search_mbyte.out \
-       test_utf8.out \
        test_wordcount.out
 
 
@@ -105,8 +103,7 @@ SCRIPTS_MORE2 = \
        test12.out \
        test25.out \
        test49.out \
-       test97.out \
-       test_listlbr_utf8.out
+       test97.out
 
 
 # Tests that run on most systems, but not MingW and Cygwin.
@@ -123,8 +120,7 @@ SCRIPTS_MORE4 = \
        test59.out \
        test72.out \
        test78.out \
-       test83.out \
-       test89.out
+       test83.out
 
 
 # Tests specifically for MS-Windows.
@@ -137,25 +133,37 @@ SCRIPTS_GUI =
 
 # Tests using runtest.vim.vim.
 # Keep test_alot*.res as the last one, sort the others.
-NEW_TESTS = test_arglist.res \
+NEW_TESTS = test_arabic.res \
+           test_arglist.res \
            test_assert.res \
            test_autochdir.res \
+           test_autocmd.res \
            test_backspace_opt.res \
+           test_breakindent.res \
            test_bufwintabinfo.res \
            test_cdo.res \
            test_channel.res \
            test_charsearch.res \
+           test_cindent.res \
+           test_clientserver.res \
            test_cmdline.res \
+           test_command_count.res \
            test_crypt.res \
            test_cscope.res \
            test_diffmode.res \
            test_digraph.res \
+           test_display.res \
+           test_edit.res \
            test_farsi.res \
            test_fnameescape.res \
+           test_fold.res \
            test_gf.res \
            test_gn.res \
            test_gui.res \
+           test_gui_init.res \
            test_hardcopy.res \
+           test_help.res \
+           test_hide.res \
            test_history.res \
            test_hlsearch.res \
            test_increment.res \
@@ -163,29 +171,48 @@ NEW_TESTS = test_arglist.res \
            test_job_fails.res \
            test_json.res \
            test_langmap.res \
+           test_listlbr.res \
+           test_listlbr_utf8.res \
+           test_lua.res \
+           test_makeencoding.res \
            test_man.res \
            test_marks.res \
            test_matchadd_conceal.res \
+           test_mksession.res \
+           test_mksession_utf8.res \
            test_nested_function.res \
            test_netbeans.res \
            test_normal.res \
+           test_number.res \
+           test_options.res \
            test_packadd.res \
+           test_paste.res \
            test_perl.res \
+           test_profile.res \
+           test_python2.res \
+           test_python3.res \
+           test_pyx2.res \
+           test_pyx3.res \
            test_quickfix.res \
+           test_quotestar.res \
+           test_retab.res \
            test_ruby.res \
            test_search.res \
            test_signs.res \
            test_smartindent.res \
+           test_spell.res \
            test_startup.res \
            test_startup_utf8.res \
            test_stat.res \
            test_substitute.res \
            test_syntax.res \
+           test_system.res \
+           test_tcl.res \
            test_textobjects.res \
            test_undo.res \
            test_usercommands.res \
            test_viminfo.res \
-           test_viml.res \
+           test_vimscript.res \
            test_visual.res \
            test_window_id.res \
            test_writefile.res \
@@ -199,3 +226,4 @@ test49.out: test49.vim
 
 test60.out: test60.vim
 
+test_options.res test_alot.res: opt_test.vim
index b6aaa6e..fe2e2ba 100644 (file)
@@ -38,30 +38,31 @@ win32:      nolog $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_WIN32) newtests report
 $(DOSTMP_INFILES): $(*B).in
        if not exist $(DOSTMP)\NUL md $(DOSTMP)
        if exist $@ del $@
-       $(VIMPROG) -u dos.vim $(NO_PLUGIN) "+set ff=dos|f $@|wq" $(*B).in
+       $(VIMPROG) -u dos.vim $(NO_INITS) "+set ff=dos|f $@|wq" $(*B).in
 
 # For each input file dostmp/test99.in run the tests.
 # This moves test99.in to test99.in.bak temporarily.
 $(TEST_OUTFILES): $(DOSTMP)\$(*B).in
        -@if exist test.out DEL test.out
-       move $(*B).in $(*B).in.bak
-       copy $(DOSTMP)\$(*B).in $(*B).in
-       copy $(*B).ok test.ok
-       $(VIMPROG) -u dos.vim $(NO_PLUGIN) -s dotest.in $(*B).in
-       -@if exist test.out MOVE /y test.out $(DOSTMP)\$(*B).out
-       -@if exist $(*B).in.bak move /y $(*B).in.bak $(*B).in
+       -@if exist $(DOSTMP)\$(*B).out DEL $(DOSTMP)\$(*B).out
+       move $(*B).in $(*B).in.bak > nul
+       copy $(DOSTMP)\$(*B).in $(*B).in > nul
+       copy $(*B).ok test.ok > nul
+       $(VIMPROG) -u dos.vim $(NO_INITS) -s dotest.in $(*B).in
+       -@if exist test.out MOVE /y test.out $(DOSTMP)\$(*B).out > nul
+       -@if exist $(*B).in.bak move /y $(*B).in.bak $(*B).in > nul
        -@if exist test.ok del test.ok
        -@if exist Xdir1 rd /s /q Xdir1
        -@if exist Xfind rd /s /q Xfind
        -@del X*
        -@if exist viminfo del viminfo
-       $(VIMPROG) -u dos.vim $(NO_PLUGIN) "+set ff=unix|f test.out|wq" \
+       $(VIMPROG) -u dos.vim $(NO_INITS) "+set ff=unix|f test.out|wq" \
                $(DOSTMP)\$(*B).out
        @diff test.out $*.ok & if errorlevel 1 \
-               ( move /y test.out $*.failed \
+               ( move /y test.out $*.failed > nul \
                 & del $(DOSTMP)\$(*B).out \
                 & echo $* FAILED >> test.log ) \
-               else ( move /y test.out $*.out )
+               else ( move /y test.out $*.out > nul )
 
 # Must run test1 first to create small.vim.
 # This rule must come after the one that copies the input files to dostmp to
@@ -94,6 +95,7 @@ clean:
        -if exist test.log del test.log
        -if exist messages del messages
        -if exist benchmark.out del benchmark.out
+       -if exist opt_test.vim del opt_test.vim
 
 nolog:
        -if exist test.log del test.log
@@ -104,7 +106,7 @@ benchmark:
 
 bench_re_freeze.out: bench_re_freeze.vim
        -if exist benchmark.out del benchmark.out
-       $(VIMPROG) -u dos.vim $(NO_PLUGIN) $*.in
+       $(VIMPROG) -u dos.vim $(NO_INITS) $*.in
        @IF EXIST benchmark.out ( type benchmark.out )
 
 # New style of tests uses Vim script with assert calls.  These are easier
@@ -115,5 +117,18 @@ newtests: $(NEW_TESTS)
 
 .vim.res:
        @echo "$(VIMPROG)" > vimcmd
-       $(VIMPROG) -u NONE $(NO_PLUGIN) -S runtest.vim $*.vim
+       $(VIMPROG) -u NONE $(NO_INITS) -S runtest.vim $*.vim
        @del vimcmd
+
+test_gui.res: test_gui.vim
+       @echo "$(VIMPROG)" > vimcmd
+       $(VIMPROG) -u NONE $(NO_INITS) -S runtest.vim $*.vim
+       @del vimcmd
+
+test_gui_init.res: test_gui_init.vim
+       @echo "$(VIMPROG)" > vimcmd
+       $(VIMPROG) -u gui_preinit.vim -U gui_init.vim $(NO_PLUGINS) -S runtest.vim $*.vim
+       @del vimcmd
+
+opt_test.vim: ../option.c gen_opt_test.vim
+       $(VIMPROG) -u NONE -S gen_opt_test.vim --noplugin --not-a-term ../option.c
index 3330691..dbf94f0 100644 (file)
@@ -66,9 +66,9 @@ win32:        fixff nolog $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_WIN32) newtests
 
 # TODO: find a way to avoid changing the distributed files.
 fixff:
-       -$(VIMPROG) -u dos.vim $(NO_PLUGIN) "+argdo set ff=dos|upd" +q *.in *.ok
-       -$(VIMPROG) -u dos.vim $(NO_PLUGIN) "+argdo set ff=unix|upd" +q \
-               dotest.in test60.ok test71.ok test74.ok test_listchars.ok \
+       -$(VIMPROG) -u dos.vim $(NO_INITS) "+argdo set ff=dos|upd" +q *.in *.ok
+       -$(VIMPROG) -u dos.vim $(NO_INITS) "+argdo set ff=unix|upd" +q \
+               dotest.in test60.ok test_listchars.ok \
                test_getcwd.ok test_wordcount.ok
 
 clean:
@@ -88,10 +88,11 @@ clean:
        -@if exist viminfo $(DEL) viminfo
        -@if exist test.log $(DEL) test.log
        -@if exist messages $(DEL) messages
+       -@if exist opt_test.vim $(DEL) opt_test.vim
 
 .in.out:
        -@if exist $*.ok $(CP) $*.ok test.ok
-       $(VIMPROG) -u dos.vim $(NO_PLUGIN) -s dotest.in $*.in
+       $(VIMPROG) -u dos.vim $(NO_INITS) -s dotest.in $*.in
        @diff test.out $*.ok
        -@if exist $*.out $(DEL) $*.out
        @$(MV) test.out $*.out
@@ -107,7 +108,7 @@ nolog:
 
 bench_re_freeze.out: bench_re_freeze.vim
        -$(DEL) benchmark.out
-       $(VIMPROG) -u dos.vim $(NO_PLUGIN) $*.in
+       $(VIMPROG) -u dos.vim $(NO_INITS) $*.in
        $(CAT) benchmark.out
 
 # New style of tests uses Vim script with assert calls.  These are easier
@@ -118,6 +119,18 @@ newtests: $(NEW_TESTS)
 
 .vim.res:
        @echo "$(VIMPROG)" > vimcmd
-       $(VIMPROG) -u NONE $(NO_PLUGIN) -S runtest.vim $*.vim
+       $(VIMPROG) -u NONE $(NO_INITS) -S runtest.vim $*.vim
        @$(DEL) vimcmd
 
+test_gui.res: test_gui.vim
+       @echo "$(VIMPROG)" > vimcmd
+       $(VIMPROG) -u NONE $(NO_INITS) -S runtest.vim $<
+       @$(DEL) vimcmd
+
+test_gui_init.res: test_gui_init.vim
+       @echo "$(VIMPROG)" > vimcmd
+       $(VIMPROG) -u gui_preinit.vim -U gui_init.vim $(NO_PLUGINS) -S runtest.vim $<
+       @$(DEL) vimcmd
+
+opt_test.vim: ../option.c gen_opt_test.vim
+       $(VIMPROG) -u NONE -S gen_opt_test.vim --noplugin --not-a-term ../option.c
index 6962cf0..4888b17 100644 (file)
@@ -91,8 +91,8 @@ SCRIPT = test1.out  test3.out  test4.out  test5.out  \
        test66.out test67.out test68.out test69.out \
        test72.out test75.out \
        test77a.out test78.out test79.out test80.out \
-       test82.out test84.out test88.out test89.out \
-       test90.out test91.out test92.out test93.out test94.out \
+       test82.out test84.out test88.out \
+       test90.out test91.out test94.out \
        test95.out test98.out test99.out \
        test103.out test104.out \
        test107.out test108.out\
index 08f11cd..ce1c24c 100644 (file)
@@ -52,10 +52,10 @@ $(SCRIPTS) $(SCRIPTS_GUI) $(NEW_TESTS): $(SCRIPTS_FIRST)
 
 RM_ON_RUN = test.out X* viminfo
 RM_ON_START = tiny.vim small.vim mbyte.vim mzscheme.vim lua.vim test.ok benchmark.out
-RUN_VIM = VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u unix.vim $(NO_PLUGIN) -s dotest.in
+RUN_VIM = VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u unix.vim $(NO_INITS) -s dotest.in
 
 clean:
-       -rm -rf *.out *.failed *.res *.rej *.orig test.log messages $(RM_ON_RUN) $(RM_ON_START) valgrind.*
+       -rm -rf *.out *.failed *.res *.rej *.orig opt_test.vim test.log messages $(RM_ON_RUN) $(RM_ON_START) valgrind.*
 
 test1.out: test1.in
        -rm -rf $*.failed $(RM_ON_RUN) $(RM_ON_START) wrongtermsize
@@ -78,7 +78,7 @@ test1.out: test1.in
        # 200 msec is sufficient, but only modern sleep supports a fraction of
        # a second, fall back to a second if it fails.
        @-/bin/sh -c "sleep .2 > /dev/null 2>&1 || sleep 1"
-       -$(RUN_VIM) $*.in
+       $(RUN_VIM) $*.in
 
        # For flaky tests retry one time.  No tests at the moment.
        #@/bin/sh -c "if test -f test.out -a $* = test61; then \
@@ -108,7 +108,7 @@ bench_re_freeze.out: bench_re_freeze.vim
        # 200 msec is sufficient, but only modern sleep supports a fraction of
        # a second, fall back to a second if it fails.
        @-/bin/sh -c "sleep .2 > /dev/null 2>&1 || sleep 1"
-       -$(RUN_VIM) $*.in
+       $(RUN_VIM) $*.in
        @/bin/sh -c "if test -f benchmark.out; then cat benchmark.out; fi"
 
 nolog:
@@ -118,7 +118,7 @@ nolog:
 # New style of tests uses Vim script with assert calls.  These are easier
 # to write and a lot easier to read and debug.
 # Limitation: Only works with the +eval feature.
-RUN_VIMTEST = VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u unix.vim $(NO_PLUGIN)
+RUN_VIMTEST = VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u unix.vim
 
 newtests: newtestssilent
        @/bin/sh -c "if test -f messages && grep -q 'SKIPPED\|FAILED' messages; then cat messages && if test -f test.log; then cat test.log; fi ; fi"
@@ -128,5 +128,18 @@ newtestssilent: $(NEW_TESTS)
 
 .vim.res:
        @echo "$(RUN_VIMTEST)" > vimcmd
-       $(RUN_VIMTEST) -U NONE -S runtest.vim $*.vim
+       $(RUN_VIMTEST) $(NO_INITS) -S runtest.vim $*.vim
+       @rm vimcmd
+
+test_gui.res: test_gui.vim
+       @echo "$(RUN_GVIMTEST)" > vimcmd
+       $(RUN_VIMTEST) -u NONE $(NO_INITS) -S runtest.vim $<
        @rm vimcmd
+
+test_gui_init.res: test_gui_init.vim
+       @echo "$(RUN_GVIMTEST_WITH_GVIMRC)" > vimcmd
+       $(RUN_VIMTEST) -u gui_preinit.vim -U gui_init.vim $(NO_PLUGINS) -S runtest.vim $<
+       @rm vimcmd
+
+opt_test.vim: ../option.c gen_opt_test.vim
+       $(VIMPROG) -u NONE -S gen_opt_test.vim --noplugin --not-a-term ../option.c
index 640c61d..6cdf12f 100644 (file)
@@ -14,10 +14,10 @@ can.  Use an old style test when it needs to run without the +eval feature.
 TO ADD A NEW STYLE TEST:
 
 1) Create a test_<subject>.vim file.
-2) Add test_<subject>.vim to NEW_TESTS in Make_all.mak in alphabetical order.
-3) Use make test_<subject>.res to run a single test in src/testdir/.
+2) Add test_<subject>.res to NEW_TESTS in Make_all.mak in alphabetical order.
+3) Also add an entry in src/Makefile.
+4) Use make test_<subject>.res to run a single test in src/testdir/.
    Use make test_<subject>  to run a single test in src/.
-4) Also add an entry in src/Makefile.
 
 What you can use (see test_assert.vim for an example):
 - Call assert_equal(), assert_true(), assert_false(), etc.
diff --git a/src/testdir/gen_opt_test.vim b/src/testdir/gen_opt_test.vim
new file mode 100644 (file)
index 0000000..019c757
--- /dev/null
@@ -0,0 +1,212 @@
+" Script to generate testdir/opt_test.vim from option.c
+
+set cpo=&vim
+
+" Only do this when build with the +eval feature.
+if 1
+
+set nomore
+
+" The terminal size is restored at the end.
+" Clear out t_WS, we don't want to resize the actual terminal.
+let script = [
+      \ 'let save_columns = &columns',
+      \ 'let save_lines = &lines',
+      \ 'let save_term = &term',
+      \ 'set t_WS=',
+      \ ]
+
+/#define p_term
+let end = line('.')
+
+" Two lists with values: values that work and values that fail.
+" When not listed, "othernum" or "otherstring" is used.
+let test_values = {
+      \ 'cmdheight': [[1, 2, 10], [-1, 0]],
+      \ 'cmdwinheight': [[1, 2, 10], [-1, 0]],
+      \ 'columns': [[12, 80], [-1, 0, 10]],
+      \ 'conceallevel': [[0, 1, 2, 3], [-1, 4, 99]],
+      \ 'foldcolumn': [[0, 1, 4, 12], [-1, 13, 999]],
+      \ 'helpheight': [[0, 10, 100], [-1]],
+      \ 'history': [[0, 1, 100], [-1, 10001]],
+      \ 'iminsert': [[0, 1], [-1, 3, 999]],
+      \ 'imsearch': [[-1, 0, 1], [-2, 3, 999]],
+      \ 'lines': [[2, 24], [-1, 0, 1]],
+      \ 'linespace': [[0, 2, 4], ['']],
+      \ 'numberwidth': [[1, 4, 8, 10], [-1, 0, 11]],
+      \ 'regexpengine': [[0, 1, 2], [-1, 3, 999]],
+      \ 'report': [[0, 1, 2, 9999], [-1]],
+      \ 'scroll': [[0, 1, 2, 20], [-1]],
+      \ 'scrolljump': [[-50, -1, 0, 1, 2, 20], [999]],
+      \ 'scrolloff': [[0, 1, 2, 20], [-1]],
+      \ 'shiftwidth': [[0, 1, 8, 999], [-1]],
+      \ 'sidescroll': [[0, 1, 8, 999], [-1]],
+      \ 'sidescrolloff': [[0, 1, 8, 999], [-1]],
+      \ 'tabstop': [[1, 4, 8, 12], [-1, 0]],
+      \ 'textwidth': [[0, 1, 8, 99], [-1]],
+      \ 'timeoutlen': [[0, 8, 99999], [-1]],
+      \ 'titlelen': [[0, 1, 8, 9999], [-1]],
+      \ 'updatecount': [[0, 1, 8, 9999], [-1]],
+      \ 'updatetime': [[0, 1, 8, 9999], [-1]],
+      \ 'verbose': [[-1, 0, 1, 8, 9999], []],
+      \ 'wildcharm': [[-1, 0, 100], []],
+      \ 'winheight': [[1, 10, 999], [-1, 0]],
+      \ 'winminheight': [[0, 1], [-1]],
+      \ 'winminwidth': [[0, 1, 10], [-1]],
+      \ 'winwidth': [[1, 10, 999], [-1, 0]],
+      \
+      \ 'ambiwidth': [['', 'single'], ['xxx']],
+      \ 'background': [['', 'light', 'dark'], ['xxx']],
+      \ 'backspace': [[0, 2, '', 'eol', 'eol,start'], ['xxx']],
+      \ 'backupcopy': [['yes', 'auto'], ['', 'xxx', 'yes,no']],
+      \ 'backupext': [['xxx'], ['']],
+      \ 'belloff': [['', 'all', 'copy,error'], ['xxx']],
+      \ 'breakindentopt': [['', 'min:3', 'sbr'], ['xxx', 'min', 'min:x']],
+      \ 'browsedir': [['', 'last', '/'], ['xxx']],
+      \ 'bufhidden': [['', 'hide', 'wipe'], ['xxx', 'hide,wipe']],
+      \ 'buftype': [['', 'help', 'nofile'], ['xxx', 'help,nofile']],
+      \ 'casemap': [['', 'internal'], ['xxx']],
+      \ 'cedit': [['', '\<Esc>'], ['xxx', 'f']],
+      \ 'clipboard': [['', 'unnamed', 'autoselect,unnamed'], ['xxx']],
+      \ 'colorcolumn': [['', '8', '+2'], ['xxx']],
+      \ 'comments': [['', 'b:#'], ['xxx']],
+      \ 'commentstring': [['', '/*%s*/'], ['xxx']],
+      \ 'complete': [['', 'w,b'], ['xxx']],
+      \ 'concealcursor': [['', 'n', 'nvic'], ['xxx']],
+      \ 'completeopt': [['', 'menu', 'menu,longest'], ['xxx', 'menu,,,longest,']],
+      \ 'cryptmethod': [['', 'zip'], ['xxx']],
+      \ 'cscopequickfix': [['', 's-', 's-,c+,e0'], ['xxx', 's,g,d']],
+      \ 'debug': [['', 'msg', 'msg', 'beep'], ['xxx']],
+      \ 'diffopt': [['', 'filler', 'icase,iwhite'], ['xxx']],
+      \ 'display': [['', 'lastline', 'lastline,uhex'], ['xxx']],
+      \ 'eadirection': [['', 'both', 'ver'], ['xxx', 'ver,hor']],
+      \ 'encoding': [['latin1'], ['xxx', '']],
+      \ 'eventignore': [['', 'WinEnter', 'WinLeave,winenter'], ['xxx']],
+      \ 'fileencoding': [['', 'latin1', 'xxx'], []],
+      \ 'fileformat': [['', 'dos', 'unix'], ['xxx']],
+      \ 'fileformats': [['', 'dos', 'dos,unix'], ['xxx']],
+      \ 'fillchars': [['', 'vert:x'], ['xxx']],
+      \ 'foldclose': [['', 'all'], ['xxx']],
+      \ 'foldmethod': [['manual', 'indent'], ['', 'xxx', 'expr,diff']],
+      \ 'foldopen': [['', 'all', 'hor,jump'], ['xxx']],
+      \ 'foldmarker': [['((,))'], ['', 'xxx']],
+      \ 'formatoptions': [['', 'vt', 'v,t'], ['xxx']],
+      \ 'guicursor': [['', 'n:block-Cursor'], ['xxx']],
+      \ 'guifont': [['', 'fixedsys'], []],
+      \ 'guifontwide': [['', 'fixedsys'], []],
+      \ 'helplang': [['', 'de', 'de,it'], ['xxx']],
+      \ 'highlight': [['', 'e:Error'], ['xxx']],
+      \ 'imactivatekey': [['', 'S-space'], ['xxx']],
+      \ 'isfname': [['', '@', '@,48-52'], ['xxx', '@48']],
+      \ 'isident': [['', '@', '@,48-52'], ['xxx', '@48']],
+      \ 'iskeyword': [['', '@', '@,48-52'], ['xxx', '@48']],
+      \ 'isprint': [['', '@', '@,48-52'], ['xxx', '@48']],
+      \ 'keymap': [['', 'accents'], ['xxx']],
+      \ 'keymodel': [['', 'startsel', 'startsel,stopsel'], ['xxx']],
+      \ 'langmap': [['', 'xX', 'aA,bB'], ['xxx']],
+      \ 'listchars': [['', 'eol:x', 'eol:x,space:y'], ['xxx']],
+      \ 'matchpairs': [['', '(:)', '(:),<:>'], ['xxx']],
+      \ 'mkspellmem': [['10000,100,12'], ['', 'xxx']],
+      \ 'mouse': [['', 'a', 'nvi'], ['xxx', 'n,v,i']],
+      \ 'mousemodel': [['', 'popup'], ['xxx']],
+      \ 'mouseshape': [['', 'n:arrow'], ['xxx']],
+      \ 'nrformats': [['', 'alpha', 'alpha,hex,bin'], ['xxx']],
+      \ 'printmbfont': [['', 'r:some', 'b:Bold,c:yes'], ['xxx']],
+      \ 'printoptions': [['', 'header:0', 'left:10pc,top:5pc'], ['xxx']],
+      \ 'scrollopt': [['', 'ver', 'ver,hor'], ['xxx']],
+      \ 'renderoptions': [['', 'type:directx'], ['xxx']],
+      \ 'selection': [['old', 'inclusive'], ['', 'xxx']],
+      \ 'selectmode': [['', 'mouse', 'key,cmd'], ['xxx']],
+      \ 'sessionoptions': [['', 'blank', 'help,options,slash'], ['xxx']],
+      \ 'signcolumn': [['', 'auto', 'no'], ['xxx', 'no,yes']],
+      \ 'spellfile': [['', 'file.en.add'], ['xxx', '/tmp/file']],
+      \ 'spellsuggest': [['', 'best', 'double,33'], ['xxx']],
+      \ 'switchbuf': [['', 'useopen', 'split,newtab'], ['xxx']],
+      \ 'tagcase': [['smart', 'match'], ['', 'xxx', 'smart,match']],
+      \ 'term': [[], []],
+      \ 'toolbar': [['', 'icons', 'text'], ['xxx']],
+      \ 'toolbariconsize': [['', 'tiny', 'huge'], ['xxx']],
+      \ 'ttymouse': [['', 'xterm'], ['xxx']],
+      \ 'ttytype': [[], []],
+      \ 'viewoptions': [['', 'cursor', 'unix,slash'], ['xxx']],
+      \ 'viminfo': [['', '''50', '"30'], ['xxx']],
+      \ 'virtualedit': [['', 'all', 'all,block'], ['xxx']],
+      \ 'whichwrap': [['', 'b,s', 'bs'], ['xxx']],
+      \ 'wildmode': [['', 'full', 'list:full', 'full,longest'], ['xxx']],
+      \ 'wildoptions': [['', 'tagfile'], ['xxx']],
+      \ 'winaltkeys': [['menu', 'no'], ['', 'xxx']],
+      \
+      \ 'luadll': [[], []],
+      \ 'perldll': [[], []],
+      \ 'pythondll': [[], []],
+      \ 'pythonthreedll': [[], []],
+      \ 'pyxversion': [[], []],
+      \ 'rubydll': [[], []],
+      \ 'tcldll': [[], []],
+      \
+      \ 'othernum': [[-1, 0, 100], ['']],
+      \ 'otherstring': [['', 'xxx'], []],
+      \}
+
+1
+/struct vimoption options
+while 1
+  /{"
+  if line('.') > end
+    break
+  endif
+  let line = getline('.')
+  let name = substitute(line, '.*{"\([^"]*\)".*', '\1', '')
+  let shortname = substitute(line, '.*"\([^"]*\)".*', '\1', '')
+
+  if has_key(test_values, name)
+    let a = test_values[name]
+  elseif line =~ 'P_NUM'
+    let a = test_values['othernum']
+  else
+    let a = test_values['otherstring']
+  endif
+  if len(a[0]) > 0 || len(a[1]) > 0
+    if line =~ 'P_BOOL'
+      call add(script, 'set ' . name)
+      call add(script, 'set ' . shortname)
+      call add(script, 'set no' . name)
+      call add(script, 'set no' . shortname)
+    else
+      for val in a[0]
+       call add(script, 'set ' . name . '=' . val)
+       call add(script, 'set ' . shortname . '=' . val)
+      endfor
+
+      " setting an option can only fail when it's implemented.
+      call add(script, "if exists('+" . name . "')")
+      for val in a[1]
+       call add(script, "call assert_fails('set " . name . "=" . val . "')")
+       call add(script, "call assert_fails('set " . shortname . "=" . val . "')")
+      endfor
+      call add(script, "endif")
+    endif
+
+    call add(script, 'set ' . name . '&')
+    call add(script, 'set ' . shortname . '&')
+    if name == 'verbosefile'
+      call add(script, 'call delete("xxx")')
+    endif
+
+    if name == 'more'
+      call add(script, 'set nomore')
+    elseif name == 'lines'
+      call add(script, 'let &lines = save_lines')
+    endif
+  endif
+endwhile
+
+call add(script, 'let &term = save_term')
+call add(script, 'let &columns = save_columns')
+call add(script, 'let &lines = save_lines')
+
+call writefile(script, 'opt_test.vim')
+
+endif
+
+qa!
diff --git a/src/testdir/gui_init.vim b/src/testdir/gui_init.vim
new file mode 100644 (file)
index 0000000..42b2bca
--- /dev/null
@@ -0,0 +1,6 @@
+" gvimrc for test_gui_init.vim
+
+if has('gui_athena') || has('gui_motif') || has('gui_gtk2') || has('gui_gtk3')
+  set guiheadroom=0
+  set guioptions+=p
+endif
diff --git a/src/testdir/gui_preinit.vim b/src/testdir/gui_preinit.vim
new file mode 100644 (file)
index 0000000..c351b72
--- /dev/null
@@ -0,0 +1,7 @@
+" vimrc for test_gui_init.vim
+
+" Note that this flag must be added in the .vimrc file, before switching on
+" syntax or filetype recognition (when the |gvimrc| file is sourced the system
+" menu has already been loaded; the ":syntax on" and ":filetype on" commands
+" load the menu too).
+set guioptions+=M
diff --git a/src/testdir/pyxfile/py2_magic.py b/src/testdir/pyxfile/py2_magic.py
new file mode 100644 (file)
index 0000000..819892f
--- /dev/null
@@ -0,0 +1,4 @@
+# requires python 2.x
+
+import sys
+print(sys.version)
diff --git a/src/testdir/pyxfile/py2_shebang.py b/src/testdir/pyxfile/py2_shebang.py
new file mode 100644 (file)
index 0000000..13bfc49
--- /dev/null
@@ -0,0 +1,4 @@
+#!/usr/bin/python2
+
+import sys
+print(sys.version)
diff --git a/src/testdir/pyxfile/py3_magic.py b/src/testdir/pyxfile/py3_magic.py
new file mode 100644 (file)
index 0000000..d4b7ee0
--- /dev/null
@@ -0,0 +1,4 @@
+# requires python 3.x
+
+import sys
+print(sys.version)
diff --git a/src/testdir/pyxfile/py3_shebang.py b/src/testdir/pyxfile/py3_shebang.py
new file mode 100644 (file)
index 0000000..ec05808
--- /dev/null
@@ -0,0 +1,4 @@
+#!/usr/bin/python3
+
+import sys
+print(sys.version)
diff --git a/src/testdir/pyxfile/pyx.py b/src/testdir/pyxfile/pyx.py
new file mode 100644 (file)
index 0000000..261a651
--- /dev/null
@@ -0,0 +1,2 @@
+import sys
+print(sys.version)
index c4cb847..0256d48 100644 (file)
@@ -49,7 +49,7 @@ source setup.vim
 " This also enables use of line continuation.
 set nocp viminfo+=nviminfo
 
-" Use utf-8 or latin1 be default, instead of whatever the system default
+" Use utf-8 or latin1 by default, instead of whatever the system default
 " happens to be.  Individual tests can overrule this at the top of the file.
 if has('multi_byte')
   set encoding=utf-8
@@ -86,10 +86,25 @@ function GetAllocId(name)
   return lnum - top - 1
 endfunc
 
-function RunTheTest(test)
+func RunTheTest(test)
   echo 'Executing ' . a:test
+
+  " Avoid stopping at the "hit enter" prompt
+  set nomore
+
+  " Avoid a three second wait when a message is about to be overwritten by the
+  " mode message.
+  set noshowmode
+
+  " Clear any overrides.
+  call test_override('ALL', 0)
+
   if exists("*SetUp")
-    call SetUp()
+    try
+      call SetUp()
+    catch
+      call add(v:errors, 'Caught exception in SetUp() before ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint)
+    endtry
   endif
 
   call add(s:messages, 'Executing ' . a:test)
@@ -104,7 +119,11 @@ function RunTheTest(test)
   endtry
 
   if exists("*TearDown")
-    call TearDown()
+    try
+      call TearDown()
+    catch
+      call add(v:errors, 'Caught exception in TearDown() after ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint)
+    endtry
   endif
 
   " Close any extra windows and make the current one not modified.
@@ -123,6 +142,60 @@ function RunTheTest(test)
   set nomodified
 endfunc
 
+func AfterTheTest()
+  if len(v:errors) > 0
+    let s:fail += 1
+    call add(s:errors, 'Found errors in ' . s:test . ':')
+    call extend(s:errors, v:errors)
+    let v:errors = []
+  endif
+endfunc
+
+" This function can be called by a test if it wants to abort testing.
+func FinishTesting()
+  call AfterTheTest()
+
+  " Don't write viminfo on exit.
+  set viminfo=
+
+  if s:fail == 0
+    " Success, create the .res file so that make knows it's done.
+    exe 'split ' . fnamemodify(g:testname, ':r') . '.res'
+    write
+  endif
+
+  if len(s:errors) > 0
+    " Append errors to test.log
+    split test.log
+    call append(line('$'), '')
+    call append(line('$'), 'From ' . g:testname . ':')
+    call append(line('$'), s:errors)
+    write
+  endif
+
+  let message = 'Executed ' . s:done . (s:done > 1 ? ' tests' : ' test')
+  echo message
+  call add(s:messages, message)
+  if s:fail > 0
+    let message = s:fail . ' FAILED:'
+    echo message
+    call add(s:messages, message)
+    call extend(s:messages, s:errors)
+  endif
+
+  " Add SKIPPED messages
+  call extend(s:messages, s:skipped)
+
+  " Append messages to the file "messages"
+  split messages
+  call append(line('$'), '')
+  call append(line('$'), 'From ' . g:testname . ':')
+  call append(line('$'), s:messages)
+  write
+
+  qall!
+endfunc
+
 " Source the test script.  First grab the file name, in case the script
 " navigates away.  g:testname can be used by the tests.
 let g:testname = expand('%')
@@ -131,7 +204,7 @@ let s:fail = 0
 let s:errors = []
 let s:messages = []
 let s:skipped = []
-if expand('%') =~ 'test_viml.vim'
+if expand('%') =~ 'test_vimscript.vim'
   " this test has intentional s:errors, don't use try/catch.
   source %
 else
@@ -145,15 +218,21 @@ endif
 
 " Names of flaky tests.
 let s:flaky = [
-      \ 'Test_reltime()',
-      \ 'Test_nb_basic()',
+      \ 'Test_client_server()',
+      \ 'Test_close_and_exit_cb()',
+      \ 'Test_collapse_buffers()',
       \ 'Test_communicate()',
+      \ 'Test_exit_callback_interval()',
+      \ 'Test_nb_basic()',
+      \ 'Test_oneshot()',
       \ 'Test_pipe_through_sort_all()',
-      \ 'Test_pipe_through_sort_some()'
+      \ 'Test_pipe_through_sort_some()',
+      \ 'Test_quoteplus()',
+      \ 'Test_quotestar()',
+      \ 'Test_reltime()',
       \ ]
 
 " Locate Test_ functions and execute them.
-set nomore
 redir @q
 silent function /^Test_
 redir END
@@ -169,55 +248,25 @@ for s:test in sort(s:tests)
   call RunTheTest(s:test)
 
   if len(v:errors) > 0 && index(s:flaky, s:test) >= 0
+    call add(s:messages, 'Found errors in ' . s:test . ':')
+    call extend(s:messages, v:errors)
     call add(s:messages, 'Flaky test failed, running it again')
+    let first_run = v:errors
+
     let v:errors = []
     call RunTheTest(s:test)
+    if len(v:errors) > 0
+      let second_run = v:errors
+      let v:errors = ['First run:']
+      call extend(v:errors, first_run)
+      call add(v:errors, 'Second run:')
+      call extend(v:errors, second_run)
+    endif
   endif
 
-  if len(v:errors) > 0
-    let s:fail += 1
-    call add(s:errors, 'Found errors in ' . s:test . ':')
-    call extend(s:errors, v:errors)
-    let v:errors = []
-  endif
+  call AfterTheTest()
 endfor
 
-" Don't write viminfo on exit.
-set viminfo=
-
-if s:fail == 0
-  " Success, create the .res file so that make knows it's done.
-  exe 'split ' . fnamemodify(g:testname, ':r') . '.res'
-  write
-endif
-
-if len(s:errors) > 0
-  " Append errors to test.log
-  split test.log
-  call append(line('$'), '')
-  call append(line('$'), 'From ' . g:testname . ':')
-  call append(line('$'), s:errors)
-  write
-endif
-
-let message = 'Executed ' . s:done . (s:done > 1 ? ' tests' : ' test')
-echo message
-call add(s:messages, message)
-if s:fail > 0
-  let message = s:fail . ' FAILED:'
-  echo message
-  call add(s:messages, message)
-  call extend(s:messages, s:errors)
-endif
-
-" Add SKIPPED messages
-call extend(s:messages, s:skipped)
-
-" Append messages to the file "messages"
-split messages
-call append(line('$'), '')
-call append(line('$'), 'From ' . g:testname . ':')
-call append(line('$'), s:messages)
-write
+call FinishTesting()
 
-qall!
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/setup_gui.vim b/src/testdir/setup_gui.vim
new file mode 100644 (file)
index 0000000..90ef1f1
--- /dev/null
@@ -0,0 +1,32 @@
+" Common preparations for running GUI tests.
+
+let g:x11_based_gui = has('gui_athena') || has('gui_motif')
+       \ || has('gui_gtk2') || has('gui_gnome') || has('gui_gtk3')
+
+" Reasons for 'skipped'.
+let g:not_supported   = "Skipped: Feature/Option not supported by this GUI: "
+let g:not_implemented = "Skipped: Test not implemented yet for this GUI"
+let g:not_hosted      = "Skipped: Test not hosted by the system/environment"
+
+" For KDE set a font, empty 'guifont' may cause a hang.
+func GUISetUpCommon()
+  if has("gui_kde")
+    set guifont=Courier\ 10\ Pitch/8/-1/5/50/0/0/0/0/0
+  endif
+
+  " Gnome insists on creating $HOME/.gnome2/, set $HOME to avoid changing the
+  " actual home directory.  But avoid triggering fontconfig by setting the
+  " cache directory.  Only needed for Unix.
+  if $XDG_CACHE_HOME == '' && exists('g:tester_HOME')
+    let $XDG_CACHE_HOME = g:tester_HOME . '/.cache'
+  endif
+  call mkdir('Xhome')
+  let $HOME = fnamemodify('Xhome', ':p')
+endfunc
+
+func GUITearDownCommon()
+  call delete('Xhome', 'rf')
+endfunc
+
+" Ignore the "failed to create input context" error.
+call test_ignore_error('E285')
index 45a2ea4..e28d162 100644 (file)
@@ -88,7 +88,7 @@ func RunServer(cmd, testfunc, args)
 
     call call(function(a:testfunc), [port])
   catch
-    call assert_false(1, "Caught exception: " . v:exception)
+    call assert_false(1, 'Caught exception: "' . v:exception . '" in ' . v:throwpoint)
   finally
     call s:kill_server(a:cmd)
   endtry
@@ -164,6 +164,22 @@ func s:feedkeys(timer)
   call feedkeys('x', 'nt')
 endfunc
 
+" Get the command to run Vim, with -u NONE and --not-a-term arguments.
+" Returns an empty string on error.
+func GetVimCommand()
+  if !filereadable('vimcmd')
+    return ''
+  endif
+  let cmd = readfile('vimcmd')[0]
+  let cmd = substitute(cmd, '-u \f\+', '-u NONE', '')
+  if cmd !~ '-u NONE'
+    let cmd = cmd . ' -u NONE'
+  endif
+  let cmd .= ' --not-a-term'
+  let cmd = substitute(cmd, 'VIMRUNTIME=.*VIMRUNTIME;', '', '')
+  return cmd
+endfunc
+
 " Run Vim, using the "vimcmd" file and "-u NORC".
 " "before" is a list of Vim commands to be executed before loading plugins.
 " "after" is a list of Vim commands to be executed after loading plugins.
@@ -174,7 +190,8 @@ func RunVim(before, after, arguments)
 endfunc
 
 func RunVimPiped(before, after, arguments, pipecmd)
-  if !filereadable('vimcmd')
+  let cmd = GetVimCommand()
+  if cmd == ''
     return 0
   endif
   let args = ''
@@ -187,17 +204,6 @@ func RunVimPiped(before, after, arguments, pipecmd)
     let args .= ' -S Xafter.vim'
   endif
 
-  let cmd = readfile('vimcmd')[0]
-  let cmd = substitute(cmd, '-u \f\+', '-u NONE', '')
-  if cmd !~ '-u NONE'
-    let cmd = cmd . ' -u NONE'
-  endif
-
-  " With pipecmd we can't set VIMRUNTIME.
-  if a:pipecmd != ''
-    let cmd = substitute(cmd, 'VIMRUNTIME=.*VIMRUNTIME;', '', '')
-  endif
-
   exe "silent !" . a:pipecmd . cmd . args . ' ' . a:arguments
 
   if len(a:before) > 0
index 7c7591e..a4c8084 100644 (file)
@@ -1,6 +1,7 @@
 Test for visual mode not being reset causing E315 error.
 STARTTEST
 :so small.vim
+:set belloff=all
 :enew
 :let g:msg="Everything's fine."
 :function! TriggerTheProblem()
index fb987eb..3fc39fe 100644 (file)
@@ -6,6 +6,7 @@ Also test search()
 
 STARTTEST
 :so small.vim
+:set belloff=all
 /Start cursor here
 vaBiBD:?Bug?,/Piece/-2w! test.out
 /^- Bug
index 65e28c1..366a551 100644 (file)
@@ -103,6 +103,7 @@ if (condition) // Remove the next comment leader!
 
 STARTTEST
 :" Test with backspace set to the non-compatible setting
+:set belloff=all
 /^\d\+ this
 :set cp bs=2
 Avim1\15\e
index c0a68d0..c78a66e 100644 (file)
@@ -1,6 +1,7 @@
 /* vim: set cin ts=4 sw=4 : */
 
-Test for 'cindent'
+Test for 'cindent'.
+For new tests, consider putting them in test_cindent.vim.
 
 STARTTEST
 :so small.vim
@@ -969,7 +970,8 @@ break;
 /* end of AUTO */
 
 STARTTEST
-:set tw=0 wm=60 columns=80 noai fo=croq
+:set tw=0 noai fo=croq
+:let &wm = &columns - 20
 /serious/e
 a about life, the universe, and the rest\e
 ENDTEST
@@ -1932,6 +1934,26 @@ namespace test
 {
   111111111111111111;
 }
+namespace test::cpp17
+{
+  111111111111111111;
+}
+namespace ::incorrectcpp17
+{
+  111111111111111111;
+}
+namespace test::incorrectcpp17::
+{
+  111111111111111111;
+}
+namespace test:incorrectcpp17
+{
+  111111111111111111;
+}
+namespace test:::incorrectcpp17
+{
+  111111111111111111;
+}
 namespace{
   111111111111111111;
 }
@@ -2298,6 +2320,25 @@ i;
 JSEND
 
 STARTTEST
+:set cin cino&
+/start of define
+=/end of define
+ENDTEST
+
+/* start of define */
+{
+}
+#define AAA \
+BBB\
+CCC
+
+#define CNT \
+1 + \
+2 + \
+4
+/* end of define */
+
+STARTTEST
 :g/^STARTTEST/.,/^ENDTEST/d
 :1;/start of AUTO/,$wq! test.out
 ENDTEST
index c4c01a3..cfb519b 100644 (file)
@@ -1730,6 +1730,26 @@ namespace test
 {
 111111111111111111;
 }
+namespace test::cpp17
+{
+111111111111111111;
+}
+namespace ::incorrectcpp17
+{
+       111111111111111111;
+}
+namespace test::incorrectcpp17::
+{
+       111111111111111111;
+}
+namespace test:incorrectcpp17
+{
+       111111111111111111;
+}
+namespace test:::incorrectcpp17
+{
+       111111111111111111;
+}
 namespace{
 111111111111111111;
 }
@@ -2060,3 +2080,17 @@ var a,
        i;
 JSEND
 
+
+/* start of define */
+{
+}
+#define AAA \
+       BBB\
+       CCC
+
+#define CNT \
+       1 + \
+       2 + \
+       4
+/* end of define */
+
index 70bedc5..df49404 100644 (file)
@@ -4,6 +4,7 @@ Note: This test will fail if "cat" is not available.
 
 STARTTEST
 :so small.vim
+:set belloff=all
 :" first write three test files, one in each format
 :set fileformat=unix
 :set fileformats=
index 6b399fa..602d9e5 100644 (file)
@@ -23,6 +23,7 @@ Test for insert expansion
 STARTTEST
 :so small.vim
 :se nocp viminfo+=nviminfo cpt=.,w ff=unix | $-2,$w!Xtestfile | set ff&
+:set belloff=all
 :se cot=
 \17nO#include "Xtestfile"
 ru\ e\ e\18\ e\e\ 1
index b1e8266..c6d7c50 100644 (file)
@@ -2,6 +2,7 @@ Tests for folding. vim: set ft=vim :
 
 STARTTEST
 :so small.vim
+:set belloff=all
 :" We also need the +syntax feature here.
 :if !has("syntax")
    e! test.ok
@@ -26,6 +27,7 @@ kYpj:call append("$", foldlevel("."))
 /^2 b
 i  \ejI    \e:call append("$", "indent " . foldlevel("."))
 k:call append("$", foldlevel("."))
+:set sw&
 :" test syntax folding
 :set fdm=syntax fdl=0
 :syn region Hup start="dd" end="ii" fold contains=Fd1,Fd2,Fd3
index e763c6f..f50062e 100644 (file)
@@ -608,7 +608,7 @@ com! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>)
 " END_OF_TEST_ENVIRONMENT - do not change or remove this line.
 
 
-" Tests 1 to 15 were moved to test_viml.vim
+" Tests 1 to 15 were moved to test_vimscript.vim
 let Xtest = 16
 
 "-------------------------------------------------------------------------------
index a407eea..961df4c 100644 (file)
@@ -4,6 +4,7 @@ undo-able pieces.  Do that by setting 'undolevels'.
 
 STARTTEST
 :so small.vim
+:set belloff=all
 :"
 :" Test 'undofile': first a simple one-line change.
 :set nocompatible viminfo+=nviminfo visualbell
@@ -25,7 +26,6 @@ u:.w! test.out
 :set undofile
 :bwipe!
 :e Xtestfile
-:" TODO: this beeps
 u:.w >>test.out
 :"
 :" Test 'undofile', add 10 lines, delete 6 lines, undo 3
index a0b9ae8..67fe455 100644 (file)
@@ -2,6 +2,7 @@ Tests for find completion.
 
 STARTTEST
 :so small.vim
+:set belloff=all
 :" Do all test in a separate window to avoid E211 when we recursively
 :" delete the Xfind directory during cleanup
 :"
index 0dbc4fc..55a1c30 100644 (file)
@@ -10,6 +10,7 @@ If it isn't available then the test will be skipped.
 
 STARTTEST
 :so small.vim
+:set belloff=all
 :if !executable("cksum")
 : e! test.ok
 : w! test.out
index 1850bd9..e97f4a4 100644 (file)
@@ -6,7 +6,7 @@ blocks.
 
 STARTTEST
 :so small.vim
-:set nocp fileformat=unix undolevels=-1 viminfo+=nviminfo
+:set nocp fileformat=unix undolevels=-1 viminfo+=nviminfo belloff=all
 :e! Xtest
 ggdG
 :let text = "\tabcdefghijklmnoparstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnoparstuvwxyz0123456789"
index c5ca873..0a13394 100644 (file)
@@ -2,6 +2,7 @@ Test for Lua interface and luaeval() function
 
 STARTTEST
 :so small.vim
+:set belloff=all
 :so lua.vim
 :set nocompatible viminfo+=nviminfo
 :lua l = vim.list():add"item0":add"dictionary with list OK":add"item2"
index 0db3a27..ac04109 100644 (file)
@@ -230,13 +230,26 @@ def ee(expr, g=globals(), l=locals()):
                 cb.append(expr + ':' + repr((e.__class__, AttributeError(str(e)[str(e).rfind(" '") + 2:-1]))))
             elif sys.version_info >= (3, 3) and e.__class__ is ImportError and str(e).find('No module named \'') >= 0:
                 cb.append(expr + ':' + repr((e.__class__, ImportError(str(e).replace("'", '')))))
+            elif sys.version_info >= (3, 6) and e.__class__ is ModuleNotFoundError:
+                # Python 3.6 gives ModuleNotFoundError, change it to an ImportError
+                cb.append(expr + ':' + repr((ImportError, ImportError(str(e).replace("'", '')))))
             elif sys.version_info >= (3, 3) and e.__class__ is TypeError:
                 m = py33_type_error_pattern.search(str(e))
                 if m:
                     msg = '__call__() takes exactly {0} positional argument ({1} given)'.format(m.group(1), m.group(2))
                     cb.append(expr + ':' + repr((e.__class__, TypeError(msg))))
                 else:
-                    cb.append(expr + ':' + repr((e.__class__, e)))
+                    msg = repr((e.__class__, e))
+                    # Messages changed with Python 3.6, change new to old.
+                    newmsg1 = """'argument must be str, bytes or bytearray, not None'"""
+                    oldmsg1 = '''"Can't convert 'NoneType' object to str implicitly"'''
+                    if msg.find(newmsg1) > -1:
+                        msg = msg.replace(newmsg1, oldmsg1)
+                    newmsg2 = """'argument must be str, bytes or bytearray, not int'"""
+                    oldmsg2 = '''"Can't convert 'int' object to str implicitly"'''
+                    if msg.find(newmsg2) > -1:
+                        msg = msg.replace(newmsg2, oldmsg2)
+                    cb.append(expr + ':' + msg)
             elif sys.version_info >= (3, 5) and e.__class__ is ValueError and str(e) == 'embedded null byte':
                 cb.append(expr + ':' + repr((TypeError, TypeError('expected bytes with no null'))))
             else:
diff --git a/src/testdir/test89.in b/src/testdir/test89.in
deleted file mode 100644 (file)
index 1c3079f..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-- Some tests for setting 'number' and 'relativenumber'
-  This is not all that useful now that the options are no longer reset when
-  setting the other.
-- Some tests for findfile() function
-
-STARTTEST
-:so small.vim
-:set hidden nocp nu rnu viminfo+=nviminfo
-:redir @a | set nu? rnu? | redir END
-:e! xx
-:redir @b | set nu? rnu? | redir END
-:e! #
-:$put ='results:'
-:$put a
-:$put b
-:"
-:set nonu nornu
-:setglobal nu
-:setlocal rnu
-:redir @c | setglobal nu? | redir END
-:set nonu nornu
-:setglobal rnu
-:setlocal nu
-:redir @d | setglobal rnu? | redir END
-:$put =':setlocal must NOT reset the other global value'
-:$put c
-:$put d
-:"
-:set nonu nornu
-:setglobal nu
-:setglobal rnu
-:redir @e | setglobal nu? | redir END
-:set nonu nornu
-:setglobal rnu
-:setglobal nu
-:redir @f | setglobal rnu? | redir END
-:$put =':setglobal MUST reset the other global value'
-:$put e
-:$put f
-:"
-:set nonu nornu
-:set nu
-:set rnu
-:redir @g | setglobal nu? | redir END
-:set nonu nornu
-:set rnu
-:set nu
-:redir @h | setglobal rnu? | redir END
-:$put =':set MUST reset the other global value'
-:$put g
-:$put h
-:"
-:let cwd=getcwd()
-:cd ..
-:" Tests may be run from a shadow directory, so an extra cd needs to be done to
-:" get above src/
-:if fnamemodify(getcwd(), ':t') != 'src' | cd ../.. | else | cd .. | endif
-:$put =''
-:$put ='Testing findfile'
-:$put =''
-:set ssl
-:$put =findfile('test19.in','src/test*')
-:exe "cd" cwd
-:cd ..
-:$put =findfile('test19.in','test*')
-:$put =findfile('test19.in','testdir')
-:exe "cd" cwd
-:/^results/,$w! test.out
-:q!
-ENDTEST
-
diff --git a/src/testdir/test89.ok b/src/testdir/test89.ok
deleted file mode 100644 (file)
index 9003475..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-results:
-
-  number
-  relativenumber
-
-  number
-  relativenumber
-:setlocal must NOT reset the other global value
-
-  number
-
-  relativenumber
-:setglobal MUST reset the other global value
-
-  number
-
-  relativenumber
-:set MUST reset the other global value
-
-  number
-
-  relativenumber
-
-Testing findfile
-
-src/testdir/test19.in
-testdir/test19.in
-testdir/test19.in
index e1365cb..c184ac3 100644 (file)
@@ -1,4 +1,4 @@
-Tests for getbufvar(), getwinvar(), gettabvar() and gettabwinvar().
+Tests for getwinvar(), gettabvar() and gettabwinvar().
 vim: set ft=vim :
 
 STARTTEST
@@ -10,34 +10,7 @@ STARTTEST
 :let t:testvar='abcd'
 :$put =string(gettabvar(1,'testvar'))
 :$put =string(gettabvar(1,'testvar'))
-:" Test for getbufvar()
-:let b:var_num = '1234'
-:let def_num = '5678'
-:$put =string(getbufvar(1, 'var_num'))
-:$put =string(getbufvar(1, 'var_num', def_num))
-:$put =string(getbufvar(1, ''))
-:$put =string(getbufvar(1, '', def_num))
-:unlet b:var_num
-:$put =string(getbufvar(1, 'var_num', def_num))
-:$put =string(getbufvar(1, ''))
-:$put =string(getbufvar(1, '', def_num))
-:$put =string(getbufvar(9, ''))
-:$put =string(getbufvar(9, '', def_num))
-:unlet def_num
-:$put =string(getbufvar(1, '&autoindent'))
-:$put =string(getbufvar(1, '&autoindent', 1))
 :"
-:" Open new window with forced option values
-:set fileformats=unix,dos
-:new ++ff=dos ++bin ++enc=iso-8859-2
-:let otherff = getbufvar(bufnr('%'), '&fileformat')
-:let otherbin = getbufvar(bufnr('%'), '&bin')
-:let otherfenc = getbufvar(bufnr('%'), '&fenc')
-:close
-:$put =otherff
-:$put =string(otherbin)
-:$put =otherfenc
-:unlet otherff otherbin otherfenc
 :" test for getwinvar()
 :let w:var_str = "Dance"
 :let def_str = "Chance"
index 62adec1..2cdf288 100644 (file)
@@ -1,20 +1,6 @@
 start:
 'abcd'
 'abcd'
-'1234'
-'1234'
-{'var_num': '1234'}
-{'var_num': '1234'}
-'5678'
-{}
-{}
-''
-'5678'
-0
-0
-dos
-1
-iso-8859-2
 'Dance'
 'Dance'
 {'var_str': 'Dance'}
diff --git a/src/testdir/test92.in b/src/testdir/test92.in
deleted file mode 100644 (file)
index 9593aec..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-vim: set ft=vim fenc=utf-8:
-
-Tests if :mksession saves cursor columns correctly in presence of tab and 
-multibyte characters when fileencoding=utf-8.
-
-STARTTEST
-:so mbyte.vim
-:if !has('mksession')
-:  e! test.ok
-:  wq! test.out
-:endif
-:set sessionoptions=buffers splitbelow fileencoding=utf-8
-/^start:
-:vsplit
-j16|:split
-j16|:split
-j16|:split
-j8|:split
-j8|:split
-j16|:split
-j16|:split
-j16|:wincmd l
-/^start:
-:set nowrap
-j16|3zl:split
-j016|3zl:split
-j016|3zl:split
-j08|3zl:split
-j08|3zl:split
-j016|3zl:split
-j016|3zl:split
-j016|3zl:split
-:mksession! test.out
-:new test.out
-:v/\(^ *normal! 0\|^ *exe 'normal!\)/d
-:w! test.out
-:qa!
-ENDTEST
-
-start:
-no multibyte chAracter
-       one leaDing tab
-    four leadinG spaces
-two            consecutive tabs
-two    tabs    in one line
-one … multibyteCharacter
-a “b” two multiByte characters
-“c”1€ three mulTibyte characters
diff --git a/src/testdir/test92.ok b/src/testdir/test92.ok
deleted file mode 100644 (file)
index cca5ec4..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-normal! 016|
-normal! 016|
-normal! 016|
-normal! 08|
-normal! 08|
-normal! 016|
-normal! 016|
-normal! 016|
-  exe 'normal! ' . s:c . '|zs' . 16 . '|'
-  normal! 016|
-  exe 'normal! ' . s:c . '|zs' . 16 . '|'
-  normal! 016|
-  exe 'normal! ' . s:c . '|zs' . 16 . '|'
-  normal! 016|
-  exe 'normal! ' . s:c . '|zs' . 8 . '|'
-  normal! 08|
-  exe 'normal! ' . s:c . '|zs' . 8 . '|'
-  normal! 08|
-  exe 'normal! ' . s:c . '|zs' . 16 . '|'
-  normal! 016|
-  exe 'normal! ' . s:c . '|zs' . 16 . '|'
-  normal! 016|
-  exe 'normal! ' . s:c . '|zs' . 16 . '|'
-  normal! 016|
-  exe 'normal! ' . s:c . '|zs' . 16 . '|'
-  normal! 016|
diff --git a/src/testdir/test93.in b/src/testdir/test93.in
deleted file mode 100644 (file)
index 877838c..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-vim: set ft=vim fenc=latin1:
-
-Tests if :mksession saves cursor columns correctly in presence of tab and 
-multibyte characters when fileencoding=latin1.
-
-STARTTEST
-:so mbyte.vim
-:if !has('mksession')
-:  e! test.ok
-:  wq! test.out
-:endif
-:set sessionoptions=buffers splitbelow fileencoding=latin1
-/^start:
-:vsplit
-j16|:split
-j16|:split
-j16|:split
-j8|:split
-j8|:split
-j16|:split
-j16|:split
-j16|:wincmd l
-/^start:
-:set nowrap
-j16|3zl:split
-j016|3zl:split
-j016|3zl:split
-j08|3zl:split
-j08|3zl:split
-j016|3zl:split
-j016|3zl:split
-j016|3zl:split
-:mksession! test.out
-:new test.out
-:v/\(^ *normal! 0\|^ *exe 'normal!\)/d
-:w! test.out
-:qa!
-ENDTEST
-
-start:
-no multibyte chAracter
-       one leaDing tab
-    four leadinG spaces
-two            consecutive tabs
-two    tabs    in one line
-one ä multibyteCharacter
-aä Ä  two multiByte characters
-Aäöü  three mulTibyte characters
diff --git a/src/testdir/test93.ok b/src/testdir/test93.ok
deleted file mode 100644 (file)
index cca5ec4..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-normal! 016|
-normal! 016|
-normal! 016|
-normal! 08|
-normal! 08|
-normal! 016|
-normal! 016|
-normal! 016|
-  exe 'normal! ' . s:c . '|zs' . 16 . '|'
-  normal! 016|
-  exe 'normal! ' . s:c . '|zs' . 16 . '|'
-  normal! 016|
-  exe 'normal! ' . s:c . '|zs' . 16 . '|'
-  normal! 016|
-  exe 'normal! ' . s:c . '|zs' . 8 . '|'
-  normal! 08|
-  exe 'normal! ' . s:c . '|zs' . 8 . '|'
-  normal! 08|
-  exe 'normal! ' . s:c . '|zs' . 16 . '|'
-  normal! 016|
-  exe 'normal! ' . s:c . '|zs' . 16 . '|'
-  normal! 016|
-  exe 'normal! ' . s:c . '|zs' . 16 . '|'
-  normal! 016|
-  exe 'normal! ' . s:c . '|zs' . 16 . '|'
-  normal! 016|
index 238fef3..447fd2b 100644 (file)
@@ -17,6 +17,7 @@ Test cases:
 
 STARTTEST
 :so small.vim
+:set belloff=all
 :set enc=utf-8 nocp viminfo+=nviminfo
 :
 :" User functions
index d24b97f..e961e99 100644 (file)
@@ -1,35 +1,44 @@
 " A series of tests that can run in one Vim invocation.
 " This makes testing go faster, since Vim doesn't need to restart.
 
+set belloff=all
 source test_assign.vim
-source test_autocmd.vim
-source test_command_count.vim
+source test_cd.vim
+source test_changedtick.vim
 source test_cursor_func.vim
 source test_delete.vim
-source test_execute_func.vim
 source test_ex_undo.vim
+source test_ex_z.vim
+source test_execute_func.vim
 source test_expand.vim
-source test_expr.vim
 source test_expand_dllpath.vim
+source test_expr.vim
 source test_feedkeys.vim
 source test_file_perm.vim
 source test_fileformat.vim
 source test_filter_cmd.vim
 source test_filter_map.vim
+source test_findfile.vim
+source test_float_func.vim
 source test_fnamemodify.vim
+source test_functions.vim
+source test_ga.vim
 source test_glob2regpat.vim
+source test_global.vim
 source test_goto.vim
 source test_help_tagjump.vim
 source test_join.vim
 source test_jumps.vim
 source test_lambda.vim
 source test_lispwords.vim
+source test_mapping.vim
 source test_match.vim
 source test_menu.vim
-source test_mapping.vim
 source test_messages.vim
 source test_partial.vim
 source test_popup.vim
+source test_put.vim
+source test_recover.vim
 source test_reltime.vim
 source test_searchpos.vim
 source test_set.vim
@@ -40,8 +49,8 @@ source test_tabline.vim
 source test_tabpage.vim
 source test_tagcase.vim
 source test_tagjump.vim
+source test_taglist.vim
 source test_timers.vim
 source test_true_false.vim
 source test_unlet.vim
 source test_window_cmd.vim
-source test_options.vim
index 539e0e1..13724cb 100644 (file)
@@ -5,7 +5,10 @@
 " runtest.vim.  Checking for the multi_byte feature is in the individual
 " files, so that they can be run by themselves.
 
+set belloff=all
+source test_charsearch_utf8.vim
 source test_expr_utf8.vim
 source test_matchadd_conceal_utf8.vim
 source test_regexp_utf8.vim
 source test_source_utf8.vim
+source test_utf8.vim
diff --git a/src/testdir/test_arabic.vim b/src/testdir/test_arabic.vim
new file mode 100644 (file)
index 0000000..e62b022
--- /dev/null
@@ -0,0 +1,613 @@
+" Simplistic testing of Arabic mode.
+" NOTE: This just checks if the code works. If you know Arabic please add
+" functional tests that check the shaping works with real text.
+
+if !has('arabic') || !has('multi_byte')
+  finish
+endif
+
+source view_util.vim
+
+" Return list of Unicode characters at line lnum.
+" Combining characters are treated as a single item.
+func s:get_chars(lnum)
+  call cursor(a:lnum, 1)
+  let chars = []
+  let numchars = strchars(getline('.'), 1)
+  for i in range(1, numchars)
+    exe 'norm ' i . '|'
+    let c=execute('ascii')
+    let c=substitute(c, '\n\?<.\{-}Hex\s*', 'U+', 'g')
+    let c=substitute(c, ',\s*Octal\s*\d*', '', 'g')
+    call add(chars, c)
+  endfor
+  return chars
+endfunc
+
+func Test_arabic_toggle()
+  set arabic
+  call assert_equal(1, &rightleft)
+  call assert_equal(1, &arabicshape)
+  call assert_equal('arabic', &keymap)
+  call assert_equal(1, &delcombine)
+
+  set iminsert=1 imsearch=1
+  set arabic&
+  call assert_equal(0, &rightleft)
+  call assert_equal(1, &arabicshape)
+  call assert_equal('arabic', &keymap)
+  call assert_equal(1, &delcombine)
+  call assert_equal(0, &iminsert)
+  call assert_equal(-1, &imsearch)
+
+  set arabicshape& keymap= delcombine&
+endfunc
+
+func Test_arabic_input()
+  new
+  set arabic
+  " Typing sghl in Arabic insert mode should show the
+  " Arabic word 'Salaam' i.e. 'peace', spelled:
+  " SEEN, LAM, ALEF, MEEM.
+  " See: https://www.mediawiki.org/wiki/VisualEditor/Typing/Right-to-left
+  call feedkeys('isghl!', 'tx')
+  call assert_match("^ *!\uFEE1\uFEFC\uFEB3$", ScreenLines(1, &columns)[0])
+  call assert_equal([
+  \ 'U+0633',
+  \ 'U+0644 U+0627',
+  \ 'U+0645',
+  \ 'U+21'], s:get_chars(1))
+
+  " Without shaping, it should give individual Arabic letters.
+  set noarabicshape
+  call assert_match("^ *!\u0645\u0627\u0644\u0633$", ScreenLines(1, &columns)[0])
+  call assert_equal([
+  \ 'U+0633',
+  \ 'U+0644',
+  \ 'U+0627',
+  \ 'U+0645',
+  \ 'U+21'], s:get_chars(1))
+
+  set arabic& arabicshape&
+  bwipe!
+endfunc
+
+func Test_arabic_toggle_keymap()
+  new
+  set arabic
+  call feedkeys("i12\<C-^>12\<C-^>12", 'tx')
+  call assert_match("^ *٢١21٢١$", ScreenLines(1, &columns)[0])
+  call assert_equal('١٢12١٢', getline('.'))
+  set arabic&
+  bwipe!
+endfunc
+
+func Test_delcombine()
+  new
+  set arabic
+  call feedkeys("isghl\<BS>\<BS>", 'tx')
+  call assert_match("^ *\uFEDE\uFEB3$", ScreenLines(1, &columns)[0])
+  call assert_equal(['U+0633', 'U+0644'], s:get_chars(1))
+
+  " Now the same with 'nodelcombine'
+  set nodelcombine
+  %d
+  call feedkeys("isghl\<BS>\<BS>", 'tx')
+  call assert_match("^ *\uFEB1$", ScreenLines(1, &columns)[0])
+  call assert_equal(['U+0633'], s:get_chars(1))
+  set arabic&
+  bwipe!
+endfunc
+
+" Values from src/arabic.h (not all used yet)
+let s:a_COMMA = "\u060C"
+let s:a_SEMICOLON = "\u061B"
+let s:a_QUESTION = "\u061F"
+let s:a_HAMZA = "\u0621"
+let s:a_ALEF_MADDA = "\u0622"
+let s:a_ALEF_HAMZA_ABOVE = "\u0623"
+let s:a_WAW_HAMZA = "\u0624"
+let s:a_ALEF_HAMZA_BELOW = "\u0625"
+let s:a_YEH_HAMZA = "\u0626"
+let s:a_ALEF = "\u0627"
+let s:a_BEH = "\u0628"
+let s:a_TEH_MARBUTA = "\u0629"
+let s:a_TEH = "\u062a"
+let s:a_THEH = "\u062b"
+let s:a_JEEM = "\u062c"
+let s:a_HAH = "\u062d"
+let s:a_KHAH = "\u062e"
+let s:a_DAL = "\u062f"
+let s:a_THAL = "\u0630"
+let s:a_REH = "\u0631"
+let s:a_ZAIN = "\u0632"
+let s:a_SEEN = "\u0633"
+let s:a_SHEEN = "\u0634"
+let s:a_SAD = "\u0635"
+let s:a_DAD = "\u0636"
+let s:a_TAH = "\u0637"
+let s:a_ZAH = "\u0638"
+let s:a_AIN = "\u0639"
+let s:a_GHAIN = "\u063a"
+let s:a_TATWEEL = "\u0640"
+let s:a_FEH = "\u0641"
+let s:a_QAF = "\u0642"
+let s:a_KAF = "\u0643"
+let s:a_LAM = "\u0644"
+let s:a_MEEM = "\u0645"
+let s:a_NOON = "\u0646"
+let s:a_HEH = "\u0647"
+let s:a_WAW = "\u0648"
+let s:a_ALEF_MAKSURA = "\u0649"
+let s:a_YEH = "\u064a"
+
+let s:a_FATHATAN = "\u064b"
+let s:a_DAMMATAN = "\u064c"
+let s:a_KASRATAN = "\u064d"
+let s:a_FATHA = "\u064e"
+let s:a_DAMMA = "\u064f"
+let s:a_KASRA = "\u0650"
+let s:a_SHADDA = "\u0651"
+let s:a_SUKUN = "\u0652"
+
+let s:a_MADDA_ABOVE = "\u0653"
+let s:a_HAMZA_ABOVE = "\u0654"
+let s:a_HAMZA_BELOW = "\u0655"
+
+let s:a_ZERO = "\u0660"
+let s:a_ONE = "\u0661"
+let s:a_TWO = "\u0662"
+let s:a_THREE = "\u0663"
+let s:a_FOUR = "\u0664"
+let s:a_FIVE = "\u0665"
+let s:a_SIX = "\u0666"
+let s:a_SEVEN = "\u0667"
+let s:a_EIGHT = "\u0668"
+let s:a_NINE = "\u0669"
+let s:a_PERCENT = "\u066a"
+let s:a_DECIMAL = "\u066b"
+let s:a_THOUSANDS = "\u066c"
+let s:a_STAR = "\u066d"
+let s:a_MINI_ALEF = "\u0670"
+
+let s:a_s_FATHATAN = "\ufe70"
+let s:a_m_TATWEEL_FATHATAN = "\ufe71"
+let s:a_s_DAMMATAN = "\ufe72"
+
+let s:a_s_KASRATAN = "\ufe74"
+
+let s:a_s_FATHA = "\ufe76"
+let s:a_m_FATHA = "\ufe77"
+let s:a_s_DAMMA = "\ufe78"
+let s:a_m_DAMMA = "\ufe79"
+let s:a_s_KASRA = "\ufe7a"
+let s:a_m_KASRA = "\ufe7b"
+let s:a_s_SHADDA = "\ufe7c"
+let s:a_m_SHADDA = "\ufe7d"
+let s:a_s_SUKUN = "\ufe7e"
+let s:a_m_SUKUN = "\ufe7f"
+
+let s:a_s_HAMZA = "\ufe80"
+let s:a_s_ALEF_MADDA = "\ufe81"
+let s:a_f_ALEF_MADDA = "\ufe82"
+let s:a_s_ALEF_HAMZA_ABOVE = "\ufe83"
+let s:a_f_ALEF_HAMZA_ABOVE = "\ufe84"
+let s:a_s_WAW_HAMZA = "\ufe85"
+let s:a_f_WAW_HAMZA = "\ufe86"
+let s:a_s_ALEF_HAMZA_BELOW = "\ufe87"
+let s:a_f_ALEF_HAMZA_BELOW = "\ufe88"
+let s:a_s_YEH_HAMZA = "\ufe89"
+let s:a_f_YEH_HAMZA = "\ufe8a"
+let s:a_i_YEH_HAMZA = "\ufe8b"
+let s:a_m_YEH_HAMZA = "\ufe8c"
+let s:a_s_ALEF = "\ufe8d"
+let s:a_f_ALEF = "\ufe8e"
+let s:a_s_BEH = "\ufe8f"
+let s:a_f_BEH = "\ufe90"
+let s:a_i_BEH = "\ufe91"
+let s:a_m_BEH = "\ufe92"
+let s:a_s_TEH_MARBUTA = "\ufe93"
+let s:a_f_TEH_MARBUTA = "\ufe94"
+let s:a_s_TEH = "\ufe95"
+let s:a_f_TEH = "\ufe96"
+let s:a_i_TEH = "\ufe97"
+let s:a_m_TEH = "\ufe98"
+let s:a_s_THEH = "\ufe99"
+let s:a_f_THEH = "\ufe9a"
+let s:a_i_THEH = "\ufe9b"
+let s:a_m_THEH = "\ufe9c"
+let s:a_s_JEEM = "\ufe9d"
+let s:a_f_JEEM = "\ufe9e"
+let s:a_i_JEEM = "\ufe9f"
+let s:a_m_JEEM = "\ufea0"
+let s:a_s_HAH = "\ufea1"
+let s:a_f_HAH = "\ufea2"
+let s:a_i_HAH = "\ufea3"
+let s:a_m_HAH = "\ufea4"
+let s:a_s_KHAH = "\ufea5"
+let s:a_f_KHAH = "\ufea6"
+let s:a_i_KHAH = "\ufea7"
+let s:a_m_KHAH = "\ufea8"
+let s:a_s_DAL = "\ufea9"
+let s:a_f_DAL = "\ufeaa"
+let s:a_s_THAL = "\ufeab"
+let s:a_f_THAL = "\ufeac"
+let s:a_s_REH = "\ufead"
+let s:a_f_REH = "\ufeae"
+let s:a_s_ZAIN = "\ufeaf"
+let s:a_f_ZAIN = "\ufeb0"
+let s:a_s_SEEN = "\ufeb1"
+let s:a_f_SEEN = "\ufeb2"
+let s:a_i_SEEN = "\ufeb3"
+let s:a_m_SEEN = "\ufeb4"
+let s:a_s_SHEEN = "\ufeb5"
+let s:a_f_SHEEN = "\ufeb6"
+let s:a_i_SHEEN = "\ufeb7"
+let s:a_m_SHEEN = "\ufeb8"
+let s:a_s_SAD = "\ufeb9"
+let s:a_f_SAD = "\ufeba"
+let s:a_i_SAD = "\ufebb"
+let s:a_m_SAD = "\ufebc"
+let s:a_s_DAD = "\ufebd"
+let s:a_f_DAD = "\ufebe"
+let s:a_i_DAD = "\ufebf"
+let s:a_m_DAD = "\ufec0"
+let s:a_s_TAH = "\ufec1"
+let s:a_f_TAH = "\ufec2"
+let s:a_i_TAH = "\ufec3"
+let s:a_m_TAH = "\ufec4"
+let s:a_s_ZAH = "\ufec5"
+let s:a_f_ZAH = "\ufec6"
+let s:a_i_ZAH = "\ufec7"
+let s:a_m_ZAH = "\ufec8"
+let s:a_s_AIN = "\ufec9"
+let s:a_f_AIN = "\ufeca"
+let s:a_i_AIN = "\ufecb"
+let s:a_m_AIN = "\ufecc"
+let s:a_s_GHAIN = "\ufecd"
+let s:a_f_GHAIN = "\ufece"
+let s:a_i_GHAIN = "\ufecf"
+let s:a_m_GHAIN = "\ufed0"
+let s:a_s_FEH = "\ufed1"
+let s:a_f_FEH = "\ufed2"
+let s:a_i_FEH = "\ufed3"
+let s:a_m_FEH = "\ufed4"
+let s:a_s_QAF = "\ufed5"
+let s:a_f_QAF = "\ufed6"
+let s:a_i_QAF = "\ufed7"
+let s:a_m_QAF = "\ufed8"
+let s:a_s_KAF = "\ufed9"
+let s:a_f_KAF = "\ufeda"
+let s:a_i_KAF = "\ufedb"
+let s:a_m_KAF = "\ufedc"
+let s:a_s_LAM = "\ufedd"
+let s:a_f_LAM = "\ufede"
+let s:a_i_LAM = "\ufedf"
+let s:a_m_LAM = "\ufee0"
+let s:a_s_MEEM = "\ufee1"
+let s:a_f_MEEM = "\ufee2"
+let s:a_i_MEEM = "\ufee3"
+let s:a_m_MEEM = "\ufee4"
+let s:a_s_NOON = "\ufee5"
+let s:a_f_NOON = "\ufee6"
+let s:a_i_NOON = "\ufee7"
+let s:a_m_NOON = "\ufee8"
+let s:a_s_HEH = "\ufee9"
+let s:a_f_HEH = "\ufeea"
+let s:a_i_HEH = "\ufeeb"
+let s:a_m_HEH = "\ufeec"
+let s:a_s_WAW = "\ufeed"
+let s:a_f_WAW = "\ufeee"
+let s:a_s_ALEF_MAKSURA = "\ufeef"
+let s:a_f_ALEF_MAKSURA = "\ufef0"
+let s:a_s_YEH = "\ufef1"
+let s:a_f_YEH = "\ufef2"
+let s:a_i_YEH = "\ufef3"
+let s:a_m_YEH = "\ufef4"
+let s:a_s_LAM_ALEF_MADDA_ABOVE = "\ufef5"
+let s:a_f_LAM_ALEF_MADDA_ABOVE = "\ufef6"
+let s:a_s_LAM_ALEF_HAMZA_ABOVE = "\ufef7"
+let s:a_f_LAM_ALEF_HAMZA_ABOVE = "\ufef8"
+let s:a_s_LAM_ALEF_HAMZA_BELOW = "\ufef9"
+let s:a_f_LAM_ALEF_HAMZA_BELOW = "\ufefa"
+let s:a_s_LAM_ALEF = "\ufefb"
+let s:a_f_LAM_ALEF = "\ufefc"
+
+let s:a_BYTE_ORDER_MARK = "\ufeff"
+
+func Test_shape_initial()
+  new
+  set arabicshape
+
+  " Shaping arabic {testchar} non-arabic   Tests chg_c_a2i().
+  " pair[0] = testchar, pair[1] = next-result, pair[2] = current-result
+  for pair in [[s:a_YEH_HAMZA, s:a_f_GHAIN, s:a_i_YEH_HAMZA],
+       \ [s:a_HAMZA, s:a_s_GHAIN, s:a_s_HAMZA],
+       \ [s:a_ALEF_MADDA, s:a_s_GHAIN, s:a_s_ALEF_MADDA],
+       \ [s:a_ALEF_HAMZA_ABOVE, s:a_s_GHAIN, s:a_s_ALEF_HAMZA_ABOVE],
+       \ [s:a_WAW_HAMZA, s:a_s_GHAIN, s:a_s_WAW_HAMZA],
+       \ [s:a_ALEF_HAMZA_BELOW, s:a_s_GHAIN, s:a_s_ALEF_HAMZA_BELOW],
+       \ [s:a_ALEF, s:a_s_GHAIN, s:a_s_ALEF],
+       \ [s:a_TEH_MARBUTA, s:a_s_GHAIN, s:a_s_TEH_MARBUTA],
+       \ [s:a_DAL, s:a_s_GHAIN, s:a_s_DAL],
+       \ [s:a_THAL, s:a_s_GHAIN, s:a_s_THAL],
+       \ [s:a_REH, s:a_s_GHAIN, s:a_s_REH],
+       \ [s:a_ZAIN, s:a_s_GHAIN, s:a_s_ZAIN],
+       \ [s:a_TATWEEL, s:a_f_GHAIN, s:a_TATWEEL],
+       \ [s:a_WAW, s:a_s_GHAIN, s:a_s_WAW],
+       \ [s:a_ALEF_MAKSURA, s:a_s_GHAIN, s:a_s_ALEF_MAKSURA],
+       \ [s:a_BEH, s:a_f_GHAIN, s:a_i_BEH],
+       \ [s:a_TEH, s:a_f_GHAIN, s:a_i_TEH],
+       \ [s:a_THEH, s:a_f_GHAIN, s:a_i_THEH],
+       \ [s:a_JEEM, s:a_f_GHAIN, s:a_i_JEEM],
+       \ [s:a_HAH, s:a_f_GHAIN, s:a_i_HAH],
+       \ [s:a_KHAH, s:a_f_GHAIN, s:a_i_KHAH],
+       \ [s:a_SEEN, s:a_f_GHAIN, s:a_i_SEEN],
+       \ [s:a_SHEEN, s:a_f_GHAIN, s:a_i_SHEEN],
+       \ [s:a_SAD, s:a_f_GHAIN, s:a_i_SAD],
+       \ [s:a_DAD, s:a_f_GHAIN, s:a_i_DAD],
+       \ [s:a_TAH, s:a_f_GHAIN, s:a_i_TAH],
+       \ [s:a_ZAH, s:a_f_GHAIN, s:a_i_ZAH],
+       \ [s:a_AIN, s:a_f_GHAIN, s:a_i_AIN],
+       \ [s:a_GHAIN, s:a_f_GHAIN, s:a_i_GHAIN],
+       \ [s:a_FEH, s:a_f_GHAIN, s:a_i_FEH],
+       \ [s:a_QAF, s:a_f_GHAIN, s:a_i_QAF],
+       \ [s:a_KAF, s:a_f_GHAIN, s:a_i_KAF],
+       \ [s:a_LAM, s:a_f_GHAIN, s:a_i_LAM],
+       \ [s:a_MEEM, s:a_f_GHAIN, s:a_i_MEEM],
+       \ [s:a_NOON, s:a_f_GHAIN, s:a_i_NOON],
+       \ [s:a_HEH, s:a_f_GHAIN, s:a_i_HEH],
+       \ [s:a_YEH, s:a_f_GHAIN, s:a_i_YEH],
+       \ ]
+    call setline(1, s:a_GHAIN . pair[0] . ' ')
+    call assert_equal([pair[1] . pair[2] . ' '], ScreenLines(1, 3))
+  endfor
+
+  set arabicshape&
+  bwipe!
+endfunc
+
+func Test_shape_isolated()
+  new
+  set arabicshape
+
+  " Shaping non-arabic {testchar} non-arabic   Tests chg_c_a2s().
+  " pair[0] = testchar, pair[1] = current-result
+  for pair in [[s:a_HAMZA, s:a_s_HAMZA],
+       \ [s:a_ALEF_MADDA, s:a_s_ALEF_MADDA],
+       \ [s:a_ALEF_HAMZA_ABOVE, s:a_s_ALEF_HAMZA_ABOVE],
+       \ [s:a_WAW_HAMZA, s:a_s_WAW_HAMZA],
+       \ [s:a_ALEF_HAMZA_BELOW, s:a_s_ALEF_HAMZA_BELOW],
+       \ [s:a_YEH_HAMZA, s:a_s_YEH_HAMZA],
+       \ [s:a_ALEF, s:a_s_ALEF],
+       \ [s:a_TEH_MARBUTA, s:a_s_TEH_MARBUTA],
+       \ [s:a_DAL, s:a_s_DAL],
+       \ [s:a_THAL, s:a_s_THAL],
+       \ [s:a_REH, s:a_s_REH],
+       \ [s:a_ZAIN, s:a_s_ZAIN],
+       \ [s:a_TATWEEL, s:a_TATWEEL],
+       \ [s:a_WAW, s:a_s_WAW],
+       \ [s:a_ALEF_MAKSURA, s:a_s_ALEF_MAKSURA],
+       \ [s:a_BEH, s:a_s_BEH],
+       \ [s:a_TEH, s:a_s_TEH],
+       \ [s:a_THEH, s:a_s_THEH],
+       \ [s:a_JEEM, s:a_s_JEEM],
+       \ [s:a_HAH, s:a_s_HAH],
+       \ [s:a_KHAH, s:a_s_KHAH],
+       \ [s:a_SEEN, s:a_s_SEEN],
+       \ [s:a_SHEEN, s:a_s_SHEEN],
+       \ [s:a_SAD, s:a_s_SAD],
+       \ [s:a_DAD, s:a_s_DAD],
+       \ [s:a_TAH, s:a_s_TAH],
+       \ [s:a_ZAH, s:a_s_ZAH],
+       \ [s:a_AIN, s:a_s_AIN],
+       \ [s:a_GHAIN, s:a_s_GHAIN],
+       \ [s:a_FEH, s:a_s_FEH],
+       \ [s:a_QAF, s:a_s_QAF],
+       \ [s:a_KAF, s:a_s_KAF],
+       \ [s:a_LAM, s:a_s_LAM],
+       \ [s:a_MEEM, s:a_s_MEEM],
+       \ [s:a_NOON, s:a_s_NOON],
+       \ [s:a_HEH, s:a_s_HEH],
+       \ [s:a_YEH, s:a_s_YEH],
+       \ ]
+    call setline(1, ' ' . pair[0] . ' ')
+    call assert_equal([' ' . pair[1] . ' '], ScreenLines(1, 3))
+  endfor
+
+  set arabicshape&
+  bwipe!
+endfunc
+
+func Test_shape_iso_to_medial()
+  new
+  set arabicshape
+
+  " Shaping arabic {testchar} arabic   Tests chg_c_a2m().
+  " pair[0] = testchar, pair[1] = next-result, pair[2] = current-result,
+  " pair[3] = previous-result
+  for pair in [[s:a_HAMZA, s:a_s_GHAIN, s:a_s_HAMZA, s:a_s_BEH],
+       \[s:a_ALEF_MADDA, s:a_s_GHAIN, s:a_f_ALEF_MADDA, s:a_i_BEH],
+       \[s:a_ALEF_HAMZA_ABOVE, s:a_s_GHAIN, s:a_f_ALEF_HAMZA_ABOVE, s:a_i_BEH],
+       \[s:a_WAW_HAMZA, s:a_s_GHAIN, s:a_f_WAW_HAMZA, s:a_i_BEH],
+       \[s:a_ALEF_HAMZA_BELOW, s:a_s_GHAIN, s:a_f_ALEF_HAMZA_BELOW, s:a_i_BEH],
+       \[s:a_YEH_HAMZA, s:a_f_GHAIN, s:a_m_YEH_HAMZA, s:a_i_BEH],
+       \[s:a_ALEF, s:a_s_GHAIN, s:a_f_ALEF, s:a_i_BEH],
+       \[s:a_BEH, s:a_f_GHAIN, s:a_m_BEH, s:a_i_BEH],
+       \[s:a_TEH_MARBUTA, s:a_s_GHAIN, s:a_f_TEH_MARBUTA, s:a_i_BEH],
+       \[s:a_TEH, s:a_f_GHAIN, s:a_m_TEH, s:a_i_BEH],
+       \[s:a_THEH, s:a_f_GHAIN, s:a_m_THEH, s:a_i_BEH],
+       \[s:a_JEEM, s:a_f_GHAIN, s:a_m_JEEM, s:a_i_BEH],
+       \[s:a_HAH, s:a_f_GHAIN, s:a_m_HAH, s:a_i_BEH],
+       \[s:a_KHAH, s:a_f_GHAIN, s:a_m_KHAH, s:a_i_BEH],
+       \[s:a_DAL, s:a_s_GHAIN, s:a_f_DAL, s:a_i_BEH],
+       \[s:a_THAL, s:a_s_GHAIN, s:a_f_THAL, s:a_i_BEH],
+       \[s:a_REH, s:a_s_GHAIN, s:a_f_REH, s:a_i_BEH],
+       \[s:a_ZAIN, s:a_s_GHAIN, s:a_f_ZAIN, s:a_i_BEH],
+       \[s:a_SEEN, s:a_f_GHAIN, s:a_m_SEEN, s:a_i_BEH],
+       \[s:a_SHEEN, s:a_f_GHAIN, s:a_m_SHEEN, s:a_i_BEH],
+       \[s:a_SAD, s:a_f_GHAIN, s:a_m_SAD, s:a_i_BEH],
+       \[s:a_DAD, s:a_f_GHAIN, s:a_m_DAD, s:a_i_BEH],
+       \[s:a_TAH, s:a_f_GHAIN, s:a_m_TAH, s:a_i_BEH],
+       \[s:a_ZAH, s:a_f_GHAIN, s:a_m_ZAH, s:a_i_BEH],
+       \[s:a_AIN, s:a_f_GHAIN, s:a_m_AIN, s:a_i_BEH],
+       \[s:a_GHAIN, s:a_f_GHAIN, s:a_m_GHAIN, s:a_i_BEH],
+       \[s:a_TATWEEL, s:a_f_GHAIN, s:a_TATWEEL, s:a_i_BEH],
+       \[s:a_FEH, s:a_f_GHAIN, s:a_m_FEH, s:a_i_BEH],
+       \[s:a_QAF, s:a_f_GHAIN, s:a_m_QAF, s:a_i_BEH],
+       \[s:a_KAF, s:a_f_GHAIN, s:a_m_KAF, s:a_i_BEH],
+       \[s:a_LAM, s:a_f_GHAIN, s:a_m_LAM, s:a_i_BEH],
+       \[s:a_MEEM, s:a_f_GHAIN, s:a_m_MEEM, s:a_i_BEH],
+       \[s:a_NOON, s:a_f_GHAIN, s:a_m_NOON, s:a_i_BEH],
+       \[s:a_HEH, s:a_f_GHAIN, s:a_m_HEH, s:a_i_BEH],
+       \[s:a_WAW, s:a_s_GHAIN, s:a_f_WAW, s:a_i_BEH],
+       \[s:a_ALEF_MAKSURA, s:a_s_GHAIN, s:a_f_ALEF_MAKSURA, s:a_i_BEH],
+       \[s:a_YEH, s:a_f_GHAIN, s:a_m_YEH, s:a_i_BEH],
+       \ ]
+    call setline(1, s:a_GHAIN . pair[0] . s:a_BEH)
+    call assert_equal([pair[1] . pair[2] . pair[3]], ScreenLines(1, 3))
+  endfor
+
+  set arabicshape&
+  bwipe!
+endfunc
+
+func Test_shape_final()
+  new
+  set arabicshape
+
+  " Shaping arabic {testchar} arabic   Tests chg_c_a2f().
+  " pair[0] = testchar,  pair[1] = current-result, pair[2] = previous-result
+  for pair in [[s:a_HAMZA, s:a_s_HAMZA, s:a_s_BEH],
+       \[s:a_ALEF_MADDA, s:a_f_ALEF_MADDA, s:a_i_BEH],
+       \[s:a_ALEF_HAMZA_ABOVE, s:a_f_ALEF_HAMZA_ABOVE, s:a_i_BEH],
+       \[s:a_WAW_HAMZA, s:a_f_WAW_HAMZA, s:a_i_BEH],
+       \[s:a_ALEF_HAMZA_BELOW, s:a_f_ALEF_HAMZA_BELOW, s:a_i_BEH],
+       \[s:a_YEH_HAMZA, s:a_f_YEH_HAMZA, s:a_i_BEH],
+       \[s:a_ALEF, s:a_f_ALEF, s:a_i_BEH],
+       \[s:a_BEH, s:a_f_BEH, s:a_i_BEH],
+       \[s:a_TEH_MARBUTA, s:a_f_TEH_MARBUTA, s:a_i_BEH],
+       \[s:a_TEH, s:a_f_TEH, s:a_i_BEH],
+       \[s:a_THEH, s:a_f_THEH, s:a_i_BEH],
+       \[s:a_JEEM, s:a_f_JEEM, s:a_i_BEH],
+       \[s:a_HAH, s:a_f_HAH, s:a_i_BEH],
+       \[s:a_KHAH, s:a_f_KHAH, s:a_i_BEH],
+       \[s:a_DAL, s:a_f_DAL, s:a_i_BEH],
+       \[s:a_THAL, s:a_f_THAL, s:a_i_BEH],
+       \[s:a_REH, s:a_f_REH, s:a_i_BEH],
+       \[s:a_ZAIN, s:a_f_ZAIN, s:a_i_BEH],
+       \[s:a_SEEN, s:a_f_SEEN, s:a_i_BEH],
+       \[s:a_SHEEN, s:a_f_SHEEN, s:a_i_BEH],
+       \[s:a_SAD, s:a_f_SAD, s:a_i_BEH],
+       \[s:a_DAD, s:a_f_DAD, s:a_i_BEH],
+       \[s:a_TAH, s:a_f_TAH, s:a_i_BEH],
+       \[s:a_ZAH, s:a_f_ZAH, s:a_i_BEH],
+       \[s:a_AIN, s:a_f_AIN, s:a_i_BEH],
+       \[s:a_GHAIN, s:a_f_GHAIN, s:a_i_BEH],
+       \[s:a_TATWEEL, s:a_TATWEEL, s:a_i_BEH],
+       \[s:a_FEH, s:a_f_FEH, s:a_i_BEH],
+       \[s:a_QAF, s:a_f_QAF, s:a_i_BEH],
+       \[s:a_KAF, s:a_f_KAF, s:a_i_BEH],
+       \[s:a_LAM, s:a_f_LAM, s:a_i_BEH],
+       \[s:a_MEEM, s:a_f_MEEM, s:a_i_BEH],
+       \[s:a_NOON, s:a_f_NOON, s:a_i_BEH],
+       \[s:a_HEH, s:a_f_HEH, s:a_i_BEH],
+       \[s:a_WAW, s:a_f_WAW, s:a_i_BEH],
+       \[s:a_ALEF_MAKSURA, s:a_f_ALEF_MAKSURA, s:a_i_BEH],
+       \[s:a_YEH, s:a_f_YEH, s:a_i_BEH],
+       \ ]
+    call setline(1, ' ' . pair[0] . s:a_BEH)
+    call assert_equal([' ' . pair[1] . pair[2]], ScreenLines(1, 3))
+  endfor
+
+  set arabicshape&
+  bwipe!
+endfunc
+
+func Test_shape_final_to_medial()
+  new
+  set arabicshape
+
+  " Shaping arabic {testchar} arabic   Tests chg_c_f2m().
+  " This does not test much...
+  " pair[0] = testchar,  pair[1] = current-result
+  for pair in [[s:a_f_YEH_HAMZA, s:a_f_BEH],
+       \[s:a_f_WAW_HAMZA, s:a_s_BEH],
+       \[s:a_f_ALEF, s:a_s_BEH],
+       \[s:a_f_TEH_MARBUTA, s:a_s_BEH],
+       \[s:a_f_DAL, s:a_s_BEH],
+       \[s:a_f_THAL, s:a_s_BEH],
+       \[s:a_f_REH, s:a_s_BEH],
+       \[s:a_f_ZAIN, s:a_s_BEH],
+       \[s:a_f_WAW, s:a_s_BEH],
+       \[s:a_f_ALEF_MAKSURA, s:a_s_BEH],
+       \[s:a_f_BEH, s:a_f_BEH],
+       \[s:a_f_TEH, s:a_f_BEH],
+       \[s:a_f_THEH, s:a_f_BEH],
+       \[s:a_f_JEEM, s:a_f_BEH],
+       \[s:a_f_HAH, s:a_f_BEH],
+       \[s:a_f_KHAH, s:a_f_BEH],
+       \[s:a_f_SEEN, s:a_f_BEH],
+       \[s:a_f_SHEEN, s:a_f_BEH],
+       \[s:a_f_SAD, s:a_f_BEH],
+       \[s:a_f_DAD, s:a_f_BEH],
+       \[s:a_f_TAH, s:a_f_BEH],
+       \[s:a_f_ZAH, s:a_f_BEH],
+       \[s:a_f_AIN, s:a_f_BEH],
+       \[s:a_f_GHAIN, s:a_f_BEH],
+       \[s:a_f_FEH, s:a_f_BEH],
+       \[s:a_f_QAF, s:a_f_BEH],
+       \[s:a_f_KAF, s:a_f_BEH],
+       \[s:a_f_LAM, s:a_f_BEH],
+       \[s:a_f_MEEM, s:a_f_BEH],
+       \[s:a_f_NOON, s:a_f_BEH],
+       \[s:a_f_HEH, s:a_f_BEH],
+       \[s:a_f_YEH, s:a_f_BEH],
+       \ ]
+    call setline(1, ' ' . s:a_BEH . pair[0])
+    call assert_equal([' ' . pair[1] . pair[0]], ScreenLines(1, 3))
+  endfor
+
+  set arabicshape&
+  bwipe!
+endfunc
+
+func Test_shape_combination_final()
+  new
+  set arabicshape
+
+  " Shaping arabic {testchar} arabic   Tests chg_c_laa2f().
+  " pair[0] = testchar,  pair[1] = current-result
+  for pair in [[s:a_ALEF_MADDA, s:a_f_LAM_ALEF_MADDA_ABOVE],
+       \ [s:a_ALEF_HAMZA_ABOVE, s:a_f_LAM_ALEF_HAMZA_ABOVE],
+       \ [s:a_ALEF_HAMZA_BELOW, s:a_f_LAM_ALEF_HAMZA_BELOW],
+       \ [s:a_ALEF, s:a_f_LAM_ALEF],
+       \ ]
+    " The test char is a composing char, put on s:a_LAM.
+    call setline(1, ' ' . s:a_LAM . pair[0] . s:a_BEH)
+    call assert_equal([' ' . pair[1] . s:a_i_BEH], ScreenLines(1, 3))
+  endfor
+
+  set arabicshape&
+  bwipe!
+endfunc
+
+func Test_shape_combination_isolated()
+  new
+  set arabicshape
+
+  " Shaping arabic {testchar} arabic   Tests chg_c_laa2i().
+  " pair[0] = testchar,  pair[1] = current-result
+  for pair in [[s:a_ALEF_MADDA, s:a_s_LAM_ALEF_MADDA_ABOVE],
+       \ [s:a_ALEF_HAMZA_ABOVE, s:a_s_LAM_ALEF_HAMZA_ABOVE],
+       \ [s:a_ALEF_HAMZA_BELOW, s:a_s_LAM_ALEF_HAMZA_BELOW],
+       \ [s:a_ALEF, s:a_s_LAM_ALEF],
+       \ ]
+    " The test char is a composing char, put on s:a_LAM.
+    call setline(1, ' ' . s:a_LAM . pair[0] . ' ')
+    call assert_equal([' ' . pair[1] . ' '], ScreenLines(1, 3))
+  endfor
+
+  set arabicshape&
+  bwipe!
+endfunc
index 0caead8..dee2d65 100644 (file)
@@ -6,6 +6,10 @@ func Test_argidx()
   call assert_equal(2, argidx())
   %argdelete
   call assert_equal(0, argidx())
+  " doing it again doesn't result in an error
+  %argdelete
+  call assert_equal(0, argidx())
+  call assert_fails('2argdelete', 'E16:')
 
   args a b c
   call assert_equal(0, argidx())
@@ -86,7 +90,7 @@ endfunc
 
 " Test for [count]argument and [count]argdelete commands
 " Ported from the test_argument_count.in test script
-function Test_argument()
+func Test_argument()
   " Clean the argument list
   arga a | %argd
 
@@ -158,11 +162,11 @@ function Test_argument()
 
   %argdelete
   call assert_fails('argument', 'E163:')
-endfunction
+endfunc
 
 " Test for 0argadd and 0argedit
 " Ported from the test_argument_0count.in test script
-function Test_zero_argadd()
+func Test_zero_argadd()
   " Clean the argument list
   arga a | %argd
 
@@ -184,22 +188,22 @@ function Test_zero_argadd()
   2argu
   arga third
   call assert_equal(['edited', 'a', 'third', 'b', 'c', 'd'], argv())
-endfunction
+endfunc
 
-function Reset_arglist()
+func Reset_arglist()
   args a | %argd
-endfunction
+endfunc
 
 " Test for argc()
-function Test_argc()
+func Test_argc()
   call Reset_arglist()
   call assert_equal(0, argc())
   argadd a b
   call assert_equal(2, argc())
-endfunction
+endfunc
 
 " Test for arglistid()
-function Test_arglistid()
+func Test_arglistid()
   call Reset_arglist()
   arga a b
   call assert_equal(0, arglistid())
@@ -214,19 +218,19 @@ function Test_arglistid()
   tabonly | only | enew!
   argglobal
   call assert_equal(0, arglistid())
-endfunction
+endfunc
 
 " Test for argv()
-function Test_argv()
+func Test_argv()
   call Reset_arglist()
   call assert_equal([], argv())
   call assert_equal("", argv(2))
   argadd a b c d
   call assert_equal('c', argv(2))
-endfunction
+endfunc
 
 " Test for the :argedit command
-function Test_argedit()
+func Test_argedit()
   call Reset_arglist()
   argedit a
   call assert_equal(['a'], argv())
@@ -250,10 +254,10 @@ function Test_argedit()
   argedit! y
   call assert_equal(['x', 'y', 'a', 'c', 'b'], argv())
   %argd
-endfunction
+endfunc
 
 " Test for the :argdelete command
-function Test_argdelete()
+func Test_argdelete()
   call Reset_arglist()
   args aa a aaa b bb
   argdelete a*
@@ -265,10 +269,10 @@ function Test_argdelete()
   call assert_fails('argdelete', 'E471:')
   call assert_fails('1,100argdelete', 'E16:')
   %argd
-endfunction
+endfunc
 
 " Tests for the :next, :prev, :first, :last, :rewind commands
-function Test_argpos()
+func Test_argpos()
   call Reset_arglist()
   args a b c d
   last
@@ -286,10 +290,10 @@ function Test_argpos()
   rewind
   call assert_equal(0, argidx())
   %argd
-endfunction
+endfunc
 
 " Test for autocommand that redefines the argument list, when doing ":all".
-function Test_arglist_autocmd()
+func Test_arglist_autocmd()
   autocmd BufReadPost Xxx2 next Xxx2 Xxx1
   call writefile(['test file Xxx1'], 'Xxx1')
   call writefile(['test file Xxx2'], 'Xxx2')
@@ -315,4 +319,11 @@ function Test_arglist_autocmd()
   call delete('Xxx3')
   argdelete Xxx*
   bwipe! Xxx1 Xxx2 Xxx3
-endfunction
+endfunc
+
+func Test_arg_all_expand()
+  call writefile(['test file Xxx1'], 'Xx x')
+  next notexist Xx\ x runtest.vim
+  call assert_equal('notexist Xx\ x runtest.vim', expand('##'))
+  call delete('Xx x')
+endfunc
index 0ab664a..8359eb1 100644 (file)
@@ -32,7 +32,13 @@ func Test_assert_notequal()
   call assert_notequal([1, 2, 3], s)
 
   call assert_notequal('foo', s)
-  call assert_match("Expected 'foo' differs from 'foo'", v:errors[0])
+  call assert_match("Expected not equal to 'foo'", v:errors[0])
+  call remove(v:errors, 0)
+endfunc
+
+func Test_assert_report()
+  call assert_report('something is wrong')
+  call assert_match('something is wrong', v:errors[0])
   call remove(v:errors, 0)
 endfunc
 
@@ -117,6 +123,22 @@ func Test_assert_inrange()
   call assert_inrange(5, 7, 8)
   call assert_match("Expected range 5 - 7, but got 8", v:errors[0])
   call remove(v:errors, 0)
+
+  call assert_fails('call assert_inrange(1, 1)', 'E119:')
+endfunc
+
+func Test_assert_with_msg()
+  call assert_equal('foo', 'bar', 'testing')
+  call assert_match("testing: Expected 'foo' but got 'bar'", v:errors[0])
+  call remove(v:errors, 0)
+endfunc
+
+func Test_override()
+  call test_override('char_avail', 1)
+  call test_override('redraw', 1)
+  call test_override('ALL', 0)
+  call assert_fails("call test_override('xxx', 1)", 'E475')
+  call assert_fails("call test_override('redraw', 'yes')", 'E474')
 endfunc
 
 func Test_user_is_happy()
index c1f036a..efc9d08 100644 (file)
@@ -7,3 +7,25 @@ func Test_no_type_checking()
   let v = 3.4
   let v = 'hello'
 endfunc
+
+func Test_let_termcap()
+  " Terminal code
+  let old_t_te = &t_te
+  let &t_te = "\<Esc>[yes;"
+  call assert_match('t_te.*^[[yes;', execute("set termcap"))
+  let &t_te = old_t_te
+
+  if exists("+t_k1")
+    " Key code
+    let old_t_k1 = &t_k1
+    let &t_k1 = "that"
+    call assert_match('t_k1.*that', execute("set termcap"))
+    let &t_k1 = old_t_k1
+  endif
+
+  call assert_fails('let x = &t_xx', 'E15')
+  let &t_xx = "yes"
+  call assert_equal("yes", &t_xx)
+  let &t_xx = ""
+  call assert_fails('let x = &t_xx', 'E15')
+endfunc
index 6ebfee4..ef28034 100644 (file)
@@ -1,5 +1,7 @@
 " Tests for autocommands
 
+set belloff=all
+
 function! s:cleanup_buffers() abort
   for bnr in range(1, bufnr('$'))
     if bufloaded(bnr) && bufnr('%') != bnr
@@ -318,7 +320,101 @@ func Test_three_windows()
   call assert_equal('Xanother', expand('%'))
 
   au!
+  enew
+  bwipe! Xtestje1
   call delete('Xtestje1')
   call delete('Xtestje2')
   call delete('Xtestje3')
 endfunc
+
+func Test_BufEnter()
+  au! BufEnter
+  au Bufenter * let val = val . '+'
+  let g:val = ''
+  split NewFile
+  call assert_equal('+', g:val)
+  bwipe!
+  call assert_equal('++', g:val)
+
+  " Also get BufEnter when editing a directory
+  call mkdir('Xdir')
+  split Xdir
+  call assert_equal('+++', g:val)
+
+  " On MS-Windows we can't edit the directory, make sure we wipe the right
+  " buffer.
+  bwipe! Xdir
+
+  call delete('Xdir', 'd')
+  au! BufEnter
+endfunc
+
+" Closing a window might cause an endless loop
+" E814 for older Vims
+function Test_autocmd_bufwipe_in_SessLoadPost()
+  tabnew
+  set noswapfile
+  mksession!
+
+  let content = ['set nocp noswapfile',
+        \ 'let v:swapchoice="e"',
+        \ 'augroup test_autocmd_sessionload',
+        \ 'autocmd!',
+        \ 'autocmd SessionLoadPost * 4bw!',
+        \ 'augroup END',
+       \ '',
+       \ 'func WriteErrors()',
+       \ '  call writefile([execute("messages")], "Xerrors")',
+       \ 'endfunc',
+       \ 'au VimLeave * call WriteErrors()',
+        \ ]
+  call writefile(content, 'Xvimrc')
+  call system(v:progpath. ' -u Xvimrc --not-a-term --noplugins -S Session.vim -c cq')
+  let errors = join(readfile('Xerrors'))
+  call assert_match('E814', errors)
+
+  set swapfile
+  for file in ['Session.vim', 'Xvimrc', 'Xerrors']
+    call delete(file)
+  endfor
+endfunc
+
+" SEGV occurs in older versions.
+function Test_autocmd_bufwipe_in_SessLoadPost2()
+  tabnew
+  set noswapfile
+  mksession!
+
+  let content = ['set nocp noswapfile',
+      \ 'function! DeleteInactiveBufs()',
+      \ '  tabfirst',
+      \ '  let tabblist = []',
+      \ '  for i in range(1, tabpagenr(''$''))',
+      \ '    call extend(tabblist, tabpagebuflist(i))',
+      \ '  endfor',
+      \ '  for b in range(1, bufnr(''$''))',
+      \ '    if bufexists(b) && buflisted(b) && (index(tabblist, b) == -1 || bufname(b) =~# ''^$'')',
+      \ '      exec ''bwipeout '' . b',
+      \ '    endif',
+      \ '  endfor',
+      \ '  echomsg "SessionLoadPost DONE"',
+      \ 'endfunction',
+      \ 'au SessionLoadPost * call DeleteInactiveBufs()',
+      \ '',
+      \ 'func WriteErrors()',
+      \ '  call writefile([execute("messages")], "Xerrors")',
+      \ 'endfunc',
+      \ 'au VimLeave * call WriteErrors()',
+      \ ]
+  call writefile(content, 'Xvimrc')
+  call system(v:progpath. ' -u Xvimrc --not-a-term --noplugins -S Session.vim -c cq')
+  let errors = join(readfile('Xerrors'))
+  " This probably only ever matches on unix.
+  call assert_notmatch('Caught deadly signal SEGV', errors)
+  call assert_match('SessionLoadPost DONE', errors)
+
+  set swapfile
+  for file in ['Session.vim', 'Xvimrc', 'Xerrors']
+    call delete(file)
+  endfor
+endfunc
diff --git a/src/testdir/test_breakindent.in b/src/testdir/test_breakindent.in
deleted file mode 100644 (file)
index d286931..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-Test for breakindent
-
-STARTTEST
-:so small.vim
-:if !exists("+breakindent") | e! test.ok | w! test.out | qa! | endif
-:10new|:vsp|:vert resize 20
-:put =\"\tabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\"
-:set ts=4 sw=4 sts=4 breakindent
-:fu! ScreenChar(line, width)
-:      let c=''
-:      for i in range(1,a:width)
-:              let c.=nr2char(screenchar(a:line, i))
-:      endfor
-:       let c.="\n"
-:      for i in range(1,a:width)
-:              let c.=nr2char(screenchar(a:line+1, i))
-:      endfor
-:       let c.="\n"
-:      for i in range(1,a:width)
-:              let c.=nr2char(screenchar(a:line+2, i))
-:      endfor
-:      return c
-:endfu
-:fu DoRecordScreen()
-:      wincmd l
-:      $put =printf(\"\n%s\", g:test)
-:      $put =g:line1
-:      wincmd p
-:endfu
-:set briopt=min:0
-:let g:test="Test 1: Simple breakindent"
-:let line1=ScreenChar(line('.'),8)
-:call DoRecordScreen()
-:let g:test="Test 2: Simple breakindent + sbr=>>"
-:set sbr=>>
-:let line1=ScreenChar(line('.'),8)
-:call DoRecordScreen()
-:let g:test ="Test 3: Simple breakindent + briopt:sbr"
-:set briopt=sbr,min:0 sbr=++
-:let line1=ScreenChar(line('.'),8)
-:call DoRecordScreen()
-:let g:test ="Test 4: Simple breakindent + min width: 18"
-:set sbr= briopt=min:18
-:let line1=ScreenChar(line('.'),8)
-:call DoRecordScreen()
-:let g:test =" Test 5: Simple breakindent + shift by 2"
-:set briopt=shift:2,min:0
-:let line1=ScreenChar(line('.'),8)
-:call DoRecordScreen()
-:let g:test=" Test 6: Simple breakindent + shift by -1"
-:set briopt=shift:-1,min:0
-:let line1=ScreenChar(line('.'),8)
-:call DoRecordScreen()
-:let g:test=" Test 7: breakindent + shift by +1 + nu + sbr=? briopt:sbr"
-:set briopt=shift:1,sbr,min:0 nu sbr=? nuw=4
-:let line1=ScreenChar(line('.'),10)
-:call DoRecordScreen()
-:let g:test=" Test 8: breakindent + shift:1 + nu + sbr=# list briopt:sbr"
-:set briopt=shift:1,sbr,min:0 nu sbr=# list
-:let line1=ScreenChar(line('.'),10)
-:call DoRecordScreen()
-:let g:test=" Test 9: breakindent + shift by +1 + 'nu' + sbr=# list"
-:set briopt-=sbr
-:let line1=ScreenChar(line('.'),10)
-:call DoRecordScreen()
-:let g:test=" Test 10: breakindent + shift by +1 + 'nu' + sbr=~ cpo+=n"
-:set cpo+=n sbr=~ nu nuw=4 nolist briopt=sbr,min:0
-:let line1=ScreenChar(line('.'),10)
-:call DoRecordScreen()
-:wincmd p
-:let g:test="\n Test 11: strdisplaywidth when breakindent is on"
-:set cpo-=n sbr=>> nu nuw=4 nolist briopt= ts=4
-:let text=getline(2) "skip leading tab when calculating text width
-:let width = strlen(text[1:])+indent(2)*4+strlen(&sbr)*3 " text wraps 3 times
-:$put =g:test
-:$put =printf(\"strdisplaywidth: %d == calculated: %d\", strdisplaywidth(text), width)
-:let g:str="\t\t\t\t\t{"
-:let g:test=" Test 12: breakindent + long indent"
-:wincmd p
-:set all& breakindent linebreak briopt=min:10 nu numberwidth=3 ts=4
-:$put =g:str
-zt:let line1=ScreenChar(1,10)
-:wincmd p
-:call DoRecordScreen()
-:"
-:" Test, that the string "    a\tb\tc\td\te" is correctly
-:" displayed in a 20 column wide window (see bug report
-:" https://groups.google.com/d/msg/vim_dev/ZOdg2mc9c9Y/TT8EhFjEy0IJ
-:only
-:vert 20new
-:set all& nocp breakindent briopt=min:10
-:call setline(1, ["    a\tb\tc\td\te", "    z   y       x       w       v"])
-:/^\s*a
-fbgjyl:let line1 = @0
-:?^\s*z
-fygjyl:let line2 = @0
-:quit!
-:$put ='Test 13: breakindent with wrapping Tab'
-:$put =line1
-:$put =line2
-:"
-:let g:test="Test 14: breakindent + visual blockwise delete #1"
-:set all& breakindent viminfo+=nviminfo
-:30vnew
-:normal! 3a1234567890
-:normal! a    abcde
-:exec "normal! 0\<C-V>tex"
-:let line1=ScreenChar(line('.'),8)
-:call DoRecordScreen()
-:"
-:let g:test="Test 15: breakindent + visual blockwise delete #2"
-:%d
-:normal! 4a1234567890
-:exec "normal! >>\<C-V>3f0x"
-:let line1=ScreenChar(line('.'),20)
-:call DoRecordScreen()
-:quit!
-:"
-:%w! test.out
-:qa!
-ENDTEST
-dummy text
diff --git a/src/testdir/test_breakindent.ok b/src/testdir/test_breakindent.ok
deleted file mode 100644 (file)
index 3eb9c24..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-
-       abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP
-
-Test 1: Simple breakindent
-    abcd
-    qrst
-    GHIJ
-
-Test 2: Simple breakindent + sbr=>>
-    abcd
-    >>qr
-    >>EF
-
-Test 3: Simple breakindent + briopt:sbr
-    abcd
-++  qrst
-++  GHIJ
-
-Test 4: Simple breakindent + min width: 18
-    abcd
-  qrstuv
-  IJKLMN
-
- Test 5: Simple breakindent + shift by 2
-    abcd
-      qr
-      EF
-
- Test 6: Simple breakindent + shift by -1
-    abcd
-   qrstu
-   HIJKL
-
- Test 7: breakindent + shift by +1 + nu + sbr=? briopt:sbr
-  2     ab
-?        m
-?        x
-
- Test 8: breakindent + shift:1 + nu + sbr=# list briopt:sbr
-  2 ^Iabcd
-#      opq
-#      BCD
-
- Test 9: breakindent + shift by +1 + 'nu' + sbr=# list
-  2 ^Iabcd
-       #op
-       #AB
-
- Test 10: breakindent + shift by +1 + 'nu' + sbr=~ cpo+=n
-  2     ab
-~       mn
-~       yz
-
- Test 11: strdisplaywidth when breakindent is on
-strdisplaywidth: 46 == calculated: 64
-                                       {
-
- Test 12: breakindent + long indent
-56        
-          
-~         
-Test 13: breakindent with wrapping Tab
-d
-w
-
-Test 14: breakindent + visual blockwise delete #1
-e       
-~       
-~       
-
-Test 15: breakindent + visual blockwise delete #2
-        1234567890  
-~                   
-~                   
diff --git a/src/testdir/test_breakindent.vim b/src/testdir/test_breakindent.vim
new file mode 100644 (file)
index 0000000..7deffbe
--- /dev/null
@@ -0,0 +1,298 @@
+" Test for breakindent
+"
+" Note: if you get strange failures when adding new tests, it might be that
+" while the test is run, the breakindent cacheing gets in its way.
+" It helps to change the tabstop setting and force a redraw (e.g. see
+" Test_breakindent08())
+if !exists('+breakindent')
+  finish
+endif
+
+source view_util.vim
+
+let s:input ="\tabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP"
+
+function s:screen_lines(lnum, width) abort
+  return ScreenLines([a:lnum, a:lnum + 2], a:width)
+endfunction
+
+function! s:compare_lines(expect, actual)
+  call assert_equal(join(a:expect, "\n"), join(a:actual, "\n"))
+endfunction
+
+function s:test_windows(...)
+  call NewWindow(10, 20)
+  setl ts=4 sw=4 sts=4 breakindent
+  put =s:input
+  exe get(a:000, 0, '')
+endfunction
+
+function s:close_windows(...)
+  call CloseWindow()
+  exe get(a:000, 0, '')
+endfunction
+
+function Test_breakindent01()
+  " simple breakindent test
+  call s:test_windows('setl briopt=min:0')
+  let lines=s:screen_lines(line('.'),8)
+  let expect=[
+\ "    abcd",
+\ "    qrst",
+\ "    GHIJ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunction
+
+function Test_breakindent02()
+  " simple breakindent test with showbreak set
+  call s:test_windows('setl briopt=min:0 sbr=>>')
+  let lines=s:screen_lines(line('.'),8)
+  let expect=[
+\ "    abcd",
+\ "    >>qr",
+\ "    >>EF",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent03()
+  " simple breakindent test with showbreak set and briopt including sbr
+  call s:test_windows('setl briopt=sbr,min:0 sbr=++')
+  let lines=s:screen_lines(line('.'),8)
+  let expect=[
+\ "    abcd",
+\ "++  qrst",
+\ "++  GHIJ",
+\ ]
+  call s:compare_lines(expect, lines)
+  " clean up
+  call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent04()
+  " breakindent set with min width 18
+  call s:test_windows('setl sbr= briopt=min:18')
+  let lines=s:screen_lines(line('.'),8)
+  let expect=[
+\ "    abcd",
+\ "  qrstuv",
+\ "  IJKLMN",
+\ ]
+  call s:compare_lines(expect, lines)
+  " clean up
+  call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent05()
+  " breakindent set and shift by 2
+  call s:test_windows('setl briopt=shift:2,min:0')
+  let lines=s:screen_lines(line('.'),8)
+  let expect=[
+\ "    abcd",
+\ "      qr",
+\ "      EF",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunction
+
+function Test_breakindent06()
+  " breakindent set and shift by -1
+  call s:test_windows('setl briopt=shift:-1,min:0')
+  let lines=s:screen_lines(line('.'),8)
+  let expect=[
+\ "    abcd",
+\ "   qrstu",
+\ "   HIJKL",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunction
+
+function Test_breakindent07()
+  " breakindent set and shift by 1, Number  set sbr=? and briopt:sbr
+  call s:test_windows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4 cpo+=n')
+  let lines=s:screen_lines(line('.'),10)
+  let expect=[
+\ "  2     ab",
+\ "?        m",
+\ "?        x",
+\ ]
+  call s:compare_lines(expect, lines)
+  " clean up
+  call s:close_windows('set sbr= cpo-=n')
+endfunction
+
+function Test_breakindent07a()
+  " breakindent set and shift by 1, Number  set sbr=? and briopt:sbr
+  call s:test_windows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4')
+  let lines=s:screen_lines(line('.'),10)
+  let expect=[
+\ "  2     ab",
+\ "    ?    m",
+\ "    ?    x",
+\ ]
+  call s:compare_lines(expect, lines)
+  " clean up
+  call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent08()
+  " breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr
+  call s:test_windows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list cpo+=n ts=4')
+  " make sure, cache is invalidated!
+  set ts=8
+  redraw!
+  set ts=4
+  redraw!
+  let lines=s:screen_lines(line('.'),10)
+  let expect=[
+\ "  2 ^Iabcd",
+\ "#      opq",
+\ "#      BCD",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows('set sbr= cpo-=n')
+endfunction
+
+function Test_breakindent08a()
+  " breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr
+  call s:test_windows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list')
+  let lines=s:screen_lines(line('.'),10)
+  let expect=[
+\ "  2 ^Iabcd",
+\ "    #  opq",
+\ "    #  BCD",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent09()
+  " breakindent set and shift by 1, Number and list set sbr=#
+  call s:test_windows('setl briopt=shift:1,min:0 nu nuw=4 sbr=# list')
+  let lines=s:screen_lines(line('.'),10)
+  let expect=[
+\ "  2 ^Iabcd",
+\ "       #op",
+\ "       #AB",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent10()
+  " breakindent set, Number set sbr=~
+  call s:test_windows('setl cpo+=n sbr=~ nu nuw=4 nolist briopt=sbr,min:0')
+  " make sure, cache is invalidated!
+  set ts=8
+  redraw!
+  set ts=4
+  redraw!
+  let lines=s:screen_lines(line('.'),10)
+  let expect=[
+\ "  2     ab",
+\ "~       mn",
+\ "~       yz",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows('set sbr= cpo-=n')
+endfunction
+
+function 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
+  call assert_equal(width, strdisplaywidth(text))
+  call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent12()
+  " test breakindent with long indent
+  let s:input="\t\t\t\t\t{"
+  call s:test_windows('setl breakindent linebreak briopt=min:10 nu numberwidth=3 ts=4 list listchars=tab:>-')
+  let lines=s:screen_lines(2,16)
+  let expect=[
+\ " 2 >--->--->--->",
+\ "          ---{  ",
+\ "~               ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows('set nuw=4 listchars=')
+endfunction
+
+function Test_breakindent13()
+  let s:input=""
+  call s:test_windows('setl breakindent briopt=min:10 ts=8')
+  vert resize 20
+  call setline(1, ["    a\tb\tc\td\te", "    z   y       x       w       v"])
+  1
+  norm! fbgj"ayl
+  2
+  norm! fygj"byl
+  call assert_equal('d', @a)
+  call assert_equal('w', @b)
+  call s:close_windows()
+endfunction
+
+function Test_breakindent14()
+  let s:input=""
+  call s:test_windows('setl breakindent briopt= ts=8')
+  vert resize 30
+  norm! 3a1234567890
+  norm! a    abcde
+  exec "norm! 0\<C-V>tex"
+  let lines=s:screen_lines(line('.'),8)
+  let expect=[
+\ "e       ",
+\ "~       ",
+\ "~       ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunction
+
+function Test_breakindent15()
+  let s:input=""
+  call s:test_windows('setl breakindent briopt= ts=8 sw=8')
+  vert resize 30
+  norm! 4a1234567890
+  exe "normal! >>\<C-V>3f0x"
+  let lines=s:screen_lines(line('.'),20)
+  let expect=[
+\ "        1234567890  ",
+\ "~                   ",
+\ "~                   ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunction
+
+function Test_breakindent16()
+  " Check that overlong lines are indented correctly.
+  let s:input=""
+  call s:test_windows('setl breakindent briopt=min:0 ts=4')
+  call setline(1, "\t".repeat("1234567890", 10))
+  resize 6
+  norm! 1gg$
+  redraw!
+  let lines=s:screen_lines(1,10)
+  let expect=[
+\ "    789012",
+\ "    345678",
+\ "    901234",
+\ ]
+  call s:compare_lines(expect, lines)
+  let lines=s:screen_lines(4,10)
+  let expect=[
+\ "    567890",
+\ "    123456",
+\ "    7890  ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunction
diff --git a/src/testdir/test_cd.vim b/src/testdir/test_cd.vim
new file mode 100644 (file)
index 0000000..e573419
--- /dev/null
@@ -0,0 +1,13 @@
+" Test for :cd
+
+func Test_cd_large_path()
+  " This used to crash with a heap write overflow.
+  call assert_fails('cd ' . repeat('x', 5000), 'E472:')
+endfunc
+
+func Test_cd_up_and_down()
+  let path = getcwd()
+  cd ..
+  exe 'cd ' . path
+  call assert_equal(path, getcwd())
+endfunc
diff --git a/src/testdir/test_changedtick.vim b/src/testdir/test_changedtick.vim
new file mode 100644 (file)
index 0000000..3a91bb5
--- /dev/null
@@ -0,0 +1,57 @@
+" Tests for b:changedtick
+
+func Test_changedtick_increments()
+  new
+  " New buffer has an empty line, tick starts at 2.
+  let expected = 2
+  call assert_equal(expected, b:changedtick)
+  call assert_equal(expected, b:['changedtick'])
+  call setline(1, 'hello')
+  let expected += 1
+  call assert_equal(expected, b:changedtick)
+  call assert_equal(expected, b:['changedtick'])
+  undo
+  " Somehow undo counts as two changes.
+  let expected += 2
+  call assert_equal(expected, b:changedtick)
+  call assert_equal(expected, b:['changedtick'])
+  bwipe!
+endfunc
+
+func Test_changedtick_dict_entry()
+  let d = b:
+  call assert_equal(b:changedtick, d['changedtick'])
+endfunc
+
+func Test_changedtick_bdel()
+  new
+  let bnr = bufnr('%')
+  let v = b:changedtick
+  bdel
+  " Delete counts as a change too.
+  call assert_equal(v + 1, getbufvar(bnr, 'changedtick'))
+endfunc
+
+func Test_changedtick_islocked()
+  call assert_equal(0, islocked('b:changedtick'))
+  let d = b:
+  call assert_equal(0, islocked('d.changedtick'))
+endfunc
+
+func Test_changedtick_fixed()
+  call assert_fails('let b:changedtick = 4', 'E46:')
+  call assert_fails('let b:["changedtick"] = 4', 'E46:')
+
+  call assert_fails('lockvar b:changedtick', 'E940:')
+  call assert_fails('lockvar b:["changedtick"]', 'E46:')
+  call assert_fails('unlockvar b:changedtick', 'E940:')
+  call assert_fails('unlockvar b:["changedtick"]', 'E46:')
+  call assert_fails('unlet b:changedtick', 'E795:')
+  call assert_fails('unlet b:["changedtick"]', 'E46:')
+
+  let d = b:
+  call assert_fails('lockvar d["changedtick"]', 'E46:')
+  call assert_fails('unlockvar d["changedtick"]', 'E46:')
+  call assert_fails('unlet d["changedtick"]', 'E46:')
+
+endfunc
index 07a2241..bafa9db 100644 (file)
@@ -62,6 +62,39 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
                     if decoded[1] == 'hello!':
                         # simply send back a string
                         response = "got it"
+                    elif decoded[1] == 'malformed1':
+                        cmd = '["ex",":"]wrong!["ex","smi"]'
+                        print("sending: {0}".format(cmd))
+                        self.request.sendall(cmd.encode('utf-8'))
+                        response = "ok"
+                        # Need to wait for Vim to give up, otherwise it
+                        # sometimes fails on OS X.
+                        time.sleep(0.2)
+                    elif decoded[1] == 'malformed2':
+                        cmd = '"unterminated string'
+                        print("sending: {0}".format(cmd))
+                        self.request.sendall(cmd.encode('utf-8'))
+                        response = "ok"
+                        # Need to wait for Vim to give up, otherwise the double
+                        # quote in the "ok" response terminates the string.
+                        time.sleep(0.2)
+                    elif decoded[1] == 'malformed3':
+                        cmd = '["ex","missing ]"'
+                        print("sending: {0}".format(cmd))
+                        self.request.sendall(cmd.encode('utf-8'))
+                        response = "ok"
+                        # Need to wait for Vim to give up, otherwise the ]
+                        # in the "ok" response terminates the list.
+                        time.sleep(0.2)
+                    elif decoded[1] == 'split':
+                        cmd = '["ex","let '
+                        print("sending: {0}".format(cmd))
+                        self.request.sendall(cmd.encode('utf-8'))
+                        time.sleep(0.01)
+                        cmd = 'g:split = 123"]'
+                        print("sending: {0}".format(cmd))
+                        self.request.sendall(cmd.encode('utf-8'))
+                        response = "ok"
                     elif decoded[1].startswith("echo "):
                         # send back the argument
                         response = decoded[1][5:]
@@ -121,36 +154,6 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
                         print("sending: {0}".format(cmd))
                         self.request.sendall(cmd.encode('utf-8'))
                         response = "ok"
-                    elif decoded[1] == 'malformed1':
-                        cmd = '["ex",":"]wrong!["ex","smi"]'
-                        print("sending: {0}".format(cmd))
-                        self.request.sendall(cmd.encode('utf-8'))
-                        response = "ok"
-                    elif decoded[1] == 'malformed2':
-                        cmd = '"unterminated string'
-                        print("sending: {0}".format(cmd))
-                        self.request.sendall(cmd.encode('utf-8'))
-                        response = "ok"
-                        # Need to wait for Vim to give up, otherwise the double
-                        # quote in the "ok" response terminates the string.
-                        time.sleep(0.2)
-                    elif decoded[1] == 'malformed3':
-                        cmd = '["ex","missing ]"'
-                        print("sending: {0}".format(cmd))
-                        self.request.sendall(cmd.encode('utf-8'))
-                        response = "ok"
-                        # Need to wait for Vim to give up, otherwise the ]
-                        # in the "ok" response terminates the list.
-                        time.sleep(0.2)
-                    elif decoded[1] == 'split':
-                        cmd = '["ex","let '
-                        print("sending: {0}".format(cmd))
-                        self.request.sendall(cmd.encode('utf-8'))
-                        time.sleep(0.01)
-                        cmd = 'g:split = 123"]'
-                        print("sending: {0}".format(cmd))
-                        self.request.sendall(cmd.encode('utf-8'))
-                        response = "ok"
                     elif decoded[1] == 'an expr':
                         # Send an expr request.
                         cmd = '["expr","setline(\\"$\\", [\\"one\\",\\"two\\",\\"three\\"])"]'
index c21e617..3694fc2 100644 (file)
@@ -8,10 +8,14 @@ source shared.vim
 
 let s:python = PythonProg()
 if s:python == ''
-  " Can't run this test.
+  " Can't run this test without Python.
   finish
 endif
 
+" Uncomment the next line to see what happens. Output is in
+" src/testdir/channellog.
+" call ch_logfile('channellog', 'w')
+
 let s:chopt = {}
 
 " Run "testfunc" after sarting the server and stop the server afterwards.
@@ -26,9 +30,12 @@ func Ch_requestHandler(handle, msg)
 endfunc
 
 func Ch_communicate(port)
+  " Avoid dropping messages, since we don't use a callback here.
+  let s:chopt.drop = 'never'
   let handle = ch_open('localhost:' . a:port, s:chopt)
+  unlet s:chopt.drop
   if ch_status(handle) == "fail"
-    call assert_false(1, "Can't open channel")
+    call assert_report("Can't open channel")
     return
   endif
   if has('job')
@@ -58,6 +65,9 @@ func Ch_communicate(port)
   " string with ][ should work
   call assert_equal('this][that', ch_evalexpr(handle, 'echo this][that'))
 
+  " nothing to read now
+  call assert_equal(0, ch_canread(handle))
+
   " sending three messages quickly then reading should work
   for i in range(3)
     call ch_sendexpr(handle, 'echo hello ' . i)
@@ -87,7 +97,7 @@ func Ch_communicate(port)
   call ch_sendexpr(handle, 'hello!', {'callback': 'Ch_requestHandler'})
   call WaitFor('exists("g:Ch_responseHandle")')
   if !exists('g:Ch_responseHandle')
-    call assert_false(1, 'g:Ch_responseHandle was not set')
+    call assert_report('g:Ch_responseHandle was not set')
   else
     call assert_equal(handle, g:Ch_responseHandle)
     unlet g:Ch_responseHandle
@@ -98,7 +108,7 @@ func Ch_communicate(port)
   call ch_sendexpr(handle, 'hello!', {'callback': function('Ch_requestHandler')})
   call WaitFor('exists("g:Ch_responseHandle")')
   if !exists('g:Ch_responseHandle')
-    call assert_false(1, 'g:Ch_responseHandle was not set')
+    call assert_report('g:Ch_responseHandle was not set')
   else
     call assert_equal(handle, g:Ch_responseHandle)
     unlet g:Ch_responseHandle
@@ -110,7 +120,7 @@ func Ch_communicate(port)
   call ch_sendexpr(handle, 'hello!', {'callback': {a, b -> Ch_requestHandler(a, b)}})
   call WaitFor('exists("g:Ch_responseHandle")')
   if !exists('g:Ch_responseHandle')
-    call assert_false(1, 'g:Ch_responseHandle was not set')
+    call assert_report('g:Ch_responseHandle was not set')
   else
     call assert_equal(handle, g:Ch_responseHandle)
     unlet g:Ch_responseHandle
@@ -126,6 +136,9 @@ func Ch_communicate(port)
   call ch_setoptions(handle, {'mode': 'json'})
   call assert_fails("call ch_setoptions(handle, {'waittime': 111})", "E475")
   call ch_setoptions(handle, {'callback': ''})
+  call ch_setoptions(handle, {'drop': 'never'})
+  call ch_setoptions(handle, {'drop': 'auto'})
+  call assert_fails("call ch_setoptions(handle, {'drop': 'bad'})", "E475")
 
   " Send an eval request that works.
   call assert_equal('ok', ch_evalexpr(handle, 'eval-works'))
@@ -200,7 +213,7 @@ func Ch_two_channels(port)
   let handle = ch_open('localhost:' . a:port, s:chopt)
   call assert_equal(v:t_channel, type(handle))
   if ch_status(handle) == "fail"
-    call assert_false(1, "Can't open channel")
+    call assert_report("Can't open channel")
     return
   endif
 
@@ -208,7 +221,7 @@ func Ch_two_channels(port)
 
   let newhandle = ch_open('localhost:' . a:port, s:chopt)
   if ch_status(newhandle) == "fail"
-    call assert_false(1, "Can't open second channel")
+    call assert_report("Can't open second channel")
     return
   endif
   call assert_equal('got it', ch_evalexpr(newhandle, 'hello!'))
@@ -229,7 +242,7 @@ endfunc
 func Ch_server_crash(port)
   let handle = ch_open('localhost:' . a:port, s:chopt)
   if ch_status(handle) == "fail"
-    call assert_false(1, "Can't open channel")
+    call assert_report("Can't open channel")
     return
   endif
 
@@ -246,6 +259,7 @@ endfunc
 """""""""
 
 func Ch_handler(chan, msg)
+  call ch_log('Ch_handler()')
   unlet g:Ch_reply
   let g:Ch_reply = a:msg
 endfunc
@@ -253,7 +267,7 @@ endfunc
 func Ch_channel_handler(port)
   let handle = ch_open('localhost:' . a:port, s:chopt)
   if ch_status(handle) == "fail"
-    call assert_false(1, "Can't open channel")
+    call assert_report("Can't open channel")
     return
   endif
 
@@ -296,7 +310,7 @@ endfunc
 func Ch_channel_zero(port)
   let handle = ch_open('localhost:' . a:port, s:chopt)
   if ch_status(handle) == "fail"
-    call assert_false(1, "Can't open channel")
+    call assert_report("Can't open channel")
     return
   endif
 
@@ -363,12 +377,12 @@ endfunc
 func Ch_raw_one_time_callback(port)
   let handle = ch_open('localhost:' . a:port, s:chopt)
   if ch_status(handle) == "fail"
-    call assert_false(1, "Can't open channel")
+    call assert_report("Can't open channel")
     return
   endif
   call ch_setoptions(handle, {'mode': 'raw'})
 
-  " The message are sent raw, we do our own JSON strings here.
+  " The messages are sent raw, we do our own JSON strings here.
   call ch_sendraw(handle, "[1, \"hello!\"]\n", {'callback': 'Ch_handleRaw1'})
   call WaitFor('g:Ch_reply1 != ""')
   call assert_equal("[1, \"got it\"]", g:Ch_reply1)
@@ -419,7 +433,7 @@ func Test_connect_waittime()
     endif
   catch
     if v:exception !~ 'Connection reset by peer'
-      call assert_false(1, "Caught exception: " . v:exception)
+      call assert_report("Caught exception: " . v:exception)
     endif
   endtry
 endfunc
@@ -431,7 +445,10 @@ func Test_raw_pipe()
     return
   endif
   call ch_log('Test_raw_pipe()')
-  let job = job_start(s:python . " test_channel_pipe.py", {'mode': 'raw'})
+  " Add a dummy close callback to avoid that messages are dropped when calling
+  " ch_canread().
+  let job = job_start(s:python . " test_channel_pipe.py",
+       \ {'mode': 'raw', 'drop': 'never'})
   call assert_equal(v:t_job, type(job))
   call assert_equal("run", job_status(job))
 
@@ -458,6 +475,9 @@ func Test_raw_pipe()
     call assert_equal("something\n", substitute(msg, "\r", "", 'g'))
 
     call ch_sendraw(job, "double this\n")
+    let g:handle = job_getchannel(job)
+    call WaitFor('ch_canread(g:handle)')
+    unlet g:handle
     let msg = ch_readraw(job)
     call assert_equal("this\nAND this\n", substitute(msg, "\r", "", 'g'))
 
@@ -1125,7 +1145,11 @@ func Test_out_cb()
 
   let dict = {'thisis': 'dict: '}
   func dict.outHandler(chan, msg) dict
-    let g:Ch_outmsg = self.thisis . a:msg
+    if type(a:msg) == v:t_string
+      let g:Ch_outmsg = self.thisis . a:msg
+    else
+      let g:Ch_outobj = a:msg
+    endif
   endfunc
   func dict.errHandler(chan, msg) dict
     let g:Ch_errmsg = self.thisis . a:msg
@@ -1145,6 +1169,12 @@ func Test_out_cb()
     call assert_equal("dict: hello", g:Ch_outmsg)
     call WaitFor('g:Ch_errmsg != ""')
     call assert_equal("dict: there", g:Ch_errmsg)
+
+    " Receive a json object split in pieces
+    unlet! g:Ch_outobj
+    call ch_sendraw(job, "echosplit [0, {\"one\": 1,| \"tw|o\": 2, \"three\": 3|}]\n")
+    call WaitFor('exists("g:Ch_outobj")')
+    call assert_equal({'one': 1, 'two': 2, 'three': 3}, g:Ch_outobj)
   finally
     call job_stop(job)
   endtry
@@ -1232,6 +1262,32 @@ func Test_out_cb_lambda()
   endtry
 endfunc
 
+func Test_close_and_exit_cb()
+  if !has('job')
+    return
+  endif
+  call ch_log('Test_close_and_exit_cb')
+
+  let dict = {'ret': {}}
+  func dict.close_cb(ch) dict
+    let self.ret['close_cb'] = job_status(ch_getjob(a:ch))
+  endfunc
+  func dict.exit_cb(job, status) dict
+    let self.ret['exit_cb'] = job_status(a:job)
+  endfunc
+
+  let g:job = job_start('echo', {
+        \ 'close_cb': dict.close_cb,
+        \ 'exit_cb': dict.exit_cb,
+        \ })
+  call assert_equal('run', job_status(g:job))
+  unlet g:job
+  call WaitFor('len(dict.ret) >= 2')
+  call assert_equal(2, len(dict.ret))
+  call assert_match('^\%(dead\|run\)', dict.ret['close_cb'])
+  call assert_equal('dead', dict.ret['exit_cb'])
+endfunc
+
 """"""""""
 
 let g:Ch_unletResponse = ''
@@ -1291,7 +1347,7 @@ func Ch_open_delay(port)
   let channel = ch_open('localhost:' . a:port, s:chopt)
   unlet s:chopt.waittime
   if ch_status(channel) == "fail"
-    call assert_false(1, "Can't open channel")
+    call assert_report("Can't open channel")
     return
   endif
   call assert_equal('got it', ch_evalexpr(channel, 'hello!'))
@@ -1313,7 +1369,7 @@ endfunc
 function Ch_test_call(port)
   let handle = ch_open('localhost:' . a:port, s:chopt)
   if ch_status(handle) == "fail"
-    call assert_false(1, "Can't open channel")
+    call assert_report("Can't open channel")
     return
   endif
 
@@ -1411,7 +1467,7 @@ endfunc
 function Ch_test_close_callback(port)
   let handle = ch_open('localhost:' . a:port, s:chopt)
   if ch_status(handle) == "fail"
-    call assert_false(1, "Can't open channel")
+    call assert_report("Can't open channel")
     return
   endif
   call ch_setoptions(handle, {'close_cb': 'MyCloseCb'})
@@ -1429,7 +1485,7 @@ endfunc
 function Ch_test_close_partial(port)
   let handle = ch_open('localhost:' . a:port, s:chopt)
   if ch_status(handle) == "fail"
-    call assert_false(1, "Can't open channel")
+    call assert_report("Can't open channel")
     return
   endif
   let g:Ch_d = {}
@@ -1579,7 +1635,7 @@ endfunc
 function Ch_test_close_lambda(port)
   let handle = ch_open('localhost:' . a:port, s:chopt)
   if ch_status(handle) == "fail"
-    call assert_false(1, "Can't open channel")
+    call assert_report("Can't open channel")
     return
   endif
   let g:Ch_close_ret = ''
@@ -1594,6 +1650,3 @@ func Test_close_lambda()
   call ch_log('Test_close_lambda()')
   call s:run_server('Ch_test_close_lambda')
 endfunc
-
-" Uncomment this to see what happens, output is in src/testdir/channellog.
-" call ch_logfile('channellog', 'w')
index 639cc6c..a67a81a 100644 (file)
@@ -29,6 +29,11 @@ if __name__ == "__main__":
         if typed.startswith("echo "):
             print(typed[5:-1])
             sys.stdout.flush()
+        if typed.startswith("echosplit "):
+            for part in typed[10:-1].split('|'):
+                sys.stdout.write(part)
+                sys.stdout.flush()
+                time.sleep(0.05)
         if typed.startswith("double "):
             print(typed[7:-1] + "\nAND " + typed[7:-1])
             sys.stdout.flush()
diff --git a/src/testdir/test_charsearch_utf8.vim b/src/testdir/test_charsearch_utf8.vim
new file mode 100644 (file)
index 0000000..ade7dd4
--- /dev/null
@@ -0,0 +1,22 @@
+" Tests for related f{char} and t{char} using utf-8.
+if !has('multi_byte')
+  finish
+endif
+
+" Test for t,f,F,T movement commands
+function! Test_search_cmds()
+  new!
+  call setline(1, "・最初から最後まで最強のVimは最高")
+  1
+  normal! f最
+  call assert_equal([0, 1, 4, 0], getpos('.'))
+  normal! ;
+  call assert_equal([0, 1, 16, 0], getpos('.'))
+  normal! 2;
+  call assert_equal([0, 1, 43, 0], getpos('.'))
+  normal! ,
+  call assert_equal([0, 1, 28, 0], getpos('.'))
+  bw!
+endfunction
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_cindent.vim b/src/testdir/test_cindent.vim
new file mode 100644 (file)
index 0000000..444c4c4
--- /dev/null
@@ -0,0 +1,76 @@
+" Test for cinoptions and cindent
+"
+" TODO: rewrite test3.in into this new style test
+
+func Test_cino_hash()
+  " Test that curbuf->b_ind_hash_comment is correctly reset
+  new
+  setlocal cindent cinoptions=#1
+  setlocal cinoptions=
+  call setline(1, ["#include <iostream>"])
+  call cursor(1, 1)
+  norm! o#include
+  "call feedkeys("o#include\<esc>", 't')
+  call assert_equal(["#include <iostream>", "#include"], getline(1,2))
+  bwipe!
+endfunc
+
+func Test_cino_extern_c()
+  " Test for cino-E
+
+  let without_ind = [
+        \ '#ifdef __cplusplus',
+        \ 'extern "C" {',
+        \ '#endif',
+        \ 'int func_a(void);',
+        \ '#ifdef __cplusplus',
+        \ '}',
+        \ '#endif'
+        \ ]
+
+  let with_ind = [
+        \ '#ifdef __cplusplus',
+        \ 'extern "C" {',
+        \ '#endif',
+        \ "\tint func_a(void);",
+        \ '#ifdef __cplusplus',
+        \ '}',
+        \ '#endif'
+        \ ]
+  new
+  setlocal cindent cinoptions=E0
+  call setline(1, without_ind)
+  call feedkeys("gg=G", 'tx')
+  call assert_equal(with_ind, getline(1, '$'))
+
+  setlocal cinoptions=E-s
+  call setline(1, with_ind)
+  call feedkeys("gg=G", 'tx')
+  call assert_equal(without_ind, getline(1, '$'))
+
+  setlocal cinoptions=Es
+  let tests = [
+        \ ['recognized', ['extern "C" {'], "\t\t;"],
+        \ ['recognized', ['extern "C++" {'], "\t\t;"],
+        \ ['recognized', ['extern /* com */ "C"{'], "\t\t;"],
+        \ ['recognized', ['extern"C"{'], "\t\t;"],
+        \ ['recognized', ['extern "C"', '{'], "\t\t;"],
+        \ ['not recognized', ['extern {'], "\t;"],
+        \ ['not recognized', ['extern /*"C"*/{'], "\t;"],
+        \ ['not recognized', ['extern "C" //{'], ";"],
+        \ ['not recognized', ['extern "C" /*{*/'], ";"],
+        \ ]
+
+  for pair in tests
+    let lines = pair[1]
+    call setline(1, lines)
+    call feedkeys(len(lines) . "Go;", 'tx')
+    call assert_equal(pair[2], getline(len(lines) + 1), 'Failed for "' . string(lines) . '"')
+  endfor
+
+
+
+  bwipe!
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_clientserver.vim b/src/testdir/test_clientserver.vim
new file mode 100644 (file)
index 0000000..86dad54
--- /dev/null
@@ -0,0 +1,105 @@
+" Tests for the +clientserver feature.
+
+if !has('job') || !has('clientserver')
+  finish
+endif
+
+source shared.vim
+
+func Test_client_server()
+  let cmd = GetVimCommand()
+  if cmd == ''
+    return
+  endif
+  if has('x11')
+    if empty($DISPLAY)
+      throw 'Skipped: $DISPLAY is not set'
+    endif
+    try
+      call remote_send('xxx', '')
+    catch
+      if v:exception =~ 'E240:'
+       throw 'Skipped: no connection to the X server'
+      endif
+      " ignore other errors
+    endtry
+  endif
+
+  let name = 'XVIMTEST'
+  let cmd .= ' --servername ' . name
+  let g:job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'})
+  call WaitFor('job_status(g:job) == "run"')
+  if job_status(g:job) != 'run'
+    call assert_report('Cannot run the Vim server')
+    return
+  endif
+
+  " Takes a short while for the server to be active.
+  call WaitFor('serverlist() =~ "' . name . '"')
+  call assert_match(name, serverlist())
+
+  call remote_foreground(name)
+
+  call remote_send(name, ":let testvar = 'yes'\<CR>")
+  call WaitFor('remote_expr("' . name . '", "testvar", "", 1) == "yes"')
+  call assert_equal('yes', remote_expr(name, "testvar", "", 2))
+
+  if has('unix') && has('gui') && !has('gui_running')
+    " Running in a terminal and the GUI is avaiable: Tell the server to open
+    " the GUI and check that the remote command still works.
+    " Need to wait for the GUI to start up, otherwise the send hangs in trying
+    " to send to the terminal window.
+    if has('gui_athena') || has('gui_motif')
+      " For those GUIs, ignore the 'failed to create input context' error.
+      call remote_send(name, ":call test_ignore_error('E285') | gui -f\<CR>")
+    else
+      call remote_send(name, ":gui -f\<CR>")
+    endif
+    " Wait for the server to be up and answering requests.
+    call WaitFor('remote_expr("' . name . '", "v:version", "", 1) != ""')
+
+    call remote_send(name, ":let testvar = 'maybe'\<CR>")
+    call WaitFor('remote_expr("' . name . '", "testvar", "", 1) == "maybe"')
+    call assert_equal('maybe', remote_expr(name, "testvar", "", 2))
+  endif
+
+  call assert_fails('call remote_send("XXX", ":let testvar = ''yes''\<CR>")', 'E241')
+
+  " Expression evaluated locally.
+  if v:servername == ''
+    call remote_startserver('MYSELF')
+    " May get MYSELF1 when running the test again.
+    call assert_match('MYSELF', v:servername)
+  endif
+  let g:testvar = 'myself'
+  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 remote_send(name, ":call server2client(expand('<client>'), 'another')\<CR>", 'g:myserverid')
+  let peek_result = 'nothing'
+  let r = remote_peek(g:myserverid, 'peek_result')
+  " unpredictable whether the result is already avaialble.
+  if r > 0
+    call assert_equal('another', peek_result)
+  elseif r == 0
+    call assert_equal('nothing', peek_result)
+  else
+    call assert_report('remote_peek() failed')
+  endif
+  let g:peek_result = 'empty'
+  call WaitFor('remote_peek(g:myserverid, "g:peek_result") > 0')
+  call assert_equal('another', g:peek_result)
+  call assert_equal('another', remote_read(g:myserverid, 2))
+
+  call remote_send(name, ":qa!\<CR>")
+  call WaitFor('job_status(g:job) == "dead"')
+  if job_status(g:job) != 'dead'
+    call assert_report('Server did not exit')
+    call job_stop(g:job, 'kill')
+  endif
+endfunc
+
+" Uncomment this line to get a debugging log
+" call ch_logfile('channellog', 'w')
index f07da99..f40fd23 100644 (file)
@@ -2,6 +2,7 @@ Tests for :[count]close! and :[count]hide     vim: set ft=vim :
 
 STARTTEST
 :so small.vim
+:set belloff=all
 :let tests = []
 :for i in range(5)
 :new
index 3718087..c272376 100644 (file)
@@ -1,5 +1,7 @@
 " Tests for editing the command line.
 
+set belloff=all
+
 func Test_complete_tab()
   call writefile(['testfile'], 'Xtestfile')
   call feedkeys(":e Xtest\t\r", "tx")
@@ -25,6 +27,92 @@ func Test_complete_wildmenu()
   set nowildmenu
 endfunc
 
+func Test_map_completion()
+  if !has('cmdline_compl')
+    return
+  endif
+  call feedkeys(":map <unique> <si\<Tab>\<Home>\"\<CR>", 'xt')
+  call assert_equal('"map <unique> <silent>', getreg(':'))
+  call feedkeys(":map <script> <un\<Tab>\<Home>\"\<CR>", 'xt')
+  call assert_equal('"map <script> <unique>', getreg(':'))
+  call feedkeys(":map <expr> <sc\<Tab>\<Home>\"\<CR>", 'xt')
+  call assert_equal('"map <expr> <script>', getreg(':'))
+  call feedkeys(":map <buffer> <e\<Tab>\<Home>\"\<CR>", 'xt')
+  call assert_equal('"map <buffer> <expr>', getreg(':'))
+  call feedkeys(":map <nowait> <b\<Tab>\<Home>\"\<CR>", 'xt')
+  call assert_equal('"map <nowait> <buffer>', getreg(':'))
+  call feedkeys(":map <special> <no\<Tab>\<Home>\"\<CR>", 'xt')
+  call assert_equal('"map <special> <nowait>', getreg(':'))
+  call feedkeys(":map <silent> <sp\<Tab>\<Home>\"\<CR>", 'xt')
+  call assert_equal('"map <silent> <special>', getreg(':'))
+endfunc
+
+func Test_match_completion()
+  if !has('cmdline_compl')
+    return
+  endif
+  hi Aardig ctermfg=green
+  call feedkeys(":match \<Tab>\<Home>\"\<CR>", 'xt')
+  call assert_equal('"match Aardig', getreg(':'))
+  call feedkeys(":match \<S-Tab>\<Home>\"\<CR>", 'xt')
+  call assert_equal('"match none', getreg(':'))
+endfunc
+
+func Test_highlight_completion()
+  if !has('cmdline_compl')
+    return
+  endif
+  hi Aardig ctermfg=green
+  call feedkeys(":hi \<Tab>\<Home>\"\<CR>", 'xt')
+  call assert_equal('"hi Aardig', getreg(':'))
+  call feedkeys(":hi default \<Tab>\<Home>\"\<CR>", 'xt')
+  call assert_equal('"hi default Aardig', getreg(':'))
+  call feedkeys(":hi clear Aa\<Tab>\<Home>\"\<CR>", 'xt')
+  call assert_equal('"hi clear Aardig', getreg(':'))
+  call feedkeys(":hi li\<S-Tab>\<Home>\"\<CR>", 'xt')
+  call assert_equal('"hi link', getreg(':'))
+  call feedkeys(":hi d\<S-Tab>\<Home>\"\<CR>", 'xt')
+  call assert_equal('"hi default', getreg(':'))
+  call feedkeys(":hi c\<S-Tab>\<Home>\"\<CR>", 'xt')
+  call assert_equal('"hi clear', getreg(':'))
+
+  " A cleared group does not show up in completions.
+  hi Anders ctermfg=green
+  call assert_equal(['Aardig', 'Anders'], getcompletion('A', 'highlight'))
+  hi clear Aardig
+  call assert_equal(['Anders'], getcompletion('A', 'highlight'))
+  hi clear Anders
+  call assert_equal([], getcompletion('A', 'highlight'))
+endfunc
+
+func Test_expr_completion()
+  if !has('cmdline_compl')
+    return
+  endif
+  for cmd in [
+       \ 'let a = ',
+       \ 'if',
+       \ 'elseif',
+       \ 'while',
+       \ 'for',
+       \ 'echo',
+       \ 'echon',
+       \ 'execute',
+       \ 'echomsg',
+       \ 'echoerr',
+       \ 'call',
+       \ 'return',
+       \ 'cexpr',
+       \ 'caddexpr',
+       \ 'cgetexpr',
+       \ 'lexpr',
+       \ 'laddexpr',
+       \ 'lgetexpr']
+    call feedkeys(":" . cmd . " getl\<Tab>\<Home>\"\<CR>", 'xt')
+    call assert_equal('"' . cmd . ' getline(', getreg(':'))
+  endfor
+endfunc
+
 func Test_getcompletion()
   if !has('cmdline_compl')
     return
@@ -194,3 +282,148 @@ func Test_expand_star_star()
   bwipe!
   call delete('a', 'rf')
 endfunc
+
+func Test_paste_in_cmdline()
+  let @a = "def"
+  call feedkeys(":abc \<C-R>a ghi\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"abc def ghi', @:)
+
+  new
+  call setline(1, 'asdf.x /tmp/some verylongword a;b-c*d ')
+
+  call feedkeys(":aaa \<C-R>\<C-W> bbb\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"aaa asdf bbb', @:)
+
+  call feedkeys("ft:aaa \<C-R>\<C-F> bbb\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"aaa /tmp/some bbb', @:)
+
+  set incsearch
+  call feedkeys("fy:aaa veryl\<C-R>\<C-W> bbb\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"aaa verylongword bbb', @:)
+
+  call feedkeys("f;:aaa \<C-R>\<C-A> bbb\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"aaa a;b-c*d bbb', @:)
+
+  call feedkeys(":\<C-\>etoupper(getline(1))\<CR>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"ASDF.X /TMP/SOME VERYLONGWORD A;B-C*D ', @:)
+  bwipe!
+endfunc
+
+func Test_remove_char_in_cmdline()
+  call feedkeys(":abc def\<S-Left>\<Del>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"abc ef', @:)
+
+  call feedkeys(":abc def\<S-Left>\<BS>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"abcdef', @:)
+
+  call feedkeys(":abc def ghi\<S-Left>\<C-W>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"abc ghi', @:)
+
+  call feedkeys(":abc def\<S-Left>\<C-U>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"def', @:)
+endfunc
+
+func Test_illegal_address1()
+  new
+  2;'(
+  2;')
+  quit
+endfunc
+
+func Test_illegal_address2()
+  call writefile(['c', 'x', '  x', '.', '1;y'], 'Xtest.vim')
+  new
+  source Xtest.vim
+  " Trigger calling validate_cursor()
+  diffsp Xtest.vim
+  quit!
+  bwipe!
+  call delete('Xtest.vim')
+endfunc
+
+func Test_cmdline_complete_wildoptions()
+  help
+  call feedkeys(":tag /\<c-a>\<c-b>\"\<cr>", 'tx')
+  let a = join(sort(split(@:)),' ')
+  set wildoptions=tagfile
+  call feedkeys(":tag /\<c-a>\<c-b>\"\<cr>", 'tx')
+  let b = join(sort(split(@:)),' ')
+  call assert_equal(a, b)
+  bw!
+endfunc
+
+func Test_cmdline_complete_user_cmd()
+  command! -complete=color -nargs=1 Foo :
+  call feedkeys(":Foo \<Tab>\<Home>\"\<cr>", 'tx')
+  call assert_equal('"Foo blue', @:)
+  call feedkeys(":Foo b\<Tab>\<Home>\"\<cr>", 'tx')
+  call assert_equal('"Foo blue', @:)
+  delcommand Foo
+endfunc
+
+" using a leading backslash here
+set cpo+=C
+
+func Test_cmdline_search_range()
+  new
+  call setline(1, ['a', 'b', 'c', 'd'])
+  /d
+  1,\/s/b/B/
+  call assert_equal('B', getline(2))
+
+  /a
+  $
+  \?,4s/c/C/
+  call assert_equal('C', getline(3))
+
+  call setline(1, ['a', 'b', 'c', 'd'])
+  %s/c/c/
+  1,\&s/b/B/
+  call assert_equal('B', getline(2))
+
+  bwipe!
+endfunc
+
+" Tests for getcmdline(), getcmdpos() and getcmdtype()
+func Check_cmdline(cmdtype)
+  call assert_equal('MyCmd a', getcmdline())
+  call assert_equal(8, getcmdpos())
+  call assert_equal(a:cmdtype, getcmdtype())
+  return ''
+endfunc
+
+func Test_getcmdtype()
+  call feedkeys(":MyCmd a\<C-R>=Check_cmdline(':')\<CR>\<Esc>", "xt")
+
+  let cmdtype = ''
+  debuggreedy
+  call feedkeys(":debug echo 'test'\<CR>", "t")
+  call feedkeys("let cmdtype = \<C-R>=string(getcmdtype())\<CR>\<CR>", "t")
+  call feedkeys("cont\<CR>", "xt")
+  0debuggreedy
+  call assert_equal('>', cmdtype)
+
+  call feedkeys("/MyCmd a\<C-R>=Check_cmdline('/')\<CR>\<Esc>", "xt")
+  call feedkeys("?MyCmd a\<C-R>=Check_cmdline('?')\<CR>\<Esc>", "xt")
+
+  call feedkeys(":call input('Answer?')\<CR>", "t")
+  call feedkeys("MyCmd a\<C-R>=Check_cmdline('@')\<CR>\<C-C>", "xt")
+
+  call feedkeys(":insert\<CR>MyCmd a\<C-R>=Check_cmdline('-')\<CR>\<Esc>", "xt")
+
+  cnoremap <expr> <F6> Check_cmdline('=')
+  call feedkeys("a\<C-R>=MyCmd a\<F6>\<Esc>\<Esc>", "xt")
+  cunmap <F6>
+endfunc
+
+func Test_verbosefile()
+  set verbosefile=Xlog
+  echomsg 'foo'
+  echomsg 'bar'
+  set verbosefile=
+  let log = readfile('Xlog')
+  call assert_match("foo\nbar", join(log, "\n"))
+  call delete('Xlog')
+endfunc
+
+set cpo&
index 4e78faa..4d776e9 100644 (file)
@@ -28,7 +28,7 @@ func Test_cscopeWithCscopeConnections()
       cscope add Xcscope.out
       set cscopeverbose
     catch
-      call assert_true(0)
+      call assert_report('exception thrown')
     endtry
     call assert_fails('cscope add', 'E560')
     call assert_fails('cscope add Xcscope.out', 'E568')
index 4b2a9b8..d784e36 100644 (file)
@@ -1,13 +1,7 @@
 " Tests for cursor().
 
 func Test_wrong_arguments()
-  try
-    call cursor(1. 3)
-    " not reached
-    call assert_false(1)
-  catch
-    call assert_exception('E474:')
-  endtry
+  call assert_fails('call cursor(1. 3)', 'E474:')
 endfunc
 
 func Test_move_cursor()
@@ -44,9 +38,9 @@ func Test_curswant_with_autocommand()
   new
   call setline(1, ['func()', '{', '}', '----'])
   autocmd! CursorMovedI * call s:Highlight_Matching_Pair()
-  call test_disable_char_avail(1)
+  call test_override("char_avail", 1)
   exe "normal! 3Ga\<Down>X\<Esc>"
-  call test_disable_char_avail(0)
+  call test_override("char_avail", 0)
   call assert_equal('-X---', getline(4))
   autocmd! CursorMovedI *
   quit!
index 3cf2623..4686a0d 100644 (file)
@@ -8,6 +8,7 @@ func Test_file_delete()
   call assert_equal(0, delete('Xfile'))
   call assert_fails('call readfile("Xfile")', 'E484:')
   call assert_equal(-1, delete('Xfile'))
+  bwipe Xfile
 endfunc
 
 func Test_dir_delete()
@@ -35,6 +36,8 @@ func Test_recursive_delete()
   call assert_equal(0, delete('Xdir1', 'rf'))
   call assert_false(isdirectory('Xdir1'))
   call assert_equal(-1, delete('Xdir1', 'd'))
+  bwipe Xdir1/Xfile
+  bwipe Xdir1/subdir/Xfile
 endfunc
 
 func Test_symlink_delete()
@@ -49,6 +52,7 @@ func Test_symlink_delete()
   call assert_equal(0, delete('Xlink'))
   call assert_equal(-1, delete('Xlink'))
   call assert_equal(0, delete('Xfile'))
+  bwipe Xfile
 endfunc
 
 func Test_symlink_dir_delete()
@@ -96,4 +100,8 @@ func Test_symlink_recursive_delete()
   call assert_equal(['a', 'b'], readfile('Xdir4/Xfile'))
   call assert_equal(0, delete('Xdir4/Xfile'))
   call assert_equal(0, delete('Xdir4', 'd'))
+
+  bwipe Xdir3/Xfile
+  bwipe Xdir3/subdir/Xfile
+  bwipe Xdir4/Xfile
 endfunc
index f40e06f..e09bcaa 100644 (file)
@@ -1,4 +1,5 @@
 " Tests for diff mode
+set belloff=all
 
 func Test_diff_fold_sync()
   enew!
@@ -212,6 +213,7 @@ func Test_diffoff()
   call setline(1, ['One', '', 'Two', 'Three'])
   diffthis
   redraw
+  call assert_notequal(normattr, screenattr(1, 1))
   diffoff!
   redraw
   call assert_equal(normattr, screenattr(1, 1))
@@ -219,6 +221,42 @@ func Test_diffoff()
   bwipe!
 endfunc
 
+func Test_diffoff_hidden()
+  set diffopt=filler,foldcolumn:0
+  e! one
+  call setline(1, ['Two', 'Three'])
+  let normattr = screenattr(1, 1)
+  diffthis
+  botright vert new two
+  call setline(1, ['One', 'Four'])
+  diffthis
+  redraw
+  call assert_notequal(normattr, screenattr(1, 1))
+  set hidden
+  close
+  redraw
+  " diffing with hidden buffer two
+  call assert_notequal(normattr, screenattr(1, 1))
+  diffoff
+  redraw
+  call assert_equal(normattr, screenattr(1, 1))
+  diffthis
+  redraw
+  " still diffing with hidden buffer two
+  call assert_notequal(normattr, screenattr(1, 1))
+  diffoff!
+  redraw
+  call assert_equal(normattr, screenattr(1, 1))
+  diffthis
+  redraw
+  " no longer diffing with hidden buffer two
+  call assert_equal(normattr, screenattr(1, 1))
+
+  bwipe!
+  bwipe!
+  set hidden& diffopt&
+endfunc
+
 func Test_setting_cursor()
   new Xtest1
   put =range(1,90)
@@ -235,3 +273,109 @@ func Test_setting_cursor()
   call delete('Xtest1')
   call delete('Xtest2')
 endfunc
+
+func Test_diff_move_to()
+  new
+  call setline(1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
+  diffthis
+  vnew
+  call setline(1, [1, '2x', 3, 4, 4, 5, '6x', 7, '8x', 9, '10x'])
+  diffthis
+  norm ]c
+  call assert_equal(2, line('.'))
+  norm 3]c
+  call assert_equal(9, line('.'))
+  norm 10]c
+  call assert_equal(11, line('.'))
+  norm [c
+  call assert_equal(9, line('.'))
+  norm 2[c
+  call assert_equal(5, line('.'))
+  norm 10[c
+  call assert_equal(2, line('.'))
+  %bwipe!
+endfunc
+
+func Test_diffpatch()
+  " The patch program on MS-Windows may fail or hang.
+  if !executable('patch') || !has('unix')
+    return
+  endif
+  new
+  insert
+***************
+*** 1,3 ****
+  1
+! 2
+  3
+--- 1,4 ----
+  1
+! 2x
+  3
++ 4
+.
+  saveas Xpatch
+  bwipe!
+  new
+  call assert_fails('diffpatch Xpatch', 'E816:')
+
+  for name in ['Xpatch', 'Xpatch$HOME', 'Xpa''tch']
+    call setline(1, ['1', '2', '3'])
+    if name != 'Xpatch'
+      call rename('Xpatch', name)
+    endif
+    exe 'diffpatch ' . escape(name, '$')
+    call assert_equal(['1', '2x', '3', '4'], getline(1, '$'))
+    if name != 'Xpatch'
+      call rename(name, 'Xpatch')
+    endif
+    bwipe!
+  endfor
+
+  call delete('Xpatch')
+  bwipe!
+endfunc
+
+func Test_diff_too_many_buffers()
+  for i in range(1, 8)
+    exe "new Xtest" . i
+    diffthis
+  endfor
+  new Xtest9
+  call assert_fails('diffthis', 'E96:')
+  %bwipe!
+endfunc
+
+func Test_diff_nomodifiable()
+  new
+  call setline(1, [1, 2, 3, 4])
+  setl nomodifiable
+  diffthis
+  vnew
+  call setline(1, ['1x', 2, 3, 3, 4])
+  diffthis
+  call assert_fails('norm dp', 'E793:')
+  setl nomodifiable
+  call assert_fails('norm do', 'E21:')
+  %bwipe!
+endfunc
+
+func Test_diff_lastline()
+  enew!
+  only!
+  call setline(1, ['This is a ', 'line with five ', 'rows'])
+  diffthis
+  botright vert new
+  call setline(1, ['This is', 'a line with ', 'four rows'])
+  diffthis
+  1
+  call feedkeys("Je a\<CR>", 'tx')
+  call feedkeys("Je a\<CR>", 'tx')
+  let w1lines = winline()
+  wincmd w
+  $
+  let w2lines = winline()
+  call assert_equal(w2lines, w1lines)
+  bwipe!
+  bwipe!
+endfunc
index 6290680..30dc9a4 100644 (file)
@@ -3,6 +3,7 @@
 if !has("digraphs") || !has("multi_byte")
   finish
 endif
+set belloff=all
 
 func! Put_Dig(chars)
   exe "norm! o\<c-k>".a:chars
diff --git a/src/testdir/test_display.vim b/src/testdir/test_display.vim
new file mode 100644 (file)
index 0000000..48b7a23
--- /dev/null
@@ -0,0 +1,69 @@
+" Test for displaying stuff
+if !has('gui_running') && has('unix')
+  set term=ansi
+endif
+
+source view_util.vim
+
+func! Test_display_foldcolumn()
+  if !has("folding")
+    return
+  endif
+  new
+  vnew
+  vert resize 25
+  call assert_equal(25, winwidth(winnr()))
+  set isprint=@
+
+  1put='e more noise blah blah\82 more stuff here'
+
+  let expect = [
+        \ "e more noise blah blah<82",
+        \ "> more stuff here        "
+        \ ]
+
+  call cursor(2, 1)
+  norm! zt
+  let lines=ScreenLines([1,2], winwidth(0))
+  call assert_equal(expect, lines)
+  set fdc=2
+  let lines=ScreenLines([1,2], winwidth(0))
+  let expect = [
+        \ "  e more noise blah blah<",
+        \ "  82> more stuff here    "
+        \ ]
+  call assert_equal(expect, lines)
+
+  quit!
+  quit!
+endfunc
+
+func! Test_display_foldtext_mbyte()
+  if !has("folding") || !has("multi_byte")
+    return
+  endif
+  call NewWindow(10, 40)
+  call append(0, range(1,20))
+  exe "set foldmethod=manual foldtext=foldtext() fillchars=fold:\u2500,vert:\u2502 fdc=2"
+  call cursor(2, 1)
+  norm! zf13G
+  let lines=ScreenLines([1,3], winwidth(0)+1)
+  let expect=[
+        \ "  1                                     \u2502",
+        \ "+ +-- 12 lines: 2". repeat("\u2500", 23). "\u2502",
+        \ "  14                                    \u2502",
+        \ ]
+  call assert_equal(expect, lines)
+
+  set fillchars=fold:-,vert:\|
+  let lines=ScreenLines([1,3], winwidth(0)+1)
+  let expect=[
+        \ "  1                                     |",
+        \ "+ +-- 12 lines: 2". repeat("-", 23). "|",
+        \ "  14                                    |",
+        \ ]
+  call assert_equal(expect, lines)
+
+  set foldtext& fillchars& foldmethod& fdc&
+  bw!
+endfunc
diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim
new file mode 100644 (file)
index 0000000..0986bf9
--- /dev/null
@@ -0,0 +1,1365 @@
+" Test for edit functions
+"
+if exists("+t_kD")
+  let &t_kD="\e[3;*~"
+endif
+set belloff=
+
+" Needed for testing basic rightleft: Test_edit_rightleft
+source view_util.vim
+
+" Needs to come first until the bug in getchar() is
+" fixed: https://groups.google.com/d/msg/vim_dev/fXL9yme4H4c/bOR-U6_bAQAJ
+func! Test_edit_00b()
+  new
+  call setline(1, ['abc '])
+  inoreabbr <buffer> h here some more
+  call cursor(1, 4)
+  " <c-l> expands the abbreviation and ends insertmode
+  call feedkeys(":set im\<cr> h\<c-l>:set noim\<cr>", 'tix')
+  call assert_equal(['abc here some more '], getline(1,'$'))
+  iunabbr <buffer> h
+  bw!
+endfunc
+
+func! Test_edit_01()
+  " set for Travis CI?
+  "  set nocp noesckeys
+  new
+  set belloff=backspace
+  " 1) empty buffer
+  call assert_equal([''], getline(1,'$'))
+  " 2) delete in an empty line
+  call feedkeys("i\<del>\<esc>", 'tnix')
+  call assert_equal([''], getline(1,'$'))
+  %d
+  " 3) delete one character
+  call setline(1, 'a')
+  call feedkeys("i\<del>\<esc>", 'tnix')
+  call assert_equal([''], getline(1,'$'))
+  %d
+  " 4) delete a multibyte character
+  if has("multi_byte")
+    call setline(1, "\u0401")
+    call feedkeys("i\<del>\<esc>", 'tnix')
+    call assert_equal([''], getline(1,'$'))
+    %d
+  endif
+  " 5.1) delete linebreak with 'bs' option containing eol
+  let _bs=&bs
+  set bs=eol
+  call setline(1, ["abc def", "ghi jkl"])
+  call cursor(1, 1)
+  call feedkeys("A\<del>\<esc>", 'tnix')
+  call assert_equal(['abc defghi jkl'], getline(1, 2))
+  %d
+  " 5.2) delete linebreak with backspace option w/out eol
+  set bs=
+  call setline(1, ["abc def", "ghi jkl"])
+  call cursor(1, 1)
+  call feedkeys("A\<del>\<esc>", 'tnix')
+  call assert_equal(["abc def", "ghi jkl"], getline(1, 2))
+  set belloff=
+  let &bs=_bs
+  bw!
+endfunc
+
+func! Test_edit_02()
+  " Change cursor position in InsertCharPre command
+  new
+  call setline(1, 'abc')
+  call cursor(1, 1)
+  fu! DoIt(...)
+    call cursor(1, 4)
+    if len(a:000)
+      let v:char=a:1
+    endif
+  endfu
+  au InsertCharPre <buffer> :call DoIt('y')
+  call feedkeys("ix\<esc>", 'tnix')
+  call assert_equal(['abcy'], getline(1, '$'))
+  " Setting <Enter> in InsertCharPre
+  au! InsertCharPre <buffer> :call DoIt("\n")
+  call setline(1, 'abc')
+  call cursor(1, 1)
+  call feedkeys("ix\<esc>", 'tnix')
+  call assert_equal(['abc', ''], getline(1, '$'))
+  %d
+  au! InsertCharPre
+  " Change cursor position in InsertEnter command
+  " 1) when setting v:char, keeps changed cursor position
+  au! InsertEnter <buffer> :call DoIt('y')
+  call setline(1, 'abc')
+  call cursor(1, 1)
+  call feedkeys("ix\<esc>", 'tnix')
+  call assert_equal(['abxc'], getline(1, '$'))
+  " 2) when not setting v:char, restores changed cursor position
+  au! InsertEnter <buffer> :call DoIt()
+  call setline(1, 'abc')
+  call cursor(1, 1)
+  call feedkeys("ix\<esc>", 'tnix')
+  call assert_equal(['xabc'], getline(1, '$'))
+  au! InsertEnter
+  delfu DoIt
+  bw!
+endfunc
+
+func! Test_edit_03()
+  " Change cursor after <c-o> command to end of line
+  new
+  call setline(1, 'abc')
+  call cursor(1, 1)
+  call feedkeys("i\<c-o>$y\<esc>", 'tnix')
+  call assert_equal(['abcy'], getline(1, '$'))
+  %d
+  call setline(1, 'abc')
+  call cursor(1, 1)
+  call feedkeys("i\<c-o>80|y\<esc>", 'tnix')
+  call assert_equal(['abcy'], getline(1, '$'))
+  %d
+  call setline(1, 'abc')
+  call feedkeys("Ad\<c-o>:s/$/efg/\<cr>hij", 'tnix')
+  call assert_equal(['hijabcdefg'], getline(1, '$'))
+  bw!
+endfunc
+
+func! Test_edit_04()
+  " test for :stopinsert
+  new
+  call setline(1, 'abc')
+  call cursor(1, 1)
+  call feedkeys("i\<c-o>:stopinsert\<cr>$", 'tnix')
+  call feedkeys("aX\<esc>", 'tnix')
+  call assert_equal(['abcX'], getline(1, '$'))
+  %d
+  bw!
+endfunc
+
+func! Test_edit_05()
+  " test for folds being opened
+  new
+  call setline(1, ['abcX', 'abcX', 'zzzZ'])
+  call cursor(1, 1)
+  set foldmethod=manual foldopen+=insert
+  " create fold for those two lines
+  norm! Vjzf
+  call feedkeys("$ay\<esc>", 'tnix')
+  call assert_equal(['abcXy', 'abcX', 'zzzZ'], getline(1, '$'))
+  %d
+  call setline(1, ['abcX', 'abcX', 'zzzZ'])
+  call cursor(1, 1)
+  set foldmethod=manual foldopen-=insert
+  " create fold for those two lines
+  norm! Vjzf
+  call feedkeys("$ay\<esc>", 'tnix')
+  call assert_equal(['abcXy', 'abcX', 'zzzZ'], getline(1, '$'))
+  %d
+  bw!
+endfunc
+
+func! Test_edit_06()
+  " Test in diff mode
+  if !has("diff") || !executable("diff")
+    return
+  endif
+  new
+  call setline(1, ['abc', 'xxx', 'yyy'])
+  vnew
+  call setline(1, ['abc', 'zzz', 'xxx', 'yyy'])
+  wincmd p
+  diffthis
+  wincmd p
+  diffthis
+  wincmd p
+  call cursor(2, 1)
+  norm! zt
+  call feedkeys("Ozzz\<esc>", 'tnix')
+  call assert_equal(['abc', 'zzz', 'xxx', 'yyy'], getline(1,'$'))
+  bw!
+  bw!
+endfunc
+
+func! Test_edit_07()
+  " 1) Test with completion <c-l> when popupmenu is visible
+  new
+  call setline(1, 'J')
+
+  func! ListMonths()
+    call complete(col('.')-1, ['January', 'February', 'March',
+    \ 'April', 'May', 'June', 'July', 'August', 'September',
+    \ 'October', 'November', 'December'])
+    return ''
+  endfunc
+  inoremap <buffer> <F5> <C-R>=ListMonths()<CR>
+
+  call feedkeys("A\<f5>\<c-p>". repeat("\<down>", 6)."\<c-l>\<down>\<c-l>\<cr>", 'tx')
+  call assert_equal(['July'], getline(1,'$'))
+  " 1) Test completion when InsertCharPre kicks in
+  %d
+  call setline(1, 'J')
+  fu! DoIt()
+    if v:char=='u'
+      let v:char='an'
+    endif
+  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,'$'))
+  %d
+  call setline(1, 'J')
+  call feedkeys("A\<f5>\<c-p>u\<down>\<c-l>\<cr>", 'tx')
+  call assert_equal(["January"], getline(1,'$'))
+
+  delfu ListMonths
+  delfu DoIt
+  iunmap <buffer> <f5>
+  bw!
+endfunc
+
+func! Test_edit_08()
+  " reset insertmode from i_ctrl-r_=
+  new
+  call setline(1, ['abc'])
+  call cursor(1, 4)
+  call feedkeys(":set im\<cr>ZZZ\<c-r>=setbufvar(1,'&im', 0)\<cr>",'tnix')
+  call assert_equal(['abZZZc'], getline(1,'$'))
+  call assert_equal([0, 1, 1, 0], getpos('.'))
+  call assert_false(0, '&im')
+  bw!
+endfunc
+
+func! Test_edit_09()
+  " test i_CTRL-\ combinations
+  new
+  call setline(1, ['abc', 'def', 'ghi'])
+  call cursor(1, 1)
+  " 1) CTRL-\ CTLR-N
+  call feedkeys(":set im\<cr>\<c-\>\<c-n>ccABC\<c-l>", 'txin')
+  call assert_equal(['ABC', 'def', 'ghi'], getline(1,'$'))
+  call setline(1, ['ABC', 'def', 'ghi'])
+  " 2) CTRL-\ CTLR-G
+  call feedkeys("j0\<c-\>\<c-g>ZZZ\<cr>\<c-l>", 'txin')
+  call assert_equal(['ABC', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
+  call feedkeys("I\<c-\>\<c-g>YYY\<c-l>", 'txin')
+  call assert_equal(['ABC', 'ZZZ', 'YYYdef', 'ghi'], getline(1,'$'))
+  set noinsertmode
+  " 3) CTRL-\ CTRL-O
+  call setline(1, ['ABC', 'ZZZ', 'def', 'ghi'])
+  call cursor(1, 1)
+  call feedkeys("A\<c-o>ix", 'txin')
+  call assert_equal(['ABxC', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
+  call feedkeys("A\<c-\>\<c-o>ix", 'txin')
+  call assert_equal(['ABxCx', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
+  " 4) CTRL-\ a (should be inserted literally, not special after <c-\>
+  call setline(1, ['ABC', 'ZZZ', 'def', 'ghi'])
+  call cursor(1, 1)
+  call feedkeys("A\<c-\>a", 'txin')
+  call assert_equal(["ABC\<c-\>a", 'ZZZ', 'def', 'ghi'], getline(1, '$'))
+  bw!
+endfunc
+
+func! Test_edit_10()
+  " Test for starting selectmode
+  new
+  set selectmode=key keymodel=startsel
+  call setline(1, ['abc', 'def', 'ghi'])
+  call cursor(1, 4)
+  call feedkeys("A\<s-home>start\<esc>", 'txin')
+  call assert_equal(['startdef', 'ghi'], getline(1, '$'))
+  set selectmode= keymodel=
+  bw!
+endfunc
+
+func! Test_edit_11()
+  " Test that indenting kicks in
+  new
+  set cindent
+  call setline(1, ['{', '', ''])
+  call cursor(2, 1)
+  call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
+  call cursor(3, 1)
+  call feedkeys("i/* comment */", 'tnix')
+  call assert_equal(['{', "\<tab>int c;", "/* comment */"], getline(1, '$'))
+  " added changed cindentkeys slightly
+  set cindent cinkeys+=*/
+  call setline(1, ['{', '', ''])
+  call cursor(2, 1)
+  call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
+  call cursor(3, 1)
+  call feedkeys("i/* comment */", 'tnix')
+  call assert_equal(['{', "\<tab>int c;", "\<tab>/* comment */"], getline(1, '$'))
+  set cindent cinkeys+==end
+  call feedkeys("oend\<cr>\<esc>", 'tnix')
+  call assert_equal(['{', "\<tab>int c;", "\<tab>/* comment */", "\tend", ''], getline(1, '$'))
+  set cinkeys-==end
+  %d
+  " Use indentexpr instead of cindenting
+  func! Do_Indent()
+    if v:lnum == 3
+      return 3*shiftwidth()
+    else
+      return 2*shiftwidth()
+    endif
+  endfunc
+  setl indentexpr=Do_Indent() indentkeys+=*/
+  call setline(1, ['{', '', ''])
+  call cursor(2, 1)
+  call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
+  call cursor(3, 1)
+  call feedkeys("i/* comment */", 'tnix')
+  call assert_equal(['{', "\<tab>\<tab>int c;", "\<tab>\<tab>\<tab>/* comment */"], getline(1, '$'))
+  set cinkeys&vim indentkeys&vim
+  set nocindent indentexpr=
+  delfu Do_Indent
+  bw!
+endfunc
+
+func! Test_edit_12()
+  " Test changing indent in replace mode
+  new
+  call setline(1, ["\tabc", "\tdef"])
+  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('.'))
+  %d
+  call setline(1, ["\tabc", "\t\tdef"])
+  call cursor(2, 2)
+  call feedkeys("R^\<c-d>", 'tnix')
+  call assert_equal(["\tabc", "def"], getline(1, '$'))
+  call assert_equal([0, 2, 1, 0], getpos('.'))
+  %d
+  call setline(1, ["\tabc", "\t\tdef"])
+  call cursor(2, 2)
+  call feedkeys("R\<c-t>", 'tnix')
+  call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
+  call assert_equal([0, 2, 2, 0], getpos('.'))
+  bw!
+  10vnew
+  call setline(1, ["\tabc", "\t\tdef"])
+  call cursor(2, 2)
+  call feedkeys("R\<c-t>", 'tnix')
+  call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
+  call assert_equal([0, 2, 2, 0], getpos('.'))
+  %d
+  set sw=4
+  call setline(1, ["\tabc", "\t\tdef"])
+  call cursor(2, 2)
+  call feedkeys("R\<c-t>\<c-t>", 'tnix')
+  call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
+  call assert_equal([0, 2, 2, 0], getpos('.'))
+  %d
+  call setline(1, ["\tabc", "\t\tdef"])
+  call cursor(2, 2)
+  call feedkeys("R\<c-t>\<c-t>", 'tnix')
+  call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
+  call assert_equal([0, 2, 2, 0], getpos('.'))
+  set et
+  set sw& et&
+  %d
+  call setline(1, ["\t/*"])
+  set formatoptions=croql
+  call cursor(1, 3)
+  call feedkeys("A\<cr>\<cr>/", 'tnix')
+  call assert_equal(["\t/*", " *", " */"], getline(1, '$'))
+  set formatoptions&
+  bw!
+endfunc
+
+func! Test_edit_13()
+  " Test smartindenting
+  if exists("+smartindent")
+    new
+    set smartindent autoindent
+    call setline(1, ["\tabc"])
+    call feedkeys("A {\<cr>more\<cr>}\<esc>", 'tnix')
+    call assert_equal(["\tabc {", "\t\tmore", "\t}"], getline(1, '$'))
+    set smartindent& autoindent&
+    bw!
+  endif
+endfunc
+
+func! Test_edit_CR()
+  " Test for <CR> in insert mode
+  " basically only in quickfix mode ist tested, the rest
+  " has been taken care of by other tests
+  if !has("quickfix")
+    return
+  endif
+  botright new
+  call writefile(range(1, 10), 'Xqflist.txt')
+  call setqflist([{'filename': 'Xqflist.txt', 'lnum': 2}])
+  copen
+  set modifiable
+  call feedkeys("A\<cr>", 'tnix')
+  call assert_equal('Xqflist.txt', bufname(''))
+  call assert_equal(2, line('.'))
+  cclose
+  botright new
+  call setloclist(0, [{'filename': 'Xqflist.txt', 'lnum': 10}])
+  lopen
+  set modifiable
+  call feedkeys("A\<cr>", 'tnix')
+  call assert_equal('Xqflist.txt', bufname(''))
+  call assert_equal(10, line('.'))
+  call feedkeys("A\<Enter>", 'tnix')
+  call feedkeys("A\<kEnter>", 'tnix')
+  call feedkeys("A\n", 'tnix')
+  call feedkeys("A\r", 'tnix')
+  call assert_equal(map(range(1, 10), 'string(v:val)') + ['', '', '', ''], getline(1, '$'))
+  bw!
+  lclose
+  call delete('Xqflist.txt')
+endfunc
+
+func! Test_edit_CTRL_()
+  " disabled for Windows builds, why?
+  if !has("multi_byte") || !has("rightleft") || has("win32")
+    return
+  endif
+  let _encoding=&encoding
+  set encoding=utf-8
+  " Test for CTRL-_
+  new
+  call setline(1, ['abc'])
+  call cursor(1, 1)
+  call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
+  call assert_equal(["\<C-_>xyzabc"], getline(1, '$'))
+  call assert_false(&revins)
+  set ari
+  call setline(1, ['abc'])
+  call cursor(1, 1)
+  call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
+  call assert_equal(["æèñabc"], getline(1, '$'))
+  call assert_true(&revins)
+  call setline(1, ['abc'])
+  call cursor(1, 1)
+  call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
+  call assert_equal(["xyzabc"], getline(1, '$'))
+  call assert_false(&revins)
+  set noari
+  let &encoding=_encoding
+  bw!
+endfunc
+
+" needs to come first, to have the @. register empty
+func! Test_edit_00a_CTRL_A()
+  " Test pressing CTRL-A
+  new
+  call setline(1, repeat([''], 5))
+  call cursor(1, 1)
+  set belloff=all
+  try
+    call feedkeys("A\<NUL>", 'tnix')
+  catch /^Vim\%((\a\+)\)\=:E29/
+    call assert_true(1, 'E29 error caught')
+  endtry
+  set belloff=
+  call cursor(1, 1)
+  call feedkeys("Afoobar \<esc>", 'tnix')
+  call cursor(2, 1)
+  call feedkeys("A\<c-a>more\<esc>", 'tnix')
+  call cursor(3, 1)
+  call feedkeys("A\<NUL>and more\<esc>", 'tnix')
+  call assert_equal(['foobar ', 'foobar more', 'foobar morend more', '', ''], getline(1, '$'))
+  bw!
+endfunc
+
+func! Test_edit_CTRL_EY()
+  " Ctrl-E/ Ctrl-Y in insert mode completion to scroll
+  10new
+  call setline(1, range(1, 100))
+  call cursor(30, 1)
+  norm! z.
+  call feedkeys("A\<c-x>\<c-e>\<c-e>\<c-e>\<c-e>\<c-e>", 'tnix')
+  call assert_equal(30, winsaveview()['topline'])
+  call assert_equal([0, 30, 2, 0], getpos('.'))
+  call feedkeys("A\<c-x>\<c-e>\<c-e>\<c-e>\<c-e>\<c-e>", 'tnix')
+  call feedkeys("A\<c-x>".repeat("\<c-y>", 10), 'tnix')
+  call assert_equal(21, winsaveview()['topline'])
+  call assert_equal([0, 30, 2, 0], getpos('.'))
+  bw!
+endfunc
+
+func! Test_edit_CTRL_G()
+  new
+  set belloff=all
+  call setline(1, ['foobar', 'foobar', 'foobar'])
+  call cursor(2, 4)
+  call feedkeys("ioooooooo\<c-g>k\<c-r>.\<esc>", 'tnix')
+  call assert_equal(['foooooooooobar', 'foooooooooobar', 'foobar'], getline(1, '$'))
+  call assert_equal([0, 1, 11, 0], getpos('.'))
+  call feedkeys("i\<c-g>k\<esc>", 'tnix')
+  call assert_equal([0, 1, 10, 0], getpos('.'))
+  call cursor(2, 4)
+  call feedkeys("i\<c-g>jzzzz\<esc>", 'tnix')
+  call assert_equal(['foooooooooobar', 'foooooooooobar', 'foozzzzbar'], getline(1, '$'))
+  call assert_equal([0, 3, 7, 0], getpos('.'))
+  call feedkeys("i\<c-g>j\<esc>", 'tnix')
+  call assert_equal([0, 3, 6, 0], getpos('.'))
+  set belloff=
+  bw!
+endfunc
+
+func! Test_edit_CTRL_I()
+  " Tab in completion mode
+  let path=expand("%:p:h")
+  new
+  call setline(1, [path."/", ''])
+  call feedkeys("Arunt\<c-x>\<c-f>\<tab>\<cr>\<esc>", 'tnix')
+  call assert_match('runtest\.vim', getline(1))
+  %d
+  call writefile(['one', 'two', 'three'], 'Xinclude.txt')
+  let include='#include Xinclude.txt'
+  call setline(1, [include, ''])
+  call cursor(2, 1)
+  call feedkeys("A\<c-x>\<tab>\<cr>\<esc>", 'tnix')
+  call assert_equal([include, 'one', ''], getline(1, '$'))
+  call feedkeys("2ggC\<c-x>\<tab>\<down>\<cr>\<esc>", 'tnix')
+  call assert_equal([include, 'two', ''], getline(1, '$'))
+  call feedkeys("2ggC\<c-x>\<tab>\<down>\<down>\<cr>\<esc>", 'tnix')
+  call assert_equal([include, 'three', ''], getline(1, '$'))
+  call feedkeys("2ggC\<c-x>\<tab>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
+  call assert_equal([include, '', ''], getline(1, '$'))
+  call delete("Xinclude.txt")
+  bw!
+endfunc
+
+func! Test_edit_CTRL_K()
+  " Test pressing CTRL-K (basically only dictionary completion and digraphs
+  " the rest is already covered
+  call writefile(['A', 'AA', 'AAA', 'AAAA'], 'Xdictionary.txt')
+  set dictionary=Xdictionary.txt
+  new
+  call setline(1, 'A')
+  call cursor(1, 1)
+  call feedkeys("A\<c-x>\<c-k>\<cr>\<esc>", 'tnix')
+  call assert_equal(['AA', ''], getline(1, '$'))
+  %d
+  call setline(1, 'A')
+  call cursor(1, 1)
+  call feedkeys("A\<c-x>\<c-k>\<down>\<cr>\<esc>", 'tnix')
+  call assert_equal(['AAA'], getline(1, '$'))
+  %d
+  call setline(1, 'A')
+  call cursor(1, 1)
+  call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<cr>\<esc>", 'tnix')
+  call assert_equal(['AAAA'], getline(1, '$'))
+  %d
+  call setline(1, 'A')
+  call cursor(1, 1)
+  call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
+  call assert_equal(['A'], getline(1, '$'))
+  %d
+  call setline(1, 'A')
+  call cursor(1, 1)
+  call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
+  call assert_equal(['AA'], getline(1, '$'))
+
+  " press an unexecpted key after dictionary completion
+  %d
+  call setline(1, 'A')
+  call cursor(1, 1)
+  call feedkeys("A\<c-x>\<c-k>\<c-]>\<cr>\<esc>", 'tnix')
+  call assert_equal(['AA', ''], getline(1, '$'))
+  %d
+  call setline(1, 'A')
+  call cursor(1, 1)
+  call feedkeys("A\<c-x>\<c-k>\<c-s>\<cr>\<esc>", 'tnix')
+  call assert_equal(["AA\<c-s>", ''], getline(1, '$'))
+  %d
+  call setline(1, 'A')
+  call cursor(1, 1)
+  call feedkeys("A\<c-x>\<c-k>\<c-f>\<cr>\<esc>", 'tnix')
+  call assert_equal(["AA\<c-f>", ''], getline(1, '$'))
+
+  set dictionary=
+  %d
+  call setline(1, 'A')
+  call cursor(1, 1)
+  set belloff=all
+  let v:testing = 1
+  try
+    call feedkeys("A\<c-x>\<c-k>\<esc>", 'tnix')
+  catch
+    " error sleeps 2 seconds, when v:testing is not set
+    let v:testing = 0
+  endtry
+  set belloff=
+  call delete('Xdictionary.txt')
+
+  if has("multi_byte")
+    call test_override("char_avail", 1)
+    set showcmd
+    %d
+    call feedkeys("A\<c-k>a:\<esc>", 'tnix')
+    call assert_equal(['ä'], getline(1, '$'))
+    call test_override("char_avail", 0)
+    set noshowcmd
+  endif
+  bw!
+endfunc
+
+func! Test_edit_CTRL_L()
+  " Test Ctrl-X Ctrl-L (line completion)
+  new
+  set complete=.
+  call setline(1, ['one', 'two', 'three', '', '', '', ''])
+  call cursor(4, 1)
+  call feedkeys("A\<c-x>\<c-l>\<esc>", 'tnix')
+  call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
+  call feedkeys("cct\<c-x>\<c-l>\<c-n>\<esc>", 'tnix')
+  call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
+  call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<esc>", 'tnix')
+  call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
+  call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix')
+  call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$'))
+  call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix')
+  call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
+  call feedkeys("cct\<c-x>\<c-l>\<c-p>\<esc>", 'tnix')
+  call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$'))
+  call feedkeys("cct\<c-x>\<c-l>\<c-p>\<c-p>\<esc>", 'tnix')
+  call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
+  call feedkeys("cct\<c-x>\<c-l>\<c-p>\<c-p>\<c-p>\<esc>", 'tnix')
+  call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
+  set complete=
+  call cursor(5, 1)
+  call feedkeys("A\<c-x>\<c-l>\<c-p>\<c-n>\<esc>", 'tnix')
+  call assert_equal(['one', 'two', 'three', 'three', "\<c-l>\<c-p>\<c-n>", '', ''], getline(1, '$'))
+  set complete&
+  %d
+  if has("conceal") && has("syntax")
+    call setline(1, ['foo', 'bar', 'foobar'])
+    call test_override("char_avail", 1)
+    set conceallevel=2 concealcursor=n
+    syn on
+    syn match ErrorMsg "^bar"
+    call matchadd("Conceal", 'oo', 10, -1, {'conceal': 'X'})
+    func! DoIt()
+      let g:change=1
+    endfunc
+    au! TextChangedI <buffer> :call DoIt()
+
+    call cursor(2, 1)
+    call assert_false(exists("g:change"))
+    call feedkeys("A \<esc>", 'tnix')
+    call assert_equal(['foo', 'bar ', 'foobar'], getline(1, '$'))
+    call assert_equal(1, g:change)
+
+    call test_override("char_avail", 0)
+    call clearmatches()
+    syn off
+    au! TextChangedI
+    delfu DoIt
+    unlet! g:change
+  endif
+  bw!
+endfunc
+
+func! Test_edit_CTRL_N()
+  " Check keyword completion
+  new
+  set complete=.
+  call setline(1, ['INFER', 'loWER', '', '', ])
+  call cursor(3, 1)
+  call feedkeys("Ai\<c-n>\<cr>\<esc>", "tnix")
+  call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix')
+  call assert_equal(['INFER', 'loWER', 'i', 'LO', '', ''], getline(1, '$'))
+  %d
+  call setline(1, ['INFER', 'loWER', '', '', ])
+  call cursor(3, 1)
+  set ignorecase infercase
+  call feedkeys("Ii\<c-n>\<cr>\<esc>", "tnix")
+  call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix')
+  call assert_equal(['INFER', 'loWER', 'infer', 'LOWER', '', ''], getline(1, '$'))
+
+  set noignorecase noinfercase complete&
+  bw!
+endfunc
+
+func! Test_edit_CTRL_O()
+  " Check for CTRL-O in insert mode
+  new
+  inoreabbr <buffer> h here some more
+  call setline(1, ['abc', 'def'])
+  call cursor(1, 1)
+  " Ctrl-O after an abbreviation
+  exe "norm A h\<c-o>:set nu\<cr> text"
+  call assert_equal(['abc here some more text', 'def'], getline(1, '$'))
+  call assert_true(&nu)
+  set nonu
+  iunabbr <buffer> h
+  " Ctrl-O at end of line with 've'=onemore
+  call cursor(1, 1)
+  call feedkeys("A\<c-o>:let g:a=getpos('.')\<cr>\<esc>", 'tnix')
+  call assert_equal([0, 1, 23, 0], g:a)
+  call cursor(1, 1)
+  set ve=onemore
+  call feedkeys("A\<c-o>:let g:a=getpos('.')\<cr>\<esc>", 'tnix')
+  call assert_equal([0, 1, 24, 0], g:a)
+  set ve=
+  unlet! g:a
+  bw!
+endfunc
+
+func! Test_edit_CTRL_R()
+  " Insert Register
+  new
+  call test_override("ALL", 1)
+  set showcmd
+  call feedkeys("AFOOBAR eins zwei\<esc>", 'tnix')
+  call feedkeys("O\<c-r>.", 'tnix')
+  call feedkeys("O\<c-r>=10*500\<cr>\<esc>", 'tnix')
+  call feedkeys("O\<c-r>=getreg('=', 1)\<cr>\<esc>", 'tnix')
+  call assert_equal(["getreg('=', 1)", '5000', "FOOBAR eins zwei", "FOOBAR eins zwei"], getline(1, '$'))
+  call test_override("ALL", 0)
+  set noshowcmd
+  bw!
+endfunc
+
+func! Test_edit_CTRL_S()
+  " Test pressing CTRL-S (basically only spellfile completion)
+  " the rest is already covered
+  new
+  if !has("spell")
+    call setline(1, 'vim')
+    call feedkeys("A\<c-x>ss\<cr>\<esc>", 'tnix')
+    call assert_equal(['vims', ''], getline(1, '$'))
+    bw!
+    return
+  endif
+  call setline(1, 'vim')
+  " spell option not yet set
+  try
+    call feedkeys("A\<c-x>\<c-s>\<cr>\<esc>", 'tnix')
+  catch /^Vim\%((\a\+)\)\=:E756/
+    call assert_true(1, 'error caught')
+  endtry
+  call assert_equal(['vim', ''], getline(1, '$'))
+  %d
+  setl spell spelllang=en
+  call setline(1, 'vim')
+  call cursor(1, 1)
+  call feedkeys("A\<c-x>\<c-s>\<cr>\<esc>", 'tnix')
+  call assert_equal(['Vim', ''], getline(1, '$'))
+  %d
+  call setline(1, 'vim')
+  call cursor(1, 1)
+  call feedkeys("A\<c-x>\<c-s>\<down>\<cr>\<esc>", 'tnix')
+  call assert_equal(['Aim'], getline(1, '$'))
+  %d
+  call setline(1, 'vim')
+  call cursor(1, 1)
+  call feedkeys("A\<c-x>\<c-s>\<c-p>\<cr>\<esc>", 'tnix')
+  call assert_equal(['vim', ''], getline(1, '$'))
+  %d
+  " empty buffer
+  call cursor(1, 1)
+  call feedkeys("A\<c-x>\<c-s>\<c-p>\<cr>\<esc>", 'tnix')
+  call assert_equal(['', ''], getline(1, '$'))
+  setl nospell
+  bw!
+endfunc
+
+func! Test_edit_CTRL_T()
+  " Check for CTRL-T and CTRL-X CTRL-T in insert mode
+  " 1) increase indent
+  new
+  call setline(1, "abc")
+  call cursor(1, 1)
+  call feedkeys("A\<c-t>xyz", 'tnix')
+  call assert_equal(["\<tab>abcxyz"], getline(1, '$'))
+  " 2) also when paste option is set
+  set paste
+  call setline(1, "abc")
+  call cursor(1, 1)
+  call feedkeys("A\<c-t>xyz", 'tnix')
+  call assert_equal(["\<tab>abcxyz"], getline(1, '$'))
+  set nopaste
+  " CTRL-X CTRL-T (thesaurus complete)
+  call writefile(['angry furious mad enraged'], 'Xthesaurus')
+  set thesaurus=Xthesaurus
+  call setline(1, 'mad')
+  call cursor(1, 1)
+  call feedkeys("A\<c-x>\<c-t>\<cr>\<esc>", 'tnix')
+  call assert_equal(['mad', ''], getline(1, '$'))
+  %d
+  call setline(1, 'mad')
+  call cursor(1, 1)
+  call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
+  call assert_equal(['angry', ''], getline(1, '$'))
+  %d
+  call setline(1, 'mad')
+  call cursor(1, 1)
+  call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
+  call assert_equal(['furious', ''], getline(1, '$'))
+  %d
+  call setline(1, 'mad')
+  call cursor(1, 1)
+  call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
+  call assert_equal(['enraged', ''], getline(1, '$'))
+  %d
+  call setline(1, 'mad')
+  call cursor(1, 1)
+  call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
+  call assert_equal(['mad', ''], getline(1, '$'))
+  %d
+  call setline(1, 'mad')
+  call cursor(1, 1)
+  call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
+  call assert_equal(['mad', ''], getline(1, '$'))
+  " Using <c-p> <c-n> when 'complete' is empty
+  set complete=
+  %d
+  call setline(1, 'mad')
+  call cursor(1, 1)
+  call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
+  call assert_equal(['angry', ''], getline(1, '$'))
+  %d
+  call setline(1, 'mad')
+  call cursor(1, 1)
+  call feedkeys("A\<c-x>\<c-t>\<c-p>\<cr>\<esc>", 'tnix')
+  call assert_equal(['mad', ''], getline(1, '$'))
+  set complete&
+
+  set thesaurus=
+  %d
+  call setline(1, 'mad')
+  call cursor(1, 1)
+  set belloff=all
+  let v:testing = 1
+  try
+    call feedkeys("A\<c-x>\<c-t>\<esc>", 'tnix')
+  catch
+    " error sleeps 2 seconds, when v:testing is not set
+    let v:testing = 0
+  endtry
+  set belloff=
+  call assert_equal(['mad'], getline(1, '$'))
+  call delete('Xthesaurus')
+  bw!
+endfunc
+
+func! Test_edit_CTRL_U()
+  " Test 'completefunc'
+  new
+  " -1, -2 and -3 are special return values
+  let g:special=0
+  fun! CompleteMonths(findstart, base)
+    if a:findstart
+      " locate the start of the word
+      return g:special
+    else
+      " find months matching with "a:base"
+      let res = []
+      for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")
+        if m =~ '^\c'.a:base
+          call add(res, {'word': m, 'abbr': m.' Month', 'icase': 0})
+        endif
+      endfor
+      return {'words': res, 'refresh': 'always'}
+    endif
+  endfun
+  set completefunc=CompleteMonths
+  call setline(1, ['', ''])
+  call cursor(1, 1)
+  call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
+  call assert_equal(['X', '', ''], getline(1, '$'))
+  %d
+  let g:special=-1
+  call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
+  call assert_equal(['XJan', ''], getline(1, '$'))
+  %d
+  let g:special=-2
+  call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
+  call assert_equal(['X', ''], getline(1, '$'))
+  %d
+  let g:special=-3
+  call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
+  call assert_equal(['X', ''], getline(1, '$'))
+  %d
+  let g:special=0
+  call feedkeys("AM\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
+  call assert_equal(['Mar', ''], getline(1, '$'))
+  %d
+  call feedkeys("AM\<c-x>\<c-u>\<c-n>\<cr>\<esc>", 'tnix')
+  call assert_equal(['May', ''], getline(1, '$'))
+  %d
+  call feedkeys("AM\<c-x>\<c-u>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
+  call assert_equal(['M', ''], getline(1, '$'))
+  delfu CompleteMonths
+  %d
+  try
+    call feedkeys("A\<c-x>\<c-u>", 'tnix')
+    call assert_fails(1, 'unknown completion function')
+  catch /^Vim\%((\a\+)\)\=:E117/
+    call assert_true(1, 'E117 error caught')
+  endtry
+  set completefunc=
+  bw!
+endfunc
+
+func! Test_edit_CTRL_Z()
+  " Ctrl-Z when insertmode is not set inserts it literally
+  new
+  call setline(1, 'abc')
+  call feedkeys("A\<c-z>\<esc>", 'tnix')
+  call assert_equal(["abc\<c-z>"], getline(1,'$'))
+  bw!
+  " TODO: How to Test Ctrl-Z in insert mode, e.g. suspend?
+endfunc
+
+func! Test_edit_DROP()
+  if !has("dnd")
+    return
+  endif
+  new
+  call setline(1, ['abc def ghi'])
+  call cursor(1, 1)
+  try
+    call feedkeys("i\<Drop>\<Esc>", 'tnix')
+    call assert_fails(1, 'Invalid register name')
+  catch /^Vim\%((\a\+)\)\=:E353/
+    call assert_true(1, 'error caught')
+  endtry
+  bw!
+endfunc
+
+func! Test_edit_CTRL_V()
+  if has("ebcdic")
+    return
+  endif
+  new
+  call setline(1, ['abc'])
+  call cursor(2, 1)
+  " force some redraws
+  set showmode showcmd
+  "call test_override_char_avail(1)
+  call test_override('ALL', 1)
+  call feedkeys("A\<c-v>\<c-n>\<c-v>\<c-l>\<c-v>\<c-b>\<esc>", 'tnix')
+  call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$'))
+
+  if has("rightleft") && exists("+rl")
+    set rl
+    call setline(1, ['abc'])
+    call cursor(2, 1)
+    call feedkeys("A\<c-v>\<c-n>\<c-v>\<c-l>\<c-v>\<c-b>\<esc>", 'tnix')
+    call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$'))
+    set norl
+  endif
+
+  call test_override('ALL', 0)
+  set noshowmode showcmd
+  bw!
+endfunc
+
+func! Test_edit_F1()
+  " Pressing <f1>
+  new
+  call feedkeys(":set im\<cr>\<f1>\<c-l>", 'tnix')
+  set noinsertmode
+  call assert_equal('help', &buftype)
+  bw
+  bw
+endfunc
+
+func! Test_edit_F21()
+  " Pressing <f21>
+  " sends a netbeans command
+  if has("netbeans_intg")
+    new
+    " I have no idea what this is supposed to do :)
+    call feedkeys("A\<F21>\<F1>\<esc>", 'tnix')
+    bw
+  endif
+endfunc
+
+func! Test_edit_HOME_END()
+  " Test Home/End Keys
+  new
+  set foldopen+=hor
+  call setline(1, ['abc', 'def'])
+  call cursor(1, 1)
+  call feedkeys("AX\<Home>Y\<esc>", 'tnix')
+  call cursor(2, 1)
+  call feedkeys("iZ\<End>Y\<esc>", 'tnix')
+  call assert_equal(['YabcX', 'ZdefY'], getline(1, '$'))
+
+  set foldopen-=hor
+  bw!
+endfunc
+
+func! Test_edit_INS()
+  " Test for Pressing <Insert>
+  new
+  call setline(1, ['abc', 'def'])
+  call cursor(1, 1)
+  call feedkeys("i\<Insert>ZYX>", 'tnix')
+  call assert_equal(['ZYX>', 'def'], getline(1, '$'))
+  call setline(1, ['abc', 'def'])
+  call cursor(1, 1)
+  call feedkeys("i\<Insert>Z\<Insert>YX>", 'tnix')
+  call assert_equal(['ZYX>bc', 'def'], getline(1, '$'))
+  bw!
+endfunc
+
+func! Test_edit_LEFT_RIGHT()
+  " Left, Shift-Left, Right, Shift-Right
+  new
+  set belloff=all
+  call setline(1, ['abc def ghi', 'ABC DEF GHI', 'ZZZ YYY XXX'])
+  let _ww=&ww
+  set ww=
+  call cursor(2, 1)
+  call feedkeys("i\<left>\<esc>", 'tnix')
+  call assert_equal([0, 2, 1, 0], getpos('.'))
+  " Is this a bug, <s-left> does not respect whichwrap option
+  call feedkeys("i\<s-left>\<esc>", 'tnix')
+  call assert_equal([0, 1, 8, 0], getpos('.'))
+  call feedkeys("i". repeat("\<s-left>", 3). "\<esc>", 'tnix')
+  call assert_equal([0, 1, 1, 0], getpos('.'))
+  call feedkeys("i\<right>\<esc>", 'tnix')
+  call assert_equal([0, 1, 1, 0], getpos('.'))
+  call feedkeys("i\<right>\<right>\<esc>", 'tnix')
+  call assert_equal([0, 1, 2, 0], getpos('.'))
+  call feedkeys("A\<right>\<esc>", 'tnix')
+  call assert_equal([0, 1, 11, 0], getpos('.'))
+  call feedkeys("A\<s-right>\<esc>", 'tnix')
+  call assert_equal([0, 2, 1, 0], getpos('.'))
+  call feedkeys("i\<s-right>\<esc>", 'tnix')
+  call assert_equal([0, 2, 4, 0], getpos('.'))
+  call cursor(3, 11)
+  call feedkeys("A\<right>\<esc>", 'tnix')
+  call feedkeys("A\<s-right>\<esc>", 'tnix')
+  call assert_equal([0, 3, 11, 0], getpos('.'))
+  call cursor(2, 11)
+  " <S-Right> does not respect 'whichwrap' option
+  call feedkeys("A\<s-right>\<esc>", 'tnix')
+  call assert_equal([0, 3, 1, 0], getpos('.'))
+  " Check motion when 'whichwrap' contains cursor keys for insert mode
+  set ww+=[,]
+  call cursor(2, 1)
+  call feedkeys("i\<left>\<esc>", 'tnix')
+  call assert_equal([0, 1, 11, 0], getpos('.'))
+  call cursor(2, 11)
+  call feedkeys("A\<right>\<esc>", 'tnix')
+  call assert_equal([0, 3, 1, 0], getpos('.'))
+  call cursor(2, 11)
+  call feedkeys("A\<s-right>\<esc>", 'tnix')
+  call assert_equal([0, 3, 1, 0], getpos('.'))
+  let &ww = _ww
+  set belloff=
+  bw!
+endfunc
+
+func! Test_edit_MOUSE()
+  " This is a simple test, since we not really using the mouse here
+  if !has("mouse")
+    return
+  endif
+  10new
+  call setline(1, range(1, 100))
+  call cursor(1, 1)
+  set mouse=a
+  call feedkeys("A\<ScrollWheelDown>\<esc>", 'tnix')
+  call assert_equal([0, 4, 1, 0], getpos('.'))
+  " This should move by one pageDown, but only moves
+  " by one line when the test is run...
+  call feedkeys("A\<S-ScrollWheelDown>\<esc>", 'tnix')
+  call assert_equal([0, 5, 1, 0], getpos('.'))
+  set nostartofline
+  call feedkeys("A\<C-ScrollWheelDown>\<esc>", 'tnix')
+  call assert_equal([0, 6, 1, 0], getpos('.'))
+  call feedkeys("A\<LeftMouse>\<esc>", 'tnix')
+  call assert_equal([0, 6, 1, 0], getpos('.'))
+  call feedkeys("A\<RightMouse>\<esc>", 'tnix')
+  call assert_equal([0, 6, 1, 0], getpos('.'))
+  call cursor(1, 100)
+  norm! zt
+  " this should move by a screen up, but when the test
+  " is run, it moves up to the top of the buffer...
+  call feedkeys("A\<ScrollWheelUp>\<esc>", 'tnix')
+  call assert_equal([0, 1, 1, 0], getpos('.'))
+  call cursor(1, 30)
+  norm! zt
+  call feedkeys("A\<S-ScrollWheelUp>\<esc>", 'tnix')
+  call assert_equal([0, 1, 1, 0], getpos('.'))
+  call cursor(1, 30)
+  norm! zt
+  call feedkeys("A\<C-ScrollWheelUp>\<esc>", 'tnix')
+  call assert_equal([0, 1, 1, 0], getpos('.'))
+  %d
+  call setline(1, repeat(["12345678901234567890"], 100))
+  call cursor(2, 1)
+  call feedkeys("A\<ScrollWheelRight>\<esc>", 'tnix')
+  call assert_equal([0, 2, 20, 0], getpos('.'))
+  call feedkeys("A\<ScrollWheelLeft>\<esc>", 'tnix')
+  call assert_equal([0, 2, 20, 0], getpos('.'))
+  call feedkeys("A\<S-ScrollWheelRight>\<esc>", 'tnix')
+  call assert_equal([0, 2, 20, 0], getpos('.'))
+  call feedkeys("A\<S-ScrollWheelLeft>\<esc>", 'tnix')
+  call assert_equal([0, 2, 20, 0], getpos('.'))
+  call feedkeys("A\<C-ScrollWheelRight>\<esc>", 'tnix')
+  call assert_equal([0, 2, 20, 0], getpos('.'))
+  call feedkeys("A\<C-ScrollWheelLeft>\<esc>", 'tnix')
+  call assert_equal([0, 2, 20, 0], getpos('.'))
+  set mouse& startofline
+  bw!
+endfunc
+
+func! Test_edit_PAGEUP_PAGEDOWN()
+  set belloff=all
+  10new
+  call setline(1, repeat(['abc def ghi'], 30))
+  call cursor(1, 1)
+  call feedkeys("i\<PageDown>\<esc>", 'tnix')
+  call assert_equal([0, 9, 1, 0], getpos('.'))
+  call feedkeys("i\<PageDown>\<esc>", 'tnix')
+  call assert_equal([0, 17, 1, 0], getpos('.'))
+  call feedkeys("i\<PageDown>\<esc>", 'tnix')
+  call assert_equal([0, 25, 1, 0], getpos('.'))
+  call feedkeys("i\<PageDown>\<esc>", 'tnix')
+  call assert_equal([0, 30, 1, 0], getpos('.'))
+  call feedkeys("i\<PageDown>\<esc>", 'tnix')
+  call assert_equal([0, 30, 1, 0], getpos('.'))
+  call feedkeys("A\<PageUp>\<esc>", 'tnix')
+  call assert_equal([0, 29, 1, 0], getpos('.'))
+  call feedkeys("A\<PageUp>\<esc>", 'tnix')
+  call assert_equal([0, 21, 1, 0], getpos('.'))
+  call feedkeys("A\<PageUp>\<esc>", 'tnix')
+  call assert_equal([0, 13, 1, 0], getpos('.'))
+  call feedkeys("A\<PageUp>\<esc>", 'tnix')
+  call assert_equal([0, 5, 1, 0], getpos('.'))
+  call feedkeys("A\<PageUp>\<esc>", 'tnix')
+  call assert_equal([0, 5, 11, 0], getpos('.'))
+  " <S-Up> is the same as <PageUp>
+  " <S-Down> is the same as <PageDown>
+  call cursor(1, 1)
+  call feedkeys("i\<S-Down>\<esc>", 'tnix')
+  call assert_equal([0, 9, 1, 0], getpos('.'))
+  call feedkeys("i\<S-Down>\<esc>", 'tnix')
+  call assert_equal([0, 17, 1, 0], getpos('.'))
+  call feedkeys("i\<S-Down>\<esc>", 'tnix')
+  call assert_equal([0, 25, 1, 0], getpos('.'))
+  call feedkeys("i\<S-Down>\<esc>", 'tnix')
+  call assert_equal([0, 30, 1, 0], getpos('.'))
+  call feedkeys("i\<S-Down>\<esc>", 'tnix')
+  call assert_equal([0, 30, 1, 0], getpos('.'))
+  call feedkeys("A\<S-Up>\<esc>", 'tnix')
+  call assert_equal([0, 29, 1, 0], getpos('.'))
+  call feedkeys("A\<S-Up>\<esc>", 'tnix')
+  call assert_equal([0, 21, 1, 0], getpos('.'))
+  call feedkeys("A\<S-Up>\<esc>", 'tnix')
+  call assert_equal([0, 13, 1, 0], getpos('.'))
+  call feedkeys("A\<S-Up>\<esc>", 'tnix')
+  call assert_equal([0, 5, 1, 0], getpos('.'))
+  call feedkeys("A\<S-Up>\<esc>", 'tnix')
+  call assert_equal([0, 5, 11, 0], getpos('.'))
+  set nostartofline
+  call cursor(30, 11)
+  norm! zt
+  call feedkeys("A\<PageUp>\<esc>", 'tnix')
+  call assert_equal([0, 29, 11, 0], getpos('.'))
+  call feedkeys("A\<PageUp>\<esc>", 'tnix')
+  call assert_equal([0, 21, 11, 0], getpos('.'))
+  call feedkeys("A\<PageUp>\<esc>", 'tnix')
+  call assert_equal([0, 13, 11, 0], getpos('.'))
+  call feedkeys("A\<PageUp>\<esc>", 'tnix')
+  call assert_equal([0, 5, 11, 0], getpos('.'))
+  call feedkeys("A\<PageUp>\<esc>", 'tnix')
+  call assert_equal([0, 5, 11, 0], getpos('.'))
+  call cursor(1, 1)
+  call feedkeys("A\<PageDown>\<esc>", 'tnix')
+  call assert_equal([0, 9, 11, 0], getpos('.'))
+  call feedkeys("A\<PageDown>\<esc>", 'tnix')
+  call assert_equal([0, 17, 11, 0], getpos('.'))
+  call feedkeys("A\<PageDown>\<esc>", 'tnix')
+  call assert_equal([0, 25, 11, 0], getpos('.'))
+  call feedkeys("A\<PageDown>\<esc>", 'tnix')
+  call assert_equal([0, 30, 11, 0], getpos('.'))
+  call feedkeys("A\<PageDown>\<esc>", 'tnix')
+  call assert_equal([0, 30, 11, 0], getpos('.'))
+  " <S-Up> is the same as <PageUp>
+  " <S-Down> is the same as <PageDown>
+  call cursor(30, 11)
+  norm! zt
+  call feedkeys("A\<S-Up>\<esc>", 'tnix')
+  call assert_equal([0, 29, 11, 0], getpos('.'))
+  call feedkeys("A\<S-Up>\<esc>", 'tnix')
+  call assert_equal([0, 21, 11, 0], getpos('.'))
+  call feedkeys("A\<S-Up>\<esc>", 'tnix')
+  call assert_equal([0, 13, 11, 0], getpos('.'))
+  call feedkeys("A\<S-Up>\<esc>", 'tnix')
+  call assert_equal([0, 5, 11, 0], getpos('.'))
+  call feedkeys("A\<S-Up>\<esc>", 'tnix')
+  call assert_equal([0, 5, 11, 0], getpos('.'))
+  call cursor(1, 1)
+  call feedkeys("A\<S-Down>\<esc>", 'tnix')
+  call assert_equal([0, 9, 11, 0], getpos('.'))
+  call feedkeys("A\<S-Down>\<esc>", 'tnix')
+  call assert_equal([0, 17, 11, 0], getpos('.'))
+  call feedkeys("A\<S-Down>\<esc>", 'tnix')
+  call assert_equal([0, 25, 11, 0], getpos('.'))
+  call feedkeys("A\<S-Down>\<esc>", 'tnix')
+  call assert_equal([0, 30, 11, 0], getpos('.'))
+  call feedkeys("A\<S-Down>\<esc>", 'tnix')
+  call assert_equal([0, 30, 11, 0], getpos('.'))
+  set startofline belloff=
+  bw!
+endfunc
+
+func! Test_edit_forbidden()
+  set belloff=error,esc
+  new
+  " 1) edit in the sandbox is not allowed
+  call setline(1, 'a')
+  com! Sandbox :sandbox call feedkeys("i\<del>\<esc>", 'tnix')
+  call assert_fails(':Sandbox', 'E48:')
+  com! Sandbox :sandbox exe "norm! i\<del>"
+  call assert_fails(':Sandbox', 'E48:')
+  delcom Sandbox
+  call assert_equal(['a'], getline(1,'$'))
+  " 2) edit with textlock set
+  fu! DoIt()
+    call feedkeys("i\<del>\<esc>", 'tnix')
+  endfu
+  au InsertCharPre <buffer> :call DoIt()
+  try
+    call feedkeys("ix\<esc>", 'tnix')
+    call assert_fails(1, 'textlock')
+  catch /^Vim\%((\a\+)\)\=:E523/ " catch E523: not allowed here
+  endtry
+  " TODO: Might be a bug: should x really be inserted here
+  call assert_equal(['xa'], getline(1, '$'))
+  delfu DoIt
+  try
+    call feedkeys("ix\<esc>", 'tnix')
+    call assert_fails(1, 'unknown function')
+  catch /^Vim\%((\a\+)\)\=:E117/ " catch E117: unknown function
+  endtry
+  au! InsertCharPre
+  " 3) edit when completion is shown
+  fun! Complete(findstart, base)
+    if a:findstart
+      return col('.')
+    else
+      call feedkeys("i\<del>\<esc>", 'tnix')
+      return []
+    endif
+  endfun
+  set completefunc=Complete
+  try
+    call feedkeys("i\<c-x>\<c-u>\<esc>", 'tnix')
+    call assert_fails(1, 'change in complete function')
+  catch /^Vim\%((\a\+)\)\=:E523/ " catch E523
+  endtry
+  delfu Complete
+  set completefunc=
+  if has("rightleft") && exists("+fkmap")
+    " 4) 'R' when 'fkmap' and 'revins' is set.
+    set revins fkmap
+    try
+      normal Ri
+      call assert_fails(1, "R with 'fkmap' and 'ri' set")
+    catch
+    finally
+      set norevins nofkmap
+    endtry
+  endif
+  set belloff=
+  bw!
+endfunc
+
+func! Test_edit_rightleft()
+  " Cursor in rightleft mode moves differently
+  if !exists("+rightleft")
+    return
+  endif
+  call NewWindow(10, 20)
+  call setline(1, ['abc', 'def', 'ghi'])
+  call cursor(1, 2)
+  set rightleft
+  " Screen looks as expected
+  let lines = ScreenLines([1, 4], winwidth(0))
+  let expect = [
+        \"                 cba",
+        \"                 fed",
+        \"                 ihg",
+        \"                   ~"]
+  call assert_equal(join(expect, "\n"), join(lines, "\n"))
+  " 2) right moves to the left
+  call feedkeys("i\<right>\<esc>x", 'txin')
+  call assert_equal(['bc', 'def', 'ghi'], getline(1,'$'))
+  call cursor(1, 2)
+  call feedkeys("i\<s-right>\<esc>", 'txin')
+  call cursor(1, 2)
+  call feedkeys("i\<c-right>\<esc>", 'txin')
+  " Screen looks as expected
+  let lines = ScreenLines([1, 4], winwidth(0))
+  let expect = [
+        \"                  cb",
+        \"                 fed",
+        \"                 ihg",
+        \"                   ~"]
+  call assert_equal(join(expect, "\n"), join(lines, "\n"))
+  " 2) left moves to the right
+  call setline(1, ['abc', 'def', 'ghi'])
+  call cursor(1, 2)
+  call feedkeys("i\<left>\<esc>x", 'txin')
+  call assert_equal(['ac', 'def', 'ghi'], getline(1,'$'))
+  call cursor(1, 2)
+  call feedkeys("i\<s-left>\<esc>", 'txin')
+  call cursor(1, 2)
+  call feedkeys("i\<c-left>\<esc>", 'txin')
+  " Screen looks as expected
+  let lines = ScreenLines([1, 4], winwidth(0))
+  let expect = [
+        \"                  ca",
+        \"                 fed",
+        \"                 ihg",
+        \"                   ~"]
+  call assert_equal(join(expect, "\n"), join(lines, "\n"))
+  set norightleft
+  bw!
+endfunc
+
+func Test_edit_complete_very_long_name()
+  if !has('unix')
+    " Long directory names only work on Unix.
+    return
+  endif
+
+  let dirname = getcwd() . "/Xdir"
+  let longdirname = dirname . repeat('/' . repeat('d', 255), 4)
+  try
+    call mkdir(longdirname, 'p')
+  catch /E739:/
+    " Long directory name probably not supported.
+    call delete(dirname, 'rf')
+    return
+  endtry
+
+  " Try to get the Vim window position before setting 'columns'.
+  let winposx = getwinposx()
+  let winposy = getwinposy()
+  let save_columns = &columns
+  " Need at least about 1100 columns to reproduce the problem.
+  set columns=2000
+  call assert_equal(2000, &columns)
+  set noswapfile
+
+  let longfilename = longdirname . '/' . repeat('a', 255)
+  call writefile(['Totum', 'Table'], longfilename)
+  new
+  exe "next Xfile " . longfilename
+  exe "normal iT\<C-N>"
+
+  bwipe!
+  exe 'bwipe! ' . longfilename
+  call delete(dirname, 'rf')
+  let &columns = save_columns
+  if winposx >= 0 && winposy >= 0
+    exe 'winpos ' . winposx . ' ' . winposy
+  endif
+  set swapfile&
+endfunc
index 1ddcd3c..36dd232 100644 (file)
@@ -2,6 +2,7 @@ Test for erasing backword
 
 STARTTEST
 :so small.vim
+:set belloff=all
 :so mbyte.vim
 :set encoding=utf-8
 G
diff --git a/src/testdir/test_ex_z.vim b/src/testdir/test_ex_z.vim
new file mode 100644 (file)
index 0000000..6e03b0b
--- /dev/null
@@ -0,0 +1,85 @@
+" Test :z
+
+func Test_z()
+  call setline(1, range(1, 100))
+
+  let a = execute('20z3')
+  call assert_equal("\n20\n21\n22", a)
+  call assert_equal(22, line('.'))
+  " 'window' should be set to the {count} value.
+  call assert_equal(3, &window)
+
+  " If there is only one window, then twice the amount of 'scroll' is used.
+  set scroll=2
+  let a = execute('20z')
+  call assert_equal("\n20\n21\n22\n23", a)
+  call assert_equal(23, line('.'))
+
+  let a = execute('20z+3')
+  " FIXME: I would expect the same result as '20z3' but it
+  " gives "\n21\n22\n23" instead. Bug in Vim or in ":help :z"?
+  "call assert_equal("\n20\n21\n22", a)
+  "call assert_equal(22, line('.'))
+
+  let a = execute('20z-3')
+  call assert_equal("\n18\n19\n20", a)
+  call assert_equal(20, line('.'))
+
+  let a = execute('20z=3')
+  call assert_match("^\n18\n19\n-\\+\n20\n-\\+\n21\n22$", a)
+  call assert_equal(20, line('.'))
+
+  let a = execute('20z^3')
+  call assert_equal("\n14\n15\n16\n17", a)
+  call assert_equal(17, line('.'))
+
+  let a = execute('20z.3')
+  call assert_equal("\n19\n20\n21", a)
+  call assert_equal(21, line('.'))
+
+  let a = execute('20z#3')
+  call assert_equal("\n 20 20\n 21 21\n 22 22", a)
+  call assert_equal(22, line('.'))
+
+  let a = execute('20z#-3')
+  call assert_equal("\n 18 18\n 19 19\n 20 20", a)
+  call assert_equal(20, line('.'))
+
+  let a = execute('20z#=3')
+  call assert_match("^\n 18 18\n 19 19\n-\\+\n 20 20\n-\\+\n 21 21\n 22 22$", a)
+  call assert_equal(20, line('.'))
+
+  " Test with {count} bigger than the number of lines in buffer.
+  let a = execute('20z1000')
+  call assert_match("^\n20\n21\n.*\n99\n100$", a)
+  call assert_equal(100, line('.'))
+
+  let a = execute('20z-1000')
+  call assert_match("^\n1\n2\n.*\n19\n20$", a)
+  call assert_equal(20, line('.'))
+
+  let a = execute('20z=1000')
+  call assert_match("^\n1\n.*\n-\\+\n20\n-\\\+\n.*\n100$", a)
+  call assert_equal(20, line('.'))
+
+  call assert_fails('20z=a', 'E144:')
+
+  set window& scroll&
+  bw!
+endfunc
+
+func Test_z_overflow()
+  " This used to access invalid memory as a result of an integer overflow
+  " and freeze vim.
+  normal ox
+  normal Heat
+  z777777776666666
+  ')
+endfunc
+
+func Test_z_negative_lnum()
+  new
+  z^
+  call assert_equal(1, line('.'))
+  bwipe!
+endfunc
index d8ab416..b3e099a 100644 (file)
@@ -14,7 +14,7 @@ func s:test_expand_dllpath(optname)
 endfunc
 
 func s:generate_test_if_exists(optname)
-  if exists('&' . a:optname)
+  if exists('+' . a:optname)
     execute join([
           \ 'func Test_expand_' . a:optname . '()',
           \ '  call s:test_expand_dllpath("' . a:optname . '")',
index e5c918c..c47bc22 100644 (file)
@@ -87,7 +87,7 @@ endfunc
 func Test_loop_over_null_list()
   let null_list = test_null_list()
   for i in null_list
-    call assert_true(0, 'should not get here')
+    call assert_report('should not get here')
   endfor
 endfunc
 
@@ -473,3 +473,8 @@ func Test_setmatches()
   call setmatches(set)
   call assert_equal(exp, getmatches())
 endfunc
+
+func Test_empty_concatenate()
+  call assert_equal('b', 'a'[4:0] . 'b')
+  call assert_equal('b', 'b' . 'a'[4:0])
+endfunc
index 81afce2..dcfa024 100644 (file)
@@ -1,4 +1,5 @@
 " Simplistic testing of Farsi mode.
+" Note: must be edited with latin1 encoding.
 
 if !has('farsi')
   finish
@@ -82,3 +83,51 @@ func Test_farsi_map()
   set noaltkeymap
   bwipe!
 endfunc
+
+func Test_input_farsi()
+  new
+  setlocal rightleft fkmap
+  " numbers switch input direction
+  call feedkeys("aabc0123456789.+-^%#=xyz\<Esc>", 'tx')
+  call assert_equal("\x8cÌν®¥ª­«¦¹¸·¶µ´³²±°Ô\x93Õ", getline('.'))
+
+  " all non-number special chars with spaces
+  call feedkeys("oB E F H I K L M O P Q R T U W Y ` !  @ # $ % ^ & * () - _ = + \\ | : \" .  / < > ? \<Esc>", 'tx')
+  call assert_equal("¡ ô ú À ö æ ç Â [ ] ÷ ó ò ð õ ñ ¢ £  § ® ¤ ¥ ª ¬ è ¨© ­ é ½ « ë ê º » ¦  ¯ ¾ ¼ ¿ ", getline('.'))
+
+  " all non-number special chars without spaces
+  call feedkeys("oBEFHIKLMOPQRTUWY`!@#$%^&*()-_=+\\|:\"./<>?\<Esc>",'tx')
+  call assert_equal("¡ôúÀöæçÂ[]÷óòðõñ¢£§®¤¥ª¬è¨©­é½«ë꺻¦¯¾¼¿", getline('.'))
+
+  " all letter chars with spaces
+  call feedkeys("oa A b c C d D e f g G h i j J k l m n N o p q r s S t u v V w x X y z Z ; \ , [ ] \<Esc>", 'tx')
+  call assert_equal("Ñ ù Ì Î Ï á þ Æ Ã Ü ø Á à Å ü Þ Ý Ä Ë Ë Ê É Ó Ù Ð û Ø Ö Í Í Ò Ô Ô × Õ ý Ú  ß Ç È ", getline('.'))
+
+  " all letter chars without spaces
+  call feedkeys("oaAbcCdDefgGhijJklmnNopqrsStuvVwxXyzZ;\,[]\<Esc>", 'tx')
+  call assert_equal("\x8cùÌÎÏ\x9fî\x86\x83ÜøÁ\x9d\x85\x80\x9c\x9b\x84ËË\x8a\x89\x8e\x96\x8bì\x95\x90ÍÍ\x8dÔÔ\x93Õý\x97ß\x87\x88", getline('.'))
+
+  bwipe!
+endfunc
+
+func Test_command_line_farsi()
+  set allowrevins altkeymap
+
+  " letter characters with spaces
+  call feedkeys(":\"\<C-_>a A b c C d D e f g G h i j J k l m n N o p q r s S t u v V w x X y z Z ; \\ , [ ]\<CR>", 'tx')
+  call assert_equal("\"\x88 Ç ß ë Ú Õ Õ × Ô Ô Ò Í Í Ö Ø û Ð Ù Ó É Ê Ë Ë Ä Ý Þ ü Å à Á ø Ü Ã Æ þ á Ï Î Ì ù Ñ", getreg(':'))
+  " letter characters without spaces
+  call feedkeys(":\"\<C-_>aAbcCdDefgGhijJklmnNopqrsStuvVwxXyzZ;\\,[]\<CR>", 'tx')
+  call assert_equal("\"\x88\x87ßëÚÕÕ\x93ÔÔ\x8dÍÍ\x90\x95ì\x8b\x96\x8e\x89\x8aËË\x84\x9b\x9c\x80\x85\x9dÁøÜ\x83\x86î\x9fÏÎÌù\x8c", getreg(':'))
+  " other characters with spaces
+  call feedkeys(":\"\<C-_>0 1 2 3 4 5 6 7 8 9 ` .  !  \" $ % ^ & / () = \\ ?  + - _ * : # ~ @ < > { } | B E F H I K L M O P Q R T U W Y\<CR>", 'tx')
+  call assert_equal("\"ñ õ ð ò ó ÷ ] [ Â ç æ ö À ú ô ¡ ê } { ¼ ¾ § ~ ® º è é ­ «  ¿ ë ½ ©¨ ¯ ¬ ª ¥ ¤ »  £  ¦ ¢ ¹ ¸ · ¶ µ ´ ³ ² ± °", getreg(':'))
+
+  " other characters without spaces
+  call feedkeys(":\"\<C-_>0123456789`.!\"$%^&/()=\\?+-_*:#~@<>{}|BEFHIKLMOPQRTUWY\<CR>", 'tx')
+  call assert_equal("\"ñõðòó÷][ÂçæöÀúô¡ê}{¼¾§~®ºèé­«¿ë½©¨¯¬ª¥¤»£¦¢¹¸·¶µ´³²±°", getreg(':'))
+
+  set noallowrevins noaltkeymap
+endfunc
index 584f20c..8dc25f6 100644 (file)
@@ -15,3 +15,19 @@ func Test_fileformat_after_bw()
   call assert_equal(test_fileformats, &fileformat)
   set fileformats&
 endfunc
+
+func Test_fileformat_autocommand()
+  let filecnt = ["", "foobar\<CR>", "eins\<CR>", "\<CR>", "zwei\<CR>", "drei", "vier", "fünf", ""]
+  let ffs = &ffs
+  call writefile(filecnt, 'Xfile', 'b')
+  au BufReadPre Xfile set ffs=dos ff=dos
+  new Xfile
+  call assert_equal('dos', &l:ff)
+  call assert_equal('dos', &ffs)
+
+  " cleanup
+  call delete('Xfile')
+  let &ffs = ffs
+  au! BufReadPre Xfile
+  bw!
+endfunc
index 0bbd905..5aa5fa6 100644 (file)
@@ -52,3 +52,25 @@ func Test_filter_fails()
   call assert_fails('filter! /pat/', 'E476:')
   call assert_fails('filter! /pat/ asdf', 'E492:')
 endfunc
+
+function s:complete_filter_cmd(filtcmd)
+  let keystroke = "\<TAB>\<C-R>=execute('let cmdline = getcmdline()')\<CR>\<C-C>"
+  let cmdline = ''
+  call feedkeys(':' . a:filtcmd . keystroke, 'ntx')
+  return cmdline
+endfunction
+
+func Test_filter_cmd_completion()
+  " Do not complete pattern
+  call assert_equal("filter \t", s:complete_filter_cmd('filter '))
+  call assert_equal("filter pat\t", s:complete_filter_cmd('filter pat'))
+  call assert_equal("filter /pat\t", s:complete_filter_cmd('filter /pat'))
+  call assert_equal("filter /pat/\t", s:complete_filter_cmd('filter /pat/'))
+
+  " Complete after string pattern
+  call assert_equal('filter pat print', s:complete_filter_cmd('filter pat pri'))
+
+  " Complete after regexp pattern
+  call assert_equal('filter /pat/ print', s:complete_filter_cmd('filter /pat/ pri'))
+  call assert_equal('filter #pat# print', s:complete_filter_cmd('filter #pat# pri'))
+endfunc
diff --git a/src/testdir/test_findfile.vim b/src/testdir/test_findfile.vim
new file mode 100644 (file)
index 0000000..85e5cd2
--- /dev/null
@@ -0,0 +1,25 @@
+" Test for findfile()
+"
+func Test_findfile()
+  new
+  let cwd=getcwd()
+  cd ..
+
+  " Tests may be run from a shadow directory, so an extra cd needs to be done to
+  " get above src/
+  if fnamemodify(getcwd(), ':t') != 'src'
+    cd ../.. 
+  else 
+    cd .. 
+  endif
+  set ssl
+
+  call assert_equal('src/testdir/test_findfile.vim', findfile('test_findfile.vim','src/test*'))
+  exe "cd" cwd
+  cd ..
+  call assert_equal('testdir/test_findfile.vim', findfile('test_findfile.vim','test*'))
+  call assert_equal('testdir/test_findfile.vim', findfile('test_findfile.vim','testdir'))
+
+  exe "cd" cwd
+  q!
+endfunc
diff --git a/src/testdir/test_float_func.vim b/src/testdir/test_float_func.vim
new file mode 100644 (file)
index 0000000..de5de65
--- /dev/null
@@ -0,0 +1,284 @@
+" test float functions
+
+if !has('float')
+  finish
+end
+
+func Test_abs()
+  call assert_equal('1.23', string(abs(1.23)))
+  call assert_equal('1.23', string(abs(-1.23)))
+  call assert_equal('0.0', string(abs(0.0)))
+  call assert_equal('0.0', string(abs(1.0/(1.0/0.0))))
+  call assert_equal('0.0', string(abs(-1.0/(1.0/0.0))))
+  call assert_equal('inf', string(abs(1.0/0.0)))
+  call assert_equal('inf', string(abs(-1.0/0.0)))
+  call assert_equal('nan', string(abs(0.0/0.0)))
+  call assert_equal('12', string(abs('-12abc')))
+  call assert_fails("call abs([])", 'E745:')
+  call assert_fails("call abs({})", 'E728:')
+  call assert_fails("call abs(function('string'))", 'E703:')
+endfunc
+
+func Test_sqrt()
+  call assert_equal('0.0', string(sqrt(0.0)))
+  call assert_equal('1.414214', string(sqrt(2.0)))
+  call assert_equal('inf', string(sqrt(1.0/0.0)))
+  call assert_equal('nan', string(sqrt(-1.0)))
+  call assert_equal('nan', string(sqrt(0.0/0.0)))
+  call assert_fails('call sqrt("")', 'E808:')
+endfunc
+
+func Test_log()
+  call assert_equal('0.0', string(log(1.0)))
+  call assert_equal('-0.693147', string(log(0.5)))
+  call assert_equal('-inf', string(log(0.0)))
+  call assert_equal('nan', string(log(-1.0)))
+  call assert_equal('inf', string(log(1.0/0.0)))
+  call assert_equal('nan', string(log(0.0/0.0)))
+  call assert_fails('call log("")', 'E808:')
+endfunc
+
+func Test_log10()
+  call assert_equal('0.0', string(log10(1.0)))
+  call assert_equal('2.0', string(log10(100.0)))
+  call assert_equal('2.079181', string(log10(120.0)))
+  call assert_equal('-inf', string(log10(0.0)))
+  call assert_equal('nan', string(log10(-1.0)))
+  call assert_equal('inf', string(log10(1.0/0.0)))
+  call assert_equal('nan', string(log10(0.0/0.0)))
+  call assert_fails('call log10("")', 'E808:')
+endfunc
+
+func Test_exp()
+  call assert_equal('1.0', string(exp(0.0)))
+  call assert_equal('7.389056', string(exp(2.0)))
+  call assert_equal('0.367879', string(exp(-1.0)))
+  call assert_equal('inf', string(exp(1.0/0.0)))
+  call assert_equal('0.0', string(exp(-1.0/0.0)))
+  call assert_equal('nan', string(exp(0.0/0.0)))
+  call assert_fails('call exp("")', 'E808:')
+endfunc
+
+func Test_sin()
+  call assert_equal('0.0', string(sin(0.0)))
+  call assert_equal('0.841471', string(sin(1.0)))
+  call assert_equal('-0.479426', string(sin(-0.5)))
+  call assert_equal('nan', string(sin(0.0/0.0)))
+  call assert_equal('nan', string(sin(1.0/0.0)))
+  call assert_equal('0.0', string(sin(1.0/(1.0/0.0))))
+  call assert_equal('-0.0', string(sin(-1.0/(1.0/0.0))))
+  call assert_fails('call sin("")', 'E808:')
+endfunc
+
+func Test_asin()
+  call assert_equal('0.0', string(asin(0.0)))
+  call assert_equal('1.570796', string(asin(1.0)))
+  call assert_equal('-0.523599', string(asin(-0.5)))
+  call assert_equal('nan', string(asin(1.1)))
+  call assert_equal('nan', string(asin(1.0/0.0)))
+  call assert_equal('nan', string(asin(0.0/0.0)))
+  call assert_fails('call asin("")', 'E808:')
+endfunc
+
+func Test_sinh()
+  call assert_equal('0.0', string(sinh(0.0)))
+  call assert_equal('0.521095', string(sinh(0.5)))
+  call assert_equal('-1.026517', string(sinh(-0.9)))
+  call assert_equal('inf', string(sinh(1.0/0.0)))
+  call assert_equal('-inf', string(sinh(-1.0/0.0)))
+  call assert_equal('nan', string(sinh(0.0/0.0)))
+  call assert_fails('call sinh("")', 'E808:')
+endfunc
+
+func Test_cos()
+  call assert_equal('1.0', string(cos(0.0)))
+  call assert_equal('0.540302', string(cos(1.0)))
+  call assert_equal('0.877583', string(cos(-0.5)))
+  call assert_equal('nan', string(cos(0.0/0.0)))
+  call assert_equal('nan', string(cos(1.0/0.0)))
+  call assert_fails('call cos("")', 'E808:')
+endfunc
+
+func Test_acos()
+  call assert_equal('1.570796', string(acos(0.0)))
+  call assert_equal('0.0', string(acos(1.0)))
+  call assert_equal('3.141593', string(acos(-1.0)))
+  call assert_equal('2.094395', string(acos(-0.5)))
+  call assert_equal('nan', string(acos(1.1)))
+  call assert_equal('nan', string(acos(1.0/0.0)))
+  call assert_equal('nan', string(acos(0.0/0.0)))
+  call assert_fails('call acos("")', 'E808:')
+endfunc
+
+func Test_cosh()
+  call assert_equal('1.0', string(cosh(0.0)))
+  call assert_equal('1.127626', string(cosh(0.5)))
+  call assert_equal('inf', string(cosh(1.0/0.0)))
+  call assert_equal('inf', string(cosh(-1.0/0.0)))
+  call assert_equal('nan', string(cosh(0.0/0.0)))
+  call assert_fails('call cosh("")', 'E808:')
+endfunc
+
+func Test_tan()
+  call assert_equal('0.0', string(tan(0.0)))
+  call assert_equal('0.546302', string(tan(0.5)))
+  call assert_equal('-0.546302', string(tan(-0.5)))
+  call assert_equal('nan', string(tan(1.0/0.0)))
+  call assert_equal('nan', string(cos(0.0/0.0)))
+  call assert_equal('0.0', string(tan(1.0/(1.0/0.0))))
+  call assert_equal('-0.0', string(tan(-1.0/(1.0/0.0))))
+  call assert_fails('call tan("")', 'E808:')
+endfunc
+
+func Test_atan()
+  call assert_equal('0.0', string(atan(0.0)))
+  call assert_equal('0.463648', string(atan(0.5)))
+  call assert_equal('-0.785398', string(atan(-1.0)))
+  call assert_equal('1.570796', string(atan(1.0/0.0)))
+  call assert_equal('-1.570796', string(atan(-1.0/0.0)))
+  call assert_equal('nan', string(atan(0.0/0.0)))
+  call assert_fails('call atan("")', 'E808:')
+endfunc
+
+func Test_atan2()
+  call assert_equal('-2.356194', string(atan2(-1, -1)))
+  call assert_equal('2.356194', string(atan2(1, -1)))
+  call assert_equal('0.0', string(atan2(1.0, 1.0/0.0)))
+  call assert_equal('1.570796', string(atan2(1.0/0.0, 1.0)))
+  call assert_equal('nan', string(atan2(0.0/0.0, 1.0)))
+  call assert_fails('call atan2("", -1)', 'E808:')
+  call assert_fails('call atan2(-1, "")', 'E808:')
+endfunc
+
+func Test_tanh()
+  call assert_equal('0.0', string(tanh(0.0)))
+  call assert_equal('0.462117', string(tanh(0.5)))
+  call assert_equal('-0.761594', string(tanh(-1.0)))
+  call assert_equal('1.0', string(tanh(1.0/0.0)))
+  call assert_equal('-1.0', string(tanh(-1.0/0.0)))
+  call assert_equal('nan', string(tanh(0.0/0.0)))
+  call assert_fails('call tanh("")', 'E808:')
+endfunc
+
+func Test_fmod()
+  call assert_equal('0.13', string(fmod(12.33, 1.22)))
+  call assert_equal('-0.13', string(fmod(-12.33, 1.22)))
+  call assert_equal('nan', string(fmod(1.0/0.0, 1.0)))
+  " On Windows we get "nan" instead of 1.0, accept both.
+  let res = string(fmod(1.0, 1.0/0.0))
+  if res != 'nan'
+    call assert_equal('1.0', res)
+  endif
+  call assert_equal('nan', string(fmod(1.0, 0.0)))
+  call assert_fails("call fmod('', 1.22)", 'E808:')
+  call assert_fails("call fmod(12.33, '')", 'E808:')
+endfunc
+
+func Test_pow()
+  call assert_equal('1.0', string(pow(0.0, 0.0)))
+  call assert_equal('8.0', string(pow(2.0, 3.0)))
+  call assert_equal('nan', string(pow(2.0, 0.0/0.0)))
+  call assert_equal('nan', string(pow(0.0/0.0, 3.0)))
+  call assert_equal('nan', string(pow(0.0/0.0, 3.0)))
+  call assert_equal('inf', string(pow(2.0, 1.0/0.0)))
+  call assert_equal('inf', string(pow(1.0/0.0, 3.0)))
+  call assert_fails("call pow('', 2.0)", 'E808:')
+  call assert_fails("call pow(2.0, '')", 'E808:')
+endfunc
+
+func Test_str2float()
+  call assert_equal('1.0', string(str2float('1')))
+  call assert_equal('1.0', string(str2float(' 1 ')))
+  call assert_equal('1.0', string(str2float(' 1.0 ')))
+  call assert_equal('1.23', string(str2float('1.23')))
+  call assert_equal('1.23', string(str2float('1.23abc')))
+  call assert_equal('1.0e40', string(str2float('1e40')))
+  call assert_equal('-1.23', string(str2float('-1.23')))
+  call assert_equal('1.23', string(str2float(' + 1.23 ')))
+
+  call assert_equal('1.0', string(str2float('+1')))
+  call assert_equal('1.0', string(str2float('+1')))
+  call assert_equal('1.0', string(str2float(' +1 ')))
+  call assert_equal('1.0', string(str2float(' + 1 ')))
+
+  call assert_equal('-1.0', string(str2float('-1')))
+  call assert_equal('-1.0', string(str2float('-1')))
+  call assert_equal('-1.0', string(str2float(' -1 ')))
+  call assert_equal('-1.0', string(str2float(' - 1 ')))
+
+  call assert_equal('0.0', string(str2float('+0.0')))
+  call assert_equal('-0.0', string(str2float('-0.0')))
+  call assert_equal('inf', string(str2float('1e1000')))
+  call assert_equal('inf', string(str2float('inf')))
+  call assert_equal('-inf', string(str2float('-inf')))
+  call assert_equal('inf', string(str2float('+inf')))
+  call assert_equal('inf', string(str2float('Inf')))
+  call assert_equal('inf', string(str2float('  +inf  ')))
+  call assert_equal('nan', string(str2float('nan')))
+  call assert_equal('nan', string(str2float('NaN')))
+  call assert_equal('nan', string(str2float('  nan  ')))
+
+  call assert_fails("call str2float(1.2)", 'E806:')
+  call assert_fails("call str2float([])", 'E730:')
+  call assert_fails("call str2float({})", 'E731:')
+  call assert_fails("call str2float(function('string'))", 'E729:')
+endfunc
+
+func Test_floor()
+  call assert_equal('2.0', string(floor(2.0)))
+  call assert_equal('2.0', string(floor(2.11)))
+  call assert_equal('2.0', string(floor(2.99)))
+  call assert_equal('-3.0', string(floor(-2.11)))
+  call assert_equal('-3.0', string(floor(-2.99)))
+  call assert_equal('nan', string(floor(0.0/0.0)))
+  call assert_equal('inf', string(floor(1.0/0.0)))
+  call assert_equal('-inf', string(floor(-1.0/0.0)))
+  call assert_fails("call floor('')", 'E808:')
+endfunc
+
+func Test_ceil()
+  call assert_equal('2.0', string(ceil(2.0)))
+  call assert_equal('3.0', string(ceil(2.11)))
+  call assert_equal('3.0', string(ceil(2.99)))
+  call assert_equal('-2.0', string(ceil(-2.11)))
+  call assert_equal('-2.0', string(ceil(-2.99)))
+  call assert_equal('nan', string(ceil(0.0/0.0)))
+  call assert_equal('inf', string(ceil(1.0/0.0)))
+  call assert_equal('-inf', string(ceil(-1.0/0.0)))
+  call assert_fails("call ceil('')", 'E808:')
+endfunc
+
+func Test_round()
+  call assert_equal('2.0', string(round(2.1)))
+  call assert_equal('3.0', string(round(2.5)))
+  call assert_equal('3.0', string(round(2.9)))
+  call assert_equal('-2.0', string(round(-2.1)))
+  call assert_equal('-3.0', string(round(-2.5)))
+  call assert_equal('-3.0', string(round(-2.9)))
+  call assert_equal('nan', string(round(0.0/0.0)))
+  call assert_equal('inf', string(round(1.0/0.0)))
+  call assert_equal('-inf', string(round(-1.0/0.0)))
+  call assert_fails("call round('')", 'E808:')
+endfunc
+
+func Test_trunc()
+  call assert_equal('2.0', string(trunc(2.1)))
+  call assert_equal('2.0', string(trunc(2.5)))
+  call assert_equal('2.0', string(trunc(2.9)))
+  call assert_equal('-2.0', string(trunc(-2.1)))
+  call assert_equal('-2.0', string(trunc(-2.5)))
+  call assert_equal('-2.0', string(trunc(-2.9)))
+  call assert_equal('nan', string(trunc(0.0/0.0)))
+  call assert_equal('inf', string(trunc(1.0/0.0)))
+  call assert_equal('-inf', string(trunc(-1.0/0.0)))
+  call assert_fails("call trunc('')", 'E808:')
+endfunc
+
+func Test_isnan()
+  call assert_equal(0, isnan(1.0))
+  call assert_equal(1, isnan(0.0/0.0))
+  call assert_equal(0, isnan(1.0/0.0))
+  call assert_equal(0, isnan('a'))
+  call assert_equal(0, isnan([]))
+  call assert_equal(0, isnan({}))
+endfunc
index 2267e18..768d311 100644 (file)
@@ -1,6 +1,8 @@
 " Test filename modifiers.
 
 func Test_fnamemodify()
+  let save_home = $HOME
+  let save_shell = &shell
   let $HOME = fnamemodify('.', ':p:h:h')
   set shell=sh
 
@@ -31,15 +33,17 @@ func Test_fnamemodify()
   call assert_equal('''abc"%"def''', fnamemodify('abc"%"def', ':S'))
   call assert_equal('''abc''\'''' ''\''''def''', fnamemodify('abc'' ''def', ':S'))
   call assert_equal('''abc''\''''%''\''''def''', fnamemodify('abc''%''def', ':S'))
-  call assert_equal(expand('%:r:S'), shellescape(expand('%:r')))
   sp test_alot.vim
+  call assert_equal(expand('%:r:S'), shellescape(expand('%:r')))
   call assert_equal('test_alot,''test_alot'',test_alot.vim', join([expand('%:r'), expand('%:r:S'), expand('%')], ','))
   quit
 
   call assert_equal("'abc\ndef'", fnamemodify("abc\ndef", ':S'))
   set shell=tcsh
   call assert_equal("'abc\\\ndef'",  fnamemodify("abc\ndef", ':S'))
-  set shell&
+
+  let $HOME = save_home
+  let &shell = save_shell
 endfunc
 
 func Test_expand()
diff --git a/src/testdir/test_fold.vim b/src/testdir/test_fold.vim
new file mode 100644 (file)
index 0000000..fe4395b
--- /dev/null
@@ -0,0 +1,449 @@
+" Test for folding
+
+func PrepIndent(arg)
+  return [a:arg] + repeat(["\t".a:arg], 5)
+endfu
+
+func Test_address_fold()
+  new
+  call setline(1, ['int FuncName() {/*{{{*/', 1, 2, 3, 4, 5, '}/*}}}*/',
+             \ 'after fold 1', 'after fold 2', 'after fold 3'])
+  setl fen fdm=marker
+  " The next commands should all copy the same part of the buffer,
+  " regardless of the addressing type, since the part to be copied
+  " is folded away
+  :1y
+  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+  :.y
+  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+  :.+y
+  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+  :.,.y
+  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+  :sil .1,.y
+  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+  " use silent to make E493 go away
+  :sil .+,.y
+  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+  :,y
+  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+  :,+y
+  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/','after fold 1'], getreg(0,1,1))
+  " using .+3 as second address should copy the whole folded line + the next 3
+  " lines
+  :.,+3y
+  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/',
+             \ 'after fold 1', 'after fold 2', 'after fold 3'], getreg(0,1,1))
+  :sil .,-2y
+  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+
+  " now test again with folding disabled
+  set nofoldenable
+  :1y
+  call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
+  :.y
+  call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
+  :.+y
+  call assert_equal(['1'], getreg(0,1,1))
+  :.,.y
+  call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
+  " use silent to make E493 go away
+  :sil .1,.y
+  call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1))
+  " use silent to make E493 go away
+  :sil .+,.y
+  call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1))
+  :,y
+  call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
+  :,+y
+  call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1))
+  " using .+3 as second address should copy the whole folded line + the next 3
+  " lines
+  :.,+3y
+  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3'], getreg(0,1,1))
+  :7
+  :sil .,-2y
+  call assert_equal(['4', '5', '}/*}}}*/'], getreg(0,1,1))
+
+  quit!
+endfunc
+
+func Test_indent_fold()
+    new
+    call setline(1, ['', 'a', '    b', '    c'])
+    setl fen fdm=indent
+    2
+    norm! >>
+    let a=map(range(1,4), 'foldclosed(v:val)')
+    call assert_equal([-1,-1,-1,-1], a)
+    bw!
+endfunc
+
+func Test_indent_fold2()
+    new
+    call setline(1, ['', '{{{', '}}}', '{{{', '}}}'])
+    setl fen fdm=marker
+    2
+    norm! >>
+    let a=map(range(1,5), 'foldclosed(v:val)')
+    call assert_equal([-1,-1,-1,4,4], a)
+    bw!
+endfunc
+
+func Test_manual_fold_with_filter()
+  if !executable('cat')
+    return
+  endif
+  for type in ['manual', 'marker']
+    exe 'set foldmethod=' . type
+    new
+    call setline(1, range(1, 20))
+    4,$fold
+    %foldopen
+    10,$fold
+    %foldopen
+    " This filter command should not have an effect
+    1,8! cat
+    call feedkeys('5ggzdzMGdd', 'xt')
+    call assert_equal(['1', '2', '3', '4', '5', '6', '7', '8', '9'], getline(1, '$'))
+
+    bwipe!
+    set foldmethod&
+  endfor
+endfunc
+
+func Test_indent_fold_with_read()
+  new
+  set foldmethod=indent
+  call setline(1, repeat(["\<Tab>a"], 4))
+  for n in range(1, 4)
+    call assert_equal(1, foldlevel(n))
+  endfor
+
+  call writefile(["a", "", "\<Tab>a"], 'Xfile')
+  foldopen
+  2read Xfile
+  %foldclose
+  call assert_equal(1, foldlevel(1))
+  call assert_equal(2, foldclosedend(1))
+  call assert_equal(0, foldlevel(3))
+  call assert_equal(0, foldlevel(4))
+  call assert_equal(1, foldlevel(5))
+  call assert_equal(7, foldclosedend(5))
+
+  bwipe!
+  set foldmethod&
+  call delete('Xfile')
+endfunc
+
+func Test_combining_folds_indent()
+  new
+  let one = "\<Tab>a"
+  let zero = 'a'
+  call setline(1, [one, one, zero, zero, zero, one, one, one])
+  set foldmethod=indent
+  3,5d
+  %foldclose
+  call assert_equal(5, foldclosedend(1))
+
+  set foldmethod&
+  bwipe!
+endfunc
+
+func Test_combining_folds_marker()
+  new
+  call setline(1, ['{{{', '}}}', '', '', '', '{{{', '', '}}}'])
+  set foldmethod=marker
+  3,5d
+  %foldclose
+  call assert_equal(2, foldclosedend(1))
+
+  set foldmethod&
+  bwipe!
+endfunc
+
+func Test_folds_marker_in_comment()
+  new
+  call setline(1, ['" foo', 'bar', 'baz'])
+  setl fen fdm=marker
+  setl com=sO:\"\ -,mO:\"\ \ ,eO:\"\",:\" cms=\"%s
+  norm! zf2j
+  setl nofen
+  :1y
+  call assert_equal(['" foo{{{'], getreg(0,1,1))
+  :+2y
+  call assert_equal(['baz"}}}'], getreg(0,1,1))
+
+  set foldmethod&
+  bwipe!
+endfunc
+
+func s:TestFoldExpr(lnum)
+  let thisline = getline(a:lnum)
+  if thisline == 'a'
+    return 1
+  elseif thisline == 'b'
+    return 0
+  elseif thisline == 'c'
+    return '<1'
+  elseif thisline == 'd'
+    return '>1'
+  endif
+  return 0
+endfunction
+
+func Test_update_folds_expr_read()
+  new
+  call setline(1, ['a', 'a', 'a', 'a', 'a', 'a'])
+  set foldmethod=expr
+  set foldexpr=s:TestFoldExpr(v:lnum)
+  2
+  foldopen
+  call writefile(['b', 'b', 'a', 'a', 'd', 'a', 'a', 'c'], 'Xfile')
+  read Xfile
+  %foldclose
+  call assert_equal(2, foldclosedend(1))
+  call assert_equal(0, foldlevel(3))
+  call assert_equal(0, foldlevel(4))
+  call assert_equal(6, foldclosedend(5))
+  call assert_equal(10, foldclosedend(7))
+  call assert_equal(14, foldclosedend(11))
+
+  call delete('Xfile')
+  bwipe!
+  set foldmethod& foldexpr&
+endfunc
+
+func Check_foldlevels(expected)
+  call assert_equal(a:expected, map(range(1, line('$')), 'foldlevel(v:val)'))
+endfunc
+
+func Test_move_folds_around_manual()
+  new
+  let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c")
+  call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
+  let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14]
+  " all folds closed
+  set foldenable foldlevel=0 fdm=indent
+  " needs a forced redraw
+  redraw!
+  set fdm=manual
+  call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
+  call assert_equal(input, getline(1, '$'))
+  7,12m0
+  call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
+  call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
+  10,12m0
+  call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] +  PrepIndent("c"), getline(1, '$'))
+  call assert_equal([1, 1, 1, 1, 1, -1, 7, 7, 7, 7, 7, -1, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
+  " moving should not close the folds
+  %d
+  call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
+  set fdm=indent
+  redraw!
+  set fdm=manual
+  call cursor(2, 1)
+  %foldopen
+  7,12m0
+  let folds=repeat([-1], 18)
+  call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
+  call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
+  norm! zM
+  " folds are not corrupted and all have been closed
+  call assert_equal([-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
+  %d
+  call setline(1, ["a", "\tb", "\tc", "\td", "\te"])
+  set fdm=indent
+  redraw!
+  set fdm=manual
+  %foldopen
+  3m4
+  %foldclose
+  call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$'))
+  call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)'))
+  %d
+  call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"])
+  set fdm=indent foldlevel=0
+  set fdm=manual
+  %foldopen
+  3m1
+  %foldclose
+  call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$'))
+  call assert_equal(0, foldlevel(2))
+  call assert_equal(5, foldclosedend(3))
+  call assert_equal([-1, -1, 3, 3, 3, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)'))
+  2,6m$
+  %foldclose
+  call assert_equal(5, foldclosedend(2))
+  call assert_equal(0, foldlevel(6))
+  call assert_equal(9, foldclosedend(7))
+  call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
+
+  %d
+  " Ensure moving around the edges still works.
+  call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
+  set fdm=indent foldlevel=0
+  set fdm=manual
+  %foldopen
+  6m$
+  " The first fold has been truncated to the 5'th line.
+  " Second fold has been moved up because the moved line is now below it.
+  call Check_foldlevels([0, 1, 1, 1, 1, 0, 0, 0, 1, 0])
+
+  %delete
+  set fdm=indent foldlevel=0
+  call setline(1, [
+       \ "a",
+       \ "\ta",
+       \ "\t\ta",
+       \ "\t\ta",
+       \ "\t\ta",
+       \ "a",
+       \ "a"])
+  set fdm=manual
+  %foldopen!
+  4,5m6
+  call Check_foldlevels([0, 1, 2, 0, 0, 0, 0])
+
+  %delete
+  set fdm=indent
+  call setline(1, [
+       \ "\ta",
+       \ "\t\ta",
+       \ "\t\ta",
+       \ "\t\ta",
+       \ "\ta",
+       \ "\t\ta",
+       \ "\t\ta",
+       \ "\t\ta",
+       \ "\ta",
+       \ "\t\ta",
+       \ "\t\ta",
+       \ "\t\ta",
+       \ "\t\ta",
+       \ "\ta",
+       \ "a"])
+  set fdm=manual
+  %foldopen!
+  13m7
+  call Check_foldlevels([1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0])
+  
+  bw!
+endfunc
+
+func Test_move_folds_around_indent()
+  new
+  let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c")
+  call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
+  let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14]
+  " all folds closed
+  set fdm=indent
+  call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
+  call assert_equal(input, getline(1, '$'))
+  7,12m0
+  call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
+  call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
+  10,12m0
+  call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] +  PrepIndent("c"), getline(1, '$'))
+  call assert_equal([1, 1, 1, 1, 1, -1, 7, 7, 7, 7, 7, -1, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
+  " moving should not close the folds
+  %d
+  call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
+  set fdm=indent
+  call cursor(2, 1)
+  %foldopen
+  7,12m0
+  let folds=repeat([-1], 18)
+  call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
+  call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
+  norm! zM
+  " folds are not corrupted and all have been closed
+  call assert_equal([-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
+  %d
+  call setline(1, ["a", "\tb", "\tc", "\td", "\te"])
+  set fdm=indent
+  %foldopen
+  3m4
+  %foldclose
+  call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$'))
+  call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)'))
+  %d
+  call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"])
+  set fdm=indent foldlevel=0
+  %foldopen
+  3m1
+  %foldclose
+  call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$'))
+  call assert_equal(1, foldlevel(2))
+  call assert_equal(5, foldclosedend(3))
+  call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)'))
+  2,6m$
+  %foldclose
+  call assert_equal(9, foldclosedend(2))
+  call assert_equal(1, foldlevel(6))
+  call assert_equal(9, foldclosedend(7))
+  call assert_equal([-1, 2, 2, 2, 2, 2, 2, 2, 2, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
+  " Ensure moving around the edges still works.
+  %d
+  call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
+  set fdm=indent foldlevel=0
+  %foldopen
+  6m$
+  " The first fold has been truncated to the 5'th line.
+  " Second fold has been moved up because the moved line is now below it.
+  call Check_foldlevels([0, 1, 1, 1, 1, 0, 0, 0, 1, 1])
+  bw!
+endfunc
+
+func Test_folddoopen_folddoclosed()
+  new
+  call setline(1, range(1, 9))
+  set foldmethod=manual
+  1,3 fold
+  6,8 fold
+
+  " Test without range.
+  folddoopen   s/$/o/
+  folddoclosed s/$/c/
+  call assert_equal(['1c', '2c', '3c',
+  \                  '4o', '5o',
+  \                  '6c', '7c', '8c',
+  \                  '9o'], getline(1, '$'))
+
+  " Test with range.
+  call setline(1, range(1, 9))
+  1,8 folddoopen   s/$/o/
+  4,$ folddoclosed s/$/c/
+  call assert_equal(['1',  '2', '3',
+  \                  '4o', '5o',
+  \                  '6c', '7c', '8c',
+  \                  '9'], getline(1, '$'))
+
+  set foldmethod&
+  bw!
+endfunc
+
+func Test_fold_error()
+  new
+  call setline(1, [1, 2])
+
+  for fm in ['indent', 'expr', 'syntax', 'diff']
+    exe 'set foldmethod=' . fm
+    call assert_fails('norm zf', 'E350:')
+    call assert_fails('norm zd', 'E351:')
+    call assert_fails('norm zE', 'E352:')
+  endfor
+
+  set foldmethod=manual
+  call assert_fails('norm zd', 'E490:')
+  call assert_fails('norm zo', 'E490:')
+  call assert_fails('3fold',   'E16:')
+
+  set foldmethod=marker
+  set nomodifiable
+  call assert_fails('1,2fold', 'E21:')
+
+  set modifiable&
+  set foldmethod&
+  bw!
+endfunc
diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim
new file mode 100644 (file)
index 0000000..e569ef1
--- /dev/null
@@ -0,0 +1,786 @@
+" Tests for various functions.
+
+func Test_empty()
+  call assert_equal(1, empty(''))
+  call assert_equal(0, empty('a'))
+
+  call assert_equal(1, empty(0))
+  call assert_equal(1, empty(-0))
+  call assert_equal(0, empty(1))
+  call assert_equal(0, empty(-1))
+
+  call assert_equal(1, empty(0.0))
+  call assert_equal(1, empty(-0.0))
+  call assert_equal(0, empty(1.0))
+  call assert_equal(0, empty(-1.0))
+  call assert_equal(0, empty(1.0/0.0))
+  call assert_equal(0, empty(0.0/0.0))
+
+  call assert_equal(1, empty([]))
+  call assert_equal(0, empty(['a']))
+
+  call assert_equal(1, empty({}))
+  call assert_equal(0, empty({'a':1}))
+
+  call assert_equal(1, empty(v:null))
+  call assert_equal(1, empty(v:none))
+  call assert_equal(1, empty(v:false))
+  call assert_equal(0, empty(v:true))
+
+  if has('channel')
+    call assert_equal(1, empty(test_null_channel()))
+  endif
+  if has('job')
+    call assert_equal(1, empty(test_null_job()))
+  endif
+
+  call assert_equal(0, empty(function('Test_empty')))
+endfunc
+
+func Test_len()
+  call assert_equal(1, len(0))
+  call assert_equal(2, len(12))
+
+  call assert_equal(0, len(''))
+  call assert_equal(2, len('ab'))
+
+  call assert_equal(0, len([]))
+  call assert_equal(2, len([2, 1]))
+
+  call assert_equal(0, len({}))
+  call assert_equal(2, len({'a': 1, 'b': 2}))
+
+  call assert_fails('call len(v:none)', 'E701:')
+  call assert_fails('call len({-> 0})', 'E701:')
+endfunc
+
+func Test_max()
+  call assert_equal(0, max([]))
+  call assert_equal(2, max([2]))
+  call assert_equal(2, max([1, 2]))
+  call assert_equal(2, max([1, 2, v:null]))
+
+  call assert_equal(0, max({}))
+  call assert_equal(2, max({'a':1, 'b':2}))
+
+  call assert_fails('call max(1)', 'E712:')
+  call assert_fails('call max(v:none)', 'E712:')
+endfunc
+
+func Test_min()
+  call assert_equal(0, min([]))
+  call assert_equal(2, min([2]))
+  call assert_equal(1, min([1, 2]))
+  call assert_equal(0, min([1, 2, v:null]))
+
+  call assert_equal(0, min({}))
+  call assert_equal(1, min({'a':1, 'b':2}))
+
+  call assert_fails('call min(1)', 'E712:')
+  call assert_fails('call min(v:none)', 'E712:')
+endfunc
+
+func Test_str2nr()
+  call assert_equal(0, str2nr(''))
+  call assert_equal(1, str2nr('1'))
+  call assert_equal(1, str2nr(' 1 '))
+
+  call assert_equal(1, str2nr('+1'))
+  call assert_equal(1, str2nr('+ 1'))
+  call assert_equal(1, str2nr(' + 1 '))
+
+  call assert_equal(-1, str2nr('-1'))
+  call assert_equal(-1, str2nr('- 1'))
+  call assert_equal(-1, str2nr(' - 1 '))
+
+  call assert_equal(123456789, str2nr('123456789'))
+  call assert_equal(-123456789, str2nr('-123456789'))
+
+  call assert_equal(5, str2nr('101', 2))
+  call assert_equal(5, str2nr('0b101', 2))
+  call assert_equal(5, str2nr('0B101', 2))
+  call assert_equal(-5, str2nr('-101', 2))
+  call assert_equal(-5, str2nr('-0b101', 2))
+  call assert_equal(-5, str2nr('-0B101', 2))
+
+  call assert_equal(65, str2nr('101', 8))
+  call assert_equal(65, str2nr('0101', 8))
+  call assert_equal(-65, str2nr('-101', 8))
+  call assert_equal(-65, str2nr('-0101', 8))
+
+  call assert_equal(11259375, str2nr('abcdef', 16))
+  call assert_equal(11259375, str2nr('ABCDEF', 16))
+  call assert_equal(-11259375, str2nr('-ABCDEF', 16))
+  call assert_equal(11259375, str2nr('0xabcdef', 16))
+  call assert_equal(11259375, str2nr('0Xabcdef', 16))
+  call assert_equal(11259375, str2nr('0XABCDEF', 16))
+  call assert_equal(-11259375, str2nr('-0xABCDEF', 16))
+
+  call assert_equal(0, str2nr('0x10'))
+  call assert_equal(0, str2nr('0b10'))
+  call assert_equal(1, str2nr('12', 2))
+  call assert_equal(1, str2nr('18', 8))
+  call assert_equal(1, str2nr('1g', 16))
+
+  call assert_equal(0, str2nr(v:null))
+  call assert_equal(0, str2nr(v:none))
+
+  call assert_fails('call str2nr([])', 'E730:')
+  call assert_fails('call str2nr({->2})', 'E729:')
+  call assert_fails('call str2nr(1.2)', 'E806:')
+  call assert_fails('call str2nr(10, [])', 'E474:')
+endfunc
+
+func Test_strftime()
+  if !exists('*strftime')
+    return
+  endif
+  " Format of strftime() depends on system. We assume
+  " that basic formats tested here are available and
+  " identical on all systems which support strftime().
+  "
+  " The 2nd parameter of strftime() is a local time, so the output day
+  " of strftime() can be 17 or 18, depending on timezone.
+  call assert_match('^2017-01-1[78]$', strftime('%Y-%m-%d', 1484695512))
+  "
+  call assert_match('^\d\d\d\d-\(0\d\|1[012]\)-\([012]\d\|3[01]\) \([01]\d\|2[0-3]\):[0-5]\d:\([0-5]\d\|60\)$', strftime('%Y-%m-%d %H:%M:%S'))
+
+  call assert_fails('call strftime([])', 'E730:')
+  call assert_fails('call strftime("%Y", [])', 'E745:')
+endfunc
+
+func Test_simplify()
+  call assert_equal('',            simplify(''))
+  call assert_equal('/',           simplify('/'))
+  call assert_equal('/',           simplify('/.'))
+  call assert_equal('/',           simplify('/..'))
+  call assert_equal('/...',        simplify('/...'))
+  call assert_equal('./dir/file',  simplify('./dir/file'))
+  call assert_equal('./dir/file',  simplify('.///dir//file'))
+  call assert_equal('./dir/file',  simplify('./dir/./file'))
+  call assert_equal('./file',      simplify('./dir/../file'))
+  call assert_equal('../dir/file', simplify('dir/../../dir/file'))
+  call assert_equal('./file',      simplify('dir/.././file'))
+
+  call assert_fails('call simplify({->0})', 'E729:')
+  call assert_fails('call simplify([])', 'E730:')
+  call assert_fails('call simplify({})', 'E731:')
+  call assert_fails('call simplify(1.2)', 'E806:')
+endfunc
+
+func Test_tolower()
+  call assert_equal("", tolower(""))
+
+  " Test with all printable ASCII characters.
+  call assert_equal(' !"#$%&''()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~',
+          \ tolower(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'))
+
+  if !has('multi_byte')
+    return
+  endif
+
+  " Test with a few uppercase diacritics.
+  call assert_equal("aàáâãäåāăąǎǟǡả", tolower("AÀÁÂÃÄÅĀĂĄǍǞǠẢ"))
+  call assert_equal("bḃḇ", tolower("BḂḆ"))
+  call assert_equal("cçćĉċč", tolower("CÇĆĈĊČ"))
+  call assert_equal("dďđḋḏḑ", tolower("DĎĐḊḎḐ"))
+  call assert_equal("eèéêëēĕėęěẻẽ", tolower("EÈÉÊËĒĔĖĘĚẺẼ"))
+  call assert_equal("fḟ ", tolower("FḞ "))
+  call assert_equal("gĝğġģǥǧǵḡ", tolower("GĜĞĠĢǤǦǴḠ"))
+  call assert_equal("hĥħḣḧḩ", tolower("HĤĦḢḦḨ"))
+  call assert_equal("iìíîïĩīĭįiǐỉ", tolower("IÌÍÎÏĨĪĬĮİǏỈ"))
+  call assert_equal("jĵ", tolower("JĴ"))
+  call assert_equal("kķǩḱḵ", tolower("KĶǨḰḴ"))
+  call assert_equal("lĺļľŀłḻ", tolower("LĹĻĽĿŁḺ"))
+  call assert_equal("mḿṁ", tolower("MḾṀ"))
+  call assert_equal("nñńņňṅṉ", tolower("NÑŃŅŇṄṈ"))
+  call assert_equal("oòóôõöøōŏőơǒǫǭỏ", tolower("OÒÓÔÕÖØŌŎŐƠǑǪǬỎ"))
+  call assert_equal("pṕṗ", tolower("PṔṖ"))
+  call assert_equal("q", tolower("Q"))
+  call assert_equal("rŕŗřṙṟ", tolower("RŔŖŘṘṞ"))
+  call assert_equal("sśŝşšṡ", tolower("SŚŜŞŠṠ"))
+  call assert_equal("tţťŧṫṯ", tolower("TŢŤŦṪṮ"))
+  call assert_equal("uùúûüũūŭůűųưǔủ", tolower("UÙÚÛÜŨŪŬŮŰŲƯǓỦ"))
+  call assert_equal("vṽ", tolower("VṼ"))
+  call assert_equal("wŵẁẃẅẇ", tolower("WŴẀẂẄẆ"))
+  call assert_equal("xẋẍ", tolower("XẊẌ"))
+  call assert_equal("yýŷÿẏỳỷỹ", tolower("YÝŶŸẎỲỶỸ"))
+  call assert_equal("zźżžƶẑẕ", tolower("ZŹŻŽƵẐẔ"))
+
+  " Test with a few lowercase diacritics, which should remain unchanged.
+  call assert_equal("aàáâãäåāăąǎǟǡả", tolower("aàáâãäåāăąǎǟǡả"))
+  call assert_equal("bḃḇ", tolower("bḃḇ"))
+  call assert_equal("cçćĉċč", tolower("cçćĉċč"))
+  call assert_equal("dďđḋḏḑ", tolower("dďđḋḏḑ"))
+  call assert_equal("eèéêëēĕėęěẻẽ", tolower("eèéêëēĕėęěẻẽ"))
+  call assert_equal("fḟ", tolower("fḟ"))
+  call assert_equal("gĝğġģǥǧǵḡ", tolower("gĝğġģǥǧǵḡ"))
+  call assert_equal("hĥħḣḧḩẖ", tolower("hĥħḣḧḩẖ"))
+  call assert_equal("iìíîïĩīĭįǐỉ", tolower("iìíîïĩīĭįǐỉ"))
+  call assert_equal("jĵǰ", tolower("jĵǰ"))
+  call assert_equal("kķǩḱḵ", tolower("kķǩḱḵ"))
+  call assert_equal("lĺļľŀłḻ", tolower("lĺļľŀłḻ"))
+  call assert_equal("mḿṁ ", tolower("mḿṁ "))
+  call assert_equal("nñńņňʼnṅṉ", tolower("nñńņňʼnṅṉ"))
+  call assert_equal("oòóôõöøōŏőơǒǫǭỏ", tolower("oòóôõöøōŏőơǒǫǭỏ"))
+  call assert_equal("pṕṗ", tolower("pṕṗ"))
+  call assert_equal("q", tolower("q"))
+  call assert_equal("rŕŗřṙṟ", tolower("rŕŗřṙṟ"))
+  call assert_equal("sśŝşšṡ", tolower("sśŝşšṡ"))
+  call assert_equal("tţťŧṫṯẗ", tolower("tţťŧṫṯẗ"))
+  call assert_equal("uùúûüũūŭůűųưǔủ", tolower("uùúûüũūŭůűųưǔủ"))
+  call assert_equal("vṽ", tolower("vṽ"))
+  call assert_equal("wŵẁẃẅẇẘ", tolower("wŵẁẃẅẇẘ"))
+  call assert_equal("ẋẍ", tolower("ẋẍ"))
+  call assert_equal("yýÿŷẏẙỳỷỹ", tolower("yýÿŷẏẙỳỷỹ"))
+  call assert_equal("zźżžƶẑẕ", tolower("zźżžƶẑẕ"))
+
+  " According to https://twitter.com/jifa/status/625776454479970304
+  " Ⱥ (U+023A) and Ⱦ (U+023E) are the *only* code points to increase
+  " in length (2 to 3 bytes) when lowercased. So let's test them.
+  call assert_equal("ⱥ ⱦ", tolower("Ⱥ Ⱦ"))
+endfunc
+
+func Test_toupper()
+  call assert_equal("", toupper(""))
+
+  " Test with all printable ASCII characters.
+  call assert_equal(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~',
+          \ toupper(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'))
+
+  if !has('multi_byte')
+    return
+  endif
+
+  " Test with a few lowercase diacritics.
+  call assert_equal("AÀÁÂÃÄÅĀĂĄǍǞǠẢ", toupper("aàáâãäåāăąǎǟǡả"))
+  call assert_equal("BḂḆ", toupper("bḃḇ"))
+  call assert_equal("CÇĆĈĊČ", toupper("cçćĉċč"))
+  call assert_equal("DĎĐḊḎḐ", toupper("dďđḋḏḑ"))
+  call assert_equal("EÈÉÊËĒĔĖĘĚẺẼ", toupper("eèéêëēĕėęěẻẽ"))
+  call assert_equal("FḞ", toupper("fḟ"))
+  call assert_equal("GĜĞĠĢǤǦǴḠ", toupper("gĝğġģǥǧǵḡ"))
+  call assert_equal("HĤĦḢḦḨẖ", toupper("hĥħḣḧḩẖ"))
+  call assert_equal("IÌÍÎÏĨĪĬĮǏỈ", toupper("iìíîïĩīĭįǐỉ"))
+  call assert_equal("JĴǰ", toupper("jĵǰ"))
+  call assert_equal("KĶǨḰḴ", toupper("kķǩḱḵ"))
+  call assert_equal("LĹĻĽĿŁḺ", toupper("lĺļľŀłḻ"))
+  call assert_equal("MḾṀ ", toupper("mḿṁ "))
+  call assert_equal("NÑŃŅŇʼnṄṈ", toupper("nñńņňʼnṅṉ"))
+  call assert_equal("OÒÓÔÕÖØŌŎŐƠǑǪǬỎ", toupper("oòóôõöøōŏőơǒǫǭỏ"))
+  call assert_equal("PṔṖ", toupper("pṕṗ"))
+  call assert_equal("Q", toupper("q"))
+  call assert_equal("RŔŖŘṘṞ", toupper("rŕŗřṙṟ"))
+  call assert_equal("SŚŜŞŠṠ", toupper("sśŝşšṡ"))
+  call assert_equal("TŢŤŦṪṮẗ", toupper("tţťŧṫṯẗ"))
+  call assert_equal("UÙÚÛÜŨŪŬŮŰŲƯǓỦ", toupper("uùúûüũūŭůűųưǔủ"))
+  call assert_equal("VṼ", toupper("vṽ"))
+  call assert_equal("WŴẀẂẄẆẘ", toupper("wŵẁẃẅẇẘ"))
+  call assert_equal("ẊẌ", toupper("ẋẍ"))
+  call assert_equal("YÝŸŶẎẙỲỶỸ", toupper("yýÿŷẏẙỳỷỹ"))
+  call assert_equal("ZŹŻŽƵẐẔ", toupper("zźżžƶẑẕ"))
+
+  " Test that uppercase diacritics, which should remain unchanged.
+  call assert_equal("AÀÁÂÃÄÅĀĂĄǍǞǠẢ", toupper("AÀÁÂÃÄÅĀĂĄǍǞǠẢ"))
+  call assert_equal("BḂḆ", toupper("BḂḆ"))
+  call assert_equal("CÇĆĈĊČ", toupper("CÇĆĈĊČ"))
+  call assert_equal("DĎĐḊḎḐ", toupper("DĎĐḊḎḐ"))
+  call assert_equal("EÈÉÊËĒĔĖĘĚẺẼ", toupper("EÈÉÊËĒĔĖĘĚẺẼ"))
+  call assert_equal("FḞ ", toupper("FḞ "))
+  call assert_equal("GĜĞĠĢǤǦǴḠ", toupper("GĜĞĠĢǤǦǴḠ"))
+  call assert_equal("HĤĦḢḦḨ", toupper("HĤĦḢḦḨ"))
+  call assert_equal("IÌÍÎÏĨĪĬĮİǏỈ", toupper("IÌÍÎÏĨĪĬĮİǏỈ"))
+  call assert_equal("JĴ", toupper("JĴ"))
+  call assert_equal("KĶǨḰḴ", toupper("KĶǨḰḴ"))
+  call assert_equal("LĹĻĽĿŁḺ", toupper("LĹĻĽĿŁḺ"))
+  call assert_equal("MḾṀ", toupper("MḾṀ"))
+  call assert_equal("NÑŃŅŇṄṈ", toupper("NÑŃŅŇṄṈ"))
+  call assert_equal("OÒÓÔÕÖØŌŎŐƠǑǪǬỎ", toupper("OÒÓÔÕÖØŌŎŐƠǑǪǬỎ"))
+  call assert_equal("PṔṖ", toupper("PṔṖ"))
+  call assert_equal("Q", toupper("Q"))
+  call assert_equal("RŔŖŘṘṞ", toupper("RŔŖŘṘṞ"))
+  call assert_equal("SŚŜŞŠṠ", toupper("SŚŜŞŠṠ"))
+  call assert_equal("TŢŤŦṪṮ", toupper("TŢŤŦṪṮ"))
+  call assert_equal("UÙÚÛÜŨŪŬŮŰŲƯǓỦ", toupper("UÙÚÛÜŨŪŬŮŰŲƯǓỦ"))
+  call assert_equal("VṼ", toupper("VṼ"))
+  call assert_equal("WŴẀẂẄẆ", toupper("WŴẀẂẄẆ"))
+  call assert_equal("XẊẌ", toupper("XẊẌ"))
+  call assert_equal("YÝŶŸẎỲỶỸ", toupper("YÝŶŸẎỲỶỸ"))
+  call assert_equal("ZŹŻŽƵẐẔ", toupper("ZŹŻŽƵẐẔ"))
+
+  call assert_equal("Ⱥ Ⱦ", toupper("ⱥ ⱦ"))
+endfunc
+
+" Tests for the mode() function
+let current_modes = ''
+func Save_mode()
+  let g:current_modes = mode(0) . '-' . mode(1)
+  return ''
+endfunc
+
+func Test_mode()
+  new
+  call append(0, ["Blue Ball Black", "Brown Band Bowl", ""])
+
+  " Only complete from the current buffer.
+  set complete=.
+
+  inoremap <F2> <C-R>=Save_mode()<CR>
+
+  normal! 3G
+  exe "normal i\<F2>\<Esc>"
+  call assert_equal('i-i', g:current_modes)
+  " i_CTRL-P: Multiple matches
+  exe "normal i\<C-G>uBa\<C-P>\<F2>\<Esc>u"
+  call assert_equal('i-ic', g:current_modes)
+  " i_CTRL-P: Single match
+  exe "normal iBro\<C-P>\<F2>\<Esc>u"
+  call assert_equal('i-ic', g:current_modes)
+  " i_CTRL-X
+  exe "normal iBa\<C-X>\<F2>\<Esc>u"
+  call assert_equal('i-ix', g:current_modes)
+  " i_CTRL-X CTRL-P: Multiple matches
+  exe "normal iBa\<C-X>\<C-P>\<F2>\<Esc>u"
+  call assert_equal('i-ic', g:current_modes)
+  " i_CTRL-X CTRL-P: Single match
+  exe "normal iBro\<C-X>\<C-P>\<F2>\<Esc>u"
+  call assert_equal('i-ic', g:current_modes)
+  " i_CTRL-X CTRL-P + CTRL-P: Single match
+  exe "normal iBro\<C-X>\<C-P>\<C-P>\<F2>\<Esc>u"
+  call assert_equal('i-ic', g:current_modes)
+  " i_CTRL-X CTRL-L: Multiple matches
+  exe "normal i\<C-X>\<C-L>\<F2>\<Esc>u"
+  call assert_equal('i-ic', g:current_modes)
+  " i_CTRL-X CTRL-L: Single match
+  exe "normal iBlu\<C-X>\<C-L>\<F2>\<Esc>u"
+  call assert_equal('i-ic', g:current_modes)
+  " i_CTRL-P: No match
+  exe "normal iCom\<C-P>\<F2>\<Esc>u"
+  call assert_equal('i-ic', g:current_modes)
+  " i_CTRL-X CTRL-P: No match
+  exe "normal iCom\<C-X>\<C-P>\<F2>\<Esc>u"
+  call assert_equal('i-ic', g:current_modes)
+  " i_CTRL-X CTRL-L: No match
+  exe "normal iabc\<C-X>\<C-L>\<F2>\<Esc>u"
+  call assert_equal('i-ic', g:current_modes)
+
+  " R_CTRL-P: Multiple matches
+  exe "normal RBa\<C-P>\<F2>\<Esc>u"
+  call assert_equal('R-Rc', g:current_modes)
+  " R_CTRL-P: Single match
+  exe "normal RBro\<C-P>\<F2>\<Esc>u"
+  call assert_equal('R-Rc', g:current_modes)
+  " R_CTRL-X
+  exe "normal RBa\<C-X>\<F2>\<Esc>u"
+  call assert_equal('R-Rx', g:current_modes)
+  " R_CTRL-X CTRL-P: Multiple matches
+  exe "normal RBa\<C-X>\<C-P>\<F2>\<Esc>u"
+  call assert_equal('R-Rc', g:current_modes)
+  " R_CTRL-X CTRL-P: Single match
+  exe "normal RBro\<C-X>\<C-P>\<F2>\<Esc>u"
+  call assert_equal('R-Rc', g:current_modes)
+  " R_CTRL-X CTRL-P + CTRL-P: Single match
+  exe "normal RBro\<C-X>\<C-P>\<C-P>\<F2>\<Esc>u"
+  call assert_equal('R-Rc', g:current_modes)
+  " R_CTRL-X CTRL-L: Multiple matches
+  exe "normal R\<C-X>\<C-L>\<F2>\<Esc>u"
+  call assert_equal('R-Rc', g:current_modes)
+  " R_CTRL-X CTRL-L: Single match
+  exe "normal RBlu\<C-X>\<C-L>\<F2>\<Esc>u"
+  call assert_equal('R-Rc', g:current_modes)
+  " R_CTRL-P: No match
+  exe "normal RCom\<C-P>\<F2>\<Esc>u"
+  call assert_equal('R-Rc', g:current_modes)
+  " R_CTRL-X CTRL-P: No match
+  exe "normal RCom\<C-X>\<C-P>\<F2>\<Esc>u"
+  call assert_equal('R-Rc', g:current_modes)
+  " R_CTRL-X CTRL-L: No match
+  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))
+
+  " How to test operator-pending mode?
+
+  call feedkeys("v", 'xt')
+  call assert_equal('v', mode())
+  call assert_equal('v', mode(1))
+  call feedkeys("\<Esc>V", 'xt')
+  call assert_equal('V', mode())
+  call assert_equal('V', mode(1))
+  call feedkeys("\<Esc>\<C-V>", 'xt')
+  call assert_equal("\<C-V>", mode())
+  call assert_equal("\<C-V>", mode(1))
+  call feedkeys("\<Esc>", 'xt')
+
+  call feedkeys("gh", 'xt')
+  call assert_equal('s', mode())
+  call assert_equal('s', mode(1))
+  call feedkeys("\<Esc>gH", 'xt')
+  call assert_equal('S', mode())
+  call assert_equal('S', mode(1))
+  call feedkeys("\<Esc>g\<C-H>", 'xt')
+  call assert_equal("\<C-S>", mode())
+  call assert_equal("\<C-S>", mode(1))
+  call feedkeys("\<Esc>", 'xt')
+
+  call feedkeys(":echo \<C-R>=Save_mode()\<C-U>\<CR>", 'xt')
+  call assert_equal('c-c', g:current_modes)
+  call feedkeys("gQecho \<C-R>=Save_mode()\<CR>\<CR>vi\<CR>", 'xt')
+  call assert_equal('c-cv', g:current_modes)
+  " How to test Ex mode?
+
+  bwipe!
+  iunmap <F2>
+  set complete&
+endfunc
+
+func Test_getbufvar()
+  let bnr = bufnr('%')
+  let b:var_num = '1234'
+  let def_num = '5678'
+  call assert_equal('1234', getbufvar(bnr, 'var_num'))
+  call assert_equal('1234', getbufvar(bnr, 'var_num', def_num))
+
+  let bd = getbufvar(bnr, '')
+  call assert_equal('1234', bd['var_num'])
+  call assert_true(exists("bd['changedtick']"))
+  call assert_equal(2, len(bd))
+
+  let bd2 = getbufvar(bnr, '', def_num)
+  call assert_equal(bd, bd2)
+
+  unlet b:var_num
+  call assert_equal(def_num, getbufvar(bnr, 'var_num', def_num))
+  call assert_equal('', getbufvar(bnr, 'var_num'))
+
+  let bd = getbufvar(bnr, '')
+  call assert_equal(1, len(bd))
+  let bd = getbufvar(bnr, '',def_num)
+  call assert_equal(1, len(bd))
+
+  call assert_equal('', getbufvar(9999, ''))
+  call assert_equal(def_num, getbufvar(9999, '', def_num))
+  unlet def_num
+
+  call assert_equal(0, getbufvar(bnr, '&autoindent'))
+  call assert_equal(0, getbufvar(bnr, '&autoindent', 1))
+
+  " Open new window with forced option values
+  set fileformats=unix,dos
+  new ++ff=dos ++bin ++enc=iso-8859-2
+  call assert_equal('dos', getbufvar(bufnr('%'), '&fileformat'))
+  call assert_equal(1, getbufvar(bufnr('%'), '&bin'))
+  call assert_equal('iso-8859-2', getbufvar(bufnr('%'), '&fenc'))
+  close
+
+  set fileformats&
+endfunc
+
+func Test_bufexists()
+  call assert_equal(0, bufexists('does_not_exist'))
+  call assert_equal(1, bufexists(bufnr('%')))
+  call assert_equal(0, bufexists(0))
+  new Xfoo
+  let bn = bufnr('%')
+  call assert_equal(1, bufexists(bn))
+  call assert_equal(1, bufexists('Xfoo'))
+  call assert_equal(1, bufexists(getcwd() . '/Xfoo'))
+  call assert_equal(1, bufexists(0))
+  bw
+  call assert_equal(0, bufexists(bn))
+  call assert_equal(0, bufexists('Xfoo'))
+endfunc
+
+func Test_last_buffer_nr()
+  call assert_equal(bufnr('$'), last_buffer_nr())
+endfunc
+
+func Test_stridx()
+  call assert_equal(-1, stridx('', 'l'))
+  call assert_equal(0,  stridx('', ''))
+  call assert_equal(0,  stridx('hello', ''))
+  call assert_equal(-1, stridx('hello', 'L'))
+  call assert_equal(2,  stridx('hello', 'l', -1))
+  call assert_equal(2,  stridx('hello', 'l', 0))
+  call assert_equal(2,  stridx('hello', 'l', 1))
+  call assert_equal(3,  stridx('hello', 'l', 3))
+  call assert_equal(-1, stridx('hello', 'l', 4))
+  call assert_equal(-1, stridx('hello', 'l', 10))
+  call assert_equal(2,  stridx('hello', 'll'))
+  call assert_equal(-1, stridx('hello', 'hello world'))
+endfunc
+
+func Test_strridx()
+  call assert_equal(-1, strridx('', 'l'))
+  call assert_equal(0,  strridx('', ''))
+  call assert_equal(5,  strridx('hello', ''))
+  call assert_equal(-1, strridx('hello', 'L'))
+  call assert_equal(3,  strridx('hello', 'l'))
+  call assert_equal(3,  strridx('hello', 'l', 10))
+  call assert_equal(3,  strridx('hello', 'l', 3))
+  call assert_equal(2,  strridx('hello', 'l', 2))
+  call assert_equal(-1, strridx('hello', 'l', 1))
+  call assert_equal(-1, strridx('hello', 'l', 0))
+  call assert_equal(-1, strridx('hello', 'l', -1))
+  call assert_equal(2,  strridx('hello', 'll'))
+  call assert_equal(-1, strridx('hello', 'hello world'))
+endfunc
+
+func Test_matchend()
+  call assert_equal(7,  matchend('testing', 'ing'))
+  call assert_equal(7,  matchend('testing', 'ing', 2))
+  call assert_equal(-1, matchend('testing', 'ing', 5))
+endfunc
+
+func Test_nextnonblank_prevnonblank()
+  new
+insert
+This
+
+
+is
+
+a
+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, 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, prevnonblank(-1))
+  call assert_equal(0, prevnonblank(0))
+  call assert_equal(1, prevnonblank(1))
+  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(6, prevnonblank(6))
+  call assert_equal(7, prevnonblank(7))
+  call assert_equal(0, prevnonblank(8))
+  bw!
+endfunc
+
+func Test_byte2line_line2byte()
+  new
+  call setline(1, ['a', 'bc', 'd'])
+
+  set fileformat=unix
+  call assert_equal([-1, -1, 1, 1, 2, 2, 2, 3, 3, -1],
+  \                 map(range(-1, 8), 'byte2line(v:val)'))
+  call assert_equal([-1, -1, 1, 3, 6, 8, -1],
+  \                 map(range(-1, 5), 'line2byte(v:val)'))
+
+  set fileformat=mac
+  call assert_equal([-1, -1, 1, 1, 2, 2, 2, 3, 3, -1],
+  \                 map(range(-1, 8), 'byte2line(v:val)'))
+  call assert_equal([-1, -1, 1, 3, 6, 8, -1],
+  \                 map(range(-1, 5), 'line2byte(v:val)'))
+
+  set fileformat=dos
+  call assert_equal([-1, -1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, -1],
+  \                 map(range(-1, 11), 'byte2line(v:val)'))
+  call assert_equal([-1, -1, 1, 4, 8, 11, -1],
+  \                 map(range(-1, 5), 'line2byte(v:val)'))
+
+  set fileformat&
+  bw!
+endfunc
+
+func Test_count()
+  let l = ['a', 'a', 'A', 'b']
+  call assert_equal(2, count(l, 'a'))
+  call assert_equal(1, count(l, 'A'))
+  call assert_equal(1, count(l, 'b'))
+  call assert_equal(0, count(l, 'B'))
+
+  call assert_equal(2, count(l, 'a', 0))
+  call assert_equal(1, count(l, 'A', 0))
+  call assert_equal(1, count(l, 'b', 0))
+  call assert_equal(0, count(l, 'B', 0))
+
+  call assert_equal(3, count(l, 'a', 1))
+  call assert_equal(3, count(l, 'A', 1))
+  call assert_equal(1, count(l, 'b', 1))
+  call assert_equal(1, count(l, 'B', 1))
+  call assert_equal(0, count(l, 'c', 1))
+
+  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:')
+
+  let d = {1: 'a', 2: 'a', 3: 'A', 4: 'b'}
+  call assert_equal(2, count(d, 'a'))
+  call assert_equal(1, count(d, 'A'))
+  call assert_equal(1, count(d, 'b'))
+  call assert_equal(0, count(d, 'B'))
+
+  call assert_equal(2, count(d, 'a', 0))
+  call assert_equal(1, count(d, 'A', 0))
+  call assert_equal(1, count(d, 'b', 0))
+  call assert_equal(0, count(d, 'B', 0))
+
+  call assert_equal(3, count(d, 'a', 1))
+  call assert_equal(3, count(d, 'A', 1))
+  call assert_equal(1, count(d, 'b', 1))
+  call assert_equal(1, count(d, 'B', 1))
+  call assert_equal(0, count(d, 'c', 1))
+
+  call assert_fails('call count(d, "a", 0, 1)', 'E474:')
+  call assert_fails('call count("a", "a")', 'E712:')
+endfunc
+
+func Test_changenr()
+  new Xchangenr
+  call assert_equal(0, changenr())
+  norm ifoo
+  call assert_equal(1, changenr())
+  set undolevels=10
+  norm Sbar
+  call assert_equal(2, changenr())
+  undo
+  call assert_equal(1, changenr())
+  redo
+  call assert_equal(2, changenr())
+  bw!
+  set undolevels&
+endfunc
+
+func Test_filewritable()
+  new Xfilewritable
+  write!
+  call assert_equal(1, filewritable('Xfilewritable'))
+
+  call assert_notequal(0, setfperm('Xfilewritable', 'r--r-----'))
+  call assert_equal(0, filewritable('Xfilewritable'))
+
+  call assert_notequal(0, setfperm('Xfilewritable', 'rw-r-----'))
+  call assert_equal(1, filewritable('Xfilewritable'))
+
+  call assert_equal(0, filewritable('doesnotexist'))
+
+  call delete('Xfilewritable')
+  bw!
+endfunc
+
+func Test_hostname()
+  let hostname_vim = hostname()
+  if has('unix')
+    let hostname_system = systemlist('uname -n')[0]
+    call assert_equal(hostname_vim, hostname_system)
+  endif
+endfunc
+
+func Test_getpid()
+  " getpid() always returns the same value within a vim instance.
+  call assert_equal(getpid(), getpid())
+  if has('unix')
+    call assert_equal(systemlist('echo $PPID')[0], string(getpid()))
+  endif
+endfunc
+
+func Test_hlexists()
+  call assert_equal(0, hlexists('does_not_exist'))
+  call assert_equal(0, hlexists('Number'))
+  call assert_equal(0, highlight_exists('does_not_exist'))
+  call assert_equal(0, highlight_exists('Number'))
+  syntax on
+  call assert_equal(0, hlexists('does_not_exist'))
+  call assert_equal(1, hlexists('Number'))
+  call assert_equal(0, highlight_exists('does_not_exist'))
+  call assert_equal(1, highlight_exists('Number'))
+  syntax off
+endfunc
+
+func Test_col()
+  new
+  call setline(1, 'abcdef')
+  norm gg4|mx6|mY2|
+  call assert_equal(2, col('.'))
+  call assert_equal(7, col('$'))
+  call assert_equal(4, col("'x"))
+  call assert_equal(6, col("'Y"))
+  call assert_equal(2, col([1, 2]))
+  call assert_equal(7, col([1, '$']))
+
+  call assert_equal(0, col(''))
+  call assert_equal(0, col('x'))
+  call assert_equal(0, col([2, '$']))
+  call assert_equal(0, col([1, 100]))
+  call assert_equal(0, col([1]))
+  bw!
+endfunc
+
+func Test_balloon_show()
+  if has('balloon_eval')
+    " This won't do anything but must not crash either.
+    call balloon_show('hi!')
+  endif
+endfunc
+
+func Test_setbufvar_options()
+  " This tests that aucmd_prepbuf() and aucmd_restbuf() properly restore the
+  " window layout.
+  call assert_equal(1, winnr('$'))
+  split dummy_preview
+  resize 2
+  set winfixheight winfixwidth
+  let prev_id = win_getid()
+
+  wincmd j
+  let wh = winheight('.')
+  let dummy_buf = bufnr('dummy_buf1', v:true)
+  call setbufvar(dummy_buf, '&buftype', 'nofile')
+  execute 'belowright vertical split #' . dummy_buf
+  call assert_equal(wh, winheight('.'))
+  let dum1_id = win_getid()
+
+  wincmd h
+  let wh = winheight('.')
+  let dummy_buf = bufnr('dummy_buf2', v:true)
+  call setbufvar(dummy_buf, '&buftype', 'nofile')
+  execute 'belowright vertical split #' . dummy_buf
+  call assert_equal(wh, winheight('.'))
+
+  bwipe!
+  call win_gotoid(prev_id)
+  bwipe!
+  call win_gotoid(dum1_id)
+  bwipe!
+endfunc
+
+func Test_redo_in_nested_functions()
+  nnoremap g. :set opfunc=Operator<CR>g@
+  function Operator( type, ... )
+     let @x = 'XXX'
+     execute 'normal! g`[' . (a:type ==# 'line' ? 'V' : 'v') . 'g`]' . '"xp'
+  endfunction
+
+  function! Apply()
+      5,6normal! .
+  endfunction
+
+  new
+  call setline(1, repeat(['some "quoted" text', 'more "quoted" text'], 3))
+  1normal g.i"
+  call assert_equal('some "XXX" text', getline(1))
+  3,4normal .
+  call assert_equal('some "XXX" text', getline(3))
+  call assert_equal('more "XXX" text', getline(4))
+  call Apply()
+  call assert_equal('some "XXX" text', getline(5))
+  call assert_equal('more "XXX" text', getline(6))
+  bwipe!
+
+  nunmap g.
+  delfunc Operator
+  delfunc Apply
+endfunc
diff --git a/src/testdir/test_ga.vim b/src/testdir/test_ga.vim
new file mode 100644 (file)
index 0000000..f9357dd
--- /dev/null
@@ -0,0 +1,37 @@
+" Test ga normal command, and :ascii Ex command.
+func Do_ga(c)
+  call setline(1, a:c)
+  let l:a = execute("norm 1goga")
+  let l:b = execute("ascii")
+  call assert_equal(l:a, l:b)
+  return l:a
+endfunc
+
+func Test_ga_command()
+  new
+  set display=uhex
+  call assert_equal("\nNUL",                            Do_ga(''))
+  call assert_equal("\n<<01>>  1,  Hex 01,  Octal 001", Do_ga("\x01"))
+  call assert_equal("\n<<09>>  9,  Hex 09,  Octal 011", Do_ga("\t"))
+
+  set display=
+  call assert_equal("\nNUL",                             Do_ga(''))
+  call assert_equal("\n<^A>  1,  Hex 01,  Octal 001",    Do_ga("\x01"))
+  call assert_equal("\n<^I>  9,  Hex 09,  Octal 011",    Do_ga("\t"))
+
+  call assert_equal("\n<e>  101,  Hex 65,  Octal 145",   Do_ga('e'))
+
+  if !has('multi_byte')
+    return
+  endif
+
+  " Test a few multi-bytes characters.
+  call assert_equal("\n<é> 233, Hex 00e9, Octal 351",    Do_ga('é'))
+  call assert_equal("\n<ẻ> 7867, Hex 1ebb, Octal 17273", Do_ga('ẻ'))
+
+  " Test with combining characters.
+  call assert_equal("\n<e>  101,  Hex 65,  Octal 145 < ́> 769, Hex 0301, Octal 1401", Do_ga("e\u0301"))
+  call assert_equal("\n<e>  101,  Hex 65,  Octal 145 < ́> 769, Hex 0301, Octal 1401 < ̱> 817, Hex 0331, Octal 1461", Do_ga("e\u0301\u0331"))
+  call assert_equal("\n<e>  101,  Hex 65,  Octal 145 < ́> 769, Hex 0301, Octal 1401 < ̱> 817, Hex 0331, Octal 1461 < ̸> 824, Hex 0338, Octal 1470", Do_ga("e\u0301\u0331\u0338"))
+  bwipe!
+endfunc
diff --git a/src/testdir/test_global.vim b/src/testdir/test_global.vim
new file mode 100644 (file)
index 0000000..be8aa69
--- /dev/null
@@ -0,0 +1,11 @@
+
+func Test_yank_put_clipboard()
+  new
+  call setline(1, ['a', 'b', 'c'])
+  set clipboard=unnamed
+  g/^/normal yyp
+  call assert_equal(['a', 'a', 'b', 'b', 'c', 'c'], getline(1, 6))
+
+  set clipboard&
+  bwipe!
+endfunc
index d0daeeb..ea67fe7 100644 (file)
@@ -273,3 +273,39 @@ func Test_gd_string_only()
        \ ]
   call XTest_goto_decl('gd', lines, 5, 10)
 endfunc
+
+" Check that setting 'cursorline' does not change curswant
+func Test_cursorline_keep_col()
+  new
+  call setline(1, ['long long long line', 'short line'])
+  normal ggfi
+  let pos = getcurpos()
+  normal j
+  set cursorline
+  normal k
+  call assert_equal(pos, getcurpos())
+  bwipe!
+  set nocursorline
+endfunc
+
+func Test_gd_local_block()
+  let lines = [
+       \ '  int main()',
+       \ '{',
+       \ '  char *a = "NOT NULL";',
+       \ '  if(a)',
+       \ '  {',
+       \ '    char *b = a;',
+       \ '    printf("%s\n", b);',
+       \ '  }',
+       \ '  else',
+       \ '  {',
+       \ '    char *b = "NULL";',
+       \ '    return b;',
+       \ '  }',
+       \ '',
+       \ '  return 0;',
+       \ '}',
+  \ ]
+  call XTest_goto_decl('1gd', lines, 11, 11)
+endfunc
index d95d991..f044f3a 100644 (file)
@@ -4,19 +4,14 @@ if !has('gui') || ($DISPLAY == "" && !has('gui_running'))
   finish
 endif
 
-" For KDE set a font, empty 'guifont' may cause a hang.
-func SetUp()
-  if has("gui_kde")
-    set guifont=Courier\ 10\ Pitch/8/-1/5/50/0/0/0/0/0
-  endif
+source setup_gui.vim
 
-  " Gnome insists on creating $HOME/.gnome2/..
-  call mkdir('Xhome')
-  let $HOME = fnamemodify('Xhome', ':p')
+func Setup()
+  call GUISetUpCommon()
 endfunc
 
 func TearDown()
-  call delete('Xhome', 'rf')
+  call GUITearDownCommon()
 endfunc
 
 " Test for resetting "secure" flag after GUI has started.
@@ -27,10 +22,674 @@ func Test_1_set_secure()
   call assert_equal(1, has('gui_running'))
 endfunc
 
+" As for non-GUI, a balloon_show() test was already added with patch 8.0.0401
+func Test_balloon_show()
+  if has('balloon_eval')
+    " This won't do anything but must not crash either.
+    call balloon_show('hi!')
+  endif
+endfunc
+
+func Test_colorscheme()
+  let colorscheme_saved = exists('g:colors_name') ? g:colors_name : 'default'
+
+  colorscheme torte
+  redraw!
+  sleep 200m
+  call assert_equal('dark', &background)
+
+  exec 'colorscheme' colorscheme_saved
+  redraw!
+endfunc
+
+func Test_getfontname_with_arg()
+  let skipped = ''
+
+  if !g:x11_based_gui
+    let skipped = g:not_implemented
+  elseif has('gui_athena') || has('gui_motif')
+    " Invalid font name. The result should be an empty string.
+    call assert_equal('', getfontname('notexist'))
+
+    " Valid font name. This is usually the real name of 7x13 by default.
+    let fname = '-Misc-Fixed-Medium-R-Normal--13-120-75-75-C-70-ISO8859-1'
+    call assert_match(fname, getfontname(fname))
+
+  elseif has('gui_gtk2') || has('gui_gnome') || has('gui_gtk3')
+    " Invalid font name. The result should be the name plus the default size.
+    call assert_equal('notexist 10', getfontname('notexist'))
+
+    " Valid font name. This is usually the real name of Monospace by default.
+    let fname = 'Bitstream Vera Sans Mono 12'
+    call assert_equal(fname, getfontname(fname))
+  endif
+
+  if !empty(skipped)
+    throw skipped
+  endif
+endfunc
+
+func Test_getfontname_without_arg()
+  let skipped = ''
+
+  let fname = getfontname()
+
+  if !g:x11_based_gui
+    let skipped = g:not_implemented
+  elseif has('gui_kde')
+    " 'expected' is the value specified by SetUp() above.
+    call assert_equal('Courier 10 Pitch/8/-1/5/50/0/0/0/0/0', fname)
+  elseif has('gui_athena') || has('gui_motif')
+    " 'expected' is DFLT_FONT of gui_x11.c or its real name.
+    let pat = '\(7x13\)\|\(\c-Misc-Fixed-Medium-R-Normal--13-120-75-75-C-70-ISO8859-1\)'
+    call assert_match(pat, fname)
+  elseif has('gui_gtk2') || has('gui_gnome') || has('gui_gtk3')
+    " 'expected' is DEFAULT_FONT of gui_gtk_x11.c.
+    call assert_equal('Monospace 10', fname)
+  endif
+
+  if !empty(skipped)
+    throw skipped
+  endif
+endfunc
+
+func Test_getwinpos()
+  call assert_match('Window position: X \d\+, Y \d\+', execute('winpos'))
+  call assert_true(getwinposx() >= 0)
+  call assert_true(getwinposy() >= 0)
+endfunc
+
+func Test_quoteplus()
+  let skipped = ''
+
+  if !g:x11_based_gui
+    let skipped = g:not_supported . 'quoteplus'
+  else
+    let quoteplus_saved = @+
+
+    let test_call     = 'Can you hear me?'
+    let test_response = 'Yes, I can.'
+    let vim_exe = exepath(v:progpath)
+    let testee = 'VIMRUNTIME=' . $VIMRUNTIME . '; export VIMRUNTIME;'
+          \ . vim_exe
+         \ . ' -u NONE -U NONE --noplugin --not-a-term -c ''%s'''
+    " Ignore the "failed to create input context" error.
+    let cmd = 'call test_ignore_error("E285") | '
+         \ . 'gui -f | '
+         \ . 'call feedkeys("'
+          \ . '\"+p'
+          \ . ':s/' . test_call . '/' . test_response . '/\<CR>'
+          \ . '\"+yis'
+          \ . ':q!\<CR>", "tx")'
+    let run_vimtest = printf(testee, cmd)
+
+    " Set the quoteplus register to test_call, and another gvim will launched.
+    " Then, it first tries to paste the content of its own quotedplus register
+    " onto it.  Second, it tries to substitute test_responce for the pasted
+    " sentence.  If the sentence is identical to test_call, the substitution
+    " should succeed.  Third, it tries to yank the result of the substitution
+    " to its own quoteplus register, and last it quits.  When system()
+    " returns, the content of the quoteplus register should be identical to
+    " test_response if those quoteplus registers are synchronized properly
+    " with/through the X11 clipboard.
+    let @+ = test_call
+    call system(run_vimtest)
+    call assert_equal(test_response, @+)
+
+    let @+ = quoteplus_saved
+  endif
+
+  if !empty(skipped)
+    throw skipped
+  endif
+endfunc
+
+func Test_set_background()
+  let background_saved = &background
+
+  set background&
+  call assert_equal('light', &background)
+
+  set background=dark
+  call assert_equal('dark', &background)
+
+  let &background = background_saved
+endfunc
+
+func Test_set_balloondelay()
+  if !exists('+balloondelay')
+    return
+  endif
+
+  let balloondelay_saved = &balloondelay
+
+  " Check if the default value is identical to that described in the manual.
+  set balloondelay&
+  call assert_equal(600, &balloondelay)
+
+  " Edge cases
+
+  " XXX This fact should be hidden so that people won't be tempted to write
+  " plugin/TimeMachine.vim.  TODO Add reasonable range checks to the source
+  " code.
+  set balloondelay=-1
+  call assert_equal(-1, &balloondelay)
+
+  " Though it's possible to interpret the zero delay to be 'as soon as
+  " possible' or even 'indefinite', its actual meaning depends on the GUI
+  " toolkit in use after all.
+  set balloondelay=0
+  call assert_equal(0, &balloondelay)
+
+  set balloondelay=1
+  call assert_equal(1, &balloondelay)
+
+  " Since p_bdelay is of type long currently, the upper bound can be
+  " impractically huge and machine-dependent.  Practically, it's sufficient
+  " to check if balloondelay works with 0x7fffffff (32 bits) for now.
+  set balloondelay=2147483647
+  call assert_equal(2147483647, &balloondelay)
+
+  let &balloondelay = balloondelay_saved
+endfunc
+
+func Test_set_ballooneval()
+  if !exists('+ballooneval')
+    return
+  endif
+
+  let ballooneval_saved = &ballooneval
+
+  set ballooneval&
+  call assert_equal(0, &ballooneval)
+
+  set ballooneval
+  call assert_notequal(0, &ballooneval)
+
+  set noballooneval
+  call assert_equal(0, &ballooneval)
+
+  let &ballooneval = ballooneval_saved
+endfunc
+
+func Test_set_balloonexpr()
+  if !exists('+balloonexpr')
+    return
+  endif
+
+  let balloonexpr_saved = &balloonexpr
+
+  " Default value
+  set balloonexpr&
+  call assert_equal('', &balloonexpr)
+
+  " User-defined function
+  new
+  func MyBalloonExpr()
+      return 'Cursor is at line ' . v:beval_lnum .
+             \', column ' . v:beval_col .
+             \ ' of file ' .  bufname(v:beval_bufnr) .
+             \ ' on word "' . v:beval_text . '"' .
+             \ ' in window ' . v:beval_winid . ' (#' . v:beval_winnr . ')'
+  endfunc
+  setl balloonexpr=MyBalloonExpr()
+  setl ballooneval
+  call assert_equal('MyBalloonExpr()', &balloonexpr)
+  " TODO Read non-empty text, place the pointer at a character of a word,
+  " and check if the content of the balloon is the smae as what is expected.
+  " Also, check if textlock works as expected.
+  setl balloonexpr&
+  call assert_equal('', &balloonexpr)
+  delfunc MyBalloonExpr
+  bwipe!
+
+  " Multiline support
+  if has('balloon_multiline')
+    " Multiline balloon using NL
+    new
+    func MyBalloonFuncForMultilineUsingNL()
+      return "Multiline\nSuppported\nBalloon\nusing NL"
+    endfunc
+    setl balloonexpr=MyBalloonFuncForMultilineUsingNL()
+    setl ballooneval
+    call assert_equal('MyBalloonFuncForMultilineUsingNL()', &balloonexpr)
+    " TODO Read non-empty text, place the pointer at a character of a word,
+    " and check if the content of the balloon is the smae as what is
+    " expected.  Also, check if textlock works as expected.
+    setl balloonexpr&
+    delfunc MyBalloonFuncForMultilineUsingNL
+    bwipe!
+
+    " Multiline balloon using List
+    new
+    func MyBalloonFuncForMultilineUsingList()
+      return [ 'Multiline', 'Suppported', 'Balloon', 'using List' ]
+    endfunc
+    setl balloonexpr=MyBalloonFuncForMultilineUsingList()
+    setl ballooneval
+    call assert_equal('MyBalloonFuncForMultilineUsingList()', &balloonexpr)
+    " TODO Read non-empty text, place the pointer at a character of a word,
+    " and check if the content of the balloon is the smae as what is
+    " expected.  Also, check if textlock works as expected.
+    setl balloonexpr&
+    delfunc MyBalloonFuncForMultilineUsingList
+    bwipe!
+  endif
+
+  let &balloonexpr = balloonexpr_saved
+endfunc
+
+" Invalid arguments are tested with test_options in conjunction with segfaults
+" caused by them (Patch 8.0.0357, 24922ec233).
+func Test_set_guicursor()
+  let guicursor_saved = &guicursor
+
+  let default = [
+        \ "n-v-c:block-Cursor/lCursor",
+        \ "ve:ver35-Cursor",
+        \ "o:hor50-Cursor",
+        \ "i-ci:ver25-Cursor/lCursor",
+        \ "r-cr:hor20-Cursor/lCursor",
+        \ "sm:block-Cursor-blinkwait175-blinkoff150-blinkon175"
+        \ ]
+
+  " Default Value
+  set guicursor&
+  call assert_equal(join(default, ','), &guicursor)
+
+  " Argument List Example 1
+  let opt_list = copy(default)
+  let opt_list[0] = "n-c-v:block-nCursor"
+  exec "set guicursor=" . join(opt_list, ',')
+  call assert_equal(join(opt_list, ','), &guicursor)
+  unlet opt_list
+
+  " Argument List Example 2
+  let opt_list = copy(default)
+  let opt_list[3] = "i-ci:ver30-iCursor-blinkwait300-blinkon200-blinkoff150"
+  exec "set guicursor=" . join(opt_list, ',')
+  call assert_equal(join(opt_list, ','), &guicursor)
+  unlet opt_list
+
+  " 'a' Mode
+  set guicursor&
+  let &guicursor .= ',a:blinkon0'
+  call assert_equal(join(default, ',') . ",a:blinkon0", &guicursor)
+
+  let &guicursor = guicursor_saved
+endfunc
+
+func Test_set_guifont()
+  let skipped = ''
+
+  let guifont_saved = &guifont
+  if has('xfontset')
+    " Prevent 'guifontset' from canceling 'guifont'.
+    let guifontset_saved = &guifontset
+    set guifontset=
+  endif
+
+  if !g:x11_based_gui
+    let skipped = g:not_implemented
+  elseif has('gui_athena') || has('gui_motif')
+    " Non-empty font list with invalid font names.
+    "
+    " This test is twofold: (1) It checks if the command fails as expected
+    " when there are no loadable fonts found in the list. (2) It checks if
+    " 'guifont' remains the same after the command loads none of the fonts
+    " listed.
+    let flist = &guifont
+    call assert_fails('set guifont=-notexist1-*,-notexist2-*')
+    call assert_equal(flist, &guifont)
+
+    " Non-empty font list with a valid font name.  Should pick up the first
+    " valid font.
+    set guifont=-notexist1-*,fixed,-notexist2-*
+    let pat = '\(fixed\)\|\(\c-Misc-Fixed-Medium-R-SemiCondensed--13-120-75-75-C-60-ISO8859-1\)'
+    call assert_match(pat, getfontname())
+
+    " Empty list. Should fallback to the built-in default.
+    set guifont=
+    let pat = '\(7x13\)\|\(\c-Misc-Fixed-Medium-R-Normal--13-120-75-75-C-70-ISO8859-1\)'
+    call assert_match(pat, getfontname())
+
+  elseif has('gui_gtk2') || has('gui_gnome') || has('gui_gtk3')
+    " For GTK, what we refer to as 'font names' in our manual are actually
+    " 'initial font patterns'.  A valid font which matches the 'canonical font
+    " pattern' constructed from a given 'initial pattern' is to be looked up
+    " and loaded.  That explains why the GTK GUIs appear to accept 'invalid
+    " font names'.
+    "
+    " Non-empty list.  Should always pick up the first element, no matter how
+    " strange it is, as explained above.
+    set guifont=(´・ω・`)\ 12,Courier\ 12
+    call assert_equal('(´・ω・`) 12', getfontname())
+
+    " Empty list. Should fallback to the built-in default.
+    set guifont=
+    call assert_equal('Monospace 10', getfontname())
+  endif
+
+  if has('xfontset')
+    let &guifontset = guifontset_saved
+  endif
+  let &guifont = guifont_saved
+
+  if !empty(skipped)
+    throw skipped
+  endif
+endfunc
+
+func Test_set_guifontset()
+  let skipped = ''
+
+  if !has('xfontset')
+    let skipped = g:not_supported . 'xfontset'
+  else
+    let ctype_saved = v:ctype
+
+    " First, since XCreateFontSet(3) is very sensitive to locale, fonts must
+    " be chosen meticulously.
+    let font_head = '-misc-fixed-medium-r-normal--14'
+
+    let font_aw70 = font_head . '-130-75-75-c-70'
+    let font_aw140 = font_head . '-130-75-75-c-140'
+
+    let font_jisx0201 = font_aw70 . '-jisx0201.1976-0'
+    let font_jisx0208 = font_aw140 . '-jisx0208.1983-0'
+
+    let full_XLFDs = join([ font_jisx0208, font_jisx0201 ], ',')
+    let short_XLFDs = join([ font_aw140, font_aw70 ], ',')
+    let singleton = font_head . '-*'
+    let aliases = 'k14,r14'
+
+    " Second, among 'locales', look up such a locale that gets 'set
+    " guifontset=' to work successfully with every fontset specified with
+    " 'fontsets'.
+    let locales = [ 'ja_JP.UTF-8', 'ja_JP.eucJP', 'ja_JP.SJIS' ]
+    let fontsets = [ full_XLFDs, short_XLFDs, singleton, aliases ]
+
+    let feasible = 0
+    for locale in locales
+      try
+        exec 'language ctype' locale
+      catch /^Vim\%((\a\+)\)\=:E197/
+        continue
+      endtry
+      let done = 0
+      for fontset in fontsets
+        try
+          exec 'set guifontset=' . fontset
+        catch /^Vim\%((\a\+)\)\=:E\%(250\|252\|234\|597\|598\)/
+          break
+        endtry
+        let done += 1
+      endfor
+      if done == len(fontsets)
+        let feasible = 1
+        break
+      endif
+    endfor
+
+    " Third, give a set of tests if it is found feasible.
+    if !feasible
+      let skipped = g:not_hosted
+    else
+      " N.B. 'v:ctype' has already been set to an appropriate value in the
+      " previous loop.
+      for fontset in fontsets
+        exec 'set guifontset=' . fontset
+        call assert_equal(fontset, &guifontset)
+      endfor
+    endif
+
+    " Finally, restore ctype.
+    exec 'language ctype' ctype_saved
+  endif
+
+  if !empty(skipped)
+    throw skipped
+  endif
+endfunc
+
+func Test_set_guifontwide()
+  let skipped = ''
+
+  if !g:x11_based_gui
+    let skipped = g:not_implemented
+  elseif has('gui_gtk')
+    let guifont_saved = &guifont
+    let guifontwide_saved = &guifontwide
+
+    let fc_match = exepath('fc-match')
+    if empty(fc_match)
+      let skipped = g:not_hosted
+    else
+      let &guifont = system('fc-match -f "%{family[0]} %{size}" monospace:size=10:lang=en')
+      let wide = system('fc-match -f "%{family[0]} %{size}" monospace:size=10:lang=ja')
+      exec 'set guifontwide=' . fnameescape(wide)
+      call assert_equal(wide, &guifontwide)
+    endif
+
+    let &guifontwide = guifontwide_saved
+    let &guifont = guifont_saved
+
+  elseif has('gui_athena') || has('gui_motif')
+    " guifontwide is premised upon the xfontset feature.
+    if !has('xfontset')
+      let skipped = g:not_supported . 'xfontset'
+    else
+      let encoding_saved    = &encoding
+      let guifont_saved     = &guifont
+      let guifontset_saved  = &guifontset
+      let guifontwide_saved = &guifontwide
+
+      let nfont = '-misc-fixed-medium-r-normal-*-18-120-100-100-c-90-iso10646-1'
+      let wfont = '-misc-fixed-medium-r-normal-*-18-120-100-100-c-180-iso10646-1'
+
+      set encoding=utf-8
+
+      " Case 1: guifontset is empty
+      set guifontset=
+
+      " Case 1-1: Automatic selection
+      set guifontwide=
+      exec 'set guifont=' . nfont
+      call assert_equal(wfont, &guifontwide)
+
+      " Case 1-2: Manual selection
+      exec 'set guifontwide=' . wfont
+      exec 'set guifont=' . nfont
+      call assert_equal(wfont, &guifontwide)
+
+      " Case 2: guifontset is invalid
+      try
+        set guifontset=-*-notexist-*
+        call assert_report("'set guifontset=-*-notexist-*' should have failed")
+      catch
+        call assert_exception('E598')
+      endtry
+      " Set it to an invalid value brutally for preparation.
+      let &guifontset = '-*-notexist-*'
+
+      " Case 2-1: Automatic selection
+      set guifontwide=
+      exec 'set guifont=' . nfont
+      call assert_equal(wfont, &guifontwide)
+
+      " Case 2-2: Manual selection
+      exec 'set guifontwide=' . wfont
+      exec 'set guifont=' . nfont
+      call assert_equal(wfont, &guifontwide)
+
+      let &guifontwide = guifontwide_saved
+      let &guifontset  = guifontset_saved
+      let &guifont     = guifont_saved
+      let &encoding    = encoding_saved
+    endif
+  endif
+
+  if !empty(skipped)
+    throw skipped
+  endif
+endfunc
+
+func Test_set_guiheadroom()
+  let skipped = ''
+
+  if !g:x11_based_gui
+    let skipped = g:not_supported . 'guiheadroom'
+  else
+    " Since this script is to be read together with '-U NONE', the default
+    " value must be preserved.
+    call assert_equal(50, &guiheadroom)
+  endif
+
+  if !empty(skipped)
+    throw skipped
+  endif
+endfunc
+
+func Test_set_guioptions()
+  let guioptions_saved = &guioptions
+  let duration = '200m'
+
+  if has('win32')
+    " Default Value
+    set guioptions&
+    call assert_equal('egmrLtT', &guioptions)
+
+  else
+    " Default Value
+    set guioptions&
+    call assert_equal('aegimrLtT', &guioptions)
+
+    " To activate scrollbars of type 'L' or 'R'.
+    wincmd v
+    redraw!
+
+    " Remove all default GUI ornaments
+    set guioptions-=T
+    exec 'sleep' . duration
+    call assert_equal('aegimrLt', &guioptions)
+    set guioptions-=t
+    exec 'sleep' . duration
+    call assert_equal('aegimrL', &guioptions)
+    set guioptions-=L
+    exec 'sleep' . duration
+    call assert_equal('aegimr', &guioptions)
+    set guioptions-=r
+    exec 'sleep' . duration
+    call assert_equal('aegim', &guioptions)
+    set guioptions-=m
+    exec 'sleep' . duration
+    call assert_equal('aegi', &guioptions)
+
+    " Try non-default GUI ornaments
+    set guioptions+=l
+    exec 'sleep' . duration
+    call assert_equal('aegil', &guioptions)
+    set guioptions-=l
+    exec 'sleep' . duration
+    call assert_equal('aegi', &guioptions)
+
+    set guioptions+=R
+    exec 'sleep' . duration
+    call assert_equal('aegiR', &guioptions)
+    set guioptions-=R
+    exec 'sleep' . duration
+    call assert_equal('aegi', &guioptions)
+
+    set guioptions+=b
+    exec 'sleep' . duration
+    call assert_equal('aegib', &guioptions)
+    set guioptions+=h
+    exec 'sleep' . duration
+    call assert_equal('aegibh', &guioptions)
+    set guioptions-=h
+    exec 'sleep' . duration
+    call assert_equal('aegib', &guioptions)
+    set guioptions-=b
+    exec 'sleep' . duration
+    call assert_equal('aegi', &guioptions)
+
+    set guioptions+=v
+    exec 'sleep' . duration
+    call assert_equal('aegiv', &guioptions)
+    set guioptions-=v
+    exec 'sleep' . duration
+    call assert_equal('aegi', &guioptions)
+
+    if has('gui_motif')
+      set guioptions+=F
+      exec 'sleep' . duration
+      call assert_equal('aegiF', &guioptions)
+      set guioptions-=F
+      exec 'sleep' . duration
+      call assert_equal('aegi', &guioptions)
+    endif
+
+    " Restore GUI ornaments to the default state.
+    set guioptions+=m
+    exec 'sleep' . duration
+    call assert_equal('aegim', &guioptions)
+    set guioptions+=r
+    exec 'sleep' . duration
+    call assert_equal('aegimr', &guioptions)
+    set guioptions+=L
+    exec 'sleep' . duration
+    call assert_equal('aegimrL', &guioptions)
+    set guioptions+=t
+    exec 'sleep' . duration
+    call assert_equal('aegimrLt', &guioptions)
+    set guioptions+=T
+    exec 'sleep' . duration
+    call assert_equal("aegimrLtT", &guioptions)
+
+    wincmd o
+    redraw!
+  endif
+
+  let &guioptions = guioptions_saved
+endfunc
+
+func Test_set_guipty()
+  let guipty_saved = &guipty
+
+  " Default Value
+  set guipty&
+  call assert_equal(1, &guipty)
+
+  set noguipty
+  call assert_equal(0, &guipty)
+
+  let &guipty = guipty_saved
+endfunc
+
 func Test_shell_command()
   new
   r !echo hello
   call assert_equal('hello', substitute(getline(2), '\W', '', 'g'))
   bwipe!
-  call assert_true(1, match(execute('winpos'), 'Window position: X \d\+, Y \d\+') >= 0)
+endfunc
+
+func Test_syntax_colortest()
+  runtime syntax/colortest.vim
+  redraw!
+  sleep 200m
+  bwipe!
+endfunc
+
+func Test_set_term()
+  " It's enough to check the current value since setting 'term' to anything
+  " other than builtin_gui makes no sense at all.
+  call assert_equal('builtin_gui', &term)
+endfunc
+
+func Test_windowid_variable()
+  if g:x11_based_gui || has('win32')
+    call assert_true(v:windowid > 0)
+  else
+    call assert_equal(0, v:windowid)
+  endif
 endfunc
diff --git a/src/testdir/test_gui_init.vim b/src/testdir/test_gui_init.vim
new file mode 100644 (file)
index 0000000..21e5bb6
--- /dev/null
@@ -0,0 +1,60 @@
+" Tests specifically for the GUI features/options that need to be set up at
+" startup to take effect at runtime.
+
+if !has('gui') || ($DISPLAY == "" && !has('gui_running'))
+  finish
+endif
+
+source setup_gui.vim
+
+func Setup()
+  call GUISetUpCommon()
+endfunc
+
+func TearDown()
+  call GUITearDownCommon()
+endfunc
+
+" Ignore the "failed to create input context" error.
+call test_ignore_error('E285')
+
+" Start the GUI now, in the foreground.
+gui -f
+
+func Test_set_guiheadroom()
+  let skipped = ''
+
+  if !g:x11_based_gui
+    let skipped = g:not_supported . 'guiheadroom'
+  else
+    " The 'expected' value must be consistent with the value specified with
+    " gui_init.vim.
+    call assert_equal(0, &guiheadroom)
+  endif
+
+  if !empty(skipped)
+    throw skipped
+  endif
+endfunc
+
+func Test_set_guioptions_for_M()
+  sleep 200ms
+  " Check if the 'M' option is included.
+  call assert_match('.*M.*', &guioptions)
+endfunc
+
+func Test_set_guioptions_for_p()
+  let skipped = ''
+
+  if !g:x11_based_gui
+    let skipped = g:not_supported . '''p'' of guioptions'
+  else
+    sleep 200ms
+    " Check if the 'p' option is included.
+    call assert_match('.*p.*', &guioptions)
+  endif
+
+  if !empty(skipped)
+    throw skipped
+  endif
+endfunc
diff --git a/src/testdir/test_help.vim b/src/testdir/test_help.vim
new file mode 100644 (file)
index 0000000..5a35b69
--- /dev/null
@@ -0,0 +1,15 @@
+" Tests for :help
+
+func Test_help_restore_snapshot()
+  help
+  set buftype=
+  help
+  edit x
+  help
+  helpclose
+endfunc
+
+func Test_help_errors()
+  call assert_fails('help doesnotexist', 'E149:')
+  call assert_fails('help!', 'E478:')
+endfunc
index 778bd9c..51b006c 100644 (file)
@@ -6,6 +6,52 @@ func Test_help_tagjump()
   call assert_true(getline('.') =~ '\*help.txt\*')
   helpclose
 
+  help |
+  call assert_equal("help", &filetype)
+  call assert_true(getline('.') =~ '\*bar\*')
+  helpclose
+
+  help "*
+  call assert_equal("help", &filetype)
+  call assert_true(getline('.') =~ '\*quotestar\*')
+  helpclose
+
+  help sm?le
+  call assert_equal("help", &filetype)
+  call assert_true(getline('.') =~ '\*:smile\*')
+  helpclose
+
+  help :?
+  call assert_equal("help", &filetype)
+  call assert_true(getline('.') =~ '\*:?\*')
+  helpclose
+
+  help FileW*Post
+  call assert_equal("help", &filetype)
+  call assert_true(getline('.') =~ '\*FileWritePost\*')
+  helpclose
+
+  help `ls`
+  call assert_equal("help", &filetype)
+  call assert_true(getline('.') =~ '\*:ls\*')
+  helpclose
+
+  help ^X
+  call assert_equal("help", &filetype)
+  call assert_true(getline('.') =~ '\*CTRL-X\*')
+  helpclose
+
+  help i_^_CTRL-D
+  call assert_equal("help", &filetype)
+  call assert_true(getline('.') =~ '\*i_^_CTRL-D\*')
+  helpclose
+
+  exec "help \<C-V>"
+  call assert_equal("help", &filetype)
+  call assert_true(getline('.') =~ '\*CTRL-V\*')
+  helpclose
+
+
   exec "help! ('textwidth'"
   call assert_equal("help", &filetype)
   call assert_true(getline('.') =~ "\\*'textwidth'\\*")
@@ -35,6 +81,16 @@ func Test_help_tagjump()
   call assert_equal("help", &filetype)
   call assert_true(getline('.') =~ '\*{address}\*')
   helpclose
+
+  exusage
+  call assert_equal("help", &filetype)
+  call assert_true(getline('.') =~ '\*:index\*')
+  helpclose
+
+  viusage
+  call assert_equal("help", &filetype)
+  call assert_true(getline('.') =~ '\*normal-index\*')
+  helpclose
 endfunc
 
 let s:langs = ['en', 'ab', 'ja']
@@ -77,17 +133,8 @@ func s:doc_config_teardown()
   endif
 endfunc
 
-func s:get_cmd_compl_list(cmd)
-  let list = []
-  let str = ''
-  for cnt in range(1, 999)
-    call feedkeys(a:cmd . repeat("\<Tab>", cnt) . "'\<C-B>let str='\<CR>", 'tx')
-    if str ==# a:cmd[1:]
-      break
-    endif
-    call add(list, str)
-  endfor
-  return list
+func s:get_help_compl_list(cmd)
+  return getcompletion(a:cmd, 'help')
 endfunc
 
 func Test_help_complete()
@@ -99,49 +146,81 @@ func Test_help_complete()
     if has('multi_lang')
       set helplang=
     endif
-    let list = s:get_cmd_compl_list(":h test")
-    call assert_equal(['h test-col', 'h test-char'], list)
+    let list = s:get_help_compl_list("test")
+    call assert_equal(['test-col', 'test-char'], list)
 
     if has('multi_lang')
       " 'helplang=ab' and help file lang is 'en'
       set helplang=ab
-      let list = s:get_cmd_compl_list(":h test")
-      call assert_equal(['h test-col', 'h test-char'], list)
+      let list = s:get_help_compl_list("test")
+      call assert_equal(['test-col', 'test-char'], list)
 
       " 'helplang=' and help file lang is 'en' and 'ab'
       set rtp+=Xdir1/doc-ab
       set helplang=
-      let list = s:get_cmd_compl_list(":h test")
-      call assert_equal(sort(['h test-col@en', 'h test-col@ab',
-            \             'h test-char@en', 'h test-char@ab']), sort(list))
+      let list = s:get_help_compl_list("test")
+      call assert_equal(sort(['test-col@en', 'test-col@ab',
+            \             'test-char@en', 'test-char@ab']), sort(list))
 
       " 'helplang=ab' and help file lang is 'en' and 'ab'
       set helplang=ab
-      let list = s:get_cmd_compl_list(":h test")
-      call assert_equal(sort(['h test-col', 'h test-col@en',
-            \             'h test-char', 'h test-char@en']), sort(list))
+      let list = s:get_help_compl_list("test")
+      call assert_equal(sort(['test-col', 'test-col@en',
+            \             'test-char', 'test-char@en']), sort(list))
 
       " 'helplang=' and help file lang is 'en', 'ab' and 'ja'
       set rtp+=Xdir1/doc-ja
       set helplang=
-      let list = s:get_cmd_compl_list(":h test")
-      call assert_equal(sort(['h test-col@en', 'h test-col@ab',
-            \             'h test-col@ja', 'h test-char@en',
-            \             'h test-char@ab', 'h test-char@ja']), sort(list))
+      let list = s:get_help_compl_list("test")
+      call assert_equal(sort(['test-col@en', 'test-col@ab',
+            \             'test-col@ja', 'test-char@en',
+            \             'test-char@ab', 'test-char@ja']), sort(list))
 
       " 'helplang=ab' and help file lang is 'en', 'ab' and 'ja'
       set helplang=ab
-      let list = s:get_cmd_compl_list(":h test")
-      call assert_equal(sort(['h test-col', 'h test-col@en',
-            \             'h test-col@ja', 'h test-char',
-            \             'h test-char@en', 'h test-char@ja']), sort(list))
+      let list = s:get_help_compl_list("test")
+      call assert_equal(sort(['test-col', 'test-col@en',
+            \             'test-col@ja', 'test-char',
+            \             'test-char@en', 'test-char@ja']), sort(list))
 
       " 'helplang=ab,ja' and help file lang is 'en', 'ab' and 'ja'
       set helplang=ab,ja
-      let list = s:get_cmd_compl_list(":h test")
-      call assert_equal(sort(['h test-col', 'h test-col@ja',
-            \             'h test-col@en', 'h test-char',
-            \             'h test-char@ja', 'h test-char@en']), sort(list))
+      let list = s:get_help_compl_list("test")
+      call assert_equal(sort(['test-col', 'test-col@ja',
+            \             'test-col@en', 'test-char',
+            \             'test-char@ja', 'test-char@en']), sort(list))
+    endif
+  catch
+    call assert_exception('X')
+  finally
+    call s:doc_config_teardown()
+  endtry
+endfunc
+
+func Test_help_respect_current_file_lang()
+  try
+    let list = []
+    call s:doc_config_setup()
+
+    if has('multi_lang')
+      function s:check_help_file_ext(help_keyword, ext)
+        exec 'help ' . a:help_keyword
+        call assert_equal(a:ext, expand('%:e'))
+        call feedkeys("\<C-]>", 'tx')
+        call assert_equal(a:ext, expand('%:e'))
+        pop
+        helpclose
+      endfunc
+
+      set rtp+=Xdir1/doc-ab
+      set rtp+=Xdir1/doc-ja
+
+      set helplang=ab
+      call s:check_help_file_ext('test-char', 'abx')
+      call s:check_help_file_ext('test-char@ja', 'jax')
+      set helplang=ab,ja
+      call s:check_help_file_ext('test-char@ja', 'jax')
+      call s:check_help_file_ext('test-char@en', 'txt')
     endif
   catch
     call assert_exception('X')
diff --git a/src/testdir/test_hide.vim b/src/testdir/test_hide.vim
new file mode 100644 (file)
index 0000000..128b8ff
--- /dev/null
@@ -0,0 +1,97 @@
+" Tests for :hide command/modifier and 'hidden' option
+
+function SetUp()
+  let s:save_hidden = &hidden
+  let s:save_bufhidden = &bufhidden
+  let s:save_autowrite = &autowrite
+  set nohidden
+  set bufhidden=
+  set noautowrite
+endfunc
+
+function TearDown()
+  let &hidden = s:save_hidden
+  let &bufhidden = s:save_bufhidden
+  let &autowrite = s:save_autowrite
+endfunc
+
+function Test_hide()
+  let orig_bname = bufname('')
+  let orig_winnr = winnr('$')
+
+  new Xf1
+  set modified
+  call assert_fails('edit Xf2')
+  bwipeout! Xf1
+
+  new Xf1
+  set modified
+  edit! Xf2
+  call assert_equal(['Xf2', 2], [bufname(''), winnr('$')])
+  call assert_equal([1, 0], [buflisted('Xf1'), bufloaded('Xf1')])
+  bwipeout! Xf1
+  bwipeout! Xf2
+
+  new Xf1
+  set modified
+  " :hide as a command
+  hide
+  call assert_equal([orig_bname, orig_winnr], [bufname(''), winnr('$')])
+  call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')])
+  bwipeout! Xf1
+
+  new Xf1
+  set modified
+  " :hide as a command with trailing comment
+  hide " comment
+  call assert_equal([orig_bname, orig_winnr], [bufname(''), winnr('$')])
+  call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')])
+  bwipeout! Xf1
+
+  new Xf1
+  set modified
+  " :hide as a command with bar
+  hide | new Xf2 " comment
+  call assert_equal(['Xf2', 2], [bufname(''), winnr('$')])
+  call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')])
+  bwipeout! Xf1
+  bwipeout! Xf2
+
+  new Xf1
+  set modified
+  " :hide as a modifier with trailing comment
+  hide edit Xf2 " comment
+  call assert_equal(['Xf2', 2], [bufname(''), winnr('$')])
+  call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')])
+  bwipeout! Xf1
+  bwipeout! Xf2
+
+  new Xf1
+  set modified
+  " To check that the bar is not recognized to separate commands
+  hide echo "one|two"
+  call assert_equal(['Xf1', 2], [bufname(''), winnr('$')])
+  call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')])
+  bwipeout! Xf1
+
+  " set hidden
+  new Xf1
+  set hidden
+  set modified
+  edit Xf2 " comment
+  call assert_equal(['Xf2', 2], [bufname(''), winnr('$')])
+  call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')])
+  bwipeout! Xf1
+  bwipeout! Xf2
+
+  " set hidden bufhidden=wipe
+  new Xf1
+  set bufhidden=wipe
+  set modified
+  hide edit! Xf2 " comment
+  call assert_equal(['Xf2', 2], [bufname(''), winnr('$')])
+  call assert_equal([0, 0], [buflisted('Xf1'), bufloaded('Xf1')])
+  bwipeout! Xf2
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
index ee6acff..ca31e3f 100644 (file)
@@ -31,6 +31,30 @@ function History_Tests(hist)
   call assert_equal('ls', histget(a:hist, -1))
   call assert_equal(4, histnr(a:hist))
 
+  let a=execute('history ' . a:hist)
+  call assert_match("^\n      #  \\S* history\n      3  buffers\n>     4  ls$", a)
+  let a=execute('history all')
+  call assert_match("^\n      #  .* history\n      3  buffers\n>     4  ls", a)
+
+  if len(a:hist) > 0
+    let a=execute('history ' . a:hist . ' 2')
+    call assert_match("^\n      #  \\S* history$", a)
+    let a=execute('history ' . a:hist . ' 3')
+    call assert_match("^\n      #  \\S* history\n      3  buffers$", a)
+    let a=execute('history ' . a:hist . ' 4')
+    call assert_match("^\n      #  \\S* history\n>     4  ls$", a)
+    let a=execute('history ' . a:hist . ' 3,4')
+    call assert_match("^\n      #  \\S* history\n      3  buffers\n>     4  ls$", a)
+    let a=execute('history ' . a:hist . ' -1')
+    call assert_match("^\n      #  \\S* history\n>     4  ls$", a)
+    let a=execute('history ' . a:hist . ' -2')
+    call assert_match("^\n      #  \\S* history\n      3  buffers$", a)
+    let a=execute('history ' . a:hist . ' -2,')
+    call assert_match("^\n      #  \\S* history\n      3  buffers\n>     4  ls$", a)
+    let a=execute('history ' . a:hist . ' -3')
+    call assert_match("^\n      #  \\S* history$", a)
+  endif
+
   " Test for removing entries matching a pattern
   for i in range(1, 3)
       call histadd(a:hist, 'text_' . i)
@@ -63,3 +87,20 @@ function Test_History()
   call assert_equal(-1, histnr('abc'))
   call assert_fails('call histnr([])', 'E730:')
 endfunction
+
+function Test_Search_history_window()
+  new
+  call setline(1, ['a', 'b', 'a', 'b'])
+  1
+  call feedkeys("/a\<CR>", 'xt')
+  call assert_equal('a', getline('.'))
+  1
+  call feedkeys("/b\<CR>", 'xt')
+  call assert_equal('b', getline('.'))
+  1
+  " select the previous /a command
+  call feedkeys("q/kk\<CR>", 'x!')
+  call assert_equal('a', getline('.'))
+  call assert_equal('a', @/)
+  bwipe!
+endfunc
index e149036..6c3d16c 100644 (file)
@@ -144,12 +144,20 @@ func Test_json_decode()
   call assert_equal(type(v:none), type(json_decode('')))
   call assert_equal("", json_decode('""'))
 
+  " empty key is OK
+  call assert_equal({'': 'ok'}, json_decode('{"": "ok"}'))
+  " but not twice
+  call assert_fails("call json_decode('{\"\": \"ok\", \"\": \"bad\"}')", 'E938:')
+
   call assert_equal({'n': 1}, json_decode('{"n":1,}'))
+  call assert_fails("call json_decode(\"{'n':'1',}\")", 'E474:')
+  call assert_fails("call json_decode(\"'n'\")", 'E474:')
 
   call assert_fails('call json_decode("\"")', "E474:")
   call assert_fails('call json_decode("blah")', "E474:")
-  call assert_fails('call json_decode("true blah")', "E474:")
+  call assert_fails('call json_decode("true blah")', "E488:")
   call assert_fails('call json_decode("<foobar>")', "E474:")
+  call assert_fails('call json_decode("{\"a\":1,\"a\":2}")', "E938:")
 
   call assert_fails('call json_decode("{")', "E474:")
   call assert_fails('call json_decode("{foobar}")', "E474:")
@@ -254,8 +262,11 @@ func Test_js_decode()
   call assert_equal(v:none, js_decode(''))
   call assert_equal(type(v:none), type(js_decode('')))
   call assert_equal("", js_decode('""'))
+  call assert_equal("", js_decode("''"))
 
+  call assert_equal('n', js_decode("'n'"))
   call assert_equal({'n': 1}, js_decode('{"n":1,}'))
+  call assert_equal({'n': '1'}, js_decode("{'n':'1',}"))
 
   call assert_fails('call js_decode("\"")', "E474:")
   call assert_fails('call js_decode("blah")', "E474:")
diff --git a/src/testdir/test_listlbr.in b/src/testdir/test_listlbr.in
deleted file mode 100644 (file)
index d51b2f9..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-Test for linebreak and list option (non-utf8)
-
-STARTTEST
-:so small.vim
-:if !exists("+linebreak") || !has("conceal") | e! test.ok | w! test.out | qa! | endif
-:10new|:vsp|:vert resize 20
-:put =\"\tabcdef hijklmn\tpqrstuvwxyz_1060ABCDEFGHIJKLMNOP \"
-:norm! zt
-:set ts=4 sw=4 sts=4 linebreak sbr=+ wrap
-:fu! ScreenChar(width)
-:      let c=''
-:      for j in range(1,4)
-:          for i in range(1,a:width)
-:              let c.=nr2char(screenchar(j, i))
-:          endfor
-:           let c.="\n"
-:      endfor
-:      return c
-:endfu
-:fu! DoRecordScreen()
-:      wincmd l
-:      $put =printf(\"\n%s\", g:test)
-:      $put =g:line
-:      wincmd p
-:endfu
-:"
-:let g:test="Test 1: set linebreak"
-:redraw!
-:let line=ScreenChar(winwidth(0))
-:call DoRecordScreen()
-:"
-:let g:test="Test 2: set linebreak + set list"
-:set linebreak list listchars=
-:redraw!
-:let line=ScreenChar(winwidth(0))
-:call DoRecordScreen()
-:"
-:let g:test ="Test 3: set linebreak nolist"
-:set nolist linebreak
-:redraw!
-:let line=ScreenChar(winwidth(0))
-:call DoRecordScreen()
-:"
-:let g:test ="Test 4: set linebreak with tab and 1 line as long as screen: should break!"
-:set nolist linebreak ts=8
-:let line="1\t".repeat('a', winwidth(0)-2)
-:$put =line
-:$
-:norm! zt
-:redraw!
-:let line=ScreenChar(winwidth(0))
-:call DoRecordScreen()
-:let line="_S_\t bla"
-:$put =line
-:$
-:norm! zt
-:"
-:let g:test ="Test 5: set linebreak with conceal and set list and tab displayed by different char (line may not be truncated)"
-:set cpo&vim list linebreak conceallevel=2 concealcursor=nv listchars=tab:ab
-:syn match ConcealVar contained /_/ conceal
-:syn match All /.*/ contains=ConcealVar
-:let line=ScreenChar(winwidth(0))
-:call DoRecordScreen()
-:set cpo&vim linebreak
-:"
-:let g:test ="Test 6: set linebreak with visual block mode"
-:let line="REMOVE: this not"
-:$put =g:test
-:$put =line
-:let line="REMOVE: aaaaaaaaaaaaa"
-:$put =line
-:1/^REMOVE:
-0\16jf x:$put
-:set cpo&vim linebreak
-:"
-:let g:test ="Test 7: set linebreak with visual block mode and v_b_A"
-:$put =g:test
-Golong line: \e40afoobar \eaTARGET at end\e
-:exe "norm! $3B\<C-v>eAx\<Esc>"
-:set cpo&vim linebreak sbr=
-:"
-:let g:test ="Test 8: set linebreak with visual char mode and changing block"
-:$put =g:test
-Go1111-1111-1111-11-1111-1111-1111\e0f-lv3lc2222\ebgj.
-:"
-:let g:test ="Test 9: using redo after block visual mode"
-:$put =g:test
-Go
-aaa
-aaa
-a\e2k\162j~e.
-:"
-:let g:test ="Test 10: using normal commands after block-visual"
-:$put =g:test
-:set linebreak
-Go
-abcd{ef
-ghijklm
-no}pqrs\e2k0f{\16\16c%\e
-:"
-:let g:test ="Test 11: using block replace mode after wrapping"
-:$put =g:test
-:set linebreak wrap
-Go\e150aa\eyypk147|\16jr0
-:"
-:let g:test ="Test 12: set linebreak list listchars=space:_,tab:>-,tail:-,eol:$"
-:set list listchars=space:_,trail:-,tab:>-,eol:$
-:$put =g:test
-:let line="a aaaaaaaaaaaaaaaaaaaaaa\ta "
-:$put =line
-:$
-:norm! zt
-:redraw!
-:let line=ScreenChar(winwidth(0))
-:call DoRecordScreen()
-:%w! test.out
-:qa!
-ENDTEST
-dummy text
diff --git a/src/testdir/test_listlbr.ok b/src/testdir/test_listlbr.ok
deleted file mode 100644 (file)
index b32a549..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-
-       abcdef hijklmn  pqrstuvwxyz_1060ABCDEFGHIJKLMNOP 
-
-Test 1: set linebreak
-    abcdef          
-+hijklmn            
-+pqrstuvwxyz_1060ABC
-+DEFGHIJKLMNOP      
-
-Test 2: set linebreak + set list
-^Iabcdef hijklmn^I  
-+pqrstuvwxyz_1060ABC
-+DEFGHIJKLMNOP      
-                    
-
-Test 3: set linebreak nolist
-    abcdef          
-+hijklmn            
-+pqrstuvwxyz_1060ABC
-+DEFGHIJKLMNOP      
-1      aaaaaaaaaaaaaaaaaa
-
-Test 4: set linebreak with tab and 1 line as long as screen: should break!
-1                   
-+aaaaaaaaaaaaaaaaaa 
-~                   
-~                   
-_S_     bla
-
-Test 5: set linebreak with conceal and set list and tab displayed by different char (line may not be truncated)
-Sabbbbbb bla        
-~                   
-~                   
-~                   
-Test 6: set linebreak with visual block mode
-this not
-aaaaaaaaaaaaa
-REMOVE: 
-REMOVE: 
-Test 7: set linebreak with visual block mode and v_b_A
-long line: foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar TARGETx at end
-Test 8: set linebreak with visual char mode and changing block
-1111-2222-1111-11-1111-2222-1111
-Test 9: using redo after block visual mode
-
-AaA
-AaA
-A
-Test 10: using normal commands after block-visual
-
-abcdpqrs
-Test 11: using block replace mode after wrapping
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0aaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0aaa
-Test 12: set linebreak list listchars=space:_,tab:>-,tail:-,eol:$
-a aaaaaaaaaaaaaaaaaaaaaa       a 
-
-Test 12: set linebreak list listchars=space:_,tab:>-,tail:-,eol:$
-a_                  
-aaaaaaaaaaaaaaaaaaaa
-aa>-----a-$         
-~                   
diff --git a/src/testdir/test_listlbr.vim b/src/testdir/test_listlbr.vim
new file mode 100644 (file)
index 0000000..7856ee8
--- /dev/null
@@ -0,0 +1,235 @@
+" Test for linebreak and list option (non-utf8)
+
+set encoding=latin1
+scriptencoding latin1
+
+if !exists("+linebreak") || !has("conceal")
+  finish
+endif
+
+source view_util.vim
+
+function s:screen_lines(lnum, width) abort
+  return ScreenLines(a:lnum, a:width)
+endfunction
+
+function! s:compare_lines(expect, actual)
+  call assert_equal(join(a:expect, "\n"), join(a:actual, "\n"))
+endfunction
+
+function s:test_windows(...)
+  call NewWindow(10, 20)
+  setl ts=8 sw=4 sts=4 linebreak sbr= wrap
+  exe get(a:000, 0, '')
+endfunction
+
+function s:close_windows(...)
+  call CloseWindow()
+  exe get(a:000, 0, '')
+endfunction
+
+func Test_set_linebreak()
+  call s:test_windows('setl ts=4 sbr=+')
+  call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz_1060ABCDEFGHIJKLMNOP ")
+  let lines = s:screen_lines([1, 4], winwidth(0))
+  let expect = [
+\ "    abcdef          ",
+\ "+hijklmn            ",
+\ "+pqrstuvwxyz_1060ABC",
+\ "+DEFGHIJKLMNOP      ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_linebreak_with_list()
+  call s:test_windows('setl ts=4 sbr=+ list listchars=')
+  call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz_1060ABCDEFGHIJKLMNOP ")
+  let lines = s:screen_lines([1, 4], winwidth(0))
+  let expect = [
+\ "^Iabcdef hijklmn^I  ",
+\ "+pqrstuvwxyz_1060ABC",
+\ "+DEFGHIJKLMNOP      ",
+\ "~                   ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_linebreak_with_nolist()
+  call s:test_windows('setl ts=4 sbr=+ nolist')
+  call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz_1060ABCDEFGHIJKLMNOP ")
+  let lines = s:screen_lines([1, 4], winwidth(0))
+  let expect = [
+\ "    abcdef          ",
+\ "+hijklmn            ",
+\ "+pqrstuvwxyz_1060ABC",
+\ "+DEFGHIJKLMNOP      ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_should_break()
+  call s:test_windows('setl sbr=+ nolist')
+  call setline(1, "1\t" . repeat('a', winwidth(0)-2))
+  let lines = s:screen_lines([1, 4], winwidth(0))
+  let expect = [
+\ "1                   ",
+\ "+aaaaaaaaaaaaaaaaaa ",
+\ "~                   ",
+\ "~                   ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_linebreak_with_conceal()
+  call s:test_windows('setl cpo&vim sbr=+ list conceallevel=2 concealcursor=nv listchars=tab:ab')
+  call setline(1, "_S_\t bla")
+  syn match ConcealVar contained /_/ conceal
+  syn match All /.*/ contains=ConcealVar
+  let lines = s:screen_lines([1, 4], winwidth(0))
+  let expect = [
+\ "Sabbbbbb bla        ",
+\ "~                   ",
+\ "~                   ",
+\ "~                   ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_virtual_block()
+  call s:test_windows('setl sbr=+')
+  call setline(1, [
+\ "REMOVE: this not",
+\ "REMOVE: aaaaaaaaaaaaa",
+\ ])
+  exe "norm! 1/^REMOVE:"
+  exe "norm! 0\<C-V>jf x"
+  $put
+  let lines = s:screen_lines([1, 4], winwidth(0))
+  let expect = [
+\ "this not            ",
+\ "aaaaaaaaaaaaa       ",
+\ "REMOVE:             ",
+\ "REMOVE:             ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_virtual_block_and_vbA()
+  call s:test_windows()
+  call setline(1, "long line: " . repeat("foobar ", 40) . "TARGET at end")
+  exe "norm! $3B\<C-v>eAx\<Esc>"
+  let lines = s:screen_lines([1, 10], winwidth(0))
+  let expect = [
+\ "foobar foobar       ",
+\ "foobar foobar       ",
+\ "foobar foobar       ",
+\ "foobar foobar       ",
+\ "foobar foobar       ",
+\ "foobar foobar       ",
+\ "foobar foobar       ",
+\ "foobar foobar       ",
+\ "foobar foobar       ",
+\ "foobar TARGETx at   ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_virtual_char_and_block()
+  call s:test_windows()
+  call setline(1, "1111-1111-1111-11-1111-1111-1111")
+  exe "norm! 0f-lv3lc2222\<Esc>bgj."
+  let lines = s:screen_lines([1, 2], winwidth(0))
+  let expect = [
+\ "1111-2222-1111-11-  ",
+\ "1111-2222-1111      ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_undo_after_block_visual()
+  call s:test_windows()
+  call setline(1, ["aaa", "aaa", "a"])
+  exe "norm! gg\<C-V>2j~e."
+  let lines = s:screen_lines([1, 3], winwidth(0))
+  let expect = [
+\ "AaA                 ",
+\ "AaA                 ",
+\ "A                   ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_norm_after_block_visual()
+  call s:test_windows()
+  call setline(1, ["abcd{ef", "ghijklm", "no}pgrs"])
+  exe "norm! ggf{\<C-V>\<C-V>c%"
+  let lines = s:screen_lines([1, 3], winwidth(0))
+  let expect = [
+\ "abcdpgrs            ",
+\ "~                   ",
+\ "~                   ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_block_replace_after_wrapping()
+  call s:test_windows()
+  call setline(1, repeat("a", 150))
+  exe "norm! 0yypk147|\<C-V>jr0"
+  call assert_equal(repeat("a", 146) . "0aaa", getline(1))
+  call assert_equal(repeat("a", 146) . "0aaa", getline(2))
+  let lines = s:screen_lines([1, 10], winwidth(0))
+  let expect = [
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaa0aaa          ",
+\ "@                   ",
+\ "@                   ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_list_with_listchars()
+  call s:test_windows('setl list listchars=space:_,trail:-,tab:>-,eol:$')
+  call setline(1, "a aaaaaaaaaaaaaaaaaaaaaa\ta ")
+  let lines = s:screen_lines([1, 3], winwidth(0))
+  let expect = [
+\ "a_                  ",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aa>-----a-$         ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_list_with_tab_and_skipping_first_chars()
+  call s:test_windows('setl list listchars=tab:>- ts=70 nowrap')
+  call setline(1, ["iiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa"])
+  call cursor(4,64)
+  norm! 2zl
+  let lines = s:screen_lines([1, 4], winwidth(0))
+  let expect = [
+\ "---------------aaaaa",
+\ "---------------aaaaa",
+\ "---------------aaaaa",
+\ "iiiiiiiii>-----aaaaa",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfu
diff --git a/src/testdir/test_listlbr_utf8.in b/src/testdir/test_listlbr_utf8.in
deleted file mode 100644 (file)
index de716a3..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-Test for linebreak and list option in utf-8 mode
-
-STARTTEST
-:so small.vim
-:if !exists("+linebreak") || !has("conceal") || !has("signs") | e! test.ok | w! test.out | qa! | endif
-:so mbyte.vim
-:set encoding=utf8
-:if &enc !=? 'utf-8'|:e! test.ok|:w! test.out|qa!|endif
-:10new|:vsp|:vert resize 20
-:put =\"\tabcdef hijklmn\tpqrstuvwxyz\u00a01060ABCDEFGHIJKLMNOP \"
-:norm! zt
-:set ts=4 sw=4 sts=4 linebreak sbr=+ wrap
-:fu! ScreenChar(width, lines)
-:      let c=''
-:      for j in range(1,a:lines)
-:          for i in range(1,a:width)
-:              let c.=nr2char(screenchar(j, i))
-:          endfor
-:           let c.="\n"
-:      endfor
-:      return c
-:endfu
-:fu! DoRecordScreen()
-:      wincmd l
-:      $put =printf(\"\n%s\", g:test)
-:      $put =g:line
-:      wincmd p
-:endfu
-:"
-:let g:test ="Test 1: set linebreak + set list + fancy listchars"
-:exe "set linebreak list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6"
-:redraw!
-:let line=ScreenChar(winwidth(0),4)
-:call DoRecordScreen()
-:"
-:let g:test ="Test 2: set nolinebreak list"
-:set list nolinebreak
-:redraw!
-:let line=ScreenChar(winwidth(0),4)
-:call DoRecordScreen()
-:"
-:let g:test ="Test 3: set linebreak nolist"
-:$put =\"\t*mask = nil;\"
-:$
-:norm! zt
-:set nolist linebreak
-:redraw!
-:let line=ScreenChar(winwidth(0),4)
-:call DoRecordScreen()
-:"
-:let g:test ="Test 4: set linebreak list listchars and concealing"
-:let c_defines=['#define ABCDE         1','#define ABCDEF              1','#define ABCDEFG             1','#define ABCDEFGH    1', '#define MSG_MODE_FILE                      1','#define MSG_MODE_CONSOLE            2','#define MSG_MODE_FILE_AND_CONSOLE   3','#define MSG_MODE_FILE_THEN_CONSOLE  4']
-:call append('$', c_defines)
-:vert resize 40
-:$-7
-:norm! zt
-:set list linebreak listchars=tab:>- cole=1
-:syn match Conceal conceal cchar=>'AB\|MSG_MODE'
-:redraw!
-:let line=ScreenChar(winwidth(0),7)
-:call DoRecordScreen()
-:"
-:let g:test ="Test 5: set linebreak list listchars and concealing part2"
-:let c_defines=['bbeeeeee              ;       some text']
-:call append('$', c_defines)
-:$
-:norm! zt
-:set nowrap ts=2 list linebreak listchars=tab:>- cole=2 concealcursor=n
-:syn clear
-:syn match meaning    /;\s*\zs.*/
-:syn match hasword    /^\x\{8}/    contains=word
-:syn match word       /\<\x\{8}\>/ contains=beginword,endword contained
-:syn match beginword  /\<\x\x/     contained conceal
-:syn match endword    /\x\{6}\>/   contained
-:hi meaning   guibg=blue
-:hi beginword guibg=green
-:hi endword   guibg=red
-:redraw!
-:let line=ScreenChar(winwidth(0),1)
-:call DoRecordScreen()
-:"
-:let g:test ="Test 6: Screenattributes for comment"
-:$put =g:test
-:call append('$', ' /*          and some more */')
-:exe "set ft=c ts=7 linebreak list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6"
-:syntax on
-:hi SpecialKey term=underline ctermfg=red guifg=red
-:let attr=[]
-:nnoremap <expr> GG ":let attr += ['".screenattr(screenrow(),screencol())."']\n"
-:$
-:norm! zt0
-GGlGGlGGlGGlGGlGGlGGlGGlGGlGGl
-:call append('$', ['ScreenAttributes for test6:'])
-:if attr[0] != attr[1] && attr[1] != attr[3] && attr[3] != attr[5]
-:   call append('$', "Attribut 0 and 1 and 3 and 5 are different!")
-:else
-:   call append('$', "Not all attributes are different")
-:endif
-:set cpo&vim linebreak selection=exclusive
-:"
-:let g:test ="Test 8: set linebreak with visual block mode and v_b_A and selection=exclusive and multibyte char"
-:$put =g:test
-Golong line: \e40afoobar \eaTARGETÃ' at end\e
-:exe "norm! $3B\<C-v>eAx\<Esc>"
-:"
-:let g:test ="Test 9: a multibyte sign and colorcolumn"
-:let attr=[]
-:let attr2=[]
-:$put =''
-:$put ='a b c'
-:$put ='a b c'
-:set list nolinebreak cc=3
-:sign define foo text=\16uff0b
-:sign place 1 name=foo line=50 buffer=2
-:norm! 2kztj
-:let line1=line('.')
-0GGlGGlGGlGGl
-:let line2=line('.')
-:let attr2=attr
-:let attr=[]
-0GGlGGlGGlGGl
-:redraw!
-:let line=ScreenChar(winwidth(0),3)
-:call DoRecordScreen()
-:" expected: attr[2] is different because of colorcolumn
-:if attr[0] != attr2[0] || attr[1] != attr2[1] || attr[2] != attr2[2]
-:   call append('$', "Screen attributes are different!")
-:else
-:   call append('$', "Screen attributes are the same!")
-:endif
-:%w! test.out
-:qa!
-ENDTEST
-dummy text
diff --git a/src/testdir/test_listlbr_utf8.ok b/src/testdir/test_listlbr_utf8.ok
deleted file mode 100644 (file)
index f1573da..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-
-       abcdef hijklmn  pqrstuvwxyz 1060ABCDEFGHIJKLMNOP 
-
-Test 1: set linebreak + set list + fancy listchars
-▕———abcdef          
-+hijklmn▕———        
-+pqrstuvwxyz␣1060ABC
-+DEFGHIJKLMNOPˑ¶    
-
-Test 2: set nolinebreak list
-▕———abcdef hijklmn▕—
-+pqrstuvwxyz␣1060ABC
-+DEFGHIJKLMNOPˑ¶    
-¶                   
-       *mask = nil;
-
-Test 3: set linebreak nolist
-    *mask = nil;    
-~                   
-~                   
-~                   
-#define ABCDE          1
-#define ABCDEF         1
-#define ABCDEFG                1
-#define ABCDEFGH       1
-#define MSG_MODE_FILE                  1
-#define MSG_MODE_CONSOLE               2
-#define MSG_MODE_FILE_AND_CONSOLE      3
-#define MSG_MODE_FILE_THEN_CONSOLE     4
-
-Test 4: set linebreak list listchars and concealing
-#define ABCDE>-->---1                   
-#define >CDEF>-->---1                   
-#define >CDEFG>->---1                   
-#define >CDEFGH>----1                   
-#define >_FILE>--------->--->---1       
-#define >_CONSOLE>---------->---2       
-#define >_FILE_AND_CONSOLE>---------3   
-bbeeeeee               ;       some text
-
-Test 5: set linebreak list listchars and concealing part2
-eeeeee>--->-;>some text                 
-Test 6: Screenattributes for comment
- /*             and some more */
-ScreenAttributes for test6:
-Attribut 0 and 1 and 3 and 5 are different!
-Test 8: set linebreak with visual block mode and v_b_A and selection=exclusive and multibyte char
-long line: foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar TARGETÃx' at end
-
-a b c
-a b c
-
-Test 9: a multibyte sign and colorcolumn
-  ¶                                     
-+a b c¶                                
-  a b c¶                                
-Screen attributes are the same!
diff --git a/src/testdir/test_listlbr_utf8.vim b/src/testdir/test_listlbr_utf8.vim
new file mode 100644 (file)
index 0000000..56a4cc9
--- /dev/null
@@ -0,0 +1,256 @@
+" Test for linebreak and list option in utf-8 mode
+
+set encoding=utf-8
+scriptencoding utf-8
+
+if !exists("+linebreak") || !has("conceal") || !has("signs")
+  finish
+endif
+
+source view_util.vim
+
+function s:screen_lines(lnum, width) abort
+  return ScreenLines(a:lnum, a:width)
+endfunction
+
+function! s:compare_lines(expect, actual)
+  call assert_equal(a:expect, a:actual)
+endfunction
+
+function s:screen_attr(lnum, chars, ...) abort
+  let line = getline(a:lnum)
+  let attr = []
+  let prefix = get(a:000, 0, 0)
+  for i in range(a:chars[0], a:chars[1])
+    let scol = strdisplaywidth(strcharpart(line, 0, i-1)) + 1
+    let attr += [screenattr(a:lnum, scol + prefix)]
+  endfor
+  return attr
+endfunction
+
+function s:test_windows(...)
+  call NewWindow(10, 20)
+  setl ts=4 sw=4 sts=4 linebreak sbr=+ wrap
+  exe get(a:000, 0, '')
+endfunction
+
+function s:close_windows(...)
+  call CloseWindow()
+  exe get(a:000, 0, '')
+endfunction
+
+func Test_linebreak_with_fancy_listchars()
+  call s:test_windows("setl list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
+  call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz\u00a01060ABCDEFGHIJKLMNOP ")
+  redraw!
+  let lines = s:screen_lines([1, 4], winwidth(0))
+  let expect = [
+\ "▕———abcdef          ",
+\ "+hijklmn▕———        ",
+\ "+pqrstuvwxyz␣1060ABC",
+\ "+DEFGHIJKLMNOPˑ¶    ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_nolinebreak_with_list()
+  call s:test_windows("setl nolinebreak list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
+  call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz\u00a01060ABCDEFGHIJKLMNOP ")
+  redraw!
+  let lines = s:screen_lines([1, 4], winwidth(0))
+  let expect = [
+\ "▕———abcdef hijklmn▕—",
+\ "+pqrstuvwxyz␣1060ABC",
+\ "+DEFGHIJKLMNOPˑ¶    ",
+\ "~                   ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_linebreak_with_nolist()
+  call s:test_windows('setl nolist')
+  call setline(1, "\t*mask = nil;")
+  redraw!
+  let lines = s:screen_lines([1, 4], winwidth(0))
+  let expect = [
+\ "    *mask = nil;    ",
+\ "~                   ",
+\ "~                   ",
+\ "~                   ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_list_and_concealing1()
+  call s:test_windows('setl list listchars=tab:>- cole=1')
+  call setline(1, [
+\ "#define ABCDE\t\t1",
+\ "#define ABCDEF\t\t1",
+\ "#define ABCDEFG\t\t1",
+\ "#define ABCDEFGH\t1",
+\ "#define MSG_MODE_FILE\t\t\t1",
+\ "#define MSG_MODE_CONSOLE\t\t2",
+\ "#define MSG_MODE_FILE_AND_CONSOLE\t3",
+\ "#define MSG_MODE_FILE_THEN_CONSOLE\t4",
+\ ])
+  vert resize 40
+  syn match Conceal conceal cchar=>'AB\|MSG_MODE'
+  redraw!
+  let lines = s:screen_lines([1, 7], winwidth(0))
+  let expect = [
+\ "#define ABCDE>-->---1                   ",
+\ "#define >CDEF>-->---1                   ",
+\ "#define >CDEFG>->---1                   ",
+\ "#define >CDEFGH>----1                   ",
+\ "#define >_FILE>--------->--->---1       ",
+\ "#define >_CONSOLE>---------->---2       ",
+\ "#define >_FILE_AND_CONSOLE>---------3   ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_list_and_concealing2()
+  call s:test_windows('setl nowrap ts=2 list listchars=tab:>- cole=2 concealcursor=n')
+  call setline(1, "bbeeeeee\t\t;\tsome text")
+  vert resize 40
+  syn clear
+  syn match meaning    /;\s*\zs.*/
+  syn match hasword    /^\x\{8}/    contains=word
+  syn match word       /\<\x\{8}\>/ contains=beginword,endword contained
+  syn match beginword  /\<\x\x/     contained conceal
+  syn match endword    /\x\{6}\>/   contained
+  hi meaning   guibg=blue
+  hi beginword guibg=green
+  hi endword   guibg=red
+  redraw!
+  let lines = s:screen_lines([1, 1], winwidth(0))
+  let expect = [
+\ "eeeeee>--->-;>some text                 ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_screenattr_for_comment()
+  call s:test_windows("setl ft=c ts=7 list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
+  call setline(1, " /*\t\t and some more */")
+  norm! gg0
+  syntax on
+  hi SpecialKey term=underline ctermfg=red guifg=red
+  redraw!
+  let line = getline(1)
+  let attr = s:screen_attr(1, [1, 6])
+  call assert_notequal(attr[0], attr[1])
+  call assert_notequal(attr[1], attr[3])
+  call assert_notequal(attr[3], attr[5])
+  call s:close_windows()
+endfunc
+
+func Test_visual_block_and_selection_exclusive()
+  call s:test_windows('setl selection=exclusive')
+  call setline(1, "long line: " . repeat("foobar ", 40) . "TARGETÃ' at end")
+  exe "norm! $3B\<C-v>eAx\<Esc>"
+  let lines = s:screen_lines([1, 10], winwidth(0))
+  let expect = [
+\ "+foobar foobar      ",
+\ "+foobar foobar      ",
+\ "+foobar foobar      ",
+\ "+foobar foobar      ",
+\ "+foobar foobar      ",
+\ "+foobar foobar      ",
+\ "+foobar foobar      ",
+\ "+foobar foobar      ",
+\ "+foobar foobar      ",
+\ "+foobar TARGETÃx'   ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_multibyte_sign_and_colorcolumn()
+  call s:test_windows("setl nolinebreak cc=3 list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
+  call setline(1, ["", "a b c", "a b c"])
+  exe "sign define foo text=\uff0b"
+  exe "sign place 1 name=foo line=2 buffer=" . bufnr('%')
+  redraw!
+  norm! ggj0
+  let signwidth = strdisplaywidth("\uff0b")
+  let attr1 = s:screen_attr(2, [1, 3], signwidth)
+  let attr2 = s:screen_attr(3, [1, 3], signwidth)
+  call assert_equal(attr1[0], attr2[0])
+  call assert_equal(attr1[1], attr2[1])
+  call assert_equal(attr1[2], attr2[2])
+  let lines = s:screen_lines([1, 3], winwidth(0))
+  let expect = [
+\ "  ¶                 ",
+\ "+a b c¶            ",
+\ "  a b c¶            ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_illegal_byte_and_breakat()
+  call s:test_windows("setl sbr= brk+=<")
+  vert resize 18
+  call setline(1, repeat("\x80", 6))
+  redraw!
+  let lines = s:screen_lines([1, 2], winwidth(0))
+  let expect = [
+\ "<80><80><80><80><8",
+\ "0><80>            ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows('setl brk&vim')
+endfunc
+
+func Test_multibyte_wrap_and_breakat()
+  call s:test_windows("setl sbr= brk+=>")
+  call setline(1, repeat('a', 17) . repeat('あ', 2))
+  redraw!
+  let lines = s:screen_lines([1, 2], winwidth(0))
+  let expect = [
+\ "aaaaaaaaaaaaaaaaaあ>",
+\ "あ                  ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows('setl brk&vim')
+endfunc
+
+func Test_chinese_char_on_wrap_column()
+  call s:test_windows("setl nolbr wrap sbr=")
+  syntax off
+  call setline(1, [
+\ 'aaaaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'hello'])
+  call cursor(1,1)
+  norm! $
+  redraw!
+  let expect=[
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中hello             ']
+  let lines = s:screen_lines([1, 10], winwidth(0))
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfu
diff --git a/src/testdir/test_lua.vim b/src/testdir/test_lua.vim
new file mode 100644 (file)
index 0000000..944ad90
--- /dev/null
@@ -0,0 +1,22 @@
+" Tests for Lua.
+" TODO: move tests from test85.in here.
+
+if !has('lua')
+  finish
+endif
+
+func Test_luado()
+  new
+  call setline(1, ['one', 'two', 'three'])
+  luado vim.command("%d_")
+  bwipe!
+
+  " Check switching to another buffer does not trigger ml_get error.
+  new
+  let wincount = winnr('$')
+  call setline(1, ['one', 'two', 'three'])
+  luado vim.command("new")
+  call assert_equal(wincount + 1, winnr('$'))
+  bwipe!
+  bwipe!
+endfunc
diff --git a/src/testdir/test_makeencoding.py b/src/testdir/test_makeencoding.py
new file mode 100644 (file)
index 0000000..041edad
--- /dev/null
@@ -0,0 +1,67 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Test program for :make, :grep and :cgetfile.
+
+from __future__ import print_function, unicode_literals
+import locale
+import io
+import sys
+
+def set_output_encoding(enc=None):
+    """Set the encoding of stdout and stderr
+
+    arguments:
+      enc -- Encoding name.
+             If omitted, locale.getpreferredencoding() is used.
+    """
+    if enc is None:
+        enc = locale.getpreferredencoding()
+
+    def get_text_writer(fo, **kwargs):
+        kw = dict(kwargs)
+        kw.setdefault('errors', 'backslashreplace') # use \uXXXX style
+        kw.setdefault('closefd', False)
+
+        if sys.version_info[0] < 3:
+            # Work around for Python 2.x
+            # New line conversion isn't needed here. Done in somewhere else.
+            writer = io.open(fo.fileno(), mode='w', newline='', **kw)
+            write = writer.write    # save the original write() function
+            enc = locale.getpreferredencoding()
+            def convwrite(s):
+                if isinstance(s, bytes):
+                    write(s.decode(enc))    # convert to unistr
+                else:
+                    write(s)
+                try:
+                    writer.flush()  # needed on Windows
+                except IOError:
+                    pass
+            writer.write = convwrite
+        else:
+            writer = io.open(fo.fileno(), mode='w', **kw)
+        return writer
+
+    sys.stdout = get_text_writer(sys.stdout, encoding=enc)
+    sys.stderr = get_text_writer(sys.stderr, encoding=enc)
+
+
+def main():
+    enc = 'utf-8'
+    if len(sys.argv) > 1:
+        enc = sys.argv[1]
+    set_output_encoding(enc)
+
+    message_tbl = {
+            'utf-8': 'ÀÈÌÒÙ こんにちは 你好',
+            'latin1': 'ÀÈÌÒÙ',
+            'cp932': 'こんにちは',
+            'cp936': '你好',
+            }
+
+    print('Xfoobar.c(10) : %s (%s)' % (message_tbl[enc], enc))
+
+
+if __name__ == "__main__":
+    main()
diff --git a/src/testdir/test_makeencoding.vim b/src/testdir/test_makeencoding.vim
new file mode 100644 (file)
index 0000000..a3d5538
--- /dev/null
@@ -0,0 +1,106 @@
+" Tests for 'makeencoding'.
+if !has('multi_byte')
+  finish
+endif
+
+source shared.vim
+
+let s:python = PythonProg()
+if s:python == ''
+  " Can't run this test.
+  finish
+endif
+
+let s:script = 'test_makeencoding.py'
+
+let s:message_tbl = {
+      \ 'utf-8': 'ÀÈÌÒÙ こんにちは 你好',
+      \ 'latin1': 'ÀÈÌÒÙ',
+      \ 'cp932': 'こんにちは',
+      \ 'cp936': '你好',
+      \}
+
+
+" Tests for :cgetfile and :lgetfile.
+func Test_getfile()
+  set errorfile=Xerror.txt
+  set errorformat=%f(%l)\ :\ %m
+
+  " :cgetfile
+  for enc in keys(s:message_tbl)
+    let &makeencoding = enc
+    exec "silent !" . s:python . " " . s:script . " " . enc . " > " . &errorfile
+    cgetfile
+    copen
+    call assert_equal("Xfoobar.c|10| " . s:message_tbl[enc] . " (" . enc . ")",
+          \ getline('.'))
+    cclose
+  endfor
+
+  " :lgetfile
+  for enc in keys(s:message_tbl)
+    let &makeencoding = enc
+    exec "silent !" . s:python . " " . s:script . " " . enc . " > " . &errorfile
+    lgetfile
+    lopen
+    call assert_equal("Xfoobar.c|10| " . s:message_tbl[enc] . " (" . enc . ")",
+          \ getline('.'))
+    lclose
+  endfor
+
+  call delete(&errorfile)
+endfunc
+
+
+" Tests for :grep and :lgrep.
+func Test_grep()
+  let &grepprg = s:python
+  set grepformat=%f(%l)\ :\ %m
+
+  " :grep
+  for enc in keys(s:message_tbl)
+    let &makeencoding = enc
+    exec "silent grep! " . s:script . " " . enc
+    copen
+    call assert_equal("Xfoobar.c|10| " . s:message_tbl[enc] . " (" . enc . ")",
+          \ getline('.'))
+    cclose
+  endfor
+
+  " :lgrep
+  for enc in keys(s:message_tbl)
+    let &makeencoding = enc
+    exec "silent lgrep! " . s:script . " " . enc
+    lopen
+    call assert_equal("Xfoobar.c|10| " . s:message_tbl[enc] . " (" . enc . ")",
+          \ getline('.'))
+    lclose
+  endfor
+endfunc
+
+
+" Tests for :make and :lmake.
+func Test_make()
+  let &makeprg = s:python
+  set errorformat=%f(%l)\ :\ %m
+
+  " :make
+  for enc in keys(s:message_tbl)
+    let &makeencoding = enc
+    exec "silent make! " . s:script . " " . enc
+    copen
+    call assert_equal("Xfoobar.c|10| " . s:message_tbl[enc] . " (" . enc . ")",
+          \ getline('.'))
+    cclose
+  endfor
+
+  " :lmake
+  for enc in keys(s:message_tbl)
+    let &makeencoding = enc
+    exec "silent lmake! " . s:script . " " . enc
+    lopen
+    call assert_equal("Xfoobar.c|10| " . s:message_tbl[enc] . " (" . enc . ")",
+          \ getline('.'))
+    lclose
+  endfor
+endfunc
index 306eb2f..5026d6b 100644 (file)
@@ -110,6 +110,8 @@ func Test_map_langmap()
   call feedkeys(":call append(line('$'), '+')\<CR>", "xt")
   call assert_equal('+', getline('$'))
 
+  iunmap a
+  iunmap c
   set nomodified
 endfunc
 
@@ -120,7 +122,7 @@ func Test_map_feedkeys()
   $-1
   call feedkeys("0qqdw.ifoo\<Esc>qj0@q\<Esc>", "xt")
   call assert_equal(['fooc d', 'fooc d'], getline(line('$') - 1, line('$')))
-  unmap .
+  nunmap .
   set nomodified
 endfunc
 
@@ -158,3 +160,41 @@ func Test_map_meta_quotes()
   set nomodified
   iunmap <M-">
 endfunc
+
+func Test_abbr_after_line_join()
+  new
+  abbr foo bar
+  set backspace=indent,eol,start
+  exe "normal o\<BS>foo "
+  call assert_equal("bar ", getline(1))
+  bwipe!
+  unabbr foo
+  set backspace&
+endfunc
+
+func Test_map_timeout()
+  nnoremap aaaa :let got_aaaa = 1<CR>
+  nnoremap bb :let got_bb = 1<CR>
+  nmap b aaa
+  new
+  func ExitInsert(timer)
+    let g:line = getline(1)
+    call feedkeys("\<Esc>", "t")
+  endfunc
+  set timeout timeoutlen=200
+  call timer_start(300, 'ExitInsert')
+  " After the 'b' Vim waits for another character to see if it matches 'bb'.
+  " When it times out it is expanded to "aaa", but there is no wait for
+  " "aaaa".  Can't check that reliably though.
+  call feedkeys("b", "xt!")
+  call assert_equal("aa", g:line)
+  call assert_false(exists('got_aaa'))
+  call assert_false(exists('got_bb'))
+
+  bwipe!
+  nunmap aaaa
+  nunmap bb
+  nunmap b
+  set timeoutlen&
+  delfunc ExitInsert
+endfunc
index d00b1dd..18a0c71 100644 (file)
@@ -24,3 +24,47 @@ function! Test_Incr_Marks()
   call assert_equal("XXX 123 123", getline(3))
   enew!
 endfunction
+
+func Test_setpos()
+  new one
+  let onebuf = bufnr('%')
+  let onewin = win_getid()
+  call setline(1, ['aaa', 'bbb', 'ccc'])
+  new two
+  let twobuf = bufnr('%')
+  let twowin = win_getid()
+  call setline(1, ['aaa', 'bbb', 'ccc'])
+
+  " for the cursor the buffer number is ignored
+  call setpos(".", [0, 2, 1, 0])
+  call assert_equal([0, 2, 1, 0], getpos("."))
+  call setpos(".", [onebuf, 3, 3, 0])
+  call assert_equal([0, 3, 3, 0], getpos("."))
+
+  call setpos("''", [0, 1, 3, 0])
+  call assert_equal([0, 1, 3, 0], getpos("''"))
+  call setpos("''", [onebuf, 2, 2, 0])
+  call assert_equal([0, 2, 2, 0], getpos("''"))
+
+  " buffer-local marks
+  for mark in ["'a", "'\"", "'[", "']", "'<", "'>"]
+    call win_gotoid(twowin)
+    call setpos(mark, [0, 2, 1, 0])
+    call assert_equal([0, 2, 1, 0], getpos(mark), "for mark " . mark)
+    call setpos(mark, [onebuf, 1, 3, 0])
+    call win_gotoid(onewin)
+    call assert_equal([0, 1, 3, 0], getpos(mark), "for mark " . mark)
+  endfor
+
+  " global marks
+  call win_gotoid(twowin)
+  call setpos("'N", [0, 2, 1, 0])
+  call assert_equal([twobuf, 2, 1, 0], getpos("'N"))
+  call setpos("'N", [onebuf, 1, 3, 0])
+  call assert_equal([onebuf, 1, 3, 0], getpos("'N"))
+
+  call win_gotoid(onewin)
+  bwipe!
+  call win_gotoid(twowin)
+  bwipe!
+endfunc
index be55946..055d944 100644 (file)
@@ -1,9 +1,32 @@
 " Test that the system menu can be loaded.
 
+if !has('menu')
+  finish
+endif
+
 func Test_load_menu()
   try
     source $VIMRUNTIME/menu.vim
   catch
-    call assert_false(1, 'error while loading menus: ' . v:exception)
+    call assert_report('error while loading menus: ' . v:exception)
   endtry
+  call assert_match('browse confirm w', execute(':menu File.Save'))
+  source $VIMRUNTIME/delmenu.vim
+endfunc
+
+func Test_translate_menu()
+  if !has('multi_lang')
+    return
+  endif
+  if !filereadable($VIMRUNTIME . '/lang/menu_de_de.latin1.vim')
+    throw 'Skipped: translated menu not found'
+  endif
+
+  " First delete any English menus.
+  source $VIMRUNTIME/delmenu.vim
+  set langmenu=de_de
+  source $VIMRUNTIME/menu.vim
+  call assert_match('browse confirm w', execute(':menu Datei.Speichern'))
+
+  source $VIMRUNTIME/delmenu.vim
 endfunc
diff --git a/src/testdir/test_mksession.vim b/src/testdir/test_mksession.vim
new file mode 100644 (file)
index 0000000..6ea3255
--- /dev/null
@@ -0,0 +1,125 @@
+" Test for :mksession, :mkview and :loadview in latin1 encoding
+
+set encoding=latin1
+scriptencoding latin1
+
+if !has('multi_byte') || !has('mksession')
+  finish
+endif
+
+func Test_mksession()
+  tabnew
+  let wrap_save = &wrap
+  set sessionoptions=buffers splitbelow fileencoding=latin1
+  call setline(1, [
+    \   'start:',
+    \   'no multibyte chAracter',
+    \   '      one leaDing tab',
+    \   '    four leadinG spaces',
+    \   'two           consecutive tabs',
+    \   'two   tabs    in one line',
+    \   'one ä multibyteCharacter',
+    \   'aä Ä  two multiByte characters',
+    \   'Aäöü  three mulTibyte characters'
+    \ ])
+  let tmpfile = 'Xtemp'
+  exec 'w! ' . tmpfile
+  /^start:
+  set wrap
+  vsplit
+  norm! j16|
+  split
+  norm! j16|
+  split
+  norm! j16|
+  split
+  norm! j8|
+  split
+  norm! j8|
+  split
+  norm! j16|
+  split
+  norm! j16|
+  split
+  norm! j16|
+  wincmd l
+
+  set nowrap
+  /^start:
+  norm! j16|3zl
+  split
+  norm! j016|3zl
+  split
+  norm! j016|3zl
+  split
+  norm! j08|3zl
+  split
+  norm! j08|3zl
+  split
+  norm! j016|3zl
+  split
+  norm! j016|3zl
+  split
+  norm! j016|3zl
+  split
+  call wincol()
+  mksession! Xtest_mks.out
+  let li = filter(readfile('Xtest_mks.out'), 'v:val =~# "\\(^ *normal! 0\\|^ *exe ''normal!\\)"')
+  let expected = [
+    \   'normal! 016|',
+    \   'normal! 016|',
+    \   'normal! 016|',
+    \   'normal! 08|',
+    \   'normal! 08|',
+    \   'normal! 016|',
+    \   'normal! 016|',
+    \   'normal! 016|',
+    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+    \   "  normal! 016|",
+    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+    \   "  normal! 016|",
+    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+    \   "  normal! 016|",
+    \   "  exe 'normal! ' . s:c . '|zs' . 8 . '|'",
+    \   "  normal! 08|",
+    \   "  exe 'normal! ' . s:c . '|zs' . 8 . '|'",
+    \   "  normal! 08|",
+    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+    \   "  normal! 016|",
+    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+    \   "  normal! 016|",
+    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+    \   "  normal! 016|",
+    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+    \   "  normal! 016|"
+    \ ]
+  call assert_equal(expected, li)
+  tabclose!
+
+  call delete('Xtest_mks.out')
+  call delete(tmpfile)
+  let &wrap = wrap_save
+endfunc
+
+func Test_mksession_winheight()
+  new
+  set winheight=10 winminheight=2
+  mksession! Xtest_mks.out
+  source Xtest_mks.out
+
+  call delete('Xtest_mks.out')
+endfunc
+
+func Test_mksession_arglist()
+  argdel *
+  next file1 file2 file3 file4
+  mksession! Xtest_mks.out
+  source Xtest_mks.out
+  call assert_equal(['file1', 'file2', 'file3', 'file4'], argv())
+
+  call delete('Xtest_mks.out')
+  argdel *
+endfunc
+
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_mksession_utf8.vim b/src/testdir/test_mksession_utf8.vim
new file mode 100644 (file)
index 0000000..c05a1d3
--- /dev/null
@@ -0,0 +1,104 @@
+" Test for :mksession, :mkview and :loadview in utf-8 encoding
+
+set encoding=utf-8
+scriptencoding utf-8
+
+if !has('multi_byte') || !has('mksession')
+  finish
+endif
+
+func Test_mksession_utf8()
+  tabnew
+  let wrap_save = &wrap
+  set sessionoptions=buffers splitbelow fileencoding=utf-8
+  call setline(1, [
+    \   'start:',
+    \   'no multibyte chAracter',
+    \   '      one leaDing tab',
+    \   '    four leadinG spaces',
+    \   'two           consecutive tabs',
+    \   'two   tabs    in one line',
+    \   'one … multibyteCharacter',
+    \   'a “b” two multiByte characters',
+    \   '“c”1€ three mulTibyte characters'
+    \ ])
+  let tmpfile = tempname()
+  exec 'w! ' . tmpfile
+  /^start:
+  set wrap
+  vsplit
+  norm! j16|
+  split
+  norm! j16|
+  split
+  norm! j16|
+  split
+  norm! j8|
+  split
+  norm! j8|
+  split
+  norm! j16|
+  split
+  norm! j16|
+  split
+  norm! j16|
+  wincmd l
+
+  set nowrap
+  /^start:
+  norm! j16|3zl
+  split
+  norm! j016|3zl
+  split
+  norm! j016|3zl
+  split
+  norm! j08|3zl
+  split
+  norm! j08|3zl
+  split
+  norm! j016|3zl
+  split
+  norm! j016|3zl
+  split
+  norm! j016|3zl
+  split
+  call wincol()
+  mksession! test_mks.out
+  let li = filter(readfile('test_mks.out'), 'v:val =~# "\\(^ *normal! 0\\|^ *exe ''normal!\\)"')
+  let expected = [
+    \   'normal! 016|',
+    \   'normal! 016|',
+    \   'normal! 016|',
+    \   'normal! 08|',
+    \   'normal! 08|',
+    \   'normal! 016|',
+    \   'normal! 016|',
+    \   'normal! 016|',
+    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+    \   "  normal! 016|",
+    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+    \   "  normal! 016|",
+    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+    \   "  normal! 016|",
+    \   "  exe 'normal! ' . s:c . '|zs' . 8 . '|'",
+    \   "  normal! 08|",
+    \   "  exe 'normal! ' . s:c . '|zs' . 8 . '|'",
+    \   "  normal! 08|",
+    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+    \   "  normal! 016|",
+    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+    \   "  normal! 016|",
+    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+    \   "  normal! 016|",
+    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+    \   "  normal! 016|"
+    \ ]
+  call assert_equal(expected, li)
+  tabclose!
+
+  call delete('test_mks.out')
+  call delete(tmpfile)
+  let &wrap = wrap_save
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
index f881730..ec48f03 100644 (file)
@@ -1,32 +1,67 @@
 "Tests for nested functions
 "
-function! NestedFunc()
-  fu! Func1()
+func NestedFunc()
+  func! Func1()
     let g:text .= 'Func1 '
-  endfunction
+  endfunc
   call Func1()
-  fu! s:func2()
+  func! s:func2()
     let g:text .= 's:func2 '
-  endfunction
+  endfunc
   call s:func2()
-  fu! s:_func3()
+  func! s:_func3()
     let g:text .= 's:_func3 '
-  endfunction
+  endfunc
   call s:_func3()
   let fn = 'Func4'
-  fu! {fn}()
+  func! {fn}()
     let g:text .= 'Func4 '
-  endfunction
+  endfunc
   call {fn}()
   let fn = 'func5'
-  fu! s:{fn}()
+  func! s:{fn}()
     let g:text .= 's:func5'
-  endfunction
+  endfunc
   call s:{fn}()
-endfunction
+endfunc
 
-function! Test_nested_functions()
+func Test_nested_functions()
   let g:text = ''
   call NestedFunc()
   call assert_equal('Func1 s:func2 s:_func3 Func4 s:func5', g:text)
 endfunction
+
+func Test_nested_argument()
+  func g:X()
+    let g:Y = function('sort')
+  endfunc
+  let g:Y = function('sort')
+  echo g:Y([], g:X())
+  delfunc g:X
+  unlet g:Y
+endfunc
+
+func Recurse(count)
+  if a:count > 0
+    call Recurse(a:count - 1)
+  endif
+endfunc
+
+func Test_max_nesting()
+  " TODO: why does this fail on Windows?  Runs out of stack perhaps?
+  if has('win32')
+    return
+  endif
+  let call_depth_here = 2
+  let ex_depth_here = 5
+  set mfd&
+
+  call Recurse(99 - call_depth_here)
+  call assert_fails('call Recurse(' . (100 - call_depth_here) . ')', 'E132:')
+
+  set mfd=210
+  call Recurse(209 - ex_depth_here)
+  call assert_fails('call Recurse(' . (210 - ex_depth_here) . ')', 'E169:')
+
+  set mfd&
+endfunc
index 29bd783..21d6aa9 100644 (file)
@@ -1,5 +1,6 @@
 " Test for various Normal mode commands
 
+set belloff=all
 func! Setup_NewWindow()
   10new
   call setline(1, range(1,100))
@@ -224,21 +225,33 @@ func! Test_normal06_formatprg()
   " only test on non windows platform
   if has('win32')
     return
-  else
-    " uses sed to number non-empty lines
-    call writefile(['#!/bin/sh', 'sed ''/./=''|sed ''/./{', 'N', 's/\n/    /', '}'''], 'Xsed_format.sh')
-    call system('chmod +x ./Xsed_format.sh')
   endif
-  call Setup_NewWindow()
-  %d
-  call setline(1, ['a', '', 'c', '', ' ', 'd', 'e'])
+
+  " uses sed to number non-empty lines
+  call writefile(['#!/bin/sh', 'sed ''/./=''|sed ''/./{', 'N', 's/\n/    /', '}'''], 'Xsed_format.sh')
+  call system('chmod +x ./Xsed_format.sh')
+  let text = ['a', '', 'c', '', ' ', 'd', 'e']
+  let expected = ['1    a', '', '3    c', '', '5     ', '6    d', '7    e']
+
+  10new
+  call setline(1, text)
   set formatprg=./Xsed_format.sh
   norm! gggqG
-  call assert_equal(['1    a', '', '3    c', '', '5     ', '6    d', '7    e'], getline(1, '$'))
+  call assert_equal(expected, getline(1, '$'))
+  bw!
+
+  10new
+  call setline(1, text)
+  set formatprg=donothing
+  setlocal formatprg=./Xsed_format.sh
+  norm! gggqG
+  call assert_equal(expected, getline(1, '$'))
+  bw!
+
   " clean up
   set formatprg=
+  setlocal formatprg=
   call delete('Xsed_format.sh')
-  bw!
 endfunc
 
 func! Test_normal07_internalfmt()
@@ -251,7 +264,7 @@ func! Test_normal07_internalfmt()
   norm! gggqG
   call assert_equal(['1    2    3', '4    5    6', '7    8    9', '10    11    '], getline(1, '$'))
   " clean up
-  set formatprg= tw=0
+  set tw=0
   bw!
 endfunc
 
@@ -831,7 +844,7 @@ func! Test_normal18_z_fold()
   norm! j
   call assert_equal('52', getline('.'))
 
-  " zA on a opened fold when foldenale is not set
+  " zA on a opened fold when foldenable is not set
   50
   set nofoldenable
   norm! zA
@@ -893,7 +906,7 @@ func! Test_normal18_z_fold()
   norm! j
   call assert_equal('55', getline('.'))
 
-  " 2) do not close fold under curser
+  " 2) do not close fold under cursor
   51
   set nofoldenable
   norm! zx
@@ -1590,6 +1603,40 @@ fun! Test_normal30_changecase()
   norm! V~
   call assert_equal('THIS IS A simple test: äüöss', getline('.'))
 
+  " Turkish ASCII turns to multi-byte.  On Mac the Turkish locale is available
+  " but toupper()/tolower() don't do the right thing.
+  if !has('mac') && !has('osx')
+    try
+      lang tr_TR.UTF-8
+      set casemap=
+      call setline(1, 'iI')
+      1normal gUU
+      call assert_equal("\u0130I", getline(1))
+      call assert_equal("\u0130I", toupper("iI"))
+
+      call setline(1, 'iI')
+      1normal guu
+      call assert_equal("i\u0131", getline(1))
+      call assert_equal("i\u0131", tolower("iI"))
+
+      set casemap&
+      call setline(1, 'iI')
+      1normal gUU
+      call assert_equal("II", getline(1))
+      call assert_equal("II", toupper("iI"))
+
+      call setline(1, 'iI')
+      1normal guu
+      call assert_equal("ii", getline(1))
+      call assert_equal("ii", tolower("iI"))
+
+      lang en_US.UTF-8
+    catch /E197:/
+      " can't use Turkish locale
+      throw 'Skipped: Turkish locale not available'
+    endtry
+  endif
+
   " clean up
   bw!
 endfunc
@@ -1759,18 +1806,60 @@ fun! Test_normal34_g_cmd3()
   if !has("multi_byte")
     return
   endif
+
   " Test for g8
   new
-  call append(0, 'abcdefghijklmnopqrstuvwxyzäüö')
-  let a=execute(':norm! 1gg$g8')
-  call assert_equal('c3 b6 ', a[1:])
+  let a=execute(':norm! 1G0g8')
+  call assert_equal("\nNUL", a)
+
+  call setline(1, 'abcdefghijklmnopqrstuvwxyzäüö')
+  let a=execute(':norm! 1G$g8')
+  call assert_equal("\nc3 b6 ", a)
+
+  call setline(1, "a\u0302")
+  let a=execute(':norm! 1G0g8')
+  call assert_equal("\n61 + cc 82 ", a)
 
-  " Test for gp gP
-  call append(1, range(1,10))
   " clean up
   bw!
 endfunc
 
+func Test_normal_8g8()
+  if !has("multi_byte")
+    return
+  endif
+  new
+
+  " Test 8g8 which finds invalid utf8 at or after the cursor.
+
+  " With invalid byte.
+  call setline(1, "___\xff___")
+  norm! 1G08g8g
+  call assert_equal([0, 1, 4, 0, 1], getcurpos())
+
+  " With invalid byte before the cursor.
+  call setline(1, "___\xff___")
+  norm! 1G$h8g8g
+  call assert_equal([0, 1, 6, 0, 9], getcurpos())
+
+  " With truncated sequence.
+  call setline(1, "___\xE2\x82___")
+  norm! 1G08g8g
+  call assert_equal([0, 1, 4, 0, 1], getcurpos())
+
+  " With overlong sequence.
+  call setline(1, "___\xF0\x82\x82\xAC___")
+  norm! 1G08g8g
+  call assert_equal([0, 1, 4, 0, 1], getcurpos())
+
+  " With valid utf8.
+  call setline(1, "café")
+  norm! 1G08g8
+  call assert_equal([0, 1, 1, 0, 1], getcurpos())
+
+  bw!
+endfunc
+
 fun! Test_normal35_g_cmd4()
   " Test for g<
   " Cannot capture its output,
@@ -2181,6 +2270,8 @@ func! Test_normal51_FileChangedRO()
   if !has("autocmd")
     return
   endif
+  " Don't sleep after the warning message.
+  call test_settime(1)
   call writefile(['foo'], 'Xreadonly.log')
   new Xreadonly.log
   setl ro
@@ -2190,6 +2281,7 @@ func! Test_normal51_FileChangedRO()
   call assert_equal('Xreadonly.log', bufname(''))
 
   " cleanup
+  call test_settime(0)
   bw!
   call delete("Xreadonly.log")
 endfunc
@@ -2243,26 +2335,46 @@ func! Test_normal53_digraph()
   bw!
 endfunc
 
-func! Test_normal54_Ctrl_bsl()
-       new
-       call setline(1, 'abcdefghijklmn')
-       exe "norm! df\<c-\>\<c-n>"
-       call assert_equal(['abcdefghijklmn'], getline(1,'$'))
-       exe "norm! df\<c-\>\<c-g>"
-       call assert_equal(['abcdefghijklmn'], getline(1,'$'))
-       exe "norm! df\<c-\>m"
-       call assert_equal(['abcdefghijklmn'], getline(1,'$'))
+func Test_normal54_Ctrl_bsl()
+  new
+  call setline(1, 'abcdefghijklmn')
+  exe "norm! df\<c-\>\<c-n>"
+  call assert_equal(['abcdefghijklmn'], getline(1,'$'))
+  exe "norm! df\<c-\>\<c-g>"
+  call assert_equal(['abcdefghijklmn'], getline(1,'$'))
+  exe "norm! df\<c-\>m"
+  call assert_equal(['abcdefghijklmn'], getline(1,'$'))
   if !has("multi_byte")
     return
   endif
-       call setline(2, 'abcdefghijklmnāf')
-       norm! 2gg0
-       exe "norm! df\<Char-0x101>"
-       call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
-       norm! 1gg0
-       exe "norm! df\<esc>"
-       call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
-
-       " clean up
-       bw!
+  call setline(2, 'abcdefghijklmnāf')
+  norm! 2gg0
+  exe "norm! df\<Char-0x101>"
+  call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
+  norm! 1gg0
+  exe "norm! df\<esc>"
+  call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
+
+  " clean up
+  bw!
+endfunc
+
+func Test_normal_large_count()
+  " This may fail with 32bit long, how do we detect that?
+  new
+  normal o
+  normal 6666666666dL
+  bwipe!
+endfunc
+
+func Test_delete_until_paragraph()
+  if !has('multi_byte')
+    return
+  endif
+  new
+  normal grádv}
+  call assert_equal('á', getline(1))
+  normal grád}
+  call assert_equal('', getline(1))
+  bwipe!
 endfunc
diff --git a/src/testdir/test_number.vim b/src/testdir/test_number.vim
new file mode 100644 (file)
index 0000000..59debce
--- /dev/null
@@ -0,0 +1,254 @@
+" Test for 'number' and 'relativenumber'
+
+source view_util.vim
+
+func! s:screen_lines(start, end) abort
+  return ScreenLines([a:start, a:end], 8)
+endfunc
+
+func! s:compare_lines(expect, actual)
+  call assert_equal(a:expect, a:actual)
+endfunc
+
+func! s:test_windows(h, w) abort
+  call NewWindow(a:h, a:w)
+endfunc
+
+func! s:close_windows() abort
+  call CloseWindow()
+endfunc
+
+func! s:validate_cursor() abort
+  " update skipcol.
+  " wincol():
+  "   f_wincol
+  "     -> validate_cursor
+  "          -> curs_columns
+  call wincol()
+endfunc
+
+func Test_set_options()
+  set nu rnu
+  call assert_equal(1, &nu)
+  call assert_equal(1, &rnu)
+
+  call s:test_windows(10, 20)
+  call assert_equal(1, &nu)
+  call assert_equal(1, &rnu)
+  call s:close_windows()
+
+  set nu& rnu&
+endfunc
+
+func Test_set_global_and_local()
+  " setlocal must NOT reset the other global value
+  set nonu nornu
+  setglobal nu
+  setlocal rnu
+  call assert_equal(1, &g:nu)
+
+  set nonu nornu
+  setglobal rnu
+  setlocal nu
+  call assert_equal(1, &g:rnu)
+
+  " setglobal MUST reset the other global value
+  set nonu nornu
+  setglobal nu
+  setglobal rnu
+  call assert_equal(1, &g:nu)
+
+  set nonu nornu
+  setglobal rnu
+  setglobal nu
+  call assert_equal(1, &g:rnu)
+
+  " set MUST reset the other global value
+  set nonu nornu
+  set nu
+  set rnu
+  call assert_equal(1, &g:nu)
+
+  set nonu nornu
+  set rnu
+  set nu
+  call assert_equal(1, &g:rnu)
+
+  set nu& rnu&
+endfunc
+
+func Test_number()
+  call s:test_windows(10, 20)
+  call setline(1, ["abcdefghij", "klmnopqrst", "uvwxyzABCD", "EFGHIJKLMN", "OPQRSTUVWX", "YZ"])
+  setl number
+  let lines = s:screen_lines(1, 4)
+  let expect = [
+\ "  1 abcd",
+\ "  2 klmn",
+\ "  3 uvwx",
+\ "  4 EFGH",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_relativenumber()
+  call s:test_windows(10, 20)
+  call setline(1, ["abcdefghij", "klmnopqrst", "uvwxyzABCD", "EFGHIJKLMN", "OPQRSTUVWX", "YZ"])
+  3
+  setl relativenumber
+  let lines = s:screen_lines(1, 6)
+  let expect = [
+\ "  2 abcd",
+\ "  1 klmn",
+\ "  0 uvwx",
+\ "  1 EFGH",
+\ "  2 OPQR",
+\ "  3 YZ  ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_number_with_relativenumber()
+  call s:test_windows(10, 20)
+  call setline(1, ["abcdefghij", "klmnopqrst", "uvwxyzABCD", "EFGHIJKLMN", "OPQRSTUVWX", "YZ"])
+  4
+  setl number relativenumber
+  let lines = s:screen_lines(1, 6)
+  let expect = [
+\ "  3 abcd",
+\ "  2 klmn",
+\ "  1 uvwx",
+\ "4   EFGH",
+\ "  1 OPQR",
+\ "  2 YZ  ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_number_with_linewrap1()
+  call s:test_windows(3, 20)
+  normal! 61ia
+  setl number wrap
+  call s:validate_cursor()
+  let lines = s:screen_lines(1, 3)
+  let expect = [
+\ "--1 aaaa",
+\ "    aaaa",
+\ "    aaaa",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+" Pending: https://groups.google.com/forum/#!topic/vim_dev/tzNKP7EDWYI
+func XTest_number_with_linewrap2()
+  call s:test_windows(3, 20)
+  normal! 61ia
+  setl number wrap
+  call s:validate_cursor()
+  0
+  call s:validate_cursor()
+  let lines = s:screen_lines(1, 3)
+  let expect = [
+\ "  1 aaaa",
+\ "    aaaa",
+\ "    aaaa",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+" Pending: https://groups.google.com/forum/#!topic/vim_dev/tzNKP7EDWYI
+func XTest_number_with_linewrap3()
+  call s:test_windows(4, 20)
+  normal! 81ia
+  setl number wrap
+  call s:validate_cursor()
+  setl nonumber
+  call s:validate_cursor()
+  let lines = s:screen_lines(1, 4)
+  let expect = [
+\ "aaaaaaaa",
+\ "aaaaaaaa",
+\ "aaaaaaaa",
+\ "a       ",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_numberwidth()
+  call s:test_windows(10, 20)
+  call setline(1, repeat(['aaaa'], 10))
+  setl number numberwidth=6
+  let lines = s:screen_lines(1, 3)
+  let expect = [
+\ "    1 aa",
+\ "    2 aa",
+\ "    3 aa",
+\ ]
+  call s:compare_lines(expect, lines)
+
+  set relativenumber
+  let lines = s:screen_lines(1, 3)
+  let expect = [
+\ "1     aa",
+\ "    1 aa",
+\ "    2 aa",
+\ ]
+  call s:compare_lines(expect, lines)
+
+  set nonumber
+  let lines = s:screen_lines(1, 3)
+  let expect = [
+\ "    0 aa",
+\ "    1 aa",
+\ "    2 aa",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
+
+func Test_numberwidth_adjusted()
+  call s:test_windows(10, 20)
+  call setline(1, repeat(['aaaa'], 10000))
+  setl number numberwidth=4
+  let lines = s:screen_lines(1, 3)
+  let expect = [
+\ "    1 aa",
+\ "    2 aa",
+\ "    3 aa",
+\ ]
+  call s:compare_lines(expect, lines)
+
+  $
+  let lines = s:screen_lines(8, 10)
+  let expect = [
+\ " 9998 aa",
+\ " 9999 aa",
+\ "10000 aa",
+\ ]
+  call s:compare_lines(expect, lines)
+
+  setl relativenumber
+  let lines = s:screen_lines(8, 10)
+  let expect = [
+\ "    2 aa",
+\ "    1 aa",
+\ "10000 aa",
+\ ]
+  call s:compare_lines(expect, lines)
+
+  setl nonumber
+  let lines = s:screen_lines(8, 10)
+  let expect = [
+\ "  2 aaaa",
+\ "  1 aaaa",
+\ "  0 aaaa",
+\ ]
+  call s:compare_lines(expect, lines)
+  call s:close_windows()
+endfunc
index 3b6f662..5d2033a 100644 (file)
@@ -13,9 +13,35 @@ function! Test_whichwrap()
   set whichwrap+=h,l
   call assert_equal('b,s,h,l', &whichwrap)
 
+  set whichwrap=h,h
+  call assert_equal('h', &whichwrap)
+
+  set whichwrap=h,h,h
+  call assert_equal('h', &whichwrap)
+
   set whichwrap&
 endfunction
 
+function! Test_isfname()
+  " This used to cause Vim to access uninitialized memory.
+  set isfname=
+  call assert_equal("~X", expand("~X"))
+  set isfname&
+endfunction
+
+function Test_wildchar()
+  " Empty 'wildchar' used to access invalid memory.
+  call assert_fails('set wildchar=', 'E521:')
+  call assert_fails('set wildchar=abc', 'E521:')
+  set wildchar=<Esc>
+  let a=execute('set wildchar?')
+  call assert_equal("\n  wildchar=<Esc>", a)
+  set wildchar=27
+  let a=execute('set wildchar?')
+  call assert_equal("\n  wildchar=<Esc>", a)
+  set wildchar&
+endfunction
+
 function Test_options()
   let caught = 'ok'
   try
@@ -106,3 +132,203 @@ func Test_keymap_valid()
   call assert_fails(":set kmp=trunc\x00name", "E544:")
   call assert_fails(":set kmp=trunc\x00name", "trunc")
 endfunc
+
+func Check_dir_option(name)
+  " Check that it's possible to set the option.
+  exe 'set ' . a:name . '=/usr/share/dict/words'
+  call assert_equal('/usr/share/dict/words', eval('&' . a:name))
+  exe 'set ' . a:name . '=/usr/share/dict/words,/and/there'
+  call assert_equal('/usr/share/dict/words,/and/there', eval('&' . a:name))
+  exe 'set ' . a:name . '=/usr/share/dict\ words'
+  call assert_equal('/usr/share/dict words', eval('&' . a:name))
+
+  " Check rejecting weird characters.
+  call assert_fails("set " . a:name . "=/not&there", "E474:")
+  call assert_fails("set " . a:name . "=/not>there", "E474:")
+  call assert_fails("set " . a:name . "=/not.*there", "E474:")
+endfunc
+
+func Test_cinkeys()
+  " This used to cause invalid memory access
+  set cindent cinkeys=0
+  norm a
+  set cindent& cinkeys&
+endfunc
+
+func Test_dictionary()
+  call Check_dir_option('dictionary')
+endfunc
+
+func Test_thesaurus()
+  call Check_dir_option('thesaurus')
+endfun
+
+func Test_complete()
+  " Trailing single backslash used to cause invalid memory access.
+  set complete=s\
+  new
+  call feedkeys("i\<C-N>\<Esc>", 'xt')
+  bwipe!
+  set complete&
+endfun
+
+func Test_set_completion()
+  call feedkeys(":set di\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"set dictionary diff diffexpr diffopt digraph directory display', @:)
+
+  " Expand boolan options. When doing :set no<Tab>
+  " vim displays the options names without "no" but completion uses "no...".
+  call feedkeys(":set nodi\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"set nodiff digraph', @:)
+
+  call feedkeys(":set invdi\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"set invdiff digraph', @:)
+
+  " Expand abbreviation of options.
+  call feedkeys(":set ts\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"set tabstop thesaurus ttyscroll', @:)
+
+  " Expand current value
+  call feedkeys(":set fileencodings=\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"set fileencodings=ucs-bom,utf-8,default,latin1', @:)
+
+  call feedkeys(":set fileencodings:\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"set fileencodings:ucs-bom,utf-8,default,latin1', @:)
+
+  " Expand key codes.
+  call feedkeys(":set <H\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"set <Help> <Home>', @:)
+
+  " Expand terminal options.
+  call feedkeys(":set t_A\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"set t_AB t_AF t_AL', @:)
+
+  " Expand directories.
+  call feedkeys(":set cdpath=./\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_match(' ./samples/ ', @:)
+  call assert_notmatch(' ./small.vim ', @:)
+
+  " Expand files and directories.
+  call feedkeys(":set tags=./\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_match(' ./samples/.* ./small.vim', @:)
+
+  call feedkeys(":set tags=./\\\\ dif\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"set tags=./\\ diff diffexpr diffopt', @:)
+endfunc
+
+func Test_set_errors()
+  call assert_fails('set scroll=-1', 'E49:')
+  call assert_fails('set backupcopy=', 'E474:')
+  call assert_fails('set regexpengine=3', 'E474:')
+  call assert_fails('set history=10001', 'E474:')
+  call assert_fails('set numberwidth=11', 'E474:')
+  call assert_fails('set colorcolumn=-a')
+  call assert_fails('set colorcolumn=a')
+  call assert_fails('set colorcolumn=1,')
+  call assert_fails('set cmdheight=-1', 'E487:')
+  call assert_fails('set cmdwinheight=-1', 'E487:')
+  if has('conceal')
+    call assert_fails('set conceallevel=-1', 'E487:')
+    call assert_fails('set conceallevel=4', 'E474:')
+  endif
+  call assert_fails('set helpheight=-1', 'E487:')
+  call assert_fails('set history=-1', 'E487:')
+  call assert_fails('set report=-1', 'E487:')
+  call assert_fails('set shiftwidth=-1', 'E487:')
+  call assert_fails('set sidescroll=-1', 'E487:')
+  call assert_fails('set tabstop=-1', 'E487:')
+  call assert_fails('set textwidth=-1', 'E487:')
+  call assert_fails('set timeoutlen=-1', 'E487:')
+  call assert_fails('set updatecount=-1', 'E487:')
+  call assert_fails('set updatetime=-1', 'E487:')
+  call assert_fails('set winheight=-1', 'E487:')
+  call assert_fails('set tabstop!', 'E488:')
+  call assert_fails('set xxx', 'E518:')
+  call assert_fails('set beautify?', 'E519:')
+  call assert_fails('set undolevels=x', 'E521:')
+  call assert_fails('set tabstop=', 'E521:')
+  call assert_fails('set comments=-', 'E524:')
+  call assert_fails('set comments=a', 'E525:')
+  call assert_fails('set foldmarker=x', 'E536:')
+  call assert_fails('set commentstring=x', 'E537:')
+  call assert_fails('set complete=x', 'E539:')
+  call assert_fails('set statusline=%{', 'E540:')
+  call assert_fails('set statusline=' . repeat("%p", 81), 'E541:')
+  call assert_fails('set statusline=%(', 'E542:')
+  if has('cursorshape')
+    " This invalid value for 'guicursor' used to cause Vim to crash.
+    call assert_fails('set guicursor=i-ci,r-cr:h', 'E545:')
+    call assert_fails('set guicursor=i-ci', 'E545:')
+    call assert_fails('set guicursor=x', 'E545:')
+    call assert_fails('set guicursor=r-cr:horx', 'E548:')
+    call assert_fails('set guicursor=r-cr:hor0', 'E549:')
+  endif
+  call assert_fails('set backupext=~ patchmode=~', 'E589:')
+  call assert_fails('set winminheight=10 winheight=9', 'E591:')
+  call assert_fails('set winminwidth=10 winwidth=9', 'E592:')
+  call assert_fails("set showbreak=\x01", 'E595:')
+  call assert_fails('set t_foo=', 'E846:')
+endfunc
+
+func Test_set_ttytype()
+  if !has('gui_running') && has('unix')
+    " Setting 'ttytype' used to cause a double-free when exiting vim and
+    " when vim is compiled with -DEXITFREE.
+    set ttytype=ansi
+    call assert_equal('ansi', &ttytype)
+    call assert_equal(&ttytype, &term)
+    set ttytype=xterm
+    call assert_equal('xterm', &ttytype)
+    call assert_equal(&ttytype, &term)
+    " "set ttytype=" gives E522 instead of E529
+    " in travis on some builds. Why?  Catch both for now
+    try
+      set ttytype=
+      call assert_report('set ttype= did not fail')
+    catch /E529\|E522/
+    endtry
+
+    " Some systems accept any terminal name and return dumb settings,
+    " check for failure of finding the entry and for missing 'cm' entry.
+    try
+      set ttytype=xxx
+      call assert_report('set ttype=xxx did not fail')
+    catch /E522\|E437/
+    endtry
+
+    set ttytype&
+    call assert_equal(&ttytype, &term)
+  endif
+endfunc
+
+func Test_set_all()
+  set tw=75
+  set iskeyword=a-z,A-Z
+  set nosplitbelow
+  let out = execute('set all')
+  call assert_match('textwidth=75', out)
+  call assert_match('iskeyword=a-z,A-Z', out)
+  call assert_match('nosplitbelow', out)
+  set tw& iskeyword& splitbelow&
+endfunc
+
+func Test_set_values()
+  if filereadable('opt_test.vim')
+    source opt_test.vim
+  else
+    throw 'Skipped: opt_test.vim does not exist'
+  endif
+endfunc
+
+func ResetIndentexpr()
+  set indentexpr=
+endfunc
+
+func Test_set_indentexpr()
+  " this was causing usage of freed memory
+  set indentexpr=ResetIndentexpr()
+  new
+  call feedkeys("i\<c-f>", 'x')
+  call assert_equal('', &indentexpr)
+  bwipe!
+endfunc
index eca1560..7dcaa60 100644 (file)
@@ -1,5 +1,7 @@
 " Tests for 'packpath' and :packadd
 
+set belloff=all
+
 func SetUp()
   let s:topdir = expand('%:h') . '/Xdir'
   exe 'set packpath=' . s:topdir
@@ -67,6 +69,41 @@ func Test_packadd_noload()
   call assert_equal(new_rtp, &rtp)
 endfunc
 
+func Test_packadd_symlink_dir()
+  if !has('unix')
+    return
+  endif
+  let top2_dir = s:topdir . '/Xdir2'
+  let real_dir = s:topdir . '/Xsym'
+  call mkdir(real_dir, 'p')
+  exec "silent !ln -s Xsym"  top2_dir
+  let &rtp = top2_dir . ',' . top2_dir . '/after'
+  let &packpath = &rtp
+
+  let s:plugdir = top2_dir . '/pack/mine/opt/mytest'
+  call mkdir(s:plugdir . '/plugin', 'p')
+
+  exe 'split ' . s:plugdir . '/plugin/test.vim'
+  call setline(1, 'let g:plugin_works = 44')
+  wq
+  let g:plugin_works = 0
+
+  packadd mytest
+
+  " Must have been inserted in the middle, not at the end
+  call assert_true(&rtp =~ '/pack/mine/opt/mytest,')
+  call assert_equal(44, g:plugin_works)
+
+  " No change when doing it again.
+  let rtp_before = &rtp
+  packadd mytest
+  call assert_equal(rtp_before, &rtp)
+
+  set rtp&
+  let rtp = &rtp
+  exec "silent !rm" top2_dir
+endfunc
+
 " Check command-line completion for 'packadd'
 func Test_packadd_completion()
   let optdir1 = &packpath . '/pack/mine/opt'
diff --git a/src/testdir/test_paste.vim b/src/testdir/test_paste.vim
new file mode 100644 (file)
index 0000000..440dc7f
--- /dev/null
@@ -0,0 +1,99 @@
+" Tests for bracketed paste.
+
+" Bracketed paste only works with "xterm".  Not in GUI.
+if has('gui_running')
+  finish
+endif
+set term=xterm
+
+func Test_paste_normal_mode()
+  new
+  " In first column text is inserted
+  call setline(1, ['a', 'b', 'c'])
+  call cursor(2, 1)
+  call feedkeys("\<Esc>[200~foo\<CR>bar\<Esc>[201~", 'xt')
+  call assert_equal('foo', getline(2))
+  call assert_equal('barb', getline(3))
+  call assert_equal('c', getline(4))
+
+  " When repeating text is appended
+  normal .
+  call assert_equal('barfoo', getline(3))
+  call assert_equal('barb', getline(4))
+  call assert_equal('c', getline(5))
+  bwipe!
+
+  " In second column text is appended
+  call setline(1, ['a', 'bbb', 'c'])
+  call cursor(2, 2)
+  call feedkeys("\<Esc>[200~foo\<CR>bar\<Esc>[201~", 'xt')
+  call assert_equal('bbfoo', getline(2))
+  call assert_equal('barb', getline(3))
+  call assert_equal('c', getline(4))
+
+  " In last column text is appended
+  call setline(1, ['a', 'bbb', 'c'])
+  call cursor(2, 3)
+  call feedkeys("\<Esc>[200~foo\<CR>bar\<Esc>[201~", 'xt')
+  call assert_equal('bbbfoo', getline(2))
+  call assert_equal('bar', getline(3))
+  call assert_equal('c', getline(4))
+endfunc
+
+func Test_paste_insert_mode()
+  new
+  call setline(1, ['a', 'b', 'c'])
+  2
+  call feedkeys("i\<Esc>[200~foo\<CR>bar\<Esc>[201~ done\<Esc>", 'xt')
+  call assert_equal('foo', getline(2))
+  call assert_equal('bar doneb', getline(3))
+  call assert_equal('c', getline(4))
+
+  normal .
+  call assert_equal('bar donfoo', getline(3))
+  call assert_equal('bar doneeb', getline(4))
+  call assert_equal('c', getline(5))
+
+  set ai et tw=10
+  call setline(1, ['a', '    b', 'c'])
+  2
+  call feedkeys("A\<Esc>[200~foo\<CR> bar bar bar\<Esc>[201~\<Esc>", 'xt')
+  call assert_equal('    bfoo', getline(2))
+  call assert_equal(' bar bar bar', getline(3))
+  call assert_equal('c', getline(4))
+
+  set ai& et& tw=0
+  bwipe!
+endfunc
+
+func Test_paste_cmdline()
+  call feedkeys(":a\<Esc>[200~foo\<CR>bar\<Esc>[201~b\<Home>\"\<CR>", 'xt')
+  call assert_equal("\"afoo\<CR>barb", getreg(':'))
+endfunc
+
+func Test_paste_visual_mode()
+  new
+  call setline(1, 'here are some words')
+  call feedkeys("0fsve\<Esc>[200~more\<Esc>[201~", 'xt')
+  call assert_equal('here are more words', getline(1))
+  call assert_equal('some', getreg('-'))
+
+  " include last char in the line
+  call feedkeys("0fwve\<Esc>[200~noises\<Esc>[201~", 'xt')
+  call assert_equal('here are more noises', getline(1))
+  call assert_equal('words', getreg('-'))
+
+  " exclude last char in the line
+  call setline(1, 'some words!')
+  call feedkeys("0fwve\<Esc>[200~noises\<Esc>[201~", 'xt')
+  call assert_equal('some noises!', getline(1))
+  call assert_equal('words', getreg('-'))
+
+  " multi-line selection
+  call setline(1, ['some words', 'and more'])
+  call feedkeys("0fwvj0fd\<Esc>[200~letters\<Esc>[201~", 'xt')
+  call assert_equal('some letters more', getline(1))
+  call assert_equal("words\nand", getreg('1'))
+
+  bwipe!
+endfunc
index da47ab1..6ef17ad 100644 (file)
@@ -26,17 +26,117 @@ EOF
   call assert_equal('abc/def/', getline('$'))
 endfunc
 
-fu <SID>catch_peval(expr)
+func Test_buffer_Delete()
+  new
+  call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])
+  perl $curbuf->Delete(7)
+  perl $curbuf->Delete(2, 5)
+  perl $curbuf->Delete(10)
+  call assert_equal(['a', 'f', 'h'],  getline(1, '$'))
+  bwipe!
+endfunc
+
+func Test_buffer_Append()
+  new
+  perl $curbuf->Append(1, '1')
+  perl $curbuf->Append(2, '2', '3', '4')
+  perl @l = ('5' ..'7')
+  perl $curbuf->Append(0, @l)
+  call assert_equal(['5', '6', '7', '', '1', '2', '3', '4'], getline(1, '$'))
+  bwipe!
+endfunc
+
+func Test_buffer_Set()
+  new
+  call setline(1, ['1', '2', '3', '4', '5'])
+  perl $curbuf->Set(2, 'a', 'b', 'c')
+  perl $curbuf->Set(4, 'A', 'B', 'C')
+  call assert_equal(['1', 'a', 'b', 'A', 'B'], getline(1, '$'))
+  bwipe!
+endfunc
+
+func Test_buffer_Get()
+  new
+  call setline(1, ['1', '2', '3', '4'])
+  call assert_equal('2:3', perleval('join(":", $curbuf->Get(2, 3))'))
+  bwipe!
+endfunc
+
+func Test_buffer_Count()
+  new
+  call setline(1, ['a', 'b', 'c'])
+  call assert_equal(3, perleval('$curbuf->Count()'))
+  bwipe!
+endfunc
+
+func Test_buffer_Name()
+  new
+  call assert_equal('', perleval('$curbuf->Name()'))
+  bwipe!
+  new Xfoo
+  call assert_equal('Xfoo', perleval('$curbuf->Name()'))
+  bwipe!
+endfunc
+
+func Test_buffer_Number()
+  call assert_equal(bufnr('%'), perleval('$curbuf->Number()'))
+endfunc
+
+func Test_window_Cursor()
+  new
+  call setline(1, ['line1', 'line2'])
+  perl $curwin->Cursor(2, 3)
+  call assert_equal('2:3', perleval('join(":", $curwin->Cursor())'))
+  " Col is numbered from 0 in Perl, and from 1 in Vim script.
+  call assert_equal([0, 2, 4, 0], getpos('.'))
+  bwipe!
+endfunc
+
+func Test_window_SetHeight()
+  new
+  perl $curwin->SetHeight(2)
+  call assert_equal(2, winheight(0))
+  bwipe!
+endfunc
+
+func Test_VIM_Windows()
+  new
+  " VIM::Windows() without argument in scalar and list context.
+  perl $winnr = VIM::Windows()
+  perl @winlist = VIM::Windows()
+  perl $curbuf->Append(0, $winnr, scalar(@winlist))
+  call assert_equal(['2', '2', ''], getline(1, '$'))
+
+  " VIM::Windows() with window number argument.
+  perl VIM::Windows(VIM::Eval('winnr()'))->Buffer()->Set(1, 'bar')
+  call assert_equal('bar', getline(1))
+  bwipe!
+endfunc
+
+func Test_VIM_Buffers()
+  new Xbar
+  " VIM::Buffers() without argument in scalar and list context.
+  perl $nbuf = VIM::Buffers()
+  perl @buflist = VIM::Buffers()
+
+  " VIM::Buffers() with argument.
+  perl $mybuf = (VIM::Buffers('Xbar'))[0]
+  perl $mybuf->Append(0, $nbuf, scalar(@buflist))
+  call assert_equal(['2', '2', ''], getline(1, '$'))
+  bwipe!
+endfunc
+
+func <SID>catch_peval(expr)
   try
     call perleval(a:expr)
   catch
     return v:exception
   endtry
-  call assert_true(0, 'no exception for `perleval("'.a:expr.'")`')
+  call assert_report('no exception for `perleval("'.a:expr.'")`')
   return ''
 endfunc
 
-function Test_perleval()
+func Test_perleval()
   call assert_false(perleval('undef'))
 
   " scalar
@@ -75,16 +175,31 @@ function Test_perleval()
   call assert_true(perleval('\\0') =~ 'SCALAR(0x\x\+)')
 endfunc
 
-function Test_perldo()
+func Test_perldo()
   sp __TEST__
   exe 'read ' g:testname
   perldo s/perl/vieux_chameau/g
   1
   call assert_false(search('\Cperl'))
   bw!
+
+  " Check deleting lines does not trigger ml_get error.
+  new
+  call setline(1, ['one', 'two', 'three'])
+  perldo VIM::DoCommand("%d_")
+  bwipe!
+
+  " Check switching to another buffer does not trigger ml_get error.
+  new
+  let wincount = winnr('$')
+  call setline(1, ['one', 'two', 'three'])
+  perldo VIM::DoCommand("new")
+  call assert_equal(wincount + 1, winnr('$'))
+  bwipe!
+  bwipe!
 endfunc
 
-function Test_VIM_package()
+func Test_VIM_package()
   perl VIM::DoCommand('let l:var = "foo"')
   call assert_equal(l:var, 'foo')
 
@@ -93,7 +208,7 @@ function Test_VIM_package()
   call assert_true(&et)
 endfunc
 
-function Test_stdio()
+func Test_stdio()
   redir =>l:out
   perl <<EOF
     VIM::Msg("&VIM::Msg");
@@ -104,7 +219,7 @@ EOF
   call assert_equal(['&VIM::Msg', 'STDOUT', 'STDERR'], split(l:out, "\n"))
 endfunc
 
-function Test_SvREFCNT()
+func Test_SvREFCNT()
   new t
   perl <<--perl
   my ($b, $w);
index f1e2c98..4789ca7 100644 (file)
@@ -7,10 +7,10 @@ func! ListMonths()
   if g:setting != ''
     exe ":set" g:setting
   endif
-  let mth=copy(g:months)
+  let mth = copy(g:months)
   let entered = strcharpart(getline('.'),0,col('.'))
   if !empty(entered)
-    let mth=filter(mth, 'v:val=~"^".entered')
+    let mth = filter(mth, 'v:val=~"^".entered')
   endif
   call complete(1, mth) 
   return ''
@@ -464,4 +464,110 @@ func Test_completefunc_with_scratch_buffer()
   set completeopt&
 endfunc
 
+" <C-E> - select original typed text before the completion started without
+" auto-wrap text.
+func Test_completion_ctrl_e_without_autowrap()
+  new
+  let tw_save = &tw
+  set tw=78
+  let li = [
+        \ '"                                                        zzz',
+        \ '" zzzyyyyyyyyyyyyyyyyyyy']
+  call setline(1, li)
+  0
+  call feedkeys("A\<C-X>\<C-N>\<C-E>\<Esc>", "tx")
+  call assert_equal(li, getline(1, '$'))
+
+  let &tw = tw_save
+  q!
+endfunc
+
+function! DummyCompleteSix()
+  call complete(1, ['Hello', 'World'])
+  return ''
+endfunction
+
+" complete() correctly clears the list of autocomplete candidates
+" See #1411
+func Test_completion_clear_candidate_list()
+  new
+  %d
+  " select first entry from the completion popup
+  call feedkeys("a    xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>", "tx")
+  call assert_equal('Hello', getline(1))
+  %d
+  " select second entry from the completion popup
+  call feedkeys("a    xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>", "tx")
+  call assert_equal('World', getline(1))
+  %d
+  " select original text
+  call feedkeys("a    xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>\<C-N>", "tx")
+  call assert_equal('    xxx', getline(1))
+  %d
+  " back at first entry from completion list
+  call feedkeys("a    xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>\<C-N>\<C-N>", "tx")
+  call assert_equal('Hello', getline(1))
+
+  bw!
+endfunc
+
+func Test_completion_respect_bs_option()
+  new
+  let li = ["aaa", "aaa12345", "aaaabcdef", "aaaABC"]
+
+  set bs=indent,eol
+  call setline(1, li)
+  1
+  call feedkeys("A\<C-X>\<C-N>\<C-P>\<BS>\<BS>\<BS>\<Esc>", "tx")
+  call assert_equal('aaa', getline(1))
+
+  %d
+  set bs=indent,eol,start
+  call setline(1, li)
+  1
+  call feedkeys("A\<C-X>\<C-N>\<C-P>\<BS>\<BS>\<BS>\<Esc>", "tx")
+  call assert_equal('', getline(1))
+
+  bw!
+endfunc
+
+func CompleteUndo() abort
+  call complete(1, g:months)
+  return ''
+endfunc
+
+func Test_completion_can_undo()
+  inoremap <Right> <c-r>=CompleteUndo()<cr>
+  set completeopt+=noinsert,noselect
+
+  new
+  call feedkeys("a\<Right>a\<Esc>", 'xt')
+  call assert_equal('a', getline(1))
+  undo
+  call assert_equal('', getline(1))
+
+  bwipe!
+  set completeopt&
+  iunmap <Right>
+endfunc
+
+func Test_completion_comment_formatting()
+  new
+  setl formatoptions=tcqro
+  call feedkeys("o/*\<cr>\<cr>/\<esc>", 'tx')
+  call assert_equal(['', '/*', ' *', ' */'], getline(1,4))
+  %d
+  call feedkeys("o/*\<cr>foobar\<cr>/\<esc>", 'tx')
+  call assert_equal(['', '/*', ' * foobar', ' */'], getline(1,4))
+  %d
+  try
+    call feedkeys("o/*\<cr>\<cr>\<c-x>\<c-u>/\<esc>", 'tx')
+    call assert_report('completefunc not set, should have failed')
+  catch
+    call assert_exception('E764:')
+  endtry
+  call assert_equal(['', '/*', ' *', ' */'], getline(1,4))
+  bwipe!
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_profile.vim b/src/testdir/test_profile.vim
new file mode 100644 (file)
index 0000000..5f15d51
--- /dev/null
@@ -0,0 +1,146 @@
+" Test Vim profiler
+if !has('profile')
+  finish
+endif
+
+func Test_profile_func()
+  let lines = [
+    \ "func! Foo1()",
+    \ "endfunc",
+    \ "func! Foo2()",
+    \ "  let l:count = 100",
+    \ "  while l:count > 0",
+    \ "    let l:count = l:count - 1",
+    \ "  endwhile",
+    \ "endfunc",
+    \ "func! Foo3()",
+    \ "endfunc",
+    \ "func! Bar()",
+    \ "endfunc",
+    \ "call Foo1()",
+    \ "call Foo1()",
+    \ "profile pause",
+    \ "call Foo1()",
+    \ "profile continue",
+    \ "call Foo2()",
+    \ "call Foo3()",
+    \ "call Bar()",
+    \ "if !v:profiling",
+    \ "  delfunc Foo2",
+    \ "endif",
+    \ "delfunc Foo3",
+    \ ]
+
+  call writefile(lines, 'Xprofile_func.vim')
+  call system(v:progpath
+    \ . ' -es -u NONE -U NONE -i NONE --noplugin'
+    \ . ' -c "profile start Xprofile_func.log"'
+    \ . ' -c "profile func Foo*"'
+    \ . ' -c "so Xprofile_func.vim"'
+    \ . ' -c "qall!"')
+  call assert_equal(0, v:shell_error)
+
+  let lines = readfile('Xprofile_func.log')
+
+  " - Foo1() is called 3 times but should be reported as called twice
+  "   since one call is in between "profile pause" .. "profile continue".
+  " - Foo2() should come before Foo1() since Foo1() does much more work.
+  " - Foo3() is not reported because function is deleted.
+  " - Unlike Foo3(), Foo2() should not be deleted since there is a check
+  "   for v:profiling.
+  " - Bar() is not reported since it does not match "profile func Foo*".
+  call assert_equal(28, len(lines))
+
+  call assert_equal('FUNCTION  Foo1()',                            lines[0])
+  call assert_equal('Called 2 times',                              lines[1])
+  call assert_match('^Total time:\s\+\d\+\.\d\+$',                 lines[2])
+  call assert_match('^ Self time:\s\+\d\+\.\d\+$',                 lines[3])
+  call assert_equal('',                                            lines[4])
+  call assert_equal('count  total (s)   self (s)',                 lines[5])
+  call assert_equal('',                                            lines[6])
+  call assert_equal('FUNCTION  Foo2()',                            lines[7])
+  call assert_equal('Called 1 time',                               lines[8])
+  call assert_match('^Total time:\s\+\d\+\.\d\+$',                 lines[9])
+  call assert_match('^ Self time:\s\+\d\+\.\d\+$',                 lines[10])
+  call assert_equal('',                                            lines[11])
+  call assert_equal('count  total (s)   self (s)',                 lines[12])
+  call assert_match('^\s*1\s\+.*\slet l:count = 100$',             lines[13])
+  call assert_match('^\s*101\s\+.*\swhile l:count > 0$',           lines[14])
+  call assert_match('^\s*100\s\+.*\s  let l:count = l:count - 1$', lines[15])
+  call assert_match('^\s*100\s\+.*\sendwhile$',                    lines[16])
+  call assert_equal('',                                            lines[17])
+  call assert_equal('FUNCTIONS SORTED ON TOTAL TIME',              lines[18])
+  call assert_equal('count  total (s)   self (s)  function',       lines[19])
+  call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$',              lines[20])
+  call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$',              lines[21])
+  call assert_equal('',                                            lines[22])
+  call assert_equal('FUNCTIONS SORTED ON SELF TIME',               lines[23])
+  call assert_equal('count  total (s)   self (s)  function',       lines[24])
+  call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$',              lines[25])
+  call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$',              lines[26])
+  call assert_equal('',                                            lines[27])
+
+  call delete('Xprofile_func.vim')
+  call delete('Xprofile_func.log')
+endfunc
+
+func Test_profile_file()
+  let lines = [
+    \ 'func! Foo()',
+    \ 'endfunc',
+    \ 'for i in range(10)',
+    \ '  " a comment',
+    \ '  call Foo()',
+    \ 'endfor',
+    \ 'call Foo()',
+    \ ]
+
+  call writefile(lines, 'Xprofile_file.vim')
+  call system(v:progpath
+    \ . ' -es -u NONE -U NONE -i NONE --noplugin'
+    \ . ' -c "profile start Xprofile_file.log"'
+    \ . ' -c "profile file Xprofile_file.vim"'
+    \ . ' -c "so Xprofile_file.vim"'
+    \ . ' -c "so Xprofile_file.vim"'
+    \ . ' -c "qall!"')
+  call assert_equal(0, v:shell_error)
+
+  let lines = readfile('Xprofile_file.log')
+
+  call assert_equal(14, len(lines))
+
+  call assert_match('^SCRIPT .*Xprofile_file.vim$',                   lines[0])
+  call assert_equal('Sourced 2 times',                                lines[1])
+  call assert_match('^Total time:\s\+\d\+\.\d\+$',                    lines[2])
+  call assert_match('^ Self time:\s\+\d\+\.\d\+$',                    lines[3])
+  call assert_equal('',                                               lines[4])
+  call assert_equal('count  total (s)   self (s)',                    lines[5])
+  call assert_equal('                            func! Foo()',        lines[6])
+  call assert_equal('                            endfunc',            lines[7])
+  " Loop iterates 10 times. Since script runs twice, body executes 20 times.
+  " First line of loop executes one more time than body to detect end of loop.
+  call assert_match('^\s*22\s\+\d\+\.\d\+\s\+for i in range(10)$',    lines[8])
+  call assert_equal('                              " a comment',      lines[9])
+  call assert_match('^\s*20\s\+\d\+\.\d\+\s\+\d\+\.\d\+\s\+call Foo()$', lines[10])
+  call assert_match('^\s*20\s\+\d\+\.\d\+\s\+endfor$',                lines[11])
+  " if self and total are equal we only get one number
+  call assert_match('^\s*2\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[12])
+  call assert_equal('',                                               lines[13])
+
+  call delete('Xprofile_file.vim')
+  call delete('Xprofile_file.log')
+endfunc
+
+func Test_profile_completion()
+  call feedkeys(":profile \<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"profile continue file func pause start', @:)
+
+  call feedkeys(":profile start test_prof\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_match('^"profile start.* test_profile\.vim', @:)
+endfunc
+
+func Test_profile_errors()
+  call assert_fails("profile func Foo", 'E750:')
+  call assert_fails("profile pause", 'E750:')
+  call assert_fails("profile continue", 'E750:')
+endfunc
diff --git a/src/testdir/test_put.vim b/src/testdir/test_put.vim
new file mode 100644 (file)
index 0000000..38c812b
--- /dev/null
@@ -0,0 +1,36 @@
+
+func Test_put_block()
+  if !has('multi_byte')
+    return
+  endif
+  new
+  call feedkeys("i\<C-V>u2500\<CR>x\<ESC>", 'x')
+  call feedkeys("\<C-V>y", 'x')
+  call feedkeys("gg0p", 'x')
+  call assert_equal("\u2500x", getline(1))
+  bwipe!
+endfunc
+
+func Test_put_char_block()
+  new
+  call setline(1, ['Line 1', 'Line 2'])
+  f Xfile_put
+  " visually select both lines and put the cursor at the top of the visual
+  " selection and then put the buffer name over it
+  exe "norm! G0\<c-v>ke\"%p"
+  call assert_equal(['Xfile_put 1', 'Xfile_put 2'], getline(1,2))
+  bw!
+endfunc
+
+func Test_put_char_block2()
+  new
+  let a = [ getreg('a'), getregtype('a') ]
+  call setreg('a', ' one ', 'v')
+  call setline(1, ['Line 1', '', 'Line 3', ''])
+  " visually select the first 3 lines and put register a over it
+  exe "norm! ggl\<c-v>2j2l\"ap"
+  call assert_equal(['L one  1', '', 'L one  3', ''], getline(1,4))
+  " clean up
+  bw!
+  call setreg('a', a[0], a[1])
+endfunc
diff --git a/src/testdir/test_python2.vim b/src/testdir/test_python2.vim
new file mode 100644 (file)
index 0000000..fb98c1e
--- /dev/null
@@ -0,0 +1,24 @@
+" Test for python 2 commands.
+" TODO: move tests from test87.in here.
+
+if !has('python')
+  finish
+endif
+
+func Test_pydo()
+  " Check deleting lines does not trigger ml_get error.
+  py import vim
+  new
+  call setline(1, ['one', 'two', 'three'])
+  pydo vim.command("%d_")
+  bwipe!
+
+  " Check switching to another buffer does not trigger ml_get error.
+  new
+  let wincount = winnr('$')
+  call setline(1, ['one', 'two', 'three'])
+  pydo vim.command("new")
+  call assert_equal(wincount + 1, winnr('$'))
+  bwipe!
+  bwipe!
+endfunc
diff --git a/src/testdir/test_python3.vim b/src/testdir/test_python3.vim
new file mode 100644 (file)
index 0000000..bb241da
--- /dev/null
@@ -0,0 +1,24 @@
+" Test for python 2 commands.
+" TODO: move tests from test88.in here.
+
+if !has('python3')
+  finish
+endif
+
+func Test_py3do()
+  " Check deleting lines does not trigger an ml_get error.
+  py3 import vim
+  new
+  call setline(1, ['one', 'two', 'three'])
+  py3do vim.command("%d_")
+  bwipe!
+
+  " Check switching to another buffer does not trigger an ml_get error.
+  new
+  let wincount = winnr('$')
+  call setline(1, ['one', 'two', 'three'])
+  py3do vim.command("new")
+  call assert_equal(wincount + 1, winnr('$'))
+  bwipe!
+  bwipe!
+endfunc
diff --git a/src/testdir/test_pyx2.vim b/src/testdir/test_pyx2.vim
new file mode 100644 (file)
index 0000000..50e57c3
--- /dev/null
@@ -0,0 +1,74 @@
+" Test for pyx* commands and functions with Python 2.
+
+set pyx=2
+if !has('python')
+  finish
+endif
+
+let s:py2pattern = '^2\.[0-7]\.\d\+'
+let s:py3pattern = '^3\.\d\+\.\d\+'
+
+
+func Test_has_pythonx()
+  call assert_true(has('pythonx'))
+endfunc
+
+
+func Test_pyx()
+  redir => var
+  pyx << EOF
+import sys
+print(sys.version)
+EOF
+  redir END
+  call assert_match(s:py2pattern, split(var)[0])
+endfunc
+
+
+func Test_pyxdo()
+  pyx import sys
+  enew
+  pyxdo return sys.version.split("\n")[0]
+  call assert_match(s:py2pattern, split(getline('.'))[0])
+endfunc
+
+
+func Test_pyxeval()
+  pyx import sys
+  call assert_match(s:py2pattern, split(pyxeval('sys.version'))[0])
+endfunc
+
+
+func Test_pyxfile()
+  " No special comments nor shebangs
+  redir => var
+  pyxfile pyxfile/pyx.py
+  redir END
+  call assert_match(s:py2pattern, split(var)[0])
+
+  " Python 2 special comment
+  redir => var
+  pyxfile pyxfile/py2_magic.py
+  redir END
+  call assert_match(s:py2pattern, split(var)[0])
+
+  " Python 2 shebang
+  redir => var
+  pyxfile pyxfile/py2_shebang.py
+  redir END
+  call assert_match(s:py2pattern, split(var)[0])
+
+  if has('python3')
+    " Python 3 special comment
+    redir => var
+    pyxfile pyxfile/py3_magic.py
+    redir END
+    call assert_match(s:py3pattern, split(var)[0])
+
+    " Python 3 shebang
+    redir => var
+    pyxfile pyxfile/py3_shebang.py
+    redir END
+    call assert_match(s:py3pattern, split(var)[0])
+  endif
+endfunc
diff --git a/src/testdir/test_pyx3.vim b/src/testdir/test_pyx3.vim
new file mode 100644 (file)
index 0000000..64546b4
--- /dev/null
@@ -0,0 +1,74 @@
+" Test for pyx* commands and functions with Python 3.
+
+set pyx=3
+if !has('python3')
+  finish
+endif
+
+let s:py2pattern = '^2\.[0-7]\.\d\+'
+let s:py3pattern = '^3\.\d\+\.\d\+'
+
+
+func Test_has_pythonx()
+  call assert_true(has('pythonx'))
+endfunc
+
+
+func Test_pyx()
+  redir => var
+  pyx << EOF
+import sys
+print(sys.version)
+EOF
+  redir END
+  call assert_match(s:py3pattern, split(var)[0])
+endfunc
+
+
+func Test_pyxdo()
+  pyx import sys
+  enew
+  pyxdo return sys.version.split("\n")[0]
+  call assert_match(s:py3pattern, split(getline('.'))[0])
+endfunc
+
+
+func Test_pyxeval()
+  pyx import sys
+  call assert_match(s:py3pattern, split(pyxeval('sys.version'))[0])
+endfunc
+
+
+func Test_pyxfile()
+  " No special comments nor shebangs
+  redir => var
+  pyxfile pyxfile/pyx.py
+  redir END
+  call assert_match(s:py3pattern, split(var)[0])
+
+  " Python 3 special comment
+  redir => var
+  pyxfile pyxfile/py3_magic.py
+  redir END
+  call assert_match(s:py3pattern, split(var)[0])
+
+  " Python 3 shebang
+  redir => var
+  pyxfile pyxfile/py3_shebang.py
+  redir END
+  call assert_match(s:py3pattern, split(var)[0])
+
+  if has('python')
+    " Python 2 special comment
+    redir => var
+    pyxfile pyxfile/py2_magic.py
+    redir END
+    call assert_match(s:py2pattern, split(var)[0])
+
+    " Python 2 shebang
+    redir => var
+    pyxfile pyxfile/py2_shebang.py
+    redir END
+    call assert_match(s:py2pattern, split(var)[0])
+  endif
+endfunc
index 118a015..fa14190 100644 (file)
@@ -6,7 +6,7 @@ endif
 
 set encoding=utf-8
 
-function! s:setup_commands(cchar)
+func s:setup_commands(cchar)
   if a:cchar == 'c'
     command! -nargs=* -bang Xlist <mods>clist<bang> <args>
     command! -nargs=* Xgetexpr <mods>cgetexpr <args>
@@ -24,19 +24,21 @@ function! s:setup_commands(cchar)
     command! -nargs=* Xgetbuffer <mods>cgetbuffer <args>
     command! -nargs=* Xaddbuffer <mods>caddbuffer <args>
     command! -nargs=* Xrewind <mods>crewind <args>
-    command! -nargs=* -bang Xnext <mods>cnext<bang> <args>
-    command! -nargs=* -bang Xprev <mods>cprev<bang> <args>
+    command! -count -nargs=* -bang Xnext <mods><count>cnext<bang> <args>
+    command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args>
     command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args>
     command! -nargs=* -bang Xlast <mods>clast<bang> <args>
     command! -nargs=* -bang Xnfile <mods>cnfile<bang> <args>
     command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args>
     command! -nargs=* Xexpr <mods>cexpr <args>
-    command! -nargs=* Xvimgrep <mods>vimgrep <args>
+    command! -range -nargs=* Xvimgrep <mods><count>vimgrep <args>
+    command! -nargs=* Xvimgrepadd <mods>vimgrepadd <args>
     command! -nargs=* Xgrep <mods> grep <args>
     command! -nargs=* Xgrepadd <mods> grepadd <args>
     command! -nargs=* Xhelpgrep helpgrep <args>
     let g:Xgetlist = function('getqflist')
     let g:Xsetlist = function('setqflist')
+    call setqflist([], 'f')
   else
     command! -nargs=* -bang Xlist <mods>llist<bang> <args>
     command! -nargs=* Xgetexpr <mods>lgetexpr <args>
@@ -54,26 +56,31 @@ function! s:setup_commands(cchar)
     command! -nargs=* Xgetbuffer <mods>lgetbuffer <args>
     command! -nargs=* Xaddbuffer <mods>laddbuffer <args>
     command! -nargs=* Xrewind <mods>lrewind <args>
-    command! -nargs=* -bang Xnext <mods>lnext<bang> <args>
-    command! -nargs=* -bang Xprev <mods>lprev<bang> <args>
+    command! -count -nargs=* -bang Xnext <mods><count>lnext<bang> <args>
+    command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args>
     command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args>
     command! -nargs=* -bang Xlast <mods>llast<bang> <args>
     command! -nargs=* -bang Xnfile <mods>lnfile<bang> <args>
     command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
     command! -nargs=* Xexpr <mods>lexpr <args>
-    command! -nargs=* Xvimgrep <mods>lvimgrep <args>
+    command! -range -nargs=* Xvimgrep <mods><count>lvimgrep <args>
+    command! -nargs=* Xvimgrepadd <mods>lvimgrepadd <args>
     command! -nargs=* Xgrep <mods> lgrep <args>
     command! -nargs=* Xgrepadd <mods> lgrepadd <args>
     command! -nargs=* Xhelpgrep lhelpgrep <args>
     let g:Xgetlist = function('getloclist', [0])
     let g:Xsetlist = function('setloclist', [0])
+    call setloclist(0, [], 'f')
   endif
-endfunction
+endfunc
 
 " Tests for the :clist and :llist commands
-function XlistTests(cchar)
+func XlistTests(cchar)
   call s:setup_commands(a:cchar)
 
+  if a:cchar == 'l'
+      call assert_fails('llist', 'E776:')
+  endif
   " With an empty list, command should return error
   Xgetexpr []
   silent! Xlist
@@ -85,62 +92,68 @@ function XlistTests(cchar)
                  \ 'non-error 3', 'Xtestfile3:3:1:Line3']
 
   " List only valid entries
-  redir => result
-  Xlist
-  redir END
-  let l = split(result, "\n")
+  let l = split(execute('Xlist', ''), "\n")
   call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
                   \ ' 4 Xtestfile2:2 col 2: Line2',
                   \ ' 6 Xtestfile3:3 col 1: Line3'], l)
 
   " List all the entries
-  redir => result
-  Xlist!
-  redir END
-  let l = split(result, "\n")
+  let l = split(execute('Xlist!', ''), "\n")
   call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
                   \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
                   \ ' 5: non-error 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
 
   " List a range of errors
-  redir => result
-  Xlist 3,6
-  redir END
-  let l = split(result, "\n")
+  let l = split(execute('Xlist 3,6', ''), "\n")
   call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
                   \ ' 6 Xtestfile3:3 col 1: Line3'], l)
 
-  redir => result
-  Xlist! 3,4
-  redir END
-  let l = split(result, "\n")
+  let l = split(execute('Xlist! 3,4', ''), "\n")
   call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
 
-  redir => result
-  Xlist -6,-4
-  redir END
-  let l = split(result, "\n")
+  let l = split(execute('Xlist -6,-4', ''), "\n")
   call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
 
-  redir => result
-  Xlist! -5,-3
-  redir END
-  let l = split(result, "\n")
+  let l = split(execute('Xlist! -5,-3', ''), "\n")
   call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
                   \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
-endfunction
 
-function Test_clist()
+  " Test for '+'
+  let l = split(execute('Xlist! +2', ''), "\n")
+  call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
+                  \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
+
+  " Different types of errors
+  call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11},
+             \ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22},
+             \ {'lnum':30,'col':15,'type':'i','text':'Info','nr':33},
+             \ {'lnum':40,'col':20,'type':'x', 'text':'Other','nr':44},
+             \ {'lnum':50,'col':25,'type':"\<C-A>",'text':'one','nr':55}])
+  let l = split(execute('Xlist', ""), "\n")
+  call assert_equal([' 1:10 col 5 warning  11: Warning',
+             \ ' 2:20 col 10 error  22: Error',
+             \ ' 3:30 col 15 info  33: Info',
+             \ ' 4:40 col 20 x  44: Other',
+             \ ' 5:50 col 25  55: one'], l)
+
+  " Error cases
+  call assert_fails('Xlist abc', 'E488:')
+endfunc
+
+func Test_clist()
   call XlistTests('c')
   call XlistTests('l')
-endfunction
+endfunc
 
 " Tests for the :colder, :cnewer, :lolder and :lnewer commands
 " Note that this test assumes that a quickfix/location list is
 " already set by the caller.
-function XageTests(cchar)
+func XageTests(cchar)
   call s:setup_commands(a:cchar)
 
+  let list = [{'bufnr': 1, 'lnum': 1}]
+  call g:Xsetlist(list)
+
   " Jumping to a non existent list should return error
   silent! Xolder 99
   call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
@@ -171,22 +184,23 @@ function XageTests(cchar)
   Xnewer 2
   let l = g:Xgetlist()
   call assert_equal('Line3', l[0].text)
-endfunction
+endfunc
 
-function Test_cage()
-  let list = [{'bufnr': 1, 'lnum': 1}]
-  call setqflist(list)
+func Test_cage()
   call XageTests('c')
-
-  call setloclist(0, list)
   call XageTests('l')
-endfunction
+endfunc
 
 " Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
 " commands
-function XwindowTests(cchar)
+func XwindowTests(cchar)
   call s:setup_commands(a:cchar)
 
+  " Opening the location list window without any errors should fail
+  if a:cchar == 'l'
+      call assert_fails('lopen', 'E776:')
+  endif
+
   " Create a list with no valid entries
   Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
 
@@ -227,16 +241,29 @@ function XwindowTests(cchar)
   " Calling cwindow should close the quickfix window with no valid errors
   Xwindow
   call assert_true(winnr('$') == 1)
-endfunction
 
-function Test_cwindow()
+  if a:cchar == 'c'
+      " Opening the quickfix window in multiple tab pages should reuse the
+      " quickfix buffer
+      Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
+                 \ 'Xtestfile3:3:1:Line3']
+      Xopen
+      let qfbufnum = bufnr('%')
+      tabnew
+      Xopen
+      call assert_equal(qfbufnum, bufnr('%'))
+      new | only | tabonly
+  endif
+endfunc
+
+func Test_cwindow()
   call XwindowTests('c')
   call XwindowTests('l')
-endfunction
+endfunc
 
 " Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
 " commands.
-function XfileTests(cchar)
+func XfileTests(cchar)
   call s:setup_commands(a:cchar)
 
   call writefile(['Xtestfile1:700:10:Line 700',
@@ -275,16 +302,16 @@ function XfileTests(cchar)
        \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
 
   call delete('Xqftestfile1')
-endfunction
+endfunc
 
-function Test_cfile()
+func Test_cfile()
   call XfileTests('c')
   call XfileTests('l')
-endfunction
+endfunc
 
 " Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
 " :lgetbuffer commands.
-function XbufferTests(cchar)
+func XbufferTests(cchar)
   call s:setup_commands(a:cchar)
 
   enew!
@@ -316,35 +343,61 @@ function XbufferTests(cchar)
        \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
   enew!
 
-endfunction
+  " Check for invalid buffer
+  call assert_fails('Xbuffer 199', 'E474:')
+
+  " Check for unloaded buffer
+  edit Xtestfile1
+  let bnr = bufnr('%')
+  enew!
+  call assert_fails('Xbuffer ' . bnr, 'E681:')
 
-function Test_cbuffer()
+  " Check for invalid range
+  " Using Xbuffer will not run the range check in the cbuffer/lbuffer
+  " commands. So directly call the commands.
+  if (a:cchar == 'c')
+      call assert_fails('900,999cbuffer', 'E16:')
+  else
+      call assert_fails('900,999lbuffer', 'E16:')
+  endif
+endfunc
+
+func Test_cbuffer()
   call XbufferTests('c')
   call XbufferTests('l')
-endfunction
+endfunc
 
-function XexprTests(cchar)
+func XexprTests(cchar)
   call s:setup_commands(a:cchar)
 
   call assert_fails('Xexpr 10', 'E777:')
-endfunction
+endfunc
 
-function Test_cexpr()
+func Test_cexpr()
   call XexprTests('c')
   call XexprTests('l')
-endfunction
+endfunc
 
 " Tests for :cnext, :cprev, :cfirst, :clast commands
-function Xtest_browse(cchar)
+func Xtest_browse(cchar)
   call s:setup_commands(a:cchar)
 
+  " Jumping to first or next location list entry without any error should
+  " result in failure
+  if a:cchar == 'l'
+      call assert_fails('lfirst', 'E776:')
+      call assert_fails('lnext', 'E776:')
+  endif
+
   call s:create_test_file('Xqftestfile1')
   call s:create_test_file('Xqftestfile2')
 
   Xgetexpr ['Xqftestfile1:5:Line5',
                \ 'Xqftestfile1:6:Line6',
                \ 'Xqftestfile2:10:Line10',
-               \ 'Xqftestfile2:11:Line11']
+               \ 'Xqftestfile2:11:Line11',
+               \ 'RegularLine1',
+               \ 'RegularLine2']
 
   Xfirst
   call assert_fails('Xprev', 'E553')
@@ -356,6 +409,7 @@ function Xtest_browse(cchar)
   call assert_equal('Xqftestfile1', bufname('%'))
   call assert_equal(6, line('.'))
   Xlast
+  Xprev
   call assert_equal('Xqftestfile2', bufname('%'))
   call assert_equal(11, line('.'))
   call assert_fails('Xnext', 'E553')
@@ -364,16 +418,26 @@ function Xtest_browse(cchar)
   call assert_equal('Xqftestfile1', bufname('%'))
   call assert_equal(5, line('.'))
 
+  10Xnext
+  call assert_equal('Xqftestfile2', bufname('%'))
+  call assert_equal(11, line('.'))
+  10Xprev
+  call assert_equal('Xqftestfile1', bufname('%'))
+  call assert_equal(5, line('.'))
+
+  Xexpr ""
+  call assert_fails('Xnext', 'E42:')
+
   call delete('Xqftestfile1')
   call delete('Xqftestfile2')
-endfunction
+endfunc
 
-function Test_browse()
+func Test_browse()
   call Xtest_browse('c')
   call Xtest_browse('l')
-endfunction
+endfunc
 
-function Test_nomem()
+func Test_nomem()
   call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0)
   call assert_fails('vimgrep vim runtest.vim', 'E342:')
 
@@ -391,7 +455,7 @@ function Test_nomem()
 
 endfunc
 
-function! s:test_xhelpgrep(cchar)
+func s:test_xhelpgrep(cchar)
   call s:setup_commands(a:cchar)
   Xhelpgrep quickfix
   Xopen
@@ -401,11 +465,35 @@ function! s:test_xhelpgrep(cchar)
     let title_text = ':lhelpgrep quickfix'
   endif
   call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
+
+  " Jumping to a help topic should open the help window
+  only
+  Xnext
+  call assert_true(&buftype == 'help')
+  call assert_true(winnr('$') == 2)
+  " Jumping to the next match should reuse the help window
+  Xnext
+  call assert_true(&buftype == 'help')
+  call assert_true(winnr() == 1)
+  call assert_true(winnr('$') == 2)
+  " Jumping to the next match from the quickfix window should reuse the help
+  " window
+  Xopen
+  Xnext
+  call assert_true(&buftype == 'help')
+  call assert_true(winnr() == 1)
+  call assert_true(winnr('$') == 2)
+
   " This wipes out the buffer, make sure that doesn't cause trouble.
   Xclose
-endfunction
 
-function Test_helpgrep()
+  new | only
+
+  " Search for non existing help string
+  call assert_fails('Xhelpgrep a1b2c3', 'E480:')
+endfunc
+
+func Test_helpgrep()
   call s:test_xhelpgrep('c')
   helpclose
   call s:test_xhelpgrep('l')
@@ -443,7 +531,7 @@ func Test_vimgreptitle()
   augroup! QfBufWinEnter
 endfunc
 
-function XqfTitleTests(cchar)
+func XqfTitleTests(cchar)
   call s:setup_commands(a:cchar)
 
   Xgetexpr ['file:1:1:message']
@@ -462,16 +550,16 @@ function XqfTitleTests(cchar)
   endif
   call assert_equal(title, w:quickfix_title)
   Xclose
-endfunction
+endfunc
 
 " Tests for quickfix window's title
-function Test_qf_title()
+func Test_qf_title()
   call XqfTitleTests('c')
   call XqfTitleTests('l')
-endfunction
+endfunc
 
 " Tests for 'errorformat'
-function Test_efm()
+func Test_efm()
   let save_efm = &efm
   set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
   cgetexpr ['WWWW', 'EEEE', 'CCCC']
@@ -484,7 +572,7 @@ function Test_efm()
   let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
   call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
   let &efm = save_efm
-endfunction
+endfunc
 
 " This will test for problems in quickfix:
 " A. incorrectly copying location lists which caused the location list to show
@@ -495,7 +583,7 @@ endfunction
 "    window it belongs to.
 "
 " Set up the test environment:
-function! ReadTestProtocol(name)
+func ReadTestProtocol(name)
   let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
   let word = substitute(base, '\v(.*)\..*', '\1', '')
 
@@ -514,9 +602,9 @@ function! ReadTestProtocol(name)
   setl nomodifiable
   setl readonly
   exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
-endfunction
+endfunc
 
-function Test_locationlist()
+func Test_locationlist()
     enew
 
     augroup testgroup
@@ -539,10 +627,7 @@ function Test_locationlist()
     lrewind
     enew
     lopen
-    lnext
-    lnext
-    lnext
-    lnext
+    4lnext
     vert split
     wincmd L
     lopen
@@ -596,15 +681,15 @@ function Test_locationlist()
     wincmd n | only
 
     augroup! testgroup
-endfunction
+endfunc
 
-function Test_locationlist_curwin_was_closed()
+func Test_locationlist_curwin_was_closed()
     augroup testgroup
       au!
       autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
     augroup END
 
-    function! R(n)
+    func! R(n)
       quit
     endfunc
 
@@ -615,9 +700,9 @@ function Test_locationlist_curwin_was_closed()
     call assert_fails('lrewind', 'E924:')
 
     augroup! testgroup
-endfunction
+endfunc
 
-function Test_locationlist_cross_tab_jump()
+func Test_locationlist_cross_tab_jump()
   call writefile(['loclistfoo'], 'loclistfoo')
   call writefile(['loclistbar'], 'loclistbar')
   set switchbuf=usetab
@@ -631,10 +716,10 @@ function Test_locationlist_cross_tab_jump()
   set switchbuf&vim
   call delete('loclistfoo')
   call delete('loclistbar')
-endfunction
+endfunc
 
 " More tests for 'errorformat'
-function! Test_efm1()
+func Test_efm1()
     if !has('unix')
        " The 'errorformat' setting is different on non-Unix systems.
        " This test works only on Unix-like systems.
@@ -752,10 +837,10 @@ function! Test_efm1()
     call delete('Xerrorfile1')
     call delete('Xerrorfile2')
     call delete('Xtestfile')
-endfunction
+endfunc
 
 " Test for quickfix directory stack support
-function! s:dir_stack_tests(cchar)
+func s:dir_stack_tests(cchar)
   call s:setup_commands(a:cchar)
 
   let save_efm=&efm
@@ -797,10 +882,10 @@ function! s:dir_stack_tests(cchar)
   call assert_equal(5, qf[11].lnum)
 
   let &efm=save_efm
-endfunction
+endfunc
 
 " Tests for %D and %X errorformat options
-function! Test_efm_dirstack()
+func Test_efm_dirstack()
   " Create the directory stack and files
   call mkdir('dir1')
   call mkdir('dir1/a')
@@ -832,10 +917,10 @@ function! Test_efm_dirstack()
   call delete('dir1', 'rf')
   call delete('dir2', 'rf')
   call delete('habits1.txt')
-endfunction
+endfunc
 
 " Test for resync after continuing an ignored message
-function! Xefm_ignore_continuations(cchar)
+func Xefm_ignore_continuations(cchar)
   call s:setup_commands(a:cchar)
 
   let save_efm = &efm
@@ -850,15 +935,15 @@ function! Xefm_ignore_continuations(cchar)
   call assert_equal([['resync', 1, 4, 'E']], l)
 
   let &efm = save_efm
-endfunction
+endfunc
 
-function! Test_efm_ignore_continuations()
+func Test_efm_ignore_continuations()
   call Xefm_ignore_continuations('c')
   call Xefm_ignore_continuations('l')
-endfunction
+endfunc
 
 " Tests for invalid error format specifies
-function Xinvalid_efm_Tests(cchar)
+func Xinvalid_efm_Tests(cchar)
   call s:setup_commands(a:cchar)
 
   let save_efm = &efm
@@ -891,17 +976,17 @@ function Xinvalid_efm_Tests(cchar)
   call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
 
   let &efm = save_efm
-endfunction
+endfunc
 
-function Test_invalid_efm()
+func Test_invalid_efm()
   call Xinvalid_efm_Tests('c')
   call Xinvalid_efm_Tests('l')
-endfunction
+endfunc
 
 " TODO:
 " Add tests for the following formats in 'errorformat'
 "      %r  %O
-function! Test_efm2()
+func Test_efm2()
   let save_efm = &efm
 
   " Test for %s format in efm
@@ -911,30 +996,44 @@ function! Test_efm2()
   call assert_equal(l[0].pattern, '^\VLine search text\$')
   call assert_equal(l[0].lnum, 0)
 
+  let l = split(execute('clist', ''), "\n")
+  call assert_equal([' 1 Xtestfile:^\VLine search text\$:  '], l)
+
   " Test for %P, %Q and %t format specifiers
   let lines=["[Xtestfile1]",
              \ "(1,17)  error: ';' missing",
              \ "(21,2)  warning: variable 'z' not defined",
              \ "(67,3)  error: end of file found before string ended",
+             \ "--",
              \ "",
              \ "[Xtestfile2]",
+             \ "--",
              \ "",
              \ "[Xtestfile3]",
              \ "NEW compiler v1.1",
              \ "(2,2)   warning: variable 'x' not defined",
-             \ "(67,3)  warning: 's' already defined"
+             \ "(67,3)  warning: 's' already defined",
+             \ "--"
              \]
-  set efm=%+P[%f],(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%-Q
+  set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
+  " To exercise the push/pop file functionality in quickfix, the test files
+  " need to be created.
+  call writefile(['Line1'], 'Xtestfile1')
+  call writefile(['Line2'], 'Xtestfile2')
+  call writefile(['Line3'], 'Xtestfile3')
   cexpr ""
   for l in lines
       caddexpr l
   endfor
   let l = getqflist()
-  call assert_equal(9, len(l))
+  call assert_equal(12, len(l))
   call assert_equal(21, l[2].lnum)
   call assert_equal(2, l[2].col)
   call assert_equal('w', l[2].type)
   call assert_equal('e', l[3].type)
+  call delete('Xtestfile1')
+  call delete('Xtestfile2')
+  call delete('Xtestfile3')
 
   " Tests for %E, %C and %Z format specifiers
   let lines = ["Error 275",
@@ -986,20 +1085,39 @@ function! Test_efm2()
   call assert_equal(1, l[4].valid)
   call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
 
+  " The following sequence of commands used to crash Vim
+  set efm=%W%m
+  cgetexpr ['msg1']
+  let l = getqflist()
+  call assert_equal(1, len(l), string(l))
+  call assert_equal('msg1', l[0].text)
+  set efm=%C%m
+  lexpr 'msg2'
+  let l = getloclist(0)
+  call assert_equal(1, len(l), string(l))
+  call assert_equal('msg2', l[0].text)
+  lopen
+  call setqflist([], 'r')
+  caddbuf
+  let l = getqflist()
+  call assert_equal(1, len(l), string(l))
+  call assert_equal('|| msg2', l[0].text)
+
+  new | only
   let &efm = save_efm
-endfunction
+endfunc
 
-function XquickfixChangedByAutocmd(cchar)
+func XquickfixChangedByAutocmd(cchar)
   call s:setup_commands(a:cchar)
   if a:cchar == 'c'
     let ErrorNr = 'E925'
-    function! ReadFunc()
+    func! ReadFunc()
       colder
       cgetexpr []
     endfunc
   else
     let ErrorNr = 'E926'
-    function! ReadFunc()
+    func! ReadFunc()
       lolder
       lgetexpr []
     endfunc
@@ -1022,10 +1140,10 @@ function XquickfixChangedByAutocmd(cchar)
   augroup! testgroup
 endfunc
 
-function Test_quickfix_was_changed_by_autocmd()
+func Test_quickfix_was_changed_by_autocmd()
   call XquickfixChangedByAutocmd('c')
   call XquickfixChangedByAutocmd('l')
-endfunction
+endfunc
 
 func Test_caddbuffer_to_empty()
   helpgr quickfix
@@ -1047,7 +1165,7 @@ func Test_cgetexpr_works()
 endfunc
 
 " Tests for the setqflist() and setloclist() functions
-function SetXlistTests(cchar, bnum)
+func SetXlistTests(cchar, bnum)
   call s:setup_commands(a:cchar)
 
   call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
@@ -1082,9 +1200,35 @@ function SetXlistTests(cchar, bnum)
   call g:Xsetlist([])
   let l = g:Xgetlist()
   call assert_equal(0, len(l))
-endfunction
 
-function Test_setqflist()
+  " Tests for setting the 'valid' flag
+  call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
+  Xwindow
+  call assert_equal(1, winnr('$'))
+  let l = g:Xgetlist()
+  call g:Xsetlist(l)
+  call assert_equal(0, g:Xgetlist()[0].valid)
+  call g:Xsetlist([{'text':'Text1', 'valid':1}])
+  Xwindow
+  call assert_equal(2, winnr('$'))
+  Xclose
+  let save_efm = &efm
+  set efm=%m
+  Xgetexpr 'TestMessage'
+  let l = g:Xgetlist()
+  call g:Xsetlist(l)
+  call assert_equal(1, g:Xgetlist()[0].valid)
+  let &efm = save_efm
+
+  " Error cases:
+  " Refer to a non-existing buffer and pass a non-dictionary type
+  call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
+             \ " {'bufnr':999, 'lnum':5}])", 'E92:')
+  call g:Xsetlist([[1, 2,3]])
+  call assert_equal(0, len(g:Xgetlist()))
+endfunc
+
+func Test_setqflist()
   new Xtestfile | only
   let bnum = bufnr('%')
   call setline(1, range(1,5))
@@ -1094,13 +1238,14 @@ function Test_setqflist()
 
   enew!
   call delete('Xtestfile')
-endfunction
+endfunc
 
-function Xlist_empty_middle(cchar)
+func Xlist_empty_middle(cchar)
   call s:setup_commands(a:cchar)
 
   " create three quickfix lists
-  Xvimgrep Test_ test_quickfix.vim
+  let @/ = 'Test_'
+  Xvimgrep // test_quickfix.vim
   let testlen = len(g:Xgetlist())
   call assert_true(testlen > 0)
   Xvimgrep empty test_quickfix.vim
@@ -1119,12 +1264,12 @@ function Xlist_empty_middle(cchar)
   call assert_equal(matchlen, len(g:Xgetlist()))
 endfunc
 
-function Test_setqflist_empty_middle()
+func Test_setqflist_empty_middle()
   call Xlist_empty_middle('c')
   call Xlist_empty_middle('l')
-endfunction
+endfunc
 
-function Xlist_empty_older(cchar)
+func Xlist_empty_older(cchar)
   call s:setup_commands(a:cchar)
 
   " create three quickfix lists
@@ -1145,14 +1290,14 @@ function Xlist_empty_older(cchar)
   call assert_equal(twolen, len(g:Xgetlist()))
   Xnewer
   call assert_equal(threelen, len(g:Xgetlist()))
-endfunction
+endfunc
 
-function Test_setqflist_empty_older()
+func Test_setqflist_empty_older()
   call Xlist_empty_older('c')
   call Xlist_empty_older('l')
-endfunction
+endfunc
 
-function! XquickfixSetListWithAct(cchar)
+func XquickfixSetListWithAct(cchar)
   call s:setup_commands(a:cchar)
 
   let list1 = [{'filename': 'fnameA', 'text': 'A'},
@@ -1226,12 +1371,12 @@ function! XquickfixSetListWithAct(cchar)
   call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
 endfunc
 
-function Test_quickfix_set_list_with_act()
+func Test_quickfix_set_list_with_act()
   call XquickfixSetListWithAct('c')
   call XquickfixSetListWithAct('l')
-endfunction
+endfunc
 
-function XLongLinesTests(cchar)
+func XLongLinesTests(cchar)
   let l = g:Xgetlist()
 
   call assert_equal(4, len(l))
@@ -1249,9 +1394,9 @@ function XLongLinesTests(cchar)
   call assert_equal(10, len(l[3].text))
 
   call g:Xsetlist([], 'r')
-endfunction
+endfunc
 
-function s:long_lines_tests(cchar)
+func s:long_lines_tests(cchar)
   call s:setup_commands(a:cchar)
 
   let testfile = 'samples/quickfix.txt'
@@ -1272,22 +1417,22 @@ function s:long_lines_tests(cchar)
   exe 'edit' testfile
   exe 'Xbuffer' bufnr('%')
   call XLongLinesTests(a:cchar)
-endfunction
+endfunc
 
-function Test_long_lines()
+func Test_long_lines()
   call s:long_lines_tests('c')
   call s:long_lines_tests('l')
-endfunction
+endfunc
 
-function! s:create_test_file(filename)
+func s:create_test_file(filename)
   let l = []
   for i in range(1, 20)
       call add(l, 'Line' . i)
   endfor
   call writefile(l, a:filename)
-endfunction
+endfunc
 
-function! Test_switchbuf()
+func Test_switchbuf()
   call s:create_test_file('Xqftestfile1')
   call s:create_test_file('Xqftestfile2')
   call s:create_test_file('Xqftestfile3')
@@ -1308,18 +1453,18 @@ function! Test_switchbuf()
   let winid = win_getid()
   cfirst | cnext
   call assert_equal(winid, win_getid())
-  cnext | cnext
+  2cnext
   call assert_equal(winid, win_getid())
-  cnext | cnext
+  2cnext
   call assert_equal(winid, win_getid())
   enew
 
   set switchbuf=useopen
   cfirst | cnext
   call assert_equal(file1_winid, win_getid())
-  cnext | cnext
+  2cnext
   call assert_equal(file2_winid, win_getid())
-  cnext | cnext
+  2cnext
   call assert_equal(file2_winid, win_getid())
 
   enew | only
@@ -1329,9 +1474,9 @@ function! Test_switchbuf()
   tabfirst
   cfirst | cnext
   call assert_equal(2, tabpagenr())
-  cnext | cnext
+  2cnext
   call assert_equal(3, tabpagenr())
-  cnext | cnext
+  2cnext
   call assert_equal(3, tabpagenr())
   tabfirst | tabonly | enew
 
@@ -1369,14 +1514,28 @@ function! Test_switchbuf()
   call assert_equal(2, winnr('$'))
   call assert_equal(1, bufwinnr('Xqftestfile3'))
 
+  " If only quickfix window is open in the current tabpage, jumping to an
+  " entry with 'switchubf' set to 'usetab' should search in other tabpages.
   enew | only
+  set switchbuf=usetab
+  tabedit Xqftestfile1
+  tabedit Xqftestfile2
+  tabedit Xqftestfile3
+  tabfirst
+  copen | only
+  clast
+  call assert_equal(4, tabpagenr())
+  tabfirst | tabonly | enew | only
 
   call delete('Xqftestfile1')
   call delete('Xqftestfile2')
   call delete('Xqftestfile3')
-endfunction
+  set switchbuf&vim
 
-function! Xadjust_qflnum(cchar)
+  enew | only
+endfunc
+
+func Xadjust_qflnum(cchar)
   call s:setup_commands(a:cchar)
 
   enew | only
@@ -1401,17 +1560,17 @@ function! Xadjust_qflnum(cchar)
 
   enew!
   call delete(fname)
-endfunction
+endfunc
 
-function! Test_adjust_lnum()
+func Test_adjust_lnum()
   call setloclist(0, [])
   call Xadjust_qflnum('c')
   call setqflist([])
   call Xadjust_qflnum('l')
-endfunction
+endfunc
 
 " Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
-function! s:test_xgrep(cchar)
+func s:test_xgrep(cchar)
   call s:setup_commands(a:cchar)
 
   " The following lines are used for the grep test. Don't remove.
@@ -1430,9 +1589,9 @@ function! s:test_xgrep(cchar)
   set makeef=Temp_File_##
   silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
   call assert_true(len(g:Xgetlist()) == 6)
-endfunction
+endfunc
 
-function! Test_grep()
+func Test_grep()
   if !has('unix')
     " The grepprg may not be set on non-Unix systems
     return
@@ -1440,9 +1599,9 @@ function! Test_grep()
 
   call s:test_xgrep('c')
   call s:test_xgrep('l')
-endfunction
+endfunc
 
-function! Test_two_windows()
+func Test_two_windows()
   " Use one 'errorformat' for two windows.  Add an expression to each of them,
   " make sure they each keep their own state.
   set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
@@ -1483,9 +1642,14 @@ function! Test_two_windows()
   call delete('Xtwo', 'rf')
 endfunc
 
-function XbottomTests(cchar)
+func XbottomTests(cchar)
   call s:setup_commands(a:cchar)
 
+  " Calling lbottom without any errors should fail
+  if a:cchar == 'l'
+      call assert_fails('lbottom', 'E776:')
+  endif
+
   call g:Xsetlist([{'filename': 'foo', 'lnum': 42}]) 
   Xopen
   let wid = win_getid()
@@ -1499,18 +1663,17 @@ function XbottomTests(cchar)
 endfunc
 
 " Tests for the :cbottom and :lbottom commands
-function Test_cbottom()
+func Test_cbottom()
   call XbottomTests('c')
   call XbottomTests('l')
-endfunction
+endfunc
 
-function HistoryTest(cchar)
+func HistoryTest(cchar)
   call s:setup_commands(a:cchar)
 
-  call assert_fails(a:cchar . 'older 99', 'E380:')
   " clear all lists after the first one, then replace the first one.
   call g:Xsetlist([])
-  Xolder
+  call assert_fails('Xolder 99', 'E380:')
   let entry = {'filename': 'foo', 'lnum': 42}
   call g:Xsetlist([entry], 'r')
   call g:Xsetlist([entry, entry])
@@ -1544,7 +1707,7 @@ func Test_duplicate_buf()
 endfunc
 
 " Quickfix/Location list set/get properties tests
-function Xproperty_tests(cchar)
+func Xproperty_tests(cchar)
     call s:setup_commands(a:cchar)
 
     " Error cases
@@ -1553,6 +1716,7 @@ function Xproperty_tests(cchar)
     call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
 
     " Set and get the title
+    call g:Xsetlist([])
     Xopen
     wincmd p
     call g:Xsetlist([{'filename':'foo', 'lnum':27}])
@@ -1579,6 +1743,22 @@ function Xproperty_tests(cchar)
     call g:Xsetlist([], ' ', {'title' : 'N3'})
     call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
 
+    " Changing the title of an earlier quickfix list
+    call g:Xsetlist([], ' ', {'title' : 'NewTitle', 'nr' : 2})
+    call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
+
+    " Changing the title of an invalid quickfix list
+    call assert_equal(-1, g:Xsetlist([], ' ',
+               \ {'title' : 'SomeTitle', 'nr' : 99}))
+    call assert_equal(-1, g:Xsetlist([], ' ',
+               \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
+
+    if a:cchar == 'c'
+       copen
+       call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
+       cclose
+    endif
+
     " Invalid arguments
     call assert_fails('call g:Xgetlist([])', 'E715')
     call assert_fails('call g:Xsetlist([], "a", [])', 'E715')
@@ -1586,23 +1766,25 @@ function Xproperty_tests(cchar)
     call assert_equal(-1, s)
 
     call assert_equal({}, g:Xgetlist({'abc':1}))
+    call assert_equal({}, g:Xgetlist({'nr':99, 'title':1}))
+    call assert_equal({}, g:Xgetlist({'nr':[], 'title':1}))
 
     if a:cchar == 'l'
        call assert_equal({}, getloclist(99, {'title': 1}))
     endif
-endfunction
+endfunc
 
-function Test_qf_property()
+func Test_qf_property()
     call Xproperty_tests('c')
     call Xproperty_tests('l')
-endfunction
+endfunc
 
 " Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
-function QfAutoCmdHandler(loc, cmd)
+func QfAutoCmdHandler(loc, cmd)
   call add(g:acmds, a:loc . a:cmd)
-endfunction
+endfunc
 
-function Test_Autocmd()
+func Test_Autocmd()
   autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
   autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
 
@@ -1630,9 +1812,9 @@ function Test_Autocmd()
              \ 'precaddbuffer',
              \ 'postcaddbuffer']
   call assert_equal(l, g:acmds)
-endfunction
+endfunc
 
-function! Test_Autocmd_Exception()
+func Test_Autocmd_Exception()
   set efm=%m
   lgetexpr '?'
 
@@ -1647,4 +1829,215 @@ function! Test_Autocmd_Exception()
   call assert_equal('1', getloclist(0)[0].text)
 
   set efm&vim
-endfunction
+endfunc
+
+func Test_caddbuffer_wrong()
+  " This used to cause a memory access in freed memory.
+  let save_efm = &efm
+  set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
+  cgetexpr ['WWWW', 'EEEE', 'CCCC']
+  let &efm = save_efm
+  caddbuffer
+  bwipe!
+endfunc
+
+func Test_caddexpr_wrong()
+  " This used to cause a memory access in freed memory.
+  cbuffer
+  cbuffer
+  copen
+  let save_efm = &efm
+  set efm=%
+  call assert_fails('caddexpr ""', 'E376:')
+  let &efm = save_efm
+endfunc
+
+func Test_dirstack_cleanup()
+  " This used to cause a memory access in freed memory.
+  let save_efm = &efm
+  lexpr '0'
+  lopen
+  fun X(c)
+    let save_efm=&efm
+    set efm=%D%f
+    if a:c == 'c'
+      caddexpr '::'
+    else
+      laddexpr ':0:0'
+    endif
+    let &efm=save_efm
+  endfun
+  call X('c')
+  call X('l')
+  call setqflist([], 'r')
+  caddbuffer
+  let &efm = save_efm
+endfunc
+
+" Tests for jumping to entries from the location list window and quickfix
+" window
+func Test_cwindow_jump()
+  set efm=%f%%%l%%%m
+  lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
+  lopen | only
+  lfirst
+  call assert_true(winnr('$') == 2)
+  call assert_true(winnr() == 1)
+  " Location list for the new window should be set
+  call assert_true(getloclist(0)[2].text == 'Line 30')
+
+  " Open a scratch buffer
+  " Open a new window and create a location list
+  " Open the location list window and close the other window
+  " Jump to an entry.
+  " Should create a new window and jump to the entry. The scrtach buffer
+  " should not be used.
+  enew | only
+  set buftype=nofile
+  below new
+  lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
+  lopen
+  2wincmd c
+  lnext
+  call assert_true(winnr('$') == 3)
+  call assert_true(winnr() == 2)
+
+  " Open two windows with two different location lists
+  " Open the location list window and close the previous window
+  " Jump to an entry in the location list window
+  " Should open the file in the first window and not set the location list.
+  enew | only
+  lgetexpr ["F1%5%Line 5"]
+  below new
+  lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
+  lopen
+  2wincmd c
+  lnext
+  call assert_true(winnr() == 1)
+  call assert_true(getloclist(0)[0].text == 'Line 5')
+
+  enew | only
+  cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
+  copen
+  cnext
+  call assert_true(winnr('$') == 2)
+  call assert_true(winnr() == 1)
+
+  enew | only
+  set efm&vim
+endfunc
+
+func XvimgrepTests(cchar)
+  call s:setup_commands(a:cchar)
+
+  call writefile(['Editor:VIM vim',
+             \ 'Editor:Emacs EmAcS',
+             \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1')
+  call writefile(['Linux', 'MacOS', 'MS-Windows'], 'Xtestfile2')
+
+  " Error cases
+  call assert_fails('Xvimgrep /abc *', 'E682:')
+
+  let @/=''
+  call assert_fails('Xvimgrep // *', 'E35:')
+
+  call assert_fails('Xvimgrep abc', 'E683:')
+  call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
+  call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
+
+  Xexpr ""
+  Xvimgrepadd Notepad Xtestfile1
+  Xvimgrepadd MacOS Xtestfile2
+  let l = g:Xgetlist()
+  call assert_equal(2, len(l))
+  call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
+
+  Xvimgrep #\cvim#g Xtestfile?
+  let l = g:Xgetlist()
+  call assert_equal(2, len(l))
+  call assert_equal(8, l[0].col)
+  call assert_equal(12, l[1].col)
+
+  1Xvimgrep ?Editor? Xtestfile*
+  let l = g:Xgetlist()
+  call assert_equal(1, len(l))
+  call assert_equal('Editor:VIM vim', l[0].text)
+
+  edit +3 Xtestfile2
+  Xvimgrep +\cemacs+j Xtestfile1
+  let l = g:Xgetlist()
+  call assert_equal('Xtestfile2', bufname(''))
+  call assert_equal('Editor:Emacs EmAcS', l[0].text)
+
+  call delete('Xtestfile1')
+  call delete('Xtestfile2')
+endfunc
+
+" Tests for the :vimgrep command
+func Test_vimgrep()
+  call XvimgrepTests('c')
+  call XvimgrepTests('l')
+endfunc
+
+func XfreeTests(cchar)
+  call s:setup_commands(a:cchar)
+
+  enew | only
+
+  " Deleting the quickfix stack should work even When the current list is
+  " somewhere in the middle of the stack
+  Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
+  Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
+  Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
+  Xolder
+  call g:Xsetlist([], 'f')
+  call assert_equal(0, len(g:Xgetlist()))
+
+  " After deleting the stack, adding a new list should create a stack with a
+  " single list.
+  Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
+  call assert_equal(1, g:Xgetlist({'all':1}).nr)
+
+  " Deleting the stack from a quickfix window should update/clear the
+  " quickfix/location list window.
+  Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
+  Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
+  Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
+  Xolder
+  Xwindow
+  call g:Xsetlist([], 'f')
+  call assert_equal(2, winnr('$'))
+  call assert_equal(1, line('$'))
+  Xclose
+
+  " Deleting the stack from a non-quickfix window should update/clear the
+  " quickfix/location list window.
+  Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
+  Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
+  Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
+  Xolder
+  Xwindow
+  wincmd p
+  call g:Xsetlist([], 'f')
+  call assert_equal(0, len(g:Xgetlist()))
+  wincmd p
+  call assert_equal(2, winnr('$'))
+  call assert_equal(1, line('$'))
+
+  " After deleting the location list stack, if the location list window is
+  " opened, then a new location list should be created. So opening the
+  " location list window again should not create a new window.
+  if a:cchar == 'l'
+      lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
+      wincmd p
+      lopen
+      call assert_equal(2, winnr('$'))
+  endif
+  Xclose
+endfunc
+
+" Tests for the quickifx free functionality
+func Test_qf_free()
+  call XfreeTests('c')
+  call XfreeTests('l')
+endfunc
diff --git a/src/testdir/test_quotestar.vim b/src/testdir/test_quotestar.vim
new file mode 100644 (file)
index 0000000..37e3a10
--- /dev/null
@@ -0,0 +1,136 @@
+" *-register (quotestar) tests
+
+if !has('clipboard')
+  finish
+endif
+
+source shared.vim
+
+func Do_test_quotestar_for_macunix()
+  if empty(exepath('pbcopy')) || empty(exepath('pbpaste'))
+    return 'Test requires pbcopy(1) and pbpaste(1)'
+  endif
+
+  let @* = ''
+
+  " Test #1: Pasteboard to Vim
+  let test_msg = "text from pasteboard to vim via quotestar"
+  " Write a piece of text to the pasteboard.
+  call system('/bin/echo -n "' . test_msg . '" | pbcopy')
+  " See if the *-register is changed as expected.
+  call assert_equal(test_msg, @*)
+
+  " Test #2: Vim to Pasteboard
+  let test_msg = "text from vim to pasteboard via quotestar"
+  " Write a piece of text to the *-register.
+  let @* = test_msg
+  " See if the pasteboard is changed as expected.
+  call assert_equal(test_msg, system('pbpaste'))
+
+  return ''
+endfunc
+
+func Do_test_quotestar_for_x11()
+  if !has('clientserver') || !has('job')
+    return 'Test requires the client-server and job features'
+  endif
+
+  let cmd = GetVimCommand()
+  if cmd == ''
+    return 'GetVimCommand() failed'
+  endif
+  try
+    call remote_send('xxx', '')
+  catch
+    if v:exception =~ 'E240:'
+      " No connection to the X server, give up.
+      return
+    endif
+    " ignore other errors
+  endtry
+
+  let name = 'XVIMCLIPBOARD'
+  let cmd .= ' --servername ' . name
+  let g:job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'})
+  call WaitFor('job_status(g:job) == "run"')
+  if job_status(g:job) != 'run'
+    call assert_report('Cannot run the Vim server')
+    return ''
+  endif
+
+  " Takes a short while for the server to be active.
+  call WaitFor('serverlist() =~ "' . name . '"')
+  call assert_match(name, serverlist())
+
+  " Wait for the server to be up and answering requests.  One second is not
+  " always sufficient.
+  call WaitFor('remote_expr("' . name . '", "v:version", "", 2) != ""')
+
+  " Clear the *-register of this vim instance.
+  let @* = ''
+
+  " Try to change the *-register of the server.
+  call remote_foreground(name)
+  call remote_send(name, ":let @* = 'yes'\<CR>")
+  call WaitFor('remote_expr("' . name . '", "@*", "", 1) == "yes"')
+  call assert_equal('yes', remote_expr(name, "@*", "", 2))
+
+  " Check that the *-register of this vim instance is changed as expected.
+  call assert_equal('yes', @*)
+
+  if has('unix') && has('gui') && !has('gui_running')
+    let @* = ''
+
+    " Running in a terminal and the GUI is avaiable: Tell the server to open
+    " the GUI and check that the remote command still works.
+    " Need to wait for the GUI to start up, otherwise the send hangs in trying
+    " to send to the terminal window.
+    if has('gui_athena') || has('gui_motif')
+      " For those GUIs, ignore the 'failed to create input context' error.
+      call remote_send(name, ":call test_ignore_error('E285') | gui -f\<CR>")
+    else
+      call remote_send(name, ":gui -f\<CR>")
+    endif
+    " Wait for the server in the GUI to be up and answering requests.
+    call WaitFor('remote_expr("' . name . '", "has(\"gui_running\")", "", 1) =~ "1"')
+
+    call remote_send(name, ":let @* = 'maybe'\<CR>")
+    call WaitFor('remote_expr("' . name . '", "@*", "", 1) == "maybe"')
+    call assert_equal('maybe', remote_expr(name, "@*", "", 2))
+
+    call assert_equal('maybe', @*)
+  endif
+
+  call remote_send(name, ":qa!\<CR>")
+  call WaitFor('job_status(g:job) == "dead"')
+  if job_status(g:job) != 'dead'
+    call assert_report('Server did not exit')
+    call job_stop(g:job, 'kill')
+  endif
+
+  return ''
+endfunc
+
+func Test_quotestar()
+  let skipped = ''
+
+  let quotestar_saved = @*
+
+  if has('macunix')
+    let skipped = Do_test_quotestar_for_macunix()
+  elseif has('x11')
+    if empty($DISPLAY)
+      let skipped = "Test can only run when $DISPLAY is set."
+    else
+      let skipped = Do_test_quotestar_for_x11()
+    endif
+  else
+    let skipped = "Test is not implemented yet for this platform."
+  endif
+
+  let @* = quotestar_saved
+
+  if !empty(skipped)
+    throw 'Skipped: ' . skipped
+  endif
+endfunc
diff --git a/src/testdir/test_recover.vim b/src/testdir/test_recover.vim
new file mode 100644 (file)
index 0000000..33cd54b
--- /dev/null
@@ -0,0 +1,18 @@
+" Test :recover
+
+func Test_recover_root_dir()
+  " This used to access invalid memory.
+  split Xtest
+  set dir=/
+  call assert_fails('recover', 'E305:')
+  close!
+
+  if has('win32')
+    " can write in / directory on MS-Windows
+    set dir=/notexist/
+  endif
+  call assert_fails('split Xtest', 'E303:')
+  set dir&
+endfunc
+
+" TODO: move recover tests from test78.in to here.
index d225983..c54b650 100644 (file)
@@ -38,12 +38,21 @@ func s:classes_test()
   set isprint=@,161-255
   call assert_equal('Motörhead', matchstr('Motörhead', '[[:print:]]\+'))
 
+  let alnumchars = ''
   let alphachars = ''
+  let backspacechar = ''
+  let blankchars = ''
+  let cntrlchars = ''
+  let digitchars = ''
+  let escapechar = ''
+  let graphchars = ''
   let lowerchars = ''
-  let upperchars = ''
-  let alnumchars = ''
   let printchars = ''
   let punctchars = ''
+  let returnchar = ''
+  let spacechars = ''
+  let tabchar = ''
+  let upperchars = ''
   let xdigitchars = ''
   let i = 1
   while i <= 255
@@ -51,21 +60,48 @@ func s:classes_test()
     if c =~ '[[:alpha:]]'
       let alphachars .= c
     endif
-    if c =~ '[[:lower:]]'
-      let lowerchars .= c
-    endif
-    if c =~ '[[:upper:]]'
-      let upperchars .= c
-    endif
     if c =~ '[[:alnum:]]'
       let alnumchars .= c
     endif
+    if c =~ '[[:backspace:]]'
+      let backspacechar .= c
+    endif
+    if c =~ '[[:blank:]]'
+      let blankchars .= c
+    endif
+    if c =~ '[[:cntrl:]]'
+      let cntrlchars .= c
+    endif
+    if c =~ '[[:digit:]]'
+      let digitchars .= c
+    endif
+    if c =~ '[[:escape:]]'
+      let escapechar .= c
+    endif
+    if c =~ '[[:graph:]]'
+      let graphchars .= c
+    endif
+    if c =~ '[[:lower:]]'
+      let lowerchars .= c
+    endif
     if c =~ '[[:print:]]'
       let printchars .= c
     endif
     if c =~ '[[:punct:]]'
       let punctchars .= c
     endif
+    if c =~ '[[:return:]]'
+      let returnchar .= c
+    endif
+    if c =~ '[[:space:]]'
+      let spacechars .= c
+    endif
+    if c =~ '[[:tab:]]'
+      let tabchar .= c
+    endif
+    if c =~ '[[:upper:]]'
+      let upperchars .= c
+    endif
     if c =~ '[[:xdigit:]]'
       let xdigitchars .= c
     endif
@@ -73,11 +109,20 @@ func s:classes_test()
   endwhile
 
   call assert_equal('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', alphachars)
-  call assert_equal('abcdefghijklmnopqrstuvwxyzµßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ', lowerchars)
-  call assert_equal('ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ', upperchars)
   call assert_equal('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', alnumchars)
+  call assert_equal("\b", backspacechar)
+  call assert_equal("\t ", blankchars)
+  call assert_equal("\x01\x02\x03\x04\x05\x06\x07\b\t\n\x0b\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\e\x1c\x1d\x1e\x1f\x7f", cntrlchars)
+  call assert_equal("0123456789", digitchars)
+  call assert_equal("\<Esc>", escapechar)
+  call assert_equal('!"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~', graphchars)
+  call assert_equal('abcdefghijklmnopqrstuvwxyzµßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ', lowerchars)
   call assert_equal(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ', printchars)
   call assert_equal('!"#$%&''()*+,-./:;<=>?@[\]^_`{|}~', punctchars)
+  call assert_equal('ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ', upperchars)
+  call assert_equal("\r", returnchar)
+  call assert_equal("\t\n\x0b\f\r ", spacechars)
+  call assert_equal("\t", tabchar)
   call assert_equal('0123456789ABCDEFabcdef', xdigitchars)
 endfunc
 
diff --git a/src/testdir/test_retab.vim b/src/testdir/test_retab.vim
new file mode 100644 (file)
index 0000000..f11a32b
--- /dev/null
@@ -0,0 +1,77 @@
+" Test :retab
+func SetUp()
+  new
+  call setline(1, "\ta  \t    b        c    ")
+endfunc
+
+func TearDown()
+  bwipe!
+endfunc
+
+func Retab(bang, n)
+  let l:old_tabstop = &tabstop
+  let l:old_line = getline(1)
+  exe "retab" . a:bang . a:n
+  let l:line = getline(1)
+  call setline(1, l:old_line)
+  if a:n > 0
+    " :retab changes 'tabstop' to n with argument n > 0.
+    call assert_equal(a:n, &tabstop)
+    exe 'set tabstop=' . l:old_tabstop
+  else
+    " :retab does not change 'tabstop' with empty or n <= 0.
+    call assert_equal(l:old_tabstop, &tabstop)
+  endif
+  return l:line
+endfunc
+
+func Test_retab()
+  set tabstop=8 noexpandtab
+  call assert_equal("\ta\t    b        c    ",            Retab('',  ''))
+  call assert_equal("\ta\t    b        c    ",            Retab('',  0))
+  call assert_equal("\ta\t    b        c    ",            Retab('',  8))
+  call assert_equal("\ta\t    b\t     c\t  ",             Retab('!', ''))
+  call assert_equal("\ta\t    b\t     c\t  ",             Retab('!', 0))
+  call assert_equal("\ta\t    b\t     c\t  ",             Retab('!', 8))
+
+  call assert_equal("\t\ta\t\t\tb        c    ",          Retab('',  4))
+  call assert_equal("\t\ta\t\t\tb\t\t c\t  ",             Retab('!', 4))
+
+  call assert_equal("        a\t\tb        c    ",        Retab('',  10))
+  call assert_equal("        a\t\tb        c    ",        Retab('!', 10))
+
+  set tabstop=8 expandtab
+  call assert_equal("        a           b        c    ", Retab('',  ''))
+  call assert_equal("        a           b        c    ", Retab('',  0))
+  call assert_equal("        a           b        c    ", Retab('',  8))
+  call assert_equal("        a           b        c    ", Retab('!', ''))
+  call assert_equal("        a           b        c    ", Retab('!', 0))
+  call assert_equal("        a           b        c    ", Retab('!', 8))
+
+  call assert_equal("        a           b        c    ", Retab(' ', 4))
+  call assert_equal("        a           b        c    ", Retab('!', 4))
+
+  call assert_equal("        a           b        c    ", Retab(' ', 10))
+  call assert_equal("        a           b        c    ", Retab('!', 10))
+
+  set tabstop=4 noexpandtab
+  call assert_equal("\ta\t\tb        c    ",              Retab('',  ''))
+  call assert_equal("\ta\t\tb\t\t c\t  ",                 Retab('!', ''))
+  call assert_equal("\t a\t\t\tb        c    ",           Retab('',  3))
+  call assert_equal("\t a\t\t\tb\t\t\tc\t  ",             Retab('!', 3))
+  call assert_equal("    a\t  b        c    ",            Retab('',  5))
+  call assert_equal("    a\t  b\t\t c\t ",                Retab('!', 5))
+
+  set tabstop=4 expandtab
+  call assert_equal("    a       b        c    ",         Retab('',  ''))
+  call assert_equal("    a       b        c    ",         Retab('!', ''))
+  call assert_equal("    a       b        c    ",         Retab('',  3))
+  call assert_equal("    a       b        c    ",         Retab('!', 3))
+  call assert_equal("    a       b        c    ",         Retab('',  5))
+  call assert_equal("    a       b        c    ",         Retab('!', 5))
+endfunc
+
+func Test_retab_error()
+  call assert_fails('retab -1',  'E487:')
+  call assert_fails('retab! -1', 'E487:')
+endfunc
index 106ccb4..174467f 100644 (file)
@@ -32,3 +32,20 @@ func Test_ruby_evaluate_dict()
   redir END
   call assert_equal(['{"a"=>"foo", "b"=>123}'], split(l:out, "\n"))
 endfunc
+
+func Test_rubydo()
+  " Check deleting lines does not trigger ml_get error.
+  new
+  call setline(1, ['one', 'two', 'three'])
+  rubydo Vim.command("%d_")
+  bwipe!
+
+  " Check switching to another buffer does not trigger ml_get error.
+  new
+  let wincount = winnr('$')
+  call setline(1, ['one', 'two', 'three'])
+  rubydo Vim.command("new")
+  call assert_equal(wincount + 1, winnr('$'))
+  bwipe!
+  bwipe!
+endfunc
index 3b9aff4..730e683 100644 (file)
@@ -1,12 +1,13 @@
 " Test for the search command
 
+set belloff=all
 func Test_search_cmdline()
   if !exists('+incsearch')
     return
   endif
   " need to disable char_avail,
   " so that expansion of commandline works
-  call test_disable_char_avail(1)
+  call test_override("char_avail", 1)
   new
   call setline(1, ['  1', '  2 these', '  3 the', '  4 their', '  5 there', '  6 their', '  7 the', '  8 them', '  9 these', ' 10 foobar'])
   " Test 1
@@ -193,7 +194,7 @@ func Test_search_cmdline()
   call assert_equal('  3 the', getline('.'))
 
   " clean up
-  call test_disable_char_avail(0)
+  call test_override("char_avail", 0)
   bw!
 endfunc
 
@@ -203,7 +204,7 @@ func Test_search_cmdline2()
   endif
   " need to disable char_avail,
   " so that expansion of commandline works
-  call test_disable_char_avail(1)
+  call test_override("char_avail", 1)
   new
   call setline(1, ['  1', '  2 these', '  3 the theother'])
   " Test 1
@@ -265,7 +266,7 @@ func Test_search_cmdline2()
 
   " clean up
   set noincsearch
-  call test_disable_char_avail(0)
+  call test_override("char_avail", 0)
   bw!
 endfunc
 
@@ -279,3 +280,25 @@ func Test_use_sub_pat()
   call X()
   bwipe!
 endfunc
+
+func Test_searchpair()
+  new
+  call setline(1, ['other code here', '', '[', '" cursor here', ']'])
+  4
+  let a=searchpair('\[','',']','bW')
+  call assert_equal(3, a)
+  set nomagic
+  4
+  let a=searchpair('\[','',']','bW')
+  call assert_equal(3, a)
+  set magic
+  q!
+endfunc
+
+func Test_searchc()
+  " These commands used to cause memory overflow in searchc().
+  new
+  norm ixx
+  exe "norm 0t\u93cf"
+  bw!
+endfunc
diff --git a/src/testdir/test_spell.vim b/src/testdir/test_spell.vim
new file mode 100644 (file)
index 0000000..0688d61
--- /dev/null
@@ -0,0 +1,29 @@
+" Test spell checking
+" TODO: move test58 tests here
+
+if !has('spell')
+  finish
+endif
+
+func Test_wrap_search()
+  new
+  call setline(1, ['The', '', 'A plong line with two zpelling mistakes', '', 'End'])
+  set spell wrapscan
+  normal ]s
+  call assert_equal('plong', expand('<cword>'))
+  normal ]s
+  call assert_equal('zpelling', expand('<cword>'))
+  normal ]s
+  call assert_equal('plong', expand('<cword>'))
+  bwipe!
+  set nospell
+endfunc
+
+func Test_z_equal_on_invalid_utf8_word()
+  split
+  set spell
+  call setline(1, "\xff")
+  norm z=
+  set nospell
+  bwipe!
+endfunc
index 8e3238c..bce431f 100644 (file)
@@ -183,3 +183,41 @@ func Test_read_stdin()
   endif
   call delete('Xtestout')
 endfunc
+
+func Test_progpath()
+  " Tests normally run with "./vim" or "../vim", these must have been expanded
+  " to a full path.
+  if has('unix')
+    call assert_equal('/', v:progpath[0])
+  elseif has('win32')
+    call assert_equal(':', v:progpath[1])
+    call assert_match('[/\\]', v:progpath[2])
+  endif
+
+  " Only expect "vim" to appear in v:progname.
+  call assert_match('vim\c', v:progname)
+endfunc
+
+func Test_silent_ex_mode()
+  if !has('unix') || has('gui_running')
+    " can't get output of Vim.
+    return
+  endif
+
+  " This caused an ml_get error.
+  let out = system(GetVimCommand() . '-u NONE -es -c''set verbose=1|h|exe "%norm\<c-y>\<c-d>"'' -c cq')
+  call assert_notmatch('E315:', out)
+endfunc
+
+func Test_default_term()
+  if !has('unix') || has('gui_running')
+    " can't get output of Vim.
+    return
+  endif
+
+  let save_term = $TERM
+  let $TERM = 'unknownxxx'
+  let out = system(GetVimCommand() . ' -c''set term'' -c cq')
+  call assert_match("defaulting to 'ansi'", out)
+  let $TERM = save_term
+endfunc
index 89ca9ef..6adc5a9 100644 (file)
@@ -1,24 +1,24 @@
 " Tests for stat functions and checktime
 
 func Test_existent_file()
-  let fname='Xtest.tmp'
+  let fname = 'Xtest.tmp'
 
-  let ts=localtime()
-  sleep 1
-  let fl=['Hello World!']
+  let ts = localtime()
+  let fl = ['Hello World!']
   call writefile(fl, fname)
-  let tf=getftime(fname)
-  sleep 1
-  let te=localtime()
+  let tf = getftime(fname)
+  let te = localtime()
 
   call assert_true(ts <= tf && tf <= te)
   call assert_equal(strlen(fl[0] . "\n"), getfsize(fname))
   call assert_equal('file', getftype(fname))
   call assert_equal('rw-', getfperm(fname)[0:2])
+
+  call delete(fname)
 endfunc
 
 func Test_existent_directory()
-  let dname='.'
+  let dname = '.'
 
   call assert_equal(0, getfsize(dname))
   call assert_equal('dir', getftype(dname))
@@ -26,22 +26,29 @@ func Test_existent_directory()
 endfunc
 
 func Test_checktime()
-  let fname='Xtest.tmp'
+  let fname = 'Xtest.tmp'
 
-  let fl=['Hello World!']
+  let fl = ['Hello World!']
   call writefile(fl, fname)
   set autoread
   exec 'e' fname
-  sleep 2
-  let fl=readfile(fname)
+  " FAT has a granularity of 2 seconds, otherwise it's usually 1 second
+  if has('win32')
+    sleep 2
+  else
+    sleep 1
+  endif
+  let fl = readfile(fname)
   let fl[0] .= ' - checktime'
   call writefile(fl, fname)
   checktime
   call assert_equal(fl[0], getline(1))
+
+  call delete(fname)
 endfunc
 
 func Test_nonexistent_file()
-  let fname='Xtest.tmp'
+  let fname = 'Xtest.tmp'
 
   call delete(fname)
   call assert_equal(-1, getftime(fname))
@@ -55,7 +62,7 @@ func Test_win32_symlink_dir()
   " So we use an existing symlink for this test.
   if has('win32')
     " Check if 'C:\Users\All Users' is a symlink to a directory.
-    let res=system('dir C:\Users /a')
+    let res = system('dir C:\Users /a')
     if match(res, '\C<SYMLINKD> *All Users') >= 0
       " Get the filetype of the symlink.
       call assert_equal('dir', getftype('C:\Users\All Users'))
index 82898df..cf85bd5 100644 (file)
@@ -1,19 +1,39 @@
-function! StatuslineWithCaughtError()
+" Test 'statusline'
+"
+" Not tested yet:
+"   %a
+"   %N
+"   %T
+"   %X
+"   %*
+
+source view_util.vim
+
+func s:get_statusline()
+  return ScreenLines(&lines - 1, &columns)[0]
+endfunc
+
+func StatuslineWithCaughtError()
   let s:func_in_statusline_called = 1
   try
     call eval('unknown expression')
   catch
   endtry
   return ''
-endfunction
+endfunc
 
-function! StatuslineWithError()
+func StatuslineWithError()
   let s:func_in_statusline_called = 1
   call eval('unknown expression')
   return ''
-endfunction
+endfunc
 
-function! Test_caught_error_in_statusline()
+" Function used to display syntax group.
+func SyntaxItem()
+  return synIDattr(synID(line("."),col("."),1),"name")
+endfunc
+
+func Test_caught_error_in_statusline()
   let s:func_in_statusline_called = 0
   set laststatus=2
   let statusline = '%{StatuslineWithCaughtError()}'
@@ -22,9 +42,9 @@ function! Test_caught_error_in_statusline()
   call assert_true(s:func_in_statusline_called)
   call assert_equal(statusline, &statusline)
   set statusline=
-endfunction
+endfunc
 
-function! Test_statusline_will_be_disabled_with_error()
+func Test_statusline_will_be_disabled_with_error()
   let s:func_in_statusline_called = 0
   set laststatus=2
   let statusline = '%{StatuslineWithError()}'
@@ -36,4 +56,219 @@ function! Test_statusline_will_be_disabled_with_error()
   call assert_true(s:func_in_statusline_called)
   call assert_equal('', &statusline)
   set statusline=
-endfunction
+endfunc
+
+func Test_statusline()
+  new Xstatusline
+  only
+  set laststatus=2
+  set splitbelow
+  call setline(1, range(1, 200))
+
+  " %b: Value of character under cursor.
+  " %B: As above, in hexadecimal.
+  call cursor(180, 2)
+  set statusline=%b,%B
+  call assert_match('^56,38\s*$', s:get_statusline())
+
+  " %o: Byte number in file of byte under cursor, first byte is 1.
+  " %O: As above, in hexadecimal.
+  set statusline=%o,%O
+  set fileformat=dos
+  call assert_match('^789,315\s*$', s:get_statusline())
+  set fileformat=mac
+  call assert_match('^610,262\s*$', s:get_statusline())
+  set fileformat=unix
+  call assert_match('^610,262\s*$', s:get_statusline())
+  set fileformat&
+
+  " %f: Path to the file in the buffer, as typed or relative to current dir.
+  set statusline=%f
+  call assert_match('^Xstatusline\s*$', s:get_statusline())
+
+  " %F: Full path to the file in the buffer.
+  set statusline=%F
+  call assert_match('/testdir/Xstatusline\s*$', s:get_statusline())
+
+  " %h: Help buffer flag, text is "[help]".
+  " %H: Help buffer flag, text is ",HLP".
+  set statusline=%h,%H
+  call assert_match('^,\s*$', s:get_statusline())
+  help
+  call assert_match('^\[Help\],HLP\s*$', s:get_statusline())
+  helpclose
+
+  " %k: Value of "b:keymap_name" or 'keymap'
+  "     when :lmap mappings are being used: <keymap>"
+  set statusline=%k
+  if has('keymap')
+    set keymap=esperanto
+    call assert_match('^<Eo>\s*$', s:get_statusline())
+    set keymap&
+  else
+    call assert_match('^\s*$', s:get_statusline())
+  endif
+
+  " %l: Line number.
+  " %L: Number of line in buffer.
+  " %c: Column number.
+  set statusline=%l/%L,%c
+  call assert_match('^180/200,2\s*$', s:get_statusline())
+
+  " %m: Modified flag, text is "[+]", "[-]" if 'modifiable' is off.
+  " %M: Modified flag, text is ",+" or ",-".
+  set statusline=%m%M
+  call assert_match('^\[+\],+\s*$', s:get_statusline())
+  set nomodifiable
+  call assert_match('^\[+-\],+-\s*$', s:get_statusline())
+  write
+  call assert_match('^\[-\],-\s*$', s:get_statusline())
+  set modifiable&
+  call assert_match('^\s*$', s:get_statusline())
+
+  " %n: Buffer number.
+  set statusline=%n
+  call assert_match('^'.bufnr('%').'\s*$', s:get_statusline())
+
+  " %p: Percentage through file in lines as in CTRL-G.
+  " %P: Percentage through file of displayed window.
+  set statusline=%p,%P
+  0
+  call assert_match('^0,Top\s*$', s:get_statusline())
+  norm G
+  call assert_match('^100,Bot\s*$', s:get_statusline())
+  180
+  " Don't check the exact percentage as it depends on the window size
+  call assert_match('^90,\(Top\|Bot\|\d\+%\)\s*$', s:get_statusline())
+
+  " %q: "[Quickfix List]", "[Location List]" or empty.
+  set statusline=%q
+  call assert_match('^\s*$', s:get_statusline())
+  copen
+  call assert_match('^\[Quickfix List\]\s*$', s:get_statusline())
+  cclose
+  lexpr getline(1, 2)
+  lopen
+  call assert_match('^\[Location List\]\s*$', s:get_statusline())
+  lclose
+
+  " %r: Readonly flag, text is "[RO]".
+  " %R: Readonly flag, text is ",RO".
+  set statusline=%r,%R
+  call assert_match('^,\s*$', s:get_statusline())
+  help
+  call assert_match('^\[RO\],RO\s*$', s:get_statusline())
+  helpclose
+
+  " %t: File name (tail) of file in the buffer.
+  set statusline=%t
+  call assert_match('^Xstatusline\s*$', s:get_statusline())
+
+  " %v: Virtual column number.
+  " %V: Virtual column number as -{num}. Not displayed if equal to 'c'.
+  call cursor(180, 2)
+  set statusline=%v,%V
+  call assert_match('^2,\s*$', s:get_statusline())
+  set virtualedit=all
+  norm 10|
+  call assert_match('^10,-10\s*$', s:get_statusline())
+  set virtualedit&
+
+  " %w: Preview window flag, text is "[Preview]".
+  " %W: Preview window flag, text is ",PRV".
+  set statusline=%w%W
+  call assert_match('^\s*$', s:get_statusline())
+  pedit
+  wincmd j
+  call assert_match('^\[Preview\],PRV\s*$', s:get_statusline())
+  pclose
+
+  " %y: Type of file in the buffer, e.g., "[vim]". See 'filetype'.
+  " %Y: Type of file in the buffer, e.g., ",VIM". See 'filetype'.
+  set statusline=%y\ %Y
+  call assert_match('^\s*$', s:get_statusline())
+  setfiletype vim
+  call assert_match('^\[vim\] VIM\s*$', s:get_statusline())
+
+  " %=: Separation point between left and right aligned items.
+  set statusline=foo%=bar
+  call assert_match('^foo\s\+bar\s*$', s:get_statusline())
+
+  " Test min/max width, leading zeroes, left/right justify.
+  set statusline=%04B
+  call cursor(180, 2)
+  call assert_match('^0038\s*$', s:get_statusline())
+  set statusline=#%4B#
+  call assert_match('^#  38#\s*$', s:get_statusline())
+  set statusline=#%-4B#
+  call assert_match('^#38  #\s*$', s:get_statusline())
+  set statusline=%.6f
+  call assert_match('^<sline\s*$', s:get_statusline())
+
+  " %<: Where to truncate.
+  exe 'set statusline=a%<b' . repeat('c', 1000) . 'd'
+  call assert_match('^a<c*d$', s:get_statusline())
+  exe 'set statusline=a' . repeat('b', 1000) . '%<c'
+  call assert_match('^ab*>$', s:get_statusline())
+
+  "%{: Evaluate expression between '%{' and '}' and substitute result.
+  syntax on
+  set statusline=%{SyntaxItem()}
+  call assert_match('^vimNumber\s*$', s:get_statusline())
+  s/^/"/
+  call assert_match('^vimLineComment\s*$', s:get_statusline())
+  syntax off
+
+  "%(: Start of item group.
+  set statusline=ab%(cd%q%)de
+  call assert_match('^abde\s*$', s:get_statusline())
+  copen
+  call assert_match('^abcd\[Quickfix List\1]de\s*$', s:get_statusline())
+  cclose
+
+  " %#: Set highlight group. The name must follow and then a # again.
+  set statusline=ab%#Todo#cd%#Error#ef
+  call assert_match('^abcdef\s*$', s:get_statusline())
+  let sa1=screenattr(&lines - 1, 1)
+  let sa2=screenattr(&lines - 1, 3)
+  let sa3=screenattr(&lines - 1, 5)
+  call assert_notequal(sa1, sa2)
+  call assert_notequal(sa1, sa3)
+  call assert_notequal(sa2, sa3)
+  call assert_equal(sa1, screenattr(&lines - 1, 2))
+  call assert_equal(sa2, screenattr(&lines - 1, 4))
+  call assert_equal(sa3, screenattr(&lines - 1, 6))
+  call assert_equal(sa3, screenattr(&lines - 1, 7))
+
+  " %*: Set highlight group to User{N}
+  set statusline=a%1*b%0*c
+  call assert_match('^abc\s*$', s:get_statusline())
+  let sa1=screenattr(&lines - 1, 1)
+  let sa2=screenattr(&lines - 1, 2)
+  let sa3=screenattr(&lines - 1, 3)
+  call assert_equal(sa1, sa3)
+  call assert_notequal(sa1, sa2)
+
+  " %%: a percent sign.
+  set statusline=10%%
+  call assert_match('^10%\s*$', s:get_statusline())
+
+  " %!: evaluated expression is used as the option value
+  set statusline=%!2*3+1
+  call assert_match('7\s*$', s:get_statusline())
+
+  " Check statusline in current and non-current window
+  " with the 'fillchars' option.
+  set fillchars=stl:^,stlnc:=,vert:\|,fold:-,diff:-
+  vsplit
+  set statusline=x%=y
+  call assert_match('^x^\+y^x=\+y$', s:get_statusline())
+  set fillchars&
+  close
+
+  %bw!
+  call delete('Xstatusline')
+  set statusline&
+  set laststatus&
+  set splitbelow&
+endfunc
index e2b6de0..f2dfdc7 100644 (file)
@@ -39,3 +39,78 @@ function! Test_multiline_subst()
   call assert_equal('xxxxx', getline(13))
   enew!
 endfunction
+
+function! Test_substitute_variants()
+  " Validate that all the 2-/3-letter variants which embed the flags into the
+  " command name actually work.
+  enew!
+  let ln = 'Testing string'
+  let variants = [
+       \ { 'cmd': ':s/Test/test/c', 'exp': 'testing string', 'prompt': 'y' },
+       \ { 'cmd': ':s/foo/bar/ce', 'exp': ln },
+       \ { 'cmd': ':s/t/r/cg', 'exp': 'Tesring srring', 'prompt': 'a' },
+       \ { 'cmd': ':s/t/r/ci', 'exp': 'resting string', 'prompt': 'y' },
+       \ { 'cmd': ':s/t/r/cI', 'exp': 'Tesring string', 'prompt': 'y' },
+       \ { 'cmd': ':s/t/r/cn', 'exp': ln },
+       \ { 'cmd': ':s/t/r/cp', 'exp': 'Tesring string', 'prompt': 'y' },
+       \ { 'cmd': ':s/t/r/cl', 'exp': 'Tesring string', 'prompt': 'y' },
+       \ { 'cmd': ':s/t/r/gc', 'exp': 'Tesring srring', 'prompt': 'a' },
+       \ { 'cmd': ':s/foo/bar/ge', 'exp': ln },
+       \ { 'cmd': ':s/t/r/g', 'exp': 'Tesring srring' },
+       \ { 'cmd': ':s/t/r/gi', 'exp': 'resring srring' },
+       \ { 'cmd': ':s/t/r/gI', 'exp': 'Tesring srring' },
+       \ { 'cmd': ':s/t/r/gn', 'exp': ln },
+       \ { 'cmd': ':s/t/r/gp', 'exp': 'Tesring srring' },
+       \ { 'cmd': ':s/t/r/gl', 'exp': 'Tesring srring' },
+       \ { 'cmd': ':s//r/gr', 'exp': 'Testr strr' },
+       \ { 'cmd': ':s/t/r/ic', 'exp': 'resting string', 'prompt': 'y' },
+       \ { 'cmd': ':s/foo/bar/ie', 'exp': ln },
+       \ { 'cmd': ':s/t/r/i', 'exp': 'resting string' },
+       \ { 'cmd': ':s/t/r/iI', 'exp': 'Tesring string' },
+       \ { 'cmd': ':s/t/r/in', 'exp': ln },
+       \ { 'cmd': ':s/t/r/ip', 'exp': 'resting string' },
+       \ { 'cmd': ':s//r/ir', 'exp': 'Testr string' },
+       \ { 'cmd': ':s/t/r/Ic', 'exp': 'Tesring string', 'prompt': 'y' },
+       \ { 'cmd': ':s/foo/bar/Ie', 'exp': ln },
+       \ { 'cmd': ':s/t/r/Ig', 'exp': 'Tesring srring' },
+       \ { 'cmd': ':s/t/r/Ii', 'exp': 'resting string' },
+       \ { 'cmd': ':s/t/r/I', 'exp': 'Tesring string' },
+       \ { 'cmd': ':s/t/r/Ip', 'exp': 'Tesring string' },
+       \ { 'cmd': ':s/t/r/Il', 'exp': 'Tesring string' },
+       \ { 'cmd': ':s//r/Ir', 'exp': 'Testr string' },
+       \ { 'cmd': ':s//r/rc', 'exp': 'Testr string', 'prompt': 'y' },
+       \ { 'cmd': ':s//r/rg', 'exp': 'Testr strr' },
+       \ { 'cmd': ':s//r/ri', 'exp': 'Testr string' },
+       \ { 'cmd': ':s//r/rI', 'exp': 'Testr string' },
+       \ { 'cmd': ':s//r/rn', 'exp': 'Testing string' },
+       \ { 'cmd': ':s//r/rp', 'exp': 'Testr string' },
+       \ { 'cmd': ':s//r/rl', 'exp': 'Testr string' },
+       \ { 'cmd': ':s//r/r', 'exp': 'Testr string' },
+       \]
+
+  for var in variants
+    for run in [1, 2]
+      let cmd = var.cmd
+      if run == 2 && cmd =~ "/.*/.*/."
+       " Change  :s/from/to/{flags}  to  :s{flags}
+       let cmd = substitute(cmd, '/.*/', '', '')
+      endif
+      call setline(1, [ln])
+      let msg = printf('using "%s"', cmd)
+      let @/='ing'
+      let v:errmsg = ''
+      call feedkeys(cmd . "\<CR>" . get(var, 'prompt', ''), 'ntx')
+      " No error should exist (matters for testing e flag)
+      call assert_equal('', v:errmsg, msg)
+      call assert_equal(var.exp, getline('.'), msg)
+    endfor
+  endfor
+endfunction
+
+func Test_substitute_repeat()
+  " This caused an invalid memory access.
+  split Xfile
+  s/^/x
+  call feedkeys("Qsc\<CR>y", 'tx')
+  bwipe!
+endfunc
index 4b88fe3..8d4be00 100644 (file)
@@ -54,7 +54,7 @@ func Test_syn_iskeyword()
   setlocal isk-=_
   call assert_equal('DLTD_BY', GetSyntaxItem('DLTD'))
   /\<D\k\+\>/:norm! ygn
-  let b2=@0
+  let b2 = @0
   call assert_equal('DLTD', @0)
 
   syn iskeyword clear
@@ -80,3 +80,324 @@ func Test_syntax_after_reload()
   call assert_true(exists('g:gotit'))
   call delete('Xsomefile')
 endfunc
+
+func Test_syntime()
+  if !has('profile')
+    return
+  endif
+
+  syntax on
+  syntime on
+  let a = execute('syntime report')
+  call assert_equal("\nNo Syntax items defined for this buffer", a)
+
+  view ../memfile_test.c
+  setfiletype cpp
+  redraw
+  let a = execute('syntime report')
+  call assert_match('^  TOTAL *COUNT *MATCH *SLOWEST *AVERAGE *NAME *PATTERN', a)
+  call assert_match(' \d*\.\d* \+[^0]\d* .* cppRawString ', a)
+  call assert_match(' \d*\.\d* \+[^0]\d* .* cppNumber ', a)
+
+  syntime off
+  syntime clear
+  let a = execute('syntime report')
+  call assert_match('^  TOTAL *COUNT *MATCH *SLOWEST *AVERAGE *NAME *PATTERN', a)
+  call assert_notmatch('.* cppRawString *', a)
+  call assert_notmatch('.* cppNumber*', a)
+  call assert_notmatch('[1-9]', a)
+
+  call assert_fails('syntime abc', 'E475')
+
+  syntax clear
+  let a = execute('syntime report')
+  call assert_equal("\nNo Syntax items defined for this buffer", a)
+
+  bd
+endfunc
+
+func Test_syntax_list()
+  syntax on
+  let a = execute('syntax list')
+  call assert_equal("\nNo Syntax items defined for this buffer", a)
+
+  view ../memfile_test.c
+  setfiletype c
+
+  let a = execute('syntax list')
+  call assert_match('cInclude*', a)
+  call assert_match('cDefine', a)
+
+  let a = execute('syntax list cDefine')
+  call assert_notmatch('cInclude*', a)
+  call assert_match('cDefine', a)
+  call assert_match(' links to Macro$', a)
+
+  call assert_fails('syntax list ABCD', 'E28:')
+  call assert_fails('syntax list @ABCD', 'E392:')
+
+  syntax clear
+  let a = execute('syntax list')
+  call assert_equal("\nNo Syntax items defined for this buffer", a)
+
+  bd
+endfunc
+
+func Test_syntax_completion()
+  call feedkeys(":syn \<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"syn case clear cluster conceal enable include iskeyword keyword list manual match off on region reset spell sync', @:)
+
+  call feedkeys(":syn case \<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"syn case ignore match', @:)
+
+  call feedkeys(":syn spell \<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"syn spell default notoplevel toplevel', @:)
+
+  call feedkeys(":syn sync \<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"syn sync ccomment clear fromstart linebreaks= linecont lines= match maxlines= minlines= region', @:)
+
+  " Check that clearing "Aap" avoids it showing up before Boolean.
+  hi Aap ctermfg=blue
+  call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_match('^"syn list Aap Boolean Character ', @:)
+  hi clear Aap
+
+  call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_match('^"syn list Boolean Character ', @:)
+
+  call feedkeys(":syn match \<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_match('^"syn match Boolean Character ', @:)
+endfunc
+
+func Test_syntax_arg_skipped()
+  syn clear
+  syntax case ignore
+  if 0
+    syntax case match
+  endif
+  call assert_match('case ignore', execute('syntax case'))
+
+  syn keyword Foo foo
+  call assert_match('Foo', execute('syntax'))
+  syn clear
+  call assert_match('case match', execute('syntax case'))
+  call assert_notmatch('Foo', execute('syntax'))
+
+  if has('conceal')
+    syn clear
+    syntax conceal on
+    if 0
+      syntax conceal off
+    endif
+    call assert_match('conceal on', execute('syntax conceal'))
+    syn clear
+    call assert_match('conceal off', execute('syntax conceal'))
+
+    syntax conceal on
+    syntax conceal off
+    call assert_match('conceal off', execute('syntax conceal'))
+  endif
+
+  syntax region Bar start=/</ end=/>/
+  if 0
+    syntax region NotTest start=/</ end=/>/ contains=@Spell
+  endif
+  call assert_match('Bar', execute('syntax'))
+  call assert_notmatch('NotTest', execute('syntax'))
+  call assert_notmatch('Spell', execute('syntax'))
+
+  hi Foo ctermfg=blue
+  let a = execute('hi Foo')
+  if 0
+    syntax rest
+  endif
+  call assert_equal(a, execute('hi Foo'))
+  hi clear Bar
+  hi clear Foo
+
+  set ft=tags
+  syn off
+  if 0
+    syntax enable
+  endif
+  call assert_match('No Syntax items defined', execute('syntax'))
+  syntax enable
+  call assert_match('tagComment', execute('syntax'))
+  set ft=
+
+  syn clear
+  if 0
+    syntax include @Spell nothing
+  endif
+  call assert_notmatch('Spell', execute('syntax'))
+
+  syn clear
+  syn iskeyword 48-57,$,_
+  call assert_match('48-57,$,_', execute('syntax iskeyword'))
+  if 0
+    syn clear
+    syn iskeyword clear
+  endif
+  call assert_match('48-57,$,_', execute('syntax iskeyword'))
+  syn iskeyword clear
+  call assert_match('not set', execute('syntax iskeyword'))
+  syn iskeyword 48-57,$,_
+  syn clear
+  call assert_match('not set', execute('syntax iskeyword'))
+
+  syn clear
+  syn keyword Foo foo
+  if 0
+    syn keyword NotAdded bar
+  endif
+  call assert_match('Foo', execute('syntax'))
+  call assert_notmatch('NotAdded', execute('highlight'))
+
+  syn clear
+  syn keyword Foo foo
+  call assert_match('Foo', execute('syntax'))
+  call assert_match('Foo', execute('syntax list'))
+  call assert_notmatch('Foo', execute('if 0 | syntax | endif'))
+  call assert_notmatch('Foo', execute('if 0 | syntax list | endif'))
+
+  syn clear
+  syn match Fopi /asdf/
+  if 0
+    syn match Fopx /asdf/
+  endif
+  call assert_match('Fopi', execute('syntax'))
+  call assert_notmatch('Fopx', execute('syntax'))
+
+  syn clear
+  syn spell toplevel
+  call assert_match('spell toplevel', execute('syntax spell'))
+  if 0
+    syn spell notoplevel
+  endif
+  call assert_match('spell toplevel', execute('syntax spell'))
+  syn spell notoplevel
+  call assert_match('spell notoplevel', execute('syntax spell'))
+  syn spell default
+  call assert_match('spell default', execute('syntax spell'))
+
+  syn clear
+  if 0
+    syntax cluster Spell
+  endif
+  call assert_notmatch('Spell', execute('syntax'))
+
+  syn clear
+  syn keyword Foo foo
+  syn sync ccomment
+  syn sync maxlines=5
+  if 0
+    syn sync maxlines=11
+  endif
+  call assert_match('on C-style comments', execute('syntax sync'))
+  call assert_match('maximal 5 lines', execute('syntax sync'))
+  syn sync clear
+  if 0
+    syn sync ccomment
+  endif
+  call assert_notmatch('on C-style comments', execute('syntax sync'))
+
+  syn clear
+endfunc
+
+func Test_syntax_invalid_arg()
+  call assert_fails('syntax case asdf', 'E390:')
+  if has('conceal')
+    call assert_fails('syntax conceal asdf', 'E390:')
+  endif
+  call assert_fails('syntax spell asdf', 'E390:')
+  call assert_fails('syntax clear @ABCD', 'E391:')
+  call assert_fails('syntax include @Xxx', 'E397:')
+  call assert_fails('syntax region X start="{"', 'E399:')
+  call assert_fails('syntax sync x', 'E404:')
+  call assert_fails('syntax keyword Abc a[', 'E789:')
+  call assert_fails('syntax keyword Abc a[bc]d', 'E890:')
+endfunc
+
+func Test_syn_sync()
+  syntax region HereGroup start=/this/ end=/that/
+  syntax sync match SyncHere grouphere HereGroup "pattern"
+  call assert_match('SyncHere', execute('syntax sync'))
+  syn sync clear
+  call assert_notmatch('SyncHere', execute('syntax sync'))
+  syn clear
+endfunc
+
+func Test_syn_clear()
+  syntax keyword Foo foo
+  syntax keyword Bar tar
+  call assert_match('Foo', execute('syntax'))
+  call assert_match('Bar', execute('syntax'))
+  call assert_equal('Foo', synIDattr(hlID("Foo"), "name"))
+  syn clear Foo
+  call assert_notmatch('Foo', execute('syntax'))
+  call assert_match('Bar', execute('syntax'))
+  call assert_equal('Foo', synIDattr(hlID("Foo"), "name"))
+  syn clear Foo Bar
+  call assert_notmatch('Foo', execute('syntax'))
+  call assert_notmatch('Bar', execute('syntax'))
+  hi clear Foo
+  call assert_equal('Foo', synIDattr(hlID("Foo"), "name"))
+  hi clear Bar
+endfunc
+
+func Test_invalid_name()
+  syn clear
+  syn keyword Nop yes
+  call assert_fails("syntax keyword Wr\x17ong bar", 'E669:')
+  syntax keyword @Wrong bar
+  call assert_match('W18:', execute('1messages'))
+  syn clear
+  hi clear Nop
+  hi clear @Wrong
+endfunc
+
+func Test_ownsyntax()
+  new Xfoo
+  call setline(1, '#define FOO')
+  syntax on
+  set filetype=c
+  ownsyntax perl
+  call assert_equal('perlComment', synIDattr(synID(line('.'), col('.'), 1), 'name'))
+  call assert_equal('c',    b:current_syntax)
+  call assert_equal('perl', w:current_syntax)
+
+  " A new split window should have the original syntax.
+  split
+  call assert_equal('cDefine', synIDattr(synID(line('.'), col('.'), 1), 'name'))
+  call assert_equal('c', b:current_syntax)
+  call assert_equal(0, exists('w:current_syntax'))
+
+  wincmd x
+  call assert_equal('perlComment', synIDattr(synID(line("."), col("."), 1), "name"))
+
+  syntax off
+  set filetype&
+  %bw!
+endfunc
+
+func Test_ownsyntax_completion()
+  call feedkeys(":ownsyntax java\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"ownsyntax java javacc javascript', @:)
+endfunc
+
+func Test_highlight_invalid_arg()
+  if has('gui_running')
+    call assert_fails('hi XXX guifg=xxx', 'E254:')
+  endif
+  call assert_fails('hi DoesNotExist', 'E411:')
+  call assert_fails('hi link', 'E412:')
+  call assert_fails('hi link a', 'E412:')
+  call assert_fails('hi link a b c', 'E413:')
+  call assert_fails('hi XXX =', 'E415:')
+  call assert_fails('hi XXX cterm', 'E416:')
+  call assert_fails('hi XXX cterm=', 'E417:')
+  call assert_fails('hi XXX cterm=DoesNotExist', 'E418:')
+  call assert_fails('hi XXX ctermfg=DoesNotExist', 'E421:')
+  call assert_fails('hi XXX xxx=White', 'E423:')
+endfunc
+
diff --git a/src/testdir/test_system.vim b/src/testdir/test_system.vim
new file mode 100644 (file)
index 0000000..d6886b0
--- /dev/null
@@ -0,0 +1,92 @@
+" Tests for system() and systemlist()
+
+function! Test_System()
+  if !executable('echo') || !executable('cat') || !executable('wc')
+    return
+  endif
+  let out = system('echo 123')
+  " On Windows we may get a trailing space.
+  if out != "123 \n"
+    call assert_equal("123\n", out)
+  endif
+
+  let out = systemlist('echo 123')
+  " On Windows we may get a trailing space and CR.
+  if out != ["123 \r"]
+    call assert_equal(['123'], out)
+  endif
+
+  call assert_equal('123',   system('cat', '123'))
+  call assert_equal(['123'], systemlist('cat', '123'))
+  call assert_equal(["as\<NL>df"], systemlist('cat', ["as\<NL>df"]))
+
+  new Xdummy
+  call setline(1, ['asdf', "pw\<NL>er", 'xxxx'])
+  let out = system('wc -l', bufnr('%'))
+  " On OS/X we get leading spaces
+  let out = substitute(out, '^ *', '', '')
+  call assert_equal("3\n", out)
+
+  let out = systemlist('wc -l', bufnr('%'))
+  " On Windows we may get a trailing CR.
+  if out != ["3\r"]
+    " On OS/X we get leading spaces
+    if type(out) == v:t_list
+      let out[0] = substitute(out[0], '^ *', '', '')
+    endif
+    call assert_equal(['3'],  out)
+  endif
+
+  let out = systemlist('cat', bufnr('%'))
+  " On Windows we may get a trailing CR.
+  if out != ["asdf\r", "pw\<NL>er\r", "xxxx\r"]
+    call assert_equal(['asdf', "pw\<NL>er", 'xxxx'],  out)
+  endif
+  bwipe!
+
+  call assert_fails('call system("wc -l", 99999)', 'E86:')
+endfunction
+
+function! Test_system_exmode()
+  if has('unix') " echo $? only works on Unix
+    let cmd = ' -es -u NONE -c "source Xscript" +q; echo $?'
+    " Need to put this in a script, "catch" isn't found after an unknown
+    " function.
+    call writefile(['try', 'call doesnotexist()', 'catch', 'endtry'], 'Xscript')
+    let a = system(v:progpath . cmd)
+    call assert_equal('0', a[0])
+    call assert_equal(0, v:shell_error)
+  endif
+
+  " Error before try does set error flag.
+  call writefile(['call nosuchfunction()', 'try', 'call doesnotexist()', 'catch', 'endtry'], 'Xscript')
+  if has('unix') " echo $? only works on Unix
+    let a = system(v:progpath . cmd)
+    call assert_notequal('0', a[0])
+  endif
+
+  let cmd = ' -es -u NONE -c "source Xscript" +q'
+  let a = system(v:progpath . cmd)
+  call assert_notequal(0, v:shell_error)
+  call delete('Xscript')
+
+  if has('unix') " echo $? only works on Unix
+    let cmd = ' -es -u NONE -c "call doesnotexist()" +q; echo $?'
+    let a = system(v:progpath. cmd)
+    call assert_notequal(0, a[0])
+  endif
+
+  let cmd = ' -es -u NONE -c "call doesnotexist()" +q'
+  let a = system(v:progpath. cmd)
+  call assert_notequal(0, v:shell_error)
+
+  if has('unix') " echo $? only works on Unix
+    let cmd = ' -es -u NONE -c "call doesnotexist()|let a=1" +q; echo $?'
+    let a = system(v:progpath. cmd)
+    call assert_notequal(0, a[0])
+  endif
+
+  let cmd = ' -es -u NONE -c "call doesnotexist()|let a=1" +q'
+  let a = system(v:progpath. cmd)
+  call assert_notequal(0, v:shell_error)
+endfunc
index 3f69fb9..c139958 100644 (file)
@@ -65,6 +65,15 @@ function Test_tabpage()
     call assert_true(tabpagenr() == 2 && tabpagewinnr(2, '$') == 2 && tabpagewinnr(2) == 1)
     tabclose
     q
+    "
+    "
+    " Test for ":tab drop vertical-split-window" to jump test1 buffer
+    tabedit test1
+    vnew
+    tabfirst
+    tab drop test1
+    call assert_equal([2, 2, 2, 2], [tabpagenr('$'), tabpagenr(), tabpagewinnr(2, '$'), tabpagewinnr(2)])
+    1tabonly
   endif
   "
   "
@@ -85,10 +94,6 @@ function Test_tabpage()
   call assert_equal(7, tabpagenr())
   tabmove
   call assert_equal(10, tabpagenr())
-  tabmove -20
-  call assert_equal(1, tabpagenr())
-  tabmove +20
-  call assert_equal(10, tabpagenr())
   0tabmove
   call assert_equal(1, tabpagenr())
   $tabmove
@@ -101,7 +106,16 @@ function Test_tabpage()
   call assert_equal(4, tabpagenr())
   7tabmove 5
   call assert_equal(5, tabpagenr())
+  call assert_fails("99tabmove", 'E16:')
+  call assert_fails("+99tabmove", 'E16:')
+  call assert_fails("-99tabmove", 'E16:')
   call assert_fails("tabmove foo", 'E474:')
+  call assert_fails("tabmove 99", 'E474:')
+  call assert_fails("tabmove +99", 'E474:')
+  call assert_fails("tabmove -99", 'E474:')
+  call assert_fails("tabmove -3+", 'E474:')
+  call assert_fails("tabmove $3", 'E474:')
+  1tabonly!
 endfunc
 
 " Test autocommands
@@ -109,7 +123,6 @@ function Test_tabpage_with_autocmd()
   if !has('autocmd')
     return
   endif
-  tabonly!
   command -nargs=1 -bar C :call add(s:li, '=== ' . <q-args> . ' ===')|<args>
   augroup TestTabpageGroup
     au!
@@ -174,8 +187,10 @@ function Test_tabpage_with_autocmd()
 
   autocmd TabDestructive TabEnter * nested :C tabnext 2 | C tabclose 3
   let s:li = []
-  C tabnext 3
-  call assert_equal(['=== tabnext 3 ===', 'BufLeave', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', '=== tabnext 2 ===', 'BufLeave', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', '=== tabnext 2 ===', '=== tabclose 3 ===', 'BufEnter', '=== tabclose 3 ==='], s:li)
+  call assert_equal(3, tabpagenr('$'))
+  C tabnext 2
+  call assert_equal(2, tabpagenr('$'))
+  call assert_equal(['=== tabnext 2 ===', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', '=== tabnext 2 ===', '=== tabclose 3 ==='], s:li)
   call assert_equal(['2/2'], [tabpagenr().'/'.tabpagenr('$')])
 
   delcommand C
@@ -183,8 +198,7 @@ function Test_tabpage_with_autocmd()
   augroup! TabDestructive
   autocmd! TestTabpageGroup
   augroup! TestTabpageGroup
-  tabonly!
-  bw!
+  1tabonly!
 endfunction
 
 function Test_tabpage_with_tab_modifier()
@@ -215,8 +229,223 @@ function Test_tabpage_with_tab_modifier()
   call assert_fails('-99tab help', 'E16:')
 
   delfunction s:check_tab
-  tabonly!
-  bw!
+  1tabonly!
+endfunction
+
+function Check_tab_count(pre_nr, cmd, post_nr)
+  exec 'tabnext' a:pre_nr
+  normal! G
+  exec a:cmd
+  call assert_equal(a:post_nr, tabpagenr(), a:cmd)
+endfunc
+
+" Test for [count] of tabnext
+function Test_tabpage_with_tabnext()
+  for n in range(4)
+    tabedit
+    call setline(1, ['', '', '3'])
+  endfor
+
+  call Check_tab_count(1, 'tabnext', 2)
+  call Check_tab_count(1, '3tabnext', 3)
+  call Check_tab_count(1, '.tabnext', 1)
+  call Check_tab_count(1, '.+1tabnext', 2)
+  call Check_tab_count(2, '+tabnext', 3)
+  call Check_tab_count(2, '+2tabnext', 4)
+  call Check_tab_count(4, '-tabnext', 3)
+  call Check_tab_count(4, '-2tabnext', 2)
+  call Check_tab_count(3, '$tabnext', 5)
+  call assert_fails('0tabnext', 'E16:')
+  call assert_fails('99tabnext', 'E16:')
+  call assert_fails('+99tabnext', 'E16:')
+  call assert_fails('-99tabnext', 'E16:')
+  call Check_tab_count(1, 'tabnext 3', 3)
+  call Check_tab_count(2, 'tabnext +', 3)
+  call Check_tab_count(2, 'tabnext +2', 4)
+  call Check_tab_count(4, 'tabnext -', 3)
+  call Check_tab_count(4, 'tabnext -2', 2)
+  call Check_tab_count(3, 'tabnext $', 5)
+  call assert_fails('tabnext 0', 'E474:')
+  call assert_fails('tabnext .', 'E474:')
+  call assert_fails('tabnext -+', 'E474:')
+  call assert_fails('tabnext +2-', 'E474:')
+  call assert_fails('tabnext $3', 'E474:')
+  call assert_fails('tabnext 99', 'E474:')
+  call assert_fails('tabnext +99', 'E474:')
+  call assert_fails('tabnext -99', 'E474:')
+
+  1tabonly!
+endfunction
+
+" Test for [count] of tabprevious
+function Test_tabpage_with_tabprevious()
+  for n in range(5)
+    tabedit
+    call setline(1, ['', '', '3'])
+  endfor
+
+  for cmd in ['tabNext', 'tabprevious']
+    call Check_tab_count(6, cmd, 5)
+    call Check_tab_count(6, '3' . cmd, 3)
+    call Check_tab_count(6, '8' . cmd, 4)
+    call Check_tab_count(6, cmd . ' 3', 3)
+    call Check_tab_count(6, cmd . ' 8', 4)
+    for n in range(2)
+      for c in ['0', '.+3', '+', '+2' , '-', '-2' , '$', '+99', '-99']
+        if n == 0 " pre count
+          let entire_cmd = c . cmd
+          let err_code = 'E16:'
+        else
+          let entire_cmd = cmd . ' ' . c
+          let err_code = 'E474:'
+        endif
+        call assert_fails(entire_cmd, err_code)
+      endfor
+    endfor
+  endfor
+
+  1tabonly!
+endfunction
+
+function s:reconstruct_tabpage_for_test(nr)
+  let n = (a:nr > 2) ? a:nr - 2 : 1
+  1tabonly!
+  0tabedit n0
+  for n in range(1, n)
+    exec '$tabedit n' . n
+    if n == 1
+      call setline(1, ['', '', '3'])
+    endif
+  endfor
+endfunc
+
+" Test for [count] of tabclose
+function Test_tabpage_with_tabclose()
+
+  " pre count
+  call s:reconstruct_tabpage_for_test(6)
+  call Check_tab_count(3, 'tabclose!', 3)
+  call Check_tab_count(1, '3tabclose', 1)
+  call Check_tab_count(4, '4tabclose', 3)
+  call Check_tab_count(3, '1tabclose', 2)
+  call Check_tab_count(2, 'tabclose', 1)
+  call assert_equal(1, tabpagenr('$'))
+  call assert_equal('', bufname(''))
+
+  call s:reconstruct_tabpage_for_test(6)
+  call Check_tab_count(2, '$tabclose', 2)
+  call Check_tab_count(4, '.tabclose', 4)
+  call Check_tab_count(3, '.+tabclose', 3)
+  call Check_tab_count(3, '.-2tabclose', 2)
+  call Check_tab_count(1, '.+1tabclose!', 1)
+  call assert_equal(1, tabpagenr('$'))
+  call assert_equal('', bufname(''))
+
+  " post count
+  call s:reconstruct_tabpage_for_test(6)
+  call Check_tab_count(3, 'tabclose!', 3)
+  call Check_tab_count(1, 'tabclose 3', 1)
+  call Check_tab_count(4, 'tabclose 4', 3)
+  call Check_tab_count(3, 'tabclose 1', 2)
+  call Check_tab_count(2, 'tabclose', 1)
+  call assert_equal(1, tabpagenr('$'))
+  call assert_equal('', bufname(''))
+
+  call s:reconstruct_tabpage_for_test(6)
+  call Check_tab_count(2, 'tabclose $', 2)
+  call Check_tab_count(4, 'tabclose', 4)
+  call Check_tab_count(3, 'tabclose +', 3)
+  call Check_tab_count(3, 'tabclose -2', 2)
+  call Check_tab_count(1, 'tabclose! +1', 1)
+  call assert_equal(1, tabpagenr('$'))
+  call assert_equal('', bufname(''))
+
+  call s:reconstruct_tabpage_for_test(6)
+  for n in range(2)
+    for c in ['0', '$3', '99', '+99', '-99']
+      if n == 0 " pre count
+        let entire_cmd = c . 'tabclose'
+        let err_code = 'E16:'
+      else
+        let entire_cmd = 'tabclose ' . c
+        let err_code = 'E474:'
+      endif
+      call assert_fails(entire_cmd, err_code)
+      call assert_equal(6, tabpagenr('$'))
+    endfor
+  endfor
+
+  call assert_fails('3tabclose', 'E37:')
+  call assert_fails('tabclose 3', 'E37:')
+  call assert_fails('tabclose -+', 'E474:')
+  call assert_fails('tabclose +2-', 'E474:')
+  call assert_equal(6, tabpagenr('$'))
+
+  1tabonly!
+endfunction
+
+" Test for [count] of tabonly
+function Test_tabpage_with_tabonly()
+
+  " Test for the normal behavior (pre count only)
+  let tc = [ [4, '.', '!'], [2, '.+', ''], [3, '.-2', '!'], [1, '.+1', '!'] ]
+  for c in tc
+    call s:reconstruct_tabpage_for_test(6)
+    let entire_cmd = c[1] . 'tabonly' . c[2]
+    call Check_tab_count(c[0], entire_cmd, 1)
+    call assert_equal(1, tabpagenr('$'))
+  endfor
+
+  " Test for the normal behavior
+  let tc2 = [ [3, '', ''], [1, '3', ''], [4, '4', '!'], [3, '1', '!'],
+        \    [2, '', '!'],
+        \    [2, '$', '!'], [3, '+', '!'], [3, '-2', '!'], [3, '+1', '!']
+        \  ]
+  for n in range(2)
+    for c in tc2
+      call s:reconstruct_tabpage_for_test(6)
+      if n == 0 " pre count
+        let entire_cmd = c[1] . 'tabonly' . c[2]
+      else
+        let entire_cmd = 'tabonly' . c[2] . ' ' . c[1]
+      endif
+      call Check_tab_count(c[0], entire_cmd, 1)
+      call assert_equal(1, tabpagenr('$'))
+    endfor
+  endfor
+
+  " Test for the error behavior
+  for n in range(2)
+    for c in ['0', '$3', '99', '+99', '-99']
+      call s:reconstruct_tabpage_for_test(6)
+      if n == 0 " pre count
+        let entire_cmd = c . 'tabonly'
+        let err_code = 'E16:'
+      else
+        let entire_cmd = 'tabonly ' . c
+        let err_code = 'E474:'
+      endif
+      call assert_fails(entire_cmd, err_code)
+      call assert_equal(6, tabpagenr('$'))
+    endfor
+  endfor
+
+  " Test for the error behavior (post count only)
+  for c in tc
+    call s:reconstruct_tabpage_for_test(6)
+    let entire_cmd = 'tabonly' . c[2] . ' ' . c[1]
+    let err_code = 'E474:'
+    call assert_fails(entire_cmd, err_code)
+    call assert_equal(6, tabpagenr('$'))
+  endfor
+
+  call assert_fails('tabonly -+', 'E474:')
+  call assert_fails('tabonly +2-', 'E474:')
+  call assert_equal(6, tabpagenr('$'))
+
+  1tabonly!
+  new
+  only!
 endfunction
 
 func Test_tabnext_on_buf_unload1()
index 11ec144..0d697b3 100644 (file)
@@ -23,6 +23,48 @@ func Test_cancel_ptjump()
   quit
 endfunc
 
+func Test_static_tagjump()
+  set tags=Xtags
+  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+        \ "one\tXfile1\t/^one/;\"\tf\tfile:\tsignature:(void)",
+        \ "word\tXfile2\tcmd2"],
+        \ 'Xtags')
+  new Xfile1
+  call setline(1, ['empty', 'one()', 'empty'])
+  write
+  tag one
+  call assert_equal(2, line('.'))
+
+  bwipe!
+  set tags&
+  call delete('Xtags')
+  call delete('Xfile1')
+endfunc
+
+func Test_duplicate_tagjump()
+  set tags=Xtags
+  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+        \ "thesame\tXfile1\t1;\"\td\tfile:",
+        \ "thesame\tXfile1\t2;\"\td\tfile:",
+        \ "thesame\tXfile1\t3;\"\td\tfile:",
+        \ ],
+        \ 'Xtags')
+  new Xfile1
+  call setline(1, ['thesame one', 'thesame two', 'thesame three'])
+  write
+  tag thesame
+  call assert_equal(1, line('.'))
+  tnext
+  call assert_equal(2, line('.'))
+  tnext
+  call assert_equal(3, line('.'))
+
+  bwipe!
+  set tags&
+  call delete('Xtags')
+  call delete('Xfile1')
+endfunc
+
 " Tests for [ CTRL-I and CTRL-W CTRL-I commands
 function Test_keyword_jump()
   call writefile(["#include Xinclude", "",
diff --git a/src/testdir/test_taglist.vim b/src/testdir/test_taglist.vim
new file mode 100644 (file)
index 0000000..2d1557e
--- /dev/null
@@ -0,0 +1,58 @@
+" test 'taglist' function
+
+func Test_taglist()
+  call writefile([
+       \ "FFoo\tXfoo\t1",
+       \ "FBar\tXfoo\t2",
+       \ "BFoo\tXbar\t1",
+       \ "BBar\tXbar\t2"
+       \ ], 'Xtags')
+  set tags=Xtags
+  split Xtext
+
+  call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo"), {i, v -> v.name}))
+  call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo", "Xtext"), {i, v -> v.name}))
+  call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo", "Xfoo"), {i, v -> v.name}))
+  call assert_equal(['BFoo', 'FFoo'], map(taglist("Foo", "Xbar"), {i, v -> v.name}))
+
+  call delete('Xtags')
+  bwipe
+endfunc
+
+func Test_taglist_native_etags()
+  if !has('emacs_tags')
+    return
+  endif
+  call writefile([
+       \ "\x0c",
+       \ "src/os_unix.c,13491",
+       \ "set_signals(\x7f1335,32699",
+       \ "reset_signals(\x7f1407,34136",
+       \ ], 'Xtags')
+
+  set tags=Xtags
+
+  call assert_equal([['set_signals', '1335,32699'], ['reset_signals', '1407,34136']],
+       \ map(taglist('set_signals'), {i, v -> [v.name, v.cmd]}))
+
+  call delete('Xtags')
+endfunc
+
+func Test_taglist_ctags_etags()
+  if !has('emacs_tags')
+    return
+  endif
+  call writefile([
+       \ "\x0c",
+       \ "src/os_unix.c,13491",
+       \ "set_signals(void)\x7fset_signals\x011335,32699",
+       \ "reset_signals(void)\x7freset_signals\x011407,34136",
+       \ ], 'Xtags')
+
+  set tags=Xtags
+
+  call assert_equal([['set_signals', '1335,32699'], ['reset_signals', '1407,34136']],
+       \ map(taglist('set_signals'), {i, v -> [v.name, v.cmd]}))
+
+  call delete('Xtags')
+endfunc
diff --git a/src/testdir/test_tcl.vim b/src/testdir/test_tcl.vim
new file mode 100644 (file)
index 0000000..ac772cc
--- /dev/null
@@ -0,0 +1,23 @@
+" Tests for the Tcl interface.
+
+if !has('tcl')
+  finish
+end
+
+function Test_tcldo()
+  " Check deleting lines does not trigger ml_get error.
+  new
+  call setline(1, ['one', 'two', 'three'])
+  tcldo ::vim::command %d_
+  bwipe!
+
+  " Check switching to another buffer does not trigger ml_get error.
+  new
+  let wincount = winnr('$')
+  call setline(1, ['one', 'two', 'three'])
+  tcldo ::vim::command new
+  call assert_equal(wincount + 1, winnr('$'))
+  bwipe!
+  bwipe!
+endfunc
+
index 630ae5d..5e67f25 100644 (file)
@@ -4,6 +4,7 @@ if !has('textobjects')
   finish
 endif
 
+set belloff=all
 function! CpoM(line, useM, expected)
   new
 
index fb1cdc8..e785c60 100644 (file)
@@ -3,6 +3,7 @@
 " undo-able pieces.  Do that by setting 'undolevels'.
 " Also tests :earlier and :later.
 
+set belloff=all
 func Test_undotree()
   exe "normal Aabc\<Esc>"
   set ul=100
@@ -176,7 +177,17 @@ func Test_undojoin()
   call assert_equal(['aaaa', 'bbbb', 'cccc'], getline(2, '$'))
   call feedkeys("u", 'xt')
   call assert_equal(['aaaa'], getline(2, '$'))
-  close!
+  bwipe!
+endfunc
+
+func Test_undojoin_redo()
+  new
+  call setline(1, ['first line', 'second line'])
+  call feedkeys("ixx\<Esc>", 'xt')
+  call feedkeys(":undojoin | redo\<CR>", 'xt')
+  call assert_equal('xxfirst line', getline(1))
+  call assert_equal('second line', getline(2))
+  bwipe!
 endfunc
 
 func Test_undo_write()
@@ -235,3 +246,31 @@ func Test_insert_expr()
 
   close!
 endfunc
+
+func Test_undofile_earlier()
+  " Issue #1254
+  " create undofile with timestamps older than Vim startup time.
+  let t0 = localtime() - 43200
+  call test_settime(t0)
+  new Xfile
+  call feedkeys("ione\<Esc>", 'xt')
+  set ul=100
+  call test_settime(t0 + 1)
+  call feedkeys("otwo\<Esc>", 'xt')
+  set ul=100
+  call test_settime(t0 + 2)
+  call feedkeys("othree\<Esc>", 'xt')
+  set ul=100
+  w
+  wundo Xundofile
+  bwipe!
+  " restore normal timestamps.
+  call test_settime(0)
+  new Xfile
+  rundo Xundofile
+  earlier 1d
+  call assert_equal('', getline(1))
+  bwipe!
+  call delete('Xfile')
+  call delete('Xundofile')
+endfunc
index 4c58785..c20b0be 100644 (file)
@@ -17,3 +17,7 @@ func Test_not_existing()
   unlet! does_not_exist
   call assert_fails('unlet does_not_exist', 'E108:')
 endfunc
+
+func Test_unlet_fails()
+  call assert_fails('unlet v:["count"]', 'E46:')
+endfunc
index 1f92ada..29db51f 100644 (file)
@@ -1,6 +1,7 @@
 " Tests for user defined commands
 
 " Test for <mods> in user defined commands
+set belloff=all
 function Test_cmdmods()
   let g:mods = ''
 
@@ -102,3 +103,107 @@ func Test_CmdUndefined()
   call assert_fails('Dothat', 'E492:')
   call assert_equal('yes', g:didnot)
 endfunc
+
+func Test_CmdErrors()
+  call assert_fails('com! docmd :', 'E183:')
+  call assert_fails('com! \<Tab> :', 'E182:')
+  call assert_fails('com! _ :', 'E182:')
+  call assert_fails('com! X :', 'E841:')
+  call assert_fails('com! - DoCmd :', 'E175:')
+  call assert_fails('com! -xxx DoCmd :', 'E181:')
+  call assert_fails('com! -addr DoCmd :', 'E179:')
+  call assert_fails('com! -complete DoCmd :', 'E179:')
+  call assert_fails('com! -complete=xxx DoCmd :', 'E180:')
+  call assert_fails('com! -complete=custom DoCmd :', 'E467:')
+  call assert_fails('com! -complete=customlist DoCmd :', 'E467:')
+  call assert_fails('com! -complete=behave,CustomComplete DoCmd :', 'E468:')
+  call assert_fails('com! -nargs=x DoCmd :', 'E176:')
+  call assert_fails('com! -count=1 -count=2 DoCmd :', 'E177:')
+  call assert_fails('com! -count=x DoCmd :', 'E178:')
+  call assert_fails('com! -range=x DoCmd :', 'E178:')
+
+  com! -nargs=0 DoCmd :
+  call assert_fails('DoCmd x', 'E488:')
+
+  com! -nargs=1 DoCmd :
+  call assert_fails('DoCmd', 'E471:')
+
+  com! -nargs=+ DoCmd :
+  call assert_fails('DoCmd', 'E471:')
+
+  call assert_fails('com DoCmd :', 'E174:')
+  comclear
+  call assert_fails('delcom DoCmd', 'E184:')
+endfunc
+
+func CustomComplete(A, L, P)
+  return "January\nFebruary\nMars\n"
+endfunc
+
+func CustomCompleteList(A, L, P)
+  return [ "Monday", "Tuesday", "Wednesday" ]
+endfunc
+
+func Test_CmdCompletion()
+  call feedkeys(":com -\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"com -addr bang bar buffer complete count nargs range register', @:)
+
+  call feedkeys(":com -nargs=0 -\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"com -nargs=0 -addr bang bar buffer complete count nargs range register', @:)
+
+  call feedkeys(":com -nargs=\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"com -nargs=* + 0 1 ?', @:)
+
+  call feedkeys(":com -addr=\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"com -addr=arguments buffers lines loaded_buffers quickfix tabs windows', @:)
+
+  call feedkeys(":com -complete=co\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"com -complete=color command compiler', @:)
+
+  command! DoCmd1 :
+  command! DoCmd2 :
+  call feedkeys(":com \<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"com DoCmd1 DoCmd2', @:)
+
+  call feedkeys(":DoC\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"DoCmd1 DoCmd2', @:)
+
+  call feedkeys(":delcom DoC\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"delcom DoCmd1 DoCmd2', @:)
+
+  delcom DoCmd1
+  call feedkeys(":delcom DoC\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"delcom DoCmd2', @:)
+
+  call feedkeys(":com DoC\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"com DoCmd2', @:)
+
+  delcom DoCmd2
+  call feedkeys(":delcom DoC\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"delcom DoC', @:)
+
+  call feedkeys(":com DoC\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"com DoC', @:)
+
+  com! -complete=behave DoCmd :
+  call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"DoCmd mswin xterm', @:)
+
+  " This does not work. Why?
+  "call feedkeys(":DoCmd x\<C-A>\<C-B>\"\<CR>", 'tx')
+  "call assert_equal('"DoCmd xterm', @:)
+
+  com! -complete=custom,CustomComplete DoCmd :
+  call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"DoCmd January February Mars', @:)
+
+  com! -complete=customlist,CustomCompleteList DoCmd :
+  call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"DoCmd Monday Tuesday Wednesday', @:)
+
+  com! -complete=custom,CustomCompleteList DoCmd :
+  call assert_fails("call feedkeys(':DoCmd \<C-D>', 'tx')", 'E730:')
+
+  com! -complete=customlist,CustomComp DoCmd :
+  call assert_fails("call feedkeys(':DoCmd \<C-D>', 'tx')", 'E117:')
+endfunc
diff --git a/src/testdir/test_utf8.in b/src/testdir/test_utf8.in
deleted file mode 100644 (file)
index 1d6a7a4..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-Tests for Unicode manipulations                vim: set ft=vim :
-STARTTEST
-:so small.vim
-:set encoding=utf-8
-:"
-:" Visual block Insert adjusts for multi-byte char
-:new
-:call setline(1, ["aaa", "あああ", "bbb"])
-:exe ":norm! gg0l\<C-V>jjIx\<Esc>"
-:let r = getline(1, '$')
-:"
-:bwipeout!
-:$put=r
-:"
-:" Test for built-in function strchars()
-:for str in ["a", "あいa", "A\u20dd", "A\u20dd\u20dd", "\u20dd"]
-:      $put=strchars(str)
-:      $put=strchars(str, 0)
-:      $put=strchars(str, 1)
-:endfor
-:"
-:" Test for customlist completion
-:function! CustomComplete1(lead, line, pos)
-:      return ['あ', 'い']
-:endfunction
-:command -nargs=1 -complete=customlist,CustomComplete1 Test1 echo
-:call feedkeys(":Test1 \<C-L>'\<C-B>$put='\<CR>", 'it')
-:"
-:function! CustomComplete2(lead, line, pos)
-:      return ['あたし', 'あたま', 'あたりめ']
-:endfunction
-:command -nargs=1 -complete=customlist,CustomComplete2 Test2 echo
-:call feedkeys(":Test2 \<C-L>'\<C-B>$put='\<CR>", 'it')
-:"
-:function! CustomComplete3(lead, line, pos)
-:      return ['Nこ', 'Nん', 'Nぶ']
-:endfunction
-:command -nargs=1 -complete=customlist,CustomComplete3 Test3 echo
-:call feedkeys(":Test3 \<C-L>'\<C-B>$put='\<CR>", 'it')
-:"
-:call garbagecollect(1)
-:/^start:/,$wq! test.out
-ENDTEST
-start:
diff --git a/src/testdir/test_utf8.ok b/src/testdir/test_utf8.ok
deleted file mode 100644 (file)
index c655922..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-start:
-axaa
-xあああ
-bxbb
-1
-1
-1
-3
-3
-3
-2
-2
-1
-3
-3
-1
-1
-1
-1
-Test1 
-Test2 あた
-Test3 N
diff --git a/src/testdir/test_utf8.vim b/src/testdir/test_utf8.vim
new file mode 100644 (file)
index 0000000..24e3db8
--- /dev/null
@@ -0,0 +1,65 @@
+" Tests for Unicode manipulations
+if !has('multi_byte')
+  finish
+endif
+
+" Visual block Insert adjusts for multi-byte char
+func Test_visual_block_insert()
+  new
+  call setline(1, ["aaa", "あああ", "bbb"])
+  exe ":norm! gg0l\<C-V>jjIx\<Esc>"
+  call assert_equal(['axaa', 'xあああ', 'bxbb'], getline(1, '$'))
+  bwipeout!
+endfunc
+
+" Test for built-in function strchars()
+func Test_strchars()
+  let inp = ["a", "あいa", "A\u20dd", "A\u20dd\u20dd", "\u20dd"]
+  let exp = [[1, 1, 1], [3, 3, 3], [2, 2, 1], [3, 3, 1], [1, 1, 1]]
+  for i in range(len(inp))
+    call assert_equal(exp[i][0], strchars(inp[i]))
+    call assert_equal(exp[i][1], strchars(inp[i], 0))
+    call assert_equal(exp[i][2], strchars(inp[i], 1))
+  endfor
+endfunc
+
+" Test for customlist completion
+function! CustomComplete1(lead, line, pos)
+       return ['あ', 'い']
+endfunction
+
+function! CustomComplete2(lead, line, pos)
+       return ['あたし', 'あたま', 'あたりめ']
+endfunction
+
+function! CustomComplete3(lead, line, pos)
+       return ['Nこ', 'Nん', 'Nぶ']
+endfunction
+
+func Test_customlist_completion()
+  command -nargs=1 -complete=customlist,CustomComplete1 Test1 echo
+  call feedkeys(":Test1 \<C-L>\<C-B>\"\<CR>", 'itx')
+  call assert_equal('"Test1 ', getreg(':'))
+
+  command -nargs=1 -complete=customlist,CustomComplete2 Test2 echo
+  call feedkeys(":Test2 \<C-L>\<C-B>\"\<CR>", 'itx')
+  call assert_equal('"Test2 あた', getreg(':'))
+
+  command -nargs=1 -complete=customlist,CustomComplete3 Test3 echo
+  call feedkeys(":Test3 \<C-L>\<C-B>\"\<CR>", 'itx')
+  call assert_equal('"Test3 N', getreg(':'))
+
+  call garbagecollect(1)
+endfunc
+
+" Yank one 3 byte character and check the mark columns.
+func Test_getvcol()
+  new
+  call setline(1, "x\u2500x")
+  normal 0lvy
+  call assert_equal(2, col("'["))
+  call assert_equal(4, col("']"))
+  call assert_equal(2, virtcol("'["))
+  call assert_equal(2, virtcol("']"))
+endfunc
index 7d0f157..6c0e533 100644 (file)
@@ -450,13 +450,13 @@ func Test_viminfo_file_mark_tabclose()
   let lnum = line('.')
   while 1
     if lnum == line('$')
-      call assert_false(1, 'mark not found in Xtestfileintab')
+      call assert_report('mark not found in Xtestfileintab')
       break
     endif
     let lnum += 1
     let line = getline(lnum)
     if line == ''
-      call assert_false(1, 'mark not found in Xtestfileintab')
+      call assert_report('mark not found in Xtestfileintab')
       break
     endif
     if line =~ "^\t\""
similarity index 92%
rename from src/testdir/test_viml.vim
rename to src/testdir/test_vimscript.vim
index 3a195dd..11961ba 100644 (file)
@@ -1,4 +1,4 @@
-" Test various aspects of the Vim language.
+" Test various aspects of the Vim script language.
 " Most of this was formerly in test49.
 
 "-------------------------------------------------------------------------------
@@ -1226,7 +1226,7 @@ func Test_num64()
 
     call assert_equal( 9223372036854775807,  1 / 0)
     call assert_equal(-9223372036854775807, -1 / 0)
-    call assert_equal(-9223372036854775808,  0 / 0)
+    call assert_equal(-9223372036854775807 - 1,  0 / 0)
 
     call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150))
     call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150))
@@ -1239,6 +1239,88 @@ func Test_num64()
 endfunc
 
 "-------------------------------------------------------------------------------
+" Test 95:  lines of :append, :change, :insert                     {{{1
+"-------------------------------------------------------------------------------
+
+function! DefineFunction(name, body)
+    let func = join(['function! ' . a:name . '()'] + a:body + ['endfunction'], "\n")
+    exec func
+endfunction
+
+func Test_script_lines()
+    " :append
+    try
+        call DefineFunction('T_Append', [
+                    \ 'append',
+                    \ 'py <<EOS',
+                    \ '.',
+                    \ ])
+    catch
+        call assert_report("Can't define function")
+    endtry
+    try
+        call DefineFunction('T_Append', [
+                    \ 'append',
+                    \ 'abc',
+                    \ ])
+        call assert_report("Shouldn't be able to define function")
+    catch
+        call assert_exception('Vim(function):E126: Missing :endfunction')
+    endtry
+
+    " :change
+    try
+        call DefineFunction('T_Change', [
+                    \ 'change',
+                    \ 'py <<EOS',
+                    \ '.',
+                    \ ])
+    catch
+        call assert_report("Can't define function")
+    endtry
+    try
+        call DefineFunction('T_Change', [
+                    \ 'change',
+                    \ 'abc',
+                    \ ])
+        call assert_report("Shouldn't be able to define function")
+    catch
+        call assert_exception('Vim(function):E126: Missing :endfunction')
+    endtry
+
+    " :insert
+    try
+        call DefineFunction('T_Insert', [
+                    \ 'insert',
+                    \ 'py <<EOS',
+                    \ '.',
+                    \ ])
+    catch
+        call assert_report("Can't define function")
+    endtry
+    try
+        call DefineFunction('T_Insert', [
+                    \ 'insert',
+                    \ 'abc',
+                    \ ])
+        call assert_report("Shouldn't be able to define function")
+    catch
+        call assert_exception('Vim(function):E126: Missing :endfunction')
+    endtry
+endfunc
+
+"-------------------------------------------------------------------------------
+" Test 96:  line continuation                                              {{{1
+"
+"           Undefined behavior was detected by ubsan with line continuation
+"           after an empty line.
+"-------------------------------------------------------------------------------
+func Test_script_emty_line_continuation()
+
+    \
+endfunc
+
+"-------------------------------------------------------------------------------
 " Modelines                                                                {{{1
 " vim: ts=8 sw=4 tw=80 fdm=marker
 " vim: fdt=substitute(substitute(foldtext(),\ '\\%(^+--\\)\\@<=\\(\\s*\\)\\(.\\{-}\\)\:\ \\%(\"\ \\)\\=\\(Test\ \\d*\\)\:\\s*',\ '\\3\ (\\2)\:\ \\1',\ \"\"),\ '\\(Test\\s*\\)\\(\\d\\)\\D\\@=',\ '\\1\ \\2',\ "")
index 240546b..371fab5 100644 (file)
@@ -1,13 +1,15 @@
-" Tests for Visual mode.  Uses double-wide character.
-if !has('multi_byte')
-  finish
-endif
-
+" Tests for various Visual mode.
 if !has('visual')
   finish
 endif
 
+set belloff=all
+
 func Test_block_shift_multibyte()
+  " Uses double-wide character.
+  if !has('multi_byte')
+    return
+  endif
   split
   call setline(1, ['xヹxxx', 'ヹxxx'])
   exe "normal 1G0l\<C-V>jl>"
@@ -15,3 +17,38 @@ func Test_block_shift_multibyte()
   call assert_equal('  ヹxxx', getline(2))
   q!
 endfunc
+
+func Test_dotregister_paste()
+  new
+  exe "norm! ihello world\<esc>"
+  norm! 0ve".p
+  call assert_equal('hello world world', getline(1))
+  q!
+endfunc
+
+func Test_Visual_ctrl_o()
+  new
+  call setline(1, ['one', 'two', 'three'])
+  call cursor(1,2)
+  set noshowmode
+  set tw=0
+  call feedkeys("\<c-v>jjlIa\<c-\>\<c-o>:set tw=88\<cr>\<esc>", 'tx')
+  call assert_equal(['oane', 'tawo', 'tahree'], getline(1, 3))
+  call assert_equal(88, &tw)
+  set tw&
+  bw!
+endfu
+
+func Test_Visual_vapo()
+  new
+  normal oxx
+  normal vapo
+  bwipe!
+endfunc
+
+func Test_Visual_inner_quote()
+  new
+  normal oxX
+  normal vki'
+  bwipe!
+endfunc
index 569a78a..f7d5317 100644 (file)
@@ -67,4 +67,309 @@ function Test_window_cmd_wincmd_gf()
   augroup! test_window_cmd_wincmd_gf
 endfunc
 
+func Test_window_quit()
+  e Xa
+  split Xb
+  call assert_equal(2, winnr('$'))
+  call assert_equal('Xb', bufname(winbufnr(1)))
+  call assert_equal('Xa', bufname(winbufnr(2)))
+
+  wincmd q
+  call assert_equal(1, winnr('$'))
+  call assert_equal('Xa', bufname(winbufnr(1)))
+
+  bw Xa Xb
+endfunc
+
+func Test_window_horizontal_split()
+  call assert_equal(1, winnr('$'))
+  3wincmd s
+  call assert_equal(2, winnr('$'))
+  call assert_equal(3, winheight(0))
+  call assert_equal(winwidth(1), winwidth(2))
+
+  call assert_fails('botright topleft wincmd s', 'E442:')
+  bw
+endfunc
+
+func Test_window_vertical_split()
+  call assert_equal(1, winnr('$'))
+  3wincmd v
+  call assert_equal(2, winnr('$'))
+  call assert_equal(3, winwidth(0))
+  call assert_equal(winheight(1), winheight(2))
+
+  call assert_fails('botright topleft wincmd v', 'E442:')
+  bw
+endfunc
+
+func Test_window_split_edit_alternate()
+  e Xa
+  e Xb
+
+  wincmd ^
+  call assert_equal('Xa', bufname(winbufnr(1)))
+  call assert_equal('Xb', bufname(winbufnr(2)))
+
+  bw Xa Xb
+endfunc
+
+func Test_window_preview()
+  " Open a preview window
+  pedit Xa
+  call assert_equal(2, winnr('$'))
+  call assert_equal(0, &previewwindow)
+
+  " Go to the preview window
+  wincmd P
+  call assert_equal(1, &previewwindow)
+
+  " Close preview window
+  wincmd z
+  call assert_equal(1, winnr('$'))
+  call assert_equal(0, &previewwindow)
+
+  call assert_fails('wincmd P', 'E441:')
+endfunc
+
+func Test_window_exchange()
+  e Xa
+
+  " Nothing happens with window exchange when there is 1 window
+  wincmd x
+  call assert_equal(1, winnr('$'))
+
+  split Xb
+  split Xc
+
+  call assert_equal('Xc', bufname(winbufnr(1)))
+  call assert_equal('Xb', bufname(winbufnr(2)))
+  call assert_equal('Xa', bufname(winbufnr(3)))
+
+  " Exchange current window 1 with window 3
+  3wincmd x
+  call assert_equal('Xa', bufname(winbufnr(1)))
+  call assert_equal('Xb', bufname(winbufnr(2)))
+  call assert_equal('Xc', bufname(winbufnr(3)))
+
+  " Exchange window with next when at the top window
+  wincmd x
+  call assert_equal('Xb', bufname(winbufnr(1)))
+  call assert_equal('Xa', bufname(winbufnr(2)))
+  call assert_equal('Xc', bufname(winbufnr(3)))
+
+  " Exchange window with next when at the middle window
+  wincmd j
+  wincmd x
+  call assert_equal('Xb', bufname(winbufnr(1)))
+  call assert_equal('Xc', bufname(winbufnr(2)))
+  call assert_equal('Xa', bufname(winbufnr(3)))
+
+  " Exchange window with next when at the bottom window.
+  " When there is no next window, it exchanges with the previous window.
+  wincmd j
+  wincmd x
+  call assert_equal('Xb', bufname(winbufnr(1)))
+  call assert_equal('Xa', bufname(winbufnr(2)))
+  call assert_equal('Xc', bufname(winbufnr(3)))
+
+  bw Xa Xb Xc
+endfunc
+
+func Test_window_rotate()
+  e Xa
+  split Xb
+  split Xc
+  call assert_equal('Xc', bufname(winbufnr(1)))
+  call assert_equal('Xb', bufname(winbufnr(2)))
+  call assert_equal('Xa', bufname(winbufnr(3)))
+
+  " Rotate downwards
+  wincmd r
+  call assert_equal('Xa', bufname(winbufnr(1)))
+  call assert_equal('Xc', bufname(winbufnr(2)))
+  call assert_equal('Xb', bufname(winbufnr(3)))
+
+  2wincmd r
+  call assert_equal('Xc', bufname(winbufnr(1)))
+  call assert_equal('Xb', bufname(winbufnr(2)))
+  call assert_equal('Xa', bufname(winbufnr(3)))
+
+  " Rotate upwards
+  wincmd R
+  call assert_equal('Xb', bufname(winbufnr(1)))
+  call assert_equal('Xa', bufname(winbufnr(2)))
+  call assert_equal('Xc', bufname(winbufnr(3)))
+
+  2wincmd R
+  call assert_equal('Xc', bufname(winbufnr(1)))
+  call assert_equal('Xb', bufname(winbufnr(2)))
+  call assert_equal('Xa', bufname(winbufnr(3)))
+
+  bot vsplit
+  call assert_fails('wincmd R', 'E443:')
+
+  bw Xa Xb Xc
+endfunc
+
+func Test_window_height()
+  e Xa
+  split Xb
+
+  let [wh1, wh2] = [winheight(1), winheight(2)]
+  " Active window (1) should have the same height or 1 more
+  " than the other window.
+  call assert_inrange(wh2, wh2 + 1, wh1)
+
+  wincmd -
+  call assert_equal(wh1 - 1, winheight(1))
+  call assert_equal(wh2 + 1, winheight(2))
+
+  wincmd +
+  call assert_equal(wh1, winheight(1))
+  call assert_equal(wh2, winheight(2))
+
+  2wincmd _
+  call assert_equal(2, winheight(1))
+  call assert_equal(wh1 + wh2 - 2, winheight(2))
+
+  wincmd =
+  call assert_equal(wh1, winheight(1))
+  call assert_equal(wh2, winheight(2))
+
+  2wincmd _
+  set winfixheight
+  split Xc
+  let [wh1, wh2, wh3] = [winheight(1), winheight(2), winheight(3)]
+  call assert_equal(2, winheight(2))
+  call assert_inrange(wh3, wh3 + 1, wh1)
+  3wincmd +
+  call assert_equal(2,       winheight(2))
+  call assert_equal(wh1 + 3, winheight(1))
+  call assert_equal(wh3 - 3, winheight(3))
+  wincmd =
+  call assert_equal(2,   winheight(2))
+  call assert_equal(wh1, winheight(1))
+  call assert_equal(wh3, winheight(3))
+
+  wincmd j
+  set winfixheight&
+
+  wincmd =
+  let [wh1, wh2, wh3] = [winheight(1), winheight(2), winheight(3)]
+  " Current window (2) should have the same height or 1 more
+  " than the other windows.
+  call assert_inrange(wh1, wh1 + 1, wh2)
+  call assert_inrange(wh3, wh3 + 1, wh2)
+
+  bw Xa Xb Xc
+endfunc
+
+func Test_window_width()
+  e Xa
+  vsplit Xb
+
+  let [ww1, ww2] = [winwidth(1), winwidth(2)]
+  " Active window (1) should have the same width or 1 more
+  " than the other window.
+  call assert_inrange(ww2, ww2 + 1, ww1)
+
+  wincmd <
+  call assert_equal(ww1 - 1, winwidth(1))
+  call assert_equal(ww2 + 1, winwidth(2))
+
+  wincmd >
+  call assert_equal(ww1, winwidth(1))
+  call assert_equal(ww2, winwidth(2))
+
+  2wincmd |
+  call assert_equal(2, winwidth(1))
+  call assert_equal(ww1 + ww2 - 2, winwidth(2))
+
+  wincmd =
+  call assert_equal(ww1, winwidth(1))
+  call assert_equal(ww2, winwidth(2))
+
+  2wincmd |
+  set winfixwidth
+  vsplit Xc
+  let [ww1, ww2, ww3] = [winwidth(1), winwidth(2), winwidth(3)]
+  call assert_equal(2, winwidth(2))
+  call assert_inrange(ww3, ww3 + 1, ww1)
+  3wincmd >
+  call assert_equal(2,       winwidth(2))
+  call assert_equal(ww1 + 3, winwidth(1))
+  call assert_equal(ww3 - 3, winwidth(3))
+  wincmd =
+  call assert_equal(2,   winwidth(2))
+  call assert_equal(ww1, winwidth(1))
+  call assert_equal(ww3, winwidth(3))
+
+  wincmd l
+  set winfixwidth&
+
+  wincmd =
+  let [ww1, ww2, ww3] = [winwidth(1), winwidth(2), winwidth(3)]
+  " Current window (2) should have the same width or 1 more
+  " than the other windows.
+  call assert_inrange(ww1, ww1 + 1, ww2)
+  call assert_inrange(ww3, ww3 + 1, ww2)
+
+  bw Xa Xb Xc
+endfunc
+
+func Test_window_jump_tag()
+  help
+  /iccf
+  call assert_match('^|iccf|',  getline('.'))
+  call assert_equal(2, winnr('$'))
+  2wincmd }
+  call assert_equal(3, winnr('$'))
+  call assert_match('^|iccf|',  getline('.'))
+  wincmd k
+  call assert_match('\*iccf\*',  getline('.'))
+  call assert_equal(2, winheight(0))
+
+  wincmd z
+  set previewheight=4
+  help
+  /bugs
+  wincmd }
+  wincmd k
+  call assert_match('\*bugs\*',  getline('.'))
+  call assert_equal(4, winheight(0))
+  set previewheight&
+
+  %bw!
+endfunc
+
+func Test_window_newtab()
+  e Xa
+
+  call assert_equal(1, tabpagenr('$'))
+  call assert_equal("\nAlready only one window", execute('wincmd T'))
+
+  split Xb
+  split Xc
+
+  wincmd T
+  call assert_equal(2, tabpagenr('$'))
+  call assert_equal(['Xb', 'Xa'], map(tabpagebuflist(1), 'bufname(v:val)'))
+  call assert_equal(['Xc'      ], map(tabpagebuflist(2), 'bufname(v:val)'))
+
+  %bw!
+endfunc
+
+func Test_next_split_all()
+  " This was causing an illegal memory access.
+  n x
+  norm axxx
+  split
+  split
+  s/x
+  s/x
+  all
+  bwipe!
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
index 66656e1..b3b506d 100644 (file)
@@ -92,3 +92,12 @@ func Test_win_getid()
 
   only!
 endfunc
+
+func Test_win_getid_curtab()
+  tabedit X
+  tabfirst
+  copen
+  only
+  call assert_equal(win_getid(1), win_getid(1, 1))
+  tabclose!
+endfunc
index 36dd4e1..b82c63c 100644 (file)
@@ -2,4 +2,12 @@
 " Always use "sh", don't use the value of "$SHELL".
 set shell=sh
 
+" Only when the +eval feature is present. 
+if 1
+  " While some tests overwrite $HOME to prevent them from polluting user files,
+  " we need to remember the original value so that we can tell external systems
+  " where to ask about their own user settings.
+  let g:tester_HOME = $HOME
+endif
+
 source setup.vim
diff --git a/src/testdir/view_util.vim b/src/testdir/view_util.vim
new file mode 100644 (file)
index 0000000..eb92630
--- /dev/null
@@ -0,0 +1,30 @@
+" Functions about view shared by several tests
+
+" ScreenLines(lnum, width) or
+" ScreenLines([start, end], width)
+function! ScreenLines(lnum, width) abort
+  redraw!
+  if type(a:lnum) == v:t_list
+    let start = a:lnum[0]
+    let end = a:lnum[1]
+  else
+    let start = a:lnum
+    let end = a:lnum
+  endif
+  let lines = []
+  for l in range(start, end)
+    let lines += [join(map(range(1, a:width), 'nr2char(screenchar(l, v:val))'), '')]
+  endfor
+  return lines
+endfunction
+
+function! NewWindow(height, width) abort
+  exe a:height . 'new'
+  exe a:width . 'vsp'
+  redraw!
+endfunction
+
+function! CloseWindow() abort
+  bw!
+  redraw!
+endfunction
index ad29190..8691ab7 100644 (file)
--- a/src/ui.c
+++ b/src/ui.c
@@ -363,12 +363,19 @@ ui_breakcheck(void)
     void
 ui_breakcheck_force(int force)
 {
+    int save_us = updating_screen;
+
+    /* We do not want gui_resize_shell() to redraw the screen here. */
+    ++updating_screen;
+
 #ifdef FEAT_GUI
     if (gui.in_use)
        gui_mch_update();
     else
 #endif
        mch_breakcheck(force);
+
+    updating_screen = save_us;
 }
 
 /*****************************************************************************
@@ -385,8 +392,6 @@ ui_breakcheck_force(int force)
 
 #if defined(FEAT_CLIPBOARD) || defined(PROTO)
 
-static void clip_copy_selection(VimClipboard *clip);
-
 /*
  * Selection stuff using Visual mode, for cutting and pasting text to other
  * windows.
@@ -435,7 +440,7 @@ clip_update_selection(VimClipboard *clip)
     /* If visual mode is only due to a redo command ("."), then ignore it */
     if (!redo_VIsual_busy && VIsual_active && (State & NORMAL))
     {
-       if (lt(VIsual, curwin->w_cursor))
+       if (LT_POS(VIsual, curwin->w_cursor))
        {
            start = VIsual;
            end = curwin->w_cursor;
@@ -449,8 +454,8 @@ clip_update_selection(VimClipboard *clip)
            start = curwin->w_cursor;
            end = VIsual;
        }
-       if (!equalpos(clip->start, start)
-               || !equalpos(clip->end, end)
+       if (!EQUAL_POS(clip->start, start)
+               || !EQUAL_POS(clip->end, end)
                || clip->vmode != VIsual_mode)
        {
            clip_clear_selection(clip);
@@ -489,7 +494,7 @@ clip_own_selection(VimClipboard *cbd)
                                            || get_real_state() == SELECTMODE)
                    && (cbd == &clip_star ? clip_isautosel_star()
                                                      : clip_isautosel_plus())
-                   && hl_attr(HLF_V) != hl_attr(HLF_VNC))
+                   && HL_ATTR(HLF_V) != HL_ATTR(HLF_VNC))
                redraw_curbuf_later(INVERTED_ALL);
        }
     }
@@ -527,7 +532,7 @@ clip_lose_selection(VimClipboard *cbd)
                                            || get_real_state() == SELECTMODE)
                && (cbd == &clip_star ?
                                clip_isautosel_star() : clip_isautosel_plus())
-               && hl_attr(HLF_V) != hl_attr(HLF_VNC))
+               && HL_ATTR(HLF_V) != HL_ATTR(HLF_VNC))
        {
            update_curbuf(INVERTED_ALL);
            setcursor();
@@ -562,7 +567,8 @@ clip_copy_selection(VimClipboard *clip)
  * considerably.
  */
 static int global_change_count = 0; /* if set, inside a start_global_changes */
-static int clipboard_needs_update; /* clipboard needs to be updated */
+static int clipboard_needs_update = FALSE; /* clipboard needs to be updated */
+static int clip_did_set_selection = TRUE;
 
 /*
  * Save clip_unnamed and reset it.
@@ -583,6 +589,16 @@ start_global_changes(void)
 }
 
 /*
+ * Return TRUE if setting the clipboard was postponed, it already contains the
+ * right text.
+ */
+    int
+is_clipboard_needs_update()
+{
+    return clipboard_needs_update;
+}
+
+/*
  * Restore clip_unnamed and set the selection when needed.
  */
     void
@@ -612,6 +628,7 @@ end_global_changes(void)
            }
        }
     }
+    clipboard_needs_update = FALSE;
 }
 
 /*
@@ -3185,7 +3202,7 @@ vcol2col(win_T *wp, linenr_T lnum, int vcol)
     while (count < vcol && *ptr != NUL)
     {
        count += win_lbr_chartabsize(wp, line, ptr, count, NULL);
-       mb_ptr_adv(ptr);
+       MB_PTR_ADV(ptr);
     }
     return (int)(ptr - line);
 }
index cc74edd..82c66b6 100644 (file)
@@ -833,7 +833,7 @@ u_get_undo_file_name(char_u *buf_ffname, int reading)
                    munged_name = vim_strsave(ffname);
                    if (munged_name == NULL)
                        return NULL;
-                   for (p = munged_name; *p != NUL; mb_ptr_adv(p))
+                   for (p = munged_name; *p != NUL; MB_PTR_ADV(p))
                        if (vim_ispathsep(*p))
                            *p = '%';
                }
@@ -1385,7 +1385,7 @@ unserialize_uep(bufinfo_T *bi, int *error, char_u *file_name)
 {
     int                i;
     u_entry_T  *uep;
-    char_u     **array;
+    char_u     **array = NULL;
     char_u     *line;
     int                line_len;
 
@@ -1402,7 +1402,8 @@ unserialize_uep(bufinfo_T *bi, int *error, char_u *file_name)
     uep->ue_size = undo_read_4c(bi);
     if (uep->ue_size > 0)
     {
-       array = (char_u **)U_ALLOC_LINE(sizeof(char_u *) * uep->ue_size);
+       if (uep->ue_size < LONG_MAX / (int)sizeof(char_u *))
+           array = (char_u **)U_ALLOC_LINE(sizeof(char_u *) * uep->ue_size);
        if (array == NULL)
        {
            *error = TRUE;
@@ -1410,8 +1411,6 @@ unserialize_uep(bufinfo_T *bi, int *error, char_u *file_name)
        }
        vim_memset(array, 0, sizeof(char_u *) * uep->ue_size);
     }
-    else
-       array = NULL;
     uep->ue_array = array;
 
     for (i = 0; i < uep->ue_size; ++i)
@@ -1787,7 +1786,7 @@ u_read_undo(char_u *name, char_u *hash, char_u *orig_name)
     linenr_T   line_lnum;
     colnr_T    line_colnr;
     linenr_T   line_count;
-    int                num_head = 0;
+    long       num_head = 0;
     long       old_header_seq, new_header_seq, cur_header_seq;
     long       seq_last, seq_cur;
     long       last_save_nr = 0;
@@ -1974,7 +1973,8 @@ u_read_undo(char_u *name, char_u *hash, char_u *orig_name)
      * When there are no headers uhp_table is NULL. */
     if (num_head > 0)
     {
-       uhp_table = (u_header_T **)U_ALLOC_LINE(
+       if (num_head < LONG_MAX / (long)sizeof(u_header_T *))
+           uhp_table = (u_header_T **)U_ALLOC_LINE(
                                             num_head * sizeof(u_header_T *));
        if (uhp_table == NULL)
            goto error;
@@ -2298,10 +2298,8 @@ undo_time(
     }
     else
     {
-       /* When doing computations with time_t subtract starttime, because
-        * time_t converted to a long may result in a wrong number. */
        if (dosec)
-           target = (long)(curbuf->b_u_time_cur - starttime) + step;
+           target = (long)(curbuf->b_u_time_cur) + step;
        else if (dofile)
        {
            if (step < 0)
@@ -2350,7 +2348,7 @@ undo_time(
        else
        {
            if (dosec)
-               closest = (long)(vim_time() - starttime + 1);
+               closest = (long)(vim_time() + 1);
            else if (dofile)
                closest = curbuf->b_u_save_nr_last + 2;
            else
@@ -2388,7 +2386,7 @@ undo_time(
        {
            uhp->uh_walk = mark;
            if (dosec)
-               val = (long)(uhp->uh_time - starttime);
+               val = (long)(uhp->uh_time);
            else if (dofile)
                val = uhp->uh_save_nr;
            else
@@ -2582,7 +2580,7 @@ undo_time(
            if (uhp == NULL || uhp->uh_walk != mark)
            {
                /* Need to redo more but can't find it... */
-               EMSG2(_(e_intern2), "undo_time()");
+               internal_error("undo_time()");
                break;
            }
        }
@@ -2654,7 +2652,7 @@ u_undoredo(int undo)
 #ifdef FEAT_AUTOCMD
            unblock_autocmds();
 #endif
-           EMSG(_("E438: u_undo: line numbers wrong"));
+           IEMSG(_("E438: u_undo: line numbers wrong"));
            changed();          /* don't want UNCHANGED now */
            return;
        }
@@ -2786,7 +2784,7 @@ u_undoredo(int undo)
 
     curhead->uh_entry = newlist;
     curhead->uh_flags = new_flags;
-    if ((old_flags & UH_EMPTYBUF) && bufempty())
+    if ((old_flags & UH_EMPTYBUF) && BUFEMPTY())
        curbuf->b_ml.ml_flags |= ML_EMPTY;
     if (old_flags & UH_CHANGED)
        changed();
@@ -3081,7 +3079,7 @@ ex_undolist(exarg_T *eap UNUSED)
 
        msg_start();
        msg_puts_attr((char_u *)_("number changes  when               saved"),
-                                                             hl_attr(HLF_T));
+                                                             HL_ATTR(HLF_T));
        for (i = 0; i < ga.ga_len && !got_int; ++i)
        {
            msg_putchar('\n');
@@ -3138,11 +3136,8 @@ ex_undojoin(exarg_T *eap UNUSED)
     if (get_undolevel() < 0)
        return;             /* no entries, nothing to do */
     else
-    {
-       /* Go back to the last entry */
-       curbuf->b_u_curhead = curbuf->b_u_newhead;
-       curbuf->b_u_synced = FALSE;  /* no entries, nothing to do */
-    }
+       /* Append next change to the last entry */
+       curbuf->b_u_synced = FALSE;
 }
 
 /*
@@ -3180,14 +3175,14 @@ u_find_first_changed(void)
        if (STRCMP(ml_get_buf(curbuf, lnum, FALSE),
                                                uep->ue_array[lnum - 1]) != 0)
        {
-           clearpos(&(uhp->uh_cursor));
+           CLEAR_POS(&(uhp->uh_cursor));
            uhp->uh_cursor.lnum = lnum;
            return;
        }
     if (curbuf->b_ml.ml_line_count != uep->ue_size)
     {
        /* lines added or deleted at the end, put the cursor there */
-       clearpos(&(uhp->uh_cursor));
+       CLEAR_POS(&(uhp->uh_cursor));
        uhp->uh_cursor.lnum = lnum;
     }
 }
@@ -3234,7 +3229,7 @@ u_get_headentry(void)
 {
     if (curbuf->b_u_newhead == NULL || curbuf->b_u_newhead->uh_entry == NULL)
     {
-       EMSG(_("E439: undo list corrupt"));
+       IEMSG(_("E439: undo list corrupt"));
        return NULL;
     }
     return curbuf->b_u_newhead->uh_entry;
@@ -3266,7 +3261,7 @@ u_getbot(void)
        uep->ue_bot = uep->ue_top + uep->ue_size + 1 + extra;
        if (uep->ue_bot < 1 || uep->ue_bot > curbuf->b_ml.ml_line_count)
        {
-           EMSG(_("E440: undo line missing"));
+           IEMSG(_("E440: undo line missing"));
            uep->ue_bot = uep->ue_top + 1;  /* assume all lines deleted, will
                                             * get all the old lines back
                                             * without deleting the current
index c75ccbc..859e6eb 100644 (file)
@@ -41,7 +41,7 @@ static garray_T funcargs = GA_EMPTY;
 /* pointer to funccal for currently active function */
 funccall_T *current_funccal = NULL;
 
-/* pointer to list of previously used funccal, still around because some
+/* Pointer to list of previously used funccal, still around because some
  * item in it is still being used. */
 funccall_T *previous_funccal = NULL;
 
@@ -628,6 +628,55 @@ free_funccal(
 }
 
 /*
+ * Handle the last part of returning from a function: free the local hashtable.
+ * Unless it is still in use by a closure.
+ */
+    static void
+cleanup_function_call(funccall_T *fc)
+{
+    current_funccal = fc->caller;
+
+    /* If the a:000 list and the l: and a: dicts are not referenced and there
+     * is no closure using it, we can free the funccall_T and what's in it. */
+    if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT
+           && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT
+           && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT
+           && fc->fc_refcount <= 0)
+    {
+       free_funccal(fc, FALSE);
+    }
+    else
+    {
+       hashitem_T      *hi;
+       listitem_T      *li;
+       int             todo;
+       dictitem_T      *v;
+
+       /* "fc" is still in use.  This can happen when returning "a:000",
+        * assigning "l:" to a global variable or defining a closure.
+        * Link "fc" in the list for garbage collection later. */
+       fc->caller = previous_funccal;
+       previous_funccal = fc;
+
+       /* Make a copy of the a: variables, since we didn't do that above. */
+       todo = (int)fc->l_avars.dv_hashtab.ht_used;
+       for (hi = fc->l_avars.dv_hashtab.ht_array; todo > 0; ++hi)
+       {
+           if (!HASHITEM_EMPTY(hi))
+           {
+               --todo;
+               v = HI2DI(hi);
+               copy_tv(&v->di_tv, &v->di_tv);
+           }
+       }
+
+       /* Make a copy of the a:000 items, since we didn't do that above. */
+       for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next)
+           copy_tv(&li->li_tv, &li->li_tv);
+    }
+}
+
+/*
  * Call a user function.
  */
     static void
@@ -982,46 +1031,9 @@ call_user_func(
     }
 
     did_emsg |= save_did_emsg;
-    current_funccal = fc->caller;
     --depth;
 
-    /* If the a:000 list and the l: and a: dicts are not referenced and there
-     * is no closure using it, we can free the funccall_T and what's in it. */
-    if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT
-           && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT
-           && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT
-           && fc->fc_refcount <= 0)
-    {
-       free_funccal(fc, FALSE);
-    }
-    else
-    {
-       hashitem_T      *hi;
-       listitem_T      *li;
-       int             todo;
-
-       /* "fc" is still in use.  This can happen when returning "a:000",
-        * assigning "l:" to a global variable or defining a closure.
-        * Link "fc" in the list for garbage collection later. */
-       fc->caller = previous_funccal;
-       previous_funccal = fc;
-
-       /* Make a copy of the a: variables, since we didn't do that above. */
-       todo = (int)fc->l_avars.dv_hashtab.ht_used;
-       for (hi = fc->l_avars.dv_hashtab.ht_array; todo > 0; ++hi)
-       {
-           if (!HASHITEM_EMPTY(hi))
-           {
-               --todo;
-               v = HI2DI(hi);
-               copy_tv(&v->di_tv, &v->di_tv);
-           }
-       }
-
-       /* Make a copy of the a:000 items, since we didn't do that above. */
-       for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next)
-           copy_tv(&li->li_tv, &li->li_tv);
-    }
+    cleanup_function_call(fc);
 }
 
 /*
@@ -1075,12 +1087,17 @@ func_remove(ufunc_T *fp)
 }
 
 /*
- * Free a function and remove it from the list of functions.
+ * Free all things that a function contains.  Does not free the function
+ * itself, use func_free() for that.
  * When "force" is TRUE we are exiting.
  */
     static void
-func_free(ufunc_T *fp, int force)
+func_clear(ufunc_T *fp, int force)
 {
+    if (fp->uf_cleared)
+       return;
+    fp->uf_cleared = TRUE;
+
     /* clear this function */
     ga_clear_strings(&(fp->uf_args));
     ga_clear_strings(&(fp->uf_lines));
@@ -1089,17 +1106,36 @@ func_free(ufunc_T *fp, int force)
     vim_free(fp->uf_tml_total);
     vim_free(fp->uf_tml_self);
 #endif
+    funccal_unref(fp->uf_scoped, fp, force);
+}
+
+/*
+ * Free a function and remove it from the list of functions.  Does not free
+ * what a function contains, call func_clear() first.
+ */
+    static void
+func_free(ufunc_T *fp)
+{
     /* only remove it when not done already, otherwise we would remove a newer
      * version of the function */
     if ((fp->uf_flags & (FC_DELETED | FC_REMOVED)) == 0)
        func_remove(fp);
 
-    funccal_unref(fp->uf_scoped, fp, force);
-
     vim_free(fp);
 }
 
 /*
+ * Free all things that a function contains and free the function itself.
+ * When "force" is TRUE we are exiting.
+ */
+    static void
+func_clear_free(ufunc_T *fp, int force)
+{
+    func_clear(fp, force);
+    func_free(fp);
+}
+
+/*
  * There are two kinds of function names:
  * 1. ordinary names, function defined with :function
  * 2. numbered functions and lambdas
@@ -1120,10 +1156,47 @@ free_all_functions(void)
     hashitem_T *hi;
     ufunc_T    *fp;
     long_u     skipped = 0;
-    long_u     todo;
+    long_u     todo = 1;
+    long_u     used;
+
+    /* Clean up the call stack. */
+    while (current_funccal != NULL)
+    {
+       clear_tv(current_funccal->rettv);
+       cleanup_function_call(current_funccal);
+    }
+
+    /* First clear what the functions contain.  Since this may lower the
+     * reference count of a function, it may also free a function and change
+     * the hash table. Restart if that happens. */
+    while (todo > 0)
+    {
+       todo = func_hashtab.ht_used;
+       for (hi = func_hashtab.ht_array; todo > 0; ++hi)
+           if (!HASHITEM_EMPTY(hi))
+           {
+               /* Only free functions that are not refcounted, those are
+                * supposed to be freed when no longer referenced. */
+               fp = HI2UF(hi);
+               if (func_name_refcount(fp->uf_name))
+                   ++skipped;
+               else
+               {
+                   used = func_hashtab.ht_used;
+                   func_clear(fp, TRUE);
+                   if (used != func_hashtab.ht_used)
+                   {
+                       skipped = 0;
+                       break;
+                   }
+               }
+               --todo;
+           }
+    }
 
-    /* Need to start all over every time, because func_free() may change the
-     * hash table. */
+    /* Now actually free the functions.  Need to start all over every time,
+     * because func_free() may change the hash table. */
+    skipped = 0;
     while (func_hashtab.ht_used > skipped)
     {
        todo = func_hashtab.ht_used;
@@ -1138,7 +1211,7 @@ free_all_functions(void)
                    ++skipped;
                else
                {
-                   func_free(fp, TRUE);
+                   func_free(fp);
                    skipped = 0;
                    break;
                }
@@ -1335,6 +1408,7 @@ call_func(
                else
                {
                    int did_save_redo = FALSE;
+                   save_redo_T save_redo;
 
                    /*
                     * Call the user function.
@@ -1346,7 +1420,7 @@ call_func(
                    if (!ins_compl_active())
 #endif
                    {
-                       saveRedobuff();
+                       saveRedobuff(&save_redo);
                        did_save_redo = TRUE;
                    }
                    ++fp->uf_calls;
@@ -1356,9 +1430,9 @@ call_func(
                    if (--fp->uf_calls <= 0 && fp->uf_refcount <= 0)
                        /* Function was unreferenced while being used, free it
                         * now. */
-                       func_free(fp, FALSE);
+                       func_clear_free(fp, FALSE);
                    if (did_save_redo)
-                       restoreRedobuff();
+                       restoreRedobuff(&save_redo);
                    restore_search_patterns();
                    error = ERROR_NONE;
                }
@@ -1440,7 +1514,7 @@ list_func_head(ufunc_T *fp, int indent)
     MSG_PUTS("function ");
     if (fp->uf_name[0] == K_SPECIAL)
     {
-       MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8));
+       MSG_PUTS_ATTR("<SNR>", HL_ATTR(HLF_8));
        msg_puts(fp->uf_name + 3);
     }
     else
@@ -2050,7 +2124,7 @@ ex_function(exarg_T *eap)
        else
        {
            /* skip ':' and blanks*/
-           for (p = theline; vim_iswhite(*p) || *p == ':'; ++p)
+           for (p = theline; VIM_ISWHITE(*p) || *p == ':'; ++p)
                ;
 
            /* Check for "endfunction". */
@@ -2085,9 +2159,14 @@ ex_function(exarg_T *eap)
                }
            }
 
-           /* Check for ":append" or ":insert". */
+           /* Check for ":append", ":change", ":insert". */
            p = skip_range(p, NULL);
            if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p'))
+                   || (p[0] == 'c'
+                       && (!ASCII_ISALPHA(p[1]) || (p[1] == 'h'
+                               && (!ASCII_ISALPHA(p[2]) || (p[2] == 'a'
+                                       && (STRNCMP(&p[3], "nge", 3) != 0
+                                           || !ASCII_ISALPHA(p[6])))))))
                    || (p[0] == 'i'
                        && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n'
                                && (!ASCII_ISALPHA(p[2]) || (p[2] == 's'))))))
@@ -2097,7 +2176,9 @@ ex_function(exarg_T *eap)
            arg = skipwhite(skiptowhite(p));
            if (arg[0] == '<' && arg[1] =='<'
                    && ((p[0] == 'p' && p[1] == 'y'
-                                   && (!ASCII_ISALPHA(p[2]) || p[2] == 't'))
+                                   && (!ASCII_ISALNUM(p[2]) || p[2] == 't'
+                                       || ((p[2] == '3' || p[2] == 'x')
+                                                  && !ASCII_ISALPHA(p[3]))))
                        || (p[0] == 'p' && p[1] == 'e'
                                    && (!ASCII_ISALPHA(p[2]) || p[2] == 'r'))
                        || (p[0] == 't' && p[1] == 'c'
@@ -2749,7 +2830,7 @@ ex_delfunction(exarg_T *eap)
                fp->uf_flags |= FC_DELETED;
            }
            else
-               func_free(fp, FALSE);
+               func_clear_free(fp, FALSE);
        }
     }
 }
@@ -2771,14 +2852,14 @@ func_unref(char_u *name)
 #ifdef EXITFREE
        if (!entered_free_all_mem)
 #endif
-           EMSG2(_(e_intern2), "func_unref()");
+           internal_error("func_unref()");
     }
     if (fp != NULL && --fp->uf_refcount <= 0)
     {
        /* Only delete it when it's not being used.  Otherwise it's done
         * when "uf_calls" becomes zero. */
        if (fp->uf_calls == 0)
-           func_free(fp, FALSE);
+           func_clear_free(fp, FALSE);
     }
 }
 
@@ -2794,7 +2875,7 @@ func_ptr_unref(ufunc_T *fp)
        /* Only delete it when it's not being used.  Otherwise it's done
         * when "uf_calls" becomes zero. */
        if (fp->uf_calls == 0)
-           func_free(fp, FALSE);
+           func_clear_free(fp, FALSE);
     }
 }
 
@@ -2814,7 +2895,7 @@ func_ref(char_u *name)
     else if (isdigit(*name))
        /* Only give an error for a numbered function.
         * Fail silently, when named or lambda function isn't found. */
-       EMSG2(_(e_intern2), "func_ref()");
+       internal_error("func_ref()");
 }
 
 /*
@@ -3549,7 +3630,7 @@ get_funccal_args_var()
 {
     if (current_funccal == NULL)
        return NULL;
-    return &current_funccal->l_avars_var;
+    return &get_funccal()->l_avars_var;
 }
 
 /*
index c698e44..3e683e8 100644 (file)
@@ -765,6 +765,1040 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    586,
+/**/
+    585,
+/**/
+    584,
+/**/
+    583,
+/**/
+    582,
+/**/
+    581,
+/**/
+    580,
+/**/
+    579,
+/**/
+    578,
+/**/
+    577,
+/**/
+    576,
+/**/
+    575,
+/**/
+    574,
+/**/
+    573,
+/**/
+    572,
+/**/
+    571,
+/**/
+    570,
+/**/
+    569,
+/**/
+    568,
+/**/
+    567,
+/**/
+    566,
+/**/
+    565,
+/**/
+    564,
+/**/
+    563,
+/**/
+    562,
+/**/
+    561,
+/**/
+    560,
+/**/
+    559,
+/**/
+    558,
+/**/
+    557,
+/**/
+    556,
+/**/
+    555,
+/**/
+    554,
+/**/
+    553,
+/**/
+    552,
+/**/
+    551,
+/**/
+    550,
+/**/
+    549,
+/**/
+    548,
+/**/
+    547,
+/**/
+    546,
+/**/
+    545,
+/**/
+    544,
+/**/
+    543,
+/**/
+    542,
+/**/
+    541,
+/**/
+    540,
+/**/
+    539,
+/**/
+    538,
+/**/
+    537,
+/**/
+    536,
+/**/
+    535,
+/**/
+    534,
+/**/
+    533,
+/**/
+    532,
+/**/
+    531,
+/**/
+    530,
+/**/
+    529,
+/**/
+    528,
+/**/
+    527,
+/**/
+    526,
+/**/
+    525,
+/**/
+    524,
+/**/
+    523,
+/**/
+    522,
+/**/
+    521,
+/**/
+    520,
+/**/
+    519,
+/**/
+    518,
+/**/
+    517,
+/**/
+    516,
+/**/
+    515,
+/**/
+    514,
+/**/
+    513,
+/**/
+    512,
+/**/
+    511,
+/**/
+    510,
+/**/
+    509,
+/**/
+    508,
+/**/
+    507,
+/**/
+    506,
+/**/
+    505,
+/**/
+    504,
+/**/
+    503,
+/**/
+    502,
+/**/
+    501,
+/**/
+    500,
+/**/
+    499,
+/**/
+    498,
+/**/
+    497,
+/**/
+    496,
+/**/
+    495,
+/**/
+    494,
+/**/
+    493,
+/**/
+    492,
+/**/
+    491,
+/**/
+    490,
+/**/
+    489,
+/**/
+    488,
+/**/
+    487,
+/**/
+    486,
+/**/
+    485,
+/**/
+    484,
+/**/
+    483,
+/**/
+    482,
+/**/
+    481,
+/**/
+    480,
+/**/
+    479,
+/**/
+    478,
+/**/
+    477,
+/**/
+    476,
+/**/
+    475,
+/**/
+    474,
+/**/
+    473,
+/**/
+    472,
+/**/
+    471,
+/**/
+    470,
+/**/
+    469,
+/**/
+    468,
+/**/
+    467,
+/**/
+    466,
+/**/
+    465,
+/**/
+    464,
+/**/
+    463,
+/**/
+    462,
+/**/
+    461,
+/**/
+    460,
+/**/
+    459,
+/**/
+    458,
+/**/
+    457,
+/**/
+    456,
+/**/
+    455,
+/**/
+    454,
+/**/
+    453,
+/**/
+    452,
+/**/
+    451,
+/**/
+    450,
+/**/
+    449,
+/**/
+    448,
+/**/
+    447,
+/**/
+    446,
+/**/
+    445,
+/**/
+    444,
+/**/
+    443,
+/**/
+    442,
+/**/
+    441,
+/**/
+    440,
+/**/
+    439,
+/**/
+    438,
+/**/
+    437,
+/**/
+    436,
+/**/
+    435,
+/**/
+    434,
+/**/
+    433,
+/**/
+    432,
+/**/
+    431,
+/**/
+    430,
+/**/
+    429,
+/**/
+    428,
+/**/
+    427,
+/**/
+    426,
+/**/
+    425,
+/**/
+    424,
+/**/
+    423,
+/**/
+    422,
+/**/
+    421,
+/**/
+    420,
+/**/
+    419,
+/**/
+    418,
+/**/
+    417,
+/**/
+    416,
+/**/
+    415,
+/**/
+    414,
+/**/
+    413,
+/**/
+    412,
+/**/
+    411,
+/**/
+    410,
+/**/
+    409,
+/**/
+    408,
+/**/
+    407,
+/**/
+    406,
+/**/
+    405,
+/**/
+    404,
+/**/
+    403,
+/**/
+    402,
+/**/
+    401,
+/**/
+    400,
+/**/
+    399,
+/**/
+    398,
+/**/
+    397,
+/**/
+    396,
+/**/
+    395,
+/**/
+    394,
+/**/
+    393,
+/**/
+    392,
+/**/
+    391,
+/**/
+    390,
+/**/
+    389,
+/**/
+    388,
+/**/
+    387,
+/**/
+    386,
+/**/
+    385,
+/**/
+    384,
+/**/
+    383,
+/**/
+    382,
+/**/
+    381,
+/**/
+    380,
+/**/
+    379,
+/**/
+    378,
+/**/
+    377,
+/**/
+    376,
+/**/
+    375,
+/**/
+    374,
+/**/
+    373,
+/**/
+    372,
+/**/
+    371,
+/**/
+    370,
+/**/
+    369,
+/**/
+    368,
+/**/
+    367,
+/**/
+    366,
+/**/
+    365,
+/**/
+    364,
+/**/
+    363,
+/**/
+    362,
+/**/
+    361,
+/**/
+    360,
+/**/
+    359,
+/**/
+    358,
+/**/
+    357,
+/**/
+    356,
+/**/
+    355,
+/**/
+    354,
+/**/
+    353,
+/**/
+    352,
+/**/
+    351,
+/**/
+    350,
+/**/
+    349,
+/**/
+    348,
+/**/
+    347,
+/**/
+    346,
+/**/
+    345,
+/**/
+    344,
+/**/
+    343,
+/**/
+    342,
+/**/
+    341,
+/**/
+    340,
+/**/
+    339,
+/**/
+    338,
+/**/
+    337,
+/**/
+    336,
+/**/
+    335,
+/**/
+    334,
+/**/
+    333,
+/**/
+    332,
+/**/
+    331,
+/**/
+    330,
+/**/
+    329,
+/**/
+    328,
+/**/
+    327,
+/**/
+    326,
+/**/
+    325,
+/**/
+    324,
+/**/
+    323,
+/**/
+    322,
+/**/
+    321,
+/**/
+    320,
+/**/
+    319,
+/**/
+    318,
+/**/
+    317,
+/**/
+    316,
+/**/
+    315,
+/**/
+    314,
+/**/
+    313,
+/**/
+    312,
+/**/
+    311,
+/**/
+    310,
+/**/
+    309,
+/**/
+    308,
+/**/
+    307,
+/**/
+    306,
+/**/
+    305,
+/**/
+    304,
+/**/
+    303,
+/**/
+    302,
+/**/
+    301,
+/**/
+    300,
+/**/
+    299,
+/**/
+    298,
+/**/
+    297,
+/**/
+    296,
+/**/
+    295,
+/**/
+    294,
+/**/
+    293,
+/**/
+    292,
+/**/
+    291,
+/**/
+    290,
+/**/
+    289,
+/**/
+    288,
+/**/
+    287,
+/**/
+    286,
+/**/
+    285,
+/**/
+    284,
+/**/
+    283,
+/**/
+    282,
+/**/
+    281,
+/**/
+    280,
+/**/
+    279,
+/**/
+    278,
+/**/
+    277,
+/**/
+    276,
+/**/
+    275,
+/**/
+    274,
+/**/
+    273,
+/**/
+    272,
+/**/
+    271,
+/**/
+    270,
+/**/
+    269,
+/**/
+    268,
+/**/
+    267,
+/**/
+    266,
+/**/
+    265,
+/**/
+    264,
+/**/
+    263,
+/**/
+    262,
+/**/
+    261,
+/**/
+    260,
+/**/
+    259,
+/**/
+    258,
+/**/
+    257,
+/**/
+    256,
+/**/
+    255,
+/**/
+    254,
+/**/
+    253,
+/**/
+    252,
+/**/
+    251,
+/**/
+    250,
+/**/
+    249,
+/**/
+    248,
+/**/
+    247,
+/**/
+    246,
+/**/
+    245,
+/**/
+    244,
+/**/
+    243,
+/**/
+    242,
+/**/
+    241,
+/**/
+    240,
+/**/
+    239,
+/**/
+    238,
+/**/
+    237,
+/**/
+    236,
+/**/
+    235,
+/**/
+    234,
+/**/
+    233,
+/**/
+    232,
+/**/
+    231,
+/**/
+    230,
+/**/
+    229,
+/**/
+    228,
+/**/
+    227,
+/**/
+    226,
+/**/
+    225,
+/**/
+    224,
+/**/
+    223,
+/**/
+    222,
+/**/
+    221,
+/**/
+    220,
+/**/
+    219,
+/**/
+    218,
+/**/
+    217,
+/**/
+    216,
+/**/
+    215,
+/**/
+    214,
+/**/
+    213,
+/**/
+    212,
+/**/
+    211,
+/**/
+    210,
+/**/
+    209,
+/**/
+    208,
+/**/
+    207,
+/**/
+    206,
+/**/
+    205,
+/**/
+    204,
+/**/
+    203,
+/**/
+    202,
+/**/
+    201,
+/**/
+    200,
+/**/
+    199,
+/**/
+    198,
+/**/
+    197,
+/**/
+    196,
+/**/
+    195,
+/**/
+    194,
+/**/
+    193,
+/**/
+    192,
+/**/
+    191,
+/**/
+    190,
+/**/
+    189,
+/**/
+    188,
+/**/
+    187,
+/**/
+    186,
+/**/
+    185,
+/**/
+    184,
+/**/
+    183,
+/**/
+    182,
+/**/
+    181,
+/**/
+    180,
+/**/
+    179,
+/**/
+    178,
+/**/
+    177,
+/**/
+    176,
+/**/
+    175,
+/**/
+    174,
+/**/
+    173,
+/**/
+    172,
+/**/
+    171,
+/**/
+    170,
+/**/
+    169,
+/**/
+    168,
+/**/
+    167,
+/**/
+    166,
+/**/
+    165,
+/**/
+    164,
+/**/
+    163,
+/**/
+    162,
+/**/
+    161,
+/**/
+    160,
+/**/
+    159,
+/**/
+    158,
+/**/
+    157,
+/**/
+    156,
+/**/
+    155,
+/**/
+    154,
+/**/
+    153,
+/**/
+    152,
+/**/
+    151,
+/**/
+    150,
+/**/
+    149,
+/**/
+    148,
+/**/
+    147,
+/**/
+    146,
+/**/
+    145,
+/**/
+    144,
+/**/
+    143,
+/**/
+    142,
+/**/
+    141,
+/**/
+    140,
+/**/
+    139,
+/**/
+    138,
+/**/
+    137,
+/**/
+    136,
+/**/
+    135,
+/**/
+    134,
+/**/
+    133,
+/**/
+    132,
+/**/
+    131,
+/**/
+    130,
+/**/
+    129,
+/**/
+    128,
+/**/
+    127,
+/**/
+    126,
+/**/
+    125,
+/**/
+    124,
+/**/
+    123,
+/**/
+    122,
+/**/
+    121,
+/**/
+    120,
+/**/
+    119,
+/**/
+    118,
+/**/
+    117,
+/**/
+    116,
+/**/
+    115,
+/**/
+    114,
+/**/
+    113,
+/**/
+    112,
+/**/
+    111,
+/**/
+    110,
+/**/
+    109,
+/**/
+    108,
+/**/
+    107,
+/**/
+    106,
+/**/
+    105,
+/**/
+    104,
+/**/
+    103,
+/**/
+    102,
+/**/
+    101,
+/**/
+    100,
+/**/
+    99,
+/**/
+    98,
+/**/
+    97,
+/**/
+    96,
+/**/
+    95,
+/**/
+    94,
+/**/
+    93,
+/**/
+    92,
+/**/
+    91,
+/**/
+    90,
+/**/
+    89,
+/**/
+    88,
+/**/
+    87,
+/**/
+    86,
+/**/
+    85,
+/**/
+    84,
+/**/
+    83,
+/**/
+    82,
+/**/
+    81,
+/**/
+    80,
+/**/
+    79,
+/**/
+    78,
+/**/
+    77,
+/**/
+    76,
+/**/
+    75,
+/**/
+    74,
+/**/
+    73,
+/**/
+    72,
+/**/
+    71,
+/**/
+    70,
+/**/
     69,
 /**/
     68,
@@ -1333,7 +2367,7 @@ static void do_intro_line(int row, char_u *mesg, int add_version, int attr);
     void
 maybe_intro_message(void)
 {
-    if (bufempty()
+    if (BUFEMPTY()
            && curbuf->b_fname == NULL
 #ifdef FEAT_WINDOWS
            && firstwin->w_next == NULL
@@ -1529,7 +2563,7 @@ do_intro_line(
 #endif
                clen += byte2cells(p[l]);
        }
-       screen_puts_len(p, l, row, col, *p == '<' ? hl_attr(HLF_8) : attr);
+       screen_puts_len(p, l, row, col, *p == '<' ? HL_ATTR(HLF_8) : attr);
        col += clen;
     }
 
index 5946d63..57866ef 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
 # define UNUSED
 #endif
 
+/* Used to check for "sun", "__sun" is used by newer compilers. */
+#if defined(__sun)
+# define SUN_SYSTEM
+#endif
+
 /* if we're compiling in C++ (currently only KVim), the system
  * headers must have the correct prototypes or nothing will build.
  * conversely, our prototypes might clash due to throw() specifiers and
@@ -482,6 +487,9 @@ typedef unsigned long u8char_T;         /* long should be 32 bits or more */
 # include <errno.h>
 #endif
 
+/* for INT_MAX et al. */
+#include <limits.h>
+
 /*
  * Allow other (non-unix) systems to configure themselves now
  * These are also in os_unix.h, because osdef.sh needs them there.
@@ -569,6 +577,7 @@ extern char *(*dyn_libintl_ngettext)(const char *msgid, const char *msgid_plural
 extern char *(*dyn_libintl_bindtextdomain)(const char *domainname, const char *dirname);
 extern char *(*dyn_libintl_bind_textdomain_codeset)(const char *domainname, const char *codeset);
 extern char *(*dyn_libintl_textdomain)(const char *domainname);
+extern int (*dyn_libintl_putenv)(const char *envstring);
 #endif
 
 
@@ -579,7 +588,7 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
 #ifdef FEAT_GETTEXT
 # ifdef DYNAMIC_GETTEXT
 #  define _(x) (*dyn_libintl_gettext)((char *)(x))
-#  define ngettext(x, xs, n) (*dyn_libintl_ngettext)((char *)(x), (char *)(xs), (n))
+#  define NGETTEXT(x, xs, n) (*dyn_libintl_ngettext)((char *)(x), (char *)(xs), (n))
 #  define N_(x) x
 #  define bindtextdomain(domain, dir) (*dyn_libintl_bindtextdomain)((domain), (dir))
 #  define bind_textdomain_codeset(domain, codeset) (*dyn_libintl_bind_textdomain_codeset)((domain), (codeset))
@@ -587,9 +596,12 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
 #   define HAVE_BIND_TEXTDOMAIN_CODESET 1
 #  endif
 #  define textdomain(domain) (*dyn_libintl_textdomain)(domain)
+#  define libintl_putenv(envstring) (*dyn_libintl_putenv)(envstring)
+#  define libintl_wputenv(envstring) (*dyn_libintl_wputenv)(envstring)
 # else
 #  include <libintl.h>
 #  define _(x) gettext((char *)(x))
+#  define NGETTEXT(x, xs, n) ngettext((x), (xs), (n))
 #  ifdef gettext_noop
 #   define N_(x) gettext_noop(x)
 #  else
@@ -598,7 +610,7 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
 # endif
 #else
 # define _(x) ((char *)(x))
-# define ngettext(x, xs, n) (((n) == 1) ? (char *)(x) : (char *)(xs))
+# define NGETTEXT(x, xs, n) (((n) == 1) ? (char *)(x) : (char *)(xs))
 # define N_(x) x
 # ifdef bindtextdomain
 #  undef bindtextdomain
@@ -1623,6 +1635,9 @@ typedef UINT32_TYPEDEF UINT32_T;
 #define EMSG3(s, p, q)             emsg3((char_u *)(s), (char_u *)(p), (char_u *)(q))
 #define EMSGN(s, n)                emsgn((char_u *)(s), (long)(n))
 #define EMSGU(s, n)                emsgu((char_u *)(s), (long_u)(n))
+#define IEMSG(s)                   iemsg((char_u *)(s))
+#define IEMSG2(s, p)               iemsg2((char_u *)(s), (char_u *)(p))
+#define IEMSGN(s, n)               iemsgn((char_u *)(s), (long)(n))
 #define OUT_STR(s)                 out_str((char_u *)(s))
 #define OUT_STR_NF(s)              out_str_nf((char_u *)(s))
 #define MSG_PUTS(s)                msg_puts((char_u *)(s))
@@ -1704,15 +1719,8 @@ typedef unsigned short disptick_T;       /* display tick type */
 
 typedef void       *vim_acl_T;         /* dummy to pass an ACL to a function */
 
-/*
- * Include a prototype for mch_memmove(), it may not be in alloc.pro.
- */
-#ifdef VIM_MEMMOVE
-void mch_memmove(void *, void *, size_t);
-#else
-# ifndef mch_memmove
-#  define mch_memmove(to, from, len) memmove(to, from, len)
-# endif
+#ifndef mch_memmove
+# define mch_memmove(to, from, len) memmove((char*)(to), (char*)(from), (size_t)(len))
 #endif
 
 /*
@@ -1730,17 +1738,6 @@ void mch_memmove(void *, void *, size_t);
 void *vim_memset(void *, int, size_t);
 #endif
 
-#ifdef HAVE_MEMCMP
-# define vim_memcmp(p1, p2, len)   memcmp((p1), (p2), (len))
-#else
-# ifdef HAVE_BCMP
-#  define vim_memcmp(p1, p2, len)   bcmp((p1), (p2), (len))
-# else
-int vim_memcmp(void *, void *, size_t);
-#  define VIM_MEMCMP
-# endif
-#endif
-
 #if defined(UNIX) || defined(FEAT_GUI) || defined(VMS) \
        || defined(FEAT_CLIENTSERVER)
 # define USE_INPUT_BUF
@@ -1764,14 +1761,8 @@ int vim_memcmp(void *, void *, size_t);
 /*
  * Enums need a typecast to be used as array index (for Ultrix).
  */
-#define hl_attr(n)     highlight_attr[(int)(n)]
-#define term_str(n)    term_strings[(int)(n)]
-
-/*
- * vim_iswhite() is used for "^" and the like. It differs from isspace()
- * because it doesn't include <CR> and <LF> and the like.
- */
-#define vim_iswhite(x) ((x) == ' ' || (x) == '\t')
+#define HL_ATTR(n)     highlight_attr[(int)(n)]
+#define TERM_STR(n)    term_strings[(int)(n)]
 
 /*
  * EXTERN is only defined in main.c.  That's where global variables are
@@ -2085,13 +2076,6 @@ typedef struct VimClipboard
 typedef int VimClipboard;      /* This is required for the prototypes. */
 #endif
 
-#ifdef __BORLANDC__
-/* work around a bug in the Borland 'stat' function: */
-# include <io.h>           /* for access() */
-
-# define stat(a,b) (access(a,0) ? -1 : stat(a,b))
-#endif
-
 /* Use 64-bit stat structure if available. */
 #if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__MINGW32__)
 # define HAVE_STAT64
@@ -2109,6 +2093,14 @@ typedef enum
     ASSERT_OTHER
 } assert_type_T;
 
+/* Mode for bracketed_paste(). */
+typedef enum {
+    PASTE_INSERT,      /* insert mode */
+    PASTE_CMDLINE,     /* command line */
+    PASTE_EX,          /* ex mode line */
+    PASTE_ONE_CHAR     /* return first character */
+} paste_mode_T;
+
 #include "ex_cmds.h"       /* Ex command defines */
 #include "spell.h"         /* spell checking stuff */
 
@@ -2141,7 +2133,7 @@ typedef enum
 #include "globals.h"       /* global variables and messages */
 
 #ifndef FEAT_VIRTUALEDIT
-# define getvvcol(w, p, s, c, e) getvcol(w, p, s, c, e)
+# define getvvcol(w, p, s, c, e) getvcol((w), (p), (s), (c), (e))
 # define virtual_active() FALSE
 # define virtual_op FALSE
 #endif
@@ -2473,10 +2465,12 @@ typedef enum
 #define TFN_QUIET      2       /* no error messages */
 #define TFN_NO_AUTOLOAD        4       /* do not use script autoloading */
 #define TFN_NO_DEREF   8       /* do not dereference a Funcref */
+#define TFN_READ_ONLY  16      /* will not change the var */
 
 /* Values for get_lval() flags argument: */
 #define GLV_QUIET      TFN_QUIET       /* no error messages */
 #define GLV_NO_AUTOLOAD        TFN_NO_AUTOLOAD /* do not use script autoloading */
+#define GLV_READ_ONLY  TFN_READ_ONLY   /* will not change the var */
 
 #define DO_NOT_FREE_CNT 99999  /* refcount for dict or list that should not
                                   be freed. */
@@ -2495,9 +2489,27 @@ typedef enum
 #define FNE_INCL_BR    1       /* include [] in name */
 #define FNE_CHECK_START        2       /* check name starts with valid character */
 
-#if (defined(sun) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) \
+#if (defined(SUN_SYSTEM) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) \
        && defined(S_ISCHR)
 # define OPEN_CHR_FILES
 #endif
 
+#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+# define ELAPSED_TIMEVAL
+# define ELAPSED_INIT(v) gettimeofday(&v, NULL)
+# define ELAPSED_FUNC(v) elapsed(&v)
+# define ELAPSED_TYPE struct timeval
+    long elapsed(struct timeval *start_tv);
+#else
+# if defined(WIN32)
+#  define ELAPSED_TICKCOUNT
+#  define ELAPSED_INIT(v) v = GetTickCount()
+#  define ELAPSED_FUNC(v) elapsed(v)
+#  define ELAPSED_TYPE DWORD
+#   ifndef PROTO
+     long elapsed(DWORD start_tick);
+#   endif
+# endif
+#endif
+
 #endif /* VIM__H */
index 58755b7..4bafa8d 100644 (file)
@@ -10,7 +10,7 @@
 /*
  * winclip.c
  *
- * Routines common to both Win16 and Win32 for clipboard handling.
+ * Routines for Win32 clipboard handling.
  * Also used by Cygwin, using os_unix.c.
  */
 
@@ -214,9 +214,8 @@ typedef struct
 /*
  * Make vim the owner of the current selection.  Return OK upon success.
  */
-/*ARGSUSED*/
     int
-clip_mch_own_selection(VimClipboard *cbd)
+clip_mch_own_selection(VimClipboard *cbd UNUSED)
 {
     /*
      * Never actually own the clipboard.  If another application sets the
@@ -228,9 +227,8 @@ clip_mch_own_selection(VimClipboard *cbd)
 /*
  * Make vim NOT the owner of the current selection.
  */
-/*ARGSUSED*/
     void
-clip_mch_lose_selection(VimClipboard *cbd)
+clip_mch_lose_selection(VimClipboard *cbd UNUSED)
 {
     /* Nothing needs to be done here */
 }
index 17656d5..2ef3198 100644 (file)
@@ -791,7 +791,7 @@ win_split_ins(
        oldwin = curwin;
 
     /* add a status line when p_ls == 1 and splitting the first window */
-    if (lastwin == firstwin && p_ls == 1 && oldwin->w_status_height == 0)
+    if (ONE_WINDOW && p_ls == 1 && oldwin->w_status_height == 0)
     {
        if (oldwin->w_height <= p_wmh && new_wp == NULL)
        {
@@ -870,9 +870,9 @@ win_split_ins(
 
        /* We don't like to take lines for the new window from a
         * 'winfixwidth' window.  Take them from a window to the left or right
-        * instead, if possible. */
+        * instead, if possible. Add one for the separator. */
        if (oldwin->w_p_wfw)
-           win_setwidth_win(oldwin->w_width + new_size, oldwin);
+           win_setwidth_win(oldwin->w_width + new_size + 1, oldwin);
 
        /* Only make all windows the same width if one of them (except oldwin)
         * is wider than one of the split windows. */
@@ -1492,7 +1492,7 @@ win_exchange(long Prenum)
     win_T      *wp2;
     int                temp;
 
-    if (lastwin == firstwin)       /* just one window */
+    if (ONE_WINDOW)        /* just one window */
     {
        beep_flush();
        return;
@@ -1674,7 +1674,7 @@ win_totop(int size, int flags)
     int                dir;
     int                height = curwin->w_height;
 
-    if (lastwin == firstwin)
+    if (ONE_WINDOW)
     {
        beep_flush();
        return;
@@ -2107,7 +2107,7 @@ win_equal_rec(
 }
 
 /*
- * close all windows for buffer 'buf'
+ * Close all windows for buffer "buf".
  */
     void
 close_windows(
@@ -2123,7 +2123,7 @@ close_windows(
 
     ++RedrawingDisabled;
 
-    for (wp = firstwin; wp != NULL && lastwin != firstwin; )
+    for (wp = firstwin; wp != NULL && !ONE_WINDOW; )
     {
        if (wp->w_buffer == buf && (!keep_curwin || wp != curwin)
 #ifdef FEAT_AUTOCMD
@@ -2131,7 +2131,10 @@ close_windows(
 #endif
                )
        {
-           win_close(wp, FALSE);
+           if (win_close(wp, FALSE) == FAIL)
+               /* If closing the window fails give up, to avoid looping
+                * forever. */
+               break;
 
            /* Start all over, autocommands may change the window layout. */
            wp = firstwin;
@@ -2450,6 +2453,10 @@ win_close(win_T *win, int free_buf)
 #endif
        curbuf = curwin->w_buffer;
        close_curwin = TRUE;
+
+       /* The cursor position may be invalid if the buffer changed after last
+        * using the window. */
+       check_cursor();
     }
     if (p_ea && (*p_ead == 'b' || *p_ead == dir))
        win_equal(curwin, TRUE, dir);
@@ -2538,7 +2545,7 @@ win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
                ;
            if (ptp == NULL)
            {
-               EMSG2(_(e_intern2), "win_close_othertab()");
+               internal_error("win_close_othertab()");
                return;
            }
            ptp->tp_next = tp->tp_next;
@@ -3373,7 +3380,7 @@ close_others(
        }
     }
 
-    if (message && lastwin != firstwin)
+    if (message && !ONE_WINDOW)
        EMSG(_("E445: Other window contains changes"));
 }
 
@@ -3755,6 +3762,59 @@ valid_tabpage(tabpage_T *tpc)
 }
 
 /*
+ * Return TRUE when "tpc" points to a valid tab page and at least one window is
+ * valid.
+ */
+    int
+valid_tabpage_win(tabpage_T *tpc)
+{
+    tabpage_T  *tp;
+    win_T      *wp;
+
+    FOR_ALL_TABPAGES(tp)
+    {
+       if (tp == tpc)
+       {
+           FOR_ALL_WINDOWS_IN_TAB(tp, wp)
+           {
+               if (win_valid_any_tab(wp))
+                   return TRUE;
+           }
+           return FALSE;
+       }
+    }
+    /* shouldn't happen */
+    return FALSE;
+}
+
+/*
+ * Close tabpage "tab", assuming it has no windows in it.
+ * There must be another tabpage or this will crash.
+ */
+    void
+close_tabpage(tabpage_T *tab)
+{
+    tabpage_T  *ptp;
+
+    if (tab == first_tabpage)
+    {
+       first_tabpage = tab->tp_next;
+       ptp = first_tabpage;
+    }
+    else
+    {
+       for (ptp = first_tabpage; ptp != NULL && ptp->tp_next != tab;
+                                                           ptp = ptp->tp_next)
+           ;
+       assert(ptp != NULL);
+       ptp->tp_next = tab->tp_next;
+    }
+
+    goto_tabpage_tp(ptp, FALSE, FALSE);
+    free_tabpage(tab);
+}
+
+/*
  * Find tab page "n" (first one is 1).  Returns NULL when not found.
  */
     tabpage_T *
@@ -5708,7 +5768,10 @@ win_new_height(win_T *wp, int height)
     wp->w_height = height;
     wp->w_skipcol = 0;
 
-    scroll_to_fraction(wp, prev_height);
+    /* There is no point in adjusting the scroll position when exiting.  Some
+     * values might be invalid. */
+    if (!exiting)
+       scroll_to_fraction(wp, prev_height);
 }
 
     void
@@ -5971,7 +6034,7 @@ last_status(
 {
     /* Don't make a difference between horizontal or vertical split. */
     last_status_rec(topframe, (p_ls == 2
-                         || (p_ls == 1 && (morewin || lastwin != firstwin))));
+                         || (p_ls == 1 && (morewin || !ONE_WINDOW))));
 }
 
     static void
@@ -6124,7 +6187,7 @@ file_name_in_line(
      */
     ptr = line + col;
     while (*ptr != NUL && !vim_isfilec(*ptr))
-       mb_ptr_adv(ptr);
+       MB_PTR_ADV(ptr);
     if (*ptr == NUL)           /* nothing found */
     {
        if (options & FNAME_MESS)
@@ -6548,7 +6611,7 @@ restore_snapshot(
 
 /*
  * Check if frames "sn" and "fr" have the same layout, same following frames
- * and same children.
+ * and same children.  And the window pointer is valid.
  */
     static int
 check_snapshot_rec(frame_T *sn, frame_T *fr)
@@ -6559,7 +6622,8 @@ check_snapshot_rec(frame_T *sn, frame_T *fr)
            || (sn->fr_next != NULL
                && check_snapshot_rec(sn->fr_next, fr->fr_next) == FAIL)
            || (sn->fr_child != NULL
-               && check_snapshot_rec(sn->fr_child, fr->fr_child) == FAIL))
+               && check_snapshot_rec(sn->fr_child, fr->fr_child) == FAIL)
+           || (sn->fr_win != NULL && !win_valid(sn->fr_win)))
        return FAIL;
     return OK;
 }
@@ -7133,7 +7197,10 @@ win_getid(typval_T *argvars)
                    break;
            if (tp == NULL)
                return -1;
-           wp = tp->tp_firstwin;
+           if (tp == curtab)
+               wp = firstwin;
+           else
+               wp = tp->tp_firstwin;
        }
        for ( ; wp != NULL; wp = wp->w_next)
            if (--winnr == 0)
index 0b9774f..844da85 100644 (file)
@@ -1087,7 +1087,7 @@ workshop_get_positions(
     *curCol = curwin->w_cursor.col;
 
     if (curbuf->b_visual.vi_mode == 'v' &&
-           equalpos(curwin->w_cursor, curbuf->b_visual.vi_end))
+           EQUAL_POS(curwin->w_cursor, curbuf->b_visual.vi_end))
     {
        *selStartLine = curbuf->b_visual.vi_start.lnum;
        *selStartCol = curbuf->b_visual.vi_start.col;
index 9b0d967..0f9c7f7 100644 (file)
@@ -17,7 +17,7 @@ There are three ways to remove Vim:
    have to use uninstal.exe.
 
 It's recommended to use the method that matches with how you installed Vim.
-Thus if you installed Vim by hand, deleted it by hand.
+Thus if you installed Vim by hand, delete it by hand.
 
 The first two methods should be available from the Add/Remove software window
 and the Vim entry in the Start menu.  If these have been removed already, find
@@ -33,8 +33,8 @@ Here are guidelines for removing Vim by hand:
    menu entry.  You only need to run uninstal.exe when you have installed the
    menu entry.  You can also run uninstal.exe from the Control panel with the
    Add/Remove programs application.
-   Note that uninstal.exe offers you to uninstal other items.  You can skip
-   this.
+   Note that uninstal.exe offers you the option to uninstal other items.  You
+   can skip this.
 
 2. Only if you have used the OLE version of gvim: Remove the registration of
    this program by running "gvim -unregister" in a console window.
@@ -46,7 +46,7 @@ Here are guidelines for removing Vim by hand:
    If you created .bat files when installing Vim, also search for vim.bat,
    gvim.bat, etc.
 
-4. If you completely want to delete vim, and are not going to install another
+4. If you want to completely delete vim, and are not going to install another
    version, you can delete the vimrc files that you created.  These are
    normally located in a directory like "C:\vim".  If the $VIM environment
    variable is set, it will tell the name of the directory.  Normally you can