diff -Nru vim-8.1.1681/ci/appveyor.bat vim-8.1.1729/ci/appveyor.bat --- vim-8.1.1681/ci/appveyor.bat 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/ci/appveyor.bat 2019-07-21 21:04:21.000000000 +0000 @@ -22,8 +22,10 @@ ) .\gvim -u NONE -c "redir @a | ver |0put a | wq" ver_ming.txt +:: Filter out the progress bar from the build log +sed -e "s/@<<$/@<< | sed -e 's#.*\\\\r.*##'/" Make_mvc.mak > Make_mvc2.mak + echo "Building MSVC 64bit console Version" -sed -e "s/\$(LINKARGS2)/\$(LINKARGS2) | sed -e 's#.*\\\\r.*##'/" Make_mvc.mak > Make_mvc2.mak nmake -f Make_mvc2.mak CPU=AMD64 OLE=no GUI=no IME=yes ICONV=yes DEBUG=no FEATURES=%FEATURE% || exit 1 nmake -f Make_mvc2.mak clean diff -Nru vim-8.1.1681/debian/changelog vim-8.1.1729/debian/changelog --- vim-8.1.1681/debian/changelog 2019-07-13 18:58:23.000000000 +0000 +++ vim-8.1.1729/debian/changelog 2019-07-22 12:21:18.000000000 +0000 @@ -1,11 +1,11 @@ -vim (2:8.1.1681-0york0~18.10) cosmic; urgency=medium +vim (2:8.1.1729-0york0~18.10) cosmic; urgency=medium * Re-enable -py2 packages, ruby interp * revert Trusty-incompatible compat, control, rules changes * debian/control: add explicit BD libtool (<< 2.4.6) | libtool-bin * d/p/disable-failing-tests.patch - -- Jonathon Fernyhough Sat, 13 Jul 2019 19:58:23 +0100 + -- Jonathon Fernyhough Mon, 22 Jul 2019 13:21:18 +0100 vim (2:8.1.0875-2ubuntu1) eoan; urgency=low diff -Nru vim-8.1.1681/debian/patches/debian/Document-Debian-s-decision-to-disable-modelines-by-defaul.patch vim-8.1.1729/debian/patches/debian/Document-Debian-s-decision-to-disable-modelines-by-defaul.patch --- vim-8.1.1681/debian/patches/debian/Document-Debian-s-decision-to-disable-modelines-by-defaul.patch 2019-07-12 13:56:32.000000000 +0000 +++ vim-8.1.1729/debian/patches/debian/Document-Debian-s-decision-to-disable-modelines-by-defaul.patch 2019-07-22 12:21:18.000000000 +0000 @@ -14,11 +14,11 @@ runtime/doc/options.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -Index: vim-8.1.1408/runtime/doc/options.txt +Index: vim-8.1.1729/runtime/doc/options.txt =================================================================== ---- vim-8.1.1408.orig/runtime/doc/options.txt -+++ vim-8.1.1408/runtime/doc/options.txt -@@ -5068,7 +5068,7 @@ A jump table for the options with a shor +--- vim-8.1.1729.orig/runtime/doc/options.txt ++++ vim-8.1.1729/runtime/doc/options.txt +@@ -5070,7 +5070,7 @@ A jump table for the options with a shor *'modeline'* *'ml'* *'nomodeline'* *'noml'* 'modeline' 'ml' boolean (Vim default: on (off for root), diff -Nru vim-8.1.1681/debian/patches/debian/Support-sourcing-a-vimrc.tiny-when-Vim-is-invoked-as-vi.patch vim-8.1.1729/debian/patches/debian/Support-sourcing-a-vimrc.tiny-when-Vim-is-invoked-as-vi.patch --- vim-8.1.1681/debian/patches/debian/Support-sourcing-a-vimrc.tiny-when-Vim-is-invoked-as-vi.patch 2019-07-12 13:57:12.000000000 +0000 +++ vim-8.1.1729/debian/patches/debian/Support-sourcing-a-vimrc.tiny-when-Vim-is-invoked-as-vi.patch 2019-07-22 12:21:18.000000000 +0000 @@ -16,10 +16,10 @@ src/structs.h | 3 +++ 3 files changed, 19 insertions(+), 1 deletion(-) -Index: vim-8.1.1662/src/main.c +Index: vim-8.1.1729/src/main.c =================================================================== ---- vim-8.1.1662.orig/src/main.c -+++ vim-8.1.1662/src/main.c +--- vim-8.1.1729.orig/src/main.c ++++ vim-8.1.1729/src/main.c @@ -1794,6 +1794,10 @@ parse_command_name(mparm_T *parmp) } else if (STRNICMP(initstr, "vim", 3) == 0) @@ -55,10 +55,10 @@ && !has_dash_c_arg) { /* When no .vimrc file was found: source defaults.vim. */ -Index: vim-8.1.1662/src/os_unix.h +Index: vim-8.1.1729/src/os_unix.h =================================================================== ---- vim-8.1.1662.orig/src/os_unix.h -+++ vim-8.1.1662/src/os_unix.h +--- vim-8.1.1729.orig/src/os_unix.h ++++ vim-8.1.1729/src/os_unix.h @@ -213,6 +213,9 @@ typedef struct dsc$descriptor DESC; /* * Unix system-dependent file names @@ -69,11 +69,11 @@ #ifndef SYS_VIMRC_FILE # define SYS_VIMRC_FILE "$VIM/vimrc" #endif -Index: vim-8.1.1662/src/structs.h +Index: vim-8.1.1729/src/structs.h =================================================================== ---- vim-8.1.1662.orig/src/structs.h -+++ vim-8.1.1662/src/structs.h -@@ -3592,6 +3592,9 @@ typedef struct +--- vim-8.1.1729.orig/src/structs.h ++++ vim-8.1.1729/src/structs.h +@@ -3661,6 +3661,9 @@ typedef struct #ifdef FEAT_DIFF int diff_mode; // start with 'diff' set #endif diff -Nru vim-8.1.1681/debian/patches/disable-failing-tests.patch vim-8.1.1729/debian/patches/disable-failing-tests.patch --- vim-8.1.1681/debian/patches/disable-failing-tests.patch 2019-07-13 16:30:35.000000000 +0000 +++ vim-8.1.1729/debian/patches/disable-failing-tests.patch 2019-07-22 12:21:18.000000000 +0000 @@ -2,20 +2,20 @@ Some tests fail Author: Jonathon Fernyhough -Index: vim-8.1.1680/src/testdir/test_balloon.vim +Index: vim-8.1.1729/src/testdir/test_balloon.vim =================================================================== ---- vim-8.1.1680.orig/src/testdir/test_balloon.vim -+++ vim-8.1.1680/src/testdir/test_balloon.vim +--- vim-8.1.1729.orig/src/testdir/test_balloon.vim ++++ vim-8.1.1729/src/testdir/test_balloon.vim @@ -1,3 +1,4 @@ +throw "Skipped: doesn't work under Launchpad" " Tests for 'balloonevalterm'. " A few tests only work in the terminal. -Index: vim-8.1.1680/src/testdir/test_popupwin.vim +Index: vim-8.1.1729/src/testdir/test_popupwin.vim =================================================================== ---- vim-8.1.1680.orig/src/testdir/test_popupwin.vim -+++ vim-8.1.1680/src/testdir/test_popupwin.vim -@@ -345,6 +345,7 @@ func Test_popup_firstline() +--- vim-8.1.1729.orig/src/testdir/test_popupwin.vim ++++ vim-8.1.1729/src/testdir/test_popupwin.vim +@@ -346,6 +346,7 @@ func Test_popup_firstline() endfunc func Test_popup_drag() @@ -23,7 +23,7 @@ if !CanRunVimInTerminal() throw 'Skipped: cannot make screendumps' endif -@@ -375,6 +376,7 @@ func Test_popup_drag() +@@ -376,6 +377,7 @@ func Test_popup_drag() endfunc func Test_popup_close_with_mouse() @@ -31,7 +31,7 @@ if !CanRunVimInTerminal() throw 'Skipped: cannot make screendumps' endif -@@ -496,6 +498,7 @@ func Test_popup_with_mask() +@@ -501,6 +503,7 @@ func Test_popup_with_mask() endfunc func Test_popup_select() @@ -39,7 +39,7 @@ if !CanRunVimInTerminal() throw 'Skipped: cannot make screendumps' endif -@@ -1027,6 +1030,7 @@ func Test_popup_atcursor() +@@ -1059,6 +1062,7 @@ func Test_popup_atcursor() endfunc func Test_popup_beval() @@ -47,7 +47,7 @@ if !CanRunVimInTerminal() throw 'Skipped: cannot make screendumps' endif -@@ -1565,6 +1569,7 @@ func Test_notifications() +@@ -1620,6 +1624,7 @@ func Test_notifications() endfunc func Test_popup_scrollbar() diff -Nru vim-8.1.1681/Filelist vim-8.1.1729/Filelist --- vim-8.1.1681/Filelist 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/Filelist 2019-07-21 21:04:21.000000000 +0000 @@ -50,6 +50,7 @@ src/gui_beval.c \ src/hardcopy.c \ src/hashtab.c \ + src/highlight.c \ src/indent.c \ src/insexpand.c \ src/json.c \ @@ -80,6 +81,7 @@ src/option.h \ src/popupmnu.c \ src/popupwin.c \ + src/profiler.c \ src/quickfix.c \ src/regexp.c \ src/regexp_nfa.c \ @@ -99,6 +101,7 @@ src/terminal.c \ src/term.h \ src/termlib.c \ + src/testing.c \ src/textprop.c \ src/ui.c \ src/undo.c \ @@ -107,6 +110,7 @@ src/version.c \ src/version.h \ src/vim.h \ + src/viminfo.c \ src/winclip.c \ src/window.c \ src/tee/tee.c \ @@ -188,6 +192,7 @@ src/proto/gui_beval.pro \ src/proto/hardcopy.pro \ src/proto/hashtab.pro \ + src/proto/highlight.pro \ src/proto/indent.pro \ src/proto/insexpand.pro \ src/proto/json.pro \ @@ -208,6 +213,7 @@ src/proto/option.pro \ src/proto/popupmnu.pro \ src/proto/popupwin.pro \ + src/proto/profiler.pro \ src/proto/quickfix.pro \ src/proto/regexp.pro \ src/proto/screen.pro \ @@ -222,12 +228,14 @@ src/proto/term.pro \ src/proto/terminal.pro \ src/proto/termlib.pro \ + src/proto/testing.pro \ src/proto/textprop.pro \ src/proto/ui.pro \ src/proto/undo.pro \ src/proto/usercmd.pro \ src/proto/userfunc.pro \ src/proto/version.pro \ + src/proto/viminfo.pro \ src/proto/winclip.pro \ src/proto/window.pro \ src/libvterm/.bzrignore \ @@ -540,10 +548,7 @@ README_amisrc.txt.info \ src.info \ src/INSTALLami.txt \ - src/Make_dice.mak \ - src/Make_manx.mak \ src/Make_morph.mak \ - src/Make_sas.mak \ src/os_amiga.c \ src/os_amiga.h \ src/proto/os_amiga.pro \ diff -Nru vim-8.1.1681/runtime/autoload/netrwSettings.vim vim-8.1.1729/runtime/autoload/netrwSettings.vim --- vim-8.1.1681/runtime/autoload/netrwSettings.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/autoload/netrwSettings.vim 2019-07-21 21:04:21.000000000 +0000 @@ -1,7 +1,7 @@ " netrwSettings.vim: makes netrw settings simpler -" Date: Dec 30, 2014 +" Date: Nov 09, 2016 " Maintainer: Charles E Campbell -" Version: 15 +" Version: 16 " Copyright: Copyright (C) 1999-2007 Charles E. Campbell {{{1 " Permission is hereby granted to use and distribute this code, " with or without modifications, provided that this copyright @@ -19,7 +19,7 @@ if exists("g:loaded_netrwSettings") || &cp finish endif -let g:loaded_netrwSettings = "v15" +let g:loaded_netrwSettings = "v16" if v:version < 700 echohl WarningMsg echo "***warning*** this version of netrwSettings needs vim 7.0" @@ -154,9 +154,13 @@ put = 'let g:netrw_list_hide = '.g:netrw_list_hide put = 'let g:netrw_liststyle = '.g:netrw_liststyle put = 'let g:netrw_localcopycmd = '.g:netrw_localcopycmd + put = 'let g:netrw_localcopycmdopt = '.g:netrw_localcopycmdopt put = 'let g:netrw_localmkdir = '.g:netrw_localmkdir + put = 'let g:netrw_localmkdiropt = '.g:netrw_localmkdiropt put = 'let g:netrw_localmovecmd = '.g:netrw_localmovecmd + put = 'let g:netrw_localmovecmdopt = '.g:netrw_localmovecmdopt put = 'let g:netrw_localrmdir = '.g:netrw_localrmdir + put = 'let g:netrw_localrmdiropt = '.g:netrw_localrmdiropt put = 'let g:netrw_maxfilenamelen = '.g:netrw_maxfilenamelen put = 'let g:netrw_menu = '.g:netrw_menu put = 'let g:netrw_mousemaps = '.g:netrw_mousemaps diff -Nru vim-8.1.1681/runtime/autoload/netrw.vim vim-8.1.1729/runtime/autoload/netrw.vim --- vim-8.1.1681/runtime/autoload/netrw.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/autoload/netrw.vim 2019-07-21 21:04:21.000000000 +0000 @@ -1,7 +1,7 @@ " netrw.vim: Handles file transfer and remote directory listing across " AUTOLOAD SECTION -" Date: Apr 20, 2016 -" Version: 156 +" Date: Jul 16, 2019 +" Version: 165 " Maintainer: Charles E Campbell " GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim " Copyright: Copyright (C) 2016 Charles E. Campbell {{{1 @@ -22,15 +22,24 @@ if &cp || exists("g:loaded_netrw") finish endif -" netrw requires vim having patch 7.4.213; netrw will benefit from vim's having patch#656, too -if v:version < 704 || (v:version == 704 && !has("patch213")) - if !exists("s:needpatch213") - unsilent echomsg "***sorry*** this version of netrw requires vim v7.4 with patch 213" - endif - let s:needpatch213= 1 - finish + +" Check that vim has patches that netrw requires. +" Patches needed for v7.4: 1557, and 213. +" (netrw will benefit from vim's having patch#656, too) +let s:needspatches=[1557,213] +if exists("s:needspatches") + for ptch in s:needspatches + if v:version < 704 || (v:version == 704 && !has("patch".ptch)) + if !exists("s:needpatch{ptch}") + unsilent echomsg "***sorry*** this version of netrw requires vim v7.4 with patch#".ptch + endif + let s:needpatch{ptch}= 1 + finish + endif + endfor endif -let g:loaded_netrw = "v156" + +let g:loaded_netrw = "v165" if !exists("s:NOTE") let s:NOTE = 0 let s:WARNING = 1 @@ -39,7 +48,7 @@ let s:keepcpo= &cpo setl cpo&vim -"let g:dechofuncname= 1 +"DechoFuncName 1 "DechoRemOn "call Decho("doing autoload/netrw.vim version ".g:loaded_netrw,'~'.expand("")) @@ -55,7 +64,7 @@ " Usage: netrw#ErrorMsg(s:NOTE | s:WARNING | s:ERROR,"some message",error-number) " netrw#ErrorMsg(s:NOTE | s:WARNING | s:ERROR,["message1","message2",...],error-number) " (this function can optionally take a list of messages) -" Jan 19, 2016 : max errnum currently is 103 +" Mar 21, 2017 : max errnum currently is 105 fun! netrw#ErrorMsg(level,msg,errnum) " call Dfunc("netrw#ErrorMsg(level=".a:level." msg<".a:msg."> errnum=".a:errnum.") g:netrw_use_errorwindow=".g:netrw_use_errorwindow) @@ -100,7 +109,7 @@ " call Decho("create a NetrwMessage buffer window",'~'.expand("")) bo 1split sil! call s:NetrwEnew() - sil! NetrwKeepj call s:NetrwSafeOptions() + sil! NetrwKeepj call s:NetrwOptionsSafe(1) setl bt=nofile NetrwKeepj file NetrwMessage " call Decho("setl ma noro",'~'.expand("")) @@ -171,7 +180,7 @@ " --------------------------------------------------------------------- " Netrw Constants: {{{2 -call s:NetrwInit("g:netrw_dirhist_cnt",0) +call s:NetrwInit("g:netrw_dirhistcnt",0) if !exists("s:LONGLIST") call s:NetrwInit("s:THINLIST",0) call s:NetrwInit("s:LONGLIST",1) @@ -181,6 +190,14 @@ endif " --------------------------------------------------------------------- +" Default option values: {{{2 +let g:netrw_localcopycmdopt = "" +let g:netrw_localcopydircmdopt = "" +let g:netrw_localmkdiropt = "" +let g:netrw_localmovecmdopt = "" +let g:netrw_localrmdiropt = "" + +" --------------------------------------------------------------------- " Default values for netrw's global protocol variables {{{2 call s:NetrwInit("g:netrw_use_errorwindow",1) @@ -215,21 +232,21 @@ let g:netrw_ftp_options= "-i -n" endif if !exists("g:netrw_http_cmd") - if executable("elinks") - let g:netrw_http_cmd = "elinks" - call s:NetrwInit("g:netrw_http_xcmd","-source >") - elseif executable("links") - let g:netrw_http_cmd = "links" - call s:NetrwInit("g:netrw_http_xcmd","-source >") - elseif executable("curl") + if executable("curl") let g:netrw_http_cmd = "curl" - call s:NetrwInit("g:netrw_http_xcmd","-o") + call s:NetrwInit("g:netrw_http_xcmd","-L -o") elseif executable("wget") let g:netrw_http_cmd = "wget" call s:NetrwInit("g:netrw_http_xcmd","-q -O") + elseif executable("elinks") + let g:netrw_http_cmd = "elinks" + call s:NetrwInit("g:netrw_http_xcmd","-source >") elseif executable("fetch") let g:netrw_http_cmd = "fetch" call s:NetrwInit("g:netrw_http_xcmd","-o") + elseif executable("links") + let g:netrw_http_cmd = "links" + call s:NetrwInit("g:netrw_http_xcmd","-http.extra-header ".shellescape("Accept-Encoding: identity", 1)." -source >") else let g:netrw_http_cmd = "" endif @@ -238,6 +255,7 @@ call s:NetrwInit("g:netrw_keepj","keepj") call s:NetrwInit("g:netrw_rcp_cmd" , "rcp") call s:NetrwInit("g:netrw_rsync_cmd", "rsync") +call s:NetrwInit("g:netrw_rsync_sep", "/") if !exists("g:netrw_scp_cmd") if executable("scp") call s:NetrwInit("g:netrw_scp_cmd" , "scp -q") @@ -299,7 +317,7 @@ call s:NetrwInit("g:netrw_cygdrive","/cygdrive") " Default values - d-g ---------- {{{3 call s:NetrwInit("s:didstarstar",0) -call s:NetrwInit("g:netrw_dirhist_cnt" , 0) +call s:NetrwInit("g:netrw_dirhistcnt" , 0) call s:NetrwInit("g:netrw_decompress" , '{ ".gz" : "gunzip", ".bz2" : "bunzip2", ".zip" : "unzip", ".tar" : "tar -xf", ".xz" : "unxz" }') call s:NetrwInit("g:netrw_dirhistmax" , 10) call s:NetrwInit("g:netrw_errorlvl" , s:NOTE) @@ -364,7 +382,8 @@ if g:netrw_cygwin let g:netrw_localcopycmd= "cp" else - let g:netrw_localcopycmd= expand("$COMSPEC")." /c copy" + let g:netrw_localcopycmd = expand("$COMSPEC") + let g:netrw_localcopycmdopt= " /c copy" endif elseif has("unix") || has("macunix") let g:netrw_localcopycmd= "cp" @@ -375,14 +394,20 @@ if !exists("g:netrw_localcopydircmd") if has("win32") || has("win95") || has("win64") || has("win16") if g:netrw_cygwin - let g:netrw_localcopydircmd= "cp -R" + let g:netrw_localcopydircmd = "cp" + let g:netrw_localcopydircmdopt= " -R" else - let g:netrw_localcopycmd= expand("$COMSPEC")." /c xcopy /e /c /h /i /k" + let g:netrw_localcopydircmd = expand("$COMSPEC") + let g:netrw_localcopydircmdopt= " /c xcopy /e /c /h /i /k" endif - elseif has("unix") || has("macunix") - let g:netrw_localcopydircmd= "cp -R" + elseif has("unix") + let g:netrw_localcopydircmd = "cp" + let g:netrw_localcopydircmdopt= " -R" + elseif has("macunix") + let g:netrw_localcopydircmd = "cp" + let g:netrw_localcopydircmdopt= " -R" else - let g:netrw_localcopycmd= "" + let g:netrw_localcopydircmd= "" endif endif if exists("g:netrw_local_mkdir") @@ -393,7 +418,8 @@ if g:netrw_cygwin call s:NetrwInit("g:netrw_localmkdir","mkdir") else - let g:netrw_localmkdir= expand("$COMSPEC")." /c mkdir" + let g:netrw_localmkdir = expand("$COMSPEC") + let g:netrw_localmkdiropt= " /c mkdir" endif else call s:NetrwInit("g:netrw_localmkdir","mkdir") @@ -408,7 +434,8 @@ if g:netrw_cygwin let g:netrw_localmovecmd= "mv" else - let g:netrw_localmovecmd= expand("$COMSPEC")." /c move" + let g:netrw_localmovecmd = expand("$COMSPEC") + let g:netrw_localmovecmdopt= " /c move" endif elseif has("unix") || has("macunix") let g:netrw_localmovecmd= "mv" @@ -416,7 +443,8 @@ let g:netrw_localmovecmd= "" endif endif -if v:version < 704 || !has("patch1109") +if v:version < 704 || (v:version == 704 && !has("patch1107")) + " 1109 provides for delete(tmpdir,"d") which is what will be used if exists("g:netrw_local_rmdir") let g:netrw_localrmdir= g:netrw_local_rmdir call netrw#ErrorMsg(s:NOTE,"g:netrw_local_rmdir is deprecated in favor of g:netrw_localrmdir",86) @@ -425,7 +453,8 @@ if g:netrw_cygwin call s:NetrwInit("g:netrw_localrmdir","rmdir") else - let g:netrw_localrmdir= expand("$COMSPEC")." /c rmdir" + let g:netrw_localrmdir = expand("$COMSPEC") + let g:netrw_localrmdiropt= " /c rmdir" endif else call s:NetrwInit("g:netrw_localrmdir","rmdir") @@ -527,7 +556,7 @@ else let s:treedepthstring= "| " endif -call s:NetrwInit("s:netrw_nbcd",'{}') +call s:NetrwInit("s:netrw_posn",'{}') " BufEnter event ignored by decho when following variable is true " Has a side effect that doau BufReadPost doesn't work, so @@ -888,7 +917,7 @@ NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Nexplore or improperly; see help for netrw-starstar",40) if has("clipboard") sil! let @* = keepregstar - sil! let @+ = keepregstar + sil! let @+ = keepregplus endif sil! let @/ = keepregslash " call Dret("netrw#Explore") @@ -913,7 +942,7 @@ NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Pexplore or improperly; see help for netrw-starstar",41) if has("clipboard") sil! let @* = keepregstar - sil! let @+ = keepregstar + sil! let @+ = keepregplus endif sil! let @/ = keepregslash " call Dret("netrw#Explore") @@ -967,8 +996,8 @@ keepalt call netrw#ErrorMsg(s:WARNING,'no files matched pattern<'.pattern.'>',45) if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif if has("clipboard") - sil! let @* = keepregstar - sil! let @+ = keepregstar + sil! let @* = keepregstar + sil! let @+ = keepregplus endif sil! let @/ = keepregslash " call Dret("netrw#Explore : no files matched pattern") @@ -1004,7 +1033,7 @@ keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no files matched",42) if has("clipboard") sil! let @* = keepregstar - sil! let @+ = keepregstar + sil! let @+ = keepregplus endif sil! let @/ = keepregslash " call Dret("netrw#Explore : no files matched") @@ -1052,7 +1081,7 @@ endif if has("clipboard") sil! let @* = keepregstar - sil! let @+ = keepregstar + sil! let @+ = keepregplus endif sil! let @/ = keepregslash " call Dret("netrw#Explore : missing +path_extra") @@ -1106,7 +1135,9 @@ let prvfname= fname endfor " call Decho("explore_match<".s:explore_match.">",'~'.expand("")) - exe "2match netrwMarkFile /".s:explore_match."/" + if has("syntax") && exists("g:syntax_on") && g:syntax_on + exe "2match netrwMarkFile /".s:explore_match."/" + endif endif echo "==Pexplore ==Nexplore" else @@ -1123,7 +1154,7 @@ let s:netrw_events= 2 if has("clipboard") sil! let @* = keepregstar - sil! let @+ = keepregstar + sil! let @+ = keepregplus endif sil! let @/ = keepregslash " call Dret("netrw#Explore : @/<".@/.">") @@ -1132,13 +1163,14 @@ " --------------------------------------------------------------------- " netrw#Lexplore: toggle Explorer window, keeping it on the left of the current tab {{{2 fun! netrw#Lexplore(count,rightside,...) -" call Dfunc("netrw#Lexplore(count=".a:count."rightside=".a:rightside.",...) a:0=".a:0." ft=".&ft) +" call Dfunc("netrw#Lexplore(count=".a:count." rightside=".a:rightside.",...) a:0=".a:0." ft=".&ft) let curwin= winnr() if a:0 > 0 && a:1 != "" " if a netrw window is already on the left-side of the tab " and a directory has been specified, explore with that " directory. +" call Decho("case has input argument(s) (a:1<".a:1.">)") let a1 = expand(a:1) " call Decho("a:1<".a:1."> curwin#".curwin,'~'.expand("")) exe "1wincmd w" @@ -1156,18 +1188,22 @@ exe curwin."wincmd w" else let a1= "" +" call Decho("no input arguments") endif if exists("t:netrw_lexbufnr") " check if t:netrw_lexbufnr refers to a netrw window let lexwinnr = bufwinnr(t:netrw_lexbufnr) +" call Decho("lexwinnr= bufwinnr(t:netrw_lexbufnr#".t:netrw_lexbufnr.")=".lexwinnr) else let lexwinnr= 0 +" call Decho("t:netrw_lexbufnr doesn't exist") endif +" call Decho("lexwinnr=".lexwinnr,'~'.expand("")) if lexwinnr > 0 " close down netrw explorer window -" call Decho("t:netrw_lexbufnr#".t:netrw_lexbufnr.": close down netrw window",'~'.expand("")) +" call Decho("t:netrw_lexbufnr#".t:netrw_lexbufnr.": close down netrw window",'~'.expand("")) exe lexwinnr."wincmd w" let g:netrw_winsize = -winwidth(0) let t:netrw_lexposn = winsaveview() @@ -1177,8 +1213,11 @@ if lexwinnr < curwin let curwin= curwin - 1 endif - exe curwin."wincmd w" + if lexwinnr != curwin + exe curwin."wincmd w" + endif unlet t:netrw_lexbufnr +" call Decho("unlet t:netrw_lexbufnr") else " open netrw explorer window @@ -1193,15 +1232,17 @@ let curfile= expand("%") " call Decho("curfile<".curfile.">",'~'.expand("")) exe (a:rightside? "botright" : "topleft")." vertical ".((g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize) . " new" +" call Decho("new buf#".bufnr("%")." win#".winnr()) if a:0 > 0 && a1 != "" " call Decho("case 1: Explore ".a1,'~'.expand("")) + call netrw#Explore(0,0,0,a1) exe "Explore ".fnameescape(a1) elseif curfile =~ '^\a\{3,}://' " call Decho("case 2: Explore ".substitute(curfile,'[^/\\]*$','',''),'~'.expand("")) - exe "Explore ".substitute(curfile,'[^/\\]*$','','') + call netrw#Explore(0,0,0,substitute(curfile,'[^/\\]*$','','')) else " call Decho("case 3: Explore .",'~'.expand("")) - Explore . + call netrw#Explore(0,0,0,".") endif if a:count != 0 let g:netrw_winsize = netrw_winsize @@ -1209,6 +1250,8 @@ setlocal winfixwidth let g:netrw_altv = keep_altv let t:netrw_lexbufnr = bufnr("%") +" call Decho("let t:netrw_lexbufnr=".t:netrw_lexbufnr) +" call Decho("t:netrw_lexposn".(exists("t:netrw_lexposn")? string(t:netrw_lexposn) : " n/a")) if exists("t:netrw_lexposn") " call Decho("restoring to t:netrw_lexposn",'~'.expand("")) " call Decho("restoring posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("")) @@ -1224,6 +1267,7 @@ else let g:netrw_chgwin= 2 endif +" call Decho("let g:netrw_chgwin=".g:netrw_chgwin) endif " call Dret("netrw#Lexplore") @@ -1341,7 +1385,7 @@ " call Decho("transfer files one at a time",'~'.expand("")) for fname in fnamelist " call Decho("system(".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath).")",'~'.expand("")) - call system(g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath)) + call system(g:netrw_localcopycmd.g:netrw_localcopycmdopt." ".s:ShellEscape(fname)." ".s:ShellEscape(topath)) if v:shell_error != 0 call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80) " call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath)) @@ -1353,7 +1397,7 @@ " call Decho("transfer files with one command",'~'.expand("")) let filelist= join(map(deepcopy(fnamelist),"s:ShellEscape(v:val)")) " call Decho("system(".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath).")",'~'.expand("")) - call system(g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath)) + call system(g:netrw_localcopycmd.g:netrw_localcopycmdopt." ".filelist." ".s:ShellEscape(topath)) if v:shell_error != 0 call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80) " call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath)) @@ -1387,7 +1431,7 @@ else let path= "" endif - let filelist= join(map(deepcopy(fnamelist),'s:ShellEscape(g:netrw_machine.":".path.v:val,1)')) + let filelist= join(map(deepcopy(fnamelist),'escape(s:ShellEscape(g:netrw_machine.":".path.v:val,1)," ")')) call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".filelist." ".s:ShellEscape(tgtdir,1)) elseif b:netrw_method == 2 @@ -1557,134 +1601,25 @@ endfun " ------------------------------------------------------------------------ -" s:NetrwOptionRestore: restore options (based on prior s:NetrwOptionSave) {{{2 -fun! s:NetrwOptionRestore(vt) -" call Dfunc("s:NetrwOptionRestore(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> winnr($)=".winnr("$")) -" call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo." a:vt=".a:vt,'~'.expand("")) - if !exists("{a:vt}netrw_optionsave") - call s:RestorePosn(s:netrw_nbcd) -" call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo." a:vt=".a:vt,'~'.expand("")) -" call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("")) -" call Dret("s:NetrwOptionRestore : ".a:vt."netrw_optionsave doesn't exist") - return - endif - unlet {a:vt}netrw_optionsave - - if exists("+acd") - if exists("{a:vt}netrw_acdkeep") -" call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("")) - let curdir = getcwd() - let &l:acd = {a:vt}netrw_acdkeep - unlet {a:vt}netrw_acdkeep - if &l:acd - call s:NetrwLcd(curdir) - endif - endif - endif - if exists("{a:vt}netrw_aikeep") |let &l:ai = {a:vt}netrw_aikeep |unlet {a:vt}netrw_aikeep |endif - if exists("{a:vt}netrw_awkeep") |let &l:aw = {a:vt}netrw_awkeep |unlet {a:vt}netrw_awkeep |endif - if exists("{a:vt}netrw_blkeep") |let &l:bl = {a:vt}netrw_blkeep |unlet {a:vt}netrw_blkeep |endif - if exists("{a:vt}netrw_btkeep") |let &l:bt = {a:vt}netrw_btkeep |unlet {a:vt}netrw_btkeep |endif - if exists("{a:vt}netrw_bombkeep") |let &l:bomb = {a:vt}netrw_bombkeep |unlet {a:vt}netrw_bombkeep |endif - if exists("{a:vt}netrw_cedit") |let &cedit = {a:vt}netrw_cedit |unlet {a:vt}netrw_cedit |endif - if exists("{a:vt}netrw_cikeep") |let &l:ci = {a:vt}netrw_cikeep |unlet {a:vt}netrw_cikeep |endif - if exists("{a:vt}netrw_cinkeep") |let &l:cin = {a:vt}netrw_cinkeep |unlet {a:vt}netrw_cinkeep |endif - if exists("{a:vt}netrw_cinokeep") |let &l:cino = {a:vt}netrw_cinokeep |unlet {a:vt}netrw_cinokeep |endif - if exists("{a:vt}netrw_comkeep") |let &l:com = {a:vt}netrw_comkeep |unlet {a:vt}netrw_comkeep |endif - if exists("{a:vt}netrw_cpokeep") |let &l:cpo = {a:vt}netrw_cpokeep |unlet {a:vt}netrw_cpokeep |endif - if exists("{a:vt}netrw_diffkeep") |let &l:diff = {a:vt}netrw_diffkeep |unlet {a:vt}netrw_diffkeep |endif - if exists("{a:vt}netrw_fenkeep") |let &l:fen = {a:vt}netrw_fenkeep |unlet {a:vt}netrw_fenkeep |endif - if exists("g:netrw_ffkep") && g:netrw_ffkeep - if exists("{a:vt}netrw_ffkeep") |let &l:ff = {a:vt}netrw_ffkeep |unlet {a:vt}netrw_ffkeep |endif - endif - if exists("{a:vt}netrw_fokeep") |let &l:fo = {a:vt}netrw_fokeep |unlet {a:vt}netrw_fokeep |endif - if exists("{a:vt}netrw_gdkeep") |let &l:gd = {a:vt}netrw_gdkeep |unlet {a:vt}netrw_gdkeep |endif - if exists("{a:vt}netrw_hidkeep") |let &l:hidden = {a:vt}netrw_hidkeep |unlet {a:vt}netrw_hidkeep |endif - if exists("{a:vt}netrw_imkeep") |let &l:im = {a:vt}netrw_imkeep |unlet {a:vt}netrw_imkeep |endif - if exists("{a:vt}netrw_iskkeep") |let &l:isk = {a:vt}netrw_iskkeep |unlet {a:vt}netrw_iskkeep |endif - if exists("{a:vt}netrw_lskeep") |let &l:ls = {a:vt}netrw_lskeep |unlet {a:vt}netrw_lskeep |endif - if exists("{a:vt}netrw_makeep") |let &l:ma = {a:vt}netrw_makeep |unlet {a:vt}netrw_makeep |endif - if exists("{a:vt}netrw_magickeep")|let &l:magic = {a:vt}netrw_magickeep |unlet {a:vt}netrw_magickeep|endif - if exists("{a:vt}netrw_modkeep") |let &l:mod = {a:vt}netrw_modkeep |unlet {a:vt}netrw_modkeep |endif - if exists("{a:vt}netrw_nukeep") |let &l:nu = {a:vt}netrw_nukeep |unlet {a:vt}netrw_nukeep |endif - if exists("{a:vt}netrw_rnukeep") |let &l:rnu = {a:vt}netrw_rnukeep |unlet {a:vt}netrw_rnukeep |endif - if exists("{a:vt}netrw_repkeep") |let &l:report = {a:vt}netrw_repkeep |unlet {a:vt}netrw_repkeep |endif - if exists("{a:vt}netrw_rokeep") |let &l:ro = {a:vt}netrw_rokeep |unlet {a:vt}netrw_rokeep |endif - if exists("{a:vt}netrw_selkeep") |let &l:sel = {a:vt}netrw_selkeep |unlet {a:vt}netrw_selkeep |endif - if exists("{a:vt}netrw_spellkeep")|let &l:spell = {a:vt}netrw_spellkeep |unlet {a:vt}netrw_spellkeep|endif - if has("clipboard") - if exists("{a:vt}netrw_starkeep") |let @* = {a:vt}netrw_starkeep |unlet {a:vt}netrw_starkeep |endif - endif - " Problem: start with liststyle=0; press : result, following line resets l:ts. -" if exists("{a:vt}netrw_tskeep") |let &l:ts = {a:vt}netrw_tskeep |unlet {a:vt}netrw_tskeep |endif - if exists("{a:vt}netrw_twkeep") |let &l:tw = {a:vt}netrw_twkeep |unlet {a:vt}netrw_twkeep |endif - if exists("{a:vt}netrw_wigkeep") |let &l:wig = {a:vt}netrw_wigkeep |unlet {a:vt}netrw_wigkeep |endif - if exists("{a:vt}netrw_wrapkeep") |let &l:wrap = {a:vt}netrw_wrapkeep |unlet {a:vt}netrw_wrapkeep |endif - if exists("{a:vt}netrw_writekeep")|let &l:write = {a:vt}netrw_writekeep |unlet {a:vt}netrw_writekeep|endif - if exists("s:yykeep") |let @@ = s:yykeep |unlet s:yykeep |endif - if exists("{a:vt}netrw_swfkeep") - if &directory == "" - " user hasn't specified a swapfile directory; - " netrw will temporarily set the swapfile directory - " to the current directory as returned by getcwd(). - let &l:directory= getcwd() - sil! let &l:swf = {a:vt}netrw_swfkeep - setl directory= - unlet {a:vt}netrw_swfkeep - elseif &l:swf != {a:vt}netrw_swfkeep - if !g:netrw_use_noswf - " following line causes a Press ENTER in windows -- can't seem to work around it!!! - sil! let &l:swf= {a:vt}netrw_swfkeep - endif - unlet {a:vt}netrw_swfkeep - endif - endif - if exists("{a:vt}netrw_dirkeep") && isdirectory(s:NetrwFile({a:vt}netrw_dirkeep)) && g:netrw_keepdir - let dirkeep = substitute({a:vt}netrw_dirkeep,'\\','/','g') - if exists("{a:vt}netrw_dirkeep") - call s:NetrwLcd(dirkeep) - unlet {a:vt}netrw_dirkeep - endif - endif - if has("clipboard") - if exists("{a:vt}netrw_regstar") |sil! let @*= {a:vt}netrw_regstar |unlet {a:vt}netrw_regstar |endif - endif - if exists("{a:vt}netrw_regslash")|sil! let @/= {a:vt}netrw_regslash|unlet {a:vt}netrw_regslash|endif - call s:RestorePosn(s:netrw_nbcd) - -" call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("")) -" call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist"),'~'.expand("")) -" call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("")) -" call Decho("diff=".&l:diff." win#".winnr()." w:netrw_diffkeep=".(exists("w:netrw_diffkeep")? w:netrw_diffkeep : "doesn't exist"),'~'.expand("")) -" call Decho("ts=".&l:ts,'~'.expand("")) - " Moved the filetype detect here from NetrwGetFile() because remote files - " were having their filetype detect-generated settings overwritten by - " NetrwOptionRestore. - if &ft != "netrw" -" call Decho("filetype detect (ft=".&ft.")",'~'.expand("")) - filetype detect - endif -" call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo." a:vt=".a:vt,'~'.expand("")) -" call Dret("s:NetrwOptionRestore : tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> modified=".&modified." modifiable=".&modifiable." readonly=".&readonly) -endfun - -" --------------------------------------------------------------------- -" s:NetrwOptionSave: save options prior to setting to "netrw-buffer-standard" form {{{2 -" Options get restored by s:NetrwOptionRestore() -" 06/08/07 : removed call to NetrwSafeOptions(), either placed -" immediately after NetrwOptionSave() calls in NetRead -" and NetWrite, or after the s:NetrwEnew() call in -" NetrwBrowse. -" vt: normally its "w:" or "s:" (a variable type) -fun! s:NetrwOptionSave(vt) -" call Dfunc("s:NetrwOptionSave(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%")).">"." winnr($)=".winnr("$")." mod=".&mod." ma=".&ma) +" s:NetrwOptionsSave: save options prior to setting to "netrw-buffer-standard" form {{{2 +" Options get restored by s:NetrwOptionsRestore() +" +" Option handling: +" * save user's options (s:NetrwOptionsSave) +" * set netrw-safe options (s:NetrwOptionsSafe) +" - change an option only when user option != safe option (s:netrwSetSafeSetting) +" * restore user's options (s:netrwOPtionsRestore) +" - restore a user option when != safe option (s:NetrwRestoreSetting) +" vt: (variable type) normally its either "w:" or "s:" +fun! s:NetrwOptionsSave(vt) +" call Dfunc("s:NetrwOptionsSave(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%")).">"." winnr($)=".winnr("$")." mod=".&mod." ma=".&ma) " call Decho(a:vt."netrw_optionsave".(exists("{a:vt}netrw_optionsave")? ("=".{a:vt}netrw_optionsave) : " doesn't exist"),'~'.expand("")) " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo." a:vt=".a:vt,'~'.expand("")) if !exists("{a:vt}netrw_optionsave") let {a:vt}netrw_optionsave= 1 else -" call Dret("s:NetrwOptionSave : options already saved") +" call Dret("s:NetrwOptionsSave : options already saved") return endif " call Decho("prior to save: fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." diff=".&l:diff,'~'.expand("")) @@ -1707,6 +1642,7 @@ let {a:vt}netrw_cpokeep = &l:cpo let {a:vt}netrw_diffkeep = &l:diff let {a:vt}netrw_fenkeep = &l:fen +" call Decho("saving current settings: got here#1",'~'.expand("")) if !exists("g:netrw_ffkeep") || g:netrw_ffkeep let {a:vt}netrw_ffkeep = &l:ff endif @@ -1725,12 +1661,10 @@ let {a:vt}netrw_rokeep = &l:ro let {a:vt}netrw_selkeep = &l:sel let {a:vt}netrw_spellkeep = &l:spell +" call Decho("saving current settings: got here#2",'~'.expand("")) if !g:netrw_use_noswf let {a:vt}netrw_swfkeep = &l:swf endif - if has("clipboard") - let {a:vt}netrw_starkeep = @* - endif let {a:vt}netrw_tskeep = &l:ts let {a:vt}netrw_twkeep = &l:tw " textwidth let {a:vt}netrw_wigkeep = &l:wig " wildignore @@ -1743,48 +1677,53 @@ let {a:vt}netrw_dirkeep = getcwd() endif if has("clipboard") - if &go =~# 'a' | sil! let {a:vt}netrw_regstar = @* | endif + sil! let {a:vt}netrw_starkeep = @* + sil! let {a:vt}netrw_pluskeep = @+ endif - sil! let {a:vt}netrw_regslash= @/ + sil! let {a:vt}netrw_slashkeep= @/ " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo." a:vt=".a:vt,'~'.expand("")) -" call Dret("s:NetrwOptionSave : tab#".tabpagenr()." win#".winnr()) +" call Dret("s:NetrwOptionsSave : tab#".tabpagenr()." win#".winnr()) endfun -" ------------------------------------------------------------------------ -" s:NetrwSafeOptions: sets options to help netrw do its job {{{2 +" --------------------------------------------------------------------- +" s:NetrwOptionsSafe: sets options to help netrw do its job {{{2 " Use s:NetrwSaveOptions() to save user settings -" Use s:NetrwOptionRestore() to restore user settings -fun! s:NetrwSafeOptions() -" call Dfunc("s:NetrwSafeOptions() win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%"))."> winnr($)=".winnr("$")) +" Use s:NetrwOptionsRestore() to restore user settings +fun! s:NetrwOptionsSafe(islocal) +" call Dfunc("s:NetrwOptionsSafe(islocal=".a:islocal.") win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%"))."> winnr($)=".winnr("$")) " call Decho("win#".winnr()."'s ft=".&ft,'~'.expand("")) " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("")) - if exists("+acd") | setl noacd | endif - setl noai - setl noaw - setl nobl - setl nobomb - setl bt=nofile - setl noci - setl nocin - setl bh=hide - setl cino= - setl com= - setl cpo-=a - setl cpo-=A + if exists("+acd") | call s:NetrwSetSafeSetting("&l:acd",0)|endif + call s:NetrwSetSafeSetting("&l:ai",0) + call s:NetrwSetSafeSetting("&l:aw",0) + call s:NetrwSetSafeSetting("&l:bl",0) + call s:NetrwSetSafeSetting("&l:bomb",0) + if a:islocal + call s:NetrwSetSafeSetting("&l:bt","nofile") + else + call s:NetrwSetSafeSetting("&l:bt","acwrite") + endif + call s:NetrwSetSafeSetting("&l:ci",0) + call s:NetrwSetSafeSetting("&l:cin",0) + call s:NetrwSetSafeSetting("&l:bh","hide") + call s:NetrwSetSafeSetting("&l:cino","") + call s:NetrwSetSafeSetting("&l:com","") + if &cpo =~ 'a' | call s:NetrwSetSafeSetting("&cpo",substitute(&cpo,'a','','g')) | endif + if &cpo =~ 'A' | call s:NetrwSetSafeSetting("&cpo",substitute(&cpo,'A','','g')) | endif setl fo=nroql2 - setl nohid - setl noim + call s:NetrwSetSafeSetting("&l:hid",0) + call s:NetrwSetSafeSetting("&l:im",0) setl isk+=@ isk+=* isk+=/ - setl magic + call s:NetrwSetSafeSetting("&l:magic",1) if g:netrw_use_noswf - setl noswf + call s:NetrwSetSafeSetting("swf",0) endif - setl report=10000 - setl sel=inclusive - setl nospell - setl tw=0 - setl wig= + call s:NetrwSetSafeSetting("&l:report",10000) + call s:NetrwSetSafeSetting("&l:sel","inclusive") + call s:NetrwSetSafeSetting("&l:spell",0) + call s:NetrwSetSafeSetting("&l:tw",0) + call s:NetrwSetSafeSetting("&l:wig","") setl cedit& call s:NetrwCursor() @@ -1792,12 +1731,194 @@ " call Decho("ft<".&ft."> ei=".&ei,'~'.expand("")) if &ft == "netrw" " call Decho("do any netrw FileType autocmds (doau FileType netrw)",'~'.expand("")) - sil! keepalt NetrwKeepj doau FileType netrw + keepalt NetrwKeepj doau FileType netrw endif " call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." bh=".&l:bh." bt<".&bt.">",'~'.expand("")) " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("")) -" call Dret("s:NetrwSafeOptions") +" call Dret("s:NetrwOptionsSafe") +endfun + +" --------------------------------------------------------------------- +" s:NetrwOptionsRestore: restore options (based on prior s:NetrwOptionsSave) {{{2 +fun! s:NetrwOptionsRestore(vt) +" call Dfunc("s:NetrwOptionsRestore(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> winnr($)=".winnr("$")) +" call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo." a:vt=".a:vt,'~'.expand("")) + if !exists("{a:vt}netrw_optionsave") +" call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo." a:vt=".a:vt,'~'.expand("")) +" call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("")) +" call Dret("s:NetrwOptionsRestore : ".a:vt."netrw_optionsave doesn't exist") + return + endif + unlet {a:vt}netrw_optionsave + + if exists("+acd") + if exists("{a:vt}netrw_acdkeep") +" call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("")) + let curdir = getcwd() + let &l:acd = {a:vt}netrw_acdkeep + unlet {a:vt}netrw_acdkeep + if &l:acd + call s:NetrwLcd(curdir) + endif + endif + endif + call s:NetrwRestoreSetting(a:vt."netrw_aikeep","&l:ai") + call s:NetrwRestoreSetting(a:vt."netrw_awkeep","&l:aw") + call s:NetrwRestoreSetting(a:vt."netrw_blkeep","&l:bl") + call s:NetrwRestoreSetting(a:vt."netrw_btkeep","&l:bt") + call s:NetrwRestoreSetting(a:vt."netrw_bombkeep","&l:bomb") + call s:NetrwRestoreSetting(a:vt."netrw_cedit","&cedit") + call s:NetrwRestoreSetting(a:vt."netrw_cikeep","&l:ci") + call s:NetrwRestoreSetting(a:vt."netrw_cinkeep","&l:cin") + call s:NetrwRestoreSetting(a:vt."netrw_cinokeep","&l:cino") + call s:NetrwRestoreSetting(a:vt."netrw_comkeep","&l:com") + call s:NetrwRestoreSetting(a:vt."netrw_cpokeep","&l:cpo") + call s:NetrwRestoreSetting(a:vt."netrw_diffkeep","&l:diff") + call s:NetrwRestoreSetting(a:vt."netrw_fenkeep","&l:fen") + if exists("g:netrw_ffkeep") && g:netrw_ffkeep + call s:NetrwRestoreSetting(a:vt."netrw_ffkeep")","&l:ff") + endif + call s:NetrwRestoreSetting(a:vt."netrw_fokeep","&l:fo") + call s:NetrwRestoreSetting(a:vt."netrw_gdkeep","&l:gd") + call s:NetrwRestoreSetting(a:vt."netrw_hidkeep","&l:hidden") + call s:NetrwRestoreSetting(a:vt."netrw_imkeep","&l:im") + call s:NetrwRestoreSetting(a:vt."netrw_iskkeep","&l:isk") + call s:NetrwRestoreSetting(a:vt."netrw_lskeep","&l:ls") + call s:NetrwRestoreSetting(a:vt."netrw_makeep","&l:ma") + call s:NetrwRestoreSetting(a:vt."netrw_magickeep","&l:magic") + call s:NetrwRestoreSetting(a:vt."netrw_modkeep","&l:mod") + call s:NetrwRestoreSetting(a:vt."netrw_nukeep","&l:nu") + call s:NetrwRestoreSetting(a:vt."netrw_rnukeep","&l:rnu") + call s:NetrwRestoreSetting(a:vt."netrw_repkeep","&l:report") + call s:NetrwRestoreSetting(a:vt."netrw_rokeep","&l:ro") + call s:NetrwRestoreSetting(a:vt."netrw_selkeep","&l:sel") + call s:NetrwRestoreSetting(a:vt."netrw_spellkeep","&l:spell") + call s:NetrwRestoreSetting(a:vt."netrw_twkeep","&l:tw") + call s:NetrwRestoreSetting(a:vt."netrw_wigkeep","&l:wig") + call s:NetrwRestoreSetting(a:vt."netrw_wrapkeep","&l:wrap") + call s:NetrwRestoreSetting(a:vt."netrw_writekeep","&l:write") + call s:NetrwRestoreSetting("s:yykeep","@@") + " former problem: start with liststyle=0; press : result, following line resets l:ts. + " Fixed; in s:PerformListing, when w:netrw_liststyle is s:LONGLIST, will use a printf to pad filename with spaces + " rather than by appending a tab which previously was using "&ts" to set the desired spacing. (Sep 28, 2018) + call s:NetrwRestoreSetting(a:vt."netrw_tskeep","&l:ts") + + if exists("{a:vt}netrw_swfkeep") + if &directory == "" + " user hasn't specified a swapfile directory; + " netrw will temporarily set the swapfile directory + " to the current directory as returned by getcwd(). + let &l:directory= getcwd() + sil! let &l:swf = {a:vt}netrw_swfkeep + setl directory= + unlet {a:vt}netrw_swfkeep + elseif &l:swf != {a:vt}netrw_swfkeep + if !g:netrw_use_noswf + " following line causes a Press ENTER in windows -- can't seem to work around it!!! + sil! let &l:swf= {a:vt}netrw_swfkeep + endif + unlet {a:vt}netrw_swfkeep + endif + endif + if exists("{a:vt}netrw_dirkeep") && isdirectory(s:NetrwFile({a:vt}netrw_dirkeep)) && g:netrw_keepdir + let dirkeep = substitute({a:vt}netrw_dirkeep,'\\','/','g') + if exists("{a:vt}netrw_dirkeep") + call s:NetrwLcd(dirkeep) + unlet {a:vt}netrw_dirkeep + endif + endif + if has("clipboard") + call s:NetrwRestoreSetting(a:vt."netrw_starkeep","@*") + call s:NetrwRestoreSetting(a:vt."netrw_pluskeep","@+") + endif + call s:NetrwRestoreSetting(a:vt."netrw_slashkeep","@/") + +" call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("")) +" call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist"),'~'.expand("")) +" call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("")) +" call Decho("diff=".&l:diff." win#".winnr()." w:netrw_diffkeep=".(exists("w:netrw_diffkeep")? w:netrw_diffkeep : "doesn't exist"),'~'.expand("")) +" call Decho("ts=".&l:ts,'~'.expand("")) + " Moved the filetype detect here from NetrwGetFile() because remote files + " were having their filetype detect-generated settings overwritten by + " NetrwOptionRestore. + if &ft != "netrw" +" call Decho("filetype detect (ft=".&ft.")",'~'.expand("")) + filetype detect + endif +" call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo." a:vt=".a:vt,'~'.expand("")) +" call Dret("s:NetrwOptionsRestore : tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> modified=".&modified." modifiable=".&modifiable." readonly=".&readonly) +endfun + +" --------------------------------------------------------------------- +" s:NetrwSetSafeSetting: sets an option to a safe setting {{{2 +" but only when the options' value and the safe setting differ +" Doing this means that netrw will not come up as having changed a +" setting last when it really didn't actually change it. +" +" Called from s:NetrwOptionsSafe +" ex. call s:NetrwSetSafeSetting("&l:sel","inclusive") +fun! s:NetrwSetSafeSetting(setting,safesetting) +" call Dfunc("s:NetrwSetSafeSetting(setting<".a:setting."> safesetting<".a:safesetting.">)") + + if a:setting =~ '^&' +" call Decho("fyi: a:setting starts with &") + exe "let settingval= ".a:setting +" call Decho("fyi: settingval<".settingval.">") + + if settingval != a:safesetting +" call Decho("set setting<".a:setting."> to option value<".a:safesetting.">") + if type(a:safesetting) == 0 + exe "let ".a:setting."=".a:safesetting + elseif type(a:safesetting) == 1 + exe "let ".a:setting."= '".a:safesetting."'" + else + call netrw#ErrorMsg(s:ERROR,"(s:NetrwRestoreSetting) doesn't know how to restore ".a:setting." with a safesetting of type#".type(a:safesetting),105) + endif + endif + endif + +" call Dret("s:NetrwSetSafeSetting") +endfun + +" ------------------------------------------------------------------------ +" s:NetrwRestoreSetting: restores specified setting using associated keepvar, {{{2 +" but only if the setting value differs from the associated keepvar. +" Doing this means that netrw will not come up as having changed a +" setting last when it really didn't actually change it. +" +" Used by s:NetrwOptionsRestore() to restore each netrw-senstive setting +" keepvars are set up by s:NetrwOptionsSave +fun! s:NetrwRestoreSetting(keepvar,setting) +"" call Dfunc("s:NetrwRestoreSetting(a:keepvar<".a:keepvar."> a:setting<".a:setting.">)") + + " typically called from s:NetrwOptionsRestore + " call s:NetrwRestoreSettings(keep-option-variable-name,'associated-option') + " ex. call s:NetrwRestoreSetting(a:vt."netrw_selkeep","&l:sel") + " Restores option (if different) from a keepvar + if exists(a:keepvar) + exe "let keepvarval= ".a:keepvar + exe "let setting= ".a:setting + +"" call Decho("fyi: a:keepvar<".a:keepvar."> exists") +"" call Decho("fyi: keepvarval=".keepvarval) +"" call Decho("fyi: a:setting<".a:setting."> setting<".setting.">") + + if setting != keepvarval +"" call Decho("restore setting<".a:setting."=".setting."> to keepvarval<".keepvarval.">") + if type(a:setting) == 0 + exe "let ".a:setting."= ".keepvarval + elseif type(a:setting) == 1 + exe "let ".a:setting."= '".keepvarval."'" + else + call netrw#ErrorMsg(s:ERROR,"(s:NetrwRestoreSetting) doesn't know how to restore ".a:keepvar." with a setting of type#".type(a:setting),105) + endif + endif + + exe "unlet ".a:keepvar + endif + +"" call Dret("s:NetrwRestoreSetting") endfun " --------------------------------------------------------------------- @@ -1833,7 +1954,7 @@ endif endfun -" --------------------------------------------------------------------- +" =============================== " Netrw Transfer Functions: {{{1 " =============================== @@ -1847,13 +1968,13 @@ " call Dfunc("netrw#NetRead(mode=".a:mode.",...) a:0=".a:0." ".g:loaded_netrw.((a:0 > 0)? " a:1<".a:1.">" : "")) " NetRead: save options {{{3 - call s:NetrwOptionSave("w:") - call s:NetrwSafeOptions() + call s:NetrwOptionsSave("w:") + call s:NetrwOptionsSafe(0) call s:RestoreCursorline() " NetrwSafeOptions sets a buffer up for a netrw listing, which includes buflisting off. " However, this setting is not wanted for a remote editing session. The buffer should be "nofile", still. setl bl -" call Decho("(netrw#NetRead) buf#".bufnr("%")."<".bufname("%")."> bl=".&bl." bt=".&bt." bh=".&bh,'~'.expand("")) +" call Decho("buf#".bufnr("%")."<".bufname("%")."> bl=".&bl." bt=".&bt." bh=".&bh,'~'.expand("")) " NetRead: interpret mode into a readcmd {{{3 if a:mode == 0 " read remote file before current line @@ -1943,7 +2064,7 @@ " NetRead: Determine method of read (ftp, rcp, etc) {{{3 call s:NetrwMethod(choice) if !exists("b:netrw_method") || b:netrw_method < 0 -" call Dfunc("netrw#NetRead : unsupported method") +" call Dret("netrw#NetRead : unsupported method") return endif let tmpfile= s:GetTempfile(b:netrw_fname) " apply correct suffix @@ -2103,7 +2224,7 @@ else let tmpfile_get = tmpfile endif - call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1)." ".s:ShellEscape(tmpfile_get,1)) + call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".escape(s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1),' ')." ".s:ShellEscape(tmpfile_get,1)) let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method) let b:netrw_lastfile = choice @@ -2185,7 +2306,7 @@ " NetRead: (rsync) NetRead Method #7 {{{3 elseif b:netrw_method == 7 " call Decho("read via rsync (method #7)",'~'.expand("")) - call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1)." ".s:ShellEscape(tmpfile,1)) + call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".s:ShellEscape(g:netrw_machine.g:netrw_rsync_sep.b:netrw_fname,1)." ".s:ShellEscape(tmpfile,1)) let result = s:NetrwGetFile(readcmd,tmpfile, b:netrw_method) let b:netrw_lastfile = choice @@ -2252,7 +2373,7 @@ " call Decho("cleanup by deleting tmpfile<".tmpfile.">",'~'.expand("")) NetrwKeepj call s:NetrwDelete(tmpfile) endif - NetrwKeepj call s:NetrwOptionRestore("w:") + NetrwKeepj call s:NetrwOptionsRestore("w:") " call Dret("netrw#NetRead :5 getcwd<".getcwd().">") endfun @@ -2264,8 +2385,8 @@ " NetWrite: option handling {{{3 let mod= 0 - call s:NetrwOptionSave("w:") - call s:NetrwSafeOptions() + call s:NetrwOptionsSave("w:") + call s:NetrwOptionsSafe(0) " NetWrite: Get Temporary Filename {{{3 let tmpfile= s:GetTempfile("") @@ -2374,7 +2495,7 @@ " ============================ if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1 echo "(netrw) Processing your write request..." -" call Decho("(netrw) Processing your write request...",'~'.expand("")) +" call Decho("Processing your write request...",'~'.expand("")) endif "......................................... @@ -2527,7 +2648,7 @@ let url= g:netrw_choice call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_http_put_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(url,1) ) elseif !exists("g:netrw_quiet") - call netrw#ErrorMsg(s:ERROR,"can't write to http using <".g:netrw_http_put_cmd".">".",16) + call netrw#ErrorMsg(s:ERROR,"can't write to http using <".g:netrw_http_put_cmd.">".",16) endif "......................................... @@ -2571,7 +2692,7 @@ " NetWrite: (rsync) NetWrite Method #7 {{{3 elseif b:netrw_method == 7 " call Decho("write via rsync (method #7)",'~'.expand("")) - call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1)) + call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(g:netrw_machine.g:netrw_rsync_sep.b:netrw_fname,1)) let b:netrw_lastfile = choice "......................................... @@ -2616,7 +2737,7 @@ " call Decho("tmpfile<".tmpfile."> readable, will now delete it",'~'.expand("")) call s:NetrwDelete(tmpfile) endif - call s:NetrwOptionRestore("w:") + call s:NetrwOptionsRestore("w:") if a:firstline == 1 && a:lastline == line("$") " restore modifiability; usually equivalent to set nomod @@ -2676,9 +2797,13 @@ " --------------------------------------------------------------------- " netrw#SetTreetop: resets the tree top to the current directory/specified directory {{{2 " (implements the :Ntree command) -fun! netrw#SetTreetop(...) -" call Dfunc("netrw#SetTreetop(".((a:0 > 0)? a:1 : "").") a:0=".a:0) - +fun! netrw#SetTreetop(iscmd,...) +" call Dfunc("netrw#SetTreetop(iscmd=".a:iscmd." ".((a:0 > 0)? a:1 : "").") a:0=".a:0) +" call Decho("w:netrw_treetop<".w:netrw_treetop.">") + + " iscmd==0: netrw#SetTreetop called using gn mapping + " iscmd==1: netrw#SetTreetop called using :Ntree from the command line +" call Decho("(iscmd=".a:iscmd.": called using :Ntree from command line",'~'.expand("")) " clear out the current tree if exists("w:netrw_treetop") " call Decho("clearing out current tree",'~'.expand("")) @@ -2689,8 +2814,9 @@ " call Decho("freeing w:netrw_treedict",'~'.expand("")) unlet w:netrw_treedict endif +" call Decho("inittreetop<".(exists("inittreetop")? inittreetop : "n/a").">") - if a:1 == "" && exists("inittreetop") + if (a:iscmd == 0 || a:1 == "") && exists("inittreetop") let treedir= s:NetrwTreePath(inittreetop) " call Decho("treedir<".treedir.">",'~'.expand("")) else @@ -2699,7 +2825,7 @@ let treedir= a:1 elseif exists("b:netrw_curdir") && (isdirectory(s:NetrwFile(b:netrw_curdir."/".a:1)) || a:1 =~ '^\a\{3,}://') let treedir= b:netrw_curdir."/".a:1 -" call Decho("a:1<".a:1."> is NOT a directory, trying treedir<".treedir.">",'~'.expand("")) +" call Decho("a:1<".a:1."> is NOT a directory, using treedir<".treedir.">",'~'.expand("")) else " normally the cursor is left in the message window. " However, here this results in the directory being listed in the message window, which is not wanted. @@ -2710,13 +2836,18 @@ endif endif " call Decho("treedir<".treedir.">",'~'.expand("")) + + " determine if treedir is remote or local let islocal= expand("%") !~ '^\a\{3,}://' " call Decho("islocal=".islocal,'~'.expand("")) + + " browse the resulting directory if islocal call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(islocal,treedir)) else call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,treedir)) endif + " call Dret("netrw#SetTreetop") endfun @@ -2755,8 +2886,7 @@ else let tfile= a:tfile endif -" call Decho("exe sil! keepalt file ".fnameescape(tfile),'~'.expand("")) - exe "sil! keepalt file ".fnameescape(tfile) + call s:NetrwBufRename(tfile) " edit temporary file (ie. read the temporary file in) if rfile =~ '\.zip$' @@ -2783,8 +2913,7 @@ endif " rename buffer back to remote filename -" call Decho("exe sil! keepalt file ".fnameescape(rfile),'~'.expand("")) - exe "sil! NetrwKeepj keepalt file ".fnameescape(rfile) + call s:NetrwBufRename(rfile) " Detect filetype of local version of remote file. " Note that isk must not include a "/" for scripts.vim @@ -2793,7 +2922,7 @@ let iskkeep= &l:isk setl isk-=/ let &l:isk= iskkeep -" call Dredir("renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">","ls!") +" call Dredir("ls!","NetrwGetFile (renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">)") let line1 = 1 let line2 = line("$") @@ -2864,13 +2993,13 @@ " g:netrw_port = optional port number (for ftp) " g:netrw_choice = copy of input url (choice) fun! s:NetrwMethod(choice) -" call Dfunc("NetrwMethod(a:choice<".a:choice.">)") +" call Dfunc("s:NetrwMethod(a:choice<".a:choice.">)") " sanity check: choice should have at least three slashes in it if strlen(substitute(a:choice,'[^/]','','g')) < 3 call netrw#ErrorMsg(s:ERROR,"not a netrw-style url; netrw uses protocol://[user@]hostname[:port]/[path])",78) let b:netrw_method = -1 -" call Dret("NetrwMethod : incorrect url format<".a:choice.">") +" call Dret("s:NetrwMethod : incorrect url format<".a:choice.">") return endif @@ -2983,7 +3112,7 @@ endif if curmachine != g:netrw_machine - if exists("s:netwr_hup[".g:netrw_machine."]") + if exists("s:netrw_hup[".g:netrw_machine."]") call NetUserPass("ftp:".g:netrw_machine) elseif exists("s:netrw_passwd") " if there's a change in hostname, require password re-entry @@ -3113,7 +3242,7 @@ " call Decho("s:netrw_passwd <".s:netrw_passwd.">",'~'.expand("")) " endif "Decho " call Decho("b:netrw_fname <".b:netrw_fname.">",'~'.expand("")) -" call Dret("NetrwMethod : b:netrw_method=".b:netrw_method." g:netrw_port=".g:netrw_port) +" call Dret("s:NetrwMethod : b:netrw_method=".b:netrw_method." g:netrw_port=".g:netrw_port) endfun " ------------------------------------------------------------------------ @@ -3257,9 +3386,9 @@ " call Dret("NetUserPass : uid<".g:netrw_uid."> passwd<".s:netrw_passwd.">") endfun -" =========================================== +" ================================= " Shared Browsing Support: {{{1 -" =========================================== +" ================================= " --------------------------------------------------------------------- " s:ExplorePatHls: converts an Explore pattern into a regular expression search pattern {{{2 @@ -3284,7 +3413,7 @@ " 5: (user: ) go down (next) directory, using history " 6: (user: ) delete bookmark fun! s:NetrwBookHistHandler(chg,curdir) -" call Dfunc("s:NetrwBookHistHandler(chg=".a:chg." curdir<".a:curdir.">) cnt=".v:count." histcnt=".g:netrw_dirhist_cnt." histmax=".g:netrw_dirhistmax) +" call Dfunc("s:NetrwBookHistHandler(chg=".a:chg." curdir<".a:curdir.">) cnt=".v:count." histcnt=".g:netrw_dirhistcnt." histmax=".g:netrw_dirhistmax) if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0 " " call Dret("s:NetrwBookHistHandler - suppressed due to g:netrw_dirhistmax") return @@ -3331,12 +3460,14 @@ endif " list directory history - let cnt = g:netrw_dirhist_cnt + " Note: history is saved only when PerformListing is done; + " ie. when netrw can re-use a netrw buffer, the current directory is not saved in the history. + let cnt = g:netrw_dirhistcnt let first = 1 let histcnt = 0 if g:netrw_dirhistmax > 0 - while ( first || cnt != g:netrw_dirhist_cnt ) -" call Decho("first=".first." cnt=".cnt." dirhist_cnt=".g:netrw_dirhist_cnt,'~'.expand("")) + while ( first || cnt != g:netrw_dirhistcnt ) +" call Decho("first=".first." cnt=".cnt." dirhistcnt=".g:netrw_dirhistcnt,'~'.expand("")) if exists("g:netrw_dirhist_{cnt}") " call Decho("Netrw History#".histcnt.": ".g:netrw_dirhist_{cnt},'~'.expand("")) echo printf("Netrw History#%-2d: %s",histcnt,g:netrw_dirhist_{cnt}) @@ -3350,7 +3481,7 @@ endif endwhile else - let g:netrw_dirhist_cnt= 0 + let g:netrw_dirhistcnt= 0 endif if didwork call inputsave()|call input("Press to continue")|call inputrestore() @@ -3359,27 +3490,27 @@ elseif a:chg == 3 " saves most recently visited directories (when they differ) " call Decho("(browsing) record curdir history",'~'.expand("")) - if !exists("g:netrw_dirhist_cnt") || !exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}") || g:netrw_dirhist_{g:netrw_dirhist_cnt} != a:curdir + if !exists("g:netrw_dirhistcnt") || !exists("g:netrw_dirhist_{g:netrw_dirhistcnt}") || g:netrw_dirhist_{g:netrw_dirhistcnt} != a:curdir if g:netrw_dirhistmax > 0 - let g:netrw_dirhist_cnt = ( g:netrw_dirhist_cnt + 1 ) % g:netrw_dirhistmax - let g:netrw_dirhist_{g:netrw_dirhist_cnt} = a:curdir + let g:netrw_dirhistcnt = ( g:netrw_dirhistcnt + 1 ) % g:netrw_dirhistmax + let g:netrw_dirhist_{g:netrw_dirhistcnt} = a:curdir endif -" call Decho("save dirhist#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">",'~'.expand("")) +" call Decho("save dirhist#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("")) endif elseif a:chg == 4 " u: change to the previous directory stored on the history list " call Decho("(user: ) chg to prev dir from history",'~'.expand("")) if g:netrw_dirhistmax > 0 - let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt - v:count1 ) % g:netrw_dirhistmax - if g:netrw_dirhist_cnt < 0 - let g:netrw_dirhist_cnt= g:netrw_dirhist_cnt + g:netrw_dirhistmax + let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt - v:count1 ) % g:netrw_dirhistmax + if g:netrw_dirhistcnt < 0 + let g:netrw_dirhistcnt= g:netrw_dirhistcnt + g:netrw_dirhistmax endif else - let g:netrw_dirhist_cnt= 0 + let g:netrw_dirhistcnt= 0 endif - if exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}") -" call Decho("changedir u#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">",'~'.expand("")) + if exists("g:netrw_dirhist_{g:netrw_dirhistcnt}") +" call Decho("changedir u#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("")) if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir") setl ma noro " call Decho("setl ma noro",'~'.expand("")) @@ -3388,13 +3519,13 @@ " call Decho("setl nomod",'~'.expand("")) " call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("")) endif -" call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt}),'~'.expand("")) - exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt}) +" call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt}),'~'.expand("")) + exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt}) else if g:netrw_dirhistmax > 0 - let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt + v:count1 ) % g:netrw_dirhistmax + let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt + v:count1 ) % g:netrw_dirhistmax else - let g:netrw_dirhist_cnt= 0 + let g:netrw_dirhistcnt= 0 endif echo "Sorry, no predecessor directory exists yet" endif @@ -3403,9 +3534,9 @@ " U: change to the subsequent directory stored on the history list " call Decho("(user: ) chg to next dir from history",'~'.expand("")) if g:netrw_dirhistmax > 0 - let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt + 1 ) % g:netrw_dirhistmax - if exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}") -" call Decho("changedir U#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">",'~'.expand("")) + let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt + 1 ) % g:netrw_dirhistmax + if exists("g:netrw_dirhist_{g:netrw_dirhistcnt}") +" call Decho("changedir U#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("")) if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir") " call Decho("setl ma noro",'~'.expand("")) setl ma noro @@ -3415,17 +3546,17 @@ setl nomod " call Decho("(set nomod) ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("")) endif -" call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt}),'~'.expand("")) - exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt}) +" call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt}),'~'.expand("")) + exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt}) else - let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt - 1 ) % g:netrw_dirhistmax - if g:netrw_dirhist_cnt < 0 - let g:netrw_dirhist_cnt= g:netrw_dirhist_cnt + g:netrw_dirhistmax + let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt - 1 ) % g:netrw_dirhistmax + if g:netrw_dirhistcnt < 0 + let g:netrw_dirhistcnt= g:netrw_dirhistcnt + g:netrw_dirhistmax endif echo "Sorry, no successor directory exists yet" endif else - let g:netrw_dirhist_cnt= 0 + let g:netrw_dirhistcnt= 0 echo "Sorry, no successor directory exists yet (g:netrw_dirhistmax is ".g:netrw_dirhistmax.")" endif @@ -3460,10 +3591,12 @@ fun! s:NetrwBookHistRead() " call Dfunc("s:NetrwBookHistRead()") if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0 -" " call Dret("s:NetrwBookHistRead - suppressed due to g:netrw_dirhistmax") +" call Dret("s:NetrwBookHistRead - nothing read (suppressed due to dirhistmax=".(exists("g:netrw_dirhistmax")? g:netrw_dirhistmax : "n/a").")") return endif let ykeep= @@ + + " read bookmarks if !exists("s:netrw_initbookhist") let home = s:NetrwHome() let savefile= home."/.netrwbook" @@ -3471,6 +3604,8 @@ " call Decho("sourcing .netrwbook",'~'.expand("")) exe "keepalt NetrwKeepj so ".savefile endif + + " read history if g:netrw_dirhistmax > 0 let savefile= home."/.netrwhist" if filereadable(s:NetrwFile(savefile)) @@ -3481,27 +3616,33 @@ au VimLeave * call s:NetrwBookHistSave() endif endif + let @@= ykeep +" call Decho("dirhistmax=".(exists("g:netrw_dirhistmax")? g:netrw_dirhistmax : "n/a"),'~'.expand("")) +" call Decho("dirhistcnt=".(exists("g:netrw_dirhistcnt")? g:netrw_dirhistcnt : "n/a"),'~'.expand("")) " call Dret("s:NetrwBookHistRead") endfun " --------------------------------------------------------------------- -" s:NetrwBookHistSave: this function saves bookmarks and history {{{2 +" s:NetrwBookHistSave: this function saves bookmarks and history to files {{{2 " Sister function: s:NetrwBookHistRead() " I used to do this via viminfo but that appears to " be unreliable for long-term storage " If g:netrw_dirhistmax is <= 0, no history or bookmarks " will be saved. +" (s:NetrwBookHistHandler(3,...) used to record history) fun! s:NetrwBookHistSave() -" call Dfunc("s:NetrwBookHistSave() dirhistmax=".g:netrw_dirhistmax) +" call Dfunc("s:NetrwBookHistSave() dirhistmax=".g:netrw_dirhistmax." dirhistcnt=".g:netrw_dirhistcnt) if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0 -" call Dret("s:NetrwBookHistSave : dirhistmax=".g:netrw_dirhistmax) +" call Dret("s:NetrwBookHistSave : nothing saved (dirhistmax=".g:netrw_dirhistmax.")") return endif let savefile= s:NetrwHome()."/.netrwhist" +" call Decho("savefile<".savefile.">",'~'.expand("")) 1split call s:NetrwEnew() +" call Decho("case g:netrw_use_noswf=".g:netrw_use_noswf.(exists("+acd")? " +acd" : " -acd"),'~'.expand("")) if g:netrw_use_noswf setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000 noswf else @@ -3512,20 +3653,37 @@ if exists("+acd") | setl noacd | endif sil! NetrwKeepj keepalt %d _ - " save .netrwhist -- no attempt to merge + " rename enew'd file: .netrwhist -- no attempt to merge + " record dirhistmax and current dirhistcnt + " save history +" call Decho("saving history: dirhistmax=".g:netrw_dirhistmax." dirhistcnt=".g:netrw_dirhistcnt." lastline=".line("$"),'~'.expand("")) sil! keepalt file .netrwhist call setline(1,"let g:netrw_dirhistmax =".g:netrw_dirhistmax) - call setline(2,"let g:netrw_dirhist_cnt =".g:netrw_dirhist_cnt) - let lastline = line("$") - let cnt = 1 - while cnt <= g:netrw_dirhist_cnt - call setline((cnt+lastline),'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'") - let cnt= cnt + 1 - endwhile - exe "sil! w! ".savefile + call setline(2,"let g:netrw_dirhistcnt =".g:netrw_dirhistcnt) + if g:netrw_dirhistmax > 0 + let lastline = line("$") + let cnt = g:netrw_dirhistcnt + let first = 1 + while ( first || cnt != g:netrw_dirhistcnt ) + let lastline= lastline + 1 + if exists("g:netrw_dirhist_{cnt}") + call setline(lastline,'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'") +" call Decho("..".lastline.'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'",'~'.expand("")) + endif + let first = 0 + let cnt = ( cnt - 1 ) % g:netrw_dirhistmax + if cnt < 0 + let cnt= cnt + g:netrw_dirhistmax + endif + endwhile + exe "sil! w! ".savefile +" call Decho("exe sil! w! ".savefile,'~'.expand("")) + endif + " save bookmarks sil NetrwKeepj %d _ if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] +" call Decho("saving bookmarks",'~'.expand("")) " merge and write .netrwbook let savefile= s:NetrwHome()."/.netrwbook" @@ -3543,7 +3701,10 @@ " construct and save .netrwbook call setline(1,"let g:netrw_bookmarklist= ".string(g:netrw_bookmarklist)) exe "sil! w! ".savefile +" call Decho("exe sil! w! ".savefile,'~'.expand("")) endif + + " cleanup -- remove buffer used to construct history let bgone= bufnr("%") q! exe "keepalt ".bgone."bwipe!" @@ -3560,9 +3721,9 @@ fun! s:NetrwBrowse(islocal,dirname) if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif " call Dfunc("s:NetrwBrowse(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".w:netrw_liststyle." ".g:loaded_netrw." buf#".bufnr("%")."<".bufname("%")."> win#".winnr()) -" call Decho("modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("")) -" call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("")) -" call Dredir("ls!") +" call Decho("fyi: modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("")) +" call Decho("fyi: tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("")) +" call Dredir("ls!","s:NetrwBrowse") " save alternate-file's filename if w:netrw_rexlocal doesn't exist " This is useful when one edits a local file, then :e ., then :Rex @@ -3579,18 +3740,24 @@ " s:NetrwBrowse : simplify the dirname (especially for ".."s in dirnames) {{{3 if a:dirname !~ '^\a\{3,}://' let dirname= simplify(a:dirname) +" call Decho("simplified dirname<".dirname.">") else let dirname= a:dirname endif + " repoint t:netrw_lexbufnr if appropriate + if exists("t:netrw_lexbufnr") && bufnr("%") == t:netrw_lexbufnr +" call Decho("set repointlexbufnr to true!") + let repointlexbufnr= 1 + endif + + " s:NetrwBrowse : sanity checks: {{{3 if exists("s:netrw_skipbrowse") unlet s:netrw_skipbrowse " call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." filename<".expand("%")."> win#".winnr()." ft<".&ft.">",'~'.expand("")) " call Dret("s:NetrwBrowse : s:netrw_skipbrowse existed") return endif - - " s:NetrwBrowse : sanity checks: {{{3 if !exists("*shellescape") NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing shellescape()",69) " call Dret("s:NetrwBrowse : missing shellescape()") @@ -3603,20 +3770,25 @@ endif " s:NetrwBrowse : save options: {{{3 - call s:NetrwOptionSave("w:") + call s:NetrwOptionsSave("w:") " s:NetrwBrowse : re-instate any marked files {{{3 - if exists("s:netrwmarkfilelist_{bufnr('%')}") -" call Decho("clearing marked files",'~'.expand("")) - exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/" + if has("syntax") && exists("g:syntax_on") && g:syntax_on + if exists("s:netrwmarkfilelist_{bufnr('%')}") +" call Decho("clearing marked files",'~'.expand("")) + exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/" + endif endif if a:islocal && exists("w:netrw_acdkeep") && w:netrw_acdkeep " s:NetrwBrowse : set up "safe" options for local directory/file {{{3 " call Decho("handle w:netrw_acdkeep:",'~'.expand("")) " call Decho("NetrwKeepj lcd ".fnameescape(dirname)." (due to w:netrw_acdkeep=".w:netrw_acdkeep." - acd=".&acd.")",'~'.expand("")) - call s:NetrwLcd(dirname) - call s:NetrwSafeOptions() + if s:NetrwLcd(dirname) +" call Dret("s:NetrwBrowse : lcd failure") + return + endif + " call s:NetrwOptionsSafe() " tst952 failed with this enabled. " call Decho("getcwd<".getcwd().">",'~'.expand("")) elseif !a:islocal && dirname !~ '[\/]$' && dirname !~ '^"' @@ -3638,13 +3810,12 @@ " s:NetrwBrowse : remote-read the requested file into current buffer {{{3 call s:NetrwEnew(dirname) - call s:NetrwSafeOptions() + call s:NetrwOptionsSafe(a:islocal) setl ma noro " call Decho("setl ma noro",'~'.expand("")) let b:netrw_curdir = dirname let url = s:method."://".((s:user == "")? "" : s:user."@").s:machine.(s:port ? ":".s:port : "")."/".s:path -" call Decho("exe sil! keepalt file ".fnameescape(url)." (bt=".&bt.")",'~'.expand("")) - exe "sil! NetrwKeepj keepalt file ".fnameescape(url) + call s:NetrwBufRename(url) exe "sil! NetrwKeepj keepalt doau BufReadPre ".fnameescape(s:fname) sil call netrw#NetRead(2,url) " netrw.vim and tar.vim have already handled decompression of the tarball; avoiding gzip.vim error @@ -3664,7 +3835,7 @@ " s:NetrwBrowse : save certain window-oriented variables into buffer-oriented variables {{{3 call s:SetBufWinVars() - call s:NetrwOptionRestore("w:") + call s:NetrwOptionsRestore("w:") " call Decho("setl ma nomod",'~'.expand("")) setl ma nomod noro " call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("")) @@ -3691,16 +3862,18 @@ let reusing= s:NetrwGetBuffer(a:islocal,dirname) " maintain markfile highlighting - if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != "" -" call Decho("bufnr(%)=".bufnr('%'),'~'.expand("")) -" call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("")) - exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/" - else -" call Decho("2match none",'~'.expand("")) - 2match none + if has("syntax") && exists("g:syntax_on") && g:syntax_on + if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != "" +" " call Decho("bufnr(%)=".bufnr('%'),'~'.expand("")) +" " call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("")) + exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/" + else +" " call Decho("2match none",'~'.expand("")) + 2match none + endif endif if reusing && line("$") > 1 - call s:NetrwOptionRestore("w:") + call s:NetrwOptionsRestore("w:") " call Decho("setl noma nomod nowrap",'~'.expand("")) setl noma nomod nowrap " call Decho("(set noma nomod nowrap) ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("")) @@ -3746,7 +3919,10 @@ " call Decho("handle g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("")) " call Decho("l:acd".(exists("&l:acd")? "=".&l:acd : " doesn't exist"),'~'.expand("")) if !exists("&l:acd") || !&l:acd - call s:NetrwLcd(b:netrw_curdir) + if s:NetrwLcd(b:netrw_curdir) +" call Dret("s:NetrwBrowse : lcd failure") + return + endif endif endif @@ -3778,7 +3954,7 @@ if !exists("g:netrw_quiet") NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw doesn't understand your dirname<".dirname.">",20) endif - NetrwKeepj call s:NetrwOptionRestore("w:") + NetrwKeepj call s:NetrwOptionsRestore("w:") " call Decho("setl noma nomod nowrap",'~'.expand("")) setl noma nomod nowrap " call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("")) @@ -3789,15 +3965,15 @@ " call Decho("b:netrw_curdir<".b:netrw_curdir."> (remote)",'~'.expand("")) endif " (additional remote handling) - " ----------------------- - " Directory Listing: {{{3 - " ----------------------- + " ------------------------------- + " Perform Directory Listing: {{{3 + " ------------------------------- NetrwKeepj call s:NetrwMaps(a:islocal) NetrwKeepj call s:NetrwCommands(a:islocal) NetrwKeepj call s:PerformListing(a:islocal) " restore option(s) - call s:NetrwOptionRestore("w:") + call s:NetrwOptionsRestore("w:") " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("")) " If there is a rexposn: restore position with rexposn @@ -3817,6 +3993,12 @@ setl beval endif + " repoint t:netrw_lexbufnr if appropriate + if exists("repointlexbufnr") + let t:netrw_lexbufnr= bufnr("%") +" call Decho("repoint t:netrw_lexbufnr to #".t:netrw_lexbufnr) + endif + " restore position if reusing " call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("")) @@ -3824,8 +4006,8 @@ endif " The s:LocalBrowseRefresh() function is called by an autocmd - " installed by s:LocalFastBrowser() when g:netrw_fastbrowse <= 1 (ie. slow, medium speed). - " However, s:NetrwBrowse() causes the FocusGained event to fire the firstt time. + " installed by s:LocalFastBrowser() when g:netrw_fastbrowse <= 1 (ie. slow or medium speed). + " However, s:NetrwBrowse() causes the FocusGained event to fire the first time. " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("")) " call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("")) " call Dret("s:NetrwBrowse : did PerformListing ft<".&ft.">") @@ -3837,17 +4019,18 @@ " may not apply correctly; ie. netrw's idea of the current directory may " differ from vim's. This function insures that netrw's idea of the current " directory is used. +" Returns a path to the file specified by a:fname fun! s:NetrwFile(fname) -" call Dfunc("s:NetrwFile(fname<".a:fname.">) win#".winnr()) -" call Decho("g:netrw_keepdir =".(exists("g:netrw_keepdir")? g:netrw_keepdir : 'n/a'),'~'.expand("")) -" call Decho("g:netrw_cygwin =".(exists("g:netrw_cygwin")? g:netrw_cygwin : 'n/a'),'~'.expand("")) -" call Decho("g:netrw_liststyle=".(exists("g:netrw_liststyle")? g:netrw_liststyle : 'n/a'),'~'.expand("")) -" call Decho("w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("")) +" "" call Dfunc("s:NetrwFile(fname<".a:fname.">) win#".winnr()) +" "" call Decho("g:netrw_keepdir =".(exists("g:netrw_keepdir")? g:netrw_keepdir : 'n/a'),'~'.expand("")) +" "" call Decho("g:netrw_cygwin =".(exists("g:netrw_cygwin")? g:netrw_cygwin : 'n/a'),'~'.expand("")) +" "" call Decho("g:netrw_liststyle=".(exists("g:netrw_liststyle")? g:netrw_liststyle : 'n/a'),'~'.expand("")) +" "" call Decho("w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("")) " clean up any leading treedepthstring if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST let fname= substitute(a:fname,'^'.s:treedepthstring.'\+','','') -" call Decho("clean up any leading treedepthstring: fname<".fname.">",'~'.expand("")) +" "" call Decho("clean up any leading treedepthstring: fname<".fname.">",'~'.expand("")) else let fname= a:fname endif @@ -3862,31 +4045,31 @@ if fname =~ '^\' || fname =~ '^\a:\' " windows, but full path given let ret= fname -" call Decho("windows+full path: isdirectory(".fname.")",'~'.expand("")) +" "" call Decho("windows+full path: isdirectory(".fname.")",'~'.expand("")) else " windows, relative path given let ret= s:ComposePath(b:netrw_curdir,fname) -" call Decho("windows+rltv path: isdirectory(".fname.")",'~'.expand("")) +" "" call Decho("windows+rltv path: isdirectory(".fname.")",'~'.expand("")) endif elseif fname =~ '^/' " not windows, full path given let ret= fname -" call Decho("unix+full path: isdirectory(".fname.")",'~'.expand("")) +" "" call Decho("unix+full path: isdirectory(".fname.")",'~'.expand("")) else " not windows, relative path given let ret= s:ComposePath(b:netrw_curdir,fname) -" call Decho("unix+rltv path: isdirectory(".fname.")",'~'.expand("")) +" "" call Decho("unix+rltv path: isdirectory(".fname.")",'~'.expand("")) endif else " vim and netrw agree on the current directory let ret= fname -" call Decho("vim and netrw agree on current directory (g:netrw_keepdir=".g:netrw_keepdir.")",'~'.expand("")) -" call Decho("vim directory: ".getcwd(),'~'.expand("")) -" call Decho("netrw directory: ".(exists("b:netrw_curdir")? b:netrw_curdir : 'n/a'),'~'.expand("")) +" "" call Decho("vim and netrw agree on current directory (g:netrw_keepdir=".g:netrw_keepdir.")",'~'.expand("")) +" "" call Decho("vim directory: ".getcwd(),'~'.expand("")) +" "" call Decho("netrw directory: ".(exists("b:netrw_curdir")? b:netrw_curdir : 'n/a'),'~'.expand("")) endif -" call Dret("s:NetrwFile ".ret) +" "" call Dret("s:NetrwFile ".ret) return ret endfun @@ -3960,31 +4143,72 @@ endfun " --------------------------------------------------------------------- -" s:NetrwGetBuffer: {{{2 +" s:NetrwGetBuffer: [get a new|find an old netrw] buffer for a netrw listing {{{2 " returns 0=cleared buffer " 1=re-used buffer (buffer not cleared) fun! s:NetrwGetBuffer(islocal,dirname) " call Dfunc("s:NetrwGetBuffer(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".g:netrw_liststyle) " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("")) -" call Decho("netrwbuf dictionary=".string(s:netrwbuf),'~'.expand("")) +" call Decho("netrwbuf dictionary=".(exists("s:netrwbuf")? string(s:netrwbuf) : 'n/a'),'~'.expand("")) +" call Dredir("ls!","s:NetrwGetBuffer") let dirname= a:dirname " re-use buffer if possible {{{3 " call Decho("--re-use a buffer if possible--",'~'.expand("")) if !exists("s:netrwbuf") +" call Decho(" s:netrwbuf initialized to {}",'~'.expand("")) let s:netrwbuf= {} endif - if has_key(s:netrwbuf,s:NetrwFullPath(dirname)) +" call Decho(" s:netrwbuf =".string(s:netrwbuf),'~'.expand("")) +" call Decho(" w:netrw_liststyle =".(exists("w:netrw_liststyle")? w:netrw_liststyle : "n/a"),'~'.expand("")) + + if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST + let bufnum = -1 + + if !empty(s:netrwbuf) && has_key(s:netrwbuf,s:NetrwFullPath(dirname)) + if has_key(s:netrwbuf,"NetrwTreeListing") + let bufnum= s:netrwbuf["NetrwTreeListing"] + else + let bufnum= s:netrwbuf[s:NetrwFullPath(dirname)] + endif +" call Decho(" NetrwTreeListing: bufnum#".bufnum,'~'.expand("")) + if !bufexists(bufnum) + call remove(s:netrwbuf,"NetrwTreeListing"]) + let bufnum= -1 + endif + elseif bufnr("NetrwTreeListing") != -1 + let bufnum= bufnr("NetrwTreeListing") +" call Decho(" NetrwTreeListing".": bufnum#".bufnum,'~'.expand("")) + else +" call Decho(" did not find a NetrwTreeListing buffer",'~'.expand("")) + let bufnum= -1 + endif + + elseif has_key(s:netrwbuf,s:NetrwFullPath(dirname)) let bufnum= s:netrwbuf[s:NetrwFullPath(dirname)] -" call Decho("lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnum) +" call Decho(" lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnum,'~'.expand("")) if !bufexists(bufnum) call remove(s:netrwbuf,s:NetrwFullPath(dirname)) let bufnum= -1 endif + else -" call Decho("lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."] not a key") +" call Decho(" lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."] not a key",'~'.expand("")) let bufnum= -1 endif +" call Decho(" bufnum#".bufnum,'~'.expand("")) + + " highjack the current buffer if + " it has the desired name + " it is empty +" call Decho("deciding if I can highjack the current buffer#".bufnr("%"),'~'.expand("")) +" call Decho("..dirname<".dirname.">",'~'.expand("")) +" call Decho("..bufname<".bufname("%").">",'~'.expand("")) +" call Decho("..getline($)<".getline("$").">",'~'.expand("")) + if dirname == bufname("%") && line("$") == 1 && getline("%") == "" +" call Dret("s:NetrwGetBuffer 0 : highjacking buffer#".bufnr("%")) + return 0 + endif " get enew buffer and name it -or- re-use buffer {{{3 if bufnum < 0 " get enew buffer and name it @@ -3995,14 +4219,8 @@ if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST " Got enew buffer; transform into a NetrwTreeListing " call Decho("--transform enew buffer#".bufnr("%")." into a NetrwTreeListing --",'~'.expand("")) - if !exists("s:netrw_treelistnum") - let s:netrw_treelistnum= 1 - else - let s:netrw_treelistnum= s:netrw_treelistnum + 1 - endif - let w:netrw_treebufnr= bufnr("%") -" call Decho(" exe sil! keepalt file NetrwTreeListing ".fnameescape(s:netrw_treelistnum),'~'.expand("")) - exe 'sil! keepalt file NetrwTreeListing\ '.fnameescape(s:netrw_treelistnum) + let w:netrw_treebufnr = bufnr("%") + call s:NetrwBufRename("NetrwTreeListing") if g:netrw_use_noswf setl nobl bt=nofile noswf else @@ -4012,15 +4230,9 @@ nnoremap ]] :sil call TreeListMove(']]') nnoremap [] :sil call TreeListMove('[]') nnoremap ][ :sil call TreeListMove('][') -" call Decho(" tree listing#".s:netrw_treelistnum." bufnr=".w:netrw_treebufnr,'~'.expand("")) +" call Decho(" tree listing bufnr=".w:netrw_treebufnr,'~'.expand("")) else -" let v:errmsg = "" " Decho - let escdirname = fnameescape(dirname) -" call Decho(" errmsg<".v:errmsg."> bufnr(escdirname<".escdirname.">)=".bufnr(escdirname)." bufname()<".bufname(bufnr(escdirname)).">",'~'.expand("")) -" call Decho(' exe sil! keepalt file '.escdirname,'~'.expand("")) -" let v:errmsg= "" " Decho - exe 'sil! keepj keepalt file '.escdirname -" call Decho(" errmsg<".v:errmsg."> bufnr(".escdirname.")=".bufnr(escdirname)."<".bufname(bufnr(escdirname)).">",'~'.expand("")) + call s:NetrwBufRename(dirname) " enter the new buffer into the s:netrwbuf dictionary let s:netrwbuf[s:NetrwFullPath(dirname)]= bufnr("%") " call Decho("update netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnr("%"),'~'.expand("")) @@ -4041,8 +4253,7 @@ endif " call Decho(" line($)=".line("$"),'~'.expand("")) if bufname("%") == '.' -" call Decho("exe sil! keepalt file ".fnameescape(getcwd()),'~'.expand("")) - exe "sil! NetrwKeepj keepalt file ".fnameescape(getcwd()) + call s:NetrwBufRename(getcwd()) endif let &ei= eikeep @@ -4066,6 +4277,7 @@ elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST " call Decho("--re-use tree listing--",'~'.expand("")) " call Decho(" clear buffer<".expand("%")."> with :%d",'~'.expand("")) + setl ma sil NetrwKeepj %d _ NetrwKeepj call s:NetrwListSettings(a:islocal) " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("")) @@ -4089,8 +4301,7 @@ " call Decho("--do netrw settings: make this buffer#".bufnr("%")." not-a-file, modifiable, not line-numbered, etc--",'~'.expand("")) let fname= expand("%") NetrwKeepj call s:NetrwListSettings(a:islocal) -" call Decho("exe sil! keepalt file ".fnameescape(fname),'~'.expand("")) - exe "sil! NetrwKeepj keepalt file ".fnameescape(fname) + call s:NetrwBufRename(fname) " delete all lines from buffer {{{3 " call Decho("--delete all lines from buffer--",'~'.expand("")) @@ -4148,7 +4359,7 @@ let curline= getline('.') if curline =~# '"\s*Sorted by\s' - NetrwKeepj norm s + NetrwKeepj norm! s let s:netrw_skipbrowse= 1 echo 'Pressing "s" also works' @@ -4157,11 +4368,11 @@ echo 'Press "S" to edit sorting sequence' elseif curline =~# '"\s*Quick Help:' - NetrwKeepj norm ? + NetrwKeepj norm! ? let s:netrw_skipbrowse= 1 elseif curline =~# '"\s*\%(Hiding\|Showing\):' - NetrwKeepj norm a + NetrwKeepj norm! a let s:netrw_skipbrowse= 1 echo 'Pressing "a" also works' @@ -4233,20 +4444,22 @@ endfun " --------------------------------------------------------------------- -" s:NetrwListSettings: make standard settings for a netrw listing {{{2 +" s:NetrwListSettings: make standard settings for making a netrw listing {{{2 +" g:netrw_bufsettings will be used after the listing is produced. +" Called by s:NetrwGetBuffer() fun! s:NetrwListSettings(islocal) " call Dfunc("s:NetrwListSettings(islocal=".a:islocal.")") " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("")) let fname= bufname("%") -" " call Decho("(NetrwListSettings) setl bt=nofile nobl ma nonu nowrap noro nornu",'~'.expand("")) - setl bt=nofile nobl ma nonu nowrap noro nornu -" call Decho("(NetrwListSettings) exe sil! keepalt file ".fnameescape(fname),'~'.expand("")) - exe "sil! keepalt file ".fnameescape(fname) +" " call Decho("setl bt=nofile nobl ma nonu nowrap noro nornu",'~'.expand("")) + " nobl noma nomod nonu noma nowrap ro nornu (std g:netrw_bufsettings) + setl bt=nofile nobl ma nonu nowrap noro nornu + call s:NetrwBufRename(fname) if g:netrw_use_noswf setl noswf endif -" call Dredir("ls!") -" call Decho("(NetrwListSettings) exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("")) +" call Dredir("ls!","s:NetrwListSettings") +" call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("")) exe "setl ts=".(g:netrw_maxfilenamelen+1) setl isk+=.,~,- if g:netrw_fastbrowse > a:islocal @@ -4259,7 +4472,7 @@ endfun " --------------------------------------------------------------------- -" s:NetrwListStyle: {{{2 +" s:NetrwListStyle: change list style (thin - long - wide - tree) {{{2 " islocal=0: remote browsing " =1: local browsing fun! s:NetrwListStyle(islocal) @@ -4275,6 +4488,12 @@ " call Decho("chgd w:netrw_liststyle to ".w:netrw_liststyle,'~'.expand("")) " call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">",'~'.expand("")) + " repoint t:netrw_lexbufnr if appropriate + if exists("t:netrw_lexbufnr") && bufnr("%") == t:netrw_lexbufnr +" call Decho("set repointlexbufnr to true!") + let repointlexbufnr= 1 + endif + if w:netrw_liststyle == s:THINLIST " use one column listing " call Decho("use one column list",'~'.expand("")) @@ -4316,6 +4535,12 @@ NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) NetrwKeepj call s:NetrwCursor() + " repoint t:netrw_lexbufnr if appropriate + if exists("repointlexbufnr") + let t:netrw_lexbufnr= bufnr("%") +" call Decho("repoint t:netrw_lexbufnr to #".t:netrw_lexbufnr) + endif + " restore position; keep cursor on the filename " call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("")) NetrwKeepj call winrestview(svpos) @@ -4339,12 +4564,14 @@ call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) " keep cursor on the filename - let fname= s:NetrwGetWord() - sil NetrwKeepj $ - let result= search('\%(^\%(|\+\s\)\=\|\s\{2,}\)\zs'.escape(fname,'.\[]*$^').'\%(\s\{2,}\|$\)','bc') -" call Decho("search result=".result." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'N/A'),'~'.expand("")) - if result <= 0 && exists("w:netrw_bannercnt") - exe "NetrwKeepj ".w:netrw_bannercnt + if g:netrw_banner && exists("w:netrw_bannercnt") && line(".") >= w:netrw_bannercnt + let fname= s:NetrwGetWord() + sil NetrwKeepj $ + let result= search('\%(^\%(|\+\s\)\=\|\s\{2,}\)\zs'.escape(fname,'.\[]*$^').'\%(\s\{2,}\|$\)','bc') +" " call Decho("search result=".result." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'N/A'),'~'.expand("")) + if result <= 0 && exists("w:netrw_bannercnt") + exe "NetrwKeepj ".w:netrw_bannercnt + endif endif let @@= ykeep " call Dret("s:NetrwBannerCtrl : g:netrw_banner=".g:netrw_banner) @@ -4435,7 +4662,7 @@ if !exists("s:netrw_menucnt") return endif -" call Dfunc("NetrwBookmarkMenu() histcnt=".g:netrw_dirhist_cnt." menucnt=".s:netrw_menucnt) +" call Dfunc("NetrwBookmarkMenu() histcnt=".g:netrw_dirhistcnt." menucnt=".s:netrw_menucnt) " the following test assures that gvim is running, has menus available, and has menus enabled. if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu @@ -4467,12 +4694,12 @@ " show directory browsing history if g:netrw_dirhistmax > 0 - let cnt = g:netrw_dirhist_cnt + let cnt = g:netrw_dirhistcnt let first = 1 let histcnt = 0 - while ( first || cnt != g:netrw_dirhist_cnt ) + while ( first || cnt != g:netrw_dirhistcnt ) let histcnt = histcnt + 1 - let priority = g:netrw_dirhist_cnt + histcnt + let priority = g:netrw_dirhistcnt + histcnt if exists("g:netrw_dirhist_{cnt}") let histdir= escape(g:netrw_dirhist_{cnt},g:netrw_menu_escape) " call Decho('sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.' :e '.histdir,'~'.expand("")) @@ -4506,7 +4733,7 @@ let @@= ykeep " call Decho("b:netrw_curdir doesn't exist!",'~'.expand("")) " call Decho("getcwd<".getcwd().">",'~'.expand("")) -" call Dredir("ls!") +" call Dredir("ls!","s:NetrwBrowseChgDir") " call Dret("s:NetrwBrowseChgDir") return endif @@ -4514,9 +4741,9 @@ " NetrwBrowseChgDir: save options and initialize {{{3 " call Decho("saving options",'~'.expand("")) - call s:SavePosn(s:netrw_nbcd) - NetrwKeepj call s:NetrwOptionSave("s:") - NetrwKeepj call s:NetrwSafeOptions() + call s:SavePosn(s:netrw_posn) + NetrwKeepj call s:NetrwOptionsSave("s:") + NetrwKeepj call s:NetrwOptionsSafe(a:islocal) if (has("win32") || has("win95") || has("win64") || has("win16")) let dirname = substitute(b:netrw_curdir,'\\','/','ge') else @@ -4526,9 +4753,10 @@ let dolockout = 0 let dorestore = 1 " call Decho("dirname<".dirname.">",'~'.expand("")) +" call Decho("newdir<".newdir.">",'~'.expand("")) " ignore s when done in the banner -" call Decho('ignore [return]s when done in banner (g:netrw_banner='.g:netrw_banner.")",'~'.expand("")) +" call Decho('(s:NetrwBrowseChgDir) ignore [return]s when done in banner (g:netrw_banner='.g:netrw_banner.")",'~'.expand("")) if g:netrw_banner " call Decho("w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a')." line(.)#".line('.')." line($)#".line("#"),'~'.expand("")) if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt && line("$") >= w:netrw_bannercnt @@ -4539,13 +4767,12 @@ setl ma noro nowrap NetrwKeepj call setline(line('.'),'" Quick Help: :help '.s:QuickHelp[g:netrw_quickhelp]) setl noma nomod nowrap - call s:RestorePosn(s:netrw_nbcd) - NetrwKeepj call s:NetrwOptionRestore("s:") + NetrwKeepj call s:NetrwOptionsRestore("s:") " call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("")) endif endif " else " Decho -" call Decho("(s:NetrwBrowseChgdir) g:netrw_banner=".g:netrw_banner." (no banner)",'~'.expand("")) +" call Decho("g:netrw_banner=".g:netrw_banner." (no banner)",'~'.expand("")) endif " set up o/s-dependent directory recognition pattern @@ -4568,7 +4795,7 @@ " ------------------------------ " NetrwBrowseChgDir: edit a file {{{3 " ------------------------------ -" call Decho('edit-a-file: case "handling a file": newdir<'.newdir.'> !~ dirpat<'.dirpat.">",'~'.expand("")) +" call Decho('(s:NetrwBrowseChgDir) edit-a-file: case "handling a file": newdir<'.newdir.'> !~ dirpat<'.dirpat.">",'~'.expand("")) " save position for benefit of Rexplore let s:rexposn_{bufnr("%")}= winsaveview() @@ -4580,6 +4807,9 @@ " call Decho("edit-a-file: handle tree listing: w:netrw_treedict<".(exists("w:netrw_treedict")? string(w:netrw_treedict) : 'n/a').">",'~'.expand("")) " call Decho("edit-a-file: newdir<".newdir.">",'~'.expand("")) let dirname= s:NetrwTreeDir(a:islocal) + "COMBAK : not working for a symlink -- but what about a regular file? a directory? +" call Decho("COMBAK : not working for a symlink -- but what about a regular file? a directory?") + " Feb 17, 2019: following if-else-endif restored -- wasn't editing a file in tree mode if dirname =~ '/$' let dirname= dirname.newdir else @@ -4597,7 +4827,7 @@ " this lets netrw#BrowseX avoid the edit if a:0 < 1 " call Decho("edit-a-file: (a:0=".a:0."<1) set up windows for editing<".fnameescape(dirname)."> didsplit=".(exists("s:didsplit")? s:didsplit : "doesn't exist"),'~'.expand("")) - NetrwKeepj call s:NetrwOptionRestore("s:") + NetrwKeepj call s:NetrwOptionsRestore("s:") let curdir= b:netrw_curdir if !exists("s:didsplit") " call Decho("edit-a-file: s:didsplit does not exist; g:netrw_browse_split=".string(g:netrw_browse_split)." win#".winnr(),'~'.expand("")) @@ -4712,14 +4942,14 @@ " call Decho('goto-newdir: case "just go to new directory spec": newdir<'.newdir.'>','~'.expand("")) let dirname = newdir NetrwKeepj call s:SetRexDir(a:islocal,dirname) - NetrwKeepj call s:NetrwOptionRestore("s:") + NetrwKeepj call s:NetrwOptionsRestore("s:") norm! m` elseif newdir == './' " --------------------------------------------- " NetrwBrowseChgDir: refresh the directory list {{{3 " --------------------------------------------- -" call Decho('refresh-dirlist: case "refresh directory listing": newdir == "./"','~'.expand("")) +" call Decho('(s:NetrwBrowseChgDir)refresh-dirlist: case "refresh directory listing": newdir == "./"','~'.expand("")) NetrwKeepj call s:SetRexDir(a:islocal,dirname) norm! m` @@ -4727,7 +4957,7 @@ " -------------------------------------- " NetrwBrowseChgDir: go up one directory {{{3 " -------------------------------------- -" call Decho('go-up: case "go up one directory": newdir == "../"','~'.expand("")) +" call Decho('(s:NetrwBrowseChgDir)go-up: case "go up one directory": newdir == "../"','~'.expand("")) if w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") " force a refresh @@ -4765,7 +4995,7 @@ else " unix or cygwin -" call Decho('go-up: case "go up one directory": newdir == "../" and unix or cygwin','~'.expand("")) +" call Decho('(s:NetrwBrowseChgDir)go-up: case "go up one directory": newdir == "../" and unix or cygwin','~'.expand("")) if a:islocal let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','') if dirname == "" @@ -4777,13 +5007,13 @@ " call Decho("go-up: unix: dirname<".dirname."> (go up one dir)",'~'.expand("")) endif NetrwKeepj call s:SetRexDir(a:islocal,dirname) - norm m` + norm! m` elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") " -------------------------------------- " NetrwBrowseChgDir: Handle Tree Listing {{{3 " -------------------------------------- -" call Decho('tree-list: case liststyle is TREELIST and w:netrw_treedict exists','~'.expand("")) +" call Decho('(s:NetrwBrowseChgDir)tree-list: case liststyle is TREELIST and w:netrw_treedict exists','~'.expand("")) " force a refresh (for TREELIST, NetrwTreeDir() will force the refresh) " call Decho("tree-list: setl noro ma",'~'.expand("")) setl noro ma @@ -4800,10 +5030,10 @@ " search treedict for tree dir as-is " call Decho("tree-list: search treedict for tree dir as-is",'~'.expand("")) if has_key(w:netrw_treedict,treedir) -" call Decho('tree-list: ....searched for treedir<'.treedir.'> : found it!','~'.expand("")) +" call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched for treedir<'.treedir.'> : found it!','~'.expand("")) let haskey= 1 else -" call Decho('tree-list: ....searched for treedir<'.treedir.'> : not found','~'.expand("")) +" call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched for treedir<'.treedir.'> : not found','~'.expand("")) endif " search treedict for treedir with a [/@] appended @@ -4811,10 +5041,10 @@ if !haskey && treedir !~ '[/@]$' if has_key(w:netrw_treedict,treedir."/") let treedir= treedir."/" -" call Decho('tree-list: ....searched.for treedir<'.treedir.'> found it!','~'.expand("")) +" call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched.for treedir<'.treedir.'> found it!','~'.expand("")) let haskey = 1 else -" call Decho('tree-list: ....searched for treedir<'.treedir.'/> : not found','~'.expand("")) +" call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched for treedir<'.treedir.'/> : not found','~'.expand("")) endif endif @@ -4823,10 +5053,10 @@ if !haskey && treedir =~ '/$' let treedir= substitute(treedir,'/$','','') if has_key(w:netrw_treedict,treedir) -" call Decho('tree-list: ....searched.for treedir<'.treedir.'> found it!','~'.expand("")) +" call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched.for treedir<'.treedir.'> found it!','~'.expand("")) let haskey = 1 else -" call Decho('tree-list: ....searched for treedir<'.treedir.'> : not found','~'.expand("")) +" call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched for treedir<'.treedir.'> : not found','~'.expand("")) endif endif @@ -4855,7 +5085,7 @@ let dirname = s:ComposePath(dirname,newdir) " call Decho("go down one dir: dirname<".dirname."> newdir<".newdir.">",'~'.expand("")) NetrwKeepj call s:SetRexDir(a:islocal,dirname) - norm m` + norm! m` endif " -------------------------------------- @@ -4865,11 +5095,10 @@ " dorestore is zero'd when a local file was hidden or bufhidden; " in such a case, we want to keep whatever settings it may have. " call Decho("doing option restore (dorestore=".dorestore.")",'~'.expand("")) - NetrwKeepj call s:NetrwOptionRestore("s:") + NetrwKeepj call s:NetrwOptionsRestore("s:") " else " Decho " call Decho("skipping option restore (dorestore==0): hidden=".&hidden." bufhidden=".&bufhidden." mod=".&mod,'~'.expand("")) endif - call s:RestorePosn(s:netrw_nbcd) if dolockout && dorestore " call Decho("restore: filewritable(dirname<".dirname.">)=".filewritable(dirname),'~'.expand("")) if filewritable(dirname) @@ -4884,6 +5113,7 @@ " call Decho("restore: ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("")) endif endif + call s:RestorePosn(s:netrw_posn) let @@= ykeep " call Dret("s:NetrwBrowseChgDir <".dirname."> : curpos<".string(getpos(".")).">") @@ -4905,10 +5135,6 @@ return endif - if !exists("w:netrw_liststyle") || w:netrw_liststyle != s:TREELIST - call s:SavePosn(s:netrw_nbcd) - endif - norm! 0 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") " call Decho("case: treestyle",'~'.expand("")) @@ -4916,28 +5142,40 @@ let swwline= winline() - 1 if exists("w:netrw_treetop") let b:netrw_curdir= w:netrw_treetop + elseif exists("b:netrw_curdir") + let w:netrw_treetop= b:netrw_curdir + else + let w:netrw_treetop= getcwd() + let b:netrw_curdir = w:netrw_treetop endif - let curdir= b:netrw_curdir + let curfile = getline(".") + let curpath = s:NetrwTreePath(w:netrw_treetop) if a:islocal call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../')) else call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../')) endif - if !search('\c^'.s:treedepthstring.curline,'cw') - if !search('\c^'.curline,'cw') - sil! NetrwKeepj 1 - endif +" call Decho("looking for curfile<^".s:treedepthstring.curfile.">",'~'.expand("")) +" call Decho("having curpath<".curpath.">",'~'.expand("")) + if w:netrw_treetop == '/' + keepj call search('^\M'.curfile,"w") + elseif curfile == '../' + keepj call search('^\M'.curfile,"wb") + else +" call Decho("search(^\\M".s:treedepthstring.curfile.") backwards")) + while 1 + keepj call search('^\M'.s:treedepthstring.curfile,"wb") + let treepath= s:NetrwTreePath(w:netrw_treetop) +" call Decho("..current treepath<".treepath.">",'~'.expand("")) + if treepath == curpath + break + endif + endwhile endif - exe "sil! NetrwKeepj norm! z\" - while winline() < swwline - let curwinline= winline() - exe "sil! NetrwKeepj norm! \" - if curwinline == winline() - break - endif - endwhile + else " call Decho("case: not treestyle",'~'.expand("")) + call s:SavePosn(s:netrw_posn) if exists("b:netrw_curdir") let curdir= b:netrw_curdir else @@ -4948,17 +5186,10 @@ else call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../')) endif - if has_key(s:netrw_nbcd,bufnr("%")) - call s:RestorePosn(s:netrw_nbcd) - elseif exists("w:netrw_bannercnt") -" call Decho("moving to line#".w:netrw_bannercnt,'~'.expand("")) - exe w:netrw_bannercnt - else - 1 - endif + call s:RestorePosn(s:netrw_posn) + let curdir= substitute(curdir,'^.*[\/]','','') + call search('\<'.curdir.'/','wc') endif - let curdir= substitute(curdir,'^.*[\/]','','') - call search('\<'.curdir.'\>','wc') " call Dret("s:NetrwBrowseUpDir") endfun @@ -4969,13 +5200,12 @@ fun! netrw#BrowseX(fname,remote) " call Dfunc("netrw#BrowseX(fname<".a:fname."> remote=".a:remote.")") - " if its really just a directory, then do a "gf" instead - if (a:remote == 0 && isdirectory(a:fname)) || (a:remote == 1 && fname =~ '/$' && fname !~ '^https\=:') + " if its really just a local directory, then do a "gf" instead + if (a:remote == 0 && isdirectory(a:fname)) || (a:remote == 1 && a:fname =~ '/$' && a:fname !~ '^https\=:') norm! gf -" call Dret("netrw#BrowseX : did gf instead") +" call Dret("(netrw#BrowseX) did gf instead") endif - let ykeep = @@ let screenposn = winsaveview() " call Decho("saving posn to screenposn<".string(screenposn).">",'~'.expand("")) @@ -5000,7 +5230,7 @@ endif endfor endif -" call Decho("restoring posn to screenposn<".string(screenposn).">,'~'.expand(""))" +" call Decho("restoring posn: screenposn<".string(screenposn).">,'~'.expand(""))" call winrestview(screenposn) let @@= ykeep let &aw= awkeep @@ -5015,6 +5245,9 @@ if has("win32") || has("win95") || has("win64") || has("win16") let exten= substitute(exten,'^.*$','\L&\E','') endif + if exten =~ "[\\/]" + let exten= "" + endif " call Decho("exten<".exten.">",'~'.expand("")) if a:remote == 1 @@ -5027,11 +5260,17 @@ let newname = substitute(s:netrw_tmpfile,'^\(.*\)/\(.*\)\.\([^.]*\)$','\1/'.basename.'.\3','') " call Decho("basename<".basename.">",'~'.expand("")) " call Decho("newname <".newname.">",'~'.expand("")) - if rename(s:netrw_tmpfile,newname) == 0 - " renaming succeeded - let fname= newname + if s:netrw_tmpfile != newname && newname != "" + if rename(s:netrw_tmpfile,newname) == 0 + " renaming succeeded +" call Decho("renaming succeeded (tmpfile<".s:netrw_tmpfile."> to <".newname.">)") + let fname= newname + else + " renaming failed +" call Decho("renaming failed (tmpfile<".s:netrw_tmpfile."> to <".newname.">)") + let fname= s:netrw_tmpfile + endif else - " renaming failed let fname= s:netrw_tmpfile endif else @@ -5098,7 +5337,7 @@ let ret= v:shell_error elseif has("win32") || has("win64") -" call Decho("windows",'~'.expand("")) +" call Decho("win".(has("win32")? "32" : "64")",'~'.expand("")) if executable("start") call s:NetrwExe('sil! !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1)) elseif executable("rundll32") @@ -5106,7 +5345,7 @@ else call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74) endif - call inputsave()|call input("Press to continue")|call inputrestore() + " call inputsave()|call input("Press to continue")|call inputrestore() let ret= v:shell_error elseif has("win32unix") @@ -5121,7 +5360,7 @@ else call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74) endif - call inputsave()|call input("Press to continue")|call inputrestore() + " call inputsave()|call input("Press to continue")|call inputrestore() let ret= v:shell_error elseif has("unix") && executable("kfmclient") && s:CheckIfKde() @@ -5134,6 +5373,11 @@ call s:NetrwExe("sil !setsid xdg-open ".s:ShellEscape(fname,1).redir) let ret= v:shell_error + elseif has("unix") && $DESKTOP_SESSION == "mate" && executable("atril") +" call Decho("unix and atril",'~'.expand("")) + call s:NetrwExe("sil !atril ".s:ShellEscape(fname,1).redir) + let ret= v:shell_error + elseif has("unix") && executable("xdg-open") " call Decho("unix and xdg-open",'~'.expand("")) call s:NetrwExe("sil !xdg-open ".s:ShellEscape(fname,1).redir) @@ -5184,22 +5428,76 @@ endfun " --------------------------------------------------------------------- +" netrw#GX: gets word under cursor for gx support {{{2 +" See also: netrw#BrowseXVis +" netrw#BrowseX +fun! netrw#GX() +" call Dfunc("netrw#GX()") + if &ft == "netrw" + let fname= s:NetrwGetWord() + else + let fname= expand((exists("g:netrw_gx")? g:netrw_gx : '')) + endif +" call Dret("netrw#GX <".fname.">") + return fname +endfun + +" --------------------------------------------------------------------- " netrw#BrowseXVis: used by gx in visual mode to select a file for browsing {{{2 fun! netrw#BrowseXVis() " call Dfunc("netrw#BrowseXVis()") let atkeep = @@ norm! gvy " call Decho("@@<".@@.">",'~'.expand("")) - call netrw#BrowseX(@@,netrw#CheckIfRemote()) + call netrw#BrowseX(@@,netrw#CheckIfRemote(@@)) let @@ = atkeep " call Dret("netrw#BrowseXVis") endfun " --------------------------------------------------------------------- +" s:NetrwBufRename: renames a buffer without the side effect of retaining an unlisted buffer having the old name {{{2 +" Using the file command on a "[No Name]" buffer does not seem to cause the old "[No Name]" buffer +" to become an unlisted buffer, so in that case don't bwipe it. +fun! s:NetrwBufRename(newname) +" call Dfunc("s:NetrwBufRename(newname<".a:newname.">) buf(%)#".bufnr("%")."<".bufname(bufnr("%")).">") +" call Dredir("ls!","s:NetrwBufRename (before rename)") + let oldbufname= bufname(bufnr("%")) +" call Decho("buf#".bufnr("%").": oldbufname<".oldbufname.">",'~'.expand("")) + + if oldbufname != a:newname +" call Decho("do buffer rename: oldbufname<".oldbufname."> ≠ a:newname<".a:newname.">",'~'.expand("")) + let b:junk= 1 +" call Decho("rename buffer: sil! keepj keepalt file ".fnameescape(a:newname),'~'.expand("")) + exe 'sil! keepj keepalt file '.fnameescape(a:newname) +" call Dredir("ls!","s:NetrwBufRename (before bwipe)") + let oldbufnr= bufnr(oldbufname) +" call Decho("oldbufname<".oldbufname."> oldbufnr#".oldbufnr,'~'.expand("")) +" call Decho("bufnr(%)=".bufnr("%"),'~'.expand("")) + if oldbufname != "" && oldbufnr != -1 && oldbufnr != bufnr("%") +" call Decho("bwipe ".oldbufnr,'~'.expand("")) + exe "bwipe! ".oldbufnr +" else " Decho +" call Decho("did *not* bwipe buf#".oldbufnr,'~'.expand("")) + endif +" call Dredir("ls!","s:NetrwBufRename (after rename)") +" else " Decho +" call Decho("oldbufname<".oldbufname."> == a:newname: did *not* rename",'~'.expand("")) + endif + +" call Dret("s:NetrwBufRename : buf#".bufnr("%").": oldname<".oldbufname."> newname<".a:newname."> expand(%)<".expand("%").">") +endfun + +" --------------------------------------------------------------------- " netrw#CheckIfRemote: returns 1 if current file looks like an url, 0 else {{{2 -fun! netrw#CheckIfRemote() -" call Dfunc("netrw#CheckIfRemote()") - if expand("%") =~ '^\a\{3,}://' +fun! netrw#CheckIfRemote(...) +" call Dfunc("netrw#CheckIfRemote() a:0=".a:0) + if a:0 > 0 + let curfile= a:1 + else + let curfile= expand("%") + endif +" call Decho("curfile<".curfile.">") + if curfile =~ '^\a\{3,}://' " call Dret("netrw#CheckIfRemote 1") return 1 else @@ -5465,17 +5763,23 @@ " call Dfunc("s:NetrwHidden()") let ykeep= @@ " save current position - let svpos= winsaveview() + let svpos = winsaveview() " call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("")) if g:netrw_list_hide =~ '\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+' - " remove pattern from hiding list + " remove .file pattern from hiding list +" call Decho("remove .file pattern from hiding list",'~'.expand("")) let g:netrw_list_hide= substitute(g:netrw_list_hide,'\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+','','') elseif s:Strlen(g:netrw_list_hide) >= 1 +" call Decho("add .file pattern from hiding list",'~'.expand("")) let g:netrw_list_hide= g:netrw_list_hide . ',\(^\|\s\s\)\zs\.\S\+' else +" call Decho("set .file pattern as hiding list",'~'.expand("")) let g:netrw_list_hide= '\(^\|\s\s\)\zs\.\S\+' endif + if g:netrw_list_hide =~ '^,' + let g:netrw_list_hide= strpart(g:netrw_list_hide,1) + endif " refresh screen and return to saved position NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) @@ -5489,7 +5793,7 @@ " s:NetrwHome: this function determines a "home" for saving bookmarks and history {{{2 fun! s:NetrwHome() if exists("g:netrw_home") - let home= g:netrw_home + let home= expand(g:netrw_home) else " go to vim plugin home for home in split(&rtp,',') + [''] @@ -5510,9 +5814,12 @@ endif " insure that the home directory exists if g:netrw_dirhistmax > 0 && !isdirectory(s:NetrwFile(home)) +" call Decho("insure that the home<".home."> directory exists") if exists("g:netrw_mkdir") +" call Decho("call system(".g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home)).")") call system(g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home))) else +" call Decho("mkdir(".home.")") call mkdir(home) endif endif @@ -5526,6 +5833,9 @@ if exists("s:netrwdrag") return endif + if &ft != "netrw" + return + endif " call Dfunc("s:NetrwLeftmouse(islocal=".a:islocal.")") let ykeep= @@ @@ -5573,6 +5883,9 @@ " --------------------------------------------------------------------- " s:NetrwCLeftmouse: used to select a file/directory for a target {{{2 fun! s:NetrwCLeftmouse(islocal) + if &ft != "netrw" + return + endif " call Dfunc("s:NetrwCLeftmouse(islocal=".a:islocal.")") call s:NetrwMarkFileTgt(a:islocal) " call Dret("s:NetrwCLeftmouse") @@ -5581,7 +5894,7 @@ " --------------------------------------------------------------------- " s:NetrwServerEdit: edit file in a server gvim, usually NETRWSERVER (implements ){{{2 " a:islocal=0 : not used, remote -" a:islocal=1 : no used, local +" a:islocal=1 : not used, local " a:islocal=2 : used, remote " a:islocal=3 : used, local fun! s:NetrwServerEdit(islocal,fname) @@ -5706,6 +6019,9 @@ " --------------------------------------------------------------------- " s:NetrwSLeftmouse: marks the file under the cursor. May be dragged to select additional files {{{2 fun! s:NetrwSLeftmouse(islocal) + if &ft != "netrw" + return + endif " call Dfunc("s:NetrwSLeftmouse(islocal=".a:islocal.")") let s:ngw= s:NetrwGetWord() @@ -5758,12 +6074,16 @@ " separated patterns given in g:netrw_list_hide fun! s:NetrwListHide() " call Dfunc("s:NetrwListHide() g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">") +" call Decho("initial: ".string(getline(w:netrw_bannercnt,'$'))) let ykeep= @@ +" call DechoBuf(bufnr("%"),"COMBAK#3") " find a character not in the "hide" string to use as a separator for :g and :v commands - " How-it-works: take the hiding command, convert it into a range. Duplicate - " characters don't matter. Remove all such characters from the '/~...90' - " string. Use the first character left as a separator character. + " How-it-works: take the hiding command, convert it into a range. + " Duplicate characters don't matter. + " Remove all such characters from the '/~@#...890' string. + " Use the first character left as a separator character. +" call Decho("find a character not in the hide string to use as a separator") let listhide= g:netrw_list_hide let sep = strpart(substitute('/~@#$%^&*{};:,<.>?|1234567890','['.escape(listhide,'-]^\').']','','ge'),1,1) " call Decho("sep=".sep,'~'.expand("")) @@ -5776,24 +6096,31 @@ let hide = listhide let listhide = "" endif +" call Decho("hide<".hide."> listhide<".listhide.'>','~'.expand("")) " Prune the list by hiding any files which match +" call Decho("prune the list by hiding any files which ",((g:netrw_hide == 1)? "" : "don't")." match hide<".hide.">") if g:netrw_hide == 1 -" call Decho("hiding<".hide."> listhide<".listhide.">",'~'.expand("")) +" call Decho("..hiding<".hide.">",'~'.expand("")) exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'d' elseif g:netrw_hide == 2 -" call Decho("showing<".hide."> listhide<".listhide.">",'~'.expand("")) +" call Decho("..showing<".hide.">",'~'.expand("")) exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'s@^@ /-KEEP-/ @' endif +" call Decho("..result: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("")) endwhile + if g:netrw_hide == 2 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$v@^ /-KEEP-/ @d' +" call Decho("..v KEEP: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("")) exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s@^\%( /-KEEP-/ \)\+@@e' +" call Decho("..g KEEP: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("")) endif " remove any blank lines that have somehow remained. " This seems to happen under Windows. exe 'sil! NetrwKeepj 1,$g@^\s*$@d' +" call DechoBuf(bufnr("%"),"COMBAK#4") let @@= ykeep " call Dret("s:NetrwListHide") @@ -5854,9 +6181,12 @@ endif else let netrw_origdir= s:NetrwGetcwd(1) - call s:NetrwLcd(b:netrw_curdir) + if s:NetrwLcd(b:netrw_curdir) +" call Dret("s:NetrwMakeDir : lcd failure") + return + endif " call Decho("netrw_origdir<".netrw_origdir.">: lcd b:netrw_curdir<".fnameescape(b:netrw_curdir).">",'~'.expand("")) - call s:NetrwExe("sil! !".g:netrw_localmkdir.' '.s:ShellEscape(newdirname,1)) + call s:NetrwExe("sil! !".g:netrw_localmkdir.g:netrw_localmkdiropt.' '.s:ShellEscape(newdirname,1)) if v:shell_error != 0 let @@= ykeep call netrw#ErrorMsg(s:ERROR,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80) @@ -5865,7 +6195,10 @@ endif if !g:netrw_keepdir " call Decho("restoring netrw_origdir since g:netrw_keepdir=".g:netrw_keepdir,'~'.expand("")) - call s:NetrwLcd(netrw_origdir) + if s:NetrwLcd(netrw_origdir) +" call Dret("s:NetrwBrowse : lcd failure") + return + endif endif endif @@ -5977,6 +6310,7 @@ fun! s:NetrwMaps(islocal) " call Dfunc("s:NetrwMaps(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">") + " mouse maps: {{{3 if g:netrw_mousemaps && g:netrw_retmap " call Decho("set up Rexplore 2-leftmouse",'~'.expand("")) if !hasmapto("NetrwReturn") @@ -5992,22 +6326,87 @@ " call Decho("made NetrwReturn map",'~'.expand("")) endif + " generate default maps {{{3 + if !hasmapto('NetrwHide') |nmap a NetrwHide_a|endif + if !hasmapto('NetrwBrowseUpDir') |nmap - NetrwBrowseUpDir |endif + if !hasmapto('NetrwOpenFile') |nmap % NetrwOpenFile|endif + if !hasmapto('NetrwBadd_cb') |nmap cb NetrwBadd_cb|endif + if !hasmapto('NetrwBadd_cB') |nmap cB NetrwBadd_cB|endif + if !hasmapto('NetrwLcd') |nmap cd NetrwLcd|endif + if !hasmapto('NetrwSetChgwin') |nmap C NetrwSetChgwin|endif + if !hasmapto('NetrwRefresh') |nmap NetrwRefresh|endif + if !hasmapto('NetrwLocalBrowseCheck') |nmap NetrwLocalBrowseCheck|endif + if !hasmapto('NetrwServerEdit') |nmap NetrwServerEdit|endif + if !hasmapto('NetrwMakeDir') |nmap d NetrwMakeDir|endif + if !hasmapto('NetrwBookHistHandler_gb')|nmap gb NetrwBookHistHandler_gb|endif +" --------------------------------------------------------------------- +" if !hasmapto('NetrwForceChgDir') |nmap gd NetrwForceChgDir|endif +" if !hasmapto('NetrwForceFile') |nmap gf NetrwForceFile|endif +" if !hasmapto('NetrwHidden') |nmap gh NetrwHidden|endif +" if !hasmapto('NetrwSetTreetop') |nmap gn NetrwSetTreetop|endif +" if !hasmapto('NetrwChgPerm') |nmap gp NetrwChgPerm|endif +" if !hasmapto('NetrwBannerCtrl') |nmap I NetrwBannerCtrl|endif +" if !hasmapto('NetrwListStyle') |nmap i NetrwListStyle|endif +" if !hasmapto('NetrwMarkMoveMF2Arglist')|nmap ma NetrwMarkMoveMF2Arglist|endif +" if !hasmapto('NetrwMarkMoveArglist2MF')|nmap mA NetrwMarkMoveArglist2MF|endif +" if !hasmapto('NetrwBookHistHandler_mA')|nmap mb NetrwBookHistHandler_mA|endif +" if !hasmapto('NetrwBookHistHandler_mB')|nmap mB NetrwBookHistHandler_mB|endif +" if !hasmapto('NetrwMarkFileCopy') |nmap mc NetrwMarkFileCopy|endif +" if !hasmapto('NetrwMarkFileDiff') |nmap md NetrwMarkFileDiff|endif +" if !hasmapto('NetrwMarkFileEdit') |nmap me NetrwMarkFileEdit|endif +" if !hasmapto('NetrwMarkFile') |nmap mf NetrwMarkFile|endif +" if !hasmapto('NetrwUnmarkList') |nmap mF NetrwUnmarkList|endif +" if !hasmapto('NetrwMarkFileGrep') |nmap mg NetrwMarkFileGrep|endif +" if !hasmapto('NetrwMarkHideSfx') |nmap mh NetrwMarkHideSfx|endif +" if !hasmapto('NetrwMarkFileMove') |nmap mm NetrwMarkFileMove|endif +" if !hasmapto('NetrwMarkFilePrint') |nmap mp NetrwMarkFilePrint|endif +" if !hasmapto('NetrwMarkFileRegexp') |nmap mr NetrwMarkFileRegexp|endif +" if !hasmapto('NetrwMarkFileSource') |nmap ms NetrwMarkFileSource|endif +" if !hasmapto('NetrwMarkFileTag') |nmap mT NetrwMarkFileTag|endif +" if !hasmapto('NetrwMarkFileTgt') |nmap mt NetrwMarkFileTgt|endif +" if !hasmapto('NetrwUnMarkFile') |nmap mu NetrwUnMarkFile|endif +" if !hasmapto('NetrwMarkFileVimCmd') |nmap mv NetrwMarkFileVimCmd|endif +" if !hasmapto('NetrwMarkFileExe_mx') |nmap mx NetrwMarkFileExe_mx|endif +" if !hasmapto('NetrwMarkFileExe_mX') |nmap mX NetrwMarkFileExe_mX|endif +" if !hasmapto('NetrwMarkFileCompress') |nmap mz NetrwMarkFileCompress|endif +" if !hasmapto('NetrwObtain') |nmap O NetrwObtain|endif +" if !hasmapto('NetrwSplit_o') |nmap o NetrwSplit_o|endif +" if !hasmapto('NetrwPreview') |nmap p NetrwPreview|endif +" if !hasmapto('NetrwPrevWinOpen') |nmap P NetrwPrevWinOpen|endif +" if !hasmapto('NetrwBookHistHandler_qb')|nmap qb NetrwBookHistHandler_qb|endif +" if !hasmapto('NetrwFileInfo') |nmap qf NetrwFileInfo|endif +" if !hasmapto('NetrwMarkFileQFEL_qF') |nmap qF NetrwMarkFileQFEL_qF|endif +" if !hasmapto('NetrwMarkFileQFEL_qL') |nmap qL NetrwMarkFileQFEL_qL|endif +" if !hasmapto('NetrwSortStyle') |nmap s NetrwSortStyle|endif +" if !hasmapto('NetSortSequence') |nmap S NetSortSequence|endif +" if !hasmapto('NetrwSetTgt_Tb') |nmap Tb NetrwSetTgt_Tb|endif +" if !hasmapto('NetrwSetTgt_Th') |nmap Th NetrwSetTgt_Th|endif +" if !hasmapto('NetrwSplit_t') |nmap t NetrwSplit_t|endif +" if !hasmapto('NetrwBookHistHandler_u') |nmap u NetrwBookHistHandler_u|endif +" if !hasmapto('NetrwBookHistHandler_U') |nmap U NetrwBookHistHandler_U|endif +" if !hasmapto('NetrwSplit_v') |nmap v NetrwSplit_v|endif +" if !hasmapto('NetrwBrowseX') |nmap x NetrwBrowseX|endif +" if !hasmapto('NetrwLocalExecute') |nmap X NetrwLocalExecute|endif + if a:islocal " call Decho("make local maps",'~'.expand("")) - " local normal-mode maps - nnoremap a :call NetrwHide(1) - nnoremap - :call NetrwBrowseUpDir(1) - nnoremap % :call NetrwOpenFile(1) - nnoremap c :call NetrwLcd(b:netrw_curdir) - nnoremap C :call NetrwSetChgwin() - nnoremap :call netrw#LocalBrowseCheck(NetrwBrowseChgDir(1,NetrwGetWord())) - nnoremap :call NetrwServerEdit(3,NetrwGetWord()) - nnoremap d :call NetrwMakeDir("") - nnoremap gb :call NetrwBookHistHandler(1,b:netrw_curdir) + " local normal-mode maps {{{3 + nnoremap NetrwHide_a :call NetrwHide(1) + nnoremap NetrwBrowseUpDir :call NetrwBrowseUpDir(1) + nnoremap NetrwOpenFile :call NetrwOpenFile(1) + nnoremap NetrwBadd_cb :call NetrwBadd(1,0) + nnoremap NetrwBadd_cB :call NetrwBadd(1,1) + nnoremap NetrwLcd :call NetrwLcd(b:netrw_curdir) + nnoremap NetrwSetChgwin :call NetrwSetChgwin() + nnoremap NetrwLocalBrowseCheck :call netrw#LocalBrowseCheck(NetrwBrowseChgDir(1,NetrwGetWord())) + nnoremap NetrwServerEdit :call NetrwServerEdit(3,NetrwGetWord()) + nnoremap NetrwMakeDir :call NetrwMakeDir("") + nnoremap NetrwBookHistHandler_gb :call NetrwBookHistHandler(1,b:netrw_curdir) +" --------------------------------------------------------------------- nnoremap gd :call NetrwForceChgDir(1,NetrwGetWord()) nnoremap gf :call NetrwForceFile(1,NetrwGetWord()) nnoremap gh :call NetrwHidden(1) - nnoremap gn :call netrw#SetTreetop(NetrwGetWord()) + nnoremap gn :call netrw#SetTreetop(0,NetrwGetWord()) nnoremap gp :call NetrwChgPerm(1,b:netrw_curdir) nnoremap I :call NetrwBannerCtrl(1) nnoremap i :call NetrwListStyle(1) @@ -6041,7 +6440,6 @@ nnoremap qf :call NetrwFileInfo(1,NetrwGetWord()) nnoremap qF :call NetrwMarkFileQFEL(1,getqflist()) nnoremap qL :call NetrwMarkFileQFEL(1,getloclist(v:count)) - nnoremap r :let g:netrw_sort_direction= (g:netrw_sort_direction =~# 'n')? 'r' : 'n'exe "norm! 0"call NetrwRefresh(1,NetrwBrowseChgDir(1,'./')) nnoremap s :call NetrwSortStyle(1) nnoremap S :call NetSortSequence(1) nnoremap Tb :call NetrwSetTgt(1,'b',v:count1) @@ -6052,104 +6450,44 @@ nnoremap v :call NetrwSplit(5) nnoremap x :call netrw#BrowseX(NetrwBrowseChgDir(1,NetrwGetWord(),0),0)" nnoremap X :call NetrwLocalExecute(expand(""))" -" " local insert-mode maps -" inoremap a :call NetrwHide(1) -" inoremap c :exe "NetrwKeepj lcd ".fnameescape(b:netrw_curdir) -" inoremap c :call NetrwLcd(b:netrw_curdir) -" inoremap C :call NetrwSetChgwin() -" inoremap % :call NetrwOpenFile(1) -" inoremap - :call NetrwBrowseUpDir(1) -" inoremap :call netrw#LocalBrowseCheck(NetrwBrowseChgDir(1,NetrwGetWord())) -" inoremap d :call NetrwMakeDir("") -" inoremap gb :call NetrwBookHistHandler(1,b:netrw_curdir) -" inoremap gh :call NetrwHidden(1) -" nnoremap gn :call netrw#SetTreetop(NetrwGetWord()) -" inoremap gp :call NetrwChgPerm(1,b:netrw_curdir) -" inoremap I :call NetrwBannerCtrl(1) -" inoremap i :call NetrwListStyle(1) -" inoremap mb :call NetrwBookHistHandler(0,b:netrw_curdir) -" inoremap mB :call NetrwBookHistHandler(6,b:netrw_curdir) -" inoremap mc :call NetrwMarkFileCopy(1) -" inoremap md :call NetrwMarkFileDiff(1) -" inoremap me :call NetrwMarkFileEdit(1) -" inoremap mf :call NetrwMarkFile(1,NetrwGetWord()) -" inoremap mg :call NetrwMarkFileGrep(1) -" inoremap mh :call NetrwMarkHideSfx(1) -" inoremap mm :call NetrwMarkFileMove(1) -" inoremap mp :call NetrwMarkFilePrint(1) -" inoremap mr :call NetrwMarkFileRegexp(1) -" inoremap ms :call NetrwMarkFileSource(1) -" inoremap mT :call NetrwMarkFileTag(1) -" inoremap mt :call NetrwMarkFileTgt(1) -" inoremap mu :call NetrwUnMarkFile(1) -" inoremap mv :call NetrwMarkFileVimCmd(1) -" inoremap mx :call NetrwMarkFileExe(1,0) -" inoremap mX :call NetrwMarkFileExe(1,1) -" inoremap mz :call NetrwMarkFileCompress(1) -" inoremap O :call NetrwObtain(1) -" inoremap o :call NetrwSplit(3) -" inoremap p :call NetrwPreview(NetrwBrowseChgDir(1,NetrwGetWord(),1)) -" inoremap P :call NetrwPrevWinOpen(1) -" inoremap qb :call NetrwBookHistHandler(2,b:netrw_curdir) -" inoremap qf :call NetrwFileInfo(1,NetrwGetWord()) -" inoremap qF :call NetrwMarkFileQFEL(1,getqflist()) -" inoremap qL :call NetrwMarkFileQFEL(1,getloclist(v:count)) -" inoremap r :let g:netrw_sort_direction= (g:netrw_sort_direction =~# 'n')? 'r' : 'n'exe "norm! 0"call NetrwRefresh(1,NetrwBrowseChgDir(1,'./')) -" inoremap s :call NetrwSortStyle(1) -" inoremap S :call NetSortSequence(1) -" inoremap t :call NetrwSplit(4) -" inoremap Tb :call NetrwSetTgt(1,'b',v:count1) -" inoremap Th :call NetrwSetTgt(1,'h',v:count) -" inoremap u :call NetrwBookHistHandler(4,expand("%")) -" inoremap U :call NetrwBookHistHandler(5,expand("%")) -" inoremap v :call NetrwSplit(5) -" inoremap x :call netrw#BrowseX(NetrwBrowseChgDir(1,NetrwGetWord(),0),0)" + + nnoremap r :let g:netrw_sort_direction= (g:netrw_sort_direction =~# 'n')? 'r' : 'n'exe "norm! 0"call NetrwRefresh(1,NetrwBrowseChgDir(1,'./')) if !hasmapto('NetrwHideEdit') nmap NetrwHideEdit -" imap NetrwHideEdit endif nnoremap NetrwHideEdit :call NetrwHideEdit(1) if !hasmapto('NetrwRefresh') nmap NetrwRefresh -" imap NetrwRefresh endif nnoremap NetrwRefresh :call NetrwRefresh(1,NetrwBrowseChgDir(1,(w:netrw_liststyle == 3)? w:netrw_treetop : './')) if s:didstarstar || !mapcheck("","n") nnoremap :Nexplore -" inoremap :Nexplore endif if s:didstarstar || !mapcheck("","n") nnoremap :Pexplore -" inoremap :Pexplore endif if !hasmapto('NetrwTreeSqueeze') nmap NetrwTreeSqueeze -" imap NetrwTreeSqueeze endif nnoremap NetrwTreeSqueeze :call TreeSqueezeDir(1) let mapsafecurdir = escape(b:netrw_curdir, s:netrw_map_escape) if g:netrw_mousemaps == 1 - nmap NetrwLeftmouse + nmap NetrwLeftmouse + nmap NetrwCLeftmouse + nmap NetrwMiddlemouse + nmap NetrwSLeftmouse + nmap NetrwSLeftdrag + nmap <2-leftmouse> Netrw2Leftmouse + imap ILeftmouse + imap IMiddlemouse nno NetrwLeftmouse :call NetrwLeftmouse(1) - nmap NetrwCLeftmouse nno NetrwCLeftmouse :call NetrwCLeftmouse(1) - nmap NetrwMiddlemouse nno NetrwMiddlemouse :call NetrwPrevWinOpen(1) - nmap NetrwSLeftmouse nno NetrwSLeftmouse :call NetrwSLeftmouse(1) - nmap NetrwSLeftdrag nno NetrwSLeftdrag :call NetrwSLeftdrag(1) - nmap <2-leftmouse> Netrw2Leftmouse nmap Netrw2Leftmouse - - imap ILeftmouse -" ino ILeftmouse :call NetrwLeftmouse(1) - imap IMiddlemouse -" ino IMiddlemouse :call NetrwPrevWinOpen(1) -" imap ISLeftmouse -" ino ISLeftmouse :call NetrwMarkFile(1,NetrwGetWord()) exe 'nnoremap :call NetrwLocalRm("'.mapsafecurdir.'")' exe 'vnoremap :call NetrwLocalRm("'.mapsafecurdir.'")' -" exe 'inoremap :call NetrwLocalRm("'.mapsafecurdir.'")' endif exe 'nnoremap :call NetrwLocalRm("'.mapsafecurdir.'")' exe 'nnoremap D :call NetrwLocalRm("'.mapsafecurdir.'")' @@ -6158,27 +6496,27 @@ exe 'vnoremap :call NetrwLocalRm("'.mapsafecurdir.'")' exe 'vnoremap D :call NetrwLocalRm("'.mapsafecurdir.'")' exe 'vnoremap R :call NetrwLocalRename("'.mapsafecurdir.'")' -" exe 'inoremap :call NetrwLocalRm("'.mapsafecurdir.'")' -" exe 'inoremap D :call NetrwLocalRm("'.mapsafecurdir.'")' -" exe 'inoremap R :call NetrwLocalRename("'.mapsafecurdir.'")' -" exe 'inoremap d :call NetrwMakeDir("")' nnoremap :he netrw-quickhelp " support user-specified maps call netrw#UserMaps(1) - else " remote + else + " remote normal-mode maps {{{3 " call Decho("make remote maps",'~'.expand("")) call s:RemotePathAnalysis(b:netrw_curdir) - " remote normal-mode maps - nnoremap a :call NetrwHide(0) - nnoremap - :call NetrwBrowseUpDir(0) - nnoremap % :call NetrwOpenFile(0) - nnoremap C :call NetrwSetChgwin() - nnoremap :call NetrwRefresh(0,NetrwBrowseChgDir(0,'./')) - nnoremap :call NetrwBrowse(0,NetrwBrowseChgDir(0,NetrwGetWord())) - nnoremap :call NetrwServerEdit(2,NetrwGetWord()) - nnoremap gb :call NetrwBookHistHandler(1,b:netrw_curdir) + nnoremap NetrwHide_a :call NetrwHide(0) + nnoremap NetrwBrowseUpDir :call NetrwBrowseUpDir(0) + nnoremap NetrwOpenFile :call NetrwOpenFile(0) + nnoremap NetrwBadd_cb :call NetrwBadd(0,0) + nnoremap NetrwBadd_cB :call NetrwBadd(0,1) + nnoremap NetrwLcd :call NetrwLcd(b:netrw_curdir) + nnoremap NetrwSetChgwin :call NetrwSetChgwin() + nnoremap NetrwRefresh :call NetrwRefresh(0,NetrwBrowseChgDir(0,'./')) + nnoremap NetrwLocalBrowseCheck :call NetrwBrowse(0,NetrwBrowseChgDir(0,NetrwGetWord())) + nnoremap NetrwServerEdit :call NetrwServerEdit(2,NetrwGetWord()) + nnoremap NetrwBookHistHandler_gb :call NetrwBookHistHandler(1,b:netrw_curdir) +" --------------------------------------------------------------------- nnoremap gd :call NetrwForceChgDir(0,NetrwGetWord()) nnoremap gf :call NetrwForceFile(0,NetrwGetWord()) nnoremap gh :call NetrwHidden(0) @@ -6225,69 +6563,15 @@ nnoremap U :call NetrwBookHistHandler(5,b:netrw_curdir) nnoremap v :call NetrwSplit(2) nnoremap x :call netrw#BrowseX(NetrwBrowseChgDir(0,NetrwGetWord()),1) -" " remote insert-mode maps -" inoremap :call NetrwBrowse(0,NetrwBrowseChgDir(0,NetrwGetWord())) -" inoremap :call NetrwRefresh(0,NetrwBrowseChgDir(0,'./')) -" inoremap :call TreeSqueezeDir(0) -" inoremap - :call NetrwBrowseUpDir(0) -" inoremap a :call NetrwHide(0) -" inoremap mb :call NetrwBookHistHandler(0,b:netrw_curdir) -" inoremap mc :call NetrwMarkFileCopy(0) -" inoremap md :call NetrwMarkFileDiff(0) -" inoremap me :call NetrwMarkFileEdit(0) -" inoremap mf :call NetrwMarkFile(0,NetrwGetWord()) -" inoremap mg :call NetrwMarkFileGrep(0) -" inoremap mh :call NetrwMarkHideSfx(0) -" inoremap mm :call NetrwMarkFileMove(0) -" inoremap mp :call NetrwMarkFilePrint(0) -" inoremap mr :call NetrwMarkFileRegexp(0) -" inoremap ms :call NetrwMarkFileSource(0) -" inoremap mt :call NetrwMarkFileTgt(0) -" inoremap mT :call NetrwMarkFileTag(0) -" inoremap mu :call NetrwUnMarkFile(0) -" nnoremap mv :call NetrwMarkFileVimCmd(1) -" inoremap mx :call NetrwMarkFileExe(0,0) -" inoremap mX :call NetrwMarkFileExe(0,1) -" inoremap mv :call NetrwMarkFileVimCmd(0) -" inoremap mz :call NetrwMarkFileCompress(0) -" inoremap gb :call NetrwBookHistHandler(1,b:netrw_curdir) -" inoremap gh :call NetrwHidden(0) -" inoremap gp :call NetrwChgPerm(0,b:netrw_curdir) -" inoremap C :call NetrwSetChgwin() -" inoremap i :call NetrwListStyle(0) -" inoremap I :call NetrwBannerCtrl(1) -" inoremap o :call NetrwSplit(0) -" inoremap O :call NetrwObtain(0) -" inoremap p :call NetrwPreview(NetrwBrowseChgDir(1,NetrwGetWord(),1)) -" inoremap P :call NetrwPrevWinOpen(0) -" inoremap qb :call NetrwBookHistHandler(2,b:netrw_curdir) -" inoremap mB :call NetrwBookHistHandler(6,b:netrw_curdir) -" inoremap qf :call NetrwFileInfo(0,NetrwGetWord()) -" inoremap qF :call NetrwMarkFileQFEL(0,getqflist()) -" inoremap qL :call NetrwMarkFileQFEL(0,getloclist(v:count)) -" inoremap r :let g:netrw_sort_direction= (g:netrw_sort_direction =~# 'n')? 'r' : 'n'exe "norm! 0"call NetrwBrowse(0,NetrwBrowseChgDir(0,'./')) -" inoremap s :call NetrwSortStyle(0) -" inoremap S :call NetSortSequence(0) -" inoremap t :call NetrwSplit(1) -" inoremap Tb :call NetrwSetTgt('b',v:count1) -" inoremap Th :call NetrwSetTgt('h',v:count) -" inoremap u :call NetrwBookHistHandler(4,b:netrw_curdir) -" inoremap U :call NetrwBookHistHandler(5,b:netrw_curdir) -" inoremap v :call NetrwSplit(2) -" inoremap x :call netrw#BrowseX(NetrwBrowseChgDir(0,NetrwGetWord()),1) -" inoremap % :call NetrwOpenFile(0) if !hasmapto('NetrwHideEdit') nmap NetrwHideEdit -" imap NetrwHideEdit endif nnoremap NetrwHideEdit :call NetrwHideEdit(0) if !hasmapto('NetrwRefresh') nmap NetrwRefresh -" imap NetrwRefresh endif if !hasmapto('NetrwTreeSqueeze') nmap NetrwTreeSqueeze -" imap NetrwTreeSqueeze endif nnoremap NetrwTreeSqueeze :call TreeSqueezeDir(0) @@ -6309,14 +6593,10 @@ nmap <2-leftmouse> Netrw2Leftmouse nmap Netrw2Leftmouse - imap ILeftmouse -" ino ILeftmouse :call NetrwLeftmouse(0) imap IMiddlemouse -" ino IMiddlemouse :call NetrwPrevWinOpen(0) imap ISLeftmouse -" ino ISLeftmouse :call NetrwMarkFile(0,NetrwGetWord()) exe 'nnoremap :call NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")' exe 'vnoremap :call NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")' -" exe 'inoremap :call NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")' endif exe 'nnoremap :call NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")' exe 'nnoremap d :call NetrwMakeDir("'.mapsafeusermach.'")' @@ -6325,16 +6605,11 @@ exe 'vnoremap :call NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")' exe 'vnoremap D :call NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")' exe 'vnoremap R :call NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")' -" exe 'inoremap :call NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")' -" exe 'inoremap d :call NetrwMakeDir("'.mapsafeusermach.'")' -" exe 'inoremap D :call NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")' -" exe 'inoremap R :call NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")' nnoremap :he netrw-quickhelp -" inoremap :he netrw-quickhelp " support user-specified maps call netrw#UserMaps(0) - endif + endif " }}}3 " call Dret("s:NetrwMaps") endfun @@ -6531,14 +6806,16 @@ endif " set up 2match'ing to netrwmarkfilemtch_# list - if exists("s:netrwmarkfilemtch_{curbufnr}") && s:netrwmarkfilemtch_{curbufnr} != "" -" call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/",'~'.expand("")) - if exists("g:did_drchip_netrwlist_syntax") - exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/" + if has("syntax") && exists("g:syntax_on") && g:syntax_on + if exists("s:netrwmarkfilemtch_{curbufnr}") && s:netrwmarkfilemtch_{curbufnr} != "" +" " call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/",'~'.expand("")) + if exists("g:did_drchip_netrwlist_syntax") + exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/" + endif + else +" " call Decho("2match none",'~'.expand("")) + 2match none endif - else -" call Decho("2match none",'~'.expand("")) - 2match none endif let @@= ykeep " call Dret("s:NetrwMarkFile : s:netrwmarkfilelist_".curbufnr."<".(exists("s:netrwmarkfilelist_{curbufnr}")? string(s:netrwmarkfilelist_{curbufnr}) : " doesn't exist").">") @@ -6624,18 +6901,15 @@ if g:netrw_keepdir let fname= s:ShellEscape(s:ComposePath(curdir,fname)) endif - else - let fname= s:ShellEscape(b:netrw_curdir.fname,1) - endif - if executable(exe) - if a:islocal - call system(exe." ".fname) - else - NetrwKeepj call s:RemoteSystem(exe." ".fname) + call system(exe." ".fname) + if v:shell_error + NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to apply<".exe."> to file<".fname.">",50) endif else - NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to apply<".exe."> to file<".fname.">",50) + let fname= s:ShellEscape(b:netrw_curdir.fname,1) + NetrwKeepj call s:RemoteSystem(exe." ".fname) endif + endif unlet sfx @@ -6644,6 +6918,9 @@ elseif a:islocal " fname not a compressed file, so compress it call system(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,fname))) + if v:shell_error + call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_compress<".g:netrw_compress."> to something that works",104) + endif else " fname not a compressed file, so compress it NetrwKeepj call s:RemoteSystem(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(fname)) @@ -6695,7 +6972,7 @@ if a:islocal && s:netrwmftgt_islocal " Copy marked files, local directory to local directory " call Decho("copy from local to local",'~'.expand("")) - if !executable(g:netrw_localcopycmd) && g:netrw_localcopycmd !~ '^'.expand("$COMSPEC").'\s' + if !executable(g:netrw_localcopycmd) call netrw#ErrorMsg(s:ERROR,"g:netrw_localcopycmd<".g:netrw_localcopycmd."> not executable on your system, aborting",91) " call Dfunc("s:NetrwMarkFileMove : g:netrw_localcopycmd<".g:netrw_localcopycmd."> n/a!") return @@ -6777,10 +7054,10 @@ " call Decho("tgt <".tgt.">",'~'.expand("")) " call Decho("copycmd<".copycmd.">",'~'.expand("")) " call Decho("system(".copycmd." '".args."' '".tgt."')",'~'.expand("")) - call system(copycmd." '".args."' '".tgt."'") + call system(copycmd.g:netrw_localcopycmdopt." '".args."' '".tgt."'") if v:shell_error != 0 if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir - call netrw#ErrorMsg(s:ERROR,"copy failed; perhaps due to vim's current directory<".getcwd()."> not matching netrw's (".b:netrw_curdir.") (see :help netrw-c)",101) + call netrw#ErrorMsg(s:ERROR,"copy failed; perhaps due to vim's current directory<".getcwd()."> not matching netrw's (".b:netrw_curdir.") (see :help netrw-cd)",101) else call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localcopycmd<".g:netrw_localcopycmd.">; it doesn't work!",80) endif @@ -6809,7 +7086,7 @@ if exists("*mkdir") call mkdir(tmpdir) else - call s:NetrwExe("sil! !".g:netrw_localmkdir.' '.s:ShellEscape(tmpdir,1)) + call s:NetrwExe("sil! !".g:netrw_localmkdir.g:netrw_localmkdiropt.' '.s:ShellEscape(tmpdir,1)) if v:shell_error != 0 call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80) " call Dret("s:NetrwMarkFileCopy : failed: sil! !".g:netrw_localmkdir.' '.s:ShellEscape(tmpdir,1) ) @@ -6817,7 +7094,10 @@ endif endif if isdirectory(s:NetrwFile(tmpdir)) - call s:NetrwLcd(tmpdir) + if s:NetrwLcd(tmpdir) +" call Dret("s:NetrwMarkFileCopy : lcd failure") + return + endif NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},tmpdir) let localfiles= map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),'substitute(v:val,"^.*/","","")') NetrwKeepj call s:NetrwUpload(localfiles,s:netrwmftgt) @@ -6825,9 +7105,12 @@ for fname in s:netrwmarkfilelist_{bufnr('%')} NetrwKeepj call s:NetrwDelete(fname) endfor - call s:NetrwLcd(curdir) - if v:version < 704 || !has("patch1109") - call s:NetrwExe("sil !".g:netrw_localrmdir." ".s:ShellEscape(tmpdir,1)) + if s:NetrwLcd(curdir) +" call Dret("s:NetrwMarkFileCopy : lcd failure") + return + endif + if v:version < 704 || (v:version == 704 && !has("patch1107")) + call s:NetrwExe("sil !".g:netrw_localrmdir.g:netrw_localrmdiropt." ".s:ShellEscape(tmpdir,1)) if v:shell_error != 0 call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localrmdir<".g:netrw_localrmdir."> to something that works",80) " " call Dret("s:NetrwMarkFileCopy : failed: sil !".g:netrw_localrmdir." ".s:ShellEscape(tmpdir,1) ) @@ -6839,7 +7122,10 @@ endif endif else - call s:NetrwLcd(curdir) + if s:NetrwLcd(curdir) +" call Dret("s:NetrwMarkFileCopy : lcd failure") + return + endif endif endif endif @@ -7366,15 +7652,15 @@ " move: local -> local " call Decho("move from local to local",'~'.expand("")) " call Decho("local to local move",'~'.expand("")) - if !executable(g:netrw_localmovecmd) && g:netrw_localmovecmd !~ '^'.expand("$COMSPEC").'\s' + if !executable(g:netrw_localmovecmd) call netrw#ErrorMsg(s:ERROR,"g:netrw_localmovecmd<".g:netrw_localmovecmd."> not executable on your system, aborting",90) " call Dfunc("s:NetrwMarkFileMove : g:netrw_localmovecmd<".g:netrw_localmovecmd."> n/a!") return endif - let tgt = s:ShellEscape(s:netrwmftgt) + let tgt = s:ShellEscape(s:netrwmftgt) " call Decho("tgt<".tgt.">",'~'.expand("")) if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16")) - let tgt = substitute(tgt, '/','\\','g') + let tgt= substitute(tgt, '/','\\','g') " call Decho("windows exception: tgt<".tgt.">",'~'.expand("")) if g:netrw_localmovecmd =~ '\s' let movecmd = substitute(g:netrw_localmovecmd,'\s.*$','','') @@ -7394,10 +7680,10 @@ let fname= substitute(fname,'/','\\','g') endif " call Decho("system(".movecmd." ".s:ShellEscape(fname)." ".tgt.")",'~'.expand("")) - let ret= system(movecmd." ".s:ShellEscape(fname)." ".tgt) + let ret= system(movecmd.g:netrw_localmovecmdopt." ".s:ShellEscape(fname)." ".tgt) if v:shell_error != 0 if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir - call netrw#ErrorMsg(s:ERROR,"move failed; perhaps due to vim's current directory<".getcwd()."> not matching netrw's (".b:netrw_curdir.") (see :help netrw-c)",100) + call netrw#ErrorMsg(s:ERROR,"move failed; perhaps due to vim's current directory<".getcwd()."> not matching netrw's (".b:netrw_curdir.") (see :help netrw-cd)",100) else call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localmovecmd<".g:netrw_localmovecmd.">; it doesn't work!",54) endif @@ -7524,21 +7810,27 @@ if a:islocal let curdir= s:NetrwGetCurdir(a:islocal) +" call Decho("curdir<".fnameescape(curdir).">") " get the matching list of files using local glob() " call Decho("handle local regexp",'~'.expand("")) let dirname = escape(b:netrw_curdir,g:netrw_glob_escape) if v:version > 704 || (v:version == 704 && has("patch656")) - let files = glob(s:ComposePath(dirname,regexp),0,0,1) + let filelist= glob(s:ComposePath(dirname,regexp),0,1,1) else let files = glob(s:ComposePath(dirname,regexp),0,0) + let filelist= split(files,"\n") endif -" call Decho("files<".files.">",'~'.expand("")) - let filelist= split(files,"\n") +" call Decho("files<".string(filelist).">",'~'.expand("")) " mark the list of files for fname in filelist -" call Decho("fname<".fname.">",'~'.expand("")) - NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(fname,'^.*/','','')) + if fname =~ '^'.fnameescape(curdir) +" call Decho("fname<".substitute(fname,'^'.fnameescape(curdir).'/','','').">",'~'.expand("")) + NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(fname,'^'.fnameescape(curdir).'/','','')) + else +" call Decho("fname<".fname.">",'~'.expand("")) + NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(fname,'^.*/','','')) + endif endfor else @@ -7552,7 +7844,7 @@ " call Decho("setl ei=all ma",'~'.expand("")) 1split NetrwKeepj call s:NetrwEnew() - NetrwKeepj call s:NetrwSafeOptions() + NetrwKeepj call s:NetrwOptionsSafe(a:islocal) sil NetrwKeepj norm! "ap NetrwKeepj 2 let bannercnt= search('^" =====','W') @@ -7649,12 +7941,13 @@ call s:NetrwUnmarkAll() if a:islocal - if executable(g:netrw_ctags) -" call Decho("call system(".g:netrw_ctags." ".netrwmarkfilelist.")",'~'.expand("")) - call system(g:netrw_ctags." ".netrwmarkfilelist) - else + +" call Decho("call system(".g:netrw_ctags." ".netrwmarkfilelist.")",'~'.expand("")) + call system(g:netrw_ctags." ".netrwmarkfilelist) + if v:shell_error call netrw#ErrorMsg(s:ERROR,"g:netrw_ctags<".g:netrw_ctags."> is not executable!",51) endif + else let cmd = s:RemoteSystem(g:netrw_ctags." ".netrwmarkfilelist) call netrw#Obtain(a:islocal,"tags") @@ -8109,7 +8402,7 @@ call netrw#Obtain(islocal,s:netrwmarkfilelist_{bufnr('%')}) call s:NetrwUnmarkList(bufnr('%'),b:netrw_curdir) else - call netrw#Obtain(a:islocal,expand("")) + call netrw#Obtain(a:islocal,s:NetrwGetWord()) endif let @@= ykeep @@ -8144,14 +8437,16 @@ if lastwinnr == 1 " if only one window, open a new one first " call Decho("only one window, so open a new one (g:netrw_alto=".g:netrw_alto.")",'~'.expand("")) + " g:netrw_preview=0: preview window shown in a horizontally split window + " g:netrw_preview=1: preview window shown in a vertically split window if g:netrw_preview " vertically split preview window - let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize + let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize " call Decho("exe ".(g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s",'~'.expand("")) exe (g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s" else " horizontally split preview window - let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize + let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize " call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("")) exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s" endif @@ -8189,7 +8484,7 @@ " only one copy of the modified buffer in a window, and " hidden not set, so overwriting will lose the modified file. Ask first... let choice = confirm("Save modified buffer<".prevbufname."> first?","&Yes\n&No\n&Cancel") -" call Decho("(NetrwPrevWinOpen) prevbufname<".prevbufname."> choice=".choice." current-winnr#".winnr(),'~'.expand("")) +" call Decho("prevbufname<".prevbufname."> choice=".choice." current-winnr#".winnr(),'~'.expand("")) let &ei= eikeep if choice == 1 @@ -8283,7 +8578,10 @@ " call Decho("handle uploading a list of files via scp",'~'.expand("")) let curdir= getcwd() if a:tgt =~ '^scp:' - call s:NetrwLcd(fromdir) + if s:NetrwLcd(fromdir) +" call Dret("s:NetrwUpload : lcd failure") + return + endif let filelist= deepcopy(s:netrwmarkfilelist_{bufnr('%')}) let args = join(map(filelist,"s:ShellEscape(v:val, 1)")) if exists("g:netrw_port") && g:netrw_port != "" @@ -8294,7 +8592,10 @@ let machine = substitute(a:tgt,'^scp://\([^/:]\+\).*$','\1','') let tgt = substitute(a:tgt,'^scp://[^/]\+/\(.*\)$','\1','') call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".args." ".s:ShellEscape(machine.":".tgt,1)) - call s:NetrwLcd(curdir) + if s:NetrwLcd(curdir) +" call Dret("s:NetrwUpload : lcd failure") + return + endif elseif a:tgt =~ '^ftp:' call s:NetrwMethod(a:tgt) @@ -8408,7 +8709,7 @@ bw!|q endif elseif !exists("b:netrw_method") || b:netrw_method < 0 -" call Dfunc("netrw#NetrwUpload : unsupported method") +" call Dret("s:#NetrwUpload : unsupported method") return endif else @@ -8420,20 +8721,49 @@ endfun " --------------------------------------------------------------------- -" s:NetrwPreview: {{{2 +" s:NetrwPreview: supports netrw's "p" map {{{2 fun! s:NetrwPreview(path) range " call Dfunc("NetrwPreview(path<".a:path.">)") +" call Decho("g:netrw_alto =".(exists("g:netrw_alto")? g:netrw_alto : 'n/a'),'~'.expand("")) +" call Decho("g:netrw_preview=".(exists("g:netrw_preview")? g:netrw_preview : 'n/a'),'~'.expand("")) let ykeep= @@ - NetrwKeepj call s:NetrwOptionSave("s:") - NetrwKeepj call s:NetrwSafeOptions() + NetrwKeepj call s:NetrwOptionsSave("s:") + if a:path !~ '^\*\{1,2}/' && a:path !~ '^\a\{3,}://' + NetrwKeepj call s:NetrwOptionsSafe(1) + else + NetrwKeepj call s:NetrwOptionsSafe(0) + endif if has("quickfix") +" call Decho("has quickfix",'~'.expand("")) if !isdirectory(s:NetrwFile(a:path)) - if g:netrw_preview && !g:netrw_alto +" call Decho("good; not previewing a directory",'~'.expand("")) + if g:netrw_preview + " vertical split let pvhkeep = &pvh let winsz = (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize let &pvh = winwidth(0) - winsz - endif +" call Decho("g:netrw_preview: winsz=".winsz." &pvh=".&pvh." (temporarily) g:netrw_winsize=".g:netrw_winsize,'~'.expand("")) + else + " horizontal split + let pvhkeep = &pvh + let winsz = (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize + let &pvh = winheight(0) - winsz +" call Decho("!g:netrw_preview: winsz=".winsz." &pvh=".&pvh." (temporarily) g:netrw_winsize=".g:netrw_winsize,'~'.expand("")) + endif + " g:netrw_preview g:netrw_alto + " 1 : vert 1: top -- preview window is vertically split off and on the left + " 1 : vert 0: bot -- preview window is vertically split off and on the right + " 0 : 1: top -- preview window is horizontally split off and on the top + " 0 : 0: bot -- preview window is horizontally split off and on the bottom + " + " Note that the file being previewed is already known to not be a directory, hence we can avoid doing a LocalBrowse() check via + " the BufEnter event set up in netrwPlugin.vim +" call Decho("exe ".(g:netrw_alto? "top " : "bot ").(g:netrw_preview? "vert " : "")."pedit ".fnameescape(a:path),'~'.expand("")) + let eikeep = &ei + set ei=BufEnter exe (g:netrw_alto? "top " : "bot ").(g:netrw_preview? "vert " : "")."pedit ".fnameescape(a:path) + let &ei= eikeep +" call Decho("winnr($)=".winnr("$"),'~'.expand("")) if exists("pvhkeep") let &pvh= pvhkeep endif @@ -8443,7 +8773,7 @@ elseif !exists("g:netrw_quiet") NetrwKeepj call netrw#ErrorMsg(s:WARNING,"sorry, to preview your vim needs the quickfix feature compiled in",39) endif - NetrwKeepj call s:NetrwOptionRestore("s:") + NetrwKeepj call s:NetrwOptionsRestore("s:") let @@= ykeep " call Dret("NetrwPreview") endfun @@ -8451,12 +8781,22 @@ " --------------------------------------------------------------------- " s:NetrwRefresh: {{{2 fun! s:NetrwRefresh(islocal,dirname) -" call Dfunc("s:NetrwRefresh(islocal<".a:islocal.">,dirname=".a:dirname.") hide=".g:netrw_hide." sortdir=".g:netrw_sort_direction) +" call Dfunc("s:NetrwRefresh(islocal<".a:islocal.">,dirname=".a:dirname.") g:netrw_hide=".g:netrw_hide." g:netrw_sort_direction=".g:netrw_sort_direction) " at the current time (Mar 19, 2007) all calls to NetrwRefresh() call NetrwBrowseChgDir() first. setl ma noro " call Decho("setl ma noro",'~'.expand("")) " call Decho("clear buffer<".expand("%")."> with :%d",'~'.expand("")) let ykeep = @@ + if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST + if !exists("w:netrw_treetop") + if exists("b:netrw_curdir") + let w:netrw_treetop= b:netrw_curdir + else + let w:netrw_treetop= getcwd() + endif + endif + NetrwKeepj call s:NetrwRefreshTreeDict(w:netrw_treetop) + endif " save the cursor position before refresh. let screenposn = winsaveview() @@ -8476,13 +8816,15 @@ NetrwKeepj call winrestview(screenposn) " restore file marks - if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != "" -" call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("")) - exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/" - else -" call Decho("2match none (bufnr(%)=".bufnr("%")."<".bufname("%").">)",'~'.expand("")) - 2match none - endif + if has("syntax") && exists("g:syntax_on") && g:syntax_on + if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != "" +" " call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("")) + exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/" + else +" " call Decho("2match none (bufnr(%)=".bufnr("%")."<".bufname("%").">)",'~'.expand("")) + 2match none + endif + endif " restore let @@= ykeep @@ -8657,7 +8999,7 @@ endfun " ===================================================================== -" s:NetrwSortStyle: change sorting style (name - time - size) and refresh display {{{2 +" s:NetrwSortStyle: change sorting style (name - time - size - exten) and refresh display {{{2 fun! s:NetrwSortStyle(islocal) " call Dfunc("s:NetrwSortStyle(islocal=".a:islocal.") netrw_sort_by<".g:netrw_sort_by.">") NetrwKeepj call s:NetrwSaveWordPosn() @@ -8821,7 +9163,7 @@ " call Decho("installing history as easy targets (histmax=".g:netrw_dirhistmax.")",'~'.expand("")) let histcnt = 1 while histcnt <= g:netrw_dirhistmax - let priority = g:netrw_dirhist_cnt + histcnt + let priority = g:netrw_dirhistcnt + histcnt if exists("g:netrw_dirhist_{histcnt}") let histentry = g:netrw_dirhist_{histcnt} if has_key(tgtdict,histentry) @@ -8958,6 +9300,36 @@ let depth= s:treedepthstring.a:depth " call Decho("display subtrees with depth<".depth."> and current leaves",'~'.expand("")) + " implement g:netrw_hide for tree listings (uses g:netrw_list_hide) + if g:netrw_hide == 1 + " hide given patterns + let listhide= split(g:netrw_list_hide,',') +" call Decho("listhide=".string(listhide)) + for pat in listhide + call filter(w:netrw_treedict[dir],'v:val !~ "'.pat.'"') + endfor + + elseif g:netrw_hide == 2 + " show given patterns (only) + let listhide= split(g:netrw_list_hide,',') +" call Decho("listhide=".string(listhide)) + let entries=[] + for entry in w:netrw_treedict[dir] + for pat in listhide + if entry =~ pat + call add(entries,entry) + break + endif + endfor + endfor + let w:netrw_treedict[dir]= entries + endif + if depth != "" + " always remove "." and ".." entries when there's depth + call filter(w:netrw_treedict[dir],'v:val !~ "\\.\\.$"') + call filter(w:netrw_treedict[dir],'v:val !~ "\\.$"') + endif + " call Decho("for every entry in w:netrw_treedict[".dir."]=".string(w:netrw_treedict[dir]),'~'.expand("")) for entry in w:netrw_treedict[dir] if dir =~ '/$' @@ -8980,6 +9352,7 @@ sil! NetrwKeepj call setline(line("$")+1,depth.entry) endif endfor +" call Decho("displaying: ".string(getline(w:netrw_bannercnt,'$'))) " call Dret("NetrwTreeDisplay") endfun @@ -8988,6 +9361,11 @@ " s:NetrwRefreshTreeDict: updates the contents information for a tree (w:netrw_treedict) {{{2 fun! s:NetrwRefreshTreeDict(dir) " call Dfunc("s:NetrwRefreshTreeDict(dir<".a:dir.">)") + if !exists("w:netrw_treedict") +" call Dret("s:NetrwRefreshTreeDict : w:netrw_treedict doesn't exist") + return + endif + for entry in w:netrw_treedict[a:dir] let direntry= substitute(a:dir.'/'.entry,'[@/]$','','e') " call Decho("a:dir<".a:dir."> entry<".entry."> direntry<".direntry.">",'~'.expand("")) @@ -9016,7 +9394,7 @@ " call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("")) else -" call Decho('not updating w:netrw_treedict['.direntry.'] with entry<'.entry.'> (no subtree)',,'~'.expand("")) +" call Decho('not updating w:netrw_treedict['.string(direntry).'] with entry<'.string(entry).'> (no subtree)','~'.expand("")) endif endfor " call Dret("s:NetrwRefreshTreeDict") @@ -9083,12 +9461,21 @@ endfun " --------------------------------------------------------------------- -" s:NetrwTreePath: returns path to current file in tree listing {{{2 +" s:NetrwTreePath: returns path to current file/directory in tree listing {{{2 " Normally, treetop is w:netrw_treetop, but a " user of the function ( netrw#SetTreetop() ) " wipes that out prior to calling this function fun! s:NetrwTreePath(treetop) -" call Dfunc("s:NetrwTreePath() line#".line(".")."<".getline(".").">") +" call Dfunc("s:NetrwTreePath(treetop<".a:treetop.">) line#".line(".")."<".getline(".").">") + if line(".") < w:netrw_bannercnt + 2 + let treedir= a:treetop + if treedir !~ '/$' + let treedir= treedir.'/' + endif +" call Dret("s:NetrwTreePath ".treedir." : line#".line(".")." ≤ ".(w:netrw_bannercnt+2)) + return treedir + endif + let svpos = winsaveview() " call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("")) let depth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e') @@ -9119,12 +9506,15 @@ let depth = substitute(depth,'^'.s:treedepthstring,'','') " call Decho("constructing treedir<".treedir.">: dirname<".dirname."> while depth<".depth.">",'~'.expand("")) endwhile +" call Decho("treedir#1<".treedir.">",'~'.expand("")) if a:treetop =~ '/$' let treedir= a:treetop.treedir else let treedir= a:treetop.'/'.treedir endif +" call Decho("treedir#2<".treedir.">",'~'.expand("")) let treedir= substitute(treedir,'//$','/','') +" call Decho("treedir#3<".treedir.">",'~'.expand("")) " call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand(""))" call winrestview(svpos) " call Dret("s:NetrwTreePath <".treedir.">") @@ -9195,7 +9585,7 @@ exe 'nno b :call search(''^.\\|\s\s\zs\S'',''bW'')'."\" " call Decho("NetrwWideListing) setl noma nomod ro",'~'.expand("")) exe "setl ".g:netrw_bufsettings -" call Decho("(NetrwWideListing) ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("")) +" call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("")) " call Dret("NetrwWideListing") return else @@ -9214,18 +9604,20 @@ fun! s:PerformListing(islocal) " call Dfunc("s:PerformListing(islocal=".a:islocal.")") " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("")) -" call Decho("settings: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (enter)",'~'.expand("")) +" call Decho("settings: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (enter)"." ei<".&ei.">",'~'.expand("")) + sil! NetrwKeepj %d _ +" call DechoBuf(bufnr("%")) " set up syntax highlighting {{{3 " call Decho("--set up syntax highlighting (ie. setl ft=netrw)",'~'.expand("")) sil! setl ft=netrw - NetrwKeepj call s:NetrwSafeOptions() + NetrwKeepj call s:NetrwOptionsSafe(a:islocal) setl noro ma " call Decho("setl noro ma bh=".&bh,'~'.expand("")) " if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1 " Decho -" call Decho("(netrw) Processing your browsing request...",'~'.expand("")) +" call Decho("Processing your browsing request...",'~'.expand("")) " endif " Decho " call Decho('w:netrw_liststyle='.(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("")) @@ -9269,6 +9661,7 @@ " call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." win#".winnr(),'~'.expand("")) " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("")) + " construct sortby string: [name|time|size|exten] [reversed] let sortby= g:netrw_sort_by if g:netrw_sort_direction =~# "^r" let sortby= sortby." reversed" @@ -9279,13 +9672,13 @@ " call Decho("--handle specified sorting: g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("")) if g:netrw_sort_by =~# "^n" " call Decho("directories will be sorted by name",'~'.expand("")) - " sorted by name + " sorted by name (also includes the sorting sequence in the banner) NetrwKeepj put ='\" Sorted by '.sortby NetrwKeepj put ='\" Sort sequence: '.g:netrw_sort_sequence let w:netrw_bannercnt= w:netrw_bannercnt + 2 else " call Decho("directories will be sorted by size or time",'~'.expand("")) - " sorted by size or date + " sorted by time, size, exten NetrwKeepj put ='\" Sorted by '.sortby let w:netrw_bannercnt= w:netrw_bannercnt + 1 endif @@ -9294,7 +9687,7 @@ " call Decho("g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")",'~'.expand("")) endif - " show copy/move target, if any + " show copy/move target, if any {{{3 if g:netrw_banner if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal") " call Decho("--show copy/move target<".s:netrwmftgt.">",'~'.expand("")) @@ -9313,7 +9706,7 @@ " Hiding... -or- Showing... {{{3 if g:netrw_banner -" call Decho("--handle hiding/showing (g:netrw_hide=".g:netrw_list_hide." g:netrw_list_hide<".g:netrw_list_hide.">)",'~'.expand("")) +" call Decho("--handle hiding/showing (g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">)",'~'.expand("")) if g:netrw_list_hide != "" && g:netrw_hide if g:netrw_hide == 1 NetrwKeepj put ='\" Hiding: '.g:netrw_list_hide @@ -9376,12 +9769,13 @@ if g:netrw_sort_by =~# "^n" " sort by name +" call Decho("sort by name",'~'.expand("")) NetrwKeepj call s:NetrwSetSort() if !g:netrw_banner || w:netrw_bannercnt < line("$") " call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("")) if g:netrw_sort_direction =~# 'n' - " normal direction sorting + " name: sort by name of file exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options else " reverse direction sorting @@ -9394,7 +9788,9 @@ NetrwKeepj call histdel("/",-1) elseif g:netrw_sort_by =~# "^ext" - " sort by extension + " exten: sort by extension + " The histdel(...,-1) calls remove the last search from the search history +" call Decho("sort by extension",'~'.expand("")) exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g+/+s/^/001'.g:netrw_sepchr.'/' NetrwKeepj call histdel("/",-1) exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+[./]+s/^/002'.g:netrw_sepchr.'/' @@ -9450,7 +9846,7 @@ " resolve symbolic links if local and (thin or tree) if a:islocal && (w:netrw_liststyle == s:THINLIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST)) " call Decho("--resolve symbolic links if local and thin|tree",'~'.expand("")) - g/@$/call s:ShowLink() + sil! g/@$/call s:ShowLink() endif if exists("w:netrw_bannercnt") && (line("$") >= w:netrw_bannercnt || !g:netrw_banner) @@ -9475,7 +9871,7 @@ " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#4)",'~'.expand("")) NetrwKeepj call s:SetBufWinVars() " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#5)",'~'.expand("")) - NetrwKeepj call s:NetrwOptionRestore("w:") + NetrwKeepj call s:NetrwOptionsRestore("w:") " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#6)",'~'.expand("")) " set display to netrw display settings @@ -9486,6 +9882,7 @@ " call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("")) exe "setl ts=".(g:netrw_maxfilenamelen+1) endif +" call DechoBuf(bufnr("%")) if exists("s:treecurpos") " call Decho("s:treecurpos exists; restore posn",'~'.expand("")) @@ -9543,9 +9940,9 @@ " call Dret("SetupNetrwStatusLine : stl=".&stl) endfun -" --------------------------------------------------------------------- -" Remote Directory Browsing Support: {{{1 -" =========================================== +" ========================================= +" Remote Directory Browsing Support: {{{1 +" ========================================= " --------------------------------------------------------------------- " s:NetrwRemoteFtpCmd: unfortunately, not all ftp servers honor options for ls {{{2 @@ -9714,7 +10111,7 @@ if !exists("g:netrw_quiet") call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ftp",18) endif - call s:NetrwOptionRestore("w:") + call s:NetrwOptionsRestore("w:") " call Dret("s:NetrwRemoteListing -1") return -1 endif @@ -9729,7 +10126,7 @@ endif endif - NetrwKeepj call s:NetrwOptionRestore("w:") + NetrwKeepj call s:NetrwOptionsRestore("w:") " call Dret("s:NetrwRemoteListing -1") return -1 endif " (remote handling sanity check) @@ -9762,7 +10159,7 @@ exe w:netrw_bannercnt.",$d _" setl noma endif - NetrwKeepj call s:NetrwOptionRestore("w:") + NetrwKeepj call s:NetrwOptionsRestore("w:") call netrw#ErrorMsg(s:WARNING,mesg,96) " call Dret("s:NetrwRemoteListing : -1") return -1 @@ -10005,7 +10402,7 @@ let ret= system(netrw_rm_cmd) if v:shell_error != 0 if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir - call netrw#ErrorMsg(s:ERROR,"remove failed; perhaps due to vim's current directory<".getcwd()."> not matching netrw's (".b:netrw_curdir.") (see :help netrw-c)",102) + call netrw#ErrorMsg(s:ERROR,"remove failed; perhaps due to vim's current directory<".getcwd()."> not matching netrw's (".b:netrw_curdir.") (see :help netrw-cd)",102) else call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60) endif @@ -10146,12 +10543,12 @@ " call Dret("NetrwRemoteRename") endfun -" --------------------------------------------------------------------- +" ========================================== " Local Directory Browsing Support: {{{1 " ========================================== " --------------------------------------------------------------------- -" netrw#FileUrlRead: handles reading file://* files {{{2 +" netrw#FileUrlEdit: handles editing file://* files {{{2 " Should accept: file://localhost/etc/fstab " file:///etc/fstab " file:///c:/WINDOWS/clock.avi @@ -10161,8 +10558,8 @@ " file://c:/foo.txt " file:///c:/foo.txt " and %XX (where X is [0-9a-fA-F] is converted into a character with the given hexadecimal value -fun! netrw#FileUrlRead(fname) -" call Dfunc("netrw#FileUrlRead(fname<".a:fname.">)") +fun! netrw#FileUrlEdit(fname) +" call Dfunc("netrw#FileUrlEdit(fname<".a:fname.">)") let fname = a:fname if fname =~ '^file://localhost/' " call Decho('converting file://localhost/ -to- file:///','~'.expand("")) @@ -10186,35 +10583,36 @@ let plainfname= substitute(plainfname,'^/\+\(\a:\)','\1','') endif endif + " call Decho("fname2396<".fname2396.">",'~'.expand("")) " call Decho("plainfname<".plainfname.">",'~'.expand("")) exe "sil doau BufReadPre ".fname2396e - exe 'NetrwKeepj r '.plainfname - exe 'sil! bdelete '.plainfname - exe 'keepalt file! '.plainfname - NetrwKeepj 1d -" call Decho("setl nomod",'~'.expand("")) - setl nomod + exe 'NetrwKeepj keepalt edit '.plainfname + exe 'sil! NetrwKeepj keepalt bdelete '.fnameescape(a:fname) + " call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("")) -" call Dret("netrw#FileUrlRead") +" call Dret("netrw#FileUrlEdit") exe "sil doau BufReadPost ".fname2396e endfun " --------------------------------------------------------------------- " netrw#LocalBrowseCheck: {{{2 fun! netrw#LocalBrowseCheck(dirname) - " This function is called by netrwPlugin.vim's s:LocalBrowse(), s:NetrwRexplore(), and by when atop listed file/directory - " unfortunate interaction -- split window debugging can't be - " used here, must use D-echoRemOn or D-echoTabOn -- the BufEnter - " event triggers another call to LocalBrowseCheck() when attempts - " to write to the DBG buffer are made. + " This function is called by netrwPlugin.vim's s:LocalBrowse(), s:NetrwRexplore(), + " and by when atop a listed file/directory (via a buffer-local map) + " + " unfortunate interaction -- split window debugging can't be used here, must use + " D-echoRemOn or D-echoTabOn as the BufEnter event triggers + " another call to LocalBrowseCheck() when attempts to write + " to the DBG buffer are made. + " " The &ft == "netrw" test was installed because the BufEnter event " would hit when re-entering netrw windows, creating unexpected " refreshes (and would do so in the middle of NetrwSaveOptions(), too) -" call Dfunc("netrw#LocalBrowseCheck(dirname<".a:dirname.">") +" call Dfunc("netrw#LocalBrowseCheck(dirname<".a:dirname.">)") " call Decho("isdir<".a:dirname."> =".isdirectory(s:NetrwFile(a:dirname)).((exists("s:treeforceredraw")? " treeforceredraw" : "")).'~'.expand("")) " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("")) -" call Dredir("ls!","ls!") +" call Dredir("ls!","netrw#LocalBrowseCheck") " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("")) " call Decho("current buffer#".bufnr("%")."<".bufname("%")."> ft=".&ft,'~'.expand("")) @@ -10241,7 +10639,7 @@ return endif - " following code wipes out currently unused netrw buffers + " The following code wipes out currently unused netrw buffers " IF g:netrw_fastbrowse is zero (ie. slow browsing selected) " AND IF the listing style is not a tree listing if exists("g:netrw_fastbrowse") && g:netrw_fastbrowse == 0 && g:netrw_liststyle != s:TREELIST @@ -10293,19 +10691,21 @@ while itab <= tabpagenr("$") let buftablist = buftablist + tabpagebuflist() let itab = itab + 1 - tabn + sil! tabn endwhile " call Decho("buftablist".string(buftablist),'~'.expand("")) " call Decho("s:netrw_browselist<".(exists("s:netrw_browselist")? string(s:netrw_browselist) : "").">",'~'.expand("")) " GO through all buffers on netrw_browselist (ie. just local-netrw buffers): " | refresh any netrw window " | wipe out any non-displaying netrw buffer - let curwin = winnr() + let curwinid = win_getid(winnr()) let ibl = 0 for ibuf in s:netrw_browselist " call Decho("bufwinnr(".ibuf.") index(buftablist,".ibuf.")=".index(buftablist,ibuf),'~'.expand("")) if bufwinnr(ibuf) == -1 && index(buftablist,ibuf) == -1 " wipe out any non-displaying netrw buffer + " (ibuf not shown in a current window AND + " ibuf not in any tab) " call Decho("wiping buf#".ibuf,"<".bufname(ibuf).">",'~'.expand("")) exe "sil! keepj bd ".fnameescape(ibuf) call remove(s:netrw_browselist,ibl) @@ -10329,8 +10729,8 @@ let ibl= ibl + 1 " call Decho("bottom of s:netrw_browselist for loop: ibl=".ibl,'~'.expand("")) endfor -" call Decho("restore window: exe ".curwin."wincmd w",'~'.expand("")) - exe curwin."wincmd w" +" call Decho("restore window: win_gotoid(".curwinid.")") + call win_gotoid(curwinid) let @@= ykeep " call Dret("s:LocalBrowseRefresh") @@ -10355,10 +10755,10 @@ " If :Explore used: it sets s:netrw_events to 2, so no FocusGained events are ignored. " =2: autocmds installed (doesn't ignore any FocusGained events) fun! s:LocalFastBrowser() -" call Dfunc("LocalFastBrowser() g:netrw_fastbrowse=".g:netrw_fastbrowse) -" call Decho("s:netrw_events ".(exists("s:netrw_events")? "exists" : 'n/a'),'~'.expand("")) -" call Decho("autocmd: ShellCmdPost ".(exists("#ShellCmdPost")? "installed" : "not installed"),'~'.expand("")) -" call Decho("autocmd: FocusGained ".(exists("#FocusGained")? "installed" : "not installed"),'~'.expand("")) +" call Dfunc("s:LocalFastBrowser() g:netrw_fastbrowse=".g:netrw_fastbrowse) +" call Decho("s:netrw_events ".(exists("s:netrw_events")? "exists" : 'n/a'),'~'.expand("")) +" call Decho("autocmd: ShellCmdPost ".(exists("#ShellCmdPost")? "already installed" : "not installed"),'~'.expand("")) +" call Decho("autocmd: FocusGained ".(exists("#FocusGained")? "already installed" : "not installed"),'~'.expand("")) " initialize browselist, a list of buffer numbers that the local browser has used if !exists("s:netrw_browselist") @@ -10403,7 +10803,7 @@ augroup! AuNetrwEvent endif -" call Dret("LocalFastBrowser : browselist<".string(s:netrw_browselist).">") +" call Dret("s:LocalFastBrowser : browselist<".string(s:netrw_browselist).">") endfun " --------------------------------------------------------------------- @@ -10449,6 +10849,7 @@ for filename in filelist " call Decho(" ",'~'.expand("")) " call Decho("for filename in filelist: filename<".filename.">",'~'.expand("")) +" call DechoBuf(bufnr("%"),"COMBAK#1") if getftype(filename) == "link" " indicate a symbolic link @@ -10509,8 +10910,9 @@ if g:netrw_sizestyle =~# "[hH]" let sz= s:NetrwHumanReadable(sz) endif - let fsz = strpart(" ",1,15-strlen(sz)).sz - let pfile= pfile."\t".fsz." ".strftime(g:netrw_timefmt,getftime(filename)) + let fsz = strpart(" ",1,15-strlen(sz)).sz + let longfile= printf("%-".(g:netrw_maxfilenamelen+1)."s",pfile) + let pfile = longfile.fsz." ".strftime(g:netrw_timefmt,getftime(filename)) " call Decho("longlist support: sz=".sz." fsz=".fsz,'~'.expand("")) endif @@ -10540,6 +10942,7 @@ " call Decho("exe NetrwKeepj put ='".pfile."'",'~'.expand("")) sil! NetrwKeepj put=pfile endif +" call DechoBuf(bufnr("%"),"COMBAK#2") endfor " cleanup any windows mess at end-of-line @@ -10786,7 +11189,7 @@ let rmfile= substitute(rmfile,'[\/]$','','e') if all || ok =~# 'y\%[es]' || ok == "" - if v:version < 704 || !has("patch1109") + if v:version < 704 || (v:version == 704 && !has("patch1107")) " " call Decho("1st attempt: system(netrw#WinPath(".g:netrw_localrmdir.') '.s:ShellEscape(rmfile).')','~'.expand("")) call system(netrw#WinPath(g:netrw_localrmdir).' '.s:ShellEscape(rmfile)) " " call Decho("v:shell_error=".v:shell_error,'~'.expand("")) @@ -10822,21 +11225,10 @@ return ok endfun -" --------------------------------------------------------------------- +" ===================================================================== " Support Functions: {{{1 " --------------------------------------------------------------------- -" s:WinNames: COMBAK {{{2 -fun! s:WinNames(id) - let curwin= winnr() - 1wincmd w -" call Decho("--- Windows By Name --- #".a:id) -" windo call Decho("win#".winnr()."<".expand("%").">") -" call Decho("--- --- --- --- --- ---") - exe curwin."wincmd w" -endfun - -" --------------------------------------------------------------------- " netrw#Access: intended to provide access to variable values for netrw's test suite {{{2 " 0: marked file list of current buffer " 1: marked file target @@ -10849,18 +11241,13 @@ endif elseif a:ilist == 1 return s:netrwmftgt + endif endfun " --------------------------------------------------------------------- " netrw#Call: allows user-specified mappings to call internal netrw functions {{{2 fun! netrw#Call(funcname,...) -" call Dfunc("netrw#Call(funcname<".a:funcname.">,".string(a:000).")") - if a:0 > 0 - exe "call s:".a:funcname."(".string(a:000).")" - else - exe "call s:".a:funcname."()" - endif -" call Dret("netrw#Call") + return call("s:".a:funcname,a:000) endfun " --------------------------------------------------------------------- @@ -10922,7 +11309,7 @@ " or it may return a List of strings. " " Each keymap-sequence will be set up with a nnoremap -" to invoke netrw#UserMaps(islocal). +" to invoke netrw#UserMaps(a:islocal). " Related functions: " netrw#Expose(varname) -- see s:varname variables " netrw#Modify(varname,newvalue) -- modify value of s:varname variable @@ -10970,6 +11357,35 @@ endfun " --------------------------------------------------------------------- +" s:NetrwBadd: adds marked files to buffer list or vice versa {{{2 +" cb : bl2mf=0 add marked files to buffer list +" cB : bl2mf=1 use bufferlist to mark files +" (mnemonic: cb = copy (marked files) to buffer list) +fun! s:NetrwBadd(islocal,bl2mf) +" " call Dfunc("s:NetrwBadd(islocal=".a:islocal." mf2bl=".mf2bl.")") + if a:bl2mf + " cB: add buffer list to marked files + redir => bufl + ls + redir END + let bufl = map(split(bufl,"\n"),'substitute(v:val,''^.\{-}"\(.*\)".\{-}$'',''\1'','''')') + for fname in bufl + call s:NetrwMarkFile(a:islocal,fname) + endfor + else + " cb: add marked files to buffer list + for fname in s:netrwmarkfilelist_{bufnr("%")} +" " call Decho("badd ".fname,'~'.expand("")) + exe "badd ".fnameescape(fname) + endfor + let curbufnr = bufnr("%") + let curdir = s:NetrwGetCurdir(a:islocal) + call s:NetrwUnmarkList(curbufnr,curdir) " remove markings from local buffer + endif +" call Dret("s:NetrwBadd") +endfun + +" --------------------------------------------------------------------- " s:ComposePath: Appends a new part to a path taking different systems into consideration {{{2 fun! s:ComposePath(base,subdir) " call Dfunc("s:ComposePath(base<".a:base."> subdir<".a:subdir.">)") @@ -10983,11 +11399,12 @@ let ret = a:base.a:subdir endif - elseif a:subdir =~ '^\a:[/\\][^/\\]' && (has("win32") || has("win95") || has("win64") || has("win16")) + " COMBAK: test on windows with changing to root directory: :e C:/ + elseif a:subdir =~ '^\a:[/\\]\([^/\\]\|$\)' && (has("win32") || has("win95") || has("win64") || has("win16")) " call Decho("windows",'~'.expand("")) let ret= a:subdir - elseif a:base =~ '^\a:[/\\][^/\\]' && (has("win32") || has("win95") || has("win64") || has("win16")) + elseif a:base =~ '^\a:[/\\]\([^/\\]\|$\)' && (has("win32") || has("win95") || has("win64") || has("win16")) " call Decho("windows",'~'.expand("")) if a:base =~ '[/\\]$' let ret= a:base.a:subdir @@ -11329,7 +11746,7 @@ " --------------------------------------------------------------------- " s:NetrwEnew: opens a new buffer, passes netrw buffer variables through {{{2 fun! s:NetrwEnew(...) -" call Dfunc("s:NetrwEnew() a:0=".a:0." bufnr($)=".bufnr("$")) +" call Dfunc("s:NetrwEnew() a:0=".a:0." bufnr($)=".bufnr("$")." expand(%)<".expand("%").">") " call Decho("curdir<".((a:0>0)? a:1 : "")."> buf#".bufnr("%")."<".bufname("%").">",'~'.expand("")) " grab a function-local-variable copy of buffer variables @@ -11351,7 +11768,7 @@ if exists("b:netrw_option") |let netrw_option = b:netrw_option |endif if exists("b:netrw_prvdir") |let netrw_prvdir = b:netrw_prvdir |endif - NetrwKeepj call s:NetrwOptionRestore("w:") + NetrwKeepj call s:NetrwOptionsRestore("w:") " call Decho("generate a buffer with NetrwKeepj keepalt enew!",'~'.expand("")) " when tree listing uses file TreeListing... a new buffer is made. " Want the old buffer to be unlisted. @@ -11361,7 +11778,7 @@ noswapfile NetrwKeepj keepalt enew! let &l:diff= netrw_keepdiff " call Decho("bufnr($)=".bufnr("$")."<".bufname(bufnr("$"))."> winnr($)=".winnr("$"),'~'.expand("")) - NetrwKeepj call s:NetrwOptionSave("w:") + NetrwKeepj call s:NetrwOptionsSave("w:") " copy function-local-variables to buffer variable equivalents " call Decho("copy function-local variables back to buffer netrw variables",'~'.expand("")) @@ -11392,7 +11809,7 @@ nno [ :sil call TreeListMove('[') nno ] :sil call TreeListMove(']') else - exe "sil! keepalt file ".fnameescape(b:netrw_curdir) + call s:NetrwBufRename(b:netrw_curdir) endif endif endif @@ -11403,17 +11820,19 @@ " --------------------------------------------------------------------- " s:NetrwExe: executes a string using "!" {{{2 fun! s:NetrwExe(cmd) -" call Dfunc("s:NetrwExe(a:cmd)") +" call Dfunc("s:NetrwExe(a:cmd<".a:cmd.">)") if has("win32") && &shell !~? 'cmd' && !g:netrw_cygwin +" call Decho("using win32:",expand("")) let savedShell=[&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash] set shell& shellcmdflag& shellxquote& shellxescape& set shellquote& shellpipe& shellredir& shellslash& exe a:cmd let [&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash] = savedShell else +" call Decho("exe ".a:cmd,'~'.expand("")) exe a:cmd endif -" call Dret("s:NetrwExe") +" call Dret("s:NetrwExe : v:shell_error=".v:shell_error) endfun " --------------------------------------------------------------------- @@ -11446,9 +11865,12 @@ " --------------------------------------------------------------------- " s:NetrwLcd: handles changing the (local) directory {{{2 +" Returns: 0=success +" -1=failed fun! s:NetrwLcd(newdir) " call Dfunc("s:NetrwLcd(newdir<".a:newdir.">)") + let err472= 0 try exe 'NetrwKeepj sil lcd '.fnameescape(a:newdir) catch /^Vim\%((\a\+)\)\=:E344/ @@ -11464,21 +11886,26 @@ endif endif catch /^Vim\%((\a\+)\)\=:E472/ + let err472= 1 + endtry + + if err472 call netrw#ErrorMsg(s:ERROR,"unable to change directory to <".a:newdir."> (permissions?)",61) if exists("w:netrw_prvdir") let a:newdir= w:netrw_prvdir else - call s:NetrwOptionRestore("w:") + call s:NetrwOptionsRestore("w:") " call Decho("setl noma nomod nowrap",'~'.expand("")) exe "setl ".g:netrw_bufsettings " call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("")) let a:newdir= dirname -" call Dret("s:NetrwBrowse : reusing buffer#".(exists("bufnum")? bufnum : 'N/A')."<".dirname."> getcwd<".getcwd().">") - return endif - endtry +" call Dret("s:NetrwBrowse -1 : reusing buffer#".(exists("bufnum")? bufnum : 'N/A')."<".dirname."> getcwd<".getcwd().">") + return -1 + endif -" call Dret("s:NetrwLcd") +" call Dret("s:NetrwLcd 0") + return 0 endfun " ------------------------------------------------------------------------ @@ -11646,7 +12073,7 @@ " s:SetRexDir() sets up <2-leftmouse> maps (if g:netrw_retmap " is true) and a command, :Rexplore, which call this function. " -" s:netrw_nbcd is set up by s:NetrwBrowseChgDir() +" s:netrw_posn is set up by s:NetrwBrowseChgDir() " " s:rexposn_BUFNR used to save/restore cursor position fun! s:NetrwRexplore(islocal,dirname) @@ -11702,8 +12129,10 @@ " call Decho("s:rexposn_".bufnr('%')."<".bufname("%")."> doesn't exist",'~'.expand("")) endif - if exists("s:explore_match") - exe "2match netrwMarkFile /".s:explore_match."/" + if has("syntax") && exists("g:syntax_on") && g:syntax_on + if exists("s:explore_match") + exe "2match netrwMarkFile /".s:explore_match."/" + endif endif " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("")) @@ -11731,8 +12160,12 @@ fun! s:SavePosn(posndict) " call Dfunc("s:SavePosn(posndict) curbuf#".bufnr("%")."<".bufname("%").">") - let a:posndict[bufnr("%")]= winsaveview() -" call Decho("saving posn: posndict[".bufnr("%")."]=".string(winsaveview()),'~'.expand("")) + if !exists("a:posndict[bufnr('%')]") + let a:posndict[bufnr("%")]= [] + endif +" call Decho("before push: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')])) + call add(a:posndict[bufnr("%")],winsaveview()) +" call Decho("after push: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')])) " call Dret("s:SavePosn posndict") return a:posndict @@ -11742,9 +12175,18 @@ " s:RestorePosn: restores position associated with current buffer using dictionary {{{2 fun! s:RestorePosn(posndict) " call Dfunc("s:RestorePosn(posndict) curbuf#".bufnr("%")."<".bufname("%").">") - if has_key(a:posndict,bufnr("%")) - call winrestview(a:posndict[bufnr("%")]) -" call Decho("restoring posn: posndict[".bufnr("%")."]=".string(a:posndict[bufnr("%")]),'~'.expand("")) + if exists("a:posndict") + if has_key(a:posndict,bufnr("%")) +" call Decho("before pop: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')])) + let posnlen= len(a:posndict[bufnr("%")]) + if posnlen > 0 + let posnlen= posnlen - 1 +" call Decho("restoring posn posndict[".bufnr("%")."][".posnlen."]=".string(a:posndict[bufnr("%")][posnlen]),'~'.expand("")) + call winrestview(a:posndict[bufnr("%")][posnlen]) + call remove(a:posndict[bufnr("%")],posnlen) +" call Decho("after pop: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')])) + endif + endif endif " call Dret("s:RestorePosn") endfun @@ -12032,11 +12474,13 @@ " call Dret("s:UserMaps") endfun -" --------------------------------------------------------------------- +" ========================== " Settings Restoration: {{{1 +" ========================== let &cpo= s:keepcpo unlet s:keepcpo -" ------------------------------------------------------------------------ +" =============== " Modelines: {{{1 +" =============== " vim:ts=8 fdm=marker diff -Nru vim-8.1.1681/runtime/compiler/gcc.vim vim-8.1.1729/runtime/compiler/gcc.vim --- vim-8.1.1681/runtime/compiler/gcc.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/compiler/gcc.vim 2019-07-21 21:04:21.000000000 +0000 @@ -2,6 +2,8 @@ " Compiler: GNU C Compiler " Previous Maintainer: Nikolai Weibull " Latest Revision: 2010-10-14 +" changed pattern for entering/leaving directories +" by Daniel Hahler, 2019 Jul 12 " added line suggested by Anton Lindqvist 2016 Mar 31 if exists("current_compiler") @@ -27,10 +29,10 @@ \%f:%l:\ %m, \%f:\\(%*[^\\)]\\):\ %m, \\"%f\"\\,\ line\ %l%*\\D%c%*[^\ ]\ %m, - \%D%*\\a[%*\\d]:\ Entering\ directory\ [`']%f', - \%X%*\\a[%*\\d]:\ Leaving\ directory\ [`']%f', - \%D%*\\a:\ Entering\ directory\ [`']%f', - \%X%*\\a:\ Leaving\ directory\ [`']%f', + \%D%*\\a[%*\\d]:\ Entering\ directory\ %*[`']%f', + \%X%*\\a[%*\\d]:\ Leaving\ directory\ %*[`']%f', + \%D%*\\a:\ Entering\ directory\ %*[`']%f', + \%X%*\\a:\ Leaving\ directory\ %*[`']%f', \%DMaking\ %*\\a\ in\ %f if exists('g:compiler_gcc_ignore_unmatched_lines') diff -Nru vim-8.1.1681/runtime/doc/change.txt vim-8.1.1729/runtime/doc/change.txt --- vim-8.1.1681/runtime/doc/change.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/change.txt 2019-07-21 21:04:21.000000000 +0000 @@ -1,4 +1,4 @@ -*change.txt* For Vim version 8.1. Last change: 2019 May 07 +*change.txt* For Vim version 8.1. Last change: 2019 Jul 04 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1179,9 +1179,9 @@ 2. 10 numbered registers "0 to "9 3. The small delete register "- 4. 26 named registers "a to "z or "A to "Z -5. three read-only registers ":, "., "% -6. alternate buffer register "# -7. the expression register "= +5. Three read-only registers ":, "., "% +6. Alternate buffer register "# +7. The expression register "= 8. The selection and drop registers "*, "+ and "~ 9. The black hole register "_ 10. Last search pattern register "/ diff -Nru vim-8.1.1681/runtime/doc/channel.txt vim-8.1.1729/runtime/doc/channel.txt --- vim-8.1.1681/runtime/doc/channel.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/channel.txt 2019-07-21 21:04:21.000000000 +0000 @@ -1,4 +1,4 @@ -*channel.txt* For Vim version 8.1. Last change: 2019 May 12 +*channel.txt* For Vim version 8.1. Last change: 2019 Jul 21 VIM REFERENCE MANUAL by Bram Moolenaar @@ -18,11 +18,13 @@ 5. Channel commands |channel-commands| 6. Using a RAW or NL channel |channel-raw| 7. More channel functions |channel-more| -8. Starting a job with a channel |job-start| -9. Starting a job without a channel |job-start-nochannel| -10. Job options |job-options| -11. Controlling a job |job-control| -12. Using a prompt buffer |prompt-buffer| +8. channel functions details |channel-functions-details| +9. Starting a job with a channel |job-start| +10. Starting a job without a channel |job-start-nochannel| +11. Job functions |job-functions-details| +12. Job options |job-options| +13. Controlling a job |job-control| +14. Using a prompt buffer |prompt-buffer| {only when compiled with the |+channel| feature for channel stuff} You can check this with: `has('channel')` @@ -460,7 +462,211 @@ This includes any sequence number. ============================================================================== -8. Starting a job with a channel *job-start* *job* +8. channel functions details *channel-functions-details* + +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. + + This is useful to read from a channel at a convenient time, + e.g. from a timer. + + Note that messages are dropped when the channel does not have + a callback. Add a close callback to avoid that. + + +ch_close({handle}) *ch_close()* + Close {handle}. See |channel-close|. + {handle} can be a Channel or a Job that has a Channel. + A close callback is not invoked. + + +ch_close_in({handle}) *ch_close_in()* + Close the "in" part of {handle}. See |channel-close-in|. + {handle} can be a Channel or a Job that has a Channel. + A close callback is not invoked. + + +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 a 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 + for this specific request. + + ch_evalexpr() waits for a response and returns the decoded + expression. When there is an error or timeout it returns an + empty string. + + +ch_evalraw({handle}, {string} [, {options}]) *ch_evalraw()* + Send {string} over {handle}. + {handle} can be a 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 + correct contents. Also does not add a newline for a channel + in NL mode, the caller must do that. The NL in the response + is removed. + Note that Vim does not know when the text received on a raw + channel is complete, it may only return the first part and you + need to use |ch_readraw()| to fetch the rest. + See |channel-use|. + + +ch_getbufnr({handle}, {what}) *ch_getbufnr()* + Get the buffer number that {handle} is using for {what}. + {handle} can be a 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. + + +ch_getjob({channel}) *ch_getjob()* + Get the Job associated with {channel}. + If there is no job calling |job_status()| on the returned Job + will result in "fail". + + +ch_info({handle}) *ch_info()* + Returns a Dictionary with information about {handle}. The + items are: + "id" number of the channel + "status" "open", "buffered" or "closed", like + ch_status() + When opened with ch_open(): + "hostname" the hostname of the address + "port" the port of the address + "sock_status" "open" or "closed" + "sock_mode" "NL", "RAW", "JSON" or "JS" + "sock_io" "socket" + "sock_timeout" timeout in msec + When opened with job_start(): + "out_status" "open", "buffered" or "closed" + "out_mode" "NL", "RAW", "JSON" or "JS" + "out_io" "null", "pipe", "file" or "buffer" + "out_timeout" timeout in msec + "err_status" "open", "buffered" or "closed" + "err_mode" "NL", "RAW", "JSON" or "JS" + "err_io" "out", "null", "pipe", "file" or "buffer" + "err_timeout" timeout in msec + "in_status" "open" or "closed" + "in_mode" "NL", "RAW", "JSON" or "JS" + "in_io" "null", "pipe", "file" or "buffer" + "in_timeout" timeout in msec + + +ch_log({msg} [, {handle}]) *ch_log()* + Write {msg} in the channel log file, if it was opened with + |ch_logfile()|. + When {handle} is passed the channel number is used for the + message. + {handle} can be a 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()* + Start logging channel activity to {fname}. + When {fname} is an empty string: stop logging. + + When {mode} is omitted or "a" append to the file. + When {mode} is "w" start with an empty file. + + Use |ch_log()| to write log messages. The file is flushed + after every message, on Unix you can use "tail -f" to see what + is going on in real time. + + This function is not available in the |sandbox|. + NOTE: the channel communication is stored in the file, be + aware that this may contain confidential and privacy sensitive + information, e.g. a password you type in a terminal window. + + +ch_open({address} [, {options}]) *ch_open()* + Open a channel to {address}. See |channel|. + Returns a Channel. Use |ch_status()| to check for failure. + + {address} has the form "hostname:port", e.g., + "localhost:8765". + + If {options} is given it must be a |Dictionary|. + See |channel-open-options|. + + +ch_read({handle} [, {options}]) *ch_read()* + Read from {handle} and return the received message. + {handle} can be a Channel or a Job that has a Channel. + For a NL channel this waits for a NL to arrive, except when + there is nothing more to read (channel was closed). + See |channel-more|. + + +ch_readblob({handle} [, {options}]) *ch_readblob()* + Like ch_read() but reads binary data and returns a |Blob|. + See |channel-more|. + + +ch_readraw({handle} [, {options}]) *ch_readraw()* + Like ch_read() but for a JS and JSON channel does not decode + the message. For a NL channel it does not block waiting for + the NL to arrive, but otherwise works like ch_read(). + See |channel-more|. + + +ch_sendexpr({handle}, {expr} [, {options}]) *ch_sendexpr()* + 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|. *E912* + {handle} can be a Channel or a Job that has a Channel. + + +ch_sendraw({handle}, {expr} [, {options}]) *ch_sendraw()* + Send |String| or |Blob| {expr} over {handle}. + Works like |ch_sendexpr()|, but does not encode the request or + decode the response. The caller is responsible for the + correct contents. Also does not add a newline for a channel + in NL mode, the caller must do that. The NL in the response + is removed. + See |channel-use|. + + +ch_setoptions({handle}, {options}) *ch_setoptions()* + Set options on {handle}: + "callback" the channel callback + "timeout" default read timeout in msec + "mode" mode for the whole channel + See |ch_open()| for more explanation. + {handle} can be a Channel or a Job that has a Channel. + + Note that changing the mode may cause queued messages to be + lost. + + These options cannot be changed: + "waittime" only applies to |ch_open()| + + +ch_status({handle} [, {options}]) *ch_status()* + Return the status of {handle}: + "fail" failed to open the channel + "open" channel can be used + "buffered" channel can be read, not written to + "closed" channel can not be used + {handle} can be a 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()|. + + If {options} is given it can contain a "part" entry to specify + the part of the channel to return the status for: "out" or + "err". For example, to get the error status: > + ch_status(job, {"part": "err"}) +< + +============================================================================== +9. Starting a job with a channel *job-start* *job* To start a job and open a channel for stdin/stdout/stderr: > let job = job_start(command, {options}) @@ -552,7 +758,7 @@ You will want to do something more useful than "echomsg". ============================================================================== -9. Starting a job without a channel *job-start-nochannel* +10. Starting a job without a channel *job-start-nochannel* To start another process without creating a channel: > let job = job_start(command, @@ -579,7 +785,164 @@ available. ============================================================================== -10. Job options *job-options* +11. Job functions *job-functions-details* + +job_getchannel({job}) *job_getchannel()* + Get the channel handle that {job} is using. + To check if the job has no channel: > + if string(job_getchannel()) == 'channel fail' +< + +job_info([{job}]) *job_info()* + Returns a Dictionary with information about {job}: + "status" what |job_status()| returns + "channel" what |job_getchannel()| returns + "cmd" List of command arguments used to start the job + "process" process ID + "tty_in" terminal input name, empty when none + "tty_out" terminal output name, empty when none + "exitval" only valid when "status" is "dead" + "exit_cb" function to be called on exit + "stoponexit" |job-stoponexit| + + Only in Unix: + "termsig" the signal which terminated the process + (See |job_stop()| for the values) + only valid when "status" is "dead" + + Only in MS-Windows: + "tty_type" Type of virtual console in use. + Values are "winpty" or "conpty". + See 'termwintype'. + + Without any arguments, returns a List with all Job objects. + + +job_setoptions({job}, {options}) *job_setoptions()* + Change options for {job}. Supported are: + "stoponexit" |job-stoponexit| + "exit_cb" |job-exit_cb| + + +job_start({command} [, {options}]) *job_start()* + Start a job and return a Job object. Unlike |system()| and + |:!cmd| this does not wait for the job to finish. + To start a job in a terminal window see |term_start()|. + + If the job fails to start then |job_status()| on the returned + Job object results in "fail" and none of the callbacks will be + invoked. + + {command} can be a String. This works best on MS-Windows. On + Unix it is split up in white-separated parts to be passed to + execvp(). Arguments in double quotes can contain white space. + + {command} can be a List, where the first item is the executable + and further items are the arguments. All items are converted + to String. This works best on Unix. + + On MS-Windows, job_start() makes a GUI application hidden. If + want to show it, Use |:!start| instead. + + The command is executed directly, not through a shell, the + 'shell' option is not used. To use the shell: > + let job = job_start(["/bin/sh", "-c", "echo hello"]) +< Or: > + let job = job_start('/bin/sh -c "echo hello"') +< Note that this will start two processes, the shell and the + command it executes. If you don't want this use the "exec" + shell command. + + On Unix $PATH is used to search for the executable only when + the command does not contain a slash. + + The job will use the same terminal as Vim. If it reads from + stdin the job and Vim will be fighting over input, that + doesn't work. Redirect stdin and stdout to avoid problems: > + let job = job_start(['sh', '-c', "myserver /dev/null"]) +< + The returned Job object can be used to get the status with + |job_status()| and stop the job with |job_stop()|. + + Note that the job object will be deleted if there are no + references to it. This closes the stdin and stderr, which may + cause the job to fail with an error. To avoid this keep a + reference to the job. Thus instead of: > + call job_start('my-command') +< use: > + let myjob = job_start('my-command') +< and unlet "myjob" once the job is not needed or is past the + point where it would fail (e.g. when it prints a message on + startup). Keep in mind that variables local to a function + will cease to exist if the function returns. Use a + script-local variable if needed: > + let s:myjob = job_start('my-command') +< + {options} must be a Dictionary. It can contain many optional + items, see |job-options|. + + +job_status({job}) *job_status()* *E916* + Returns a String with the status of {job}: + "run" job is running + "fail" job failed to start + "dead" job died or was stopped after running + + On Unix a non-existing command results in "dead" instead of + "fail", because a fork happens before the failure can be + detected. + + If an exit callback was set with the "exit_cb" option and the + job is now detected to be "dead" the callback will be invoked. + + For more information see |job_info()|. + + +job_stop({job} [, {how}]) *job_stop()* + Stop the {job}. This can also be used to signal the job. + + When {how} is omitted or is "term" the job will be terminated. + For Unix SIGTERM is sent. On MS-Windows the job will be + terminated forcedly (there is no "gentle" way). + This goes to the process group, thus children may also be + affected. + + Effect for Unix: + "term" SIGTERM (default) + "hup" SIGHUP + "quit" SIGQUIT + "int" SIGINT + "kill" SIGKILL (strongest way to stop) + number signal with that number + + Effect for MS-Windows: + "term" terminate process forcedly (default) + "hup" CTRL_BREAK + "quit" CTRL_BREAK + "int" CTRL_C + "kill" terminate process forcedly + Others CTRL_BREAK + + On Unix the signal is sent to the process group. This means + that when the job is "sh -c command" it affects both the shell + and the command. + + The result is a Number: 1 if the operation could be executed, + 0 if "how" is not supported on the system. + Note that even when the operation was executed, whether the + job was actually stopped needs to be checked with + |job_status()|. + + If the status of the job is "dead", the signal will not be + sent. This is to avoid to stop the wrong job (esp. on Unix, + where process numbers are recycled). + + When using "kill" Vim will assume the job will die and close + the channel. + + +============================================================================== +12. Job options *job-options* The {options} argument in job_start() is a dictionary. All entries are optional. Some options can be used after the job has started, using @@ -773,7 +1136,7 @@ If the file already exists it is truncated. ============================================================================== -11. Controlling a job *job-control* +13. Controlling a job *job-control* To get the status of a job: > echo job_status(job) @@ -789,7 +1152,7 @@ For more options see |job_stop()|. ============================================================================== -12. Using a prompt buffer *prompt-buffer* +14. Using a prompt buffer *prompt-buffer* If you want to type input for the job in a Vim window you have a few options: - Use a normal buffer and handle all possible commands yourself. diff -Nru vim-8.1.1681/runtime/doc/debugger.txt vim-8.1.1729/runtime/doc/debugger.txt --- vim-8.1.1681/runtime/doc/debugger.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/debugger.txt 2019-07-21 21:04:21.000000000 +0000 @@ -1,4 +1,4 @@ -*debugger.txt* For Vim version 8.1. Last change: 2019 May 12 +*debugger.txt* For Vim version 8.1. Last change: 2019 Jul 06 VIM REFERENCE MANUAL by Gordon Prieur @@ -6,6 +6,10 @@ Debugger Support Features *debugger-support* +These features are for integration with a debugger or an Integrated +Programming Environment (IPE) or Integrated Development Environment (IDE). +For the debugger running in a Vim terminal window see |terminal-debugger|. + 1. Debugger Features |debugger-features| 2. Vim Compile Options |debugger-compilation| 3. Integrated Debuggers |debugger-integration| @@ -14,9 +18,7 @@ ============================================================================== 1. Debugger Features *debugger-features* -The following features are available for an integration with a debugger or -an Integrated Programming Environment (IPE) or Integrated Development -Environment (IDE): +The following features are available: Alternate Command Input |alt-input| Debug Signs |debug-signs| @@ -90,6 +92,9 @@ could be used for displaying other information as well. The functionality is limited though, for advanced popups see |popup-window|. +Another way to use the balloon is with the 'balloonexpr' option. This is +completely user definable. + The Balloon Evaluation has some settable parameters too. For Motif the font list and colors can be set via X resources (XmNballoonEvalFontList, XmNballoonEvalBackground, and XmNballoonEvalForeground). @@ -106,9 +111,6 @@ toolbar. The 'ballooneval' option does not need to be set for this. But the other settings apply. -Another way to use the balloon is with the 'balloonexpr' option. This is -completely user definable. - ============================================================================== 2. Vim Compile Options *debugger-compilation* diff -Nru vim-8.1.1681/runtime/doc/eval.txt vim-8.1.1729/runtime/doc/eval.txt --- vim-8.1.1681/runtime/doc/eval.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/eval.txt 2019-07-21 21:04:21.000000000 +0000 @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 8.1. Last change: 2019 Jul 04 +*eval.txt* For Vim version 8.1. Last change: 2019 Jul 21 VIM REFERENCE MANUAL by Bram Moolenaar @@ -31,7 +31,9 @@ 11. No +eval feature |no-eval-feature| 12. The sandbox |eval-sandbox| 13. Textlock |textlock| -14. Testing |testing| + +Testing support is documented in |testing.txt|. +Profiling is documented at |profiling|. ============================================================================== 1. Variables *variables* @@ -58,7 +60,9 @@ Dictionary An associative, unordered array: Each entry has a key and a value. |Dictionary| - Example: {'blue': "#0000ff", 'red': "#ff0000"} + Examples: + {'blue': "#0000ff", 'red': "#ff0000"} + #{blue: "#0000ff", red: "#ff0000"} Funcref A reference to a function |Funcref|. Example: function("strlen") @@ -477,8 +481,14 @@ A key is always a String. You can use a Number, it will be converted to a String automatically. Thus the String '4' and the number 4 will find the same entry. Note that the String '04' and the Number 04 are different, since the -Number will be converted to the String '4'. The empty string can be used as a -key. +Number will be converted to the String '4'. The empty string can also be used +as a key. + *literal-Dict* +To avoid having to put quotes around every key the #{} form can be used. This +does require the key to consist only of ASCII letters, digits, '-' and '_'. +Example: > + let mydict = #{zero: 0, one_key: 1, two-key: 2, 333: 3} +Note that 333 here is the string "333". Empty keys are not possible with #{}. A value can be any expression. Using a Dictionary for a value creates a nested Dictionary: > @@ -2660,6 +2670,7 @@ command argument shiftwidth([{col}]) Number effective value of 'shiftwidth' sign_define({name} [, {dict}]) Number define or update a sign +sign_define({list}) List define or update a list of signs sign_getdefined([{name}]) List get a list of defined signs sign_getplaced([{expr} [, {dict}]]) List get a list of placed signs @@ -2667,9 +2678,12 @@ Number jump to a sign sign_place({id}, {group}, {name}, {expr} [, {dict}]) Number place a sign +sign_placelist({list}) List place a list of signs sign_undefine([{name}]) Number undefine a sign +sign_undefine({list}) List undefine a list of signs sign_unplace({group} [, {dict}]) Number unplace a sign +sign_unplacelist({list}) List unplace a list of signs simplify({filename}) String simplify filename as much as possible sin({expr}) Float sine of {expr} sinh({expr}) Float hyperbolic sine of {expr} @@ -2940,117 +2954,9 @@ The {winid} argument specifies the window ID, see |argc()|. -assert_beeps({cmd}) *assert_beeps()* - Run {cmd} and add an error message to |v:errors| if it does - NOT produce a beep or visual bell. - Also see |assert_fails()| and |assert-return|. - - *assert_equal()* -assert_equal({expected}, {actual} [, {msg}]) - When {expected} and {actual} are not equal an error message is - added to |v:errors| and 1 is returned. Otherwise zero is - returned |assert-return|. - There is no automatic conversion, the String "4" is different - from the Number 4. And the number 4 is different from the - Float 4.0. The value of 'ignorecase' is not used here, case - always matters. - When {msg} is omitted an error in the form "Expected - {expected} but got {actual}" is produced. - Example: > - assert_equal('foo', 'bar') -< Will result in a string to be added to |v:errors|: - test.vim line 12: Expected 'foo' but got 'bar' ~ - *assert_equalfile()* -assert_equalfile({fname-one}, {fname-two}) - When the files {fname-one} and {fname-two} do not contain - exactly the same text an error message is added to |v:errors|. - Also see |assert-return|. - When {fname-one} or {fname-two} does not exist the error will - mention that. - Mainly useful with |terminal-diff|. - -assert_exception({error} [, {msg}]) *assert_exception()* - When v:exception does not contain the string {error} an error - message is added to |v:errors|. Also see |assert-return|. - This can be used to assert that a command throws an exception. - Using the error number, followed by a colon, avoids problems - with translations: > - try - commandthatfails - call assert_false(1, 'command should have failed') - catch - call assert_exception('E492:') - endtry - -assert_fails({cmd} [, {error} [, {msg}]]) *assert_fails()* - Run {cmd} and add an error message to |v:errors| if it does - NOT produce an error. Also see |assert-return|. - When {error} is given it must match in |v:errmsg|. - Note that beeping is not considered an error, and some failing - commands only beep. Use |assert_beeps()| for those. - -assert_false({actual} [, {msg}]) *assert_false()* - When {actual} is not false an error message is added to - |v:errors|, like with |assert_equal()|. - Also see |assert-return|. - A value is false when it is zero. When {actual} is not a - number the assert fails. - When {msg} is omitted an error in the form - "Expected False but got {actual}" is produced. - -assert_inrange({lower}, {upper}, {actual} [, {msg}]) *assert_inrange()* - This asserts number and |Float| values. When {actual} is lower - than {lower} or higher than {upper} an error message is added - to |v:errors|. Also see |assert-return|. - When {msg} is omitted an error in the form - "Expected range {lower} - {upper}, but got {actual}" is - produced. - - *assert_match()* -assert_match({pattern}, {actual} [, {msg}]) - When {pattern} does not match {actual} an error message is - added to |v:errors|. Also see |assert-return|. - - {pattern} is used as with |=~|: The matching is always done - like 'magic' was set and 'cpoptions' is empty, no matter what - the actual value of 'magic' or 'cpoptions' is. - - {actual} is used as a string, automatic conversion applies. - Use "^" and "$" to match with the start and end of the text. - Use both to match the whole text. - - When {msg} is omitted an error in the form - "Pattern {pattern} does not match {actual}" is produced. - Example: > - assert_match('^f.*o$', 'foobar') -< Will result in a string to be added to |v:errors|: - test.vim line 12: Pattern '^f.*o$' does not match 'foobar' ~ - - *assert_notequal()* -assert_notequal({expected}, {actual} [, {msg}]) - The opposite of `assert_equal()`: add an error message to - |v:errors| when {expected} and {actual} are equal. - Also see |assert-return|. - - *assert_notmatch()* -assert_notmatch({pattern}, {actual} [, {msg}]) - The opposite of `assert_match()`: add an error message to - |v:errors| when {pattern} matches {actual}. - Also see |assert-return|. - -assert_report({msg}) *assert_report()* - Report a test failure directly, using {msg}. - Always returns one. - -assert_true({actual} [, {msg}]) *assert_true()* - When {actual} is not true an error message is added to - |v:errors|, like with |assert_equal()|. - Also see |assert-return|. - A value is TRUE when it is a non-zero number. When {actual} - is not a number the assert fails. - When {msg} is omitted an error in the form "Expected True but - got {actual}" is produced. +assert_ functions are documented here: |assert-functions| + asin({expr}) *asin()* Return the arc sine of {expr} measured in radians, as a |Float| @@ -3346,213 +3252,10 @@ < 4.0 {only available when compiled with the |+float| feature} -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. - - This is useful to read from a channel at a convenient time, - e.g. from a timer. - - Note that messages are dropped when the channel does not have - a callback. Add a close callback to avoid that. - - {only available when compiled with the |+channel| feature} - -ch_close({handle}) *ch_close()* - Close {handle}. See |channel-close|. - {handle} can be a 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 a Channel or a Job that has a Channel. - A close callback is not invoked. - - {only available when compiled with the |+channel| feature} - -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 a 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 - for this specific request. - ch_evalexpr() waits for a response and returns the decoded - expression. When there is an error or timeout it returns an - empty string. +ch_ functions are documented here: |channel-functions-details| - {only available when compiled with the |+channel| feature} -ch_evalraw({handle}, {string} [, {options}]) *ch_evalraw()* - Send {string} over {handle}. - {handle} can be a 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 - correct contents. Also does not add a newline for a channel - in NL mode, the caller must do that. The NL in the response - is removed. - Note that Vim does not know when the text received on a raw - channel is complete, it may only return the first part and you - need to use |ch_readraw()| to fetch the rest. - See |channel-use|. - - {only available when compiled with the |+channel| feature} - -ch_getbufnr({handle}, {what}) *ch_getbufnr()* - Get the buffer number that {handle} is using for {what}. - {handle} can be a 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. - {only available when compiled with the |+channel| feature} - -ch_getjob({channel}) *ch_getjob()* - Get the Job associated with {channel}. - If there is no job calling |job_status()| on the returned Job - will result in "fail". - - {only available when compiled with the |+channel| and - |+job| features} - -ch_info({handle}) *ch_info()* - Returns a Dictionary with information about {handle}. The - items are: - "id" number of the channel - "status" "open", "buffered" or "closed", like - ch_status() - When opened with ch_open(): - "hostname" the hostname of the address - "port" the port of the address - "sock_status" "open" or "closed" - "sock_mode" "NL", "RAW", "JSON" or "JS" - "sock_io" "socket" - "sock_timeout" timeout in msec - When opened with job_start(): - "out_status" "open", "buffered" or "closed" - "out_mode" "NL", "RAW", "JSON" or "JS" - "out_io" "null", "pipe", "file" or "buffer" - "out_timeout" timeout in msec - "err_status" "open", "buffered" or "closed" - "err_mode" "NL", "RAW", "JSON" or "JS" - "err_io" "out", "null", "pipe", "file" or "buffer" - "err_timeout" timeout in msec - "in_status" "open" or "closed" - "in_mode" "NL", "RAW", "JSON" or "JS" - "in_io" "null", "pipe", "file" or "buffer" - "in_timeout" timeout in msec - -ch_log({msg} [, {handle}]) *ch_log()* - Write {msg} in the channel log file, if it was opened with - |ch_logfile()|. - When {handle} is passed the channel number is used for the - message. - {handle} can be a 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()* - Start logging channel activity to {fname}. - When {fname} is an empty string: stop logging. - - When {mode} is omitted or "a" append to the file. - When {mode} is "w" start with an empty file. - - Use |ch_log()| to write log messages. The file is flushed - after every message, on Unix you can use "tail -f" to see what - is going on in real time. - - This function is not available in the |sandbox|. - NOTE: the channel communication is stored in the file, be - aware that this may contain confidential and privacy sensitive - information, e.g. a password you type in a terminal window. - - -ch_open({address} [, {options}]) *ch_open()* - Open a channel to {address}. See |channel|. - Returns a Channel. Use |ch_status()| to check for failure. - - {address} has the form "hostname:port", e.g., - "localhost:8765". - - If {options} is given it must be a |Dictionary|. - See |channel-open-options|. - - {only available when compiled with the |+channel| feature} - -ch_read({handle} [, {options}]) *ch_read()* - Read from {handle} and return the received message. - {handle} can be a Channel or a Job that has a Channel. - For a NL channel this waits for a NL to arrive, except when - there is nothing more to read (channel was closed). - See |channel-more|. - {only available when compiled with the |+channel| feature} - -ch_readblob({handle} [, {options}]) *ch_readblob()* - Like ch_read() but reads binary data and returns a |Blob|. - See |channel-more|. - {only available when compiled with the |+channel| feature} - -ch_readraw({handle} [, {options}]) *ch_readraw()* - Like ch_read() but for a JS and JSON channel does not decode - the message. For a NL channel it does not block waiting for - the NL to arrive, but otherwise works like ch_read(). - See |channel-more|. - {only available when compiled with the |+channel| feature} - -ch_sendexpr({handle}, {expr} [, {options}]) *ch_sendexpr()* - 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|. *E912* - {handle} can be a Channel or a Job that has a Channel. - - {only available when compiled with the |+channel| feature} - -ch_sendraw({handle}, {expr} [, {options}]) *ch_sendraw()* - Send |String| or |Blob| {expr} over {handle}. - Works like |ch_sendexpr()|, but does not encode the request or - decode the response. The caller is responsible for the - correct contents. Also does not add a newline for a channel - in NL mode, the caller must do that. The NL in the response - is removed. - See |channel-use|. - - {only available when compiled with the |+channel| feature} - -ch_setoptions({handle}, {options}) *ch_setoptions()* - Set options on {handle}: - "callback" the channel callback - "timeout" default read timeout in msec - "mode" mode for the whole channel - See |ch_open()| for more explanation. - {handle} can be a Channel or a Job that has a Channel. - - Note that changing the mode may cause queued messages to be - lost. - - These options cannot be changed: - "waittime" only applies to |ch_open()| - -ch_status({handle} [, {options}]) *ch_status()* - Return the status of {handle}: - "fail" failed to open the channel - "open" channel can be used - "buffered" channel can be read, not written to - "closed" channel can not be used - {handle} can be a 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()|. - - If {options} is given it can contain a "part" entry to specify - the part of the channel to return the status for: "out" or - "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 @@ -6032,161 +5735,9 @@ echo key . ': ' . value endfor -job_getchannel({job}) *job_getchannel()* - Get the channel handle that {job} is using. - To check if the job has no channel: > - if string(job_getchannel()) == 'channel fail' -< - {only available when compiled with the |+job| feature} - -job_info([{job}]) *job_info()* - Returns a Dictionary with information about {job}: - "status" what |job_status()| returns - "channel" what |job_getchannel()| returns - "cmd" List of command arguments used to start the job - "process" process ID - "tty_in" terminal input name, empty when none - "tty_out" terminal output name, empty when none - "exitval" only valid when "status" is "dead" - "exit_cb" function to be called on exit - "stoponexit" |job-stoponexit| - - Only in Unix: - "termsig" the signal which terminated the process - (See |job_stop()| for the values) - only valid when "status" is "dead" - - Only in MS-Windows: - "tty_type" Type of virtual console in use. - Values are "winpty" or "conpty". - See 'termwintype'. - - Without any arguments, returns a List with all Job objects. - -job_setoptions({job}, {options}) *job_setoptions()* - Change options for {job}. Supported are: - "stoponexit" |job-stoponexit| - "exit_cb" |job-exit_cb| - -job_start({command} [, {options}]) *job_start()* - Start a job and return a Job object. Unlike |system()| and - |:!cmd| this does not wait for the job to finish. - To start a job in a terminal window see |term_start()|. - - If the job fails to start then |job_status()| on the returned - Job object results in "fail" and none of the callbacks will be - invoked. - - {command} can be a String. This works best on MS-Windows. On - Unix it is split up in white-separated parts to be passed to - execvp(). Arguments in double quotes can contain white space. - - {command} can be a List, where the first item is the executable - and further items are the arguments. All items are converted - to String. This works best on Unix. - - On MS-Windows, job_start() makes a GUI application hidden. If - want to show it, Use |:!start| instead. - - The command is executed directly, not through a shell, the - 'shell' option is not used. To use the shell: > - let job = job_start(["/bin/sh", "-c", "echo hello"]) -< Or: > - let job = job_start('/bin/sh -c "echo hello"') -< Note that this will start two processes, the shell and the - command it executes. If you don't want this use the "exec" - shell command. - - On Unix $PATH is used to search for the executable only when - the command does not contain a slash. - - The job will use the same terminal as Vim. If it reads from - stdin the job and Vim will be fighting over input, that - doesn't work. Redirect stdin and stdout to avoid problems: > - let job = job_start(['sh', '-c', "myserver /dev/null"]) -< - The returned Job object can be used to get the status with - |job_status()| and stop the job with |job_stop()|. - - Note that the job object will be deleted if there are no - references to it. This closes the stdin and stderr, which may - cause the job to fail with an error. To avoid this keep a - reference to the job. Thus instead of: > - call job_start('my-command') -< use: > - let myjob = job_start('my-command') -< and unlet "myjob" once the job is not needed or is past the - point where it would fail (e.g. when it prints a message on - startup). Keep in mind that variables local to a function - will cease to exist if the function returns. Use a - script-local variable if needed: > - let s:myjob = job_start('my-command') -< - {options} must be a Dictionary. It can contain many optional - items, see |job-options|. - - {only available when compiled with the |+job| feature} - -job_status({job}) *job_status()* *E916* - Returns a String with the status of {job}: - "run" job is running - "fail" job failed to start - "dead" job died or was stopped after running - - On Unix a non-existing command results in "dead" instead of - "fail", because a fork happens before the failure can be - detected. - - If an exit callback was set with the "exit_cb" option and the - job is now detected to be "dead" the callback will be invoked. - - For more information see |job_info()|. - - {only available when compiled with the |+job| feature} - -job_stop({job} [, {how}]) *job_stop()* - Stop the {job}. This can also be used to signal the job. - - When {how} is omitted or is "term" the job will be terminated. - For Unix SIGTERM is sent. On MS-Windows the job will be - terminated forcedly (there is no "gentle" way). - This goes to the process group, thus children may also be - affected. - - Effect for Unix: - "term" SIGTERM (default) - "hup" SIGHUP - "quit" SIGQUIT - "int" SIGINT - "kill" SIGKILL (strongest way to stop) - number signal with that number - - Effect for MS-Windows: - "term" terminate process forcedly (default) - "hup" CTRL_BREAK - "quit" CTRL_BREAK - "int" CTRL_C - "kill" terminate process forcedly - Others CTRL_BREAK - - On Unix the signal is sent to the process group. This means - that when the job is "sh -c command" it affects both the shell - and the command. - - The result is a Number: 1 if the operation could be executed, - 0 if "how" is not supported on the system. - Note that even when the operation was executed, whether the - job was actually stopped needs to be checked with - |job_status()|. - - If the status of the job is "dead", the signal will not be - sent. This is to avoid to stop the wrong job (esp. on Unix, - where process numbers are recycled). - When using "kill" Vim will assume the job will die and close - the channel. +job_ functions are documented here: |job-functions-details| - {only available when compiled with the |+job| feature} join({list} [, {sep}]) *join()* Join the items in {list} together into one String. @@ -6494,6 +6045,8 @@ listener_remove({id}) *listener_remove()* Remove a listener previously added with listener_add(). + Returns zero when {id} could not be found, one when {id} was + removed. localtime() *localtime()* Return the current time, measured as seconds since 1st Jan @@ -7319,201 +6872,7 @@ "prompt". Example: > call prompt_setprompt(bufnr(''), 'command: ') < - *prop_add()* *E965* -prop_add({lnum}, {col}, {props}) - Attach a text property at position {lnum}, {col}. {col} is - counted in bytes, use one for the first column. - If {lnum} is invalid an error is given. *E966* - If {col} is invalid an error is given. *E964* - - {props} is a dictionary with these fields: - length length of text in bytes, can only be used - for a property that does not continue in - another line; can be zero - end_lnum line number for the end of text - end_col column just after the text; not used when - "length" is present; when {col} and "end_col" - are equal, and "end_lnum" is omitted or equal - to {lnum}, this is a zero-width text property - bufnr buffer to add the property to; when omitted - the current buffer is used - id user defined ID for the property; when omitted - zero is used - type name of the text property type - All fields except "type" are optional. - - It is an error when both "length" and "end_lnum" or "end_col" - are given. Either use "length" or "end_col" for a property - within one line, or use "end_lnum" and "end_col" for a - property that spans more than one line. - When neither "length" nor "end_col" are given the property - will be zero-width. That means it will not be highlighted but - will move with the text, as a kind of mark. - The property can end exactly at the last character of the - text, or just after it. In the last case, if text is appended - to the line, the text property size will increase, also when - the property type does not have "end_incl" set. - - "type" will first be looked up in the buffer the property is - added to. When not found, the global property types are used. - If not found an error is given. - - See |text-properties| for information about text properties. - - -prop_clear({lnum} [, {lnum-end} [, {props}]]) *prop_clear()* - Remove all text properties from line {lnum}. - When {lnum-end} is given, remove all text properties from line - {lnum} to {lnum-end} (inclusive). - - When {props} contains a "bufnr" item use this buffer, - otherwise use the current buffer. - - See |text-properties| for information about text properties. - - *prop_find()* -prop_find({props} [, {direction}]) - NOT IMPLEMENTED YET - Search for a text property as specified with {props}: - id property with this ID - type property with this type name - bufnr buffer to search in; when present a - start position with "lnum" and "col" - must be given; when omitted the - current buffer is used - lnum start in this line (when omitted start - at the cursor) - col start at this column (when omitted - and "lnum" is given: use column 1, - otherwise start at the cursor) - skipstart do not look for a match at the start - position - - {direction} can be "f" for forward and "b" for backward. When - omitted forward search is performed. - - If a match is found then a Dict is returned with the entries - as with prop_list(), and additionally an "lnum" entry. - If no match is found then an empty Dict is returned. - - See |text-properties| for information about text properties. - - -prop_list({lnum} [, {props}]) *prop_list()* - Return a List with all text properties in line {lnum}. - - When {props} contains a "bufnr" item, use this buffer instead - of the current buffer. - - The properties are ordered by starting column and priority. - Each property is a Dict with these entries: - col starting column - length length in bytes, one more if line break is - included - id property ID - type name of the property type, omitted if - the type was deleted - start when TRUE property starts in this line - end when TRUE property ends in this line - - When "start" is zero the property started in a previous line, - the current one is a continuation. - When "end" is zero the property continues in the next line. - The line break after this line is included. - - See |text-properties| for information about text properties. - - - *prop_remove()* *E968* -prop_remove({props} [, {lnum} [, {lnum-end}]]) - Remove a matching text property from line {lnum}. When - {lnum-end} is given, remove matching text properties from line - {lnum} to {lnum-end} (inclusive). - When {lnum} is omitted remove matching text properties from - all lines. - - {props} is a dictionary with these fields: - id remove text properties with this ID - type remove text properties with this type name - bufnr use this buffer instead of the current one - all when TRUE remove all matching text properties, - not just the first one - A property matches when either "id" or "type" matches. - If buffer "bufnr" does not exist you get an error message. - If buffer "bufnr" is not loaded then nothing happens. - - Returns the number of properties that were removed. - - See |text-properties| for information about text properties. - - -prop_type_add({name}, {props}) *prop_type_add()* *E969* *E970* - Add a text property type {name}. If a property type with this - name already exists an error is given. - {props} is a dictionary with these optional fields: - bufnr define the property only for this buffer; this - avoids name collisions and automatically - clears the property types when the buffer is - deleted. - highlight name of highlight group to use - priority when a character has multiple text - properties the one with the highest priority - will be used; negative values can be used, the - default priority is zero - combine when TRUE combine the highlight with any - syntax highlight; when omitted or FALSE syntax - highlight will not be used - start_incl when TRUE inserts at the start position will - be included in the text property - end_incl when TRUE inserts at the end position will be - included in the text property - - See |text-properties| for information about text properties. - - -prop_type_change({name}, {props}) *prop_type_change()* - Change properties of an existing text property type. If a - property with this name does not exist an error is given. - The {props} argument is just like |prop_type_add()|. - - See |text-properties| for information about text properties. - - -prop_type_delete({name} [, {props}]) *prop_type_delete()* - Remove the text property type {name}. When text properties - using the type {name} are still in place, they will not have - an effect and can no longer be removed by name. - - {props} can contain a "bufnr" item. When it is given, delete - a property type from this buffer instead of from the global - property types. - - When text property type {name} is not found there is no error. - - See |text-properties| for information about text properties. - - -prop_type_get([{name} [, {props}]) *prop_type_get()* - Returns the properties of property type {name}. This is a - dictionary with the same fields as was given to - prop_type_add(). - When the property type {name} does not exist, an empty - dictionary is returned. - - {props} can contain a "bufnr" item. When it is given, use - this buffer instead of the global property types. - - See |text-properties| for information about text properties. - - -prop_type_list([{props}]) *prop_type_list()* - Returns a list with all property type names. - - {props} can contain a "bufnr" item. When it is given, use - this buffer instead of the global property types. - - See |text-properties| for information about text properties. - +prop_ functions are documented here: |text-prop-functions|. pumvisible() *pumvisible()* Returns non-zero when the popup menu is visible, zero @@ -8623,240 +7982,9 @@ 'vartabstop' feature. If the 'vartabstop' setting is enabled and no {col} argument is given, column 1 will be assumed. -sign_define({name} [, {dict}]) *sign_define()* - Define a new sign named {name} or modify the attributes of an - existing sign. This is similar to the |:sign-define| command. - - Prefix {name} with a unique text to avoid name collisions. - There is no {group} like with placing signs. - - The {name} can be a String or a Number. The optional {dict} - argument specifies the sign attributes. The following values - are supported: - icon full path to the bitmap file for the sign. - linehl highlight group used for the whole line the - sign is placed in. - text text that is displayed when there is no icon - or the GUI is not being used. - texthl highlight group used for the text item - - If the sign named {name} already exists, then the attributes - of the sign are updated. - - Returns 0 on success and -1 on failure. - - Examples: > - call sign_define("mySign", {"text" : "=>", "texthl" : - \ "Error", "linehl" : "Search"}) -< -sign_getdefined([{name}]) *sign_getdefined()* - Get a list of defined signs and their attributes. - This is similar to the |:sign-list| command. - - If the {name} is not supplied, then a list of all the defined - signs is returned. Otherwise the attribute of the specified - sign is returned. - - Each list item in the returned value is a dictionary with the - following entries: - icon full path to the bitmap file of the sign - linehl highlight group used for the whole line the - sign is placed in. - name name of the sign - text text that is displayed when there is no icon - or the GUI is not being used. - texthl highlight group used for the text item - - Returns an empty List if there are no signs and when {name} is - not found. - - Examples: > - " Get a list of all the defined signs - echo sign_getdefined() - - " Get the attribute of the sign named mySign - echo sign_getdefined("mySign") -< -sign_getplaced([{expr} [, {dict}]]) *sign_getplaced()* - Return a list of signs placed in a buffer or all the buffers. - This is similar to the |:sign-place-list| command. - - If the optional buffer name {expr} is specified, then only the - list of signs placed in that buffer is returned. For the use - of {expr}, see |bufname()|. The optional {dict} can contain - the following entries: - group select only signs in this group - id select sign with this identifier - lnum select signs placed in this line. For the use - of {lnum}, see |line()|. - If {group} is '*', then signs in all the groups including the - global group are returned. If {group} is not supplied or is an - empty string, then only signs in the global group are - returned. If no arguments are supplied, then signs in the - global group placed in all the buffers are returned. - See |sign-group|. - - Each list item in the returned value is a dictionary with the - following entries: - bufnr number of the buffer with the sign - signs list of signs placed in {bufnr}. Each list - item is a dictionary with the below listed - entries - - The dictionary for each sign contains the following entries: - group sign group. Set to '' for the global group. - id identifier of the sign - lnum line number where the sign is placed - name name of the defined sign - priority sign priority - - The returned signs in a buffer are ordered by their line - number and priority. - - Returns an empty list on failure or if there are no placed - signs. - - Examples: > - " Get a List of signs placed in eval.c in the - " global group - echo sign_getplaced("eval.c") - - " Get a List of signs in group 'g1' placed in eval.c - echo sign_getplaced("eval.c", {'group' : 'g1'}) - - " Get a List of signs placed at line 10 in eval.c - echo sign_getplaced("eval.c", {'lnum' : 10}) - - " Get sign with identifier 10 placed in a.py - echo sign_getplaced("a.py", {'id' : 10}) - - " Get sign with id 20 in group 'g1' placed in a.py - echo sign_getplaced("a.py", {'group' : 'g1', - \ 'id' : 20}) - - " Get a List of all the placed signs - echo sign_getplaced() -< - *sign_jump()* -sign_jump({id}, {group}, {expr}) - Open the buffer {expr} or jump to the window that contains - {expr} and position the cursor at sign {id} in group {group}. - This is similar to the |:sign-jump| command. - - For the use of {expr}, see |bufname()|. - - Returns the line number of the sign. Returns -1 if the - arguments are invalid. - - Example: > - " Jump to sign 10 in the current buffer - call sign_jump(10, '', '') -< - *sign_place()* -sign_place({id}, {group}, {name}, {expr} [, {dict}]) - Place the sign defined as {name} at line {lnum} in file or - buffer {expr} and assign {id} and {group} to sign. This is - similar to the |:sign-place| command. - - If the sign identifier {id} is zero, then a new identifier is - allocated. Otherwise the specified number is used. {group} is - the sign group name. To use the global sign group, use an - empty string. {group} functions as a namespace for {id}, thus - two groups can use the same IDs. Refer to |sign-identifier| - and |sign-group| for more information. - - {name} refers to a defined sign. - {expr} refers to a buffer name or number. For the accepted - values, see |bufname()|. - - The optional {dict} argument supports the following entries: - lnum line number in the file or buffer - {expr} where the sign is to be placed. - For the accepted values, see |line()|. - priority priority of the sign. See - |sign-priority| for more information. - - If the optional {dict} is not specified, then it modifies the - placed sign {id} in group {group} to use the defined sign - {name}. - - Returns the sign identifier on success and -1 on failure. - - Examples: > - " Place a sign named sign1 with id 5 at line 20 in - " buffer json.c - call sign_place(5, '', 'sign1', 'json.c', - \ {'lnum' : 20}) - - " Updates sign 5 in buffer json.c to use sign2 - call sign_place(5, '', 'sign2', 'json.c') - - " Place a sign named sign3 at line 30 in - " buffer json.c with a new identifier - let id = sign_place(0, '', 'sign3', 'json.c', - \ {'lnum' : 30}) - - " Place a sign named sign4 with id 10 in group 'g3' - " at line 40 in buffer json.c with priority 90 - call sign_place(10, 'g3', 'sign4', 'json.c', - \ {'lnum' : 40, 'priority' : 90}) -< -sign_undefine([{name}]) *sign_undefine()* - Deletes a previously defined sign {name}. This is similar to - the |:sign-undefine| command. If {name} is not supplied, then - deletes all the defined signs. - - Returns 0 on success and -1 on failure. - - Examples: > - " Delete a sign named mySign - call sign_undefine("mySign") - - " Delete all the signs - call sign_undefine() -< -sign_unplace({group} [, {dict}]) *sign_unplace()* - Remove a previously placed sign in one or more buffers. This - is similar to the |:sign-unplace| command. - - {group} is the sign group name. To use the global sign group, - use an empty string. If {group} is set to '*', then all the - groups including the global group are used. - The signs in {group} are selected based on the entries in - {dict}. The following optional entries in {dict} are - supported: - buffer buffer name or number. See |bufname()|. - id sign identifier - If {dict} is not supplied, then all the signs in {group} are - removed. - - Returns 0 on success and -1 on failure. - - Examples: > - " Remove sign 10 from buffer a.vim - call sign_unplace('', {'buffer' : "a.vim", 'id' : 10}) - - " Remove sign 20 in group 'g1' from buffer 3 - call sign_unplace('g1', {'buffer' : 3, 'id' : 20}) - - " Remove all the signs in group 'g2' from buffer 10 - call sign_unplace('g2', {'buffer' : 10}) - - " Remove sign 30 in group 'g3' from all the buffers - call sign_unplace('g3', {'id' : 30}) - - " Remove all the signs placed in buffer 5 - call sign_unplace('*', {'buffer' : 5}) - - " Remove the signs in group 'g4' from all the buffers - call sign_unplace('g4') +sign_ functions are documented here: |sign-functions-details| - " Remove sign 40 from all the buffers - call sign_unplace('*', {'id' : 40}) - " Remove all the placed signs from all the buffers - call sign_unplace('*') -< simplify({filename}) *simplify()* Simplify the file name as much as possible without changing the meaning. Shortcuts (on MS-Windows) or symbolic links (on @@ -9697,147 +8825,11 @@ For MS-Windows forward slashes are used when the 'shellslash' option is set or when 'shellcmdflag' starts with '-'. -term_ functions are documented here: |terminal-function-details| -test_alloc_fail({id}, {countdown}, {repeat}) *test_alloc_fail()* - This is for testing: If the memory allocation with {id} is - called, then decrement {countdown}, and when it reaches zero - let memory allocation fail {repeat} times. When {repeat} is - smaller than one it fails one time. - -test_autochdir() *test_autochdir()* - Set a flag to enable the effect of 'autochdir' before Vim - startup has finished. +term_ functions are documented here: |terminal-function-details| -test_feedinput({string}) *test_feedinput()* - Characters in {string} are queued for processing as if they - were typed by the user. This uses a low level input buffer. - This function works only when with |+unix| or GUI is running. +test_ functions are documented here: |test-functions| -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_garbagecollect_soon() *test_garbagecollect_soon()* - Set the flag to call the garbagecollector as if in the main - loop. Only to be used in tests. - -test_getvalue({name}) *test_getvalue()* - Get the value of an internal variable. These values for - {name} are supported: - need_fileinfo - -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. - When the {expr} is the string "RESET" then the list of ignored - errors is made empty. - -test_null_blob() *test_null_blob()* - Return a |Blob| that is null. Only useful for testing. - -test_null_channel() *test_null_channel()* - Return a |Channel| that is null. Only useful for testing. - {only available when compiled with the +channel feature} - -test_null_dict() *test_null_dict()* - Return a |Dict| that is null. Only useful for testing. - -test_null_job() *test_null_job()* - Return a |Job| that is null. Only useful for testing. - {only available when compiled with the +job feature} - -test_null_list() *test_null_list()* - Return a |List| that is null. Only useful for testing. - -test_null_partial() *test_null_partial()* - Return a |Partial| that is null. Only useful for testing. - -test_null_string() *test_null_string()* - Return a |String| that is null. Only useful for testing. - -test_option_not_set({name}) *test_option_not_set()* - Reset the flag that indicates option {name} was set. Thus it - looks like it still has the default value. Use like this: > - set ambiwidth=double - call test_option_not_set('ambiwidth') -< Now the 'ambiwidth' option behaves like it was never changed, - even though the value is "double". - Only to be used for testing! - -test_override({name}, {val}) *test_override()* - Overrides certain parts of Vim's 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 - redraw_flag ignore the RedrawingDisabled flag - char_avail disable the char_avail() function - starting reset the "starting" variable, see below - nfa_fail makes the NFA regexp engine fail to force a - fallback to the old engine - no_query_mouse do not query the mouse position for "dec" - terminals - no_wait_return set the "no_wait_return" flag. Not restored - with "ALL". - ALL clear all overrides ({val} is not used) - - "starting" is to be used when a test should behave like - startup was done. Since the tests are run by sourcing a - script the "starting" variable is non-zero. This is usually a - good thing (tests run faster), but sometimes changes behavior - in a way that the test doesn't work properly. - When using: > - call test_override('starting', 1) -< The value of "starting" is saved. It is restored by: > - call test_override('starting', 0) - -test_refcount({expr}) *test_refcount()* - Return the reference count of {expr}. When {expr} is of a - type that does not have a reference count, returns -1. Only - to be used for testing. - -test_scrollbar({which}, {value}, {dragging}) *test_scrollbar()* - Pretend using scrollbar {which} to move it to position - {value}. {which} can be: - left Left scrollbar of the current window - right Right scrollbar of the current window - hor Horizontal scrollbar - - For the vertical scrollbars {value} can be 1 to the - line-count of the buffer. For the horizontal scrollbar the - {value} can be between 1 and the maximum line length, assuming - 'wrap' is not set. - - When {dragging} is non-zero it's like dragging the scrollbar, - otherwise it's like clicking in the scrollbar. - Only works when the {which} scrollbar actually exists, - obviously only when using the GUI. - -test_setmouse({row}, {col}) *test_setmouse()* - Set the mouse position to be used for the next mouse action. - {row} and {col} are one based. - For example: > - call test_setmouse(4, 20) - call feedkeys("\", "xt") - -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. *timer_info()* timer_info([{id}]) @@ -9917,8 +8909,8 @@ timer_stopall() *timer_stopall()* Stop all timers. The timer callbacks will no longer be - invoked. Useful if some timers is misbehaving. If there are - no timers there is no error. + invoked. Useful if a timer is misbehaving. If there are no + timers there is no error. {only available when compiled with the |+timers| feature} @@ -11261,7 +10253,8 @@ Like above, but append/add/subtract the value for each |List| item. - *:let=<<* *:let-heredoc* *E990* *E991* + *:let=<<* *:let-heredoc* + *E990* *E991* *E172* *E221* :let {var-name} =<< [trim] {marker} text... text... @@ -11269,11 +10262,10 @@ Set internal variable {var-name} to a List containing the lines of text bounded by the string {marker}. {marker} must not contain white space. + {marker} cannot start with a lower case character. The last line should end only with the {marker} string without any other character. Watch out for white space after {marker}! - If {marker} is not supplied, then "." is used as the - default marker. Without "trim" any white space characters in the lines of text are preserved. If "trim" is specified before @@ -11380,6 +10372,11 @@ register values cannot be used here, since they cannot be locked. +:cons[t] +:cons[t] {var-name} + If no argument is given or only {var-name} is given, + the behavior is the same as |:let|. + :lockv[ar][!] [depth] {name} ... *:lockvar* *:lockv* Lock the internal variable {name}. Locking means that it can no longer be changed (until it is unlocked). @@ -12991,26 +11988,5 @@ - closing a window or quitting Vim - etc. -============================================================================== -14. Testing *testing* - -Vim can be tested after building it, usually with "make test". -The tests are located in the directory "src/testdir". - -There are several types of tests added over time: - test33.in oldest, don't add any more - test_something.in old style tests - test_something.vim new style tests - - *new-style-testing* -New tests should be added as new style tests. These use functions such as -|assert_equal()| to keep the test commands and the expected result in one -place. - *old-style-testing* -In some cases an old style test needs to be used. E.g. when testing Vim -without the |+eval| feature. - -Find more information in the file src/testdir/README.txt. - vim:tw=78:ts=8:noet:ft=help:norl: diff -Nru vim-8.1.1681/runtime/doc/filetype.txt vim-8.1.1729/runtime/doc/filetype.txt --- vim-8.1.1681/runtime/doc/filetype.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/filetype.txt 2019-07-21 21:04:21.000000000 +0000 @@ -1,4 +1,4 @@ -*filetype.txt* For Vim version 8.1. Last change: 2019 May 05 +*filetype.txt* For Vim version 8.1. Last change: 2019 Jul 16 VIM REFERENCE MANUAL by Bram Moolenaar @@ -642,6 +642,16 @@ let g:python_recommended_style = 0 +QF QUICKFIX *qf.vim* *ft-qf-plugin* + +The "qf" filetype is used for the quickfix window, see |quickfix-window|. + +The quickfix filetype plugin includes configuration for displaying the command +that produced the quickfix list in the |status-line|. To disable this setting, +configure as follows: > + :let g:qf_disable_statusline = 1 + + R MARKDOWN *ft-rmd-plugin* By default ftplugin/html.vim is not sourced. If you want it sourced, add to diff -Nru vim-8.1.1681/runtime/doc/help.txt vim-8.1.1729/runtime/doc/help.txt --- vim-8.1.1681/runtime/doc/help.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/help.txt 2019-07-21 21:04:21.000000000 +0000 @@ -1,4 +1,4 @@ -*help.txt* For Vim version 8.1. Last change: 2019 May 12 +*help.txt* For Vim version 8.1. Last change: 2019 Jul 21 VIM - main help file k @@ -139,6 +139,7 @@ |fold.txt| hide (fold) ranges of lines Special issues ~ +|testing.txt| testing Vim and Vim scripts |print.txt| printing |remote.txt| using Vim as a server or client |term.txt| using different terminals and mice diff -Nru vim-8.1.1681/runtime/doc/Makefile vim-8.1.1729/runtime/doc/Makefile --- vim-8.1.1681/runtime/doc/Makefile 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/Makefile 2019-07-21 21:04:21.000000000 +0000 @@ -103,6 +103,7 @@ tagsrch.txt \ term.txt \ terminal.txt \ + testing.txt \ textprop.txt \ tips.txt \ todo.txt \ @@ -241,6 +242,7 @@ tagsrch.html \ term.html \ terminal.html \ + testing.html \ textprop.html \ tips.html \ todo.html \ diff -Nru vim-8.1.1681/runtime/doc/mbyte.txt vim-8.1.1729/runtime/doc/mbyte.txt --- vim-8.1.1681/runtime/doc/mbyte.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/mbyte.txt 2019-07-21 21:04:21.000000000 +0000 @@ -1,4 +1,4 @@ -*mbyte.txt* For Vim version 8.1. Last change: 2019 Apr 28 +*mbyte.txt* For Vim version 8.1. Last change: 2019 Jul 04 VIM REFERENCE MANUAL by Bram Moolenaar et al. @@ -943,11 +943,12 @@ IME many many many times. Because IME with status on is hooking all of your key inputs, you cannot input 'j', 'k', or almost all of keys to Vim directly. -This |+multi_byte_ime| feature help this. It reduce times of switch status of -IME manually. In normal mode, there are almost no need working IME, even -editing multibyte text. So exiting insert mode with ESC, Vim memorize last -status of IME and force turn off IME. When re-enter insert mode, Vim revert -IME status to that memorized automatically. +The |+multi_byte_ime| feature helps for this. It reduces the number of times +the IME status has to be switched manually. In Normal mode, there is almost +no need to use IME, even when editing multibyte text. So when exiting Insert +mode, Vim memorizes the last status of IME and turns off IME. When +re-entering Insert mode, Vim sets the IME status to that memorized status +automatically. This works on not only insert-normal mode, but also search-command input and replace mode. diff -Nru vim-8.1.1681/runtime/doc/options.txt vim-8.1.1729/runtime/doc/options.txt --- vim-8.1.1681/runtime/doc/options.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/options.txt 2019-07-21 21:04:21.000000000 +0000 @@ -1,4 +1,4 @@ -*options.txt* For Vim version 8.1. Last change: 2019 Jun 27 +*options.txt* For Vim version 8.1. Last change: 2019 Jul 18 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1142,8 +1142,10 @@ set bexpr=MyBalloonExpr() set ballooneval < - Also see |balloon_show()|, can be used if the content of the balloon - is to be fetched asynchronously. + Also see |balloon_show()|, it can be used if the content of the balloon + is to be fetched asynchronously. In that case evaluating + 'balloonexpr' should result in an empty string. If you get a balloon + with only "0" you probably didn't return anything from your function. NOTE: The balloon is displayed only if the cursor is on a text character. If the result of evaluating 'balloonexpr' is not empty, @@ -1155,7 +1157,7 @@ This option cannot be set in a modeline when 'modelineexpr' is off. It is not allowed to change text or jump to another window while - evaluating 'balloonexpr' |textlock|. + evaluating 'balloonexpr', see |textlock|. To check whether line breaks in the balloon text work use this check: > if has("balloon_multiline") @@ -5625,7 +5627,16 @@ {not available when compiled without the |+windows| or |+quickfix| features} Default height for a preview window. Used for |:ptag| and associated - commands. Used for |CTRL-W_}| when no count is given. + commands. Used for |CTRL-W_}| when no count is given. Not used when + 'previewpopup' is set. + + *'previewpopup'* *'pvp'* +'previewpopup' 'pvp' string (default empty) + global + {not available when compiled without the |+windows|, + |+textprop| or |+quickfix| feature} + When not empty a popup window is used for commands that would open a + preview window. See |preview-popup|. *'previewwindow'* *'nopreviewwindow'* *'pvw'* *'nopvw'* *E590* diff -Nru vim-8.1.1681/runtime/doc/pi_netrw.txt vim-8.1.1729/runtime/doc/pi_netrw.txt --- vim-8.1.1681/runtime/doc/pi_netrw.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/pi_netrw.txt 2019-07-21 21:04:21.000000000 +0000 @@ -1,4 +1,4 @@ -*pi_netrw.txt* For Vim version 8.1. Last change: 2019 May 05 +*pi_netrw.txt* For Vim version 8.1. Last change: 2019 Jul 17 ------------------------------------------------ NETRW REFERENCE MANUAL by Charles E. Campbell @@ -1184,7 +1184,7 @@ *.netrwbook* Bookmarks are retained in between sessions of vim in a file called .netrwbook as a |List|, which is typically stored in the first directory on the user's -'|runtimepath|'; entries are kept in sorted order. +'runtimepath'; entries are kept in sorted order. If there are marked files and/or directories, mb will add them to the bookmark list. @@ -2094,7 +2094,7 @@ However, given the default setting for g:netrw_keepdir of 1 where netrw maintains its own separate notion of the current directory, in order to make -the two directories the same, use the "c" map (just type c). That map will +the two directories the same, use the "cd" map (type cd). That map will set Vim's notion of the current directory to netrw's current browsing directory. @@ -2739,7 +2739,7 @@ =0 : show all =1 : show not-hidden files =2 : show hidden files only - default: =0 + default: =1 *g:netrw_home* The home directory for where bookmarks and history are saved (as .netrwbook and @@ -2940,14 +2940,23 @@ netrwBak : *.bak netrwCompress: *.gz *.bz2 *.Z *.zip + netrwCoreDump: core.\d\+ netrwData : *.dat + netrwDoc : *.doc,*.txt,*.pdf, + *.pdf,*.docx netrwHdr : *.h + netrwLex : *.l *.lex netrwLib : *.a *.so *.lib *.dll netrwMakefile: [mM]akefile *.mak netrwObj : *.o *.obj + netrwPix : *.bmp,*.fit,*.fits,*.gif, + *.jpg,*.jpeg,*.pcx,*.ppc + *.pgm,*.png,*.psd,*.rgb + *.tif,*.xbm,*.xcf netrwTags : tags ANmenu ANtags netrwTilde : * netrwTmp : tmp* *tmp + netrwYacc : *.y In addition, those groups mentioned in |'suffixes'| are also added to the special @@ -3032,8 +3041,9 @@ current netrw buffer's window to be used for the new window. If g:netrw_winsize is less than zero, then - the absolute value of g:netrw_winsize lines - or columns will be used for the new window. + the absolute value of g:netrw_winsize will be + used to specify the quantity of lines or + columns for the new window. If g:netrw_winsize is zero, then a normal split will be made (ie. |'equalalways'| will take effect, for example). @@ -3371,7 +3381,7 @@ (This section is likely to grow as I get feedback) (also see |netrw-debug|) *netrw-p1* - P1. I use windows 95, and my ftp dumps four blank lines at the + P1. I use windows 95, and my ftp dumps four blank lines at the {{{2 end of every read. See |netrw-fixup|, and put the following into your @@ -3380,7 +3390,7 @@ let g:netrw_win95ftp= 1 *netrw-p2* - P2. I use Windows, and my network browsing with ftp doesn't sort by + P2. I use Windows, and my network browsing with ftp doesn't sort by {{{2 time or size! -or- The remote system is a Windows server; why don't I get sorts by time or size? @@ -3407,7 +3417,7 @@ *netrw-p3* - P3. I tried rcp://user@host/ (or protocol other than ftp) and netrw + P3. I tried rcp://user@host/ (or protocol other than ftp) and netrw {{{2 used ssh! That wasn't what I asked for... Netrw has two methods for browsing remote directories: ssh @@ -3416,7 +3426,7 @@ listing), netrw will use the given protocol to do so. *netrw-p4* - P4. I would like long listings to be the default. + P4. I would like long listings to be the default. {{{2 Put the following statement into your |.vimrc|: > @@ -3426,7 +3436,7 @@ you can set. *netrw-p5* - P5. My times come up oddly in local browsing + P5. My times come up oddly in local browsing {{{2 Does your system's strftime() accept the "%c" to yield dates such as "Sun Apr 27 11:49:23 1997"? If not, do a @@ -3436,7 +3446,7 @@ let g:netrw_timefmt= "%X" (where X is the option) < *netrw-p6* - P6. I want my current directory to track my browsing. + P6. I want my current directory to track my browsing. {{{2 How do I do that? Put the following line in your |.vimrc|: @@ -3444,8 +3454,8 @@ let g:netrw_keepdir= 0 < *netrw-p7* - P7. I use Chinese (or other non-ascii) characters in my filenames, and - netrw (Explore, Sexplore, Hexplore, etc) doesn't display them! + P7. I use Chinese (or other non-ascii) characters in my filenames, {{{2 + and netrw (Explore, Sexplore, Hexplore, etc) doesn't display them! (taken from an answer provided by Wu Yongwei on the vim mailing list) @@ -3459,7 +3469,7 @@ (...it is one more reason to recommend that people use utf-8!) *netrw-p8* - P8. I'm getting "ssh is not executable on your system" -- what do I + P8. I'm getting "ssh is not executable on your system" -- what do I {{{2 do? (Dudley Fox) Most people I know use putty for windows ssh. It @@ -3502,7 +3512,7 @@ - Click "Add..." - Set External Editor (adjust path as needed, include the quotes and !.! at the end): - "c:\Program Files\Vim\vim81\gvim.exe" !.! + "c:\Program Files\Vim\vim70\gvim.exe" !.! - Check that the filetype in the box below is {asterisk}.{asterisk} (all files), or whatever types you want (cec: change {asterisk} to * ; I had to @@ -3542,7 +3552,7 @@ default. *netrw-p9* *netrw-ml_get* - P9. I'm browsing, changing directory, and bang! ml_get errors + P9. I'm browsing, changing directory, and bang! ml_get errors {{{2 appear and I have to kill vim. Any way around this? Normally netrw attempts to avoid writing swapfiles for @@ -3553,7 +3563,7 @@ let g:netrw_use_noswf= 0 < *netrw-p10* - P10. I'm being pestered with "[something] is a directory" and + P10. I'm being pestered with "[something] is a directory" and {{{2 "Press ENTER or type command to continue" prompts... The "[something] is a directory" prompt is issued by Vim, @@ -3564,8 +3574,8 @@ your <.vimrc> file. *netrw-p11* - P11. I want to have two windows; a thin one on the left and my editing - window on the right. How may I accomplish this? + P11. I want to have two windows; a thin one on the left and my {{{2 + editing window on the right. How may I accomplish this? You probably want netrw running as in a side window. If so, you will likely find that ":[N]Lexplore" does what you want. The @@ -3590,7 +3600,7 @@ *netrw-p12* - P12. My directory isn't sorting correctly, or unwanted letters are + P12. My directory isn't sorting correctly, or unwanted letters are {{{2 appearing in the listed filenames, or things aren't lining up properly in the wide listing, ... @@ -3600,9 +3610,9 @@ You may need to change |g:netrw_sepchr| and/or |g:netrw_xstrlen|. *netrw-p13* - P13. I'm a Windows + putty + ssh user, and when I attempt to browse, - the directories are missing trailing "/"s so netrw treats them - as file transfers instead of as attempts to browse + P13. I'm a Windows + putty + ssh user, and when I attempt to {{{2 + browse, the directories are missing trailing "/"s so netrw treats + them as file transfers instead of as attempts to browse subdirectories. How may I fix this? (mikeyao) If you want to use vim via ssh and putty under Windows, @@ -3621,7 +3631,7 @@ "let g:netrw_scp_cmd = "d:\\dev\\putty\\PSCP.exe" < *netrw-p14* - P14. I would like to speed up writes using Nwrite and scp/ssh + P14. I would like to speed up writes using Nwrite and scp/ssh {{{2 style connections. How? (Thomer M. Gil) Try using ssh's ControlMaster and ControlPath (see the ssh_config @@ -3648,8 +3658,8 @@ vim scp://host.domain.com//home/user/.bashrc < *netrw-p15* - P15. How may I use a double-click instead of netrw's usual single click - to open a file or directory? (Ben Fritz) + P15. How may I use a double-click instead of netrw's usual single {{{2 + click to open a file or directory? (Ben Fritz) First, disable netrw's mapping with > let g:netrw_mousemaps= 0 @@ -3661,7 +3671,7 @@ (see |g:netrw_mousemaps|) *netrw-p16* - P16. When editing remote files (ex. :e ftp://hostname/path/file), + P16. When editing remote files (ex. :e ftp://hostname/path/file), {{{2 under Windows I get an |E303| message complaining that its unable to open a swap file. @@ -3670,7 +3680,7 @@ directory. *netrw-p17* - P17. Netrw is closing buffers on its own. + P17. Netrw is closing buffers on its own. {{{2 What steps will reproduce the problem? 1. :Explore, navigate directories, open a file 2. :Explore, open another file @@ -3684,14 +3694,14 @@ a ":ls!" will show them (although ":ls" does not). *netrw-P18* - P18. How to locally edit a file that's only available via + P18. How to locally edit a file that's only available via {{{2 another server accessible via ssh? See http://stackoverflow.com/questions/12469645/ "Using Vim to Remotely Edit A File on ServerB Only Accessible From ServerA" *netrw-P19* - P19. How do I get numbering on in directory listings? + P19. How do I get numbering on in directory listings? {{{2 With |g:netrw_bufsettings|, you can control netrw's buffer settings; try putting > let g:netrw_bufsettings="noma nomod nu nobl nowrap ro nornu" @@ -3700,7 +3710,7 @@ let g:netrw_bufsettings="noma nomod nonu nobl nowrap ro rnu" < *netrw-P20* - P20. How may I have gvim start up showing a directory listing? + P20. How may I have gvim start up showing a directory listing? {{{2 Try putting the following code snippet into your .vimrc: > augroup VimStartup au! @@ -3713,8 +3723,8 @@ (ie. a "huge" vim version). *netrw-P21* - P21. I've made a directory (or file) with an accented character, but - netrw isn't letting me enter that directory/read that file: + P21. I've made a directory (or file) with an accented character, {{{2 + but netrw isn't letting me enter that directory/read that file: Its likely that the shell or o/s is using a different encoding than you have vim (netrw) using. A patch to vim supporting @@ -3724,7 +3734,7 @@ au FileType netrw set enc=latin1 < *netrw-P22* - P22. I get an error message when I try to copy or move a file: + P22. I get an error message when I try to copy or move a file: {{{2 **error** (netrw) tried using g:netrw_localcopycmd; it doesn't work! @@ -3752,8 +3762,8 @@ The script is typically installed on systems as something like: > - /usr/local/share/vim/vim8x/plugin/netrwPlugin.vim - /usr/local/share/vim/vim8x/autoload/netrw.vim + /usr/local/share/vim/vim7x/plugin/netrwPlugin.vim + /usr/local/share/vim/vim7x/autoload/netrw.vim (see output of :echo &rtp) < which is loaded automatically at startup (assuming :set nocp). If you @@ -3832,6 +3842,16 @@ ============================================================================== 12. History *netrw-history* {{{1 + v163: Dec 05, 2017 * (Cristi Balan) reported that a setting ('sel') + was left changed + * (Holger Mitschke) reported a problem with + saving and restoring history. Fixed. + * Hopefully I fixed a nasty bug that caused a + file rename to wipe out a buffer that it + should not have wiped out. + * (Holger Mitschke) amended this help file + with additional |g:netrw_special_syntax| + items v162: Sep 19, 2016 * (haya14busa) pointed out two syntax errors with a patch; these are now fixed. Oct 26, 2016 * I started using mate-terminal and found that diff -Nru vim-8.1.1681/runtime/doc/popup.txt vim-8.1.1729/runtime/doc/popup.txt --- vim-8.1.1681/runtime/doc/popup.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/popup.txt 2019-07-21 21:04:21.000000000 +0000 @@ -1,4 +1,4 @@ -*popup.txt* For Vim version 8.1. Last change: 2019 Jul 04 +*popup.txt* For Vim version 8.1. Last change: 2019 Jul 18 VIM REFERENCE MANUAL by Bram Moolenaar @@ -178,11 +178,11 @@ popup_atcursor({what}, {options}) *popup_atcursor()* Show the {what} above the cursor, and close it when the cursor moves. This works like: > - call popup_create({what}, { - \ 'pos': 'botleft', - \ 'line': 'cursor-1', - \ 'col': 'cursor', - \ 'moved': 'WORD', + call popup_create({what}, #{ + \ pos: 'botleft', + \ line: 'cursor-1', + \ col: 'cursor', + \ moved: 'WORD', \ }) < Use {options} to change the properties. @@ -191,11 +191,11 @@ Show the {what} above the position from 'ballooneval' and close it when the mouse moves. This works like: > let pos = screenpos(v:beval_winnr, v:beval_lnum, v:beval_col) - call popup_create({what}, { - \ 'pos': 'botleft', - \ 'line': pos.row - 1, - \ 'col': pos.col, - \ 'mousemoved': 'WORD', + call popup_create({what}, #{ + \ pos: 'botleft', + \ line: pos.row - 1, + \ col: pos.col, + \ mousemoved: 'WORD', \ }) < Use {options} to change the properties. See |popup_beval_example| for an example use. @@ -240,18 +240,18 @@ popup_dialog({what}, {options}) *popup_dialog()* Just like |popup_create()| but with these default options: > - call popup_create({what}, { - \ 'pos': 'center', - \ 'zindex': 200, - \ 'drag': 1, - \ 'border': [], - \ 'padding': [], + call popup_create({what}, #{ + \ pos: 'center', + \ zindex: 200, + \ drag: 1, + \ border: [], + \ padding: [], \}) < Use {options} to change the properties. E.g. add a 'filter' option with value 'popup_filter_yesno'. Example: > - call popup_create('do you want to quit (Yes/no)?', { - \ 'filter': 'popup_filter_yesno', - \ 'callback': 'QuitCallback', + call popup_create('do you want to quit (Yes/no)?', #{ + \ filter: 'popup_filter_yesno', + \ callback: 'QuitCallback', \ }) < By default the dialog can be dragged, so that text below it @@ -303,7 +303,7 @@ zero. When all values are one then an empty list is included. "borderhighlight" is not included when all values are empty. - "scrollbarhighlight" and "thumbhighlight" are onlu included + "scrollbarhighlight" and "thumbhighlight" are only included when set. "tabpage" will be -1 for a global popup, zero for a popup on @@ -345,7 +345,7 @@ popup_locate({row}, {col}) *popup_locate()* - Return the |window-ID| of the popup at screen positoin {row} + Return the |window-ID| of the popup at screen position {row} and {col}. If there are multiple popups the one with the highest zindex is returned. If there are no popups at this position then zero is returned. @@ -356,14 +356,15 @@ items with cursorkeys, and close it an item is selected with Space or Enter. {what} should have multiple lines to make this useful. This works like: > - call popup_create({what}, { - \ 'pos': 'center', - \ 'zindex': 200, - \ 'drag': 1, - \ 'wrap': 0, - \ 'border': [], - \ 'padding': [], - \ 'filter': 'popup_filter_menu', + call popup_create({what}, #{ + \ pos: 'center', + \ zindex: 200, + \ drag: 1, + \ wrap: 0, + \ border: [], + \ cursorline: 1, + \ padding: [0,1,0,1], + \ filter: 'popup_filter_menu', \ }) < The current line is highlighted with a match using "PopupSelected", or "PmenuSel" if that is not defined. @@ -391,18 +392,18 @@ popup_notification({what}, {options}) *popup_notification()* Show the {what} for 3 seconds at the top of the Vim window. This works like: > - call popup_create({what}, { - \ 'line': 1, - \ 'col': 10, - \ 'minwidth': 20, - \ 'time': 3000, - \ 'tabpage': -1, - \ 'zindex': 300, - \ 'drag': 1, - \ 'highlight': 'WarningMsg', - \ 'border': [], - \ 'close': 'click', - \ 'padding': [0,1,0,1], + call popup_create({what}, #{ + \ line: 1, + \ col: 10, + \ minwidth: 20, + \ time: 3000, + \ tabpage: -1, + \ zindex: 300, + \ drag: 1, + \ highlight: 'WarningMsg', + \ border: [], + \ close: 'click', + \ padding: [0,1,0,1], \ }) < The PopupNotification highlight group is used instead of WarningMsg if it is defined. @@ -429,6 +430,7 @@ callback close drag + cursorline filter firstline flip @@ -598,6 +600,11 @@ {start} or after {end} The popup also closes if the cursor moves to another line or to another window. + cursorline non-zero: Highlight the cursor line. Also scrolls the + text to show this line (only works properly + when 'wrap' is off). + zero: Do not highlight the cursor line. + Default is zero, except for |popup_menu()|. filter A callback that can filter typed characters, see |popup-filter|. callback A callback that is called when the popup closes, e.g. @@ -695,9 +702,9 @@ the window. This can be disabled by setting the "scrollbar" option to zero. When the scrollbar is displayed mouse scroll events, while the mouse pointer is on the popup, will cause the text to scroll up or down as you would expect. -A click in the upper halve of the scrollbar will scroll the text one line -down. A click in the lower halve wil scroll the text one line up. However, -this is limited so that the popup does not get smaller. +A click in the upper half of the scrollbar will scroll the text down one line. +A click in the lower half will scroll the text up one line. However, this is +limited so that the popup does not get smaller. POPUP MASK *popup-mask* @@ -709,7 +716,7 @@ leftmost, negative for counting from the right, -1 for rightmost endcol last column, like "col" - line start line, positive for conting from the top, 1 for top, + line start line, positive for counting from the top, 1 for top, negative for counting from the bottom, -1 for bottom endline end line, like "line" @@ -732,17 +739,17 @@ endif endfunc - call popup_dialog('Continue? y/n', { - \ 'filter': 'popup_filter_yesno', - \ 'callback': 'MyDialogHandler', + call popup_dialog('Continue? y/n', #{ + \ filter: 'popup_filter_yesno', + \ callback: 'MyDialogHandler', \ }) < *popup_menu-shortcut-example* Extend popup_filter_menu() with shortcut keys: > - call popup_menu(['Save', 'Cancel', 'Discard'], { - \ 'filter': 'MyMenuFilter', - \ 'callback': 'MyMenuHandler', + call popup_menu(['Save', 'Cancel', 'Discard'], #{ + \ filter: 'MyMenuFilter', + \ callback: 'MyMenuHandler', \ }) func MyMenuFilter(id, key) @@ -781,7 +788,7 @@ endif call popup_close(s:winid) endif - let s:winid = popup_beval(v:beval_text, {'mousemoved': 'word'}) + let s:winid = popup_beval(v:beval_text, #{mousemoved: 'word'}) let s:last_text = v:beval_text return '' endfunc @@ -812,7 +819,7 @@ endfunc func ShowPopup(id) - let s:winid = popup_beval(s:balloonText, {'mousemoved': 'word'}) + let s:winid = popup_beval(s:balloonText, #{mousemoved: 'word'}) endfunc < diff -Nru vim-8.1.1681/runtime/doc/quickfix.txt vim-8.1.1729/runtime/doc/quickfix.txt --- vim-8.1.1681/runtime/doc/quickfix.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/quickfix.txt 2019-07-21 21:04:21.000000000 +0000 @@ -1,4 +1,4 @@ -*quickfix.txt* For Vim version 8.1. Last change: 2019 Jun 02 +*quickfix.txt* For Vim version 8.1. Last change: 2019 Jul 15 VIM REFERENCE MANUAL by Bram Moolenaar @@ -650,9 +650,9 @@ When the quickfix window has been filled, two autocommand events are triggered. First the 'filetype' option is set to "qf", which triggers the -FileType event. Then the BufReadPost event is triggered, using "quickfix" for -the buffer name. This can be used to perform some action on the listed -errors. Example: > +FileType event (also see |qf.vim|). Then the BufReadPost event is triggered, +using "quickfix" for the buffer name. This can be used to perform some action +on the listed errors. Example: > au BufReadPost quickfix setlocal modifiable \ | silent exe 'g/^/s//\=line(".")." "/' \ | setlocal nomodifiable diff -Nru vim-8.1.1681/runtime/doc/quickref.txt vim-8.1.1729/runtime/doc/quickref.txt --- vim-8.1.1681/runtime/doc/quickref.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/quickref.txt 2019-07-21 21:04:21.000000000 +0000 @@ -1,4 +1,4 @@ -*quickref.txt* For Vim version 8.1. Last change: 2019 May 31 +*quickref.txt* For Vim version 8.1. Last change: 2019 Jul 18 VIM REFERENCE MANUAL by Bram Moolenaar @@ -829,6 +829,7 @@ 'perldll' name of the Perl dynamic library 'preserveindent' 'pi' preserve the indent structure when reindenting 'previewheight' 'pvh' height of the preview window +'previewpopup' 'pvp' use popup window for preview 'previewwindow' 'pvw' identifies the preview window 'printdevice' 'pdev' name of the printer to be used for :hardcopy 'printencoding' 'penc' encoding to be used for printing diff -Nru vim-8.1.1681/runtime/doc/sign.txt vim-8.1.1729/runtime/doc/sign.txt --- vim-8.1.1681/runtime/doc/sign.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/sign.txt 2019-07-21 21:04:21.000000000 +0000 @@ -1,4 +1,4 @@ -*sign.txt* For Vim version 8.1. Last change: 2019 Jun 04 +*sign.txt* For Vim version 8.1. Last change: 2019 Jul 21 VIM REFERENCE MANUAL by Gordon Prieur @@ -9,6 +9,7 @@ 1. Introduction |sign-intro| 2. Commands |sign-commands| +3. Functions |sign-functions-details| {only available when compiled with the |+signs| feature} @@ -344,4 +345,357 @@ Same but jump to the sign in group {group} +============================================================================== +3. Functions *sign-functions-details* + +sign_define({name} [, {dict}]) *sign_define()* +sign_define({list}) + Define a new sign named {name} or modify the attributes of an + existing sign. This is similar to the |:sign-define| command. + + Prefix {name} with a unique text to avoid name collisions. + There is no {group} like with placing signs. + + The {name} can be a String or a Number. The optional {dict} + argument specifies the sign attributes. The following values + are supported: + icon full path to the bitmap file for the sign. + linehl highlight group used for the whole line the + sign is placed in. + text text that is displayed when there is no icon + or the GUI is not being used. + texthl highlight group used for the text item + + If the sign named {name} already exists, then the attributes + of the sign are updated. + + The one argument {list} can be used to define a list of signs. + Each list item is a dictionary with the above items in {dict} + and a 'name' item for the sign name. + + Returns 0 on success and -1 on failure. When the one argument + {list} is used, then returns a List of values one for each + defined sign. + + Examples: > + call sign_define("mySign", { + \ "text" : "=>", + \ "texthl" : "Error", + \ "linehl" : "Search"}) + call sign_define([ + \ {'name' : 'sign1', + \ 'text' : '=>'}, + \ {'name' : 'sign2', + \ 'text' : '!!'} + \ ]) +< +sign_getdefined([{name}]) *sign_getdefined()* + Get a list of defined signs and their attributes. + This is similar to the |:sign-list| command. + + If the {name} is not supplied, then a list of all the defined + signs is returned. Otherwise the attribute of the specified + sign is returned. + + Each list item in the returned value is a dictionary with the + following entries: + icon full path to the bitmap file of the sign + linehl highlight group used for the whole line the + sign is placed in. + name name of the sign + text text that is displayed when there is no icon + or the GUI is not being used. + texthl highlight group used for the text item + + Returns an empty List if there are no signs and when {name} is + not found. + + Examples: > + " Get a list of all the defined signs + echo sign_getdefined() + + " Get the attribute of the sign named mySign + echo sign_getdefined("mySign") +< +sign_getplaced([{expr} [, {dict}]]) *sign_getplaced()* + Return a list of signs placed in a buffer or all the buffers. + This is similar to the |:sign-place-list| command. + + If the optional buffer name {expr} is specified, then only the + list of signs placed in that buffer is returned. For the use + of {expr}, see |bufname()|. The optional {dict} can contain + the following entries: + group select only signs in this group + id select sign with this identifier + lnum select signs placed in this line. For the use + of {lnum}, see |line()|. + If {group} is '*', then signs in all the groups including the + global group are returned. If {group} is not supplied or is an + empty string, then only signs in the global group are + returned. If no arguments are supplied, then signs in the + global group placed in all the buffers are returned. + See |sign-group|. + + Each list item in the returned value is a dictionary with the + following entries: + bufnr number of the buffer with the sign + signs list of signs placed in {bufnr}. Each list + item is a dictionary with the below listed + entries + + The dictionary for each sign contains the following entries: + group sign group. Set to '' for the global group. + id identifier of the sign + lnum line number where the sign is placed + name name of the defined sign + priority sign priority + + The returned signs in a buffer are ordered by their line + number and priority. + + Returns an empty list on failure or if there are no placed + signs. + + Examples: > + " Get a List of signs placed in eval.c in the + " global group + echo sign_getplaced("eval.c") + + " Get a List of signs in group 'g1' placed in eval.c + echo sign_getplaced("eval.c", {'group' : 'g1'}) + + " Get a List of signs placed at line 10 in eval.c + echo sign_getplaced("eval.c", {'lnum' : 10}) + + " Get sign with identifier 10 placed in a.py + echo sign_getplaced("a.py", {'id' : 10}) + + " Get sign with id 20 in group 'g1' placed in a.py + echo sign_getplaced("a.py", {'group' : 'g1', + \ 'id' : 20}) + + " Get a List of all the placed signs + echo sign_getplaced() +< + *sign_jump()* +sign_jump({id}, {group}, {expr}) + Open the buffer {expr} or jump to the window that contains + {expr} and position the cursor at sign {id} in group {group}. + This is similar to the |:sign-jump| command. + + For the use of {expr}, see |bufname()|. + + Returns the line number of the sign. Returns -1 if the + arguments are invalid. + + Example: > + " Jump to sign 10 in the current buffer + call sign_jump(10, '', '') +< + + *sign_place()* +sign_place({id}, {group}, {name}, {expr} [, {dict}]) + Place the sign defined as {name} at line {lnum} in file or + buffer {expr} and assign {id} and {group} to sign. This is + similar to the |:sign-place| command. + + If the sign identifier {id} is zero, then a new identifier is + allocated. Otherwise the specified number is used. {group} is + the sign group name. To use the global sign group, use an + empty string. {group} functions as a namespace for {id}, thus + two groups can use the same IDs. Refer to |sign-identifier| + and |sign-group| for more information. + + {name} refers to a defined sign. + {expr} refers to a buffer name or number. For the accepted + values, see |bufname()|. + + The optional {dict} argument supports the following entries: + lnum line number in the file or buffer + {expr} where the sign is to be placed. + For the accepted values, see |line()|. + priority priority of the sign. See + |sign-priority| for more information. + + If the optional {dict} is not specified, then it modifies the + placed sign {id} in group {group} to use the defined sign + {name}. + + Returns the sign identifier on success and -1 on failure. + + Examples: > + " Place a sign named sign1 with id 5 at line 20 in + " buffer json.c + call sign_place(5, '', 'sign1', 'json.c', + \ {'lnum' : 20}) + + " Updates sign 5 in buffer json.c to use sign2 + call sign_place(5, '', 'sign2', 'json.c') + + " Place a sign named sign3 at line 30 in + " buffer json.c with a new identifier + let id = sign_place(0, '', 'sign3', 'json.c', + \ {'lnum' : 30}) + + " Place a sign named sign4 with id 10 in group 'g3' + " at line 40 in buffer json.c with priority 90 + call sign_place(10, 'g3', 'sign4', 'json.c', + \ {'lnum' : 40, 'priority' : 90}) +< + + *sign_placelist()* +sign_placelist({list}) + Place one or more signs. This is similar to the + |sign_place()| function. The {list} argument specifies the + List of signs to place. Each list item is a dict with the + following sign attributes: + buffer buffer name or number. For the accepted + values, see |bufname()|. + group sign group. {group} functions as a namespace + for {id}, thus two groups can use the same + IDs. If not specified or set to an empty + string, then the global group is used. See + |sign-group| for more information. + id sign identifier. If not specified or zero, + then a new unique identifier is allocated. + Otherwise the specified number is used. See + |sign-identifier| for more information. + lnum line number in the buffer {expr} where the + sign is to be placed. For the accepted values, + see |line()|. + name name of the sign to place. See |sign_define()| + for more information. + priority priority of the sign. When multiple signs are + placed on a line, the sign with the highest + priority is used. If not specified, the + default value of 10 is used. See + |sign-priority| for more information. + + If {id} refers to an existing sign, then the existing sign is + modified to use the specified {name} and/or {priority}. + + Returns a List of sign identifiers. If failed to place a + sign, the corresponding list item is set to -1. + + Examples: > + " Place sign s1 with id 5 at line 20 and id 10 at line + " 30 in buffer a.c + let [n1, n2] = sign_placelist([ + \ {'id' : 5, + \ 'name' : 's1', + \ 'buffer' : 'a.c', + \ 'lnum' : 20}, + \ {'id' : 10, + \ 'name' : 's1', + \ 'buffer' : 'a.c', + \ 'lnum' : 30} + \ ]) + + " Place sign s1 in buffer a.c at line 40 and 50 + " with auto-generated identifiers + let [n1, n2] = sign_placelist([ + \ {'name' : 's1', + \ 'buffer' : 'a.c', + \ 'lnum' : 40}, + \ {'name' : 's1', + \ 'buffer' : 'a.c', + \ 'lnum' : 50} + \ ]) +< + +sign_undefine([{name}]) *sign_undefine()* +sign_undefine({list}) + Deletes a previously defined sign {name}. This is similar to + the |:sign-undefine| command. If {name} is not supplied, then + deletes all the defined signs. + + The one argument {list} can be used to undefine a list of + signs. Each list item is the name of a sign. + + Returns 0 on success and -1 on failure. For the one argument + {list} call, returns a list of values one for each undefined + sign. + + Examples: > + " Delete a sign named mySign + call sign_undefine("mySign") + + " Delete signs 'sign1' and 'sign2' + call sign_undefine(["sign1", "sign2"]) + + " Delete all the signs + call sign_undefine() +< + +sign_unplace({group} [, {dict}]) *sign_unplace()* + Remove a previously placed sign in one or more buffers. This + is similar to the |:sign-unplace| command. + + {group} is the sign group name. To use the global sign group, + use an empty string. If {group} is set to '*', then all the + groups including the global group are used. + The signs in {group} are selected based on the entries in + {dict}. The following optional entries in {dict} are + supported: + buffer buffer name or number. See |bufname()|. + id sign identifier + If {dict} is not supplied, then all the signs in {group} are + removed. + + Returns 0 on success and -1 on failure. + + Examples: > + " Remove sign 10 from buffer a.vim + call sign_unplace('', {'buffer' : "a.vim", 'id' : 10}) + + " Remove sign 20 in group 'g1' from buffer 3 + call sign_unplace('g1', {'buffer' : 3, 'id' : 20}) + + " Remove all the signs in group 'g2' from buffer 10 + call sign_unplace('g2', {'buffer' : 10}) + + " Remove sign 30 in group 'g3' from all the buffers + call sign_unplace('g3', {'id' : 30}) + + " Remove all the signs placed in buffer 5 + call sign_unplace('*', {'buffer' : 5}) + + " Remove the signs in group 'g4' from all the buffers + call sign_unplace('g4') + + " Remove sign 40 from all the buffers + call sign_unplace('*', {'id' : 40}) + + " Remove all the placed signs from all the buffers + call sign_unplace('*') +< +sign_unplacelist({list}) *sign_unplacelist()* + Remove previously placed signs from one or more buffers. This + is similar to the |sign_unplace()| function. + + The {list} argument specifies the List of signs to remove. + Each list item is a dict with the following sign attributes: + buffer buffer name or number. For the accepted + values, see |bufname()|. If not specified, + then the specified sign is removed from all + the buffers. + group sign group name. If not specified or set to an + empty string, then the global sign group is + used. If set to '*', then all the groups + including the global group are used. + id sign identifier. If not specified, then all + the signs in the specified group are removed. + + Returns a List where an entry is set to 0 if the corresponding + sign was successfully removed or -1 on failure. + + Example: > + " Remove sign with id 10 from buffer a.vim and sign + " with id 20 from buffer b.vim + call sign_unplacelist([ + \ {'id' : 10, 'buffer' : "a.vim"}, + \ {'id' : 20, 'buffer' : 'b.vim'}, + \ ]) +< + vim:tw=78:ts=8:noet:ft=help:norl: diff -Nru vim-8.1.1681/runtime/doc/syntax.txt vim-8.1.1729/runtime/doc/syntax.txt --- vim-8.1.1681/runtime/doc/syntax.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/syntax.txt 2019-07-21 21:04:21.000000000 +0000 @@ -1,4 +1,4 @@ -*syntax.txt* For Vim version 8.1. Last change: 2019 Jun 13 +*syntax.txt* For Vim version 8.1. Last change: 2019 Jul 15 VIM REFERENCE MANUAL by Bram Moolenaar @@ -2623,7 +2623,6 @@ Note: only existence of these options matter, not their value. You can replace 1 above with anything. - QUAKE *quake.vim* *ft-quake-syntax* The Quake syntax definition should work for most any FPS (First Person diff -Nru vim-8.1.1681/runtime/doc/tags vim-8.1.1729/runtime/doc/tags --- vim-8.1.1681/runtime/doc/tags 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/tags 2019-07-21 21:04:21.000000000 +0000 @@ -775,6 +775,7 @@ 'pp' options.txt /*'pp'* 'preserveindent' options.txt /*'preserveindent'* 'previewheight' options.txt /*'previewheight'* +'previewpopup' options.txt /*'previewpopup'* 'previewwindow' options.txt /*'previewwindow'* 'printdevice' options.txt /*'printdevice'* 'printencoding' options.txt /*'printencoding'* @@ -789,6 +790,7 @@ 'pumheight' options.txt /*'pumheight'* 'pumwidth' options.txt /*'pumwidth'* 'pvh' options.txt /*'pvh'* +'pvp' options.txt /*'pvp'* 'pvw' options.txt /*'pvw'* 'pw' options.txt /*'pw'* 'pythondll' options.txt /*'pythondll'* @@ -3912,6 +3914,7 @@ E17 message.txt /*E17* E170 eval.txt /*E170* E171 eval.txt /*E171* +E172 eval.txt /*E172* E173 message.txt /*E173* E174 map.txt /*E174* E175 map.txt /*E175* @@ -3965,6 +3968,7 @@ E219 message.txt /*E219* E22 message.txt /*E22* E220 message.txt /*E220* +E221 eval.txt /*E221* E222 message.txt /*E222* E223 options.txt /*E223* E224 map.txt /*E224* @@ -4681,12 +4685,12 @@ E91 options.txt /*E91* E910 eval.txt /*E910* E911 eval.txt /*E911* -E912 eval.txt /*E912* +E912 channel.txt /*E912* E913 eval.txt /*E913* E914 eval.txt /*E914* E915 channel.txt /*E915* -E916 eval.txt /*E916* -E917 eval.txt /*E917* +E916 channel.txt /*E916* +E917 channel.txt /*E917* E918 channel.txt /*E918* E919 repeat.txt /*E919* E92 message.txt /*E92* @@ -4737,14 +4741,14 @@ E961 cmdline.txt /*E961* E962 eval.txt /*E962* E963 eval.txt /*E963* -E964 eval.txt /*E964* -E965 eval.txt /*E965* -E966 eval.txt /*E966* +E964 textprop.txt /*E964* +E965 textprop.txt /*E965* +E966 textprop.txt /*E966* E967 textprop.txt /*E967* -E968 eval.txt /*E968* -E969 eval.txt /*E969* +E968 textprop.txt /*E968* +E969 textprop.txt /*E969* E97 diff.txt /*E97* -E970 eval.txt /*E970* +E970 textprop.txt /*E970* E971 textprop.txt /*E971* E972 eval.txt /*E972* E973 eval.txt /*E973* @@ -5289,19 +5293,20 @@ asm.vim syntax.txt /*asm.vim* asm68k syntax.txt /*asm68k* asmh8300.vim syntax.txt /*asmh8300.vim* +assert-functions testing.txt /*assert-functions* assert-return eval.txt /*assert-return* -assert_beeps() eval.txt /*assert_beeps()* -assert_equal() eval.txt /*assert_equal()* -assert_equalfile() eval.txt /*assert_equalfile()* -assert_exception() eval.txt /*assert_exception()* -assert_fails() eval.txt /*assert_fails()* -assert_false() eval.txt /*assert_false()* -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()* +assert_beeps() testing.txt /*assert_beeps()* +assert_equal() testing.txt /*assert_equal()* +assert_equalfile() testing.txt /*assert_equalfile()* +assert_exception() testing.txt /*assert_exception()* +assert_fails() testing.txt /*assert_fails()* +assert_false() testing.txt /*assert_false()* +assert_inrange() testing.txt /*assert_inrange()* +assert_match() testing.txt /*assert_match()* +assert_notequal() testing.txt /*assert_notequal()* +assert_notmatch() testing.txt /*assert_notmatch()* +assert_report() testing.txt /*assert_report()* +assert_true() testing.txt /*assert_true()* at motion.txt /*at* atan() eval.txt /*atan()* atan2() eval.txt /*atan2()* @@ -5572,24 +5577,24 @@ ceil() eval.txt /*ceil()* cfilter-plugin quickfix.txt /*cfilter-plugin* 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()* -ch_evalraw() eval.txt /*ch_evalraw()* -ch_getbufnr() eval.txt /*ch_getbufnr()* -ch_getjob() eval.txt /*ch_getjob()* -ch_info() eval.txt /*ch_info()* -ch_log() eval.txt /*ch_log()* -ch_logfile() eval.txt /*ch_logfile()* -ch_open() eval.txt /*ch_open()* -ch_read() eval.txt /*ch_read()* -ch_readblob() eval.txt /*ch_readblob()* -ch_readraw() eval.txt /*ch_readraw()* -ch_sendexpr() eval.txt /*ch_sendexpr()* -ch_sendraw() eval.txt /*ch_sendraw()* -ch_setoptions() eval.txt /*ch_setoptions()* -ch_status() eval.txt /*ch_status()* +ch_canread() channel.txt /*ch_canread()* +ch_close() channel.txt /*ch_close()* +ch_close_in() channel.txt /*ch_close_in()* +ch_evalexpr() channel.txt /*ch_evalexpr()* +ch_evalraw() channel.txt /*ch_evalraw()* +ch_getbufnr() channel.txt /*ch_getbufnr()* +ch_getjob() channel.txt /*ch_getjob()* +ch_info() channel.txt /*ch_info()* +ch_log() channel.txt /*ch_log()* +ch_logfile() channel.txt /*ch_logfile()* +ch_open() channel.txt /*ch_open()* +ch_read() channel.txt /*ch_read()* +ch_readblob() channel.txt /*ch_readblob()* +ch_readraw() channel.txt /*ch_readraw()* +ch_sendexpr() channel.txt /*ch_sendexpr()* +ch_sendraw() channel.txt /*ch_sendraw()* +ch_setoptions() channel.txt /*ch_setoptions()* +ch_status() channel.txt /*ch_status()* change-list-jumps motion.txt /*change-list-jumps* change-name tips.txt /*change-name* change-tabs change.txt /*change-tabs* @@ -5624,6 +5629,7 @@ channel-demo channel.txt /*channel-demo* channel-drop channel.txt /*channel-drop* channel-functions usr_41.txt /*channel-functions* +channel-functions-details channel.txt /*channel-functions-details* channel-mode channel.txt /*channel-mode* channel-more channel.txt /*channel-more* channel-noblock channel.txt /*channel-noblock* @@ -6440,6 +6446,7 @@ ft-python-indent indent.txt /*ft-python-indent* ft-python-plugin filetype.txt /*ft-python-plugin* ft-python-syntax syntax.txt /*ft-python-syntax* +ft-qf-plugin filetype.txt /*ft-qf-plugin* ft-quake-syntax syntax.txt /*ft-quake-syntax* ft-r-indent indent.txt /*ft-r-indent* ft-r-syntax syntax.txt /*ft-r-syntax* @@ -7360,6 +7367,7 @@ job-err_io channel.txt /*job-err_io* job-exit_cb channel.txt /*job-exit_cb* job-functions usr_41.txt /*job-functions* +job-functions-details channel.txt /*job-functions-details* job-in_io channel.txt /*job-in_io* job-noblock channel.txt /*job-noblock* job-options channel.txt /*job-options* @@ -7371,12 +7379,12 @@ job-stoponexit channel.txt /*job-stoponexit* job-term channel.txt /*job-term* job-timeout channel.txt /*job-timeout* -job_getchannel() eval.txt /*job_getchannel()* -job_info() eval.txt /*job_info()* -job_setoptions() eval.txt /*job_setoptions()* -job_start() eval.txt /*job_start()* -job_status() eval.txt /*job_status()* -job_stop() eval.txt /*job_stop()* +job_getchannel() channel.txt /*job_getchannel()* +job_info() channel.txt /*job_info()* +job_setoptions() channel.txt /*job_setoptions()* +job_start() channel.txt /*job_start()* +job_status() channel.txt /*job_status()* +job_stop() channel.txt /*job_stop()* join() eval.txt /*join()* js_decode() eval.txt /*js_decode()* js_encode() eval.txt /*js_encode()* @@ -7468,6 +7476,7 @@ listener_flush() eval.txt /*listener_flush()* listener_remove() eval.txt /*listener_remove()* lite.vim syntax.txt /*lite.vim* +literal-Dict eval.txt /*literal-Dict* literal-string eval.txt /*literal-string* lnum-variable eval.txt /*lnum-variable* load-plugins starting.txt /*load-plugins* @@ -8032,7 +8041,7 @@ new-searchpat version6.txt /*new-searchpat* new-session-files version5.txt /*new-session-files* new-spell version7.txt /*new-spell* -new-style-testing eval.txt /*new-style-testing* +new-style-testing testing.txt /*new-style-testing* new-tab-pages version7.txt /*new-tab-pages* new-terminal-window version8.txt /*new-terminal-window* new-undo-branches version7.txt /*new-undo-branches* @@ -8080,7 +8089,7 @@ octal eval.txt /*octal* octal-nrformats options.txt /*octal-nrformats* octal-number eval.txt /*octal-number* -old-style-testing eval.txt /*old-style-testing* +old-style-testing testing.txt /*old-style-testing* oldfiles-variable eval.txt /*oldfiles-variable* ole-activation if_ole.txt /*ole-activation* ole-eval if_ole.txt /*ole-eval* @@ -8241,6 +8250,8 @@ popup-window-functions usr_41.txt /*popup-window-functions* popup.txt popup.txt /*popup.txt* popup_atcursor() popup.txt /*popup_atcursor()* +popup_beval() popup.txt /*popup_beval()* +popup_beval_example popup.txt /*popup_beval_example* popup_clear() popup.txt /*popup_clear()* popup_close() popup.txt /*popup_close()* popup_create() popup.txt /*popup_create()* @@ -8252,6 +8263,7 @@ popup_getoptions() popup.txt /*popup_getoptions()* popup_getpos() popup.txt /*popup_getpos()* popup_hide() popup.txt /*popup_hide()* +popup_locate() popup.txt /*popup_locate()* popup_menu() popup.txt /*popup_menu()* popup_menu-shortcut-example popup.txt /*popup_menu-shortcut-example* popup_move() popup.txt /*popup_move()* @@ -8278,6 +8290,7 @@ press-enter message.txt /*press-enter* press-return message.txt /*press-return* prevcount-variable eval.txt /*prevcount-variable* +preview-popup windows.txt /*preview-popup* preview-window windows.txt /*preview-window* prevnonblank() eval.txt /*prevnonblank()* print-intro print.txt /*print-intro* @@ -8313,16 +8326,16 @@ prompt_setprompt() eval.txt /*prompt_setprompt()* promptbuffer-functions usr_41.txt /*promptbuffer-functions* pronounce intro.txt /*pronounce* -prop_add() eval.txt /*prop_add()* -prop_clear() eval.txt /*prop_clear()* -prop_find() eval.txt /*prop_find()* -prop_list() eval.txt /*prop_list()* -prop_remove() eval.txt /*prop_remove()* -prop_type_add() eval.txt /*prop_type_add()* -prop_type_change() eval.txt /*prop_type_change()* -prop_type_delete() eval.txt /*prop_type_delete()* -prop_type_get() eval.txt /*prop_type_get()* -prop_type_list() eval.txt /*prop_type_list()* +prop_add() textprop.txt /*prop_add()* +prop_clear() textprop.txt /*prop_clear()* +prop_find() textprop.txt /*prop_find()* +prop_list() textprop.txt /*prop_list()* +prop_remove() textprop.txt /*prop_remove()* +prop_type_add() textprop.txt /*prop_type_add()* +prop_type_change() textprop.txt /*prop_type_change()* +prop_type_delete() textprop.txt /*prop_type_delete()* +prop_type_get() textprop.txt /*prop_type_get()* +prop_type_list() textprop.txt /*prop_type_list()* psql ft_sql.txt /*psql* ptcap.vim syntax.txt /*ptcap.vim* pterm-mouse options.txt /*pterm-mouse* @@ -8383,6 +8396,7 @@ q/ cmdline.txt /*q\/* q: cmdline.txt /*q:* q? cmdline.txt /*q?* +qf.vim filetype.txt /*qf.vim* qnx os_qnx.txt /*qnx* qnx-compiling os_qnx.txt /*qnx-compiling* qnx-general os_qnx.txt /*qnx-general* @@ -8590,6 +8604,7 @@ screenchar() eval.txt /*screenchar()* screenchars() eval.txt /*screenchars()* screencol() eval.txt /*screencol()* +screenpos() eval.txt /*screenpos()* screenrow() eval.txt /*screenrow()* screenstring() eval.txt /*screenstring()* script usr_41.txt /*script* @@ -8682,19 +8697,22 @@ sign-column sign.txt /*sign-column* sign-commands sign.txt /*sign-commands* sign-functions usr_41.txt /*sign-functions* +sign-functions-details sign.txt /*sign-functions-details* sign-group sign.txt /*sign-group* sign-identifier sign.txt /*sign-identifier* sign-intro sign.txt /*sign-intro* sign-priority sign.txt /*sign-priority* sign-support sign.txt /*sign-support* sign.txt sign.txt /*sign.txt* -sign_define() eval.txt /*sign_define()* -sign_getdefined() eval.txt /*sign_getdefined()* -sign_getplaced() eval.txt /*sign_getplaced()* -sign_jump() eval.txt /*sign_jump()* -sign_place() eval.txt /*sign_place()* -sign_undefine() eval.txt /*sign_undefine()* -sign_unplace() eval.txt /*sign_unplace()* +sign_define() sign.txt /*sign_define()* +sign_getdefined() sign.txt /*sign_getdefined()* +sign_getplaced() sign.txt /*sign_getplaced()* +sign_jump() sign.txt /*sign_jump()* +sign_place() sign.txt /*sign_place()* +sign_placelist() sign.txt /*sign_placelist()* +sign_undefine() sign.txt /*sign_undefine()* +sign_unplace() sign.txt /*sign_unplace()* +sign_unplacelist() sign.txt /*sign_unplacelist()* signs sign.txt /*signs* simple-change change.txt /*simple-change* simplify() eval.txt /*simplify()* @@ -9345,29 +9363,32 @@ terminal.txt terminal.txt /*terminal.txt* terminfo term.txt /*terminfo* termresponse-variable eval.txt /*termresponse-variable* +test-functions testing.txt /*test-functions* test-functions usr_41.txt /*test-functions* -test_alloc_fail() eval.txt /*test_alloc_fail()* -test_autochdir() eval.txt /*test_autochdir()* -test_feedinput() eval.txt /*test_feedinput()* -test_garbagecollect_now() eval.txt /*test_garbagecollect_now()* -test_garbagecollect_soon() eval.txt /*test_garbagecollect_soon()* -test_getvalue() eval.txt /*test_getvalue()* -test_ignore_error() eval.txt /*test_ignore_error()* -test_null_blob() eval.txt /*test_null_blob()* -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_option_not_set() eval.txt /*test_option_not_set()* -test_override() eval.txt /*test_override()* -test_refcount() eval.txt /*test_refcount()* -test_scrollbar() eval.txt /*test_scrollbar()* -test_setmouse() eval.txt /*test_setmouse()* -test_settime() eval.txt /*test_settime()* -testing eval.txt /*testing* +test_alloc_fail() testing.txt /*test_alloc_fail()* +test_autochdir() testing.txt /*test_autochdir()* +test_feedinput() testing.txt /*test_feedinput()* +test_garbagecollect_now() testing.txt /*test_garbagecollect_now()* +test_garbagecollect_soon() testing.txt /*test_garbagecollect_soon()* +test_getvalue() testing.txt /*test_getvalue()* +test_ignore_error() testing.txt /*test_ignore_error()* +test_null_blob() testing.txt /*test_null_blob()* +test_null_channel() testing.txt /*test_null_channel()* +test_null_dict() testing.txt /*test_null_dict()* +test_null_job() testing.txt /*test_null_job()* +test_null_list() testing.txt /*test_null_list()* +test_null_partial() testing.txt /*test_null_partial()* +test_null_string() testing.txt /*test_null_string()* +test_option_not_set() testing.txt /*test_option_not_set()* +test_override() testing.txt /*test_override()* +test_refcount() testing.txt /*test_refcount()* +test_scrollbar() testing.txt /*test_scrollbar()* +test_setmouse() testing.txt /*test_setmouse()* +test_settime() testing.txt /*test_settime()* +testing testing.txt /*testing* +testing-support testing.txt /*testing-support* testing-variable eval.txt /*testing-variable* +testing.txt testing.txt /*testing.txt* tex-cchar syntax.txt /*tex-cchar* tex-cole syntax.txt /*tex-cole* tex-conceal syntax.txt /*tex-conceal* diff -Nru vim-8.1.1681/runtime/doc/testing.txt vim-8.1.1729/runtime/doc/testing.txt --- vim-8.1.1681/runtime/doc/testing.txt 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/runtime/doc/testing.txt 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,317 @@ +*testing.txt* For Vim version 8.1. Last change: 2019 Jul 21 + + + VIM REFERENCE MANUAL by Bram Moolenaar + + +Testing Vim and Vim script *testing-support* + +Expression evaluation is explained in |eval.txt|. This file goes into details +about writing tests in Vim script. This can be used for testing Vim itself +and for testing plugins. + +1. Testing Vim |testing| +2. Test functions |test-functions| +3. Assert funtions |assert-functions| + +============================================================================== +1. Testing Vim *testing* + +Vim can be tested after building it, usually with "make test". +The tests are located in the directory "src/testdir". + +There are several types of tests added over time: + test33.in oldest, don't add any of these + test_something.in old style tests + test_something.vim new style tests + + *new-style-testing* +New tests should be added as new style tests. These use functions such as +|assert_equal()| to keep the test commands and the expected result in one +place. + *old-style-testing* +In some cases an old style test needs to be used. E.g. when testing Vim +without the |+eval| feature. + +Find more information in the file src/testdir/README.txt. + +============================================================================== +2. Test functions *test-functions* + +test_alloc_fail({id}, {countdown}, {repeat}) *test_alloc_fail()* + This is for testing: If the memory allocation with {id} is + called, then decrement {countdown}, and when it reaches zero + let memory allocation fail {repeat} times. When {repeat} is + smaller than one it fails one time. + + +test_autochdir() *test_autochdir()* + Set a flag to enable the effect of 'autochdir' before Vim + startup has finished. + + +test_feedinput({string}) *test_feedinput()* + Characters in {string} are queued for processing as if they + were typed by the user. This uses a low level input buffer. + This function works only when with |+unix| or GUI is running. + + +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_garbagecollect_soon() *test_garbagecollect_soon()* + Set the flag to call the garbagecollector as if in the main + loop. Only to be used in tests. + + +test_getvalue({name}) *test_getvalue()* + Get the value of an internal variable. These values for + {name} are supported: + need_fileinfo + + +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. + When the {expr} is the string "RESET" then the list of ignored + errors is made empty. + + +test_null_blob() *test_null_blob()* + Return a |Blob| that is null. Only useful for testing. + + +test_null_channel() *test_null_channel()* + Return a |Channel| that is null. Only useful for testing. + {only available when compiled with the +channel feature} + + +test_null_dict() *test_null_dict()* + Return a |Dict| that is null. Only useful for testing. + + +test_null_job() *test_null_job()* + Return a |Job| that is null. Only useful for testing. + {only available when compiled with the +job feature} + + +test_null_list() *test_null_list()* + Return a |List| that is null. Only useful for testing. + + +test_null_partial() *test_null_partial()* + Return a |Partial| that is null. Only useful for testing. + + +test_null_string() *test_null_string()* + Return a |String| that is null. Only useful for testing. + + +test_option_not_set({name}) *test_option_not_set()* + Reset the flag that indicates option {name} was set. Thus it + looks like it still has the default value. Use like this: > + set ambiwidth=double + call test_option_not_set('ambiwidth') +< Now the 'ambiwidth' option behaves like it was never changed, + even though the value is "double". + Only to be used for testing! + + +test_override({name}, {val}) *test_override()* + Overrides certain parts of Vim's 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 + redraw_flag ignore the RedrawingDisabled flag + char_avail disable the char_avail() function + starting reset the "starting" variable, see below + nfa_fail makes the NFA regexp engine fail to force a + fallback to the old engine + no_query_mouse do not query the mouse position for "dec" + terminals + no_wait_return set the "no_wait_return" flag. Not restored + with "ALL". + ALL clear all overrides ({val} is not used) + + "starting" is to be used when a test should behave like + startup was done. Since the tests are run by sourcing a + script the "starting" variable is non-zero. This is usually a + good thing (tests run faster), but sometimes changes behavior + in a way that the test doesn't work properly. + When using: > + call test_override('starting', 1) +< The value of "starting" is saved. It is restored by: > + call test_override('starting', 0) + + +test_refcount({expr}) *test_refcount()* + Return the reference count of {expr}. When {expr} is of a + type that does not have a reference count, returns -1. Only + to be used for testing. + + +test_scrollbar({which}, {value}, {dragging}) *test_scrollbar()* + Pretend using scrollbar {which} to move it to position + {value}. {which} can be: + left Left scrollbar of the current window + right Right scrollbar of the current window + hor Horizontal scrollbar + + For the vertical scrollbars {value} can be 1 to the + line-count of the buffer. For the horizontal scrollbar the + {value} can be between 1 and the maximum line length, assuming + 'wrap' is not set. + + When {dragging} is non-zero it's like dragging the scrollbar, + otherwise it's like clicking in the scrollbar. + Only works when the {which} scrollbar actually exists, + obviously only when using the GUI. + + +test_setmouse({row}, {col}) *test_setmouse()* + Set the mouse position to be used for the next mouse action. + {row} and {col} are one based. + For example: > + call test_setmouse(4, 20) + call feedkeys("\", "xt") + + +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. + +============================================================================== +3. Assert functions *assert-functions* + + +assert_beeps({cmd}) *assert_beeps()* + Run {cmd} and add an error message to |v:errors| if it does + NOT produce a beep or visual bell. + Also see |assert_fails()| and |assert-return|. + + *assert_equal()* +assert_equal({expected}, {actual} [, {msg}]) + When {expected} and {actual} are not equal an error message is + added to |v:errors| and 1 is returned. Otherwise zero is + returned |assert-return|. + There is no automatic conversion, the String "4" is different + from the Number 4. And the number 4 is different from the + Float 4.0. The value of 'ignorecase' is not used here, case + always matters. + When {msg} is omitted an error in the form "Expected + {expected} but got {actual}" is produced. + Example: > + assert_equal('foo', 'bar') +< Will result in a string to be added to |v:errors|: + test.vim line 12: Expected 'foo' but got 'bar' ~ + + *assert_equalfile()* +assert_equalfile({fname-one}, {fname-two}) + When the files {fname-one} and {fname-two} do not contain + exactly the same text an error message is added to |v:errors|. + Also see |assert-return|. + When {fname-one} or {fname-two} does not exist the error will + mention that. + Mainly useful with |terminal-diff|. + +assert_exception({error} [, {msg}]) *assert_exception()* + When v:exception does not contain the string {error} an error + message is added to |v:errors|. Also see |assert-return|. + This can be used to assert that a command throws an exception. + Using the error number, followed by a colon, avoids problems + with translations: > + try + commandthatfails + call assert_false(1, 'command should have failed') + catch + call assert_exception('E492:') + endtry + +assert_fails({cmd} [, {error} [, {msg}]]) *assert_fails()* + Run {cmd} and add an error message to |v:errors| if it does + NOT produce an error. Also see |assert-return|. + When {error} is given it must match in |v:errmsg|. + Note that beeping is not considered an error, and some failing + commands only beep. Use |assert_beeps()| for those. + +assert_false({actual} [, {msg}]) *assert_false()* + When {actual} is not false an error message is added to + |v:errors|, like with |assert_equal()|. + Also see |assert-return|. + A value is false when it is zero. When {actual} is not a + number the assert fails. + When {msg} is omitted an error in the form + "Expected False but got {actual}" is produced. + +assert_inrange({lower}, {upper}, {actual} [, {msg}]) *assert_inrange()* + This asserts number and |Float| values. When {actual} is lower + than {lower} or higher than {upper} an error message is added + to |v:errors|. Also see |assert-return|. + When {msg} is omitted an error in the form + "Expected range {lower} - {upper}, but got {actual}" is + produced. + + *assert_match()* +assert_match({pattern}, {actual} [, {msg}]) + When {pattern} does not match {actual} an error message is + added to |v:errors|. Also see |assert-return|. + + {pattern} is used as with |=~|: The matching is always done + like 'magic' was set and 'cpoptions' is empty, no matter what + the actual value of 'magic' or 'cpoptions' is. + + {actual} is used as a string, automatic conversion applies. + Use "^" and "$" to match with the start and end of the text. + Use both to match the whole text. + + When {msg} is omitted an error in the form + "Pattern {pattern} does not match {actual}" is produced. + Example: > + assert_match('^f.*o$', 'foobar') +< Will result in a string to be added to |v:errors|: + test.vim line 12: Pattern '^f.*o$' does not match 'foobar' ~ + + *assert_notequal()* +assert_notequal({expected}, {actual} [, {msg}]) + The opposite of `assert_equal()`: add an error message to + |v:errors| when {expected} and {actual} are equal. + Also see |assert-return|. + + *assert_notmatch()* +assert_notmatch({pattern}, {actual} [, {msg}]) + The opposite of `assert_match()`: add an error message to + |v:errors| when {pattern} matches {actual}. + Also see |assert-return|. + +assert_report({msg}) *assert_report()* + Report a test failure directly, using {msg}. + Always returns one. + +assert_true({actual} [, {msg}]) *assert_true()* + When {actual} is not true an error message is added to + |v:errors|, like with |assert_equal()|. + Also see |assert-return|. + A value is TRUE when it is a non-zero number. When {actual} + is not a number the assert fails. + When {msg} is omitted an error in the form "Expected True but + got {actual}" is produced. + + + vim:tw=78:ts=8:noet:ft=help:norl: diff -Nru vim-8.1.1681/runtime/doc/textprop.txt vim-8.1.1729/runtime/doc/textprop.txt --- vim-8.1.1681/runtime/doc/textprop.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/textprop.txt 2019-07-21 21:04:21.000000000 +0000 @@ -1,4 +1,4 @@ -*textprop.txt* For Vim version 8.1. Last change: 2019 Jun 13 +*textprop.txt* For Vim version 8.1. Last change: 2019 Jul 20 VIM REFERENCE MANUAL by Bram Moolenaar @@ -116,6 +116,202 @@ prop_remove({props} [, {lnum} [, {lnum-end}]]) remove a text property + *prop_add()* *E965* +prop_add({lnum}, {col}, {props}) + Attach a text property at position {lnum}, {col}. {col} is + counted in bytes, use one for the first column. + If {lnum} is invalid an error is given. *E966* + If {col} is invalid an error is given. *E964* + + {props} is a dictionary with these fields: + length length of text in bytes, can only be used + for a property that does not continue in + another line; can be zero + end_lnum line number for the end of text + end_col column just after the text; not used when + "length" is present; when {col} and "end_col" + are equal, and "end_lnum" is omitted or equal + to {lnum}, this is a zero-width text property + bufnr buffer to add the property to; when omitted + the current buffer is used + id user defined ID for the property; when omitted + zero is used + type name of the text property type + All fields except "type" are optional. + + It is an error when both "length" and "end_lnum" or "end_col" + are given. Either use "length" or "end_col" for a property + within one line, or use "end_lnum" and "end_col" for a + property that spans more than one line. + When neither "length" nor "end_col" are given the property + will be zero-width. That means it will not be highlighted but + will move with the text, as a kind of mark. + The property can end exactly at the last character of the + text, or just after it. In the last case, if text is appended + to the line, the text property size will increase, also when + the property type does not have "end_incl" set. + + "type" will first be looked up in the buffer the property is + added to. When not found, the global property types are used. + If not found an error is given. + + See |text-properties| for information about text properties. + + +prop_clear({lnum} [, {lnum-end} [, {props}]]) *prop_clear()* + Remove all text properties from line {lnum}. + When {lnum-end} is given, remove all text properties from line + {lnum} to {lnum-end} (inclusive). + + When {props} contains a "bufnr" item use this buffer, + otherwise use the current buffer. + + See |text-properties| for information about text properties. + + *prop_find()* +prop_find({props} [, {direction}]) + NOT IMPLEMENTED YET + Search for a text property as specified with {props}: + id property with this ID + type property with this type name + bufnr buffer to search in; when present a + start position with "lnum" and "col" + must be given; when omitted the + current buffer is used + lnum start in this line (when omitted start + at the cursor) + col start at this column (when omitted + and "lnum" is given: use column 1, + otherwise start at the cursor) + skipstart do not look for a match at the start + position + + {direction} can be "f" for forward and "b" for backward. When + omitted forward search is performed. + + If a match is found then a Dict is returned with the entries + as with prop_list(), and additionally an "lnum" entry. + If no match is found then an empty Dict is returned. + + See |text-properties| for information about text properties. + + +prop_list({lnum} [, {props}]) *prop_list()* + Return a List with all text properties in line {lnum}. + + When {props} contains a "bufnr" item, use this buffer instead + of the current buffer. + + The properties are ordered by starting column and priority. + Each property is a Dict with these entries: + col starting column + length length in bytes, one more if line break is + included + id property ID + type name of the property type, omitted if + the type was deleted + start when TRUE property starts in this line + end when TRUE property ends in this line + + When "start" is zero the property started in a previous line, + the current one is a continuation. + When "end" is zero the property continues in the next line. + The line break after this line is included. + + See |text-properties| for information about text properties. + + + *prop_remove()* *E968* +prop_remove({props} [, {lnum} [, {lnum-end}]]) + Remove a matching text property from line {lnum}. When + {lnum-end} is given, remove matching text properties from line + {lnum} to {lnum-end} (inclusive). + When {lnum} is omitted remove matching text properties from + all lines. + + {props} is a dictionary with these fields: + id remove text properties with this ID + type remove text properties with this type name + bufnr use this buffer instead of the current one + all when TRUE remove all matching text properties, + not just the first one + A property matches when either "id" or "type" matches. + If buffer "bufnr" does not exist you get an error message. + If buffer "bufnr" is not loaded then nothing happens. + + Returns the number of properties that were removed. + + See |text-properties| for information about text properties. + + +prop_type_add({name}, {props}) *prop_type_add()* *E969* *E970* + Add a text property type {name}. If a property type with this + name already exists an error is given. + {props} is a dictionary with these optional fields: + bufnr define the property only for this buffer; this + avoids name collisions and automatically + clears the property types when the buffer is + deleted. + highlight name of highlight group to use + priority when a character has multiple text + properties the one with the highest priority + will be used; negative values can be used, the + default priority is zero + combine when TRUE combine the highlight with any + syntax highlight; when omitted or FALSE syntax + highlight will not be used + start_incl when TRUE inserts at the start position will + be included in the text property + end_incl when TRUE inserts at the end position will be + included in the text property + + See |text-properties| for information about text properties. + + +prop_type_change({name}, {props}) *prop_type_change()* + Change properties of an existing text property type. If a + property with this name does not exist an error is given. + The {props} argument is just like |prop_type_add()|. + + See |text-properties| for information about text properties. + + +prop_type_delete({name} [, {props}]) *prop_type_delete()* + Remove the text property type {name}. When text properties + using the type {name} are still in place, they will not have + an effect and can no longer be removed by name. + + {props} can contain a "bufnr" item. When it is given, delete + a property type from this buffer instead of from the global + property types. + + When text property type {name} is not found there is no error. + + See |text-properties| for information about text properties. + + +prop_type_get([{name} [, {props}]) *prop_type_get()* + Returns the properties of property type {name}. This is a + dictionary with the same fields as was given to + prop_type_add(). + When the property type {name} does not exist, an empty + dictionary is returned. + + {props} can contain a "bufnr" item. When it is given, use + this buffer instead of the global property types. + + See |text-properties| for information about text properties. + + +prop_type_list([{props}]) *prop_type_list()* + Returns a list with all property type names. + + {props} can contain a "bufnr" item. When it is given, use + this buffer instead of the global property types. + + See |text-properties| for information about text properties. + + ============================================================================== 3. When text changes *text-prop-changes* diff -Nru vim-8.1.1681/runtime/doc/todo.txt vim-8.1.1729/runtime/doc/todo.txt --- vim-8.1.1681/runtime/doc/todo.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/todo.txt 2019-07-21 21:04:21.000000000 +0000 @@ -1,4 +1,4 @@ -*todo.txt* For Vim version 8.1. Last change: 2019 Jul 04 +*todo.txt* For Vim version 8.1. Last change: 2019 Jul 19 VIM REFERENCE MANUAL by Bram Moolenaar @@ -38,33 +38,31 @@ *known-bugs* -------------------- Known bugs and current work ----------------------- -Ongoing work on text properties, see src/textprop.c - -Popup windows are being implemented, see |popup-window|. - Patch to fix session file when using multiple tabs. (Jason Franklin, 2019 May 20) Also put :argadd commands at the start for all buffers, so that their order remains equal? Then %argdel to clean it up. Do try this with 'hidden' set. -Listener causes extra } to be inserted. (Paul Jolly, #4455) - Refactor: Move common things out of evalfunc.c, it's too big. +Move function specs out of eval.txt, it's too big. + +Convert comments in option.h -Template string: review #4491 +Patch to convert encoding of strftime(). (Ken Takata, #4685, fixes #4681) -Terminal test fails when vim is configured with some features. (Dominique, -#4597) +Patch to Move viminfo related functions to a separate file: #4686 Popup windows: +- avoid preview popup going outside of the screen +- add popup_getpreview() - get ID of preview window +- bug: double click in scrollbar starts selection +- Allow resizing from the bottom-right corner - Implement flip option -- Have a way to scroll to the bottom? (#4577) +- Have a way to scroll to the bottom, e.g. set 'firstline' to -1? (#4577) - Why does 'nrformats' leak from the popup window buffer??? + Happens in Test_simple_popup() at the second screendump. - Disable commands, feedkeys(), CTRL-W, etc. in a popup window. Use ERROR_IF_POPUP_WINDOW for more commands. -- Add 'balloonpopup': instead of showing text, let the callback open a popup - window and return the window ID. The popup will then be closed when the - mouse moves, except when it moves inside the popup. - For the "moved" property also include mouse movement? - Can the buffer be re-used if it was the last one, to avoid using up lots of buffer numbers? @@ -150,6 +148,14 @@ - When 'encoding' is not utf-8, or the job is using another encoding, setup conversions. +Error numbers available: E172, E221, E242, E249, E260, E274, E275, E276, +E278, E279, E281, E290, E291, E292, E361, E362, E366, E396, E450, E451, E452, +E453, E454, E460, E489, E491, E56, E57, E565, E569, E578, E610, E611, E653, +E654, E693, E706, E856, E857, E860, E861, E863, E889, E900, E959 + +Problem with German spell file. Hint for solution by Klaus-Peter Schreiner in +#4314, solves the Rasenmäher problem. + Sound: support on Mac? Or does libcanberra work there? Patch to use forward slash for completion even when 'shellslash' is set. @@ -157,6 +163,8 @@ Patch to add win_splitmove() function. (Andy Massimino, #4561) +Resolve() works incorrectly under windows. (#4661) + Completion mixes results from the current buffer with tags and other files. Happens when typing CTRL-N while still search for results. E.g., type "b_" in terminal.c and then CTRL-N twice. @@ -169,18 +177,24 @@ Adding "10" to 'spellsuggest' causes spell suggestions to become very slow. (#4087) -Patch to the code to get sign information. (Yegappan Lakshmanan, #4586) +Patch to support 'cursorlineopt' - only highlight the line number of the +cursor line: #4693 + +Patch for Template string: #4491 Not ready yet. New pull: #4634 ":bnext" in a help buffer is supposed to go to the next help buffer, but it goes to any buffer, and then :bnext skips help buffers, since they are unlisted. (#4478) -Problem with German spell file. Hint for solution by Klaus-Peter Schreiner in -#4314, solves the Rasenmäher problem. - Problem showing a line if the number column width changes when using "o". (Mateusz Morusiewicz, #4245) +When using :packadd for a replacement language plugin, it is loaded after the +default one. #4698 + +When using :packadd files under "later" are not used, which is inconsistent +with packages under "start". (xtal8, #1994) + Visual highlight not removed when 'dipslay' is "lastline" and line doesn't fit. (Kevin Lawler, #4457) @@ -227,9 +241,36 @@ Problem with colors in terminal window. (Jason Franklin, 2019 May 12) +Lifepillar: Updated/cleaned up color schemes: +https://github.com/lifepillar/vim8-colorschemes. + +Include a few color schemes, based on popularity: +http://www.vim.org/scripts/script_search_results.php?keywords=&script_type=color+scheme&order_by=rating&direction=descending&search=search +http://vimawesome.com/?q=tag:color-scheme +Use names that indicate their appearance (Christian Brabandt, 2017 Aug 3) +- monokai - Xia Crusoe (2017 Aug 4) +- seoul256 - Christian Brabandt (2017 Aug 3) +- gruvbox - Christian Brabandt (2017 Aug 3) (simplified version from + Lifepillar, 2018 Jan 22, #2573) +- janah - Marco Hinz (2017 Aug 4) +- apprentice - Romain Lafourcade (2017 Aug 6) remarks about help file #1964 +Suggested by Hiroki Kokubun: +- [Iceberg](https://github.com/cocopon/iceberg.vim) (my one) +- [hybrid](https://github.com/w0ng/vim-hybrid) +Include solarized color scheme?, it does not support termguicolors. +- Sanitized version of pablo (Lifepillar, 2017 Nov 21) + Bug: "vipgw" does not put cursor back where it belongs. (Jason Franklin, 2019 Mar 5) +Many users don't like 'thesaurus' to match so many words. (#4667, #1611) +- when the match with the first word is partial, don't add other words on that + line. +- support other file formats, such as comma separated. Indicate by a prefix + to the file in the 'thesaurus' option. +- 'threglookexp' option: only match with first word in thesaurus file. + (Jakson A. Aquino, 2006 Jun 14) + Some composing characters actually add a cell width to the character they are on top off, making the whole thing two characters wide. (#4526) @@ -309,6 +350,10 @@ Missing tests for: - add_termcap_entry() +Redo only remembers the last change. Could use "{count}g." to redo an older +change. How does the user know which change? At least have a way to list +them: ":repeats". Add to history, like search history and command line history. + When using exclusive selection and vi" that fails, cursor moves to the left. Cursor should not move. (#4024) @@ -579,9 +624,6 @@ included in the existing fold. Deleting the empty line and undo fixes it. (Oleg Koshovetc, 2018 Jul 15, #3214) -When using :packadd files under "later" are not used, which is inconsistent -with packages under "start". (xtal8, #1994) - Patch to support "xxd -ps". (Erik Auerswald, 2018 May 1) Lacks a test. @@ -791,22 +833,6 @@ clip_x11_convert_selection_cb() is invoked, thus in X library code. Kazunobu Kuriyama is working on a proper fix. (2017 Jul 25) -Include a few color schemes, based on popularity: -http://www.vim.org/scripts/script_search_results.php?keywords=&script_type=color+scheme&order_by=rating&direction=descending&search=search -http://vimawesome.com/?q=tag:color-scheme -Use names that indicate their appearance (Christian Brabandt, 2017 Aug 3) -- monokai - Xia Crusoe (2017 Aug 4) -- seoul256 - Christian Brabandt (2017 Aug 3) -- gruvbox - Christian Brabandt (2017 Aug 3) (simplified version from - Lifepillar, 2018 Jan 22, #2573) -- janah - Marco Hinz (2017 Aug 4) -- apprentice - Romain Lafourcade (2017 Aug 6) remarks about help file #1964 -Suggested by Hiroki Kokubun: -- [Iceberg](https://github.com/cocopon/iceberg.vim) (my one) -- [hybrid](https://github.com/w0ng/vim-hybrid) -Include solarized color scheme?, it does not support termguicolors. -- Sanitized version of pablo (Lifepillar, 2017 Nov 21) - Problem with three-piece comment. (Michael Lee, 2017 May 11, #1696) Creating a partial with an autoload function is confused about the "self" @@ -1521,10 +1547,6 @@ Patch: On MS-Windows shellescape() may have to triple double quotes. (Ingo Karkat, 2015 Jan 16) -Redo only remembers the last change. Could use "{count}g." to redo an older -change. How does the user know which change? At least have a way to list -them: ":repeats". - Patch for glob(), adding slash to normal files. (Ingo Karkat, 2014 Dec 22) When entering and leaving the preview window autocommands are triggered, but @@ -3013,8 +3035,6 @@ - Add 'cscopeignorecase' option. (Liang Wenzhi, 2006 Sept 3) - Extra argument to strtrans() to translate special keys to their name (Eric Arnold, 2006 May 22) -- 'threglookexp' option: only match with first word in thesaurus file. - (Jakson A. Aquino, 2006 Jun 14) - Mac: indicate whether a buffer was modified. (Nicolas Weber, 2006 Jun 30) - Allow negative 'nrwidth' for left aligning. (Nathan Laredo, 2006 Aug 16) - ml_append_string(): efficiently append to an existing line. (Brad diff -Nru vim-8.1.1681/runtime/doc/usr_27.txt vim-8.1.1729/runtime/doc/usr_27.txt --- vim-8.1.1681/runtime/doc/usr_27.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/usr_27.txt 2019-07-21 21:04:21.000000000 +0000 @@ -1,4 +1,4 @@ -*usr_27.txt* For Vim version 8.1. Last change: 2018 Jan 26 +*usr_27.txt* For Vim version 8.1. Last change: 2019 Jul 14 VIM USER MANUAL - by Bram Moolenaar @@ -474,19 +474,19 @@ break. To check for a line break in a specific place, use the "\n" item: > - /the\nword + /one\ntwo -This will match at a line that ends in "the" and the next line starts with -"word". To match "the word" as well, you need to match a space or a line +This will match at a line that ends in "one" and the next line starts with +"two". To match "one two" as well, you need to match a space or a line break. The item to use for it is "\_s": > - /the\_sword + /one\_stwo To allow any amount of white space: > - /the\_s\+word + /one\_s\+two -This also matches when "the " is at the end of a line and " word" at the +This also matches when "one " is at the end of a line and " two" at the start of the next one. "\s" matches white space, "\_s" matches white space or a line break. diff -Nru vim-8.1.1681/runtime/doc/usr_41.txt vim-8.1.1729/runtime/doc/usr_41.txt --- vim-8.1.1681/runtime/doc/usr_41.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/usr_41.txt 2019-07-21 21:04:21.000000000 +0000 @@ -1,4 +1,4 @@ -*usr_41.txt* For Vim version 8.1. Last change: 2019 Jul 04 +*usr_41.txt* For Vim version 8.1. Last change: 2019 Jul 06 VIM USER MANUAL - by Bram Moolenaar @@ -1015,8 +1015,10 @@ sign_getplaced() get a list of placed signs sign_jump() jump to a sign sign_place() place a sign + sign_placelist() place a list of signs sign_undefine() undefine a sign sign_unplace() unplace a sign + sign_unplacelist() unplace a list of signs Terminal window: *terminal-functions* term_start() open a terminal window and run a job diff -Nru vim-8.1.1681/runtime/doc/version8.txt vim-8.1.1729/runtime/doc/version8.txt --- vim-8.1.1681/runtime/doc/version8.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/version8.txt 2019-07-21 21:04:21.000000000 +0000 @@ -7625,8 +7625,8 @@ Solution: Remove __ARGS in several files. (script by Hirohito Higashi) Files: src/ex_eval.c, src/ex_getln.c, src/farsi.c, src/fileio.c, src/fold.c, src/getchar.c, src/gui.c, src/gui_at_fs.c, - gui_at_sb.c, src/gui_athena.c, src/gui_beval.c, src/gui_motif.c, - src/gui_w32.c, src/gui_w48.c + src/gui_at_sb.c, src/gui_athena.c, src/gui_beval.c, + src/gui_motif.c, src/gui_w32.c, src/gui_w48.c Patch 7.4.1198 Problem: Still using __ARGS. @@ -8045,7 +8045,7 @@ Problem: Crash when receiving an empty array. Solution: Check for array with wrong number of arguments. (Damien) Files: src/channel.c, src/eval.c, src/testdir/test_channel.py, - src/testdir.test_channel.vim + src/testdir/test_channel.vim Patch 7.4.1265 Problem: Not all channel commands are tested. @@ -8454,8 +8454,8 @@ Patch 7.4.1336 Problem: Channel NL mode is not supported yet. Solution: Add NL mode support to channels. -Files: src/channel.c, src/netbeans.c, src/structs.h, src/os_unix.d, - src/os_win32.c, src/proto/channel.pro, src/proto/os_unix.pro, +Files: src/channel.c, src/netbeans.c, src/structs.h, src/os_win32.c, + src/proto/channel.pro, src/proto/os_unix.pro, src/proto/os_win32.pro, src/testdir/test_channel.vim, src/testdir/test_channel_pipe.py @@ -13904,7 +13904,7 @@ search match. Solution: Pass NULL as last item to next_search_hl() when searching for 'hlsearch' match. (Shane Harper, closes #1013) -Files: src/screen.c, src/testdir/test_match.vim. +Files: src/screen.c, src/testdir/test_match.vim Patch 7.4.2270 Problem: Insufficient testing for NUL bytes on a raw channel. @@ -18306,13 +18306,13 @@ Problem: The screen is redrawn when t_BG is set and used to detect the value for 'background'. Solution: Don't redraw when the value of 'background' didn't change. -Files: src/term.c. +Files: src/term.c Patch 8.0.0611 Problem: When t_u7 is sent a few characters in the second screen line are overwritten and not redrawn later. (Rastislav Barlik) Solution: Move redrawing the screen to after overwriting the characters. -Files: src/main.c, src/term.c. +Files: src/main.c, src/term.c Patch 8.0.0612 Problem: Package directories are added to 'runtimepath' only after loading @@ -27638,7 +27638,7 @@ Patch 8.1.0327 Problem: The "g CTRL-G" command isn't tested much. Solution: Add more tests. (Dominique Pelle, closes #3369) -Files: src/testdir/test_normal.c +Files: src/testdir/test_normal.vim Patch 8.1.0328 Problem: inputlist() doesn't work with a timer. (Dominique Pelle) @@ -29424,7 +29424,7 @@ Problem: "gn" selects the wrong text with a multi-line match. Solution: Get the end position from searchit() directly. (closes #3695) Files: src/testdir/test_gn.vim, src/search.c, src/proto/search.pro, - src/edit.c, src/evalfunc.c, src/ex_docmd.c, ex_getln.c, + src/edit.c, src/evalfunc.c, src/ex_docmd.c, src/ex_getln.c, src/normal.c Patch 8.1.0630 @@ -30859,7 +30859,7 @@ Problem: Cursorline highlight is not always updated. Solution: Set w_last_cursorline when redrawing. Fix resetting cursor flags when using the popup menu. -Files: src/screen.c, src/popupmenu.c, src/testdir/test_highlight.vim, +Files: src/screen.c, src/popupmnu.c, src/testdir/test_highlight.vim, src/testdir/dumps/Test_cursorline_yank_01.dump Patch 8.1.0850 @@ -33447,7 +33447,7 @@ Problem: Cannot combine text properties with syntax highlighting. Solution: Add the "combine" field to prop_type_add(). (closes #4343) Files: runtime/doc/eval.txt, runtime/doc/textprop.txt, src/screen.c, - src/testprop.c, src/structs.h, src/testdir/test_textprop.vim + src/structs.h, src/testdir/test_textprop.vim Patch 8.1.1277 (after 8.1.1276) Problem: Missing screenshot update. diff -Nru vim-8.1.1681/runtime/doc/windows.txt vim-8.1.1729/runtime/doc/windows.txt --- vim-8.1.1681/runtime/doc/windows.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/doc/windows.txt 2019-07-21 21:04:21.000000000 +0000 @@ -1,4 +1,4 @@ -*windows.txt* For Vim version 8.1. Last change: 2019 Jun 02 +*windows.txt* For Vim version 8.1. Last change: 2019 Jul 18 VIM REFERENCE MANUAL by Bram Moolenaar @@ -864,7 +864,15 @@ set in the preview window to be able to recognize it. The 'winfixheight' option is set to have it keep the same height when opening/closing other windows. - + *preview-popup* +Alternatively, a popup window can be used by setting the 'previewpopup' +option. When set, it overrules the 'previewwindow' and 'previewheight' +settings. The option is a comma separated list of values: + height maximum height of the popup + width maximum width of the popup +Example: > + :set previewpopup=height:10,width:60 +< *:pta* *:ptag* :pta[g][!] [tagname] Does ":tag[!] [tagname]" and shows the found tag in a diff -Nru vim-8.1.1681/runtime/filetype.vim vim-8.1.1729/runtime/filetype.vim --- vim-8.1.1681/runtime/filetype.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/filetype.vim 2019-07-21 21:04:21.000000000 +0000 @@ -707,6 +707,9 @@ " HTML (.shtml and .stm for server side) au BufNewFile,BufRead *.html,*.htm,*.shtml,*.stm call dist#ft#FThtml() +" Vue.js Single File Component +au BufNewFile,BufRead *.vue setf vuejs + " HTML with Ruby - eRuby au BufNewFile,BufRead *.erb,*.rhtml setf eruby diff -Nru vim-8.1.1681/runtime/ftplugin/qf.vim vim-8.1.1729/runtime/ftplugin/qf.vim --- vim-8.1.1681/runtime/ftplugin/qf.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/ftplugin/qf.vim 2019-07-21 21:04:21.000000000 +0000 @@ -1,7 +1,7 @@ " Vim filetype plugin file " Language: Vim's quickfix window " Maintainer: Lech Lorens -" Last Changed: 30 Apr 2012 +" Last Change: 2019 Jul 15 if exists("b:did_ftplugin") finish @@ -10,7 +10,9 @@ " Don't load another plugin for this buffer let b:did_ftplugin = 1 -let b:undo_ftplugin = "set stl<" +if !get(g:, 'qf_disable_statusline') + let b:undo_ftplugin = "set stl<" -" Display the command that produced the list in the quickfix window: -setlocal stl=%t%{exists('w:quickfix_title')?\ '\ '.w:quickfix_title\ :\ ''}\ %=%-15(%l,%c%V%)\ %P + " Display the command that produced the list in the quickfix window: + setlocal stl=%t%{exists('w:quickfix_title')?\ '\ '.w:quickfix_title\ :\ ''}\ %=%-15(%l,%c%V%)\ %P +endif diff -Nru vim-8.1.1681/runtime/lang/menu_sr_rs.utf-8.vim vim-8.1.1729/runtime/lang/menu_sr_rs.utf-8.vim --- vim-8.1.1681/runtime/lang/menu_sr_rs.utf-8.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/lang/menu_sr_rs.utf-8.vim 2019-07-21 21:04:21.000000000 +0000 @@ -27,11 +27,11 @@ menutrans &About &О\ програму " File menu -menutrans &File &Датотека +menutrans &File &Фајл menutrans &Open\.\.\.:e &Отвори\.\.\.:e menutrans Sp&lit-Open\.\.\.:sp &Подели-отвори\.\.\.:sp menutrans Open\ Tab\.\.\.:tabnew Отвори\ картицу\.\.\.:tabnew -menutrans &New:enew &Нова:enew +menutrans &New:enew &Нов:enew menutrans &Close:close &Затвори:close menutrans &Save:w &Сачувај:w menutrans Save\ &As\.\.\.:sav Сачувај\ &као\.\.\.:sav @@ -43,14 +43,14 @@ " Edit menu menutrans &Edit &Уређивање -menutrans &Undou &Вратиu -menutrans &Redo^R &Поврати^R +menutrans &Undou &Поништиu +menutrans &Redo^R &Врати\ измену^R menutrans Rep&eat\. П&онови\. menutrans Cu&t"+x Исе&ци"+x menutrans &Copy"+y &Копирај"+y menutrans &Paste"+gP &Убаци"+gP -menutrans &Paste"+P &Убаци"+gP -menutrans Put\ &Before[p Стави\ пре&д[p +menutrans &Paste"+P &Убаци"+P +menutrans Put\ &Before[p Стави\ испре&д[p menutrans Put\ &After]p Стави\ &иза]p menutrans &Deletex Из&бришиx menutrans &Select\ allggVG Изабери\ св&еggVG @@ -59,11 +59,11 @@ menutrans Settings\ &Window П&розор\ подешавања menutrans Startup\ &Settings По&дешавања\ при\ покретању menutrans &Global\ Settings Оп&шта\ подешавања -menutrans F&ile\ Settings Подешавања\ за\ да&тотеке -menutrans &Shiftwidth &Померај +menutrans F&ile\ Settings Подешавања\ за\ фај&лове +menutrans &Shiftwidth &Корак\ увлачења menutrans Soft\ &Tabstop &Мека\ табулација menutrans Te&xt\ Width\.\.\. &Ширина\ текста\.\.\. -menutrans &File\ Format\.\.\. &Врста\ датотеке\.\.\. +menutrans &File\ Format\.\.\. &Врста\ фајла\.\.\. menutrans Show\ C&olor\ Schemes\ in\ Menu Прикажи\ шеме\ бо&ја\ у\ менију menutrans C&olor\ Scheme \Шеме\ бо&ја menutrans Show\ &Keymaps\ in\ Menu Прикажи\ прес&ликавања\ тастатуре\ у\ менију @@ -71,15 +71,15 @@ menutrans Select\ Fo&nt\.\.\. Избор\ &фонта\.\.\. " Edit/Global Settings -menutrans Toggle\ Pattern\ &Highlight:set\ hls! Нагласи\ &образце\ (да/не):set\ hls! +menutrans Toggle\ Pattern\ &Highlight:set\ hls! Истицање\ &шаблона\ (да/не):set\ hls! menutrans Toggle\ &Ignoring\ Case:set\ ic! Занемари\ величину\ &слова\ (да/не):set\ ic! -menutrans Toggle\ &Showing\ Matched\ Pairs:set\ sm! Провери\ пратећу\ &заграду\ (да/не):set\ sm! +menutrans Toggle\ &Showing\ Matched\ Pairs:set\ sm! Прикажи\ упарену\ &заграду\ (да/не):set\ sm! menutrans &Context\ lines Видљиви\ &редови menutrans &Virtual\ Edit Виртуелно\ &уређивање -menutrans Toggle\ Insert\ &Mode:set\ im! Режим\ у&носа\ (да/не):set\ im! +menutrans Toggle\ Insert\ &Mode:set\ im! Режим\ У&метање\ (да/не):set\ im! menutrans Toggle\ Vi\ C&ompatibility:set\ cp! '&Vi'\ сагласно\ (да/не):set\ cp! menutrans Search\ &Path\.\.\. Путања\ &претраге\.\.\. -menutrans Ta&g\ Files\.\.\. &Датотеке\ ознака\.\.\. +menutrans Ta&g\ Files\.\.\. &Фајлови\ ознака\.\.\. menutrans Toggle\ &Toolbar Линија\ са\ &алаткама\ (да/не) menutrans Toggle\ &Bottom\ Scrollbar Доња\ л&инија\ клизања\ (да/не) menutrans Toggle\ &Left\ Scrollbar &Лева\ линија\ клизања\ (да/не) @@ -88,8 +88,8 @@ " Edit/Global Settings/Virtual Edit menutrans Never Никад menutrans Block\ Selection Избор\ блока -menutrans Insert\ mode Режим\ уноса -menutrans Block\ and\ Insert Блок\ и\ унос +menutrans Insert\ mode Режим\ Уметање +menutrans Block\ and\ Insert Блок\ и\ Уметање menutrans Always Увек " Edit/File Settings @@ -109,13 +109,13 @@ menutrans &Tools &Алатке menutrans &Jump\ to\ this\ tagg^] Скочи\ на\ &ову\ ознакуg^] menutrans Jump\ &back^T Скочи\ &натраг^T -menutrans Build\ &Tags\ File Изгради\ &датотеку\ ознака +menutrans Build\ &Tags\ File Изгради\ &фајл\ ознака menutrans &Spelling Пра&вопис menutrans &Folding &Подвијање -menutrans Create\ &Foldzf С&твори\ подвијутакzf -menutrans &Delete\ Foldzd О&бриши\ подвијутакzd -menutrans Delete\ &All\ FoldszD Обриши\ све\ по&двијуткеzD -menutrans Fold\ column\ &width Ширина\ &реда\ подвијутка +menutrans Create\ &Foldzf С&твори\ свијутакzf +menutrans &Delete\ Foldzd О&бриши\ свијутакzd +menutrans Delete\ &All\ FoldszD Обриши\ све\ св&ијуткеzD +menutrans Fold\ column\ &width Ширина\ &реда\ цвијутка "menutrans &Diff &Упоређивање menutrans &Make:make 'mak&е':make menutrans &List\ Errors:cl Списак\ &грешака:cl @@ -146,15 +146,15 @@ menutrans &Find\ More\ Languages Пронађи\ још\ језика " Tools/Folding -menutrans &Enable/Disable\ foldszi &Омогући/прекини\ подвијањеzi +menutrans &Enable/Disable\ foldszi &Омогући/прекини\ свијањеzi menutrans &View\ Cursor\ Linezv &Покажи\ ред\ са\ курсоромzv menutrans Vie&w\ Cursor\ Line\ onlyzMzx Покажи\ &само\ ред\ са\ курсоромzMzx -menutrans C&lose\ more\ foldszm &Затвори\ више\ подвијутакаzm -menutrans &Close\ all\ foldszM Затвори\ с&ве\ подвијуткеzM -menutrans O&pen\ more\ foldszr Отвори\ виш&е\ подвијутакаzr -menutrans &Open\ all\ foldszR О&твори\ све\ подвијуткеzR +menutrans C&lose\ more\ foldszm &Затвори\ више\ свијутакаzm +menutrans &Close\ all\ foldszM Затвори\ с&ве\ свијуткеzM +menutrans O&pen\ more\ foldszr Отвори\ виш&е\ свијутакаzr +menutrans &Open\ all\ foldszR О&твори\ све\ свијуткеzR menutrans Fold\ Met&hod &Начин\ подвијања -menutrans Fold\ Col&umn\ Width Ширина\ колоне\ испред\ подвијутака +menutrans Fold\ Col&umn\ Width Ширина\ колоне\ испред\ свијутака " Tools/Folding/Fold Method menutrans M&anual &Ручно @@ -181,7 +181,7 @@ menutrans &Alternate А&лтернативни menutrans &Next &Следећи menutrans &Previous &Претходни -menutrans [No\ File] [Нема\ датотеке] +menutrans [No\ File] [Нема\ фајла] " Window menu menutrans &Window &Прозор @@ -189,7 +189,7 @@ menutrans S&plit^Ws &Подели^Ws menutrans Sp&lit\ To\ #^W^^ Подели\ са\ &алтернативним^W^^ menutrans Split\ &Vertically^Wv Подели\ &усправно^Wv -menutrans Split\ File\ E&xplorer Подели\ за\ преглед\ &датотека +menutrans Split\ File\ E&xplorer Подели\ за\ преглед\ &фајлова menutrans &Close^Wc &Затвори^Wc menutrans Close\ &Other(s)^Wo Затвори\ &остале^Wo "menutrans Ne&xt^Ww &Следећи^Ww @@ -210,7 +210,7 @@ menutrans &Right\ side^WL У&десно^WL " The popup menu -menutrans &Undo &Врати +menutrans &Undo &Поништи menutrans Cu&t &Исеци menutrans &Copy &Копирај menutrans &Paste &Убаци @@ -218,7 +218,7 @@ menutrans Select\ Blockwise Бирај\ б&локовски menutrans Select\ &Word Изабери\ &реч menutrans Select\ &Sentence Изабери\ р&еченицу -menutrans Select\ Pa&ragraph Изабери\ &параграф +menutrans Select\ Pa&ragraph Изабери\ &пасус menutrans Select\ &Line Изабери\ р&ед menutrans Select\ &Block Изабери\ &блок menutrans Select\ &All Изабери\ &све @@ -264,13 +264,13 @@ " Syntax menu menutrans &Syntax &Синтакса -menutrans &Show\ File\ Types\ in\ Menu Прикажи\ типове\ датотека\ у\ &менију +menutrans &Show\ File\ Types\ in\ Menu Прикажи\ типове\ фајлова\ у\ &менију menutrans Set\ '&syntax'\ only Поде&си\ само\ 'syntax' menutrans Set\ '&filetype'\ too Подеси\ &такође\ и\ 'filetype' menutrans &Off &Искључено menutrans &Manual &Ручно menutrans A&utomatic &Аутоматски -menutrans on/off\ for\ &This\ file Да/не\ за\ ову\ &датотеку +menutrans on/off\ for\ &This\ file Да/не\ за\ овај\ &фајл menutrans Co&lor\ test Провера\ &боја menutrans &Highlight\ test Провера\ исти&цања menutrans &Convert\ to\ HTML Претвори\ &у\ HTML @@ -278,17 +278,17 @@ " dialog texts let menutrans_help_dialog = "Унесите наредбу или реч чије појашњење тражите:\n\nДодајте i_ за наредбе уноса (нпр. i_CTRL-X)\nДодајте c_ за наредбе командног режима (нпр. с_)\nДодајте ' за имена опција (нпр. 'shiftwidth')" -let g:menutrans_path_dialog = "Унесите пут претраге за датотеке\nРаздвојите зарезима имена директоријума." +let g:menutrans_path_dialog = "Унесите путању претраге за фајлове\nРаздвојите зарезима имена директоријума." -let g:menutrans_tags_dialog = "Унесите имена датотека са ознакама\nРаздвојите зарезима имена." +let g:menutrans_tags_dialog = "Унесите имена фајлова са ознакама\nРаздвојите зарезима имена." let g:menutrans_textwidth_dialog = "Унесите нову ширину текста (0 спречава прелом)" -let g:menutrans_fileformat_dialog = "Изаберите формат записа датотеке" +let g:menutrans_fileformat_dialog = "Изаберите формат записа фајла" let g:menutrans_fileformat_choices = "&Unix\n&Dos\n&Mac\n&Откажи" -let menutrans_no_file = "[Нема датотеке]" +let menutrans_no_file = "[Нема фајла]" let &cpo = s:keepcpo unlet s:keepcpo diff -Nru vim-8.1.1681/runtime/makemenu.vim vim-8.1.1729/runtime/makemenu.vim --- vim-8.1.1681/runtime/makemenu.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/makemenu.vim 2019-07-21 21:04:21.000000000 +0000 @@ -272,6 +272,7 @@ SynMenu HIJK.HTML.HTML\ with\ Ruby\ (eRuby):eruby SynMenu HIJK.HTML.Cheetah\ HTML\ template:htmlcheetah SynMenu HIJK.HTML.Django\ HTML\ template:htmldjango +SynMenu HIJK.HTML.Vue.js\ HTML\ template:vuejs SynMenu HIJK.HTML.HTML/OS:htmlos SynMenu HIJK.HTML.XHTML:xhtml SynMenu HIJK.Host\.conf:hostconf diff -Nru vim-8.1.1681/runtime/optwin.vim vim-8.1.1729/runtime/optwin.vim --- vim-8.1.1681/runtime/optwin.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/optwin.vim 2019-07-21 21:04:21.000000000 +0000 @@ -1,7 +1,7 @@ " These commands create the option window. " " Maintainer: Bram Moolenaar -" Last Change: 2019 May 25 +" Last Change: 2019 Jul 18 " If there already is an option window, jump to that one. let buf = bufnr('option-window') @@ -479,6 +479,8 @@ call append("$", "helpheight\tinitial height of the help window") call append("$", " \tset hh=" . &hh) if has("quickfix") + call append("$", "previewpopup\tuse a popup window for preview") + call append("$", " \tset pvp=" . &pvp) call append("$", "previewheight\tdefault height for the preview window") call append("$", " \tset pvh=" . &pvh) call append("$", "previewwindow\tidentifies the preview window") diff -Nru vim-8.1.1681/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim vim-8.1.1729/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim --- vim-8.1.1681/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim 2019-07-21 21:04:21.000000000 +0000 @@ -838,12 +838,12 @@ " if there is any. func TermDebugBalloonExpr() if v:beval_winid != s:sourcewin - return + return '' endif if !s:stopped " Only evaluate when stopped, otherwise setting a breakpoint using the " mouse triggers a balloon. - return + return '' endif let s:evalFromBalloonExpr = 1 let s:evalFromBalloonExprResult = '' diff -Nru vim-8.1.1681/runtime/plugin/netrwPlugin.vim vim-8.1.1729/runtime/plugin/netrwPlugin.vim --- vim-8.1.1681/runtime/plugin/netrwPlugin.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/plugin/netrwPlugin.vim 2019-07-21 21:04:21.000000000 +0000 @@ -20,7 +20,7 @@ if &cp || exists("g:loaded_netrwPlugin") finish endif -let g:loaded_netrwPlugin = "v156" +let g:loaded_netrwPlugin = "v165" let s:keepcpo = &cpo set cpo&vim "DechoRemOn @@ -42,8 +42,8 @@ " Network Browsing Reading Writing: {{{2 augroup Network au! - au BufReadCmd file://* call netrw#FileUrlRead(expand("")) - au BufReadCmd ftp://*,rcp://*,scp://*,http://*,file://*,https://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau BufReadPre ".fnameescape(expand(""))|call netrw#Nread(2,expand(""))|exe "sil doau BufReadPost ".fnameescape(expand("")) + au BufReadCmd file://* call netrw#FileUrlEdit(expand("")) + au BufReadCmd ftp://*,rcp://*,scp://*,http://*,https://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau BufReadPre ".fnameescape(expand(""))|call netrw#Nread(2,expand(""))|exe "sil doau BufReadPost ".fnameescape(expand("")) au FileReadCmd ftp://*,rcp://*,scp://*,http://*,file://*,https://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau FileReadPre ".fnameescape(expand(""))|call netrw#Nread(1,expand(""))|exe "sil doau FileReadPost ".fnameescape(expand("")) au BufWriteCmd ftp://*,rcp://*,scp://*,http://*,file://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau BufWritePre ".fnameescape(expand(""))|exe 'Nwrite '.fnameescape(expand(""))|exe "sil doau BufWritePost ".fnameescape(expand("")) au FileWriteCmd ftp://*,rcp://*,scp://*,http://*,file://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau FileWritePre ".fnameescape(expand(""))|exe "'[,']".'Nwrite '.fnameescape(expand(""))|exe "sil doau FileWritePost ".fnameescape(expand("")) @@ -59,7 +59,7 @@ com! -range=% -nargs=* Nwrite let s:svpos= winsaveview(),call netrw#NetWrite()call winrestview(s:svpos) com! -nargs=* NetUserPass call NetUserPass() com! -nargs=* Nsource let s:svpos= winsaveview()call netrw#NetSource()call winrestview(s:svpos) -com! -nargs=? Ntree call netrw#SetTreetop() +com! -nargs=? Ntree call netrw#SetTreetop(1,) " Commands: :Explore, :Sexplore, Hexplore, Vexplore, Lexplore {{{2 com! -nargs=* -bar -bang -count=0 -complete=dir Explore call netrw#Explore(,0,0+0,) @@ -81,7 +81,7 @@ if !hasmapto('NetrwBrowseX') nmap gx NetrwBrowseX endif - nno NetrwBrowseX :call netrw#BrowseX(expand((exists("g:netrw_gx")? g:netrw_gx : '')),netrw#CheckIfRemote()) + nno NetrwBrowseX :call netrw#BrowseX(netrw#GX(),netrw#CheckIfRemote(netrw#GX())) endif if maparg('gx','v') == "" if !hasmapto('NetrwBrowseXVis') @@ -129,19 +129,15 @@ elseif isdirectory(a:dirname) " call Decho("(LocalBrowse) dirname<".a:dirname."> ft=".&ft." (isdirectory, not amiga)") " call Dredir("LocalBrowse ft last set: ","verbose set ft") -" call Decho("(s:LocalBrowse) COMBAK#23: buf#".bufnr("%")." file<".expand("%")."> line#".line(".")." col#".col(".")) sil! call netrw#LocalBrowseCheck(a:dirname) -" call Decho("(s:LocalBrowse) COMBAK#24: buf#".bufnr("%")." file<".expand("%")."> line#".line(".")." col#".col(".")) if exists("w:netrw_bannercnt") && line('.') < w:netrw_bannercnt exe w:netrw_bannercnt -" call Decho("(s:LocalBrowse) COMBAK#25: buf#".bufnr("%")." file<".expand("%")."> line#".line(".")." col#".col(".")) endif else " not a directory, ignore it " call Decho("(LocalBrowse) dirname<".a:dirname."> not a directory, ignoring...") endif -" call Decho("(s:LocalBrowse) COMBAK#26: buf#".bufnr("%")." file<".expand("%")."> line#".line(".")." col#".col(".")) " call Dret("s:LocalBrowse") endfun diff -Nru vim-8.1.1681/runtime/synmenu.vim vim-8.1.1729/runtime/synmenu.vim --- vim-8.1.1681/runtime/synmenu.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/synmenu.vim 2019-07-21 21:04:21.000000000 +0000 @@ -252,48 +252,49 @@ an 50.50.230 &Syntax.HIJK.HTML.HTML\ with\ Ruby\ (eRuby) :cal SetSyn("eruby") an 50.50.240 &Syntax.HIJK.HTML.Cheetah\ HTML\ template :cal SetSyn("htmlcheetah") an 50.50.250 &Syntax.HIJK.HTML.Django\ HTML\ template :cal SetSyn("htmldjango") -an 50.50.260 &Syntax.HIJK.HTML.HTML/OS :cal SetSyn("htmlos") -an 50.50.270 &Syntax.HIJK.HTML.XHTML :cal SetSyn("xhtml") -an 50.50.280 &Syntax.HIJK.Host\.conf :cal SetSyn("hostconf") -an 50.50.290 &Syntax.HIJK.Hosts\ access :cal SetSyn("hostsaccess") -an 50.50.300 &Syntax.HIJK.Hyper\ Builder :cal SetSyn("hb") -an 50.50.320 &Syntax.HIJK.Icewm\ menu :cal SetSyn("icemenu") -an 50.50.330 &Syntax.HIJK.Icon :cal SetSyn("icon") -an 50.50.340 &Syntax.HIJK.IDL\Generic\ IDL :cal SetSyn("idl") -an 50.50.350 &Syntax.HIJK.IDL\Microsoft\ IDL :cal SetSyn("msidl") -an 50.50.360 &Syntax.HIJK.Indent\ profile :cal SetSyn("indent") -an 50.50.370 &Syntax.HIJK.Inform :cal SetSyn("inform") -an 50.50.380 &Syntax.HIJK.Informix\ 4GL :cal SetSyn("fgl") -an 50.50.390 &Syntax.HIJK.Initng :cal SetSyn("initng") -an 50.50.400 &Syntax.HIJK.Inittab :cal SetSyn("inittab") -an 50.50.410 &Syntax.HIJK.Inno\ setup :cal SetSyn("iss") -an 50.50.420 &Syntax.HIJK.Innovation\ Data\ Processing.Upstream\ dat :cal SetSyn("upstreamdat") -an 50.50.430 &Syntax.HIJK.Innovation\ Data\ Processing.Upstream\ log :cal SetSyn("upstreamlog") -an 50.50.440 &Syntax.HIJK.Innovation\ Data\ Processing.Upstream\ rpt :cal SetSyn("upstreamrpt") -an 50.50.450 &Syntax.HIJK.Innovation\ Data\ Processing.Upstream\ Install\ log :cal SetSyn("upstreaminstalllog") -an 50.50.460 &Syntax.HIJK.Innovation\ Data\ Processing.Usserver\ log :cal SetSyn("usserverlog") -an 50.50.470 &Syntax.HIJK.Innovation\ Data\ Processing.USW2KAgt\ log :cal SetSyn("usw2kagtlog") -an 50.50.480 &Syntax.HIJK.InstallShield\ script :cal SetSyn("ishd") -an 50.50.490 &Syntax.HIJK.Interactive\ Data\ Lang :cal SetSyn("idlang") -an 50.50.500 &Syntax.HIJK.IPfilter :cal SetSyn("ipfilter") -an 50.50.520 &Syntax.HIJK.J :cal SetSyn("j") -an 50.50.530 &Syntax.HIJK.JAL :cal SetSyn("jal") -an 50.50.540 &Syntax.HIJK.JAM :cal SetSyn("jam") -an 50.50.550 &Syntax.HIJK.Jargon :cal SetSyn("jargon") -an 50.50.560 &Syntax.HIJK.Java.Java :cal SetSyn("java") -an 50.50.570 &Syntax.HIJK.Java.JavaCC :cal SetSyn("javacc") -an 50.50.580 &Syntax.HIJK.Java.Java\ Server\ Pages :cal SetSyn("jsp") -an 50.50.590 &Syntax.HIJK.Java.Java\ Properties :cal SetSyn("jproperties") -an 50.50.600 &Syntax.HIJK.JavaScript :cal SetSyn("javascript") -an 50.50.610 &Syntax.HIJK.Jess :cal SetSyn("jess") -an 50.50.620 &Syntax.HIJK.Jgraph :cal SetSyn("jgraph") -an 50.50.630 &Syntax.HIJK.Jovial :cal SetSyn("jovial") -an 50.50.640 &Syntax.HIJK.JSON :cal SetSyn("json") -an 50.50.660 &Syntax.HIJK.Kconfig :cal SetSyn("kconfig") -an 50.50.670 &Syntax.HIJK.KDE\ script :cal SetSyn("kscript") -an 50.50.680 &Syntax.HIJK.Kimwitu++ :cal SetSyn("kwt") -an 50.50.690 &Syntax.HIJK.Kivy :cal SetSyn("kivy") -an 50.50.700 &Syntax.HIJK.KixTart :cal SetSyn("kix") +an 50.50.260 &Syntax.HIJK.HTML.Vue.js\ HTML\ template :cal SetSyn("vuejs") +an 50.50.270 &Syntax.HIJK.HTML.HTML/OS :cal SetSyn("htmlos") +an 50.50.280 &Syntax.HIJK.HTML.XHTML :cal SetSyn("xhtml") +an 50.50.290 &Syntax.HIJK.Host\.conf :cal SetSyn("hostconf") +an 50.50.300 &Syntax.HIJK.Hosts\ access :cal SetSyn("hostsaccess") +an 50.50.310 &Syntax.HIJK.Hyper\ Builder :cal SetSyn("hb") +an 50.50.330 &Syntax.HIJK.Icewm\ menu :cal SetSyn("icemenu") +an 50.50.340 &Syntax.HIJK.Icon :cal SetSyn("icon") +an 50.50.350 &Syntax.HIJK.IDL\Generic\ IDL :cal SetSyn("idl") +an 50.50.360 &Syntax.HIJK.IDL\Microsoft\ IDL :cal SetSyn("msidl") +an 50.50.370 &Syntax.HIJK.Indent\ profile :cal SetSyn("indent") +an 50.50.380 &Syntax.HIJK.Inform :cal SetSyn("inform") +an 50.50.390 &Syntax.HIJK.Informix\ 4GL :cal SetSyn("fgl") +an 50.50.400 &Syntax.HIJK.Initng :cal SetSyn("initng") +an 50.50.410 &Syntax.HIJK.Inittab :cal SetSyn("inittab") +an 50.50.420 &Syntax.HIJK.Inno\ setup :cal SetSyn("iss") +an 50.50.430 &Syntax.HIJK.Innovation\ Data\ Processing.Upstream\ dat :cal SetSyn("upstreamdat") +an 50.50.440 &Syntax.HIJK.Innovation\ Data\ Processing.Upstream\ log :cal SetSyn("upstreamlog") +an 50.50.450 &Syntax.HIJK.Innovation\ Data\ Processing.Upstream\ rpt :cal SetSyn("upstreamrpt") +an 50.50.460 &Syntax.HIJK.Innovation\ Data\ Processing.Upstream\ Install\ log :cal SetSyn("upstreaminstalllog") +an 50.50.470 &Syntax.HIJK.Innovation\ Data\ Processing.Usserver\ log :cal SetSyn("usserverlog") +an 50.50.480 &Syntax.HIJK.Innovation\ Data\ Processing.USW2KAgt\ log :cal SetSyn("usw2kagtlog") +an 50.50.490 &Syntax.HIJK.InstallShield\ script :cal SetSyn("ishd") +an 50.50.500 &Syntax.HIJK.Interactive\ Data\ Lang :cal SetSyn("idlang") +an 50.50.510 &Syntax.HIJK.IPfilter :cal SetSyn("ipfilter") +an 50.50.530 &Syntax.HIJK.J :cal SetSyn("j") +an 50.50.540 &Syntax.HIJK.JAL :cal SetSyn("jal") +an 50.50.550 &Syntax.HIJK.JAM :cal SetSyn("jam") +an 50.50.560 &Syntax.HIJK.Jargon :cal SetSyn("jargon") +an 50.50.570 &Syntax.HIJK.Java.Java :cal SetSyn("java") +an 50.50.580 &Syntax.HIJK.Java.JavaCC :cal SetSyn("javacc") +an 50.50.590 &Syntax.HIJK.Java.Java\ Server\ Pages :cal SetSyn("jsp") +an 50.50.600 &Syntax.HIJK.Java.Java\ Properties :cal SetSyn("jproperties") +an 50.50.610 &Syntax.HIJK.JavaScript :cal SetSyn("javascript") +an 50.50.620 &Syntax.HIJK.Jess :cal SetSyn("jess") +an 50.50.630 &Syntax.HIJK.Jgraph :cal SetSyn("jgraph") +an 50.50.640 &Syntax.HIJK.Jovial :cal SetSyn("jovial") +an 50.50.650 &Syntax.HIJK.JSON :cal SetSyn("json") +an 50.50.670 &Syntax.HIJK.Kconfig :cal SetSyn("kconfig") +an 50.50.680 &Syntax.HIJK.KDE\ script :cal SetSyn("kscript") +an 50.50.690 &Syntax.HIJK.Kimwitu++ :cal SetSyn("kwt") +an 50.50.700 &Syntax.HIJK.Kivy :cal SetSyn("kivy") +an 50.50.710 &Syntax.HIJK.KixTart :cal SetSyn("kix") an 50.60.100 &Syntax.L.Lace :cal SetSyn("lace") an 50.60.110 &Syntax.L.LamdaProlog :cal SetSyn("lprolog") an 50.60.120 &Syntax.L.Latte :cal SetSyn("latte") diff -Nru vim-8.1.1681/runtime/syntax/json.vim vim-8.1.1729/runtime/syntax/json.vim --- vim-8.1.1681/runtime/syntax/json.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/syntax/json.vim 2019-07-21 21:04:21.000000000 +0000 @@ -1,7 +1,8 @@ " Vim syntax file " Language: JSON -" Maintainer: Eli Parra -" Last Change: 2014 Aug 23 +" Maintainer: vacancy +" Previous Maintainer: Eli Parra +" Last Change: 2019 Jul 08 " Version: 0.12 if !exists("main_syntax") @@ -16,8 +17,19 @@ " NOTE that for the concealing to work your conceallevel should be set to 2 +" Syntax: JSON Keywords +" Separated into a match and region because a region by itself is always greedy +syn match jsonKeywordMatch /"\([^"]\|\\\"\)\+"[[:blank:]\r\n]*\:/ contains=jsonKeyword +if has('conceal') + syn region jsonKeyword matchgroup=jsonQuote start=/"/ end=/"\ze[[:blank:]\r\n]*\:/ concealends contained +else + syn region jsonKeyword matchgroup=jsonQuote start=/"/ end=/"\ze[[:blank:]\r\n]*\:/ contained +endif + " Syntax: Strings " Separated into a match and region because a region by itself is always greedy +" Needs to come after keywords or else a json encoded string will break the +" syntax syn match jsonStringMatch /"\([^"]\|\\\"\)\+"\ze[[:blank:]\r\n]*[,}\]]/ contains=jsonString if has('conceal') syn region jsonString oneline matchgroup=jsonQuote start=/"/ skip=/\\\\\|\\"/ end=/"/ concealends contains=jsonEscape contained @@ -28,14 +40,6 @@ " Syntax: JSON does not allow strings with single quotes, unlike JavaScript. syn region jsonStringSQError oneline start=+'+ skip=+\\\\\|\\"+ end=+'+ -" Syntax: JSON Keywords -" Separated into a match and region because a region by itself is always greedy -syn match jsonKeywordMatch /"\([^"]\|\\\"\)\+"[[:blank:]\r\n]*\:/ contains=jsonKeyword -if has('conceal') - syn region jsonKeyword matchgroup=jsonQuote start=/"/ end=/"\ze[[:blank:]\r\n]*\:/ concealends contained -else - syn region jsonKeyword matchgroup=jsonQuote start=/"/ end=/"\ze[[:blank:]\r\n]*\:/ contained -endif " Syntax: Escape sequences syn match jsonEscape "\\["\\/bfnrt]" contained diff -Nru vim-8.1.1681/runtime/syntax/lisp.vim vim-8.1.1729/runtime/syntax/lisp.vim --- vim-8.1.1681/runtime/syntax/lisp.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/syntax/lisp.vim 2019-07-21 21:04:21.000000000 +0000 @@ -1,8 +1,8 @@ " Vim syntax file " Language: Lisp " Maintainer: Charles E. Campbell -" Last Change: Mar 26, 2019 -" Version: 28 +" Last Change: Jul 11, 2019 +" Version: 29 " URL: http://www.drchip.org/astronaut/vim/index.html#SYNTAX_LISP " " Thanks to F Xavier Noria for a list of 978 Common Lisp symbols taken from HyperSpec @@ -54,7 +54,7 @@ syn region lispParen8 contained matchgroup=hlLevel8 start="`\=(" end=")" skip="|.\{-}|" contains=@lispListCluster,lispParen9 syn region lispParen9 contained matchgroup=hlLevel9 start="`\=(" end=")" skip="|.\{-}|" contains=@lispListCluster,lispParen0 else - syn region lispList matchgroup=Delimiter start="(" skip="|.\{-}|" matchgroup=Delimiter end=")" contains=@lispListCluster + syn region lispList matchgroup=lispParen start="(" skip="|.\{-}|" matchgroup=lispParen end=")" contains=@lispListCluster syn region lispBQList matchgroup=PreProc start="`(" skip="|.\{-}|" matchgroup=PreProc end=")" contains=@lispListCluster endif @@ -608,6 +608,8 @@ hi def hlLevel8 ctermfg=blue guifg=darkslateblue hi def hlLevel9 ctermfg=darkmagenta guifg=darkviolet endif + else + hi def link lispParen Delimiter endif endif diff -Nru vim-8.1.1681/runtime/syntax/vim.vim vim-8.1.1729/runtime/syntax/vim.vim --- vim-8.1.1681/runtime/syntax/vim.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/syntax/vim.vim 2019-07-21 21:04:21.000000000 +0000 @@ -1,8 +1,8 @@ " Vim syntax file " Language: Vim 8.0 script " Maintainer: Charles E. Campbell -" Last Change: Jun 16, 2019 -" Version: 8.0-22 +" Last Change: July 18, 2019 +" Version: 8.0-23 " URL: http://www.drchip.org/astronaut/vim/index.html#SYNTAX_VIM " Automatically generated keyword lists: {{{1 @@ -19,38 +19,38 @@ syn cluster vimCommentGroup contains=vimTodo,@Spell " regular vim commands {{{2 -syn keyword vimCommand contained a arga[dd] argu[ment] bad[d] bn[ext] breakd[el] bw[ipeout] cadde[xpr] cc cf[ile] changes cla[st] cnf[ile] comp[iler] cq[uit] cw[indow] delep dell diffg[et] dig[raphs] doau ea el[se] endt[ry] f[ile] fina[lly] foldd[oopen] go[to] ha[rdcopy] hid[e] ij[ump] isp[lit] keepa l[ist] lat lcl[ose] lex[pr] lgete[xpr] lla[st] lnf[ile] lol[der] lt[ag] lw[indow] menut[ranslate] mkv[imrc] nb[key] noa nos[wapfile] on[ly] packl[oadall] po[p] pro ps[earch] ptl[ast] pu[t] pydo pyxdo r[ead] redraws[tatus] rew[ind] rubyd[o] sIc sIp san[dbox] sbf[irst] sbr[ewind] sci scs setl[ocal] sgc sgp sie sin sm[agic] sn[ext] sor[t] spellr[epall] srI srl star[tinsert] sts[elect] sv[iew] syncbind tab tabf[ind] tabnew tags ter[minal] tm[enu] to[pleft] tu[nmenu] undol[ist] up[date] vi[sual] vmapc[lear] wa[ll] winp[os] ws[verb] xmapc[lear] xprop -syn keyword vimCommand contained ab argd[elete] as[cii] bd[elete] bo[tright] breakl[ist] cN[ext] caddf[ile] ccl[ose] cfdo chd[ir] cle[arjumps] co[py] con[tinue] cr[ewind] d[elete] deletel delm[arks] diffo[ff] dir dp earlier elsei[f] endw[hile] files fini[sh] folddoc[losed] gr[ep] helpc[lose] his[tory] il[ist] iuna[bbrev] keepalt la[st] later lcs lf[ile] lgr[ep] lli[st] lo[adview] lop[en] lua m[ove] mes mkvie[w] nbc[lose] noautocmd nu[mber] opt[ions] pc[lose] popu[p] prof[ile] ptN[ext] ptn[ext] pw[d] pyf[ile] pyxfile rec[over] reg[isters] ri[ght] rubyf[ile] sIe sIr sav[eas] sbl[ast] sc scl scscope sf[ind] sge sgr sig sip sm[ap] sno[magic] sp[lit] spellu[ndo] src srn startg[replace] sun[hide] sw[apname] syntime tabN[ext] tabfir[st] tabo[nly] tc[l] tf[irst] tma[p] tp[revious] tunma[p] unh[ide] v vie[w] vne[w] wh[ile] wn[ext] wundo xme xunme -syn keyword vimCommand contained abc[lear] argdo au bel[owright] bp[revious] bro[wse] cNf[ile] cal[l] cd cfir[st] che[ckpath] clo[se] col[der] conf[irm] cs debug deletep delp diffp[atch] dj[ump] dr[op] ec em[enu] ene[w] filet fir[st] foldo[pen] grepa[dd] helpf[ind] i imapc[lear] j[oin] keepj[umps] lad[dexpr] lb[uffer] lcscope lfdo lgrepa[dd] lmak[e] loadk lp[revious] luado ma[rk] messages mod[e] nbs[tart] noh[lsearch] o[pen] ownsyntax pe[rl] pp[op] profd[el] pta[g] ptp[revious] py3 python3 q[uit] red[o] res[ize] rightb[elow] rundo sIg sN[ext] sbN[ext] sbm[odified] scI scp se[t] sfir[st] sgi sh[ell] sign sir sme snoreme spe[llgood] spellw[rong] sre[wind] srp startr[eplace] sunme sy t tabc[lose] tabl[ast] tabp[revious] tcld[o] th[row] tmapc[lear] tr[ewind] u[ndo] unl ve[rsion] vim[grep] vs[plit] win[size] wp[revious] wv[iminfo] xmenu xunmenu -syn keyword vimCommand contained abo[veleft] arge[dit] bN[ext] bf[irst] br[ewind] bufdo c[hange] cat[ch] cdo cg[etfile] checkt[ime] cmapc[lear] colo[rscheme] cope[n] cscope debugg[reedy] deletl dep diffpu[t] dl ds[earch] echoe[rr] en[dif] ex filetype fix[del] for gui helpg[rep] ia in ju[mps] keepp[atterns] laddb[uffer] lbo[ttom] ld[o] lfir[st] lh[elpgrep] lmapc[lear] loadkeymap lpf[ile] luafile mak[e] mk[exrc] mz[scheme] new nor ol[dfiles] p[rint] ped[it] pre[serve] promptf[ind] ptf[irst] ptr[ewind] py3do pythonx qa[ll] redi[r] ret[ab] ru[ntime] rv[iminfo] sIl sa[rgument] sb[uffer] sbn[ext] sce scr[iptnames] setf[iletype] sg sgl si sil[ent] sl[eep] smenu snoremenu spelld[ump] spr[evious] srg st[op] stj[ump] sunmenu syn tN[ext] tabd[o] tabm[ove] tabr[ewind] tclf[ile] tj[ump] tn[ext] try una[bbreviate] unlo[ckvar] verb[ose] vimgrepa[dd] wN[ext] winc[md] wq x[it] xnoreme xwininfo -syn keyword vimCommand contained al[l] argg[lobal] b[uffer] bl[ast] brea[k] buffers cabc[lear] cb[uffer] ce[nter] cgetb[uffer] chi[story] cn[ext] com cp[revious] cstag delc[ommand] deletp di[splay] diffs[plit] dli[st] dsp[lit] echom[sg] endf[unction] exi[t] filt[er] fo[ld] fu[nction] gvim helpt[ags] iabc[lear] intro k lN[ext] laddf[ile] lc[d] le[ft] lg[etfile] lhi[story] lne[xt] loc[kmarks] lr[ewind] lv[imgrep] marks mks[ession] mzf[ile] nmapc[lear] nore omapc[lear] pa[ckadd] perld[o] prev[ious] promptr[epl] ptj[ump] pts[elect] py[thon] pyx quita[ll] redr[aw] retu[rn] rub[y] sI sIn sal[l] sba[ll] sbp[revious] scg scripte[ncoding] setg[lobal] sgI sgn sic sim[alt] sla[st] smile so[urce] spelli[nfo] sr sri sta[g] stopi[nsert] sus[pend] sync ta[g] tabe[dit] tabn[ext] tabs te[aroff] tl[ast] tno[remap] ts[elect] undoj[oin] uns[ilent] vert[ical] viu[sage] w[rite] windo wqa[ll] xa[ll] xnoremenu y[ank] -syn keyword vimCommand contained ar[gs] argl[ocal] ba[ll] bm[odified] breaka[dd] bun[load] cad[dbuffer] cbo[ttom] cex[pr] cgete[xpr] cl[ist] cnew[er] comc[lear] cpf[ile] cuna[bbrev] delel delf[unction] dif[fupdate] difft[his] do e[dit] echon endfo[r] exu[sage] fin[d] foldc[lose] g h[elp] hi if is[earch] kee[pmarks] lNf[ile] lan[guage] lch[dir] lefta[bove] lgetb[uffer] ll lnew[er] lockv[ar] ls lvimgrepa[dd] mat[ch] mksp[ell] n[ext] +syn keyword vimCommand contained a ar[gs] argl[ocal] ba[ll] bm[odified] breaka[dd] bun[load] cabc[lear] cal[l] cc cf[ile] changes cla[st] cnf[ile] comc[lear] cp[revious] cstag debugg[reedy] deletl dep diffpu[t] dl dr[op] ec em[enu] ene[w] filet fir[st] foldo[pen] grepa[dd] helpf[ind] i imapc[lear] iuna[bbrev] keepalt la[st] lan[guage] lbo[ttom] ld[o] lfir[st] lh[elpgrep] lmak[e] loadk lp[revious] luado ma[rk] messages mod[e] nbs[tart] nor omapc[lear] packl[oadall] popu[p] profd[el] ptf[irst] pts[elect] pydo pyxfile red[o] res[ize] ru[ntime] sI sIp sav[eas] sbm[odified] sce scripte[ncoding] setg[lobal] sgc sgr sign sl[eep] smenu snoremenu spelld[ump] spr[evious] srg st[op] stj[ump] sunmenu syn tN[ext] tabd[o] tabm[ove] tabr[ewind] tch[dir] tf[irst] tlmenu tm[enu] to[pleft] tu[nmenu] undol[ist] up[date] vi[sual] vmapc[lear] wa[ll] winp[os] wundo xme xr[estore] +syn keyword vimCommand contained ab arga[dd] argu[ment] bad[d] bn[ext] breakd[el] bw[ipeout] cabo[ve] cat[ch] ccl[ose] cfdo chd[ir] cle[arjumps] cnor comp[iler] cpf[ile] cun delc[ommand] deletp di[splay] diffs[plit] dli[st] ds[earch] echoe[rr] en[dif] ex filetype fix[del] for gui helpg[rep] ia in j[oin] keepj[umps] lab[ove] lat lc[d] le[ft] lg[etfile] lhi[story] lmapc[lear] loadkeymap lpf[ile] luafile mak[e] mk[exrc] mz[scheme] new nore on[ly] pc[lose] pp[op] promptf[ind] ptj[ump] pu[t] pyf[ile] q[uit] redi[r] ret[ab] rub[y] sIc sIr sbN[ext] sbn[ext] scg scriptv[ersion] setl[ocal] sge sh[ell] sil[ent] sla[st] smile so[urce] spelli[nfo] sr sri sta[g] stopi[nsert] sus[pend] sync ta[g] tabe[dit] tabn[ext] tabs tcld[o] th[row] tln tma[p] tp[revious] tunma[p] unh[ide] v vie[w] vne[w] wh[ile] wn[ext] wv[iminfo] xmenu xunme +syn keyword vimCommand contained abc[lear] argd[elete] as[cii] bd[elete] bo[tright] breakl[ist] cN[ext] cad[dbuffer] cb[uffer] cd cfir[st] che[ckpath] clo[se] co[py] con[tinue] cq[uit] cuna[bbrev] delel delf[unction] dif[fupdate] difft[his] do dsp[lit] echom[sg] endf[unction] exi[t] filt[er] fo[ld] fu[nction] gvim helpt[ags] iabc[lear] inor ju[mps] keepp[atterns] lad[dexpr] later lch[dir] lefta[bove] lgetb[uffer] ll lne[xt] loc[kmarks] lr[ewind] lv[imgrep] marks mks[ession] mzf[ile] nmapc[lear] nos[wapfile] opt[ions] pe[rl] pre[serve] promptr[epl] ptl[ast] pw[d] python3 qa[ll] redr[aw] retu[rn] rubyd[o] sIe sN[ext] sb[uffer] sbp[revious] sci scs sf[ind] sgi si sim[alt] sm[agic] sn[ext] sor[t] spellr[epall] srI srl star[tinsert] sts[elect] sv[iew] syncbind tab tabf[ind] tabnew tags tclf[ile] tj[ump] tlnoremenu tmapc[lear] tr[ewind] u[ndo] unl ve[rsion] vim[grep] vs[plit] win[size] wp[revious] x[it] xnoreme xunmenu +syn keyword vimCommand contained abo[veleft] argdo au bel[owright] bp[revious] bro[wse] cNf[ile] cadde[xpr] cbe[fore] cdo cg[etfile] checkt[ime] cmapc[lear] col[der] conf[irm] cr[ewind] cw[indow] delep dell diffg[et] dig[raphs] doau e[dit] echon endfo[r] exu[sage] fin[d] foldc[lose] g h[elp] hi if intro k lN[ext] laddb[uffer] lb[uffer] lcl[ose] lex[pr] lgete[xpr] lla[st] lnew[er] lockv[ar] ls lvimgrepa[dd] mat[ch] mksp[ell] n[ext] noa nu[mber] ownsyntax ped[it] prev[ious] ps[earch] ptn[ext] py3 pythonx quita[ll] redraws[tatus] rew[ind] rubyf[ile] sIg sa[rgument] sba[ll] sbr[ewind] scl scscope sfir[st] sgl sic sin sm[ap] sno[magic] sp[lit] spellu[ndo] src srn startg[replace] sun[hide] sw[apname] syntime tabN[ext] tabfir[st] tabo[nly] tc[l] te[aroff] tl[ast] tlu tn[ext] try una[bbreviate] unlo[ckvar] verb[ose] vimgrepa[dd] wN[ext] winc[md] wq xa[ll] xnoremenu xwininfo +syn keyword vimCommand contained addd arge[dit] bN[ext] bf[irst] br[ewind] bufdo c[hange] caddf[ile] cbel[ow] ce[nter] cgetb[uffer] chi[story] cn[ext] colo[rscheme] cons[t] cs d[elete] deletel delm[arks] diffo[ff] dir doaut ea el[se] endt[ry] f[ile] fina[lly] foldd[oopen] go[to] ha[rdcopy] hid[e] ij[ump] is[earch] kee[pmarks] lNf[ile] laddf[ile] lbe[fore] lcs lf[ile] lgr[ep] lli[st] lnf[ile] lol[der] lt[ag] lw[indow] menut[ranslate] mkv[imrc] nb[key] noautocmd o[pen] p[rint] perld[o] pro ptN[ext] ptp[revious] py3do pyx r[ead] redrawt[abline] ri[ght] rundo sIl sal[l] sbf[irst] sc scp se[t] sg sgn sie sip sme snoreme spe[llgood] spellw[rong] sre[wind] srp startr[eplace] sunme sy t tabc[lose] tabl[ast] tabp[revious] tcd ter[minal] tlm tlunmenu tno[remap] ts[elect] undoj[oin] uns[ilent] vert[ical] viu[sage] w[rite] windo wqa[ll] xmapc[lear] xprop y[ank] +syn keyword vimCommand contained al[l] argg[lobal] b[uffer] bl[ast] brea[k] buffers ca caf[ter] cbo[ttom] cex[pr] cgete[xpr] cl[ist] cnew[er] com cope[n] cscope debug deletep delp diffp[atch] dj[ump] dp earlier elsei[f] endw[hile] files fini[sh] folddoc[losed] gr[ep] helpc[lose] his[tory] il[ist] isp[lit] keepa l[ist] laf[ter] lbel[ow] lcscope lfdo lgrepa[dd] lma lo[adview] lop[en] lua m[ove] mes mkvie[w] nbc[lose] noh[lsearch] ol[dfiles] pa[ckadd] po[p] prof[ile] pta[g] ptr[ewind] py[thon] pyxdo rec[over] reg[isters] rightb[elow] rv[iminfo] sIn san[dbox] sbl[ast] scI scr[iptnames] setf[iletype] sgI sgp sig sir syn match vimCommand contained "\" -syn keyword vimStdPlugin contained Arguments Break Clear Continue DiffOrig Evaluate Finish Gdb Man N[ext] Over P[rint] Program Run S Source Step Stop Termdebug TermdebugCommand TOhtml Winbar XMLent XMLns +syn keyword vimStdPlugin contained Arguments Break Cfilter Clear Continue DiffOrig Evaluate Finish Gdb Lfilter Man N[ext] Over P[rint] Program Run S Source Step Stop Termdebug TermdebugCommand TOhtml Winbar XMLent XMLns " vimOptions are caught only when contained in a vimSet {{{2 -syn keyword vimOption contained acd ambw arshape background ballooneval bex bl brk buftype cf cinkeys cmdwinheight com conceallevel crb cscopeverbose cuc def diffexpr ea ei ep eventignore fdi fenc fileformat fkmap foldexpr foldopen fsync gfw guicursor guitabtooltip hidden hlg imactivatefunc imi inc inex isident keymap langnoremap linespace loadplugins ma matchtime mef ml modeline mousefocus mousetime mzschemegcdll odev osfiletype patchexpr pexpr pmbfn printencoding prompt pythondll quoteescape remap rightleftcmd rtp sb scroll sections sh shellslash shm showmode siso smc spc spl ss statusline suffixesadd sws tabline tagrelative tbis termencoding textmode timeout tm ts ttybuiltin twk ul ur ve vif vts wd wic wildmode winheight wm wrapscan -syn keyword vimOption contained ai anti autochdir backspace balloonevalterm bexpr bo browsedir casemap cfu cino cmp comments confirm cryptmethod cspc cul define diffopt ead ek equalalways ex fdl fencs fileformats flp foldignore foldtext ft ghr guifont helpfile highlight hls imactivatekey iminsert include inf isk keymodel langremap lisp lpl macatsui maxcombine menc mls modelines mousehide mp nf oft pa patchmode pfn popt printexpr pt pythonhome rdt renderoptions rl ru sbo scrollbind secure shcf shelltemp shortmess showtabline sj smd spell splitbelow ssl stl sw sxe tabpagemax tags tbs termguicolors textwidth timeoutlen to tsl ttyfast tws undodir ut verbose viminfo wa weirdinvert wig wildoptions winminheight wmh write -syn keyword vimOption contained akm antialias autoindent backup balloonexpr bg bomb bs cb ch cinoptions cms commentstring copyindent cscopepathcomp csprg cursorbind delcombine digraph eadirection emo equalprg expandtab fdls fex fileignorecase fml foldlevel formatexpr gcr go guifontset helpheight history hlsearch imaf ims includeexpr infercase iskeyword keywordprg laststatus lispwords lrm magic maxfuncdepth menuitems mm modifiable mousem mps nrformats ofu packpath path ph pp printfont pumheight pythonthreedll re report rlc rubydll sbr scrolljump sel shell shelltype shortname shq slm sn spellcapcheck splitright ssop stmp swapfile sxq tabstop tagstack tc termwinkey tf title toolbar tsr ttym twsl undofile varsofttabstop verbosefile viminfofile wak wfh wildchar wim winminwidth wmnu writeany -syn keyword vimOption contained al ar autoread backupcopy bdir bh breakat bsdir cc charconvert cinw co compatible cot cscopeprg csqf cursorcolumn dex dip eb emoji errorbells exrc fdm ff filetype fmr foldlevelstart formatlistpat gd gp guifontwide helplang hk ic imak imsearch incsearch insertmode isp km lazyredraw list ls makeef maxmapdepth mfd mmd modified mousemodel msm nu omnifunc para pdev pheader preserveindent printheader pumwidth pythonthreehome readonly restorescreen rnu ruf sc scrolloff selection shellcmdflag shellxescape showbreak si sm so spellfile spr st sts swapsync syn tag tal tcldll termwinscroll tgc titlelen toolbariconsize ttimeout ttymouse tx undolevels vartabstop vfile virtualedit warn wfw wildcharm winaltkeys winptydll wmw writebackup -syn keyword vimOption contained aleph arab autowrite backupdir bdlay bin breakindent bsk ccv ci cinwords cocu complete cp cscopequickfix csre cursorline dg dir ed enc errorfile fcl fdn ffs fillchars fo foldmarker formatoptions gdefault grepformat guiheadroom hf hkmap icon imc imsf inde is isprint kmp lbr listchars lsp makeencoding maxmem mh mmp more mouses mzq number opendevice paragraphs penc pi previewheight printmbcharset pvh pyx redrawtime revins ro ruler scb scrollopt selectmode shellpipe shellxquote showcmd sidescroll smartcase softtabstop spelllang sps sta su swb synmaxcol tagbsearch tb tenc termwinsize tgst titleold top ttimeoutlen ttyscroll uc undoreload vb vi visualbell wb wh wildignore window winwidth wop writedelay -syn keyword vimOption contained allowrevins arabic autowriteall backupext belloff binary breakindentopt bt cd cin clipboard cole completefunc cpo cscoperelative cst cwh dict directory edcompatible encoding errorformat fcs fdo fic fixendofline foldclose foldmethod formatprg gfm grepprg guioptions hh hkmapp iconstring imcmdline imst indentexpr isf joinspaces kp lcs lm luadll makeprg maxmempattern mis mmt mouse mouseshape mzquantum numberwidth operatorfunc paste perldll pm previewwindow printmbfont pvw pyxversion regexpengine ri rop rulerformat scl scs sessionoptions shellquote shiftround showfulltag sidescrolloff smartindent sol spellsuggest sr stal sua swf syntax tagcase tbi term terse thesaurus titlestring tpm ttm ttytype udf updatecount vbs viewdir vop wc whichwrap wildignorecase winfixheight wiv wrap ws -syn keyword vimOption contained altkeymap arabicshape aw backupskip beval bk bri bufhidden cdpath cindent cm colorcolumn completeopt cpoptions cscopetag csto debug dictionary display ef endofline esckeys fdc fdt fileencoding fixeol foldcolumn foldminlines fp gfn gtl guipty hi hkp ignorecase imd imstatusfunc indentkeys isfname js langmap linebreak lmap lw mat maxmemtot mkspellmem mod mousef mouset mzschemedll nuw opfunc pastetoggle pex pmbcs printdevice printoptions pw qe relativenumber rightleft rs runtimepath scr sect sft shellredir shiftwidth showmatch signcolumn smarttab sp spf srr startofline suffixes switchbuf ta taglength tbidi termbidi textauto tildeop tl tr tty tw udir updatetime vdir viewoptions vsts wcm wi wildmenu winfixwidth wiw wrapmargin ww -syn keyword vimOption contained ambiwidth ari awa balloondelay bevalterm bkc briopt buflisted cedit cink cmdheight columns concealcursor cpt cscopetagorder csverb deco diff dy efm eol et fde fen fileencodings fk foldenable foldnestmax fs gfs gtt guitablabel hid hl im imdisable imstyle indk isi key langmenu lines lnr lz matchpairs mco +syn keyword vimOption contained acd ambw arshape background ballooneval bex bl brk buftype cf cinkeys cmdwinheight com conceallevel crb cscopeverbose cuc def diffexpr ea ei ep eventignore fdi fenc fileformat fkmap foldexpr foldopen fsync gfw guicursor guitabtooltip hidden hlg imactivatefunc imi inc inex isident keymap langnoremap linespace loadplugins ma matchtime mef mle modelineexpr mousehide mps nu opendevice paste pex pmbcs printdevice printoptions pw qe relativenumber rightleft rs runtimepath scr sect sft shellredir shiftwidth showmatch signcolumn smarttab sp spf srr startofline suffixes switchbuf ta tagfunc tbi term termwintype tgc titlelen toolbariconsize ttimeout ttymouse twt undofile varsofttabstop verbosefile viminfofile wak weirdinvert wig wildoptions winheight wm wrapscan +syn keyword vimOption contained ai anti autochdir backspace balloonevalterm bexpr bo browsedir casemap cfu cino cmp comments confirm cryptmethod cspc cul define diffopt ead ek equalalways ex fdl fencs fileformats flp foldignore foldtext ft ghr guifont helpfile highlight hls imactivatekey iminsert include inf isk keymodel langremap lisp lpl macatsui maxcombine menc mls modelines mousem msm number operatorfunc pastetoggle pexpr pmbfn printencoding prompt pythondll quoteescape remap rightleftcmd rtp sb scroll sections sh shellslash shm showmode siso smc spc spl ss statusline suffixesadd sws tabline taglength tbidi termbidi terse tgst titleold top ttimeoutlen ttyscroll tx undolevels vartabstop vfile virtualedit warn wfh wildchar wim winminheight wmh write +syn keyword vimOption contained akm antialias autoindent backup balloonexpr bg bomb bs cb ch cinoptions cms commentstring copyindent cscopepathcomp csprg cursorbind delcombine digraph eadirection emo equalprg expandtab fdls fex fileignorecase fml foldlevel formatexpr gcr go guifontset helpheight history hlsearch imaf ims includeexpr infercase iskeyword keywordprg laststatus lispwords lrm magic maxfuncdepth menuitems mm modifiable mousemodel mzq numberwidth opfunc patchexpr pfn popt printexpr pt pythonhome rdt renderoptions rl ru sbo scrollbind secure shcf shelltemp shortmess showtabline sj smd spell splitbelow ssl stl sw sxe tabpagemax tagrelative tbis termencoding textauto thesaurus titlestring tpm ttm ttytype uc undoreload vb vi visualbell wb wfw wildcharm winaltkeys winminwidth wmnu writeany +syn keyword vimOption contained al ar autoread backupcopy bdir bh breakat bsdir cc charconvert cinw co compatible cot cscopeprg csqf cursorcolumn dex dip eb emoji errorbells exrc fdm ff filetype fmr foldlevelstart formatlistpat gd gp guifontwide helplang hk ic imak imsearch incsearch insertmode isp km lazyredraw list ls makeef maxmapdepth mfd mmd modified mouses mzquantum nuw osfiletype patchmode ph pp printfont pumheight pythonthreedll re report rlc rubydll sbr scrolljump sel shell shelltype shortname shq slm sn spellcapcheck splitright ssop stmp swapfile sxq tabstop tags tbs termguicolors textmode tildeop tl tr tty tw udf updatecount vbs viewdir vop wc wh wildignore wincolor winptydll wmw writebackup +syn keyword vimOption contained aleph arab autowrite backupdir bdlay bin breakindent bsk ccv ci cinwords cocu complete cp cscopequickfix csre cursorline dg dir ed enc errorfile fcl fdn ffs fillchars fo foldmarker formatoptions gdefault grepformat guiheadroom hf hkmap icon imc imsf inde is isprint kmp lbr listchars lsp makeencoding maxmem mh mmp more mouseshape mzschemedll odev pa path pheader preserveindent printheader pumwidth pythonthreehome readonly restorescreen rnu ruf sc scrolloff selection shellcmdflag shellxescape showbreak si sm so spellfile spr st sts swapsync syn tag tagstack tc termwinkey textwidth timeout tm ts ttybuiltin twk udir updatetime vdir viewoptions vsts wcm whichwrap wildignorecase window winwidth wop writedelay +syn keyword vimOption contained allowrevins arabic autowriteall backupext belloff binary breakindentopt bt cd cin clipboard cole completefunc cpo cscoperelative cst cwh dict directory edcompatible encoding errorformat fcs fdo fic fixendofline foldclose foldmethod formatprg gfm grepprg guioptions hh hkmapp iconstring imcmdline imst indentexpr isf joinspaces kp lcs lm luadll makeprg maxmempattern mis mmt mouse mouset mzschemegcdll oft packpath pdev pi previewheight printmbcharset pvh pyx redrawtime revins ro ruler scb scrollopt selectmode shellpipe shellxquote showcmd sidescroll smartcase softtabstop spelllang sps sta su swb synmaxcol tagbsearch tal tcldll termwinscroll tf timeoutlen to tsl ttyfast tws ul ur ve vif vts wcr wi wildmenu winfixheight wiv wrap ws +syn keyword vimOption contained altkeymap arabicshape aw backupskip beval bk bri bufhidden cdpath cindent cm colorcolumn completeopt cpoptions cscopetag csto debug dictionary display ef endofline esckeys fdc fdt fileencoding fixeol foldcolumn foldminlines fp gfn gtl guipty hi hkp ignorecase imd imstatusfunc indentkeys isfname js langmap linebreak lmap lw mat maxmemtot mkspellmem mod mousef mousetime nf ofu para penc pm previewwindow printmbfont pvw pyxversion regexpengine ri rop rulerformat scl scs sessionoptions shellquote shiftround showfulltag sidescrolloff smartindent sol spellsuggest sr stal sua swf syntax tagcase tb tenc termwinsize tfu title toolbar tsr ttym twsl undodir ut verbose viminfo wa wd wic wildmode winfixwidth wiw wrapmargin ww +syn keyword vimOption contained ambiwidth ari awa balloondelay bevalterm bkc briopt buflisted cedit cink cmdheight columns concealcursor cpt cscopetagorder csverb deco diff dy efm eol et fde fen fileencodings fk foldenable foldnestmax fs gfs gtt guitablabel hid hl im imdisable imstyle indk isi key langmenu lines lnr lz matchpairs mco ml modeline mousefocus mp nrformats omnifunc paragraphs perldll " vimOptions: These are the turn-off setting variants {{{2 -syn keyword vimOption contained noacd noallowrevins noantialias noarabic noarshape noautoread noaw noballooneval nobevalterm nobk nobreakindent nocf nocindent nocopyindent nocscoperelative nocsre nocuc nocursorcolumn nodelcombine nodigraph noed noemo noeol noesckeys noexpandtab nofic nofixeol nofoldenable nogd nohid nohkmap nohls noicon noimc noimdisable noinfercase nojoinspaces nolangremap nolinebreak nolist noloadplugins nolrm noma nomagic noml nomodeline nomodified nomousef nomousehide nonumber noopendevice nopi nopreviewwindow nopvw norelativenumber norestorescreen nori norl noro noru nosb noscb noscs nosft noshelltemp noshortname noshowfulltag noshowmode nosm nosmartindent nosmd nosol nosplitbelow nospr nossl nostartofline noswapfile nota notagrelative notbi notbs noterse notextmode notgst notimeout noto notr nottybuiltin notx noundofile novisualbell nowarn noweirdinvert nowfw nowildignorecase nowinfixheight nowiv nowrap nowrite nowritebackup -syn keyword vimOption contained noai noaltkeymap noar noarabicshape noautochdir noautowrite noawa noballoonevalterm nobin nobl nobri noci nocompatible nocp nocscopetag nocst nocul nocursorline nodg noea noedcompatible noemoji noequalalways noet noexrc nofileignorecase nofk nofs nogdefault nohidden nohkmapp nohlsearch noignorecase noimcmdline noincsearch noinsertmode nojs nolazyredraw nolisp nolnr nolpl nolz nomacatsui nomh nomod nomodifiable nomore nomousefocus nonu noodev nopaste nopreserveindent noprompt noreadonly noremap norevins norightleft nornu nors noruler nosc noscrollbind nosecure noshellslash noshiftround noshowcmd noshowmatch nosi nosmartcase nosmarttab nosn nospell nosplitright nosr nosta nostmp noswf notagbsearch notagstack notbidi notermbidi notextauto notf notildeop notitle notop nottimeout nottyfast noudf novb nowa nowb nowfh nowic nowildmenu nowinfixwidth nowmnu nowrapscan nowriteany nows -syn keyword vimOption contained noakm noanti noarab noari noautoindent noautowriteall nobackup nobeval nobinary nobomb nobuflisted nocin noconfirm nocrb nocscopeverbose nocsverb nocursorbind nodeco nodiff noeb noek noendofline noerrorbells noex nofen nofixendofline nofkmap nofsync noguipty nohk nohkp noic noim noimd noinf nois nolangnoremap nolbr +syn keyword vimOption contained noacd noallowrevins noantialias noarabic noarshape noautoread noaw noballooneval nobevalterm nobk nobreakindent nocf nocindent nocopyindent nocscoperelative nocsre nocuc nocursorcolumn nodelcombine nodigraph noed noemo noeol noesckeys noexpandtab nofic nofixeol nofoldenable nogd nohid nohkmap nohls noicon noimc noimdisable noinfercase nojoinspaces nolangremap nolinebreak nolnr nolrm noma nomagic noml nomod nomodelineexpr nomodified nomousef nomousehide nonumber noopendevice nopi nopreviewwindow nopvw norelativenumber norestorescreen nori norl noro noru nosb noscb noscs nosft noshelltemp noshortname noshowfulltag noshowmode nosm nosmartindent nosmd nosol nosplitbelow nospr nossl nostartofline noswapfile nota notagrelative notbi notbs noterse notextmode notgst notimeout noto notr nottybuiltin notx noundofile novisualbell nowarn noweirdinvert nowfw nowildignorecase nowinfixheight nowiv nowrap nowrite nowritebackup +syn keyword vimOption contained noai noaltkeymap noar noarabicshape noautochdir noautowrite noawa noballoonevalterm nobin nobl nobri noci nocompatible nocp nocscopetag nocst nocul nocursorline nodg noea noedcompatible noemoji noequalalways noet noexrc nofileignorecase nofk nofs nogdefault nohidden nohkmapp nohlsearch noignorecase noimcmdline noincsearch noinsertmode nojs nolazyredraw nolisp noloadplugins nolz nomacatsui nomh nomle nomodeline nomodifiable nomore nomousefocus nonu noodev nopaste nopreserveindent noprompt noreadonly noremap norevins norightleft nornu nors noruler nosc noscrollbind nosecure noshellslash noshiftround noshowcmd noshowmatch nosi nosmartcase nosmarttab nosn nospell nosplitright nosr nosta nostmp noswf notagbsearch notagstack notbidi notermbidi notextauto notf notildeop notitle notop nottimeout nottyfast noudf novb nowa nowb nowfh nowic nowildmenu nowinfixwidth nowmnu nowrapscan nowriteany nows +syn keyword vimOption contained noakm noanti noarab noari noautoindent noautowriteall nobackup nobeval nobinary nobomb nobuflisted nocin noconfirm nocrb nocscopeverbose nocsverb nocursorbind nodeco nodiff noeb noek noendofline noerrorbells noex nofen nofixendofline nofkmap nofsync noguipty nohk nohkp noic noim noimd noinf nois nolangnoremap nolbr nolist nolpl " vimOptions: These are the invertible variants {{{2 -syn keyword vimOption contained invacd invallowrevins invantialias invarabic invarshape invautoread invaw invballooneval invbevalterm invbk invbreakindent invcf invcindent invcopyindent invcscoperelative invcsre invcuc invcursorcolumn invdelcombine invdigraph inved invemo inveol invesckeys invexpandtab invfic invfixeol invfoldenable invgd invhid invhkmap invhls invicon invimc invimdisable invinfercase invjoinspaces invlangremap invlinebreak invlist invloadplugins invlrm invma invmagic invml invmodeline invmodified invmousef invmousehide invnumber invopendevice invpi invpreviewwindow invpvw invrelativenumber invrestorescreen invri invrl invro invru invsb invscb invscs invsft invshelltemp invshortname invshowfulltag invshowmode invsm invsmartindent invsmd invsol invsplitbelow invspr invssl invstartofline invswapfile invta invtagrelative invtbi invtbs invterse invtextmode invtgst invtimeout invto invtr invttybuiltin invtx invundofile invvisualbell invwarn invweirdinvert invwfw invwildignorecase invwinfixheight invwiv invwrap invwrite invwritebackup -syn keyword vimOption contained invai invaltkeymap invar invarabicshape invautochdir invautowrite invawa invballoonevalterm invbin invbl invbri invci invcompatible invcp invcscopetag invcst invcul invcursorline invdg invea invedcompatible invemoji invequalalways invet invexrc invfileignorecase invfk invfs invgdefault invhidden invhkmapp invhlsearch invignorecase invimcmdline invincsearch invinsertmode invjs invlazyredraw invlisp invlnr invlpl invlz invmacatsui invmh invmod invmodifiable invmore invmousefocus invnu invodev invpaste invpreserveindent invprompt invreadonly invremap invrevins invrightleft invrnu invrs invruler invsc invscrollbind invsecure invshellslash invshiftround invshowcmd invshowmatch invsi invsmartcase invsmarttab invsn invspell invsplitright invsr invsta invstmp invswf invtagbsearch invtagstack invtbidi invtermbidi invtextauto invtf invtildeop invtitle invtop invttimeout invttyfast invudf invvb invwa invwb invwfh invwic invwildmenu invwinfixwidth invwmnu invwrapscan invwriteany invws -syn keyword vimOption contained invakm invanti invarab invari invautoindent invautowriteall invbackup invbeval invbinary invbomb invbuflisted invcin invconfirm invcrb invcscopeverbose invcsverb invcursorbind invdeco invdiff inveb invek invendofline inverrorbells invex invfen invfixendofline invfkmap invfsync invguipty invhk invhkp invic invim invimd invinf invis invlangnoremap invlbr +syn keyword vimOption contained invacd invallowrevins invantialias invarabic invarshape invautoread invaw invballooneval invbevalterm invbk invbreakindent invcf invcindent invcopyindent invcscoperelative invcsre invcuc invcursorcolumn invdelcombine invdigraph inved invemo inveol invesckeys invexpandtab invfic invfixeol invfoldenable invgd invhid invhkmap invhls invicon invimc invimdisable invinfercase invjoinspaces invlangremap invlinebreak invlnr invlrm invma invmagic invml invmod invmodelineexpr invmodified invmousef invmousehide invnumber invopendevice invpi invpreviewwindow invpvw invrelativenumber invrestorescreen invri invrl invro invru invsb invscb invscs invsft invshelltemp invshortname invshowfulltag invshowmode invsm invsmartindent invsmd invsol invsplitbelow invspr invssl invstartofline invswapfile invta invtagrelative invtbi invtbs invterse invtextmode invtgst invtimeout invto invtr invttybuiltin invtx invundofile invvisualbell invwarn invweirdinvert invwfw invwildignorecase invwinfixheight invwiv invwrap invwrite invwritebackup +syn keyword vimOption contained invai invaltkeymap invar invarabicshape invautochdir invautowrite invawa invballoonevalterm invbin invbl invbri invci invcompatible invcp invcscopetag invcst invcul invcursorline invdg invea invedcompatible invemoji invequalalways invet invexrc invfileignorecase invfk invfs invgdefault invhidden invhkmapp invhlsearch invignorecase invimcmdline invincsearch invinsertmode invjs invlazyredraw invlisp invloadplugins invlz invmacatsui invmh invmle invmodeline invmodifiable invmore invmousefocus invnu invodev invpaste invpreserveindent invprompt invreadonly invremap invrevins invrightleft invrnu invrs invruler invsc invscrollbind invsecure invshellslash invshiftround invshowcmd invshowmatch invsi invsmartcase invsmarttab invsn invspell invsplitright invsr invsta invstmp invswf invtagbsearch invtagstack invtbidi invtermbidi invtextauto invtf invtildeop invtitle invtop invttimeout invttyfast invudf invvb invwa invwb invwfh invwic invwildmenu invwinfixwidth invwmnu invwrapscan invwriteany invws +syn keyword vimOption contained invakm invanti invarab invari invautoindent invautowriteall invbackup invbeval invbinary invbomb invbuflisted invcin invconfirm invcrb invcscopeverbose invcsverb invcursorbind invdeco invdiff inveb invek invendofline inverrorbells invex invfen invfixendofline invfkmap invfsync invguipty invhk invhkp invic invim invimd invinf invis invlangnoremap invlbr invlist invlpl " termcap codes (which can also be set) {{{2 -syn keyword vimOption contained t_8b t_AB t_al t_bc t_BE t_ce t_cl t_Co t_Cs t_CV t_db t_DL t_EI t_F2 t_F4 t_F6 t_F8 t_fs t_IE t_k1 t_k2 t_K3 t_K4 t_K5 t_K6 t_K7 t_k8 t_K8 t_k9 t_K9 t_KA t_kb t_kB t_KB t_KC t_kd t_kD t_KD t_ke t_KE t_KF t_KG t_kh t_KH t_kI t_KI t_KJ t_KK t_kl t_KL t_kN t_kP t_kr t_ks t_ku t_le t_mb t_md t_me t_mr t_ms t_nd t_op t_PE t_PS t_RB t_RC t_RF t_RI t_RS t_RV t_Sb t_SC t_se t_Sf t_SH t_SI t_so t_sr t_SR t_te t_Te t_ti t_ts t_Ts t_u7 t_ue t_us t_ut t_vb t_ve t_vi t_vs t_VS t_WP t_WS t_xn t_xs t_ZH t_ZR -syn keyword vimOption contained t_8f t_AF t_AL t_BD t_cd t_Ce t_cm t_cs t_CS t_da t_dl t_EC t_F1 t_F3 t_F5 t_F7 t_F9 t_GP t_IS t_K1 t_k3 t_k4 t_k5 t_k6 t_k7 +syn keyword vimOption contained t_8b t_AB t_al t_bc t_BE t_ce t_cl t_Co t_Cs t_CV t_db t_DL t_EI t_F2 t_F4 t_F6 t_F8 t_fs t_IE t_k1 t_k2 t_K3 t_K4 t_K5 t_K6 t_K7 t_K8 t_K9 t_kb t_KB t_KC t_kd t_kD t_KD t_ke t_KE t_KF t_KG t_kh t_KH t_kI t_KI t_KJ t_KK t_kl t_KL t_kN t_kP t_kr t_ks t_ku t_le t_mb t_md t_me t_mr t_ms t_nd t_op t_PE t_PS t_RB t_RC t_RF t_Ri t_RI t_RS t_RT t_RV t_Sb t_SC t_se t_Sf t_SH t_Si t_SI t_so t_sr t_SR t_ST t_te t_Te t_ti t_ts t_Ts t_u7 t_ue t_us t_ut t_vb t_ve t_vi t_vs t_VS t_WP t_WS t_xn t_xs t_ZH t_ZR +syn keyword vimOption contained t_8f t_AF t_AL t_BD t_cd t_Ce t_cm t_cs t_CS t_da t_dl t_EC t_F1 t_F3 t_F5 t_F7 t_F9 t_GP t_IS t_K1 t_k3 t_k4 t_k5 t_k6 t_k7 t_k8 t_k9 t_KA t_kB syn match vimOption contained "t_%1" syn match vimOption contained "t_#2" syn match vimOption contained "t_#4" @@ -66,7 +66,8 @@ " AutoCmd Events {{{2 syn case ignore -syn keyword vimAutoEvent contained BufAdd BufCreate BufDelete BufEnter BufFilePost BufFilePre BufHidden BufLeave BufNew BufNewFile BufRead BufReadCmd BufReadPost BufReadPre BufUnload BufWinEnter BufWinLeave BufWipeout BufWrite BufWriteCmd BufWritePost BufWritePre CmdlineChanged CmdlineEnter CmdlineLeave CmdUndefined CmdwinEnter CmdwinLeave ColorScheme ColorSchemePre CompleteDone CursorHold CursorHoldI CursorMoved CursorMovedI DirChanged EncodingChanged ExitPre FileAppendCmd FileAppendPost FileAppendPre FileChangedRO FileChangedShell FileChangedShellPost FileEncoding FileReadCmd FileReadPost FileReadPre FileType FileWriteCmd FileWritePost FileWritePre FilterReadPost FilterReadPre FilterWritePost FilterWritePre FocusGained FocusLost FuncUndefined GUIEnter GUIFailed InsertChange InsertCharPre InsertEnter InsertLeave MenuPopup OptionSet QuickFixCmdPost QuickFixCmdPre QuitPre RemoteReply SessionLoadPost ShellCmdPost ShellFilterPost SourceCmd SourcePre SpellFileMissing StdinReadPost StdinReadPre SwapExists Syntax TabClosed TabEnter TabLeave TabNew TermChanged TerminalOpen TermResponse TextChanged TextChangedI TextChangedP TextYankPost User VimEnter VimLeave VimLeavePre VimResized WinEnter WinLeave WinNew +syn keyword vimAutoEvent contained BufAdd BufDelete BufFilePost BufHidden BufLeave BufNew BufNewFile BufRead BufReadCmd BufReadPost BufReadPre BufUnload BufWinEnter BufWinLeave BufWipeout BufWrite BufWriteCmd BufWritePost BufWritePre CmdlineChanged CmdlineEnter CmdlineLeave CmdUndefined CmdwinEnter CmdwinLeave ColorScheme ColorSchemePre CompleteChanged CompleteDone CursorHold CursorHoldI CursorMoved CursorMovedI DiffUpdated DirChanged EncodingChanged ExitPre FileAppendCmd FileAppendPost FileAppendPre FileChangedRO FileChangedShell FileChangedShellPost FileEncoding FileReadCmd FileReadPost FileReadPre FileType FileWriteCmd FileWritePost FileWritePre FilterReadPost FilterReadPre FilterWritePost FilterWritePre FocusGained FocusLost FuncUndefined GUIEnter GUIFailed InsertChange InsertCharPre InsertEnter InsertLeave MenuPopup OptionSet QuickFixCmdPost QuickFixCmdPre QuitPre RemoteReply SessionLoadPost ShellCmdPost ShellFilterPost SourceCmd SourcePost SourcePre SpellFileMissing StdinReadPost StdinReadPre SwapExists Syntax TabClosed TabEnter TabLeave TabNew TermChanged TerminalOpen TermResponse TextChanged TextChangedI TextChangedP TextYankPost User VimEnter VimLeave VimLeavePre VimResized WinEnter WinLeave WinNew +syn keyword vimAutoEvent contained BufCreate BufEnter BufFilePre " Highlight commonly used Groupnames {{{2 syn keyword vimGroup contained Comment Constant String Character Number Boolean Float Identifier Function Statement Conditional Repeat Label Operator Keyword Exception PreProc Include Define Macro PreCondit Type StorageClass Structure Typedef Special SpecialChar Tag Delimiter SpecialComment Debug Underlined Ignore Error Todo @@ -77,10 +78,11 @@ syn case match " Function Names {{{2 -syn keyword vimFuncName contained abs append arglistid assert_equal assert_false assert_notmatch atan2 browsedir bufname byte2line ceil ch_close ch_getbufnr ch_logfile ch_sendexpr cindent complete_add cos cursor deletebufline empty executable exp filereadable findfile fnameescape foldlevel funcref getbufinfo getchar getcmdpos getcurpos getfsize getline getpos gettabinfo getwinpos glob has_key histdel hlID index inputrestore invert items job_start js_decode keys line log maparg matchaddpos matchlist min nextnonblank perleval prompt_addtext pumvisible range reltime remote_foreground remote_startserver resolve screenchar searchdecl server2client setcharsearch setloclist setreg sha256 sin spellbadword str2float strdisplaywidth string strtrans synconcealed synstack tabpagenr tan term_dumpload term_getattr term_getscrolled term_gettty term_setansicolors term_start test_feedinput test_null_dict test_null_string timer_pause tolower trunc undotree virtcol winbufnr win_getid win_id2tabwin winnr winsaveview wordcount -syn keyword vimFuncName contained acos appendbufline argv assert_equalfile assert_inrange assert_report balloon_show bufexists bufnr byteidx changenr ch_close_in ch_getjob ch_open ch_sendraw clearmatches complete_check cosh debugbreak did_filetype escape execute expand filewritable float2nr fnamemodify foldtext function getbufline getcharmod getcmdtype getcwd getftime getloclist getqflist gettabvar getwinposx glob2regpat haslocaldir histget hostname input inputsave isdirectory job_getchannel job_status js_encode len line2byte log10 mapcheck matcharg matchstr mkdir nr2char pow prompt_setcallback py3eval readfile reltimefloat remote_peek remove reverse screencol searchpair serverlist setcmdpos setmatches settabvar shellescape sinh spellsuggest str2nr strftime strlen strwidth synID system tabpagewinnr tanh term_dumpwrite term_getcursor term_getsize term_list term_setkill term_wait test_garbagecollect_now test_null_job test_override timer_start toupper type uniq visualmode wincol win_gotoid win_id2win winrestcmd win_screenpos writefile -syn keyword vimFuncName contained add argc asin assert_exception assert_match assert_true balloon_split buflisted bufwinid byteidxcomp char2nr ch_evalexpr ch_info ch_read ch_setoptions col confirm count deepcopy diff_filler eval exepath extend filter floor foldclosed foldtextresult garbagecollect getbufvar getcharsearch getcmdwintype getfontname getftype getmatches getreg gettabwinvar getwinposy globpath hasmapto histnr iconv inputdialog inputsecret islocked job_info job_stop json_decode libcall lispindent luaeval match matchdelete matchstrpos mode or prevnonblank prompt_setinterrupt pyeval reg_executing reltimestr remote_read rename round screenrow searchpairpos setbufline setfperm setpos settabwinvar shiftwidth sort split strcharpart strgetchar strpart submatch synIDattr systemlist tagfiles tempname term_getaltscreen term_getjob term_getstatus term_scrape term_setrestore test_alloc_fail test_ignore_error test_null_list test_settime timer_stop tr undofile values wildmenumode win_findbuf winheight winline winrestview winwidth xor -syn keyword vimFuncName contained and argidx assert_beeps assert_fails assert_notequal atan browse bufloaded bufwinnr call ch_canread ch_evalraw ch_log ch_readraw ch_status complete copy cscope_connection delete diff_hlID eventhandler exists feedkeys finddir fmod foldclosedend foreground get getchangelist getcmdline getcompletion getfperm getjumplist getpid getregtype getwininfo getwinvar has histadd hlexists indent inputlist insert isnan job_setoptions join json_encode libcallnr localtime map matchadd matchend max mzeval pathshorten printf prompt_setprompt pyxeval reg_recording remote_expr remote_send repeat screenattr search searchpos setbufvar setline setqflist setwinvar simplify soundfold sqrt strchars stridx strridx substitute synIDtrans tabpagebuflist taglist term_dumpdiff term_getansicolors term_getline term_gettitle term_sendkeys term_setsize test_autochdir test_null_channel test_null_partial timer_info timer_stopall trim +syn keyword vimFuncName contained abs appendbufline asin assert_fails assert_notmatch balloon_gettext bufadd bufname byteidx char2nr ch_evalexpr ch_log ch_readraw cindent complete_check cosh deepcopy diff_hlID eventhandler exp filereadable float2nr foldclosed foreground getbufinfo getcharmod getcmdwintype getfontname getjumplist getpos gettabvar getwinposx globpath histadd hlID input inputsecret islocked job_setoptions js_decode len lispindent localtime maparg matcharg matchstrpos mzeval perleval popup_create popup_getpos popup_setoptions printf prop_clear prop_type_change py3eval readfile reltimestr remote_send resolve screenchar screenstring searchpos setcharsearch setloclist settabvar sha256 sign_getdefined sign_placelist simplify sound_clear sound_stop sqrt strcharpart strgetchar strpart submatch synconcealed synstack tabpagenr tan term_dumpload term_getattr term_getscrolled term_gettty term_setansicolors term_start test_feedinput test_ignore_error test_null_job test_option_not_set test_setmouse timer_start toupper type values winbufnr win_getid win_id2win winrestcmd winwidth +syn keyword vimFuncName contained acos argc assert_beeps assert_false assert_report balloon_show bufexists bufnr byteidxcomp ch_canread ch_evalraw ch_logfile ch_sendexpr clearmatches complete_info count delete empty executable expand filewritable floor foldclosedend funcref getbufline getcharsearch getcompletion getfperm getline getqflist gettabwinvar getwinposy has histdel hostname inputdialog insert isnan job_start js_encode libcall list2str log mapcheck matchdelete max nextnonblank popup_atcursor popup_dialog popup_hide popup_settext prompt_setcallback prop_find prop_type_delete pyeval reg_executing remote_expr remote_startserver reverse screenchars search server2client setcmdpos setmatches settabwinvar shellescape sign_getplaced sign_undefine sin soundfold spellbadword str2float strchars stridx strridx substitute synID system tabpagewinnr tanh term_dumpwrite term_getcursor term_getsize term_list term_setkill term_wait test_garbagecollect_now test_null_blob test_null_list test_override test_settime timer_stop tr undofile virtcol wincol win_gotoid winlayout winrestview wordcount +syn keyword vimFuncName contained add argidx assert_equal assert_inrange assert_true balloon_split buflisted bufwinid call ch_close ch_getbufnr ch_open ch_sendraw col confirm cscope_connection deletebufline environ execute expandcmd filter fmod foldlevel function getbufvar getcmdline getcurpos getfsize getloclist getreg gettagstack getwinvar has_key histget iconv inputlist invert items job_status json_decode libcallnr listener_add log10 match matchend min nr2char popup_beval popup_filter_menu popup_menu popup_show prompt_setinterrupt prop_list prop_type_get pyxeval reg_recording remote_foreground remove round screencol searchdecl serverlist setenv setpos settagstack shiftwidth sign_jump sign_unplace sinh sound_playevent spellsuggest str2list strdisplaywidth string strtrans swapinfo synIDattr systemlist tagfiles tempname term_getaltscreen term_getjob term_getstatus term_scrape term_setrestore test_alloc_fail test_garbagecollect_soon test_null_channel test_null_partial test_refcount timer_info timer_stopall trim undotree visualmode win_execute winheight winline winsaveview writefile +syn keyword vimFuncName contained and arglistid assert_equalfile assert_match atan browse bufload bufwinnr ceil ch_close_in ch_getjob ch_read ch_setoptions complete copy cursor did_filetype escape exepath extend finddir fnameescape foldtext garbagecollect getchangelist getcmdpos getcwd getftime getmatches getregtype getwininfo glob haslocaldir histnr indent inputrestore isdirectory job_getchannel job_stop json_encode line listener_flush luaeval matchadd matchlist mkdir or popup_clear popup_filter_yesno popup_move pow prompt_setprompt prop_remove prop_type_list range reltime remote_peek rename rubyeval screenpos searchpair setbufline setfperm setqflist setwinvar sign_define sign_place sign_unplacelist sort sound_playfile split str2nr strftime strlen strwidth swapname synIDtrans tabpagebuflist taglist term_dumpdiff term_getansicolors term_getline term_gettitle term_sendkeys term_setsize test_autochdir test_getvalue test_null_dict test_null_string test_scrollbar timer_pause tolower trunc uniq wildmenumode win_findbuf win_id2tabwin winnr win_screenpos xor +syn keyword vimFuncName contained append argv assert_exception assert_notequal atan2 browsedir bufloaded byte2line changenr chdir ch_info ch_readblob ch_status complete_add cos debugbreak diff_filler eval exists feedkeys findfile fnamemodify foldtextresult get getchar getcmdtype getenv getftype getpid gettabinfo getwinpos glob2regpat hasmapto hlexists index inputsave isinf job_info join keys line2byte listener_remove map matchaddpos matchstr mode pathshorten popup_close popup_getoptions popup_notification prevnonblank prop_add prop_type_add pumvisible readdir reltimefloat remote_read repeat screenattr screenrow searchpairpos setbufvar setline setreg "--- syntax here and above generated by mkvimvim --- " Special Vim Highlighting (not automatic) {{{1 @@ -393,9 +395,9 @@ " Maps {{{2 " ==== syn match vimMap "\!\=\ze\s*[^(]" skipwhite nextgroup=vimMapMod,vimMapLhs -syn keyword vimMap cm[ap] cno[remap] im[ap] ino[remap] lm[ap] ln[oremap] nm[ap] nn[oremap] no[remap] om[ap] ono[remap] smap snor[emap] vm[ap] vn[oremap] xm[ap] xn[oremap] skipwhite nextgroup=vimMapBang,vimMapMod,vimMapLhs +syn keyword vimMap cm[ap] cno[remap] im[ap] ino[remap] lm[ap] ln[oremap] nm[ap] nn[oremap] no[remap] om[ap] ono[remap] smap snor[emap] tno[remap] tm[ap] vm[ap] vn[oremap] xm[ap] xn[oremap] skipwhite nextgroup=vimMapBang,vimMapMod,vimMapLhs syn keyword vimMap mapc[lear] smapc[lear] -syn keyword vimUnmap cu[nmap] iu[nmap] lu[nmap] nun[map] ou[nmap] sunm[ap] unm[ap] unm[ap] vu[nmap] xu[nmap] skipwhite nextgroup=vimMapBang,vimMapMod,vimMapLhs +syn keyword vimUnmap cu[nmap] iu[nmap] lu[nmap] nun[map] ou[nmap] sunm[ap] tunma[p] unm[ap] unm[ap] vu[nmap] xu[nmap] skipwhite nextgroup=vimMapBang,vimMapMod,vimMapLhs syn match vimMapLhs contained "\S\+" contains=vimNotation,vimCtrlChar skipwhite nextgroup=vimMapRhs syn match vimMapBang contained "!" skipwhite nextgroup=vimMapMod,vimMapLhs syn match vimMapMod contained "\%#=1\c<\(buffer\|expr\|\(local\)\=leader\|nowait\|plug\|script\|sid\|unique\|silent\)\+>" contains=vimMapModKey,vimMapModErr skipwhite nextgroup=vimMapMod,vimMapLhs diff -Nru vim-8.1.1681/runtime/syntax/vuejs.vim vim-8.1.1729/runtime/syntax/vuejs.vim --- vim-8.1.1681/runtime/syntax/vuejs.vim 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/runtime/syntax/vuejs.vim 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,14 @@ +" Vim syntax file +" Language: Vue.js Single File Component +" Maintainer: Ralph Giles +" URL: https://vuejs.org/v2/guide/single-file-components.html +" Last Change: 2019 Jul 8 + +" Quit if a syntax file was already loaded. +if exists("b:current_syntax") + finish +endif + +" We have a collection of html, css and javascript wrapped in +" tags. The default HTML syntax highlight works well enough. +runtime! syntax/html.vim diff -Nru vim-8.1.1681/runtime/tutor/README.txt vim-8.1.1729/runtime/tutor/README.txt --- vim-8.1.1681/runtime/tutor/README.txt 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/runtime/tutor/README.txt 2019-07-21 21:04:21.000000000 +0000 @@ -24,7 +24,7 @@ ----------- The tutor.xx and tutor.xx.utf-8 files are translated files (where xx is the -langage code). The encoding of tutor.xx might be latin1 or other traditional +language code). The encoding of tutor.xx might be latin1 or other traditional encoding. If you don't need a translation with such traditional encoding, you just need to prepare the tutor.xx.utf-8 file. If you need another encoding, you can also prepare a file named tutor.xx.enc diff -Nru vim-8.1.1681/src/beval.c vim-8.1.1729/src/beval.c --- vim-8.1.1681/src/beval.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/beval.c 2019-07-21 21:04:21.000000000 +0000 @@ -10,7 +10,7 @@ #include "vim.h" -#if defined(FEAT_BEVAL) || defined(FEAT_TEXT_PROP) || defined(PROT) +#if defined(FEAT_BEVAL) || defined(FEAT_TEXT_PROP) || defined(PROTO) /* * Find text under the mouse position "row" / "col". * If "getword" is TRUE the returned text in "*textp" is not the whole line but @@ -72,6 +72,7 @@ } col = vcol2col(wp, lnum, col); + scol = col; if (VIsual_active && wp->w_buffer == curwin->w_buffer @@ -95,6 +96,7 @@ lbuf = vim_strnsave(lbuf + spos->col, len); lnum = spos->lnum; col = spos->col; + scol = col; } else { diff -Nru vim-8.1.1681/src/buffer.c vim-8.1.1729/src/buffer.c --- vim-8.1.1681/src/buffer.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/buffer.c 2019-07-21 21:04:21.000000000 +0000 @@ -29,7 +29,6 @@ static char_u *buflist_match(regmatch_T *rmp, buf_T *buf, int ignore_case); static char_u *fname_match(regmatch_T *rmp, char_u *name, int ignore_case); -static void buflist_setfpos(buf_T *buf, win_T *win, linenr_T lnum, colnr_T col, int copy_options); #ifdef UNIX static buf_T *buflist_findname_stat(char_u *ffname, stat_T *st); static int otherfile_buf(buf_T *buf, char_u *ffname, stat_T *stp); @@ -449,7 +448,8 @@ } } if (!can_unload) - emsg(_("E937: Attempt to delete a buffer that is in use")); + semsg(_("E937: Attempt to delete a buffer that is in use: %s"), + buf->b_fname); return can_unload; } @@ -2774,7 +2774,7 @@ * When "copy_options" is TRUE save the local window option values. * When "lnum" is 0 only do the options. */ - static void + void buflist_setfpos( buf_T *buf, win_T *win, @@ -5545,112 +5545,6 @@ return retval; } -#if defined(FEAT_VIMINFO) || defined(PROTO) - int -read_viminfo_bufferlist( - vir_T *virp, - int writing) -{ - char_u *tab; - linenr_T lnum; - colnr_T col; - buf_T *buf; - char_u *sfname; - char_u *xline; - - /* Handle long line and escaped characters. */ - xline = viminfo_readstring(virp, 1, FALSE); - - /* don't read in if there are files on the command-line or if writing: */ - if (xline != NULL && !writing && ARGCOUNT == 0 - && find_viminfo_parameter('%') != NULL) - { - /* Format is: Tab Tab . - * Watch out for a Tab in the file name, work from the end. */ - lnum = 0; - col = 0; - tab = vim_strrchr(xline, '\t'); - if (tab != NULL) - { - *tab++ = '\0'; - col = (colnr_T)atoi((char *)tab); - tab = vim_strrchr(xline, '\t'); - if (tab != NULL) - { - *tab++ = '\0'; - lnum = atol((char *)tab); - } - } - - /* Expand "~/" in the file name at "line + 1" to a full path. - * Then try shortening it by comparing with the current directory */ - expand_env(xline, NameBuff, MAXPATHL); - sfname = shorten_fname1(NameBuff); - - buf = buflist_new(NameBuff, sfname, (linenr_T)0, BLN_LISTED); - if (buf != NULL) /* just in case... */ - { - buf->b_last_cursor.lnum = lnum; - buf->b_last_cursor.col = col; - buflist_setfpos(buf, curwin, lnum, col, FALSE); - } - } - vim_free(xline); - - return viminfo_readline(virp); -} - - void -write_viminfo_bufferlist(FILE *fp) -{ - buf_T *buf; - win_T *win; - tabpage_T *tp; - char_u *line; - int max_buffers; - - if (find_viminfo_parameter('%') == NULL) - return; - - /* Without a number -1 is returned: do all buffers. */ - max_buffers = get_viminfo_parameter('%'); - - /* Allocate room for the file name, lnum and col. */ -#define LINE_BUF_LEN (MAXPATHL + 40) - line = alloc(LINE_BUF_LEN); - if (line == NULL) - return; - - FOR_ALL_TAB_WINDOWS(tp, win) - set_last_cursor(win); - - fputs(_("\n# Buffer list:\n"), fp); - FOR_ALL_BUFFERS(buf) - { - if (buf->b_fname == NULL - || !buf->b_p_bl -#ifdef FEAT_QUICKFIX - || bt_quickfix(buf) -#endif -#ifdef FEAT_TERMINAL - || bt_terminal(buf) -#endif - || removable(buf->b_ffname)) - continue; - - if (max_buffers-- == 0) - break; - putc('%', fp); - home_replace(NULL, buf->b_ffname, line, MAXPATHL, TRUE); - vim_snprintf_add((char *)line, LINE_BUF_LEN, "\t%ld\t%d", - (long)buf->b_last_cursor.lnum, - buf->b_last_cursor.col); - viminfo_writestring(fp, line); - } - vim_free(line); -} -#endif - /* * Return TRUE if "buf" is a normal buffer, 'buftype' is empty. */ diff -Nru vim-8.1.1681/src/change.c vim-8.1.1729/src/change.c --- vim-8.1.1681/src/change.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/change.c 2019-07-21 21:04:21.000000000 +0000 @@ -155,19 +155,16 @@ static long next_listener_id = 0; /* - * Check if the change at "lnum" / "col" is above or overlaps with an existing - * changed. If above then flush changes and invoke listeners. - * If "merge" is TRUE do the merge. + * Check if the change at "lnum" is above or overlaps with an existing + * change. If above then flush changes and invoke listeners. * Returns TRUE if the change was merged. */ static int check_recorded_changes( buf_T *buf, linenr_T lnum, - colnr_T col, linenr_T lnume, - long xtra, - int merge) + long xtra) { if (buf->b_recorded_changes != NULL && xtra != 0) { @@ -182,42 +179,12 @@ li->li_tv.vval.v_dict, (char_u *)"lnum"); prev_lnume = (linenr_T)dict_get_number( li->li_tv.vval.v_dict, (char_u *)"end"); - if (prev_lnum >= lnum || prev_lnum > lnume - || (prev_lnume >= lnum && xtra != 0)) + if (prev_lnum >= lnum || prev_lnum > lnume || prev_lnume >= lnum) { - if (li->li_next == NULL && lnum == prev_lnum - && xtra == 0 - && col + 1 == (colnr_T)dict_get_number( - li->li_tv.vval.v_dict, (char_u *)"col")) - { - if (merge) - { - dictitem_T *di; - - // Same start point and nothing is following, entries - // can be merged. - di = dict_find(li->li_tv.vval.v_dict, - (char_u *)"end", -1); - if (di != NULL) - { - prev_lnum = tv_get_number(&di->di_tv); - if (lnume > prev_lnum) - di->di_tv.vval.v_number = lnume; - } - di = dict_find(li->li_tv.vval.v_dict, - (char_u *)"added", -1); - if (di != NULL) - di->di_tv.vval.v_number += xtra; - return TRUE; - } - } - else - { - // the current change is going to make the line number in - // the older change invalid, flush now - invoke_listeners(curbuf); - break; - } + // the current change is going to make the line number in + // the older change invalid, flush now + invoke_listeners(curbuf); + break; } } } @@ -242,7 +209,7 @@ // If the new change is going to change the line numbers in already listed // changes, then flush. - if (check_recorded_changes(curbuf, lnum, col, lnume, xtra, TRUE)) + if (check_recorded_changes(curbuf, lnum, lnume, xtra)) return; if (curbuf->b_recorded_changes == NULL) @@ -362,7 +329,7 @@ void may_invoke_listeners(buf_T *buf, linenr_T lnum, linenr_T lnume, int added) { - check_recorded_changes(buf, lnum, 0, lnume, added, FALSE); + check_recorded_changes(buf, lnum, lnume, added); } /* diff -Nru vim-8.1.1681/src/dict.c vim-8.1.1729/src/dict.c --- vim-8.1.1681/src/dict.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/dict.c 2019-07-21 21:04:21.000000000 +0000 @@ -709,11 +709,33 @@ } /* + * Get the key for *{key: val} into "tv" and advance "arg". + * Return FAIL when there is no valid key. + */ + static int +get_literal_key(char_u **arg, typval_T *tv) +{ + char_u *p; + + if (!ASCII_ISALNUM(**arg) && **arg != '_' && **arg != '-') + return FAIL; + + for (p = *arg; ASCII_ISALNUM(*p) || *p == '_' || *p == '-'; ++p) + ; + tv->v_type = VAR_STRING; + tv->vval.v_string = vim_strnsave(*arg, (int)(p - *arg)); + + *arg = skipwhite(p); + return OK; +} + +/* * Allocate a variable for a Dictionary and fill it from "*arg". + * "literal" is TRUE for *{key: val} * Return OK or FAIL. Returns NOTDONE for {expr}. */ int -dict_get_tv(char_u **arg, typval_T *rettv, int evaluate) +dict_get_tv(char_u **arg, typval_T *rettv, int evaluate, int literal) { dict_T *d = NULL; typval_T tvkey; @@ -750,8 +772,11 @@ *arg = skipwhite(*arg + 1); while (**arg != '}' && **arg != NUL) { - if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ + if ((literal + ? get_literal_key(arg, &tvkey) + : eval1(arg, &tvkey, evaluate)) == FAIL) // recursive! goto failret; + if (**arg != ':') { semsg(_("E720: Missing colon in Dictionary: %s"), *arg); diff -Nru vim-8.1.1681/src/eval.c vim-8.1.1729/src/eval.c --- vim-8.1.1681/src/eval.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/eval.c 2019-07-21 21:04:21.000000000 +0000 @@ -36,7 +36,6 @@ #define NAMESPACE_CHAR (char_u *)"abglstvw" static dictitem_T globvars_var; /* variable used for g: */ -#define globvarht globvardict.dv_hashtab /* * Old Vim variables such as "v:version" are also available without the "v:". @@ -1283,7 +1282,7 @@ text_indent_len = -1; } - // The marker is the next word. Default marker is "." + // The marker is the next word. if (*cmd != NUL && *cmd != '"') { marker = skipwhite(cmd); @@ -1294,9 +1293,17 @@ return NULL; } *p = NUL; + if (vim_islower(*marker)) + { + emsg(_("E221: Marker cannot start with lower case letter")); + return NULL; + } } else - marker = (char_u *)"."; + { + emsg(_("E172: Missing marker")); + return NULL; + } l = list_alloc(); if (l == NULL) @@ -1486,7 +1493,7 @@ /* * Assign the typevalue "tv" to the variable or variables at "arg_start". * Handles both "var" with any type and "[var, var; var]" with a list type. - * When "nextchars" is not NULL it points to a string with characters that + * When "op" is not NULL it points to a string with characters that * must appear after the variable(s). Use "+", "-" or "." for add, subtract * or concatenate. * Returns OK or FAIL; @@ -1499,7 +1506,7 @@ int semicolon, // from skip_var_list() int var_count, // from skip_var_list() int is_const, // lock variables for const - char_u *nextchars) + char_u *op) { char_u *arg = arg_start; list_T *l; @@ -1512,7 +1519,7 @@ /* * ":let var = expr" or ":for var in list" */ - if (ex_let_one(arg, tv, copy, is_const, nextchars, nextchars) == NULL) + if (ex_let_one(arg, tv, copy, is_const, op, op) == NULL) return FAIL; return OK; } @@ -1543,7 +1550,7 @@ { arg = skipwhite(arg + 1); arg = ex_let_one(arg, &item->li_tv, TRUE, is_const, - (char_u *)",;]", nextchars); + (char_u *)",;]", op); item = item->li_next; if (arg == NULL) return FAIL; @@ -1568,7 +1575,7 @@ l->lv_refcount = 1; arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, is_const, - (char_u *)"]", nextchars); + (char_u *)"]", op); clear_tv(<v); if (arg == NULL) return FAIL; @@ -3621,7 +3628,7 @@ * Return TRUE if "pat" matches "text". * Does not use 'cpo' and always uses 'magic'. */ - static int + int pattern_match(char_u *pat, char_u *text, int ic) { int matches = FALSE; @@ -4391,7 +4398,8 @@ * $VAR environment variable * (expression) nested expression * [expr, expr] List - * {key: val, key: val} Dictionary + * {key: val, key: val} Dictionary + * #{key: val, key: val} Dictionary with literal keys * * Also handle: * ! in front logical NOT @@ -4576,12 +4584,24 @@ break; /* + * Dictionary: #{key: val, key: val} + */ + case '#': if ((*arg)[1] == '{') + { + ++*arg; + ret = dict_get_tv(arg, rettv, evaluate, TRUE); + } + else + ret = NOTDONE; + break; + + /* * Lambda: {arg, arg -> expr} - * Dictionary: {key: val, key: val} + * Dictionary: {'key': val, 'key': val} */ case '{': ret = get_lambda_tv(arg, rettv, evaluate); if (ret == NOTDONE) - ret = dict_get_tv(arg, rettv, evaluate); + ret = dict_get_tv(arg, rettv, evaluate, FALSE); break; /* @@ -6977,6 +6997,15 @@ } /* + * Get typval_T v: variable value. + */ + typval_T * +get_vim_var_tv(int idx) +{ + return &vimvars[idx].vv_tv; +} + +/* * Get number v: variable value. */ varnumber_T @@ -7333,9 +7362,14 @@ int len; typval_T functv; + // "." is ".name" lookup when we found a dict or when evaluating and + // scriptversion is at least 2, where string concatenation is "..". while (ret == OK && (**arg == '[' - || (**arg == '.' && rettv->v_type == VAR_DICT) + || (**arg == '.' && (rettv->v_type == VAR_DICT + || (!evaluate + && (*arg)[1] != '.' + && current_sctx.sc_version >= 2))) || (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC || rettv->v_type == VAR_PARTIAL))) && !VIM_ISWHITE(*(*arg - 1))) @@ -7941,8 +7975,7 @@ *varname = name + 2; if (*name == 'g') /* global variable */ return &globvarht; - /* There must be no ':' or '#' in the rest of the name, unless g: is used - */ + // There must be no ':' or '#' in the rest of the name, unless g: is used if (vim_strchr(name + 2, ':') != NULL || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) return NULL; @@ -9287,14 +9320,7 @@ } #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) -typedef enum -{ - VAR_FLAVOUR_DEFAULT, /* doesn't start with uppercase */ - VAR_FLAVOUR_SESSION, /* starts with uppercase, some lower */ - VAR_FLAVOUR_VIMINFO /* all uppercase */ -} var_flavour_T; - - static var_flavour_T + var_flavour_T var_flavour(char_u *varname) { char_u *p = varname; @@ -9311,161 +9337,6 @@ } #endif -#if defined(FEAT_VIMINFO) || defined(PROTO) -/* - * Restore global vars that start with a capital from the viminfo file - */ - int -read_viminfo_varlist(vir_T *virp, int writing) -{ - char_u *tab; - int type = VAR_NUMBER; - typval_T tv; - funccal_entry_T funccal_entry; - - if (!writing && (find_viminfo_parameter('!') != NULL)) - { - tab = vim_strchr(virp->vir_line + 1, '\t'); - if (tab != NULL) - { - *tab++ = '\0'; /* isolate the variable name */ - switch (*tab) - { - case 'S': type = VAR_STRING; break; -#ifdef FEAT_FLOAT - case 'F': type = VAR_FLOAT; break; -#endif - case 'D': type = VAR_DICT; break; - case 'L': type = VAR_LIST; break; - case 'B': type = VAR_BLOB; break; - case 'X': type = VAR_SPECIAL; break; - } - - tab = vim_strchr(tab, '\t'); - if (tab != NULL) - { - tv.v_type = type; - if (type == VAR_STRING || type == VAR_DICT - || type == VAR_LIST || type == VAR_BLOB) - tv.vval.v_string = viminfo_readstring(virp, - (int)(tab - virp->vir_line + 1), TRUE); -#ifdef FEAT_FLOAT - else if (type == VAR_FLOAT) - (void)string2float(tab + 1, &tv.vval.v_float); -#endif - else - tv.vval.v_number = atol((char *)tab + 1); - if (type == VAR_DICT || type == VAR_LIST) - { - typval_T *etv = eval_expr(tv.vval.v_string, NULL); - - if (etv == NULL) - /* Failed to parse back the dict or list, use it as a - * string. */ - tv.v_type = VAR_STRING; - else - { - vim_free(tv.vval.v_string); - tv = *etv; - vim_free(etv); - } - } - else if (type == VAR_BLOB) - { - blob_T *blob = string2blob(tv.vval.v_string); - - if (blob == NULL) - // Failed to parse back the blob, use it as a string. - tv.v_type = VAR_STRING; - else - { - vim_free(tv.vval.v_string); - tv.v_type = VAR_BLOB; - tv.vval.v_blob = blob; - } - } - - /* when in a function use global variables */ - save_funccal(&funccal_entry); - set_var(virp->vir_line + 1, &tv, FALSE); - restore_funccal(); - - if (tv.v_type == VAR_STRING) - vim_free(tv.vval.v_string); - else if (tv.v_type == VAR_DICT || tv.v_type == VAR_LIST || - tv.v_type == VAR_BLOB) - clear_tv(&tv); - } - } - } - - return viminfo_readline(virp); -} - -/* - * Write global vars that start with a capital to the viminfo file - */ - void -write_viminfo_varlist(FILE *fp) -{ - hashitem_T *hi; - dictitem_T *this_var; - int todo; - char *s = ""; - char_u *p; - char_u *tofree; - char_u numbuf[NUMBUFLEN]; - - if (find_viminfo_parameter('!') == NULL) - return; - - fputs(_("\n# global variables:\n"), fp); - - todo = (int)globvarht.ht_used; - for (hi = globvarht.ht_array; todo > 0; ++hi) - { - if (!HASHITEM_EMPTY(hi)) - { - --todo; - this_var = HI2DI(hi); - if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) - { - switch (this_var->di_tv.v_type) - { - case VAR_STRING: s = "STR"; break; - case VAR_NUMBER: s = "NUM"; break; - case VAR_FLOAT: s = "FLO"; break; - case VAR_DICT: s = "DIC"; break; - case VAR_LIST: s = "LIS"; break; - case VAR_BLOB: s = "BLO"; break; - case VAR_SPECIAL: s = "XPL"; break; - - case VAR_UNKNOWN: - case VAR_FUNC: - case VAR_PARTIAL: - case VAR_JOB: - case VAR_CHANNEL: - continue; - } - fprintf(fp, "!%s\t%s\t", this_var->di_key, s); - if (this_var->di_tv.v_type == VAR_SPECIAL) - { - sprintf((char *)numbuf, "%ld", - (long)this_var->di_tv.vval.v_number); - p = numbuf; - tofree = NULL; - } - else - p = echo_string(&this_var->di_tv, &tofree, numbuf, 0); - if (p != NULL) - viminfo_writestring(fp, p); - vim_free(tofree); - } - } - } -} -#endif - #if defined(FEAT_SESSION) || defined(PROTO) int store_session_globals(FILE *fd) @@ -9579,30 +9450,6 @@ } /* - * Prepare "gap" for an assert error and add the sourcing position. - */ - void -prepare_assert_error(garray_T *gap) -{ - char buf[NUMBUFLEN]; - - ga_init2(gap, 1, 100); - if (sourcing_name != NULL) - { - ga_concat(gap, sourcing_name); - if (sourcing_lnum > 0) - ga_concat(gap, (char_u *)" "); - } - if (sourcing_lnum > 0) - { - sprintf(buf, "line %ld", (long)sourcing_lnum); - ga_concat(gap, (char_u *)buf); - } - if (sourcing_name != NULL || sourcing_lnum > 0) - ga_concat(gap, (char_u *)": "); -} - -/* * Add an assert error to v:errors. */ void @@ -9615,477 +9462,6 @@ set_vim_var_list(VV_ERRORS, list_alloc()); list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len); } - - int -assert_equal_common(typval_T *argvars, assert_type_T atype) -{ - garray_T ga; - - if (tv_equal(&argvars[0], &argvars[1], FALSE, FALSE) - != (atype == ASSERT_EQUAL)) - { - prepare_assert_error(&ga); - fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1], - atype); - assert_error(&ga); - ga_clear(&ga); - return 1; - } - return 0; -} - - int -assert_equalfile(typval_T *argvars) -{ - char_u buf1[NUMBUFLEN]; - char_u buf2[NUMBUFLEN]; - char_u *fname1 = tv_get_string_buf_chk(&argvars[0], buf1); - char_u *fname2 = tv_get_string_buf_chk(&argvars[1], buf2); - garray_T ga; - FILE *fd1; - FILE *fd2; - - if (fname1 == NULL || fname2 == NULL) - return 0; - - IObuff[0] = NUL; - fd1 = mch_fopen((char *)fname1, READBIN); - if (fd1 == NULL) - { - vim_snprintf((char *)IObuff, IOSIZE, (char *)e_notread, fname1); - } - else - { - fd2 = mch_fopen((char *)fname2, READBIN); - if (fd2 == NULL) - { - fclose(fd1); - vim_snprintf((char *)IObuff, IOSIZE, (char *)e_notread, fname2); - } - else - { - int c1, c2; - long count = 0; - - for (;;) - { - c1 = fgetc(fd1); - c2 = fgetc(fd2); - if (c1 == EOF) - { - if (c2 != EOF) - STRCPY(IObuff, "first file is shorter"); - break; - } - else if (c2 == EOF) - { - STRCPY(IObuff, "second file is shorter"); - break; - } - else if (c1 != c2) - { - vim_snprintf((char *)IObuff, IOSIZE, - "difference at byte %ld", count); - break; - } - ++count; - } - fclose(fd1); - fclose(fd2); - } - } - if (IObuff[0] != NUL) - { - prepare_assert_error(&ga); - ga_concat(&ga, IObuff); - assert_error(&ga); - ga_clear(&ga); - return 1; - } - return 0; -} - - int -assert_match_common(typval_T *argvars, assert_type_T atype) -{ - garray_T ga; - char_u buf1[NUMBUFLEN]; - char_u buf2[NUMBUFLEN]; - char_u *pat = tv_get_string_buf_chk(&argvars[0], buf1); - char_u *text = tv_get_string_buf_chk(&argvars[1], buf2); - - if (pat == NULL || text == NULL) - emsg(_(e_invarg)); - else if (pattern_match(pat, text, FALSE) != (atype == ASSERT_MATCH)) - { - prepare_assert_error(&ga); - fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1], - atype); - assert_error(&ga); - ga_clear(&ga); - return 1; - } - return 0; -} - - int -assert_inrange(typval_T *argvars) -{ - garray_T ga; - int error = FALSE; - char_u *tofree; - char msg[200]; - char_u numbuf[NUMBUFLEN]; - -#ifdef FEAT_FLOAT - if (argvars[0].v_type == VAR_FLOAT - || argvars[1].v_type == VAR_FLOAT - || argvars[2].v_type == VAR_FLOAT) - { - float_T flower = tv_get_float(&argvars[0]); - float_T fupper = tv_get_float(&argvars[1]); - float_T factual = tv_get_float(&argvars[2]); - - if (factual < flower || factual > fupper) - { - prepare_assert_error(&ga); - if (argvars[3].v_type != VAR_UNKNOWN) - { - ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0)); - vim_free(tofree); - } - else - { - vim_snprintf(msg, 200, "Expected range %g - %g, but got %g", - flower, fupper, factual); - ga_concat(&ga, (char_u *)msg); - } - assert_error(&ga); - ga_clear(&ga); - return 1; - } - } - else -#endif - { - varnumber_T lower = tv_get_number_chk(&argvars[0], &error); - varnumber_T upper = tv_get_number_chk(&argvars[1], &error); - varnumber_T actual = tv_get_number_chk(&argvars[2], &error); - - if (error) - return 0; - if (actual < lower || actual > upper) - { - prepare_assert_error(&ga); - if (argvars[3].v_type != VAR_UNKNOWN) - { - ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0)); - vim_free(tofree); - } - else - { - vim_snprintf(msg, 200, "Expected range %ld - %ld, but got %ld", - (long)lower, (long)upper, (long)actual); - ga_concat(&ga, (char_u *)msg); - } - assert_error(&ga); - ga_clear(&ga); - return 1; - } - } - return 0; -} - -/* - * Common for assert_true() and assert_false(). - * Return non-zero for failure. - */ - int -assert_bool(typval_T *argvars, int isTrue) -{ - int error = FALSE; - garray_T ga; - - if (argvars[0].v_type == VAR_SPECIAL - && argvars[0].vval.v_number == (isTrue ? VVAL_TRUE : VVAL_FALSE)) - return 0; - if (argvars[0].v_type != VAR_NUMBER - || (tv_get_number_chk(&argvars[0], &error) == 0) == isTrue - || error) - { - prepare_assert_error(&ga); - fill_assert_error(&ga, &argvars[1], - (char_u *)(isTrue ? "True" : "False"), - NULL, &argvars[0], ASSERT_OTHER); - assert_error(&ga); - ga_clear(&ga); - return 1; - } - return 0; -} - - int -assert_report(typval_T *argvars) -{ - garray_T ga; - - prepare_assert_error(&ga); - ga_concat(&ga, tv_get_string(&argvars[0])); - assert_error(&ga); - ga_clear(&ga); - return 1; -} - - int -assert_exception(typval_T *argvars) -{ - garray_T ga; - char_u *error = tv_get_string_chk(&argvars[0]); - - if (vimvars[VV_EXCEPTION].vv_str == NULL) - { - prepare_assert_error(&ga); - ga_concat(&ga, (char_u *)"v:exception is not set"); - assert_error(&ga); - ga_clear(&ga); - return 1; - } - else if (error != NULL - && strstr((char *)vimvars[VV_EXCEPTION].vv_str, (char *)error) == NULL) - { - prepare_assert_error(&ga); - fill_assert_error(&ga, &argvars[1], NULL, &argvars[0], - &vimvars[VV_EXCEPTION].vv_tv, ASSERT_OTHER); - assert_error(&ga); - ga_clear(&ga); - return 1; - } - return 0; -} - - int -assert_beeps(typval_T *argvars) -{ - char_u *cmd = tv_get_string_chk(&argvars[0]); - garray_T ga; - int ret = 0; - - called_vim_beep = FALSE; - suppress_errthrow = TRUE; - emsg_silent = FALSE; - do_cmdline_cmd(cmd); - if (!called_vim_beep) - { - prepare_assert_error(&ga); - ga_concat(&ga, (char_u *)"command did not beep: "); - ga_concat(&ga, cmd); - assert_error(&ga); - ga_clear(&ga); - ret = 1; - } - - suppress_errthrow = FALSE; - emsg_on_display = FALSE; - return ret; -} - - static void -assert_append_cmd_or_arg(garray_T *gap, typval_T *argvars, char_u *cmd) -{ - char_u *tofree; - char_u numbuf[NUMBUFLEN]; - - if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) - { - ga_concat(gap, echo_string(&argvars[2], &tofree, numbuf, 0)); - vim_free(tofree); - } - else - ga_concat(gap, cmd); -} - - int -assert_fails(typval_T *argvars) -{ - char_u *cmd = tv_get_string_chk(&argvars[0]); - garray_T ga; - int ret = 0; - int save_trylevel = trylevel; - - // trylevel must be zero for a ":throw" command to be considered failed - trylevel = 0; - called_emsg = FALSE; - suppress_errthrow = TRUE; - emsg_silent = TRUE; - - do_cmdline_cmd(cmd); - if (!called_emsg) - { - prepare_assert_error(&ga); - ga_concat(&ga, (char_u *)"command did not fail: "); - assert_append_cmd_or_arg(&ga, argvars, cmd); - assert_error(&ga); - ga_clear(&ga); - ret = 1; - } - else if (argvars[1].v_type != VAR_UNKNOWN) - { - char_u buf[NUMBUFLEN]; - char *error = (char *)tv_get_string_buf_chk(&argvars[1], buf); - - if (error == NULL - || strstr((char *)vimvars[VV_ERRMSG].vv_str, error) == NULL) - { - prepare_assert_error(&ga); - fill_assert_error(&ga, &argvars[2], NULL, &argvars[1], - &vimvars[VV_ERRMSG].vv_tv, ASSERT_OTHER); - ga_concat(&ga, (char_u *)": "); - assert_append_cmd_or_arg(&ga, argvars, cmd); - assert_error(&ga); - ga_clear(&ga); - ret = 1; - } - } - - trylevel = save_trylevel; - called_emsg = FALSE; - suppress_errthrow = FALSE; - emsg_silent = FALSE; - emsg_on_display = FALSE; - set_vim_var_string(VV_ERRMSG, NULL, 0); - return ret; -} - -/* - * Append "p[clen]" to "gap", escaping unprintable characters. - * Changes NL to \n, CR to \r, etc. - */ - static void -ga_concat_esc(garray_T *gap, char_u *p, int clen) -{ - char_u buf[NUMBUFLEN]; - - if (clen > 1) - { - mch_memmove(buf, p, clen); - buf[clen] = NUL; - ga_concat(gap, buf); - } - else switch (*p) - { - case BS: ga_concat(gap, (char_u *)"\\b"); break; - case ESC: ga_concat(gap, (char_u *)"\\e"); break; - case FF: ga_concat(gap, (char_u *)"\\f"); break; - case NL: ga_concat(gap, (char_u *)"\\n"); break; - case TAB: ga_concat(gap, (char_u *)"\\t"); break; - case CAR: ga_concat(gap, (char_u *)"\\r"); break; - case '\\': ga_concat(gap, (char_u *)"\\\\"); break; - default: - if (*p < ' ') - { - vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p); - ga_concat(gap, buf); - } - else - ga_append(gap, *p); - break; - } -} - -/* - * Append "str" to "gap", escaping unprintable characters. - * Changes NL to \n, CR to \r, etc. - */ - static void -ga_concat_shorten_esc(garray_T *gap, char_u *str) -{ - char_u *p; - char_u *s; - int c; - int clen; - char_u buf[NUMBUFLEN]; - int same_len; - - if (str == NULL) - { - ga_concat(gap, (char_u *)"NULL"); - return; - } - - for (p = str; *p != NUL; ++p) - { - same_len = 1; - s = p; - c = mb_ptr2char_adv(&s); - clen = s - p; - while (*s != NUL && c == mb_ptr2char(s)) - { - ++same_len; - s += clen; - } - if (same_len > 20) - { - ga_concat(gap, (char_u *)"\\["); - ga_concat_esc(gap, p, clen); - ga_concat(gap, (char_u *)" occurs "); - vim_snprintf((char *)buf, NUMBUFLEN, "%d", same_len); - ga_concat(gap, buf); - ga_concat(gap, (char_u *)" times]"); - p = s - 1; - } - else - ga_concat_esc(gap, p, clen); - } -} - -/* - * Fill "gap" with information about an assert error. - */ - void -fill_assert_error( - garray_T *gap, - typval_T *opt_msg_tv, - char_u *exp_str, - typval_T *exp_tv, - typval_T *got_tv, - assert_type_T atype) -{ - char_u numbuf[NUMBUFLEN]; - char_u *tofree; - - if (opt_msg_tv->v_type != VAR_UNKNOWN) - { - 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_shorten_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0)); - vim_free(tofree); - } - else - ga_concat_shorten_esc(gap, exp_str); - if (atype != ASSERT_NOTEQUAL) - { - 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 - ga_concat(gap, (char_u *)" but got "); - ga_concat_shorten_esc(gap, tv2string(got_tv, &tofree, numbuf, 0)); - vim_free(tofree); - } -} - /* * Compare "typ1" and "typ2". Put the result in "typ1". */ diff -Nru vim-8.1.1681/src/evalfunc.c vim-8.1.1729/src/evalfunc.c --- vim-8.1.1681/src/evalfunc.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/evalfunc.c 2019-07-21 21:04:21.000000000 +0000 @@ -41,18 +41,6 @@ static void f_argidx(typval_T *argvars, typval_T *rettv); static void f_arglistid(typval_T *argvars, typval_T *rettv); static void f_argv(typval_T *argvars, typval_T *rettv); -static void f_assert_beeps(typval_T *argvars, typval_T *rettv); -static void f_assert_equal(typval_T *argvars, typval_T *rettv); -static void f_assert_equalfile(typval_T *argvars, typval_T *rettv); -static void f_assert_exception(typval_T *argvars, typval_T *rettv); -static void f_assert_fails(typval_T *argvars, typval_T *rettv); -static void f_assert_false(typval_T *argvars, typval_T *rettv); -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); @@ -396,34 +384,6 @@ static void f_taglist(typval_T *argvars, typval_T *rettv); 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_feedinput(typval_T *argvars, typval_T *rettv); -static void f_test_getvalue(typval_T *argvars, typval_T *rettv); -static void f_test_option_not_set(typval_T *argvars, typval_T *rettv); -static void f_test_override(typval_T *argvars, typval_T *rettv); -static void f_test_refcount(typval_T *argvars, typval_T *rettv); -static void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv); -static void f_test_garbagecollect_soon(typval_T *argvars, typval_T *rettv); -static void f_test_ignore_error(typval_T *argvars, typval_T *rettv); -static void f_test_null_blob(typval_T *argvars, typval_T *rettv); -#ifdef FEAT_JOB_CHANNEL -static void f_test_null_channel(typval_T *argvars, typval_T *rettv); -#endif -static void f_test_null_dict(typval_T *argvars, typval_T *rettv); -#ifdef FEAT_JOB_CHANNEL -static void f_test_null_job(typval_T *argvars, typval_T *rettv); -#endif -static void f_test_null_list(typval_T *argvars, typval_T *rettv); -static void f_test_null_partial(typval_T *argvars, typval_T *rettv); -static void f_test_null_string(typval_T *argvars, typval_T *rettv); -#ifdef FEAT_GUI -static void f_test_scrollbar(typval_T *argvars, typval_T *rettv); -#endif -#ifdef FEAT_MOUSE -static void f_test_setmouse(typval_T *argvars, typval_T *rettv); -#endif -static void f_test_settime(typval_T *argvars, typval_T *rettv); #ifdef FEAT_FLOAT static void f_tan(typval_T *argvars, typval_T *rettv); static void f_tanh(typval_T *argvars, typval_T *rettv); @@ -888,8 +848,10 @@ {"sign_getplaced", 0, 2, f_sign_getplaced}, {"sign_jump", 3, 3, f_sign_jump}, {"sign_place", 4, 5, f_sign_place}, + {"sign_placelist", 1, 1, f_sign_placelist}, {"sign_undefine", 0, 1, f_sign_undefine}, {"sign_unplace", 1, 2, f_sign_unplace}, + {"sign_unplacelist", 1, 2, f_sign_unplacelist}, #endif {"simplify", 1, 1, f_simplify}, #ifdef FEAT_FLOAT @@ -1607,114 +1569,6 @@ get_arglist_as_rettv(ARGLIST, ARGCOUNT, rettv); } -/* - * "assert_beeps(cmd [, error])" function - */ - static void -f_assert_beeps(typval_T *argvars, typval_T *rettv) -{ - rettv->vval.v_number = assert_beeps(argvars); -} - -/* - * "assert_equal(expected, actual[, msg])" function - */ - static void -f_assert_equal(typval_T *argvars, typval_T *rettv) -{ - rettv->vval.v_number = assert_equal_common(argvars, ASSERT_EQUAL); -} - -/* - * "assert_equalfile(fname-one, fname-two)" function - */ - static void -f_assert_equalfile(typval_T *argvars, typval_T *rettv) -{ - rettv->vval.v_number = assert_equalfile(argvars); -} - -/* - * "assert_notequal(expected, actual[, msg])" function - */ - static void -f_assert_notequal(typval_T *argvars, typval_T *rettv) -{ - rettv->vval.v_number = assert_equal_common(argvars, ASSERT_NOTEQUAL); -} - -/* - * "assert_exception(string[, msg])" function - */ - static void -f_assert_exception(typval_T *argvars, typval_T *rettv) -{ - rettv->vval.v_number = assert_exception(argvars); -} - -/* - * "assert_fails(cmd [, error[, msg]])" function - */ - static void -f_assert_fails(typval_T *argvars, typval_T *rettv) -{ - rettv->vval.v_number = assert_fails(argvars); -} - -/* - * "assert_false(actual[, msg])" function - */ - static void -f_assert_false(typval_T *argvars, typval_T *rettv) -{ - rettv->vval.v_number = assert_bool(argvars, FALSE); -} - -/* - * "assert_inrange(lower, upper[, msg])" function - */ - static void -f_assert_inrange(typval_T *argvars, typval_T *rettv) -{ - rettv->vval.v_number = assert_inrange(argvars); -} - -/* - * "assert_match(pattern, actual[, msg])" function - */ - static void -f_assert_match(typval_T *argvars, typval_T *rettv) -{ - rettv->vval.v_number = assert_match_common(argvars, ASSERT_MATCH); -} - -/* - * "assert_notmatch(pattern, actual[, msg])" function - */ - static void -f_assert_notmatch(typval_T *argvars, typval_T *rettv) -{ - rettv->vval.v_number = assert_match_common(argvars, ASSERT_NOTMATCH); -} - -/* - * "assert_report(msg)" function - */ - static void -f_assert_report(typval_T *argvars, typval_T *rettv) -{ - rettv->vval.v_number = assert_report(argvars); -} - -/* - * "assert_true(actual[, msg])" function - */ - static void -f_assert_true(typval_T *argvars, typval_T *rettv) -{ - rettv->vval.v_number = assert_bool(argvars, TRUE); -} - #ifdef FEAT_FLOAT /* * "asin()" function @@ -13545,351 +13399,6 @@ #endif /* - * "test_alloc_fail(id, countdown, repeat)" function - */ - static void -f_test_alloc_fail(typval_T *argvars, typval_T *rettv UNUSED) -{ - if (argvars[0].v_type != VAR_NUMBER - || argvars[0].vval.v_number <= 0 - || argvars[1].v_type != VAR_NUMBER - || argvars[1].vval.v_number < 0 - || argvars[2].v_type != VAR_NUMBER) - emsg(_(e_invarg)); - else - { - alloc_fail_id = argvars[0].vval.v_number; - if (alloc_fail_id >= aid_last) - emsg(_(e_invarg)); - alloc_fail_countdown = argvars[1].vval.v_number; - alloc_fail_repeat = argvars[2].vval.v_number; - did_outofmem_msg = FALSE; - } -} - -/* - * "test_autochdir()" - */ - static void -f_test_autochdir(typval_T *argvars UNUSED, typval_T *rettv UNUSED) -{ -#if defined(FEAT_AUTOCHDIR) - test_autochdir = TRUE; -#endif -} - -/* - * "test_feedinput()" - */ - static void -f_test_feedinput(typval_T *argvars, typval_T *rettv UNUSED) -{ -#ifdef USE_INPUT_BUF - char_u *val = tv_get_string_chk(&argvars[0]); - - if (val != NULL) - { - trash_input_buf(); - add_to_input_buf_csi(val, (int)STRLEN(val)); - } -#endif -} - -/* - * "test_getvalue({name})" function - */ - static void -f_test_getvalue(typval_T *argvars, typval_T *rettv) -{ - if (argvars[0].v_type != VAR_STRING) - emsg(_(e_invarg)); - else - { - char_u *name = tv_get_string(&argvars[0]); - - if (STRCMP(name, (char_u *)"need_fileinfo") == 0) - rettv->vval.v_number = need_fileinfo; - else - semsg(_(e_invarg2), name); - } -} - -/* - * "test_option_not_set({name})" function - */ - static void -f_test_option_not_set(typval_T *argvars, typval_T *rettv UNUSED) -{ - char_u *name = (char_u *)""; - - if (argvars[0].v_type != VAR_STRING) - emsg(_(e_invarg)); - else - { - name = tv_get_string(&argvars[0]); - if (reset_option_was_set(name) == FAIL) - semsg(_(e_invarg2), name); - } -} - -/* - * "test_override({name}, {val})" function - */ - static void -f_test_override(typval_T *argvars, typval_T *rettv UNUSED) -{ - char_u *name = (char_u *)""; - int val; - static int save_starting = -1; - - if (argvars[0].v_type != VAR_STRING - || (argvars[1].v_type) != VAR_NUMBER) - emsg(_(e_invarg)); - else - { - name = tv_get_string(&argvars[0]); - val = (int)tv_get_number(&argvars[1]); - - if (STRCMP(name, (char_u *)"redraw") == 0) - disable_redraw_for_testing = val; - else if (STRCMP(name, (char_u *)"redraw_flag") == 0) - ignore_redraw_flag_for_testing = val; - else if (STRCMP(name, (char_u *)"char_avail") == 0) - disable_char_avail_for_testing = val; - else if (STRCMP(name, (char_u *)"starting") == 0) - { - if (val) - { - if (save_starting < 0) - save_starting = starting; - starting = 0; - } - else - { - starting = save_starting; - save_starting = -1; - } - } - else if (STRCMP(name, (char_u *)"nfa_fail") == 0) - nfa_fail_for_testing = val; - else if (STRCMP(name, (char_u *)"no_query_mouse") == 0) - no_query_mouse_for_testing = val; - else if (STRCMP(name, (char_u *)"no_wait_return") == 0) - no_wait_return = val; - else if (STRCMP(name, (char_u *)"ALL") == 0) - { - disable_char_avail_for_testing = FALSE; - disable_redraw_for_testing = FALSE; - ignore_redraw_flag_for_testing = FALSE; - nfa_fail_for_testing = FALSE; - no_query_mouse_for_testing = FALSE; - if (save_starting >= 0) - { - starting = save_starting; - save_starting = -1; - } - } - else - semsg(_(e_invarg2), name); - } -} - -/* - * "test_refcount({expr})" function - */ - static void -f_test_refcount(typval_T *argvars, typval_T *rettv) -{ - int retval = -1; - - switch (argvars[0].v_type) - { - case VAR_UNKNOWN: - case VAR_NUMBER: - case VAR_FLOAT: - case VAR_SPECIAL: - case VAR_STRING: - break; - case VAR_JOB: -#ifdef FEAT_JOB_CHANNEL - if (argvars[0].vval.v_job != NULL) - retval = argvars[0].vval.v_job->jv_refcount - 1; -#endif - break; - case VAR_CHANNEL: -#ifdef FEAT_JOB_CHANNEL - if (argvars[0].vval.v_channel != NULL) - retval = argvars[0].vval.v_channel->ch_refcount - 1; -#endif - break; - case VAR_FUNC: - if (argvars[0].vval.v_string != NULL) - { - ufunc_T *fp; - - fp = find_func(argvars[0].vval.v_string); - if (fp != NULL) - retval = fp->uf_refcount; - } - break; - case VAR_PARTIAL: - if (argvars[0].vval.v_partial != NULL) - retval = argvars[0].vval.v_partial->pt_refcount - 1; - break; - case VAR_BLOB: - if (argvars[0].vval.v_blob != NULL) - retval = argvars[0].vval.v_blob->bv_refcount - 1; - break; - case VAR_LIST: - if (argvars[0].vval.v_list != NULL) - retval = argvars[0].vval.v_list->lv_refcount - 1; - break; - case VAR_DICT: - if (argvars[0].vval.v_dict != NULL) - retval = argvars[0].vval.v_dict->dv_refcount - 1; - break; - } - - rettv->v_type = VAR_NUMBER; - rettv->vval.v_number = retval; - -} - -/* - * "test_garbagecollect_now()" function - */ - static void -f_test_garbagecollect_now(typval_T *argvars UNUSED, typval_T *rettv UNUSED) -{ - /* This is dangerous, any Lists and Dicts used internally may be freed - * while still in use. */ - garbage_collect(TRUE); -} - -/* - * "test_garbagecollect_soon()" function - */ - static void -f_test_garbagecollect_soon(typval_T *argvars UNUSED, typval_T *rettv UNUSED) -{ - may_garbage_collect = TRUE; -} - -/* - * "test_ignore_error()" function - */ - static void -f_test_ignore_error(typval_T *argvars, typval_T *rettv UNUSED) -{ - ignore_error_for_testing(tv_get_string(&argvars[0])); -} - - static void -f_test_null_blob(typval_T *argvars UNUSED, typval_T *rettv) -{ - rettv->v_type = VAR_BLOB; - rettv->vval.v_blob = NULL; -} - -#ifdef FEAT_JOB_CHANNEL - static void -f_test_null_channel(typval_T *argvars UNUSED, typval_T *rettv) -{ - rettv->v_type = VAR_CHANNEL; - rettv->vval.v_channel = NULL; -} -#endif - - static void -f_test_null_dict(typval_T *argvars UNUSED, typval_T *rettv) -{ - rettv_dict_set(rettv, NULL); -} - -#ifdef FEAT_JOB_CHANNEL - static void -f_test_null_job(typval_T *argvars UNUSED, typval_T *rettv) -{ - rettv->v_type = VAR_JOB; - rettv->vval.v_job = NULL; -} -#endif - - static void -f_test_null_list(typval_T *argvars UNUSED, typval_T *rettv) -{ - rettv_list_set(rettv, NULL); -} - - static void -f_test_null_partial(typval_T *argvars UNUSED, typval_T *rettv) -{ - rettv->v_type = VAR_PARTIAL; - rettv->vval.v_partial = NULL; -} - - static void -f_test_null_string(typval_T *argvars UNUSED, typval_T *rettv) -{ - rettv->v_type = VAR_STRING; - rettv->vval.v_string = NULL; -} - -#ifdef FEAT_GUI - static void -f_test_scrollbar(typval_T *argvars, typval_T *rettv UNUSED) -{ - char_u *which; - long value; - int dragging; - scrollbar_T *sb = NULL; - - if (argvars[0].v_type != VAR_STRING - || (argvars[1].v_type) != VAR_NUMBER - || (argvars[2].v_type) != VAR_NUMBER) - { - emsg(_(e_invarg)); - return; - } - which = tv_get_string(&argvars[0]); - value = tv_get_number(&argvars[1]); - dragging = tv_get_number(&argvars[2]); - - if (STRCMP(which, "left") == 0) - sb = &curwin->w_scrollbars[SBAR_LEFT]; - else if (STRCMP(which, "right") == 0) - sb = &curwin->w_scrollbars[SBAR_RIGHT]; - else if (STRCMP(which, "hor") == 0) - sb = &gui.bottom_sbar; - if (sb == NULL) - { - semsg(_(e_invarg2), which); - return; - } - gui_drag_scrollbar(sb, value, dragging); -# ifndef USE_ON_FLY_SCROLL - // need to loop through normal_cmd() to handle the scroll events - exec_normal(FALSE, TRUE, FALSE); -# endif -} -#endif - -#ifdef FEAT_MOUSE - static void -f_test_setmouse(typval_T *argvars, typval_T *rettv UNUSED) -{ - mouse_row = (time_t)tv_get_number(&argvars[0]) - 1; - mouse_col = (time_t)tv_get_number(&argvars[1]) - 1; -} -#endif - - static void -f_test_settime(typval_T *argvars, typval_T *rettv UNUSED) -{ - time_for_testing = (time_t)tv_get_number(&argvars[0]); -} - -/* * Get a callback from "arg". It can be a Funcref or a function name. * When "arg" is zero return an empty string. * "cb_name" is not allocated. diff -Nru vim-8.1.1681/src/ex_cmds2.c vim-8.1.1729/src/ex_cmds2.c --- vim-8.1.1681/src/ex_cmds2.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/ex_cmds2.c 2019-07-21 21:04:21.000000000 +0000 @@ -16,215 +16,7 @@ static void cmd_source(char_u *fname, exarg_T *eap); -#ifdef FEAT_EVAL -/* Growarray to store info about already sourced scripts. - * For Unix also store the dev/ino, so that we don't have to stat() each - * script when going through the list. */ -typedef struct scriptitem_S -{ - char_u *sn_name; -# ifdef UNIX - int sn_dev_valid; - dev_t sn_dev; - ino_t sn_ino; -# endif -# ifdef FEAT_PROFILE - int sn_prof_on; /* TRUE when script is/was profiled */ - int sn_pr_force; /* forceit: profile functions in this script */ - proftime_T sn_pr_child; /* time set when going into first child */ - int sn_pr_nest; /* nesting for sn_pr_child */ - /* profiling the script as a whole */ - int sn_pr_count; /* nr of times sourced */ - proftime_T sn_pr_total; /* time spent in script + children */ - proftime_T sn_pr_self; /* time spent in script itself */ - proftime_T sn_pr_start; /* time at script start */ - proftime_T sn_pr_children; /* time in children after script start */ - /* profiling the script per line */ - garray_T sn_prl_ga; /* things stored for every line */ - proftime_T sn_prl_start; /* start time for current line */ - proftime_T sn_prl_children; /* time spent in children for this line */ - proftime_T sn_prl_wait; /* wait start time for current line */ - int sn_prl_idx; /* index of line being timed; -1 if none */ - int sn_prl_execed; /* line being timed was executed */ -# endif -} scriptitem_T; - -static garray_T script_items = {0, 0, sizeof(scriptitem_T), 4, NULL}; -#define SCRIPT_ITEM(id) (((scriptitem_T *)script_items.ga_data)[(id) - 1]) - -# ifdef FEAT_PROFILE -/* Struct used in sn_prl_ga for every line of a script. */ -typedef struct sn_prl_S -{ - int snp_count; /* nr of times line was executed */ - proftime_T sn_prl_total; /* time spent in a line + children */ - proftime_T sn_prl_self; /* time spent in a line itself */ -} sn_prl_T; - -# define PRL_ITEM(si, idx) (((sn_prl_T *)(si)->sn_prl_ga.ga_data)[(idx)]) -# endif -#endif - #if defined(FEAT_EVAL) || defined(PROTO) -# if defined(FEAT_PROFILE) || defined(FEAT_RELTIME) || defined(PROTO) -/* - * Store the current time in "tm". - */ - void -profile_start(proftime_T *tm) -{ -# ifdef MSWIN - QueryPerformanceCounter(tm); -# else - gettimeofday(tm, NULL); -# endif -} - -/* - * Compute the elapsed time from "tm" till now and store in "tm". - */ - void -profile_end(proftime_T *tm) -{ - proftime_T now; - -# ifdef MSWIN - QueryPerformanceCounter(&now); - tm->QuadPart = now.QuadPart - tm->QuadPart; -# else - gettimeofday(&now, NULL); - tm->tv_usec = now.tv_usec - tm->tv_usec; - tm->tv_sec = now.tv_sec - tm->tv_sec; - if (tm->tv_usec < 0) - { - tm->tv_usec += 1000000; - --tm->tv_sec; - } -# endif -} - -/* - * Subtract the time "tm2" from "tm". - */ - void -profile_sub(proftime_T *tm, proftime_T *tm2) -{ -# ifdef MSWIN - tm->QuadPart -= tm2->QuadPart; -# else - tm->tv_usec -= tm2->tv_usec; - tm->tv_sec -= tm2->tv_sec; - if (tm->tv_usec < 0) - { - tm->tv_usec += 1000000; - --tm->tv_sec; - } -# endif -} - -/* - * Return a string that represents the time in "tm". - * Uses a static buffer! - */ - char * -profile_msg(proftime_T *tm) -{ - static char buf[50]; - -# ifdef MSWIN - LARGE_INTEGER fr; - - QueryPerformanceFrequency(&fr); - sprintf(buf, "%10.6lf", (double)tm->QuadPart / (double)fr.QuadPart); -# else - sprintf(buf, "%3ld.%06ld", (long)tm->tv_sec, (long)tm->tv_usec); -# endif - return buf; -} - -# if defined(FEAT_FLOAT) || defined(PROTO) -/* - * Return a float that represents the time in "tm". - */ - float_T -profile_float(proftime_T *tm) -{ -# ifdef MSWIN - LARGE_INTEGER fr; - - QueryPerformanceFrequency(&fr); - return (float_T)tm->QuadPart / (float_T)fr.QuadPart; -# else - return (float_T)tm->tv_sec + (float_T)tm->tv_usec / 1000000.0; -# endif -} -# endif - -/* - * Put the time "msec" past now in "tm". - */ - void -profile_setlimit(long msec, proftime_T *tm) -{ - if (msec <= 0) /* no limit */ - profile_zero(tm); - else - { -# ifdef MSWIN - LARGE_INTEGER fr; - - QueryPerformanceCounter(tm); - QueryPerformanceFrequency(&fr); - tm->QuadPart += (LONGLONG)((double)msec / 1000.0 * (double)fr.QuadPart); -# else - long usec; - - gettimeofday(tm, NULL); - usec = (long)tm->tv_usec + (long)msec * 1000; - tm->tv_usec = usec % 1000000L; - tm->tv_sec += usec / 1000000L; -# endif - } -} - -/* - * Return TRUE if the current time is past "tm". - */ - int -profile_passed_limit(proftime_T *tm) -{ - proftime_T now; - -# ifdef MSWIN - if (tm->QuadPart == 0) /* timer was not set */ - return FALSE; - QueryPerformanceCounter(&now); - return (now.QuadPart > tm->QuadPart); -# else - if (tm->tv_sec == 0) /* timer was not set */ - return FALSE; - gettimeofday(&now, NULL); - return (now.tv_sec > tm->tv_sec - || (now.tv_sec == tm->tv_sec && now.tv_usec > tm->tv_usec)); -# endif -} - -/* - * Set the time in "tm" to zero. - */ - void -profile_zero(proftime_T *tm) -{ -# ifdef MSWIN - tm->QuadPart = 0; -# else - tm->tv_usec = 0; - tm->tv_sec = 0; -# endif -} - -# endif /* FEAT_PROFILE || FEAT_RELTIME */ - # if defined(FEAT_TIMERS) || defined(PROTO) static timer_T *first_timer = NULL; static long last_timer_id = 0; @@ -603,433 +395,6 @@ # endif # endif -#if defined(FEAT_SYN_HL) && defined(FEAT_RELTIME) && defined(FEAT_FLOAT) && defined(FEAT_PROFILE) -# if defined(HAVE_MATH_H) -# include -# endif - -/* - * Divide the time "tm" by "count" and store in "tm2". - */ - void -profile_divide(proftime_T *tm, int count, proftime_T *tm2) -{ - if (count == 0) - profile_zero(tm2); - else - { -# ifdef MSWIN - tm2->QuadPart = tm->QuadPart / count; -# else - double usec = (tm->tv_sec * 1000000.0 + tm->tv_usec) / count; - - tm2->tv_sec = floor(usec / 1000000.0); - tm2->tv_usec = vim_round(usec - (tm2->tv_sec * 1000000.0)); -# endif - } -} -#endif - -# if defined(FEAT_PROFILE) || defined(PROTO) -/* - * Functions for profiling. - */ -static void script_dump_profile(FILE *fd); -static proftime_T prof_wait_time; - -/* - * Add the time "tm2" to "tm". - */ - void -profile_add(proftime_T *tm, proftime_T *tm2) -{ -# ifdef MSWIN - tm->QuadPart += tm2->QuadPart; -# else - tm->tv_usec += tm2->tv_usec; - tm->tv_sec += tm2->tv_sec; - if (tm->tv_usec >= 1000000) - { - tm->tv_usec -= 1000000; - ++tm->tv_sec; - } -# endif -} - -/* - * Add the "self" time from the total time and the children's time. - */ - void -profile_self(proftime_T *self, proftime_T *total, proftime_T *children) -{ - /* Check that the result won't be negative. Can happen with recursive - * calls. */ -#ifdef MSWIN - if (total->QuadPart <= children->QuadPart) - return; -#else - if (total->tv_sec < children->tv_sec - || (total->tv_sec == children->tv_sec - && total->tv_usec <= children->tv_usec)) - return; -#endif - profile_add(self, total); - profile_sub(self, children); -} - -/* - * Get the current waittime. - */ - void -profile_get_wait(proftime_T *tm) -{ - *tm = prof_wait_time; -} - -/* - * Subtract the passed waittime since "tm" from "tma". - */ - void -profile_sub_wait(proftime_T *tm, proftime_T *tma) -{ - proftime_T tm3 = prof_wait_time; - - profile_sub(&tm3, tm); - profile_sub(tma, &tm3); -} - -/* - * Return TRUE if "tm1" and "tm2" are equal. - */ - int -profile_equal(proftime_T *tm1, proftime_T *tm2) -{ -# ifdef MSWIN - return (tm1->QuadPart == tm2->QuadPart); -# else - return (tm1->tv_usec == tm2->tv_usec && tm1->tv_sec == tm2->tv_sec); -# endif -} - -/* - * Return <0, 0 or >0 if "tm1" < "tm2", "tm1" == "tm2" or "tm1" > "tm2" - */ - int -profile_cmp(const proftime_T *tm1, const proftime_T *tm2) -{ -# ifdef MSWIN - return (int)(tm2->QuadPart - tm1->QuadPart); -# else - if (tm1->tv_sec == tm2->tv_sec) - return tm2->tv_usec - tm1->tv_usec; - return tm2->tv_sec - tm1->tv_sec; -# endif -} - -static char_u *profile_fname = NULL; -static proftime_T pause_time; - -/* - * ":profile cmd args" - */ - void -ex_profile(exarg_T *eap) -{ - char_u *e; - int len; - - e = skiptowhite(eap->arg); - len = (int)(e - eap->arg); - e = skipwhite(e); - - if (len == 5 && STRNCMP(eap->arg, "start", 5) == 0 && *e != NUL) - { - vim_free(profile_fname); - profile_fname = expand_env_save_opt(e, TRUE); - do_profiling = PROF_YES; - profile_zero(&prof_wait_time); - set_vim_var_nr(VV_PROFILING, 1L); - } - else if (do_profiling == PROF_NONE) - emsg(_("E750: First use \":profile start {fname}\"")); - else if (STRCMP(eap->arg, "pause") == 0) - { - if (do_profiling == PROF_YES) - profile_start(&pause_time); - do_profiling = PROF_PAUSED; - } - else if (STRCMP(eap->arg, "continue") == 0) - { - if (do_profiling == PROF_PAUSED) - { - profile_end(&pause_time); - profile_add(&prof_wait_time, &pause_time); - } - do_profiling = PROF_YES; - } - else - { - /* The rest is similar to ":breakadd". */ - ex_breakadd(eap); - } -} - -/* Command line expansion for :profile. */ -static enum -{ - PEXP_SUBCMD, /* expand :profile sub-commands */ - PEXP_FUNC /* expand :profile func {funcname} */ -} pexpand_what; - -static char *pexpand_cmds[] = { - "start", -#define PROFCMD_START 0 - "pause", -#define PROFCMD_PAUSE 1 - "continue", -#define PROFCMD_CONTINUE 2 - "func", -#define PROFCMD_FUNC 3 - "file", -#define PROFCMD_FILE 4 - NULL -#define PROFCMD_LAST 5 -}; - -/* - * Function given to ExpandGeneric() to obtain the profile command - * specific expansion. - */ - char_u * -get_profile_name(expand_T *xp UNUSED, int idx) -{ - switch (pexpand_what) - { - case PEXP_SUBCMD: - return (char_u *)pexpand_cmds[idx]; - /* case PEXP_FUNC: TODO */ - default: - return NULL; - } -} - -/* - * Handle command line completion for :profile command. - */ - void -set_context_in_profile_cmd(expand_T *xp, char_u *arg) -{ - char_u *end_subcmd; - - /* Default: expand subcommands. */ - xp->xp_context = EXPAND_PROFILE; - pexpand_what = PEXP_SUBCMD; - xp->xp_pattern = arg; - - end_subcmd = skiptowhite(arg); - if (*end_subcmd == NUL) - return; - - if (end_subcmd - arg == 5 && STRNCMP(arg, "start", 5) == 0) - { - xp->xp_context = EXPAND_FILES; - xp->xp_pattern = skipwhite(end_subcmd); - return; - } - - /* TODO: expand function names after "func" */ - xp->xp_context = EXPAND_NOTHING; -} - -/* - * Dump the profiling info. - */ - void -profile_dump(void) -{ - FILE *fd; - - if (profile_fname != NULL) - { - fd = mch_fopen((char *)profile_fname, "w"); - if (fd == NULL) - semsg(_(e_notopen), profile_fname); - else - { - script_dump_profile(fd); - func_dump_profile(fd); - fclose(fd); - } - } -} - -/* - * Start profiling script "fp". - */ - static void -script_do_profile(scriptitem_T *si) -{ - si->sn_pr_count = 0; - profile_zero(&si->sn_pr_total); - profile_zero(&si->sn_pr_self); - - ga_init2(&si->sn_prl_ga, sizeof(sn_prl_T), 100); - si->sn_prl_idx = -1; - si->sn_prof_on = TRUE; - si->sn_pr_nest = 0; -} - -/* - * Save time when starting to invoke another script or function. - */ - void -script_prof_save( - proftime_T *tm) /* place to store wait time */ -{ - scriptitem_T *si; - - if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len) - { - si = &SCRIPT_ITEM(current_sctx.sc_sid); - if (si->sn_prof_on && si->sn_pr_nest++ == 0) - profile_start(&si->sn_pr_child); - } - profile_get_wait(tm); -} - -/* - * Count time spent in children after invoking another script or function. - */ - void -script_prof_restore(proftime_T *tm) -{ - scriptitem_T *si; - - if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len) - { - si = &SCRIPT_ITEM(current_sctx.sc_sid); - if (si->sn_prof_on && --si->sn_pr_nest == 0) - { - profile_end(&si->sn_pr_child); - profile_sub_wait(tm, &si->sn_pr_child); /* don't count wait time */ - profile_add(&si->sn_pr_children, &si->sn_pr_child); - profile_add(&si->sn_prl_children, &si->sn_pr_child); - } - } -} - -static proftime_T inchar_time; - -/* - * Called when starting to wait for the user to type a character. - */ - void -prof_inchar_enter(void) -{ - profile_start(&inchar_time); -} - -/* - * Called when finished waiting for the user to type a character. - */ - void -prof_inchar_exit(void) -{ - profile_end(&inchar_time); - profile_add(&prof_wait_time, &inchar_time); -} - -/* - * Dump the profiling results for all scripts in file "fd". - */ - static void -script_dump_profile(FILE *fd) -{ - int id; - scriptitem_T *si; - int i; - FILE *sfd; - sn_prl_T *pp; - - for (id = 1; id <= script_items.ga_len; ++id) - { - si = &SCRIPT_ITEM(id); - if (si->sn_prof_on) - { - fprintf(fd, "SCRIPT %s\n", si->sn_name); - if (si->sn_pr_count == 1) - fprintf(fd, "Sourced 1 time\n"); - else - fprintf(fd, "Sourced %d times\n", si->sn_pr_count); - fprintf(fd, "Total time: %s\n", profile_msg(&si->sn_pr_total)); - fprintf(fd, " Self time: %s\n", profile_msg(&si->sn_pr_self)); - fprintf(fd, "\n"); - fprintf(fd, "count total (s) self (s)\n"); - - sfd = mch_fopen((char *)si->sn_name, "r"); - if (sfd == NULL) - fprintf(fd, "Cannot open file!\n"); - else - { - /* Keep going till the end of file, so that trailing - * continuation lines are listed. */ - for (i = 0; ; ++i) - { - if (vim_fgets(IObuff, IOSIZE, sfd)) - break; - /* When a line has been truncated, append NL, taking care - * of multi-byte characters . */ - if (IObuff[IOSIZE - 2] != NUL && IObuff[IOSIZE - 2] != NL) - { - int n = IOSIZE - 2; - - if (enc_utf8) - { - /* Move to the first byte of this char. - * utf_head_off() doesn't work, because it checks - * for a truncated character. */ - while (n > 0 && (IObuff[n] & 0xc0) == 0x80) - --n; - } - else if (has_mbyte) - n -= mb_head_off(IObuff, IObuff + n); - IObuff[n] = NL; - IObuff[n + 1] = NUL; - } - if (i < si->sn_prl_ga.ga_len - && (pp = &PRL_ITEM(si, i))->snp_count > 0) - { - fprintf(fd, "%5d ", pp->snp_count); - if (profile_equal(&pp->sn_prl_total, &pp->sn_prl_self)) - fprintf(fd, " "); - else - fprintf(fd, "%s ", profile_msg(&pp->sn_prl_total)); - fprintf(fd, "%s ", profile_msg(&pp->sn_prl_self)); - } - else - fprintf(fd, " "); - fprintf(fd, "%s", IObuff); - } - fclose(sfd); - } - fprintf(fd, "\n"); - } - } -} - -/* - * Return TRUE when a function defined in the current script should be - * profiled. - */ - int -prof_def_func(void) -{ - if (current_sctx.sc_sid > 0) - return SCRIPT_ITEM(current_sctx.sc_sid).sn_pr_force; - return FALSE; -} - -# endif #endif /* @@ -4035,91 +3400,6 @@ return NULL; } -#if defined(FEAT_PROFILE) || defined(PROTO) -/* - * Called when starting to read a script line. - * "sourcing_lnum" must be correct! - * When skipping lines it may not actually be executed, but we won't find out - * until later and we need to store the time now. - */ - void -script_line_start(void) -{ - scriptitem_T *si; - sn_prl_T *pp; - - if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) - return; - si = &SCRIPT_ITEM(current_sctx.sc_sid); - if (si->sn_prof_on && sourcing_lnum >= 1) - { - /* Grow the array before starting the timer, so that the time spent - * here isn't counted. */ - (void)ga_grow(&si->sn_prl_ga, - (int)(sourcing_lnum - si->sn_prl_ga.ga_len)); - si->sn_prl_idx = sourcing_lnum - 1; - while (si->sn_prl_ga.ga_len <= si->sn_prl_idx - && si->sn_prl_ga.ga_len < si->sn_prl_ga.ga_maxlen) - { - /* Zero counters for a line that was not used before. */ - pp = &PRL_ITEM(si, si->sn_prl_ga.ga_len); - pp->snp_count = 0; - profile_zero(&pp->sn_prl_total); - profile_zero(&pp->sn_prl_self); - ++si->sn_prl_ga.ga_len; - } - si->sn_prl_execed = FALSE; - profile_start(&si->sn_prl_start); - profile_zero(&si->sn_prl_children); - profile_get_wait(&si->sn_prl_wait); - } -} - -/* - * Called when actually executing a function line. - */ - void -script_line_exec(void) -{ - scriptitem_T *si; - - if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) - return; - si = &SCRIPT_ITEM(current_sctx.sc_sid); - if (si->sn_prof_on && si->sn_prl_idx >= 0) - si->sn_prl_execed = TRUE; -} - -/* - * Called when done with a script line. - */ - void -script_line_end(void) -{ - scriptitem_T *si; - sn_prl_T *pp; - - if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) - return; - si = &SCRIPT_ITEM(current_sctx.sc_sid); - if (si->sn_prof_on && si->sn_prl_idx >= 0 - && si->sn_prl_idx < si->sn_prl_ga.ga_len) - { - if (si->sn_prl_execed) - { - pp = &PRL_ITEM(si, si->sn_prl_idx); - ++pp->snp_count; - profile_end(&si->sn_prl_start); - profile_sub_wait(&si->sn_prl_wait, &si->sn_prl_start); - profile_add(&pp->sn_prl_total, &si->sn_prl_start); - profile_self(&pp->sn_prl_self, &si->sn_prl_start, - &si->sn_prl_children); - } - si->sn_prl_idx = -1; - } -} -#endif - /* * ":scriptencoding": Set encoding conversion for a sourced script. */ diff -Nru vim-8.1.1681/src/ex_cmds.c vim-8.1.1729/src/ex_cmds.c --- vim-8.1.1681/src/ex_cmds.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/ex_cmds.c 2019-07-21 21:04:21.000000000 +0000 @@ -20,12 +20,6 @@ static int linelen(int *has_tab); static void do_filter(linenr_T line1, linenr_T line2, exarg_T *eap, char_u *cmd, int do_in, int do_out); -#ifdef FEAT_VIMINFO -static char_u *viminfo_filename(char_u *); -static void do_viminfo(FILE *fp_in, FILE *fp_out, int flags); -static int viminfo_encoding(vir_T *virp); -static int read_viminfo_up_to_marks(vir_T *virp, int forceit, int writing); -#endif static int check_readonly(int *forceit, buf_T *buf); static void delbuf_msg(char_u *name); @@ -1849,1136 +1843,6 @@ (char *)opt, (char *)fname); } -#if defined(FEAT_VIMINFO) || defined(PROTO) - -static int read_viminfo_barline(vir_T *virp, int got_encoding, int force, int writing); -static void write_viminfo_version(FILE *fp_out); -static void write_viminfo_barlines(vir_T *virp, FILE *fp_out); -static int viminfo_errcnt; - - static int -no_viminfo(void) -{ - /* "vim -i NONE" does not read or write a viminfo file */ - return STRCMP(p_viminfofile, "NONE") == 0; -} - -/* - * Report an error for reading a viminfo file. - * Count the number of errors. When there are more than 10, return TRUE. - */ - int -viminfo_error(char *errnum, char *message, char_u *line) -{ - vim_snprintf((char *)IObuff, IOSIZE, _("%sviminfo: %s in line: "), - errnum, message); - STRNCAT(IObuff, line, IOSIZE - STRLEN(IObuff) - 1); - if (IObuff[STRLEN(IObuff) - 1] == '\n') - IObuff[STRLEN(IObuff) - 1] = NUL; - emsg((char *)IObuff); - if (++viminfo_errcnt >= 10) - { - emsg(_("E136: viminfo: Too many errors, skipping rest of file")); - return TRUE; - } - return FALSE; -} - -/* - * read_viminfo() -- Read the viminfo file. Registers etc. which are already - * set are not over-written unless "flags" includes VIF_FORCEIT. -- webb - */ - int -read_viminfo( - char_u *file, /* file name or NULL to use default name */ - int flags) /* VIF_WANT_INFO et al. */ -{ - FILE *fp; - char_u *fname; - - if (no_viminfo()) - return FAIL; - - fname = viminfo_filename(file); /* get file name in allocated buffer */ - if (fname == NULL) - return FAIL; - fp = mch_fopen((char *)fname, READBIN); - - if (p_verbose > 0) - { - verbose_enter(); - smsg(_("Reading viminfo file \"%s\"%s%s%s"), - fname, - (flags & VIF_WANT_INFO) ? _(" info") : "", - (flags & VIF_WANT_MARKS) ? _(" marks") : "", - (flags & VIF_GET_OLDFILES) ? _(" oldfiles") : "", - fp == NULL ? _(" FAILED") : ""); - verbose_leave(); - } - - vim_free(fname); - if (fp == NULL) - return FAIL; - - viminfo_errcnt = 0; - do_viminfo(fp, NULL, flags); - - fclose(fp); - return OK; -} - -/* - * Write the viminfo file. The old one is read in first so that effectively a - * merge of current info and old info is done. This allows multiple vims to - * run simultaneously, without losing any marks etc. - * If "forceit" is TRUE, then the old file is not read in, and only internal - * info is written to the file. - */ - void -write_viminfo(char_u *file, int forceit) -{ - char_u *fname; - FILE *fp_in = NULL; /* input viminfo file, if any */ - FILE *fp_out = NULL; /* output viminfo file */ - char_u *tempname = NULL; /* name of temp viminfo file */ - stat_T st_new; /* mch_stat() of potential new file */ -#if defined(UNIX) || defined(VMS) - mode_t umask_save; -#endif -#ifdef UNIX - int shortname = FALSE; /* use 8.3 file name */ - stat_T st_old; /* mch_stat() of existing viminfo file */ -#endif -#ifdef MSWIN - int hidden = FALSE; -#endif - - if (no_viminfo()) - return; - - fname = viminfo_filename(file); /* may set to default if NULL */ - if (fname == NULL) - return; - - fp_in = mch_fopen((char *)fname, READBIN); - if (fp_in == NULL) - { - int fd; - - /* if it does exist, but we can't read it, don't try writing */ - if (mch_stat((char *)fname, &st_new) == 0) - goto end; - - /* Create the new .viminfo non-accessible for others, because it may - * contain text from non-accessible documents. It is up to the user to - * widen access (e.g. to a group). This may also fail if there is a - * race condition, then just give up. */ - fd = mch_open((char *)fname, - O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW, 0600); - if (fd < 0) - goto end; - fp_out = fdopen(fd, WRITEBIN); - } - else - { - /* - * There is an existing viminfo file. Create a temporary file to - * write the new viminfo into, in the same directory as the - * existing viminfo file, which will be renamed once all writing is - * successful. - */ -#ifdef UNIX - /* - * For Unix we check the owner of the file. It's not very nice to - * overwrite a user's viminfo file after a "su root", with a - * viminfo file that the user can't read. - */ - st_old.st_dev = (dev_t)0; - st_old.st_ino = 0; - st_old.st_mode = 0600; - if (mch_stat((char *)fname, &st_old) == 0 - && getuid() != ROOT_UID - && !(st_old.st_uid == getuid() - ? (st_old.st_mode & 0200) - : (st_old.st_gid == getgid() - ? (st_old.st_mode & 0020) - : (st_old.st_mode & 0002)))) - { - int tt = msg_didany; - - /* avoid a wait_return for this message, it's annoying */ - semsg(_("E137: Viminfo file is not writable: %s"), fname); - msg_didany = tt; - fclose(fp_in); - goto end; - } -#endif -#ifdef MSWIN - /* Get the file attributes of the existing viminfo file. */ - hidden = mch_ishidden(fname); -#endif - - /* - * Make tempname, find one that does not exist yet. - * Beware of a race condition: If someone logs out and all Vim - * instances exit at the same time a temp file might be created between - * stat() and open(). Use mch_open() with O_EXCL to avoid that. - * May try twice: Once normal and once with shortname set, just in - * case somebody puts his viminfo file in an 8.3 filesystem. - */ - for (;;) - { - int next_char = 'z'; - char_u *wp; - - tempname = buf_modname( -#ifdef UNIX - shortname, -#else - FALSE, -#endif - fname, -#ifdef VMS - (char_u *)"-tmp", -#else - (char_u *)".tmp", -#endif - FALSE); - if (tempname == NULL) /* out of memory */ - break; - - /* - * Try a series of names. Change one character, just before - * the extension. This should also work for an 8.3 - * file name, when after adding the extension it still is - * the same file as the original. - */ - wp = tempname + STRLEN(tempname) - 5; - if (wp < gettail(tempname)) /* empty file name? */ - wp = gettail(tempname); - for (;;) - { - /* - * Check if tempfile already exists. Never overwrite an - * existing file! - */ - if (mch_stat((char *)tempname, &st_new) == 0) - { -#ifdef UNIX - /* - * Check if tempfile is same as original file. May happen - * when modname() gave the same file back. E.g. silly - * link, or file name-length reached. Try again with - * shortname set. - */ - if (!shortname && st_new.st_dev == st_old.st_dev - && st_new.st_ino == st_old.st_ino) - { - VIM_CLEAR(tempname); - shortname = TRUE; - break; - } -#endif - } - else - { - /* Try creating the file exclusively. This may fail if - * another Vim tries to do it at the same time. */ -#ifdef VMS - /* fdopen() fails for some reason */ - umask_save = umask(077); - fp_out = mch_fopen((char *)tempname, WRITEBIN); - (void)umask(umask_save); -#else - int fd; - - /* Use mch_open() to be able to use O_NOFOLLOW and set file - * protection: - * Unix: same as original file, but strip s-bit. Reset - * umask to avoid it getting in the way. - * Others: r&w for user only. */ -# ifdef UNIX - umask_save = umask(0); - fd = mch_open((char *)tempname, - O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW, - (int)((st_old.st_mode & 0777) | 0600)); - (void)umask(umask_save); -# else - fd = mch_open((char *)tempname, - O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW, 0600); -# endif - if (fd < 0) - { - fp_out = NULL; -# ifdef EEXIST - /* Avoid trying lots of names while the problem is lack - * of permission, only retry if the file already - * exists. */ - if (errno != EEXIST) - break; -# endif - } - else - fp_out = fdopen(fd, WRITEBIN); -#endif /* VMS */ - if (fp_out != NULL) - break; - } - - /* Assume file exists, try again with another name. */ - if (next_char == 'a' - 1) - { - /* They all exist? Must be something wrong! Don't write - * the viminfo file then. */ - semsg(_("E929: Too many viminfo temp files, like %s!"), - tempname); - break; - } - *wp = next_char; - --next_char; - } - - if (tempname != NULL) - break; - /* continue if shortname was set */ - } - -#if defined(UNIX) && defined(HAVE_FCHOWN) - if (tempname != NULL && fp_out != NULL) - { - stat_T tmp_st; - - /* - * Make sure the original owner can read/write the tempfile and - * otherwise preserve permissions, making sure the group matches. - */ - if (mch_stat((char *)tempname, &tmp_st) >= 0) - { - if (st_old.st_uid != tmp_st.st_uid) - /* Changing the owner might fail, in which case the - * file will now owned by the current user, oh well. */ - vim_ignored = fchown(fileno(fp_out), st_old.st_uid, -1); - if (st_old.st_gid != tmp_st.st_gid - && fchown(fileno(fp_out), -1, st_old.st_gid) == -1) - /* can't set the group to what it should be, remove - * group permissions */ - (void)mch_setperm(tempname, 0600); - } - else - /* can't stat the file, set conservative permissions */ - (void)mch_setperm(tempname, 0600); - } -#endif - } - - /* - * Check if the new viminfo file can be written to. - */ - if (fp_out == NULL) - { - semsg(_("E138: Can't write viminfo file %s!"), - (fp_in == NULL || tempname == NULL) ? fname : tempname); - if (fp_in != NULL) - fclose(fp_in); - goto end; - } - - if (p_verbose > 0) - { - verbose_enter(); - smsg(_("Writing viminfo file \"%s\""), fname); - verbose_leave(); - } - - viminfo_errcnt = 0; - do_viminfo(fp_in, fp_out, forceit ? 0 : (VIF_WANT_INFO | VIF_WANT_MARKS)); - - if (fclose(fp_out) == EOF) - ++viminfo_errcnt; - - if (fp_in != NULL) - { - fclose(fp_in); - - /* In case of an error keep the original viminfo file. Otherwise - * rename the newly written file. Give an error if that fails. */ - if (viminfo_errcnt == 0) - { - if (vim_rename(tempname, fname) == -1) - { - ++viminfo_errcnt; - semsg(_("E886: Can't rename viminfo file to %s!"), fname); - } -# ifdef MSWIN - /* If the viminfo file was hidden then also hide the new file. */ - else if (hidden) - mch_hide(fname); -# endif - } - if (viminfo_errcnt > 0) - mch_remove(tempname); - } - -end: - vim_free(fname); - vim_free(tempname); -} - -/* - * Get the viminfo file name to use. - * If "file" is given and not empty, use it (has already been expanded by - * cmdline functions). - * Otherwise use "-i file_name", value from 'viminfo' or the default, and - * expand environment variables. - * Returns an allocated string. NULL when out of memory. - */ - static char_u * -viminfo_filename(char_u *file) -{ - if (file == NULL || *file == NUL) - { - if (*p_viminfofile != NUL) - file = p_viminfofile; - else if ((file = find_viminfo_parameter('n')) == NULL || *file == NUL) - { -#ifdef VIMINFO_FILE2 -# ifdef VMS - if (mch_getenv((char_u *)"SYS$LOGIN") == NULL) -# else -# ifdef MSWIN - /* Use $VIM only if $HOME is the default "C:/". */ - if (STRCMP(vim_getenv((char_u *)"HOME", NULL), "C:/") == 0 - && mch_getenv((char_u *)"HOME") == NULL) -# else - if (mch_getenv((char_u *)"HOME") == NULL) -# endif -# endif - { - /* don't use $VIM when not available. */ - expand_env((char_u *)"$VIM", NameBuff, MAXPATHL); - if (STRCMP("$VIM", NameBuff) != 0) /* $VIM was expanded */ - file = (char_u *)VIMINFO_FILE2; - else - file = (char_u *)VIMINFO_FILE; - } - else -#endif - file = (char_u *)VIMINFO_FILE; - } - expand_env(file, NameBuff, MAXPATHL); - file = NameBuff; - } - return vim_strsave(file); -} - -/* - * do_viminfo() -- Should only be called from read_viminfo() & write_viminfo(). - */ - static void -do_viminfo(FILE *fp_in, FILE *fp_out, int flags) -{ - int eof = FALSE; - vir_T vir; - int merge = FALSE; - int do_copy_marks = FALSE; - garray_T buflist; - - if ((vir.vir_line = alloc(LSIZE)) == NULL) - return; - vir.vir_fd = fp_in; - vir.vir_conv.vc_type = CONV_NONE; - ga_init2(&vir.vir_barlines, (int)sizeof(char_u *), 100); - vir.vir_version = -1; - - if (fp_in != NULL) - { - if (flags & VIF_WANT_INFO) - { - if (fp_out != NULL) - { - /* Registers and marks are read and kept separate from what - * this Vim is using. They are merged when writing. */ - prepare_viminfo_registers(); - prepare_viminfo_marks(); - } - - eof = read_viminfo_up_to_marks(&vir, - flags & VIF_FORCEIT, fp_out != NULL); - merge = TRUE; - } - else if (flags != 0) - /* Skip info, find start of marks */ - while (!(eof = viminfo_readline(&vir)) - && vir.vir_line[0] != '>') - ; - - do_copy_marks = (flags & - (VIF_WANT_MARKS | VIF_GET_OLDFILES | VIF_FORCEIT)); - } - - if (fp_out != NULL) - { - /* Write the info: */ - fprintf(fp_out, _("# This viminfo file was generated by Vim %s.\n"), - VIM_VERSION_MEDIUM); - fputs(_("# You may edit it if you're careful!\n\n"), fp_out); - write_viminfo_version(fp_out); - fputs(_("# Value of 'encoding' when this file was written\n"), fp_out); - fprintf(fp_out, "*encoding=%s\n\n", p_enc); - write_viminfo_search_pattern(fp_out); - write_viminfo_sub_string(fp_out); -#ifdef FEAT_CMDHIST - write_viminfo_history(fp_out, merge); -#endif - write_viminfo_registers(fp_out); - finish_viminfo_registers(); -#ifdef FEAT_EVAL - write_viminfo_varlist(fp_out); -#endif - write_viminfo_filemarks(fp_out); - finish_viminfo_marks(); - write_viminfo_bufferlist(fp_out); - write_viminfo_barlines(&vir, fp_out); - - if (do_copy_marks) - ga_init2(&buflist, sizeof(buf_T *), 50); - write_viminfo_marks(fp_out, do_copy_marks ? &buflist : NULL); - } - - if (do_copy_marks) - { - copy_viminfo_marks(&vir, fp_out, &buflist, eof, flags); - if (fp_out != NULL) - ga_clear(&buflist); - } - - vim_free(vir.vir_line); - if (vir.vir_conv.vc_type != CONV_NONE) - convert_setup(&vir.vir_conv, NULL, NULL); - ga_clear_strings(&vir.vir_barlines); -} - -/* - * read_viminfo_up_to_marks() -- Only called from do_viminfo(). Reads in the - * first part of the viminfo file which contains everything but the marks that - * are local to a file. Returns TRUE when end-of-file is reached. -- webb - */ - static int -read_viminfo_up_to_marks( - vir_T *virp, - int forceit, - int writing) -{ - int eof; - buf_T *buf; - int got_encoding = FALSE; - -#ifdef FEAT_CMDHIST - prepare_viminfo_history(forceit ? 9999 : 0, writing); -#endif - - eof = viminfo_readline(virp); - while (!eof && virp->vir_line[0] != '>') - { - switch (virp->vir_line[0]) - { - /* Characters reserved for future expansion, ignored now */ - case '+': /* "+40 /path/dir file", for running vim without args */ - case '^': /* to be defined */ - case '<': /* long line - ignored */ - /* A comment or empty line. */ - case NUL: - case '\r': - case '\n': - case '#': - eof = viminfo_readline(virp); - break; - case '|': - eof = read_viminfo_barline(virp, got_encoding, - forceit, writing); - break; - case '*': /* "*encoding=value" */ - got_encoding = TRUE; - eof = viminfo_encoding(virp); - break; - case '!': /* global variable */ -#ifdef FEAT_EVAL - eof = read_viminfo_varlist(virp, writing); -#else - eof = viminfo_readline(virp); -#endif - break; - case '%': /* entry for buffer list */ - eof = read_viminfo_bufferlist(virp, writing); - break; - case '"': - /* When registers are in bar lines skip the old style register - * lines. */ - if (virp->vir_version < VIMINFO_VERSION_WITH_REGISTERS) - eof = read_viminfo_register(virp, forceit); - else - do { - eof = viminfo_readline(virp); - } while (!eof && (virp->vir_line[0] == TAB - || virp->vir_line[0] == '<')); - break; - case '/': /* Search string */ - case '&': /* Substitute search string */ - case '~': /* Last search string, followed by '/' or '&' */ - eof = read_viminfo_search_pattern(virp, forceit); - break; - case '$': - eof = read_viminfo_sub_string(virp, forceit); - break; - case ':': - case '?': - case '=': - case '@': -#ifdef FEAT_CMDHIST - /* When history is in bar lines skip the old style history - * lines. */ - if (virp->vir_version < VIMINFO_VERSION_WITH_HISTORY) - eof = read_viminfo_history(virp, writing); - else -#endif - eof = viminfo_readline(virp); - break; - case '-': - case '\'': - /* When file marks are in bar lines skip the old style lines. */ - if (virp->vir_version < VIMINFO_VERSION_WITH_MARKS) - eof = read_viminfo_filemark(virp, forceit); - else - eof = viminfo_readline(virp); - break; - default: - if (viminfo_error("E575: ", _("Illegal starting char"), - virp->vir_line)) - eof = TRUE; - else - eof = viminfo_readline(virp); - break; - } - } - -#ifdef FEAT_CMDHIST - /* Finish reading history items. */ - if (!writing) - finish_viminfo_history(virp); -#endif - - /* Change file names to buffer numbers for fmarks. */ - FOR_ALL_BUFFERS(buf) - fmarks_check_names(buf); - - return eof; -} - -/* - * Compare the 'encoding' value in the viminfo file with the current value of - * 'encoding'. If different and the 'c' flag is in 'viminfo', setup for - * conversion of text with iconv() in viminfo_readstring(). - */ - static int -viminfo_encoding(vir_T *virp) -{ - char_u *p; - int i; - - if (get_viminfo_parameter('c') != 0) - { - p = vim_strchr(virp->vir_line, '='); - if (p != NULL) - { - /* remove trailing newline */ - ++p; - for (i = 0; vim_isprintc(p[i]); ++i) - ; - p[i] = NUL; - - convert_setup(&virp->vir_conv, p, p_enc); - } - } - return viminfo_readline(virp); -} - -/* - * Read a line from the viminfo file. - * Returns TRUE for end-of-file; - */ - int -viminfo_readline(vir_T *virp) -{ - return vim_fgets(virp->vir_line, LSIZE, virp->vir_fd); -} - -/* - * Check string read from viminfo file. - * Remove '\n' at the end of the line. - * - replace CTRL-V CTRL-V with CTRL-V - * - replace CTRL-V 'n' with '\n' - * - * Check for a long line as written by viminfo_writestring(). - * - * Return the string in allocated memory (NULL when out of memory). - */ - char_u * -viminfo_readstring( - vir_T *virp, - int off, /* offset for virp->vir_line */ - int convert UNUSED) /* convert the string */ -{ - char_u *retval; - char_u *s, *d; - long len; - - if (virp->vir_line[off] == Ctrl_V && vim_isdigit(virp->vir_line[off + 1])) - { - len = atol((char *)virp->vir_line + off + 1); - retval = alloc(len); - if (retval == NULL) - { - /* Line too long? File messed up? Skip next line. */ - (void)vim_fgets(virp->vir_line, 10, virp->vir_fd); - return NULL; - } - (void)vim_fgets(retval, (int)len, virp->vir_fd); - s = retval + 1; /* Skip the leading '<' */ - } - else - { - retval = vim_strsave(virp->vir_line + off); - if (retval == NULL) - return NULL; - s = retval; - } - - /* Change CTRL-V CTRL-V to CTRL-V and CTRL-V n to \n in-place. */ - d = retval; - while (*s != NUL && *s != '\n') - { - if (s[0] == Ctrl_V && s[1] != NUL) - { - if (s[1] == 'n') - *d++ = '\n'; - else - *d++ = Ctrl_V; - s += 2; - } - else - *d++ = *s++; - } - *d = NUL; - - if (convert && virp->vir_conv.vc_type != CONV_NONE && *retval != NUL) - { - d = string_convert(&virp->vir_conv, retval, NULL); - if (d != NULL) - { - vim_free(retval); - retval = d; - } - } - - return retval; -} - -/* - * write string to viminfo file - * - replace CTRL-V with CTRL-V CTRL-V - * - replace '\n' with CTRL-V 'n' - * - add a '\n' at the end - * - * For a long line: - * - write " CTRL-V \n " in first line - * - write " < \n " in second line - */ - void -viminfo_writestring(FILE *fd, char_u *p) -{ - int c; - char_u *s; - int len = 0; - - for (s = p; *s != NUL; ++s) - { - if (*s == Ctrl_V || *s == '\n') - ++len; - ++len; - } - - /* If the string will be too long, write its length and put it in the next - * line. Take into account that some room is needed for what comes before - * the string (e.g., variable name). Add something to the length for the - * '<', NL and trailing NUL. */ - if (len > LSIZE / 2) - fprintf(fd, IF_EB("\026%d\n<", CTRL_V_STR "%d\n<"), len + 3); - - while ((c = *p++) != NUL) - { - if (c == Ctrl_V || c == '\n') - { - putc(Ctrl_V, fd); - if (c == '\n') - c = 'n'; - } - putc(c, fd); - } - putc('\n', fd); -} - -/* - * Write a string in quotes that barline_parse() can read back. - * Breaks the line in less than LSIZE pieces when needed. - * Returns remaining characters in the line. - */ - int -barline_writestring(FILE *fd, char_u *s, int remaining_start) -{ - char_u *p; - int remaining = remaining_start; - int len = 2; - - /* Count the number of characters produced, including quotes. */ - for (p = s; *p != NUL; ++p) - { - if (*p == NL) - len += 2; - else if (*p == '"' || *p == '\\') - len += 2; - else - ++len; - } - if (len > remaining - 2) - { - fprintf(fd, ">%d\n|<", len); - remaining = LSIZE - 20; - } - - putc('"', fd); - for (p = s; *p != NUL; ++p) - { - if (*p == NL) - { - putc('\\', fd); - putc('n', fd); - --remaining; - } - else if (*p == '"' || *p == '\\') - { - putc('\\', fd); - putc(*p, fd); - --remaining; - } - else - putc(*p, fd); - --remaining; - - if (remaining < 3) - { - putc('\n', fd); - putc('|', fd); - putc('<', fd); - /* Leave enough space for another continuation. */ - remaining = LSIZE - 20; - } - } - putc('"', fd); - return remaining - 2; -} - -/* - * Parse a viminfo line starting with '|'. - * Add each decoded value to "values". - * Returns TRUE if the next line is to be read after using the parsed values. - */ - static int -barline_parse(vir_T *virp, char_u *text, garray_T *values) -{ - char_u *p = text; - char_u *nextp = NULL; - char_u *buf = NULL; - bval_T *value; - int i; - int allocated = FALSE; - int eof; - char_u *sconv; - int converted; - - while (*p == ',') - { - ++p; - if (ga_grow(values, 1) == FAIL) - break; - value = (bval_T *)(values->ga_data) + values->ga_len; - - if (*p == '>') - { - /* Need to read a continuation line. Put strings in allocated - * memory, because virp->vir_line is overwritten. */ - if (!allocated) - { - for (i = 0; i < values->ga_len; ++i) - { - bval_T *vp = (bval_T *)(values->ga_data) + i; - - if (vp->bv_type == BVAL_STRING && !vp->bv_allocated) - { - vp->bv_string = vim_strnsave(vp->bv_string, vp->bv_len); - vp->bv_allocated = TRUE; - } - } - allocated = TRUE; - } - - if (vim_isdigit(p[1])) - { - size_t len; - size_t todo; - size_t n; - - /* String value was split into lines that are each shorter - * than LSIZE: - * |{bartype},>{length of "{text}{text2}"} - * |<"{text1} - * |<{text2}",{value} - * Length includes the quotes. - */ - ++p; - len = getdigits(&p); - buf = alloc(len + 1); - if (buf == NULL) - return TRUE; - p = buf; - for (todo = len; todo > 0; todo -= n) - { - eof = viminfo_readline(virp); - if (eof || virp->vir_line[0] != '|' - || virp->vir_line[1] != '<') - { - /* File was truncated or garbled. Read another line if - * this one starts with '|'. */ - vim_free(buf); - return eof || virp->vir_line[0] == '|'; - } - /* Get length of text, excluding |< and NL chars. */ - n = STRLEN(virp->vir_line); - while (n > 0 && (virp->vir_line[n - 1] == NL - || virp->vir_line[n - 1] == CAR)) - --n; - n -= 2; - if (n > todo) - { - /* more values follow after the string */ - nextp = virp->vir_line + 2 + todo; - n = todo; - } - mch_memmove(p, virp->vir_line + 2, n); - p += n; - } - *p = NUL; - p = buf; - } - else - { - /* Line ending in ">" continues in the next line: - * |{bartype},{lots of values},> - * |<{value},{value} - */ - eof = viminfo_readline(virp); - if (eof || virp->vir_line[0] != '|' - || virp->vir_line[1] != '<') - /* File was truncated or garbled. Read another line if - * this one starts with '|'. */ - return eof || virp->vir_line[0] == '|'; - p = virp->vir_line + 2; - } - } - - if (isdigit(*p)) - { - value->bv_type = BVAL_NR; - value->bv_nr = getdigits(&p); - ++values->ga_len; - } - else if (*p == '"') - { - int len = 0; - char_u *s = p; - - /* Unescape special characters in-place. */ - ++p; - while (*p != '"') - { - if (*p == NL || *p == NUL) - return TRUE; /* syntax error, drop the value */ - if (*p == '\\') - { - ++p; - if (*p == 'n') - s[len++] = '\n'; - else - s[len++] = *p; - ++p; - } - else - s[len++] = *p++; - } - ++p; - s[len] = NUL; - - converted = FALSE; - if (virp->vir_conv.vc_type != CONV_NONE && *s != NUL) - { - sconv = string_convert(&virp->vir_conv, s, NULL); - if (sconv != NULL) - { - if (s == buf) - vim_free(s); - s = sconv; - buf = s; - converted = TRUE; - } - } - - /* Need to copy in allocated memory if the string wasn't allocated - * above and we did allocate before, thus vir_line may change. */ - if (s != buf && allocated) - s = vim_strsave(s); - value->bv_string = s; - value->bv_type = BVAL_STRING; - value->bv_len = len; - value->bv_allocated = allocated || converted; - ++values->ga_len; - if (nextp != NULL) - { - /* values following a long string */ - p = nextp; - nextp = NULL; - } - } - else if (*p == ',') - { - value->bv_type = BVAL_EMPTY; - ++values->ga_len; - } - else - break; - } - return TRUE; -} - - static int -read_viminfo_barline(vir_T *virp, int got_encoding, int force, int writing) -{ - char_u *p = virp->vir_line + 1; - int bartype; - garray_T values; - bval_T *vp; - int i; - int read_next = TRUE; - - /* The format is: |{bartype},{value},... - * For a very long string: - * |{bartype},>{length of "{text}{text2}"} - * |<{text1} - * |<{text2},{value} - * For a long line not using a string - * |{bartype},{lots of values},> - * |<{value},{value} - */ - if (*p == '<') - { - /* Continuation line of an unrecognized item. */ - if (writing) - ga_add_string(&virp->vir_barlines, virp->vir_line); - } - else - { - ga_init2(&values, sizeof(bval_T), 20); - bartype = getdigits(&p); - switch (bartype) - { - case BARTYPE_VERSION: - /* Only use the version when it comes before the encoding. - * If it comes later it was copied by a Vim version that - * doesn't understand the version. */ - if (!got_encoding) - { - read_next = barline_parse(virp, p, &values); - vp = (bval_T *)values.ga_data; - if (values.ga_len > 0 && vp->bv_type == BVAL_NR) - virp->vir_version = vp->bv_nr; - } - break; - - case BARTYPE_HISTORY: - read_next = barline_parse(virp, p, &values); - handle_viminfo_history(&values, writing); - break; - - case BARTYPE_REGISTER: - read_next = barline_parse(virp, p, &values); - handle_viminfo_register(&values, force); - break; - - case BARTYPE_MARK: - read_next = barline_parse(virp, p, &values); - handle_viminfo_mark(&values, force); - break; - - default: - /* copy unrecognized line (for future use) */ - if (writing) - ga_add_string(&virp->vir_barlines, virp->vir_line); - } - for (i = 0; i < values.ga_len; ++i) - { - vp = (bval_T *)values.ga_data + i; - if (vp->bv_type == BVAL_STRING && vp->bv_allocated) - vim_free(vp->bv_string); - } - ga_clear(&values); - } - - if (read_next) - return viminfo_readline(virp); - return FALSE; -} - - static void -write_viminfo_version(FILE *fp_out) -{ - fprintf(fp_out, "# Viminfo version\n|%d,%d\n\n", - BARTYPE_VERSION, VIMINFO_VERSION); -} - - static void -write_viminfo_barlines(vir_T *virp, FILE *fp_out) -{ - int i; - garray_T *gap = &virp->vir_barlines; - int seen_useful = FALSE; - char *line; - - if (gap->ga_len > 0) - { - fputs(_("\n# Bar lines, copied verbatim:\n"), fp_out); - - /* Skip over continuation lines until seeing a useful line. */ - for (i = 0; i < gap->ga_len; ++i) - { - line = ((char **)(gap->ga_data))[i]; - if (seen_useful || line[1] != '<') - { - fputs(line, fp_out); - seen_useful = TRUE; - } - } - } -} -#endif /* FEAT_VIMINFO */ - /* * Return the current time in seconds. Calls time(), unless test_settime() * was used. @@ -6240,7 +5104,7 @@ viminfo_writestring(fp, old_sub); } } -#endif /* FEAT_VIMINFO */ +#endif // FEAT_VIMINFO #if defined(EXITFREE) || defined(PROTO) void @@ -6270,9 +5134,20 @@ */ if (!curwin->w_p_pvw) { - FOR_ALL_WINDOWS(wp) - if (wp->w_p_pvw) - break; +# ifdef FEAT_TEXT_PROP + if (*p_pvp != NUL) + { + wp = popup_find_preview_window(); + if (wp != NULL) + popup_set_wantpos(wp); + } + else +# endif + { + FOR_ALL_WINDOWS(wp) + if (wp->w_p_pvw) + break; + } if (wp != NULL) win_enter(wp, undo_sync); else @@ -6280,18 +5155,21 @@ /* * There is no preview window open yet. Create one. */ - if (win_split(g_do_tagpreview > 0 ? g_do_tagpreview : 0, 0) - == FAIL) +# ifdef FEAT_TEXT_PROP + if (*p_pvp != NUL) + return popup_create_preview_window(); +# endif + if (win_split(g_do_tagpreview > 0 ? g_do_tagpreview : 0, 0) == FAIL) return FALSE; curwin->w_p_pvw = TRUE; curwin->w_p_wfh = TRUE; - RESET_BINDING(curwin); /* don't take over 'scrollbind' - and 'cursorbind' */ + RESET_BINDING(curwin); // don't take over 'scrollbind' + // and 'cursorbind' # ifdef FEAT_DIFF - curwin->w_p_diff = FALSE; /* no 'diff' */ + curwin->w_p_diff = FALSE; // no 'diff' # endif # ifdef FEAT_FOLDING - curwin->w_p_fdc = 0; /* no 'foldcolumn' */ + curwin->w_p_fdc = 0; // no 'foldcolumn' # endif return TRUE; } diff -Nru vim-8.1.1681/src/ex_docmd.c vim-8.1.1729/src/ex_docmd.c --- vim-8.1.1681/src/ex_docmd.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/ex_docmd.c 2019-07-21 21:04:21.000000000 +0000 @@ -318,9 +318,7 @@ #ifndef FEAT_EVAL # define ex_compiler ex_ni #endif -#ifdef FEAT_VIMINFO -static void ex_viminfo(exarg_T *eap); -#else +#ifndef FEAT_VIMINFO # define ex_viminfo ex_ni #endif static void ex_behave(exarg_T *eap); @@ -5893,12 +5891,17 @@ { win_T *win; + // First close any normal window. FOR_ALL_WINDOWS(win) if (win->w_p_pvw) { ex_win_close(eap->forceit, win, NULL); - break; + return; } +# ifdef FEAT_TEXT_PROP + // Also when 'previewpopup' is empty, it might have been cleared. + popup_close_preview(); +# endif } #endif @@ -10708,31 +10711,6 @@ return OK; } -#ifdef FEAT_VIMINFO -/* - * ":rviminfo" and ":wviminfo". - */ - static void -ex_viminfo( - exarg_T *eap) -{ - char_u *save_viminfo; - - save_viminfo = p_viminfo; - if (*p_viminfo == NUL) - p_viminfo = (char_u *)"'100"; - if (eap->cmdidx == CMD_rviminfo) - { - if (read_viminfo(eap->arg, VIF_WANT_INFO | VIF_WANT_MARKS - | (eap->forceit ? VIF_FORCEIT : 0)) == FAIL) - emsg(_("E195: Cannot open viminfo file for reading")); - } - else - write_viminfo(eap->arg, eap->forceit); - p_viminfo = save_viminfo; -} -#endif - #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) || defined(PROTO) /* * Make a dialog message in "buff[DIALOG_MSG_SIZE]". diff -Nru vim-8.1.1681/src/ex_getln.c vim-8.1.1729/src/ex_getln.c --- vim-8.1.1681/src/ex_getln.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/ex_getln.c 2019-07-21 21:04:21.000000000 +0000 @@ -60,21 +60,11 @@ static int extra_char_shift; #ifdef FEAT_CMDHIST -typedef struct hist_entry -{ - int hisnum; /* identifying number */ - int viminfo; /* when TRUE hisstr comes from viminfo */ - char_u *hisstr; /* actual entry, separator char after the NUL */ - time_t time_set; /* when it was typed, zero if unknown */ -} histentry_T; - static histentry_T *(history[HIST_COUNT]) = {NULL, NULL, NULL, NULL, NULL}; static int hisidx[HIST_COUNT] = {-1, -1, -1, -1, -1}; /* lastused entry */ static int hisnum[HIST_COUNT] = {0, 0, 0, 0, 0}; /* identifying (unique) number of newest history entry */ static int hislen = 0; /* actual length of history tables */ - -static int hist_char2type(int c); #endif #ifdef FEAT_RIGHTLEFT @@ -116,9 +106,6 @@ static int ExpandUserList(expand_T *xp, int *num_file, char_u ***file); # endif #endif -#ifdef FEAT_CMDHIST -static void clear_hist_entry(histentry_T *hisptr); -#endif #ifdef FEAT_CMDWIN static int open_cmdwin(void); @@ -713,6 +700,7 @@ save_viewstate(&is_state->old_viewstate); update_screen(NOT_VALID); redrawcmdline(); + curwin->w_cursor = is_state->match_end; } else vim_beep(BO_ERROR); @@ -5872,7 +5860,7 @@ /* * Translate a history character to the associated type number. */ - static int + int hist_char2type(int c) { if (c == ':') @@ -6009,7 +5997,7 @@ } } - static void + void clear_hist_entry(histentry_T *hisptr) { hisptr->hisnum = 0; @@ -6022,7 +6010,7 @@ * Check if command line 'str' is already in history. * If 'move_to_front' is TRUE, matching entry is moved to end of history. */ - static int + int in_history( int type, char_u *str, @@ -6628,479 +6616,37 @@ #endif #if (defined(FEAT_VIMINFO) && defined(FEAT_CMDHIST)) || defined(PROTO) -/* - * Buffers for history read from a viminfo file. Only valid while reading. - */ -static histentry_T *viminfo_history[HIST_COUNT] = - {NULL, NULL, NULL, NULL, NULL}; -static int viminfo_hisidx[HIST_COUNT] = {0, 0, 0, 0, 0}; -static int viminfo_hislen[HIST_COUNT] = {0, 0, 0, 0, 0}; -static int viminfo_add_at_front = FALSE; - -/* - * Translate a history type number to the associated character. - */ - static int -hist_type2char( - int type, - int use_question) /* use '?' instead of '/' */ -{ - if (type == HIST_CMD) - return ':'; - if (type == HIST_SEARCH) - { - if (use_question) - return '?'; - else - return '/'; - } - if (type == HIST_EXPR) - return '='; - return '@'; -} - -/* - * Prepare for reading the history from the viminfo file. - * This allocates history arrays to store the read history lines. - */ - void -prepare_viminfo_history(int asklen, int writing) + int +get_hislen(void) { - int i; - int num; - int type; - int len; - - init_history(); - viminfo_add_at_front = (asklen != 0 && !writing); - if (asklen > hislen) - asklen = hislen; - - for (type = 0; type < HIST_COUNT; ++type) - { - /* Count the number of empty spaces in the history list. Entries read - * from viminfo previously are also considered empty. If there are - * more spaces available than we request, then fill them up. */ - for (i = 0, num = 0; i < hislen; i++) - if (history[type][i].hisstr == NULL || history[type][i].viminfo) - num++; - len = asklen; - if (num > len) - len = num; - if (len <= 0) - viminfo_history[type] = NULL; - else - viminfo_history[type] = LALLOC_MULT(histentry_T, len); - if (viminfo_history[type] == NULL) - len = 0; - viminfo_hislen[type] = len; - viminfo_hisidx[type] = 0; - } + return hislen; } -/* - * Accept a line from the viminfo, store it in the history array when it's - * new. - */ - int -read_viminfo_history(vir_T *virp, int writing) + histentry_T * +get_histentry(int hist_type) { - int type; - long_u len; - char_u *val; - char_u *p; - - type = hist_char2type(virp->vir_line[0]); - if (viminfo_hisidx[type] < viminfo_hislen[type]) - { - val = viminfo_readstring(virp, 1, TRUE); - if (val != NULL && *val != NUL) - { - int sep = (*val == ' ' ? NUL : *val); - - if (!in_history(type, val + (type == HIST_SEARCH), - viminfo_add_at_front, sep, writing)) - { - /* Need to re-allocate to append the separator byte. */ - len = STRLEN(val); - p = alloc(len + 2); - if (p != NULL) - { - if (type == HIST_SEARCH) - { - /* Search entry: Move the separator from the first - * column to after the NUL. */ - mch_memmove(p, val + 1, (size_t)len); - p[len] = sep; - } - else - { - /* Not a search entry: No separator in the viminfo - * file, add a NUL separator. */ - mch_memmove(p, val, (size_t)len + 1); - p[len + 1] = NUL; - } - viminfo_history[type][viminfo_hisidx[type]].hisstr = p; - viminfo_history[type][viminfo_hisidx[type]].time_set = 0; - viminfo_history[type][viminfo_hisidx[type]].viminfo = TRUE; - viminfo_history[type][viminfo_hisidx[type]].hisnum = 0; - viminfo_hisidx[type]++; - } - } - } - vim_free(val); - } - return viminfo_readline(virp); + return history[hist_type]; } -/* - * Accept a new style history line from the viminfo, store it in the history - * array when it's new. - */ void -handle_viminfo_history( - garray_T *values, - int writing) +set_histentry(int hist_type, histentry_T *entry) { - int type; - long_u len; - char_u *val; - char_u *p; - bval_T *vp = (bval_T *)values->ga_data; - - /* Check the format: - * |{bartype},{histtype},{timestamp},{separator},"text" */ - if (values->ga_len < 4 - || vp[0].bv_type != BVAL_NR - || vp[1].bv_type != BVAL_NR - || (vp[2].bv_type != BVAL_NR && vp[2].bv_type != BVAL_EMPTY) - || vp[3].bv_type != BVAL_STRING) - return; - - type = vp[0].bv_nr; - if (type >= HIST_COUNT) - return; - if (viminfo_hisidx[type] < viminfo_hislen[type]) - { - val = vp[3].bv_string; - if (val != NULL && *val != NUL) - { - int sep = type == HIST_SEARCH && vp[2].bv_type == BVAL_NR - ? vp[2].bv_nr : NUL; - int idx; - int overwrite = FALSE; - - if (!in_history(type, val, viminfo_add_at_front, sep, writing)) - { - /* If lines were written by an older Vim we need to avoid - * getting duplicates. See if the entry already exists. */ - for (idx = 0; idx < viminfo_hisidx[type]; ++idx) - { - p = viminfo_history[type][idx].hisstr; - if (STRCMP(val, p) == 0 - && (type != HIST_SEARCH || sep == p[STRLEN(p) + 1])) - { - overwrite = TRUE; - break; - } - } - - if (!overwrite) - { - /* Need to re-allocate to append the separator byte. */ - len = vp[3].bv_len; - p = alloc(len + 2); - } - else - len = 0; /* for picky compilers */ - if (p != NULL) - { - viminfo_history[type][idx].time_set = vp[1].bv_nr; - if (!overwrite) - { - mch_memmove(p, val, (size_t)len + 1); - /* Put the separator after the NUL. */ - p[len + 1] = sep; - viminfo_history[type][idx].hisstr = p; - viminfo_history[type][idx].hisnum = 0; - viminfo_history[type][idx].viminfo = TRUE; - viminfo_hisidx[type]++; - } - } - } - } - } + history[hist_type] = entry; } -/* - * Concatenate history lines from viminfo after the lines typed in this Vim. - */ - static void -concat_history(int type) + int * +get_hisidx(int hist_type) { - int idx; - int i; - - idx = hisidx[type] + viminfo_hisidx[type]; - if (idx >= hislen) - idx -= hislen; - else if (idx < 0) - idx = hislen - 1; - if (viminfo_add_at_front) - hisidx[type] = idx; - else - { - if (hisidx[type] == -1) - hisidx[type] = hislen - 1; - do - { - if (history[type][idx].hisstr != NULL - || history[type][idx].viminfo) - break; - if (++idx == hislen) - idx = 0; - } while (idx != hisidx[type]); - if (idx != hisidx[type] && --idx < 0) - idx = hislen - 1; - } - for (i = 0; i < viminfo_hisidx[type]; i++) - { - vim_free(history[type][idx].hisstr); - history[type][idx].hisstr = viminfo_history[type][i].hisstr; - history[type][idx].viminfo = TRUE; - history[type][idx].time_set = viminfo_history[type][i].time_set; - if (--idx < 0) - idx = hislen - 1; - } - idx += 1; - idx %= hislen; - for (i = 0; i < viminfo_hisidx[type]; i++) - { - history[type][idx++].hisnum = ++hisnum[type]; - idx %= hislen; - } + return &hisidx[hist_type]; } -#if defined(FEAT_CMDL_COMPL) || defined(PROTO) - static int -sort_hist(const void *s1, const void *s2) + int * +get_hisnum(int hist_type) { - histentry_T *p1 = *(histentry_T **)s1; - histentry_T *p2 = *(histentry_T **)s2; - - if (p1->time_set < p2->time_set) return -1; - if (p1->time_set > p2->time_set) return 1; - return 0; + return &hisnum[hist_type]; } #endif -/* - * Merge history lines from viminfo and lines typed in this Vim based on the - * timestamp; - */ - static void -merge_history(int type) -{ - int max_len; - histentry_T **tot_hist; - histentry_T *new_hist; - int i; - int len; - - /* Make one long list with all entries. */ - max_len = hislen + viminfo_hisidx[type]; - tot_hist = ALLOC_MULT(histentry_T *, max_len); - new_hist = ALLOC_MULT(histentry_T, hislen ); - if (tot_hist == NULL || new_hist == NULL) - { - vim_free(tot_hist); - vim_free(new_hist); - return; - } - for (i = 0; i < viminfo_hisidx[type]; i++) - tot_hist[i] = &viminfo_history[type][i]; - len = i; - for (i = 0; i < hislen; i++) - if (history[type][i].hisstr != NULL) - tot_hist[len++] = &history[type][i]; - - /* Sort the list on timestamp. */ - qsort((void *)tot_hist, (size_t)len, sizeof(histentry_T *), sort_hist); - - /* Keep the newest ones. */ - for (i = 0; i < hislen; i++) - { - if (i < len) - { - new_hist[i] = *tot_hist[i]; - tot_hist[i]->hisstr = NULL; - if (new_hist[i].hisnum == 0) - new_hist[i].hisnum = ++hisnum[type]; - } - else - clear_hist_entry(&new_hist[i]); - } - hisidx[type] = (i < len ? i : len) - 1; - - /* Free what is not kept. */ - for (i = 0; i < viminfo_hisidx[type]; i++) - vim_free(viminfo_history[type][i].hisstr); - for (i = 0; i < hislen; i++) - vim_free(history[type][i].hisstr); - vim_free(history[type]); - history[type] = new_hist; - vim_free(tot_hist); -} - -/* - * Finish reading history lines from viminfo. Not used when writing viminfo. - */ - void -finish_viminfo_history(vir_T *virp) -{ - int type; - int merge = virp->vir_version >= VIMINFO_VERSION_WITH_HISTORY; - - for (type = 0; type < HIST_COUNT; ++type) - { - if (history[type] == NULL) - continue; - - if (merge) - merge_history(type); - else - concat_history(type); - - VIM_CLEAR(viminfo_history[type]); - viminfo_hisidx[type] = 0; - } -} - -/* - * Write history to viminfo file in "fp". - * When "merge" is TRUE merge history lines with a previously read viminfo - * file, data is in viminfo_history[]. - * When "merge" is FALSE just write all history lines. Used for ":wviminfo!". - */ - void -write_viminfo_history(FILE *fp, int merge) -{ - int i; - int type; - int num_saved; - int round; - - init_history(); - if (hislen == 0) - return; - for (type = 0; type < HIST_COUNT; ++type) - { - num_saved = get_viminfo_parameter(hist_type2char(type, FALSE)); - if (num_saved == 0) - continue; - if (num_saved < 0) /* Use default */ - num_saved = hislen; - fprintf(fp, _("\n# %s History (newest to oldest):\n"), - type == HIST_CMD ? _("Command Line") : - type == HIST_SEARCH ? _("Search String") : - type == HIST_EXPR ? _("Expression") : - type == HIST_INPUT ? _("Input Line") : - _("Debug Line")); - if (num_saved > hislen) - num_saved = hislen; - - /* - * Merge typed and viminfo history: - * round 1: history of typed commands. - * round 2: history from recently read viminfo. - */ - for (round = 1; round <= 2; ++round) - { - if (round == 1) - /* start at newest entry, somewhere in the list */ - i = hisidx[type]; - else if (viminfo_hisidx[type] > 0) - /* start at newest entry, first in the list */ - i = 0; - else - /* empty list */ - i = -1; - if (i >= 0) - while (num_saved > 0 - && !(round == 2 && i >= viminfo_hisidx[type])) - { - char_u *p; - time_t timestamp; - int c = NUL; - - if (round == 1) - { - p = history[type][i].hisstr; - timestamp = history[type][i].time_set; - } - else - { - p = viminfo_history[type] == NULL ? NULL - : viminfo_history[type][i].hisstr; - timestamp = viminfo_history[type] == NULL ? 0 - : viminfo_history[type][i].time_set; - } - - if (p != NULL && (round == 2 - || !merge - || !history[type][i].viminfo)) - { - --num_saved; - fputc(hist_type2char(type, TRUE), fp); - /* For the search history: put the separator in the - * second column; use a space if there isn't one. */ - if (type == HIST_SEARCH) - { - c = p[STRLEN(p) + 1]; - putc(c == NUL ? ' ' : c, fp); - } - viminfo_writestring(fp, p); - - { - char cbuf[NUMBUFLEN]; - - /* New style history with a bar line. Format: - * |{bartype},{histtype},{timestamp},{separator},"text" */ - if (c == NUL) - cbuf[0] = NUL; - else - sprintf(cbuf, "%d", c); - fprintf(fp, "|%d,%d,%ld,%s,", BARTYPE_HISTORY, - type, (long)timestamp, cbuf); - barline_writestring(fp, p, LSIZE - 20); - putc('\n', fp); - } - } - if (round == 1) - { - /* Decrement index, loop around and stop when back at - * the start. */ - if (--i < 0) - i = hislen - 1; - if (i == hisidx[type]) - break; - } - else - { - /* Increment index. Stop at the end in the while. */ - ++i; - } - } - } - for (i = 0; i < viminfo_hisidx[type]; ++i) - if (viminfo_history[type] != NULL) - vim_free(viminfo_history[type][i].hisstr); - VIM_CLEAR(viminfo_history[type]); - viminfo_hisidx[type] = 0; - } -} -#endif /* FEAT_VIMINFO */ - #if defined(FEAT_CMDWIN) || defined(PROTO) /* * Open a window on the current command line and history. Allow editing in diff -Nru vim-8.1.1681/src/feature.h vim-8.1.1729/src/feature.h --- vim-8.1.1681/src/feature.h 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/feature.h 2019-07-21 21:04:21.000000000 +0000 @@ -483,6 +483,11 @@ # define FEAT_TEXT_PROP #endif +#if defined(FEAT_SYN_HL) && defined(FEAT_RELTIME) +// Can limit syntax highlight time to 'redrawtime'. +# define SYN_TIME_LIMIT 1 +#endif + /* * +spell spell checking * @@ -1236,7 +1241,7 @@ * +signs Allow signs to be displayed to the left of text lines. * Adds the ":sign" command. */ -#if defined(FEAT_BIG) || defined(FEAT_NETBEANS_INTG) +#if defined(FEAT_BIG) || defined(FEAT_NETBEANS_INTG) || defined(FEAT_TEXT_PROP) # define FEAT_SIGNS # if ((defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) \ && defined(HAVE_X11_XPM_H)) \ diff -Nru vim-8.1.1681/src/globals.h vim-8.1.1729/src/globals.h --- vim-8.1.1681/src/globals.h 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/globals.h 2019-07-21 21:04:21.000000000 +0000 @@ -190,6 +190,7 @@ EXTERN int did_endif INIT(= FALSE); /* just had ":endif" */ EXTERN dict_T vimvardict; /* Dictionary with v: variables */ EXTERN dict_T globvardict; /* Dictionary with g: variables */ +#define globvarht globvardict.dv_hashtab #endif EXTERN int did_emsg; /* set by emsg() when the message is displayed or thrown */ @@ -252,6 +253,9 @@ # ifdef FEAT_PROFILE EXTERN int do_profiling INIT(= PROF_NONE); /* PROF_ values */ # endif +EXTERN garray_T script_items INIT(= {0 COMMA 0 COMMA sizeof(scriptitem_T) COMMA 4 COMMA NULL}); +#define SCRIPT_ITEM(id) (((scriptitem_T *)script_items.ga_data)[(id) - 1]) +#define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j] /* * The exception currently being thrown. Used to pass an exception to @@ -352,6 +356,13 @@ EXTERN int scroll_region INIT(= FALSE); /* term supports scroll region */ EXTERN int t_colors INIT(= 0); /* int value of T_CCO */ +#ifdef FEAT_CMDL_COMPL +// Flags to indicate an additional string for highlight name completion. +EXTERN int include_none INIT(= 0); // when 1 include "None" +EXTERN int include_default INIT(= 0); // when 1 include "default" +EXTERN int include_link INIT(= 0); // when 2 include "link" and "clear" +#endif + /* * When highlight_match is TRUE, highlight a match, starting at the cursor * position. Search_match_lines is the number of lines after the match (0 for diff -Nru vim-8.1.1681/src/gui.c vim-8.1.1729/src/gui.c --- vim-8.1.1681/src/gui.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/gui.c 2019-07-21 21:04:21.000000000 +0000 @@ -2253,7 +2253,7 @@ int col = gui.col; #ifdef FEAT_SIGN_ICONS int draw_sign = FALSE; - int signcol; + int signcol = 0; char_u extra[18]; # ifdef FEAT_NETBEANS_INTG int multi_sign = FALSE; diff -Nru vim-8.1.1681/src/highlight.c vim-8.1.1729/src/highlight.c --- vim-8.1.1681/src/highlight.c 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/highlight.c 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,3655 @@ +/* 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. + */ + +/* + * Highlighting stuff + */ + +#include "vim.h" + +#define SG_TERM 1 // term has been set +#define SG_CTERM 2 // cterm has been set +#define SG_GUI 4 // gui has been set +#define SG_LINK 8 // link has been set + +/* + * The "term", "cterm" and "gui" arguments can be any combination of the + * following names, separated by commas (but no spaces!). + */ +static char *(hl_name_table[]) = + {"bold", "standout", "underline", "undercurl", + "italic", "reverse", "inverse", "nocombine", "strikethrough", "NONE"}; +static int hl_attr_table[] = + {HL_BOLD, HL_STANDOUT, HL_UNDERLINE, HL_UNDERCURL, HL_ITALIC, HL_INVERSE, HL_INVERSE, HL_NOCOMBINE, HL_STRIKETHROUGH, 0}; +#define ATTR_COMBINE(attr_a, attr_b) ((((attr_b) & HL_NOCOMBINE) ? attr_b : (attr_a)) | (attr_b)) + +/* + * Structure that stores information about a highlight group. + * The ID of a highlight group is also called group ID. It is the index in + * the highlight_ga array PLUS ONE. + */ +typedef struct +{ + 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 + char_u *sg_stop; // terminal string for stop highl + int sg_term_attr; // Screen attr for term mode +// for color terminals + int sg_cterm; // "cterm=" highlighting attr + int sg_cterm_bold; // bold attr was set for light color + int sg_cterm_fg; // terminal fg color number + 1 + int sg_cterm_bg; // terminal bg color number + 1 + int sg_cterm_attr; // Screen attr for color term mode +// for when using the GUI +#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) + guicolor_T sg_gui_fg; // GUI foreground color handle + guicolor_T sg_gui_bg; // GUI background color handle +#endif +#ifdef FEAT_GUI + guicolor_T sg_gui_sp; // GUI special color handle + GuiFont sg_font; // GUI font handle +#ifdef FEAT_XFONTSET + GuiFontset sg_fontset; // GUI fontset handle +#endif + char_u *sg_font_name; // GUI font or fontset name + int sg_gui_attr; // Screen attr for GUI mode +#endif +#if defined(FEAT_GUI) || defined(FEAT_EVAL) +// Store the sp color name for the GUI or synIDattr() + int sg_gui; // "gui=" highlighting attributes + char_u *sg_gui_fg_name;// GUI foreground color name + char_u *sg_gui_bg_name;// GUI background color name + char_u *sg_gui_sp_name;// GUI special color name +#endif + int sg_link; // link to this highlight group ID + int sg_set; // combination of SG_* flags +#ifdef FEAT_EVAL + sctx_T sg_script_ctx; // script in which the group was last set +#endif +} hl_group_T; + +// highlight groups for 'highlight' option +static garray_T highlight_ga; +#define HL_TABLE() ((hl_group_T *)((highlight_ga.ga_data))) + +/* + * An attribute number is the index in attr_table plus ATTR_OFF. + */ +#define ATTR_OFF (HL_ALL + 1) + +static void syn_unadd_group(void); +static void set_hl_attr(int idx); +static void highlight_list_one(int id); +static int highlight_list_arg(int id, int didh, int type, int iarg, char_u *sarg, char *name); +static int syn_add_group(char_u *name); +static int hl_has_settings(int idx, int check_link); +static void highlight_clear(int idx); + +#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) +static void gui_do_one_color(int idx, int do_menu, int do_tooltip); +#endif +#ifdef FEAT_GUI +static int set_group_colors(char_u *name, guicolor_T *fgp, guicolor_T *bgp, int do_menu, int use_norm, int do_tooltip); +static void hl_do_font(int idx, char_u *arg, int do_normal, int do_menu, int do_tooltip, int free_font); +#endif + +/* + * The default highlight groups. These are compiled-in for fast startup and + * they still work when the runtime files can't be found. + * When making changes here, also change runtime/colors/default.vim! + * The #ifdefs are needed to reduce the amount of static data. Helps to make + * the 16 bit DOS (museum) version compile. + */ +#if defined(FEAT_GUI) || defined(FEAT_EVAL) +# define CENT(a, b) b +#else +# define CENT(a, b) a +#endif +static char *(highlight_init_both[]) = { + CENT("ErrorMsg term=standout ctermbg=DarkRed ctermfg=White", + "ErrorMsg term=standout ctermbg=DarkRed ctermfg=White guibg=Red guifg=White"), + CENT("IncSearch term=reverse cterm=reverse", + "IncSearch term=reverse cterm=reverse gui=reverse"), + CENT("ModeMsg term=bold cterm=bold", + "ModeMsg term=bold cterm=bold gui=bold"), + CENT("NonText term=bold ctermfg=Blue", + "NonText term=bold ctermfg=Blue gui=bold guifg=Blue"), + CENT("StatusLine term=reverse,bold cterm=reverse,bold", + "StatusLine term=reverse,bold cterm=reverse,bold gui=reverse,bold"), + CENT("StatusLineNC term=reverse cterm=reverse", + "StatusLineNC term=reverse cterm=reverse gui=reverse"), + "default link EndOfBuffer NonText", + CENT("VertSplit term=reverse cterm=reverse", + "VertSplit term=reverse cterm=reverse gui=reverse"), +#ifdef FEAT_CLIPBOARD + CENT("VisualNOS term=underline,bold cterm=underline,bold", + "VisualNOS term=underline,bold cterm=underline,bold gui=underline,bold"), +#endif +#ifdef FEAT_DIFF + CENT("DiffText term=reverse cterm=bold ctermbg=Red", + "DiffText term=reverse cterm=bold ctermbg=Red gui=bold guibg=Red"), +#endif +#ifdef FEAT_INS_EXPAND + CENT("PmenuSbar ctermbg=Grey", + "PmenuSbar ctermbg=Grey guibg=Grey"), +#endif + CENT("TabLineSel term=bold cterm=bold", + "TabLineSel term=bold cterm=bold gui=bold"), + CENT("TabLineFill term=reverse cterm=reverse", + "TabLineFill term=reverse cterm=reverse gui=reverse"), +#ifdef FEAT_GUI + "Cursor guibg=fg guifg=bg", + "lCursor guibg=fg guifg=bg", // should be different, but what? +#endif + "default link QuickFixLine Search", + CENT("Normal cterm=NONE", "Normal gui=NONE"), + NULL +}; + +/* Default colors only used with a light background. */ +static char *(highlight_init_light[]) = { + CENT("Directory term=bold ctermfg=DarkBlue", + "Directory term=bold ctermfg=DarkBlue guifg=Blue"), + CENT("LineNr term=underline ctermfg=Brown", + "LineNr term=underline ctermfg=Brown guifg=Brown"), + CENT("CursorLineNr term=bold ctermfg=Brown", + "CursorLineNr term=bold ctermfg=Brown gui=bold guifg=Brown"), + CENT("MoreMsg term=bold ctermfg=DarkGreen", + "MoreMsg term=bold ctermfg=DarkGreen gui=bold guifg=SeaGreen"), + CENT("Question term=standout ctermfg=DarkGreen", + "Question term=standout ctermfg=DarkGreen gui=bold guifg=SeaGreen"), + CENT("Search term=reverse ctermbg=Yellow ctermfg=NONE", + "Search term=reverse ctermbg=Yellow ctermfg=NONE guibg=Yellow guifg=NONE"), +#ifdef FEAT_SPELL + CENT("SpellBad term=reverse ctermbg=LightRed", + "SpellBad term=reverse ctermbg=LightRed guisp=Red gui=undercurl"), + CENT("SpellCap term=reverse ctermbg=LightBlue", + "SpellCap term=reverse ctermbg=LightBlue guisp=Blue gui=undercurl"), + CENT("SpellRare term=reverse ctermbg=LightMagenta", + "SpellRare term=reverse ctermbg=LightMagenta guisp=Magenta gui=undercurl"), + CENT("SpellLocal term=underline ctermbg=Cyan", + "SpellLocal term=underline ctermbg=Cyan guisp=DarkCyan gui=undercurl"), +#endif +#ifdef FEAT_INS_EXPAND + CENT("PmenuThumb ctermbg=Black", + "PmenuThumb ctermbg=Black guibg=Black"), + CENT("Pmenu ctermbg=LightMagenta ctermfg=Black", + "Pmenu ctermbg=LightMagenta ctermfg=Black guibg=LightMagenta"), + CENT("PmenuSel ctermbg=LightGrey ctermfg=Black", + "PmenuSel ctermbg=LightGrey ctermfg=Black guibg=Grey"), +#endif + CENT("SpecialKey term=bold ctermfg=DarkBlue", + "SpecialKey term=bold ctermfg=DarkBlue guifg=Blue"), + CENT("Title term=bold ctermfg=DarkMagenta", + "Title term=bold ctermfg=DarkMagenta gui=bold guifg=Magenta"), + CENT("WarningMsg term=standout ctermfg=DarkRed", + "WarningMsg term=standout ctermfg=DarkRed guifg=Red"), +#ifdef FEAT_WILDMENU + CENT("WildMenu term=standout ctermbg=Yellow ctermfg=Black", + "WildMenu term=standout ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"), +#endif +#ifdef FEAT_FOLDING + CENT("Folded term=standout ctermbg=Grey ctermfg=DarkBlue", + "Folded term=standout ctermbg=Grey ctermfg=DarkBlue guibg=LightGrey guifg=DarkBlue"), + CENT("FoldColumn term=standout ctermbg=Grey ctermfg=DarkBlue", + "FoldColumn term=standout ctermbg=Grey ctermfg=DarkBlue guibg=Grey guifg=DarkBlue"), +#endif +#ifdef FEAT_SIGNS + CENT("SignColumn term=standout ctermbg=Grey ctermfg=DarkBlue", + "SignColumn term=standout ctermbg=Grey ctermfg=DarkBlue guibg=Grey guifg=DarkBlue"), +#endif + CENT("Visual term=reverse", + "Visual term=reverse guibg=LightGrey"), +#ifdef FEAT_DIFF + CENT("DiffAdd term=bold ctermbg=LightBlue", + "DiffAdd term=bold ctermbg=LightBlue guibg=LightBlue"), + CENT("DiffChange term=bold ctermbg=LightMagenta", + "DiffChange term=bold ctermbg=LightMagenta guibg=LightMagenta"), + CENT("DiffDelete term=bold ctermfg=Blue ctermbg=LightCyan", + "DiffDelete term=bold ctermfg=Blue ctermbg=LightCyan gui=bold guifg=Blue guibg=LightCyan"), +#endif + CENT("TabLine term=underline cterm=underline ctermfg=black ctermbg=LightGrey", + "TabLine term=underline cterm=underline ctermfg=black ctermbg=LightGrey gui=underline guibg=LightGrey"), +#ifdef FEAT_SYN_HL + CENT("CursorColumn term=reverse ctermbg=LightGrey", + "CursorColumn term=reverse ctermbg=LightGrey guibg=Grey90"), + CENT("CursorLine term=underline cterm=underline", + "CursorLine term=underline cterm=underline guibg=Grey90"), + CENT("ColorColumn term=reverse ctermbg=LightRed", + "ColorColumn term=reverse ctermbg=LightRed guibg=LightRed"), +#endif +#ifdef FEAT_CONCEAL + CENT("Conceal ctermbg=DarkGrey ctermfg=LightGrey", + "Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey"), +#endif + CENT("MatchParen term=reverse ctermbg=Cyan", + "MatchParen term=reverse ctermbg=Cyan guibg=Cyan"), +#ifdef FEAT_TERMINAL + CENT("StatusLineTerm term=reverse,bold cterm=bold ctermfg=White ctermbg=DarkGreen", + "StatusLineTerm term=reverse,bold cterm=bold ctermfg=White ctermbg=DarkGreen gui=bold guifg=bg guibg=DarkGreen"), + CENT("StatusLineTermNC term=reverse ctermfg=White ctermbg=DarkGreen", + "StatusLineTermNC term=reverse ctermfg=White ctermbg=DarkGreen guifg=bg guibg=DarkGreen"), +#endif +#ifdef FEAT_MENU + CENT("ToolbarLine term=underline ctermbg=LightGrey", + "ToolbarLine term=underline ctermbg=LightGrey guibg=LightGrey"), + CENT("ToolbarButton cterm=bold ctermfg=White ctermbg=DarkGrey", + "ToolbarButton cterm=bold ctermfg=White ctermbg=DarkGrey gui=bold guifg=White guibg=Grey40"), +#endif + NULL +}; + +/* Default colors only used with a dark background. */ +static char *(highlight_init_dark[]) = { + CENT("Directory term=bold ctermfg=LightCyan", + "Directory term=bold ctermfg=LightCyan guifg=Cyan"), + CENT("LineNr term=underline ctermfg=Yellow", + "LineNr term=underline ctermfg=Yellow guifg=Yellow"), + CENT("CursorLineNr term=bold ctermfg=Yellow", + "CursorLineNr term=bold ctermfg=Yellow gui=bold guifg=Yellow"), + CENT("MoreMsg term=bold ctermfg=LightGreen", + "MoreMsg term=bold ctermfg=LightGreen gui=bold guifg=SeaGreen"), + CENT("Question term=standout ctermfg=LightGreen", + "Question term=standout ctermfg=LightGreen gui=bold guifg=Green"), + CENT("Search term=reverse ctermbg=Yellow ctermfg=Black", + "Search term=reverse ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"), + CENT("SpecialKey term=bold ctermfg=LightBlue", + "SpecialKey term=bold ctermfg=LightBlue guifg=Cyan"), +#ifdef FEAT_SPELL + CENT("SpellBad term=reverse ctermbg=Red", + "SpellBad term=reverse ctermbg=Red guisp=Red gui=undercurl"), + CENT("SpellCap term=reverse ctermbg=Blue", + "SpellCap term=reverse ctermbg=Blue guisp=Blue gui=undercurl"), + CENT("SpellRare term=reverse ctermbg=Magenta", + "SpellRare term=reverse ctermbg=Magenta guisp=Magenta gui=undercurl"), + CENT("SpellLocal term=underline ctermbg=Cyan", + "SpellLocal term=underline ctermbg=Cyan guisp=Cyan gui=undercurl"), +#endif +#ifdef FEAT_INS_EXPAND + CENT("PmenuThumb ctermbg=White", + "PmenuThumb ctermbg=White guibg=White"), + CENT("Pmenu ctermbg=Magenta ctermfg=Black", + "Pmenu ctermbg=Magenta ctermfg=Black guibg=Magenta"), + CENT("PmenuSel ctermbg=Black ctermfg=DarkGrey", + "PmenuSel ctermbg=Black ctermfg=DarkGrey guibg=DarkGrey"), +#endif + CENT("Title term=bold ctermfg=LightMagenta", + "Title term=bold ctermfg=LightMagenta gui=bold guifg=Magenta"), + CENT("WarningMsg term=standout ctermfg=LightRed", + "WarningMsg term=standout ctermfg=LightRed guifg=Red"), +#ifdef FEAT_WILDMENU + CENT("WildMenu term=standout ctermbg=Yellow ctermfg=Black", + "WildMenu term=standout ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"), +#endif +#ifdef FEAT_FOLDING + CENT("Folded term=standout ctermbg=DarkGrey ctermfg=Cyan", + "Folded term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=DarkGrey guifg=Cyan"), + CENT("FoldColumn term=standout ctermbg=DarkGrey ctermfg=Cyan", + "FoldColumn term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=Grey guifg=Cyan"), +#endif +#ifdef FEAT_SIGNS + CENT("SignColumn term=standout ctermbg=DarkGrey ctermfg=Cyan", + "SignColumn term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=Grey guifg=Cyan"), +#endif + CENT("Visual term=reverse", + "Visual term=reverse guibg=DarkGrey"), +#ifdef FEAT_DIFF + CENT("DiffAdd term=bold ctermbg=DarkBlue", + "DiffAdd term=bold ctermbg=DarkBlue guibg=DarkBlue"), + CENT("DiffChange term=bold ctermbg=DarkMagenta", + "DiffChange term=bold ctermbg=DarkMagenta guibg=DarkMagenta"), + CENT("DiffDelete term=bold ctermfg=Blue ctermbg=DarkCyan", + "DiffDelete term=bold ctermfg=Blue ctermbg=DarkCyan gui=bold guifg=Blue guibg=DarkCyan"), +#endif + CENT("TabLine term=underline cterm=underline ctermfg=white ctermbg=DarkGrey", + "TabLine term=underline cterm=underline ctermfg=white ctermbg=DarkGrey gui=underline guibg=DarkGrey"), +#ifdef FEAT_SYN_HL + CENT("CursorColumn term=reverse ctermbg=DarkGrey", + "CursorColumn term=reverse ctermbg=DarkGrey guibg=Grey40"), + CENT("CursorLine term=underline cterm=underline", + "CursorLine term=underline cterm=underline guibg=Grey40"), + CENT("ColorColumn term=reverse ctermbg=DarkRed", + "ColorColumn term=reverse ctermbg=DarkRed guibg=DarkRed"), +#endif + CENT("MatchParen term=reverse ctermbg=DarkCyan", + "MatchParen term=reverse ctermbg=DarkCyan guibg=DarkCyan"), +#ifdef FEAT_CONCEAL + CENT("Conceal ctermbg=DarkGrey ctermfg=LightGrey", + "Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey"), +#endif +#ifdef FEAT_TERMINAL + CENT("StatusLineTerm term=reverse,bold cterm=bold ctermfg=Black ctermbg=LightGreen", + "StatusLineTerm term=reverse,bold cterm=bold ctermfg=Black ctermbg=LightGreen gui=bold guifg=bg guibg=LightGreen"), + CENT("StatusLineTermNC term=reverse ctermfg=Black ctermbg=LightGreen", + "StatusLineTermNC term=reverse ctermfg=Black ctermbg=LightGreen guifg=bg guibg=LightGreen"), +#endif +#ifdef FEAT_MENU + CENT("ToolbarLine term=underline ctermbg=DarkGrey", + "ToolbarLine term=underline ctermbg=DarkGrey guibg=Grey50"), + CENT("ToolbarButton cterm=bold ctermfg=Black ctermbg=LightGrey", + "ToolbarButton cterm=bold ctermfg=Black ctermbg=LightGrey gui=bold guifg=Black guibg=LightGrey"), +#endif + NULL +}; + +/* + * Returns the number of highlight groups. + */ + int +highlight_num_groups(void) +{ + return highlight_ga.ga_len; +} + +/* + * Returns the name of a highlight group. + */ + char_u * +highlight_group_name(int id) +{ + return HL_TABLE()[id].sg_name; +} + +/* + * Returns the ID of the link to a highlight group. + */ + int +highlight_link_id(int id) +{ + return HL_TABLE()[id].sg_link; +} + + void +init_highlight( + int both, // include groups where 'bg' doesn't matter + int reset) // clear group first +{ + int i; + char **pp; + static int had_both = FALSE; +#ifdef FEAT_EVAL + char_u *p; + + /* + * Try finding the color scheme file. Used when a color file was loaded + * and 'background' or 't_Co' is changed. + */ + p = get_var_value((char_u *)"g:colors_name"); + if (p != NULL) + { + // The value of g:colors_name could be freed when sourcing the script, + // making "p" invalid, so copy it. + char_u *copy_p = vim_strsave(p); + int r; + + if (copy_p != NULL) + { + r = load_colors(copy_p); + vim_free(copy_p); + if (r == OK) + return; + } + } + +#endif + + /* + * Didn't use a color file, use the compiled-in colors. + */ + if (both) + { + had_both = TRUE; + pp = highlight_init_both; + for (i = 0; pp[i] != NULL; ++i) + do_highlight((char_u *)pp[i], reset, TRUE); + } + else if (!had_both) + // Don't do anything before the call with both == TRUE from main(). + // Not everything has been setup then, and that call will overrule + // everything anyway. + return; + + if (*p_bg == 'l') + pp = highlight_init_light; + else + pp = highlight_init_dark; + for (i = 0; pp[i] != NULL; ++i) + do_highlight((char_u *)pp[i], reset, TRUE); + + // Reverse looks ugly, but grey may not work for 8 colors. Thus let it + // depend on the number of colors available. + // With 8 colors brown is equal to yellow, need to use black for Search fg + // to avoid Statement highlighted text disappears. + // Clear the attributes, needed when changing the t_Co value. + if (t_colors > 8) + do_highlight((char_u *)(*p_bg == 'l' + ? "Visual cterm=NONE ctermbg=LightGrey" + : "Visual cterm=NONE ctermbg=DarkGrey"), FALSE, TRUE); + else + { + do_highlight((char_u *)"Visual cterm=reverse ctermbg=NONE", + FALSE, TRUE); + if (*p_bg == 'l') + do_highlight((char_u *)"Search ctermfg=black", FALSE, TRUE); + } + +#ifdef FEAT_SYN_HL + /* + * If syntax highlighting is enabled load the highlighting for it. + */ + if (get_var_value((char_u *)"g:syntax_on") != NULL) + { + static int recursive = 0; + + if (recursive >= 5) + emsg(_("E679: recursive loop loading syncolor.vim")); + else + { + ++recursive; + (void)source_runtime((char_u *)"syntax/syncolor.vim", DIP_ALL); + --recursive; + } + } +#endif +} + +/* + * Load color file "name". + * Return OK for success, FAIL for failure. + */ + int +load_colors(char_u *name) +{ + char_u *buf; + int retval = FAIL; + static int recursive = FALSE; + + // When being called recursively, this is probably because setting + // 'background' caused the highlighting to be reloaded. This means it is + // working, thus we should return OK. + if (recursive) + return OK; + + recursive = TRUE; + buf = alloc(STRLEN(name) + 12); + if (buf != NULL) + { + apply_autocmds(EVENT_COLORSCHEMEPRE, name, + curbuf->b_fname, FALSE, curbuf); + sprintf((char *)buf, "colors/%s.vim", name); + retval = source_runtime(buf, DIP_START + DIP_OPT); + vim_free(buf); + apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, FALSE, curbuf); + } + recursive = FALSE; + + return retval; +} + +static char *(color_names[28]) = { + "Black", "DarkBlue", "DarkGreen", "DarkCyan", + "DarkRed", "DarkMagenta", "Brown", "DarkYellow", + "Gray", "Grey", "LightGray", "LightGrey", + "DarkGray", "DarkGrey", + "Blue", "LightBlue", "Green", "LightGreen", + "Cyan", "LightCyan", "Red", "LightRed", "Magenta", + "LightMagenta", "Yellow", "LightYellow", "White", "NONE"}; + // indices: + // 0, 1, 2, 3, + // 4, 5, 6, 7, + // 8, 9, 10, 11, + // 12, 13, + // 14, 15, 16, 17, + // 18, 19, 20, 21, 22, + // 23, 24, 25, 26, 27 +static int color_numbers_16[28] = {0, 1, 2, 3, + 4, 5, 6, 6, + 7, 7, 7, 7, + 8, 8, + 9, 9, 10, 10, + 11, 11, 12, 12, 13, + 13, 14, 14, 15, -1}; +// for xterm with 88 colors... +static int color_numbers_88[28] = {0, 4, 2, 6, + 1, 5, 32, 72, + 84, 84, 7, 7, + 82, 82, + 12, 43, 10, 61, + 14, 63, 9, 74, 13, + 75, 11, 78, 15, -1}; +// for xterm with 256 colors... +static int color_numbers_256[28] = {0, 4, 2, 6, + 1, 5, 130, 130, + 248, 248, 7, 7, + 242, 242, + 12, 81, 10, 121, + 14, 159, 9, 224, 13, + 225, 11, 229, 15, -1}; +// for terminals with less than 16 colors... +static int color_numbers_8[28] = {0, 4, 2, 6, + 1, 5, 3, 3, + 7, 7, 7, 7, + 0+8, 0+8, + 4+8, 4+8, 2+8, 2+8, + 6+8, 6+8, 1+8, 1+8, 5+8, + 5+8, 3+8, 3+8, 7+8, -1}; + +/* + * Lookup the "cterm" value to be used for color with index "idx" in + * color_names[]. + * "boldp" will be set to TRUE or FALSE for a foreground color when using 8 + * colors, otherwise it will be unchanged. + */ + int +lookup_color(int idx, int foreground, int *boldp) +{ + int color = color_numbers_16[idx]; + char_u *p; + + // Use the _16 table to check if it's a valid color name. + if (color < 0) + return -1; + + if (t_colors == 8) + { + // t_Co is 8: use the 8 colors table +#if defined(__QNXNTO__) + color = color_numbers_8_qansi[idx]; +#else + color = color_numbers_8[idx]; +#endif + if (foreground) + { + // set/reset bold attribute to get light foreground + // colors (on some terminals, e.g. "linux") + if (color & 8) + *boldp = TRUE; + else + *boldp = FALSE; + } + color &= 7; // truncate to 8 colors + } + else if (t_colors == 16 || t_colors == 88 + || t_colors >= 256) + { + /* + * Guess: if the termcap entry ends in 'm', it is + * probably an xterm-like terminal. Use the changed + * order for colors. + */ + if (*T_CAF != NUL) + p = T_CAF; + else + p = T_CSF; + if (*p != NUL && (t_colors > 256 + || *(p + STRLEN(p) - 1) == 'm')) + { + if (t_colors == 88) + color = color_numbers_88[idx]; + else if (t_colors >= 256) + color = color_numbers_256[idx]; + else + color = color_numbers_8[idx]; + } +#ifdef FEAT_TERMRESPONSE + if (t_colors >= 256 && color == 15 && is_mac_terminal) + // Terminal.app has a bug: 15 is light grey. Use white + // from the color cube instead. + color = 231; +#endif + } + return color; +} + +/* + * Handle the ":highlight .." command. + * When using ":hi clear" this is called recursively for each group with + * "forceit" and "init" both TRUE. + */ + void +do_highlight( + char_u *line, + int forceit, + int init) // TRUE when called for initializing +{ + char_u *name_end; + char_u *p; + char_u *linep; + char_u *key_start; + char_u *arg_start; + char_u *key = NULL, *arg = NULL; + long i; + int off; + int len; + int attr; + int id; + int idx; + hl_group_T item_before; + int did_change = FALSE; + int dodefault = FALSE; + int doclear = FALSE; + int dolink = FALSE; + int error = FALSE; + int color; + int is_normal_group = FALSE; // "Normal" group +#ifdef FEAT_TERMINAL + int is_terminal_group = FALSE; // "Terminal" group +#endif +#ifdef FEAT_GUI_X11 + int is_menu_group = FALSE; // "Menu" group + int is_scrollbar_group = FALSE; // "Scrollbar" group + int is_tooltip_group = FALSE; // "Tooltip" group + int do_colors = FALSE; // need to update colors? +#else +# define is_menu_group 0 +# define is_tooltip_group 0 +#endif +#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) + int did_highlight_changed = FALSE; +#endif + + /* + * If no argument, list current highlighting. + */ + if (ends_excmd(*line)) + { + for (i = 1; i <= highlight_ga.ga_len && !got_int; ++i) + // TODO: only call when the group has attributes set + highlight_list_one((int)i); + return; + } + + /* + * Isolate the name. + */ + name_end = skiptowhite(line); + linep = skipwhite(name_end); + + /* + * Check for "default" argument. + */ + if (STRNCMP(line, "default", name_end - line) == 0) + { + dodefault = TRUE; + line = linep; + name_end = skiptowhite(line); + linep = skipwhite(name_end); + } + + /* + * Check for "clear" or "link" argument. + */ + if (STRNCMP(line, "clear", name_end - line) == 0) + doclear = TRUE; + if (STRNCMP(line, "link", name_end - line) == 0) + dolink = TRUE; + + /* + * ":highlight {group-name}": list highlighting for one group. + */ + if (!doclear && !dolink && ends_excmd(*linep)) + { + id = syn_namen2id(line, (int)(name_end - line)); + if (id == 0) + semsg(_("E411: highlight group not found: %s"), line); + else + highlight_list_one(id); + return; + } + + /* + * Handle ":highlight link {from} {to}" command. + */ + if (dolink) + { + char_u *from_start = linep; + char_u *from_end; + char_u *to_start; + char_u *to_end; + int from_id; + int to_id; + + from_end = skiptowhite(from_start); + to_start = skipwhite(from_end); + to_end = skiptowhite(to_start); + + if (ends_excmd(*from_start) || ends_excmd(*to_start)) + { + semsg(_("E412: Not enough arguments: \":highlight link %s\""), + from_start); + return; + } + + if (!ends_excmd(*skipwhite(to_end))) + { + semsg(_("E413: Too many arguments: \":highlight link %s\""), from_start); + return; + } + + from_id = syn_check_group(from_start, (int)(from_end - from_start)); + if (STRNCMP(to_start, "NONE", 4) == 0) + to_id = 0; + else + to_id = syn_check_group(to_start, (int)(to_end - to_start)); + + if (from_id > 0 && (!init || HL_TABLE()[from_id - 1].sg_set == 0)) + { + /* + * Don't allow a link when there already is some highlighting + * for the group, unless '!' is used + */ + if (to_id > 0 && !forceit && !init + && hl_has_settings(from_id - 1, dodefault)) + { + if (sourcing_name == NULL && !dodefault) + emsg(_("E414: group has settings, highlight link ignored")); + } + else if (HL_TABLE()[from_id - 1].sg_link != to_id +#ifdef FEAT_EVAL + || HL_TABLE()[from_id - 1].sg_script_ctx.sc_sid + != current_sctx.sc_sid +#endif + || HL_TABLE()[from_id - 1].sg_cleared) + { + if (!init) + HL_TABLE()[from_id - 1].sg_set |= SG_LINK; + HL_TABLE()[from_id - 1].sg_link = to_id; +#ifdef FEAT_EVAL + HL_TABLE()[from_id - 1].sg_script_ctx = current_sctx; + HL_TABLE()[from_id - 1].sg_script_ctx.sc_lnum += sourcing_lnum; +#endif + HL_TABLE()[from_id - 1].sg_cleared = FALSE; + redraw_all_later(SOME_VALID); + + // Only call highlight_changed() once after multiple changes. + need_highlight_changed = TRUE; + } + } + + return; + } + + if (doclear) + { + /* + * ":highlight clear [group]" command. + */ + line = linep; + if (ends_excmd(*line)) + { +#ifdef FEAT_GUI + // First, we do not destroy the old values, but allocate the new + // ones and update the display. THEN we destroy the old values. + // If we destroy the old values first, then the old values + // (such as GuiFont's or GuiFontset's) will still be displayed but + // invalid because they were free'd. + if (gui.in_use) + { +# ifdef FEAT_BEVAL_TIP + gui_init_tooltip_font(); +# endif +# if defined(FEAT_MENU) && (defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MOTIF)) + gui_init_menu_font(); +# endif + } +# if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_X11) + gui_mch_def_colors(); +# endif +# ifdef FEAT_GUI_X11 +# ifdef FEAT_MENU + + // This only needs to be done when there is no Menu highlight + // group defined by default, which IS currently the case. + gui_mch_new_menu_colors(); +# endif + if (gui.in_use) + { + gui_new_scrollbar_colors(); +# ifdef FEAT_BEVAL_GUI + gui_mch_new_tooltip_colors(); +# endif +# ifdef FEAT_MENU + gui_mch_new_menu_font(); +# endif + } +# endif + + // Ok, we're done allocating the new default graphics items. + // The screen should already be refreshed at this point. + // It is now Ok to clear out the old data. +#endif +#ifdef FEAT_EVAL + do_unlet((char_u *)"colors_name", TRUE); +#endif + restore_cterm_colors(); + + /* + * Clear all default highlight groups and load the defaults. + */ + for (idx = 0; idx < highlight_ga.ga_len; ++idx) + highlight_clear(idx); + init_highlight(TRUE, TRUE); +#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) + if (USE_24BIT) + highlight_gui_started(); + else +#endif + highlight_changed(); + redraw_later_clear(); + return; + } + name_end = skiptowhite(line); + linep = skipwhite(name_end); + } + + /* + * Find the group name in the table. If it does not exist yet, add it. + */ + id = syn_check_group(line, (int)(name_end - line)); + if (id == 0) // failed (out of memory) + return; + idx = id - 1; // index is ID minus one + + // Return if "default" was used and the group already has settings. + if (dodefault && hl_has_settings(idx, TRUE)) + return; + + // Make a copy so we can check if any attribute actually changed. + item_before = HL_TABLE()[idx]; + + if (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0) + is_normal_group = TRUE; +#ifdef FEAT_TERMINAL + else if (STRCMP(HL_TABLE()[idx].sg_name_u, "TERMINAL") == 0) + is_terminal_group = TRUE; +#endif +#ifdef FEAT_GUI_X11 + else if (STRCMP(HL_TABLE()[idx].sg_name_u, "MENU") == 0) + is_menu_group = TRUE; + else if (STRCMP(HL_TABLE()[idx].sg_name_u, "SCROLLBAR") == 0) + is_scrollbar_group = TRUE; + else if (STRCMP(HL_TABLE()[idx].sg_name_u, "TOOLTIP") == 0) + is_tooltip_group = TRUE; +#endif + + // Clear the highlighting for ":hi clear {group}" and ":hi clear". + if (doclear || (forceit && init)) + { + highlight_clear(idx); + if (!doclear) + HL_TABLE()[idx].sg_set = 0; + } + + if (!doclear) + while (!ends_excmd(*linep)) + { + key_start = linep; + if (*linep == '=') + { + semsg(_("E415: unexpected equal sign: %s"), key_start); + error = TRUE; + break; + } + + /* + * Isolate the key ("term", "ctermfg", "ctermbg", "font", "guifg" or + * "guibg"). + */ + while (*linep && !VIM_ISWHITE(*linep) && *linep != '=') + ++linep; + vim_free(key); + key = vim_strnsave_up(key_start, (int)(linep - key_start)); + if (key == NULL) + { + error = TRUE; + break; + } + linep = skipwhite(linep); + + if (STRCMP(key, "NONE") == 0) + { + if (!init || HL_TABLE()[idx].sg_set == 0) + { + if (!init) + HL_TABLE()[idx].sg_set |= SG_TERM+SG_CTERM+SG_GUI; + highlight_clear(idx); + } + continue; + } + + /* + * Check for the equal sign. + */ + if (*linep != '=') + { + semsg(_("E416: missing equal sign: %s"), key_start); + error = TRUE; + break; + } + ++linep; + + /* + * Isolate the argument. + */ + linep = skipwhite(linep); + if (*linep == '\'') // guifg='color name' + { + arg_start = ++linep; + linep = vim_strchr(linep, '\''); + if (linep == NULL) + { + semsg(_(e_invarg2), key_start); + error = TRUE; + break; + } + } + else + { + arg_start = linep; + linep = skiptowhite(linep); + } + if (linep == arg_start) + { + semsg(_("E417: missing argument: %s"), key_start); + error = TRUE; + break; + } + vim_free(arg); + arg = vim_strnsave(arg_start, (int)(linep - arg_start)); + if (arg == NULL) + { + error = TRUE; + break; + } + if (*linep == '\'') + ++linep; + + /* + * Store the argument. + */ + if ( STRCMP(key, "TERM") == 0 + || STRCMP(key, "CTERM") == 0 + || STRCMP(key, "GUI") == 0) + { + attr = 0; + off = 0; + while (arg[off] != NUL) + { + for (i = sizeof(hl_attr_table) / sizeof(int); --i >= 0; ) + { + len = (int)STRLEN(hl_name_table[i]); + if (STRNICMP(arg + off, hl_name_table[i], len) == 0) + { + attr |= hl_attr_table[i]; + off += len; + break; + } + } + if (i < 0) + { + semsg(_("E418: Illegal value: %s"), arg); + error = TRUE; + break; + } + if (arg[off] == ',') // another one follows + ++off; + } + if (error) + break; + if (*key == 'T') + { + if (!init || !(HL_TABLE()[idx].sg_set & SG_TERM)) + { + if (!init) + HL_TABLE()[idx].sg_set |= SG_TERM; + HL_TABLE()[idx].sg_term = attr; + } + } + else if (*key == 'C') + { + if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) + { + if (!init) + HL_TABLE()[idx].sg_set |= SG_CTERM; + HL_TABLE()[idx].sg_cterm = attr; + HL_TABLE()[idx].sg_cterm_bold = FALSE; + } + } +#if defined(FEAT_GUI) || defined(FEAT_EVAL) + else + { + if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) + { + if (!init) + HL_TABLE()[idx].sg_set |= SG_GUI; + HL_TABLE()[idx].sg_gui = attr; + } + } +#endif + } + else if (STRCMP(key, "FONT") == 0) + { + // in non-GUI fonts are simply ignored +#ifdef FEAT_GUI + if (HL_TABLE()[idx].sg_font_name != NULL + && STRCMP(HL_TABLE()[idx].sg_font_name, arg) == 0) + { + // Font name didn't change, ignore. + } + else if (!gui.shell_created) + { + // GUI not started yet, always accept the name. + vim_free(HL_TABLE()[idx].sg_font_name); + HL_TABLE()[idx].sg_font_name = vim_strsave(arg); + did_change = TRUE; + } + else + { + GuiFont temp_sg_font = HL_TABLE()[idx].sg_font; +# ifdef FEAT_XFONTSET + GuiFontset temp_sg_fontset = HL_TABLE()[idx].sg_fontset; +# endif + // First, save the current font/fontset. + // Then try to allocate the font/fontset. + // If the allocation fails, HL_TABLE()[idx].sg_font OR + // sg_fontset will be set to NOFONT or NOFONTSET respectively. + + HL_TABLE()[idx].sg_font = NOFONT; +# ifdef FEAT_XFONTSET + HL_TABLE()[idx].sg_fontset = NOFONTSET; +# endif + hl_do_font(idx, arg, is_normal_group, is_menu_group, + is_tooltip_group, FALSE); + +# ifdef FEAT_XFONTSET + if (HL_TABLE()[idx].sg_fontset != NOFONTSET) + { + // New fontset was accepted. Free the old one, if there + // was one. + gui_mch_free_fontset(temp_sg_fontset); + vim_free(HL_TABLE()[idx].sg_font_name); + HL_TABLE()[idx].sg_font_name = vim_strsave(arg); + did_change = TRUE; + } + else + HL_TABLE()[idx].sg_fontset = temp_sg_fontset; +# endif + if (HL_TABLE()[idx].sg_font != NOFONT) + { + // New font was accepted. Free the old one, if there was + // one. + gui_mch_free_font(temp_sg_font); + vim_free(HL_TABLE()[idx].sg_font_name); + HL_TABLE()[idx].sg_font_name = vim_strsave(arg); + did_change = TRUE; + } + else + HL_TABLE()[idx].sg_font = temp_sg_font; + } +#endif + } + else if (STRCMP(key, "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0) + { + if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) + { + if (!init) + HL_TABLE()[idx].sg_set |= SG_CTERM; + + // When setting the foreground color, and previously the "bold" + // flag was set for a light color, reset it now + if (key[5] == 'F' && HL_TABLE()[idx].sg_cterm_bold) + { + HL_TABLE()[idx].sg_cterm &= ~HL_BOLD; + HL_TABLE()[idx].sg_cterm_bold = FALSE; + } + + if (VIM_ISDIGIT(*arg)) + color = atoi((char *)arg); + else if (STRICMP(arg, "fg") == 0) + { + if (cterm_normal_fg_color) + color = cterm_normal_fg_color - 1; + else + { + emsg(_("E419: FG color unknown")); + error = TRUE; + break; + } + } + else if (STRICMP(arg, "bg") == 0) + { + if (cterm_normal_bg_color > 0) + color = cterm_normal_bg_color - 1; + else + { + emsg(_("E420: BG color unknown")); + error = TRUE; + break; + } + } + else + { + int bold = MAYBE; + +#if defined(__QNXNTO__) + static int *color_numbers_8_qansi = color_numbers_8; + // On qnx, the 8 & 16 color arrays are the same + if (STRNCMP(T_NAME, "qansi", 5) == 0) + color_numbers_8_qansi = color_numbers_16; +#endif + + // reduce calls to STRICMP a bit, it can be slow + off = TOUPPER_ASC(*arg); + for (i = (sizeof(color_names) / sizeof(char *)); --i >= 0; ) + if (off == color_names[i][0] + && STRICMP(arg + 1, color_names[i] + 1) == 0) + break; + if (i < 0) + { + semsg(_("E421: Color name or number not recognized: %s"), key_start); + error = TRUE; + break; + } + + color = lookup_color(i, key[5] == 'F', &bold); + + // set/reset bold attribute to get light foreground + // colors (on some terminals, e.g. "linux") + if (bold == TRUE) + { + HL_TABLE()[idx].sg_cterm |= HL_BOLD; + HL_TABLE()[idx].sg_cterm_bold = TRUE; + } + else if (bold == FALSE) + HL_TABLE()[idx].sg_cterm &= ~HL_BOLD; + } + + // Add one to the argument, to avoid zero. Zero is used for + // "NONE", then "color" is -1. + if (key[5] == 'F') + { + HL_TABLE()[idx].sg_cterm_fg = color + 1; + if (is_normal_group) + { + cterm_normal_fg_color = color + 1; + cterm_normal_fg_bold = (HL_TABLE()[idx].sg_cterm & HL_BOLD); +#ifdef FEAT_GUI + // Don't do this if the GUI is used. + if (!gui.in_use && !gui.starting) +#endif + { + must_redraw = CLEAR; + if (termcap_active && color >= 0) + term_fg_color(color); + } + } + } + else + { + HL_TABLE()[idx].sg_cterm_bg = color + 1; + if (is_normal_group) + { + cterm_normal_bg_color = color + 1; +#ifdef FEAT_GUI + // Don't mess with 'background' if the GUI is used. + if (!gui.in_use && !gui.starting) +#endif + { + must_redraw = CLEAR; + if (color >= 0) + { + int dark = -1; + + if (termcap_active) + term_bg_color(color); + if (t_colors < 16) + dark = (color == 0 || color == 4); + // Limit the heuristic to the standard 16 colors + else if (color < 16) + dark = (color < 7 || color == 8); + // Set the 'background' option if the value is + // wrong. + if (dark != -1 + && dark != (*p_bg == 'd') + && !option_was_set((char_u *)"bg")) + { + set_option_value((char_u *)"bg", 0L, + (char_u *)(dark ? "dark" : "light"), 0); + reset_option_was_set((char_u *)"bg"); + } + } + } + } + } + } + } + else if (STRCMP(key, "GUIFG") == 0) + { +#if defined(FEAT_GUI) || defined(FEAT_EVAL) + char_u **namep = &HL_TABLE()[idx].sg_gui_fg_name; + + if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) + { + if (!init) + HL_TABLE()[idx].sg_set |= SG_GUI; + +# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) + // In GUI guifg colors are only used when recognized + i = color_name2handle(arg); + if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT) + { + HL_TABLE()[idx].sg_gui_fg = i; +# endif + if (*namep == NULL || STRCMP(*namep, arg) != 0) + { + vim_free(*namep); + if (STRCMP(arg, "NONE") != 0) + *namep = vim_strsave(arg); + else + *namep = NULL; + did_change = TRUE; + } +# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) +# ifdef FEAT_GUI_X11 + if (is_menu_group && gui.menu_fg_pixel != i) + { + gui.menu_fg_pixel = i; + do_colors = TRUE; + } + if (is_scrollbar_group && gui.scroll_fg_pixel != i) + { + gui.scroll_fg_pixel = i; + do_colors = TRUE; + } +# ifdef FEAT_BEVAL_GUI + if (is_tooltip_group && gui.tooltip_fg_pixel != i) + { + gui.tooltip_fg_pixel = i; + do_colors = TRUE; + } +# endif +# endif + } +# endif + } +#endif + } + else if (STRCMP(key, "GUIBG") == 0) + { +#if defined(FEAT_GUI) || defined(FEAT_EVAL) + char_u **namep = &HL_TABLE()[idx].sg_gui_bg_name; + + if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) + { + if (!init) + HL_TABLE()[idx].sg_set |= SG_GUI; + +# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) + // In GUI guifg colors are only used when recognized + i = color_name2handle(arg); + if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT) + { + HL_TABLE()[idx].sg_gui_bg = i; +# endif + if (*namep == NULL || STRCMP(*namep, arg) != 0) + { + vim_free(*namep); + if (STRCMP(arg, "NONE") != 0) + *namep = vim_strsave(arg); + else + *namep = NULL; + did_change = TRUE; + } +# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) +# ifdef FEAT_GUI_X11 + if (is_menu_group && gui.menu_bg_pixel != i) + { + gui.menu_bg_pixel = i; + do_colors = TRUE; + } + if (is_scrollbar_group && gui.scroll_bg_pixel != i) + { + gui.scroll_bg_pixel = i; + do_colors = TRUE; + } +# ifdef FEAT_BEVAL_GUI + if (is_tooltip_group && gui.tooltip_bg_pixel != i) + { + gui.tooltip_bg_pixel = i; + do_colors = TRUE; + } +# endif +# endif + } +# endif + } +#endif + } + else if (STRCMP(key, "GUISP") == 0) + { +#if defined(FEAT_GUI) || defined(FEAT_EVAL) + char_u **namep = &HL_TABLE()[idx].sg_gui_sp_name; + + if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) + { + if (!init) + HL_TABLE()[idx].sg_set |= SG_GUI; + +# ifdef FEAT_GUI + i = color_name2handle(arg); + if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !gui.in_use) + { + HL_TABLE()[idx].sg_gui_sp = i; +# endif + if (*namep == NULL || STRCMP(*namep, arg) != 0) + { + vim_free(*namep); + if (STRCMP(arg, "NONE") != 0) + *namep = vim_strsave(arg); + else + *namep = NULL; + did_change = TRUE; + } +# ifdef FEAT_GUI + } +# endif + } +#endif + } + else if (STRCMP(key, "START") == 0 || STRCMP(key, "STOP") == 0) + { + char_u buf[100]; + char_u *tname; + + if (!init) + HL_TABLE()[idx].sg_set |= SG_TERM; + + /* + * The "start" and "stop" arguments can be a literal escape + * sequence, or a comma separated list of terminal codes. + */ + if (STRNCMP(arg, "t_", 2) == 0) + { + off = 0; + buf[0] = 0; + while (arg[off] != NUL) + { + // Isolate one termcap name + for (len = 0; arg[off + len] && + arg[off + len] != ','; ++len) + ; + tname = vim_strnsave(arg + off, len); + if (tname == NULL) // out of memory + { + error = TRUE; + break; + } + // lookup the escape sequence for the item + p = get_term_code(tname); + vim_free(tname); + if (p == NULL) // ignore non-existing things + p = (char_u *)""; + + // Append it to the already found stuff + if ((int)(STRLEN(buf) + STRLEN(p)) >= 99) + { + semsg(_("E422: terminal code too long: %s"), arg); + error = TRUE; + break; + } + STRCAT(buf, p); + + // Advance to the next item + off += len; + if (arg[off] == ',') // another one follows + ++off; + } + } + else + { + /* + * Copy characters from arg[] to buf[], translating <> codes. + */ + for (p = arg, off = 0; off < 100 - 6 && *p; ) + { + len = trans_special(&p, buf + off, FALSE, FALSE); + if (len > 0) // recognized special char + off += len; + else // copy as normal char + buf[off++] = *p++; + } + buf[off] = NUL; + } + if (error) + break; + + if (STRCMP(buf, "NONE") == 0) // resetting the value + p = NULL; + else + p = vim_strsave(buf); + if (key[2] == 'A') + { + vim_free(HL_TABLE()[idx].sg_start); + HL_TABLE()[idx].sg_start = p; + } + else + { + vim_free(HL_TABLE()[idx].sg_stop); + HL_TABLE()[idx].sg_stop = p; + } + } + else + { + semsg(_("E423: Illegal argument: %s"), key_start); + error = TRUE; + break; + } + HL_TABLE()[idx].sg_cleared = FALSE; + + /* + * When highlighting has been given for a group, don't link it. + */ + if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK)) + HL_TABLE()[idx].sg_link = 0; + + /* + * Continue with next argument. + */ + linep = skipwhite(linep); + } + + /* + * If there is an error, and it's a new entry, remove it from the table. + */ + if (error && idx == highlight_ga.ga_len) + syn_unadd_group(); + else + { + if (is_normal_group) + { + HL_TABLE()[idx].sg_term_attr = 0; + HL_TABLE()[idx].sg_cterm_attr = 0; +#ifdef FEAT_GUI + HL_TABLE()[idx].sg_gui_attr = 0; + /* + * Need to update all groups, because they might be using "bg" + * and/or "fg", which have been changed now. + */ +#endif +#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) + if (USE_24BIT) + { + highlight_gui_started(); + did_highlight_changed = TRUE; + redraw_all_later(NOT_VALID); + } +#endif + } +#ifdef FEAT_TERMINAL + else if (is_terminal_group) + set_terminal_default_colors( + HL_TABLE()[idx].sg_cterm_fg, HL_TABLE()[idx].sg_cterm_bg); +#endif +#ifdef FEAT_GUI_X11 +# ifdef FEAT_MENU + else if (is_menu_group) + { + if (gui.in_use && do_colors) + gui_mch_new_menu_colors(); + } +# endif + else if (is_scrollbar_group) + { + if (gui.in_use && do_colors) + gui_new_scrollbar_colors(); + else + set_hl_attr(idx); + } +# ifdef FEAT_BEVAL_GUI + else if (is_tooltip_group) + { + if (gui.in_use && do_colors) + gui_mch_new_tooltip_colors(); + } +# endif +#endif + else + set_hl_attr(idx); +#ifdef FEAT_EVAL + HL_TABLE()[idx].sg_script_ctx = current_sctx; + HL_TABLE()[idx].sg_script_ctx.sc_lnum += sourcing_lnum; +#endif + } + + vim_free(key); + vim_free(arg); + + // Only call highlight_changed() once, after a sequence of highlight + // commands, and only if an attribute actually changed. + if ((did_change + || memcmp(&HL_TABLE()[idx], &item_before, sizeof(item_before)) != 0) +#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) + && !did_highlight_changed +#endif + ) + { + // Do not trigger a redraw when highlighting is changed while + // redrawing. This may happen when evaluating 'statusline' changes the + // StatusLine group. + if (!updating_screen) + redraw_all_later(NOT_VALID); + need_highlight_changed = TRUE; + } +} + +#if defined(EXITFREE) || defined(PROTO) + void +free_highlight(void) +{ + int i; + + for (i = 0; i < highlight_ga.ga_len; ++i) + { + highlight_clear(i); + vim_free(HL_TABLE()[i].sg_name); + vim_free(HL_TABLE()[i].sg_name_u); + } + ga_clear(&highlight_ga); +} +#endif + +/* + * Reset the cterm colors to what they were before Vim was started, if + * possible. Otherwise reset them to zero. + */ + void +restore_cterm_colors(void) +{ +#if defined(MSWIN) && !defined(FEAT_GUI_MSWIN) + // Since t_me has been set, this probably means that the user + // wants to use this as default colors. Need to reset default + // background/foreground colors. + mch_set_normal_colors(); +#else +# ifdef VIMDLL + if (!gui.in_use) + { + mch_set_normal_colors(); + return; + } +# endif + cterm_normal_fg_color = 0; + cterm_normal_fg_bold = 0; + cterm_normal_bg_color = 0; +# ifdef FEAT_TERMGUICOLORS + cterm_normal_fg_gui_color = INVALCOLOR; + cterm_normal_bg_gui_color = INVALCOLOR; +# endif +#endif +} + +/* + * Return TRUE if highlight group "idx" has any settings. + * When "check_link" is TRUE also check for an existing link. + */ + static int +hl_has_settings(int idx, int check_link) +{ + return ( HL_TABLE()[idx].sg_term_attr != 0 + || HL_TABLE()[idx].sg_cterm_attr != 0 + || HL_TABLE()[idx].sg_cterm_fg != 0 + || HL_TABLE()[idx].sg_cterm_bg != 0 +#ifdef FEAT_GUI + || HL_TABLE()[idx].sg_gui_attr != 0 + || 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 != NULL +#endif + || (check_link && (HL_TABLE()[idx].sg_set & SG_LINK))); +} + +/* + * Clear highlighting for one group. + */ + static void +highlight_clear(int idx) +{ + HL_TABLE()[idx].sg_cleared = TRUE; + + HL_TABLE()[idx].sg_term = 0; + VIM_CLEAR(HL_TABLE()[idx].sg_start); + VIM_CLEAR(HL_TABLE()[idx].sg_stop); + HL_TABLE()[idx].sg_term_attr = 0; + HL_TABLE()[idx].sg_cterm = 0; + HL_TABLE()[idx].sg_cterm_bold = FALSE; + HL_TABLE()[idx].sg_cterm_fg = 0; + HL_TABLE()[idx].sg_cterm_bg = 0; + HL_TABLE()[idx].sg_cterm_attr = 0; +#if defined(FEAT_GUI) || defined(FEAT_EVAL) + HL_TABLE()[idx].sg_gui = 0; + VIM_CLEAR(HL_TABLE()[idx].sg_gui_fg_name); + VIM_CLEAR(HL_TABLE()[idx].sg_gui_bg_name); + VIM_CLEAR(HL_TABLE()[idx].sg_gui_sp_name); +#endif +#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) + HL_TABLE()[idx].sg_gui_fg = INVALCOLOR; + HL_TABLE()[idx].sg_gui_bg = INVALCOLOR; +#endif +#ifdef FEAT_GUI + HL_TABLE()[idx].sg_gui_sp = INVALCOLOR; + gui_mch_free_font(HL_TABLE()[idx].sg_font); + HL_TABLE()[idx].sg_font = NOFONT; +# ifdef FEAT_XFONTSET + gui_mch_free_fontset(HL_TABLE()[idx].sg_fontset); + HL_TABLE()[idx].sg_fontset = NOFONTSET; +# endif + VIM_CLEAR(HL_TABLE()[idx].sg_font_name); + HL_TABLE()[idx].sg_gui_attr = 0; +#endif +#ifdef FEAT_EVAL + // Clear the script ID only when there is no link, since that is not + // cleared. + if (HL_TABLE()[idx].sg_link == 0) + { + HL_TABLE()[idx].sg_script_ctx.sc_sid = 0; + HL_TABLE()[idx].sg_script_ctx.sc_lnum = 0; + } +#endif +} + +#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO) +/* + * Set the normal foreground and background colors according to the "Normal" + * highlighting group. For X11 also set "Menu", "Scrollbar", and + * "Tooltip" colors. + */ + void +set_normal_colors(void) +{ +# ifdef FEAT_GUI +# ifdef FEAT_TERMGUICOLORS + if (gui.in_use) +# endif + { + if (set_group_colors((char_u *)"Normal", + &gui.norm_pixel, &gui.back_pixel, + FALSE, TRUE, FALSE)) + { + gui_mch_new_colors(); + must_redraw = CLEAR; + } +# ifdef FEAT_GUI_X11 + if (set_group_colors((char_u *)"Menu", + &gui.menu_fg_pixel, &gui.menu_bg_pixel, + TRUE, FALSE, FALSE)) + { +# ifdef FEAT_MENU + gui_mch_new_menu_colors(); +# endif + must_redraw = CLEAR; + } +# ifdef FEAT_BEVAL_GUI + if (set_group_colors((char_u *)"Tooltip", + &gui.tooltip_fg_pixel, &gui.tooltip_bg_pixel, + FALSE, FALSE, TRUE)) + { +# ifdef FEAT_TOOLBAR + gui_mch_new_tooltip_colors(); +# endif + must_redraw = CLEAR; + } +# endif + if (set_group_colors((char_u *)"Scrollbar", + &gui.scroll_fg_pixel, &gui.scroll_bg_pixel, + FALSE, FALSE, FALSE)) + { + gui_new_scrollbar_colors(); + must_redraw = CLEAR; + } +# endif + } +# endif +# ifdef FEAT_TERMGUICOLORS +# ifdef FEAT_GUI + else +# endif + { + int idx; + + idx = syn_name2id((char_u *)"Normal") - 1; + if (idx >= 0) + { + gui_do_one_color(idx, FALSE, FALSE); + + // If the normal fg or bg color changed a complete redraw is + // required. + if (cterm_normal_fg_gui_color != HL_TABLE()[idx].sg_gui_fg + || cterm_normal_bg_gui_color != HL_TABLE()[idx].sg_gui_bg) + { + // if the GUI color is INVALCOLOR then we use the default cterm + // color + cterm_normal_fg_gui_color = HL_TABLE()[idx].sg_gui_fg; + cterm_normal_bg_gui_color = HL_TABLE()[idx].sg_gui_bg; + must_redraw = CLEAR; + } + } + } +# endif +} +#endif + +#if defined(FEAT_GUI) || defined(PROTO) +/* + * Set the colors for "Normal", "Menu", "Tooltip" or "Scrollbar". + */ + static int +set_group_colors( + char_u *name, + guicolor_T *fgp, + guicolor_T *bgp, + int do_menu, + int use_norm, + int do_tooltip) +{ + int idx; + + idx = syn_name2id(name) - 1; + if (idx >= 0) + { + gui_do_one_color(idx, do_menu, do_tooltip); + + if (HL_TABLE()[idx].sg_gui_fg != INVALCOLOR) + *fgp = HL_TABLE()[idx].sg_gui_fg; + else if (use_norm) + *fgp = gui.def_norm_pixel; + if (HL_TABLE()[idx].sg_gui_bg != INVALCOLOR) + *bgp = HL_TABLE()[idx].sg_gui_bg; + else if (use_norm) + *bgp = gui.def_back_pixel; + return TRUE; + } + return FALSE; +} + +/* + * Get the font of the "Normal" group. + * Returns "" when it's not found or not set. + */ + char_u * +hl_get_font_name(void) +{ + int id; + char_u *s; + + id = syn_name2id((char_u *)"Normal"); + if (id > 0) + { + s = HL_TABLE()[id - 1].sg_font_name; + if (s != NULL) + return s; + } + return (char_u *)""; +} + +/* + * Set font for "Normal" group. Called by gui_mch_init_font() when a font has + * actually chosen to be used. + */ + void +hl_set_font_name(char_u *font_name) +{ + int id; + + id = syn_name2id((char_u *)"Normal"); + if (id > 0) + { + vim_free(HL_TABLE()[id - 1].sg_font_name); + HL_TABLE()[id - 1].sg_font_name = vim_strsave(font_name); + } +} + +/* + * Set background color for "Normal" group. Called by gui_set_bg_color() + * when the color is known. + */ + void +hl_set_bg_color_name( + char_u *name) // must have been allocated +{ + int id; + + if (name != NULL) + { + id = syn_name2id((char_u *)"Normal"); + if (id > 0) + { + vim_free(HL_TABLE()[id - 1].sg_gui_bg_name); + HL_TABLE()[id - 1].sg_gui_bg_name = name; + } + } +} + +/* + * Set foreground color for "Normal" group. Called by gui_set_fg_color() + * when the color is known. + */ + void +hl_set_fg_color_name( + char_u *name) // must have been allocated +{ + int id; + + if (name != NULL) + { + id = syn_name2id((char_u *)"Normal"); + if (id > 0) + { + vim_free(HL_TABLE()[id - 1].sg_gui_fg_name); + HL_TABLE()[id - 1].sg_gui_fg_name = name; + } + } +} + +/* + * Return the handle for a font name. + * Returns NOFONT when failed. + */ + static GuiFont +font_name2handle(char_u *name) +{ + if (STRCMP(name, "NONE") == 0) + return NOFONT; + + return gui_mch_get_font(name, TRUE); +} + +# ifdef FEAT_XFONTSET +/* + * Return the handle for a fontset name. + * Returns NOFONTSET when failed. + */ + static GuiFontset +fontset_name2handle(char_u *name, int fixed_width) +{ + if (STRCMP(name, "NONE") == 0) + return NOFONTSET; + + return gui_mch_get_fontset(name, TRUE, fixed_width); +} +# endif + +/* + * Get the font or fontset for one highlight group. + */ + static void +hl_do_font( + int idx, + char_u *arg, + int do_normal, // set normal font + int do_menu UNUSED, // set menu font + int do_tooltip UNUSED, // set tooltip font + int free_font) // free current font/fontset +{ +# ifdef FEAT_XFONTSET + // If 'guifontset' is not empty, first try using the name as a + // fontset. If that doesn't work, use it as a font name. + if (*p_guifontset != NUL +# ifdef FONTSET_ALWAYS + || do_menu +# endif +# ifdef FEAT_BEVAL_TIP + // In Athena & Motif, the Tooltip highlight group is always a fontset + || do_tooltip +# endif + ) + { + if (free_font) + gui_mch_free_fontset(HL_TABLE()[idx].sg_fontset); + HL_TABLE()[idx].sg_fontset = fontset_name2handle(arg, 0 +# ifdef FONTSET_ALWAYS + || do_menu +# endif +# ifdef FEAT_BEVAL_TIP + || do_tooltip +# endif + ); + } + if (HL_TABLE()[idx].sg_fontset != NOFONTSET) + { + // If it worked and it's the Normal group, use it as the normal + // fontset. Same for the Menu group. + if (do_normal) + gui_init_font(arg, TRUE); +# if (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) && defined(FEAT_MENU) + if (do_menu) + { +# ifdef FONTSET_ALWAYS + gui.menu_fontset = HL_TABLE()[idx].sg_fontset; +# else + // YIKES! This is a bug waiting to crash the program + gui.menu_font = HL_TABLE()[idx].sg_fontset; +# endif + gui_mch_new_menu_font(); + } +# ifdef FEAT_BEVAL_GUI + if (do_tooltip) + { + // The Athena widget set cannot currently handle switching between + // displaying a single font and a fontset. + // If the XtNinternational resource is set to True at widget + // creation, then a fontset is always used, otherwise an + // XFontStruct is used. + gui.tooltip_fontset = (XFontSet)HL_TABLE()[idx].sg_fontset; + gui_mch_new_tooltip_font(); + } +# endif +# endif + } + else +# endif + { + if (free_font) + gui_mch_free_font(HL_TABLE()[idx].sg_font); + HL_TABLE()[idx].sg_font = font_name2handle(arg); + // If it worked and it's the Normal group, use it as the + // normal font. Same for the Menu group. + if (HL_TABLE()[idx].sg_font != NOFONT) + { + if (do_normal) + gui_init_font(arg, FALSE); +#ifndef FONTSET_ALWAYS +# if (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) && defined(FEAT_MENU) + if (do_menu) + { + gui.menu_font = HL_TABLE()[idx].sg_font; + gui_mch_new_menu_font(); + } +# endif +#endif + } + } +} + +#endif // FEAT_GUI + +#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO) +/* + * Return the handle for a color name. + * Returns INVALCOLOR when failed. + */ + guicolor_T +color_name2handle(char_u *name) +{ + if (STRCMP(name, "NONE") == 0) + return INVALCOLOR; + + if (STRICMP(name, "fg") == 0 || STRICMP(name, "foreground") == 0) + { +#if defined(FEAT_TERMGUICOLORS) && defined(FEAT_GUI) + if (gui.in_use) +#endif +#ifdef FEAT_GUI + return gui.norm_pixel; +#endif +#ifdef FEAT_TERMGUICOLORS + if (cterm_normal_fg_gui_color != INVALCOLOR) + return cterm_normal_fg_gui_color; + // Guess that the foreground is black or white. + return GUI_GET_COLOR((char_u *)(*p_bg == 'l' ? "black" : "white")); +#endif + } + if (STRICMP(name, "bg") == 0 || STRICMP(name, "background") == 0) + { +#if defined(FEAT_TERMGUICOLORS) && defined(FEAT_GUI) + if (gui.in_use) +#endif +#ifdef FEAT_GUI + return gui.back_pixel; +#endif +#ifdef FEAT_TERMGUICOLORS + if (cterm_normal_bg_gui_color != INVALCOLOR) + return cterm_normal_bg_gui_color; + // Guess that the background is white or black. + return GUI_GET_COLOR((char_u *)(*p_bg == 'l' ? "white" : "black")); +#endif + } + + return GUI_GET_COLOR(name); +} +#endif + +/* + * Table with the specifications for an attribute number. + * Note that this table is used by ALL buffers. This is required because the + * GUI can redraw at any time for any buffer. + */ +static garray_T term_attr_table = {0, 0, 0, 0, NULL}; + +#define TERM_ATTR_ENTRY(idx) ((attrentry_T *)term_attr_table.ga_data)[idx] + +static garray_T cterm_attr_table = {0, 0, 0, 0, NULL}; + +#define CTERM_ATTR_ENTRY(idx) ((attrentry_T *)cterm_attr_table.ga_data)[idx] + +#ifdef FEAT_GUI +static garray_T gui_attr_table = {0, 0, 0, 0, NULL}; + +#define GUI_ATTR_ENTRY(idx) ((attrentry_T *)gui_attr_table.ga_data)[idx] +#endif + +/* + * Return the attr number for a set of colors and font. + * Add a new entry to the term_attr_table, cterm_attr_table or gui_attr_table + * if the combination is new. + * Return 0 for error (no more room). + */ + static int +get_attr_entry(garray_T *table, attrentry_T *aep) +{ + int i; + attrentry_T *taep; + static int recursive = FALSE; + + /* + * Init the table, in case it wasn't done yet. + */ + table->ga_itemsize = sizeof(attrentry_T); + table->ga_growsize = 7; + + /* + * Try to find an entry with the same specifications. + */ + for (i = 0; i < table->ga_len; ++i) + { + taep = &(((attrentry_T *)table->ga_data)[i]); + if ( aep->ae_attr == taep->ae_attr + && ( +#ifdef FEAT_GUI + (table == &gui_attr_table + && (aep->ae_u.gui.fg_color == taep->ae_u.gui.fg_color + && aep->ae_u.gui.bg_color + == taep->ae_u.gui.bg_color + && aep->ae_u.gui.sp_color + == taep->ae_u.gui.sp_color + && aep->ae_u.gui.font == taep->ae_u.gui.font +# ifdef FEAT_XFONTSET + && aep->ae_u.gui.fontset == taep->ae_u.gui.fontset +# endif + )) + || +#endif + (table == &term_attr_table + && (aep->ae_u.term.start == NULL) + == (taep->ae_u.term.start == NULL) + && (aep->ae_u.term.start == NULL + || STRCMP(aep->ae_u.term.start, + taep->ae_u.term.start) == 0) + && (aep->ae_u.term.stop == NULL) + == (taep->ae_u.term.stop == NULL) + && (aep->ae_u.term.stop == NULL + || STRCMP(aep->ae_u.term.stop, + taep->ae_u.term.stop) == 0)) + || (table == &cterm_attr_table + && aep->ae_u.cterm.fg_color + == taep->ae_u.cterm.fg_color + && aep->ae_u.cterm.bg_color + == taep->ae_u.cterm.bg_color +#ifdef FEAT_TERMGUICOLORS + && aep->ae_u.cterm.fg_rgb + == taep->ae_u.cterm.fg_rgb + && aep->ae_u.cterm.bg_rgb + == taep->ae_u.cterm.bg_rgb +#endif + ))) + + return i + ATTR_OFF; + } + + if (table->ga_len + ATTR_OFF > MAX_TYPENR) + { + /* + * Running out of attribute entries! remove all attributes, and + * compute new ones for all groups. + * When called recursively, we are really out of numbers. + */ + if (recursive) + { + emsg(_("E424: Too many different highlighting attributes in use")); + return 0; + } + recursive = TRUE; + + clear_hl_tables(); + + must_redraw = CLEAR; + + for (i = 0; i < highlight_ga.ga_len; ++i) + set_hl_attr(i); + + recursive = FALSE; + } + + /* + * This is a new combination of colors and font, add an entry. + */ + if (ga_grow(table, 1) == FAIL) + return 0; + + taep = &(((attrentry_T *)table->ga_data)[table->ga_len]); + vim_memset(taep, 0, sizeof(attrentry_T)); + taep->ae_attr = aep->ae_attr; +#ifdef FEAT_GUI + if (table == &gui_attr_table) + { + taep->ae_u.gui.fg_color = aep->ae_u.gui.fg_color; + taep->ae_u.gui.bg_color = aep->ae_u.gui.bg_color; + taep->ae_u.gui.sp_color = aep->ae_u.gui.sp_color; + taep->ae_u.gui.font = aep->ae_u.gui.font; +# ifdef FEAT_XFONTSET + taep->ae_u.gui.fontset = aep->ae_u.gui.fontset; +# endif + } +#endif + if (table == &term_attr_table) + { + if (aep->ae_u.term.start == NULL) + taep->ae_u.term.start = NULL; + else + taep->ae_u.term.start = vim_strsave(aep->ae_u.term.start); + if (aep->ae_u.term.stop == NULL) + taep->ae_u.term.stop = NULL; + else + taep->ae_u.term.stop = vim_strsave(aep->ae_u.term.stop); + } + else if (table == &cterm_attr_table) + { + taep->ae_u.cterm.fg_color = aep->ae_u.cterm.fg_color; + taep->ae_u.cterm.bg_color = aep->ae_u.cterm.bg_color; +#ifdef FEAT_TERMGUICOLORS + taep->ae_u.cterm.fg_rgb = aep->ae_u.cterm.fg_rgb; + taep->ae_u.cterm.bg_rgb = aep->ae_u.cterm.bg_rgb; +#endif + } + ++table->ga_len; + return (table->ga_len - 1 + ATTR_OFF); +} + +#if defined(FEAT_TERMINAL) || defined(PROTO) +/* + * Get an attribute index for a cterm entry. + * Uses an existing entry when possible or adds one when needed. + */ + int +get_cterm_attr_idx(int attr, int fg, int bg) +{ + attrentry_T at_en; + + vim_memset(&at_en, 0, sizeof(attrentry_T)); +#ifdef FEAT_TERMGUICOLORS + at_en.ae_u.cterm.fg_rgb = INVALCOLOR; + at_en.ae_u.cterm.bg_rgb = INVALCOLOR; +#endif + at_en.ae_attr = attr; + at_en.ae_u.cterm.fg_color = fg; + at_en.ae_u.cterm.bg_color = bg; + return get_attr_entry(&cterm_attr_table, &at_en); +} +#endif + +#if (defined(FEAT_TERMINAL) && defined(FEAT_TERMGUICOLORS)) || defined(PROTO) +/* + * Get an attribute index for a 'termguicolors' entry. + * Uses an existing entry when possible or adds one when needed. + */ + int +get_tgc_attr_idx(int attr, guicolor_T fg, guicolor_T bg) +{ + attrentry_T at_en; + + vim_memset(&at_en, 0, sizeof(attrentry_T)); + at_en.ae_attr = attr; + if (fg == INVALCOLOR && bg == INVALCOLOR) + { + // If both GUI colors are not set fall back to the cterm colors. Helps + // if the GUI only has an attribute, such as undercurl. + at_en.ae_u.cterm.fg_rgb = CTERMCOLOR; + at_en.ae_u.cterm.bg_rgb = CTERMCOLOR; + } + else + { + at_en.ae_u.cterm.fg_rgb = fg; + at_en.ae_u.cterm.bg_rgb = bg; + } + return get_attr_entry(&cterm_attr_table, &at_en); +} +#endif + +#if (defined(FEAT_TERMINAL) && defined(FEAT_GUI)) || defined(PROTO) +/* + * Get an attribute index for a cterm entry. + * Uses an existing entry when possible or adds one when needed. + */ + int +get_gui_attr_idx(int attr, guicolor_T fg, guicolor_T bg) +{ + attrentry_T at_en; + + vim_memset(&at_en, 0, sizeof(attrentry_T)); + at_en.ae_attr = attr; + at_en.ae_u.gui.fg_color = fg; + at_en.ae_u.gui.bg_color = bg; + return get_attr_entry(&gui_attr_table, &at_en); +} +#endif + +/* + * Clear all highlight tables. + */ + void +clear_hl_tables(void) +{ + int i; + attrentry_T *taep; + +#ifdef FEAT_GUI + ga_clear(&gui_attr_table); +#endif + for (i = 0; i < term_attr_table.ga_len; ++i) + { + taep = &(((attrentry_T *)term_attr_table.ga_data)[i]); + vim_free(taep->ae_u.term.start); + vim_free(taep->ae_u.term.stop); + } + ga_clear(&term_attr_table); + ga_clear(&cterm_attr_table); +} + +/* + * Combine special attributes (e.g., for spelling) with other attributes + * (e.g., for syntax highlighting). + * "prim_attr" overrules "char_attr". + * This creates a new group when required. + * Since we expect there to be few spelling mistakes we don't cache the + * result. + * Return the resulting attributes. + */ + int +hl_combine_attr(int char_attr, int prim_attr) +{ + attrentry_T *char_aep = NULL; + attrentry_T *spell_aep; + attrentry_T new_en; + + if (char_attr == 0) + return prim_attr; + if (char_attr <= HL_ALL && prim_attr <= HL_ALL) + return ATTR_COMBINE(char_attr, prim_attr); +#ifdef FEAT_GUI + if (gui.in_use) + { + if (char_attr > HL_ALL) + char_aep = syn_gui_attr2entry(char_attr); + if (char_aep != NULL) + new_en = *char_aep; + else + { + vim_memset(&new_en, 0, sizeof(new_en)); + new_en.ae_u.gui.fg_color = INVALCOLOR; + new_en.ae_u.gui.bg_color = INVALCOLOR; + new_en.ae_u.gui.sp_color = INVALCOLOR; + if (char_attr <= HL_ALL) + new_en.ae_attr = char_attr; + } + + if (prim_attr <= HL_ALL) + new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, prim_attr); + else + { + spell_aep = syn_gui_attr2entry(prim_attr); + if (spell_aep != NULL) + { + new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, + spell_aep->ae_attr); + if (spell_aep->ae_u.gui.fg_color != INVALCOLOR) + new_en.ae_u.gui.fg_color = spell_aep->ae_u.gui.fg_color; + if (spell_aep->ae_u.gui.bg_color != INVALCOLOR) + new_en.ae_u.gui.bg_color = spell_aep->ae_u.gui.bg_color; + if (spell_aep->ae_u.gui.sp_color != INVALCOLOR) + new_en.ae_u.gui.sp_color = spell_aep->ae_u.gui.sp_color; + if (spell_aep->ae_u.gui.font != NOFONT) + new_en.ae_u.gui.font = spell_aep->ae_u.gui.font; +# ifdef FEAT_XFONTSET + if (spell_aep->ae_u.gui.fontset != NOFONTSET) + new_en.ae_u.gui.fontset = spell_aep->ae_u.gui.fontset; +# endif + } + } + return get_attr_entry(&gui_attr_table, &new_en); + } +#endif + + if (IS_CTERM) + { + if (char_attr > HL_ALL) + char_aep = syn_cterm_attr2entry(char_attr); + if (char_aep != NULL) + new_en = *char_aep; + 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; + } + + if (prim_attr <= HL_ALL) + new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, prim_attr); + else + { + spell_aep = syn_cterm_attr2entry(prim_attr); + if (spell_aep != NULL) + { + new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, + spell_aep->ae_attr); + if (spell_aep->ae_u.cterm.fg_color > 0) + new_en.ae_u.cterm.fg_color = spell_aep->ae_u.cterm.fg_color; + if (spell_aep->ae_u.cterm.bg_color > 0) + new_en.ae_u.cterm.bg_color = spell_aep->ae_u.cterm.bg_color; +#ifdef FEAT_TERMGUICOLORS + // If both fg and bg are not set fall back to cterm colors. + // Helps for SpellBad which uses undercurl in the GUI. + if (COLOR_INVALID(spell_aep->ae_u.cterm.fg_rgb) + && COLOR_INVALID(spell_aep->ae_u.cterm.bg_rgb)) + { + if (spell_aep->ae_u.cterm.fg_color > 0) + new_en.ae_u.cterm.fg_rgb = CTERMCOLOR; + if (spell_aep->ae_u.cterm.bg_color > 0) + new_en.ae_u.cterm.bg_rgb = CTERMCOLOR; + } + else + { + if (spell_aep->ae_u.cterm.fg_rgb != INVALCOLOR) + new_en.ae_u.cterm.fg_rgb = spell_aep->ae_u.cterm.fg_rgb; + if (spell_aep->ae_u.cterm.bg_rgb != INVALCOLOR) + new_en.ae_u.cterm.bg_rgb = spell_aep->ae_u.cterm.bg_rgb; + } +#endif + } + } + return get_attr_entry(&cterm_attr_table, &new_en); + } + + if (char_attr > HL_ALL) + char_aep = syn_term_attr2entry(char_attr); + if (char_aep != NULL) + new_en = *char_aep; + else + { + vim_memset(&new_en, 0, sizeof(new_en)); + if (char_attr <= HL_ALL) + new_en.ae_attr = char_attr; + } + + if (prim_attr <= HL_ALL) + new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, prim_attr); + else + { + spell_aep = syn_term_attr2entry(prim_attr); + if (spell_aep != NULL) + { + new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, spell_aep->ae_attr); + if (spell_aep->ae_u.term.start != NULL) + { + new_en.ae_u.term.start = spell_aep->ae_u.term.start; + new_en.ae_u.term.stop = spell_aep->ae_u.term.stop; + } + } + } + return get_attr_entry(&term_attr_table, &new_en); +} + +#ifdef FEAT_GUI + attrentry_T * +syn_gui_attr2entry(int attr) +{ + attr -= ATTR_OFF; + if (attr >= gui_attr_table.ga_len) // did ":syntax clear" + return NULL; + return &(GUI_ATTR_ENTRY(attr)); +} +#endif + +/* + * Get the highlight attributes (HL_BOLD etc.) from an attribute nr. + * Only to be used when "attr" > HL_ALL. + */ + int +syn_attr2attr(int attr) +{ + attrentry_T *aep; + +#ifdef FEAT_GUI + if (gui.in_use) + aep = syn_gui_attr2entry(attr); + else +#endif + if (IS_CTERM) + aep = syn_cterm_attr2entry(attr); + else + aep = syn_term_attr2entry(attr); + + if (aep == NULL) // highlighting not set + return 0; + return aep->ae_attr; +} + + + attrentry_T * +syn_term_attr2entry(int attr) +{ + attr -= ATTR_OFF; + if (attr >= term_attr_table.ga_len) // did ":syntax clear" + return NULL; + return &(TERM_ATTR_ENTRY(attr)); +} + + attrentry_T * +syn_cterm_attr2entry(int attr) +{ + attr -= ATTR_OFF; + if (attr >= cterm_attr_table.ga_len) // did ":syntax clear" + return NULL; + return &(CTERM_ATTR_ENTRY(attr)); +} + +#define LIST_ATTR 1 +#define LIST_STRING 2 +#define LIST_INT 3 + + static void +highlight_list_one(int id) +{ + hl_group_T *sgp; + int didh = FALSE; + + sgp = &HL_TABLE()[id - 1]; // index is ID minus one + + if (message_filtered(sgp->sg_name)) + return; + + didh = highlight_list_arg(id, didh, LIST_ATTR, + sgp->sg_term, NULL, "term"); + didh = highlight_list_arg(id, didh, LIST_STRING, + 0, sgp->sg_start, "start"); + didh = highlight_list_arg(id, didh, LIST_STRING, + 0, sgp->sg_stop, "stop"); + + didh = highlight_list_arg(id, didh, LIST_ATTR, + sgp->sg_cterm, NULL, "cterm"); + didh = highlight_list_arg(id, didh, LIST_INT, + sgp->sg_cterm_fg, NULL, "ctermfg"); + didh = highlight_list_arg(id, didh, LIST_INT, + sgp->sg_cterm_bg, NULL, "ctermbg"); + +#if defined(FEAT_GUI) || defined(FEAT_EVAL) + didh = highlight_list_arg(id, didh, LIST_ATTR, + sgp->sg_gui, NULL, "gui"); + didh = highlight_list_arg(id, didh, LIST_STRING, + 0, sgp->sg_gui_fg_name, "guifg"); + didh = highlight_list_arg(id, didh, LIST_STRING, + 0, sgp->sg_gui_bg_name, "guibg"); + didh = highlight_list_arg(id, didh, LIST_STRING, + 0, sgp->sg_gui_sp_name, "guisp"); +#endif +#ifdef FEAT_GUI + didh = highlight_list_arg(id, didh, LIST_STRING, + 0, sgp->sg_font_name, "font"); +#endif + + if (sgp->sg_link && !got_int) + { + (void)syn_list_header(didh, 9999, id); + didh = TRUE; + msg_puts_attr("links to", HL_ATTR(HLF_D)); + msg_putchar(' '); + msg_outtrans(HL_TABLE()[HL_TABLE()[id - 1].sg_link - 1].sg_name); + } + + if (!didh) + highlight_list_arg(id, didh, LIST_STRING, 0, (char_u *)"cleared", ""); +#ifdef FEAT_EVAL + if (p_verbose > 0) + last_set_msg(sgp->sg_script_ctx); +#endif +} + + static int +highlight_list_arg( + int id, + int didh, + int type, + int iarg, + char_u *sarg, + char *name) +{ + char_u buf[100]; + char_u *ts; + int i; + + if (got_int) + return FALSE; + if (type == LIST_STRING ? (sarg != NULL) : (iarg != 0)) + { + ts = buf; + if (type == LIST_INT) + sprintf((char *)buf, "%d", iarg - 1); + else if (type == LIST_STRING) + ts = sarg; + else // type == LIST_ATTR + { + buf[0] = NUL; + for (i = 0; hl_attr_table[i] != 0; ++i) + { + if (iarg & hl_attr_table[i]) + { + if (buf[0] != NUL) + vim_strcat(buf, (char_u *)",", 100); + vim_strcat(buf, (char_u *)hl_name_table[i], 100); + iarg &= ~hl_attr_table[i]; // don't want "inverse" + } + } + } + + (void)syn_list_header(didh, + (int)(vim_strsize(ts) + STRLEN(name) + 1), id); + didh = TRUE; + if (!got_int) + { + if (*name != NUL) + { + msg_puts_attr(name, HL_ATTR(HLF_D)); + msg_puts_attr("=", HL_ATTR(HLF_D)); + } + msg_outtrans(ts); + } + } + return didh; +} + +#if (((defined(FEAT_EVAL) || defined(FEAT_PRINTER))) && defined(FEAT_SYN_HL)) || defined(PROTO) +/* + * Return "1" if highlight group "id" has attribute "flag". + * Return NULL otherwise. + */ + char_u * +highlight_has_attr( + int id, + int flag, + int modec) // 'g' for GUI, 'c' for cterm, 't' for term +{ + int attr; + + if (id <= 0 || id > highlight_ga.ga_len) + return NULL; + +#if defined(FEAT_GUI) || defined(FEAT_EVAL) + if (modec == 'g') + attr = HL_TABLE()[id - 1].sg_gui; + else +#endif + if (modec == 'c') + attr = HL_TABLE()[id - 1].sg_cterm; + else + attr = HL_TABLE()[id - 1].sg_term; + + if (attr & flag) + return (char_u *)"1"; + return NULL; +} +#endif + +#if (defined(FEAT_SYN_HL) && defined(FEAT_EVAL)) || defined(PROTO) +/* + * Return color name of highlight group "id". + */ + char_u * +highlight_color( + int id, + char_u *what, // "font", "fg", "bg", "sp", "fg#", "bg#" or "sp#" + int modec) // 'g' for GUI, 'c' for cterm, 't' for term +{ + static char_u name[20]; + int n; + int fg = FALSE; + int sp = FALSE; + int font = FALSE; + + if (id <= 0 || id > highlight_ga.ga_len) + return NULL; + + if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'g') + fg = TRUE; + else if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'o' + && TOLOWER_ASC(what[2]) == 'n' && TOLOWER_ASC(what[3]) == 't') + font = TRUE; + else if (TOLOWER_ASC(what[0]) == 's' && TOLOWER_ASC(what[1]) == 'p') + sp = TRUE; + else if (!(TOLOWER_ASC(what[0]) == 'b' && TOLOWER_ASC(what[1]) == 'g')) + return NULL; + if (modec == 'g') + { +# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) +# ifdef FEAT_GUI + // return font name + if (font) + return HL_TABLE()[id - 1].sg_font_name; +# endif + + // return #RRGGBB form (only possible when GUI is running) + if ((USE_24BIT) && what[2] == '#') + { + guicolor_T color; + long_u rgb; + static char_u buf[10]; + + if (fg) + color = HL_TABLE()[id - 1].sg_gui_fg; + else if (sp) +# ifdef FEAT_GUI + color = HL_TABLE()[id - 1].sg_gui_sp; +# else + color = INVALCOLOR; +# endif + else + color = HL_TABLE()[id - 1].sg_gui_bg; + if (color == INVALCOLOR) + return NULL; + rgb = (long_u)GUI_MCH_GET_RGB(color); + sprintf((char *)buf, "#%02x%02x%02x", + (unsigned)(rgb >> 16), + (unsigned)(rgb >> 8) & 255, + (unsigned)rgb & 255); + return buf; + } +# endif + if (fg) + return (HL_TABLE()[id - 1].sg_gui_fg_name); + if (sp) + return (HL_TABLE()[id - 1].sg_gui_sp_name); + return (HL_TABLE()[id - 1].sg_gui_bg_name); + } + if (font || sp) + return NULL; + if (modec == 'c') + { + if (fg) + n = HL_TABLE()[id - 1].sg_cterm_fg - 1; + else + n = HL_TABLE()[id - 1].sg_cterm_bg - 1; + if (n < 0) + return NULL; + sprintf((char *)name, "%d", n); + return name; + } + // term doesn't have color + return NULL; +} +#endif + +#if (defined(FEAT_SYN_HL) \ + && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)) \ + && defined(FEAT_PRINTER)) || defined(PROTO) +/* + * Return color name of highlight group "id" as RGB value. + */ + long_u +highlight_gui_color_rgb( + int id, + int fg) // TRUE = fg, FALSE = bg +{ + guicolor_T color; + + if (id <= 0 || id > highlight_ga.ga_len) + return 0L; + + if (fg) + color = HL_TABLE()[id - 1].sg_gui_fg; + else + color = HL_TABLE()[id - 1].sg_gui_bg; + + if (color == INVALCOLOR) + return 0L; + + return GUI_MCH_GET_RGB(color); +} +#endif + +/* + * Output the syntax list header. + * Return TRUE when started a new line. + */ + int +syn_list_header( + int did_header, // did header already + int outlen, // length of string that comes + int id) // highlight group id +{ + int endcol = 19; + int newline = TRUE; + int name_col = 0; + + if (!did_header) + { + msg_putchar('\n'); + if (got_int) + return TRUE; + msg_outtrans(HL_TABLE()[id - 1].sg_name); + name_col = msg_col; + endcol = 15; + } + else if (msg_col + outlen + 1 >= Columns) + { + msg_putchar('\n'); + if (got_int) + return TRUE; + } + else + { + if (msg_col >= endcol) // wrap around is like starting a new line + newline = FALSE; + } + + if (msg_col >= endcol) // output at least one space + endcol = msg_col + 1; + if (Columns <= endcol) // avoid hang for tiny window + endcol = Columns - 1; + + msg_advance(endcol); + + // Show "xxx" with the attributes. + if (!did_header) + { + if (endcol == Columns - 1 && endcol <= name_col) + msg_putchar(' '); + msg_puts_attr("xxx", syn_id2attr(id)); + msg_putchar(' '); + } + + return newline; +} + +/* + * Set the attribute numbers for a highlight group. + * Called after one of the attributes has changed. + */ + static void +set_hl_attr( + int idx) // index in array +{ + attrentry_T at_en; + hl_group_T *sgp = HL_TABLE() + idx; + + // The "Normal" group doesn't need an attribute number + if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0) + return; + +#ifdef FEAT_GUI + /* + * For the GUI mode: If there are other than "normal" highlighting + * attributes, need to allocate an attr number. + */ + if (sgp->sg_gui_fg == INVALCOLOR + && sgp->sg_gui_bg == INVALCOLOR + && sgp->sg_gui_sp == INVALCOLOR + && sgp->sg_font == NOFONT +# ifdef FEAT_XFONTSET + && sgp->sg_fontset == NOFONTSET +# endif + ) + { + sgp->sg_gui_attr = sgp->sg_gui; + } + else + { + at_en.ae_attr = sgp->sg_gui; + at_en.ae_u.gui.fg_color = sgp->sg_gui_fg; + at_en.ae_u.gui.bg_color = sgp->sg_gui_bg; + at_en.ae_u.gui.sp_color = sgp->sg_gui_sp; + at_en.ae_u.gui.font = sgp->sg_font; +# ifdef FEAT_XFONTSET + at_en.ae_u.gui.fontset = sgp->sg_fontset; +# endif + sgp->sg_gui_attr = get_attr_entry(&gui_attr_table, &at_en); + } +#endif + /* + * For the term mode: If there are other than "normal" highlighting + * attributes, need to allocate an attr number. + */ + if (sgp->sg_start == NULL && sgp->sg_stop == NULL) + sgp->sg_term_attr = sgp->sg_term; + else + { + at_en.ae_attr = sgp->sg_term; + at_en.ae_u.term.start = sgp->sg_start; + at_en.ae_u.term.stop = sgp->sg_stop; + sgp->sg_term_attr = get_attr_entry(&term_attr_table, &at_en); + } + + /* + * For the color term mode: If there are other than "normal" + * highlighting attributes, need to allocate an attr number. + */ + if (sgp->sg_cterm_fg == 0 && sgp->sg_cterm_bg == 0 +# ifdef FEAT_TERMGUICOLORS + && sgp->sg_gui_fg == INVALCOLOR + && sgp->sg_gui_bg == INVALCOLOR +# endif + ) + sgp->sg_cterm_attr = sgp->sg_cterm; + else + { + at_en.ae_attr = sgp->sg_cterm; + at_en.ae_u.cterm.fg_color = sgp->sg_cterm_fg; + at_en.ae_u.cterm.bg_color = sgp->sg_cterm_bg; +# ifdef FEAT_TERMGUICOLORS +# ifdef MSWIN +# ifdef VIMDLL + // Only when not using the GUI. + if (!gui.in_use && !gui.starting) +# endif + { + int id; + guicolor_T fg, bg; + + id = syn_name2id((char_u *)"Normal"); + if (id > 0) + { + syn_id2colors(id, &fg, &bg); + if (sgp->sg_gui_fg == INVALCOLOR) + sgp->sg_gui_fg = fg; + if (sgp->sg_gui_bg == INVALCOLOR) + sgp->sg_gui_bg = bg; + } + + } +# endif + at_en.ae_u.cterm.fg_rgb = GUI_MCH_GET_RGB2(sgp->sg_gui_fg); + at_en.ae_u.cterm.bg_rgb = GUI_MCH_GET_RGB2(sgp->sg_gui_bg); + if (at_en.ae_u.cterm.fg_rgb == INVALCOLOR + && at_en.ae_u.cterm.bg_rgb == INVALCOLOR) + { + // If both fg and bg are invalid fall back to the cterm colors. + // Helps when the GUI only uses an attribute, e.g. undercurl. + at_en.ae_u.cterm.fg_rgb = CTERMCOLOR; + at_en.ae_u.cterm.bg_rgb = CTERMCOLOR; + } +# endif + sgp->sg_cterm_attr = get_attr_entry(&cterm_attr_table, &at_en); + } +} + +/* + * Lookup a highlight group name and return its ID. + * If it is not found, 0 is returned. + */ + int +syn_name2id(char_u *name) +{ + int i; + char_u name_u[200]; + + // Avoid using stricmp() too much, it's slow on some systems + // Avoid alloc()/free(), these are slow too. ID names over 200 chars + // don't deserve to be found! + vim_strncpy(name_u, name, 199); + vim_strup(name_u); + for (i = highlight_ga.ga_len; --i >= 0; ) + if (HL_TABLE()[i].sg_name_u != NULL + && STRCMP(name_u, HL_TABLE()[i].sg_name_u) == 0) + break; + return i + 1; +} + +/* + * Lookup a highlight group name and return its attributes. + * Return zero if not found. + */ + int +syn_name2attr(char_u *name) +{ + int id = syn_name2id(name); + + if (id != 0) + return syn_id2attr(id); + return 0; +} + +#if defined(FEAT_EVAL) || defined(PROTO) +/* + * Return TRUE if highlight group "name" exists. + */ + int +highlight_exists(char_u *name) +{ + return (syn_name2id(name) > 0); +} + +# if defined(FEAT_SEARCH_EXTRA) || defined(PROTO) +/* + * Return the name of highlight group "id". + * When not a valid ID return an empty string. + */ + char_u * +syn_id2name(int id) +{ + if (id <= 0 || id > highlight_ga.ga_len) + return (char_u *)""; + return HL_TABLE()[id - 1].sg_name; +} +# endif +#endif + +/* + * Like syn_name2id(), but take a pointer + length argument. + */ + int +syn_namen2id(char_u *linep, int len) +{ + char_u *name; + int id = 0; + + name = vim_strnsave(linep, len); + if (name != NULL) + { + id = syn_name2id(name); + vim_free(name); + } + return 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. + */ + int +syn_check_group(char_u *pp, int len) +{ + int id; + char_u *name; + + name = vim_strnsave(pp, len); + if (name == NULL) + return 0; + + id = syn_name2id(name); + if (id == 0) // doesn't exist yet + id = syn_add_group(name); + else + vim_free(name); + return id; +} + +/* + * Add new highlight group and return its ID. + * "name" must be an allocated string, it will be consumed. + * Return 0 for failure. + */ + static int +syn_add_group(char_u *name) +{ + char_u *p; + + // Check that the name is ASCII letters, digits and underscore. + for (p = name; *p != NUL; ++p) + { + if (!vim_isprintc(*p)) + { + emsg(_("E669: Unprintable character in group name")); + vim_free(name); + return 0; + } + else if (!ASCII_ISALNUM(*p) && *p != '_') + { + // This is an error, but since there previously was no check only + // give a warning. + msg_source(HL_ATTR(HLF_W)); + msg(_("W18: Invalid character in group name")); + break; + } + } + + /* + * First call for this growarray: init growing array. + */ + if (highlight_ga.ga_data == NULL) + { + highlight_ga.ga_itemsize = sizeof(hl_group_T); + highlight_ga.ga_growsize = 10; + } + + if (highlight_ga.ga_len >= MAX_HL_ID) + { + emsg(_("E849: Too many highlight and syntax groups")); + vim_free(name); + return 0; + } + + /* + * Make room for at least one other syntax_highlight entry. + */ + if (ga_grow(&highlight_ga, 1) == FAIL) + { + vim_free(name); + return 0; + } + + vim_memset(&(HL_TABLE()[highlight_ga.ga_len]), 0, sizeof(hl_group_T)); + HL_TABLE()[highlight_ga.ga_len].sg_name = name; + HL_TABLE()[highlight_ga.ga_len].sg_name_u = vim_strsave_up(name); +#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) + HL_TABLE()[highlight_ga.ga_len].sg_gui_bg = INVALCOLOR; + HL_TABLE()[highlight_ga.ga_len].sg_gui_fg = INVALCOLOR; +# ifdef FEAT_GUI + HL_TABLE()[highlight_ga.ga_len].sg_gui_sp = INVALCOLOR; +# endif +#endif + ++highlight_ga.ga_len; + + return highlight_ga.ga_len; // ID is index plus one +} + +/* + * When, just after calling syn_add_group(), an error is discovered, this + * function deletes the new name. + */ + static void +syn_unadd_group(void) +{ + --highlight_ga.ga_len; + vim_free(HL_TABLE()[highlight_ga.ga_len].sg_name); + vim_free(HL_TABLE()[highlight_ga.ga_len].sg_name_u); +} + +/* + * Translate a group ID to highlight attributes. + */ + int +syn_id2attr(int hl_id) +{ + int attr; + hl_group_T *sgp; + + hl_id = syn_get_final_id(hl_id); + sgp = &HL_TABLE()[hl_id - 1]; // index is ID minus one + +#ifdef FEAT_GUI + /* + * Only use GUI attr when the GUI is being used. + */ + if (gui.in_use) + attr = sgp->sg_gui_attr; + else +#endif + if (IS_CTERM) + attr = sgp->sg_cterm_attr; + else + attr = sgp->sg_term_attr; + + return attr; +} + +#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO) +/* + * Get the GUI colors and attributes for a group ID. + * NOTE: the colors will be INVALCOLOR when not set, the color otherwise. + */ + int +syn_id2colors(int hl_id, guicolor_T *fgp, guicolor_T *bgp) +{ + hl_group_T *sgp; + + hl_id = syn_get_final_id(hl_id); + sgp = &HL_TABLE()[hl_id - 1]; // index is ID minus one + + *fgp = sgp->sg_gui_fg; + *bgp = sgp->sg_gui_bg; + return sgp->sg_gui; +} +#endif + +#if (defined(MSWIN) \ + && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) \ + && defined(FEAT_TERMGUICOLORS)) || defined(PROTO) + void +syn_id2cterm_bg(int hl_id, int *fgp, int *bgp) +{ + hl_group_T *sgp; + + hl_id = syn_get_final_id(hl_id); + sgp = &HL_TABLE()[hl_id - 1]; // index is ID minus one + *fgp = sgp->sg_cterm_fg - 1; + *bgp = sgp->sg_cterm_bg - 1; +} +#endif + +/* + * Translate a group ID to the final group ID (following links). + */ + int +syn_get_final_id(int hl_id) +{ + int count; + hl_group_T *sgp; + + if (hl_id > highlight_ga.ga_len || hl_id < 1) + return 0; // Can be called from eval!! + + /* + * Follow links until there is no more. + * Look out for loops! Break after 100 links. + */ + for (count = 100; --count >= 0; ) + { + sgp = &HL_TABLE()[hl_id - 1]; // index is ID minus one + if (sgp->sg_link == 0 || sgp->sg_link > highlight_ga.ga_len) + break; + hl_id = sgp->sg_link; + } + + return hl_id; +} + +#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO) +/* + * Call this function just after the GUI has started. + * Also called when 'termguicolors' was set, gui.in_use will be FALSE then. + * It finds the font and color handles for the highlighting groups. + */ + void +highlight_gui_started(void) +{ + int idx; + + // First get the colors from the "Normal" and "Menu" group, if set + if (USE_24BIT) + set_normal_colors(); + + for (idx = 0; idx < highlight_ga.ga_len; ++idx) + gui_do_one_color(idx, FALSE, FALSE); + + highlight_changed(); +} + + static void +gui_do_one_color( + int idx, + int do_menu UNUSED, // TRUE: might set the menu font + int do_tooltip UNUSED) // TRUE: might set the tooltip font +{ + int didit = FALSE; + +# ifdef FEAT_GUI +# ifdef FEAT_TERMGUICOLORS + if (gui.in_use) +# endif + if (HL_TABLE()[idx].sg_font_name != NULL) + { + hl_do_font(idx, HL_TABLE()[idx].sg_font_name, FALSE, do_menu, + do_tooltip, TRUE); + didit = TRUE; + } +# endif + if (HL_TABLE()[idx].sg_gui_fg_name != NULL) + { + HL_TABLE()[idx].sg_gui_fg = + color_name2handle(HL_TABLE()[idx].sg_gui_fg_name); + didit = TRUE; + } + if (HL_TABLE()[idx].sg_gui_bg_name != NULL) + { + HL_TABLE()[idx].sg_gui_bg = + color_name2handle(HL_TABLE()[idx].sg_gui_bg_name); + didit = TRUE; + } +# ifdef FEAT_GUI + if (HL_TABLE()[idx].sg_gui_sp_name != NULL) + { + HL_TABLE()[idx].sg_gui_sp = + color_name2handle(HL_TABLE()[idx].sg_gui_sp_name); + didit = TRUE; + } +# endif + if (didit) // need to get a new attr number + set_hl_attr(idx); +} +#endif + +#if defined(USER_HIGHLIGHT) && defined(FEAT_STL_OPT) +/* + * Apply difference between User[1-9] and HLF_S to HLF_SNC, HLF_ST or HLF_STNC. + */ + static void +combine_stl_hlt( + int id, + int id_S, + int id_alt, + int hlcnt, + int i, + int hlf, + int *table) +{ + hl_group_T *hlt = HL_TABLE(); + + if (id_alt == 0) + { + vim_memset(&hlt[hlcnt + i], 0, sizeof(hl_group_T)); + hlt[hlcnt + i].sg_term = highlight_attr[hlf]; + hlt[hlcnt + i].sg_cterm = highlight_attr[hlf]; +# if defined(FEAT_GUI) || defined(FEAT_EVAL) + hlt[hlcnt + i].sg_gui = highlight_attr[hlf]; +# endif + } + else + mch_memmove(&hlt[hlcnt + i], + &hlt[id_alt - 1], + sizeof(hl_group_T)); + hlt[hlcnt + i].sg_link = 0; + + hlt[hlcnt + i].sg_term ^= + hlt[id - 1].sg_term ^ hlt[id_S - 1].sg_term; + if (hlt[id - 1].sg_start != hlt[id_S - 1].sg_start) + hlt[hlcnt + i].sg_start = hlt[id - 1].sg_start; + if (hlt[id - 1].sg_stop != hlt[id_S - 1].sg_stop) + hlt[hlcnt + i].sg_stop = hlt[id - 1].sg_stop; + hlt[hlcnt + i].sg_cterm ^= + hlt[id - 1].sg_cterm ^ hlt[id_S - 1].sg_cterm; + if (hlt[id - 1].sg_cterm_fg != hlt[id_S - 1].sg_cterm_fg) + hlt[hlcnt + i].sg_cterm_fg = hlt[id - 1].sg_cterm_fg; + if (hlt[id - 1].sg_cterm_bg != hlt[id_S - 1].sg_cterm_bg) + hlt[hlcnt + i].sg_cterm_bg = hlt[id - 1].sg_cterm_bg; +# if defined(FEAT_GUI) || defined(FEAT_EVAL) + hlt[hlcnt + i].sg_gui ^= + hlt[id - 1].sg_gui ^ hlt[id_S - 1].sg_gui; +# endif +# ifdef FEAT_GUI + if (hlt[id - 1].sg_gui_fg != hlt[id_S - 1].sg_gui_fg) + hlt[hlcnt + i].sg_gui_fg = hlt[id - 1].sg_gui_fg; + if (hlt[id - 1].sg_gui_bg != hlt[id_S - 1].sg_gui_bg) + hlt[hlcnt + i].sg_gui_bg = hlt[id - 1].sg_gui_bg; + if (hlt[id - 1].sg_gui_sp != hlt[id_S - 1].sg_gui_sp) + hlt[hlcnt + i].sg_gui_sp = hlt[id - 1].sg_gui_sp; + if (hlt[id - 1].sg_font != hlt[id_S - 1].sg_font) + hlt[hlcnt + i].sg_font = hlt[id - 1].sg_font; +# ifdef FEAT_XFONTSET + if (hlt[id - 1].sg_fontset != hlt[id_S - 1].sg_fontset) + hlt[hlcnt + i].sg_fontset = hlt[id - 1].sg_fontset; +# endif +# endif + highlight_ga.ga_len = hlcnt + i + 1; + set_hl_attr(hlcnt + i); // At long last we can apply + table[i] = syn_id2attr(hlcnt + i + 1); +} +#endif + +/* + * Translate the 'highlight' option into attributes in highlight_attr[] and + * set up the user highlights User1..9. If FEAT_STL_OPT is in use, a set of + * corresponding highlights to use on top of HLF_SNC is computed. + * Called only when the 'highlight' option has been changed and upon first + * screen redraw after any :highlight command. + * Return FAIL when an invalid flag is found in 'highlight'. OK otherwise. + */ + int +highlight_changed(void) +{ + int hlf; + int i; + char_u *p; + int attr; + char_u *end; + int id; +#ifdef USER_HIGHLIGHT + char_u userhl[30]; // use 30 to avoid compiler warning +# ifdef FEAT_STL_OPT + int id_S = -1; + int id_SNC = 0; +# ifdef FEAT_TERMINAL + int id_ST = 0; + int id_STNC = 0; +# endif + int hlcnt; +# endif +#endif + static int hl_flags[HLF_COUNT] = HL_FLAGS; + + need_highlight_changed = FALSE; + + /* + * Clear all attributes. + */ + for (hlf = 0; hlf < (int)HLF_COUNT; ++hlf) + highlight_attr[hlf] = 0; + + /* + * First set all attributes to their default value. + * Then use the attributes from the 'highlight' option. + */ + for (i = 0; i < 2; ++i) + { + if (i) + p = p_hl; + else + p = get_highlight_default(); + if (p == NULL) // just in case + continue; + + while (*p) + { + for (hlf = 0; hlf < (int)HLF_COUNT; ++hlf) + if (hl_flags[hlf] == *p) + break; + ++p; + if (hlf == (int)HLF_COUNT || *p == NUL) + return FAIL; + + /* + * Allow several hl_flags to be combined, like "bu" for + * bold-underlined. + */ + attr = 0; + for ( ; *p && *p != ','; ++p) // parse upto comma + { + if (VIM_ISWHITE(*p)) // ignore white space + continue; + + if (attr > HL_ALL) // Combination with ':' is not allowed. + return FAIL; + + switch (*p) + { + case 'b': attr |= HL_BOLD; + break; + case 'i': attr |= HL_ITALIC; + break; + case '-': + case 'n': // no highlighting + break; + case 'r': attr |= HL_INVERSE; + break; + case 's': attr |= HL_STANDOUT; + break; + case 'u': attr |= HL_UNDERLINE; + break; + case 'c': attr |= HL_UNDERCURL; + break; + case 't': attr |= HL_STRIKETHROUGH; + break; + case ':': ++p; // highlight group name + if (attr || *p == NUL) // no combinations + return FAIL; + end = vim_strchr(p, ','); + if (end == NULL) + end = p + STRLEN(p); + id = syn_check_group(p, (int)(end - p)); + if (id == 0) + return FAIL; + attr = syn_id2attr(id); + p = end - 1; +#if defined(FEAT_STL_OPT) && defined(USER_HIGHLIGHT) + if (hlf == (int)HLF_SNC) + id_SNC = syn_get_final_id(id); +# ifdef FEAT_TERMINAL + else if (hlf == (int)HLF_ST) + id_ST = syn_get_final_id(id); + else if (hlf == (int)HLF_STNC) + id_STNC = syn_get_final_id(id); +# endif + else if (hlf == (int)HLF_S) + id_S = syn_get_final_id(id); +#endif + break; + default: return FAIL; + } + } + highlight_attr[hlf] = attr; + + p = skip_to_option_part(p); // skip comma and spaces + } + } + +#ifdef USER_HIGHLIGHT + /* + * Setup the user highlights + * + * Temporarily utilize 28 more hl entries: + * 9 for User1-User9 combined with StatusLineNC + * 9 for User1-User9 combined with StatusLineTerm + * 9 for User1-User9 combined with StatusLineTermNC + * 1 for StatusLine default + * Have to be in there simultaneously in case of table overflows in + * get_attr_entry() + */ +# ifdef FEAT_STL_OPT + if (ga_grow(&highlight_ga, 28) == FAIL) + return FAIL; + hlcnt = highlight_ga.ga_len; + if (id_S == -1) + { + // Make sure id_S is always valid to simplify code below. Use the last + // entry. + vim_memset(&HL_TABLE()[hlcnt + 27], 0, sizeof(hl_group_T)); + HL_TABLE()[hlcnt + 18].sg_term = highlight_attr[HLF_S]; + id_S = hlcnt + 19; + } +# endif + for (i = 0; i < 9; i++) + { + sprintf((char *)userhl, "User%d", i + 1); + id = syn_name2id(userhl); + if (id == 0) + { + highlight_user[i] = 0; +# ifdef FEAT_STL_OPT + highlight_stlnc[i] = 0; +# ifdef FEAT_TERMINAL + highlight_stlterm[i] = 0; + highlight_stltermnc[i] = 0; +# endif +# endif + } + else + { + highlight_user[i] = syn_id2attr(id); +# ifdef FEAT_STL_OPT + combine_stl_hlt(id, id_S, id_SNC, hlcnt, i, + HLF_SNC, highlight_stlnc); +# ifdef FEAT_TERMINAL + combine_stl_hlt(id, id_S, id_ST, hlcnt + 9, i, + HLF_ST, highlight_stlterm); + combine_stl_hlt(id, id_S, id_STNC, hlcnt + 18, i, + HLF_STNC, highlight_stltermnc); +# endif +# endif + } + } +# ifdef FEAT_STL_OPT + highlight_ga.ga_len = hlcnt; +# endif + +#endif // USER_HIGHLIGHT + + return OK; +} + +#if defined(FEAT_CMDL_COMPL) || defined(PROTO) + +static void highlight_list(void); +static void highlight_list_two(int cnt, int attr); + +/* + * Handle command line completion for :highlight command. + */ + void +set_context_in_highlight_cmd(expand_T *xp, char_u *arg) +{ + char_u *p; + + // Default: expand group names + xp->xp_context = EXPAND_HIGHLIGHT; + xp->xp_pattern = arg; + include_link = 2; + include_default = 1; + + // (part of) subcommand already typed + if (*arg != NUL) + { + p = skiptowhite(arg); + if (*p != NUL) // past "default" or group name + { + include_default = 0; + if (STRNCMP("default", arg, p - arg) == 0) + { + arg = skipwhite(p); + xp->xp_pattern = arg; + p = skiptowhite(arg); + } + if (*p != NUL) // past group name + { + include_link = 0; + if (arg[1] == 'i' && arg[0] == 'N') + highlight_list(); + if (STRNCMP("link", arg, p - arg) == 0 + || STRNCMP("clear", arg, p - arg) == 0) + { + xp->xp_pattern = skipwhite(p); + p = skiptowhite(xp->xp_pattern); + if (*p != NUL) // past first group name + { + xp->xp_pattern = skipwhite(p); + p = skiptowhite(xp->xp_pattern); + } + } + if (*p != NUL) // past group name(s) + xp->xp_context = EXPAND_NOTHING; + } + } + } +} + +/* + * List highlighting matches in a nice way. + */ + static void +highlight_list(void) +{ + int i; + + for (i = 10; --i >= 0; ) + highlight_list_two(i, HL_ATTR(HLF_D)); + for (i = 40; --i >= 0; ) + highlight_list_two(99, 0); +} + + static void +highlight_list_two(int cnt, int attr) +{ + msg_puts_attr(&("N \bI \b! \b"[cnt / 11]), attr); + msg_clr_eos(); + out_flush(); + ui_delay(cnt == 99 ? 40L : (long)cnt * 50L, FALSE); +} + +#endif // FEAT_CMDL_COMPL + +#if defined(FEAT_CMDL_COMPL) || (defined(FEAT_SYN_HL) && defined(FEAT_EVAL)) \ + || defined(FEAT_SIGNS) || defined(PROTO) +/* + * Function given to ExpandGeneric() to obtain the list of group names. + */ + 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"; + if (idx == highlight_ga.ga_len + include_none && include_default != 0) + return (char_u *)"default"; + if (idx == highlight_ga.ga_len + include_none + include_default + && include_link != 0) + return (char_u *)"link"; + if (idx == highlight_ga.ga_len + include_none + include_default + 1 + && include_link != 0) + return (char_u *)"clear"; +#endif + if (idx >= highlight_ga.ga_len) + return NULL; + return HL_TABLE()[idx].sg_name; +} +#endif + +#if defined(FEAT_GUI) || defined(PROTO) +/* + * Free all the highlight group fonts. + * Used when quitting for systems which need it. + */ + void +free_highlight_fonts(void) +{ + int idx; + + for (idx = 0; idx < highlight_ga.ga_len; ++idx) + { + gui_mch_free_font(HL_TABLE()[idx].sg_font); + HL_TABLE()[idx].sg_font = NOFONT; +# ifdef FEAT_XFONTSET + gui_mch_free_fontset(HL_TABLE()[idx].sg_fontset); + HL_TABLE()[idx].sg_fontset = NOFONTSET; +# endif + } + + gui_mch_free_font(gui.norm_font); +# ifdef FEAT_XFONTSET + gui_mch_free_fontset(gui.fontset); +# endif +# ifndef FEAT_GUI_GTK + gui_mch_free_font(gui.bold_font); + gui_mch_free_font(gui.ital_font); + gui_mch_free_font(gui.boldital_font); +# endif +} +#endif diff -Nru vim-8.1.1681/src/Make_cyg_ming.mak vim-8.1.1729/src/Make_cyg_ming.mak --- vim-8.1.1681/src/Make_cyg_ming.mak 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/Make_cyg_ming.mak 2019-07-21 21:04:21.000000000 +0000 @@ -730,6 +730,7 @@ $(OUTDIR)/getchar.o \ $(OUTDIR)/hardcopy.o \ $(OUTDIR)/hashtab.o \ + $(OUTDIR)/highlight.o \ $(OUTDIR)/indent.o \ $(OUTDIR)/insexpand.o \ $(OUTDIR)/json.o \ @@ -752,6 +753,7 @@ $(OUTDIR)/pathdef.o \ $(OUTDIR)/popupmnu.o \ $(OUTDIR)/popupwin.o \ + $(OUTDIR)/profiler.o \ $(OUTDIR)/quickfix.o \ $(OUTDIR)/regexp.o \ $(OUTDIR)/screen.o \ @@ -763,12 +765,14 @@ $(OUTDIR)/syntax.o \ $(OUTDIR)/tag.o \ $(OUTDIR)/term.o \ + $(OUTDIR)/testing.o \ $(OUTDIR)/textprop.o \ $(OUTDIR)/ui.o \ $(OUTDIR)/undo.o \ $(OUTDIR)/usercmd.o \ $(OUTDIR)/userfunc.o \ $(OUTDIR)/version.o \ + $(OUTDIR)/viminfo.o \ $(OUTDIR)/winclip.o \ $(OUTDIR)/window.o diff -Nru vim-8.1.1681/src/Make_dice.mak vim-8.1.1729/src/Make_dice.mak --- vim-8.1.1681/src/Make_dice.mak 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/Make_dice.mak 1970-01-01 00:00:00.000000000 +0000 @@ -1,301 +0,0 @@ -# -# Makefile for VIM, using DICE 3 -# - -#>>>>> choose options: -### See feature.h for a list of optionals. -### Any other defines can be included here. -DEFINES = -DHAVE_TGETENT -DUP_BC_PC_EXTERN -DOSPEED_EXTERN - -#>>>>> if HAVE_TGETENT is defined o/termlib.o has to be used -TERMLIB = o/termlib.o -#TERMLIB = - -#>>>>> end of choices -########################################################################### - -CFLAGS = -c -DAMIGA -Iproto $(DEFINES) - -SYMS = vim.syms -PRE = -H${SYMS}=vim.h -LIBS = -la -CC = dcc -LD = dcc - -.c.o: - ${CC} ${PRE} ${CFLAGS} $< -o $@ - -SRC = \ - arabic.c \ - autocmd.c \ - blowfish.c \ - buffer.c \ - change.c \ - charset.c \ - crypt.c \ - crypt_zip.c \ - debugger.c \ - dict.c \ - diff.c \ - digraph.c \ - edit.c \ - eval.c \ - evalfunc.c \ - ex_cmds.c \ - ex_cmds2.c \ - ex_docmd.c \ - ex_eval.c \ - ex_getln.c \ - fileio.c \ - findfile.c \ - fold.c \ - getchar.c \ - hardcopy.c \ - hashtab.c \ - indent.c \ - insexpand.c \ - json.c \ - list.c \ - main.c \ - mark.c \ - memfile.c \ - memline.c \ - menu.c \ - message.c \ - misc1.c \ - misc2.c \ - move.c \ - mbyte.c \ - normal.c \ - ops.c \ - option.c \ - os_amiga.c \ - popupmnu.c \ - quickfix.c \ - regexp.c \ - screen.c \ - search.c \ - sha256.c \ - sign.c \ - spell.c \ - spellfile.c \ - syntax.c \ - tag.c \ - term.c \ - ui.c \ - undo.c \ - usercmd.c \ - userfunc.c \ - window.c \ - version.c - -OBJ = o/arabic.o \ - o/autocmd.o \ - o/blowfish.o \ - o/buffer.o \ - o/change.o \ - o/charset.o \ - o/crypt.o \ - o/crypt_zip.o \ - o/debugger.o \ - o/dict.o \ - o/diff.o \ - o/digraph.o \ - o/edit.o \ - o/eval.o \ - o/evalfunc.o \ - o/ex_cmds.o \ - o/ex_cmds2.o \ - o/ex_docmd.o \ - o/ex_eval.o \ - o/ex_getln.o \ - o/fileio.o \ - o/findfile.o \ - o/fold.o \ - o/getchar.o \ - o/hardcopy.o \ - o/hashtab.o \ - o/indent.o \ - o/insexpand.o \ - o/json.o \ - o/list.o \ - o/main.o \ - o/mark.o \ - o/memfile.o \ - o/memline.o \ - o/menu.o \ - o/message.o \ - o/misc1.o \ - o/misc2.o \ - o/move.o \ - o/mbyte.o \ - o/normal.o \ - o/ops.o \ - o/option.o \ - o/os_amiga.o \ - o/popupmnu.o \ - o/quickfix.o \ - o/regexp.o \ - o/screen.o \ - o/search.o \ - o/sha256.o \ - o/sign.o \ - o/spell.o \ - o/spellfile.o \ - o/syntax.o \ - o/tag.o \ - o/term.o \ - o/ui.o \ - o/undo.o \ - o/usercmd.o \ - o/userfunc.o \ - o/window.o \ - $(TERMLIB) - -Vim: $(OBJ) version.c version.h - ${CC} $(CFLAGS) version.c -o o/version.o - ${LD} -o Vim $(OBJ) o/version.o $(LIBS) - -debug: $(OBJ) version.c version.h - ${CC} $(CFLAGS) version.c -o o/version.o - ${LD} -s -o Vim $(OBJ) o/version.o $(LIBS) - -tags: - csh -c ctags $(SRC) *.h - -clean: - delete o/*.o Vim $(SYMS) - -$(SYMS) : vim.h globals.h keymap.h macros.h ascii.h term.h os_amiga.h structs.h - delete $(SYMS) - -########################################################################### - -o/arabic.o: arabic.c $(SYMS) - -o/autocmd.o: autocmd.c $(SYMS) - -o/blowfish.o: blowfish.c $(SYMS) - -o/buffer.o: buffer.c $(SYMS) - -o/change.o: change.c $(SYMS) - -o/charset.o: charset.c $(SYMS) - -o/crypt.o: crypt.c $(SYMS) - -o/crypt_zip.o: crypt_zip.c $(SYMS) - -o/debugger.o: debugger.c $(SYMS) - -o/dict.o: dict.c $(SYMS) - -o/diff.o: diff.c $(SYMS) - -o/digraph.o: digraph.c $(SYMS) - -o/edit.o: edit.c $(SYMS) - -o/eval.o: eval.c $(SYMS) - -o/evalfunc.o: evalfunc.c $(SYMS) - -o/ex_cmds.o: ex_cmds.c $(SYMS) - -o/ex_cmds2.o: ex_cmds2.c $(SYMS) - -o/ex_docmd.o: ex_docmd.c $(SYMS) ex_cmds.h - -o/ex_eval.o: ex_eval.c $(SYMS) ex_cmds.h - -o/ex_getln.o: ex_getln.c $(SYMS) - -o/fileio.o: fileio.c $(SYMS) - -o/findfile.o: findfile.c $(SYMS) - -o/fold.o: fold.c $(SYMS) - -o/getchar.o: getchar.c $(SYMS) - -o/hardcopy.o: hardcopy.c $(SYMS) - -o/hashtab.o: hashtab.c $(SYMS) - -o/indent.o: indent.c $(SYMS) - -o/insexpand.o: insexpand.c $(SYMS) - -o/json.o: json.c $(SYMS) - -o/list.o: list.c $(SYMS) - -o/main.o: main.c $(SYMS) - -o/mark.o: mark.c $(SYMS) - -o/memfile.o: memfile.c $(SYMS) - -o/memline.o: memline.c $(SYMS) - -o/menu.o: menu.c $(SYMS) - -o/message.o: message.c $(SYMS) - -o/misc1.o: misc1.c $(SYMS) - -o/misc2.o: misc2.c $(SYMS) - -o/move.o: move.c $(SYMS) - -o/mbyte.o: mbyte.c $(SYMS) - -o/normal.o: normal.c $(SYMS) - -o/ops.o: ops.c $(SYMS) - -o/option.o: option.c $(SYMS) -# Because of a bug in DC1 2.06.40, initialisation of unions does not -# work correctly. dc1-21 is DC1 2.06.21 which does work. -# rename dc1-21 dc1 - ${CC} ${CFLAGS} option.c -o o/option.o -# rename dc1 dc1-21 - -o/os_amiga.o: os_amiga.c $(SYMS) os_amiga.h - -o/popupmnu.o: popupmnu.c $(SYMS) - -o/quickfix.o: quickfix.c $(SYMS) - -o/regexp.o: regexp.c $(SYMS) regexp.h - -o/screen.o: screen.c $(SYMS) - -o/search.o: search.c $(SYMS) regexp.h - -o/sha256.o: sha256.c $(SYMS) - -o/sign.o: sign.c $(SYMS) - -o/spell.o: spell.c $(SYMS) spell.h - -o/spellfile.o: spellfile.c $(SYMS) spell.h - -o/syntax.o: syntax.c $(SYMS) - -o/tag.o: tag.c $(SYMS) - -o/term.o: term.c $(SYMS) term.h - -o/termlib.o: termlib.c $(SYMS) - -o/ui.o: ui.c $(SYMS) - -o/undo.o: undo.c $(SYMS) - -o/usercmd.o: usercmd.c $(SYMS) - -o/userfunc.o: userfunc.c $(SYMS) - -o/window.o: window.c $(SYMS) diff -Nru vim-8.1.1681/src/Makefile vim-8.1.1729/src/Makefile --- vim-8.1.1681/src/Makefile 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/Makefile 2019-07-21 21:04:21.000000000 +0000 @@ -521,6 +521,7 @@ # gpm - For mouse support on Linux console via gpm # Uncomment this when you do not want to include gpm support, even # though you have gpm libraries and includes. +# For Debian/Ubuntu gpm support requires the libgpm-dev package. #CONF_OPT_GPM = --disable-gpm # sysmouse - For mouse support on FreeBSD and DragonFly console via sysmouse @@ -1603,6 +1604,7 @@ getchar.c \ hardcopy.c \ hashtab.c \ + highlight.c \ if_cscope.c \ if_xcmdsrv.c \ indent.c \ @@ -1626,6 +1628,7 @@ auto/pathdef.c \ popupmnu.c \ popupwin.c \ + profiler.c \ pty.c \ quickfix.c \ regexp.c \ @@ -1640,12 +1643,14 @@ tag.c \ term.c \ terminal.c \ + testing.c \ textprop.c \ ui.c \ undo.c \ usercmd.c \ userfunc.c \ version.c \ + viminfo.c \ window.c \ $(OS_EXTRA_SRC) @@ -1722,6 +1727,7 @@ objects/getchar.o \ objects/hardcopy.o \ objects/hashtab.o \ + objects/highlight.o \ $(HANGULIN_OBJ) \ objects/if_cscope.o \ objects/if_xcmdsrv.o \ @@ -1742,6 +1748,7 @@ objects/pathdef.o \ objects/popupmnu.o \ objects/popupwin.o \ + objects/profiler.o \ objects/pty.o \ objects/quickfix.o \ objects/regexp.o \ @@ -1756,12 +1763,14 @@ objects/tag.o \ objects/term.o \ objects/terminal.o \ + objects/testing.o \ objects/textprop.o \ objects/ui.o \ objects/undo.o \ objects/usercmd.o \ objects/userfunc.o \ objects/version.o \ + objects/viminfo.o \ objects/window.o \ $(GUI_OBJ) \ $(TERM_OBJ) \ @@ -1855,6 +1864,7 @@ hardcopy.pro \ hashtab.pro \ hangulin.pro \ + highlight.pro \ if_cscope.pro \ if_lua.pro \ if_mzsch.pro \ @@ -1883,6 +1893,7 @@ os_unix.pro \ popupmnu.pro \ popupwin.pro \ + profiler.pro \ pty.pro \ quickfix.pro \ regexp.pro \ @@ -1898,12 +1909,14 @@ term.pro \ terminal.pro \ termlib.pro \ + testing.pro \ textprop.pro \ ui.pro \ undo.pro \ usercmd.pro \ userfunc.pro \ version.pro \ + viminfo.pro \ window.pro \ beval.pro \ gui_beval.pro \ @@ -3096,6 +3109,9 @@ objects/hangulin.o: hangulin.c $(CCC) -o $@ hangulin.c +objects/highlight.o: highlight.c + $(CCC) -o $@ highlight.c + objects/if_cscope.o: if_cscope.c $(CCC) -o $@ if_cscope.c @@ -3222,6 +3238,9 @@ objects/popupwin.o: popupwin.c $(CCC) -o $@ popupwin.c +objects/profiler.o: profiler.c + $(CCC) -o $@ profiler.c + objects/pty.o: pty.c $(CCC) -o $@ pty.c @@ -3264,6 +3283,9 @@ objects/terminal.o: terminal.c $(TERM_DEPS) $(CCC) -o $@ terminal.c +objects/testing.o: testing.c + $(CCC) -o $@ testing.c + objects/textprop.o: textprop.c $(CCC) -o $@ textprop.c @@ -3279,6 +3301,9 @@ objects/userfunc.o: userfunc.c $(CCC) -o $@ userfunc.c +objects/viminfo.o: viminfo.c + $(CCC) -o $@ viminfo.c + objects/window.o: window.c $(CCC) -o $@ window.c @@ -3541,6 +3566,10 @@ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ proto.h globals.h +objects/highlight.o: highlight.c vim.h protodef.h auto/config.h feature.h os_unix.h \ + auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ + proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ + proto.h globals.h objects/if_cscope.o: if_cscope.c vim.h protodef.h auto/config.h feature.h \ os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ @@ -3633,6 +3662,10 @@ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ proto.h globals.h +objects/profiler.o: profiler.c vim.h protodef.h auto/config.h feature.h os_unix.h \ + auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ + proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ + proto.h globals.h objects/pty.o: pty.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ @@ -3691,6 +3724,10 @@ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ proto.h globals.h libvterm/include/vterm.h \ libvterm/include/vterm_keycodes.h +objects/testing.o: testing.c vim.h protodef.h auto/config.h feature.h os_unix.h \ + auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ + proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ + proto.h globals.h objects/textprop.o: textprop.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ @@ -3715,6 +3752,10 @@ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ proto.h globals.h version.h +objects/viminfo.o: viminfo.c vim.h protodef.h auto/config.h feature.h \ + os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ + proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ + proto.h globals.h objects/window.o: window.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ diff -Nru vim-8.1.1681/src/Make_manx.mak vim-8.1.1729/src/Make_manx.mak --- vim-8.1.1681/src/Make_manx.mak 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/Make_manx.mak 1970-01-01 00:00:00.000000000 +0000 @@ -1,462 +0,0 @@ -# -# Makefile for VIM on the Amiga, using Aztec/Manx C 5.0 or later -# -# NOTE: THIS IS OLD AND PROBABLY NO LONGER WORKS. -# -# Note: Not all dependencies are included. This was done to avoid having -# to compile everything when a global variable or function is added. -# Careful when changing a global struct or variable! -# - -#>>>>> choose options: - -### See feature.h for a list of optionals. -### Any other defines can be included here. -DEFINES = - -#>>>>> if HAVE_TGETENT is defined obj/termlib.o has to be used -#TERMLIB = obj/termlib.o -TERMLIB = - -#>>>>> choose between debugging (-bs) or optimizing (-so) -OPTIONS = -so -#OPTIONS = -bs - -#>>>>> end of choices -########################################################################### - -CFLAGS = $(OPTIONS) -wapruq -ps -qf -Iproto $(DEFINES) -DAMIGA - -LIBS = -lc16 -SYMS = vim.syms -CC = cc -LN = ln -LNFLAGS = +q -SHELL = csh -REN = $(SHELL) -c mv -f -DEL = $(SHELL) -c rm -f - -SRC = arabic.c \ - autocmd.c \ - blowfish.c \ - buffer.c \ - change.c \ - charset.c \ - crypt.c \ - crypt_zip.c \ - debugger.c \ - dict.c \ - diff.c \ - digraph.c \ - edit.c \ - eval.c \ - evalfunc.c \ - ex_cmds.c \ - ex_cmds2.c \ - ex_docmd.c \ - ex_eval.c \ - ex_getln.c \ - fileio.c \ - findfile.c \ - fold.c \ - getchar.c \ - hardcopy.c \ - hashtab.c \ - indent.c \ - insexpand.c \ - json.c \ - list.c \ - main.c \ - mark.c \ - memfile.c \ - memline.c \ - menu.c \ - message.c \ - misc1.c \ - misc2.c \ - move.c \ - mbyte.c \ - normal.c \ - ops.c \ - option.c \ - os_amiga.c \ - popupmnu.c \ - quickfix.c \ - regexp.c \ - screen.c \ - search.c \ - sha256.c \ - sign.c \ - spell.c \ - spellfile.c \ - syntax.c \ - tag.c \ - term.c \ - ui.c \ - undo.c \ - usercmd.c \ - userfunc.c \ - window.c \ - version.c - -INCL = vim.h feature.h keymap.h macros.h ascii.h term.h structs.h os_amiga.h - -OBJ = obj/arabic.o \ - obj/autocmd.o \ - obj/blowfish.o \ - obj/buffer.o \ - obj/change.o \ - obj/charset.o \ - obj/crypt.o \ - obj/crypt_zip.o \ - obj/debugger.o \ - obj/dict.o \ - obj/diff.o \ - obj/digraph.o \ - obj/edit.o \ - obj/eval.o \ - obj/evalfunc.o \ - obj/ex_cmds.o \ - obj/ex_cmds2.o \ - obj/ex_docmd.o \ - obj/ex_eval.o \ - obj/ex_getln.o \ - obj/fileio.o \ - obj/findfile.o \ - obj/fold.o \ - obj/getchar.o \ - obj/hardcopy.o \ - obj/hashtab.o \ - obj/indent.o \ - obj/insexpand.o \ - obj/json.o \ - obj/list.o \ - obj/main.o \ - obj/mark.o \ - obj/memfile.o \ - obj/memline.o \ - obj/menu.o \ - obj/message.o \ - obj/misc1.o \ - obj/misc2.o \ - obj/move.o \ - obj/mbyte.o \ - obj/normal.o \ - obj/ops.o \ - obj/option.o \ - obj/os_amiga.o \ - obj/popupmnu.o \ - obj/quickfix.o \ - obj/regexp.o \ - obj/screen.o \ - obj/search.o \ - obj/sha256.o \ - obj/sign.o \ - obj/spell.o \ - obj/spellfile.o \ - obj/syntax.o \ - obj/tag.o \ - obj/term.o \ - obj/ui.o \ - obj/undo.o \ - obj/usercmd.o \ - obj/userfunc.o \ - obj/window.o \ - $(TERMLIB) - -PRO = proto/arabic.pro \ - proto/autocmd.pro \ - proto/blowfish.pro \ - proto/buffer.pro \ - proto/change.pro \ - proto/charset.pro \ - proto/crypt.pro \ - proto/crypt_zip.pro \ - proto/debugger.pro \ - proto/dict.pro \ - proto/diff.pro \ - proto/digraph.pro \ - proto/edit.pro \ - proto/eval.pro \ - proto/evalfunc.pro \ - proto/ex_cmds.pro \ - proto/ex_cmds2.pro \ - proto/ex_docmd.pro \ - proto/ex_eval.pro \ - proto/ex_getln.pro \ - proto/fileio.pro \ - proto/findfile.pro \ - proto/fold.pro \ - proto/getchar.pro \ - proto/hardcopy.pro \ - proto/hashtab.pro \ - proto/indent.pro \ - proto/insexpand.pro \ - proto/json.pro \ - proto/list.pro \ - proto/main.pro \ - proto/mark.pro \ - proto/memfile.pro \ - proto/memline.pro \ - proto/menu.pro \ - proto/message.pro \ - proto/misc1.pro \ - proto/misc2.pro \ - proto/move.pro \ - proto/mbyte.pro \ - proto/normal.pro \ - proto/ops.pro \ - proto/option.pro \ - proto/os_amiga.pro \ - proto/popupmnu.pro \ - proto/quickfix.pro \ - proto/regexp.pro \ - proto/screen.pro \ - proto/search.pro \ - proto/sha256.pro \ - proto/sign.pro \ - proto/spell.pro \ - proto/spellfile.pro \ - proto/syntax.pro \ - proto/tag.pro \ - proto/term.pro \ - proto/termlib.pro \ - proto/ui.pro \ - proto/undo.pro \ - proto/usercmd.pro \ - proto/userfunc.pro \ - proto/window.pro - -all: Vim xxd/Xxd - -Vim: obj $(OBJ) version.c version.h - $(CC) $(CFLAGS) version.c -o obj/version.o - $(LN) $(LNFLAGS) -m -o Vim $(OBJ) obj/version.o $(LIBS) - -debug: obj $(OBJ) version.c version.h - $(CC) $(CFLAGS) version.c -o obj/version.o - $(LN) $(LNFLAGS) -m -g -o Vim $(OBJ) obj/version.o $(LIBS) - -xxd/Xxd: xxd/xxd.c - $(SHELL) -c cd xxd; make -f Make_amiga.mak; cd .. - -# Making prototypes with Manx has been removed, because it caused too many -# problems. -#proto: $(SYMS) $(PRO) - -obj: - makedir obj - -tags: $(SRC) $(INCL) - $(SHELL) -c ctags $(SRC) *.h - -# can't use delete here, too many file names -clean: - $(DEL) $(OBJ) obj/version.o \ - obj/termlib.o Vim $(SYMS) xxd/Xxd - -test: - $(SHELL) -c cd testdir; make -f Make_amiga.mak; cd .. - -$(SYMS): $(INCL) $(PRO) - $(CC) $(CFLAGS) -ho$(SYMS) vim.h - -########################################################################### - -# Unfortunately, Manx's make doesn't understand a .c.o rule, so each -# compilation command has to be given explicitly. - -CCSYM = $(CC) $(CFLAGS) -hi$(SYMS) -o -CCNOSYM = $(CC) $(CFLAGS) -o - -$(OBJ): $(SYMS) - -obj/arabic.o: arabic.c - $(CCSYM) $@ arabic.c - -obj/autocmd.o: autocmd.c - $(CCSYM) $@ autocmd.c - -obj/blowfish.o: blowfish.c - $(CCSYM) $@ blowfish.c - -obj/buffer.o: buffer.c - $(CCSYM) $@ buffer.c - -obj/change.o: change.c - $(CCSYM) $@ change.c - -obj/charset.o: charset.c - $(CCSYM) $@ charset.c - -obj/crypt.o: crypt.c - $(CCSYM) $@ crypt.c - -obj/crypt_zip.o: crypt_zip.c - $(CCSYM) $@ crypt_zip.c - -obj/debugger.o: debugger.c - $(CCSYM) $@ debugger.c - -obj/dict.o: dict.c - $(CCSYM) $@ dict.c - -obj/diff.o: diff.c - $(CCSYM) $@ diff.c - -obj/digraph.o: digraph.c - $(CCSYM) $@ digraph.c - -obj/edit.o: edit.c - $(CCSYM) $@ edit.c - -obj/eval.o: eval.c - $(CCSYM) $@ eval.c - -obj/evalfunc.o: evalfunc.c - $(CCSYM) $@ evalfunc.c - -obj/ex_cmds.o: ex_cmds.c - $(CCSYM) $@ ex_cmds.c - -obj/ex_cmds2.o: ex_cmds2.c - $(CCSYM) $@ ex_cmds2.c - -# Don't use $(SYMS) here, because ex_docmd.c defines DO_DECLARE_EXCMD -obj/ex_docmd.o: ex_docmd.c ex_cmds.h - $(CCNOSYM) $@ ex_docmd.c - -obj/ex_eval.o: ex_eval.c ex_cmds.h - $(CCSYM) $@ ex_eval.c - -obj/ex_getln.o: ex_getln.c - $(CCSYM) $@ ex_getln.c - -obj/fileio.o: fileio.c - $(CCSYM) $@ fileio.c - -obj/findfile.o: findfile.c - $(CCSYM) $@ findfile.c - -obj/fold.o: fold.c - $(CCSYM) $@ fold.c - -obj/getchar.o: getchar.c - $(CCSYM) $@ getchar.c - -obj/hardcopy.o: hardcopy.c - $(CCSYM) $@ hardcopy.c - -obj/hashtab.o: hashtab.c - $(CCSYM) $@ hashtab.c - -obj/indent.o: indent.c - $(CCSYM) $@ indent.c - -obj/insexpand.o: insexpand.c - $(CCSYM) $@ insexpand.c - -obj/json.o: json.c - $(CCSYM) $@ json.c - -obj/list.o: list.c - $(CCSYM) $@ list.c - -# Don't use $(SYMS) here, because main.c defines EXTERN -obj/main.o: main.c option.h globals.h - $(CCNOSYM) $@ main.c - -obj/mark.o: mark.c - $(CCSYM) $@ mark.c - -obj/memfile.o: memfile.c - $(CCSYM) $@ memfile.c - -obj/memline.o: memline.c - $(CCSYM) $@ memline.c - -obj/menu.o: menu.c - $(CCSYM) $@ menu.c - -# Don't use $(SYMS) here, because message.c defines MESSAGE_FILE -obj/message.o: message.c - $(CCNOSYM) $@ message.c - -obj/misc1.o: misc1.c - $(CCSYM) $@ misc1.c - -obj/misc2.o: misc2.c - $(CCSYM) $@ misc2.c - -obj/move.o: move.c - $(CCSYM) $@ move.c - -obj/mbyte.o: mbyte.c - $(CCSYM) $@ mbyte.c - -obj/normal.o: normal.c - $(CCSYM) $@ normal.c - -obj/ops.o: ops.c - $(CCSYM) $@ ops.c - -# Don't use $(SYMS) here, because option.h defines variables here -obj/option.o: option.c - $(CCNOSYM) $@ option.c - -obj/os_amiga.o: os_amiga.c - $(CCSYM) $@ os_amiga.c - -obj/popupmnu.o: popupmnu.c - $(CCSYM) $@ popupmnu.c - -obj/quickfix.o: quickfix.c - $(CCSYM) $@ quickfix.c - -obj/regexp.o: regexp.c - $(CCSYM) $@ regexp.c - -obj/screen.o: screen.c - $(CCSYM) $@ screen.c - -obj/search.o: search.c - $(CCSYM) $@ search.c - -obj/sha256.o: sha256.c - $(CCSYM) $@ sha256.c - -obj/sign.o: sign.c - $(CCSYM) $@ sign.c - -obj/spell.o: spell.c - $(CCSYM) $@ spell.c - -obj/spellfile.o: spellfile.c - $(CCSYM) $@ spellfile.c - -obj/syntax.o: syntax.c - $(CCSYM) $@ syntax.c - -obj/tag.o: tag.c - $(CCSYM) $@ tag.c - -obj/term.o: term.c term.h - $(CCSYM) $@ term.c - -obj/termlib.o: termlib.c - $(CCSYM) $@ termlib.c - -obj/ui.o: ui.c - $(CCSYM) $@ ui.c - -obj/undo.o: undo.c - $(CCSYM) $@ undo.c - -obj/usercmd.o: usercmd.c - $(CCSYM) $@ usercmd.c - -obj/userfunc.o: userfunc.c - $(CCSYM) $@ userfunc.c - -obj/window.o: window.c - $(CCSYM) $@ window.c diff -Nru vim-8.1.1681/src/Make_morph.mak vim-8.1.1729/src/Make_morph.mak --- vim-8.1.1681/src/Make_morph.mak 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/Make_morph.mak 2019-07-21 21:04:21.000000000 +0000 @@ -50,6 +50,7 @@ getchar.c \ hardcopy.c \ hashtab.c \ + highlight.c \ indent.c \ insexpand.c \ json.c \ @@ -69,6 +70,7 @@ option.c \ os_amiga.c \ popupmnu.c \ + profiler.c \ quickfix.c \ regexp.c \ screen.c \ @@ -80,11 +82,14 @@ syntax.c \ tag.c \ term.c \ + testing.c \ + textprop.c \ ui.c \ undo.c \ usercmd.c \ userfunc.c \ version.c \ + viminfo.c \ window.c \ OBJ = $(SRC:.c=.o) diff -Nru vim-8.1.1681/src/Make_mvc.mak vim-8.1.1729/src/Make_mvc.mak --- vim-8.1.1681/src/Make_mvc.mak 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/Make_mvc.mak 2019-07-21 21:04:21.000000000 +0000 @@ -739,6 +739,7 @@ $(OUTDIR)\getchar.obj \ $(OUTDIR)\hardcopy.obj \ $(OUTDIR)\hashtab.obj \ + $(OUTDIR)\highlight.obj \ $(OUTDIR)\indent.obj \ $(OUTDIR)\insexpand.obj \ $(OUTDIR)\json.obj \ @@ -761,6 +762,7 @@ $(OUTDIR)\pathdef.obj \ $(OUTDIR)\popupmnu.obj \ $(OUTDIR)\popupwin.obj \ + $(OUTDIR)\profiler.obj \ $(OUTDIR)\quickfix.obj \ $(OUTDIR)\regexp.obj \ $(OUTDIR)\screen.obj \ @@ -772,11 +774,13 @@ $(OUTDIR)\syntax.obj \ $(OUTDIR)\tag.obj \ $(OUTDIR)\term.obj \ + $(OUTDIR)\testing.obj \ $(OUTDIR)\textprop.obj \ $(OUTDIR)\ui.obj \ $(OUTDIR)\undo.obj \ $(OUTDIR)\usercmd.obj \ $(OUTDIR)\userfunc.obj \ + $(OUTDIR)\viminfo.obj \ $(OUTDIR)\winclip.obj \ $(OUTDIR)\window.obj \ @@ -1266,6 +1270,9 @@ tee/tee.exe \ GvimExt/gvimext.dll +# To get around the command line limit: Make use of nmake's response files to +# capture the arguments for $(link) in a file using the @<>>>> choose options: - -### See feature.h for a list of optionals. -### Any other defines can be included here. - -# NO_ARP Don't include ARP functions -# SASC=658 Sas/C version number -# NEWSASC fixes a bug in the syntax highlighting? -DEFINES = DEF=NO_ARP DEF=NEWSASC DEF="SASC=658" - -#>>>>> if HAVE_TGETENT is defined termlib.o has to be used -#TERMLIB = termlib.o -TERMLIB = - -#>>>>> choose NODEBUG for normal compiling, the other for debugging and -# profiling -# don't switch on debugging when generating proto files, it crashes the -# compiler. -DBG = NODEBUG -#DBG = DBG=SF - -#>>>>> choose NOOPTPEEP for 6.0 to 6.3, NOOPT for debugging -# with version 6.56 and later you can probably use OPT -OPTIMIZE = OPT -#OPTIMIZE = NOOPTPEEP -#OPTIMIZE = NOOPT - -# for 6.58 you can use the line below, but be warned it takes a loooonnnggg time -#OPTIMIZE=OPT OPTIMIZERSCHEDULER OPTIMIZERTIME NoOPTIMIZERALIAS \ - OptimizerComplexity=10 OptimizerDepth=10 OptimizerRecurDepth=10 \ - OptimizerInLocal OPTPEEP - -#generate code for your processor - 68060 will work for 040's as well. -CPU=68000 -#CPU=68020 -#CPU=68030 -#CPU=68040 -#CPU=68060 - -#Error reporting - rexx or console -ERROR = ERRORCONSOLE ERRORSOURCE ERRORHIGHLIGHT -#ERROR = ERRORREXX ERRORCONSOLE ERRORSOURCE ERRORHIGHLIGHT - -#memory types, if you have fast use it :->, -# ANY = will work on all machines -# FAST = this is the best option, for speed -#MEMORYTYPE=FAST -MEMORYTYPE=ANY - -#MEMSIZE - this is for compile time only for speed of compilation -#MEMSIZE=HUGE -MEMSIZE=LARGE -#MEMSIZE=SMALL - -#>>>>> end of choices -########################################################################### - -CC = sc -GST = vim.gst -COPTS = SINT SCODE SDATA -SHELL = csh -DEL = $(SHELL) -c rm -f - -# ignore error messages for uninitialized variables, they are mostly not correct -CFLAGS = NOLINK $(DBG) CPU=$(CPU) NOSTACKCHECK DEF=AMIGA CODE=FAR idir=proto ignore=317 -CFLAGS2 = $(OPTIMIZE) $(ERROR) GSTIMMEDIATE GST=$(GST) -CFLAGS3 = $(COPTS) STRINGMERGE MEMSIZE=$(MEMSIZE) -CFLAGS4 = $(DEFINES) DATAMEMORY=$(MEMORYTYPE) - -PROPT = DEF=PROTO GPROTO GPPARM MAXIMUMERRORS=999 GENPROTOSTATICS GENPROTOPARAMETERS - -SRC = \ - arabic.c \ - autocmd.c \ - blowfish.c \ - buffer.c \ - change.c \ - charset.c \ - crypt.c \ - crypt_zip.c \ - debugger.c \ - dict.c \ - diff.c \ - digraph.c \ - edit.c \ - eval.c \ - evalfunc.c \ - ex_cmds.c \ - ex_cmds2.c \ - ex_docmd.c \ - ex_eval.c \ - ex_getln.c \ - fileio.c \ - findfile.c \ - fold.c \ - getchar.c \ - hardcopy.c \ - hashtab.c \ - indent.c \ - insexpand.c \ - json.c \ - list.c \ - main.c \ - mark.c \ - memfile.c \ - memline.c \ - menu.c \ - message.c \ - misc1.c \ - misc2.c \ - move.c \ - mbyte.c \ - normal.c \ - ops.c \ - option.c \ - os_amiga.c \ - popupmnu.c \ - quickfix.c \ - regexp.c \ - screen.c \ - search.c \ - sha256.c \ - sign.c \ - spell.c \ - spellfile.c \ - syntax.c \ - tag.c \ - term.c \ - ui.c \ - undo.c \ - usercmd.c \ - userfunc.c \ - window.c \ - version.c - -OBJ = \ - arabic.o \ - autocmd.o \ - blowfish.o \ - buffer.o \ - change.o \ - charset.o \ - crypt.o \ - crypt_zip.o \ - debugger.o \ - dict.o \ - diff.o \ - digraph.o \ - edit.o \ - eval.o \ - evalfunc.o \ - ex_cmds.o \ - ex_cmds2.o \ - ex_docmd.o \ - ex_eval.o \ - ex_getln.o \ - fileio.o \ - findfile.o \ - fold.o \ - getchar.o \ - hardcopy.o \ - hashtab.o \ - indent.o \ - insexpand.o \ - json.o \ - list.o \ - main.o \ - mark.o \ - memfile.o \ - memline.o \ - menu.o \ - message.o \ - misc1.o \ - misc2.o \ - move.o \ - mbyte.o \ - normal.o \ - ops.o \ - option.o \ - os_amiga.o \ - popupmnu.o \ - quickfix.o \ - regexp.o \ - screen.o \ - search.o \ - sha256.o \ - sign.o \ - spell.o \ - spellfile.o \ - syntax.o \ - tag.o \ - term.o \ - ui.o \ - undo.o \ - usercmd.o \ - userfunc.o \ - window.o \ - $(TERMLIB) - -PRO = \ - proto/arabic.pro \ - proto/autocmd.pro \ - proto/blowfish.pro \ - proto/buffer.pro \ - proto/change.pro \ - proto/charset.pro \ - proto/crypt.pro \ - proto/crypt_zip.pro \ - proto/debugger.pro \ - proto/dict.pro \ - proto/diff.pro \ - proto/digraph.pro \ - proto/edit.pro \ - proto/eval.pro \ - proto/evalfunc.pro \ - proto/ex_cmds.pro \ - proto/ex_cmds2.pro \ - proto/ex_docmd.pro \ - proto/ex_eval.pro \ - proto/ex_getln.pro \ - proto/fileio.pro \ - proto/findfile.pro \ - proto/fold.pro \ - proto/getchar.pro \ - proto/hardcopy.pro \ - proto/hashtab.pro \ - proto/indent.pro \ - proto/insexpand.pro \ - proto/json.pro \ - proto/list.pro \ - proto/main.pro \ - proto/mark.pro \ - proto/memfile.pro \ - proto/memline.pro \ - proto/menu.pro \ - proto/message.pro \ - proto/misc1.pro \ - proto/misc2.pro \ - proto/move.pro \ - proto/mbyte.pro \ - proto/normal.pro \ - proto/ops.pro \ - proto/option.pro \ - proto/os_amiga.pro \ - proto/popupmnu.pro \ - proto/quickfix.pro \ - proto/regexp.pro \ - proto/screen.pro \ - proto/search.pro \ - proto/sha256.pro \ - proto/sign.pro \ - proto/spell.pro \ - proto/spellfile.pro \ - proto/syntax.pro \ - proto/tag.pro \ - proto/term.pro \ - proto/termlib.pro \ - proto/ui.pro \ - proto/undo.pro \ - proto/usercmd.pro \ - proto/userfunc.pro \ - proto/window.pro - -all: proto Vim - -Vim: scoptions $(OBJ) version.c version.h - $(CC) $(CFLAGS) version.c - $(CC) LINK $(COPTS) $(OBJ) version.o $(DBG) PNAME=Vim - -debug: scoptions $(OBJ) version.c version.h - $(CC) $(CFLAGS) version.c - $(CC) LINK $(COPTS) $(OBJ) version.o $(DBG) PNAME=Vim - -proto: $(GST) $(PRO) - -tags: - spat ctags $(SRC) *.h -# csh -c ctags $(SRC) *.h - -# can't use delete here, too many file names -clean: - $(DEL) *.o Vim $(GST) - -# generate GlobalSymbolTable, which speeds up the compile time. -# -# A preprocessing stage is used to work around a bug in the GST generator, in -# that it does not handle nested makefiles properly in this stage. -# Ignore error message for not producing any code (105). -$(GST): scoptions vim.h keymap.h macros.h ascii.h term.h structs.h - $(CC) $(CFLAGS) PREPROCESSORONLY vim.h objectname pre.h - $(CC) MGST=$(GST) pre.h ignore=105 - $(DEL) pre.h - -# generate an options file, because SAS/C smake can't handle the amiga command -# line can handle the lengths that this makefile will impose on the shell. -# (Manx's make can do this). -scoptions: Make_sas.mak - @echo "Generating - $@ ..." - @echo $(CFLAGS) > scoptions - @echo $(CFLAGS1) >> scoptions - @echo $(CFLAGS2) >> scoptions - @echo $(CFLAGS3) >> scoptions - @echo $(CFLAGS4) >> scoptions - @echo $(COPTS) >>scoptions - @echo done - -########################################################################### - -$(OBJ): $(GST) vim.h -$(PRO): $(GST) vim.h - -.c.o: - $(CC) $(CFLAGS) $*.c - -.c.pro: - $(CC) $(CFLAGS) GPFILE=proto/$*.pro $(PROPT) $*.c - -# dependencies -arabic.o: arabic.c -proto/arabic.pro: arabic.c -autocmd.o: autocmd.c -proto/autocmd.pro: autocmd.c -blowfish.o: blowfish.c -proto/blowfish.pro: blowfish.c -buffer.o: buffer.c -proto/buffer.pro: buffer.c -change.o: change.c -proto/change.pro: change.c -charset.o: charset.c -proto/charset.pro: charset.c -crypt.o: crypt.c -proto/crypt.pro: crypt.c -crypt_zip.o: crypt_zip.c -proto/crypt_zip.pro: crypt_zip.c -debugger.o: debugger.c -proto/debugger.pro: debugger.c -dict.o: dict.c -proto/dict.pro: dict.c -diff.o: diff.c -proto/diff.pro: diff.c -digraph.o: digraph.c -proto/digraph.pro: digraph.c -edit.o: edit.c -proto/edit.pro: edit.c -eval.o: eval.c -proto/eval.pro: eval.c -evalfunc.o: evalfunc.c -proto/evalfunc.pro: evalfunc.c -ex_cmds.o: ex_cmds.c -proto/ex_cmds.pro: ex_cmds.c -ex_cmds2.o: ex_cmds2.c -proto/ex_cmds2.pro: ex_cmds2.c -ex_docmd.o: ex_docmd.c ex_cmds.h -proto/ex_docmd.pro: ex_docmd.c ex_cmds.h -ex_eval.o: ex_eval.c ex_cmds.h -proto/ex_eval.pro: ex_eval.c ex_cmds.h -ex_getln.o: ex_getln.c -proto/ex_getln.pro: ex_getln.c -fileio.o: fileio.c -proto/fileio.pro: fileio.c -findfile.o: findfile.c -proto/findfile.pro: findfile.c -fold.o: fold.c -proto/fold.pro: fold.c -getchar.o: getchar.c -proto/getchar.pro: getchar.c -hardcopy.o: hardcopy.c -proto/hardcopy.pro: hardcopy.c -hashtab.o: hashtab.c -proto/hashtab.pro: hashtab.c -indent.o: indent.c -proto/indent.pro: indent.c -insexpand.o: insexpand.c -proto/insexpand.pro: insexpand.c -json.o: json.c -proto/json.pro: json.c -list.o: list.c -proto/list.pro: list.c -main.o: main.c -proto/main.pro: main.c -mark.o: mark.c -proto/mark.pro: mark.c -memfile.o: memfile.c -proto/memfile.pro: memfile.c -memline.o: memline.c -proto/memline.pro: memline.c -menu.o: menu.c -proto/menu.pro: menu.c -message.o: message.c -proto/message.pro: message.c -misc1.o: misc1.c -proto/misc1.pro: misc1.c -misc2.o: misc2.c -proto/misc2.pro: misc2.c -move.o: move.c -proto/move.pro: move.c -mbyte.o: mbyte.c -proto/mbyte.pro: mbyte.c -normal.o: normal.c -proto/normal.pro: normal.c -ops.o: ops.c -proto/ops.pro: ops.c -option.o: option.c -proto/option.pro: option.c -os_amiga.o: os_amiga.c -proto/os_amiga.pro: os_amiga.c -popupmnu.o: popupmnu.c -proto/popupmnu.pro: popupmnu.c -quickfix.o: quickfix.c -proto/quickfix.pro: quickfix.c -regexp.o: regexp.c -proto/regexp.pro: regexp.c -screen.o: screen.c -proto/screen.pro: screen.c -search.o: search.c -proto/search.pro: search.c -sha256.o: sha256.c -proto/sha256.pro: sha256.c -sign.o: sign.c -proto/sign.pro: sign.c -spell.o: spell.c -proto/spell.pro: spell.c -spellfile.o: spellfile.c -proto/spellfile.pro: spellfile.c -syntax.o: syntax.c -proto/syntax.pro: syntax.c -tag.o: tag.c -proto/tag.pro: tag.c -term.o: term.c -proto/term.pro: term.c -termlib.o: termlib.c -proto/termlib.pro: termlib.c -ui.o: ui.c -proto/ui.pro: ui.c -undo.o: undo.c -proto/undo.pro: undo.c -usercmd.o: usercmd.c -proto/usercmd.pro: usercmd.c -userfunc.o: userfunc.c -proto/userfunc.pro: userfunc.c -window.o: window.c diff -Nru vim-8.1.1681/src/Make_vms.mms vim-8.1.1729/src/Make_vms.mms --- vim-8.1.1681/src/Make_vms.mms 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/Make_vms.mms 2019-07-21 21:04:21.000000000 +0000 @@ -2,7 +2,7 @@ # Makefile for Vim on OpenVMS # # Maintainer: Zoltan Arpadffy -# Last change: 2019 May 24 +# Last change: 2019 Jul 14 # # This has script been tested on VMS 6.2 to 8.2 on DEC Alpha, VAX and IA64 # with MMS and MMK @@ -311,12 +311,13 @@ crypt.c crypt_zip.c debugger.c dict.c diff.c digraph.c edit.c eval.c \ evalfunc.c ex_cmds.c ex_cmds2.c ex_docmd.c ex_eval.c ex_getln.c \ if_cscope.c if_xcmdsrv.c fileio.c findfile.c fold.c getchar.c \ - hardcopy.c hashtab.c indent.c insexpand.c json.c list.c main.c mark.c \ - menu.c mbyte.c memfile.c memline.c message.c misc1.c misc2.c move.c \ - normal.c ops.c option.c popupmnu.c popupwin.c, quickfix.c regexp.c search.c \ - sha256.c sign.c spell.c spellfile.c syntax.c tag.c term.c termlib.c \ - textprop.c ui.c undo.c usercmd.c userfunc.c version.c screen.c \ - window.c os_unix.c os_vms.c pathdef.c \ + hardcopy.c hashtab.c highlight.c indent.c insexpand.c json.c list.c \ + main.c mark.c menu.c mbyte.c memfile.c memline.c message.c misc1.c \ + misc2.c move.c normal.c ops.c option.c popupmnu.c popupwin.c \ + profiler.c quickfix.c regexp.c search.c sha256.c sign.c spell.c \ + spellfile.c syntax.c tag.c term.c termlib.c testing.c textprop.c ui.c \ + undo.c usercmd.c userfunc.c version.c viminfo.c screen.c window.c \ + os_unix.c os_vms.c pathdef.c \ $(GUI_SRC) $(PERL_SRC) $(PYTHON_SRC) $(TCL_SRC) \ $(RUBY_SRC) $(HANGULIN_SRC) $(MZSCH_SRC) $(XDIFF_SRC) @@ -325,13 +326,14 @@ digraph.obj edit.obj eval.obj evalfunc.obj ex_cmds.obj ex_cmds2.obj \ ex_docmd.obj ex_eval.obj ex_getln.obj if_cscope.obj if_xcmdsrv.obj \ fileio.obj findfile.obj fold.obj getchar.obj hardcopy.obj hashtab.obj \ - indent.obj insexpand.obj json.obj list.obj main.obj mark.obj \ - menu.obj memfile.obj memline.obj message.obj misc1.obj misc2.obj \ - move.obj mbyte.obj normal.obj ops.obj option.obj popupmnu.obj popupwin.obj\ - quickfix.obj regexp.obj search.obj sha256.obj sign.obj spell.obj \ - spellfile.obj syntax.obj tag.obj term.obj termlib.obj textprop.obj \ - ui.obj undo.obj usercmd.obj userfunc.obj screen.obj version.obj \ - window.obj os_unix.obj os_vms.obj pathdef.obj if_mzsch.obj \ + highlight.obj indent.obj insexpand.obj json.obj list.obj main.obj \ + mark.obj menu.obj memfile.obj memline.obj message.obj misc1.obj \ + misc2.obj move.obj mbyte.obj normal.obj ops.obj option.obj \ + popupmnu.obj popupwin.obj profiler.obj quickfix.obj regexp.obj \ + search.obj sha256.obj sign.obj spell.obj spellfile.obj syntax.obj \ + tag.obj term.obj termlib.obj testing.obj textprop.obj ui.obj undo.obj \ + usercmd.obj userfunc.obj screen.obj version.obj viminfo.obj window.obj \ + os_unix.obj os_vms.obj pathdef.obj if_mzsch.obj \ $(GUI_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(TCL_OBJ) \ $(RUBY_OBJ) $(HANGULIN_OBJ) $(MZSCH_OBJ) $(XDIFF_OBJ) @@ -598,6 +600,10 @@ ascii.h keymap.h term.h macros.h structs.h regexp.h \ gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ globals.h +highlight.obj : highlight.c vim.h [.auto]config.h feature.h os_unix.h \ + ascii.h keymap.h term.h macros.h structs.h regexp.h \ + gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ + globals.h if_cscope.obj : if_cscope.c vim.h [.auto]config.h feature.h os_unix.h \ ascii.h keymap.h term.h macros.h structs.h regexp.h \ gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ @@ -692,6 +698,10 @@ ascii.h keymap.h term.h macros.h structs.h regexp.h \ gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ globals.h +profiler.obj : profiler.c vim.h [.auto]config.h feature.h os_unix.h \ + ascii.h keymap.h term.h macros.h structs.h regexp.h \ + gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ + globals.h quickfix.obj : quickfix.c vim.h [.auto]config.h feature.h os_unix.h \ ascii.h keymap.h term.h macros.h structs.h regexp.h \ gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ @@ -740,6 +750,10 @@ ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \ [.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h \ +testing.obj : testing.c vim.h [.auto]config.h feature.h os_unix.h \ + ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \ + [.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h \ + textprop.obj : textprop.c vim.h [.auto]config.h feature.h os_unix.h \ ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \ [.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h \ @@ -766,6 +780,10 @@ ascii.h keymap.h term.h macros.h structs.h regexp.h \ gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ globals.h version.h +viminfo.obj : viminfo.c vim.h [.auto]config.h feature.h os_unix.h \ + ascii.h keymap.h term.h macros.h structs.h regexp.h \ + gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ + globals.h version.h window.obj : window.c vim.h [.auto]config.h feature.h os_unix.h \ ascii.h keymap.h term.h macros.h structs.h regexp.h \ gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ diff -Nru vim-8.1.1681/src/memline.c vim-8.1.1729/src/memline.c --- vim-8.1.1681/src/memline.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/memline.c 2019-07-21 21:04:21.000000000 +0000 @@ -243,7 +243,6 @@ static void add_b0_fenc(ZERO_BL *b0p, buf_T *buf); static time_t swapfile_info(char_u *); static int recov_file_names(char_u **, char_u *, int prepend_dot); -static int ml_append_int(buf_T *, linenr_T, char_u *, colnr_T, int, int); static int ml_delete_int(buf_T *, linenr_T, int); static char_u *findswapname(buf_T *, char_u **, char_u *); static void ml_flush_line(buf_T *); @@ -2143,7 +2142,24 @@ if (curtime == NULL) vim_strncpy((char_u *)buf, (char_u *)_("(Invalid)"), sizeof(buf) - 1); else - (void)strftime(buf, sizeof(buf) - 1, "%a %b %d %H:%M:%S %Y", curtime); + { + (void)strftime(buf, sizeof(buf) - 1, _("%a %b %d %H:%M:%S %Y"), + curtime); +# ifdef MSWIN + if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) + { + char_u *to_free = NULL; + int len; + + acp_to_enc((char_u *)buf, (int)strlen(buf), &to_free, &len); + if (to_free != NULL) + { + STRCPY(buf, to_free); + vim_free(to_free); + } + } +# endif + } #else STRCPY(buf, "(unknown)"); #endif @@ -2746,56 +2762,6 @@ } #endif -/* - * Append a line after lnum (may be 0 to insert a line in front of the file). - * "line" does not need to be allocated, but can't be another line in a - * buffer, unlocking may make it invalid. - * - * newfile: TRUE when starting to edit a new file, meaning that pe_old_lnum - * will be set for recovery - * Check: The caller of this function should probably also call - * appended_lines(). - * - * return FAIL for failure, OK otherwise - */ - int -ml_append( - linenr_T lnum, /* append after this line (can be 0) */ - char_u *line, /* text of the new line */ - colnr_T len, /* length of new line, including NUL, or 0 */ - int newfile) /* flag, see above */ -{ - /* When starting up, we might still need to create the memfile */ - if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL) - return FAIL; - - if (curbuf->b_ml.ml_line_lnum != 0) - ml_flush_line(curbuf); - return ml_append_int(curbuf, lnum, line, len, newfile, FALSE); -} - -#if defined(FEAT_SPELL) || defined(FEAT_QUICKFIX) || defined(PROTO) -/* - * Like ml_append() but for an arbitrary buffer. The buffer must already have - * a memline. - */ - int -ml_append_buf( - buf_T *buf, - linenr_T lnum, /* append after this line (can be 0) */ - char_u *line, /* text of the new line */ - colnr_T len, /* length of new line, including NUL, or 0 */ - int newfile) /* flag, see above */ -{ - if (buf->b_ml.ml_mfp == NULL) - return FAIL; - - if (buf->b_ml.ml_line_lnum != 0) - ml_flush_line(buf); - return ml_append_int(buf, lnum, line, len, newfile, FALSE); -} -#endif - static int ml_append_int( buf_T *buf, @@ -2834,14 +2800,6 @@ if (len == 0) len = (colnr_T)STRLEN(line) + 1; // space needed for the text -#ifdef FEAT_EVAL - // When inserting above recorded changes: flush the changes before changing - // the text. Then flush the cached line, it may become invalid. - may_invoke_listeners(buf, lnum + 1, lnum + 1, 1); - if (curbuf->b_ml.ml_line_lnum != 0) - ml_flush_line(curbuf); -#endif - #ifdef FEAT_TEXT_PROP if (curbuf->b_has_textprop && lnum > 0) // Add text properties that continue from the previous line. @@ -3326,6 +3284,79 @@ } /* + * Flush any pending change and call ml_append_int() + */ + static int +ml_append_flush( + buf_T *buf, + linenr_T lnum, // append after this line (can be 0) + char_u *line, // text of the new line + colnr_T len, // length of line, including NUL, or 0 + int newfile) // flag, see above +{ + if (lnum > buf->b_ml.ml_line_count) + return FAIL; // lnum out of range + + if (buf->b_ml.ml_line_lnum != 0) + // This may also invoke ml_append_int(). + ml_flush_line(buf); + +#ifdef FEAT_EVAL + // When inserting above recorded changes: flush the changes before changing + // the text. Then flush the cached line, it may become invalid. + may_invoke_listeners(buf, lnum + 1, lnum + 1, 1); + if (buf->b_ml.ml_line_lnum != 0) + ml_flush_line(buf); +#endif + + return ml_append_int(buf, lnum, line, len, newfile, FALSE); +} + +/* + * Append a line after lnum (may be 0 to insert a line in front of the file). + * "line" does not need to be allocated, but can't be another line in a + * buffer, unlocking may make it invalid. + * + * newfile: TRUE when starting to edit a new file, meaning that pe_old_lnum + * will be set for recovery + * Check: The caller of this function should probably also call + * appended_lines(). + * + * return FAIL for failure, OK otherwise + */ + int +ml_append( + linenr_T lnum, /* append after this line (can be 0) */ + char_u *line, /* text of the new line */ + colnr_T len, /* length of new line, including NUL, or 0 */ + int newfile) /* flag, see above */ +{ + /* When starting up, we might still need to create the memfile */ + if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL) + return FAIL; + return ml_append_flush(curbuf, lnum, line, len, newfile); +} + +#if defined(FEAT_SPELL) || defined(FEAT_QUICKFIX) || defined(PROTO) +/* + * Like ml_append() but for an arbitrary buffer. The buffer must already have + * a memline. + */ + int +ml_append_buf( + buf_T *buf, + linenr_T lnum, /* append after this line (can be 0) */ + char_u *line, /* text of the new line */ + colnr_T len, /* length of new line, including NUL, or 0 */ + int newfile) /* flag, see above */ +{ + if (buf->b_ml.ml_mfp == NULL) + return FAIL; + return ml_append_flush(buf, lnum, line, len, newfile); +} +#endif + +/* * Replace line lnum, with buffering, in current buffer. * * If "copy" is TRUE, make a copy of the line, otherwise the line has been @@ -3552,6 +3583,15 @@ ml_delete(linenr_T lnum, int message) { ml_flush_line(curbuf); + if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) + return FAIL; + +#ifdef FEAT_EVAL + // When inserting above recorded changes: flush the changes before changing + // the text. + may_invoke_listeners(curbuf, lnum, lnum + 1, -1); +#endif + return ml_delete_int(curbuf, lnum, message); } @@ -3576,14 +3616,6 @@ int textprop_save_len; #endif - if (lnum < 1 || lnum > buf->b_ml.ml_line_count) - return FAIL; - -#ifdef FEAT_EVAL - // When inserting above recorded changes: flush the changes before changing - // the text. - may_invoke_listeners(buf, lnum, lnum + 1, -1); -#endif if (lowest_marked && lowest_marked > lnum) lowest_marked--; diff -Nru vim-8.1.1681/src/misc1.c vim-8.1.1729/src/misc1.c --- vim-8.1.1681/src/misc1.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/misc1.c 2019-07-21 21:04:21.000000000 +0000 @@ -3182,11 +3182,7 @@ */ #ifndef BREAKCHECK_SKIP -# ifdef FEAT_GUI /* assume the GUI only runs on fast computers */ -# define BREAKCHECK_SKIP 200 -# else -# define BREAKCHECK_SKIP 32 -# endif +# define BREAKCHECK_SKIP 1000 #endif static int breakcheck_count = 0; diff -Nru vim-8.1.1681/src/misc2.c vim-8.1.1729/src/misc2.c --- vim-8.1.1681/src/misc2.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/misc2.c 2019-07-21 21:04:21.000000000 +0000 @@ -4442,7 +4442,8 @@ void parse_queued_messages(void) { - win_T *old_curwin = curwin; + int old_curwin_id = curwin->w_id; + int old_curbuf_fnum = curbuf->b_fnum; int i; int save_may_garbage_collect = may_garbage_collect; @@ -4494,9 +4495,9 @@ may_garbage_collect = save_may_garbage_collect; - // If the current window changed we need to bail out of the waiting loop. - // E.g. when a job exit callback closes the terminal window. - if (curwin != old_curwin) + // If the current window or buffer changed we need to bail out of the + // waiting loop. E.g. when a job exit callback closes the terminal window. + if (curwin->w_id != old_curwin_id || curbuf->b_fnum != old_curbuf_fnum) ins_char_typebuf(K_IGNORE); } #endif diff -Nru vim-8.1.1681/src/option.c vim-8.1.1729/src/option.c --- vim-8.1.1681/src/option.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/option.c 2019-07-21 21:04:21.000000000 +0000 @@ -2079,6 +2079,15 @@ (char_u *)NULL, PV_NONE, #endif {(char_u *)12L, (char_u *)0L} SCTX_INIT}, + {"previewpopup", "pvp", P_STRING|P_VI_DEF|P_COMMA|P_NODUP, +#ifdef FEAT_TEXT_PROP + (char_u *)&p_pvp, PV_NONE, + {(char_u *)"", (char_u *)0L} +#else + (char_u *)NULL, PV_NONE, + {(char_u *)NULL, (char_u *)0L} +#endif + SCTX_INIT}, {"previewwindow", "pvw", P_BOOL|P_VI_DEF|P_RSTAT|P_NOGLOB, #if defined(FEAT_QUICKFIX) (char_u *)VAR_WIN, PV_PVW, @@ -7831,6 +7840,15 @@ } #endif +#ifdef FEAT_TEXT_PROP + // 'previewpopup' + else if (varp == &p_pvp) + { + if (parse_previewpopup(NULL) == FAIL) + errmsg = e_invarg; + } +#endif + /* Options that are a list of flags. */ else { diff -Nru vim-8.1.1681/src/option.h vim-8.1.1729/src/option.h --- vim-8.1.1681/src/option.h 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/option.h 2019-07-21 21:04:21.000000000 +0000 @@ -26,7 +26,7 @@ # else # ifdef VMS # define DFLT_EFM "%A%p^,%C%%CC-%t-%m,%Cat line number %l in file %f,%f|%l| %m" -# else /* Unix, probably */ +# else // Unix, probably # ifdef EBCDIC #define DFLT_EFM "%*[^ ] %*[^ ] %f:%l%*[ ]%m,%*[^\"]\"%f\"%*\\D%l: %m,\"%f\"%*\\D%l: %m,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,\"%f\"\\, line %l%*\\D%c%*[^ ] %m,%D%*\\a[%*\\d]: Entering directory %*[`']%f',%X%*\\a[%*\\d]: Leaving directory %*[`']%f',%DMaking %*\\a in %f,%f|%l| %m" # else @@ -39,7 +39,7 @@ #define DFLT_GREPFORMAT "%f:%l:%m,%f:%l%m,%f %l%m" -/* default values for b_p_ff 'fileformat' and p_ffs 'fileformats' */ +// default values for b_p_ff 'fileformat' and p_ffs 'fileformats' #define FF_DOS "dos" #define FF_MAC "mac" #define FF_UNIX "unix" @@ -47,13 +47,13 @@ #ifdef USE_CRNL # define DFLT_FF "dos" # define DFLT_FFS_VIM "dos,unix" -# define DFLT_FFS_VI "dos,unix" /* also autodetect in compatible mode */ +# define DFLT_FFS_VI "dos,unix" // also autodetect in compatible mode # define DFLT_TEXTAUTO TRUE #else # define DFLT_FF "unix" # define DFLT_FFS_VIM "unix,dos" # ifdef __CYGWIN__ -# define DFLT_FFS_VI "unix,dos" /* Cygwin always needs file detection */ +# define DFLT_FFS_VI "unix,dos" // Cygwin always needs file detection # define DFLT_TEXTAUTO TRUE # else # define DFLT_FFS_VI "" @@ -62,19 +62,19 @@ #endif -/* Possible values for 'encoding' */ -#define ENC_UCSBOM "ucs-bom" /* check for BOM at start of file */ +// Possible values for 'encoding' +#define ENC_UCSBOM "ucs-bom" // check for BOM at start of file -/* default value for 'encoding' */ +// default value for 'encoding' #define ENC_DFLT "latin1" -/* end-of-line style */ -#define EOL_UNKNOWN -1 /* not defined yet */ -#define EOL_UNIX 0 /* NL */ -#define EOL_DOS 1 /* CR NL */ -#define EOL_MAC 2 /* CR */ +// end-of-line style +#define EOL_UNKNOWN -1 // not defined yet +#define EOL_UNIX 0 // NL +#define EOL_DOS 1 // CR NL +#define EOL_MAC 2 // CR -/* Formatting options for p_fo 'formatoptions' */ +// Formatting options for p_fo 'formatoptions' #define FO_WRAP 't' #define FO_WRAP_COMS 'c' #define FO_RET_COMS 'r' @@ -85,104 +85,104 @@ #define FO_INS_VI 'v' #define FO_INS_LONG 'l' #define FO_INS_BLANK 'b' -#define FO_MBYTE_BREAK 'm' /* break before/after multi-byte char */ -#define FO_MBYTE_JOIN 'M' /* no space before/after multi-byte char */ -#define FO_MBYTE_JOIN2 'B' /* no space between multi-byte chars */ +#define FO_MBYTE_BREAK 'm' // break before/after multi-byte char +#define FO_MBYTE_JOIN 'M' // no space before/after multi-byte char +#define FO_MBYTE_JOIN2 'B' // no space between multi-byte chars #define FO_ONE_LETTER '1' -#define FO_WHITE_PAR 'w' /* trailing white space continues paragr. */ -#define FO_AUTO 'a' /* automatic formatting */ -#define FO_REMOVE_COMS 'j' /* remove comment leaders when joining lines */ -#define FO_PERIOD_ABBR 'p' /* don't break a single space after a period */ +#define FO_WHITE_PAR 'w' // trailing white space continues paragr. +#define FO_AUTO 'a' // automatic formatting +#define FO_REMOVE_COMS 'j' // remove comment leaders when joining lines +#define FO_PERIOD_ABBR 'p' // don't break a single space after a period #define DFLT_FO_VI "vt" #define DFLT_FO_VIM "tcq" -#define FO_ALL "tcroq2vlb1mMBn,awjp" /* for do_set() */ +#define FO_ALL "tcroq2vlb1mMBn,awjp" // for do_set() -/* characters for the p_cpo option: */ -#define CPO_ALTREAD 'a' /* ":read" sets alternate file name */ -#define CPO_ALTWRITE 'A' /* ":write" sets alternate file name */ -#define CPO_BAR 'b' /* "\|" ends a mapping */ -#define CPO_BSLASH 'B' /* backslash in mapping is not special */ +// characters for the p_cpo option: +#define CPO_ALTREAD 'a' // ":read" sets alternate file name +#define CPO_ALTWRITE 'A' // ":write" sets alternate file name +#define CPO_BAR 'b' // "\|" ends a mapping +#define CPO_BSLASH 'B' // backslash in mapping is not special #define CPO_SEARCH 'c' -#define CPO_CONCAT 'C' /* Don't concatenate sourced lines */ -#define CPO_DOTTAG 'd' /* "./tags" in 'tags' is in current dir */ -#define CPO_DIGRAPH 'D' /* No digraph after "r", "f", etc. */ +#define CPO_CONCAT 'C' // Don't concatenate sourced lines +#define CPO_DOTTAG 'd' // "./tags" in 'tags' is in current dir +#define CPO_DIGRAPH 'D' // No digraph after "r", "f", etc. #define CPO_EXECBUF 'e' -#define CPO_EMPTYREGION 'E' /* operating on empty region is an error */ -#define CPO_FNAMER 'f' /* set file name for ":r file" */ -#define CPO_FNAMEW 'F' /* set file name for ":w file" */ -#define CPO_GOTO1 'g' /* goto line 1 for ":edit" */ -#define CPO_INSEND 'H' /* "I" inserts before last blank in line */ -#define CPO_INTMOD 'i' /* interrupt a read makes buffer modified */ -#define CPO_INDENT 'I' /* remove auto-indent more often */ -#define CPO_JOINSP 'j' /* only use two spaces for join after '.' */ -#define CPO_ENDOFSENT 'J' /* need two spaces to detect end of sentence */ -#define CPO_KEYCODE 'k' /* don't recognize raw key code in mappings */ -#define CPO_KOFFSET 'K' /* don't wait for key code in mappings */ -#define CPO_LITERAL 'l' /* take char after backslash in [] literal */ -#define CPO_LISTWM 'L' /* 'list' changes wrapmargin */ +#define CPO_EMPTYREGION 'E' // operating on empty region is an error +#define CPO_FNAMER 'f' // set file name for ":r file" +#define CPO_FNAMEW 'F' // set file name for ":w file" +#define CPO_GOTO1 'g' // goto line 1 for ":edit" +#define CPO_INSEND 'H' // "I" inserts before last blank in line +#define CPO_INTMOD 'i' // interrupt a read makes buffer modified +#define CPO_INDENT 'I' // remove auto-indent more often +#define CPO_JOINSP 'j' // only use two spaces for join after '.' +#define CPO_ENDOFSENT 'J' // need two spaces to detect end of sentence +#define CPO_KEYCODE 'k' // don't recognize raw key code in mappings +#define CPO_KOFFSET 'K' // don't wait for key code in mappings +#define CPO_LITERAL 'l' // take char after backslash in [] literal +#define CPO_LISTWM 'L' // 'list' changes wrapmargin #define CPO_SHOWMATCH 'm' -#define CPO_MATCHBSL 'M' /* "%" ignores use of backslashes */ -#define CPO_NUMCOL 'n' /* 'number' column also used for text */ +#define CPO_MATCHBSL 'M' // "%" ignores use of backslashes +#define CPO_NUMCOL 'n' // 'number' column also used for text #define CPO_LINEOFF 'o' -#define CPO_OVERNEW 'O' /* silently overwrite new file */ -#define CPO_LISP 'p' /* 'lisp' indenting */ -#define CPO_FNAMEAPP 'P' /* set file name for ":w >>file" */ -#define CPO_JOINCOL 'q' /* with "3J" use column after first join */ +#define CPO_OVERNEW 'O' // silently overwrite new file +#define CPO_LISP 'p' // 'lisp' indenting +#define CPO_FNAMEAPP 'P' // set file name for ":w >>file" +#define CPO_JOINCOL 'q' // with "3J" use column after first join #define CPO_REDO 'r' -#define CPO_REMMARK 'R' /* remove marks when filtering */ +#define CPO_REMMARK 'R' // remove marks when filtering #define CPO_BUFOPT 's' #define CPO_BUFOPTGLOB 'S' #define CPO_TAGPAT 't' -#define CPO_UNDO 'u' /* "u" undoes itself */ -#define CPO_BACKSPACE 'v' /* "v" keep deleted text */ -#define CPO_CW 'w' /* "cw" only changes one blank */ -#define CPO_FWRITE 'W' /* "w!" doesn't overwrite readonly files */ +#define CPO_UNDO 'u' // "u" undoes itself +#define CPO_BACKSPACE 'v' // "v" keep deleted text +#define CPO_CW 'w' // "cw" only changes one blank +#define CPO_FWRITE 'W' // "w!" doesn't overwrite readonly files #define CPO_ESC 'x' -#define CPO_REPLCNT 'X' /* "R" with a count only deletes chars once */ +#define CPO_REPLCNT 'X' // "R" with a count only deletes chars once #define CPO_YANK 'y' -#define CPO_KEEPRO 'Z' /* don't reset 'readonly' on ":w!" */ +#define CPO_KEEPRO 'Z' // don't reset 'readonly' on ":w!" #define CPO_DOLLAR '$' #define CPO_FILTER '!' #define CPO_MATCH '%' -#define CPO_STAR '*' /* ":*" means ":@" */ -#define CPO_PLUS '+' /* ":write file" resets 'modified' */ -#define CPO_MINUS '-' /* "9-" fails at and before line 9 */ -#define CPO_SPECI '<' /* don't recognize <> in mappings */ -#define CPO_REGAPPEND '>' /* insert NL when appending to a register */ +#define CPO_STAR '*' // ":*" means ":@" +#define CPO_PLUS '+' // ":write file" resets 'modified' +#define CPO_MINUS '-' // "9-" fails at and before line 9 +#define CPO_SPECI '<' // don't recognize <> in mappings +#define CPO_REGAPPEND '>' // insert NL when appending to a register /* POSIX flags */ -#define CPO_HASH '#' /* "D", "o" and "O" do not use a count */ -#define CPO_PARA '{' /* "{" is also a paragraph boundary */ -#define CPO_TSIZE '|' /* $LINES and $COLUMNS overrule term size */ -#define CPO_PRESERVE '&' /* keep swap file after :preserve */ -#define CPO_SUBPERCENT '/' /* % in :s string uses previous one */ -#define CPO_BACKSL '\\' /* \ is not special in [] */ -#define CPO_CHDIR '.' /* don't chdir if buffer is modified */ -#define CPO_SCOLON ';' /* using "," and ";" will skip over char if - * cursor would not move */ +#define CPO_HASH '#' // "D", "o" and "O" do not use a count +#define CPO_PARA '{' // "{" is also a paragraph boundary +#define CPO_TSIZE '|' // $LINES and $COLUMNS overrule term size +#define CPO_PRESERVE '&' // keep swap file after :preserve +#define CPO_SUBPERCENT '/' // % in :s string uses previous one +#define CPO_BACKSL '\\' // \ is not special in [] +#define CPO_CHDIR '.' // don't chdir if buffer is modified +#define CPO_SCOLON ';' // using "," and ";" will skip over char if + // cursor would not move /* default values for Vim, Vi and POSIX */ #define CPO_VIM "aABceFs" #define CPO_VI "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>;" #define CPO_ALL "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>#{|&/\\.;" -/* characters for p_ww option: */ +// characters for p_ww option: #define WW_ALL "bshl<>[],~" -/* characters for p_mouse option: */ -#define MOUSE_NORMAL 'n' /* use mouse in Normal mode */ -#define MOUSE_VISUAL 'v' /* use mouse in Visual/Select mode */ -#define MOUSE_INSERT 'i' /* use mouse in Insert mode */ -#define MOUSE_COMMAND 'c' /* use mouse in Command-line mode */ -#define MOUSE_HELP 'h' /* use mouse in help buffers */ -#define MOUSE_RETURN 'r' /* use mouse for hit-return message */ -#define MOUSE_A "nvich" /* used for 'a' flag */ -#define MOUSE_ALL "anvichr" /* all possible characters */ -#define MOUSE_NONE ' ' /* don't use Visual selection */ -#define MOUSE_NONEF 'x' /* forced modeless selection */ +// characters for p_mouse option: +#define MOUSE_NORMAL 'n' // use mouse in Normal mode +#define MOUSE_VISUAL 'v' // use mouse in Visual/Select mode +#define MOUSE_INSERT 'i' // use mouse in Insert mode +#define MOUSE_COMMAND 'c' // use mouse in Command-line mode +#define MOUSE_HELP 'h' // use mouse in help buffers +#define MOUSE_RETURN 'r' // use mouse for hit-return message +#define MOUSE_A "nvich" // used for 'a' flag +#define MOUSE_ALL "anvichr" // all possible characters +#define MOUSE_NONE ' ' // don't use Visual selection +#define MOUSE_NONEF 'x' // forced modeless selection -#define COCU_ALL "nvic" /* flags for 'concealcursor' */ +#define COCU_ALL "nvic" // flags for 'concealcursor' -/* characters for p_shm option: */ +// characters for p_shm option: #define SHM_RO 'r' // readonly #define SHM_MOD 'm' // modified #define SHM_FILE 'f' // (file 1 of 2) @@ -207,94 +207,94 @@ #define SHM_POSIX "AS" // POSIX value #define SHM_ALL "rmfixlnwaWtToOsAIcqFS" // all possible flags for 'shm' -/* characters for p_go: */ -#define GO_TERMINAL '!' /* use terminal for system commands */ -#define GO_ASEL 'a' /* autoselect */ -#define GO_ASELML 'A' /* autoselect modeless selection */ -#define GO_BOT 'b' /* use bottom scrollbar */ -#define GO_CONDIALOG 'c' /* use console dialog */ -#define GO_TABLINE 'e' /* may show tabline */ -#define GO_FORG 'f' /* start GUI in foreground */ -#define GO_GREY 'g' /* use grey menu items */ -#define GO_HORSCROLL 'h' /* flexible horizontal scrolling */ -#define GO_ICON 'i' /* use Vim icon */ -#define GO_LEFT 'l' /* use left scrollbar */ -#define GO_VLEFT 'L' /* left scrollbar with vert split */ -#define GO_MENUS 'm' /* use menu bar */ -#define GO_NOSYSMENU 'M' /* don't source system menu */ -#define GO_POINTER 'p' /* pointer enter/leave callbacks */ -#define GO_ASELPLUS 'P' /* autoselectPlus */ -#define GO_RIGHT 'r' /* use right scrollbar */ -#define GO_VRIGHT 'R' /* right scrollbar with vert split */ -#define GO_TEAROFF 't' /* add tear-off menu items */ -#define GO_TOOLBAR 'T' /* add toolbar */ -#define GO_FOOTER 'F' /* add footer */ -#define GO_VERTICAL 'v' /* arrange dialog buttons vertically */ -#define GO_KEEPWINSIZE 'k' /* keep GUI window size */ -#define GO_ALL "!aAbcefFghilmMprtTvk" /* all possible flags for 'go' */ - -/* flags for 'comments' option */ -#define COM_NEST 'n' /* comments strings nest */ -#define COM_BLANK 'b' /* needs blank after string */ -#define COM_START 's' /* start of comment */ -#define COM_MIDDLE 'm' /* middle of comment */ -#define COM_END 'e' /* end of comment */ -#define COM_AUTO_END 'x' /* last char of end closes comment */ -#define COM_FIRST 'f' /* first line comment only */ -#define COM_LEFT 'l' /* left adjusted */ -#define COM_RIGHT 'r' /* right adjusted */ -#define COM_NOBACK 'O' /* don't use for "O" command */ -#define COM_ALL "nbsmexflrO" /* all flags for 'comments' option */ -#define COM_MAX_LEN 50 /* maximum length of a part */ - -/* flags for 'statusline' option */ -#define STL_FILEPATH 'f' /* path of file in buffer */ -#define STL_FULLPATH 'F' /* full path of file in buffer */ -#define STL_FILENAME 't' /* last part (tail) of file path */ -#define STL_COLUMN 'c' /* column og cursor*/ -#define STL_VIRTCOL 'v' /* virtual column */ -#define STL_VIRTCOL_ALT 'V' /* - with 'if different' display */ -#define STL_LINE 'l' /* line number of cursor */ -#define STL_NUMLINES 'L' /* number of lines in buffer */ -#define STL_BUFNO 'n' /* current buffer number */ -#define STL_KEYMAP 'k' /* 'keymap' when active */ -#define STL_OFFSET 'o' /* offset of character under cursor*/ -#define STL_OFFSET_X 'O' /* - in hexadecimal */ -#define STL_BYTEVAL 'b' /* byte value of character */ -#define STL_BYTEVAL_X 'B' /* - in hexadecimal */ -#define STL_ROFLAG 'r' /* readonly flag */ -#define STL_ROFLAG_ALT 'R' /* - other display */ -#define STL_HELPFLAG 'h' /* window is showing a help file */ -#define STL_HELPFLAG_ALT 'H' /* - other display */ -#define STL_FILETYPE 'y' /* 'filetype' */ -#define STL_FILETYPE_ALT 'Y' /* - other display */ -#define STL_PREVIEWFLAG 'w' /* window is showing the preview buf */ -#define STL_PREVIEWFLAG_ALT 'W' /* - other display */ -#define STL_MODIFIED 'm' /* modified flag */ -#define STL_MODIFIED_ALT 'M' /* - other display */ -#define STL_QUICKFIX 'q' /* quickfix window description */ -#define STL_PERCENTAGE 'p' /* percentage through file */ -#define STL_ALTPERCENT 'P' /* percentage as TOP BOT ALL or NN% */ -#define STL_ARGLISTSTAT 'a' /* argument list status as (x of y) */ -#define STL_PAGENUM 'N' /* page number (when printing)*/ -#define STL_VIM_EXPR '{' /* start of expression to substitute */ -#define STL_MIDDLEMARK '=' /* separation between left and right */ -#define STL_TRUNCMARK '<' /* truncation mark if line is too long*/ -#define STL_USER_HL '*' /* highlight from (User)1..9 or 0 */ -#define STL_HIGHLIGHT '#' /* highlight name */ -#define STL_TABPAGENR 'T' /* tab page label nr */ -#define STL_TABCLOSENR 'X' /* tab page close nr */ +// characters for p_go: +#define GO_TERMINAL '!' // use terminal for system commands +#define GO_ASEL 'a' // autoselect +#define GO_ASELML 'A' // autoselect modeless selection +#define GO_BOT 'b' // use bottom scrollbar +#define GO_CONDIALOG 'c' // use console dialog +#define GO_TABLINE 'e' // may show tabline +#define GO_FORG 'f' // start GUI in foreground +#define GO_GREY 'g' // use grey menu items +#define GO_HORSCROLL 'h' // flexible horizontal scrolling +#define GO_ICON 'i' // use Vim icon +#define GO_LEFT 'l' // use left scrollbar +#define GO_VLEFT 'L' // left scrollbar with vert split +#define GO_MENUS 'm' // use menu bar +#define GO_NOSYSMENU 'M' // don't source system menu +#define GO_POINTER 'p' // pointer enter/leave callbacks +#define GO_ASELPLUS 'P' // autoselectPlus +#define GO_RIGHT 'r' // use right scrollbar +#define GO_VRIGHT 'R' // right scrollbar with vert split +#define GO_TEAROFF 't' // add tear-off menu items +#define GO_TOOLBAR 'T' // add toolbar +#define GO_FOOTER 'F' // add footer +#define GO_VERTICAL 'v' // arrange dialog buttons vertically +#define GO_KEEPWINSIZE 'k' // keep GUI window size +#define GO_ALL "!aAbcefFghilmMprtTvk" // all possible flags for 'go' + +// flags for 'comments' option +#define COM_NEST 'n' // comments strings nest +#define COM_BLANK 'b' // needs blank after string +#define COM_START 's' // start of comment +#define COM_MIDDLE 'm' // middle of comment +#define COM_END 'e' // end of comment +#define COM_AUTO_END 'x' // last char of end closes comment +#define COM_FIRST 'f' // first line comment only +#define COM_LEFT 'l' // left adjusted +#define COM_RIGHT 'r' // right adjusted +#define COM_NOBACK 'O' // don't use for "O" command +#define COM_ALL "nbsmexflrO" // all flags for 'comments' option +#define COM_MAX_LEN 50 // maximum length of a part + +// flags for 'statusline' option +#define STL_FILEPATH 'f' // path of file in buffer +#define STL_FULLPATH 'F' // full path of file in buffer +#define STL_FILENAME 't' // last part (tail) of file path +#define STL_COLUMN 'c' // column og cursor +#define STL_VIRTCOL 'v' // virtual column +#define STL_VIRTCOL_ALT 'V' // - with 'if different' display +#define STL_LINE 'l' // line number of cursor +#define STL_NUMLINES 'L' // number of lines in buffer +#define STL_BUFNO 'n' // current buffer number +#define STL_KEYMAP 'k' // 'keymap' when active +#define STL_OFFSET 'o' // offset of character under cursor +#define STL_OFFSET_X 'O' // - in hexadecimal +#define STL_BYTEVAL 'b' // byte value of character +#define STL_BYTEVAL_X 'B' // - in hexadecimal +#define STL_ROFLAG 'r' // readonly flag +#define STL_ROFLAG_ALT 'R' // - other display +#define STL_HELPFLAG 'h' // window is showing a help file +#define STL_HELPFLAG_ALT 'H' // - other display +#define STL_FILETYPE 'y' // 'filetype' +#define STL_FILETYPE_ALT 'Y' // - other display +#define STL_PREVIEWFLAG 'w' // window is showing the preview buf +#define STL_PREVIEWFLAG_ALT 'W' // - other display +#define STL_MODIFIED 'm' // modified flag +#define STL_MODIFIED_ALT 'M' // - other display +#define STL_QUICKFIX 'q' // quickfix window description +#define STL_PERCENTAGE 'p' // percentage through file +#define STL_ALTPERCENT 'P' // percentage as TOP BOT ALL or NN% +#define STL_ARGLISTSTAT 'a' // argument list status as (x of y) +#define STL_PAGENUM 'N' // page number (when printing) +#define STL_VIM_EXPR '{' // start of expression to substitute +#define STL_MIDDLEMARK '=' // separation between left and right +#define STL_TRUNCMARK '<' // truncation mark if line is too long +#define STL_USER_HL '*' // highlight from (User)1..9 or 0 +#define STL_HIGHLIGHT '#' // highlight name +#define STL_TABPAGENR 'T' // tab page label nr +#define STL_TABCLOSENR 'X' // tab page close nr #define STL_ALL ((char_u *) "fFtcvVlLknoObBrRhHmYyWwMqpPaN{#") -/* flags used for parsed 'wildmode' */ +// flags used for parsed 'wildmode' #define WIM_FULL 1 #define WIM_LONGEST 2 #define WIM_LIST 4 -/* arguments for can_bs() */ -#define BS_INDENT 'i' /* "Indent" */ -#define BS_EOL 'o' /* "eOl" */ -#define BS_START 's' /* "Start" */ +// arguments for can_bs() +#define BS_INDENT 'i' // "Indent" +#define BS_EOL 'o' // "eOl" +#define BS_START 's' // "Start" #define LISPWORD_VALUE "defun,define,defmacro,set!,lambda,if,case,let,flet,let*,letrec,do,do*,define-syntax,let-syntax,letrec-syntax,destructuring-bind,defpackage,defparameter,defstruct,deftype,defvar,do-all-symbols,do-external-symbols,do-symbols,dolist,dotimes,ecase,etypecase,eval-when,labels,macrolet,multiple-value-bind,multiple-value-call,multiple-value-prog1,multiple-value-setq,prog1,progv,typecase,unless,unwind-protect,when,with-input-from-string,with-open-file,with-open-stream,with-output-to-string,with-package-iterator,define-condition,handler-bind,handler-case,restart-bind,restart-case,with-simple-restart,store-value,use-value,muffle-warning,abort,continue,with-slots,with-slots*,with-accessors,with-accessors*,defclass,defmethod,print-unreadable-object" @@ -303,24 +303,24 @@ */ #ifdef FEAT_RIGHTLEFT -EXTERN long p_aleph; /* 'aleph' */ +EXTERN long p_aleph; // 'aleph' #endif #ifdef FEAT_AUTOCHDIR -EXTERN int p_acd; /* 'autochdir' */ +EXTERN int p_acd; // 'autochdir' #endif -EXTERN char_u *p_ambw; /* 'ambiwidth' */ -EXTERN char_u *p_emoji; /* 'emoji' */ +EXTERN char_u *p_ambw; // 'ambiwidth' +EXTERN char_u *p_emoji; // 'emoji' #if defined(FEAT_GUI) && defined(MACOS_X) -EXTERN int *p_antialias; /* 'antialias' */ +EXTERN int *p_antialias; // 'antialias' #endif -EXTERN int p_ar; /* 'autoread' */ -EXTERN int p_aw; /* 'autowrite' */ -EXTERN int p_awa; /* 'autowriteall' */ -EXTERN char_u *p_bs; /* 'backspace' */ -EXTERN char_u *p_bg; /* 'background' */ -EXTERN int p_bk; /* 'backup' */ -EXTERN char_u *p_bkc; /* 'backupcopy' */ -EXTERN unsigned bkc_flags; /* flags from 'backupcopy' */ +EXTERN int p_ar; // 'autoread' +EXTERN int p_aw; // 'autowrite' +EXTERN int p_awa; // 'autowriteall' +EXTERN char_u *p_bs; // 'backspace' +EXTERN char_u *p_bg; // 'background' +EXTERN int p_bk; // 'backup' +EXTERN char_u *p_bkc; // 'backupcopy' +EXTERN unsigned bkc_flags; // flags from 'backupcopy' #ifdef IN_OPTION_C static char *(p_bkc_values[]) = {"yes", "auto", "no", "breaksymlink", "breakhardlink", NULL}; #endif @@ -329,9 +329,9 @@ # define BKC_NO 0x004 # define BKC_BREAKSYMLINK 0x008 # define BKC_BREAKHARDLINK 0x010 -EXTERN char_u *p_bdir; /* 'backupdir' */ -EXTERN char_u *p_bex; /* 'backupext' */ -EXTERN char_u *p_bo; /* 'belloff' */ +EXTERN char_u *p_bdir; // 'backupdir' +EXTERN char_u *p_bex; // 'backupext' +EXTERN char_u *p_bo; // 'belloff' EXTERN unsigned bo_flags; # ifdef IN_OPTION_C static char *(p_bo_values[]) = {"all", "backspace", "cursor", "complete", @@ -341,7 +341,7 @@ "spell", "wildmode", NULL}; # endif -/* values for the 'beepon' option */ +// values for the 'beepon' option #define BO_ALL 0x0001 #define BO_BS 0x0002 #define BO_CRSR 0x0004 @@ -363,91 +363,91 @@ #define BO_WILD 0x40000 #ifdef FEAT_WILDIGN -EXTERN char_u *p_bsk; /* 'backupskip' */ +EXTERN char_u *p_bsk; // 'backupskip' #endif #ifdef FEAT_CRYPT -EXTERN char_u *p_cm; /* 'cryptmethod' */ +EXTERN char_u *p_cm; // 'cryptmethod' #endif #ifdef FEAT_BEVAL # ifdef FEAT_BEVAL_GUI -EXTERN int p_beval; /* 'ballooneval' */ +EXTERN int p_beval; // 'ballooneval' # endif -EXTERN long p_bdlay; /* 'balloondelay' */ +EXTERN long p_bdlay; // 'balloondelay' # ifdef FEAT_EVAL EXTERN char_u *p_bexpr; # endif # ifdef FEAT_BEVAL_TERM -EXTERN int p_bevalterm; /* 'balloonevalterm' */ +EXTERN int p_bevalterm; // 'balloonevalterm' # endif #endif #ifdef FEAT_BROWSE -EXTERN char_u *p_bsdir; /* 'browsedir' */ +EXTERN char_u *p_bsdir; // 'browsedir' #endif #ifdef FEAT_LINEBREAK -EXTERN char_u *p_breakat; /* 'breakat' */ +EXTERN char_u *p_breakat; // 'breakat' #endif -EXTERN char_u *p_cmp; /* 'casemap' */ +EXTERN char_u *p_cmp; // 'casemap' EXTERN unsigned cmp_flags; #ifdef IN_OPTION_C static char *(p_cmp_values[]) = {"internal", "keepascii", NULL}; #endif #define CMP_INTERNAL 0x001 #define CMP_KEEPASCII 0x002 -EXTERN char_u *p_enc; /* 'encoding' */ -EXTERN int p_deco; /* 'delcombine' */ +EXTERN char_u *p_enc; // 'encoding' +EXTERN int p_deco; // 'delcombine' #ifdef FEAT_EVAL -EXTERN char_u *p_ccv; /* 'charconvert' */ +EXTERN char_u *p_ccv; // 'charconvert' #endif #ifdef FEAT_CMDWIN -EXTERN char_u *p_cedit; /* 'cedit' */ -EXTERN long p_cwh; /* 'cmdwinheight' */ +EXTERN char_u *p_cedit; // 'cedit' +EXTERN long p_cwh; // 'cmdwinheight' #endif #ifdef FEAT_CLIPBOARD -EXTERN char_u *p_cb; /* 'clipboard' */ +EXTERN char_u *p_cb; // 'clipboard' #endif -EXTERN long p_ch; /* 'cmdheight' */ +EXTERN long p_ch; // 'cmdheight' #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) -EXTERN int p_confirm; /* 'confirm' */ +EXTERN int p_confirm; // 'confirm' #endif -EXTERN int p_cp; /* 'compatible' */ +EXTERN int p_cp; // 'compatible' #ifdef FEAT_INS_EXPAND -EXTERN char_u *p_cot; /* 'completeopt' */ -EXTERN long p_ph; /* 'pumheight' */ -EXTERN long p_pw; /* 'pumwidth' */ +EXTERN char_u *p_cot; // 'completeopt' +EXTERN long p_ph; // 'pumheight' +EXTERN long p_pw; // 'pumwidth' #endif -EXTERN char_u *p_cpo; /* 'cpoptions' */ +EXTERN char_u *p_cpo; // 'cpoptions' #ifdef FEAT_CSCOPE -EXTERN char_u *p_csprg; /* 'cscopeprg' */ -EXTERN int p_csre; /* 'cscoperelative' */ +EXTERN char_u *p_csprg; // 'cscopeprg' +EXTERN int p_csre; // 'cscoperelative' # ifdef FEAT_QUICKFIX -EXTERN char_u *p_csqf; /* 'cscopequickfix' */ +EXTERN char_u *p_csqf; // 'cscopequickfix' # define CSQF_CMDS "sgdctefia" # define CSQF_FLAGS "+-0" # endif -EXTERN int p_cst; /* 'cscopetag' */ -EXTERN long p_csto; /* 'cscopetagorder' */ -EXTERN long p_cspc; /* 'cscopepathcomp' */ -EXTERN int p_csverbose; /* 'cscopeverbose' */ +EXTERN int p_cst; // 'cscopetag' +EXTERN long p_csto; // 'cscopetagorder' +EXTERN long p_cspc; // 'cscopepathcomp' +EXTERN int p_csverbose; // 'cscopeverbose' #endif -EXTERN char_u *p_debug; /* 'debug' */ +EXTERN char_u *p_debug; // 'debug' #ifdef FEAT_FIND_ID -EXTERN char_u *p_def; /* 'define' */ +EXTERN char_u *p_def; // 'define' EXTERN char_u *p_inc; #endif #ifdef FEAT_DIFF -EXTERN char_u *p_dip; /* 'diffopt' */ +EXTERN char_u *p_dip; // 'diffopt' # ifdef FEAT_EVAL -EXTERN char_u *p_dex; /* 'diffexpr' */ +EXTERN char_u *p_dex; // 'diffexpr' # endif #endif #ifdef FEAT_INS_EXPAND -EXTERN char_u *p_dict; /* 'dictionary' */ +EXTERN char_u *p_dict; // 'dictionary' #endif #ifdef FEAT_DIGRAPHS -EXTERN int p_dg; /* 'digraph' */ +EXTERN int p_dg; // 'digraph' #endif -EXTERN char_u *p_dir; /* 'directory' */ -EXTERN char_u *p_dy; /* 'display' */ +EXTERN char_u *p_dir; // 'directory' +EXTERN char_u *p_dy; // 'display' EXTERN unsigned dy_flags; #ifdef IN_OPTION_C static char *(p_dy_values[]) = {"lastline", "truncate", "uhex", NULL}; @@ -455,27 +455,27 @@ #define DY_LASTLINE 0x001 #define DY_TRUNCATE 0x002 #define DY_UHEX 0x004 -EXTERN int p_ed; /* 'edcompatible' */ -EXTERN char_u *p_ead; /* 'eadirection' */ -EXTERN int p_ea; /* 'equalalways' */ -EXTERN char_u *p_ep; /* 'equalprg' */ -EXTERN int p_eb; /* 'errorbells' */ +EXTERN int p_ed; // 'edcompatible' +EXTERN char_u *p_ead; // 'eadirection' +EXTERN int p_ea; // 'equalalways' +EXTERN char_u *p_ep; // 'equalprg' +EXTERN int p_eb; // 'errorbells' #ifdef FEAT_QUICKFIX -EXTERN char_u *p_ef; /* 'errorfile' */ -EXTERN char_u *p_efm; /* 'errorformat' */ -EXTERN char_u *p_gefm; /* 'grepformat' */ -EXTERN char_u *p_gp; /* 'grepprg' */ -#endif -EXTERN char_u *p_ei; /* 'eventignore' */ -EXTERN int p_ek; /* 'esckeys' */ -EXTERN int p_exrc; /* 'exrc' */ -EXTERN char_u *p_fencs; /* 'fileencodings' */ -EXTERN char_u *p_ffs; /* 'fileformats' */ -EXTERN long p_fic; /* 'fileignorecase' */ +EXTERN char_u *p_ef; // 'errorfile' +EXTERN char_u *p_efm; // 'errorformat' +EXTERN char_u *p_gefm; // 'grepformat' +EXTERN char_u *p_gp; // 'grepprg' +#endif +EXTERN char_u *p_ei; // 'eventignore' +EXTERN int p_ek; // 'esckeys' +EXTERN int p_exrc; // 'exrc' +EXTERN char_u *p_fencs; // 'fileencodings' +EXTERN char_u *p_ffs; // 'fileformats' +EXTERN long p_fic; // 'fileignorecase' #ifdef FEAT_FOLDING -EXTERN char_u *p_fcl; /* 'foldclose' */ -EXTERN long p_fdls; /* 'foldlevelstart' */ -EXTERN char_u *p_fdo; /* 'foldopen' */ +EXTERN char_u *p_fcl; // 'foldclose' +EXTERN long p_fdls; // 'foldlevelstart' +EXTERN char_u *p_fdo; // 'foldopen' EXTERN unsigned fdo_flags; # ifdef IN_OPTION_C static char *(p_fdo_values[]) = {"all", "block", "hor", "mark", "percent", @@ -494,235 +494,238 @@ # define FDO_UNDO 0x200 # define FDO_JUMP 0x400 #endif -EXTERN char_u *p_fp; /* 'formatprg' */ +EXTERN char_u *p_fp; // 'formatprg' #ifdef HAVE_FSYNC -EXTERN int p_fs; /* 'fsync' */ +EXTERN int p_fs; // 'fsync' +#endif +EXTERN int p_gd; // 'gdefault' +#ifdef FEAT_TEXT_PROP +EXTERN char_u *p_pvp; // 'previewpopup' #endif -EXTERN int p_gd; /* 'gdefault' */ #ifdef FEAT_PRINTER -EXTERN char_u *p_pdev; /* 'printdevice' */ +EXTERN char_u *p_pdev; // 'printdevice' # ifdef FEAT_POSTSCRIPT -EXTERN char_u *p_penc; /* 'printencoding' */ -EXTERN char_u *p_pexpr; /* 'printexpr' */ -EXTERN char_u *p_pmfn; /* 'printmbfont' */ -EXTERN char_u *p_pmcs; /* 'printmbcharset' */ +EXTERN char_u *p_penc; // 'printencoding' +EXTERN char_u *p_pexpr; // 'printexpr' +EXTERN char_u *p_pmfn; // 'printmbfont' +EXTERN char_u *p_pmcs; // 'printmbcharset' # endif -EXTERN char_u *p_pfn; /* 'printfont' */ -EXTERN char_u *p_popt; /* 'printoptions' */ -EXTERN char_u *p_header; /* 'printheader' */ +EXTERN char_u *p_pfn; // 'printfont' +EXTERN char_u *p_popt; // 'printoptions' +EXTERN char_u *p_header; // 'printheader' #endif -EXTERN int p_prompt; /* 'prompt' */ +EXTERN int p_prompt; // 'prompt' #ifdef FEAT_GUI -EXTERN char_u *p_guifont; /* 'guifont' */ +EXTERN char_u *p_guifont; // 'guifont' # ifdef FEAT_XFONTSET -EXTERN char_u *p_guifontset; /* 'guifontset' */ +EXTERN char_u *p_guifontset; // 'guifontset' # endif -EXTERN char_u *p_guifontwide; /* 'guifontwide' */ -EXTERN int p_guipty; /* 'guipty' */ +EXTERN char_u *p_guifontwide; // 'guifontwide' +EXTERN int p_guipty; // 'guipty' #endif #if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_X11) -EXTERN long p_ghr; /* 'guiheadroom' */ +EXTERN long p_ghr; // 'guiheadroom' #endif #ifdef CURSOR_SHAPE -EXTERN char_u *p_guicursor; /* 'guicursor' */ +EXTERN char_u *p_guicursor; // 'guicursor' #endif #ifdef FEAT_MOUSESHAPE -EXTERN char_u *p_mouseshape; /* 'mouseshape' */ +EXTERN char_u *p_mouseshape; // 'mouseshape' #endif #if defined(FEAT_GUI) -EXTERN char_u *p_go; /* 'guioptions' */ +EXTERN char_u *p_go; // 'guioptions' #endif #if defined(FEAT_GUI_TABLINE) -EXTERN char_u *p_gtl; /* 'guitablabel' */ -EXTERN char_u *p_gtt; /* 'guitabtooltip' */ +EXTERN char_u *p_gtl; // 'guitablabel' +EXTERN char_u *p_gtt; // 'guitabtooltip' #endif -EXTERN char_u *p_hf; /* 'helpfile' */ -EXTERN long p_hh; /* 'helpheight' */ +EXTERN char_u *p_hf; // 'helpfile' +EXTERN long p_hh; // 'helpheight' #ifdef FEAT_MULTI_LANG -EXTERN char_u *p_hlg; /* 'helplang' */ +EXTERN char_u *p_hlg; // 'helplang' #endif -EXTERN int p_hid; /* 'hidden' */ -EXTERN char_u *p_hl; /* 'highlight' */ -EXTERN int p_hls; /* 'hlsearch' */ -EXTERN long p_hi; /* 'history' */ +EXTERN int p_hid; // 'hidden' +EXTERN char_u *p_hl; // 'highlight' +EXTERN int p_hls; // 'hlsearch' +EXTERN long p_hi; // 'history' #ifdef FEAT_RIGHTLEFT -EXTERN int p_hkmap; /* 'hkmap' */ -EXTERN int p_hkmapp; /* 'hkmapp' */ +EXTERN int p_hkmap; // 'hkmap' +EXTERN int p_hkmapp; // 'hkmapp' # ifdef FEAT_ARABIC -EXTERN int p_arshape; /* 'arabicshape' */ +EXTERN int p_arshape; // 'arabicshape' # endif #endif #ifdef FEAT_TITLE -EXTERN int p_icon; /* 'icon' */ -EXTERN char_u *p_iconstring; /* 'iconstring' */ +EXTERN int p_icon; // 'icon' +EXTERN char_u *p_iconstring; // 'iconstring' #endif -EXTERN int p_ic; /* 'ignorecase' */ +EXTERN int p_ic; // 'ignorecase' #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) -EXTERN char_u *p_imak; /* 'imactivatekey' */ +EXTERN char_u *p_imak; // 'imactivatekey' #define IM_ON_THE_SPOT 0L #define IM_OVER_THE_SPOT 1L -EXTERN long p_imst; /* 'imstyle' */ +EXTERN long p_imst; // 'imstyle' #endif #if defined(FEAT_EVAL) -EXTERN char_u *p_imaf; /* 'imactivatefunc' */ -EXTERN char_u *p_imsf; /* 'imstatusfunc' */ +EXTERN char_u *p_imaf; // 'imactivatefunc' +EXTERN char_u *p_imsf; // 'imstatusfunc' #endif -EXTERN int p_imcmdline; /* 'imcmdline' */ -EXTERN int p_imdisable; /* 'imdisable' */ -EXTERN int p_is; /* 'incsearch' */ -EXTERN int p_im; /* 'insertmode' */ -EXTERN char_u *p_isf; /* 'isfname' */ -EXTERN char_u *p_isi; /* 'isident' */ -EXTERN char_u *p_isp; /* 'isprint' */ -EXTERN int p_js; /* 'joinspaces' */ -EXTERN char_u *p_kp; /* 'keywordprg' */ -EXTERN char_u *p_km; /* 'keymodel' */ +EXTERN int p_imcmdline; // 'imcmdline' +EXTERN int p_imdisable; // 'imdisable' +EXTERN int p_is; // 'incsearch' +EXTERN int p_im; // 'insertmode' +EXTERN char_u *p_isf; // 'isfname' +EXTERN char_u *p_isi; // 'isident' +EXTERN char_u *p_isp; // 'isprint' +EXTERN int p_js; // 'joinspaces' +EXTERN char_u *p_kp; // 'keywordprg' +EXTERN char_u *p_km; // 'keymodel' #ifdef FEAT_LANGMAP -EXTERN char_u *p_langmap; /* 'langmap'*/ -EXTERN int p_lnr; /* 'langnoremap' */ -EXTERN int p_lrm; /* 'langremap' */ +EXTERN char_u *p_langmap; // 'langmap' +EXTERN int p_lnr; // 'langnoremap' +EXTERN int p_lrm; // 'langremap' #endif #if defined(FEAT_MENU) && defined(FEAT_MULTI_LANG) -EXTERN char_u *p_lm; /* 'langmenu' */ +EXTERN char_u *p_lm; // 'langmenu' #endif #ifdef FEAT_GUI -EXTERN long p_linespace; /* 'linespace' */ +EXTERN long p_linespace; // 'linespace' #endif #ifdef FEAT_LISP -EXTERN char_u *p_lispwords; /* 'lispwords' */ +EXTERN char_u *p_lispwords; // 'lispwords' #endif -EXTERN long p_ls; /* 'laststatus' */ -EXTERN long p_stal; /* 'showtabline' */ -EXTERN char_u *p_lcs; /* 'listchars' */ +EXTERN long p_ls; // 'laststatus' +EXTERN long p_stal; // 'showtabline' +EXTERN char_u *p_lcs; // 'listchars' -EXTERN int p_lz; /* 'lazyredraw' */ -EXTERN int p_lpl; /* 'loadplugins' */ +EXTERN int p_lz; // 'lazyredraw' +EXTERN int p_lpl; // 'loadplugins' #if defined(DYNAMIC_LUA) -EXTERN char_u *p_luadll; /* 'luadll' */ +EXTERN char_u *p_luadll; // 'luadll' #endif #ifdef FEAT_GUI_MAC -EXTERN int p_macatsui; /* 'macatsui' */ +EXTERN int p_macatsui; // 'macatsui' #endif -EXTERN int p_magic; /* 'magic' */ -EXTERN char_u *p_menc; /* 'makeencoding' */ +EXTERN int p_magic; // 'magic' +EXTERN char_u *p_menc; // 'makeencoding' #ifdef FEAT_QUICKFIX -EXTERN char_u *p_mef; /* 'makeef' */ -EXTERN char_u *p_mp; /* 'makeprg' */ +EXTERN char_u *p_mef; // 'makeef' +EXTERN char_u *p_mp; // 'makeprg' #endif #ifdef FEAT_SIGNS -EXTERN char_u *p_scl; /* signcolumn */ +EXTERN char_u *p_scl; // signcolumn #endif #ifdef FEAT_SYN_HL -EXTERN char_u *p_cc; /* 'colorcolumn' */ -EXTERN int p_cc_cols[256]; /* array for 'colorcolumn' columns */ +EXTERN char_u *p_cc; // 'colorcolumn' +EXTERN int p_cc_cols[256]; // array for 'colorcolumn' columns #endif -EXTERN long p_mat; /* 'matchtime' */ -EXTERN long p_mco; /* 'maxcombine' */ +EXTERN long p_mat; // 'matchtime' +EXTERN long p_mco; // 'maxcombine' #ifdef FEAT_EVAL -EXTERN long p_mfd; /* 'maxfuncdepth' */ +EXTERN long p_mfd; // 'maxfuncdepth' #endif -EXTERN long p_mmd; /* 'maxmapdepth' */ -EXTERN long p_mm; /* 'maxmem' */ -EXTERN long p_mmp; /* 'maxmempattern' */ -EXTERN long p_mmt; /* 'maxmemtot' */ +EXTERN long p_mmd; // 'maxmapdepth' +EXTERN long p_mm; // 'maxmem' +EXTERN long p_mmp; // 'maxmempattern' +EXTERN long p_mmt; // 'maxmemtot' #ifdef FEAT_MENU -EXTERN long p_mis; /* 'menuitems' */ +EXTERN long p_mis; // 'menuitems' #endif #ifdef FEAT_SPELL -EXTERN char_u *p_msm; /* 'mkspellmem' */ +EXTERN char_u *p_msm; // 'mkspellmem' #endif -EXTERN long p_mle; /* 'modelineexpr' */ -EXTERN long p_mls; /* 'modelines' */ -EXTERN char_u *p_mouse; /* 'mouse' */ +EXTERN long p_mle; // 'modelineexpr' +EXTERN long p_mls; // 'modelines' +EXTERN char_u *p_mouse; // 'mouse' #ifdef FEAT_GUI -EXTERN int p_mousef; /* 'mousefocus' */ -EXTERN int p_mh; /* 'mousehide' */ +EXTERN int p_mousef; // 'mousefocus' +EXTERN int p_mh; // 'mousehide' #endif -EXTERN char_u *p_mousem; /* 'mousemodel' */ -EXTERN long p_mouset; /* 'mousetime' */ -EXTERN int p_more; /* 'more' */ +EXTERN char_u *p_mousem; // 'mousemodel' +EXTERN long p_mouset; // 'mousetime' +EXTERN int p_more; // 'more' #ifdef FEAT_MZSCHEME -EXTERN long p_mzq; /* 'mzquantum */ +EXTERN long p_mzq; // 'mzquantum # if defined(DYNAMIC_MZSCHEME) -EXTERN char_u *p_mzschemedll; /* 'mzschemedll' */ -EXTERN char_u *p_mzschemegcdll; /* 'mzschemegcdll' */ +EXTERN char_u *p_mzschemedll; // 'mzschemedll' +EXTERN char_u *p_mzschemegcdll; // 'mzschemegcdll' # endif #endif #if defined(MSWIN) -EXTERN int p_odev; /* 'opendevice' */ +EXTERN int p_odev; // 'opendevice' #endif -EXTERN char_u *p_opfunc; /* 'operatorfunc' */ -EXTERN char_u *p_para; /* 'paragraphs' */ -EXTERN int p_paste; /* 'paste' */ -EXTERN char_u *p_pt; /* 'pastetoggle' */ +EXTERN char_u *p_opfunc; // 'operatorfunc' +EXTERN char_u *p_para; // 'paragraphs' +EXTERN int p_paste; // 'paste' +EXTERN char_u *p_pt; // 'pastetoggle' #if defined(FEAT_EVAL) && defined(FEAT_DIFF) -EXTERN char_u *p_pex; /* 'patchexpr' */ +EXTERN char_u *p_pex; // 'patchexpr' #endif -EXTERN char_u *p_pm; /* 'patchmode' */ -EXTERN char_u *p_path; /* 'path' */ +EXTERN char_u *p_pm; // 'patchmode' +EXTERN char_u *p_path; // 'path' #ifdef FEAT_SEARCHPATH -EXTERN char_u *p_cdpath; /* 'cdpath' */ +EXTERN char_u *p_cdpath; // 'cdpath' #endif #if defined(DYNAMIC_PERL) -EXTERN char_u *p_perldll; /* 'perldll' */ +EXTERN char_u *p_perldll; // 'perldll' #endif #if defined(DYNAMIC_PYTHON3) -EXTERN char_u *p_py3dll; /* 'pythonthreedll' */ +EXTERN char_u *p_py3dll; // 'pythonthreedll' #endif #ifdef FEAT_PYTHON3 -EXTERN char_u *p_py3home; /* 'pythonthreehome' */ +EXTERN char_u *p_py3home; // 'pythonthreehome' #endif #if defined(DYNAMIC_PYTHON) -EXTERN char_u *p_pydll; /* 'pythondll' */ +EXTERN char_u *p_pydll; // 'pythondll' #endif #ifdef FEAT_PYTHON -EXTERN char_u *p_pyhome; /* 'pythonhome' */ +EXTERN char_u *p_pyhome; // 'pythonhome' #endif #if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) -EXTERN long p_pyx; /* 'pyxversion' */ +EXTERN long p_pyx; // 'pyxversion' #endif #ifdef FEAT_RELTIME -EXTERN long p_rdt; /* 'redrawtime' */ +EXTERN long p_rdt; // 'redrawtime' #endif -EXTERN int p_remap; /* 'remap' */ -EXTERN long p_re; /* 'regexpengine' */ +EXTERN int p_remap; // 'remap' +EXTERN long p_re; // 'regexpengine' #ifdef FEAT_RENDER_OPTIONS -EXTERN char_u *p_rop; /* 'renderoptions' */ +EXTERN char_u *p_rop; // 'renderoptions' #endif -EXTERN long p_report; /* 'report' */ +EXTERN long p_report; // 'report' #if defined(FEAT_QUICKFIX) -EXTERN long p_pvh; /* 'previewheight' */ +EXTERN long p_pvh; // 'previewheight' #endif #ifdef MSWIN -EXTERN int p_rs; /* 'restorescreen' */ +EXTERN int p_rs; // 'restorescreen' #endif #ifdef FEAT_RIGHTLEFT -EXTERN int p_ari; /* 'allowrevins' */ -EXTERN int p_ri; /* 'revins' */ +EXTERN int p_ari; // 'allowrevins' +EXTERN int p_ri; // 'revins' #endif #if defined(DYNAMIC_RUBY) -EXTERN char_u *p_rubydll; /* 'rubydll' */ +EXTERN char_u *p_rubydll; // 'rubydll' #endif #ifdef FEAT_CMDL_INFO -EXTERN int p_ru; /* 'ruler' */ +EXTERN int p_ru; // 'ruler' #endif #ifdef FEAT_STL_OPT -EXTERN char_u *p_ruf; /* 'rulerformat' */ +EXTERN char_u *p_ruf; // 'rulerformat' #endif -EXTERN char_u *p_pp; /* 'packpath' */ -EXTERN char_u *p_rtp; /* 'runtimepath' */ -EXTERN long p_sj; /* 'scrolljump' */ -EXTERN long p_so; /* 'scrolloff' */ -EXTERN char_u *p_sbo; /* 'scrollopt' */ -EXTERN char_u *p_sections; /* 'sections' */ -EXTERN int p_secure; /* 'secure' */ -EXTERN char_u *p_sel; /* 'selection' */ -EXTERN char_u *p_slm; /* 'selectmode' */ +EXTERN char_u *p_pp; // 'packpath' +EXTERN char_u *p_rtp; // 'runtimepath' +EXTERN long p_sj; // 'scrolljump' +EXTERN long p_so; // 'scrolloff' +EXTERN char_u *p_sbo; // 'scrollopt' +EXTERN char_u *p_sections; // 'sections' +EXTERN int p_secure; // 'secure' +EXTERN char_u *p_sel; // 'selection' +EXTERN char_u *p_slm; // 'selectmode' #ifdef FEAT_SESSION -EXTERN char_u *p_ssop; /* 'sessionoptions' */ +EXTERN char_u *p_ssop; // 'sessionoptions' EXTERN unsigned ssop_flags; # ifdef IN_OPTION_C -/* Also used for 'viewoptions'! */ +// Also used for 'viewoptions'! static char *(p_ssop_values[]) = {"buffers", "winpos", "resize", "winsize", "localoptions", "options", "help", "blank", "globals", "slash", "unix", "sesdir", "curdir", "folds", "cursor", "tabpages", "terminal", NULL}; @@ -745,53 +748,53 @@ # define SSOP_TABPAGES 0x8000 # define SSOP_TERMINAL 0x10000 #endif -EXTERN char_u *p_sh; /* 'shell' */ -EXTERN char_u *p_shcf; /* 'shellcmdflag' */ +EXTERN char_u *p_sh; // 'shell' +EXTERN char_u *p_shcf; // 'shellcmdflag' #ifdef FEAT_QUICKFIX -EXTERN char_u *p_sp; /* 'shellpipe' */ +EXTERN char_u *p_sp; // 'shellpipe' #endif -EXTERN char_u *p_shq; /* 'shellquote' */ -EXTERN char_u *p_sxq; /* 'shellxquote' */ -EXTERN char_u *p_sxe; /* 'shellxescape' */ -EXTERN char_u *p_srr; /* 'shellredir' */ +EXTERN char_u *p_shq; // 'shellquote' +EXTERN char_u *p_sxq; // 'shellxquote' +EXTERN char_u *p_sxe; // 'shellxescape' +EXTERN char_u *p_srr; // 'shellredir' #ifdef AMIGA -EXTERN long p_st; /* 'shelltype' */ +EXTERN long p_st; // 'shelltype' #endif -EXTERN int p_stmp; /* 'shelltemp' */ +EXTERN int p_stmp; // 'shelltemp' #ifdef BACKSLASH_IN_FILENAME -EXTERN int p_ssl; /* 'shellslash' */ +EXTERN int p_ssl; // 'shellslash' #endif #ifdef FEAT_STL_OPT -EXTERN char_u *p_stl; /* 'statusline' */ +EXTERN char_u *p_stl; // 'statusline' #endif -EXTERN int p_sr; /* 'shiftround' */ -EXTERN char_u *p_shm; /* 'shortmess' */ +EXTERN int p_sr; // 'shiftround' +EXTERN char_u *p_shm; // 'shortmess' #ifdef FEAT_LINEBREAK -EXTERN char_u *p_sbr; /* 'showbreak' */ +EXTERN char_u *p_sbr; // 'showbreak' #endif #ifdef FEAT_CMDL_INFO -EXTERN int p_sc; /* 'showcmd' */ +EXTERN int p_sc; // 'showcmd' #endif -EXTERN int p_sft; /* 'showfulltag' */ -EXTERN int p_sm; /* 'showmatch' */ -EXTERN int p_smd; /* 'showmode' */ -EXTERN long p_ss; /* 'sidescroll' */ -EXTERN long p_siso; /* 'sidescrolloff' */ -EXTERN int p_scs; /* 'smartcase' */ -EXTERN int p_sta; /* 'smarttab' */ -EXTERN int p_sb; /* 'splitbelow' */ -EXTERN long p_tpm; /* 'tabpagemax' */ +EXTERN int p_sft; // 'showfulltag' +EXTERN int p_sm; // 'showmatch' +EXTERN int p_smd; // 'showmode' +EXTERN long p_ss; // 'sidescroll' +EXTERN long p_siso; // 'sidescrolloff' +EXTERN int p_scs; // 'smartcase' +EXTERN int p_sta; // 'smarttab' +EXTERN int p_sb; // 'splitbelow' +EXTERN long p_tpm; // 'tabpagemax' # if defined(FEAT_STL_OPT) -EXTERN char_u *p_tal; /* 'tabline' */ +EXTERN char_u *p_tal; // 'tabline' # endif #ifdef FEAT_SPELL -EXTERN char_u *p_sps; /* 'spellsuggest' */ +EXTERN char_u *p_sps; // 'spellsuggest' #endif -EXTERN int p_spr; /* 'splitright' */ -EXTERN int p_sol; /* 'startofline' */ -EXTERN char_u *p_su; /* 'suffixes' */ -EXTERN char_u *p_sws; /* 'swapsync' */ -EXTERN char_u *p_swb; /* 'switchbuf' */ +EXTERN int p_spr; // 'splitright' +EXTERN int p_sol; // 'startofline' +EXTERN char_u *p_su; // 'suffixes' +EXTERN char_u *p_sws; // 'swapsync' +EXTERN char_u *p_swb; // 'switchbuf' EXTERN unsigned swb_flags; #ifdef IN_OPTION_C static char *(p_swb_values[]) = {"useopen", "usetab", "split", "newtab", "vsplit", NULL}; @@ -801,9 +804,9 @@ #define SWB_SPLIT 0x004 #define SWB_NEWTAB 0x008 #define SWB_VSPLIT 0x010 -EXTERN int p_tbs; /* 'tagbsearch' */ -EXTERN char_u *p_tc; /* 'tagcase' */ -EXTERN unsigned tc_flags; /* flags from 'tagcase' */ +EXTERN int p_tbs; // 'tagbsearch' +EXTERN char_u *p_tc; // 'tagcase' +EXTERN unsigned tc_flags; // flags from 'tagcase' #ifdef IN_OPTION_C static char *(p_tc_values[]) = {"followic", "ignore", "match", "followscs", "smart", NULL}; #endif @@ -812,43 +815,43 @@ #define TC_MATCH 0x04 #define TC_FOLLOWSCS 0x08 #define TC_SMART 0x10 -EXTERN long p_tl; /* 'taglength' */ -EXTERN int p_tr; /* 'tagrelative' */ -EXTERN char_u *p_tags; /* 'tags' */ -EXTERN int p_tgst; /* 'tagstack' */ +EXTERN long p_tl; // 'taglength' +EXTERN int p_tr; // 'tagrelative' +EXTERN char_u *p_tags; // 'tags' +EXTERN int p_tgst; // 'tagstack' #if defined(DYNAMIC_TCL) -EXTERN char_u *p_tcldll; /* 'tcldll' */ +EXTERN char_u *p_tcldll; // 'tcldll' #endif #ifdef FEAT_ARABIC -EXTERN int p_tbidi; /* 'termbidi' */ +EXTERN int p_tbidi; // 'termbidi' #endif -EXTERN char_u *p_tenc; /* 'termencoding' */ +EXTERN char_u *p_tenc; // 'termencoding' #ifdef FEAT_TERMGUICOLORS -EXTERN int p_tgc; /* 'termguicolors' */ +EXTERN int p_tgc; // 'termguicolors' #endif #if defined(MSWIN) && defined(FEAT_TERMINAL) EXTERN char_u *p_twt; // 'termwintype' #endif -EXTERN int p_terse; /* 'terse' */ -EXTERN int p_ta; /* 'textauto' */ -EXTERN int p_to; /* 'tildeop' */ -EXTERN int p_timeout; /* 'timeout' */ -EXTERN long p_tm; /* 'timeoutlen' */ +EXTERN int p_terse; // 'terse' +EXTERN int p_ta; // 'textauto' +EXTERN int p_to; // 'tildeop' +EXTERN int p_timeout; // 'timeout' +EXTERN long p_tm; // 'timeoutlen' #ifdef FEAT_TITLE -EXTERN int p_title; /* 'title' */ -EXTERN long p_titlelen; /* 'titlelen' */ -EXTERN char_u *p_titleold; /* 'titleold' */ -EXTERN char_u *p_titlestring; /* 'titlestring' */ +EXTERN int p_title; // 'title' +EXTERN long p_titlelen; // 'titlelen' +EXTERN char_u *p_titleold; // 'titleold' +EXTERN char_u *p_titlestring; // 'titlestring' #endif #ifdef FEAT_INS_EXPAND -EXTERN char_u *p_tsr; /* 'thesaurus' */ +EXTERN char_u *p_tsr; // 'thesaurus' #endif -EXTERN int p_ttimeout; /* 'ttimeout' */ -EXTERN long p_ttm; /* 'ttimeoutlen' */ -EXTERN int p_tbi; /* 'ttybuiltin' */ -EXTERN int p_tf; /* 'ttyfast' */ +EXTERN int p_ttimeout; // 'ttimeout' +EXTERN long p_ttm; // 'ttimeoutlen' +EXTERN int p_tbi; // 'ttybuiltin' +EXTERN int p_tf; // 'ttyfast' #if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_MSWIN) -EXTERN char_u *p_toolbar; /* 'toolbar' */ +EXTERN char_u *p_toolbar; // 'toolbar' EXTERN unsigned toolbar_flags; # ifdef IN_OPTION_C static char *(p_toolbar_values[]) = {"text", "icons", "tooltips", "horiz", NULL}; @@ -859,7 +862,7 @@ # define TOOLBAR_HORIZ 0x08 #endif #if defined(FEAT_TOOLBAR) && defined(FEAT_GUI_GTK) -EXTERN char_u *p_tbis; /* 'toolbariconsize' */ +EXTERN char_u *p_tbis; // 'toolbariconsize' EXTERN unsigned tbis_flags; # ifdef IN_OPTION_C static char *(p_tbis_values[]) = {"tiny", "small", "medium", "large", "huge", "giant", NULL}; @@ -871,9 +874,9 @@ # define TBIS_HUGE 0x10 # define TBIS_GIANT 0x20 #endif -EXTERN long p_ttyscroll; /* 'ttyscroll' */ +EXTERN long p_ttyscroll; // 'ttyscroll' #if defined(FEAT_MOUSE) && (defined(UNIX) || defined(VMS)) -EXTERN char_u *p_ttym; /* 'ttymouse' */ +EXTERN char_u *p_ttym; // 'ttymouse' EXTERN unsigned ttym_flags; # ifdef IN_OPTION_C static char *(p_ttym_values[]) = {"xterm", "xterm2", "dec", "netterm", "jsbterm", "pterm", "urxvt", "sgr", NULL}; @@ -887,71 +890,71 @@ # define TTYM_URXVT 0x40 # define TTYM_SGR 0x80 #endif -EXTERN char_u *p_udir; /* 'undodir' */ -EXTERN long p_ul; /* 'undolevels' */ -EXTERN long p_ur; /* 'undoreload' */ -EXTERN long p_uc; /* 'updatecount' */ -EXTERN long p_ut; /* 'updatetime' */ -EXTERN char_u *p_fcs; /* 'fillchar' */ +EXTERN char_u *p_udir; // 'undodir' +EXTERN long p_ul; // 'undolevels' +EXTERN long p_ur; // 'undoreload' +EXTERN long p_uc; // 'updatecount' +EXTERN long p_ut; // 'updatetime' +EXTERN char_u *p_fcs; // 'fillchar' #ifdef FEAT_VIMINFO -EXTERN char_u *p_viminfo; /* 'viminfo' */ -EXTERN char_u *p_viminfofile; /* 'viminfofile' */ +EXTERN char_u *p_viminfo; // 'viminfo' +EXTERN char_u *p_viminfofile; // 'viminfofile' #endif #ifdef FEAT_SESSION -EXTERN char_u *p_vdir; /* 'viewdir' */ -EXTERN char_u *p_vop; /* 'viewoptions' */ -EXTERN unsigned vop_flags; /* uses SSOP_ flags */ +EXTERN char_u *p_vdir; // 'viewdir' +EXTERN char_u *p_vop; // 'viewoptions' +EXTERN unsigned vop_flags; // uses SSOP_ flags #endif -EXTERN int p_vb; /* 'visualbell' */ -EXTERN char_u *p_ve; /* 'virtualedit' */ +EXTERN int p_vb; // 'visualbell' +EXTERN char_u *p_ve; // 'virtualedit' EXTERN unsigned ve_flags; #ifdef IN_OPTION_C static char *(p_ve_values[]) = {"block", "insert", "all", "onemore", NULL}; #endif -#define VE_BLOCK 5 /* includes "all" */ -#define VE_INSERT 6 /* includes "all" */ +#define VE_BLOCK 5 // includes "all" +#define VE_INSERT 6 // includes "all" #define VE_ALL 4 #define VE_ONEMORE 8 -EXTERN long p_verbose; /* 'verbose' */ +EXTERN long p_verbose; // 'verbose' #ifdef IN_OPTION_C -char_u *p_vfile = (char_u *)""; /* used before options are initialized */ +char_u *p_vfile = (char_u *)""; // used before options are initialized #else -extern char_u *p_vfile; /* 'verbosefile' */ +extern char_u *p_vfile; // 'verbosefile' #endif -EXTERN int p_warn; /* 'warn' */ +EXTERN int p_warn; // 'warn' #ifdef FEAT_CMDL_COMPL -EXTERN char_u *p_wop; /* 'wildoptions' */ +EXTERN char_u *p_wop; // 'wildoptions' #endif -EXTERN long p_window; /* 'window' */ +EXTERN long p_window; // 'window' #if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) || defined(LINT) \ || defined (FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON) #define FEAT_WAK -EXTERN char_u *p_wak; /* 'winaltkeys' */ +EXTERN char_u *p_wak; // 'winaltkeys' #endif #ifdef FEAT_WILDIGN -EXTERN char_u *p_wig; /* 'wildignore' */ +EXTERN char_u *p_wig; // 'wildignore' #endif -EXTERN int p_wiv; /* 'weirdinvert' */ -EXTERN char_u *p_ww; /* 'whichwrap' */ -EXTERN long p_wc; /* 'wildchar' */ -EXTERN long p_wcm; /* 'wildcharm' */ -EXTERN long p_wic; /* 'wildignorecase' */ -EXTERN char_u *p_wim; /* 'wildmode' */ +EXTERN int p_wiv; // 'weirdinvert' +EXTERN char_u *p_ww; // 'whichwrap' +EXTERN long p_wc; // 'wildchar' +EXTERN long p_wcm; // 'wildcharm' +EXTERN long p_wic; // 'wildignorecase' +EXTERN char_u *p_wim; // 'wildmode' #ifdef FEAT_WILDMENU -EXTERN int p_wmnu; /* 'wildmenu' */ +EXTERN int p_wmnu; // 'wildmenu' #endif -EXTERN long p_wh; /* 'winheight' */ -EXTERN long p_wmh; /* 'winminheight' */ -EXTERN long p_wmw; /* 'winminwidth' */ -EXTERN long p_wiw; /* 'winwidth' */ +EXTERN long p_wh; // 'winheight' +EXTERN long p_wmh; // 'winminheight' +EXTERN long p_wmw; // 'winminwidth' +EXTERN long p_wiw; // 'winwidth' #if defined(MSWIN) && defined(FEAT_TERMINAL) -EXTERN char_u *p_winptydll; /* 'winptydll' */ +EXTERN char_u *p_winptydll; // 'winptydll' #endif -EXTERN int p_ws; /* 'wrapscan' */ -EXTERN int p_write; /* 'write' */ -EXTERN int p_wa; /* 'writeany' */ -EXTERN int p_wb; /* 'writebackup' */ -EXTERN long p_wd; /* 'writedelay' */ +EXTERN int p_ws; // 'wrapscan' +EXTERN int p_write; // 'write' +EXTERN int p_wa; // 'writeany' +EXTERN int p_wb; // 'writebackup' +EXTERN long p_wd; // 'writedelay' /* * "indir" values for buffer-local opions. @@ -1089,7 +1092,7 @@ , BV_VSTS , BV_VTS #endif - , BV_COUNT /* must be the last one */ + , BV_COUNT // must be the last one }; /* @@ -1170,8 +1173,8 @@ #ifdef FEAT_SIGNS , WV_SCL #endif - , WV_COUNT /* must be the last one */ + , WV_COUNT // must be the last one }; -/* Value for b_p_ul indicating the global value must be used. */ +// Value for b_p_ul indicating the global value must be used. #define NO_LOCAL_UNDOLEVEL -123456 diff -Nru vim-8.1.1681/src/os_win32.c vim-8.1.1729/src/os_win32.c --- vim-8.1.1681/src/os_win32.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/os_win32.c 2019-07-21 21:04:21.000000000 +0000 @@ -3738,6 +3738,7 @@ CONSOLE_SCREEN_BUFFER_INFO csbi; /* hold current console buffer info */ SMALL_RECT srWindowRect; /* hold the new console size */ COORD coordScreen; + COORD cursor; static int resized = FALSE; #ifdef MCH_WRITE_DUMP @@ -3792,6 +3793,11 @@ } else { + // Workaround for a Windows 10 bug + cursor.X = srWindowRect.Left; + cursor.Y = srWindowRect.Top; + SetConsoleCursorPosition(hConsole, cursor); + ResizeConBuf(hConsole, coordScreen); ResizeWindow(hConsole, srWindowRect); resized = TRUE; diff -Nru vim-8.1.1681/src/po/sr.po vim-8.1.1729/src/po/sr.po --- vim-8.1.1681/src/po/sr.po 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/po/sr.po 2019-07-21 21:04:21.000000000 +0000 @@ -121,7 +121,7 @@ msgid "W14: Warning: List of file names overflow" msgstr "" -"W14: Упозорење: Прекорачена је максимална величина листе имена датотека" +"W14: Упозорење: Прекорачена је максимална величина листе имена фајлова" #, c-format msgid "E92: Buffer %ld not found" @@ -149,7 +149,7 @@ msgstr "[Није уређивано]" msgid "[New file]" -msgstr "[Нова датотека]" +msgstr "[Нов фајл]" msgid "[Read errors]" msgstr "[Грешке при читању]" @@ -263,7 +263,7 @@ msgstr "E906: није отворен канал" msgid "E920: _io file requires _name to be set" -msgstr "E920: _io датотека захтева да _name буде постављено" +msgstr "E920: _io фајл захтева да _name буде постављено" msgid "E915: in_io buffer requires in_buf or in_name to be set" msgstr "E915: in_io бафер захтева да in_buf или in_name буде постављено" @@ -273,7 +273,7 @@ msgstr "E918: бафер мора бити учитан: %s" msgid "E821: File is encrypted with unknown method" -msgstr "E821: Датотека је шифрована непознатом методом" +msgstr "E821: Фајл је шифрован непознатом методом" msgid "Warning: Using a weak encryption method; see :help 'cm'" msgstr "Упозорење: Користи се слаба метода шифрирања; погледајте :help 'cm'" @@ -318,13 +318,13 @@ msgstr "E96: Не може да се упоређује више од %ld бафера" msgid "E810: Cannot read or write temp files" -msgstr "E810: Није могуће читање или упис у привремене датотеке" +msgstr "E810: Није могуће читање или упис у привремене фајлове" msgid "E97: Cannot create diffs" msgstr "E97: Није могуће креирање diff-ова" msgid "Patch file" -msgstr "Patch датотека" +msgstr "Patch фајл" msgid "E816: Cannot read patch output" msgstr "E816: Није могуће читање patch излаза" @@ -359,10 +359,10 @@ msgstr "E104: Escape није дозвољен у digraph" msgid "E544: Keymap file not found" -msgstr "E544: Keymap датотека није пронађена" +msgstr "E544: Keymap фајл није пронађен" msgid "E105: Using :loadkeymap not in a sourced file" -msgstr "E105: Коришћење :loadkeymap ван датотеке која се учитава као скрипта" +msgstr "E105: Коришћење :loadkeymap ван фајла који се учитава као скрипта" msgid "E791: Empty keymap entry" msgstr "E791: Празна keymap ставка" @@ -377,7 +377,7 @@ msgstr " Довршавање целе линије (^L^N^P)" msgid " File name completion (^F^N^P)" -msgstr " Довршавање имена датотеке (^F^N^P)" +msgstr " Довршавање имена фајла (^F^N^P)" msgid " Tag completion (^]^N^P)" msgstr " Довршавање ознаке (^]^N^P)" @@ -410,7 +410,7 @@ msgstr " Довршавање локалне кључне речи (^N^P)" msgid "Hit end of paragraph" -msgstr "Достигнут крај пасуса" +msgstr "Достигнут је крај пасуса" msgid "E839: Completion function changed window" msgstr "E839: Функција довршавања је променила прозор" @@ -442,7 +442,7 @@ msgstr "Скенирање ознака." msgid "match in file" -msgstr "подударање у датотеци" +msgstr "подударање у фајлу" msgid " Adding" msgstr " Додавање" @@ -805,7 +805,7 @@ msgstr "E935: неисправан број подпоклапања: %d" msgid "E677: Error writing temp file" -msgstr "E677: Грешка при упису temp датотеке" +msgstr "E677: Грешка при упису temp фајла" msgid "E921: Invalid callback argument" msgstr "E921: Неисправан callback аргумент" @@ -859,11 +859,11 @@ msgstr "%sviminfo: %s у линији: " msgid "E136: viminfo: Too many errors, skipping rest of file" -msgstr "E136: viminfo: Превише грешака, остатак датотеке се прескаче" +msgstr "E136: viminfo: Превише грешака, остатак фајла се прескаче" #, c-format msgid "Reading viminfo file \"%s\"%s%s%s" -msgstr "Читање viminfo датотеке \"%s\"%s%s%s" +msgstr "Читање viminfo фајла \"%s\"%s%s%s" msgid " info" msgstr " инфо" @@ -872,44 +872,44 @@ msgstr " маркера" msgid " oldfiles" -msgstr " старихдатотека" +msgstr " старихфајлова" msgid " FAILED" msgstr " НЕУСПЕЛО" #, c-format msgid "E137: Viminfo file is not writable: %s" -msgstr "E137: Viminfo датотека није уписива: %s" +msgstr "E137: Viminfo фајл није уписив: %s" #, c-format msgid "E929: Too many viminfo temp files, like %s!" -msgstr "E929: Превише viminfo temp датотека, као %s!" +msgstr "E929: Превише viminfo temp фајлова, као %s!" #, c-format msgid "E138: Can't write viminfo file %s!" -msgstr "E138: Viminfo датотека %s не може да се упише!" +msgstr "E138: Viminfo фајл %s не може да се упише!" #, c-format msgid "Writing viminfo file \"%s\"" -msgstr "Уписивање viminfo датотеке \"%s\"" +msgstr "Уписивање viminfo фајла \"%s\"" #, c-format msgid "E886: Can't rename viminfo file to %s!" -msgstr "E886: Viminfo датотека не може да се преименује у %s!" +msgstr "E886: Viminfo фајл не може да се преименује у %s!" #, c-format msgid "# This viminfo file was generated by Vim %s.\n" -msgstr "# Ову viminfo датотеку је генерисао Vim %s.\n" +msgstr "# Овај viminfo фајл је генерисао Vim %s.\n" msgid "" "# You may edit it if you're careful!\n" "\n" msgstr "" -"# Можете да је уређујете ако сте опрезни!\n" +"# Можете да га уређујете ако сте опрезни!\n" "\n" msgid "# Value of 'encoding' when this file was written\n" -msgstr "# Вредност опције 'encoding' када је ова датотека написана\n" +msgstr "# Вредност опције 'encoding' када је овај фајл записан\n" msgid "Illegal starting char" msgstr "Неисправан почетни карактер" @@ -925,29 +925,29 @@ msgstr "Сачувај као" msgid "Write partial file?" -msgstr "Да упишем парцијалну датотеку?" +msgstr "Да упишем парцијални фајл?" msgid "E140: Use ! to write partial buffer" msgstr "E140: Користите ! да бисте уписали парцијални бафер" #, c-format msgid "Overwrite existing file \"%s\"?" -msgstr "Да препишем постојећи датотеку \"%s\"?" +msgstr "Да препишем постојећи фајл \"%s\"?" #, c-format msgid "Swap file \"%s\" exists, overwrite anyway?" -msgstr "Swap датотека \"%s\" постоји, да је препишем у сваком случају?" +msgstr "Swap фајл \"%s\" постоји, да га препишем у сваком случају?" #, c-format msgid "E768: Swap file exists: %s (:silent! overrides)" -msgstr "E768: Swap датотека постоји: %s (:silent! премошћава)" +msgstr "E768: Swap фајл постоји: %s (:silent! премошћава)" #, c-format msgid "E141: No file name for buffer %ld" -msgstr "E141: Нема имена датотеке за бафер %ld" +msgstr "E141: Нема имена фајла за бафер %ld" msgid "E142: File not written: Writing is disabled by 'write' option" -msgstr "E142: Датотека није уписана: Уписивање је онемогућено опцијом 'write'" +msgstr "E142: Фајл није уписан: Уписивање је онемогућено опцијом 'write'" #, c-format msgid "" @@ -963,7 +963,7 @@ "It may still be possible to write it.\n" "Do you wish to try?" msgstr "" -"Дозволе датотеке \"%s\" омогућавају само читање.\n" +"Дозволе за фајл \"%s\" омогућавају само читање.\n" "Можда је ипак могуће да се упише.\n" "Да ли желите да покушате?" @@ -972,7 +972,7 @@ msgstr "E505: \"%s\" је само за читање (додајте ! за премошћавање)" msgid "Edit File" -msgstr "Уреди датотеку" +msgstr "Уреди фајл" #, c-format msgid "E143: Autocommands unexpectedly deleted new buffer %s" @@ -1023,7 +1023,7 @@ #, c-format msgid "Pattern found in every line: %s" -msgstr "Шаблон је пронаћен у свакој линији: %s" +msgstr "Шаблон је пронађен у свакој линији: %s" #, c-format msgid "Pattern not found: %s" @@ -1051,7 +1051,7 @@ #, c-format msgid "Sorry, help file \"%s\" not found" -msgstr "Жао нам је, датотека помоћи \"%s\" није пронађена" +msgstr "Жао нам је, фајл помоћи \"%s\" није пронађен" #, c-format msgid "E151: No match: %s" @@ -1071,7 +1071,7 @@ #, c-format msgid "E154: Duplicate tag \"%s\" in file %s/%s" -msgstr "E154: Дуплирана ознака \"%s\" у датотеци %s/%s" +msgstr "E154: Дуплирана ознака \"%s\" у фајлу %s/%s" #, c-format msgid "E150: Not a directory: %s" @@ -1103,7 +1103,7 @@ msgstr "E158: Неисправно име бафера: %s" msgid "E934: Cannot jump to a buffer that does not have a name" -msgstr "E934: Не може да се скочи на бафер који нема име`" +msgstr "E934: Не може да се скочи на бафер који нема име" #, c-format msgid "E157: Invalid sign ID: %ld" @@ -1123,7 +1123,7 @@ msgstr "[Обрисано]" msgid "No old files" -msgstr "Нема старих датотека" +msgstr "Нема старих фајлова" msgid "Entering Debug mode. Type \"cont\" to continue." msgstr "Улазак у Debug режим. Откуцајте \"cont\" за наставак." @@ -1134,7 +1134,7 @@ #, c-format msgid "Newval = \"%s\"" -msgstr "Новаавред = \"%s\"" +msgstr "Новавред = \"%s\"" #, c-format msgid "line %ld: %s" @@ -1189,13 +1189,13 @@ msgstr "Упозорење: Неочекивано се прешло у други бафер (проверите аутокоманде)" msgid "E163: There is only one file to edit" -msgstr "E163: Постоји само једна датотека за уређивање" +msgstr "E163: Постоји само један фајл за уређивање" msgid "E164: Cannot go before first file" -msgstr "E164: Не може да се иде испред прве датотеке" +msgstr "E164: Не може да се иде испред првог фајла" msgid "E165: Cannot go beyond last file" -msgstr "E165: Не може да се иде испред прве датотеке" +msgstr "E165: Не може да се иде иза последњег фајла" #, c-format msgid "E666: compiler not supported: %s" @@ -1216,12 +1216,12 @@ #, c-format msgid "W20: Required python version 2.x not supported, ignoring file: %s" msgstr "" -"W20: Захтевани python version 2.x није подржан, датотека: %s се игнорише" +"W20: Захтевани python верзије 2.x није подржан, фајл: %s се игнорише" #, c-format msgid "W21: Required python version 3.x not supported, ignoring file: %s" msgstr "" -"W21: Захтевани python version 3.x није подржан, датотека: %s се игнорише" +"W21: Захтевани python верзије 3.x није подржан, фајл: %s се игнорише" msgid "Source Vim script" msgstr "Изворна Vim скрипта" @@ -1232,11 +1232,11 @@ #, c-format msgid "could not source \"%s\"" -msgstr "не може бити извор \"%s\"" +msgstr "не може да се прибави \"%s\"" #, c-format msgid "line %ld: could not source \"%s\"" -msgstr "линија %ld: не може бити извор \"%s\"" +msgstr "линија %ld: не може да се прибави \"%s\"" #, c-format msgid "sourcing \"%s\"" @@ -1273,10 +1273,10 @@ msgstr "W15: Упозорење: Погрешан сепаратор линије, можда недостаје ^M" msgid "E167: :scriptencoding used outside of a sourced file" -msgstr "E167: :scriptencoding се користи ван изворишне датотеке" +msgstr "E167: :scriptencoding се користи ван изворишног фајла" msgid "E168: :finish used outside of a sourced file" -msgstr "E168: :finish се користи ван изворишне датотеке" +msgstr "E168: :finish се користи ван изворишног фајла" #, c-format msgid "Current %slanguage: \"%s\"" @@ -1291,7 +1291,7 @@ "Улазак у Ex режим. Откуцајте \"visual\" да бисте прешли у Нормални режим." msgid "E501: At end-of-file" -msgstr "E501: На крају-датотеке" +msgstr "E501: На крају-фајла" msgid "E169: Command too recursive" msgstr "E169: Команда је сувише рекурзивна" @@ -1301,7 +1301,7 @@ msgstr "E605: Изузетак није ухваћен: %s" msgid "End of sourced file" -msgstr "Крај изворишне датотеке" +msgstr "Крај изворишног фајла" msgid "End of function" msgstr "Крај функције" @@ -1328,18 +1328,18 @@ msgstr "E319: Жао нам је, та команда није доступна у овој верзији" msgid "1 more file to edit. Quit anyway?" -msgstr "Још 1 датотека за уређивање. Ипак желите да напустите програм?" +msgstr "Још 1 фајл за уређивање. Ипак желите да напустите програм?" #, c-format msgid "%d more files to edit. Quit anyway?" -msgstr "Још %d датотека за уређивање. Ипак желите да напустите програм?" +msgstr "Још %d фајлова за уређивање. Ипак желите да напустите програм?" msgid "E173: 1 more file to edit" -msgstr "E173: Још 1 датотека за уређивање" +msgstr "E173: Још 1 фајл за уређивање" #, c-format msgid "E173: %ld more files to edit" -msgstr "E173: Још %ld датотека за уређивање" +msgstr "E173: Још %ld фајлова за уређивање" msgid "E174: Command already exists: add ! to replace it" msgstr "E174: Команда већ постоји: додајте ! да је замените" @@ -1421,17 +1421,17 @@ msgstr "Већ сте на само једној картици" msgid "Edit File in new window" -msgstr "Уређивање Датотеке у новом прозору" +msgstr "Уређивање Фајла у новом прозору" #, c-format msgid "Tab page %d" msgstr "Картица %d" msgid "No swap file" -msgstr "Нема swap датотеке" +msgstr "Нема swap фајла" msgid "Append File" -msgstr "Додавање на крај Датотеке" +msgstr "Додавање на крај Фајла" msgid "E747: Cannot change directory, buffer is modified (add ! to override)" msgstr "" @@ -1497,7 +1497,7 @@ msgstr "E194: Нема алтернативног имена које би заменило '#'" msgid "E495: no autocommand file name to substitute for \"\"" -msgstr "E495: нема имена датотеке за аутокоманде које би заменило \"\"" +msgstr "E495: нема имена фајла за аутокоманде које би заменило \"\"" msgid "E496: no autocommand buffer number to substitute for \"\"" msgstr "E496: нема броја бафера за аутокоманду који би заменио \"\"" @@ -1506,20 +1506,20 @@ msgstr "E497: нема имена подударања аутокоманде које би заменило \"\"" msgid "E498: no :source file name to substitute for \"\"" -msgstr "E498: нема имена :source датотеке које би заменило \"\"" +msgstr "E498: нема имена :source фајла које би заменило \"\"" msgid "E842: no line number to use for \"\"" msgstr "E842: нема броја линије који би се користио за \"\"" #, no-c-format msgid "E499: Empty file name for '%' or '#', only works with \":p:h\"" -msgstr "E499: Празно име датотеке за'%' or '#', функционише само са \":p:h\"" +msgstr "E499: Празно име фајла за'%' или '#', функционише само са \":p:h\"" msgid "E500: Evaluates to an empty string" msgstr "E500: Резултат израчунавања је празан стринг" msgid "E195: Cannot open viminfo file for reading" -msgstr "E195: viminfo датотека не може да се отвори за читање" +msgstr "E195: viminfo фајл не може да се отвори за читање" msgid "Untitled" msgstr "Без наслова" @@ -1638,7 +1638,7 @@ msgstr "ознака" msgid " kind file\n" -msgstr " врста датотеке\n" +msgstr " врста фајла\n" msgid "'history' option is zero" msgstr "опција 'history' је нула" @@ -1676,31 +1676,31 @@ msgstr "E812: Аутокоманде су промениле багер или име бафера" msgid "Illegal file name" -msgstr "Недозвољено име датотеке" +msgstr "Недозвољено име фајла" msgid "is a directory" msgstr "је директоријум" msgid "is not a file" -msgstr "није датотека" +msgstr "није фајл" msgid "is a device (disabled with 'opendevice' option)" msgstr "је уређај (онемогућен опцијом 'opendevice')" msgid "[New File]" -msgstr "[Нова датотека]" +msgstr "[Нов фајл]" msgid "[New DIRECTORY]" msgstr "[Нов ДИРЕКТОРИЈУМ]" msgid "[File too big]" -msgstr "[Датотека је сувише велика]" +msgstr "[Фајл је сувише велики]" msgid "[Permission Denied]" msgstr "[Дозвола одбијена]" msgid "E200: *ReadPre autocommands made the file unreadable" -msgstr "E200: *ReadPre аутокоманде су учиниле датотеку нечитљивом" +msgstr "E200: *ReadPre аутокоманде су учиниле фајл нечитљивим" msgid "E201: *ReadPre autocommands must not change current buffer" msgstr "E201: *ReadPre аутокоманде не смеју да измене текући бафер" @@ -1712,7 +1712,7 @@ msgstr "Читање са stdin..." msgid "E202: Conversion made file unreadable!" -msgstr "E202: Конверзија је учинила датотеку нечитљивом!" +msgstr "E202: Конверзија је учинила фајл нечитљивим!" msgid "[fifo/socket]" msgstr "[fifo/утичница]" @@ -1750,7 +1750,7 @@ msgstr "[ГРЕШКЕ ПРИ ЧИТАЊУ]" msgid "Can't find temp file for conversion" -msgstr "Привремена датотека за конверзију не може да се пронађе" +msgstr "Привремени фајл за конверзију не може да се пронађе" msgid "Conversion with 'charconvert' failed" msgstr "Конверзија са 'charconvert' није успела" @@ -1776,7 +1776,7 @@ msgstr "Парцијални уписи нису дозвољени за NetBeans бафере" msgid "is not a file or writable device" -msgstr "није датотека или уређај на који може да се уписује" +msgstr "није фајл или уређај на који може да се уписује" msgid "writing to device disabled with 'opendevice' option" msgstr "упис на уређај је онемогућен опцијом 'opendevice'" @@ -1786,38 +1786,38 @@ msgid "E506: Can't write to backup file (add ! to override)" msgstr "" -"E506: Не може да се упише у резервну датотеку (додајте ! за премошћавање)" +"E506: Не може да се упише у резервни фајл (додајте ! за премошћавање)" msgid "E507: Close error for backup file (add ! to override)" msgstr "" -"E507: Грешка код затварања за резервну датотеку (додајте ! за премошћавање)" +"E507: Грешка код затварања за резервни фајл (додајте ! за премошћавање)" msgid "E508: Can't read file for backup (add ! to override)" msgstr "" -"E508: Резервна датотека не може да се прочита (додајте ! за премошћавање)" +"E508: Резервни фајл не може да се прочита (додајте ! за премошћавање)" msgid "E509: Cannot create backup file (add ! to override)" msgstr "" -"E509: Резервна датотека не може да се креира (додајте ! за премошћавање)" +"E509: Резервни фајл не може да се креира (додајте ! за премошћавање)" msgid "E510: Can't make backup file (add ! to override)" msgstr "" -"E510: Резервна датотека не може да се направи (додајте ! за премошћавање)" +"E510: Резервни фајл не може да се направи (додајте ! за премошћавање)" msgid "E214: Can't find temp file for writing" -msgstr "E214: Привремена датотека за упис не може да се пронађе" +msgstr "E214: Привремени фајл за упис не може да се пронађе" msgid "E213: Cannot convert (add ! to write without conversion)" msgstr "E213: Конверзија није могућа (додајте ! за упис без конверзије)" msgid "E166: Can't open linked file for writing" -msgstr "E166: Повезана датотека не може да се отвори за упис" +msgstr "E166: Повезани фајл не може да се отвори за упис" msgid "E212: Can't open file for writing" -msgstr "E212: Датотека не може да се отвори за упис" +msgstr "E212: фајл не може да се отвори за упис" msgid "E949: File changed while writing" -msgstr "E949: Датотека је промењена током уписа" +msgstr "E949: фајл је промењен током уписа" msgid "E512: Close failed" msgstr "E512: Затварање није успело" @@ -1836,7 +1836,7 @@ "празно да премостите)" msgid "E514: write error (file system full?)" -msgstr "E514: грешка при упису (систем датотека је пун?)" +msgstr "E514: грешка при упису (систем фајллова је пун?)" msgid " CONVERSION ERROR" msgstr " ГРЕШКА КОНВЕРЗИЈЕ" @@ -1864,23 +1864,23 @@ msgstr " уписано" msgid "E205: Patchmode: can't save original file" -msgstr "E205: Patch режим: оригинална датотека не може да се сачува" +msgstr "E205: Patch режим: оригинални фајл не може да се сачува" msgid "E206: patchmode: can't touch empty original file" -msgstr "E206: Patch режим: не може да се креира празна оригинална датотека" +msgstr "E206: Patch режим: не може да се креира празан оригинални фајл" msgid "E207: Can't delete backup file" -msgstr "E207: Резервна датотека не може да се обрише" +msgstr "E207: Резервни фајл не може да се обрише" msgid "" "\n" "WARNING: Original file may be lost or damaged\n" msgstr "" "\n" -"УПОЗОРЕЊЕ: Оригинална датотека је можда изгубљена или оштећена\n" +"УПОЗОРЕЊЕ: Оригинални фајл је можда изгубљен или оштећен\n" msgid "don't quit the editor until the file is successfully written!" -msgstr "не напуштајте едитор док се датотека успешно не упише!" +msgstr "не напуштајте едитор док се фајл успешно не упише!" msgid "[dos]" msgstr "[dos]" @@ -1921,10 +1921,10 @@ msgstr "[Последња линија није комплетна]" msgid "WARNING: The file has been changed since reading it!!!" -msgstr "УПОЗОРЕЊЕ: Ова датотека је промењена од кад је прочитана!!!" +msgstr "УПОЗОРЕЊЕ: Овај фајл је промењен од кад је прочитан!!!" msgid "Do you really want to write to it" -msgstr "Да ли заиста желите да пишете у њу" +msgstr "Да ли заиста желите да пишете у њега" #, c-format msgid "E208: Error writing to \"%s\"" @@ -1943,14 +1943,14 @@ #, c-format msgid "E211: File \"%s\" no longer available" -msgstr "E211: Датотека \"%s\" више није доступна" +msgstr "E211: Фајл \"%s\" више није доступан" #, c-format msgid "" "W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as " "well" msgstr "" -"W12: Упозорење: Датотека \"%s\" је измењена и бафер у програму Vim је такође " +"W12: Упозорење: Фајл \"%s\" је измењен и бафер у програму Vim је такође " "измењен" msgid "See \":help W12\" for more info." @@ -1959,7 +1959,7 @@ #, c-format msgid "W11: Warning: File \"%s\" has changed since editing started" msgstr "" -"W11: Упозорење: Датотека \"%s\" је измењена откад је започето уређивање" +"W11: Упозорење: Фајл \"%s\" је измењен откад је започето уређивање" msgid "See \":help W11\" for more info." msgstr "Погледајте \":help W11\" за више информација." @@ -1967,14 +1967,14 @@ #, c-format msgid "W16: Warning: Mode of file \"%s\" has changed since editing started" msgstr "" -"W16: Упозорење: Режим датотеке \"%s\" је измењен откад је започето уређивање" +"W16: Упозорење: Режим фајла \"%s\" је измењен откад је започето уређивање" msgid "See \":help W16\" for more info." msgstr "Погледајте \":help W16\" за више информација." #, c-format msgid "W13: Warning: File \"%s\" has been created after editing started" -msgstr "W13: Упозорење: Датотека \"%s\" је креирана након почетка уређивања" +msgstr "W13: Упозорење: Фајл \"%s\" је креиран након почетка уређивања" msgid "Warning" msgstr "Упозорење" @@ -1984,7 +1984,7 @@ "&Load File" msgstr "" "&OK\n" -"&Учитај датотеку" +"&Учитај фајл" #, c-format msgid "E462: Could not prepare for reloading \"%s\"" @@ -2108,20 +2108,20 @@ msgstr "E228: makemap: Недозвољен режим" msgid "E851: Failed to create a new process for the GUI" -msgstr "E851: Креирање новог процеса за GUI није успело" +msgstr "E851: Креирање новог процеса за ГКИ није успело" msgid "E852: The child process failed to start the GUI" -msgstr "E852: Процес потомак није успео да покрене GUI" +msgstr "E852: Процес потомак није успео да покрене ГКИ" msgid "E229: Cannot start the GUI" -msgstr "E229: GUI не може да се покрене" +msgstr "E229: ГКИ не може да се покрене" #, c-format msgid "E230: Cannot read from \"%s\"" msgstr "E230: Из \"%s\" не може да се чита" msgid "E665: Cannot start GUI, no valid font found" -msgstr "E665: GUI не може да се покрене, није пронађен валидан фонт" +msgstr "E665: ГКИ не може да се покрене, није пронађен валидан фонт" msgid "E231: 'guifontwide' invalid" msgstr "E231: 'guifontwide' неисправан" @@ -2199,7 +2199,7 @@ msgstr "_Методе уноса" msgid "VIM - Search and Replace..." -msgstr "VIM - Претрага and Замена..." +msgstr "VIM - Претрага и Замена..." msgid "VIM - Search..." msgstr "VIM - Претрага..." @@ -2268,7 +2268,7 @@ msgstr "&Помоћ" msgid "Files" -msgstr "Датотеке" +msgstr "Фајлови" msgid "&OK" msgstr "&ОК" @@ -2419,27 +2419,27 @@ msgstr "Штампање прекинуто" msgid "E455: Error writing to PostScript output file" -msgstr "E455: Грешка приликом уписа у PostScript излазну датотеку" +msgstr "E455: Грешка приликом уписа у PostScript излазни фајл" #, c-format msgid "E624: Can't open file \"%s\"" -msgstr "E624: Датотека \"%s\" не може да се отвори" +msgstr "E624: Фајл \"%s\" не може да се отвори" #, c-format msgid "E457: Can't read PostScript resource file \"%s\"" -msgstr "E457: PostScript resource датотека \"%s\" не може да се чита" +msgstr "E457: PostScript resource фајл \"%s\" не може да се чита" #, c-format msgid "E618: file \"%s\" is not a PostScript resource file" -msgstr "E618: датотека \"%s\" није PostScript resource датотека" +msgstr "E618: фајл \"%s\" није PostScript resource фајл" #, c-format msgid "E619: file \"%s\" is not a supported PostScript resource file" -msgstr "E619: датотека \"%s\" није подржана PostScript resource датотека" +msgstr "E619: фајл \"%s\" није подржан PostScript resource фајл" #, c-format msgid "E621: \"%s\" resource file has wrong version" -msgstr "E621: \"%s\" resource датотека је погрешне верзије" +msgstr "E621: \"%s\" resource фајл је погрешне верзије" msgid "E673: Incompatible multi-byte encoding and character set." msgstr "E673: Вишебајтно кодирање и скуп карактера нису компатибилни." @@ -2451,22 +2451,22 @@ msgstr "E675: Није наведен подразумевани фонт за вишебајтно штампање." msgid "E324: Can't open PostScript output file" -msgstr "E324: PostScript излазна датотека не може да се отвори" +msgstr "E324: PostScript излазни фајл не може да се отвори" #, c-format msgid "E456: Can't open file \"%s\"" -msgstr "E456: Датотека \"%s\" не може да се отвори" +msgstr "E456: Фајл \"%s\" не може да се отвори" msgid "E456: Can't find PostScript resource file \"prolog.ps\"" -msgstr "E456: PostScript resource датотека \"prolog.ps\" не може да се пронађе" +msgstr "E456: PostScript resource фајл \"prolog.ps\" не може да се пронађе" msgid "E456: Can't find PostScript resource file \"cidfont.ps\"" msgstr "" -"E456: PostScript resource датотека \"cidfont.ps\" не може да се пронађе" +"E456: PostScript resource фајл \"cidfont.ps\" не може да се пронађе" #, c-format msgid "E456: Can't find PostScript resource file \"%s.ps\"" -msgstr "E456: PostScript resource датотека \"%s.ps\" не може да се пронађе" +msgstr "E456: PostScript resource фајл \"%s.ps\" не може да се пронађе" #, c-format msgid "E620: Unable to convert to print encoding \"%s\"" @@ -2476,7 +2476,7 @@ msgstr "Слање штампачу..." msgid "E365: Failed to print PostScript file" -msgstr "E365: PostScript датотека није успела да се одштампа" +msgstr "E365: PostScript фајл није успео да се одштампа" msgid "Print job sent." msgstr "Задатак штампе је послат" @@ -2590,9 +2590,9 @@ " c: Пронађи функције које позивају ову функцију\n" " d: Пронађи функције које зове ова функција\n" " e: Пронађи овај egrep шаблон\n" -" f: Пронађи ову датотеку\n" +" f: Пронађи овај фајл\n" " g: Пронађи ову дефиницију\n" -" i: Пронађи датотеке које #includе ову датотеку\n" +" i: Пронађи фајлове који #includе овај фајл\n" " s: Пронађи овај C симбол\n" " t: Пронађи овај текст стринг\n" @@ -2629,7 +2629,7 @@ " # линија" msgid "filename / context / line\n" -msgstr "датотека / контекст / линија\n" +msgstr "фајл / контекст / линија\n" #, c-format msgid "E609: Cscope error: %s" @@ -2897,10 +2897,10 @@ #, c-format msgid "%d files to edit\n" -msgstr "%d датотека за уређивање\n" +msgstr "%d фајлова за уређивање\n" msgid "netbeans is not supported with this GUI\n" -msgstr "NetBeans није подржан са овим GUI\n" +msgstr "NetBeans није подржан са овим ГКИ\n" msgid "'-nb' cannot be used: not enabled at compile time\n" msgstr "'-nb' не може да се користи: није омогућено у време компилације\n" @@ -2909,7 +2909,7 @@ msgstr "Овај Vim није компајлиран са diff могућношћу." msgid "Attempt to open script file again: \"" -msgstr "Покушај да се поново отвори скрипт датотека: \"" +msgstr "Покушај да се поново отвори скрипт фајл: \"" msgid "Cannot open for reading: \"" msgstr "Не може да се отвори за читање: \"" @@ -2945,16 +2945,16 @@ "Више инфо са: \"vim -h\"\n" msgid "[file ..] edit specified file(s)" -msgstr "[датотека ..] уређуј наведену(е) датотеку(е)" +msgstr "[фајл ..] уређуј наведени(е) фајл(ове)" msgid "- read text from stdin" msgstr "- читај текст са stdin" msgid "-t tag edit file where tag is defined" -msgstr "-t tag уређуј датотеку где је дефинисана ознака" +msgstr "-t tag уређуј фајл где је дефинисана ознака" msgid "-q [errorfile] edit file with first error" -msgstr "-q [дат.грешке] уређуј датотеку са првом грешком" +msgstr "-q [фајлгрешке] уређуј фајл са првом грешком" msgid "" "\n" @@ -2993,7 +2993,7 @@ "Аргументи:\n" msgid "--\t\t\tOnly file names after this" -msgstr "--\t\t\tСамо имена датотека након овога" +msgstr "--\t\t\tСамо имена фајлова након овога" msgid "--literal\t\tDon't expand wildcards" msgstr "--literal\t\tНе развијај џокере" @@ -3005,10 +3005,10 @@ msgstr "-unregister\t\tУклони регистрацију gvim за OLE" msgid "-g\t\t\tRun using GUI (like \"gvim\")" -msgstr "-g\t\t\tПокрени користећи GUI (као \"gvim\")" +msgstr "-g\t\t\tПокрени користећи ГКИ (као \"gvim\")" msgid "-f or --nofork\tForeground: Don't fork when starting GUI" -msgstr "-f или --nofork\tУ предњем плану: немој да рачваш кад се покреће GUI" +msgstr "-f или --nofork\tУ предњем плану: немој да рачваш кад се покреће ГКИ" msgid "-v\t\t\tVi mode (like \"vi\")" msgstr "-v\t\t\tVi режим (као \"vi\")" @@ -3035,7 +3035,7 @@ msgstr "-Z\t\t\tRestricted режим (као \"rvim\")" msgid "-m\t\t\tModifications (writing files) not allowed" -msgstr "-m\t\t\tИзмене (уписивање датотека) нису дозвољене" +msgstr "-m\t\t\tИзмене (уписивање фајлова) нису дозвољене" msgid "-M\t\t\tModifications in text not allowed" msgstr "-M\t\t\tИзмене у тексту нису дозвољене" @@ -3059,13 +3059,13 @@ msgstr "-D\t\t\tDebugging режим" msgid "-n\t\t\tNo swap file, use memory only" -msgstr "-n\t\t\tБез swap датотеке, користи само меморију" +msgstr "-n\t\t\tБез swap фајла, користи само меморију" msgid "-r\t\t\tList swap files and exit" -msgstr "-r\t\t\tИзлистај swap датотеке и изађи" +msgstr "-r\t\t\tИзлистај swap фајлове и изађи" msgid "-r (with file name)\tRecover crashed session" -msgstr "-r (са именом датотеке)\tОбнови срушену сесију" +msgstr "-r (са именом фајла)\tОбнови срушену сесију" msgid "-L\t\t\tSame as -r" msgstr "-L\t\t\tИсто као -r" @@ -3104,46 +3104,44 @@ msgstr "--noplugin\t\tНе учитавај скрипте додатака" msgid "-p[N]\t\tOpen N tab pages (default: one for each file)" -msgstr "-p[N]\t\tОтвори N картица (подразумевано: по једну за сваку датотеку)" +msgstr "-p[N]\t\tОтвори N картица (подразумевано: по једну за сваки фајл)" msgid "-o[N]\t\tOpen N windows (default: one for each file)" -msgstr "-o[N]\t\tОтвори N прозора (подразумевано: по један за сваку датотеку)" +msgstr "-o[N]\t\tОтвори N прозора (подразумевано: по један за сваки фајл)" msgid "-O[N]\t\tLike -o but split vertically" msgstr "-O[N]\t\tКао -o али подели по вертикали" msgid "+\t\t\tStart at end of file" -msgstr "+\t\t\tПочни на крају датотеке" +msgstr "+\t\t\tПочни на крају фајла" msgid "+\t\tStart at line " msgstr "+<бројл>\t\tПочни на линији <бројл>" msgid "--cmd \tExecute before loading any vimrc file" msgstr "" -"--cmd <команда>\tИзврши <команда> пре учитавања било које vimrc датотеке" +"--cmd <команда>\tИзврши <команда> пре учитавања било ког vimrc фајла" msgid "-c \t\tExecute after loading the first file" -msgstr "-c <команда>\t\tИзврши <команда> након учитавања прве датотеке" +msgstr "-c <команда>\t\tИзврши <команда> након учитавања првог фајла" msgid "-S \t\tSource file after loading the first file" -msgstr "" -"-S <сесија>\t\tИзворна датотека <сесија> након учитавања прве " -"датотеке" +msgstr "-S <сесија>\t\tИзврши фајл <сесија> након учитавања првог фајла" msgid "-s \tRead Normal mode commands from file " msgstr "" -"-s <скриптулаз>\tЧитај команде Нормалног режима из датотеке <скриптулаз>" +"-s <скриптулаз>\tЧитај команде Нормалног режима из фајла <скриптулаз>" msgid "-w \tAppend all typed commands to file " msgstr "" -"-w <скриптизлаз>\tНадовежи све откуцане команде на крај датотеке " +"-w <скриптизлаз>\tНадовежи све откуцане команде на крај фајла " "<скриптизлаз>" msgid "-W \tWrite all typed commands to file " -msgstr "-W <скриптизлаз>\tУписуј све откуцане команде у датотеку <скриптизлаз>" +msgstr "-W <скриптизлаз>\tУписуј све откуцане команде у фајл <скриптизлаз>" msgid "-x\t\t\tEdit encrypted files" -msgstr "-x\t\t\tУређуј шифроване датотеке" +msgstr "-x\t\t\tУређуј шифроване фајлове" msgid "-display \tConnect vim to this particular X-server" msgstr "-display <дисплеј>\tПовежи vim на овај X-сервер" @@ -3152,25 +3150,25 @@ msgstr "-X\t\t\tНе повезуј се на X сервер" msgid "--remote \tEdit in a Vim server if possible" -msgstr "--remote <датотеке>\tУређуј <датотеке> у Vim серверу ако је могуће" +msgstr "--remote <фајлови>\tУређуј <фајлови> у Vim серверу ако је могуће" msgid "--remote-silent Same, don't complain if there is no server" -msgstr "--remote-silent <датотеке> Исто, не буни се ако нема сервера" +msgstr "--remote-silent <фајлови> Исто, не буни се ако нема сервера" msgid "" "--remote-wait As --remote but wait for files to have been edited" msgstr "" -"--remote-wait <датотеке> Као --remote али чекај да датотеке буду уређене" +"--remote-wait <фајлови> Као --remote али чекај да фајлови буду уређени" msgid "" "--remote-wait-silent Same, don't complain if there is no server" -msgstr "--remote-wait-silent <датотеке> Исто, не буни се ако нема сервера" +msgstr "--remote-wait-silent <фајлови> Исто, не буни се ако нема сервера" msgid "" "--remote-tab[-wait][-silent] As --remote but use tab page per file" msgstr "" -"--remote-tab[-wait][-silent] <датотеке> Као --remote али користи једну " -"картицу по датотеци" +"--remote-tab[-wait][-silent] <фајлови> Као --remote али користи једну " +"картицу по фајлу" msgid "--remote-send \tSend to a Vim server and exit" msgstr "--remote-send <тастери>\tПошаљи <тастери> Vim серверу и изађи" @@ -3186,7 +3184,7 @@ msgstr "--servername <име>\tПошаљи/постани Vim сервер <име>" msgid "--startuptime \tWrite startup timing messages to " -msgstr "--startuptime <датотека>\tУпиши поруке о дужини покретања у <датотеку>" +msgstr "--startuptime <фајл>\tУпиши поруке о дужини покретања у <фајл>" msgid "-i \t\tUse instead of .viminfo" msgstr "-i \t\tКористи уместо .viminfo" @@ -3326,14 +3324,14 @@ "mark line col file/text" msgstr "" "\n" -"линија маркера кол датотека/текст" +"линија маркера кол фајл/текст" msgid "" "\n" " jump line col file/text" msgstr "" "\n" -" линија скока кол датотека/текст" +" линија скока кол фајл/текст" msgid "" "\n" @@ -3347,7 +3345,7 @@ "# File marks:\n" msgstr "" "\n" -"# Маркери датотеке:\n" +"# Маркери фајла:\n" msgid "" "\n" @@ -3361,7 +3359,7 @@ "# History of marks within files (newest to oldest):\n" msgstr "" "\n" -"# Историја маркера унутар датотека (ок најновијег до најстаријег):\n" +"# Историја маркера унутар фајлова (од најновијег до најстаријег):\n" msgid "Missing '>'" msgstr "Недостаје '>'" @@ -3392,19 +3390,19 @@ msgstr "E293: блок није закључан" msgid "E294: Seek error in swap file read" -msgstr "E294: Грешка код постављања показивача за читање swap датотеке" +msgstr "E294: Грешка код постављања показивача за читање swap фајла" msgid "E295: Read error in swap file" -msgstr "E295: Грешка при читању swap датотеке" +msgstr "E295: Грешка при читању swap фајла" msgid "E296: Seek error in swap file write" -msgstr "E296: Грешка код постављања показивача за упис swap датотеке" +msgstr "E296: Грешка код постављања показивача за упис swap фајла" msgid "E297: Write error in swap file" -msgstr "E297: Грешка при упису swap датотеке" +msgstr "E297: Грешка при упису swap фајла" msgid "E300: Swap file already exists (symlink attack?)" -msgstr "E300: Swap датотека већ постоји (symlink напад?)" +msgstr "E300: Swap фајл већ постоји (symlink напад?)" msgid "E298: Didn't get block nr 0?" msgstr "E298: Блок бр 0 није добављен?" @@ -3416,28 +3414,28 @@ msgstr "E298: Блок бр 2 није добављен?" msgid "E843: Error while updating swap file crypt" -msgstr "E843: Грешка приликом осважавања криптовања swap датотеке" +msgstr "E843: Грешка приликом освежавања криптовања swap фајла" msgid "E301: Oops, lost the swap file!!!" -msgstr "E301: Уупс, swap датотека је изгубљена!!!" +msgstr "E301: Уупс, swap фајл је изгубљен!!!" msgid "E302: Could not rename swap file" -msgstr "E302: Промена имена swap датотеке није успела" +msgstr "E302: Промена имена swap фајла није успела" #, c-format msgid "E303: Unable to open swap file for \"%s\", recovery impossible" msgstr "" -"E303: Отварање swap датотеке за \"%s\" није успело, опоравак је немогућ" +"E303: Отварање swap фајла за \"%s\" није успело, опоравак је немогућ" msgid "E304: ml_upd_block0(): Didn't get block 0??" msgstr "E304: ml_upd_block0(): Блок бр 0 није добављен??" #, c-format msgid "E305: No swap file found for %s" -msgstr "E305: За %s није пронађена swap датотека" +msgstr "E305: За %s није пронађен swap фајл" msgid "Enter number of swap file to use (0 to quit): " -msgstr "Унесите број swap датотеке која ће да се користи (0 за отказивање): " +msgstr "Унесите број swap фајла који ће да се користи (0 за отказивање): " #, c-format msgid "E306: Cannot open %s" @@ -3451,7 +3449,7 @@ "Maybe no changes were made or Vim did not update the swap file." msgstr "" "\n" -"Можда нису направљене никакве измене или Vim није освежио swap датотеку." +"Можда нису направљене никакве измене или Vim није освежио swap фајл." msgid " cannot be used with this version of Vim.\n" msgstr " не може да се користи са овом верзијом Vim-а.\n" @@ -3461,20 +3459,20 @@ #, c-format msgid "E307: %s does not look like a Vim swap file" -msgstr "E307: %s не изгледа као Vim swap датотека" +msgstr "E307: %s не изгледа као Vim swap фајл" msgid " cannot be used on this computer.\n" msgstr " не може да се користи на овом компјутеру.\n" msgid "The file was created on " -msgstr "Ова датотека је креирана са " +msgstr "Овај фајл је креиран са " msgid "" ",\n" "or the file has been damaged." msgstr "" ",\n" -"или је датотека оштећена." +"или је фајл оштећен." #, c-format msgid "" @@ -3486,25 +3484,25 @@ #, c-format msgid "Using swap file \"%s\"" -msgstr "Користи се swap датотека \"%s\"" +msgstr "Користи се swap фајл \"%s\"" #, c-format msgid "Original file \"%s\"" -msgstr "Оригинална датотека \"%s\"" +msgstr "Оригинални фајл \"%s\"" msgid "E308: Warning: Original file may have been changed" -msgstr "E308: Упозорење: Можда је промењена оригинална датотека" +msgstr "E308: Упозорење: Можда је промењен оригинални фајл" #, c-format msgid "Swap file is encrypted: \"%s\"" -msgstr "Swap датотека је шифрована: \"%s\"" +msgstr "Swap фајл је шифрован: \"%s\"" msgid "" "\n" "If you entered a new crypt key but did not write the text file," msgstr "" "\n" -"Ако сте унели нов кључ за шифрирање али нисте уписали текст датотеку," +"Ако сте унели нов кључ за шифрирање али нисте уписали текст фајл," msgid "" "\n" @@ -3518,7 +3516,7 @@ "If you wrote the text file after changing the crypt key press enter" msgstr "" "\n" -"Ако сте уписали текст датотеку на диск након промене кључа за шифрирање " +"Ако сте уписали текст фајл на диск након промене кључа за шифрирање " "притисните ентер" msgid "" @@ -3526,7 +3524,7 @@ "to use the same key for text file and swap file" msgstr "" "\n" -"да бисте користили исти кључ за текст датотеку и swap датотеку" +"да бисте користили исти кључ за текст фајл и swap фајл" #, c-format msgid "E309: Unable to read block 1 from %s" @@ -3546,7 +3544,7 @@ #, c-format msgid "E310: Block 1 ID wrong (%s not a .swp file?)" -msgstr "E310: ID блока 1 је погрешан (%s није .swp датотека?)" +msgstr "E310: ID блока 1 је погрешан (%s није .swp фајл?)" msgid "???BLOCK MISSING" msgstr "???НЕДОСТАЈЕ БЛОК" @@ -3580,13 +3578,13 @@ "(You might want to write out this file under another name\n" msgstr "" "\n" -"(Можда бисте хтели да запишете ову датотеку под другим именом\n" +"(Можда бисте хтели да запишете овај фајл под другим именом\n" msgid "and run diff with the original file to check for changes)" -msgstr "и покренете diff са оригиналном датотеком да провелите има ли измена)" +msgstr "и покренете diff са оригиналним фајлом да проверите има ли измена)" msgid "Recovery completed. Buffer contents equals file contents." -msgstr "Опоравак је завршен. Садржај бафера је истоветан садржају датотеке." +msgstr "Опоравак је завршен. Садржај бафера је истоветан садржају фајла." msgid "" "\n" @@ -3594,14 +3592,14 @@ "\n" msgstr "" "\n" -"Сада можда желите да обришете .swp датотеку.\n" +"Сада можда желите да обришете .swp фајл.\n" "\n" msgid "Using crypt key from swap file for the text file.\n" -msgstr "За текст датотеку се користи кључ за шифрирање из swap датотеке.\n" +msgstr "За текст фајл се користи кључ за шифрирање из swap фајла.\n" msgid "Swap files found:" -msgstr "Пронађене су swap датотеке:" +msgstr "Пронађени су swap фајлови:" msgid " In current directory:\n" msgstr " У текућем директоријуму:\n" @@ -3613,32 +3611,32 @@ msgstr " У директоријуму " msgid " -- none --\n" -msgstr " -- ниједна --\n" +msgstr " -- ниједан --\n" msgid " owned by: " -msgstr " које поседује: " +msgstr " који поседује: " msgid " dated: " -msgstr " датиране: " +msgstr " датиран: " msgid " dated: " -msgstr " датиране: " +msgstr " датиран: " msgid " [from Vim version 3.0]" msgstr " [од Vim верзије 3.0]" msgid " [does not look like a Vim swap file]" -msgstr " [не изгледа као Vim swap датотека]" +msgstr " [не изгледа као Vim swap фајл]" msgid " file name: " -msgstr " име датотеке: " +msgstr " име фајла: " msgid "" "\n" " modified: " msgstr "" "\n" -" измењено: " +" измењен: " msgid "YES" msgstr "ДА" @@ -3678,14 +3676,14 @@ " [not usable with this version of Vim]" msgstr "" "\n" -" [није употребљива са овом верзијом Vim-а]" +" [није употребљив са овом верзијом Vim-а]" msgid "" "\n" " [not usable on this computer]" msgstr "" "\n" -" [није употребљива на овом компјутеру]" +" [није употребљив на овом компјутеру]" msgid " [cannot be read]" msgstr " [не може да се прочита]" @@ -3694,10 +3692,10 @@ msgstr " [не може да се отвори]" msgid "E313: Cannot preserve, there is no swap file" -msgstr "E313: Не може да се презервира, нема swap датотеке" +msgstr "E313: Не може да се презервира, нема swap фајла" msgid "File preserved" -msgstr "Датотека је презервирана" +msgstr "Фајл је презервиран" msgid "E314: Preserve failed" msgstr "E314: Презервација није успела" @@ -3761,13 +3759,13 @@ "Found a swap file by the name \"" msgstr "" "\n" -"Пронађена је swap датотека под именом \"" +"Пронађен је swap фајл под именом \"" msgid "While opening file \"" -msgstr "Док се отварала датотекa \"" +msgstr "Док се отварао фајл \"" msgid " NEWER than swap file!\n" -msgstr " НОВИЈА од swap датотеке!\n" +msgstr " НОВИЈИ од swap фајла!\n" msgid "" "\n" @@ -3776,12 +3774,12 @@ " file when making changes. Quit, or continue with caution.\n" msgstr "" "\n" -"(1) Можда други програм уређује исту датотеку. Ако је ово случај,\n" +"(1) Можда други програм уређује исти фајл. Ако је ово случај,\n" " кад правите измене, пазите да не завршите са две различите\n" -" инстанце исте датотеке. Изађите, или опрезно наставите.\n" +" инстанце истог фајла. Изађите, или опрезно наставите.\n" msgid "(2) An edit session for this file crashed.\n" -msgstr "(2) Сесија уређивања ове датотеке се срушила.\n" +msgstr "(2) Сесија уређивања овог фајла се срушила.\n" msgid " If this is the case, use \":recover\" or \"vim -r " msgstr " Ако је ово случај, користите \":recover\" или \"vim -r " @@ -3794,7 +3792,7 @@ " да опоравите измене (погледајте \":help recovery\").\n" msgid " If you did this already, delete the swap file \"" -msgstr " Ако сте ово већ учинили, обришите swap датотеку \"" +msgstr " Ако сте ово већ учинили, обришите swap фајл \"" msgid "" "\"\n" @@ -3804,7 +3802,7 @@ " како би избегли ову поруку.\n" msgid "Swap file \"" -msgstr "Swap датотека \"" +msgstr "Swap фајл \"" msgid "\" already exists!" msgstr "\" већ постоји!" @@ -3813,7 +3811,7 @@ msgstr "VIM - ПАЖЊА" msgid "Swap file already exists!" -msgstr "Swap датотека већ постоји!" +msgstr "Swap фајл већ постоји!" msgid "" "&Open Read-Only\n" @@ -3839,11 +3837,12 @@ "Отвори &Само за читање\n" "Ипак &Уређуј\n" "&Опорави\n" +"Обриши &Га\n" "&Изађи\n" "&Прекини" msgid "E326: Too many swap files found" -msgstr "E326: Пронађено је превише swap датотека" +msgstr "E326: Пронађено је превише swap фајлова" msgid "E327: Part of menu-item path is not sub-menu" msgstr "E327: Део путање ставке менија није подмени" @@ -3952,13 +3951,13 @@ msgstr "Дијалог избора директоријума" msgid "Save File dialog" -msgstr "Дијалог чувања датотеке" +msgstr "Дијалог чувања фајла" msgid "Open File dialog" -msgstr "Дијалог отварања датотеке" +msgstr "Дијалог отварања фајла" msgid "E338: Sorry, no file browser in console mode" -msgstr "E338: Жао нам је, нема претраживача датотека у конзолном режиму" +msgstr "E338: Жао нам је, нема претраживача фајлова у конзолном режиму" msgid "E766: Insufficient arguments for printf()" msgstr "E766: Недовољно аргумената за printf()" @@ -3970,13 +3969,13 @@ msgstr "E767: Сувише аргумената за printf()" msgid "W10: Warning: Changing a readonly file" -msgstr "W10: Упозорење: Мења се датотека која може само да се чита" +msgstr "W10: Упозорење: Мења се фајл која може само да се чита" msgid "Type number and or click with mouse (empty cancels): " -msgstr "Унесите број и или кликните мишем (ништа за отказ): " +msgstr "Унесите број и <Ентер> или кликните мишем (ништа за отказ): " msgid "Type number and (empty cancels): " -msgstr "Унесите број и (ништа за отказ): " +msgstr "Унесите број и <Ентер> (ништа за отказ): " msgid "1 more line" msgstr "1 линија више" @@ -4064,7 +4063,7 @@ #, c-format msgid "E345: Can't find file \"%s\" in path" -msgstr "E345: Датотека \"%s\" не може да се пронађе у path" +msgstr "E345: Фајл \"%s\" не може да се пронађе у path" #, c-format msgid "E346: No more directory \"%s\" found in cdpath" @@ -4072,18 +4071,18 @@ #, c-format msgid "E347: No more file \"%s\" found in path" -msgstr "E347: Датотека \"%s\" више не може да се пронађе у path" +msgstr "E347: Фајл \"%s\" више не може да се пронађе у path" #, c-format msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\"" -msgstr "E668: Погрешан режим приступа за инфо датотеку NetBeans везе: \"%s\"" +msgstr "E668: Погрешан режим приступа за инфо фајл NetBeans везе: \"%s\"" #, c-format msgid "E658: NetBeans connection lost for buffer %ld" msgstr "E658: NetBeans веза је изгубљена за бафер %ld" msgid "E838: netbeans is not supported with this GUI" -msgstr "E838: netbeans није подржан са овим GUI" +msgstr "E838: netbeans није подржан са овим ГКИ" msgid "E511: netbeans already connected" msgstr "E511: netbeans је већ повезан" @@ -4284,10 +4283,10 @@ msgstr "E529: 'term' не може да се постави на празан стринг" msgid "E530: Cannot change term in GUI" -msgstr "E530: term не може да се промени из GUI" +msgstr "E530: term не може да се промени из ГКИ" msgid "E531: Use \":gui\" to start the GUI" -msgstr "E531: Користите \":gui\" да покренете GUI" +msgstr "E531: Користите \":gui\" да покренете ГКИ" msgid "E589: 'backupext' and 'patchmode' are equal" msgstr "E589: 'backupext' и 'patchmode' су истоветни" @@ -4299,7 +4298,7 @@ msgstr "E835: У конфликту са вредношћу 'fillchars'" msgid "E617: Cannot be changed in the GTK+ 2 GUI" -msgstr "E617: Не може да се промени у GTK+ 2 GUI" +msgstr "E617: Не може да се промени у GTK+ 2 ГКИ" #, c-format msgid "E950: Cannot convert between %s and %s" @@ -4721,14 +4720,14 @@ msgstr "Нема уноса" msgid "Error file" -msgstr "Датотека грешака" +msgstr "Фајл грешака" msgid "E683: File name missing or invalid pattern" -msgstr "E683: Недостаје име датотеке или неважећи шаблон" +msgstr "E683: Недостаје име фајла или неважећи шаблон" #, c-format msgid "Cannot open file \"%s\"" -msgstr "Датотека \"%s\" не може да се отвори" +msgstr "Фајл \"%s\" не може да се отвори" msgid "E681: Buffer is not loaded" msgstr "E681: Бафер није учитан" @@ -4911,7 +4910,7 @@ msgid "" "Could not open temporary log file for writing, displaying on stderr... " msgstr "" -"Привремена лог датотека није могла да се отвори за упис, приказује се на " +"Привремени лог фајл није могао да се отвори за упис, приказује се на " "stderr... " #, c-format @@ -4919,7 +4918,7 @@ msgstr "(NFA) %s НЕ МОЖЕ ДА СЕ ОТВОРИ !" msgid "Could not open temporary log file for writing " -msgstr "Привремена лог датотека није могла да се отвори за упис " +msgstr "Привремени лог фајл није могао да се отвори за упис " msgid " VREPLACE" msgstr "ВЗАМЕНА" @@ -4991,10 +4990,10 @@ msgstr " (укључује претходно наведена подударања)" msgid "--- Included files " -msgstr "--- Прикључене датотеке " +msgstr "--- Прикључени фајлови " msgid "not found " -msgstr "нису пронађене " +msgstr "нису пронађени " msgid "in path ---\n" msgstr "у путањи ---\n" @@ -5007,20 +5006,20 @@ #, c-format msgid "Scanning included file: %s" -msgstr "Прегледање уметнуте датотеке: %s" +msgstr "Прегледање прикљученог фајла: %s" #, c-format msgid "Searching included file %s" -msgstr "Претраживање уметнуте датотеке %s" +msgstr "Претраживање прикљученог фајла %s" msgid "E387: Match is on current line" msgstr "E387: Подударање је у текућој линији" msgid "All included files were found" -msgstr "Све уметнуте датотеке су пронађене" +msgstr "Пронађени су сви прикључени фајлови" msgid "No included files" -msgstr "Нема уметнутих датотека" +msgstr "Нема прикључених фајлова" msgid "E388: Couldn't find definition" msgstr "E388: Дефиниција не може да се пронађе" @@ -5086,18 +5085,18 @@ msgstr "E753: Није пронађено: %s" msgid "E758: Truncated spell file" -msgstr "E758: Правописна датотека је прекраћена" +msgstr "E758: Правописни фајл је прекраћен" #, c-format msgid "Trailing text in %s line %d: %s" -msgstr "Текст вишак у %s линија %d: %s" +msgstr "Вишак текста у %s линија %d: %s" #, c-format msgid "Affix name too long in %s line %d: %s" msgstr "Име наставка је предугачко у %s линија %d: %s" msgid "E761: Format error in affix file FOL, LOW or UPP" -msgstr "E761: Грешка формата у датотеци наставака FOL, LOW или UPP" +msgstr "E761: Грешка формата у фајлу наставака FOL, LOW или UPP" msgid "E762: Character in FOL, LOW or UPP is out of range" msgstr "E762: Карактер у FOL, LOW или UPP је ван опсега" @@ -5107,43 +5106,43 @@ #, c-format msgid "Reading spell file \"%s\"" -msgstr "Читање правописне датотеке \"%s\"" +msgstr "Читање правописног фајла \"%s\"" msgid "E757: This does not look like a spell file" -msgstr "E757: Ово не изгледа као правописна датотека" +msgstr "E757: Ово не изгледа као правописни фајл" msgid "E771: Old spell file, needs to be updated" -msgstr "E771: Стара правописна датотека, потребно је да се освежи" +msgstr "E771: Стари правописни фајл, потребно је да се освежи" msgid "E772: Spell file is for newer version of Vim" -msgstr "E772: Правописна датотека је за новију верзију Vim-а" +msgstr "E772: Правописни фајл је за новију верзију Vim-а" msgid "E770: Unsupported section in spell file" -msgstr "E770: Неподржана секција у правописној датотеци" +msgstr "E770: Неподржана секција у правописном фајлу" #, c-format msgid "E778: This does not look like a .sug file: %s" -msgstr "E778: Ово не изгледа као .sug датотека: %s" +msgstr "E778: Ово не изгледа као .sug фајл: %s" #, c-format msgid "E779: Old .sug file, needs to be updated: %s" -msgstr "E779: Стара .sug датотека, потребно је да се освежи: %s" +msgstr "E779: Стари .sug фајл, потребно је да се освежи: %s" #, c-format msgid "E780: .sug file is for newer version of Vim: %s" -msgstr "E780: .sug датотека је за новију верзију Vim-а: %s" +msgstr "E780: .sug фајл је за новију верзију Vim-а: %s" #, c-format msgid "E781: .sug file doesn't match .spl file: %s" -msgstr "E781: .sug датотека не одговара .spl датотеци: %s" +msgstr "E781: .sug фајл не одговара .spl фајлу: %s" #, c-format msgid "E782: error while reading .sug file: %s" -msgstr "E782: грешка приликом читања .sug датотеке: %s" +msgstr "E782: грешка приликом читања .sug фајла: %s" #, c-format msgid "Reading affix file %s..." -msgstr "Читање датотеке наставака %s..." +msgstr "Читање фајла наставака %s..." #, c-format msgid "Conversion failure for word in %s line %d: %s" @@ -5278,11 +5277,11 @@ #, c-format msgid "%s value differs from what is used in another .aff file" msgstr "" -"%s вредност се разликује од онога што је коришћено у другој .aff датотеци" +"%s вредност се разликује од онога што је коришћено у другом .aff фајлу" #, c-format msgid "Reading dictionary file %s..." -msgstr "Читање датотеке речника %s..." +msgstr "Читање фајла речника %s..." #, c-format msgid "E760: No word count in %s" @@ -5310,7 +5309,7 @@ #, c-format msgid "Reading word file %s..." -msgstr "Читање датотеке речи %s..." +msgstr "Читање фајла речи %s..." #, c-format msgid "Duplicate /encoding= line ignored in %s line %d: %s" @@ -5352,7 +5351,7 @@ msgstr "Компресовано је %d од %d чворова; преостало је још %d (%d%%)" msgid "Reading back spell file..." -msgstr "Читање правописне датотеке..." +msgstr "Читање правописног фајла..." msgid "Performing soundfolding..." msgstr "Извођење склапања по звучности..." @@ -5367,14 +5366,14 @@ #, c-format msgid "Writing suggestion file %s..." -msgstr "Уписивање датотеке предлога %s..." +msgstr "Уписивање фајла предлога %s..." #, c-format msgid "Estimated runtime memory use: %d bytes" msgstr "Процењена потребна величина меморије у време извршавања: %d бајтова" msgid "E751: Output file name must not have region name" -msgstr "E751: Име излазне датотеке не сме да има име региона" +msgstr "E751: Име излазног фајла не сме да има име региона" #, c-format msgid "E754: Only up to %ld regions supported" @@ -5389,7 +5388,7 @@ #, c-format msgid "Writing spell file %s..." -msgstr "Уписивање правописне датотеке %s..." +msgstr "Уписивање правописног фајла %s..." msgid "Done!" msgstr "Завршено!" @@ -5407,13 +5406,13 @@ msgstr "Реч '%.*s' је додата у %s" msgid "E763: Word characters differ between spell files" -msgstr "E763: Карактери у речи се разликују између правописних датотека" +msgstr "E763: Карактери у речи се разликују између правописних фајлова" msgid "E783: duplicate char in MAP entry" msgstr "E783: карактер дупликат у MAP ставци" msgid "No Syntax items defined for this buffer" -msgstr "За оба јбафер нису дефинисане синтаксне ставке" +msgstr "Синтаксне ставке нису дефинисане за овај бафер" msgid "syntax conceal on" msgstr "скривање синтаксе укључено" @@ -5510,7 +5509,7 @@ msgstr "E394: Ставка региона није пронађена за %s" msgid "E397: Filename required" -msgstr "E397: Потребно име датотеке" +msgstr "E397: Потребно је име фајла" msgid "E847: Too many syntax includes" msgstr "E847: Превише синтаксних уметања" @@ -5659,10 +5658,10 @@ msgstr "E426: ознака није пронађена: %s" msgid " # pri kind tag" -msgstr " # ознака pri врсте" +msgstr " # pri ознака врста" msgid "file\n" -msgstr "датотека\n" +msgstr "фајл\n" msgid "E427: There is only one matching tag" msgstr "E427: Постоји само једна подударајућа ознака" @@ -5672,7 +5671,7 @@ #, c-format msgid "File \"%s\" does not exist" -msgstr "Датотека \"%s\" не постоји" +msgstr "Фајл \"%s\" не постоји" #, c-format msgid "tag %d of %d%s" @@ -5686,29 +5685,29 @@ #, c-format msgid "E429: File \"%s\" does not exist" -msgstr "E429: Датотека \"%s\" не постоји" +msgstr "E429: Фајл \"%s\" не постоји" msgid "" "\n" " # TO tag FROM line in file/text" msgstr "" "\n" -" # НА ознака ОД линије у датот/текст" +" # НА ознаку ИЗ линије у фајлу/тексту" #, c-format msgid "Searching tags file %s" -msgstr "Претраживање датотеке ознака %s" +msgstr "Претраживање фајла ознака %s" #, c-format msgid "E430: Tag file path truncated for %s\n" -msgstr "E430: Путања датотеке ознака је прекинута за %s\n" +msgstr "E430: Путања фајла ознака је прекинута за %s\n" msgid "Ignoring long line in tags file" -msgstr "Дугачка линија у датотеци ознака се игнорише" +msgstr "Дугачка линија у фајлу ознака се игнорише" #, c-format msgid "E431: Format error in tags file \"%s\"" -msgstr "E431: Грешка формата у датотеци ознака \"%s\"" +msgstr "E431: Грешка формата у фајлу ознака \"%s\"" #, c-format msgid "Before byte %ld" @@ -5716,10 +5715,10 @@ #, c-format msgid "E432: Tags file not sorted: %s" -msgstr "E432: Датотека ознака није сортирана: %s" +msgstr "E432: Фајл ознака није сортиран: %s" msgid "E433: No tags file" -msgstr "E433: Нема датотеке ознака" +msgstr "E433: Нема фајла ознака" msgid "E434: Can't find tag pattern" msgstr "E434: Не може да се пронађе шаблон ознаке" @@ -5738,7 +5737,7 @@ msgstr "подразумева се '" msgid "E557: Cannot open termcap file" -msgstr "E557: termcap датотека не може да се отвори" +msgstr "E557: termcap фајл не може да се отвори" msgid "E558: Terminal entry not found in terminfo" msgstr "E558: У terminfo није пронађена ставка за терминал" @@ -5784,7 +5783,7 @@ #, c-format msgid "E953: File exists: %s" -msgstr "E953: Датотека већ постоји: %s" +msgstr "E953: Фајл већ постоји: %s" msgid "E955: Not a terminal buffer" msgstr "E955: Није терминалски бафер" @@ -5806,76 +5805,76 @@ #, c-format msgid "E828: Cannot open undo file for writing: %s" -msgstr "E828: Датотека опозива не може да се отвори за упис: %s" +msgstr "E828: Фајл опозива не може да се отвори за упис: %s" #, c-format msgid "E825: Corrupted undo file (%s): %s" -msgstr "E825: Искварена датотека за опозив (%s): %s" +msgstr "E825: Искварен фајл за опозив (%s): %s" msgid "Cannot write undo file in any directory in 'undodir'" msgstr "" -"Датотека за опозив не може да се упише ни у један директоријум из 'undodir'" +"Фајл за опозив не може да се упише ни у један директоријум из 'undodir'" #, c-format msgid "Will not overwrite with undo file, cannot read: %s" msgstr "" -"Неће се вршити преписивање са датотеком опозива, читање није могуће: %s" +"Неће се вршити преписивање са фајлом опозива, читање није могуће: %s" #, c-format msgid "Will not overwrite, this is not an undo file: %s" -msgstr "Неће се цршити преписивање, ово није датотека за опозив: %s" +msgstr "Неће се вршити преписивање, ово није фајл за опозив: %s" msgid "Skipping undo file write, nothing to undo" -msgstr "Прескакање уписа у датотеку за опозив, нема шта да се опозове" +msgstr "Прескакање уписа у фајл за опозив, нема шта да се опозове" #, c-format msgid "Writing undo file: %s" -msgstr "Упис датотеке за опозив: %s" +msgstr "Упис фајла за опозив: %s" #, c-format msgid "E829: write error in undo file: %s" -msgstr "E829: грешка код уписа у датотеку за опозив: %s" +msgstr "E829: грешка код уписа у фајл за опозив: %s" #, c-format msgid "Not reading undo file, owner differs: %s" -msgstr "Датотека за опозив се не чита, власник се разликује: %s" +msgstr "Фајл за опозив се не чита, власник се разликује: %s" #, c-format msgid "Reading undo file: %s" -msgstr "Читање датотеке за опозив: %s" +msgstr "Читање фајла за опозив: %s" #, c-format msgid "E822: Cannot open undo file for reading: %s" -msgstr "E822: Датотека за опозив не може да се отвори за читање: %s" +msgstr "E822: Фајл за опозив не може да се отвори за читање: %s" #, c-format msgid "E823: Not an undo file: %s" -msgstr "E823: Није датотека за опозив: %s" +msgstr "E823: Није фајл за опозив: %s" #, c-format msgid "E832: Non-encrypted file has encrypted undo file: %s" msgstr "" -"E832: Датотека која није шифрована има шифровану датотеку за опозив: %s" +"E832: Фајл који није шифрован има шифрован фајл за опозив: %s" #, c-format msgid "E826: Undo file decryption failed: %s" -msgstr "E826: Дешифровање датотеке за опозив није успело: %s" +msgstr "E826: Дешифровање фајла за опозив није успело: %s" #, c-format msgid "E827: Undo file is encrypted: %s" -msgstr "E827: Датотека за опозив је шифрована: %s" +msgstr "E827: Фајл за опозив је шифрован: %s" #, c-format msgid "E824: Incompatible undo file: %s" -msgstr "E824: Некомпатибилна датотека за опозив: %s" +msgstr "E824: Некомпатибилан фајл за опозив: %s" msgid "File contents changed, cannot use undo info" msgstr "" -"Садржај датотеке је промењен, информације за опозив не могу да се користе" +"Садржај фајла је промењен, информације за опозив не могу да се користе" #, c-format msgid "Finished reading undo file %s" -msgstr "Тавршено је читање датотеке за опозив %s" +msgstr "Завршено је читање фајла за опозив %s" msgid "Already at oldest change" msgstr "Већ сте на најстаријој измени" @@ -6052,7 +6051,7 @@ #, c-format msgid "E746: Function name does not match script file name: %s" -msgstr "E746: Име функције се не поклапа са именом скрипт датотеке: %s" +msgstr "E746: Име функције се не поклапа са именом скрипт фајла: %s" #, c-format msgid "E131: Cannot delete function %s: It is in use" @@ -6070,14 +6069,14 @@ "MS-Windows 64-bit GUI version" msgstr "" "\n" -"MS-Windows 64-битна GUI верзија" +"MS-Windows 64-битна ГКИ верзија" msgid "" "\n" "MS-Windows 32-bit GUI version" msgstr "" "\n" -"MS-Windows 32-битна GUI верзија" +"MS-Windows 32-битна ГКИ верзија" msgid " with OLE support" msgstr " са OLE подршком" @@ -6180,76 +6179,76 @@ "Сићушна верзија " msgid "without GUI." -msgstr "без GUI." +msgstr "без ГКИ." msgid "with GTK3 GUI." -msgstr "са GTK3 GUI." +msgstr "са GTK3 ГКИ." msgid "with GTK2-GNOME GUI." -msgstr "са GTK2-GNOME GUI." +msgstr "са GTK2-GNOME ГКИ." msgid "with GTK2 GUI." -msgstr "са GTK2 GUI." +msgstr "са GTK2 ГКИ." msgid "with X11-Motif GUI." -msgstr "са X11-Motif GUI." +msgstr "са X11-Motif ГКИ." msgid "with X11-neXtaw GUI." -msgstr "са X11-neXtaw GUI." +msgstr "са X11-neXtaw ГКИ." msgid "with X11-Athena GUI." -msgstr "са X11-Athena GUI." +msgstr "са X11-Athena ГКИ." msgid "with Photon GUI." -msgstr "са Photon GUI." +msgstr "са Photon ГКИ." msgid "with GUI." -msgstr "са GUI." +msgstr "са ГКИ." msgid "with Carbon GUI." -msgstr "са Carbon GUI." +msgstr "са Carbon ГКИ." msgid "with Cocoa GUI." -msgstr "са Cocoa GUI." +msgstr "са Cocoa ГКИ." msgid " Features included (+) or not (-):\n" msgstr " Могућности укључене (+) или не (-):\n" msgid " system vimrc file: \"" -msgstr " системскa vimrc датотека: \"" +msgstr " системски vimrc фајл: \"" msgid " user vimrc file: \"" -msgstr " корисничка vimrc датотека: \"" +msgstr " кориснички vimrc фајл: \"" msgid " 2nd user vimrc file: \"" -msgstr " 2га корисничка vimrc датотека: \"" +msgstr " 2ги кориснички vimrc фајл: \"" msgid " 3rd user vimrc file: \"" -msgstr " 3ћа корисничка vimrc датотека: \"" +msgstr " 3ћи кориснички vimrc фајл: \"" msgid " user exrc file: \"" -msgstr " корисничка exrc датотека: \"" +msgstr " кориснички exrc фајл: \"" msgid " 2nd user exrc file: \"" -msgstr " 2га корисничка exrc датотека: \"" +msgstr " 2ги кориснички exrc фајл: \"" msgid " system gvimrc file: \"" -msgstr " системска gvimrc датотека: \"" +msgstr " системски gvimrc фајл: \"" msgid " user gvimrc file: \"" -msgstr " корисничка gvimrc датотека: \"" +msgstr " кориснички gvimrc фајл: \"" msgid "2nd user gvimrc file: \"" -msgstr "2га корисничка gvimrc датотека: \"" +msgstr "2ги кориснички gvimrc фајл: \"" msgid "3rd user gvimrc file: \"" -msgstr "3ћа корисничка gvimrc датотека: \"" +msgstr "3ћи кориснички gvimrc фајл: \"" msgid " defaults file: \"" -msgstr " датотека са подраз. опцијама: \"" +msgstr " фајл са подраз. опцијама: \"" msgid " system menu file: \"" -msgstr " системска датотека менија: \"" +msgstr " системски фајл менија: \"" msgid " fall-back for $VIM: \"" msgstr " резервна вредност за $VIM: \"" @@ -6285,25 +6284,25 @@ msgstr "Помозите сиромашној деци у Уганди!" msgid "type :help iccf for information " -msgstr "откуцајте :help iccf за информације " +msgstr "откуцајте :help iccf<Ентер> за информације " msgid "type :q to exit " -msgstr "откуцајте :q за излаз " +msgstr "откуцајте :q<Ентер> за излаз " msgid "type :help or for on-line help" -msgstr "откуцајте :help или за on-line помоћ " +msgstr "откуцајте :help<Ентер> или за on-line помоћ " msgid "type :help version8 for version info" -msgstr "откуцајте :help version8 за инфо о верзији" +msgstr "откуцајте :help version8<Ентер> за инфо о верзији" msgid "Running in Vi compatible mode" msgstr "Рад у Vi компатибилном режиму" msgid "type :set nocp for Vim defaults" -msgstr "откуцајте :set nocp за Vim подразумевано" +msgstr "откуцајте :set nocp<Ентер> за Vim подразумевано" msgid "type :help cp-default for info on this" -msgstr "откуцајте :help cp-default за инфо о овоме" +msgstr "откуцајте :help cp-default<Ентер> за инфо о овоме" msgid "menu Help->Orphans for information " msgstr "мени Помоћ->Сирочићи за информације " @@ -6330,10 +6329,10 @@ msgstr "Постаните регистровани Vim корисник!" msgid "type :help sponsor for information " -msgstr "откуцајте :help sponsor за информације " +msgstr "откуцајте :help sponsor<Ентер> за информације " msgid "type :help register for information " -msgstr "откуцајте :help register за информације " +msgstr "откуцајте :help register<Ентер> за информације " msgid "menu Help->Sponsor/Register for information " msgstr "мени Помоћ->Спонзор/Региструј се за информације " @@ -6363,11 +6362,11 @@ msgstr "E445: Други прозори садрже измене" msgid "E446: No file name under cursor" -msgstr "E446: Под курсором се не налази име датотеке" +msgstr "E446: Под курсором се не налази име фајла" #, c-format msgid "E447: Can't find file \"%s\" in path" -msgstr "E447: Датотека \"%s\" не може да се пронађе у путањи" +msgstr "E447: Фајл \"%s\" не може да се пронађе у путањи" #, c-format msgid "E799: Invalid ID: %ld (must be greater than or equal to 1)" @@ -6404,7 +6403,7 @@ msgstr "Уређуј са постојећим Vim - " msgid "Edits the selected file(s) with Vim" -msgstr "Уређује селектовауе датотеку(е) са Vim-ом" +msgstr "Уређује селектовани фајл(е) са Vim-ом" msgid "Error creating process: Check if gvim is in your path!" msgstr "" @@ -6456,7 +6455,7 @@ msgstr "E588: :endfor без :for" msgid "E13: File exists (add ! to override)" -msgstr "E13: Датотека постоји (додајте ! за премошћавање)" +msgstr "E13: Фајл постоји (додајте ! за премошћавање)" msgid "E472: Command failed" msgstr "E472: Команда није успела" @@ -6539,7 +6538,7 @@ msgstr "E22: Скрипте су предубоко угњеждене" msgid "E23: No alternate file" -msgstr "E23: Нема алтернативне датотеке" +msgstr "E23: Нема алтернативног фајла" msgid "E24: No such abbreviation" msgstr "E24: Таква скраћеница не постоји" @@ -6548,7 +6547,7 @@ msgstr "E477: ! није дозвољен" msgid "E25: GUI cannot be used: Not enabled at compile time" -msgstr "E25: GUI не може да се користи: Није омогућен у време компилације" +msgstr "E25: ГКИ не може да се користи: Није омогућен у време компилације" msgid "E26: Hebrew cannot be used: Not enabled at compile time\n" msgstr "" @@ -6582,7 +6581,7 @@ msgstr "E480: Нема подударања: %s" msgid "E32: No file name" -msgstr "E32: Нема имена датотеке" +msgstr "E32: Нема имена фајла" msgid "E33: No previous substitute regular expression" msgstr "E33: Нема претходног регуларног израза за замену" @@ -6605,18 +6604,18 @@ #, c-format msgid "E482: Can't create file %s" -msgstr "E482: Датотека %s не може да се креира" +msgstr "E482: Фајл %s не може да се креира" msgid "E483: Can't get temp file name" -msgstr "E483: Име привремене датотке не може да се добије" +msgstr "E483: Име привременог фајла не може да се добије" #, c-format msgid "E484: Can't open file %s" -msgstr "E484: Датотека %s не може да се отвори" +msgstr "E484: Фајл %s не може да се отвори" #, c-format msgid "E485: Can't read file %s" -msgstr "E485: Датотека %s не може да се прочита" +msgstr "E485: Фајл %s не може да се прочита" msgid "E38: Null argument" msgstr "E38: Празан аргумент" @@ -6626,10 +6625,10 @@ #, c-format msgid "E40: Can't open errorfile %s" -msgstr "E40: Датотека грешке %s не може да се отвори" +msgstr "E40: Фајл грешке %s не може да се отвори" msgid "E233: cannot open display" -msgstr "E233: проказ не може да се отвори" +msgstr "E233: приказ не може да се отвори" msgid "E41: Out of memory!" msgstr "E41: Нема више меморије!" @@ -6696,7 +6695,7 @@ msgstr "E712: Аргумент за %s мора бити Листа или Речник" msgid "E47: Error while reading errorfile" -msgstr "E47: Грешка приликом читаља датотеке грешке" +msgstr "E47: Грешка приликом читања фајла грешке" msgid "E48: Not allowed in sandbox" msgstr "E48: Није дозвољено у sandbox-у" @@ -6717,7 +6716,7 @@ msgstr "E255: Подаци за знак нису могли да се прочитају!" msgid "E72: Close error on swap file" -msgstr "E72: Грешка код затвањара swap датотеке" +msgstr "E72: Грешка код затвањара swap фајла" msgid "E73: tag stack empty" msgstr "E73: стек ознака је празан" @@ -6732,7 +6731,7 @@ msgstr "E76: Превише [" msgid "E77: Too many file names" -msgstr "E77: Превише имена датотека" +msgstr "E77: Превише имена фајлова" msgid "E488: Trailing characters" msgstr "E488: Карактери вишка на крају" @@ -6766,7 +6765,7 @@ msgid "E744: NetBeans does not allow changes in read-only files" msgstr "" -"E744: NetBeans не дозвољава измене датотека које смеју само да се читају" +"E744: NetBeans не дозвољава измене на фајловима који смеју само да се читају" msgid "E363: pattern uses more memory than 'maxmempattern'" msgstr "E363: шаблон користи више меморије од 'maxmempattern'" @@ -6782,7 +6781,7 @@ msgstr "E682: Неважећи шаблон претраге или раздвојни карактер" msgid "E139: File is loaded in another buffer" -msgstr "E139: Датотека је учитана у други бафер" +msgstr "E139: Фајл је учитан у други бафер" #, c-format msgid "E764: Option '%s' is not set" @@ -7074,11 +7073,11 @@ "Vim macro files (*.vim)\t*.vim\n" "All Files (*.*)\t*.*\n" msgstr "" -"Vim макро датотеке (*.vim)\t*.vim\n" -"Све датотеке (*.*)\t*.*\n" +"Vim макро фајлови (*.vim)\t*.vim\n" +"Сви фајлови (*.*)\t*.*\n" msgid "All Files (*.*)\t*.*\n" -msgstr "Све датотеке (*.*)\t*.*\n" +msgstr "Сви фајлови (*.*)\t*.*\n" msgid "" "All Files (*.*)\t*.*\n" @@ -7087,21 +7086,21 @@ "VB code (*.bas, *.frm)\t*.bas;*.frm\n" "Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" msgstr "" -"Све датотеке (*.*)\t*.*\n" +"Сви фајлови (*.*)\t*.*\n" "C изворни код (*.c, *.h)\t*.c;*.h\n" "C++ изворни код (*.cpp, *.hpp)\t*.cpp;*.hpp\n" "VB код (*.bas, *.frm)\t*.bas;*.frm\n" -"Vim датотеке (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" +"Vim фајлови (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" msgid "" "Vim macro files (*.vim)\t*.vim\n" "All Files (*)\t*\n" msgstr "" -"Vim макро датотеке (*.vim)\t*.vim\n" -"Све датотеке (*)\t*\n" +"Vim макро фајлови (*.vim)\t*.vim\n" +"Сви фајлови (*)\t*\n" msgid "All Files (*)\t*\n" -msgstr "Све датотеке (*)\t*\n" +msgstr "Сви фајлови (*)\t*\n" msgid "" "All Files (*)\t*\n" @@ -7109,7 +7108,7 @@ "C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n" "Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" msgstr "" -"Све датотеке (*)\t*\n" +"Сви фајлови (*)\t*\n" "C изворни код (*.c, *.h)\t*.c;*.h\n" "C++ изворни код (*.cpp, *.hpp)\t*.cpp;*.hpp\n" -"Vim датотеке (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" +"Vim фајлови (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" diff -Nru vim-8.1.1681/src/popupwin.c vim-8.1.1729/src/popupwin.c --- vim-8.1.1681/src/popupwin.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/popupwin.c 2019-07-21 21:04:21.000000000 +0000 @@ -13,7 +13,7 @@ #include "vim.h" -#ifdef FEAT_TEXT_PROP +#if defined(FEAT_TEXT_PROP) || defined(PROTO) typedef struct { char *pp_name; @@ -442,6 +442,68 @@ } /* + * Scroll to show the line with the cursor. This assumes lines don't wrap. + */ + static void +popup_show_curline(win_T *wp) +{ + if (wp->w_cursor.lnum < wp->w_topline) + wp->w_topline = wp->w_cursor.lnum; + else if (wp->w_cursor.lnum >= wp->w_botline) + wp->w_topline = wp->w_cursor.lnum - wp->w_height + 1; + + // Don't use "firstline" now. + wp->w_firstline = 0; +} + +/* + * Get the sign group name for window "wp". + * Returns a pointer to a static buffer, overwritten on the next call. + */ + static char_u * +popup_get_sign_name(win_T *wp) +{ + static char buf[30]; + + vim_snprintf(buf, sizeof(buf), "popup-%d", wp->w_id); + return (char_u *)buf; +} + +/* + * Highlight the line with the cursor. + * Also scrolls the text to put the cursor line in view. + */ + static void +popup_highlight_curline(win_T *wp) +{ + int sign_id = 0; + char_u *sign_name = popup_get_sign_name(wp); + + buf_delete_signs(wp->w_buffer, (char_u *)"popupmenu"); + + if ((wp->w_popup_flags & POPF_CURSORLINE) != 0) + { + popup_show_curline(wp); + + if (!sign_exists_by_name(sign_name)) + { + char *linehl = "PopupSelected"; + + if (syn_name2id((char_u *)linehl) == 0) + linehl = "PmenuSel"; + sign_define_by_name(sign_name, NULL, + (char_u *)linehl, NULL, NULL); + } + + sign_place(&sign_id, (char_u *)"popupmenu", sign_name, + wp->w_buffer, wp->w_cursor.lnum, SIGN_DEF_PRIO); + redraw_win_later(wp, NOT_VALID); + } + else + sign_undefine_by_name(sign_name, FALSE); +} + +/* * Shared between popup_create() and f_popup_setoptions(). */ static void @@ -510,13 +572,15 @@ set_string_option_direct_in_win(wp, (char_u *)"wincolor", -1, str, OPT_FREE|OPT_LOCAL, 0); + set_string_option_direct_in_win(wp, (char_u *)"signcolumn", -1, + (char_u *)"no", OPT_FREE|OPT_LOCAL, 0); set_padding_border(dict, wp->w_popup_padding, "padding", 999); set_padding_border(dict, wp->w_popup_border, "border", 1); di = dict_find(dict, (char_u *)"borderhighlight", -1); if (di != NULL) { - if (di->di_tv.v_type != VAR_LIST) + if (di->di_tv.v_type != VAR_LIST || di->di_tv.vval.v_list == NULL) emsg(_(e_listreq)); else { @@ -524,17 +588,16 @@ listitem_T *li; int i; - if (list != NULL) - for (i = 0, li = list->lv_first; i < 4 && i < list->lv_len; - ++i, li = li->li_next) - { - str = tv_get_string(&li->li_tv); - if (*str != NUL) - wp->w_border_highlight[i] = vim_strsave(str); - } + for (i = 0, li = list->lv_first; i < 4 && i < list->lv_len; + ++i, li = li->li_next) + { + str = tv_get_string(&li->li_tv); + if (*str != NUL) + wp->w_border_highlight[i] = vim_strsave(str); + } if (list->lv_len == 1 && wp->w_border_highlight[0] != NULL) for (i = 1; i < 4; ++i) - wp->w_border_highlight[i] = + wp->w_border_highlight[i] = vim_strsave(wp->w_border_highlight[0]); } } @@ -587,14 +650,13 @@ di = dict_find(dict, (char_u *)"mask", -1); if (di != NULL) { - int ok = TRUE; + int ok = FALSE; - if (di->di_tv.v_type != VAR_LIST) - ok = FALSE; - else if (di->di_tv.vval.v_list != NULL) + if (di->di_tv.v_type == VAR_LIST && di->di_tv.vval.v_list != NULL) { listitem_T *li; + ok = TRUE; for (li = di->di_tv.vval.v_list->lv_first; li != NULL; li = li->li_next) { @@ -637,6 +699,20 @@ handle_moved_argument(wp, di, TRUE); } + di = dict_find(dict, (char_u *)"cursorline", -1); + if (di != NULL) + { + if (di->di_tv.v_type == VAR_NUMBER) + { + if (di->di_tv.vval.v_number != 0) + wp->w_popup_flags |= POPF_CURSORLINE; + else + wp->w_popup_flags &= ~POPF_CURSORLINE; + } + else + semsg(_(e_invargval), "cursorline"); + } + di = dict_find(dict, (char_u *)"filter", -1); if (di != NULL) { @@ -664,6 +740,7 @@ /* * Go through the options in "dict" and apply them to popup window "wp". + * Only used when creating a new popup window. */ static void apply_options(win_T *wp, dict_T *dict) @@ -681,6 +758,7 @@ } popup_mask_refresh = TRUE; + popup_highlight_curline(wp); } /* @@ -881,7 +959,8 @@ } // start at the desired first line - wp->w_topline = wp->w_firstline; + if (wp->w_firstline != 0) + wp->w_topline = wp->w_firstline; if (wp->w_topline > wp->w_buffer->b_ml.ml_line_count) wp->w_topline = wp->w_buffer->b_ml.ml_line_count; @@ -892,9 +971,16 @@ wp->w_width = 1; for (lnum = wp->w_topline; lnum <= wp->w_buffer->b_ml.ml_line_count; ++lnum) { - // count Tabs for what they are worth - int len = win_linetabsize(wp, ml_get_buf(wp->w_buffer, lnum, FALSE), + int len; + int w_width = wp->w_width; + + // Count Tabs for what they are worth and compute the length based on + // the maximum width (matters when 'showbreak' is set). + if (wp->w_width < maxwidth) + wp->w_width = maxwidth; + len = win_linetabsize(wp, ml_get_buf(wp->w_buffer, lnum, FALSE), (colnr_T)MAXCOL); + wp->w_width = w_width; if (wp->w_p_wrap) { @@ -1036,7 +1122,8 @@ TYPE_BEVAL, TYPE_NOTIFICATION, TYPE_DIALOG, - TYPE_MENU + TYPE_MENU, + TYPE_PREVIEW } create_type_T; /* @@ -1082,59 +1169,134 @@ } /* + * Parse the 'previewpopup' option and apply the values to window "wp" if it + * not NULL. + * Return FAIL if the parsing fails. + */ + int +parse_previewpopup(win_T *wp) +{ + char_u *p; + + for (p = p_pvp; *p != NUL; p += (*p == ',' ? 1 : 0)) + { + char_u *e, *dig; + char_u *s = p; + int x; + + e = vim_strchr(p, ':'); + if (e == NULL || e[1] == NUL) + return FAIL; + + p = vim_strchr(e, ','); + if (p == NULL) + p = e + STRLEN(e); + dig = e + 1; + x = getdigits(&dig); + if (dig != p) + return FAIL; + + if (STRNCMP(s, "height:", 7) == 0) + { + if (wp != NULL) + { + wp->w_minheight = x; + wp->w_maxheight = x; + } + } + else if (STRNCMP(s, "width:", 6) == 0) + { + if (wp != NULL) + { + wp->w_minwidth = x; + wp->w_maxwidth = x; + } + } + else + return FAIL; + } + return OK; +} + +/* + * Set w_wantline and w_wantcol for the cursor position in the current window. + */ + void +popup_set_wantpos(win_T *wp) +{ + setcursor_mayforce(TRUE); + wp->w_wantline = curwin->w_winrow + curwin->w_wrow; + if (wp->w_wantline == 0) // cursor in first line + { + wp->w_wantline = 2; + wp->w_popup_pos = POPPOS_TOPLEFT; + } + wp->w_wantcol = curwin->w_wincol + curwin->w_wcol + 1; + popup_adjust_position(wp); +} + +/* * popup_create({text}, {options}) * popup_atcursor({text}, {options}) + * etc. + * When creating a preview window popup "argvars" and "rettv" are NULL. */ static win_T * popup_create(typval_T *argvars, typval_T *rettv, create_type_T type) { win_T *wp; tabpage_T *tp = NULL; - int tabnr; + int tabnr = 0; int new_buffer; buf_T *buf = NULL; - dict_T *d; + dict_T *d = NULL; int nr; int i; - // Check arguments look OK. - if (argvars[0].v_type == VAR_NUMBER) + if (argvars != NULL) { - buf = buflist_findnr( argvars[0].vval.v_number); - if (buf == NULL) + // Check that arguments look OK. + if (argvars[0].v_type == VAR_NUMBER) { - semsg(_(e_nobufnr), argvars[0].vval.v_number); + buf = buflist_findnr( argvars[0].vval.v_number); + if (buf == NULL) + { + semsg(_(e_nobufnr), argvars[0].vval.v_number); + return NULL; + } + } + else if (!(argvars[0].v_type == VAR_STRING + && argvars[0].vval.v_string != NULL) + && !(argvars[0].v_type == VAR_LIST + && argvars[0].vval.v_list != NULL)) + { + emsg(_(e_listreq)); return NULL; } + if (argvars[1].v_type != VAR_DICT || argvars[1].vval.v_dict == NULL) + { + emsg(_(e_dictreq)); + return NULL; + } + d = argvars[1].vval.v_dict; } - else if (!(argvars[0].v_type == VAR_STRING - && argvars[0].vval.v_string != NULL) - && !(argvars[0].v_type == VAR_LIST - && argvars[0].vval.v_list != NULL)) - { - emsg(_(e_listreq)); - return NULL; - } - if (argvars[1].v_type != VAR_DICT || argvars[1].vval.v_dict == NULL) - { - emsg(_(e_dictreq)); - return NULL; - } - d = argvars[1].vval.v_dict; - if (dict_find(d, (char_u *)"tabpage", -1) != NULL) - tabnr = (int)dict_get_number(d, (char_u *)"tabpage"); - else if (type == TYPE_NOTIFICATION) - tabnr = -1; // notifications are global by default - else - tabnr = 0; - if (tabnr > 0) + if (d != NULL) { - tp = find_tabpage(tabnr); - if (tp == NULL) + if (dict_find(d, (char_u *)"tabpage", -1) != NULL) + tabnr = (int)dict_get_number(d, (char_u *)"tabpage"); + else if (type == TYPE_NOTIFICATION) + tabnr = -1; // notifications are global by default + else + tabnr = 0; + if (tabnr > 0) { - semsg(_("E997: Tabpage not found: %d"), tabnr); - return NULL; + tp = find_tabpage(tabnr); + if (tp == NULL) + { + semsg(_("E997: Tabpage not found: %d"), tabnr); + return NULL; + } } } @@ -1142,7 +1304,8 @@ wp = win_alloc_popup_win(); if (wp == NULL) return NULL; - rettv->vval.v_number = wp->w_id; + if (rettv != NULL) + rettv->vval.v_number = wp->w_id; wp->w_popup_pos = POPPOS_TOPLEFT; wp->w_popup_flags = POPF_IS_POPUP; @@ -1169,7 +1332,7 @@ set_string_option_direct_in_buf(buf, (char_u *)"buftype", -1, (char_u *)"popup", OPT_FREE|OPT_LOCAL, 0); set_string_option_direct_in_buf(buf, (char_u *)"bufhidden", -1, - (char_u *)"hide", OPT_FREE|OPT_LOCAL, 0); + (char_u *)"wipe", OPT_FREE|OPT_LOCAL, 0); buf->b_p_ul = -1; // no undo buf->b_p_swf = FALSE; // no swap file buf->b_p_bl = FALSE; // unlisted buffer @@ -1208,20 +1371,16 @@ } } - if (new_buffer) + if (new_buffer && argvars != NULL) popup_set_buffer_text(buf, argvars[0]); - if (type == TYPE_ATCURSOR) + if (type == TYPE_ATCURSOR || type == TYPE_PREVIEW) { wp->w_popup_pos = POPPOS_BOTLEFT; - setcursor_mayforce(TRUE); - wp->w_wantline = curwin->w_winrow + curwin->w_wrow; - if (wp->w_wantline == 0) // cursor in first line - { - wp->w_wantline = 2; - wp->w_popup_pos = POPPOS_TOPLEFT; - } - wp->w_wantcol = curwin->w_wincol + curwin->w_wcol + 1; + popup_set_wantpos(wp); + } + if (type == TYPE_ATCURSOR) + { set_moved_values(wp); set_moved_columns(wp, FIND_STRING); } @@ -1299,7 +1458,7 @@ for (i = 0; i < 4; ++i) { wp->w_popup_border[i] = 1; - wp->w_popup_padding[i] = 1; + wp->w_popup_padding[i] = (i & 1) ? 1 : 0; } } @@ -1315,6 +1474,16 @@ set_callback(&wp->w_filter_cb, &callback); wp->w_p_wrap = 0; + wp->w_popup_flags |= POPF_CURSORLINE; + } + + if (type == TYPE_PREVIEW) + { + wp->w_popup_drag = 1; + wp->w_popup_close = POPCLOSE_BUTTON; + for (i = 0; i < 4; ++i) + wp->w_popup_border[i] = 1; + parse_previewpopup(wp); } for (i = 0; i < 4; ++i) @@ -1324,8 +1493,9 @@ wp->w_want_scrollbar = 1; wp->w_popup_fixed = 0; - // Deal with options. - apply_options(wp, argvars[1].vval.v_dict); + if (d != NULL) + // Deal with options. + apply_options(wp, d); #ifdef FEAT_TIMERS if (type == TYPE_NOTIFICATION && wp->w_popup_timer == NULL) @@ -1504,26 +1674,6 @@ rettv->vval.v_number = 0; } - static void -popup_highlight_curline(win_T *wp) -{ - int id; - char buf[100]; - - match_delete(wp, 1, FALSE); - - // Scroll to show the line with the cursor. This assumes lines don't wrap. - while (wp->w_topline + wp->w_height - 1 < wp->w_cursor.lnum) - wp->w_topline++; - while (wp->w_cursor.lnum < wp->w_topline) - wp->w_topline--; - - id = syn_name2id((char_u *)"PopupSelected"); - vim_snprintf(buf, sizeof(buf), "\\%%%dl.*", (int)wp->w_cursor.lnum); - match_add(wp, (char_u *)(id == 0 ? "PmenuSel" : "PopupSelected"), - (char_u *)buf, 10, 1, NULL, NULL); -} - /* * popup_filter_menu({text}, {options}) */ @@ -1557,7 +1707,7 @@ ++wp->w_cursor.lnum; if (old_lnum != wp->w_cursor.lnum) { - popup_highlight_curline(wp); + // caller will call popup_highlight_curline() return; } @@ -1632,10 +1782,7 @@ void f_popup_menu(typval_T *argvars, typval_T *rettv) { - win_T *wp = popup_create(argvars, rettv, TYPE_MENU); - - if (wp != NULL) - popup_highlight_curline(wp); + popup_create(argvars, rettv, TYPE_MENU); } /* @@ -1738,10 +1885,12 @@ static void popup_free(win_T *wp) { + sign_undefine_by_name(popup_get_sign_name(wp), FALSE); wp->w_buffer->b_locked = FALSE; if (wp->w_winrow + wp->w_height >= cmdline_row) clear_cmdline = TRUE; win_free_popup(wp); + redraw_all_later(NOT_VALID); popup_mask_refresh = TRUE; } @@ -1860,6 +2009,7 @@ if (old_firstline != wp->w_firstline) redraw_win_later(wp, NOT_VALID); popup_mask_refresh = TRUE; + popup_highlight_curline(wp); popup_adjust_position(wp); } @@ -2049,6 +2199,8 @@ dict_add_string(dict, "title", wp->w_popup_title); dict_add_number(dict, "wrap", wp->w_p_wrap); dict_add_number(dict, "drag", wp->w_popup_drag); + dict_add_number(dict, "cursorline", + (wp->w_popup_flags & POPF_CURSORLINE) != 0); dict_add_string(dict, "highlight", wp->w_p_wcr); if (wp->w_scrollbar_highlight != NULL) dict_add_string(dict, "scrollbarhighlight", @@ -2183,6 +2335,7 @@ int dummy; typval_T argv[3]; char_u buf[NUMBUFLEN]; + linenr_T old_lnum = wp->w_cursor.lnum; // Emergency exit: CTRL-C closes the popup. if (c == Ctrl_C) @@ -2207,6 +2360,9 @@ // NOTE: The callback might close the popup, thus make "wp" invalid. call_callback(&wp->w_filter_cb, -1, &rettv, 2, argv, NULL, 0L, 0L, &dummy, TRUE, NULL); + if (win_valid_popup(wp) && old_lnum != wp->w_cursor.lnum) + popup_highlight_curline(wp); + res = tv_get_number(&rettv); vim_free(argv[1].vval.v_string); clear_tv(&rettv); @@ -2813,4 +2969,72 @@ } return abort; } + +/* + * Find an existing popup used as the preview window, in the current tab page. + * Return NULL if not found. + */ + win_T * +popup_find_preview_window(void) +{ + win_T *wp; + + // Preview window popup is always local to tab page. + for (wp = curtab->tp_first_popupwin; wp != NULL; wp = wp->w_next) + if (wp->w_p_pvw) + return wp; + return wp; +} + + int +popup_is_popup(win_T *wp) +{ + return wp->w_popup_flags != 0; +} + +/* + * Create a popup to be used as the preview window. + * NOTE: this makes the popup the current window, so that the file can be + * edited. However, it must not remain to be the current window, the caller + * must make sure of that. + */ + int +popup_create_preview_window(void) +{ + win_T *wp = popup_create(NULL, NULL, TYPE_PREVIEW); + + if (wp == NULL) + return FAIL; + wp->w_p_pvw = TRUE; + + // Set the width to a reasonable value, so that w_topline can be computed. + if (wp->w_minwidth > 0) + wp->w_width = wp->w_minwidth; + else if (wp->w_maxwidth > 0) + wp->w_width = wp->w_maxwidth; + else + wp->w_width = curwin->w_width; + + // Will switch to another buffer soon, dummy one can be wiped. + wp->w_buffer->b_locked = FALSE; + + win_enter(wp, FALSE); + return OK; +} + + void +popup_close_preview() +{ + win_T *wp = popup_find_preview_window(); + + if (wp != NULL) + { + typval_T res; + + res.v_type = VAR_NUMBER; + res.vval.v_number = -1; + popup_close_and_callback(wp, &res); + } +} + #endif // FEAT_TEXT_PROP diff -Nru vim-8.1.1681/src/profiler.c vim-8.1.1729/src/profiler.c --- vim-8.1.1681/src/profiler.c 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/profiler.c 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,975 @@ +/* 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. + */ + +/* + * profiler.c: vim script profiler + */ + +#include "vim.h" + +#if defined(FEAT_EVAL) || defined(PROTO) +# if defined(FEAT_PROFILE) || defined(FEAT_RELTIME) || defined(PROTO) +/* + * Store the current time in "tm". + */ + void +profile_start(proftime_T *tm) +{ +# ifdef MSWIN + QueryPerformanceCounter(tm); +# else + gettimeofday(tm, NULL); +# endif +} + +/* + * Compute the elapsed time from "tm" till now and store in "tm". + */ + void +profile_end(proftime_T *tm) +{ + proftime_T now; + +# ifdef MSWIN + QueryPerformanceCounter(&now); + tm->QuadPart = now.QuadPart - tm->QuadPart; +# else + gettimeofday(&now, NULL); + tm->tv_usec = now.tv_usec - tm->tv_usec; + tm->tv_sec = now.tv_sec - tm->tv_sec; + if (tm->tv_usec < 0) + { + tm->tv_usec += 1000000; + --tm->tv_sec; + } +# endif +} + +/* + * Subtract the time "tm2" from "tm". + */ + void +profile_sub(proftime_T *tm, proftime_T *tm2) +{ +# ifdef MSWIN + tm->QuadPart -= tm2->QuadPart; +# else + tm->tv_usec -= tm2->tv_usec; + tm->tv_sec -= tm2->tv_sec; + if (tm->tv_usec < 0) + { + tm->tv_usec += 1000000; + --tm->tv_sec; + } +# endif +} + +/* + * Return a string that represents the time in "tm". + * Uses a static buffer! + */ + char * +profile_msg(proftime_T *tm) +{ + static char buf[50]; + +# ifdef MSWIN + LARGE_INTEGER fr; + + QueryPerformanceFrequency(&fr); + sprintf(buf, "%10.6lf", (double)tm->QuadPart / (double)fr.QuadPart); +# else + sprintf(buf, "%3ld.%06ld", (long)tm->tv_sec, (long)tm->tv_usec); +# endif + return buf; +} + +# if defined(FEAT_FLOAT) || defined(PROTO) +/* + * Return a float that represents the time in "tm". + */ + float_T +profile_float(proftime_T *tm) +{ +# ifdef MSWIN + LARGE_INTEGER fr; + + QueryPerformanceFrequency(&fr); + return (float_T)tm->QuadPart / (float_T)fr.QuadPart; +# else + return (float_T)tm->tv_sec + (float_T)tm->tv_usec / 1000000.0; +# endif +} +# endif + +/* + * Put the time "msec" past now in "tm". + */ + void +profile_setlimit(long msec, proftime_T *tm) +{ + if (msec <= 0) // no limit + profile_zero(tm); + else + { +# ifdef MSWIN + LARGE_INTEGER fr; + + QueryPerformanceCounter(tm); + QueryPerformanceFrequency(&fr); + tm->QuadPart += (LONGLONG)((double)msec / 1000.0 * (double)fr.QuadPart); +# else + long usec; + + gettimeofday(tm, NULL); + usec = (long)tm->tv_usec + (long)msec * 1000; + tm->tv_usec = usec % 1000000L; + tm->tv_sec += usec / 1000000L; +# endif + } +} + +/* + * Return TRUE if the current time is past "tm". + */ + int +profile_passed_limit(proftime_T *tm) +{ + proftime_T now; + +# ifdef MSWIN + if (tm->QuadPart == 0) // timer was not set + return FALSE; + QueryPerformanceCounter(&now); + return (now.QuadPart > tm->QuadPart); +# else + if (tm->tv_sec == 0) // timer was not set + return FALSE; + gettimeofday(&now, NULL); + return (now.tv_sec > tm->tv_sec + || (now.tv_sec == tm->tv_sec && now.tv_usec > tm->tv_usec)); +# endif +} + +/* + * Set the time in "tm" to zero. + */ + void +profile_zero(proftime_T *tm) +{ +# ifdef MSWIN + tm->QuadPart = 0; +# else + tm->tv_usec = 0; + tm->tv_sec = 0; +# endif +} + +# endif // FEAT_PROFILE || FEAT_RELTIME + +#if defined(FEAT_SYN_HL) && defined(FEAT_RELTIME) && defined(FEAT_FLOAT) && defined(FEAT_PROFILE) +# if defined(HAVE_MATH_H) +# include +# endif + +/* + * Divide the time "tm" by "count" and store in "tm2". + */ + void +profile_divide(proftime_T *tm, int count, proftime_T *tm2) +{ + if (count == 0) + profile_zero(tm2); + else + { +# ifdef MSWIN + tm2->QuadPart = tm->QuadPart / count; +# else + double usec = (tm->tv_sec * 1000000.0 + tm->tv_usec) / count; + + tm2->tv_sec = floor(usec / 1000000.0); + tm2->tv_usec = vim_round(usec - (tm2->tv_sec * 1000000.0)); +# endif + } +} +#endif + +# if defined(FEAT_PROFILE) || defined(PROTO) +/* + * Functions for profiling. + */ +static proftime_T prof_wait_time; + +/* + * Add the time "tm2" to "tm". + */ + void +profile_add(proftime_T *tm, proftime_T *tm2) +{ +# ifdef MSWIN + tm->QuadPart += tm2->QuadPart; +# else + tm->tv_usec += tm2->tv_usec; + tm->tv_sec += tm2->tv_sec; + if (tm->tv_usec >= 1000000) + { + tm->tv_usec -= 1000000; + ++tm->tv_sec; + } +# endif +} + +/* + * Add the "self" time from the total time and the children's time. + */ + void +profile_self(proftime_T *self, proftime_T *total, proftime_T *children) +{ + // Check that the result won't be negative. Can happen with recursive + // calls. +#ifdef MSWIN + if (total->QuadPart <= children->QuadPart) + return; +#else + if (total->tv_sec < children->tv_sec + || (total->tv_sec == children->tv_sec + && total->tv_usec <= children->tv_usec)) + return; +#endif + profile_add(self, total); + profile_sub(self, children); +} + +/* + * Get the current waittime. + */ + void +profile_get_wait(proftime_T *tm) +{ + *tm = prof_wait_time; +} + +/* + * Subtract the passed waittime since "tm" from "tma". + */ + void +profile_sub_wait(proftime_T *tm, proftime_T *tma) +{ + proftime_T tm3 = prof_wait_time; + + profile_sub(&tm3, tm); + profile_sub(tma, &tm3); +} + +/* + * Return TRUE if "tm1" and "tm2" are equal. + */ + int +profile_equal(proftime_T *tm1, proftime_T *tm2) +{ +# ifdef MSWIN + return (tm1->QuadPart == tm2->QuadPart); +# else + return (tm1->tv_usec == tm2->tv_usec && tm1->tv_sec == tm2->tv_sec); +# endif +} + +/* + * Return <0, 0 or >0 if "tm1" < "tm2", "tm1" == "tm2" or "tm1" > "tm2" + */ + int +profile_cmp(const proftime_T *tm1, const proftime_T *tm2) +{ +# ifdef MSWIN + return (int)(tm2->QuadPart - tm1->QuadPart); +# else + if (tm1->tv_sec == tm2->tv_sec) + return tm2->tv_usec - tm1->tv_usec; + return tm2->tv_sec - tm1->tv_sec; +# endif +} + +static char_u *profile_fname = NULL; +static proftime_T pause_time; + +/* + * ":profile cmd args" + */ + void +ex_profile(exarg_T *eap) +{ + char_u *e; + int len; + + e = skiptowhite(eap->arg); + len = (int)(e - eap->arg); + e = skipwhite(e); + + if (len == 5 && STRNCMP(eap->arg, "start", 5) == 0 && *e != NUL) + { + vim_free(profile_fname); + profile_fname = expand_env_save_opt(e, TRUE); + do_profiling = PROF_YES; + profile_zero(&prof_wait_time); + set_vim_var_nr(VV_PROFILING, 1L); + } + else if (do_profiling == PROF_NONE) + emsg(_("E750: First use \":profile start {fname}\"")); + else if (STRCMP(eap->arg, "pause") == 0) + { + if (do_profiling == PROF_YES) + profile_start(&pause_time); + do_profiling = PROF_PAUSED; + } + else if (STRCMP(eap->arg, "continue") == 0) + { + if (do_profiling == PROF_PAUSED) + { + profile_end(&pause_time); + profile_add(&prof_wait_time, &pause_time); + } + do_profiling = PROF_YES; + } + else + { + // The rest is similar to ":breakadd". + ex_breakadd(eap); + } +} + +// Command line expansion for :profile. +static enum +{ + PEXP_SUBCMD, // expand :profile sub-commands + PEXP_FUNC // expand :profile func {funcname} +} pexpand_what; + +static char *pexpand_cmds[] = { + "start", +#define PROFCMD_START 0 + "pause", +#define PROFCMD_PAUSE 1 + "continue", +#define PROFCMD_CONTINUE 2 + "func", +#define PROFCMD_FUNC 3 + "file", +#define PROFCMD_FILE 4 + NULL +#define PROFCMD_LAST 5 +}; + +/* + * Function given to ExpandGeneric() to obtain the profile command + * specific expansion. + */ + char_u * +get_profile_name(expand_T *xp UNUSED, int idx) +{ + switch (pexpand_what) + { + case PEXP_SUBCMD: + return (char_u *)pexpand_cmds[idx]; + // case PEXP_FUNC: TODO + default: + return NULL; + } +} + +/* + * Handle command line completion for :profile command. + */ + void +set_context_in_profile_cmd(expand_T *xp, char_u *arg) +{ + char_u *end_subcmd; + + // Default: expand subcommands. + xp->xp_context = EXPAND_PROFILE; + pexpand_what = PEXP_SUBCMD; + xp->xp_pattern = arg; + + end_subcmd = skiptowhite(arg); + if (*end_subcmd == NUL) + return; + + if (end_subcmd - arg == 5 && STRNCMP(arg, "start", 5) == 0) + { + xp->xp_context = EXPAND_FILES; + xp->xp_pattern = skipwhite(end_subcmd); + return; + } + + // TODO: expand function names after "func" + xp->xp_context = EXPAND_NOTHING; +} + +static proftime_T inchar_time; + +/* + * Called when starting to wait for the user to type a character. + */ + void +prof_inchar_enter(void) +{ + profile_start(&inchar_time); +} + +/* + * Called when finished waiting for the user to type a character. + */ + void +prof_inchar_exit(void) +{ + profile_end(&inchar_time); + profile_add(&prof_wait_time, &inchar_time); +} + + +/* + * Return TRUE when a function defined in the current script should be + * profiled. + */ + int +prof_def_func(void) +{ + if (current_sctx.sc_sid > 0) + return SCRIPT_ITEM(current_sctx.sc_sid).sn_pr_force; + return FALSE; +} + +/* + * Print the count and times for one function or function line. + */ + static void +prof_func_line( + FILE *fd, + int count, + proftime_T *total, + proftime_T *self, + int prefer_self) // when equal print only self time +{ + if (count > 0) + { + fprintf(fd, "%5d ", count); + if (prefer_self && profile_equal(total, self)) + fprintf(fd, " "); + else + fprintf(fd, "%s ", profile_msg(total)); + if (!prefer_self && profile_equal(total, self)) + fprintf(fd, " "); + else + fprintf(fd, "%s ", profile_msg(self)); + } + else + fprintf(fd, " "); +} + + static void +prof_sort_list( + FILE *fd, + ufunc_T **sorttab, + int st_len, + char *title, + int prefer_self) // when equal print only self time +{ + int i; + ufunc_T *fp; + + fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); + fprintf(fd, "count total (s) self (s) function\n"); + for (i = 0; i < 20 && i < st_len; ++i) + { + fp = sorttab[i]; + prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, + prefer_self); + if (fp->uf_name[0] == K_SPECIAL) + fprintf(fd, " %s()\n", fp->uf_name + 3); + else + fprintf(fd, " %s()\n", fp->uf_name); + } + fprintf(fd, "\n"); +} + +/* + * Compare function for total time sorting. + */ + static int +prof_total_cmp(const void *s1, const void *s2) +{ + ufunc_T *p1, *p2; + + p1 = *(ufunc_T **)s1; + p2 = *(ufunc_T **)s2; + return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); +} + +/* + * Compare function for self time sorting. + */ + static int +prof_self_cmp(const void *s1, const void *s2) +{ + ufunc_T *p1, *p2; + + p1 = *(ufunc_T **)s1; + p2 = *(ufunc_T **)s2; + return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); +} + +/* + * Start profiling function "fp". + */ + void +func_do_profile(ufunc_T *fp) +{ + int len = fp->uf_lines.ga_len; + + if (!fp->uf_prof_initialized) + { + if (len == 0) + len = 1; // avoid getting error for allocating zero bytes + fp->uf_tm_count = 0; + profile_zero(&fp->uf_tm_self); + profile_zero(&fp->uf_tm_total); + if (fp->uf_tml_count == NULL) + fp->uf_tml_count = ALLOC_CLEAR_MULT(int, len); + if (fp->uf_tml_total == NULL) + fp->uf_tml_total = ALLOC_CLEAR_MULT(proftime_T, len); + if (fp->uf_tml_self == NULL) + fp->uf_tml_self = ALLOC_CLEAR_MULT(proftime_T, len); + fp->uf_tml_idx = -1; + if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL + || fp->uf_tml_self == NULL) + return; // out of memory + fp->uf_prof_initialized = TRUE; + } + + fp->uf_profiling = TRUE; +} + +/* + * Prepare profiling for entering a child or something else that is not + * counted for the script/function itself. + * Should always be called in pair with prof_child_exit(). + */ + void +prof_child_enter( + proftime_T *tm) // place to store waittime +{ + funccall_T *fc = get_current_funccal(); + + if (fc != NULL && fc->func->uf_profiling) + profile_start(&fc->prof_child); + script_prof_save(tm); +} + +/* + * Take care of time spent in a child. + * Should always be called after prof_child_enter(). + */ + void +prof_child_exit( + proftime_T *tm) // where waittime was stored +{ + funccall_T *fc = get_current_funccal(); + + if (fc != NULL && fc->func->uf_profiling) + { + profile_end(&fc->prof_child); + profile_sub_wait(tm, &fc->prof_child); // don't count waiting time + profile_add(&fc->func->uf_tm_children, &fc->prof_child); + profile_add(&fc->func->uf_tml_children, &fc->prof_child); + } + script_prof_restore(tm); +} + +/* + * Called when starting to read a function line. + * "sourcing_lnum" must be correct! + * When skipping lines it may not actually be executed, but we won't find out + * until later and we need to store the time now. + */ + void +func_line_start(void *cookie) +{ + funccall_T *fcp = (funccall_T *)cookie; + ufunc_T *fp = fcp->func; + + if (fp->uf_profiling && sourcing_lnum >= 1 + && sourcing_lnum <= fp->uf_lines.ga_len) + { + fp->uf_tml_idx = sourcing_lnum - 1; + // Skip continuation lines. + while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL) + --fp->uf_tml_idx; + fp->uf_tml_execed = FALSE; + profile_start(&fp->uf_tml_start); + profile_zero(&fp->uf_tml_children); + profile_get_wait(&fp->uf_tml_wait); + } +} + +/* + * Called when actually executing a function line. + */ + void +func_line_exec(void *cookie) +{ + funccall_T *fcp = (funccall_T *)cookie; + ufunc_T *fp = fcp->func; + + if (fp->uf_profiling && fp->uf_tml_idx >= 0) + fp->uf_tml_execed = TRUE; +} + +/* + * Called when done with a function line. + */ + void +func_line_end(void *cookie) +{ + funccall_T *fcp = (funccall_T *)cookie; + ufunc_T *fp = fcp->func; + + if (fp->uf_profiling && fp->uf_tml_idx >= 0) + { + if (fp->uf_tml_execed) + { + ++fp->uf_tml_count[fp->uf_tml_idx]; + profile_end(&fp->uf_tml_start); + profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); + profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); + profile_self(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start, + &fp->uf_tml_children); + } + fp->uf_tml_idx = -1; + } +} + +/* + * Dump the profiling results for all functions in file "fd". + */ + static void +func_dump_profile(FILE *fd) +{ + hashtab_T *functbl; + hashitem_T *hi; + int todo; + ufunc_T *fp; + int i; + ufunc_T **sorttab; + int st_len = 0; + char_u *p; + + functbl = func_tbl_get(); + todo = (int)functbl->ht_used; + if (todo == 0) + return; // nothing to dump + + sorttab = ALLOC_MULT(ufunc_T *, todo); + + for (hi = functbl->ht_array; todo > 0; ++hi) + { + if (!HASHITEM_EMPTY(hi)) + { + --todo; + fp = HI2UF(hi); + if (fp->uf_prof_initialized) + { + if (sorttab != NULL) + sorttab[st_len++] = fp; + + if (fp->uf_name[0] == K_SPECIAL) + fprintf(fd, "FUNCTION %s()\n", fp->uf_name + 3); + else + fprintf(fd, "FUNCTION %s()\n", fp->uf_name); + p = home_replace_save(NULL, + get_scriptname(fp->uf_script_ctx.sc_sid)); + if (p != NULL) + { + fprintf(fd, " Defined: %s line %ld\n", + p, (long)fp->uf_script_ctx.sc_lnum); + vim_free(p); + } + if (fp->uf_tm_count == 1) + fprintf(fd, "Called 1 time\n"); + else + fprintf(fd, "Called %d times\n", fp->uf_tm_count); + fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); + fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); + fprintf(fd, "\n"); + fprintf(fd, "count total (s) self (s)\n"); + + for (i = 0; i < fp->uf_lines.ga_len; ++i) + { + if (FUNCLINE(fp, i) == NULL) + continue; + prof_func_line(fd, fp->uf_tml_count[i], + &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); + fprintf(fd, "%s\n", FUNCLINE(fp, i)); + } + fprintf(fd, "\n"); + } + } + } + + if (sorttab != NULL && st_len > 0) + { + qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), + prof_total_cmp); + prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); + qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), + prof_self_cmp); + prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); + } + + vim_free(sorttab); +} + +/* + * Start profiling script "fp". + */ + void +script_do_profile(scriptitem_T *si) +{ + si->sn_pr_count = 0; + profile_zero(&si->sn_pr_total); + profile_zero(&si->sn_pr_self); + + ga_init2(&si->sn_prl_ga, sizeof(sn_prl_T), 100); + si->sn_prl_idx = -1; + si->sn_prof_on = TRUE; + si->sn_pr_nest = 0; +} + +/* + * Save time when starting to invoke another script or function. + */ + void +script_prof_save( + proftime_T *tm) // place to store wait time +{ + scriptitem_T *si; + + if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len) + { + si = &SCRIPT_ITEM(current_sctx.sc_sid); + if (si->sn_prof_on && si->sn_pr_nest++ == 0) + profile_start(&si->sn_pr_child); + } + profile_get_wait(tm); +} + +/* + * Count time spent in children after invoking another script or function. + */ + void +script_prof_restore(proftime_T *tm) +{ + scriptitem_T *si; + + if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len) + { + si = &SCRIPT_ITEM(current_sctx.sc_sid); + if (si->sn_prof_on && --si->sn_pr_nest == 0) + { + profile_end(&si->sn_pr_child); + profile_sub_wait(tm, &si->sn_pr_child); // don't count wait time + profile_add(&si->sn_pr_children, &si->sn_pr_child); + profile_add(&si->sn_prl_children, &si->sn_pr_child); + } + } +} + +/* + * Dump the profiling results for all scripts in file "fd". + */ + static void +script_dump_profile(FILE *fd) +{ + int id; + scriptitem_T *si; + int i; + FILE *sfd; + sn_prl_T *pp; + + for (id = 1; id <= script_items.ga_len; ++id) + { + si = &SCRIPT_ITEM(id); + if (si->sn_prof_on) + { + fprintf(fd, "SCRIPT %s\n", si->sn_name); + if (si->sn_pr_count == 1) + fprintf(fd, "Sourced 1 time\n"); + else + fprintf(fd, "Sourced %d times\n", si->sn_pr_count); + fprintf(fd, "Total time: %s\n", profile_msg(&si->sn_pr_total)); + fprintf(fd, " Self time: %s\n", profile_msg(&si->sn_pr_self)); + fprintf(fd, "\n"); + fprintf(fd, "count total (s) self (s)\n"); + + sfd = mch_fopen((char *)si->sn_name, "r"); + if (sfd == NULL) + fprintf(fd, "Cannot open file!\n"); + else + { + // Keep going till the end of file, so that trailing + // continuation lines are listed. + for (i = 0; ; ++i) + { + if (vim_fgets(IObuff, IOSIZE, sfd)) + break; + // When a line has been truncated, append NL, taking care + // of multi-byte characters . + if (IObuff[IOSIZE - 2] != NUL && IObuff[IOSIZE - 2] != NL) + { + int n = IOSIZE - 2; + + if (enc_utf8) + { + // Move to the first byte of this char. + // utf_head_off() doesn't work, because it checks + // for a truncated character. + while (n > 0 && (IObuff[n] & 0xc0) == 0x80) + --n; + } + else if (has_mbyte) + n -= mb_head_off(IObuff, IObuff + n); + IObuff[n] = NL; + IObuff[n + 1] = NUL; + } + if (i < si->sn_prl_ga.ga_len + && (pp = &PRL_ITEM(si, i))->snp_count > 0) + { + fprintf(fd, "%5d ", pp->snp_count); + if (profile_equal(&pp->sn_prl_total, &pp->sn_prl_self)) + fprintf(fd, " "); + else + fprintf(fd, "%s ", profile_msg(&pp->sn_prl_total)); + fprintf(fd, "%s ", profile_msg(&pp->sn_prl_self)); + } + else + fprintf(fd, " "); + fprintf(fd, "%s", IObuff); + } + fclose(sfd); + } + fprintf(fd, "\n"); + } + } +} + +/* + * Dump the profiling info. + */ + void +profile_dump(void) +{ + FILE *fd; + + if (profile_fname != NULL) + { + fd = mch_fopen((char *)profile_fname, "w"); + if (fd == NULL) + semsg(_(e_notopen), profile_fname); + else + { + script_dump_profile(fd); + func_dump_profile(fd); + fclose(fd); + } + } +} + +/* + * Called when starting to read a script line. + * "sourcing_lnum" must be correct! + * When skipping lines it may not actually be executed, but we won't find out + * until later and we need to store the time now. + */ + void +script_line_start(void) +{ + scriptitem_T *si; + sn_prl_T *pp; + + if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) + return; + si = &SCRIPT_ITEM(current_sctx.sc_sid); + if (si->sn_prof_on && sourcing_lnum >= 1) + { + // Grow the array before starting the timer, so that the time spent + // here isn't counted. + (void)ga_grow(&si->sn_prl_ga, + (int)(sourcing_lnum - si->sn_prl_ga.ga_len)); + si->sn_prl_idx = sourcing_lnum - 1; + while (si->sn_prl_ga.ga_len <= si->sn_prl_idx + && si->sn_prl_ga.ga_len < si->sn_prl_ga.ga_maxlen) + { + // Zero counters for a line that was not used before. + pp = &PRL_ITEM(si, si->sn_prl_ga.ga_len); + pp->snp_count = 0; + profile_zero(&pp->sn_prl_total); + profile_zero(&pp->sn_prl_self); + ++si->sn_prl_ga.ga_len; + } + si->sn_prl_execed = FALSE; + profile_start(&si->sn_prl_start); + profile_zero(&si->sn_prl_children); + profile_get_wait(&si->sn_prl_wait); + } +} + +/* + * Called when actually executing a function line. + */ + void +script_line_exec(void) +{ + scriptitem_T *si; + + if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) + return; + si = &SCRIPT_ITEM(current_sctx.sc_sid); + if (si->sn_prof_on && si->sn_prl_idx >= 0) + si->sn_prl_execed = TRUE; +} + +/* + * Called when done with a script line. + */ + void +script_line_end(void) +{ + scriptitem_T *si; + sn_prl_T *pp; + + if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) + return; + si = &SCRIPT_ITEM(current_sctx.sc_sid); + if (si->sn_prof_on && si->sn_prl_idx >= 0 + && si->sn_prl_idx < si->sn_prl_ga.ga_len) + { + if (si->sn_prl_execed) + { + pp = &PRL_ITEM(si, si->sn_prl_idx); + ++pp->snp_count; + profile_end(&si->sn_prl_start); + profile_sub_wait(&si->sn_prl_wait, &si->sn_prl_start); + profile_add(&pp->sn_prl_total, &si->sn_prl_start); + profile_self(&pp->sn_prl_self, &si->sn_prl_start, + &si->sn_prl_children); + } + si->sn_prl_idx = -1; + } +} +# endif // FEAT_PROFILE + +#endif diff -Nru vim-8.1.1681/src/proto/buffer.pro vim-8.1.1729/src/proto/buffer.pro --- vim-8.1.1681/src/proto/buffer.pro 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/proto/buffer.pro 2019-07-21 21:04:21.000000000 +0000 @@ -27,6 +27,7 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options); buf_T *buflist_findnr(int nr); char_u *buflist_nr2name(int n, int fullname, int helptail); +void buflist_setfpos(buf_T *buf, win_T *win, linenr_T lnum, colnr_T col, int copy_options); void get_winopts(buf_T *buf); pos_T *buflist_findfpos(buf_T *buf); linenr_T buflist_findlnum(buf_T *buf); @@ -55,8 +56,6 @@ void do_arg_all(int count, int forceit, int keep_tabs); void ex_buffer_all(exarg_T *eap); void do_modelines(int flags); -int read_viminfo_bufferlist(vir_T *virp, int writing); -void write_viminfo_bufferlist(FILE *fp); int bt_normal(buf_T *buf); int bt_quickfix(buf_T *buf); int bt_terminal(buf_T *buf); diff -Nru vim-8.1.1681/src/proto/dict.pro vim-8.1.1729/src/proto/dict.pro --- vim-8.1.1681/src/proto/dict.pro 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/proto/dict.pro 2019-07-21 21:04:21.000000000 +0000 @@ -28,7 +28,7 @@ varnumber_T dict_get_number(dict_T *d, char_u *key); varnumber_T dict_get_number_check(dict_T *d, char_u *key); char_u *dict2string(typval_T *tv, int copyID, int restore_copyID); -int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate); +int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate, int literal); void dict_extend(dict_T *d1, dict_T *d2, char_u *action); dictitem_T *dict_lookup(hashitem_T *hi); int dict_equal(dict_T *d1, dict_T *d2, int ic, int recursive); diff -Nru vim-8.1.1681/src/proto/eval.pro vim-8.1.1729/src/proto/eval.pro --- vim-8.1.1681/src/proto/eval.pro 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/proto/eval.pro 2019-07-21 21:04:21.000000000 +0000 @@ -41,6 +41,7 @@ int do_unlet(char_u *name, int forceit); void del_menutrans_vars(void); char_u *get_user_var_name(expand_T *xp, int idx); +int pattern_match(char_u *pat, char_u *text, int ic); int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate); int eval1(char_u **arg, typval_T *rettv, int evaluate); int get_option_tv(char_u **arg, typval_T *rettv, int evaluate); @@ -67,6 +68,7 @@ int eval_isnamec(int c); int eval_isnamec1(int c); void set_vim_var_nr(int idx, varnumber_T val); +typval_T *get_vim_var_tv(int idx); varnumber_T get_vim_var_nr(int idx); char_u *get_vim_var_str(int idx); list_T *get_vim_var_list(int idx); @@ -124,23 +126,11 @@ void setwinvar(typval_T *argvars, typval_T *rettv, int off); char_u *autoload_name(char_u *name); int script_autoload(char_u *name, int reload); -int read_viminfo_varlist(vir_T *virp, int writing); -void write_viminfo_varlist(FILE *fp); +var_flavour_T var_flavour(char_u *varname); int store_session_globals(FILE *fd); void last_set_msg(sctx_T script_ctx); void reset_v_option_vars(void); -void prepare_assert_error(garray_T *gap); void assert_error(garray_T *gap); -int assert_equal_common(typval_T *argvars, assert_type_T atype); -int assert_equalfile(typval_T *argvars); -int assert_match_common(typval_T *argvars, assert_type_T atype); -int assert_inrange(typval_T *argvars); -int assert_bool(typval_T *argvars, int isTrue); -int assert_report(typval_T *argvars); -int assert_exception(typval_T *argvars); -int assert_beeps(typval_T *argvars); -int 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); int typval_compare(typval_T *typ1, typval_T *typ2, exptype_T type, int type_is, int ic); char_u *typval_tostring(typval_T *arg); int var_exists(char_u *var); diff -Nru vim-8.1.1681/src/proto/ex_cmds2.pro vim-8.1.1729/src/proto/ex_cmds2.pro --- vim-8.1.1681/src/proto/ex_cmds2.pro 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/proto/ex_cmds2.pro 2019-07-21 21:04:21.000000000 +0000 @@ -1,12 +1,4 @@ /* ex_cmds2.c */ -void profile_start(proftime_T *tm); -void profile_end(proftime_T *tm); -void profile_sub(proftime_T *tm, proftime_T *tm2); -char *profile_msg(proftime_T *tm); -float_T profile_float(proftime_T *tm); -void profile_setlimit(long msec, proftime_T *tm); -int profile_passed_limit(proftime_T *tm); -void profile_zero(proftime_T *tm); long proftime_time_left(proftime_T *due, proftime_T *now); timer_T *create_timer(long msec, int repeat); long check_due_timer(void); @@ -17,22 +9,6 @@ void add_timer_info_all(typval_T *rettv); int set_ref_in_timer(int copyID); void timer_free_all(void); -void profile_divide(proftime_T *tm, int count, proftime_T *tm2); -void profile_add(proftime_T *tm, proftime_T *tm2); -void profile_self(proftime_T *self, proftime_T *total, proftime_T *children); -void profile_get_wait(proftime_T *tm); -void profile_sub_wait(proftime_T *tm, proftime_T *tma); -int profile_equal(proftime_T *tm1, proftime_T *tm2); -int profile_cmp(const proftime_T *tm1, const proftime_T *tm2); -void ex_profile(exarg_T *eap); -char_u *get_profile_name(expand_T *xp, int idx); -void set_context_in_profile_cmd(expand_T *xp, char_u *arg); -void profile_dump(void); -void script_prof_save(proftime_T *tm); -void script_prof_restore(proftime_T *tm); -void prof_inchar_enter(void); -void prof_inchar_exit(void); -int prof_def_func(void); int autowrite(buf_T *buf, int forceit); void autowrite_all(void); int check_changed(buf_T *buf, int flags); @@ -83,9 +59,6 @@ void free_scriptnames(void); linenr_T get_sourced_lnum(char_u *(*fgetline)(int, void *, int, int), void *cookie); char_u *getsourceline(int c, void *cookie, int indent, int do_concat); -void script_line_start(void); -void script_line_exec(void); -void script_line_end(void); void ex_scriptencoding(exarg_T *eap); void ex_scriptversion(exarg_T *eap); void ex_finish(exarg_T *eap); diff -Nru vim-8.1.1681/src/proto/ex_cmds.pro vim-8.1.1729/src/proto/ex_cmds.pro --- vim-8.1.1681/src/proto/ex_cmds.pro 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/proto/ex_cmds.pro 2019-07-21 21:04:21.000000000 +0000 @@ -10,13 +10,6 @@ void do_shell(char_u *cmd, int flags); char_u *make_filter_cmd(char_u *cmd, char_u *itmp, char_u *otmp); void append_redir(char_u *buf, int buflen, char_u *opt, char_u *fname); -int viminfo_error(char *errnum, char *message, char_u *line); -int read_viminfo(char_u *file, int flags); -void write_viminfo(char_u *file, int forceit); -int viminfo_readline(vir_T *virp); -char_u *viminfo_readstring(vir_T *virp, int off, int convert); -void viminfo_writestring(FILE *fd, char_u *p); -int barline_writestring(FILE *fd, char_u *s, int remaining_start); time_T vim_time(void); void do_fixdel(exarg_T *eap); void print_line_no_prefix(linenr_T lnum, int use_number, int list); diff -Nru vim-8.1.1681/src/proto/ex_getln.pro vim-8.1.1729/src/proto/ex_getln.pro --- vim-8.1.1681/src/proto/ex_getln.pro 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/proto/ex_getln.pro 2019-07-21 21:04:21.000000000 +0000 @@ -34,7 +34,10 @@ int expand_cmdline(expand_T *xp, char_u *str, int col, int *matchcount, char_u ***matches); int ExpandGeneric(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file, char_u *((*func)(expand_T *, int)), int escaped); void globpath(char_u *path, char_u *file, garray_T *ga, int expand_options); +int hist_char2type(int c); void init_history(void); +void clear_hist_entry(histentry_T *hisptr); +int in_history(int type, char_u *str, int move_to_front, int sep, int writing); int get_histtype(char_u *name); void add_to_history(int histype, char_u *new_entry, int in_map, int sep); int get_history_idx(int histype); @@ -49,10 +52,10 @@ int get_cmdline_type(void); int get_list_range(char_u **str, int *num1, int *num2); void ex_history(exarg_T *eap); -void prepare_viminfo_history(int asklen, int writing); -int read_viminfo_history(vir_T *virp, int writing); -void handle_viminfo_history(garray_T *values, int writing); -void finish_viminfo_history(vir_T *virp); -void write_viminfo_history(FILE *fp, int merge); +int get_hislen(void); +histentry_T *get_histentry(int hist_type); +void set_histentry(int hist_type, histentry_T *entry); +int *get_hisidx(int hist_type); +int *get_hisnum(int hist_type); char_u *script_get(exarg_T *eap, char_u *cmd); /* vim: set ft=c : */ diff -Nru vim-8.1.1681/src/proto/highlight.pro vim-8.1.1729/src/proto/highlight.pro --- vim-8.1.1681/src/proto/highlight.pro 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/proto/highlight.pro 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,46 @@ +/* highlight.c */ +int highlight_num_groups(void); +char_u *highlight_group_name(int id); +int highlight_link_id(int id); +void init_highlight(int both, int reset); +int load_colors(char_u *name); +int lookup_color(int idx, int foreground, int *boldp); +void do_highlight(char_u *line, int forceit, int init); +void free_highlight(void); +void restore_cterm_colors(void); +void set_normal_colors(void); +char_u *hl_get_font_name(void); +void hl_set_font_name(char_u *font_name); +void hl_set_bg_color_name(char_u *name); +void hl_set_fg_color_name(char_u *name); +guicolor_T color_name2handle(char_u *name); +int get_cterm_attr_idx(int attr, int fg, int bg); +int get_tgc_attr_idx(int attr, guicolor_T fg, guicolor_T bg); +int get_gui_attr_idx(int attr, guicolor_T fg, guicolor_T bg); +void clear_hl_tables(void); +int hl_combine_attr(int char_attr, int prim_attr); +attrentry_T *syn_gui_attr2entry(int attr); +int syn_attr2attr(int attr); +attrentry_T *syn_term_attr2entry(int attr); +attrentry_T *syn_cterm_attr2entry(int attr); +char_u *highlight_has_attr(int id, int flag, int modec); +char_u *highlight_color(int id, char_u *what, int modec); +long_u highlight_gui_color_rgb(int id, int fg); +int syn_list_header(int did_header, int outlen, int id); +int syn_name2id(char_u *name); +int syn_name2attr(char_u *name); +int highlight_exists(char_u *name); +char_u *syn_id2name(int id); +int syn_namen2id(char_u *linep, int len); +int syn_check_group(char_u *pp, int len); +int syn_id2attr(int hl_id); +int syn_id2colors(int hl_id, guicolor_T *fgp, guicolor_T *bgp); +void syn_id2cterm_bg(int hl_id, int *fgp, int *bgp); +int syn_get_final_id(int hl_id); +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 : */ diff -Nru vim-8.1.1681/src/proto/popupwin.pro vim-8.1.1729/src/proto/popupwin.pro --- vim-8.1.1681/src/proto/popupwin.pro 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/proto/popupwin.pro 2019-07-21 21:04:21.000000000 +0000 @@ -8,6 +8,8 @@ int popup_height(win_T *wp); int popup_width(win_T *wp); void popup_adjust_position(win_T *wp); +int parse_previewpopup(win_T *wp); +void popup_set_wantpos(win_T *wp); void f_popup_clear(typval_T *argvars, typval_T *rettv); void f_popup_create(typval_T *argvars, typval_T *rettv); void f_popup_atcursor(typval_T *argvars, typval_T *rettv); @@ -39,4 +41,8 @@ void may_update_popup_mask(int type); void update_popups(void (*win_update)(win_T *wp)); int set_ref_in_popups(int copyID); +win_T *popup_find_preview_window(void); +int popup_is_popup(win_T *wp); +int popup_create_preview_window(void); +void popup_close_preview(void); /* vim: set ft=c : */ diff -Nru vim-8.1.1681/src/proto/profiler.pro vim-8.1.1729/src/proto/profiler.pro --- vim-8.1.1681/src/proto/profiler.pro 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/proto/profiler.pro 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,36 @@ +/* profiler.c */ +void profile_start(proftime_T *tm); +void profile_end(proftime_T *tm); +void profile_sub(proftime_T *tm, proftime_T *tm2); +char *profile_msg(proftime_T *tm); +float_T profile_float(proftime_T *tm); +void profile_setlimit(long msec, proftime_T *tm); +int profile_passed_limit(proftime_T *tm); +void profile_zero(proftime_T *tm); +void profile_divide(proftime_T *tm, int count, proftime_T *tm2); +void profile_add(proftime_T *tm, proftime_T *tm2); +void profile_self(proftime_T *self, proftime_T *total, proftime_T *children); +void profile_get_wait(proftime_T *tm); +void profile_sub_wait(proftime_T *tm, proftime_T *tma); +int profile_equal(proftime_T *tm1, proftime_T *tm2); +int profile_cmp(const proftime_T *tm1, const proftime_T *tm2); +void ex_profile(exarg_T *eap); +char_u *get_profile_name(expand_T *xp, int idx); +void set_context_in_profile_cmd(expand_T *xp, char_u *arg); +void prof_inchar_enter(void); +void prof_inchar_exit(void); +int prof_def_func(void); +void func_do_profile(ufunc_T *fp); +void prof_child_enter(proftime_T *tm); +void prof_child_exit(proftime_T *tm); +void func_line_start(void *cookie); +void func_line_exec(void *cookie); +void func_line_end(void *cookie); +void script_do_profile(scriptitem_T *si); +void script_prof_save(proftime_T *tm); +void script_prof_restore(proftime_T *tm); +void profile_dump(void); +void script_line_start(void); +void script_line_exec(void); +void script_line_end(void); +/* vim: set ft=c : */ diff -Nru vim-8.1.1681/src/proto/sign.pro vim-8.1.1729/src/proto/sign.pro --- vim-8.1.1681/src/proto/sign.pro 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/proto/sign.pro 2019-07-21 21:04:21.000000000 +0000 @@ -9,7 +9,9 @@ void buf_delete_signs(buf_T *buf, char_u *group); void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after); int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl); -int sign_undefine_by_name(char_u *name); +int sign_exists_by_name(char_u *name); +int sign_undefine_by_name(char_u *name, int give_error); +int sign_place(int *sign_id, char_u *sign_group, char_u *sign_name, buf_T *buf, linenr_T lnum, int prio); void ex_sign(exarg_T *eap); void get_buffer_signs(buf_T *buf, list_T *l); void sign_gui_started(void); @@ -22,6 +24,8 @@ void f_sign_getplaced(typval_T *argvars, typval_T *rettv); void f_sign_jump(typval_T *argvars, typval_T *rettv); void f_sign_place(typval_T *argvars, typval_T *rettv); +void f_sign_placelist(typval_T *argvars, typval_T *rettv); void f_sign_undefine(typval_T *argvars, typval_T *rettv); void f_sign_unplace(typval_T *argvars, typval_T *rettv); +void f_sign_unplacelist(typval_T *argvars, typval_T *rettv); /* vim: set ft=c : */ diff -Nru vim-8.1.1681/src/proto/syntax.pro vim-8.1.1729/src/proto/syntax.pro --- vim-8.1.1681/src/proto/syntax.pro 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/proto/syntax.pro 2019-07-21 21:04:21.000000000 +0000 @@ -22,44 +22,4 @@ int syn_get_foldlevel(win_T *wp, long lnum); void ex_syntime(exarg_T *eap); char_u *get_syntime_arg(expand_T *xp, int idx); -void init_highlight(int both, int reset); -int load_colors(char_u *name); -int lookup_color(int idx, int foreground, int *boldp); -void do_highlight(char_u *line, int forceit, int init); -void free_highlight(void); -void restore_cterm_colors(void); -void set_normal_colors(void); -char_u *hl_get_font_name(void); -void hl_set_font_name(char_u *font_name); -void hl_set_bg_color_name(char_u *name); -void hl_set_fg_color_name(char_u *name); -guicolor_T color_name2handle(char_u *name); -int get_cterm_attr_idx(int attr, int fg, int bg); -int get_tgc_attr_idx(int attr, guicolor_T fg, guicolor_T bg); -int get_gui_attr_idx(int attr, guicolor_T fg, guicolor_T bg); -void clear_hl_tables(void); -int hl_combine_attr(int char_attr, int prim_attr); -attrentry_T *syn_gui_attr2entry(int attr); -int syn_attr2attr(int attr); -attrentry_T *syn_term_attr2entry(int attr); -attrentry_T *syn_cterm_attr2entry(int attr); -char_u *highlight_has_attr(int id, int flag, int modec); -char_u *highlight_color(int id, char_u *what, int modec); -long_u highlight_gui_color_rgb(int id, int fg); -int syn_name2id(char_u *name); -int syn_name2attr(char_u *name); -int highlight_exists(char_u *name); -char_u *syn_id2name(int id); -int syn_namen2id(char_u *linep, int len); -int syn_check_group(char_u *pp, int len); -int syn_id2attr(int hl_id); -int syn_id2colors(int hl_id, guicolor_T *fgp, guicolor_T *bgp); -void syn_id2cterm_bg(int hl_id, int *fgp, int *bgp); -int syn_get_final_id(int hl_id); -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 : */ diff -Nru vim-8.1.1681/src/proto/testing.pro vim-8.1.1729/src/proto/testing.pro --- vim-8.1.1681/src/proto/testing.pro 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/proto/testing.pro 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,34 @@ +/* testing.c */ +void f_assert_beeps(typval_T *argvars, typval_T *rettv); +void f_assert_equal(typval_T *argvars, typval_T *rettv); +void f_assert_equalfile(typval_T *argvars, typval_T *rettv); +void f_assert_notequal(typval_T *argvars, typval_T *rettv); +void f_assert_exception(typval_T *argvars, typval_T *rettv); +void f_assert_fails(typval_T *argvars, typval_T *rettv); +void f_assert_false(typval_T *argvars, typval_T *rettv); +void f_assert_inrange(typval_T *argvars, typval_T *rettv); +void f_assert_match(typval_T *argvars, typval_T *rettv); +void f_assert_notmatch(typval_T *argvars, typval_T *rettv); +void f_assert_report(typval_T *argvars, typval_T *rettv); +void f_assert_true(typval_T *argvars, typval_T *rettv); +void f_test_alloc_fail(typval_T *argvars, typval_T *rettv); +void f_test_autochdir(typval_T *argvars, typval_T *rettv); +void f_test_feedinput(typval_T *argvars, typval_T *rettv); +void f_test_getvalue(typval_T *argvars, typval_T *rettv); +void f_test_option_not_set(typval_T *argvars, typval_T *rettv); +void f_test_override(typval_T *argvars, typval_T *rettv); +void f_test_refcount(typval_T *argvars, typval_T *rettv); +void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv); +void f_test_garbagecollect_soon(typval_T *argvars, typval_T *rettv); +void f_test_ignore_error(typval_T *argvars, typval_T *rettv); +void f_test_null_blob(typval_T *argvars, typval_T *rettv); +void f_test_null_channel(typval_T *argvars, typval_T *rettv); +void f_test_null_dict(typval_T *argvars, typval_T *rettv); +void f_test_null_job(typval_T *argvars, typval_T *rettv); +void f_test_null_list(typval_T *argvars, typval_T *rettv); +void f_test_null_partial(typval_T *argvars, typval_T *rettv); +void f_test_null_string(typval_T *argvars, typval_T *rettv); +void f_test_scrollbar(typval_T *argvars, typval_T *rettv); +void f_test_setmouse(typval_T *argvars, typval_T *rettv); +void f_test_settime(typval_T *argvars, typval_T *rettv); +/* vim: set ft=c : */ diff -Nru vim-8.1.1681/src/proto/userfunc.pro vim-8.1.1729/src/proto/userfunc.pro --- vim-8.1.1681/src/proto/userfunc.pro 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/proto/userfunc.pro 2019-07-21 21:04:21.000000000 +0000 @@ -1,11 +1,13 @@ /* userfunc.c */ void func_init(void); +hashtab_T *func_tbl_get(void); int get_lambda_tv(char_u **arg, typval_T *rettv, int evaluate); char_u *deref_func_name(char_u *name, int *lenp, partial_T **partialp, int no_autoload); int get_func_tv(char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, partial_T *partial, dict_T *selfdict); ufunc_T *find_func(char_u *name); void save_funccal(funccal_entry_T *entry); void restore_funccal(void); +funccall_T *get_current_funccal(void); void free_all_functions(void); int func_call(char_u *name, typval_T *args, partial_T *partial, dict_T *selfdict, typval_T *rettv); int call_callback(callback_T *callback, int len, typval_T *rettv, int argcount, typval_T *argvars, int (*argv_func)(int, typval_T *, int), linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict); @@ -16,9 +18,6 @@ int translated_function_exists(char_u *name); int function_exists(char_u *name, int no_deref); char_u *get_expanded_name(char_u *name, int check); -void func_dump_profile(FILE *fd); -void prof_child_enter(proftime_T *tm); -void prof_child_exit(proftime_T *tm); char_u *get_user_func_name(expand_T *xp, int idx); void ex_delfunction(exarg_T *eap); void func_unref(char_u *name); @@ -31,9 +30,6 @@ void discard_pending_return(void *rettv); char_u *get_return_cmd(void *rettv); char_u *get_func_line(int c, void *cookie, int indent, int do_concat); -void func_line_start(void *cookie); -void func_line_exec(void *cookie); -void func_line_end(void *cookie); int func_has_ended(void *cookie); int func_has_abort(void *cookie); dict_T *make_partial(dict_T *selfdict_in, typval_T *rettv); diff -Nru vim-8.1.1681/src/proto/viminfo.pro vim-8.1.1729/src/proto/viminfo.pro --- vim-8.1.1681/src/proto/viminfo.pro 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/proto/viminfo.pro 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,10 @@ +/* viminfo.c */ +int viminfo_error(char *errnum, char *message, char_u *line); +int read_viminfo(char_u *file, int flags); +void write_viminfo(char_u *file, int forceit); +int viminfo_readline(vir_T *virp); +char_u *viminfo_readstring(vir_T *virp, int off, int convert); +void viminfo_writestring(FILE *fd, char_u *p); +int barline_writestring(FILE *fd, char_u *s, int remaining_start); +void ex_viminfo(exarg_T *eap); +/* vim: set ft=c : */ diff -Nru vim-8.1.1681/src/proto.h vim-8.1.1729/src/proto.h --- vim-8.1.1681/src/proto.h 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/proto.h 2019-07-21 21:04:21.000000000 +0000 @@ -89,6 +89,7 @@ # endif # include "hardcopy.pro" # include "hashtab.pro" +# include "highlight.pro" # include "indent.pro" # ifdef FEAT_INS_EXPAND # include "insexpand.pro" @@ -106,6 +107,9 @@ # ifdef FEAT_ARABIC # include "arabic.pro" # endif +# ifdef FEAT_VIMINFO +# include "viminfo.pro" +# endif /* These prototypes cannot be produced automatically. */ int smsg(const char *, ...) @@ -171,6 +175,9 @@ # include "ops.pro" # include "option.pro" # include "popupmnu.pro" +# if defined(FEAT_PROFILE) || defined(FEAT_RELTIME) +# include "profiler.pro" +# endif # ifdef FEAT_QUICKFIX # include "quickfix.pro" # endif @@ -199,6 +206,7 @@ # include "popupwin.pro" # include "textprop.pro" # endif +# include "testing.pro" # include "ui.pro" # include "undo.pro" # include "usercmd.pro" diff -Nru vim-8.1.1681/src/README.md vim-8.1.1729/src/README.md --- vim-8.1.1681/src/README.md 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/README.md 2019-07-21 21:04:21.000000000 +0000 @@ -21,8 +21,8 @@ Most code can be found in a file with an obvious name (incomplete list): -File name | Description ---------- | ----------- +File name | Description +--------------- | ----------- autocmd.c | autocommands buffer.c | manipulating buffers (loaded files) change.c | handling changes to text @@ -34,6 +34,7 @@ findfile.c | search for files in 'path' fold.c | folding getchar.c | getting characters and key mapping +highlight.c | syntax highlighting indent.c | C and Lisp indentation insexpand.c | Insert mode completion mark.c | marks @@ -44,15 +45,20 @@ message.c | (error) messages ops.c | handling operators ("d", "y", "p") option.c | options +popupmnu.c | popup menu +popupwin.c | popup window +profiler.c | vim script profiler quickfix.c | quickfix commands (":make", ":cn") regexp.c | pattern matching screen.c | updating the windows search.c | pattern searching sign.c | signs spell.c | spell checking -syntax.c | syntax and other highlighting +syntax.c | syntax and other highlighting tag.c | tags term.c | terminal handling, termcap codes +testing.c | testing: assert and test functions +textprop.c | text properties undo.c | undo and redo usercmd.c | user defined commands userfunc.c | user defined functions diff -Nru vim-8.1.1681/src/regexp.c vim-8.1.1729/src/regexp.c --- vim-8.1.1681/src/regexp.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/regexp.c 2019-07-21 21:04:21.000000000 +0000 @@ -2175,7 +2175,11 @@ if (ret == NULL) ret = br; else + { regtail(lastnode, br); + if (reg_toolong) + return NULL; + } ungetchr(); one_exactly = TRUE; @@ -2200,6 +2204,8 @@ if (OP(br) == BRANCH) { regtail(br, lastbranch); + if (reg_toolong) + return NULL; br = OPERAND(br); } else diff -Nru vim-8.1.1681/src/screen.c vim-8.1.1729/src/screen.c --- vim-8.1.1681/src/screen.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/screen.c 2019-07-21 21:04:21.000000000 +0000 @@ -167,11 +167,6 @@ /* Ugly global: overrule attribute used by screen_char() */ static int screen_char_attr = 0; -#if defined(FEAT_SYN_HL) && defined(FEAT_RELTIME) -/* Can limit syntax highlight time to 'redrawtime'. */ -# define SYN_TIME_LIMIT 1 -#endif - #ifdef FEAT_RIGHTLEFT # define HAS_RIGHTLEFT(x) x #else @@ -3120,8 +3115,13 @@ { if (nrcol) { - sprintf((char *)extra, "%*s ", number_width(wp), - *pp_extra); + int n, width = number_width(wp) - 2; + + for (n = 0; n < width; n++) + extra[n] = ' '; + extra[n] = 0; + STRCAT(extra, *pp_extra); + STRCAT(extra, " "); *pp_extra = extra; } *c_extrap = NUL; @@ -3214,10 +3214,10 @@ int syntax_attr = 0; /* attributes desired by syntax */ int has_syntax = FALSE; /* this buffer has syntax highl. */ int save_did_emsg; - int eol_hl_off = 0; /* 1 if highlighted char after EOL */ int draw_color_col = FALSE; /* highlight colorcolumn */ int *color_cols = NULL; /* pointer to according columns array */ #endif + int eol_hl_off = 0; /* 1 if highlighted char after EOL */ #ifdef FEAT_TEXT_PROP int text_prop_count; int text_prop_next = 0; // next text property to use @@ -5361,6 +5361,8 @@ if (wp->w_p_cul && lnum == wp->w_cursor.lnum) char_attr = hl_combine_attr(char_attr, HL_ATTR(HLF_CUL)); + else if (line_attr) + char_attr = hl_combine_attr(char_attr, line_attr); } # endif } @@ -5552,11 +5554,11 @@ /* * At end of the text line or just after the last character. */ - if (c == NUL + if ((c == NUL #if defined(LINE_ATTR) || did_line_attr == 1 #endif - ) + ) && eol_hl_off == 0) { #ifdef FEAT_SEARCH_EXTRA long prevcol = (long)(ptr - line) - (c == NUL); @@ -5682,9 +5684,7 @@ ++off; } ++vcol; -#ifdef FEAT_SYN_HL eol_hl_off = 1; -#endif } } diff -Nru vim-8.1.1681/src/sign.c vim-8.1.1729/src/sign.c --- vim-8.1.1681/src/sign.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/sign.c 2019-07-21 21:04:21.000000000 +0000 @@ -442,7 +442,8 @@ buf_T *buf, // buffer to store sign in int markId, // sign ID char_u *group, // sign group - int typenr) // typenr of sign we are adding + int typenr, // typenr of sign we are adding + int prio) // sign priority { signlist_T *sign; // a sign in the signlist @@ -451,6 +452,8 @@ if (sign->id == markId && sign_in_group(sign, group)) { sign->typenr = typenr; + sign->priority = prio; + sign_sort_by_prio_on_line(buf, sign); return sign->lnum; } } @@ -1022,10 +1025,19 @@ } /* + * Return TRUE if sign "name" exists. + */ + int +sign_exists_by_name(char_u *name) +{ + return sign_find(name, NULL) != NULL; +} + +/* * Free the sign specified by 'name'. */ int -sign_undefine_by_name(char_u *name) +sign_undefine_by_name(char_u *name, int give_error) { sign_T *sp_prev; sign_T *sp; @@ -1033,7 +1045,8 @@ sp = sign_find(name, &sp_prev); if (sp == NULL) { - semsg(_("E155: Unknown sign: %s"), name); + if (give_error) + semsg(_("E155: Unknown sign: %s"), name); return FAIL; } sign_undefine(sp, sp_prev); @@ -1073,7 +1086,7 @@ /* * Place a sign at the specified file location or update a sign. */ - static int + int sign_place( int *sign_id, char_u *sign_group, @@ -1104,8 +1117,9 @@ // place a sign buf_addsign(buf, *sign_id, sign_group, prio, lnum, sp->sn_typenr); else - // ":sign place {id} file={fname}": change sign type - lnum = buf_change_sign_type(buf, *sign_id, sign_group, sp->sn_typenr); + // ":sign place {id} file={fname}": change sign type and/or priority + lnum = buf_change_sign_type(buf, *sign_id, sign_group, sp->sn_typenr, + prio); if (lnum > 0) { redraw_buf_line_later(buf, lnum); @@ -1587,7 +1601,7 @@ sign_list_by_name(name); else // ":sign undefine {name}" - sign_undefine_by_name(name); + sign_undefine_by_name(name, TRUE); vim_free(name); return; @@ -2096,51 +2110,104 @@ # endif /* - * "sign_define()" function + * Define a sign using the attributes in 'dict'. Returns 0 on success and -1 on + * failure. */ - void -f_sign_define(typval_T *argvars, typval_T *rettv) + static int +sign_define_from_dict(char_u *name_arg, dict_T *dict) { - char_u *name; - dict_T *dict; + char_u *name = NULL; char_u *icon = NULL; char_u *linehl = NULL; char_u *text = NULL; char_u *texthl = NULL; + int retval = -1; - rettv->vval.v_number = -1; - - name = tv_get_string_chk(&argvars[0]); - if (name == NULL) - return; - - if (argvars[1].v_type != VAR_UNKNOWN) + if (name_arg == NULL) { - if (argvars[1].v_type != VAR_DICT) - { - emsg(_(e_dictreq)); - return; - } - - // sign attributes - dict = argvars[1].vval.v_dict; - if (dict_find(dict, (char_u *)"icon", -1) != NULL) - icon = dict_get_string(dict, (char_u *)"icon", TRUE); - if (dict_find(dict, (char_u *)"linehl", -1) != NULL) - linehl = dict_get_string(dict, (char_u *)"linehl", TRUE); - if (dict_find(dict, (char_u *)"text", -1) != NULL) - text = dict_get_string(dict, (char_u *)"text", TRUE); - if (dict_find(dict, (char_u *)"texthl", -1) != NULL) - texthl = dict_get_string(dict, (char_u *)"texthl", TRUE); + if (dict == NULL) + return -1; + name = dict_get_string(dict, (char_u *)"name", TRUE); + } + else + name = vim_strsave(name_arg); + if (name == NULL || name[0] == NUL) + goto cleanup; + if (dict != NULL) + { + icon = dict_get_string(dict, (char_u *)"icon", TRUE); + linehl = dict_get_string(dict, (char_u *)"linehl", TRUE); + text = dict_get_string(dict, (char_u *)"text", TRUE); + texthl = dict_get_string(dict, (char_u *)"texthl", TRUE); } if (sign_define_by_name(name, icon, linehl, text, texthl) == OK) - rettv->vval.v_number = 0; + retval = 0; +cleanup: + vim_free(name); vim_free(icon); vim_free(linehl); vim_free(text); vim_free(texthl); + + return retval; +} + +/* + * Define multiple signs using attributes from list 'l' and store the return + * values in 'retlist'. + */ + static void +sign_define_multiple(list_T *l, list_T *retlist) +{ + listitem_T *li; + int retval; + + for (li = l->lv_first; li != NULL; li = li->li_next) + { + retval = -1; + if (li->li_tv.v_type == VAR_DICT) + retval = sign_define_from_dict(NULL, li->li_tv.vval.v_dict); + else + emsg(_(e_dictreq)); + list_append_number(retlist, retval); + } +} + +/* + * "sign_define()" function + */ + void +f_sign_define(typval_T *argvars, typval_T *rettv) +{ + char_u *name; + + if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_UNKNOWN) + { + // Define multiple signs + if (rettv_list_alloc(rettv) != OK) + return; + + sign_define_multiple(argvars[0].vval.v_list, rettv->vval.v_list); + return; + } + + // Define a single sign + rettv->vval.v_number = -1; + + name = tv_get_string_chk(&argvars[0]); + if (name == NULL) + return; + + if (argvars[1].v_type != VAR_UNKNOWN && argvars[1].v_type != VAR_DICT) + { + emsg(_(e_dictreq)); + return; + } + + rettv->vval.v_number = sign_define_from_dict(name, + argvars[1].v_type == VAR_DICT ? argvars[1].vval.v_dict : NULL); } /* @@ -2269,87 +2336,196 @@ } /* - * "sign_place()" function + * Place a new sign using the values specified in dict 'dict'. Returns the sign + * identifier if successfully placed, otherwise returns 0. */ - void -f_sign_place(typval_T *argvars, typval_T *rettv) + static int +sign_place_from_dict( + typval_T *id_tv, + typval_T *group_tv, + typval_T *name_tv, + typval_T *buf_tv, + dict_T *dict) { - int sign_id; + int sign_id = 0; char_u *group = NULL; - char_u *sign_name; - buf_T *buf; - dict_T *dict; + char_u *sign_name = NULL; + buf_T *buf = NULL; dictitem_T *di; linenr_T lnum = 0; int prio = SIGN_DEF_PRIO; int notanum = FALSE; + int ret_sign_id = -1; - rettv->vval.v_number = -1; - - // Sign identifier - sign_id = (int)tv_get_number_chk(&argvars[0], ¬anum); - if (notanum) - return; - if (sign_id < 0) + // sign identifier + if (id_tv == NULL) { - emsg(_(e_invarg)); - return; + di = dict_find(dict, (char_u *)"id", -1); + if (di != NULL) + id_tv = &di->di_tv; + } + if (id_tv == NULL) + sign_id = 0; + else + { + sign_id = tv_get_number_chk(id_tv, ¬anum); + if (notanum) + return -1; + if (sign_id < 0) + { + emsg(_(e_invarg)); + return -1; + } } - // Sign group - group = tv_get_string_chk(&argvars[1]); - if (group == NULL) - return; - if (group[0] == '\0') - group = NULL; // global sign group + // sign group + if (group_tv == NULL) + { + di = dict_find(dict, (char_u *)"group", -1); + if (di != NULL) + group_tv = &di->di_tv; + } + if (group_tv == NULL) + group = NULL; // global group else { - group = vim_strsave(group); + group = tv_get_string_chk(group_tv); if (group == NULL) - return; + goto cleanup; + if (group[0] == '\0') // global sign group + group = NULL; + else + { + group = vim_strsave(group); + if (group == NULL) + return -1; + } } - // Sign name - sign_name = tv_get_string_chk(&argvars[2]); + // sign name + if (name_tv == NULL) + { + di = dict_find(dict, (char_u *)"name", -1); + if (di != NULL) + name_tv = &di->di_tv; + } + if (name_tv == NULL) + goto cleanup; + sign_name = tv_get_string_chk(name_tv); if (sign_name == NULL) goto cleanup; - // Buffer to place the sign - buf = get_buf_arg(&argvars[3]); + // buffer to place the sign + if (buf_tv == NULL) + { + di = dict_find(dict, (char_u *)"buffer", -1); + if (di != NULL) + buf_tv = &di->di_tv; + } + if (buf_tv == NULL) + goto cleanup; + buf = get_buf_arg(buf_tv); if (buf == NULL) goto cleanup; - if (argvars[4].v_type != VAR_UNKNOWN) + // line number of the sign + di = dict_find(dict, (char_u *)"lnum", -1); + if (di != NULL) { - if (argvars[4].v_type != VAR_DICT || - ((dict = argvars[4].vval.v_dict) == NULL)) - { - emsg(_(e_dictreq)); + lnum = (int)tv_get_number_chk(&di->di_tv, ¬anum); + if (notanum) goto cleanup; - } + } - // Line number where the sign is to be placed - if ((di = dict_find(dict, (char_u *)"lnum", -1)) != NULL) - { - (void)tv_get_number_chk(&di->di_tv, ¬anum); - if (notanum) - goto cleanup; - lnum = tv_get_lnum(&di->di_tv); - } - if ((di = dict_find(dict, (char_u *)"priority", -1)) != NULL) - { - // Sign priority - prio = (int)tv_get_number_chk(&di->di_tv, ¬anum); - if (notanum) - goto cleanup; - } + // sign priority + di = dict_find(dict, (char_u *)"priority", -1); + if (di != NULL) + { + prio = (int)tv_get_number_chk(&di->di_tv, ¬anum); + if (notanum) + goto cleanup; } if (sign_place(&sign_id, group, sign_name, buf, lnum, prio) == OK) - rettv->vval.v_number = sign_id; + ret_sign_id = sign_id; cleanup: vim_free(group); + + return ret_sign_id; +} + +/* + * "sign_place()" function + */ + void +f_sign_place(typval_T *argvars, typval_T *rettv) +{ + dict_T *dict = NULL; + + rettv->vval.v_number = -1; + + if (argvars[4].v_type != VAR_UNKNOWN + && (argvars[4].v_type != VAR_DICT + || ((dict = argvars[4].vval.v_dict) == NULL))) + { + emsg(_(e_dictreq)); + return; + } + + rettv->vval.v_number = sign_place_from_dict(&argvars[0], &argvars[1], + &argvars[2], &argvars[3], dict); +} + +/* + * "sign_placelist()" function. Place multiple signs. + */ + void +f_sign_placelist(typval_T *argvars, typval_T *rettv) +{ + listitem_T *li; + int sign_id; + + if (rettv_list_alloc(rettv) != OK) + return; + + if (argvars[0].v_type != VAR_LIST) + { + emsg(_(e_listreq)); + return; + } + + // Process the List of sign attributes + for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) + { + sign_id = -1; + if (li->li_tv.v_type == VAR_DICT) + sign_id = sign_place_from_dict(NULL, NULL, NULL, NULL, + li->li_tv.vval.v_dict); + else + emsg(_(e_dictreq)); + list_append_number(rettv->vval.v_list, sign_id); + } +} + +/* + * Undefine multiple signs + */ + static void +sign_undefine_multiple(list_T *l, list_T *retlist) +{ + char_u *name; + listitem_T *li; + int retval; + + for (li = l->lv_first; li != NULL; li = li->li_next) + { + retval = -1; + name = tv_get_string_chk(&li->li_tv); + if (name != NULL && (sign_undefine_by_name(name, TRUE) == OK)) + retval = 0; + list_append_number(retlist, retval); + } } /* @@ -2360,6 +2536,16 @@ { char_u *name; + if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_UNKNOWN) + { + // Undefine multiple signs + if (rettv_list_alloc(rettv) != OK) + return; + + sign_undefine_multiple(argvars[0].vval.v_list, rettv->vval.v_list); + return; + } + rettv->vval.v_number = -1; if (argvars[0].v_type == VAR_UNKNOWN) @@ -2375,50 +2561,43 @@ if (name == NULL) return; - if (sign_undefine_by_name(name) == OK) + if (sign_undefine_by_name(name, TRUE) == OK) rettv->vval.v_number = 0; } } /* - * "sign_unplace()" function + * Unplace the sign with attributes specified in 'dict'. Returns 0 on success + * and -1 on failure. */ - void -f_sign_unplace(typval_T *argvars, typval_T *rettv) + static int +sign_unplace_from_dict(typval_T *group_tv, dict_T *dict) { - dict_T *dict; dictitem_T *di; int sign_id = 0; buf_T *buf = NULL; char_u *group = NULL; + int retval = -1; - rettv->vval.v_number = -1; - - if (argvars[0].v_type != VAR_STRING) - { - emsg(_(e_invarg)); - return; - } - - group = tv_get_string(&argvars[0]); - if (group[0] == '\0') - group = NULL; // global sign group + // sign group + if (group_tv != NULL) + group = tv_get_string(group_tv); else + group = dict_get_string(dict, (char_u *)"group", FALSE); + if (group != NULL) { - group = vim_strsave(group); - if (group == NULL) - return; - } - - if (argvars[1].v_type != VAR_UNKNOWN) - { - if (argvars[1].v_type != VAR_DICT) + if (group[0] == '\0') // global sign group + group = NULL; + else { - emsg(_(e_dictreq)); - goto cleanup; + group = vim_strsave(group); + if (group == NULL) + return -1; } - dict = argvars[1].vval.v_dict; + } + if (dict != NULL) + { if ((di = dict_find(dict, (char_u *)"buffer", -1)) != NULL) { buf = get_buf_arg(&di->di_tv); @@ -2426,24 +2605,89 @@ goto cleanup; } if (dict_find(dict, (char_u *)"id", -1) != NULL) + { sign_id = dict_get_number(dict, (char_u *)"id"); + if (sign_id <= 0) + { + emsg(_(e_invarg)); + goto cleanup; + } + } } if (buf == NULL) { // Delete the sign in all the buffers + retval = 0; FOR_ALL_BUFFERS(buf) - if (sign_unplace(sign_id, group, buf, 0) == OK) - rettv->vval.v_number = 0; - } - else - { - if (sign_unplace(sign_id, group, buf, 0) == OK) - rettv->vval.v_number = 0; + if (sign_unplace(sign_id, group, buf, 0) != OK) + retval = -1; } + else if (sign_unplace(sign_id, group, buf, 0) == OK) + retval = 0; cleanup: vim_free(group); + + return retval; +} + +/* + * "sign_unplace()" function + */ + void +f_sign_unplace(typval_T *argvars, typval_T *rettv) +{ + dict_T *dict = NULL; + + rettv->vval.v_number = -1; + + if (argvars[0].v_type != VAR_STRING) + { + emsg(_(e_invarg)); + return; + } + + if (argvars[1].v_type != VAR_UNKNOWN) + { + if (argvars[1].v_type != VAR_DICT) + { + emsg(_(e_dictreq)); + return; + } + dict = argvars[1].vval.v_dict; + } + + rettv->vval.v_number = sign_unplace_from_dict(&argvars[0], dict); +} + +/* + * "sign_unplacelist()" function + */ + void +f_sign_unplacelist(typval_T *argvars, typval_T *rettv) +{ + listitem_T *li; + int retval; + + if (rettv_list_alloc(rettv) != OK) + return; + + if (argvars[0].v_type != VAR_LIST) + { + emsg(_(e_listreq)); + return; + } + + for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) + { + retval = -1; + if (li->li_tv.v_type == VAR_DICT) + retval = sign_unplace_from_dict(NULL, li->li_tv.vval.v_dict); + else + emsg(_(e_dictreq)); + list_append_number(rettv->vval.v_list, retval); + } } #endif /* FEAT_SIGNS */ diff -Nru vim-8.1.1681/src/spell.c vim-8.1.1729/src/spell.c --- vim-8.1.1681/src/spell.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/spell.c 2019-07-21 21:04:21.000000000 +0000 @@ -3077,7 +3077,7 @@ if (wp->w_s->b_cjk) /* East Asian characters are not considered word characters. */ return cl == 2 || cl == 0x2800; - return cl >= 2 && cl != 0x2070 && cl != 0x2080; + return cl >= 2 && cl != 0x2070 && cl != 0x2080 && cl != 3; } /* diff -Nru vim-8.1.1681/src/structs.h vim-8.1.1729/src/structs.h --- vim-8.1.1681/src/structs.h 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/structs.h 2019-07-21 21:04:21.000000000 +0000 @@ -999,6 +999,8 @@ }; #endif // FEAT_SYN_HL +#define MAX_HL_ID 20000 // maximum value for a highlight ID. + /* * Structure shared between syntax.c, screen.c and gui_x11.c. */ @@ -1113,6 +1115,17 @@ garray_T vir_barlines; // lines starting with | } vir_T; +/* + * Structure used for the command line history. + */ +typedef struct hist_entry +{ + int hisnum; /* identifying number */ + int viminfo; /* when TRUE hisstr comes from viminfo */ + char_u *hisstr; /* actual entry, separator char after the NUL */ + time_t time_set; /* when it was typed, zero if unknown */ +} histentry_T; + #define CONV_NONE 0 #define CONV_TO_UTF8 1 #define CONV_9_TO_UTF8 2 @@ -1518,6 +1531,54 @@ funccal_entry_T *next; }; +/* From user function to hashitem and back. */ +#define UF2HIKEY(fp) ((fp)->uf_name) +#define HIKEY2UF(p) ((ufunc_T *)((p) - offsetof(ufunc_T, uf_name))) +#define HI2UF(hi) HIKEY2UF((hi)->hi_key) + +/* Growarray to store info about already sourced scripts. + * For Unix also store the dev/ino, so that we don't have to stat() each + * script when going through the list. */ +typedef struct scriptitem_S +{ + char_u *sn_name; +# ifdef UNIX + int sn_dev_valid; + dev_t sn_dev; + ino_t sn_ino; +# endif +# ifdef FEAT_PROFILE + int sn_prof_on; /* TRUE when script is/was profiled */ + int sn_pr_force; /* forceit: profile functions in this script */ + proftime_T sn_pr_child; /* time set when going into first child */ + int sn_pr_nest; /* nesting for sn_pr_child */ + /* profiling the script as a whole */ + int sn_pr_count; /* nr of times sourced */ + proftime_T sn_pr_total; /* time spent in script + children */ + proftime_T sn_pr_self; /* time spent in script itself */ + proftime_T sn_pr_start; /* time at script start */ + proftime_T sn_pr_children; /* time in children after script start */ + /* profiling the script per line */ + garray_T sn_prl_ga; /* things stored for every line */ + proftime_T sn_prl_start; /* start time for current line */ + proftime_T sn_prl_children; /* time spent in children for this line */ + proftime_T sn_prl_wait; /* wait start time for current line */ + int sn_prl_idx; /* index of line being timed; -1 if none */ + int sn_prl_execed; /* line being timed was executed */ +# endif +} scriptitem_T; + +# ifdef FEAT_PROFILE +/* Struct used in sn_prl_ga for every line of a script. */ +typedef struct sn_prl_S +{ + int snp_count; /* nr of times line was executed */ + proftime_T sn_prl_total; /* time spent in a line + children */ + proftime_T sn_prl_self; /* time spent in a line itself */ +} sn_prl_T; + +# define PRL_ITEM(si, idx) (((sn_prl_T *)(si)->sn_prl_ga.ga_data)[(idx)]) +# endif #else // dummy typedefs for use in function prototypes typedef struct @@ -1527,11 +1588,19 @@ typedef struct { int dummy; +} funccall_T; +typedef struct +{ + int dummy; } funcdict_T; typedef struct { int dummy; } funccal_entry_T; +typedef struct +{ + int dummy; +} scriptitem_T; #endif struct partial_S @@ -3667,6 +3736,14 @@ CDSCOPE_WINDOW // :lcd } cdscope_T; +// Variable flavor +typedef enum +{ + VAR_FLAVOUR_DEFAULT, /* doesn't start with uppercase */ + VAR_FLAVOUR_SESSION, /* starts with uppercase, some lower */ + VAR_FLAVOUR_VIMINFO /* all uppercase */ +} var_flavour_T; + // argument for mouse_find_win() typedef enum { IGNORE_POPUP, // only check non-popup windows diff -Nru vim-8.1.1681/src/syntax.c vim-8.1.1729/src/syntax.c --- vim-8.1.1681/src/syntax.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/syntax.c 2019-07-21 21:04:21.000000000 +0000 @@ -13,106 +13,6 @@ #include "vim.h" -/* - * Structure that stores information about a highlight group. - * The ID of a highlight group is also called group ID. It is the index in - * the highlight_ga array PLUS ONE. - */ -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 */ - char_u *sg_stop; /* terminal string for stop highl */ - int sg_term_attr; /* Screen attr for term mode */ -/* for color terminals */ - int sg_cterm; /* "cterm=" highlighting attr */ - int sg_cterm_bold; /* bold attr was set for light color */ - int sg_cterm_fg; /* terminal fg color number + 1 */ - int sg_cterm_bg; /* terminal bg color number + 1 */ - int sg_cterm_attr; /* Screen attr for color term mode */ -/* for when using the GUI */ -#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) - guicolor_T sg_gui_fg; /* GUI foreground color handle */ - guicolor_T sg_gui_bg; /* GUI background color handle */ -#endif -#ifdef FEAT_GUI - guicolor_T sg_gui_sp; /* GUI special color handle */ - GuiFont sg_font; /* GUI font handle */ -#ifdef FEAT_XFONTSET - GuiFontset sg_fontset; /* GUI fontset handle */ -#endif - char_u *sg_font_name; /* GUI font or fontset name */ - int sg_gui_attr; /* Screen attr for GUI mode */ -#endif -#if defined(FEAT_GUI) || defined(FEAT_EVAL) -/* Store the sp color name for the GUI or synIDattr() */ - int sg_gui; /* "gui=" highlighting attributes */ - char_u *sg_gui_fg_name;/* GUI foreground color name */ - char_u *sg_gui_bg_name;/* GUI background color name */ - char_u *sg_gui_sp_name;/* GUI special color name */ -#endif - int sg_link; /* link to this highlight group ID */ - int sg_set; /* combination of SG_* flags */ -#ifdef FEAT_EVAL - sctx_T sg_script_ctx; /* script in which the group was last set */ -#endif -}; - -#define SG_TERM 1 /* term has been set */ -#define SG_CTERM 2 /* cterm has been set */ -#define SG_GUI 4 /* gui has been set */ -#define SG_LINK 8 /* link has been set */ - -static garray_T highlight_ga; /* highlight groups for 'highlight' option */ - -#define HL_TABLE() ((struct hl_group *)((highlight_ga.ga_data))) - -#define MAX_HL_ID 20000 /* maximum value for a highlight ID. */ - -#ifdef FEAT_CMDL_COMPL -/* Flags to indicate an additional string for highlight name completion. */ -static int include_none = 0; /* when 1 include "None" */ -static int include_default = 0; /* when 1 include "default" */ -static int include_link = 0; /* when 2 include "link" and "clear" */ -#endif - -/* - * The "term", "cterm" and "gui" arguments can be any combination of the - * following names, separated by commas (but no spaces!). - */ -static char *(hl_name_table[]) = - {"bold", "standout", "underline", "undercurl", - "italic", "reverse", "inverse", "nocombine", "strikethrough", "NONE"}; -static int hl_attr_table[] = - {HL_BOLD, HL_STANDOUT, HL_UNDERLINE, HL_UNDERCURL, HL_ITALIC, HL_INVERSE, HL_INVERSE, HL_NOCOMBINE, HL_STRIKETHROUGH, 0}; -#define ATTR_COMBINE(attr_a, attr_b) ((((attr_b) & HL_NOCOMBINE) ? attr_b : (attr_a)) | (attr_b)) - -static void syn_unadd_group(void); -static void set_hl_attr(int idx); -static void highlight_list_one(int id); -static int highlight_list_arg(int id, int didh, int type, int iarg, char_u *sarg, char *name); -static int syn_add_group(char_u *name); -static int syn_list_header(int did_header, int outlen, int id); -static int hl_has_settings(int idx, int check_link); -static void highlight_clear(int idx); - -#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) -static void gui_do_one_color(int idx, int do_menu, int do_tooltip); -#endif -#ifdef FEAT_GUI -static int set_group_colors(char_u *name, guicolor_T *fgp, guicolor_T *bgp, int do_menu, int use_norm, int do_tooltip); -static void hl_do_font(int idx, char_u *arg, int do_normal, int do_menu, int do_tooltip, int free_font); -#endif - -/* - * An attribute number is the index in attr_table plus ATTR_OFF. - */ -#define ATTR_OFF (HL_ALL + 1) - #if defined(FEAT_SYN_HL) || defined(PROTO) #define SYN_NAMELEN 50 /* maximum length of a syntax name */ @@ -3947,7 +3847,7 @@ /* * No argument: List all group IDs and all syntax clusters. */ - for (id = 1; id <= highlight_ga.ga_len && !got_int; ++id) + for (id = 1; id <= highlight_num_groups() && !got_int; ++id) syn_list_one(id, syncing, FALSE); for (id = 0; id < curwin->w_s->b_syn_clusters.ga_len && !got_int; ++id) syn_list_cluster(id); @@ -4095,7 +3995,7 @@ if (SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_SKIP) put_pattern("skip", '=', &SYN_ITEMS(curwin->w_s)[idx++], attr); while (idx < curwin->w_s->b_syn_patterns.ga_len - && SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_END) + && SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_END) put_pattern("end", '=', &SYN_ITEMS(curwin->w_s)[idx++], attr); --idx; msg_putchar(' '); @@ -4122,8 +4022,8 @@ msg_puts_attr("groupthere", attr); msg_putchar(' '); if (spp->sp_sync_idx >= 0) - msg_outtrans(HL_TABLE()[SYN_ITEMS(curwin->w_s) - [spp->sp_sync_idx].sp_syn.id - 1].sg_name); + msg_outtrans(highlight_group_name(SYN_ITEMS(curwin->w_s) + [spp->sp_sync_idx].sp_syn.id - 1)); else msg_puts("NONE"); msg_putchar(' '); @@ -4131,12 +4031,12 @@ } /* list the link, if there is one */ - if (HL_TABLE()[id - 1].sg_link && (did_header || link_only) && !got_int) + if (highlight_link_id(id - 1) && (did_header || link_only) && !got_int) { (void)syn_list_header(did_header, 999, id); msg_puts_attr("links to", attr); msg_putchar(' '); - msg_outtrans(HL_TABLE()[HL_TABLE()[id - 1].sg_link - 1].sg_name); + msg_outtrans(highlight_group_name(highlight_link_id(id - 1) - 1)); } } @@ -4215,7 +4115,7 @@ msg_outtrans(SYN_CLSTR(curwin->w_s)[scl_id].scl_name); } else - msg_outtrans(HL_TABLE()[*p - 1].sg_name); + msg_outtrans(highlight_group_name(*p - 1)); if (p[1]) msg_putchar(','); } @@ -4244,7 +4144,7 @@ if (last_matchgroup == 0) msg_outtrans((char_u *)"NONE"); else - msg_outtrans(HL_TABLE()[last_matchgroup - 1].sg_name); + msg_outtrans(highlight_group_name(last_matchgroup - 1)); msg_putchar(' '); } @@ -6067,9 +5967,9 @@ regmatch.rm_ic = TRUE; id = 0; - for (i = highlight_ga.ga_len; --i >= 0; ) + for (i = highlight_num_groups(); --i >= 0; ) { - if (vim_regexec(®match, HL_TABLE()[i].sg_name, + if (vim_regexec(®match, highlight_group_name(i), (colnr_T)0)) { if (round == 2) @@ -6785,7 +6685,7 @@ msg_puts(" "); # endif msg_advance(50); - msg_outtrans(HL_TABLE()[p->id - 1].sg_name); + msg_outtrans(highlight_group_name(p->id - 1)); msg_puts(" "); msg_advance(69); @@ -6811,3540 +6711,3 @@ #endif #endif /* FEAT_SYN_HL */ - -/************************************** - * Highlighting stuff * - **************************************/ - -/* - * The default highlight groups. These are compiled-in for fast startup and - * they still work when the runtime files can't be found. - * When making changes here, also change runtime/colors/default.vim! - * The #ifdefs are needed to reduce the amount of static data. Helps to make - * the 16 bit DOS (museum) version compile. - */ -#if defined(FEAT_GUI) || defined(FEAT_EVAL) -# define CENT(a, b) b -#else -# define CENT(a, b) a -#endif -static char *(highlight_init_both[]) = { - CENT("ErrorMsg term=standout ctermbg=DarkRed ctermfg=White", - "ErrorMsg term=standout ctermbg=DarkRed ctermfg=White guibg=Red guifg=White"), - CENT("IncSearch term=reverse cterm=reverse", - "IncSearch term=reverse cterm=reverse gui=reverse"), - CENT("ModeMsg term=bold cterm=bold", - "ModeMsg term=bold cterm=bold gui=bold"), - CENT("NonText term=bold ctermfg=Blue", - "NonText term=bold ctermfg=Blue gui=bold guifg=Blue"), - CENT("StatusLine term=reverse,bold cterm=reverse,bold", - "StatusLine term=reverse,bold cterm=reverse,bold gui=reverse,bold"), - CENT("StatusLineNC term=reverse cterm=reverse", - "StatusLineNC term=reverse cterm=reverse gui=reverse"), - "default link EndOfBuffer NonText", - CENT("VertSplit term=reverse cterm=reverse", - "VertSplit term=reverse cterm=reverse gui=reverse"), -#ifdef FEAT_CLIPBOARD - CENT("VisualNOS term=underline,bold cterm=underline,bold", - "VisualNOS term=underline,bold cterm=underline,bold gui=underline,bold"), -#endif -#ifdef FEAT_DIFF - CENT("DiffText term=reverse cterm=bold ctermbg=Red", - "DiffText term=reverse cterm=bold ctermbg=Red gui=bold guibg=Red"), -#endif -#ifdef FEAT_INS_EXPAND - CENT("PmenuSbar ctermbg=Grey", - "PmenuSbar ctermbg=Grey guibg=Grey"), -#endif - CENT("TabLineSel term=bold cterm=bold", - "TabLineSel term=bold cterm=bold gui=bold"), - CENT("TabLineFill term=reverse cterm=reverse", - "TabLineFill term=reverse cterm=reverse gui=reverse"), -#ifdef FEAT_GUI - "Cursor guibg=fg guifg=bg", - "lCursor guibg=fg guifg=bg", /* should be different, but what? */ -#endif - "default link QuickFixLine Search", - CENT("Normal cterm=NONE", "Normal gui=NONE"), - NULL -}; - -/* Default colors only used with a light background. */ -static char *(highlight_init_light[]) = { - CENT("Directory term=bold ctermfg=DarkBlue", - "Directory term=bold ctermfg=DarkBlue guifg=Blue"), - CENT("LineNr term=underline ctermfg=Brown", - "LineNr term=underline ctermfg=Brown guifg=Brown"), - CENT("CursorLineNr term=bold ctermfg=Brown", - "CursorLineNr term=bold ctermfg=Brown gui=bold guifg=Brown"), - CENT("MoreMsg term=bold ctermfg=DarkGreen", - "MoreMsg term=bold ctermfg=DarkGreen gui=bold guifg=SeaGreen"), - CENT("Question term=standout ctermfg=DarkGreen", - "Question term=standout ctermfg=DarkGreen gui=bold guifg=SeaGreen"), - CENT("Search term=reverse ctermbg=Yellow ctermfg=NONE", - "Search term=reverse ctermbg=Yellow ctermfg=NONE guibg=Yellow guifg=NONE"), -#ifdef FEAT_SPELL - CENT("SpellBad term=reverse ctermbg=LightRed", - "SpellBad term=reverse ctermbg=LightRed guisp=Red gui=undercurl"), - CENT("SpellCap term=reverse ctermbg=LightBlue", - "SpellCap term=reverse ctermbg=LightBlue guisp=Blue gui=undercurl"), - CENT("SpellRare term=reverse ctermbg=LightMagenta", - "SpellRare term=reverse ctermbg=LightMagenta guisp=Magenta gui=undercurl"), - CENT("SpellLocal term=underline ctermbg=Cyan", - "SpellLocal term=underline ctermbg=Cyan guisp=DarkCyan gui=undercurl"), -#endif -#ifdef FEAT_INS_EXPAND - CENT("PmenuThumb ctermbg=Black", - "PmenuThumb ctermbg=Black guibg=Black"), - CENT("Pmenu ctermbg=LightMagenta ctermfg=Black", - "Pmenu ctermbg=LightMagenta ctermfg=Black guibg=LightMagenta"), - CENT("PmenuSel ctermbg=LightGrey ctermfg=Black", - "PmenuSel ctermbg=LightGrey ctermfg=Black guibg=Grey"), -#endif - CENT("SpecialKey term=bold ctermfg=DarkBlue", - "SpecialKey term=bold ctermfg=DarkBlue guifg=Blue"), - CENT("Title term=bold ctermfg=DarkMagenta", - "Title term=bold ctermfg=DarkMagenta gui=bold guifg=Magenta"), - CENT("WarningMsg term=standout ctermfg=DarkRed", - "WarningMsg term=standout ctermfg=DarkRed guifg=Red"), -#ifdef FEAT_WILDMENU - CENT("WildMenu term=standout ctermbg=Yellow ctermfg=Black", - "WildMenu term=standout ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"), -#endif -#ifdef FEAT_FOLDING - CENT("Folded term=standout ctermbg=Grey ctermfg=DarkBlue", - "Folded term=standout ctermbg=Grey ctermfg=DarkBlue guibg=LightGrey guifg=DarkBlue"), - CENT("FoldColumn term=standout ctermbg=Grey ctermfg=DarkBlue", - "FoldColumn term=standout ctermbg=Grey ctermfg=DarkBlue guibg=Grey guifg=DarkBlue"), -#endif -#ifdef FEAT_SIGNS - CENT("SignColumn term=standout ctermbg=Grey ctermfg=DarkBlue", - "SignColumn term=standout ctermbg=Grey ctermfg=DarkBlue guibg=Grey guifg=DarkBlue"), -#endif - CENT("Visual term=reverse", - "Visual term=reverse guibg=LightGrey"), -#ifdef FEAT_DIFF - CENT("DiffAdd term=bold ctermbg=LightBlue", - "DiffAdd term=bold ctermbg=LightBlue guibg=LightBlue"), - CENT("DiffChange term=bold ctermbg=LightMagenta", - "DiffChange term=bold ctermbg=LightMagenta guibg=LightMagenta"), - CENT("DiffDelete term=bold ctermfg=Blue ctermbg=LightCyan", - "DiffDelete term=bold ctermfg=Blue ctermbg=LightCyan gui=bold guifg=Blue guibg=LightCyan"), -#endif - CENT("TabLine term=underline cterm=underline ctermfg=black ctermbg=LightGrey", - "TabLine term=underline cterm=underline ctermfg=black ctermbg=LightGrey gui=underline guibg=LightGrey"), -#ifdef FEAT_SYN_HL - CENT("CursorColumn term=reverse ctermbg=LightGrey", - "CursorColumn term=reverse ctermbg=LightGrey guibg=Grey90"), - CENT("CursorLine term=underline cterm=underline", - "CursorLine term=underline cterm=underline guibg=Grey90"), - CENT("ColorColumn term=reverse ctermbg=LightRed", - "ColorColumn term=reverse ctermbg=LightRed guibg=LightRed"), -#endif -#ifdef FEAT_CONCEAL - CENT("Conceal ctermbg=DarkGrey ctermfg=LightGrey", - "Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey"), -#endif - CENT("MatchParen term=reverse ctermbg=Cyan", - "MatchParen term=reverse ctermbg=Cyan guibg=Cyan"), -#ifdef FEAT_TERMINAL - CENT("StatusLineTerm term=reverse,bold cterm=bold ctermfg=White ctermbg=DarkGreen", - "StatusLineTerm term=reverse,bold cterm=bold ctermfg=White ctermbg=DarkGreen gui=bold guifg=bg guibg=DarkGreen"), - CENT("StatusLineTermNC term=reverse ctermfg=White ctermbg=DarkGreen", - "StatusLineTermNC term=reverse ctermfg=White ctermbg=DarkGreen guifg=bg guibg=DarkGreen"), -#endif -#ifdef FEAT_MENU - CENT("ToolbarLine term=underline ctermbg=LightGrey", - "ToolbarLine term=underline ctermbg=LightGrey guibg=LightGrey"), - CENT("ToolbarButton cterm=bold ctermfg=White ctermbg=DarkGrey", - "ToolbarButton cterm=bold ctermfg=White ctermbg=DarkGrey gui=bold guifg=White guibg=Grey40"), -#endif - NULL -}; - -/* Default colors only used with a dark background. */ -static char *(highlight_init_dark[]) = { - CENT("Directory term=bold ctermfg=LightCyan", - "Directory term=bold ctermfg=LightCyan guifg=Cyan"), - CENT("LineNr term=underline ctermfg=Yellow", - "LineNr term=underline ctermfg=Yellow guifg=Yellow"), - CENT("CursorLineNr term=bold ctermfg=Yellow", - "CursorLineNr term=bold ctermfg=Yellow gui=bold guifg=Yellow"), - CENT("MoreMsg term=bold ctermfg=LightGreen", - "MoreMsg term=bold ctermfg=LightGreen gui=bold guifg=SeaGreen"), - CENT("Question term=standout ctermfg=LightGreen", - "Question term=standout ctermfg=LightGreen gui=bold guifg=Green"), - CENT("Search term=reverse ctermbg=Yellow ctermfg=Black", - "Search term=reverse ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"), - CENT("SpecialKey term=bold ctermfg=LightBlue", - "SpecialKey term=bold ctermfg=LightBlue guifg=Cyan"), -#ifdef FEAT_SPELL - CENT("SpellBad term=reverse ctermbg=Red", - "SpellBad term=reverse ctermbg=Red guisp=Red gui=undercurl"), - CENT("SpellCap term=reverse ctermbg=Blue", - "SpellCap term=reverse ctermbg=Blue guisp=Blue gui=undercurl"), - CENT("SpellRare term=reverse ctermbg=Magenta", - "SpellRare term=reverse ctermbg=Magenta guisp=Magenta gui=undercurl"), - CENT("SpellLocal term=underline ctermbg=Cyan", - "SpellLocal term=underline ctermbg=Cyan guisp=Cyan gui=undercurl"), -#endif -#ifdef FEAT_INS_EXPAND - CENT("PmenuThumb ctermbg=White", - "PmenuThumb ctermbg=White guibg=White"), - CENT("Pmenu ctermbg=Magenta ctermfg=Black", - "Pmenu ctermbg=Magenta ctermfg=Black guibg=Magenta"), - CENT("PmenuSel ctermbg=Black ctermfg=DarkGrey", - "PmenuSel ctermbg=Black ctermfg=DarkGrey guibg=DarkGrey"), -#endif - CENT("Title term=bold ctermfg=LightMagenta", - "Title term=bold ctermfg=LightMagenta gui=bold guifg=Magenta"), - CENT("WarningMsg term=standout ctermfg=LightRed", - "WarningMsg term=standout ctermfg=LightRed guifg=Red"), -#ifdef FEAT_WILDMENU - CENT("WildMenu term=standout ctermbg=Yellow ctermfg=Black", - "WildMenu term=standout ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"), -#endif -#ifdef FEAT_FOLDING - CENT("Folded term=standout ctermbg=DarkGrey ctermfg=Cyan", - "Folded term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=DarkGrey guifg=Cyan"), - CENT("FoldColumn term=standout ctermbg=DarkGrey ctermfg=Cyan", - "FoldColumn term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=Grey guifg=Cyan"), -#endif -#ifdef FEAT_SIGNS - CENT("SignColumn term=standout ctermbg=DarkGrey ctermfg=Cyan", - "SignColumn term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=Grey guifg=Cyan"), -#endif - CENT("Visual term=reverse", - "Visual term=reverse guibg=DarkGrey"), -#ifdef FEAT_DIFF - CENT("DiffAdd term=bold ctermbg=DarkBlue", - "DiffAdd term=bold ctermbg=DarkBlue guibg=DarkBlue"), - CENT("DiffChange term=bold ctermbg=DarkMagenta", - "DiffChange term=bold ctermbg=DarkMagenta guibg=DarkMagenta"), - CENT("DiffDelete term=bold ctermfg=Blue ctermbg=DarkCyan", - "DiffDelete term=bold ctermfg=Blue ctermbg=DarkCyan gui=bold guifg=Blue guibg=DarkCyan"), -#endif - CENT("TabLine term=underline cterm=underline ctermfg=white ctermbg=DarkGrey", - "TabLine term=underline cterm=underline ctermfg=white ctermbg=DarkGrey gui=underline guibg=DarkGrey"), -#ifdef FEAT_SYN_HL - CENT("CursorColumn term=reverse ctermbg=DarkGrey", - "CursorColumn term=reverse ctermbg=DarkGrey guibg=Grey40"), - CENT("CursorLine term=underline cterm=underline", - "CursorLine term=underline cterm=underline guibg=Grey40"), - CENT("ColorColumn term=reverse ctermbg=DarkRed", - "ColorColumn term=reverse ctermbg=DarkRed guibg=DarkRed"), -#endif - CENT("MatchParen term=reverse ctermbg=DarkCyan", - "MatchParen term=reverse ctermbg=DarkCyan guibg=DarkCyan"), -#ifdef FEAT_CONCEAL - CENT("Conceal ctermbg=DarkGrey ctermfg=LightGrey", - "Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey"), -#endif -#ifdef FEAT_TERMINAL - CENT("StatusLineTerm term=reverse,bold cterm=bold ctermfg=Black ctermbg=LightGreen", - "StatusLineTerm term=reverse,bold cterm=bold ctermfg=Black ctermbg=LightGreen gui=bold guifg=bg guibg=LightGreen"), - CENT("StatusLineTermNC term=reverse ctermfg=Black ctermbg=LightGreen", - "StatusLineTermNC term=reverse ctermfg=Black ctermbg=LightGreen guifg=bg guibg=LightGreen"), -#endif -#ifdef FEAT_MENU - CENT("ToolbarLine term=underline ctermbg=DarkGrey", - "ToolbarLine term=underline ctermbg=DarkGrey guibg=Grey50"), - CENT("ToolbarButton cterm=bold ctermfg=Black ctermbg=LightGrey", - "ToolbarButton cterm=bold ctermfg=Black ctermbg=LightGrey gui=bold guifg=Black guibg=LightGrey"), -#endif - NULL -}; - - void -init_highlight( - int both, /* include groups where 'bg' doesn't matter */ - int reset) /* clear group first */ -{ - int i; - char **pp; - static int had_both = FALSE; -#ifdef FEAT_EVAL - char_u *p; - - /* - * Try finding the color scheme file. Used when a color file was loaded - * and 'background' or 't_Co' is changed. - */ - p = get_var_value((char_u *)"g:colors_name"); - if (p != NULL) - { - /* The value of g:colors_name could be freed when sourcing the script, - * making "p" invalid, so copy it. */ - char_u *copy_p = vim_strsave(p); - int r; - - if (copy_p != NULL) - { - r = load_colors(copy_p); - vim_free(copy_p); - if (r == OK) - return; - } - } - -#endif - - /* - * Didn't use a color file, use the compiled-in colors. - */ - if (both) - { - had_both = TRUE; - pp = highlight_init_both; - for (i = 0; pp[i] != NULL; ++i) - do_highlight((char_u *)pp[i], reset, TRUE); - } - else if (!had_both) - /* Don't do anything before the call with both == TRUE from main(). - * Not everything has been setup then, and that call will overrule - * everything anyway. */ - return; - - if (*p_bg == 'l') - pp = highlight_init_light; - else - pp = highlight_init_dark; - for (i = 0; pp[i] != NULL; ++i) - do_highlight((char_u *)pp[i], reset, TRUE); - - /* Reverse looks ugly, but grey may not work for 8 colors. Thus let it - * depend on the number of colors available. - * With 8 colors brown is equal to yellow, need to use black for Search fg - * to avoid Statement highlighted text disappears. - * Clear the attributes, needed when changing the t_Co value. */ - if (t_colors > 8) - do_highlight((char_u *)(*p_bg == 'l' - ? "Visual cterm=NONE ctermbg=LightGrey" - : "Visual cterm=NONE ctermbg=DarkGrey"), FALSE, TRUE); - else - { - do_highlight((char_u *)"Visual cterm=reverse ctermbg=NONE", - FALSE, TRUE); - if (*p_bg == 'l') - do_highlight((char_u *)"Search ctermfg=black", FALSE, TRUE); - } - -#ifdef FEAT_SYN_HL - /* - * If syntax highlighting is enabled load the highlighting for it. - */ - if (get_var_value((char_u *)"g:syntax_on") != NULL) - { - static int recursive = 0; - - if (recursive >= 5) - emsg(_("E679: recursive loop loading syncolor.vim")); - else - { - ++recursive; - (void)source_runtime((char_u *)"syntax/syncolor.vim", DIP_ALL); - --recursive; - } - } -#endif -} - -/* - * Load color file "name". - * Return OK for success, FAIL for failure. - */ - int -load_colors(char_u *name) -{ - char_u *buf; - int retval = FAIL; - static int recursive = FALSE; - - /* When being called recursively, this is probably because setting - * 'background' caused the highlighting to be reloaded. This means it is - * working, thus we should return OK. */ - if (recursive) - return OK; - - recursive = TRUE; - buf = alloc(STRLEN(name) + 12); - if (buf != NULL) - { - apply_autocmds(EVENT_COLORSCHEMEPRE, name, - curbuf->b_fname, FALSE, curbuf); - sprintf((char *)buf, "colors/%s.vim", name); - retval = source_runtime(buf, DIP_START + DIP_OPT); - vim_free(buf); - apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, FALSE, curbuf); - } - recursive = FALSE; - - return retval; -} - -static char *(color_names[28]) = { - "Black", "DarkBlue", "DarkGreen", "DarkCyan", - "DarkRed", "DarkMagenta", "Brown", "DarkYellow", - "Gray", "Grey", "LightGray", "LightGrey", - "DarkGray", "DarkGrey", - "Blue", "LightBlue", "Green", "LightGreen", - "Cyan", "LightCyan", "Red", "LightRed", "Magenta", - "LightMagenta", "Yellow", "LightYellow", "White", "NONE"}; - /* indices: - * 0, 1, 2, 3, - * 4, 5, 6, 7, - * 8, 9, 10, 11, - * 12, 13, - * 14, 15, 16, 17, - * 18, 19, 20, 21, 22, - * 23, 24, 25, 26, 27 */ -static int color_numbers_16[28] = {0, 1, 2, 3, - 4, 5, 6, 6, - 7, 7, 7, 7, - 8, 8, - 9, 9, 10, 10, - 11, 11, 12, 12, 13, - 13, 14, 14, 15, -1}; -/* for xterm with 88 colors... */ -static int color_numbers_88[28] = {0, 4, 2, 6, - 1, 5, 32, 72, - 84, 84, 7, 7, - 82, 82, - 12, 43, 10, 61, - 14, 63, 9, 74, 13, - 75, 11, 78, 15, -1}; -/* for xterm with 256 colors... */ -static int color_numbers_256[28] = {0, 4, 2, 6, - 1, 5, 130, 130, - 248, 248, 7, 7, - 242, 242, - 12, 81, 10, 121, - 14, 159, 9, 224, 13, - 225, 11, 229, 15, -1}; -/* for terminals with less than 16 colors... */ -static int color_numbers_8[28] = {0, 4, 2, 6, - 1, 5, 3, 3, - 7, 7, 7, 7, - 0+8, 0+8, - 4+8, 4+8, 2+8, 2+8, - 6+8, 6+8, 1+8, 1+8, 5+8, - 5+8, 3+8, 3+8, 7+8, -1}; - -/* - * Lookup the "cterm" value to be used for color with index "idx" in - * color_names[]. - * "boldp" will be set to TRUE or FALSE for a foreground color when using 8 - * colors, otherwise it will be unchanged. - */ - int -lookup_color(int idx, int foreground, int *boldp) -{ - int color = color_numbers_16[idx]; - char_u *p; - - /* Use the _16 table to check if it's a valid color name. */ - if (color < 0) - return -1; - - if (t_colors == 8) - { - /* t_Co is 8: use the 8 colors table */ -#if defined(__QNXNTO__) - color = color_numbers_8_qansi[idx]; -#else - color = color_numbers_8[idx]; -#endif - if (foreground) - { - /* set/reset bold attribute to get light foreground - * colors (on some terminals, e.g. "linux") */ - if (color & 8) - *boldp = TRUE; - else - *boldp = FALSE; - } - color &= 7; /* truncate to 8 colors */ - } - else if (t_colors == 16 || t_colors == 88 - || t_colors >= 256) - { - /* - * Guess: if the termcap entry ends in 'm', it is - * probably an xterm-like terminal. Use the changed - * order for colors. - */ - if (*T_CAF != NUL) - p = T_CAF; - else - p = T_CSF; - if (*p != NUL && (t_colors > 256 - || *(p + STRLEN(p) - 1) == 'm')) - { - if (t_colors == 88) - color = color_numbers_88[idx]; - else if (t_colors >= 256) - color = color_numbers_256[idx]; - else - color = color_numbers_8[idx]; - } -#ifdef FEAT_TERMRESPONSE - if (t_colors >= 256 && color == 15 && is_mac_terminal) - /* Terminal.app has a bug: 15 is light grey. Use white - * from the color cube instead. */ - color = 231; -#endif - } - return color; -} - -/* - * Handle the ":highlight .." command. - * When using ":hi clear" this is called recursively for each group with - * "forceit" and "init" both TRUE. - */ - void -do_highlight( - char_u *line, - int forceit, - int init) /* TRUE when called for initializing */ -{ - char_u *name_end; - char_u *p; - char_u *linep; - char_u *key_start; - char_u *arg_start; - char_u *key = NULL, *arg = NULL; - long i; - int off; - int len; - int attr; - int id; - int idx; - struct hl_group item_before; - int did_change = FALSE; - int dodefault = FALSE; - int doclear = FALSE; - int dolink = FALSE; - int error = FALSE; - int color; - int is_normal_group = FALSE; /* "Normal" group */ -#ifdef FEAT_TERMINAL - int is_terminal_group = FALSE; /* "Terminal" group */ -#endif -#ifdef FEAT_GUI_X11 - int is_menu_group = FALSE; /* "Menu" group */ - int is_scrollbar_group = FALSE; /* "Scrollbar" group */ - int is_tooltip_group = FALSE; /* "Tooltip" group */ - int do_colors = FALSE; /* need to update colors? */ -#else -# define is_menu_group 0 -# define is_tooltip_group 0 -#endif -#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) - int did_highlight_changed = FALSE; -#endif - - /* - * If no argument, list current highlighting. - */ - if (ends_excmd(*line)) - { - for (i = 1; i <= highlight_ga.ga_len && !got_int; ++i) - /* TODO: only call when the group has attributes set */ - highlight_list_one((int)i); - return; - } - - /* - * Isolate the name. - */ - name_end = skiptowhite(line); - linep = skipwhite(name_end); - - /* - * Check for "default" argument. - */ - if (STRNCMP(line, "default", name_end - line) == 0) - { - dodefault = TRUE; - line = linep; - name_end = skiptowhite(line); - linep = skipwhite(name_end); - } - - /* - * Check for "clear" or "link" argument. - */ - if (STRNCMP(line, "clear", name_end - line) == 0) - doclear = TRUE; - if (STRNCMP(line, "link", name_end - line) == 0) - dolink = TRUE; - - /* - * ":highlight {group-name}": list highlighting for one group. - */ - if (!doclear && !dolink && ends_excmd(*linep)) - { - id = syn_namen2id(line, (int)(name_end - line)); - if (id == 0) - semsg(_("E411: highlight group not found: %s"), line); - else - highlight_list_one(id); - return; - } - - /* - * Handle ":highlight link {from} {to}" command. - */ - if (dolink) - { - char_u *from_start = linep; - char_u *from_end; - char_u *to_start; - char_u *to_end; - int from_id; - int to_id; - - from_end = skiptowhite(from_start); - to_start = skipwhite(from_end); - to_end = skiptowhite(to_start); - - if (ends_excmd(*from_start) || ends_excmd(*to_start)) - { - semsg(_("E412: Not enough arguments: \":highlight link %s\""), - from_start); - return; - } - - if (!ends_excmd(*skipwhite(to_end))) - { - semsg(_("E413: Too many arguments: \":highlight link %s\""), from_start); - return; - } - - from_id = syn_check_group(from_start, (int)(from_end - from_start)); - if (STRNCMP(to_start, "NONE", 4) == 0) - to_id = 0; - else - to_id = syn_check_group(to_start, (int)(to_end - to_start)); - - if (from_id > 0 && (!init || HL_TABLE()[from_id - 1].sg_set == 0)) - { - /* - * Don't allow a link when there already is some highlighting - * for the group, unless '!' is used - */ - if (to_id > 0 && !forceit && !init - && hl_has_settings(from_id - 1, dodefault)) - { - if (sourcing_name == NULL && !dodefault) - emsg(_("E414: group has settings, highlight link ignored")); - } - else if (HL_TABLE()[from_id - 1].sg_link != to_id -#ifdef FEAT_EVAL - || HL_TABLE()[from_id - 1].sg_script_ctx.sc_sid - != current_sctx.sc_sid -#endif - || HL_TABLE()[from_id - 1].sg_cleared) - { - if (!init) - HL_TABLE()[from_id - 1].sg_set |= SG_LINK; - HL_TABLE()[from_id - 1].sg_link = to_id; -#ifdef FEAT_EVAL - HL_TABLE()[from_id - 1].sg_script_ctx = current_sctx; - HL_TABLE()[from_id - 1].sg_script_ctx.sc_lnum += sourcing_lnum; -#endif - HL_TABLE()[from_id - 1].sg_cleared = FALSE; - redraw_all_later(SOME_VALID); - - /* Only call highlight_changed() once after multiple changes. */ - need_highlight_changed = TRUE; - } - } - - return; - } - - if (doclear) - { - /* - * ":highlight clear [group]" command. - */ - line = linep; - if (ends_excmd(*line)) - { -#ifdef FEAT_GUI - /* First, we do not destroy the old values, but allocate the new - * ones and update the display. THEN we destroy the old values. - * If we destroy the old values first, then the old values - * (such as GuiFont's or GuiFontset's) will still be displayed but - * invalid because they were free'd. - */ - if (gui.in_use) - { -# ifdef FEAT_BEVAL_TIP - gui_init_tooltip_font(); -# endif -# if defined(FEAT_MENU) && (defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MOTIF)) - gui_init_menu_font(); -# endif - } -# if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_X11) - gui_mch_def_colors(); -# endif -# ifdef FEAT_GUI_X11 -# ifdef FEAT_MENU - - /* This only needs to be done when there is no Menu highlight - * group defined by default, which IS currently the case. - */ - gui_mch_new_menu_colors(); -# endif - if (gui.in_use) - { - gui_new_scrollbar_colors(); -# ifdef FEAT_BEVAL_GUI - gui_mch_new_tooltip_colors(); -# endif -# ifdef FEAT_MENU - gui_mch_new_menu_font(); -# endif - } -# endif - - /* Ok, we're done allocating the new default graphics items. - * The screen should already be refreshed at this point. - * It is now Ok to clear out the old data. - */ -#endif -#ifdef FEAT_EVAL - do_unlet((char_u *)"colors_name", TRUE); -#endif - restore_cterm_colors(); - - /* - * Clear all default highlight groups and load the defaults. - */ - for (idx = 0; idx < highlight_ga.ga_len; ++idx) - highlight_clear(idx); - init_highlight(TRUE, TRUE); -#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) - if (USE_24BIT) - highlight_gui_started(); - else -#endif - highlight_changed(); - redraw_later_clear(); - return; - } - name_end = skiptowhite(line); - linep = skipwhite(name_end); - } - - /* - * Find the group name in the table. If it does not exist yet, add it. - */ - id = syn_check_group(line, (int)(name_end - line)); - if (id == 0) /* failed (out of memory) */ - return; - idx = id - 1; /* index is ID minus one */ - - /* Return if "default" was used and the group already has settings. */ - if (dodefault && hl_has_settings(idx, TRUE)) - return; - - /* Make a copy so we can check if any attribute actually changed. */ - item_before = HL_TABLE()[idx]; - - if (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0) - is_normal_group = TRUE; -#ifdef FEAT_TERMINAL - else if (STRCMP(HL_TABLE()[idx].sg_name_u, "TERMINAL") == 0) - is_terminal_group = TRUE; -#endif -#ifdef FEAT_GUI_X11 - else if (STRCMP(HL_TABLE()[idx].sg_name_u, "MENU") == 0) - is_menu_group = TRUE; - else if (STRCMP(HL_TABLE()[idx].sg_name_u, "SCROLLBAR") == 0) - is_scrollbar_group = TRUE; - else if (STRCMP(HL_TABLE()[idx].sg_name_u, "TOOLTIP") == 0) - is_tooltip_group = TRUE; -#endif - - /* Clear the highlighting for ":hi clear {group}" and ":hi clear". */ - if (doclear || (forceit && init)) - { - highlight_clear(idx); - if (!doclear) - HL_TABLE()[idx].sg_set = 0; - } - - if (!doclear) - while (!ends_excmd(*linep)) - { - key_start = linep; - if (*linep == '=') - { - semsg(_("E415: unexpected equal sign: %s"), key_start); - error = TRUE; - break; - } - - /* - * Isolate the key ("term", "ctermfg", "ctermbg", "font", "guifg" or - * "guibg"). - */ - while (*linep && !VIM_ISWHITE(*linep) && *linep != '=') - ++linep; - vim_free(key); - key = vim_strnsave_up(key_start, (int)(linep - key_start)); - if (key == NULL) - { - error = TRUE; - break; - } - linep = skipwhite(linep); - - if (STRCMP(key, "NONE") == 0) - { - if (!init || HL_TABLE()[idx].sg_set == 0) - { - if (!init) - HL_TABLE()[idx].sg_set |= SG_TERM+SG_CTERM+SG_GUI; - highlight_clear(idx); - } - continue; - } - - /* - * Check for the equal sign. - */ - if (*linep != '=') - { - semsg(_("E416: missing equal sign: %s"), key_start); - error = TRUE; - break; - } - ++linep; - - /* - * Isolate the argument. - */ - linep = skipwhite(linep); - if (*linep == '\'') /* guifg='color name' */ - { - arg_start = ++linep; - linep = vim_strchr(linep, '\''); - if (linep == NULL) - { - semsg(_(e_invarg2), key_start); - error = TRUE; - break; - } - } - else - { - arg_start = linep; - linep = skiptowhite(linep); - } - if (linep == arg_start) - { - semsg(_("E417: missing argument: %s"), key_start); - error = TRUE; - break; - } - vim_free(arg); - arg = vim_strnsave(arg_start, (int)(linep - arg_start)); - if (arg == NULL) - { - error = TRUE; - break; - } - if (*linep == '\'') - ++linep; - - /* - * Store the argument. - */ - if ( STRCMP(key, "TERM") == 0 - || STRCMP(key, "CTERM") == 0 - || STRCMP(key, "GUI") == 0) - { - attr = 0; - off = 0; - while (arg[off] != NUL) - { - for (i = sizeof(hl_attr_table) / sizeof(int); --i >= 0; ) - { - len = (int)STRLEN(hl_name_table[i]); - if (STRNICMP(arg + off, hl_name_table[i], len) == 0) - { - attr |= hl_attr_table[i]; - off += len; - break; - } - } - if (i < 0) - { - semsg(_("E418: Illegal value: %s"), arg); - error = TRUE; - break; - } - if (arg[off] == ',') /* another one follows */ - ++off; - } - if (error) - break; - if (*key == 'T') - { - if (!init || !(HL_TABLE()[idx].sg_set & SG_TERM)) - { - if (!init) - HL_TABLE()[idx].sg_set |= SG_TERM; - HL_TABLE()[idx].sg_term = attr; - } - } - else if (*key == 'C') - { - if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) - { - if (!init) - HL_TABLE()[idx].sg_set |= SG_CTERM; - HL_TABLE()[idx].sg_cterm = attr; - HL_TABLE()[idx].sg_cterm_bold = FALSE; - } - } -#if defined(FEAT_GUI) || defined(FEAT_EVAL) - else - { - if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) - { - if (!init) - HL_TABLE()[idx].sg_set |= SG_GUI; - HL_TABLE()[idx].sg_gui = attr; - } - } -#endif - } - else if (STRCMP(key, "FONT") == 0) - { - /* in non-GUI fonts are simply ignored */ -#ifdef FEAT_GUI - if (HL_TABLE()[idx].sg_font_name != NULL - && STRCMP(HL_TABLE()[idx].sg_font_name, arg) == 0) - { - /* Font name didn't change, ignore. */ - } - else if (!gui.shell_created) - { - /* GUI not started yet, always accept the name. */ - vim_free(HL_TABLE()[idx].sg_font_name); - HL_TABLE()[idx].sg_font_name = vim_strsave(arg); - did_change = TRUE; - } - else - { - GuiFont temp_sg_font = HL_TABLE()[idx].sg_font; -# ifdef FEAT_XFONTSET - GuiFontset temp_sg_fontset = HL_TABLE()[idx].sg_fontset; -# endif - /* First, save the current font/fontset. - * Then try to allocate the font/fontset. - * If the allocation fails, HL_TABLE()[idx].sg_font OR - * sg_fontset will be set to NOFONT or NOFONTSET respectively. - */ - - HL_TABLE()[idx].sg_font = NOFONT; -# ifdef FEAT_XFONTSET - HL_TABLE()[idx].sg_fontset = NOFONTSET; -# endif - hl_do_font(idx, arg, is_normal_group, is_menu_group, - is_tooltip_group, FALSE); - -# ifdef FEAT_XFONTSET - if (HL_TABLE()[idx].sg_fontset != NOFONTSET) - { - /* New fontset was accepted. Free the old one, if there - * was one. */ - gui_mch_free_fontset(temp_sg_fontset); - vim_free(HL_TABLE()[idx].sg_font_name); - HL_TABLE()[idx].sg_font_name = vim_strsave(arg); - did_change = TRUE; - } - else - HL_TABLE()[idx].sg_fontset = temp_sg_fontset; -# endif - if (HL_TABLE()[idx].sg_font != NOFONT) - { - /* New font was accepted. Free the old one, if there was - * one. */ - gui_mch_free_font(temp_sg_font); - vim_free(HL_TABLE()[idx].sg_font_name); - HL_TABLE()[idx].sg_font_name = vim_strsave(arg); - did_change = TRUE; - } - else - HL_TABLE()[idx].sg_font = temp_sg_font; - } -#endif - } - else if (STRCMP(key, "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0) - { - if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) - { - if (!init) - HL_TABLE()[idx].sg_set |= SG_CTERM; - - /* When setting the foreground color, and previously the "bold" - * flag was set for a light color, reset it now */ - if (key[5] == 'F' && HL_TABLE()[idx].sg_cterm_bold) - { - HL_TABLE()[idx].sg_cterm &= ~HL_BOLD; - HL_TABLE()[idx].sg_cterm_bold = FALSE; - } - - if (VIM_ISDIGIT(*arg)) - color = atoi((char *)arg); - else if (STRICMP(arg, "fg") == 0) - { - if (cterm_normal_fg_color) - color = cterm_normal_fg_color - 1; - else - { - emsg(_("E419: FG color unknown")); - error = TRUE; - break; - } - } - else if (STRICMP(arg, "bg") == 0) - { - if (cterm_normal_bg_color > 0) - color = cterm_normal_bg_color - 1; - else - { - emsg(_("E420: BG color unknown")); - error = TRUE; - break; - } - } - else - { - int bold = MAYBE; - -#if defined(__QNXNTO__) - static int *color_numbers_8_qansi = color_numbers_8; - /* On qnx, the 8 & 16 color arrays are the same */ - if (STRNCMP(T_NAME, "qansi", 5) == 0) - color_numbers_8_qansi = color_numbers_16; -#endif - - /* reduce calls to STRICMP a bit, it can be slow */ - off = TOUPPER_ASC(*arg); - for (i = (sizeof(color_names) / sizeof(char *)); --i >= 0; ) - if (off == color_names[i][0] - && STRICMP(arg + 1, color_names[i] + 1) == 0) - break; - if (i < 0) - { - semsg(_("E421: Color name or number not recognized: %s"), key_start); - error = TRUE; - break; - } - - color = lookup_color(i, key[5] == 'F', &bold); - - /* set/reset bold attribute to get light foreground - * colors (on some terminals, e.g. "linux") */ - if (bold == TRUE) - { - HL_TABLE()[idx].sg_cterm |= HL_BOLD; - HL_TABLE()[idx].sg_cterm_bold = TRUE; - } - else if (bold == FALSE) - HL_TABLE()[idx].sg_cterm &= ~HL_BOLD; - } - - /* Add one to the argument, to avoid zero. Zero is used for - * "NONE", then "color" is -1. */ - if (key[5] == 'F') - { - HL_TABLE()[idx].sg_cterm_fg = color + 1; - if (is_normal_group) - { - cterm_normal_fg_color = color + 1; - cterm_normal_fg_bold = (HL_TABLE()[idx].sg_cterm & HL_BOLD); -#ifdef FEAT_GUI - /* Don't do this if the GUI is used. */ - if (!gui.in_use && !gui.starting) -#endif - { - must_redraw = CLEAR; - if (termcap_active && color >= 0) - term_fg_color(color); - } - } - } - else - { - HL_TABLE()[idx].sg_cterm_bg = color + 1; - if (is_normal_group) - { - cterm_normal_bg_color = color + 1; -#ifdef FEAT_GUI - /* Don't mess with 'background' if the GUI is used. */ - if (!gui.in_use && !gui.starting) -#endif - { - must_redraw = CLEAR; - if (color >= 0) - { - int dark = -1; - - if (termcap_active) - term_bg_color(color); - if (t_colors < 16) - dark = (color == 0 || color == 4); - /* Limit the heuristic to the standard 16 colors */ - else if (color < 16) - dark = (color < 7 || color == 8); - /* Set the 'background' option if the value is - * wrong. */ - if (dark != -1 - && dark != (*p_bg == 'd') - && !option_was_set((char_u *)"bg")) - { - set_option_value((char_u *)"bg", 0L, - (char_u *)(dark ? "dark" : "light"), 0); - reset_option_was_set((char_u *)"bg"); - } - } - } - } - } - } - } - else if (STRCMP(key, "GUIFG") == 0) - { -#if defined(FEAT_GUI) || defined(FEAT_EVAL) - char_u **namep = &HL_TABLE()[idx].sg_gui_fg_name; - - if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) - { - if (!init) - HL_TABLE()[idx].sg_set |= SG_GUI; - -# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) - /* In GUI guifg colors are only used when recognized */ - i = color_name2handle(arg); - if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT) - { - HL_TABLE()[idx].sg_gui_fg = i; -# endif - if (*namep == NULL || STRCMP(*namep, arg) != 0) - { - vim_free(*namep); - if (STRCMP(arg, "NONE") != 0) - *namep = vim_strsave(arg); - else - *namep = NULL; - did_change = TRUE; - } -# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) -# ifdef FEAT_GUI_X11 - if (is_menu_group && gui.menu_fg_pixel != i) - { - gui.menu_fg_pixel = i; - do_colors = TRUE; - } - if (is_scrollbar_group && gui.scroll_fg_pixel != i) - { - gui.scroll_fg_pixel = i; - do_colors = TRUE; - } -# ifdef FEAT_BEVAL_GUI - if (is_tooltip_group && gui.tooltip_fg_pixel != i) - { - gui.tooltip_fg_pixel = i; - do_colors = TRUE; - } -# endif -# endif - } -# endif - } -#endif - } - else if (STRCMP(key, "GUIBG") == 0) - { -#if defined(FEAT_GUI) || defined(FEAT_EVAL) - char_u **namep = &HL_TABLE()[idx].sg_gui_bg_name; - - if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) - { - if (!init) - HL_TABLE()[idx].sg_set |= SG_GUI; - -# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) - /* In GUI guifg colors are only used when recognized */ - i = color_name2handle(arg); - if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT) - { - HL_TABLE()[idx].sg_gui_bg = i; -# endif - if (*namep == NULL || STRCMP(*namep, arg) != 0) - { - vim_free(*namep); - if (STRCMP(arg, "NONE") != 0) - *namep = vim_strsave(arg); - else - *namep = NULL; - did_change = TRUE; - } -# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) -# ifdef FEAT_GUI_X11 - if (is_menu_group && gui.menu_bg_pixel != i) - { - gui.menu_bg_pixel = i; - do_colors = TRUE; - } - if (is_scrollbar_group && gui.scroll_bg_pixel != i) - { - gui.scroll_bg_pixel = i; - do_colors = TRUE; - } -# ifdef FEAT_BEVAL_GUI - if (is_tooltip_group && gui.tooltip_bg_pixel != i) - { - gui.tooltip_bg_pixel = i; - do_colors = TRUE; - } -# endif -# endif - } -# endif - } -#endif - } - else if (STRCMP(key, "GUISP") == 0) - { -#if defined(FEAT_GUI) || defined(FEAT_EVAL) - char_u **namep = &HL_TABLE()[idx].sg_gui_sp_name; - - if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) - { - if (!init) - HL_TABLE()[idx].sg_set |= SG_GUI; - -# ifdef FEAT_GUI - i = color_name2handle(arg); - if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !gui.in_use) - { - HL_TABLE()[idx].sg_gui_sp = i; -# endif - if (*namep == NULL || STRCMP(*namep, arg) != 0) - { - vim_free(*namep); - if (STRCMP(arg, "NONE") != 0) - *namep = vim_strsave(arg); - else - *namep = NULL; - did_change = TRUE; - } -# ifdef FEAT_GUI - } -# endif - } -#endif - } - else if (STRCMP(key, "START") == 0 || STRCMP(key, "STOP") == 0) - { - char_u buf[100]; - char_u *tname; - - if (!init) - HL_TABLE()[idx].sg_set |= SG_TERM; - - /* - * The "start" and "stop" arguments can be a literal escape - * sequence, or a comma separated list of terminal codes. - */ - if (STRNCMP(arg, "t_", 2) == 0) - { - off = 0; - buf[0] = 0; - while (arg[off] != NUL) - { - /* Isolate one termcap name */ - for (len = 0; arg[off + len] && - arg[off + len] != ','; ++len) - ; - tname = vim_strnsave(arg + off, len); - if (tname == NULL) /* out of memory */ - { - error = TRUE; - break; - } - /* lookup the escape sequence for the item */ - p = get_term_code(tname); - vim_free(tname); - if (p == NULL) /* ignore non-existing things */ - p = (char_u *)""; - - /* Append it to the already found stuff */ - if ((int)(STRLEN(buf) + STRLEN(p)) >= 99) - { - semsg(_("E422: terminal code too long: %s"), arg); - error = TRUE; - break; - } - STRCAT(buf, p); - - /* Advance to the next item */ - off += len; - if (arg[off] == ',') /* another one follows */ - ++off; - } - } - else - { - /* - * Copy characters from arg[] to buf[], translating <> codes. - */ - for (p = arg, off = 0; off < 100 - 6 && *p; ) - { - len = trans_special(&p, buf + off, FALSE, FALSE); - if (len > 0) /* recognized special char */ - off += len; - else /* copy as normal char */ - buf[off++] = *p++; - } - buf[off] = NUL; - } - if (error) - break; - - if (STRCMP(buf, "NONE") == 0) /* resetting the value */ - p = NULL; - else - p = vim_strsave(buf); - if (key[2] == 'A') - { - vim_free(HL_TABLE()[idx].sg_start); - HL_TABLE()[idx].sg_start = p; - } - else - { - vim_free(HL_TABLE()[idx].sg_stop); - HL_TABLE()[idx].sg_stop = p; - } - } - else - { - semsg(_("E423: Illegal argument: %s"), key_start); - error = TRUE; - break; - } - HL_TABLE()[idx].sg_cleared = FALSE; - - /* - * When highlighting has been given for a group, don't link it. - */ - if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK)) - HL_TABLE()[idx].sg_link = 0; - - /* - * Continue with next argument. - */ - linep = skipwhite(linep); - } - - /* - * If there is an error, and it's a new entry, remove it from the table. - */ - if (error && idx == highlight_ga.ga_len) - syn_unadd_group(); - else - { - if (is_normal_group) - { - HL_TABLE()[idx].sg_term_attr = 0; - HL_TABLE()[idx].sg_cterm_attr = 0; -#ifdef FEAT_GUI - HL_TABLE()[idx].sg_gui_attr = 0; - /* - * Need to update all groups, because they might be using "bg" - * and/or "fg", which have been changed now. - */ -#endif -#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) - if (USE_24BIT) - { - highlight_gui_started(); - did_highlight_changed = TRUE; - redraw_all_later(NOT_VALID); - } -#endif - } -#ifdef FEAT_TERMINAL - else if (is_terminal_group) - set_terminal_default_colors( - HL_TABLE()[idx].sg_cterm_fg, HL_TABLE()[idx].sg_cterm_bg); -#endif -#ifdef FEAT_GUI_X11 -# ifdef FEAT_MENU - else if (is_menu_group) - { - if (gui.in_use && do_colors) - gui_mch_new_menu_colors(); - } -# endif - else if (is_scrollbar_group) - { - if (gui.in_use && do_colors) - gui_new_scrollbar_colors(); - else - set_hl_attr(idx); - } -# ifdef FEAT_BEVAL_GUI - else if (is_tooltip_group) - { - if (gui.in_use && do_colors) - gui_mch_new_tooltip_colors(); - } -# endif -#endif - else - set_hl_attr(idx); -#ifdef FEAT_EVAL - HL_TABLE()[idx].sg_script_ctx = current_sctx; - HL_TABLE()[idx].sg_script_ctx.sc_lnum += sourcing_lnum; -#endif - } - - vim_free(key); - vim_free(arg); - - /* Only call highlight_changed() once, after a sequence of highlight - * commands, and only if an attribute actually changed. */ - if ((did_change - || memcmp(&HL_TABLE()[idx], &item_before, sizeof(item_before)) != 0) -#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) - && !did_highlight_changed -#endif - ) - { - /* Do not trigger a redraw when highlighting is changed while - * redrawing. This may happen when evaluating 'statusline' changes the - * StatusLine group. */ - if (!updating_screen) - redraw_all_later(NOT_VALID); - need_highlight_changed = TRUE; - } -} - -#if defined(EXITFREE) || defined(PROTO) - void -free_highlight(void) -{ - int i; - - for (i = 0; i < highlight_ga.ga_len; ++i) - { - highlight_clear(i); - vim_free(HL_TABLE()[i].sg_name); - vim_free(HL_TABLE()[i].sg_name_u); - } - ga_clear(&highlight_ga); -} -#endif - -/* - * Reset the cterm colors to what they were before Vim was started, if - * possible. Otherwise reset them to zero. - */ - void -restore_cterm_colors(void) -{ -#if defined(MSWIN) && !defined(FEAT_GUI_MSWIN) - /* Since t_me has been set, this probably means that the user - * wants to use this as default colors. Need to reset default - * background/foreground colors. */ - mch_set_normal_colors(); -#else -# ifdef VIMDLL - if (!gui.in_use) - { - mch_set_normal_colors(); - return; - } -# endif - cterm_normal_fg_color = 0; - cterm_normal_fg_bold = 0; - cterm_normal_bg_color = 0; -# ifdef FEAT_TERMGUICOLORS - cterm_normal_fg_gui_color = INVALCOLOR; - cterm_normal_bg_gui_color = INVALCOLOR; -# endif -#endif -} - -/* - * Return TRUE if highlight group "idx" has any settings. - * When "check_link" is TRUE also check for an existing link. - */ - static int -hl_has_settings(int idx, int check_link) -{ - return ( HL_TABLE()[idx].sg_term_attr != 0 - || HL_TABLE()[idx].sg_cterm_attr != 0 - || HL_TABLE()[idx].sg_cterm_fg != 0 - || HL_TABLE()[idx].sg_cterm_bg != 0 -#ifdef FEAT_GUI - || HL_TABLE()[idx].sg_gui_attr != 0 - || 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 != NULL -#endif - || (check_link && (HL_TABLE()[idx].sg_set & SG_LINK))); -} - -/* - * Clear highlighting for one group. - */ - static void -highlight_clear(int idx) -{ - HL_TABLE()[idx].sg_cleared = TRUE; - - HL_TABLE()[idx].sg_term = 0; - VIM_CLEAR(HL_TABLE()[idx].sg_start); - VIM_CLEAR(HL_TABLE()[idx].sg_stop); - HL_TABLE()[idx].sg_term_attr = 0; - HL_TABLE()[idx].sg_cterm = 0; - HL_TABLE()[idx].sg_cterm_bold = FALSE; - HL_TABLE()[idx].sg_cterm_fg = 0; - HL_TABLE()[idx].sg_cterm_bg = 0; - HL_TABLE()[idx].sg_cterm_attr = 0; -#if defined(FEAT_GUI) || defined(FEAT_EVAL) - HL_TABLE()[idx].sg_gui = 0; - VIM_CLEAR(HL_TABLE()[idx].sg_gui_fg_name); - VIM_CLEAR(HL_TABLE()[idx].sg_gui_bg_name); - VIM_CLEAR(HL_TABLE()[idx].sg_gui_sp_name); -#endif -#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) - HL_TABLE()[idx].sg_gui_fg = INVALCOLOR; - HL_TABLE()[idx].sg_gui_bg = INVALCOLOR; -#endif -#ifdef FEAT_GUI - HL_TABLE()[idx].sg_gui_sp = INVALCOLOR; - gui_mch_free_font(HL_TABLE()[idx].sg_font); - HL_TABLE()[idx].sg_font = NOFONT; -# ifdef FEAT_XFONTSET - gui_mch_free_fontset(HL_TABLE()[idx].sg_fontset); - HL_TABLE()[idx].sg_fontset = NOFONTSET; -# endif - VIM_CLEAR(HL_TABLE()[idx].sg_font_name); - HL_TABLE()[idx].sg_gui_attr = 0; -#endif -#ifdef FEAT_EVAL - /* Clear the script ID only when there is no link, since that is not - * cleared. */ - if (HL_TABLE()[idx].sg_link == 0) - { - HL_TABLE()[idx].sg_script_ctx.sc_sid = 0; - HL_TABLE()[idx].sg_script_ctx.sc_lnum = 0; - } -#endif -} - -#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO) -/* - * Set the normal foreground and background colors according to the "Normal" - * highlighting group. For X11 also set "Menu", "Scrollbar", and - * "Tooltip" colors. - */ - void -set_normal_colors(void) -{ -# ifdef FEAT_GUI -# ifdef FEAT_TERMGUICOLORS - if (gui.in_use) -# endif - { - if (set_group_colors((char_u *)"Normal", - &gui.norm_pixel, &gui.back_pixel, - FALSE, TRUE, FALSE)) - { - gui_mch_new_colors(); - must_redraw = CLEAR; - } -# ifdef FEAT_GUI_X11 - if (set_group_colors((char_u *)"Menu", - &gui.menu_fg_pixel, &gui.menu_bg_pixel, - TRUE, FALSE, FALSE)) - { -# ifdef FEAT_MENU - gui_mch_new_menu_colors(); -# endif - must_redraw = CLEAR; - } -# ifdef FEAT_BEVAL_GUI - if (set_group_colors((char_u *)"Tooltip", - &gui.tooltip_fg_pixel, &gui.tooltip_bg_pixel, - FALSE, FALSE, TRUE)) - { -# ifdef FEAT_TOOLBAR - gui_mch_new_tooltip_colors(); -# endif - must_redraw = CLEAR; - } -# endif - if (set_group_colors((char_u *)"Scrollbar", - &gui.scroll_fg_pixel, &gui.scroll_bg_pixel, - FALSE, FALSE, FALSE)) - { - gui_new_scrollbar_colors(); - must_redraw = CLEAR; - } -# endif - } -# endif -# ifdef FEAT_TERMGUICOLORS -# ifdef FEAT_GUI - else -# endif - { - int idx; - - idx = syn_name2id((char_u *)"Normal") - 1; - if (idx >= 0) - { - gui_do_one_color(idx, FALSE, FALSE); - - /* If the normal fg or bg color changed a complete redraw is - * required. */ - if (cterm_normal_fg_gui_color != HL_TABLE()[idx].sg_gui_fg - || cterm_normal_bg_gui_color != HL_TABLE()[idx].sg_gui_bg) - { - /* if the GUI color is INVALCOLOR then we use the default cterm - * color */ - cterm_normal_fg_gui_color = HL_TABLE()[idx].sg_gui_fg; - cterm_normal_bg_gui_color = HL_TABLE()[idx].sg_gui_bg; - must_redraw = CLEAR; - } - } - } -# endif -} -#endif - -#if defined(FEAT_GUI) || defined(PROTO) -/* - * Set the colors for "Normal", "Menu", "Tooltip" or "Scrollbar". - */ - static int -set_group_colors( - char_u *name, - guicolor_T *fgp, - guicolor_T *bgp, - int do_menu, - int use_norm, - int do_tooltip) -{ - int idx; - - idx = syn_name2id(name) - 1; - if (idx >= 0) - { - gui_do_one_color(idx, do_menu, do_tooltip); - - if (HL_TABLE()[idx].sg_gui_fg != INVALCOLOR) - *fgp = HL_TABLE()[idx].sg_gui_fg; - else if (use_norm) - *fgp = gui.def_norm_pixel; - if (HL_TABLE()[idx].sg_gui_bg != INVALCOLOR) - *bgp = HL_TABLE()[idx].sg_gui_bg; - else if (use_norm) - *bgp = gui.def_back_pixel; - return TRUE; - } - return FALSE; -} - -/* - * Get the font of the "Normal" group. - * Returns "" when it's not found or not set. - */ - char_u * -hl_get_font_name(void) -{ - int id; - char_u *s; - - id = syn_name2id((char_u *)"Normal"); - if (id > 0) - { - s = HL_TABLE()[id - 1].sg_font_name; - if (s != NULL) - return s; - } - return (char_u *)""; -} - -/* - * Set font for "Normal" group. Called by gui_mch_init_font() when a font has - * actually chosen to be used. - */ - void -hl_set_font_name(char_u *font_name) -{ - int id; - - id = syn_name2id((char_u *)"Normal"); - if (id > 0) - { - vim_free(HL_TABLE()[id - 1].sg_font_name); - HL_TABLE()[id - 1].sg_font_name = vim_strsave(font_name); - } -} - -/* - * Set background color for "Normal" group. Called by gui_set_bg_color() - * when the color is known. - */ - void -hl_set_bg_color_name( - char_u *name) /* must have been allocated */ -{ - int id; - - if (name != NULL) - { - id = syn_name2id((char_u *)"Normal"); - if (id > 0) - { - vim_free(HL_TABLE()[id - 1].sg_gui_bg_name); - HL_TABLE()[id - 1].sg_gui_bg_name = name; - } - } -} - -/* - * Set foreground color for "Normal" group. Called by gui_set_fg_color() - * when the color is known. - */ - void -hl_set_fg_color_name( - char_u *name) /* must have been allocated */ -{ - int id; - - if (name != NULL) - { - id = syn_name2id((char_u *)"Normal"); - if (id > 0) - { - vim_free(HL_TABLE()[id - 1].sg_gui_fg_name); - HL_TABLE()[id - 1].sg_gui_fg_name = name; - } - } -} - -/* - * Return the handle for a font name. - * Returns NOFONT when failed. - */ - static GuiFont -font_name2handle(char_u *name) -{ - if (STRCMP(name, "NONE") == 0) - return NOFONT; - - return gui_mch_get_font(name, TRUE); -} - -# ifdef FEAT_XFONTSET -/* - * Return the handle for a fontset name. - * Returns NOFONTSET when failed. - */ - static GuiFontset -fontset_name2handle(char_u *name, int fixed_width) -{ - if (STRCMP(name, "NONE") == 0) - return NOFONTSET; - - return gui_mch_get_fontset(name, TRUE, fixed_width); -} -# endif - -/* - * Get the font or fontset for one highlight group. - */ - static void -hl_do_font( - int idx, - char_u *arg, - int do_normal, /* set normal font */ - int do_menu UNUSED, /* set menu font */ - int do_tooltip UNUSED, /* set tooltip font */ - int free_font) /* free current font/fontset */ -{ -# ifdef FEAT_XFONTSET - /* If 'guifontset' is not empty, first try using the name as a - * fontset. If that doesn't work, use it as a font name. */ - if (*p_guifontset != NUL -# ifdef FONTSET_ALWAYS - || do_menu -# endif -# ifdef FEAT_BEVAL_TIP - /* In Athena & Motif, the Tooltip highlight group is always a fontset */ - || do_tooltip -# endif - ) - { - if (free_font) - gui_mch_free_fontset(HL_TABLE()[idx].sg_fontset); - HL_TABLE()[idx].sg_fontset = fontset_name2handle(arg, 0 -# ifdef FONTSET_ALWAYS - || do_menu -# endif -# ifdef FEAT_BEVAL_TIP - || do_tooltip -# endif - ); - } - if (HL_TABLE()[idx].sg_fontset != NOFONTSET) - { - /* If it worked and it's the Normal group, use it as the normal - * fontset. Same for the Menu group. */ - if (do_normal) - gui_init_font(arg, TRUE); -# if (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) && defined(FEAT_MENU) - if (do_menu) - { -# ifdef FONTSET_ALWAYS - gui.menu_fontset = HL_TABLE()[idx].sg_fontset; -# else - /* YIKES! This is a bug waiting to crash the program */ - gui.menu_font = HL_TABLE()[idx].sg_fontset; -# endif - gui_mch_new_menu_font(); - } -# ifdef FEAT_BEVAL_GUI - if (do_tooltip) - { - /* The Athena widget set cannot currently handle switching between - * displaying a single font and a fontset. - * If the XtNinternational resource is set to True at widget - * creation, then a fontset is always used, otherwise an - * XFontStruct is used. - */ - gui.tooltip_fontset = (XFontSet)HL_TABLE()[idx].sg_fontset; - gui_mch_new_tooltip_font(); - } -# endif -# endif - } - else -# endif - { - if (free_font) - gui_mch_free_font(HL_TABLE()[idx].sg_font); - HL_TABLE()[idx].sg_font = font_name2handle(arg); - /* If it worked and it's the Normal group, use it as the - * normal font. Same for the Menu group. */ - if (HL_TABLE()[idx].sg_font != NOFONT) - { - if (do_normal) - gui_init_font(arg, FALSE); -#ifndef FONTSET_ALWAYS -# if (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) && defined(FEAT_MENU) - if (do_menu) - { - gui.menu_font = HL_TABLE()[idx].sg_font; - gui_mch_new_menu_font(); - } -# endif -#endif - } - } -} - -#endif /* FEAT_GUI */ - -#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO) -/* - * Return the handle for a color name. - * Returns INVALCOLOR when failed. - */ - guicolor_T -color_name2handle(char_u *name) -{ - if (STRCMP(name, "NONE") == 0) - return INVALCOLOR; - - if (STRICMP(name, "fg") == 0 || STRICMP(name, "foreground") == 0) - { -#if defined(FEAT_TERMGUICOLORS) && defined(FEAT_GUI) - if (gui.in_use) -#endif -#ifdef FEAT_GUI - return gui.norm_pixel; -#endif -#ifdef FEAT_TERMGUICOLORS - if (cterm_normal_fg_gui_color != INVALCOLOR) - return cterm_normal_fg_gui_color; - /* Guess that the foreground is black or white. */ - return GUI_GET_COLOR((char_u *)(*p_bg == 'l' ? "black" : "white")); -#endif - } - if (STRICMP(name, "bg") == 0 || STRICMP(name, "background") == 0) - { -#if defined(FEAT_TERMGUICOLORS) && defined(FEAT_GUI) - if (gui.in_use) -#endif -#ifdef FEAT_GUI - return gui.back_pixel; -#endif -#ifdef FEAT_TERMGUICOLORS - if (cterm_normal_bg_gui_color != INVALCOLOR) - return cterm_normal_bg_gui_color; - /* Guess that the background is white or black. */ - return GUI_GET_COLOR((char_u *)(*p_bg == 'l' ? "white" : "black")); -#endif - } - - return GUI_GET_COLOR(name); -} -#endif - -/* - * Table with the specifications for an attribute number. - * Note that this table is used by ALL buffers. This is required because the - * GUI can redraw at any time for any buffer. - */ -static garray_T term_attr_table = {0, 0, 0, 0, NULL}; - -#define TERM_ATTR_ENTRY(idx) ((attrentry_T *)term_attr_table.ga_data)[idx] - -static garray_T cterm_attr_table = {0, 0, 0, 0, NULL}; - -#define CTERM_ATTR_ENTRY(idx) ((attrentry_T *)cterm_attr_table.ga_data)[idx] - -#ifdef FEAT_GUI -static garray_T gui_attr_table = {0, 0, 0, 0, NULL}; - -#define GUI_ATTR_ENTRY(idx) ((attrentry_T *)gui_attr_table.ga_data)[idx] -#endif - -/* - * Return the attr number for a set of colors and font. - * Add a new entry to the term_attr_table, cterm_attr_table or gui_attr_table - * if the combination is new. - * Return 0 for error (no more room). - */ - static int -get_attr_entry(garray_T *table, attrentry_T *aep) -{ - int i; - attrentry_T *taep; - static int recursive = FALSE; - - /* - * Init the table, in case it wasn't done yet. - */ - table->ga_itemsize = sizeof(attrentry_T); - table->ga_growsize = 7; - - /* - * Try to find an entry with the same specifications. - */ - for (i = 0; i < table->ga_len; ++i) - { - taep = &(((attrentry_T *)table->ga_data)[i]); - if ( aep->ae_attr == taep->ae_attr - && ( -#ifdef FEAT_GUI - (table == &gui_attr_table - && (aep->ae_u.gui.fg_color == taep->ae_u.gui.fg_color - && aep->ae_u.gui.bg_color - == taep->ae_u.gui.bg_color - && aep->ae_u.gui.sp_color - == taep->ae_u.gui.sp_color - && aep->ae_u.gui.font == taep->ae_u.gui.font -# ifdef FEAT_XFONTSET - && aep->ae_u.gui.fontset == taep->ae_u.gui.fontset -# endif - )) - || -#endif - (table == &term_attr_table - && (aep->ae_u.term.start == NULL) - == (taep->ae_u.term.start == NULL) - && (aep->ae_u.term.start == NULL - || STRCMP(aep->ae_u.term.start, - taep->ae_u.term.start) == 0) - && (aep->ae_u.term.stop == NULL) - == (taep->ae_u.term.stop == NULL) - && (aep->ae_u.term.stop == NULL - || STRCMP(aep->ae_u.term.stop, - taep->ae_u.term.stop) == 0)) - || (table == &cterm_attr_table - && aep->ae_u.cterm.fg_color - == taep->ae_u.cterm.fg_color - && aep->ae_u.cterm.bg_color - == taep->ae_u.cterm.bg_color -#ifdef FEAT_TERMGUICOLORS - && aep->ae_u.cterm.fg_rgb - == taep->ae_u.cterm.fg_rgb - && aep->ae_u.cterm.bg_rgb - == taep->ae_u.cterm.bg_rgb -#endif - ))) - - return i + ATTR_OFF; - } - - if (table->ga_len + ATTR_OFF > MAX_TYPENR) - { - /* - * Running out of attribute entries! remove all attributes, and - * compute new ones for all groups. - * When called recursively, we are really out of numbers. - */ - if (recursive) - { - emsg(_("E424: Too many different highlighting attributes in use")); - return 0; - } - recursive = TRUE; - - clear_hl_tables(); - - must_redraw = CLEAR; - - for (i = 0; i < highlight_ga.ga_len; ++i) - set_hl_attr(i); - - recursive = FALSE; - } - - /* - * This is a new combination of colors and font, add an entry. - */ - if (ga_grow(table, 1) == FAIL) - return 0; - - taep = &(((attrentry_T *)table->ga_data)[table->ga_len]); - vim_memset(taep, 0, sizeof(attrentry_T)); - taep->ae_attr = aep->ae_attr; -#ifdef FEAT_GUI - if (table == &gui_attr_table) - { - taep->ae_u.gui.fg_color = aep->ae_u.gui.fg_color; - taep->ae_u.gui.bg_color = aep->ae_u.gui.bg_color; - taep->ae_u.gui.sp_color = aep->ae_u.gui.sp_color; - taep->ae_u.gui.font = aep->ae_u.gui.font; -# ifdef FEAT_XFONTSET - taep->ae_u.gui.fontset = aep->ae_u.gui.fontset; -# endif - } -#endif - if (table == &term_attr_table) - { - if (aep->ae_u.term.start == NULL) - taep->ae_u.term.start = NULL; - else - taep->ae_u.term.start = vim_strsave(aep->ae_u.term.start); - if (aep->ae_u.term.stop == NULL) - taep->ae_u.term.stop = NULL; - else - taep->ae_u.term.stop = vim_strsave(aep->ae_u.term.stop); - } - else if (table == &cterm_attr_table) - { - taep->ae_u.cterm.fg_color = aep->ae_u.cterm.fg_color; - taep->ae_u.cterm.bg_color = aep->ae_u.cterm.bg_color; -#ifdef FEAT_TERMGUICOLORS - taep->ae_u.cterm.fg_rgb = aep->ae_u.cterm.fg_rgb; - taep->ae_u.cterm.bg_rgb = aep->ae_u.cterm.bg_rgb; -#endif - } - ++table->ga_len; - return (table->ga_len - 1 + ATTR_OFF); -} - -#if defined(FEAT_TERMINAL) || defined(PROTO) -/* - * Get an attribute index for a cterm entry. - * Uses an existing entry when possible or adds one when needed. - */ - int -get_cterm_attr_idx(int attr, int fg, int bg) -{ - attrentry_T at_en; - - vim_memset(&at_en, 0, sizeof(attrentry_T)); -#ifdef FEAT_TERMGUICOLORS - at_en.ae_u.cterm.fg_rgb = INVALCOLOR; - at_en.ae_u.cterm.bg_rgb = INVALCOLOR; -#endif - at_en.ae_attr = attr; - at_en.ae_u.cterm.fg_color = fg; - at_en.ae_u.cterm.bg_color = bg; - return get_attr_entry(&cterm_attr_table, &at_en); -} -#endif - -#if (defined(FEAT_TERMINAL) && defined(FEAT_TERMGUICOLORS)) || defined(PROTO) -/* - * Get an attribute index for a 'termguicolors' entry. - * Uses an existing entry when possible or adds one when needed. - */ - int -get_tgc_attr_idx(int attr, guicolor_T fg, guicolor_T bg) -{ - attrentry_T at_en; - - vim_memset(&at_en, 0, sizeof(attrentry_T)); - at_en.ae_attr = attr; - if (fg == INVALCOLOR && bg == INVALCOLOR) - { - /* If both GUI colors are not set fall back to the cterm colors. Helps - * if the GUI only has an attribute, such as undercurl. */ - at_en.ae_u.cterm.fg_rgb = CTERMCOLOR; - at_en.ae_u.cterm.bg_rgb = CTERMCOLOR; - } - else - { - at_en.ae_u.cterm.fg_rgb = fg; - at_en.ae_u.cterm.bg_rgb = bg; - } - return get_attr_entry(&cterm_attr_table, &at_en); -} -#endif - -#if (defined(FEAT_TERMINAL) && defined(FEAT_GUI)) || defined(PROTO) -/* - * Get an attribute index for a cterm entry. - * Uses an existing entry when possible or adds one when needed. - */ - int -get_gui_attr_idx(int attr, guicolor_T fg, guicolor_T bg) -{ - attrentry_T at_en; - - vim_memset(&at_en, 0, sizeof(attrentry_T)); - at_en.ae_attr = attr; - at_en.ae_u.gui.fg_color = fg; - at_en.ae_u.gui.bg_color = bg; - return get_attr_entry(&gui_attr_table, &at_en); -} -#endif - -/* - * Clear all highlight tables. - */ - void -clear_hl_tables(void) -{ - int i; - attrentry_T *taep; - -#ifdef FEAT_GUI - ga_clear(&gui_attr_table); -#endif - for (i = 0; i < term_attr_table.ga_len; ++i) - { - taep = &(((attrentry_T *)term_attr_table.ga_data)[i]); - vim_free(taep->ae_u.term.start); - vim_free(taep->ae_u.term.stop); - } - ga_clear(&term_attr_table); - ga_clear(&cterm_attr_table); -} - -/* - * Combine special attributes (e.g., for spelling) with other attributes - * (e.g., for syntax highlighting). - * "prim_attr" overrules "char_attr". - * This creates a new group when required. - * Since we expect there to be few spelling mistakes we don't cache the - * result. - * Return the resulting attributes. - */ - int -hl_combine_attr(int char_attr, int prim_attr) -{ - attrentry_T *char_aep = NULL; - attrentry_T *spell_aep; - attrentry_T new_en; - - if (char_attr == 0) - return prim_attr; - if (char_attr <= HL_ALL && prim_attr <= HL_ALL) - return ATTR_COMBINE(char_attr, prim_attr); -#ifdef FEAT_GUI - if (gui.in_use) - { - if (char_attr > HL_ALL) - char_aep = syn_gui_attr2entry(char_attr); - if (char_aep != NULL) - new_en = *char_aep; - else - { - vim_memset(&new_en, 0, sizeof(new_en)); - new_en.ae_u.gui.fg_color = INVALCOLOR; - new_en.ae_u.gui.bg_color = INVALCOLOR; - new_en.ae_u.gui.sp_color = INVALCOLOR; - if (char_attr <= HL_ALL) - new_en.ae_attr = char_attr; - } - - if (prim_attr <= HL_ALL) - new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, prim_attr); - else - { - spell_aep = syn_gui_attr2entry(prim_attr); - if (spell_aep != NULL) - { - new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, - spell_aep->ae_attr); - if (spell_aep->ae_u.gui.fg_color != INVALCOLOR) - new_en.ae_u.gui.fg_color = spell_aep->ae_u.gui.fg_color; - if (spell_aep->ae_u.gui.bg_color != INVALCOLOR) - new_en.ae_u.gui.bg_color = spell_aep->ae_u.gui.bg_color; - if (spell_aep->ae_u.gui.sp_color != INVALCOLOR) - new_en.ae_u.gui.sp_color = spell_aep->ae_u.gui.sp_color; - if (spell_aep->ae_u.gui.font != NOFONT) - new_en.ae_u.gui.font = spell_aep->ae_u.gui.font; -# ifdef FEAT_XFONTSET - if (spell_aep->ae_u.gui.fontset != NOFONTSET) - new_en.ae_u.gui.fontset = spell_aep->ae_u.gui.fontset; -# endif - } - } - return get_attr_entry(&gui_attr_table, &new_en); - } -#endif - - if (IS_CTERM) - { - if (char_attr > HL_ALL) - char_aep = syn_cterm_attr2entry(char_attr); - if (char_aep != NULL) - new_en = *char_aep; - 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; - } - - if (prim_attr <= HL_ALL) - new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, prim_attr); - else - { - spell_aep = syn_cterm_attr2entry(prim_attr); - if (spell_aep != NULL) - { - new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, - spell_aep->ae_attr); - if (spell_aep->ae_u.cterm.fg_color > 0) - new_en.ae_u.cterm.fg_color = spell_aep->ae_u.cterm.fg_color; - if (spell_aep->ae_u.cterm.bg_color > 0) - new_en.ae_u.cterm.bg_color = spell_aep->ae_u.cterm.bg_color; -#ifdef FEAT_TERMGUICOLORS - /* If both fg and bg are not set fall back to cterm colors. - * Helps for SpellBad which uses undercurl in the GUI. */ - if (COLOR_INVALID(spell_aep->ae_u.cterm.fg_rgb) - && COLOR_INVALID(spell_aep->ae_u.cterm.bg_rgb)) - { - if (spell_aep->ae_u.cterm.fg_color > 0) - new_en.ae_u.cterm.fg_rgb = CTERMCOLOR; - if (spell_aep->ae_u.cterm.bg_color > 0) - new_en.ae_u.cterm.bg_rgb = CTERMCOLOR; - } - else - { - if (spell_aep->ae_u.cterm.fg_rgb != INVALCOLOR) - new_en.ae_u.cterm.fg_rgb = spell_aep->ae_u.cterm.fg_rgb; - if (spell_aep->ae_u.cterm.bg_rgb != INVALCOLOR) - new_en.ae_u.cterm.bg_rgb = spell_aep->ae_u.cterm.bg_rgb; - } -#endif - } - } - return get_attr_entry(&cterm_attr_table, &new_en); - } - - if (char_attr > HL_ALL) - char_aep = syn_term_attr2entry(char_attr); - if (char_aep != NULL) - new_en = *char_aep; - else - { - vim_memset(&new_en, 0, sizeof(new_en)); - if (char_attr <= HL_ALL) - new_en.ae_attr = char_attr; - } - - if (prim_attr <= HL_ALL) - new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, prim_attr); - else - { - spell_aep = syn_term_attr2entry(prim_attr); - if (spell_aep != NULL) - { - new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, spell_aep->ae_attr); - if (spell_aep->ae_u.term.start != NULL) - { - new_en.ae_u.term.start = spell_aep->ae_u.term.start; - new_en.ae_u.term.stop = spell_aep->ae_u.term.stop; - } - } - } - return get_attr_entry(&term_attr_table, &new_en); -} - -#ifdef FEAT_GUI - - attrentry_T * -syn_gui_attr2entry(int attr) -{ - attr -= ATTR_OFF; - if (attr >= gui_attr_table.ga_len) /* did ":syntax clear" */ - return NULL; - return &(GUI_ATTR_ENTRY(attr)); -} -#endif /* FEAT_GUI */ - -/* - * Get the highlight attributes (HL_BOLD etc.) from an attribute nr. - * Only to be used when "attr" > HL_ALL. - */ - int -syn_attr2attr(int attr) -{ - attrentry_T *aep; - -#ifdef FEAT_GUI - if (gui.in_use) - aep = syn_gui_attr2entry(attr); - else -#endif - if (IS_CTERM) - aep = syn_cterm_attr2entry(attr); - else - aep = syn_term_attr2entry(attr); - - if (aep == NULL) /* highlighting not set */ - return 0; - return aep->ae_attr; -} - - - attrentry_T * -syn_term_attr2entry(int attr) -{ - attr -= ATTR_OFF; - if (attr >= term_attr_table.ga_len) /* did ":syntax clear" */ - return NULL; - return &(TERM_ATTR_ENTRY(attr)); -} - - attrentry_T * -syn_cterm_attr2entry(int attr) -{ - attr -= ATTR_OFF; - if (attr >= cterm_attr_table.ga_len) /* did ":syntax clear" */ - return NULL; - return &(CTERM_ATTR_ENTRY(attr)); -} - -#define LIST_ATTR 1 -#define LIST_STRING 2 -#define LIST_INT 3 - - static void -highlight_list_one(int id) -{ - struct hl_group *sgp; - int didh = FALSE; - - sgp = &HL_TABLE()[id - 1]; // index is ID minus one - - if (message_filtered(sgp->sg_name)) - return; - - didh = highlight_list_arg(id, didh, LIST_ATTR, - sgp->sg_term, NULL, "term"); - didh = highlight_list_arg(id, didh, LIST_STRING, - 0, sgp->sg_start, "start"); - didh = highlight_list_arg(id, didh, LIST_STRING, - 0, sgp->sg_stop, "stop"); - - didh = highlight_list_arg(id, didh, LIST_ATTR, - sgp->sg_cterm, NULL, "cterm"); - didh = highlight_list_arg(id, didh, LIST_INT, - sgp->sg_cterm_fg, NULL, "ctermfg"); - didh = highlight_list_arg(id, didh, LIST_INT, - sgp->sg_cterm_bg, NULL, "ctermbg"); - -#if defined(FEAT_GUI) || defined(FEAT_EVAL) - didh = highlight_list_arg(id, didh, LIST_ATTR, - sgp->sg_gui, NULL, "gui"); - didh = highlight_list_arg(id, didh, LIST_STRING, - 0, sgp->sg_gui_fg_name, "guifg"); - didh = highlight_list_arg(id, didh, LIST_STRING, - 0, sgp->sg_gui_bg_name, "guibg"); - didh = highlight_list_arg(id, didh, LIST_STRING, - 0, sgp->sg_gui_sp_name, "guisp"); -#endif -#ifdef FEAT_GUI - didh = highlight_list_arg(id, didh, LIST_STRING, - 0, sgp->sg_font_name, "font"); -#endif - - if (sgp->sg_link && !got_int) - { - (void)syn_list_header(didh, 9999, id); - didh = TRUE; - msg_puts_attr("links to", HL_ATTR(HLF_D)); - msg_putchar(' '); - msg_outtrans(HL_TABLE()[HL_TABLE()[id - 1].sg_link - 1].sg_name); - } - - if (!didh) - highlight_list_arg(id, didh, LIST_STRING, 0, (char_u *)"cleared", ""); -#ifdef FEAT_EVAL - if (p_verbose > 0) - last_set_msg(sgp->sg_script_ctx); -#endif -} - - static int -highlight_list_arg( - int id, - int didh, - int type, - int iarg, - char_u *sarg, - char *name) -{ - char_u buf[100]; - char_u *ts; - int i; - - if (got_int) - return FALSE; - if (type == LIST_STRING ? (sarg != NULL) : (iarg != 0)) - { - ts = buf; - if (type == LIST_INT) - sprintf((char *)buf, "%d", iarg - 1); - else if (type == LIST_STRING) - ts = sarg; - else /* type == LIST_ATTR */ - { - buf[0] = NUL; - for (i = 0; hl_attr_table[i] != 0; ++i) - { - if (iarg & hl_attr_table[i]) - { - if (buf[0] != NUL) - vim_strcat(buf, (char_u *)",", 100); - vim_strcat(buf, (char_u *)hl_name_table[i], 100); - iarg &= ~hl_attr_table[i]; /* don't want "inverse" */ - } - } - } - - (void)syn_list_header(didh, - (int)(vim_strsize(ts) + STRLEN(name) + 1), id); - didh = TRUE; - if (!got_int) - { - if (*name != NUL) - { - msg_puts_attr(name, HL_ATTR(HLF_D)); - msg_puts_attr("=", HL_ATTR(HLF_D)); - } - msg_outtrans(ts); - } - } - return didh; -} - -#if (((defined(FEAT_EVAL) || defined(FEAT_PRINTER))) && defined(FEAT_SYN_HL)) || defined(PROTO) -/* - * Return "1" if highlight group "id" has attribute "flag". - * Return NULL otherwise. - */ - char_u * -highlight_has_attr( - int id, - int flag, - int modec) /* 'g' for GUI, 'c' for cterm, 't' for term */ -{ - int attr; - - if (id <= 0 || id > highlight_ga.ga_len) - return NULL; - -#if defined(FEAT_GUI) || defined(FEAT_EVAL) - if (modec == 'g') - attr = HL_TABLE()[id - 1].sg_gui; - else -#endif - if (modec == 'c') - attr = HL_TABLE()[id - 1].sg_cterm; - else - attr = HL_TABLE()[id - 1].sg_term; - - if (attr & flag) - return (char_u *)"1"; - return NULL; -} -#endif - -#if (defined(FEAT_SYN_HL) && defined(FEAT_EVAL)) || defined(PROTO) -/* - * Return color name of highlight group "id". - */ - char_u * -highlight_color( - int id, - char_u *what, /* "font", "fg", "bg", "sp", "fg#", "bg#" or "sp#" */ - int modec) /* 'g' for GUI, 'c' for cterm, 't' for term */ -{ - static char_u name[20]; - int n; - int fg = FALSE; - int sp = FALSE; - int font = FALSE; - - if (id <= 0 || id > highlight_ga.ga_len) - return NULL; - - if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'g') - fg = TRUE; - else if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'o' - && TOLOWER_ASC(what[2]) == 'n' && TOLOWER_ASC(what[3]) == 't') - font = TRUE; - else if (TOLOWER_ASC(what[0]) == 's' && TOLOWER_ASC(what[1]) == 'p') - sp = TRUE; - else if (!(TOLOWER_ASC(what[0]) == 'b' && TOLOWER_ASC(what[1]) == 'g')) - return NULL; - if (modec == 'g') - { -# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) -# ifdef FEAT_GUI - /* return font name */ - if (font) - return HL_TABLE()[id - 1].sg_font_name; -# endif - - /* return #RRGGBB form (only possible when GUI is running) */ - if ((USE_24BIT) && what[2] == '#') - { - guicolor_T color; - long_u rgb; - static char_u buf[10]; - - if (fg) - color = HL_TABLE()[id - 1].sg_gui_fg; - else if (sp) -# ifdef FEAT_GUI - color = HL_TABLE()[id - 1].sg_gui_sp; -# else - color = INVALCOLOR; -# endif - else - color = HL_TABLE()[id - 1].sg_gui_bg; - if (color == INVALCOLOR) - return NULL; - rgb = (long_u)GUI_MCH_GET_RGB(color); - sprintf((char *)buf, "#%02x%02x%02x", - (unsigned)(rgb >> 16), - (unsigned)(rgb >> 8) & 255, - (unsigned)rgb & 255); - return buf; - } -# endif - if (fg) - return (HL_TABLE()[id - 1].sg_gui_fg_name); - if (sp) - return (HL_TABLE()[id - 1].sg_gui_sp_name); - return (HL_TABLE()[id - 1].sg_gui_bg_name); - } - if (font || sp) - return NULL; - if (modec == 'c') - { - if (fg) - n = HL_TABLE()[id - 1].sg_cterm_fg - 1; - else - n = HL_TABLE()[id - 1].sg_cterm_bg - 1; - if (n < 0) - return NULL; - sprintf((char *)name, "%d", n); - return name; - } - /* term doesn't have color */ - return NULL; -} -#endif - -#if (defined(FEAT_SYN_HL) \ - && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)) \ - && defined(FEAT_PRINTER)) || defined(PROTO) -/* - * Return color name of highlight group "id" as RGB value. - */ - long_u -highlight_gui_color_rgb( - int id, - int fg) /* TRUE = fg, FALSE = bg */ -{ - guicolor_T color; - - if (id <= 0 || id > highlight_ga.ga_len) - return 0L; - - if (fg) - color = HL_TABLE()[id - 1].sg_gui_fg; - else - color = HL_TABLE()[id - 1].sg_gui_bg; - - if (color == INVALCOLOR) - return 0L; - - return GUI_MCH_GET_RGB(color); -} -#endif - -/* - * Output the syntax list header. - * Return TRUE when started a new line. - */ - static int -syn_list_header( - int did_header, /* did header already */ - int outlen, /* length of string that comes */ - int id) /* highlight group id */ -{ - int endcol = 19; - int newline = TRUE; - int name_col = 0; - - if (!did_header) - { - msg_putchar('\n'); - if (got_int) - return TRUE; - msg_outtrans(HL_TABLE()[id - 1].sg_name); - name_col = msg_col; - endcol = 15; - } - else if (msg_col + outlen + 1 >= Columns) - { - msg_putchar('\n'); - if (got_int) - return TRUE; - } - else - { - if (msg_col >= endcol) /* wrap around is like starting a new line */ - newline = FALSE; - } - - if (msg_col >= endcol) /* output at least one space */ - endcol = msg_col + 1; - if (Columns <= endcol) /* avoid hang for tiny window */ - endcol = Columns - 1; - - msg_advance(endcol); - - /* Show "xxx" with the attributes. */ - if (!did_header) - { - if (endcol == Columns - 1 && endcol <= name_col) - msg_putchar(' '); - msg_puts_attr("xxx", syn_id2attr(id)); - msg_putchar(' '); - } - - return newline; -} - -/* - * Set the attribute numbers for a highlight group. - * Called after one of the attributes has changed. - */ - static void -set_hl_attr( - int idx) /* index in array */ -{ - attrentry_T at_en; - struct hl_group *sgp = HL_TABLE() + idx; - - /* The "Normal" group doesn't need an attribute number */ - if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0) - return; - -#ifdef FEAT_GUI - /* - * For the GUI mode: If there are other than "normal" highlighting - * attributes, need to allocate an attr number. - */ - if (sgp->sg_gui_fg == INVALCOLOR - && sgp->sg_gui_bg == INVALCOLOR - && sgp->sg_gui_sp == INVALCOLOR - && sgp->sg_font == NOFONT -# ifdef FEAT_XFONTSET - && sgp->sg_fontset == NOFONTSET -# endif - ) - { - sgp->sg_gui_attr = sgp->sg_gui; - } - else - { - at_en.ae_attr = sgp->sg_gui; - at_en.ae_u.gui.fg_color = sgp->sg_gui_fg; - at_en.ae_u.gui.bg_color = sgp->sg_gui_bg; - at_en.ae_u.gui.sp_color = sgp->sg_gui_sp; - at_en.ae_u.gui.font = sgp->sg_font; -# ifdef FEAT_XFONTSET - at_en.ae_u.gui.fontset = sgp->sg_fontset; -# endif - sgp->sg_gui_attr = get_attr_entry(&gui_attr_table, &at_en); - } -#endif - /* - * For the term mode: If there are other than "normal" highlighting - * attributes, need to allocate an attr number. - */ - if (sgp->sg_start == NULL && sgp->sg_stop == NULL) - sgp->sg_term_attr = sgp->sg_term; - else - { - at_en.ae_attr = sgp->sg_term; - at_en.ae_u.term.start = sgp->sg_start; - at_en.ae_u.term.stop = sgp->sg_stop; - sgp->sg_term_attr = get_attr_entry(&term_attr_table, &at_en); - } - - /* - * For the color term mode: If there are other than "normal" - * highlighting attributes, need to allocate an attr number. - */ - if (sgp->sg_cterm_fg == 0 && sgp->sg_cterm_bg == 0 -# ifdef FEAT_TERMGUICOLORS - && sgp->sg_gui_fg == INVALCOLOR - && sgp->sg_gui_bg == INVALCOLOR -# endif - ) - sgp->sg_cterm_attr = sgp->sg_cterm; - else - { - at_en.ae_attr = sgp->sg_cterm; - at_en.ae_u.cterm.fg_color = sgp->sg_cterm_fg; - at_en.ae_u.cterm.bg_color = sgp->sg_cterm_bg; -# ifdef FEAT_TERMGUICOLORS -# ifdef MSWIN -# ifdef VIMDLL - // Only when not using the GUI. - if (!gui.in_use && !gui.starting) -# endif - { - int id; - guicolor_T fg, bg; - - id = syn_name2id((char_u *)"Normal"); - if (id > 0) - { - syn_id2colors(id, &fg, &bg); - if (sgp->sg_gui_fg == INVALCOLOR) - sgp->sg_gui_fg = fg; - if (sgp->sg_gui_bg == INVALCOLOR) - sgp->sg_gui_bg = bg; - } - - } -# endif - at_en.ae_u.cterm.fg_rgb = GUI_MCH_GET_RGB2(sgp->sg_gui_fg); - at_en.ae_u.cterm.bg_rgb = GUI_MCH_GET_RGB2(sgp->sg_gui_bg); - if (at_en.ae_u.cterm.fg_rgb == INVALCOLOR - && at_en.ae_u.cterm.bg_rgb == INVALCOLOR) - { - /* If both fg and bg are invalid fall back to the cterm colors. - * Helps when the GUI only uses an attribute, e.g. undercurl. */ - at_en.ae_u.cterm.fg_rgb = CTERMCOLOR; - at_en.ae_u.cterm.bg_rgb = CTERMCOLOR; - } -# endif - sgp->sg_cterm_attr = get_attr_entry(&cterm_attr_table, &at_en); - } -} - -/* - * Lookup a highlight group name and return its ID. - * If it is not found, 0 is returned. - */ - int -syn_name2id(char_u *name) -{ - int i; - char_u name_u[200]; - - /* Avoid using stricmp() too much, it's slow on some systems */ - /* Avoid alloc()/free(), these are slow too. ID names over 200 chars - * don't deserve to be found! */ - vim_strncpy(name_u, name, 199); - vim_strup(name_u); - for (i = highlight_ga.ga_len; --i >= 0; ) - if (HL_TABLE()[i].sg_name_u != NULL - && STRCMP(name_u, HL_TABLE()[i].sg_name_u) == 0) - break; - return i + 1; -} - -/* - * Lookup a highlight group name and return its attributes. - * Return zero if not found. - */ - int -syn_name2attr(char_u *name) -{ - int id = syn_name2id(name); - - if (id != 0) - return syn_id2attr(id); - return 0; -} - -#if defined(FEAT_EVAL) || defined(PROTO) -/* - * Return TRUE if highlight group "name" exists. - */ - int -highlight_exists(char_u *name) -{ - return (syn_name2id(name) > 0); -} - -# if defined(FEAT_SEARCH_EXTRA) || defined(PROTO) -/* - * Return the name of highlight group "id". - * When not a valid ID return an empty string. - */ - char_u * -syn_id2name(int id) -{ - if (id <= 0 || id > highlight_ga.ga_len) - return (char_u *)""; - return HL_TABLE()[id - 1].sg_name; -} -# endif -#endif - -/* - * Like syn_name2id(), but take a pointer + length argument. - */ - int -syn_namen2id(char_u *linep, int len) -{ - char_u *name; - int id = 0; - - name = vim_strnsave(linep, len); - if (name != NULL) - { - id = syn_name2id(name); - vim_free(name); - } - return 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. - */ - int -syn_check_group(char_u *pp, int len) -{ - int id; - char_u *name; - - name = vim_strnsave(pp, len); - if (name == NULL) - return 0; - - id = syn_name2id(name); - if (id == 0) /* doesn't exist yet */ - id = syn_add_group(name); - else - vim_free(name); - return id; -} - -/* - * Add new highlight group and return its ID. - * "name" must be an allocated string, it will be consumed. - * Return 0 for failure. - */ - static int -syn_add_group(char_u *name) -{ - char_u *p; - - /* Check that the name is ASCII letters, digits and underscore. */ - for (p = name; *p != NUL; ++p) - { - if (!vim_isprintc(*p)) - { - emsg(_("E669: Unprintable character in group name")); - vim_free(name); - return 0; - } - else if (!ASCII_ISALNUM(*p) && *p != '_') - { - /* This is an error, but since there previously was no check only - * give a warning. */ - msg_source(HL_ATTR(HLF_W)); - msg(_("W18: Invalid character in group name")); - break; - } - } - - /* - * First call for this growarray: init growing array. - */ - if (highlight_ga.ga_data == NULL) - { - highlight_ga.ga_itemsize = sizeof(struct hl_group); - highlight_ga.ga_growsize = 10; - } - - if (highlight_ga.ga_len >= MAX_HL_ID) - { - emsg(_("E849: Too many highlight and syntax groups")); - vim_free(name); - return 0; - } - - /* - * Make room for at least one other syntax_highlight entry. - */ - if (ga_grow(&highlight_ga, 1) == FAIL) - { - vim_free(name); - return 0; - } - - vim_memset(&(HL_TABLE()[highlight_ga.ga_len]), 0, sizeof(struct hl_group)); - HL_TABLE()[highlight_ga.ga_len].sg_name = name; - HL_TABLE()[highlight_ga.ga_len].sg_name_u = vim_strsave_up(name); -#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) - HL_TABLE()[highlight_ga.ga_len].sg_gui_bg = INVALCOLOR; - HL_TABLE()[highlight_ga.ga_len].sg_gui_fg = INVALCOLOR; -# ifdef FEAT_GUI - HL_TABLE()[highlight_ga.ga_len].sg_gui_sp = INVALCOLOR; -# endif -#endif - ++highlight_ga.ga_len; - - return highlight_ga.ga_len; /* ID is index plus one */ -} - -/* - * When, just after calling syn_add_group(), an error is discovered, this - * function deletes the new name. - */ - static void -syn_unadd_group(void) -{ - --highlight_ga.ga_len; - vim_free(HL_TABLE()[highlight_ga.ga_len].sg_name); - vim_free(HL_TABLE()[highlight_ga.ga_len].sg_name_u); -} - -/* - * Translate a group ID to highlight attributes. - */ - int -syn_id2attr(int hl_id) -{ - int attr; - struct hl_group *sgp; - - hl_id = syn_get_final_id(hl_id); - sgp = &HL_TABLE()[hl_id - 1]; /* index is ID minus one */ - -#ifdef FEAT_GUI - /* - * Only use GUI attr when the GUI is being used. - */ - if (gui.in_use) - attr = sgp->sg_gui_attr; - else -#endif - if (IS_CTERM) - attr = sgp->sg_cterm_attr; - else - attr = sgp->sg_term_attr; - - return attr; -} - -#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO) -/* - * Get the GUI colors and attributes for a group ID. - * NOTE: the colors will be INVALCOLOR when not set, the color otherwise. - */ - int -syn_id2colors(int hl_id, guicolor_T *fgp, guicolor_T *bgp) -{ - struct hl_group *sgp; - - hl_id = syn_get_final_id(hl_id); - sgp = &HL_TABLE()[hl_id - 1]; /* index is ID minus one */ - - *fgp = sgp->sg_gui_fg; - *bgp = sgp->sg_gui_bg; - return sgp->sg_gui; -} -#endif - -#if (defined(MSWIN) \ - && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) \ - && defined(FEAT_TERMGUICOLORS)) || defined(PROTO) - void -syn_id2cterm_bg(int hl_id, int *fgp, int *bgp) -{ - struct hl_group *sgp; - - hl_id = syn_get_final_id(hl_id); - sgp = &HL_TABLE()[hl_id - 1]; /* index is ID minus one */ - *fgp = sgp->sg_cterm_fg - 1; - *bgp = sgp->sg_cterm_bg - 1; -} -#endif - -/* - * Translate a group ID to the final group ID (following links). - */ - int -syn_get_final_id(int hl_id) -{ - int count; - struct hl_group *sgp; - - if (hl_id > highlight_ga.ga_len || hl_id < 1) - return 0; /* Can be called from eval!! */ - - /* - * Follow links until there is no more. - * Look out for loops! Break after 100 links. - */ - for (count = 100; --count >= 0; ) - { - sgp = &HL_TABLE()[hl_id - 1]; /* index is ID minus one */ - if (sgp->sg_link == 0 || sgp->sg_link > highlight_ga.ga_len) - break; - hl_id = sgp->sg_link; - } - - return hl_id; -} - -#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO) -/* - * Call this function just after the GUI has started. - * Also called when 'termguicolors' was set, gui.in_use will be FALSE then. - * It finds the font and color handles for the highlighting groups. - */ - void -highlight_gui_started(void) -{ - int idx; - - /* First get the colors from the "Normal" and "Menu" group, if set */ - if (USE_24BIT) - set_normal_colors(); - - for (idx = 0; idx < highlight_ga.ga_len; ++idx) - gui_do_one_color(idx, FALSE, FALSE); - - highlight_changed(); -} - - static void -gui_do_one_color( - int idx, - int do_menu UNUSED, /* TRUE: might set the menu font */ - int do_tooltip UNUSED) /* TRUE: might set the tooltip font */ -{ - int didit = FALSE; - -# ifdef FEAT_GUI -# ifdef FEAT_TERMGUICOLORS - if (gui.in_use) -# endif - if (HL_TABLE()[idx].sg_font_name != NULL) - { - hl_do_font(idx, HL_TABLE()[idx].sg_font_name, FALSE, do_menu, - do_tooltip, TRUE); - didit = TRUE; - } -# endif - if (HL_TABLE()[idx].sg_gui_fg_name != NULL) - { - HL_TABLE()[idx].sg_gui_fg = - color_name2handle(HL_TABLE()[idx].sg_gui_fg_name); - didit = TRUE; - } - if (HL_TABLE()[idx].sg_gui_bg_name != NULL) - { - HL_TABLE()[idx].sg_gui_bg = - color_name2handle(HL_TABLE()[idx].sg_gui_bg_name); - didit = TRUE; - } -# ifdef FEAT_GUI - if (HL_TABLE()[idx].sg_gui_sp_name != NULL) - { - HL_TABLE()[idx].sg_gui_sp = - color_name2handle(HL_TABLE()[idx].sg_gui_sp_name); - didit = TRUE; - } -# endif - if (didit) /* need to get a new attr number */ - set_hl_attr(idx); -} -#endif - -#if defined(USER_HIGHLIGHT) && defined(FEAT_STL_OPT) -/* - * Apply difference between User[1-9] and HLF_S to HLF_SNC, HLF_ST or HLF_STNC. - */ - static void -combine_stl_hlt( - int id, - int id_S, - int id_alt, - int hlcnt, - int i, - int hlf, - int *table) -{ - struct hl_group *hlt = HL_TABLE(); - - if (id_alt == 0) - { - vim_memset(&hlt[hlcnt + i], 0, sizeof(struct hl_group)); - hlt[hlcnt + i].sg_term = highlight_attr[hlf]; - hlt[hlcnt + i].sg_cterm = highlight_attr[hlf]; -# if defined(FEAT_GUI) || defined(FEAT_EVAL) - hlt[hlcnt + i].sg_gui = highlight_attr[hlf]; -# endif - } - else - mch_memmove(&hlt[hlcnt + i], - &hlt[id_alt - 1], - sizeof(struct hl_group)); - hlt[hlcnt + i].sg_link = 0; - - hlt[hlcnt + i].sg_term ^= - hlt[id - 1].sg_term ^ hlt[id_S - 1].sg_term; - if (hlt[id - 1].sg_start != hlt[id_S - 1].sg_start) - hlt[hlcnt + i].sg_start = hlt[id - 1].sg_start; - if (hlt[id - 1].sg_stop != hlt[id_S - 1].sg_stop) - hlt[hlcnt + i].sg_stop = hlt[id - 1].sg_stop; - hlt[hlcnt + i].sg_cterm ^= - hlt[id - 1].sg_cterm ^ hlt[id_S - 1].sg_cterm; - if (hlt[id - 1].sg_cterm_fg != hlt[id_S - 1].sg_cterm_fg) - hlt[hlcnt + i].sg_cterm_fg = hlt[id - 1].sg_cterm_fg; - if (hlt[id - 1].sg_cterm_bg != hlt[id_S - 1].sg_cterm_bg) - hlt[hlcnt + i].sg_cterm_bg = hlt[id - 1].sg_cterm_bg; -# if defined(FEAT_GUI) || defined(FEAT_EVAL) - hlt[hlcnt + i].sg_gui ^= - hlt[id - 1].sg_gui ^ hlt[id_S - 1].sg_gui; -# endif -# ifdef FEAT_GUI - if (hlt[id - 1].sg_gui_fg != hlt[id_S - 1].sg_gui_fg) - hlt[hlcnt + i].sg_gui_fg = hlt[id - 1].sg_gui_fg; - if (hlt[id - 1].sg_gui_bg != hlt[id_S - 1].sg_gui_bg) - hlt[hlcnt + i].sg_gui_bg = hlt[id - 1].sg_gui_bg; - if (hlt[id - 1].sg_gui_sp != hlt[id_S - 1].sg_gui_sp) - hlt[hlcnt + i].sg_gui_sp = hlt[id - 1].sg_gui_sp; - if (hlt[id - 1].sg_font != hlt[id_S - 1].sg_font) - hlt[hlcnt + i].sg_font = hlt[id - 1].sg_font; -# ifdef FEAT_XFONTSET - if (hlt[id - 1].sg_fontset != hlt[id_S - 1].sg_fontset) - hlt[hlcnt + i].sg_fontset = hlt[id - 1].sg_fontset; -# endif -# endif - highlight_ga.ga_len = hlcnt + i + 1; - set_hl_attr(hlcnt + i); /* At long last we can apply */ - table[i] = syn_id2attr(hlcnt + i + 1); -} -#endif - -/* - * Translate the 'highlight' option into attributes in highlight_attr[] and - * set up the user highlights User1..9. If FEAT_STL_OPT is in use, a set of - * corresponding highlights to use on top of HLF_SNC is computed. - * Called only when the 'highlight' option has been changed and upon first - * screen redraw after any :highlight command. - * Return FAIL when an invalid flag is found in 'highlight'. OK otherwise. - */ - int -highlight_changed(void) -{ - int hlf; - int i; - char_u *p; - int attr; - char_u *end; - int id; -#ifdef USER_HIGHLIGHT - char_u userhl[30]; // use 30 to avoid compiler warning -# ifdef FEAT_STL_OPT - int id_S = -1; - int id_SNC = 0; -# ifdef FEAT_TERMINAL - int id_ST = 0; - int id_STNC = 0; -# endif - int hlcnt; -# endif -#endif - static int hl_flags[HLF_COUNT] = HL_FLAGS; - - need_highlight_changed = FALSE; - - /* - * Clear all attributes. - */ - for (hlf = 0; hlf < (int)HLF_COUNT; ++hlf) - highlight_attr[hlf] = 0; - - /* - * First set all attributes to their default value. - * Then use the attributes from the 'highlight' option. - */ - for (i = 0; i < 2; ++i) - { - if (i) - p = p_hl; - else - p = get_highlight_default(); - if (p == NULL) /* just in case */ - continue; - - while (*p) - { - for (hlf = 0; hlf < (int)HLF_COUNT; ++hlf) - if (hl_flags[hlf] == *p) - break; - ++p; - if (hlf == (int)HLF_COUNT || *p == NUL) - return FAIL; - - /* - * Allow several hl_flags to be combined, like "bu" for - * bold-underlined. - */ - attr = 0; - for ( ; *p && *p != ','; ++p) /* parse upto comma */ - { - if (VIM_ISWHITE(*p)) /* ignore white space */ - continue; - - if (attr > HL_ALL) /* Combination with ':' is not allowed. */ - return FAIL; - - switch (*p) - { - case 'b': attr |= HL_BOLD; - break; - case 'i': attr |= HL_ITALIC; - break; - case '-': - case 'n': /* no highlighting */ - break; - case 'r': attr |= HL_INVERSE; - break; - case 's': attr |= HL_STANDOUT; - break; - case 'u': attr |= HL_UNDERLINE; - break; - case 'c': attr |= HL_UNDERCURL; - break; - case 't': attr |= HL_STRIKETHROUGH; - break; - case ':': ++p; /* highlight group name */ - if (attr || *p == NUL) /* no combinations */ - return FAIL; - end = vim_strchr(p, ','); - if (end == NULL) - end = p + STRLEN(p); - id = syn_check_group(p, (int)(end - p)); - if (id == 0) - return FAIL; - attr = syn_id2attr(id); - p = end - 1; -#if defined(FEAT_STL_OPT) && defined(USER_HIGHLIGHT) - if (hlf == (int)HLF_SNC) - id_SNC = syn_get_final_id(id); -# ifdef FEAT_TERMINAL - else if (hlf == (int)HLF_ST) - id_ST = syn_get_final_id(id); - else if (hlf == (int)HLF_STNC) - id_STNC = syn_get_final_id(id); -# endif - else if (hlf == (int)HLF_S) - id_S = syn_get_final_id(id); -#endif - break; - default: return FAIL; - } - } - highlight_attr[hlf] = attr; - - p = skip_to_option_part(p); /* skip comma and spaces */ - } - } - -#ifdef USER_HIGHLIGHT - /* Setup the user highlights - * - * Temporarily utilize 28 more hl entries: - * 9 for User1-User9 combined with StatusLineNC - * 9 for User1-User9 combined with StatusLineTerm - * 9 for User1-User9 combined with StatusLineTermNC - * 1 for StatusLine default - * Have to be in there simultaneously in case of table overflows in - * get_attr_entry() - */ -# ifdef FEAT_STL_OPT - if (ga_grow(&highlight_ga, 28) == FAIL) - return FAIL; - hlcnt = highlight_ga.ga_len; - if (id_S == -1) - { - /* Make sure id_S is always valid to simplify code below. Use the last - * entry. */ - vim_memset(&HL_TABLE()[hlcnt + 27], 0, sizeof(struct hl_group)); - HL_TABLE()[hlcnt + 18].sg_term = highlight_attr[HLF_S]; - id_S = hlcnt + 19; - } -# endif - for (i = 0; i < 9; i++) - { - sprintf((char *)userhl, "User%d", i + 1); - id = syn_name2id(userhl); - if (id == 0) - { - highlight_user[i] = 0; -# ifdef FEAT_STL_OPT - highlight_stlnc[i] = 0; -# ifdef FEAT_TERMINAL - highlight_stlterm[i] = 0; - highlight_stltermnc[i] = 0; -# endif -# endif - } - else - { - highlight_user[i] = syn_id2attr(id); -# ifdef FEAT_STL_OPT - combine_stl_hlt(id, id_S, id_SNC, hlcnt, i, - HLF_SNC, highlight_stlnc); -# ifdef FEAT_TERMINAL - combine_stl_hlt(id, id_S, id_ST, hlcnt + 9, i, - HLF_ST, highlight_stlterm); - combine_stl_hlt(id, id_S, id_STNC, hlcnt + 18, i, - HLF_STNC, highlight_stltermnc); -# endif -# endif - } - } -# ifdef FEAT_STL_OPT - highlight_ga.ga_len = hlcnt; -# endif - -#endif /* USER_HIGHLIGHT */ - - return OK; -} - -#if defined(FEAT_CMDL_COMPL) || defined(PROTO) - -static void highlight_list(void); -static void highlight_list_two(int cnt, int attr); - -/* - * Handle command line completion for :highlight command. - */ - void -set_context_in_highlight_cmd(expand_T *xp, char_u *arg) -{ - char_u *p; - - /* Default: expand group names */ - xp->xp_context = EXPAND_HIGHLIGHT; - xp->xp_pattern = arg; - include_link = 2; - include_default = 1; - - /* (part of) subcommand already typed */ - if (*arg != NUL) - { - p = skiptowhite(arg); - if (*p != NUL) /* past "default" or group name */ - { - include_default = 0; - if (STRNCMP("default", arg, p - arg) == 0) - { - arg = skipwhite(p); - xp->xp_pattern = arg; - p = skiptowhite(arg); - } - if (*p != NUL) /* past group name */ - { - include_link = 0; - if (arg[1] == 'i' && arg[0] == 'N') - highlight_list(); - if (STRNCMP("link", arg, p - arg) == 0 - || STRNCMP("clear", arg, p - arg) == 0) - { - xp->xp_pattern = skipwhite(p); - p = skiptowhite(xp->xp_pattern); - if (*p != NUL) /* past first group name */ - { - xp->xp_pattern = skipwhite(p); - p = skiptowhite(xp->xp_pattern); - } - } - if (*p != NUL) /* past group name(s) */ - xp->xp_context = EXPAND_NOTHING; - } - } - } -} - -/* - * List highlighting matches in a nice way. - */ - static void -highlight_list(void) -{ - int i; - - for (i = 10; --i >= 0; ) - highlight_list_two(i, HL_ATTR(HLF_D)); - for (i = 40; --i >= 0; ) - highlight_list_two(99, 0); -} - - static void -highlight_list_two(int cnt, int attr) -{ - msg_puts_attr(&("N \bI \b! \b"[cnt / 11]), attr); - msg_clr_eos(); - out_flush(); - ui_delay(cnt == 99 ? 40L : (long)cnt * 50L, FALSE); -} - -#endif /* FEAT_CMDL_COMPL */ - -#if defined(FEAT_CMDL_COMPL) || (defined(FEAT_SYN_HL) && defined(FEAT_EVAL)) \ - || defined(FEAT_SIGNS) || defined(PROTO) -/* - * Function given to ExpandGeneric() to obtain the list of group names. - */ - 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"; - if (idx == highlight_ga.ga_len + include_none && include_default != 0) - return (char_u *)"default"; - if (idx == highlight_ga.ga_len + include_none + include_default - && include_link != 0) - return (char_u *)"link"; - if (idx == highlight_ga.ga_len + include_none + include_default + 1 - && include_link != 0) - return (char_u *)"clear"; -#endif - if (idx >= highlight_ga.ga_len) - return NULL; - return HL_TABLE()[idx].sg_name; -} -#endif - -#if defined(FEAT_GUI) || defined(PROTO) -/* - * Free all the highlight group fonts. - * Used when quitting for systems which need it. - */ - void -free_highlight_fonts(void) -{ - int idx; - - for (idx = 0; idx < highlight_ga.ga_len; ++idx) - { - gui_mch_free_font(HL_TABLE()[idx].sg_font); - HL_TABLE()[idx].sg_font = NOFONT; -# ifdef FEAT_XFONTSET - gui_mch_free_fontset(HL_TABLE()[idx].sg_fontset); - HL_TABLE()[idx].sg_fontset = NOFONTSET; -# endif - } - - gui_mch_free_font(gui.norm_font); -# ifdef FEAT_XFONTSET - gui_mch_free_fontset(gui.fontset); -# endif -# ifndef FEAT_GUI_GTK - gui_mch_free_font(gui.bold_font); - gui_mch_free_font(gui.ital_font); - gui_mch_free_font(gui.boldital_font); -# endif -} -#endif - -/************************************** - * End of Highlighting stuff * - **************************************/ diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_07.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_07.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_07.dump 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_07.dump 2019-07-21 21:04:21.000000000 +0000 @@ -6,5 +6,5 @@ |~| @73 |~| @52|o+0#0000001#ffd7ff255|t|h|e|r| |t|a|b| @11 |~+0#4040ff13#ffffff0| @52|a+0#0000001#ffd7ff255| |c+0#ff404010&|o|m@1|e|n|t| +0#0000001&|l|i|n|e| @6 -|:+0#0000000#ffffff0|c|a|l@1| |p|o|p|u|p|_|m|o|v|e|(|p|o|p|u|p|w|i|n|,| |{|'|l|i|n|e|'|:| |7|,| |'|c|o|l|'|:| |5@1|}|)| @3|t+0#0000001#ffd7ff255|h|i|s| |l|i|n|e| |w|i|l@1| |n|o|t| |f|i +|:+0#0000000#ffffff0| @52|t+0#0000001#ffd7ff255|h|i|s| |l|i|n|e| |w|i|l@1| |n|o|t| |f|i | +0#0000000#ffffff0@53|t+0#0000001#ffd7ff255| |h|e|r|e| @14 diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_cursorline_1.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_cursorline_1.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_cursorline_1.dump 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_cursorline_1.dump 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,10 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @34|1+0#0000001#ffd7ff255@2| +0#4040ff13#ffffff0@35 +|~| @34|2+0#0000001#ffd7ff255@2| +0#4040ff13#ffffff0@35 +|~| @34|3+0#0000001#ffd7ff255@2| +0#4040ff13#ffffff0@35 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|0|,|0|-|1| @8|A|l@1| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_cursorline_2.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_cursorline_2.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_cursorline_2.dump 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_cursorline_2.dump 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,10 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @34|1+0#0000001#e0e0e08@2| +0#4040ff13#ffffff0@35 +|~| @34|2+0#0000001#ffd7ff255@2| +0#4040ff13#ffffff0@35 +|~| @34|3+0#0000001#ffd7ff255@2| +0#4040ff13#ffffff0@35 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|0|,|0|-|1| @8|A|l@1| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_cursorline_3.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_cursorline_3.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_cursorline_3.dump 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_cursorline_3.dump 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,10 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @32|╔+0#0000001#ffd7ff255|═@5|╗| +0#4040ff13#ffffff0@32 +|~| @32|║+0#0000001#ffd7ff255| |1@2| | +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@32 +|~| @32|║+0#0000001#ffd7ff255| |2@2| | +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@32 +|~| @32|╚+0#0000001#ffd7ff255|═@5|╝| +0#4040ff13#ffffff0@32 +|~| @73 +|~| @73 +| +0#0000000&@56|0|,|0|-|1| @8|A|l@1| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_cursorline_4.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_cursorline_4.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_cursorline_4.dump 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_cursorline_4.dump 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,10 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @32|╔+0#0000001#ffd7ff255|═@5|╗| +0#4040ff13#ffffff0@32 +|~| @32|║+0#0000001#ffd7ff255| |2@2| | +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@32 +|~| @32|║+0#0000001#ffd7ff255| |3@2| | +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@32 +|~| @32|╚+0#0000001#ffd7ff255|═@5|╝| +0#4040ff13#ffffff0@32 +|~| @73 +|~| @73 +| +0#0000000&@56|0|,|0|-|1| @8|A|l@1| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_cursorline_5.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_cursorline_5.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_cursorline_5.dump 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_cursorline_5.dump 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,10 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @32|╔+0#0000001#ffd7ff255|═@5|╗| +0#4040ff13#ffffff0@32 +|~| @32|║+0#0000001#ffd7ff255| |1+0&#e0e0e08@2| +0&#ffd7ff255| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@32 +|~| @32|║+0#0000001#ffd7ff255| |2@2| | +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@32 +|~| @32|╚+0#0000001#ffd7ff255|═@5|╝| +0#4040ff13#ffffff0@32 +|~| @73 +|~| @73 +| +0#0000000&@56|0|,|0|-|1| @8|A|l@1| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_cursorline_6.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_cursorline_6.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_cursorline_6.dump 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_cursorline_6.dump 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,10 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @32|╔+0#0000001#ffd7ff255|═@5|╗| +0#4040ff13#ffffff0@32 +|~| @32|║+0#0000001#ffd7ff255| |2@2| | +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@32 +|~| @32|║+0#0000001#ffd7ff255| |3+0&#e0e0e08@2| +0&#ffd7ff255| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@32 +|~| @32|╚+0#0000001#ffd7ff255|═@5|╝| +0#4040ff13#ffffff0@32 +|~| @73 +|~| @73 +| +0#0000000&@56|0|,|0|-|1| @8|A|l@1| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_mask_2.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_mask_2.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_mask_2.dump 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_mask_2.dump 2019-07-21 21:04:21.000000000 +0000 @@ -10,4 +10,4 @@ |1|2|3|4|5|6|7|8|9|1|0|║+0#0000001#ffd7ff255| @10|1+0#0000000#ffffff0|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 |1|2|3|4|5|6|7|8|9|1|0|╚+0#0000001#ffd7ff255|═|1+0#0000000#ffffff0|2|1|═+0#0000001#ffd7ff255@4|1+0#0000000#ffffff0|6|1|7|═+0#0000001#ffd7ff255@1|╝|9+0#0000000#ffffff0|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 |1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 -|:|c|a|l@1| |p|o|p|u|p|_|m|o|v|e|(|w|i|n|i|d|b|,| |{|'|c|o|l|'|:| |1|2|}|)| @19|1|,|1| @10|T|o|p| +|:| @55|1|,|1| @10|T|o|p| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_mask_3.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_mask_3.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_mask_3.dump 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_mask_3.dump 2019-07-21 21:04:21.000000000 +0000 @@ -10,4 +10,4 @@ |1+0#0000000#ffffff0|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|║+0#0000001#ffd7ff255| @10|2+0#0000000#ffffff0 |1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|╚+0#0000001#ffd7ff255|═|7+0#0000000#ffffff0|3|8|═+0#0000001#ffd7ff255@4|1+0#0000000#ffffff0|4|2 |1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 -|:|c|a|l@1| |p|o|p|u|p|_|m|o|v|e|(|w|i|n|i|d|b|,| |{|'|c|o|l|'|:| |6|3|}|)| @19|1|,|1| @10|T|o|p| +|:| @55|1|,|1| @10|T|o|p| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_mask_4.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_mask_4.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_mask_4.dump 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_mask_4.dump 2019-07-21 21:04:21.000000000 +0000 @@ -10,4 +10,4 @@ | +0#0000001#ffd7ff255@6|8+0#0000000#ffffff0|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 |═+0#0000001#ffd7ff255@4|6+0#0000000#ffffff0|7|8|9|═+0#0000001#ffd7ff255@1|╝|1+0#0000000#ffffff0@1|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 |1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 -|:|c|a|l@1| |p|o|p|u|p|_|m|o|v|e|(|w|i|n|i|d|b|,| |{|'|p|o|s|'|:| |'|t|o|p|r|i|g|h|t|'|,| |'|c|o|l|'|:| |1|2|}|)| |1|,|1| @10|T|o|p| +|:| @55|1|,|1| @10|T|o|p| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_mask_5.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_mask_5.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_mask_5.dump 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_mask_5.dump 2019-07-21 21:04:21.000000000 +0000 @@ -10,4 +10,4 @@ |1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 | +0&#e0e0e08@11|1+0&#ffffff0@1|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|═+0#0000001#ffd7ff255@13|X|4+0#0000000#ffffff0|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 |o+0&#e0e0e08|m|e| |5+0&#ffffff0|6|7|t+0&#e0e0e08| @3|1+0&#ffffff0@1|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|║+0#0000001#ffd7ff255| @4|2+0#0000000#ffffff0|9|3| +0#0000001#ffd7ff255@6|║|4+0#0000000#ffffff0|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 -|:|c|t+0&#e0e0e08|h|l+0&#ffffff0| |p|l+0&#e0e0e08|i|n|e| |m+0&#ffffff0|o|v|e|(|w|i|n|i|d|b|,| |{|'|p|o|s|'|:| |'|t|o|p|l|e|f|t|║+0#0000001#ffd7ff255| |j|u|s|t|l+0#0000000#ffffff0|'|:|e+0#0000001#ffd7ff255| |l|i|n|e| |║|,+0#0000000#ffffff0|1| @10|T|o|p| +|:| |t+0&#e0e0e08|h| +0&#ffffff0@2|l+0&#e0e0e08|i|n|e| | +0&#ffffff0@28|║+0#0000001#ffd7ff255| |j|u|s|t| +0#0000000#ffffff0@2|e+0#0000001#ffd7ff255| |l|i|n|e| |║|,+0#0000000#ffffff0|1| @10|T|o|p| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_01.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_01.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_01.dump 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_01.dump 2019-07-21 21:04:21.000000000 +0000 @@ -1,10 +1,10 @@ >1+0&#ffffff0| @73 -|2| @20|╔+0#0000001#ffd7ff255| |m|a|k|e| |a| |c|h|o|i|c|e| |f|r|o|m| |t|h|e| |l|i|s|t| |╗| +0#0000000#ffffff0@21 -|3| @20|║+0#0000001#ffd7ff255| @28|║| +0#0000000#ffffff0@21 -|4| @20|║+0#0000001#ffd7ff255| |o+0#0000000#5fd7ff255|n|e| +0#0000001#ffd7ff255@24|║| +0#0000000#ffffff0@21 +|2| @73 +|3| @20|╔+0#0000001#ffd7ff255| |m|a|k|e| |a| |c|h|o|i|c|e| |f|r|o|m| |t|h|e| |l|i|s|t| |╗| +0#0000000#ffffff0@21 +|4| @20|║+0#0000001#ffd7ff255| |o+0#0000000#5fd7ff255|n|e| +0#0000001&@23| +0&#ffd7ff255|║| +0#0000000#ffffff0@21 |5| @20|║+0#0000001#ffd7ff255| |t|w|o| @24|║| +0#0000000#ffffff0@21 |6| @20|║+0#0000001#ffd7ff255| |a|n|o|t|h|e|r| @20|║| +0#0000000#ffffff0@21 -|7| @20|║+0#0000001#ffd7ff255| @28|║| +0#0000000#ffffff0@21 -|8| @20|╚+0#0000001#ffd7ff255|═@28|╝| +0#0000000#ffffff0@21 +|7| @20|╚+0#0000001#ffd7ff255|═@28|╝| +0#0000000#ffffff0@21 +|8| @73 |9| @73 @57|1|,|1| @10|T|o|p| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_02.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_02.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_02.dump 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_02.dump 2019-07-21 21:04:21.000000000 +0000 @@ -1,10 +1,10 @@ >1+0&#ffffff0| @73 -|2| @20|╔+0#0000001#ffd7ff255| |m|a|k|e| |a| |c|h|o|i|c|e| |f|r|o|m| |t|h|e| |l|i|s|t| |╗| +0#0000000#ffffff0@21 -|3| @20|║+0#0000001#ffd7ff255| @28|║| +0#0000000#ffffff0@21 +|2| @73 +|3| @20|╔+0#0000001#ffd7ff255| |m|a|k|e| |a| |c|h|o|i|c|e| |f|r|o|m| |t|h|e| |l|i|s|t| |╗| +0#0000000#ffffff0@21 |4| @20|║+0#0000001#ffd7ff255| |o|n|e| @24|║| +0#0000000#ffffff0@21 |5| @20|║+0#0000001#ffd7ff255| |t|w|o| @24|║| +0#0000000#ffffff0@21 -|6| @20|║+0#0000001#ffd7ff255| |a+0#0000000#5fd7ff255|n|o|t|h|e|r| +0#0000001#ffd7ff255@20|║| +0#0000000#ffffff0@21 -|7| @20|║+0#0000001#ffd7ff255| @28|║| +0#0000000#ffffff0@21 -|8| @20|╚+0#0000001#ffd7ff255|═@28|╝| +0#0000000#ffffff0@21 +|6| @20|║+0#0000001#ffd7ff255| |a+0#0000000#5fd7ff255|n|o|t|h|e|r| +0#0000001&@19| +0&#ffd7ff255|║| +0#0000000#ffffff0@21 +|7| @20|╚+0#0000001#ffd7ff255|═@28|╝| +0#0000000#ffffff0@21 +|8| @73 |9| @73 @57|1|,|1| @10|T|o|p| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_04.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_04.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_04.dump 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_04.dump 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,10 @@ +>1+0&#ffffff0| @73 +|2| @73 +|3| @31|╔+0#0000001#ffd7ff255|═@6|╗| +0#0000000#ffffff0@32 +|4| @31|║+0#0000001#ffd7ff255| |o+0#0000000#40ff4011|n|e| +0#0000001&@1| +0&#ffd7ff255|║| +0#0000000#ffffff0@32 +|5| @31|║+0#0000001#ffd7ff255| |t|w|o| @2|║| +0#0000000#ffffff0@32 +|6| @31|║+0#0000001#ffd7ff255| |t|h|r|e@1| |║| +0#0000000#ffffff0@32 +|7| @31|╚+0#0000001#ffd7ff255|═@6|╝| +0#0000000#ffffff0@32 +|8| @73 +|9| @73 +@57|1|,|1| @10|T|o|p| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_filter_1.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_filter_1.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_filter_1.dump 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_filter_1.dump 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,10 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @32|╔+0#0000001#ffd7ff255|═@5|╗| +0#4040ff13#ffffff0@32 +|~| @32|║+0#0000001#ffd7ff255| |1@2| | +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@32 +|~| @32|║+0#0000001#ffd7ff255| |2+0&#e0e0e08@2| +0&#ffd7ff255| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@32 +|~| @32|║+0#0000001#ffd7ff255| |3@2| | +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@32 +|~| @32|╚+0#0000001#ffd7ff255|═@5|╝| +0#4040ff13#ffffff0@32 +|~| @73 +|~| @73 +| +0#0000000&@56|0|,|0|-|1| @8|A|l@1| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_filter_2.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_filter_2.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_filter_2.dump 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_filter_2.dump 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,10 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @32|╔+0#0000001#ffd7ff255|═@5|╗| +0#4040ff13#ffffff0@32 +|~| @32|║+0#0000001#ffd7ff255| |1+0&#e0e0e08@2| +0&#ffd7ff255| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@32 +|~| @32|║+0#0000001#ffd7ff255| |2@2| | +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@32 +|~| @32|║+0#0000001#ffd7ff255| |3@2| | +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@32 +|~| @32|╚+0#0000001#ffd7ff255|═@5|╝| +0#4040ff13#ffffff0@32 +|~| @73 +|~| @73 +| +0#0000000&@56|0|,|0|-|1| @8|A|l@1| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_filter_3.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_filter_3.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_filter_3.dump 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_filter_3.dump 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,10 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @32|╔+0#0000001#ffd7ff255|═@5|╗| +0#4040ff13#ffffff0@32 +|~| @32|║+0#0000001#ffd7ff255| |7@2| | +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@32 +|~| @32|║+0#0000001#ffd7ff255| |8@2| | +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@32 +|~| @32|║+0#0000001#ffd7ff255| |9+0&#e0e0e08@2| +0&#ffd7ff255| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@32 +|~| @32|╚+0#0000001#ffd7ff255|═@5|╝| +0#4040ff13#ffffff0@32 +|~| @73 +|~| @73 +| +0#0000000&@56|0|,|0|-|1| @8|A|l@1| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_filter_4.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_filter_4.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_filter_4.dump 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_filter_4.dump 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,10 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @32|╔+0#0000001#ffd7ff255|═@5|╗| +0#4040ff13#ffffff0@32 +|~| @32|║+0#0000001#ffd7ff255| |1+0&#e0e0e08@2| +0&#ffd7ff255| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@32 +|~| @32|║+0#0000001#ffd7ff255| |2@2| | +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@32 +|~| @32|║+0#0000001#ffd7ff255| |3@2| | +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@32 +|~| @32|╚+0#0000001#ffd7ff255|═@5|╝| +0#4040ff13#ffffff0@32 +|~| @73 +|~| @73 +| +0#0000000&@56|0|,|0|-|1| @8|A|l@1| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_maxwidth_1.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_maxwidth_1.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_maxwidth_1.dump 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_maxwidth_1.dump 2019-07-21 21:04:21.000000000 +0000 @@ -1,13 +1,13 @@ >╔+0#0000001#ffd7ff255|═@2|╗| +0#0000000#ffffff0@9|╔+0#0000001#ffd7ff255|═@11|╗| +0#0000000#ffffff0@2|╔+0#0000001#ffd7ff255|═@12|╗| +0#0000000#ffffff0@27 -|║+0#0000001#ffd7ff255| @2|║| +0#0000000#ffffff0@9|║+0#0000001#ffd7ff255| @11|║| +0#0000000#ffffff0@2|║+0#0000001#ffd7ff255| @12|║| +0#0000000#ffffff0@27 |║+0#0000001#ffd7ff255| |x+0&#e0e0e08| +0&#ffd7ff255|║| +0#0000000#ffffff0@9|║+0#0000001#ffd7ff255| |1+0&#e0e0e08|2|3|4|5|6|7|8|9||| +0&#ffd7ff255|║| +0#0000000#ffffff0@2|║+0#0000001#ffd7ff255| |1+0&#e0e0e08|2|3|4|5|6|7|8|9||| +0&#ffd7ff255| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@27 -|║+0#0000001#ffd7ff255| @2|║| +0#0000000#ffffff0@9|║+0#0000001#ffd7ff255| @11|║| +0#0000000#ffffff0@2|║+0#0000001#ffd7ff255| |1|2|3|4|5|6|7|8|9||| | +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@27 -|╚+0#0000001#ffd7ff255|═@2|╝| +0#0000000#ffffff0@9|╚+0#0000001#ffd7ff255|═@11|╝| +0#0000000#ffffff0@2|║+0#0000001#ffd7ff255| |1|2|3|4|5|6|7|8|9||| | +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@27 -|6| @30|║+0#0000001#ffd7ff255| @12|║| +0#0000000#ffffff0@27 -|╔+0#0000001#ffd7ff255|═@11|╗| +0#0000000#ffffff0|╔+0#0000001#ffd7ff255|═@11|╗| +0#0000000#ffffff0@2|╚+0#0000001#ffd7ff255|═@12|╝| +0#0000000#ffffff0@27 -|║+0#0000001#ffd7ff255| @11|║| +0#0000000#ffffff0|║+0#0000001#ffd7ff255| @11|║| +0#0000000#ffffff0@45 +|╚+0#0000001#ffd7ff255|═@2|╝| +0#0000000#ffffff0@9|╚+0#0000001#ffd7ff255|═@11|╝| +0#0000000#ffffff0@2|║+0#0000001#ffd7ff255| |1|2|3|4|5|6|7|8|9||| | +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@27 +|4| @30|║+0#0000001#ffd7ff255| |1|2|3|4|5|6|7|8|9||| | +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@27 +|5| @30|╚+0#0000001#ffd7ff255|═@12|╝| +0#0000000#ffffff0@27 +|6| @73 +|╔+0#0000001#ffd7ff255|═@11|╗| +0#0000000#ffffff0|╔+0#0000001#ffd7ff255|═@11|╗| +0#0000000#ffffff0@45 |║+0#0000001#ffd7ff255| |1+0&#e0e0e08|2|3|4|5|6|7|8|9||| +0&#ffd7ff255|║| +0#0000000#ffffff0|║+0#0000001#ffd7ff255| |1+0&#e0e0e08|2|3|4|5|6|7|8|9||| +0&#ffd7ff255|║| +0#0000000#ffffff0@45 -|║+0#0000001#ffd7ff255| @11|║| +0#0000000#ffffff0|║+0#0000001#ffd7ff255| @11|║| +0#0000000#ffffff0@45 -|╚+0#0000001#ffd7ff255|═@11|╝| +0#4040ff13#ffffff0|╚+0#0000001#ffd7ff255|═@11|╝| +0#4040ff13#ffffff0@45 +|╚+0#0000001#ffd7ff255|═@11|╝| +0#0000000#ffffff0|╚+0#0000001#ffd7ff255|═@11|╝| +0#0000000#ffffff0@45 +|1|0| @72 +|~+0#4040ff13&| @73 |~| @73 | +0#0000000&@56|1|,|1| @10|A|l@1| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_scroll_1.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_scroll_1.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_scroll_1.dump 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_scroll_1.dump 2019-07-21 21:04:21.000000000 +0000 @@ -1,10 +1,10 @@ >1+0&#ffffff0| @73 -|2| @29|╔+0#0000001#ffd7ff255|═@10|╗| +0#0000000#ffffff0@30 -|3| @29|║+0#0000001#ffd7ff255| @10|║| +0#0000000#ffffff0@30 +|2| @73 +|3| @29|╔+0#0000001#ffd7ff255|═@10|╗| +0#0000000#ffffff0@30 |4| @29|║+0#0000001#ffd7ff255| |o|n|e| @5| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 -|5| @29|║+0#0000001#ffd7ff255| |t+0&#e0e0e08|w|o| +0&#ffd7ff255@5| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 +|5| @29|║+0#0000001#ffd7ff255| |t+0&#e0e0e08|w|o| @4| +0&#ffd7ff255| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 |6| @29|║+0#0000001#ffd7ff255| |t|h|r|e@1| @3| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 -|7| @29|║+0#0000001#ffd7ff255| @10|║| +0#0000000#ffffff0@30 -|8| @29|╚+0#0000001#ffd7ff255|═@10|╝| +0#0000000#ffffff0@30 +|7| @29|╚+0#0000001#ffd7ff255|═@10|╝| +0#0000000#ffffff0@30 +|8| @73 |9| @73 @57|1|,|1| @10|T|o|p| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_scroll_2.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_scroll_2.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_scroll_2.dump 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_scroll_2.dump 2019-07-21 21:04:21.000000000 +0000 @@ -1,10 +1,10 @@ >1+0&#ffffff0| @73 -|2| @29|╔+0#0000001#ffd7ff255|═@10|╗| +0#0000000#ffffff0@30 -|3| @29|║+0#0000001#ffd7ff255| @10|║| +0#0000000#ffffff0@30 +|2| @73 +|3| @29|╔+0#0000001#ffd7ff255|═@10|╗| +0#0000000#ffffff0@30 |4| @29|║+0#0000001#ffd7ff255| |t|h|r|e@1| @3| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 |5| @29|║+0#0000001#ffd7ff255| |f|o|u|r| @4| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 -|6| @29|║+0#0000001#ffd7ff255| |f+0&#e0e0e08|i|v|e| +0&#ffd7ff255@4| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 -|7| @29|║+0#0000001#ffd7ff255| @10|║| +0#0000000#ffffff0@30 -|8| @29|╚+0#0000001#ffd7ff255|═@10|╝| +0#0000000#ffffff0@30 +|6| @29|║+0#0000001#ffd7ff255| |f+0&#e0e0e08|i|v|e| @3| +0&#ffd7ff255| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 +|7| @29|╚+0#0000001#ffd7ff255|═@10|╝| +0#0000000#ffffff0@30 +|8| @73 |9| @73 @57|1|,|1| @10|T|o|p| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_scroll_3.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_scroll_3.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_scroll_3.dump 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_scroll_3.dump 2019-07-21 21:04:21.000000000 +0000 @@ -1,10 +1,10 @@ >1+0&#ffffff0| @73 -|2| @29|╔+0#0000001#ffd7ff255|═@10|╗| +0#0000000#ffffff0@30 -|3| @29|║+0#0000001#ffd7ff255| @10|║| +0#0000000#ffffff0@30 +|2| @73 +|3| @29|╔+0#0000001#ffd7ff255|═@10|╗| +0#0000000#ffffff0@30 |4| @29|║+0#0000001#ffd7ff255| |s|e|v|e|n| @3| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 |5| @29|║+0#0000001#ffd7ff255| |e|i|g|h|t| @3| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 -|6| @29|║+0#0000001#ffd7ff255| |n+0&#e0e0e08|i|n|e| +0&#ffd7ff255@4| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 -|7| @29|║+0#0000001#ffd7ff255| @10|║| +0#0000000#ffffff0@30 -|8| @29|╚+0#0000001#ffd7ff255|═@10|╝| +0#0000000#ffffff0@30 +|6| @29|║+0#0000001#ffd7ff255| |n+0&#e0e0e08|i|n|e| @3| +0&#ffd7ff255| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 +|7| @29|╚+0#0000001#ffd7ff255|═@10|╝| +0#0000000#ffffff0@30 +|8| @73 |9| @73 @57|1|,|1| @10|T|o|p| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_scroll_4.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_scroll_4.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_scroll_4.dump 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_scroll_4.dump 2019-07-21 21:04:21.000000000 +0000 @@ -1,10 +1,10 @@ >1+0&#ffffff0| @73 -|2| @29|╔+0#0000001#ffd7ff255|═@10|╗| +0#0000000#ffffff0@30 -|3| @29|║+0#0000001#ffd7ff255| @10|║| +0#0000000#ffffff0@30 -|4| @29|║+0#0000001#ffd7ff255| |s+0&#e0e0e08|e|v|e|n| +0&#ffd7ff255@3| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 +|2| @73 +|3| @29|╔+0#0000001#ffd7ff255|═@10|╗| +0#0000000#ffffff0@30 +|4| @29|║+0#0000001#ffd7ff255| |s+0&#e0e0e08|e|v|e|n| @2| +0&#ffd7ff255| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 |5| @29|║+0#0000001#ffd7ff255| |e|i|g|h|t| @3| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 |6| @29|║+0#0000001#ffd7ff255| |n|i|n|e| @4| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 -|7| @29|║+0#0000001#ffd7ff255| @10|║| +0#0000000#ffffff0@30 -|8| @29|╚+0#0000001#ffd7ff255|═@10|╝| +0#0000000#ffffff0@30 +|7| @29|╚+0#0000001#ffd7ff255|═@10|╝| +0#0000000#ffffff0@30 +|8| @73 |9| @73 @57|1|,|1| @10|T|o|p| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_scroll_5.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_scroll_5.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_scroll_5.dump 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_scroll_5.dump 2019-07-21 21:04:21.000000000 +0000 @@ -1,10 +1,10 @@ >1+0&#ffffff0| @73 -|2| @29|╔+0#0000001#ffd7ff255|═@10|╗| +0#0000000#ffffff0@30 -|3| @29|║+0#0000001#ffd7ff255| @10|║| +0#0000000#ffffff0@30 -|4| @29|║+0#0000001#ffd7ff255| |s+0&#e0e0e08|i|x| +0&#ffd7ff255@5| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 +|2| @73 +|3| @29|╔+0#0000001#ffd7ff255|═@10|╗| +0#0000000#ffffff0@30 +|4| @29|║+0#0000001#ffd7ff255| |s+0&#e0e0e08|i|x| @4| +0&#ffd7ff255| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 |5| @29|║+0#0000001#ffd7ff255| |s|e|v|e|n| @3| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 |6| @29|║+0#0000001#ffd7ff255| |e|i|g|h|t| @3| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 -|7| @29|║+0#0000001#ffd7ff255| @10|║| +0#0000000#ffffff0@30 -|8| @29|╚+0#0000001#ffd7ff255|═@10|╝| +0#0000000#ffffff0@30 +|7| @29|╚+0#0000001#ffd7ff255|═@10|╝| +0#0000000#ffffff0@30 +|8| @73 |9| @73 @57|1|,|1| @10|T|o|p| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_scroll_6.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_scroll_6.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_menu_scroll_6.dump 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_menu_scroll_6.dump 2019-07-21 21:04:21.000000000 +0000 @@ -1,10 +1,10 @@ >1+0&#ffffff0| @73 -|2| @29|╔+0#0000001#ffd7ff255|═@10|╗| +0#0000000#ffffff0@30 -|3| @29|║+0#0000001#ffd7ff255| @10|║| +0#0000000#ffffff0@30 -|4| @29|║+0#0000001#ffd7ff255| |o+0&#e0e0e08|n|e| +0&#ffd7ff255@5| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 +|2| @73 +|3| @29|╔+0#0000001#ffd7ff255|═@10|╗| +0#0000000#ffffff0@30 +|4| @29|║+0#0000001#ffd7ff255| |o+0&#e0e0e08|n|e| @4| +0&#ffd7ff255| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 |5| @29|║+0#0000001#ffd7ff255| |t|w|o| @5| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 |6| @29|║+0#0000001#ffd7ff255| |t|h|r|e@1| @3| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@30 -|7| @29|║+0#0000001#ffd7ff255| @10|║| +0#0000000#ffffff0@30 -|8| @29|╚+0#0000001#ffd7ff255|═@10|╝| +0#0000000#ffffff0@30 +|7| @29|╚+0#0000001#ffd7ff255|═@10|╝| +0#0000000#ffffff0@30 +|8| @73 |9| @73 @57|1|,|1| @10|T|o|p| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_previewpopup_1.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_previewpopup_1.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_previewpopup_1.dump 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_previewpopup_1.dump 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,14 @@ +|o+0&#ffffff0|n|e| @71 +|t|w|o| @1|╔+0#0000001#ffd7ff255|═@40|X| +0#0000000#ffffff0@26 +|t|h|r|e@1|║+0#0000001#ffd7ff255|2|0| @37| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26 +|f|o|u|r| |║+0#0000001#ffd7ff255|t|h|e|w|o|r|d| |i|s| |h|e|r|e| @24| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26 +|f|i|v|e| |║+0#0000001#ffd7ff255|2@1| @37| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26 +|s|i|x| @1|║+0#0000001#ffd7ff255|2|3| @37| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26 +|s|e|v|e|n|╚+0#0000001#ffd7ff255|═@40|╝| +0#0000000#ffffff0@26 +|f|i|n|d| >t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| @52 +|n|i|n|e| @70 +|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @54 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|:+0#0000000&| @55|8|,|6| @10|A|l@1| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_previewpopup_2.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_previewpopup_2.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_previewpopup_2.dump 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_previewpopup_2.dump 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,14 @@ +|o+0&#ffffff0|n|e| @71 +|t|w|o| @71 +|t|h|r|e@1| @69 +|f|o|u|r| @3|╔+0#0000001#ffd7ff255|═@40|X| +0#0000000#ffffff0@23 +|f|i|v|e| @3|║+0#0000001#ffd7ff255|2|7| @37| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@23 +|s|i|x| @4|║+0#0000001#ffd7ff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @18| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@23 +|s|e|v|e|n| @2|║+0#0000001#ffd7ff255|2|9| @37| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@23 +|f|i|n|d| |t|h|e|║+0#0000001#ffd7ff255|3|0| @37| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@23 +|n|i|n|e| @3|╚+0#0000001#ffd7ff255|═@40|╝| +0#0000000#ffffff0@23 +|t|h|i|s| |i|s| >a|n|o|t|h|e|r| |w|o|r|d| @54 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|/+0#0000000&|a|n|o|t|h|e|r| @48|1|0|,|9| @9|A|l@1| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_scroll_2.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_scroll_2.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_scroll_2.dump 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_scroll_2.dump 2019-07-21 21:04:21.000000000 +0000 @@ -7,4 +7,4 @@ |7| @31|f+0#0000001#ffd7ff255|i|v|e| @3| +0#0000000#a8a8a8255| +0&#ffffff0@32 |8| @73 |9| @73 -|:|c|a|l@1| |p|o|p|u|p|_|s|e|t|o|p|t|i|o|n|s|(|w|i|n|i|d|,| |{|'|f|i|r|s|t|l|i|n|e|'|:| |2|}|)| @9|1|,|1| @10|T|o|p| +|:| @55|1|,|1| @10|T|o|p| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_scroll_3.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_scroll_3.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_scroll_3.dump 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_scroll_3.dump 2019-07-21 21:04:21.000000000 +0000 @@ -7,4 +7,4 @@ |7| @31|n+0#0000001#ffd7ff255|i|n|e| @3| +0#0000000#0000001| +0&#ffffff0@32 |8| @73 |9| @73 -|:|c|a|l@1| |p|o|p|u|p|_|s|e|t|o|p|t|i|o|n|s|(|w|i|n|i|d|,| |{|'|f|i|r|s|t|l|i|n|e|'|:| |6|}|)| @9|1|,|1| @10|T|o|p| +|:| @55|1|,|1| @10|T|o|p| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_scroll_4.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_scroll_4.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_scroll_4.dump 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_scroll_4.dump 2019-07-21 21:04:21.000000000 +0000 @@ -7,4 +7,4 @@ |7| @73 |8| @73 |9| @73 -|:|c|a|l@1| |p|o|p|u|p|_|s|e|t|o|p|t|i|o|n|s|(|w|i|n|i|d|,| |{|'|f|i|r|s|t|l|i|n|e|'|:| |9|}|)| @9|1|,|1| @10|T|o|p| +|:| @55|1|,|1| @10|T|o|p| diff -Nru vim-8.1.1681/src/testdir/dumps/Test_popupwin_showbreak.dump vim-8.1.1729/src/testdir/dumps/Test_popupwin_showbreak.dump --- vim-8.1.1681/src/testdir/dumps/Test_popupwin_showbreak.dump 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/testdir/dumps/Test_popupwin_showbreak.dump 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,10 @@ +>1+0&#ffffff0| @73 +|2| @73 +|3| @73 +|4| @25|╔+0#0000001#ffd7ff255|═@17|╗| +0#0000000#ffffff0@27 +|5| @25|║+0#0000001#ffd7ff255| |a| |l|o|n|g| |l|i|n|e| |h|e|r|e| |║| +0#0000000#ffffff0@27 +|6| @25|╚+0#0000001#ffd7ff255|═@17|╝| +0#0000000#ffffff0@27 +|7| @73 +|8| @73 +|9| @73 +@57|1|,|1| @10|T|o|p| diff -Nru vim-8.1.1681/src/testdir/gen_opt_test.vim vim-8.1.1729/src/testdir/gen_opt_test.vim --- vim-8.1.1681/src/testdir/gen_opt_test.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/gen_opt_test.vim 2019-07-21 21:04:21.000000000 +0000 @@ -116,6 +116,7 @@ \ 'mousemodel': [['', 'popup'], ['xxx']], \ 'mouseshape': [['', 'n:arrow'], ['xxx']], \ 'nrformats': [['', 'alpha', 'alpha,hex,bin'], ['xxx']], + \ 'previewpopup': [['', 'height:13', 'width:10,height:234'], ['height:yes', 'xxx', 'xxx:99']], \ 'printmbfont': [['', 'r:some', 'b:Bold,c:yes'], ['xxx']], \ 'printoptions': [['', 'header:0', 'left:10pc,top:5pc'], ['xxx']], \ 'scrollopt': [['', 'ver', 'ver,hor'], ['xxx']], diff -Nru vim-8.1.1681/src/testdir/Makefile vim-8.1.1729/src/testdir/Makefile --- vim-8.1.1681/src/testdir/Makefile 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/Makefile 2019-07-21 21:04:21.000000000 +0000 @@ -81,7 +81,7 @@ RM_ON_RUN = test.out X* viminfo RM_ON_START = tiny.vim small.vim mbyte.vim mzscheme.vim test.ok benchmark.out -RUN_VIM = VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u unix.vim $(NO_INITS) -s dotest.in +RUN_VIM = VIMRUNTIME=$(SCRIPTSOURCE) $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u unix.vim $(NO_INITS) -s dotest.in clean: -rm -rf *.out *.failed *.res *.rej *.orig XfakeHOME Xdir1 Xfind @@ -150,7 +150,7 @@ # 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 +RUN_VIMTEST = VIMRUNTIME=$(SCRIPTSOURCE) $(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; fi" diff -Nru vim-8.1.1681/src/testdir/shared.vim vim-8.1.1729/src/testdir/shared.vim --- vim-8.1.1681/src/testdir/shared.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/shared.vim 2019-07-21 21:04:21.000000000 +0000 @@ -261,7 +261,7 @@ let cmd = cmd . ' -u ' . name endif let cmd .= ' --not-a-term' - let cmd = substitute(cmd, 'VIMRUNTIME=.*VIMRUNTIME;', '', '') + let cmd = substitute(cmd, 'VIMRUNTIME=\S\+', '', '') " If using valgrind, make sure every run uses a different log file. if cmd =~ 'valgrind.*--log-file=' diff -Nru vim-8.1.1681/src/testdir/test_diffmode.vim vim-8.1.1729/src/testdir/test_diffmode.vim --- vim-8.1.1681/src/testdir/test_diffmode.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/test_diffmode.vim 2019-07-21 21:04:21.000000000 +0000 @@ -743,6 +743,7 @@ call term_sendkeys(a:buf, ":diffupdate!\") " trailing : for leaving the cursor on the command line call term_sendkeys(a:buf, ":set diffopt=internal,filler" . a:extra . "\:") + call term_wait(a:buf) call VerifyScreenDump(a:buf, a:dumpfile, {}) endfunc diff -Nru vim-8.1.1681/src/testdir/test_eval_stuff.vim vim-8.1.1729/src/testdir/test_eval_stuff.vim --- vim-8.1.1681/src/testdir/test_eval_stuff.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/test_eval_stuff.vim 2019-07-21 21:04:21.000000000 +0000 @@ -176,6 +176,13 @@ call assert_true(v:versionlong > 8011525) endfunc +func Test_dict_access_scriptversion2() + let l:x = {'foo': 1} + + call assert_false(0 && l:x.foo) + call assert_true(1 && l:x.foo) +endfunc + func Test_scriptversion() call writefile(['scriptversion 9'], 'Xversionscript') call assert_fails('source Xversionscript', 'E999:') diff -Nru vim-8.1.1681/src/testdir/test_let.vim vim-8.1.1729/src/testdir/test_let.vim --- vim-8.1.1681/src/testdir/test_let.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/test_let.vim 2019-07-21 21:04:21.000000000 +0000 @@ -164,14 +164,37 @@ call assert_fails('source XheredocFail', 'E126:') call delete('XheredocFail') - let text =<< trim END + let text =<< trim CodeEnd func MissingEnd() let v =<< END endfunc - END + CodeEnd call writefile(text, 'XheredocWrong') call assert_fails('source XheredocWrong', 'E126:') call delete('XheredocWrong') + + let text =<< trim TEXTend + let v =<< " comment + TEXTend + call writefile(text, 'XheredocNoMarker') + call assert_fails('source XheredocNoMarker', 'E172:') + call delete('XheredocNoMarker') + + let text =<< trim TEXTend + let v =<< text + TEXTend + call writefile(text, 'XheredocBadMarker') + call assert_fails('source XheredocBadMarker', 'E221:') + call delete('XheredocBadMarker') +endfunc + +func Test_let_heredoc_trim_no_indent_marker() + let text =<< trim END + Text + with + indent +END + call assert_equal(['Text', 'with', 'indent'], text) endfunc " Test for the setting a variable using the heredoc syntax @@ -184,9 +207,9 @@ call assert_equal(["Some sample text", "\tText with indent", " !@#$%^&*()-+_={}|[]\\~`:\";'<>?,./"], var1) - let var2 =<< + let var2 =<< XXX Editor -. +XXX call assert_equal(['Editor'], var2) let var3 =<") call term_sendkeys(buf, ":let popupwin = popup_create([" - \ .. "{'text': 'other tab'}," - \ .. "{'text': 'a comment line', 'props': [{" - \ .. "'col': 3, 'length': 7, 'minwidth': 20, 'type': 'comment'" + \ .. "#{text: 'other tab'}," + \ .. "#{text: 'a comment line', props: [#{" + \ .. "col: 3, length: 7, minwidth: 20, type: 'comment'" \ .. "}]}," - \ .. "], {'line': 4, 'col': 9, 'minwidth': 20})\") + \ .. "], #{line: 4, col: 9, minwidth: 20})\") call VerifyScreenDump(buf, 'Test_popupwin_02', {}) " switch back to first tabpage @@ -48,7 +48,7 @@ call term_sendkeys(buf, ":let &columns = cols\") " resize popup, show empty line at bottom - call term_sendkeys(buf, ":call popup_move(popupwin, {'minwidth': 15, 'maxwidth': 25, 'minheight': 3, 'maxheight': 5})\") + call term_sendkeys(buf, ":call popup_move(popupwin, #{minwidth: 15, maxwidth: 25, minheight: 3, maxheight: 5})\") call term_sendkeys(buf, ":redraw\") call VerifyScreenDump(buf, 'Test_popupwin_05', {}) @@ -59,7 +59,8 @@ " move popup over ruler call term_sendkeys(buf, ":set cmdheight=2\") - call term_sendkeys(buf, ":call popup_move(popupwin, {'line': 7, 'col': 55})\") + call term_sendkeys(buf, ":call popup_move(popupwin, #{line: 7, col: 55})\") + call term_sendkeys(buf, ":\") call VerifyScreenDump(buf, 'Test_popupwin_07', {}) " clear all popups after moving the cursor a bit, so that ruler is updated @@ -83,17 +84,17 @@ for iter in range(0, 1) let lines =<< trim END call setline(1, range(1, 100)) - call popup_create('hello border', {'line': 2, 'col': 3, 'border': []}) - call popup_create('hello padding', {'line': 2, 'col': 23, 'padding': []}) - call popup_create('hello both', {'line': 2, 'col': 43, 'border': [], 'padding': []}) - call popup_create('border TL', {'line': 6, 'col': 3, 'border': [1, 0, 0, 4]}) - call popup_create('paddings', {'line': 6, 'col': 23, 'padding': [1, 3, 2, 4]}) - call popup_create('wrapped longer text', {'line': 8, 'col': 55, 'padding': [0, 3, 0, 3], 'border': [0, 1, 0, 1]}) - call popup_create('right aligned text', {'line': 11, 'col': 56, 'wrap': 0, 'padding': [0, 3, 0, 3], 'border': [0, 1, 0, 1]}) + call popup_create('hello border', #{line: 2, col: 3, border: []}) + call popup_create('hello padding', #{line: 2, col: 23, padding: []}) + call popup_create('hello both', #{line: 2, col: 43, border: [], padding: []}) + call popup_create('border TL', #{line: 6, col: 3, border: [1, 0, 0, 4]}) + call popup_create('paddings', #{line: 6, col: 23, padding: [1, 3, 2, 4]}) + call popup_create('wrapped longer text', #{line: 8, col: 55, padding: [0, 3, 0, 3], border: [0, 1, 0, 1]}) + call popup_create('right aligned text', #{line: 11, col: 56, wrap: 0, padding: [0, 3, 0, 3], border: [0, 1, 0, 1]}) END call insert(lines, iter == 1 ? '' : 'set enc=latin1') call writefile(lines, 'XtestPopupBorder') - let buf = RunVimInTerminal('-S XtestPopupBorder', {'rows': 15}) + let buf = RunVimInTerminal('-S XtestPopupBorder', #{rows: 15}) call VerifyScreenDump(buf, 'Test_popupwin_2' .. iter, {}) call StopVimInTerminal(buf) @@ -107,22 +108,22 @@ hi RightColor ctermbg=245 hi BottomColor ctermbg=240 hi LeftColor ctermbg=248 - call popup_create('hello border', {'line': 2, 'col': 3, 'border': [], 'borderhighlight': ['BlueColor']}) - call popup_create(['hello border', 'and more'], {'line': 2, 'col': 23, 'border': [], 'borderhighlight': ['TopColor', 'RightColor', 'BottomColor', 'LeftColor']}) - call popup_create(['hello border', 'lines only'], {'line': 2, 'col': 43, 'border': [], 'borderhighlight': ['BlueColor'], 'borderchars': ['x']}) - call popup_create(['hello border', 'with corners'], {'line': 2, 'col': 60, 'border': [], 'borderhighlight': ['BlueColor'], 'borderchars': ['x', '#']}) - let winid = popup_create(['hello border', 'with numbers'], {'line': 6, 'col': 3, 'border': [], 'borderhighlight': ['BlueColor'], 'borderchars': ['0', '1', '2', '3', '4', '5', '6', '7']}) - call popup_create(['hello border', 'just blanks'], {'line': 7, 'col': 23, 'border': [], 'borderhighlight': ['BlueColor'], 'borderchars': [' ']}) + call popup_create('hello border', #{line: 2, col: 3, border: [], borderhighlight: ['BlueColor']}) + call popup_create(['hello border', 'and more'], #{line: 2, col: 23, border: [], borderhighlight: ['TopColor', 'RightColor', 'BottomColor', 'LeftColor']}) + call popup_create(['hello border', 'lines only'], #{line: 2, col: 43, border: [], borderhighlight: ['BlueColor'], borderchars: ['x']}) + call popup_create(['hello border', 'with corners'], #{line: 2, col: 60, border: [], borderhighlight: ['BlueColor'], borderchars: ['x', '#']}) + let winid = popup_create(['hello border', 'with numbers'], #{line: 6, col: 3, border: [], borderhighlight: ['BlueColor'], borderchars: ['0', '1', '2', '3', '4', '5', '6', '7']}) + call popup_create(['hello border', 'just blanks'], #{line: 7, col: 23, border: [], borderhighlight: ['BlueColor'], borderchars: [' ']}) func MultiByte() - call popup_create(['hello'], {'line': 8, 'col': 43, 'border': [], 'borderchars': ['─', '│', '─', '│', '┌', '┐', '┘', '└']}) + call popup_create(['hello'], #{line: 8, col: 43, border: [], borderchars: ['─', '│', '─', '│', '┌', '┐', '┘', '└']}) endfunc END call writefile(lines, 'XtestPopupBorder') - let buf = RunVimInTerminal('-S XtestPopupBorder', {'rows': 12}) + let buf = RunVimInTerminal('-S XtestPopupBorder', #{rows: 12}) call VerifyScreenDump(buf, 'Test_popupwin_22', {}) " check that changing borderchars triggers a redraw - call term_sendkeys(buf, ":call popup_setoptions(winid, {'borderchars': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']})\") + call term_sendkeys(buf, ":call popup_setoptions(winid, #{borderchars: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']})\") call VerifyScreenDump(buf, 'Test_popupwin_23', {}) " check multi-byte border only with 'ambiwidth' single @@ -134,25 +135,25 @@ call StopVimInTerminal(buf) call delete('XtestPopupBorder') - let with_border_or_padding = { - \ 'line': 2, - \ 'core_line': 3, - \ 'col': 3, - \ 'core_col': 4, - \ 'width': 14, - \ 'core_width': 12, - \ 'height': 3, - \ 'core_height': 1, - \ 'firstline': 1, - \ 'scrollbar': 0, - \ 'visible': 1} - let winid = popup_create('hello border', {'line': 2, 'col': 3, 'border': []})", + let with_border_or_padding = #{ + \ line: 2, + \ core_line: 3, + \ col: 3, + \ core_col: 4, + \ width: 14, + \ core_width: 12, + \ height: 3, + \ core_height: 1, + \ firstline: 1, + \ scrollbar: 0, + \ visible: 1} + let winid = popup_create('hello border', #{line: 2, col: 3, border: []})", call assert_equal(with_border_or_padding, popup_getpos(winid)) let options = popup_getoptions(winid) call assert_equal([], options.border) call assert_false(has_key(options, "padding")) - let winid = popup_create('hello padding', {'line': 2, 'col': 3, 'padding': []}) + let winid = popup_create('hello padding', #{line: 2, col: 3, padding: []}) let with_border_or_padding.width = 15 let with_border_or_padding.core_width = 13 call assert_equal(with_border_or_padding, popup_getpos(winid)) @@ -160,11 +161,11 @@ call assert_false(has_key(options, "border")) call assert_equal([], options.padding) - call popup_setoptions(winid, { - \ 'padding': [1, 2, 3, 4], - \ 'border': [4, 0, 7, 8], - \ 'borderhighlight': ['Top', 'Right', 'Bottom', 'Left'], - \ 'borderchars': ['1', '^', '2', '>', '3', 'v', '4', '<'], + call popup_setoptions(winid, #{ + \ padding: [1, 2, 3, 4], + \ border: [4, 0, 7, 8], + \ borderhighlight: ['Top', 'Right', 'Bottom', 'Left'], + \ borderchars: ['1', '^', '2', '>', '3', 'v', '4', '<'], \ }) let options = popup_getoptions(winid) call assert_equal([1, 0, 1, 1], options.border) @@ -172,19 +173,19 @@ call assert_equal(['Top', 'Right', 'Bottom', 'Left'], options.borderhighlight) call assert_equal(['1', '^', '2', '>', '3', 'v', '4', '<'], options.borderchars) - let winid = popup_create('hello both', {'line': 3, 'col': 8, 'border': [], 'padding': []}) - call assert_equal({ - \ 'line': 3, - \ 'core_line': 5, - \ 'col': 8, - \ 'core_col': 10, - \ 'width': 14, - \ 'core_width': 10, - \ 'height': 5, - \ 'scrollbar': 0, - \ 'core_height': 1, - \ 'firstline': 1, - \ 'visible': 1}, popup_getpos(winid)) + let winid = popup_create('hello both', #{line: 3, col: 8, border: [], padding: []}) + call assert_equal(#{ + \ line: 3, + \ core_line: 5, + \ col: 8, + \ core_col: 10, + \ width: 14, + \ core_width: 10, + \ height: 5, + \ scrollbar: 0, + \ core_height: 1, + \ firstline: 1, + \ visible: 1}, popup_getpos(winid)) call popup_clear() endfunc @@ -202,11 +203,11 @@ \ '{', \ ' printf(123);', \ '}', - \], {'line': 3, 'col': 25, 'highlight': 'PopupColor'}) + \], #{line: 3, col: 25, highlight: 'PopupColor'}) call win_execute(winid, 'set syntax=cpp') END call writefile(lines, 'XtestPopup') - let buf = RunVimInTerminal('-S XtestPopup', {'rows': 10}) + let buf = RunVimInTerminal('-S XtestPopup', #{rows: 10}) call VerifyScreenDump(buf, 'Test_popupwin_10', {}) " clean up @@ -227,11 +228,11 @@ \ '{', \ "\tprintf(567);", \ '}', - \], {'line': 3, 'col': 21, 'highlight': 'PopupColor'}) + \], #{line: 3, col: 21, highlight: 'PopupColor'}) call setbufvar(winbufnr(winid), '&syntax', 'cpp') END call writefile(lines, 'XtestPopup') - let buf = RunVimInTerminal('-S XtestPopup', {'rows': 10}) + let buf = RunVimInTerminal('-S XtestPopup', #{rows: 10}) call VerifyScreenDump(buf, 'Test_popupwin_11', {}) " clean up @@ -248,7 +249,7 @@ let winid = popup_create([ \ '111 222 333', \ '444 555 666', - \], {'line': 3, 'col': 10, 'border': []}) + \], #{line: 3, col: 10, border: []}) set hlsearch /666 call matchadd('ErrorMsg', '111') @@ -257,7 +258,7 @@ call win_execute(winid, "call matchadd('ErrorMsg', '555')") END call writefile(lines, 'XtestPopupMatches') - let buf = RunVimInTerminal('-S XtestPopupMatches', {'rows': 10}) + let buf = RunVimInTerminal('-S XtestPopupMatches', #{rows: 10}) call VerifyScreenDump(buf, 'Test_popupwin_matches', {}) " clean up @@ -273,40 +274,40 @@ call setline(1, repeat([repeat('-', 60)], 15)) set so=0 normal 2G3|r# - let winid1 = popup_create(['first', 'second'], { - \ 'line': 'cursor+1', - \ 'col': 'cursor', - \ 'pos': 'topleft', - \ 'border': [], - \ 'padding': [], + let winid1 = popup_create(['first', 'second'], #{ + \ line: 'cursor+1', + \ col: 'cursor', + \ pos: 'topleft', + \ border: [], + \ padding: [], \ }) normal 25|r@ - let winid1 = popup_create(['First', 'SeconD'], { - \ 'line': 'cursor+1', - \ 'col': 'cursor', - \ 'pos': 'topright', - \ 'border': [], - \ 'padding': [], + let winid1 = popup_create(['First', 'SeconD'], #{ + \ line: 'cursor+1', + \ col: 'cursor', + \ pos: 'topright', + \ border: [], + \ padding: [], \ }) normal 9G29|r% - let winid1 = popup_create(['fiRSt', 'seCOnd'], { - \ 'line': 'cursor-1', - \ 'col': 'cursor', - \ 'pos': 'botleft', - \ 'border': [], - \ 'padding': [], + let winid1 = popup_create(['fiRSt', 'seCOnd'], #{ + \ line: 'cursor-1', + \ col: 'cursor', + \ pos: 'botleft', + \ border: [], + \ padding: [], \ }) normal 51|r& - let winid1 = popup_create(['FIrsT', 'SEcoND'], { - \ 'line': 'cursor-1', - \ 'col': 'cursor', - \ 'pos': 'botright', - \ 'border': [], - \ 'padding': [], + let winid1 = popup_create(['FIrsT', 'SEcoND'], #{ + \ line: 'cursor-1', + \ col: 'cursor', + \ pos: 'botright', + \ border: [], + \ padding: [], \ }) END call writefile(lines, 'XtestPopupCorners') - let buf = RunVimInTerminal('-S XtestPopupCorners', {'rows': 12}) + let buf = RunVimInTerminal('-S XtestPopupCorners', #{rows: 12}) call VerifyScreenDump(buf, 'Test_popupwin_corners', {}) " clean up @@ -320,25 +321,25 @@ endif let lines =<< trim END call setline(1, range(1, 20)) - call popup_create(['1111', '222222', '33333', '44', '5', '666666', '77777', '888', '9999999999999999'], { - \ 'maxheight': 4, - \ 'firstline': 3, + call popup_create(['1111', '222222', '33333', '44', '5', '666666', '77777', '888', '9999999999999999'], #{ + \ maxheight: 4, + \ firstline: 3, \ }) END call writefile(lines, 'XtestPopupFirstline') - let buf = RunVimInTerminal('-S XtestPopupFirstline', {'rows': 10}) + let buf = RunVimInTerminal('-S XtestPopupFirstline', #{rows: 10}) call VerifyScreenDump(buf, 'Test_popupwin_firstline', {}) " clean up call StopVimInTerminal(buf) call delete('XtestPopupFirstline') - let winid = popup_create(['1111', '222222', '33333', '44444'], { - \ 'maxheight': 2, - \ 'firstline': 3, + let winid = popup_create(['1111', '222222', '33333', '44444'], #{ + \ maxheight: 2, + \ firstline: 3, \ }) call assert_equal(3, popup_getoptions(winid).firstline) - call popup_setoptions(winid, {'firstline': 1}) + call popup_setoptions(winid, #{firstline: 1}) call assert_equal(1, popup_getoptions(winid).firstline) call popup_close(winid) @@ -351,10 +352,10 @@ " create a popup that covers the command line let lines =<< trim END call setline(1, range(1, 20)) - let winid = popup_create(['1111', '222222', '33333'], { - \ 'drag': 1, - \ 'border': [], - \ 'line': &lines - 4, + let winid = popup_create(['1111', '222222', '33333'], #{ + \ drag: 1, + \ border: [], + \ line: &lines - 4, \ }) func Dragit() call feedkeys("\\\\\", "xt") @@ -363,7 +364,7 @@ map :call test_setmouse(&lines - 8, &columns / 2) END call writefile(lines, 'XtestPopupDrag') - let buf = RunVimInTerminal('-S XtestPopupDrag', {'rows': 10}) + let buf = RunVimInTerminal('-S XtestPopupDrag', #{rows: 10}) call VerifyScreenDump(buf, 'Test_popupwin_drag_01', {}) call term_sendkeys(buf, ":call Dragit()\") @@ -381,31 +382,31 @@ let lines =<< trim END call setline(1, range(1, 20)) " With border, can click on X - let winid = popup_create('foobar', { - \ 'close': 'button', - \ 'border': [], - \ 'line': 1, - \ 'col': 1, + let winid = popup_create('foobar', #{ + \ close: 'button', + \ border: [], + \ line: 1, + \ col: 1, \ }) func CloseMsg(id, result) echomsg 'Popup closed with ' .. a:result endfunc - let winid = popup_create('notification', { - \ 'close': 'click', - \ 'line': 3, - \ 'col': 15, - \ 'callback': 'CloseMsg', + let winid = popup_create('notification', #{ + \ close: 'click', + \ line: 3, + \ col: 15, + \ callback: 'CloseMsg', \ }) - let winid = popup_create('no border here', { - \ 'close': 'button', - \ 'line': 5, - \ 'col': 3, + let winid = popup_create('no border here', #{ + \ close: 'button', + \ line: 5, + \ col: 3, \ }) - let winid = popup_create('only padding', { - \ 'close': 'button', - \ 'padding': [], - \ 'line': 5, - \ 'col': 23, + let winid = popup_create('only padding', #{ + \ close: 'button', + \ padding: [], + \ line: 5, + \ col: 23, \ }) func CloseWithX() call feedkeys("\\\", "xt") @@ -417,7 +418,7 @@ map :call test_setmouse(3, 17) END call writefile(lines, 'XtestPopupClose') - let buf = RunVimInTerminal('-S XtestPopupClose', {'rows': 10}) + let buf = RunVimInTerminal('-S XtestPopupClose', #{rows: 10}) call VerifyScreenDump(buf, 'Test_popupwin_close_01', {}) call term_sendkeys(buf, ":call CloseWithX()\") @@ -441,53 +442,57 @@ let winid = popup_create([ \ 'some text', \ 'another line', - \], { - \ 'line': 1, - \ 'col': 10, - \ 'wrap': 0, - \ 'fixed': 1, - \ 'zindex': 90, - \ 'padding': [], - \ 'highlight': 'PopupColor', - \ 'mask': [[1,1,1,1], [-5,-1,4,4], [7,9,2,3], [2,4,3,3]]}) + \], #{ + \ line: 1, + \ col: 10, + \ wrap: 0, + \ fixed: 1, + \ zindex: 90, + \ padding: [], + \ highlight: 'PopupColor', + \ mask: [[1,1,1,1], [-5,-1,4,4], [7,9,2,3], [2,4,3,3]]}) call popup_create([ \ 'xxxxxxxxx', \ 'yyyyyyyyy', - \], { - \ 'line': 3, - \ 'col': 18, - \ 'zindex': 20}) + \], #{ + \ line: 3, + \ col: 18, + \ zindex: 20}) let winidb = popup_create([ \ 'just one line', - \], { - \ 'line': 7, - \ 'col': 10, - \ 'wrap': 0, - \ 'fixed': 1, - \ 'close': 'button', - \ 'zindex': 90, - \ 'padding': [], - \ 'border': [], - \ 'mask': [[1,2,1,1], [-5,-1,4,4], [7,9,2,3], [3,5,5,5],[-7,-4,5,5]]}) + \], #{ + \ line: 7, + \ col: 10, + \ wrap: 0, + \ fixed: 1, + \ close: 'button', + \ zindex: 90, + \ padding: [], + \ border: [], + \ mask: [[1,2,1,1], [-5,-1,4,4], [7,9,2,3], [3,5,5,5],[-7,-4,5,5]]}) END call writefile(lines, 'XtestPopupMask') - let buf = RunVimInTerminal('-S XtestPopupMask', {'rows': 13}) + let buf = RunVimInTerminal('-S XtestPopupMask', #{rows: 13}) call VerifyScreenDump(buf, 'Test_popupwin_mask_1', {}) - call term_sendkeys(buf, ":call popup_move(winid, {'col': 11, 'line': 2})\") - call term_sendkeys(buf, ":call popup_move(winidb, {'col': 12})\") + call term_sendkeys(buf, ":call popup_move(winid, #{col: 11, line: 2})\") + call term_sendkeys(buf, ":call popup_move(winidb, #{col: 12})\") + call term_sendkeys(buf, ":\") call VerifyScreenDump(buf, 'Test_popupwin_mask_2', {}) - call term_sendkeys(buf, ":call popup_move(winid, {'col': 65, 'line': 2})\") - call term_sendkeys(buf, ":call popup_move(winidb, {'col': 63})\") + call term_sendkeys(buf, ":call popup_move(winid, #{col: 65, line: 2})\") + call term_sendkeys(buf, ":call popup_move(winidb, #{col: 63})\") + call term_sendkeys(buf, ":\") call VerifyScreenDump(buf, 'Test_popupwin_mask_3', {}) - call term_sendkeys(buf, ":call popup_move(winid, {'pos': 'topright', 'col': 12, 'line': 2})\") - call term_sendkeys(buf, ":call popup_move(winidb, {'pos': 'topright', 'col': 12})\") + call term_sendkeys(buf, ":call popup_move(winid, #{pos: 'topright', col: 12, line: 2})\") + call term_sendkeys(buf, ":call popup_move(winidb, #{pos: 'topright', col: 12})\") + call term_sendkeys(buf, ":\") call VerifyScreenDump(buf, 'Test_popupwin_mask_4', {}) - call term_sendkeys(buf, ":call popup_move(winid, {'pos': 'topright', 'col': 12, 'line': 11})\") - call term_sendkeys(buf, ":call popup_move(winidb, {'pos': 'topleft', 'col': 42, 'line': 11})\") + call term_sendkeys(buf, ":call popup_move(winid, #{pos: 'topright', col: 12, line: 11})\") + call term_sendkeys(buf, ":call popup_move(winidb, #{pos: 'topleft', col: 42, line: 11})\") + call term_sendkeys(buf, ":\") call VerifyScreenDump(buf, 'Test_popupwin_mask_5', {}) " clean up @@ -506,11 +511,11 @@ let lines =<< trim END set clipboard=autoselect call setline(1, range(1, 20)) - let winid = popup_create(['the word', 'some more', 'several words here'], { - \ 'drag': 1, - \ 'border': [], - \ 'line': 3, - \ 'col': 10, + let winid = popup_create(['the word', 'some more', 'several words here'], #{ + \ drag: 1, + \ border: [], + \ line: 3, + \ col: 10, \ }) func Select1() call feedkeys("\\\\\", "xt") @@ -519,7 +524,7 @@ map :call test_setmouse(6, 23) END call writefile(lines, 'XtestPopupSelect') - let buf = RunVimInTerminal('-S XtestPopupSelect', {'rows': 10}) + let buf = RunVimInTerminal('-S XtestPopupSelect', #{rows: 10}) call term_sendkeys(buf, ":call Select1()\") call VerifyScreenDump(buf, 'Test_popupwin_select_01', {}) @@ -553,7 +558,7 @@ call assert_equal(0, bufexists(bufnr)) " global popup is visible in any tab - let winid = popup_create("text", {'tabpage': -1}) + let winid = popup_create("text", #{tabpage: -1}) call assert_equal(1, popup_getpos(winid).visible) call assert_equal(-1, popup_getoptions(winid).tabpage) tabnew @@ -565,7 +570,7 @@ " create popup in other tab tabnew - let winid = popup_create("text", {'tabpage': 1}) + let winid = popup_create("text", #{tabpage: 1}) call assert_equal(0, popup_getpos(winid).visible) call assert_equal(1, popup_getoptions(winid).tabpage) quit @@ -576,19 +581,19 @@ func Test_popup_valid_arguments() " Zero value is like the property wasn't there - let winid = popup_create("text", {"col": 0}) + let winid = popup_create("text", #{col: 0}) let pos = popup_getpos(winid) call assert_inrange(&columns / 2 - 1, &columns / 2 + 1, pos.col) call popup_clear() " using cursor column has minimum value of 1 - let winid = popup_create("text", {"col": 'cursor-100'}) + let winid = popup_create("text", #{col: 'cursor-100'}) let pos = popup_getpos(winid) call assert_equal(1, pos.col) call popup_clear() " center - let winid = popup_create("text", {"pos": 'center'}) + let winid = popup_create("text", #{pos: 'center'}) let pos = popup_getpos(winid) let around = (&columns - pos.width) / 2 call assert_inrange(around - 1, around + 1, pos.col) @@ -603,40 +608,46 @@ call assert_fails('call popup_create("text", "none")', 'E715:') call popup_clear() - call assert_fails('call popup_create("text", {"col": "xxx"})', 'E475:') + call assert_fails('call popup_create("text", #{col: "xxx"})', 'E475:') call popup_clear() - call assert_fails('call popup_create("text", {"col": "cursor8"})', 'E15:') + call assert_fails('call popup_create("text", #{col: "cursor8"})', 'E15:') call popup_clear() - call assert_fails('call popup_create("text", {"col": "cursor+x"})', 'E15:') + call assert_fails('call popup_create("text", #{col: "cursor+x"})', 'E15:') call popup_clear() - call assert_fails('call popup_create("text", {"col": "cursor+8x"})', 'E15:') + call assert_fails('call popup_create("text", #{col: "cursor+8x"})', 'E15:') call popup_clear() - call assert_fails('call popup_create("text", {"line": "xxx"})', 'E475:') + call assert_fails('call popup_create("text", #{line: "xxx"})', 'E475:') call popup_clear() - call assert_fails('call popup_create("text", {"line": "cursor8"})', 'E15:') + call assert_fails('call popup_create("text", #{line: "cursor8"})', 'E15:') call popup_clear() - call assert_fails('call popup_create("text", {"line": "cursor+x"})', 'E15:') + call assert_fails('call popup_create("text", #{line: "cursor+x"})', 'E15:') call popup_clear() - call assert_fails('call popup_create("text", {"line": "cursor+8x"})', 'E15:') + call assert_fails('call popup_create("text", #{line: "cursor+8x"})', 'E15:') call popup_clear() - call assert_fails('call popup_create("text", {"pos": "there"})', 'E475:') + call assert_fails('call popup_create("text", #{pos: "there"})', 'E475:') call popup_clear() - call assert_fails('call popup_create("text", {"padding": "none"})', 'E714:') + call assert_fails('call popup_create("text", #{padding: "none"})', 'E714:') call popup_clear() - call assert_fails('call popup_create("text", {"border": "none"})', 'E714:') + call assert_fails('call popup_create("text", #{border: "none"})', 'E714:') call popup_clear() - call assert_fails('call popup_create("text", {"borderhighlight": "none"})', 'E714:') + call assert_fails('call popup_create("text", #{borderhighlight: "none"})', 'E714:') call popup_clear() - call assert_fails('call popup_create("text", {"borderchars": "none"})', 'E714:') + call assert_fails('call popup_create("text", #{borderhighlight: test_null_list()})', 'E714:') + call popup_clear() + call assert_fails('call popup_create("text", #{borderchars: "none"})', 'E714:') call popup_clear() - call assert_fails('call popup_create([{"text": "text"}, 666], {})', 'E715:') + call assert_fails('call popup_create([#{text: "text"}, 666], {})', 'E715:') + call popup_clear() + call assert_fails('call popup_create([#{text: "text", props: "none"}], {})', 'E714:') + call popup_clear() + call assert_fails('call popup_create([#{text: "text", props: ["none"]}], {})', 'E715:') call popup_clear() - call assert_fails('call popup_create([{"text": "text", "props": "none"}], {})', 'E714:') + call assert_fails('call popup_create("text", #{mask: ["asdf"]})', 'E475:') call popup_clear() - call assert_fails('call popup_create([{"text": "text", "props": ["none"]}], {})', 'E715:') + call assert_fails('call popup_create("text", #{mask: test_null_list()})', 'E475:') call popup_clear() endfunc @@ -676,10 +687,10 @@ call setline(1, range(1, 100)) let winid = popup_create( \ 'a long line that wont fit', - \ {'line': 3, 'col': 20, 'maxwidth': 10, 'wrap': 1}) + \ #{line: 3, col: 20, maxwidth: 10, wrap: 1}) END call writefile(lines, 'XtestPopup') - let buf = RunVimInTerminal('-S XtestPopup', {'rows': 10}) + let buf = RunVimInTerminal('-S XtestPopup', #{rows: 10}) call VerifyScreenDump(buf, 'Test_popupwin_wrap', {}) " clean up @@ -695,10 +706,10 @@ call setline(1, range(1, 100)) let winid = popup_create( \ 'a long line that wont fit', - \ {'line': 3, 'col': 20, 'maxwidth': 10, 'wrap': 0}) + \ #{line: 3, col: 20, maxwidth: 10, wrap: 0}) END call writefile(lines, 'XtestPopup') - let buf = RunVimInTerminal('-S XtestPopup', {'rows': 10}) + let buf = RunVimInTerminal('-S XtestPopup', #{rows: 10}) call VerifyScreenDump(buf, 'Test_popupwin_nowrap', {}) " clean up @@ -706,6 +717,27 @@ call delete('XtestPopup') endfunc +func Test_popup_with_showbreak() + if !CanRunVimInTerminal() + throw 'Skipped: cannot make screendumps' + endif + let lines =<< trim END + set showbreak=>>\ + call setline(1, range(1, 20)) + let winid = popup_dialog( + \ 'a long line here', + \ #{filter: 'popup_filter_yesno'}) + END + call writefile(lines, 'XtestPopupShowbreak') + let buf = RunVimInTerminal('-S XtestPopupShowbreak', #{rows: 10}) + call VerifyScreenDump(buf, 'Test_popupwin_showbreak', {}) + + " clean up + call term_sendkeys(buf, "y") + call StopVimInTerminal(buf) + call delete('XtestPopupShowbreak') +endfunc + func Test_popup_time() if !has('timers') throw 'Skipped: timer feature not supported' @@ -713,11 +745,11 @@ topleft vnew call setline(1, 'hello') - let winid = popup_create('world', { - \ 'line': 1, - \ 'col': 1, - \ 'minwidth': 20, - \ 'time': 500, + let winid = popup_create('world', #{ + \ line: 1, + \ col: 1, + \ minwidth: 20, + \ time: 500, \}) redraw let line = join(map(range(1, 5), 'screenstring(1, v:val)'), '') @@ -733,11 +765,11 @@ let line = join(map(range(1, 5), 'screenstring(1, v:val)'), '') call assert_equal('hello', line) - call popup_create('on the command line', { - \ 'line': &lines, - \ 'col': 10, - \ 'minwidth': 20, - \ 'time': 500, + call popup_create('on the command line', #{ + \ line: &lines, + \ col: 10, + \ minwidth: 20, + \ time: 500, \}) redraw let line = join(map(range(1, 30), 'screenstring(&lines, v:val)'), '') @@ -755,10 +787,10 @@ topleft vnew call setline(1, 'hello') - let winid = popup_create('world', { - \ 'line': 1, - \ 'col': 1, - \ 'minwidth': 20, + let winid = popup_create('world', #{ + \ line: 1, + \ col: 1, + \ minwidth: 20, \}) redraw let line = join(map(range(1, 5), 'screenstring(1, v:val)'), '') @@ -801,23 +833,23 @@ topleft vnew call setline(1, 'hello') - let winid = popup_create('world', { - \ 'line': 1, - \ 'col': 1, - \ 'minwidth': 20, + let winid = popup_create('world', #{ + \ line: 1, + \ col: 1, + \ minwidth: 20, \}) redraw let line = join(map(range(1, 6), 'screenstring(1, v:val)'), '') call assert_equal('world ', line) - call popup_move(winid, {'line': 2, 'col': 2}) + call popup_move(winid, #{line: 2, col: 2}) redraw let line = join(map(range(1, 6), 'screenstring(1, v:val)'), '') call assert_equal('hello ', line) let line = join(map(range(1, 6), 'screenstring(2, v:val)'), '') call assert_equal('~world', line) - call popup_move(winid, {'line': 1}) + call popup_move(winid, #{line: 1}) redraw let line = join(map(range(1, 6), 'screenstring(1, v:val)'), '') call assert_equal('hworld', line) @@ -828,11 +860,11 @@ endfunc func Test_popup_getpos() - let winid = popup_create('hello', { - \ 'line': 2, - \ 'col': 3, - \ 'minwidth': 10, - \ 'minheight': 11, + let winid = popup_create('hello', #{ + \ line: 2, + \ col: 3, + \ minwidth: 10, + \ minheight: 11, \}) redraw let res = popup_getpos(winid) @@ -855,7 +887,7 @@ \ ] for test in tests - let winid = popup_create(test[0], {'line': 2, 'col': 3}) + let winid = popup_create(test[0], #{line: 2, col: 3}) redraw let position = popup_getpos(winid) call assert_equal(test[1], position.width) @@ -871,7 +903,7 @@ \ ] for test in tests let winid = popup_create(test[0], - \ {'line': 2, 'col': 3, 'maxwidth': 12}) + \ #{line: 2, col: 3, maxwidth: 12}) redraw let position = popup_getpos(winid) call assert_equal(test[1], position.width) @@ -883,16 +915,16 @@ endfunc func Test_popup_getoptions() - let winid = popup_create('hello', { - \ 'line': 2, - \ 'col': 3, - \ 'minwidth': 10, - \ 'minheight': 11, - \ 'maxwidth': 20, - \ 'maxheight': 21, - \ 'zindex': 100, - \ 'time': 5000, - \ 'fixed': 1 + let winid = popup_create('hello', #{ + \ line: 2, + \ col: 3, + \ minwidth: 10, + \ minheight: 11, + \ maxwidth: 20, + \ maxheight: 21, + \ zindex: 100, + \ time: 5000, + \ fixed: 1 \}) redraw let res = popup_getoptions(winid) @@ -976,10 +1008,10 @@ call cursor(1, 1) redraw - let winid = popup_create('vim', { - \ 'line': 'cursor+2', - \ 'col': 'cursor+1', - \}) + let winid = popup_create('vim', #{ + \ line: 'cursor+2', + \ col: 'cursor+1', + \}) redraw let line = join(map(range(1, 17), 'screenstring(3, v:val)'), '') call assert_equal('xvimxxxxxxxxxxxxx', line) @@ -987,10 +1019,10 @@ call cursor(3, 3) redraw - let winid = popup_create('vim', { - \ 'line': 'cursor-2', - \ 'col': 'cursor-1', - \}) + let winid = popup_create('vim', #{ + \ line: 'cursor-2', + \ col: 'cursor-1', + \}) redraw let line = join(map(range(1, 17), 'screenstring(1, v:val)'), '') call assert_equal('xvimxxxxxxxxxxxxx', line) @@ -1056,7 +1088,7 @@ endfunc END call writefile(lines, 'XtestPopupBeval') - let buf = RunVimInTerminal('-S XtestPopupBeval', {'rows': 10}) + let buf = RunVimInTerminal('-S XtestPopupBeval', #{rows: 10}) call term_wait(buf, 100) call term_sendkeys(buf, 'j') call term_sendkeys(buf, ":call Hover()\") @@ -1093,7 +1125,7 @@ return 0 endfunc - let winid = popup_create('something', {'filter': 'MyPopupFilter'}) + let winid = popup_create('something', #{filter: 'MyPopupFilter'}) redraw " e is consumed by the filter @@ -1118,9 +1150,9 @@ func ShowDialog(key, result) let s:cb_res = 999 - let winid = popup_dialog('do you want to quit (Yes/no)?', { - \ 'filter': 'popup_filter_yesno', - \ 'callback': 'QuitCallback', + let winid = popup_dialog('do you want to quit (Yes/no)?', #{ + \ filter: 'popup_filter_yesno', + \ callback: 'QuitCallback', \ }) redraw call feedkeys(a:key, "xt") @@ -1148,8 +1180,8 @@ func ShowMenu(key, result) let s:cb_res = 999 - let winid = popup_menu(['one', 'two', 'something else'], { - \ 'callback': 'QuitCallback', + let winid = popup_menu(['one', 'two', 'something else'], #{ + \ callback: 'QuitCallback', \ }) redraw call feedkeys(a:key, "xt") @@ -1184,13 +1216,13 @@ let lines =<< trim END call setline(1, range(1, 20)) hi PopupSelected ctermbg=lightblue - call popup_menu(['one', 'two', 'another'], {'callback': 'MenuDone', 'title': ' make a choice from the list '}) + call popup_menu(['one', 'two', 'another'], #{callback: 'MenuDone', title: ' make a choice from the list '}) func MenuDone(id, res) echomsg "selected " .. a:res endfunc END call writefile(lines, 'XtestPopupMenu') - let buf = RunVimInTerminal('-S XtestPopupMenu', {'rows': 10}) + let buf = RunVimInTerminal('-S XtestPopupMenu', #{rows: 10}) call VerifyScreenDump(buf, 'Test_popupwin_menu_01', {}) call term_sendkeys(buf, "jj") @@ -1204,6 +1236,29 @@ call delete('XtestPopupMenu') endfunc +func Test_popup_menu_narrow() + if !CanRunVimInTerminal() + throw 'Skipped: cannot make screendumps' + endif + + let lines =<< trim END + call setline(1, range(1, 20)) + hi PopupSelected ctermbg=green + call popup_menu(['one', 'two', 'three'], #{callback: 'MenuDone'}) + func MenuDone(id, res) + echomsg "selected " .. a:res + endfunc + END + call writefile(lines, 'XtestPopupNarrowMenu') + let buf = RunVimInTerminal('-S XtestPopupNarrowMenu', #{rows: 10}) + call VerifyScreenDump(buf, 'Test_popupwin_menu_04', {}) + + " clean up + call term_sendkeys(buf, "x") + call StopVimInTerminal(buf) + call delete('XtestPopupNarrowMenu') +endfunc + func Test_popup_title() if !CanRunVimInTerminal() throw 'Skipped: cannot make screendumps' @@ -1213,19 +1268,19 @@ " put the title on. let lines =<< trim END call setline(1, range(1, 20)) - call popup_create(['one', 'two', 'another'], {'title': 'Title String'}) + call popup_create(['one', 'two', 'another'], #{title: 'Title String'}) END call writefile(lines, 'XtestPopupTitle') - let buf = RunVimInTerminal('-S XtestPopupTitle', {'rows': 10}) + let buf = RunVimInTerminal('-S XtestPopupTitle', #{rows: 10}) call VerifyScreenDump(buf, 'Test_popupwin_title', {}) " clean up call StopVimInTerminal(buf) call delete('XtestPopupTitle') - let winid = popup_create('something', {'title': 'Some Title'}) + let winid = popup_create('something', #{title: 'Some Title'}) call assert_equal('Some Title', popup_getoptions(winid).title) - call popup_setoptions(winid, {'title': 'Another Title'}) + call popup_setoptions(winid, #{title: 'Another Title'}) call assert_equal('Another Title', popup_getoptions(winid).title) call popup_clear() @@ -1235,20 +1290,20 @@ func PopupDone(id, result) let g:result = a:result endfunc - let winid = popup_create('something', {'callback': 'PopupDone'}) + let winid = popup_create('something', #{callback: 'PopupDone'}) redraw call popup_close(winid, 'done') call assert_equal('done', g:result) endfunc func Test_popup_empty() - let winid = popup_create('', {'padding': [2,2,2,2]}) + let winid = popup_create('', #{padding: [2,2,2,2]}) redraw let pos = popup_getpos(winid) call assert_equal(5, pos.width) call assert_equal(5, pos.height) - let winid = popup_create([], {'border': []}) + let winid = popup_create([], #{border: []}) redraw let pos = popup_getpos(winid) call assert_equal(3, pos.width) @@ -1277,13 +1332,13 @@ let info_window1 = getwininfo()[0] let line = info_window1['height'] let col = info_window1['width'] - call popup_create(['line1', 'line2', 'line3', 'line4'], { - \ 'line' : line, - \ 'col' : col, + call popup_create(['line1', 'line2', 'line3', 'line4'], #{ + \ line : line, + \ col : col, \ }) END call writefile(lines, 'XtestPopupBehind') - let buf = RunVimInTerminal('-S XtestPopupBehind', {'rows': 10}) + let buf = RunVimInTerminal('-S XtestPopupBehind', #{rows: 10}) call term_sendkeys(buf, "\w") call VerifyScreenDump(buf, 'Test_popupwin_behind', {}) @@ -1340,13 +1395,13 @@ " - expected width " - expected height let tests = [ - \ { - \ 'comment': 'left-aligned with wrapping', - \ 'options': { - \ 'wrap': 1, - \ 'pos': 'botleft', + \ #{ + \ comment: 'left-aligned with wrapping', + \ options: #{ + \ wrap: 1, + \ pos: 'botleft', \ }, - \ 'tests': both_wrap_tests + [ + \ tests: both_wrap_tests + [ \ [ 'aaaa', 5, &columns, 4, &columns - 2, 3, 2 ], \ [ 'bbbb', 5, &columns + 1, 4, &columns - 2, 3, 2 ], \ [ 'cccc', 5, &columns - 1, 4, &columns - 2, 3, 2 ], @@ -1354,13 +1409,13 @@ \ [ 'eeee', 5, &columns - 3, 5, &columns - 3, 4, 1 ], \ ], \ }, - \ { - \ 'comment': 'left aligned without wrapping', - \ 'options': { - \ 'wrap': 0, - \ 'pos': 'botleft', + \ #{ + \ comment: 'left aligned without wrapping', + \ options: #{ + \ wrap: 0, + \ pos: 'botleft', \ }, - \ 'tests': both_wrap_tests + [ + \ tests: both_wrap_tests + [ \ [ 'aaaa', 5, &columns, 5, &columns - 3, 4, 1 ], \ [ 'bbbb', 5, &columns + 1, 5, &columns - 3, 4, 1 ], \ [ 'cccc', 5, &columns - 1, 5, &columns - 3, 4, 1 ], @@ -1368,14 +1423,14 @@ \ [ 'eeee', 5, &columns - 3, 5, &columns - 3, 4, 1 ], \ ], \ }, - \ { - \ 'comment': 'left aligned with fixed position', - \ 'options': { - \ 'wrap': 0, - \ 'fixed': 1, - \ 'pos': 'botleft', + \ #{ + \ comment: 'left aligned with fixed position', + \ options: #{ + \ wrap: 0, + \ fixed: 1, + \ pos: 'botleft', \ }, - \ 'tests': both_wrap_tests + [ + \ tests: both_wrap_tests + [ \ [ 'aaaa', 5, &columns, 5, &columns - 2, 3, 1 ], \ [ 'bbbb', 5, &columns + 1, 5, &columns - 2, 3, 1 ], \ [ 'cccc', 5, &columns - 1, 5, &columns - 2, 3, 1 ], @@ -1388,17 +1443,17 @@ for test_group in tests for test in test_group.tests let [ text, line, col, e_line, e_col, e_width, e_height ] = test - let options = { - \ 'line': line, - \ 'col': col, + let options = #{ + \ line: line, + \ col: col, \ } call extend( options, test_group.options ) let p = popup_create( text, options ) - let msg = string( extend( options, { 'text': text } ) ) - call s:VerifyPosition( p, msg, e_line, e_col, e_width, e_height ) - call popup_close( p ) + let msg = string(extend(options, #{text: text})) + call s:VerifyPosition(p, msg, e_line, e_col, e_width, e_height) + call popup_close(p) endfor endfor @@ -1410,7 +1465,7 @@ " width of screen let X = join(map(range(&columns), {->'X'}), '') - let p = popup_create( X, { 'line': 1, 'col': 1, 'wrap': 0 } ) + let p = popup_create( X, #{line: 1, col: 1, wrap: 0}) call s:VerifyPosition( p, 'full width topleft', 1, 1, &columns, 1 ) redraw @@ -1421,7 +1476,7 @@ redraw " Same if placed on the right hand side - let p = popup_create( X, { 'line': 1, 'col': &columns, 'wrap': 0 } ) + let p = popup_create( X, #{line: 1, col: &columns, wrap: 0}) call s:VerifyPosition( p, 'full width topright', 1, 1, &columns, 1 ) redraw @@ -1434,7 +1489,7 @@ " Extend so > window width let X .= 'x' - let p = popup_create( X, { 'line': 1, 'col': 1, 'wrap': 0 } ) + let p = popup_create( X, #{line: 1, col: 1, wrap: 0}) call s:VerifyPosition( p, 'full width + 1 topleft', 1, 1, &columns, 1 ) redraw @@ -1445,7 +1500,7 @@ redraw " Shifted then truncated (the x is not visible) - let p = popup_create( X, { 'line': 1, 'col': &columns - 3, 'wrap': 0 } ) + let p = popup_create( X, #{line: 1, col: &columns - 3, wrap: 0}) call s:VerifyPosition( p, 'full width + 1 topright', 1, 1, &columns, 1 ) redraw @@ -1457,7 +1512,7 @@ " Not shifted, just truncated let p = popup_create( X, - \ { 'line': 1, 'col': 2, 'wrap': 0, 'fixed': 1 } ) + \ #{line: 1, col: 2, wrap: 0, fixed: 1}) call s:VerifyPosition( p, 'full width + 1 fixed', 1, 2, &columns - 1, 1) redraw @@ -1478,7 +1533,7 @@ call setline(1, ['one word to move around', 'a WORD.and->some thing']) exe "normal gg0/word\" - let winid = popup_atcursor('text', {'moved': 'any'}) + let winid = popup_atcursor('text', #{moved: 'any'}) redraw call assert_equal(1, popup_getpos(winid).visible) call assert_equal([1, 4, 4], popup_getoptions(winid).moved) @@ -1488,7 +1543,7 @@ call popup_clear() exe "normal gg0/word\" - let winid = popup_atcursor('text', {'moved': 'word'}) + let winid = popup_atcursor('text', #{moved: 'word'}) redraw call assert_equal(1, popup_getpos(winid).visible) call assert_equal([1, 4, 7], popup_getoptions(winid).moved) @@ -1497,7 +1552,7 @@ call popup_clear() exe "normal gg0/word\" - let winid = popup_atcursor('text', {'moved': 'word'}) + let winid = popup_atcursor('text', #{moved: 'word'}) redraw call assert_equal(1, popup_getpos(winid).visible) call assert_equal([1, 4, 7], popup_getoptions(winid).moved) @@ -1524,7 +1579,7 @@ call popup_clear() exe "normal gg0/word\" - let winid = popup_atcursor('text', {'moved': [5, 10]}) + let winid = popup_atcursor('text', #{moved: [5, 10]}) redraw call assert_equal(1, popup_getpos(winid).visible) call feedkeys("eli\", 'xt') @@ -1551,7 +1606,7 @@ \ "hi Notification ctermbg=lightblue", \ "call popup_notification('first notification', {})", \], 'XtestNotifications') - let buf = RunVimInTerminal('-S XtestNotifications', {'rows': 10}) + let buf = RunVimInTerminal('-S XtestNotifications', #{rows: 10}) call VerifyScreenDump(buf, 'Test_popupwin_notify_01', {}) " second one goes below the first one @@ -1574,9 +1629,9 @@ hi ScrollThumb ctermbg=blue hi ScrollBar ctermbg=red let winid = popup_create(['one', 'two', 'three', 'four', 'five', - \ 'six', 'seven', 'eight', 'nine'], { - \ 'minwidth': 8, - \ 'maxheight': 4, + \ 'six', 'seven', 'eight', 'nine'], #{ + \ minwidth: 8, + \ maxheight: 4, \ }) func ScrollUp() call feedkeys("\\", "xt") @@ -1588,7 +1643,7 @@ call feedkeys("\\", "xt") endfunc func ClickBot() - call popup_setoptions(g:winid, {'border': [], 'close': 'button'}) + call popup_setoptions(g:winid, #{border: [], close: 'button'}) call feedkeys("\\", "xt") endfunc map :call test_setmouse(5, 36) @@ -1596,19 +1651,22 @@ map :call test_setmouse(7, 42) END call writefile(lines, 'XtestPopupScroll') - let buf = RunVimInTerminal('-S XtestPopupScroll', {'rows': 10}) + let buf = RunVimInTerminal('-S XtestPopupScroll', #{rows: 10}) call VerifyScreenDump(buf, 'Test_popupwin_scroll_1', {}) - call term_sendkeys(buf, ":call popup_setoptions(winid, {'firstline': 2})\") + call term_sendkeys(buf, ":call popup_setoptions(winid, #{firstline: 2})\") + call term_sendkeys(buf, ":\") call VerifyScreenDump(buf, 'Test_popupwin_scroll_2', {}) - call term_sendkeys(buf, ":call popup_setoptions(winid, {'firstline': 6})\") + call term_sendkeys(buf, ":call popup_setoptions(winid, #{firstline: 6})\") + call term_sendkeys(buf, ":\") call VerifyScreenDump(buf, 'Test_popupwin_scroll_3', {}) - call term_sendkeys(buf, ":call popup_setoptions(winid, {'firstline': 9})\") + call term_sendkeys(buf, ":call popup_setoptions(winid, #{firstline: 9})\") + call term_sendkeys(buf, ":\") call VerifyScreenDump(buf, 'Test_popupwin_scroll_4', {}) - call term_sendkeys(buf, ":call popup_setoptions(winid, {'scrollbarhighlight': 'ScrollBar', 'thumbhighlight': 'ScrollThumb'})\") + call term_sendkeys(buf, ":call popup_setoptions(winid, #{scrollbarhighlight: 'ScrollBar', thumbhighlight: 'ScrollThumb'})\") call term_sendkeys(buf, ":call ScrollUp()\") call VerifyScreenDump(buf, 'Test_popupwin_scroll_5', {}) @@ -1637,11 +1695,11 @@ func Test_popup_fitting_scrollbar() " this was causing a crash, divide by zero let winid = popup_create([ - \ 'one', 'two', 'longer line that wraps', 'four', 'five'], { - \ 'scrollbar': 1, - \ 'maxwidth': 10, - \ 'maxheight': 5, - \ 'firstline': 2}) + \ 'one', 'two', 'longer line that wraps', 'four', 'five'], #{ + \ scrollbar: 1, + \ maxwidth: 10, + \ maxheight: 5, + \ firstline: 2}) redraw call popup_clear() endfunc @@ -1652,13 +1710,13 @@ endif let lines =<< trim END - let opts = {'wrap': 0} + let opts = #{wrap: 0} let p = popup_create('test', opts) call popup_settext(p, 'this is a text') END call writefile( lines, 'XtestPopupSetText' ) - let buf = RunVimInTerminal('-S XtestPopupSetText', {'rows': 10}) + let buf = RunVimInTerminal('-S XtestPopupSetText', #{rows: 10}) call VerifyScreenDump(buf, 'Test_popup_settext_01', {}) " Setting to empty string clears it @@ -1682,7 +1740,7 @@ call VerifyScreenDump(buf, 'Test_popup_settext_05', {}) " Dicts - call term_sendkeys(buf, ":call popup_settext(p, [{'text': 'aaaa'}, {'text': 'bbbb'}, {'text': 'cccc'}])\") + call term_sendkeys(buf, ":call popup_settext(p, [#{text: 'aaaa'}, #{text: 'bbbb'}, #{text: 'cccc'}])\") call VerifyScreenDump(buf, 'Test_popup_settext_06', {}) " clean up @@ -1693,12 +1751,12 @@ func Test_popup_hidden() new - let winid = popup_atcursor('text', {'hidden': 1}) + let winid = popup_atcursor('text', #{hidden: 1}) redraw call assert_equal(0, popup_getpos(winid).visible) call popup_close(winid) - let winid = popup_create('text', {'hidden': 1}) + let winid = popup_create('text', #{hidden: 1}) redraw call assert_equal(0, popup_getpos(winid).visible) call popup_close(winid) @@ -1707,9 +1765,9 @@ let s:cb_winid = a:id let s:cb_res = a:res endfunc - let winid = popup_dialog('make a choice', {'hidden': 1, - \ 'filter': 'popup_filter_yesno', - \ 'callback': 'QuitCallback', + let winid = popup_dialog('make a choice', #{hidden: 1, + \ filter: 'popup_filter_yesno', + \ callback: 'QuitCallback', \ }) redraw call assert_equal(0, popup_getpos(winid).visible) @@ -1728,13 +1786,13 @@ " Test options not checked elsewhere func Test_set_get_options() - let winid = popup_create('some text', {'highlight': 'Beautiful'}) + let winid = popup_create('some text', #{highlight: 'Beautiful'}) let options = popup_getoptions(winid) call assert_equal(1, options.wrap) call assert_equal(0, options.drag) call assert_equal('Beautiful', options.highlight) - call popup_setoptions(winid, {'wrap': 0, 'drag': 1, 'highlight': 'Another'}) + call popup_setoptions(winid, #{wrap: 0, drag: 1, highlight: 'Another'}) let options = popup_getoptions(winid) call assert_equal(0, options.wrap) call assert_equal(1, options.drag) @@ -1748,7 +1806,7 @@ " NOP endfunc - let winid = popup_create('something', {'filter': function('MyPopupFilter', [{}])}) + let winid = popup_create('something', #{filter: function('MyPopupFilter', [{}])}) call test_garbagecollect_now() redraw " Must not crach caused by invalid memory access @@ -1781,12 +1839,12 @@ endfunc func Test_popupwin_width() - let winid = popup_create(repeat(['short', 'long long long line', 'medium width'], 50), { - \ 'maxwidth': 40, - \ 'maxheight': 10, + let winid = popup_create(repeat(['short', 'long long long line', 'medium width'], 50), #{ + \ maxwidth: 40, + \ maxheight: 10, \ }) for top in range(1, 20) - call popup_setoptions(winid, {'firstline': top}) + call popup_setoptions(winid, #{firstline: top}) redraw call assert_equal(19, popup_getpos(winid).width) endfor @@ -1830,13 +1888,13 @@ hi ScrollThumb ctermbg=blue hi ScrollBar ctermbg=red func PopupMenu(lines, line, col, scrollbar = 0) - return popup_menu(a:lines, { - \ 'maxwidth': 10, - \ 'maxheight': 3, - \ 'pos' : 'topleft', - \ 'col' : a:col, - \ 'line' : a:line, - \ 'scrollbar' : a:scrollbar, + return popup_menu(a:lines, #{ + \ maxwidth: 10, + \ maxheight: 3, + \ pos : 'topleft', + \ col : a:col, + \ line : a:line, + \ scrollbar : a:scrollbar, \ }) endfunc call PopupMenu(['x'], 1, 1) @@ -1846,7 +1904,7 @@ call PopupMenu(repeat(['123456789|' .. ' '], 5), 1, 33, 1) END call writefile(lines, 'XtestPopupMenuMaxWidth') - let buf = RunVimInTerminal('-S XtestPopupMenuMaxWidth', {'rows': 13}) + let buf = RunVimInTerminal('-S XtestPopupMenuMaxWidth', #{rows: 13}) call VerifyScreenDump(buf, 'Test_popupwin_menu_maxwidth_1', {}) " close the menu popupwin. @@ -1871,13 +1929,13 @@ hi ScrollThumb ctermbg=blue hi ScrollBar ctermbg=red call popup_menu(['one', 'two', 'three', 'four', 'five', - \ 'six', 'seven', 'eight', 'nine'], { - \ 'minwidth': 8, - \ 'maxheight': 3, + \ 'six', 'seven', 'eight', 'nine'], #{ + \ minwidth: 8, + \ maxheight: 3, \ }) END call writefile(lines, 'XtestPopupMenuScroll') - let buf = RunVimInTerminal('-S XtestPopupMenuScroll', {'rows': 10}) + let buf = RunVimInTerminal('-S XtestPopupMenuScroll', #{rows: 10}) call term_sendkeys(buf, "j") call VerifyScreenDump(buf, 'Test_popupwin_menu_scroll_1', {}) @@ -1907,4 +1965,222 @@ call delete('XtestPopupMenuScroll') endfunc -" vim: shiftwidth=2 sts=2 expandtab +func Test_popup_menu_filter() + if !CanRunVimInTerminal() + throw 'Skipped: cannot make screendumps' + endif + + let lines =<< trim END + function! MyFilter(winid, key) abort + if a:key == "0" + call win_execute(a:winid, "call setpos('.', [0, 1, 1, 0])") + return 1 + endif + if a:key == "G" + call win_execute(a:winid, "call setpos('.', [0, line('$'), 1, 0])") + return 1 + endif + if a:key == "j" + call win_execute(a:winid, "call setpos('.', [0, line('.') + 1, 1, 0])") + return 1 + endif + if a:key == "k" + call win_execute(a:winid, "call setpos('.', [0, line('.') - 1, 1, 0])") + return 1 + endif + if a:key == 'x' + call popup_close(a:winid) + return 1 + endif + return 0 + endfunction + call popup_menu(['111', '222', '333', '444', '555', '666', '777', '888', '999'], #{ + \ maxheight : 3, + \ filter : 'MyFilter' + \ }) + END + call writefile(lines, 'XtestPopupMenuFilter') + let buf = RunVimInTerminal('-S XtestPopupMenuFilter', #{rows: 10}) + + call term_sendkeys(buf, "j") + call VerifyScreenDump(buf, 'Test_popupwin_menu_filter_1', {}) + + call term_sendkeys(buf, "k") + call VerifyScreenDump(buf, 'Test_popupwin_menu_filter_2', {}) + + call term_sendkeys(buf, "G") + call VerifyScreenDump(buf, 'Test_popupwin_menu_filter_3', {}) + + call term_sendkeys(buf, "0") + call VerifyScreenDump(buf, 'Test_popupwin_menu_filter_4', {}) + + call term_sendkeys(buf, "x") + + " clean up + call StopVimInTerminal(buf) + call delete('XtestPopupMenuFilter') +endfunc + +func Test_popup_cursorline() + if !CanRunVimInTerminal() + throw 'Skipped: cannot make screendumps' + endif + + let winid = popup_create('some text', {}) + call assert_equal(0, popup_getoptions(winid).cursorline) + call popup_close(winid) + + let winid = popup_create('some text', #{ cursorline: 1, }) + call assert_equal(1, popup_getoptions(winid).cursorline) + call popup_close(winid) + + let winid = popup_create('some text', #{ cursorline: 0, }) + call assert_equal(0, popup_getoptions(winid).cursorline) + call popup_close(winid) + + let winid = popup_menu('some text', {}) + call assert_equal(1, popup_getoptions(winid).cursorline) + call popup_close(winid) + + let winid = popup_menu('some text', #{ cursorline: 1, }) + call assert_equal(1, popup_getoptions(winid).cursorline) + call popup_close(winid) + + let winid = popup_menu('some text', #{ cursorline: 0, }) + call assert_equal(0, popup_getoptions(winid).cursorline) + call popup_close(winid) + + " --------- + " Pattern 1 + " --------- + let lines =<< trim END + call popup_create(['111', '222', '333'], #{ cursorline : 0 }) + END + call writefile(lines, 'XtestPopupCursorLine') + let buf = RunVimInTerminal('-S XtestPopupCursorLine', #{rows: 10}) + call VerifyScreenDump(buf, 'Test_popupwin_cursorline_1', {}) + call term_sendkeys(buf, ":call popup_clear()\") + call StopVimInTerminal(buf) + + " --------- + " Pattern 2 + " --------- + let lines =<< trim END + call popup_create(['111', '222', '333'], #{ cursorline : 1 }) + END + call writefile(lines, 'XtestPopupCursorLine') + let buf = RunVimInTerminal('-S XtestPopupCursorLine', #{rows: 10}) + call VerifyScreenDump(buf, 'Test_popupwin_cursorline_2', {}) + call term_sendkeys(buf, ":call popup_clear()\") + call StopVimInTerminal(buf) + + " --------- + " Pattern 3 + " --------- + let lines =<< trim END + function! MyFilter(winid, key) abort + if a:key == "j" + call win_execute(a:winid, "call setpos('.', [0, line('.') + 1, 1, 0]) | redraw") + return 1 + endif + if a:key == 'x' + call popup_close(a:winid) + return 1 + endif + return 0 + endfunction + call popup_menu(['111', '222', '333'], #{ + \ cursorline : 0, + \ maxheight : 2, + \ filter : 'MyFilter', + \ }) + END + call writefile(lines, 'XtestPopupCursorLine') + let buf = RunVimInTerminal('-S XtestPopupCursorLine', #{rows: 10}) + call VerifyScreenDump(buf, 'Test_popupwin_cursorline_3', {}) + call term_sendkeys(buf, "j") + call term_sendkeys(buf, "j") + call VerifyScreenDump(buf, 'Test_popupwin_cursorline_4', {}) + call term_sendkeys(buf, "x") + call StopVimInTerminal(buf) + + " --------- + " Pattern 4 + " --------- + let lines =<< trim END + function! MyFilter(winid, key) abort + if a:key == "j" + call win_execute(a:winid, "call setpos('.', [0, line('.') + 1, 1, 0]) | redraw") + return 1 + endif + if a:key == 'x' + call popup_close(a:winid) + return 1 + endif + return 0 + endfunction + call popup_menu(['111', '222', '333'], #{ + \ cursorline : 1, + \ maxheight : 2, + \ filter : 'MyFilter', + \ }) + END + call writefile(lines, 'XtestPopupCursorLine') + let buf = RunVimInTerminal('-S XtestPopupCursorLine', #{rows: 10}) + call VerifyScreenDump(buf, 'Test_popupwin_cursorline_5', {}) + call term_sendkeys(buf, "j") + call term_sendkeys(buf, "j") + call VerifyScreenDump(buf, 'Test_popupwin_cursorline_6', {}) + call term_sendkeys(buf, "x") + call StopVimInTerminal(buf) + + call delete('XtestPopupCursorLine') +endfunc + +func Test_previewpopup() + if !CanRunVimInTerminal() + throw 'Skipped: cannot make screendumps' + endif + call writefile([ + \ "!_TAG_FILE_ENCODING\tutf-8\t//", + \ "another\tXtagfile\t/^this is another", + \ "theword\tXtagfile\t/^theword"], + \ 'Xtags') + call writefile(range(1,20) + \ + ['theword is here'] + \ + range(22, 27) + \ + ['this is another place'] + \ + range(29, 40), + \ "Xtagfile") + let lines =<< trim END + set tags=Xtags + call setline(1, [ + \ 'one', + \ 'two', + \ 'three', + \ 'four', + \ 'five', + \ 'six', + \ 'seven', + \ 'find theword somewhere', + \ 'nine', + \ 'this is another word']) + set previewpopup=height:4,width:40 + END + call writefile(lines, 'XtestPreviewPopup') + let buf = RunVimInTerminal('-S XtestPreviewPopup', #{rows: 14}) + + call term_sendkeys(buf, "/theword\\}") + call term_sendkeys(buf, ":\") + call VerifyScreenDump(buf, 'Test_popupwin_previewpopup_1', {}) + + call term_sendkeys(buf, "/another\\}") + call VerifyScreenDump(buf, 'Test_popupwin_previewpopup_2', {}) + + call StopVimInTerminal(buf) + call delete('Xtags') + call delete('Xtagfile') + call delete('XtestPreviewPopup') +endfunc + +" vim: shiftwidth=2 sts=2 diff -Nru vim-8.1.1681/src/testdir/test_regexp_utf8.vim vim-8.1.1729/src/testdir/test_regexp_utf8.vim --- vim-8.1.1681/src/testdir/test_regexp_utf8.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/test_regexp_utf8.vim 2019-07-21 21:04:21.000000000 +0000 @@ -206,3 +206,12 @@ call assert_equal(1, "\u3042" =~# '[\u3000-\u4000]') set re=0 endfunc + +func Test_optmatch_toolong() + set re=1 + " Can only handle about 8000 characters. + let pat = '\\%[' .. repeat('x', 9000) .. ']' + call assert_fails('call match("abc def", "' .. pat .. '")', 'E339:') + set re=0 +endfunc + diff -Nru vim-8.1.1681/src/testdir/test_search.vim vim-8.1.1729/src/testdir/test_search.vim --- vim-8.1.1681/src/testdir/test_search.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/test_search.vim 2019-07-21 21:04:21.000000000 +0000 @@ -240,6 +240,10 @@ " go to previous match (on line 2) call feedkeys("/the\\\\\\\", 'tx') call assert_equal(' 2 these', getline('.')) + 1 + " go to previous match (on line 2) + call feedkeys("/the\\\\", 'tx') + call assert_equal('theother', @/) " Test 2: keep the view, " after deleting a character from the search cmd @@ -251,7 +255,7 @@ call assert_equal({'lnum': 10, 'leftcol': 0, 'col': 4, 'topfill': 0, 'topline': 6, 'coladd': 0, 'skipcol': 0, 'curswant': 4}, winsaveview()) " remove all history entries - for i in range(10) + for i in range(11) call histdel('/') endfor @@ -477,14 +481,14 @@ " Do not call test_override("char_avail", 1) so that and work " regardless char_avail. new - call setline(1, [' 1 the first', ' 2 the second', ' 3 the third']) + call setline(1, [' 1 the first', ' 2 the second', ' 3 the third', '']) set incsearch 1 call feedkeys("/the\\\", 'tx') call assert_equal(' 3 the third', getline('.')) $ call feedkeys("?the\\\\", 'tx') - call assert_equal(' 2 the second', getline('.')) + call assert_equal(' 1 the first', getline('.')) " clean up set noincsearch bw! diff -Nru vim-8.1.1681/src/testdir/test_signs.vim vim-8.1.1729/src/testdir/test_signs.vim --- vim-8.1.1681/src/testdir/test_signs.vim 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/testdir/test_signs.vim 2019-07-21 21:04:21.000000000 +0000 @@ -412,7 +412,7 @@ " Tests for invalid arguments to sign_define() call assert_fails('call sign_define("sign4", {"text" : "===>"})', 'E239:') call assert_fails('call sign_define("sign5", {"text" : ""})', 'E239:') - call assert_fails('call sign_define([])', 'E730:') + call assert_fails('call sign_define({})', 'E731:') call assert_fails('call sign_define("sign6", [])', 'E715:') " Tests for sign_getdefined() @@ -441,7 +441,7 @@ call assert_fails('call sign_place([], "", "mySign", 1)', 'E745:') call assert_fails('call sign_place(5, "", "mySign", -1)', 'E158:') call assert_fails('call sign_place(-1, "", "sign1", "Xsign", [])', - \ 'E474:') + \ 'E715:') call assert_fails('call sign_place(-1, "", "sign1", "Xsign", \ {"lnum" : 30})', 'E474:') call assert_fails('call sign_place(10, "", "xsign1x", "Xsign", @@ -501,11 +501,21 @@ \ {'id' : 20, 'buffer' : 200})", 'E158:') call assert_fails("call sign_unplace('g1', 'mySign')", 'E715:') + call sign_unplace('*') + + " Test for modifying a placed sign + call assert_equal(15, sign_place(15, '', 'sign1', 'Xsign', {'lnum' : 20})) + call assert_equal(15, sign_place(15, '', 'sign2', 'Xsign')) + call assert_equal([{'bufnr' : bufnr(''), 'signs' : + \ [{'id' : 15, 'group' : '', 'lnum' : 20, 'name' : 'sign2', + \ 'priority' : 10}]}], + \ sign_getplaced()) + " Tests for sign_undefine() call assert_equal(0, sign_undefine("sign1")) call assert_equal([], sign_getdefined("sign1")) call assert_fails('call sign_undefine("none")', 'E155:') - call assert_fails('call sign_undefine([])', 'E730:') + call assert_fails('call sign_undefine({})', 'E731:') call delete("Xsign") call sign_unplace('*') @@ -631,7 +641,7 @@ call assert_equal([], sign_getplaced(bnum, {'group' : '*'})[0].signs) " Error case - call assert_fails("call sign_unplace([])", 'E474:') + call assert_fails("call sign_unplace({})", 'E474:') " Place a sign in the global group and try to delete it using a group call assert_equal(5, sign_place(5, '', 'sign1', bnum, {'lnum' : 10})) @@ -1117,8 +1127,8 @@ call delete("Xsign2") endfunc -" Tests for auto-generating the sign identifier -func Test_sign_id_autogen() +" Tests for auto-generating the sign identifier. +func Test_aaa_sign_id_autogen() enew | only call sign_unplace('*') call sign_undefine() @@ -1756,6 +1766,7 @@ set number set signcolumn=number sign define sign1 text==> + sign define sign2 text=V sign place 10 line=1 name=sign1 redraw! call assert_equal("=> 01234", s:ScreenLine(1, 1, 8)) @@ -1836,6 +1847,12 @@ redraw! call assert_equal("=> 01234", s:ScreenLine(1, 1, 8)) call assert_equal(" 2 abcde", s:ScreenLine(2, 1, 8)) + " Add sign with multi-byte text + set numberwidth=4 + sign place 40 line=2 name=sign2 + redraw! + call assert_equal(" => 01234", s:ScreenLine(1, 1, 9)) + call assert_equal(" V abcde", s:ScreenLine(2, 1, 9)) sign unplace * group=* sign undefine sign1 @@ -1843,3 +1860,113 @@ set number& enew! | close endfunc + +" Test for managing multiple signs using the sign functions +func Test_sign_funcs_multi() + call writefile(repeat(["Sun is shining"], 30), "Xsign") + edit Xsign + let bnum = bufnr('') + + " Define multiple signs at once + call assert_equal([0, 0, 0, 0], sign_define([ + \ {'name' : 'sign1', 'text' : '=>', 'linehl' : 'Search', + \ 'texthl' : 'Search'}, + \ {'name' : 'sign2', 'text' : '=>', 'linehl' : 'Search', + \ 'texthl' : 'Search'}, + \ {'name' : 'sign3', 'text' : '=>', 'linehl' : 'Search', + \ 'texthl' : 'Search'}, + \ {'name' : 'sign4', 'text' : '=>', 'linehl' : 'Search', + \ 'texthl' : 'Search'}])) + + " Negative cases for sign_define() + call assert_equal([], sign_define([])) + call assert_equal([-1], sign_define([{}])) + call assert_fails('call sign_define([6])', 'E715:') + call assert_fails('call sign_define(["abc"])', 'E715:') + call assert_fails('call sign_define([[]])', 'E715:') + + " Place multiple signs at once with specific sign identifier + let l = sign_placelist([{'id' : 1, 'group' : 'g1', 'name' : 'sign1', + \ 'buffer' : 'Xsign', 'lnum' : 11, 'priority' : 50}, + \ {'id' : 2, 'group' : 'g2', 'name' : 'sign2', + \ 'buffer' : 'Xsign', 'lnum' : 11, 'priority' : 100}, + \ {'id' : 3, 'group' : '', 'name' : 'sign3', + \ 'buffer' : 'Xsign', 'lnum' : 11}]) + call assert_equal([1, 2, 3], l) + let s = sign_getplaced('Xsign', {'group' : '*'}) + call assert_equal([ + \ {'id' : 2, 'name' : 'sign2', 'lnum' : 11, + \ 'group' : 'g2', 'priority' : 100}, + \ {'id' : 1, 'name' : 'sign1', 'lnum' : 11, + \ 'group' : 'g1', 'priority' : 50}, + \ {'id' : 3, 'name' : 'sign3', 'lnum' : 11, + \ 'group' : '', 'priority' : 10}], s[0].signs) + + call sign_unplace('*') + + " Place multiple signs at once with auto-generated sign identifier + call assert_equal([1, 1, 5], sign_placelist([ + \ {'group' : 'g1', 'name' : 'sign1', + \ 'buffer' : 'Xsign', 'lnum' : 11}, + \ {'group' : 'g2', 'name' : 'sign2', + \ 'buffer' : 'Xsign', 'lnum' : 11}, + \ {'group' : '', 'name' : 'sign3', + \ 'buffer' : 'Xsign', 'lnum' : 11}])) + let s = sign_getplaced('Xsign', {'group' : '*'}) + call assert_equal([ + \ {'id' : 5, 'name' : 'sign3', 'lnum' : 11, + \ 'group' : '', 'priority' : 10}, + \ {'id' : 1, 'name' : 'sign2', 'lnum' : 11, + \ 'group' : 'g2', 'priority' : 10}, + \ {'id' : 1, 'name' : 'sign1', 'lnum' : 11, + \ 'group' : 'g1', 'priority' : 10}], s[0].signs) + + " Change an existing sign without specifying the group + call assert_equal([5], sign_placelist([ + \ {'id' : 5, 'name' : 'sign1', 'buffer' : 'Xsign'}])) + let s = sign_getplaced('Xsign', {'id' : 5, 'group' : ''}) + call assert_equal([{'id' : 5, 'name' : 'sign1', 'lnum' : 11, + \ 'group' : '', 'priority' : 10}], s[0].signs) + + " Place sign without a sign name + call assert_equal([-1], sign_placelist([{'id' : 10, 'buffer' : 'Xsign', + \ 'lnum' : 12, 'group' : ''}])) + + " Place sign without a buffer + call assert_equal([-1], sign_placelist([{'id' : 10, 'name' : 'sign1', + \ 'lnum' : 12, 'group' : ''}])) + + " Invalid arguments + call assert_equal([], sign_placelist([])) + call assert_fails('call sign_placelist({})', "E714:") + call assert_fails('call sign_placelist([[]])', "E715:") + call assert_fails('call sign_placelist(["abc"])', "E715:") + call assert_fails('call sign_placelist([100])', "E715:") + + " Unplace multiple signs + call assert_equal([0, 0, 0], sign_unplacelist([{'id' : 5}, + \ {'id' : 1, 'group' : 'g1'}, {'id' : 1, 'group' : 'g2'}])) + + " Invalid arguments + call assert_equal([], sign_unplacelist([])) + call assert_fails('call sign_unplacelist({})', "E714:") + call assert_fails('call sign_unplacelist([[]])', "E715:") + call assert_fails('call sign_unplacelist(["abc"])', "E715:") + call assert_fails('call sign_unplacelist([100])', "E715:") + call assert_fails("call sign_unplacelist([{'id' : -1}])", 'E474') + + call assert_equal([0, 0, 0, 0], + \ sign_undefine(['sign1', 'sign2', 'sign3', 'sign4'])) + call assert_equal([], sign_getdefined()) + + " Invalid arguments + call assert_equal([], sign_undefine([])) + call assert_fails('call sign_undefine([[]])', 'E730:') + call assert_fails('call sign_undefine([{}])', 'E731:') + call assert_fails('call sign_undefine(["1abc2"])', 'E155:') + + call sign_unplace('*') + call sign_undefine() + enew! + call delete("Xsign") +endfunc diff -Nru vim-8.1.1681/src/testing.c vim-8.1.1729/src/testing.c --- vim-8.1.1681/src/testing.c 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/testing.c 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,945 @@ +/* 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. + */ + +/* + * testing.c: Support for tests. + */ + +#include "vim.h" + +#if defined(FEAT_EVAL) || defined(PROTO) + +/* + * Prepare "gap" for an assert error and add the sourcing position. + */ + static void +prepare_assert_error(garray_T *gap) +{ + char buf[NUMBUFLEN]; + + ga_init2(gap, 1, 100); + if (sourcing_name != NULL) + { + ga_concat(gap, sourcing_name); + if (sourcing_lnum > 0) + ga_concat(gap, (char_u *)" "); + } + if (sourcing_lnum > 0) + { + sprintf(buf, "line %ld", (long)sourcing_lnum); + ga_concat(gap, (char_u *)buf); + } + if (sourcing_name != NULL || sourcing_lnum > 0) + ga_concat(gap, (char_u *)": "); +} + +/* + * Append "p[clen]" to "gap", escaping unprintable characters. + * Changes NL to \n, CR to \r, etc. + */ + static void +ga_concat_esc(garray_T *gap, char_u *p, int clen) +{ + char_u buf[NUMBUFLEN]; + + if (clen > 1) + { + mch_memmove(buf, p, clen); + buf[clen] = NUL; + ga_concat(gap, buf); + } + else switch (*p) + { + case BS: ga_concat(gap, (char_u *)"\\b"); break; + case ESC: ga_concat(gap, (char_u *)"\\e"); break; + case FF: ga_concat(gap, (char_u *)"\\f"); break; + case NL: ga_concat(gap, (char_u *)"\\n"); break; + case TAB: ga_concat(gap, (char_u *)"\\t"); break; + case CAR: ga_concat(gap, (char_u *)"\\r"); break; + case '\\': ga_concat(gap, (char_u *)"\\\\"); break; + default: + if (*p < ' ') + { + vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p); + ga_concat(gap, buf); + } + else + ga_append(gap, *p); + break; + } +} + +/* + * Append "str" to "gap", escaping unprintable characters. + * Changes NL to \n, CR to \r, etc. + */ + static void +ga_concat_shorten_esc(garray_T *gap, char_u *str) +{ + char_u *p; + char_u *s; + int c; + int clen; + char_u buf[NUMBUFLEN]; + int same_len; + + if (str == NULL) + { + ga_concat(gap, (char_u *)"NULL"); + return; + } + + for (p = str; *p != NUL; ++p) + { + same_len = 1; + s = p; + c = mb_ptr2char_adv(&s); + clen = s - p; + while (*s != NUL && c == mb_ptr2char(s)) + { + ++same_len; + s += clen; + } + if (same_len > 20) + { + ga_concat(gap, (char_u *)"\\["); + ga_concat_esc(gap, p, clen); + ga_concat(gap, (char_u *)" occurs "); + vim_snprintf((char *)buf, NUMBUFLEN, "%d", same_len); + ga_concat(gap, buf); + ga_concat(gap, (char_u *)" times]"); + p = s - 1; + } + else + ga_concat_esc(gap, p, clen); + } +} + +/* + * Fill "gap" with information about an assert error. + */ + static void +fill_assert_error( + garray_T *gap, + typval_T *opt_msg_tv, + char_u *exp_str, + typval_T *exp_tv, + typval_T *got_tv, + assert_type_T atype) +{ + char_u numbuf[NUMBUFLEN]; + char_u *tofree; + + if (opt_msg_tv->v_type != VAR_UNKNOWN) + { + 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_shorten_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0)); + vim_free(tofree); + } + else + ga_concat_shorten_esc(gap, exp_str); + if (atype != ASSERT_NOTEQUAL) + { + 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 + ga_concat(gap, (char_u *)" but got "); + ga_concat_shorten_esc(gap, tv2string(got_tv, &tofree, numbuf, 0)); + vim_free(tofree); + } +} + + static int +assert_equal_common(typval_T *argvars, assert_type_T atype) +{ + garray_T ga; + + if (tv_equal(&argvars[0], &argvars[1], FALSE, FALSE) + != (atype == ASSERT_EQUAL)) + { + prepare_assert_error(&ga); + fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1], + atype); + assert_error(&ga); + ga_clear(&ga); + return 1; + } + return 0; +} + + static int +assert_match_common(typval_T *argvars, assert_type_T atype) +{ + garray_T ga; + char_u buf1[NUMBUFLEN]; + char_u buf2[NUMBUFLEN]; + char_u *pat = tv_get_string_buf_chk(&argvars[0], buf1); + char_u *text = tv_get_string_buf_chk(&argvars[1], buf2); + + if (pat == NULL || text == NULL) + emsg(_(e_invarg)); + else if (pattern_match(pat, text, FALSE) != (atype == ASSERT_MATCH)) + { + prepare_assert_error(&ga); + fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1], + atype); + assert_error(&ga); + ga_clear(&ga); + return 1; + } + return 0; +} + +/* + * Common for assert_true() and assert_false(). + * Return non-zero for failure. + */ + static int +assert_bool(typval_T *argvars, int isTrue) +{ + int error = FALSE; + garray_T ga; + + if (argvars[0].v_type == VAR_SPECIAL + && argvars[0].vval.v_number == (isTrue ? VVAL_TRUE : VVAL_FALSE)) + return 0; + if (argvars[0].v_type != VAR_NUMBER + || (tv_get_number_chk(&argvars[0], &error) == 0) == isTrue + || error) + { + prepare_assert_error(&ga); + fill_assert_error(&ga, &argvars[1], + (char_u *)(isTrue ? "True" : "False"), + NULL, &argvars[0], ASSERT_OTHER); + assert_error(&ga); + ga_clear(&ga); + return 1; + } + return 0; +} + + static void +assert_append_cmd_or_arg(garray_T *gap, typval_T *argvars, char_u *cmd) +{ + char_u *tofree; + char_u numbuf[NUMBUFLEN]; + + if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) + { + ga_concat(gap, echo_string(&argvars[2], &tofree, numbuf, 0)); + vim_free(tofree); + } + else + ga_concat(gap, cmd); +} + + static int +assert_beeps(typval_T *argvars) +{ + char_u *cmd = tv_get_string_chk(&argvars[0]); + garray_T ga; + int ret = 0; + + called_vim_beep = FALSE; + suppress_errthrow = TRUE; + emsg_silent = FALSE; + do_cmdline_cmd(cmd); + if (!called_vim_beep) + { + prepare_assert_error(&ga); + ga_concat(&ga, (char_u *)"command did not beep: "); + ga_concat(&ga, cmd); + assert_error(&ga); + ga_clear(&ga); + ret = 1; + } + + suppress_errthrow = FALSE; + emsg_on_display = FALSE; + return ret; +} + +/* + * "assert_beeps(cmd [, error])" function + */ + void +f_assert_beeps(typval_T *argvars, typval_T *rettv) +{ + rettv->vval.v_number = assert_beeps(argvars); +} + +/* + * "assert_equal(expected, actual[, msg])" function + */ + void +f_assert_equal(typval_T *argvars, typval_T *rettv) +{ + rettv->vval.v_number = assert_equal_common(argvars, ASSERT_EQUAL); +} + + static int +assert_equalfile(typval_T *argvars) +{ + char_u buf1[NUMBUFLEN]; + char_u buf2[NUMBUFLEN]; + char_u *fname1 = tv_get_string_buf_chk(&argvars[0], buf1); + char_u *fname2 = tv_get_string_buf_chk(&argvars[1], buf2); + garray_T ga; + FILE *fd1; + FILE *fd2; + + if (fname1 == NULL || fname2 == NULL) + return 0; + + IObuff[0] = NUL; + fd1 = mch_fopen((char *)fname1, READBIN); + if (fd1 == NULL) + { + vim_snprintf((char *)IObuff, IOSIZE, (char *)e_notread, fname1); + } + else + { + fd2 = mch_fopen((char *)fname2, READBIN); + if (fd2 == NULL) + { + fclose(fd1); + vim_snprintf((char *)IObuff, IOSIZE, (char *)e_notread, fname2); + } + else + { + int c1, c2; + long count = 0; + + for (;;) + { + c1 = fgetc(fd1); + c2 = fgetc(fd2); + if (c1 == EOF) + { + if (c2 != EOF) + STRCPY(IObuff, "first file is shorter"); + break; + } + else if (c2 == EOF) + { + STRCPY(IObuff, "second file is shorter"); + break; + } + else if (c1 != c2) + { + vim_snprintf((char *)IObuff, IOSIZE, + "difference at byte %ld", count); + break; + } + ++count; + } + fclose(fd1); + fclose(fd2); + } + } + if (IObuff[0] != NUL) + { + prepare_assert_error(&ga); + ga_concat(&ga, IObuff); + assert_error(&ga); + ga_clear(&ga); + return 1; + } + return 0; +} + +/* + * "assert_equalfile(fname-one, fname-two)" function + */ + void +f_assert_equalfile(typval_T *argvars, typval_T *rettv) +{ + rettv->vval.v_number = assert_equalfile(argvars); +} + +/* + * "assert_notequal(expected, actual[, msg])" function + */ + void +f_assert_notequal(typval_T *argvars, typval_T *rettv) +{ + rettv->vval.v_number = assert_equal_common(argvars, ASSERT_NOTEQUAL); +} + +/* + * "assert_exception(string[, msg])" function + */ + void +f_assert_exception(typval_T *argvars, typval_T *rettv) +{ + garray_T ga; + char_u *error = tv_get_string_chk(&argvars[0]); + + if (*get_vim_var_str(VV_EXCEPTION) == NUL) + { + prepare_assert_error(&ga); + ga_concat(&ga, (char_u *)"v:exception is not set"); + assert_error(&ga); + ga_clear(&ga); + rettv->vval.v_number = 1; + } + else if (error != NULL + && strstr((char *)get_vim_var_str(VV_EXCEPTION), (char *)error) == NULL) + { + prepare_assert_error(&ga); + fill_assert_error(&ga, &argvars[1], NULL, &argvars[0], + get_vim_var_tv(VV_EXCEPTION), ASSERT_OTHER); + assert_error(&ga); + ga_clear(&ga); + rettv->vval.v_number = 1; + } +} + +/* + * "assert_fails(cmd [, error[, msg]])" function + */ + void +f_assert_fails(typval_T *argvars, typval_T *rettv) +{ + char_u *cmd = tv_get_string_chk(&argvars[0]); + garray_T ga; + int save_trylevel = trylevel; + + // trylevel must be zero for a ":throw" command to be considered failed + trylevel = 0; + called_emsg = FALSE; + suppress_errthrow = TRUE; + emsg_silent = TRUE; + + do_cmdline_cmd(cmd); + if (!called_emsg) + { + prepare_assert_error(&ga); + ga_concat(&ga, (char_u *)"command did not fail: "); + assert_append_cmd_or_arg(&ga, argvars, cmd); + assert_error(&ga); + ga_clear(&ga); + rettv->vval.v_number = 1; + } + else if (argvars[1].v_type != VAR_UNKNOWN) + { + char_u buf[NUMBUFLEN]; + char *error = (char *)tv_get_string_buf_chk(&argvars[1], buf); + + if (error == NULL + || strstr((char *)get_vim_var_str(VV_ERRMSG), error) == NULL) + { + prepare_assert_error(&ga); + fill_assert_error(&ga, &argvars[2], NULL, &argvars[1], + get_vim_var_tv(VV_ERRMSG), ASSERT_OTHER); + ga_concat(&ga, (char_u *)": "); + assert_append_cmd_or_arg(&ga, argvars, cmd); + assert_error(&ga); + ga_clear(&ga); + rettv->vval.v_number = 1; + } + } + + trylevel = save_trylevel; + called_emsg = FALSE; + suppress_errthrow = FALSE; + emsg_silent = FALSE; + emsg_on_display = FALSE; + set_vim_var_string(VV_ERRMSG, NULL, 0); +} + +/* + * "assert_false(actual[, msg])" function + */ + void +f_assert_false(typval_T *argvars, typval_T *rettv) +{ + rettv->vval.v_number = assert_bool(argvars, FALSE); +} + + static int +assert_inrange(typval_T *argvars) +{ + garray_T ga; + int error = FALSE; + char_u *tofree; + char msg[200]; + char_u numbuf[NUMBUFLEN]; + +#ifdef FEAT_FLOAT + if (argvars[0].v_type == VAR_FLOAT + || argvars[1].v_type == VAR_FLOAT + || argvars[2].v_type == VAR_FLOAT) + { + float_T flower = tv_get_float(&argvars[0]); + float_T fupper = tv_get_float(&argvars[1]); + float_T factual = tv_get_float(&argvars[2]); + + if (factual < flower || factual > fupper) + { + prepare_assert_error(&ga); + if (argvars[3].v_type != VAR_UNKNOWN) + { + ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0)); + vim_free(tofree); + } + else + { + vim_snprintf(msg, 200, "Expected range %g - %g, but got %g", + flower, fupper, factual); + ga_concat(&ga, (char_u *)msg); + } + assert_error(&ga); + ga_clear(&ga); + return 1; + } + } + else +#endif + { + varnumber_T lower = tv_get_number_chk(&argvars[0], &error); + varnumber_T upper = tv_get_number_chk(&argvars[1], &error); + varnumber_T actual = tv_get_number_chk(&argvars[2], &error); + + if (error) + return 0; + if (actual < lower || actual > upper) + { + prepare_assert_error(&ga); + if (argvars[3].v_type != VAR_UNKNOWN) + { + ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0)); + vim_free(tofree); + } + else + { + vim_snprintf(msg, 200, "Expected range %ld - %ld, but got %ld", + (long)lower, (long)upper, (long)actual); + ga_concat(&ga, (char_u *)msg); + } + assert_error(&ga); + ga_clear(&ga); + return 1; + } + } + return 0; +} + +/* + * "assert_inrange(lower, upper[, msg])" function + */ + void +f_assert_inrange(typval_T *argvars, typval_T *rettv) +{ + rettv->vval.v_number = assert_inrange(argvars); +} + +/* + * "assert_match(pattern, actual[, msg])" function + */ + void +f_assert_match(typval_T *argvars, typval_T *rettv) +{ + rettv->vval.v_number = assert_match_common(argvars, ASSERT_MATCH); +} + +/* + * "assert_notmatch(pattern, actual[, msg])" function + */ + void +f_assert_notmatch(typval_T *argvars, typval_T *rettv) +{ + rettv->vval.v_number = assert_match_common(argvars, ASSERT_NOTMATCH); +} + +/* + * "assert_report(msg)" function + */ + void +f_assert_report(typval_T *argvars, typval_T *rettv) +{ + garray_T ga; + + prepare_assert_error(&ga); + ga_concat(&ga, tv_get_string(&argvars[0])); + assert_error(&ga); + ga_clear(&ga); + rettv->vval.v_number = 1; +} + +/* + * "assert_true(actual[, msg])" function + */ + void +f_assert_true(typval_T *argvars, typval_T *rettv) +{ + rettv->vval.v_number = assert_bool(argvars, TRUE); +} + +/* + * "test_alloc_fail(id, countdown, repeat)" function + */ + void +f_test_alloc_fail(typval_T *argvars, typval_T *rettv UNUSED) +{ + if (argvars[0].v_type != VAR_NUMBER + || argvars[0].vval.v_number <= 0 + || argvars[1].v_type != VAR_NUMBER + || argvars[1].vval.v_number < 0 + || argvars[2].v_type != VAR_NUMBER) + emsg(_(e_invarg)); + else + { + alloc_fail_id = argvars[0].vval.v_number; + if (alloc_fail_id >= aid_last) + emsg(_(e_invarg)); + alloc_fail_countdown = argvars[1].vval.v_number; + alloc_fail_repeat = argvars[2].vval.v_number; + did_outofmem_msg = FALSE; + } +} + +/* + * "test_autochdir()" + */ + void +f_test_autochdir(typval_T *argvars UNUSED, typval_T *rettv UNUSED) +{ +#if defined(FEAT_AUTOCHDIR) + test_autochdir = TRUE; +#endif +} + +/* + * "test_feedinput()" + */ + void +f_test_feedinput(typval_T *argvars, typval_T *rettv UNUSED) +{ +#ifdef USE_INPUT_BUF + char_u *val = tv_get_string_chk(&argvars[0]); + + if (val != NULL) + { + trash_input_buf(); + add_to_input_buf_csi(val, (int)STRLEN(val)); + } +#endif +} + +/* + * "test_getvalue({name})" function + */ + void +f_test_getvalue(typval_T *argvars, typval_T *rettv) +{ + if (argvars[0].v_type != VAR_STRING) + emsg(_(e_invarg)); + else + { + char_u *name = tv_get_string(&argvars[0]); + + if (STRCMP(name, (char_u *)"need_fileinfo") == 0) + rettv->vval.v_number = need_fileinfo; + else + semsg(_(e_invarg2), name); + } +} + +/* + * "test_option_not_set({name})" function + */ + void +f_test_option_not_set(typval_T *argvars, typval_T *rettv UNUSED) +{ + char_u *name = (char_u *)""; + + if (argvars[0].v_type != VAR_STRING) + emsg(_(e_invarg)); + else + { + name = tv_get_string(&argvars[0]); + if (reset_option_was_set(name) == FAIL) + semsg(_(e_invarg2), name); + } +} + +/* + * "test_override({name}, {val})" function + */ + void +f_test_override(typval_T *argvars, typval_T *rettv UNUSED) +{ + char_u *name = (char_u *)""; + int val; + static int save_starting = -1; + + if (argvars[0].v_type != VAR_STRING + || (argvars[1].v_type) != VAR_NUMBER) + emsg(_(e_invarg)); + else + { + name = tv_get_string(&argvars[0]); + val = (int)tv_get_number(&argvars[1]); + + if (STRCMP(name, (char_u *)"redraw") == 0) + disable_redraw_for_testing = val; + else if (STRCMP(name, (char_u *)"redraw_flag") == 0) + ignore_redraw_flag_for_testing = val; + else if (STRCMP(name, (char_u *)"char_avail") == 0) + disable_char_avail_for_testing = val; + else if (STRCMP(name, (char_u *)"starting") == 0) + { + if (val) + { + if (save_starting < 0) + save_starting = starting; + starting = 0; + } + else + { + starting = save_starting; + save_starting = -1; + } + } + else if (STRCMP(name, (char_u *)"nfa_fail") == 0) + nfa_fail_for_testing = val; + else if (STRCMP(name, (char_u *)"no_query_mouse") == 0) + no_query_mouse_for_testing = val; + else if (STRCMP(name, (char_u *)"no_wait_return") == 0) + no_wait_return = val; + else if (STRCMP(name, (char_u *)"ALL") == 0) + { + disable_char_avail_for_testing = FALSE; + disable_redraw_for_testing = FALSE; + ignore_redraw_flag_for_testing = FALSE; + nfa_fail_for_testing = FALSE; + no_query_mouse_for_testing = FALSE; + if (save_starting >= 0) + { + starting = save_starting; + save_starting = -1; + } + } + else + semsg(_(e_invarg2), name); + } +} + +/* + * "test_refcount({expr})" function + */ + void +f_test_refcount(typval_T *argvars, typval_T *rettv) +{ + int retval = -1; + + switch (argvars[0].v_type) + { + case VAR_UNKNOWN: + case VAR_NUMBER: + case VAR_FLOAT: + case VAR_SPECIAL: + case VAR_STRING: + break; + case VAR_JOB: +#ifdef FEAT_JOB_CHANNEL + if (argvars[0].vval.v_job != NULL) + retval = argvars[0].vval.v_job->jv_refcount - 1; +#endif + break; + case VAR_CHANNEL: +#ifdef FEAT_JOB_CHANNEL + if (argvars[0].vval.v_channel != NULL) + retval = argvars[0].vval.v_channel->ch_refcount - 1; +#endif + break; + case VAR_FUNC: + if (argvars[0].vval.v_string != NULL) + { + ufunc_T *fp; + + fp = find_func(argvars[0].vval.v_string); + if (fp != NULL) + retval = fp->uf_refcount; + } + break; + case VAR_PARTIAL: + if (argvars[0].vval.v_partial != NULL) + retval = argvars[0].vval.v_partial->pt_refcount - 1; + break; + case VAR_BLOB: + if (argvars[0].vval.v_blob != NULL) + retval = argvars[0].vval.v_blob->bv_refcount - 1; + break; + case VAR_LIST: + if (argvars[0].vval.v_list != NULL) + retval = argvars[0].vval.v_list->lv_refcount - 1; + break; + case VAR_DICT: + if (argvars[0].vval.v_dict != NULL) + retval = argvars[0].vval.v_dict->dv_refcount - 1; + break; + } + + rettv->v_type = VAR_NUMBER; + rettv->vval.v_number = retval; + +} + +/* + * "test_garbagecollect_now()" function + */ + void +f_test_garbagecollect_now(typval_T *argvars UNUSED, typval_T *rettv UNUSED) +{ + /* This is dangerous, any Lists and Dicts used internally may be freed + * while still in use. */ + garbage_collect(TRUE); +} + +/* + * "test_garbagecollect_soon()" function + */ + void +f_test_garbagecollect_soon(typval_T *argvars UNUSED, typval_T *rettv UNUSED) +{ + may_garbage_collect = TRUE; +} + +/* + * "test_ignore_error()" function + */ + void +f_test_ignore_error(typval_T *argvars, typval_T *rettv UNUSED) +{ + ignore_error_for_testing(tv_get_string(&argvars[0])); +} + + void +f_test_null_blob(typval_T *argvars UNUSED, typval_T *rettv) +{ + rettv->v_type = VAR_BLOB; + rettv->vval.v_blob = NULL; +} + +#ifdef FEAT_JOB_CHANNEL + void +f_test_null_channel(typval_T *argvars UNUSED, typval_T *rettv) +{ + rettv->v_type = VAR_CHANNEL; + rettv->vval.v_channel = NULL; +} +#endif + + void +f_test_null_dict(typval_T *argvars UNUSED, typval_T *rettv) +{ + rettv_dict_set(rettv, NULL); +} + +#ifdef FEAT_JOB_CHANNEL + void +f_test_null_job(typval_T *argvars UNUSED, typval_T *rettv) +{ + rettv->v_type = VAR_JOB; + rettv->vval.v_job = NULL; +} +#endif + + void +f_test_null_list(typval_T *argvars UNUSED, typval_T *rettv) +{ + rettv_list_set(rettv, NULL); +} + + void +f_test_null_partial(typval_T *argvars UNUSED, typval_T *rettv) +{ + rettv->v_type = VAR_PARTIAL; + rettv->vval.v_partial = NULL; +} + + void +f_test_null_string(typval_T *argvars UNUSED, typval_T *rettv) +{ + rettv->v_type = VAR_STRING; + rettv->vval.v_string = NULL; +} + +#ifdef FEAT_GUI + void +f_test_scrollbar(typval_T *argvars, typval_T *rettv UNUSED) +{ + char_u *which; + long value; + int dragging; + scrollbar_T *sb = NULL; + + if (argvars[0].v_type != VAR_STRING + || (argvars[1].v_type) != VAR_NUMBER + || (argvars[2].v_type) != VAR_NUMBER) + { + emsg(_(e_invarg)); + return; + } + which = tv_get_string(&argvars[0]); + value = tv_get_number(&argvars[1]); + dragging = tv_get_number(&argvars[2]); + + if (STRCMP(which, "left") == 0) + sb = &curwin->w_scrollbars[SBAR_LEFT]; + else if (STRCMP(which, "right") == 0) + sb = &curwin->w_scrollbars[SBAR_RIGHT]; + else if (STRCMP(which, "hor") == 0) + sb = &gui.bottom_sbar; + if (sb == NULL) + { + semsg(_(e_invarg2), which); + return; + } + gui_drag_scrollbar(sb, value, dragging); +# ifndef USE_ON_FLY_SCROLL + // need to loop through normal_cmd() to handle the scroll events + exec_normal(FALSE, TRUE, FALSE); +# endif +} +#endif + +#ifdef FEAT_MOUSE + void +f_test_setmouse(typval_T *argvars, typval_T *rettv UNUSED) +{ + mouse_row = (time_t)tv_get_number(&argvars[0]) - 1; + mouse_col = (time_t)tv_get_number(&argvars[1]) - 1; +} +#endif + + void +f_test_settime(typval_T *argvars, typval_T *rettv UNUSED) +{ + time_for_testing = (time_t)tv_get_number(&argvars[0]); +} + + +#endif // defined(FEAT_EVAL) diff -Nru vim-8.1.1681/src/userfunc.c vim-8.1.1729/src/userfunc.c --- vim-8.1.1681/src/userfunc.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/userfunc.c 2019-07-21 21:04:21.000000000 +0000 @@ -23,13 +23,7 @@ #define FC_REMOVED 0x20 // function redefined while uf_refcount > 0 #define FC_SANDBOX 0x40 // function defined in the sandbox -/* From user function to hashitem and back. */ -#define UF2HIKEY(fp) ((fp)->uf_name) -#define HIKEY2UF(p) ((ufunc_T *)((p) - offsetof(ufunc_T, uf_name))) -#define HI2UF(hi) HIKEY2UF((hi)->hi_key) - #define FUNCARG(fp, j) ((char_u **)(fp->uf_args.ga_data))[j] -#define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j] /* * All user-defined functions are found in this hashtable. @@ -51,13 +45,6 @@ static char *e_funcref = N_("E718: Funcref required"); static char *e_nofunc = N_("E130: Unknown function: %s"); -#ifdef FEAT_PROFILE -static void func_do_profile(ufunc_T *fp); -static void prof_sort_list(FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self); -static void prof_func_line(FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self); -static int prof_total_cmp(const void *s1, const void *s2); -static int prof_self_cmp(const void *s1, const void *s2); -#endif static void funccal_unref(funccall_T *fc, ufunc_T *fp, int force); void @@ -67,6 +54,15 @@ } /* + * Return the function hash table + */ + hashtab_T * +func_tbl_get(void) +{ + return &func_hashtab; +} + +/* * Get function arguments. */ static int @@ -1312,6 +1308,12 @@ } } + funccall_T * +get_current_funccal(void) +{ + return current_funccal; +} + #if defined(EXITFREE) || defined(PROTO) void free_all_functions(void) @@ -1998,8 +2000,6 @@ int overwrite = FALSE; int indent; int nesting; - char_u *skip_until = NULL; - char_u *trimmed = NULL; dictitem_T *v; funcdict_T fudi; static int func_nr = 0; /* number for nameless function */ @@ -2010,6 +2010,9 @@ int do_concat = TRUE; linenr_T sourcing_lnum_off; linenr_T sourcing_lnum_top; + int is_heredoc = FALSE; + char_u *skip_until = NULL; + char_u *heredoc_trimmed = NULL; /* * ":function" without argument: list functions. @@ -2329,17 +2332,28 @@ if (skip_until != NULL) { - // Between ":append" and "." and between ":python <uf_lines.ga_len; - - if (!fp->uf_prof_initialized) - { - if (len == 0) - len = 1; /* avoid getting error for allocating zero bytes */ - fp->uf_tm_count = 0; - profile_zero(&fp->uf_tm_self); - profile_zero(&fp->uf_tm_total); - if (fp->uf_tml_count == NULL) - fp->uf_tml_count = ALLOC_CLEAR_MULT(int, len); - if (fp->uf_tml_total == NULL) - fp->uf_tml_total = ALLOC_CLEAR_MULT(proftime_T, len); - if (fp->uf_tml_self == NULL) - fp->uf_tml_self = ALLOC_CLEAR_MULT(proftime_T, len); - fp->uf_tml_idx = -1; - if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL - || fp->uf_tml_self == NULL) - return; /* out of memory */ - fp->uf_prof_initialized = TRUE; - } - - fp->uf_profiling = TRUE; -} - -/* - * Dump the profiling results for all functions in file "fd". - */ - void -func_dump_profile(FILE *fd) -{ - hashitem_T *hi; - int todo; - ufunc_T *fp; - int i; - ufunc_T **sorttab; - int st_len = 0; - char_u *p; - - todo = (int)func_hashtab.ht_used; - if (todo == 0) - return; /* nothing to dump */ - - sorttab = ALLOC_MULT(ufunc_T *, todo); - - for (hi = func_hashtab.ht_array; todo > 0; ++hi) - { - if (!HASHITEM_EMPTY(hi)) - { - --todo; - fp = HI2UF(hi); - if (fp->uf_prof_initialized) - { - if (sorttab != NULL) - sorttab[st_len++] = fp; - - if (fp->uf_name[0] == K_SPECIAL) - fprintf(fd, "FUNCTION %s()\n", fp->uf_name + 3); - else - fprintf(fd, "FUNCTION %s()\n", fp->uf_name); - p = home_replace_save(NULL, - get_scriptname(fp->uf_script_ctx.sc_sid)); - if (p != NULL) - { - fprintf(fd, " Defined: %s line %ld\n", - p, (long)fp->uf_script_ctx.sc_lnum); - vim_free(p); - } - if (fp->uf_tm_count == 1) - fprintf(fd, "Called 1 time\n"); - else - fprintf(fd, "Called %d times\n", fp->uf_tm_count); - fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); - fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); - fprintf(fd, "\n"); - fprintf(fd, "count total (s) self (s)\n"); - - for (i = 0; i < fp->uf_lines.ga_len; ++i) - { - if (FUNCLINE(fp, i) == NULL) - continue; - prof_func_line(fd, fp->uf_tml_count[i], - &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); - fprintf(fd, "%s\n", FUNCLINE(fp, i)); - } - fprintf(fd, "\n"); - } - } - } - - if (sorttab != NULL && st_len > 0) - { - qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), - prof_total_cmp); - prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); - qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), - prof_self_cmp); - prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); - } - - vim_free(sorttab); -} - - static void -prof_sort_list( - FILE *fd, - ufunc_T **sorttab, - int st_len, - char *title, - int prefer_self) /* when equal print only self time */ -{ - int i; - ufunc_T *fp; - - fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); - fprintf(fd, "count total (s) self (s) function\n"); - for (i = 0; i < 20 && i < st_len; ++i) - { - fp = sorttab[i]; - prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, - prefer_self); - if (fp->uf_name[0] == K_SPECIAL) - fprintf(fd, " %s()\n", fp->uf_name + 3); - else - fprintf(fd, " %s()\n", fp->uf_name); - } - fprintf(fd, "\n"); -} - -/* - * Print the count and times for one function or function line. - */ - static void -prof_func_line( - FILE *fd, - int count, - proftime_T *total, - proftime_T *self, - int prefer_self) /* when equal print only self time */ -{ - if (count > 0) - { - fprintf(fd, "%5d ", count); - if (prefer_self && profile_equal(total, self)) - fprintf(fd, " "); - else - fprintf(fd, "%s ", profile_msg(total)); - if (!prefer_self && profile_equal(total, self)) - fprintf(fd, " "); - else - fprintf(fd, "%s ", profile_msg(self)); - } - else - fprintf(fd, " "); -} - -/* - * Compare function for total time sorting. - */ - static int -prof_total_cmp(const void *s1, const void *s2) -{ - ufunc_T *p1, *p2; - - p1 = *(ufunc_T **)s1; - p2 = *(ufunc_T **)s2; - return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); -} - -/* - * Compare function for self time sorting. - */ - static int -prof_self_cmp(const void *s1, const void *s2) -{ - ufunc_T *p1, *p2; - - p1 = *(ufunc_T **)s1; - p2 = *(ufunc_T **)s2; - return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); -} - -/* - * Prepare profiling for entering a child or something else that is not - * counted for the script/function itself. - * Should always be called in pair with prof_child_exit(). - */ - void -prof_child_enter( - proftime_T *tm) /* place to store waittime */ -{ - funccall_T *fc = current_funccal; - - if (fc != NULL && fc->func->uf_profiling) - profile_start(&fc->prof_child); - script_prof_save(tm); -} - -/* - * Take care of time spent in a child. - * Should always be called after prof_child_enter(). - */ - void -prof_child_exit( - proftime_T *tm) /* where waittime was stored */ -{ - funccall_T *fc = current_funccal; - - if (fc != NULL && fc->func->uf_profiling) - { - profile_end(&fc->prof_child); - profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ - profile_add(&fc->func->uf_tm_children, &fc->prof_child); - profile_add(&fc->func->uf_tml_children, &fc->prof_child); - } - script_prof_restore(tm); -} - -#endif /* FEAT_PROFILE */ - #if defined(FEAT_CMDL_COMPL) || defined(PROTO) /* @@ -3574,71 +3358,6 @@ return retval; } -#if defined(FEAT_PROFILE) || defined(PROTO) -/* - * Called when starting to read a function line. - * "sourcing_lnum" must be correct! - * When skipping lines it may not actually be executed, but we won't find out - * until later and we need to store the time now. - */ - void -func_line_start(void *cookie) -{ - funccall_T *fcp = (funccall_T *)cookie; - ufunc_T *fp = fcp->func; - - if (fp->uf_profiling && sourcing_lnum >= 1 - && sourcing_lnum <= fp->uf_lines.ga_len) - { - fp->uf_tml_idx = sourcing_lnum - 1; - /* Skip continuation lines. */ - while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL) - --fp->uf_tml_idx; - fp->uf_tml_execed = FALSE; - profile_start(&fp->uf_tml_start); - profile_zero(&fp->uf_tml_children); - profile_get_wait(&fp->uf_tml_wait); - } -} - -/* - * Called when actually executing a function line. - */ - void -func_line_exec(void *cookie) -{ - funccall_T *fcp = (funccall_T *)cookie; - ufunc_T *fp = fcp->func; - - if (fp->uf_profiling && fp->uf_tml_idx >= 0) - fp->uf_tml_execed = TRUE; -} - -/* - * Called when done with a function line. - */ - void -func_line_end(void *cookie) -{ - funccall_T *fcp = (funccall_T *)cookie; - ufunc_T *fp = fcp->func; - - if (fp->uf_profiling && fp->uf_tml_idx >= 0) - { - if (fp->uf_tml_execed) - { - ++fp->uf_tml_count[fp->uf_tml_idx]; - profile_end(&fp->uf_tml_start); - profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); - profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); - profile_self(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start, - &fp->uf_tml_children); - } - fp->uf_tml_idx = -1; - } -} -#endif - /* * Return TRUE if the currently active function should be ended, because a * return was encountered or an error occurred. Used inside a ":while". diff -Nru vim-8.1.1681/src/version.c vim-8.1.1729/src/version.c --- vim-8.1.1681/src/version.c 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/version.c 2019-07-21 21:04:21.000000000 +0000 @@ -778,6 +778,102 @@ static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1729, +/**/ + 1728, +/**/ + 1727, +/**/ + 1726, +/**/ + 1725, +/**/ + 1724, +/**/ + 1723, +/**/ + 1722, +/**/ + 1721, +/**/ + 1720, +/**/ + 1719, +/**/ + 1718, +/**/ + 1717, +/**/ + 1716, +/**/ + 1715, +/**/ + 1714, +/**/ + 1713, +/**/ + 1712, +/**/ + 1711, +/**/ + 1710, +/**/ + 1709, +/**/ + 1708, +/**/ + 1707, +/**/ + 1706, +/**/ + 1705, +/**/ + 1704, +/**/ + 1703, +/**/ + 1702, +/**/ + 1701, +/**/ + 1700, +/**/ + 1699, +/**/ + 1698, +/**/ + 1697, +/**/ + 1696, +/**/ + 1695, +/**/ + 1694, +/**/ + 1693, +/**/ + 1692, +/**/ + 1691, +/**/ + 1690, +/**/ + 1689, +/**/ + 1688, +/**/ + 1687, +/**/ + 1686, +/**/ + 1685, +/**/ + 1684, +/**/ + 1683, +/**/ + 1682, +/**/ 1681, /**/ 1680, diff -Nru vim-8.1.1681/src/vim.h vim-8.1.1729/src/vim.h --- vim-8.1.1681/src/vim.h 2019-07-13 18:14:45.000000000 +0000 +++ vim-8.1.1729/src/vim.h 2019-07-21 21:04:21.000000000 +0000 @@ -617,6 +617,7 @@ #define POPF_IS_POPUP 1 // this is a popup window #define POPF_HIDDEN 2 // popup is not displayed #define POPF_HANDLED 4 // popup was just redrawn or filtered +#define POPF_CURSORLINE 8 // popup is highlighting at the cursorline #ifdef FEAT_TEXT_PROP # define WIN_IS_POPUP(wp) ((wp)->w_popup_flags != 0) #else diff -Nru vim-8.1.1681/src/viminfo.c vim-8.1.1729/src/viminfo.c --- vim-8.1.1681/src/viminfo.c 1970-01-01 00:00:00.000000000 +0000 +++ vim-8.1.1729/src/viminfo.c 2019-07-21 21:04:21.000000000 +0000 @@ -0,0 +1,1911 @@ +/* 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. + */ + +/* + * viminfo.c: viminfo related functions + */ + +#include "vim.h" +#include "version.h" + +#if defined(FEAT_VIMINFO) || defined(PROTO) + +static int viminfo_errcnt; + +/* + * Get the viminfo file name to use. + * If "file" is given and not empty, use it (has already been expanded by + * cmdline functions). + * Otherwise use "-i file_name", value from 'viminfo' or the default, and + * expand environment variables. + * Returns an allocated string. NULL when out of memory. + */ + static char_u * +viminfo_filename(char_u *file) +{ + if (file == NULL || *file == NUL) + { + if (*p_viminfofile != NUL) + file = p_viminfofile; + else if ((file = find_viminfo_parameter('n')) == NULL || *file == NUL) + { +#ifdef VIMINFO_FILE2 +# ifdef VMS + if (mch_getenv((char_u *)"SYS$LOGIN") == NULL) +# else +# ifdef MSWIN + // Use $VIM only if $HOME is the default "C:/". + if (STRCMP(vim_getenv((char_u *)"HOME", NULL), "C:/") == 0 + && mch_getenv((char_u *)"HOME") == NULL) +# else + if (mch_getenv((char_u *)"HOME") == NULL) +# endif +# endif + { + // don't use $VIM when not available. + expand_env((char_u *)"$VIM", NameBuff, MAXPATHL); + if (STRCMP("$VIM", NameBuff) != 0) // $VIM was expanded + file = (char_u *)VIMINFO_FILE2; + else + file = (char_u *)VIMINFO_FILE; + } + else +#endif + file = (char_u *)VIMINFO_FILE; + } + expand_env(file, NameBuff, MAXPATHL); + file = NameBuff; + } + return vim_strsave(file); +} + + static int +read_viminfo_bufferlist( + vir_T *virp, + int writing) +{ + char_u *tab; + linenr_T lnum; + colnr_T col; + buf_T *buf; + char_u *sfname; + char_u *xline; + + // Handle long line and escaped characters. + xline = viminfo_readstring(virp, 1, FALSE); + + // don't read in if there are files on the command-line or if writing: + if (xline != NULL && !writing && ARGCOUNT == 0 + && find_viminfo_parameter('%') != NULL) + { + // Format is: Tab Tab . + // Watch out for a Tab in the file name, work from the end. + lnum = 0; + col = 0; + tab = vim_strrchr(xline, '\t'); + if (tab != NULL) + { + *tab++ = '\0'; + col = (colnr_T)atoi((char *)tab); + tab = vim_strrchr(xline, '\t'); + if (tab != NULL) + { + *tab++ = '\0'; + lnum = atol((char *)tab); + } + } + + // Expand "~/" in the file name at "line + 1" to a full path. + // Then try shortening it by comparing with the current directory + expand_env(xline, NameBuff, MAXPATHL); + sfname = shorten_fname1(NameBuff); + + buf = buflist_new(NameBuff, sfname, (linenr_T)0, BLN_LISTED); + if (buf != NULL) // just in case... + { + buf->b_last_cursor.lnum = lnum; + buf->b_last_cursor.col = col; + buflist_setfpos(buf, curwin, lnum, col, FALSE); + } + } + vim_free(xline); + + return viminfo_readline(virp); +} + + static void +write_viminfo_bufferlist(FILE *fp) +{ + buf_T *buf; + win_T *win; + tabpage_T *tp; + char_u *line; + int max_buffers; + + if (find_viminfo_parameter('%') == NULL) + return; + + // Without a number -1 is returned: do all buffers. + max_buffers = get_viminfo_parameter('%'); + + // Allocate room for the file name, lnum and col. +#define LINE_BUF_LEN (MAXPATHL + 40) + line = alloc(LINE_BUF_LEN); + if (line == NULL) + return; + + FOR_ALL_TAB_WINDOWS(tp, win) + set_last_cursor(win); + + fputs(_("\n# Buffer list:\n"), fp); + FOR_ALL_BUFFERS(buf) + { + if (buf->b_fname == NULL + || !buf->b_p_bl +#ifdef FEAT_QUICKFIX + || bt_quickfix(buf) +#endif +#ifdef FEAT_TERMINAL + || bt_terminal(buf) +#endif + || removable(buf->b_ffname)) + continue; + + if (max_buffers-- == 0) + break; + putc('%', fp); + home_replace(NULL, buf->b_ffname, line, MAXPATHL, TRUE); + vim_snprintf_add((char *)line, LINE_BUF_LEN, "\t%ld\t%d", + (long)buf->b_last_cursor.lnum, + buf->b_last_cursor.col); + viminfo_writestring(fp, line); + } + vim_free(line); +} + +#if defined(FEAT_CMDHIST) || defined(PROTO) +/* + * Buffers for history read from a viminfo file. Only valid while reading. + */ +static histentry_T *viminfo_history[HIST_COUNT] = + {NULL, NULL, NULL, NULL, NULL}; +static int viminfo_hisidx[HIST_COUNT] = {0, 0, 0, 0, 0}; +static int viminfo_hislen[HIST_COUNT] = {0, 0, 0, 0, 0}; +static int viminfo_add_at_front = FALSE; + +/* + * Translate a history type number to the associated character. + */ + static int +hist_type2char( + int type, + int use_question) // use '?' instead of '/' +{ + if (type == HIST_CMD) + return ':'; + if (type == HIST_SEARCH) + { + if (use_question) + return '?'; + else + return '/'; + } + if (type == HIST_EXPR) + return '='; + return '@'; +} + +/* + * Prepare for reading the history from the viminfo file. + * This allocates history arrays to store the read history lines. + */ + static void +prepare_viminfo_history(int asklen, int writing) +{ + int i; + int num; + int type; + int len; + int hislen = get_hislen(); + + init_history(); + viminfo_add_at_front = (asklen != 0 && !writing); + if (asklen > hislen) + asklen = hislen; + + for (type = 0; type < HIST_COUNT; ++type) + { + histentry_T *histentry = get_histentry(type); + + // Count the number of empty spaces in the history list. Entries read + // from viminfo previously are also considered empty. If there are + // more spaces available than we request, then fill them up. + for (i = 0, num = 0; i < hislen; i++) + if (histentry[i].hisstr == NULL || histentry[i].viminfo) + num++; + len = asklen; + if (num > len) + len = num; + if (len <= 0) + viminfo_history[type] = NULL; + else + viminfo_history[type] = LALLOC_MULT(histentry_T, len); + if (viminfo_history[type] == NULL) + len = 0; + viminfo_hislen[type] = len; + viminfo_hisidx[type] = 0; + } +} + +/* + * Accept a line from the viminfo, store it in the history array when it's + * new. + */ + static int +read_viminfo_history(vir_T *virp, int writing) +{ + int type; + long_u len; + char_u *val; + char_u *p; + + type = hist_char2type(virp->vir_line[0]); + if (viminfo_hisidx[type] < viminfo_hislen[type]) + { + val = viminfo_readstring(virp, 1, TRUE); + if (val != NULL && *val != NUL) + { + int sep = (*val == ' ' ? NUL : *val); + + if (!in_history(type, val + (type == HIST_SEARCH), + viminfo_add_at_front, sep, writing)) + { + // Need to re-allocate to append the separator byte. + len = STRLEN(val); + p = alloc(len + 2); + if (p != NULL) + { + if (type == HIST_SEARCH) + { + // Search entry: Move the separator from the first + // column to after the NUL. + mch_memmove(p, val + 1, (size_t)len); + p[len] = sep; + } + else + { + // Not a search entry: No separator in the viminfo + // file, add a NUL separator. + mch_memmove(p, val, (size_t)len + 1); + p[len + 1] = NUL; + } + viminfo_history[type][viminfo_hisidx[type]].hisstr = p; + viminfo_history[type][viminfo_hisidx[type]].time_set = 0; + viminfo_history[type][viminfo_hisidx[type]].viminfo = TRUE; + viminfo_history[type][viminfo_hisidx[type]].hisnum = 0; + viminfo_hisidx[type]++; + } + } + } + vim_free(val); + } + return viminfo_readline(virp); +} + +/* + * Accept a new style history line from the viminfo, store it in the history + * array when it's new. + */ + static void +handle_viminfo_history( + garray_T *values, + int writing) +{ + int type; + long_u len; + char_u *val; + char_u *p; + bval_T *vp = (bval_T *)values->ga_data; + + // Check the format: + // |{bartype},{histtype},{timestamp},{separator},"text" + if (values->ga_len < 4 + || vp[0].bv_type != BVAL_NR + || vp[1].bv_type != BVAL_NR + || (vp[2].bv_type != BVAL_NR && vp[2].bv_type != BVAL_EMPTY) + || vp[3].bv_type != BVAL_STRING) + return; + + type = vp[0].bv_nr; + if (type >= HIST_COUNT) + return; + if (viminfo_hisidx[type] < viminfo_hislen[type]) + { + val = vp[3].bv_string; + if (val != NULL && *val != NUL) + { + int sep = type == HIST_SEARCH && vp[2].bv_type == BVAL_NR + ? vp[2].bv_nr : NUL; + int idx; + int overwrite = FALSE; + + if (!in_history(type, val, viminfo_add_at_front, sep, writing)) + { + // If lines were written by an older Vim we need to avoid + // getting duplicates. See if the entry already exists. + for (idx = 0; idx < viminfo_hisidx[type]; ++idx) + { + p = viminfo_history[type][idx].hisstr; + if (STRCMP(val, p) == 0 + && (type != HIST_SEARCH || sep == p[STRLEN(p) + 1])) + { + overwrite = TRUE; + break; + } + } + + if (!overwrite) + { + // Need to re-allocate to append the separator byte. + len = vp[3].bv_len; + p = alloc(len + 2); + } + else + len = 0; // for picky compilers + if (p != NULL) + { + viminfo_history[type][idx].time_set = vp[1].bv_nr; + if (!overwrite) + { + mch_memmove(p, val, (size_t)len + 1); + // Put the separator after the NUL. + p[len + 1] = sep; + viminfo_history[type][idx].hisstr = p; + viminfo_history[type][idx].hisnum = 0; + viminfo_history[type][idx].viminfo = TRUE; + viminfo_hisidx[type]++; + } + } + } + } + } +} + +/* + * Concatenate history lines from viminfo after the lines typed in this Vim. + */ + static void +concat_history(int type) +{ + int idx; + int i; + int hislen = get_hislen(); + histentry_T *histentry = get_histentry(type); + int *hisidx = get_hisidx(type); + int *hisnum = get_hisnum(type); + + idx = *hisidx + viminfo_hisidx[type]; + if (idx >= hislen) + idx -= hislen; + else if (idx < 0) + idx = hislen - 1; + if (viminfo_add_at_front) + *hisidx = idx; + else + { + if (*hisidx == -1) + *hisidx = hislen - 1; + do + { + if (histentry[idx].hisstr != NULL || histentry[idx].viminfo) + break; + if (++idx == hislen) + idx = 0; + } while (idx != *hisidx); + if (idx != *hisidx && --idx < 0) + idx = hislen - 1; + } + for (i = 0; i < viminfo_hisidx[type]; i++) + { + vim_free(histentry[idx].hisstr); + histentry[idx].hisstr = viminfo_history[type][i].hisstr; + histentry[idx].viminfo = TRUE; + histentry[idx].time_set = viminfo_history[type][i].time_set; + if (--idx < 0) + idx = hislen - 1; + } + idx += 1; + idx %= hislen; + for (i = 0; i < viminfo_hisidx[type]; i++) + { + histentry[idx++].hisnum = ++*hisnum; + idx %= hislen; + } +} + + static int +sort_hist(const void *s1, const void *s2) +{ + histentry_T *p1 = *(histentry_T **)s1; + histentry_T *p2 = *(histentry_T **)s2; + + if (p1->time_set < p2->time_set) return -1; + if (p1->time_set > p2->time_set) return 1; + return 0; +} + +/* + * Merge history lines from viminfo and lines typed in this Vim based on the + * timestamp; + */ + static void +merge_history(int type) +{ + int max_len; + histentry_T **tot_hist; + histentry_T *new_hist; + int i; + int len; + int hislen = get_hislen(); + histentry_T *histentry = get_histentry(type); + int *hisidx = get_hisidx(type); + int *hisnum = get_hisnum(type); + + // Make one long list with all entries. + max_len = hislen + viminfo_hisidx[type]; + tot_hist = ALLOC_MULT(histentry_T *, max_len); + new_hist = ALLOC_MULT(histentry_T, hislen ); + if (tot_hist == NULL || new_hist == NULL) + { + vim_free(tot_hist); + vim_free(new_hist); + return; + } + for (i = 0; i < viminfo_hisidx[type]; i++) + tot_hist[i] = &viminfo_history[type][i]; + len = i; + for (i = 0; i < hislen; i++) + if (histentry[i].hisstr != NULL) + tot_hist[len++] = &histentry[i]; + + // Sort the list on timestamp. + qsort((void *)tot_hist, (size_t)len, sizeof(histentry_T *), sort_hist); + + // Keep the newest ones. + for (i = 0; i < hislen; i++) + { + if (i < len) + { + new_hist[i] = *tot_hist[i]; + tot_hist[i]->hisstr = NULL; + if (new_hist[i].hisnum == 0) + new_hist[i].hisnum = ++*hisnum; + } + else + clear_hist_entry(&new_hist[i]); + } + *hisidx = (i < len ? i : len) - 1; + + // Free what is not kept. + for (i = 0; i < viminfo_hisidx[type]; i++) + vim_free(viminfo_history[type][i].hisstr); + for (i = 0; i < hislen; i++) + vim_free(histentry[i].hisstr); + vim_free(histentry); + set_histentry(type, new_hist); + vim_free(tot_hist); +} + +/* + * Finish reading history lines from viminfo. Not used when writing viminfo. + */ + static void +finish_viminfo_history(vir_T *virp) +{ + int type; + int merge = virp->vir_version >= VIMINFO_VERSION_WITH_HISTORY; + + for (type = 0; type < HIST_COUNT; ++type) + { + if (get_histentry(type) == NULL) + continue; + + if (merge) + merge_history(type); + else + concat_history(type); + + VIM_CLEAR(viminfo_history[type]); + viminfo_hisidx[type] = 0; + } +} + +/* + * Write history to viminfo file in "fp". + * When "merge" is TRUE merge history lines with a previously read viminfo + * file, data is in viminfo_history[]. + * When "merge" is FALSE just write all history lines. Used for ":wviminfo!". + */ + static void +write_viminfo_history(FILE *fp, int merge) +{ + int i; + int type; + int num_saved; + int round; + int hislen; + + init_history(); + hislen = get_hislen(); + if (hislen == 0) + return; + for (type = 0; type < HIST_COUNT; ++type) + { + histentry_T *histentry = get_histentry(type); + int *hisidx = get_hisidx(type); + + num_saved = get_viminfo_parameter(hist_type2char(type, FALSE)); + if (num_saved == 0) + continue; + if (num_saved < 0) // Use default + num_saved = hislen; + fprintf(fp, _("\n# %s History (newest to oldest):\n"), + type == HIST_CMD ? _("Command Line") : + type == HIST_SEARCH ? _("Search String") : + type == HIST_EXPR ? _("Expression") : + type == HIST_INPUT ? _("Input Line") : + _("Debug Line")); + if (num_saved > hislen) + num_saved = hislen; + + /* + * Merge typed and viminfo history: + * round 1: history of typed commands. + * round 2: history from recently read viminfo. + */ + for (round = 1; round <= 2; ++round) + { + if (round == 1) + // start at newest entry, somewhere in the list + i = *hisidx; + else if (viminfo_hisidx[type] > 0) + // start at newest entry, first in the list + i = 0; + else + // empty list + i = -1; + if (i >= 0) + while (num_saved > 0 + && !(round == 2 && i >= viminfo_hisidx[type])) + { + char_u *p; + time_t timestamp; + int c = NUL; + + if (round == 1) + { + p = histentry[i].hisstr; + timestamp = histentry[i].time_set; + } + else + { + p = viminfo_history[type] == NULL ? NULL + : viminfo_history[type][i].hisstr; + timestamp = viminfo_history[type] == NULL ? 0 + : viminfo_history[type][i].time_set; + } + + if (p != NULL && (round == 2 + || !merge + || !histentry[i].viminfo)) + { + --num_saved; + fputc(hist_type2char(type, TRUE), fp); + // For the search history: put the separator in the + // second column; use a space if there isn't one. + if (type == HIST_SEARCH) + { + c = p[STRLEN(p) + 1]; + putc(c == NUL ? ' ' : c, fp); + } + viminfo_writestring(fp, p); + + { + char cbuf[NUMBUFLEN]; + + // New style history with a bar line. Format: + // |{bartype},{histtype},{timestamp},{separator},"text" + if (c == NUL) + cbuf[0] = NUL; + else + sprintf(cbuf, "%d", c); + fprintf(fp, "|%d,%d,%ld,%s,", BARTYPE_HISTORY, + type, (long)timestamp, cbuf); + barline_writestring(fp, p, LSIZE - 20); + putc('\n', fp); + } + } + if (round == 1) + { + // Decrement index, loop around and stop when back at + // the start. + if (--i < 0) + i = hislen - 1; + if (i == *hisidx) + break; + } + else + { + // Increment index. Stop at the end in the while. + ++i; + } + } + } + for (i = 0; i < viminfo_hisidx[type]; ++i) + if (viminfo_history[type] != NULL) + vim_free(viminfo_history[type][i].hisstr); + VIM_CLEAR(viminfo_history[type]); + viminfo_hisidx[type] = 0; + } +} +#endif // FEAT_VIMINFO + + static void +write_viminfo_barlines(vir_T *virp, FILE *fp_out) +{ + int i; + garray_T *gap = &virp->vir_barlines; + int seen_useful = FALSE; + char *line; + + if (gap->ga_len > 0) + { + fputs(_("\n# Bar lines, copied verbatim:\n"), fp_out); + + // Skip over continuation lines until seeing a useful line. + for (i = 0; i < gap->ga_len; ++i) + { + line = ((char **)(gap->ga_data))[i]; + if (seen_useful || line[1] != '<') + { + fputs(line, fp_out); + seen_useful = TRUE; + } + } + } +} + +/* + * Parse a viminfo line starting with '|'. + * Add each decoded value to "values". + * Returns TRUE if the next line is to be read after using the parsed values. + */ + static int +barline_parse(vir_T *virp, char_u *text, garray_T *values) +{ + char_u *p = text; + char_u *nextp = NULL; + char_u *buf = NULL; + bval_T *value; + int i; + int allocated = FALSE; + int eof; + char_u *sconv; + int converted; + + while (*p == ',') + { + ++p; + if (ga_grow(values, 1) == FAIL) + break; + value = (bval_T *)(values->ga_data) + values->ga_len; + + if (*p == '>') + { + // Need to read a continuation line. Put strings in allocated + // memory, because virp->vir_line is overwritten. + if (!allocated) + { + for (i = 0; i < values->ga_len; ++i) + { + bval_T *vp = (bval_T *)(values->ga_data) + i; + + if (vp->bv_type == BVAL_STRING && !vp->bv_allocated) + { + vp->bv_string = vim_strnsave(vp->bv_string, vp->bv_len); + vp->bv_allocated = TRUE; + } + } + allocated = TRUE; + } + + if (vim_isdigit(p[1])) + { + size_t len; + size_t todo; + size_t n; + + // String value was split into lines that are each shorter + // than LSIZE: + // |{bartype},>{length of "{text}{text2}"} + // |<"{text1} + // |<{text2}",{value} + // Length includes the quotes. + ++p; + len = getdigits(&p); + buf = alloc((int)(len + 1)); + if (buf == NULL) + return TRUE; + p = buf; + for (todo = len; todo > 0; todo -= n) + { + eof = viminfo_readline(virp); + if (eof || virp->vir_line[0] != '|' + || virp->vir_line[1] != '<') + { + // File was truncated or garbled. Read another line if + // this one starts with '|'. + vim_free(buf); + return eof || virp->vir_line[0] == '|'; + } + // Get length of text, excluding |< and NL chars. + n = STRLEN(virp->vir_line); + while (n > 0 && (virp->vir_line[n - 1] == NL + || virp->vir_line[n - 1] == CAR)) + --n; + n -= 2; + if (n > todo) + { + // more values follow after the string + nextp = virp->vir_line + 2 + todo; + n = todo; + } + mch_memmove(p, virp->vir_line + 2, n); + p += n; + } + *p = NUL; + p = buf; + } + else + { + // Line ending in ">" continues in the next line: + // |{bartype},{lots of values},> + // |<{value},{value} + eof = viminfo_readline(virp); + if (eof || virp->vir_line[0] != '|' + || virp->vir_line[1] != '<') + // File was truncated or garbled. Read another line if + // this one starts with '|'. + return eof || virp->vir_line[0] == '|'; + p = virp->vir_line + 2; + } + } + + if (isdigit(*p)) + { + value->bv_type = BVAL_NR; + value->bv_nr = getdigits(&p); + ++values->ga_len; + } + else if (*p == '"') + { + int len = 0; + char_u *s = p; + + // Unescape special characters in-place. + ++p; + while (*p != '"') + { + if (*p == NL || *p == NUL) + return TRUE; // syntax error, drop the value + if (*p == '\\') + { + ++p; + if (*p == 'n') + s[len++] = '\n'; + else + s[len++] = *p; + ++p; + } + else + s[len++] = *p++; + } + ++p; + s[len] = NUL; + + converted = FALSE; + if (virp->vir_conv.vc_type != CONV_NONE && *s != NUL) + { + sconv = string_convert(&virp->vir_conv, s, NULL); + if (sconv != NULL) + { + if (s == buf) + vim_free(s); + s = sconv; + buf = s; + converted = TRUE; + } + } + + // Need to copy in allocated memory if the string wasn't allocated + // above and we did allocate before, thus vir_line may change. + if (s != buf && allocated) + s = vim_strsave(s); + value->bv_string = s; + value->bv_type = BVAL_STRING; + value->bv_len = len; + value->bv_allocated = allocated || converted; + ++values->ga_len; + if (nextp != NULL) + { + // values following a long string + p = nextp; + nextp = NULL; + } + } + else if (*p == ',') + { + value->bv_type = BVAL_EMPTY; + ++values->ga_len; + } + else + break; + } + return TRUE; +} + + static int +read_viminfo_barline(vir_T *virp, int got_encoding, int force, int writing) +{ + char_u *p = virp->vir_line + 1; + int bartype; + garray_T values; + bval_T *vp; + int i; + int read_next = TRUE; + + /* + * The format is: |{bartype},{value},... + * For a very long string: + * |{bartype},>{length of "{text}{text2}"} + * |<{text1} + * |<{text2},{value} + * For a long line not using a string + * |{bartype},{lots of values},> + * |<{value},{value} + */ + if (*p == '<') + { + // Continuation line of an unrecognized item. + if (writing) + ga_add_string(&virp->vir_barlines, virp->vir_line); + } + else + { + ga_init2(&values, sizeof(bval_T), 20); + bartype = getdigits(&p); + switch (bartype) + { + case BARTYPE_VERSION: + // Only use the version when it comes before the encoding. + // If it comes later it was copied by a Vim version that + // doesn't understand the version. + if (!got_encoding) + { + read_next = barline_parse(virp, p, &values); + vp = (bval_T *)values.ga_data; + if (values.ga_len > 0 && vp->bv_type == BVAL_NR) + virp->vir_version = vp->bv_nr; + } + break; + + case BARTYPE_HISTORY: + read_next = barline_parse(virp, p, &values); + handle_viminfo_history(&values, writing); + break; + + case BARTYPE_REGISTER: + read_next = barline_parse(virp, p, &values); + handle_viminfo_register(&values, force); + break; + + case BARTYPE_MARK: + read_next = barline_parse(virp, p, &values); + handle_viminfo_mark(&values, force); + break; + + default: + // copy unrecognized line (for future use) + if (writing) + ga_add_string(&virp->vir_barlines, virp->vir_line); + } + for (i = 0; i < values.ga_len; ++i) + { + vp = (bval_T *)values.ga_data + i; + if (vp->bv_type == BVAL_STRING && vp->bv_allocated) + vim_free(vp->bv_string); + } + ga_clear(&values); + } + + if (read_next) + return viminfo_readline(virp); + return FALSE; +} + + static void +write_viminfo_version(FILE *fp_out) +{ + fprintf(fp_out, "# Viminfo version\n|%d,%d\n\n", + BARTYPE_VERSION, VIMINFO_VERSION); +} + + static int +no_viminfo(void) +{ + // "vim -i NONE" does not read or write a viminfo file + return STRCMP(p_viminfofile, "NONE") == 0; +} + +/* + * Report an error for reading a viminfo file. + * Count the number of errors. When there are more than 10, return TRUE. + */ + int +viminfo_error(char *errnum, char *message, char_u *line) +{ + vim_snprintf((char *)IObuff, IOSIZE, _("%sviminfo: %s in line: "), + errnum, message); + STRNCAT(IObuff, line, IOSIZE - STRLEN(IObuff) - 1); + if (IObuff[STRLEN(IObuff) - 1] == '\n') + IObuff[STRLEN(IObuff) - 1] = NUL; + emsg((char *)IObuff); + if (++viminfo_errcnt >= 10) + { + emsg(_("E136: viminfo: Too many errors, skipping rest of file")); + return TRUE; + } + return FALSE; +} + +/* + * Compare the 'encoding' value in the viminfo file with the current value of + * 'encoding'. If different and the 'c' flag is in 'viminfo', setup for + * conversion of text with iconv() in viminfo_readstring(). + */ + static int +viminfo_encoding(vir_T *virp) +{ + char_u *p; + int i; + + if (get_viminfo_parameter('c') != 0) + { + p = vim_strchr(virp->vir_line, '='); + if (p != NULL) + { + // remove trailing newline + ++p; + for (i = 0; vim_isprintc(p[i]); ++i) + ; + p[i] = NUL; + + convert_setup(&virp->vir_conv, p, p_enc); + } + } + return viminfo_readline(virp); +} + +#if defined(FEAT_EVAL) || defined(PROTO) +/* + * Restore global vars that start with a capital from the viminfo file + */ + static int +read_viminfo_varlist(vir_T *virp, int writing) +{ + char_u *tab; + int type = VAR_NUMBER; + typval_T tv; + funccal_entry_T funccal_entry; + + if (!writing && (find_viminfo_parameter('!') != NULL)) + { + tab = vim_strchr(virp->vir_line + 1, '\t'); + if (tab != NULL) + { + *tab++ = '\0'; // isolate the variable name + switch (*tab) + { + case 'S': type = VAR_STRING; break; +#ifdef FEAT_FLOAT + case 'F': type = VAR_FLOAT; break; +#endif + case 'D': type = VAR_DICT; break; + case 'L': type = VAR_LIST; break; + case 'B': type = VAR_BLOB; break; + case 'X': type = VAR_SPECIAL; break; + } + + tab = vim_strchr(tab, '\t'); + if (tab != NULL) + { + tv.v_type = type; + if (type == VAR_STRING || type == VAR_DICT + || type == VAR_LIST || type == VAR_BLOB) + tv.vval.v_string = viminfo_readstring(virp, + (int)(tab - virp->vir_line + 1), TRUE); +#ifdef FEAT_FLOAT + else if (type == VAR_FLOAT) + (void)string2float(tab + 1, &tv.vval.v_float); +#endif + else + tv.vval.v_number = atol((char *)tab + 1); + if (type == VAR_DICT || type == VAR_LIST) + { + typval_T *etv = eval_expr(tv.vval.v_string, NULL); + + if (etv == NULL) + // Failed to parse back the dict or list, use it as a + // string. + tv.v_type = VAR_STRING; + else + { + vim_free(tv.vval.v_string); + tv = *etv; + vim_free(etv); + } + } + else if (type == VAR_BLOB) + { + blob_T *blob = string2blob(tv.vval.v_string); + + if (blob == NULL) + // Failed to parse back the blob, use it as a string. + tv.v_type = VAR_STRING; + else + { + vim_free(tv.vval.v_string); + tv.v_type = VAR_BLOB; + tv.vval.v_blob = blob; + } + } + + // when in a function use global variables + save_funccal(&funccal_entry); + set_var(virp->vir_line + 1, &tv, FALSE); + restore_funccal(); + + if (tv.v_type == VAR_STRING) + vim_free(tv.vval.v_string); + else if (tv.v_type == VAR_DICT || tv.v_type == VAR_LIST || + tv.v_type == VAR_BLOB) + clear_tv(&tv); + } + } + } + + return viminfo_readline(virp); +} + +/* + * Write global vars that start with a capital to the viminfo file + */ + static void +write_viminfo_varlist(FILE *fp) +{ + hashitem_T *hi; + dictitem_T *this_var; + int todo; + char *s = ""; + char_u *p; + char_u *tofree; + char_u numbuf[NUMBUFLEN]; + + if (find_viminfo_parameter('!') == NULL) + return; + + fputs(_("\n# global variables:\n"), fp); + + todo = (int)globvarht.ht_used; + for (hi = globvarht.ht_array; todo > 0; ++hi) + { + if (!HASHITEM_EMPTY(hi)) + { + --todo; + this_var = HI2DI(hi); + if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) + { + switch (this_var->di_tv.v_type) + { + case VAR_STRING: s = "STR"; break; + case VAR_NUMBER: s = "NUM"; break; + case VAR_FLOAT: s = "FLO"; break; + case VAR_DICT: s = "DIC"; break; + case VAR_LIST: s = "LIS"; break; + case VAR_BLOB: s = "BLO"; break; + case VAR_SPECIAL: s = "XPL"; break; + + case VAR_UNKNOWN: + case VAR_FUNC: + case VAR_PARTIAL: + case VAR_JOB: + case VAR_CHANNEL: + continue; + } + fprintf(fp, "!%s\t%s\t", this_var->di_key, s); + if (this_var->di_tv.v_type == VAR_SPECIAL) + { + sprintf((char *)numbuf, "%ld", + (long)this_var->di_tv.vval.v_number); + p = numbuf; + tofree = NULL; + } + else + p = echo_string(&this_var->di_tv, &tofree, numbuf, 0); + if (p != NULL) + viminfo_writestring(fp, p); + vim_free(tofree); + } + } + } +} +#endif // FEAT_EVAL + +/* + * read_viminfo_up_to_marks() -- Only called from do_viminfo(). Reads in the + * first part of the viminfo file which contains everything but the marks that + * are local to a file. Returns TRUE when end-of-file is reached. -- webb + */ + static int +read_viminfo_up_to_marks( + vir_T *virp, + int forceit, + int writing) +{ + int eof; + buf_T *buf; + int got_encoding = FALSE; + +#ifdef FEAT_CMDHIST + prepare_viminfo_history(forceit ? 9999 : 0, writing); +#endif + + eof = viminfo_readline(virp); + while (!eof && virp->vir_line[0] != '>') + { + switch (virp->vir_line[0]) + { + // Characters reserved for future expansion, ignored now + case '+': // "+40 /path/dir file", for running vim without args + case '^': // to be defined + case '<': // long line - ignored + // A comment or empty line. + case NUL: + case '\r': + case '\n': + case '#': + eof = viminfo_readline(virp); + break; + case '|': + eof = read_viminfo_barline(virp, got_encoding, + forceit, writing); + break; + case '*': // "*encoding=value" + got_encoding = TRUE; + eof = viminfo_encoding(virp); + break; + case '!': // global variable +#ifdef FEAT_EVAL + eof = read_viminfo_varlist(virp, writing); +#else + eof = viminfo_readline(virp); +#endif + break; + case '%': // entry for buffer list + eof = read_viminfo_bufferlist(virp, writing); + break; + case '"': + // When registers are in bar lines skip the old style register + // lines. + if (virp->vir_version < VIMINFO_VERSION_WITH_REGISTERS) + eof = read_viminfo_register(virp, forceit); + else + do { + eof = viminfo_readline(virp); + } while (!eof && (virp->vir_line[0] == TAB + || virp->vir_line[0] == '<')); + break; + case '/': // Search string + case '&': // Substitute search string + case '~': // Last search string, followed by '/' or '&' + eof = read_viminfo_search_pattern(virp, forceit); + break; + case '$': + eof = read_viminfo_sub_string(virp, forceit); + break; + case ':': + case '?': + case '=': + case '@': +#ifdef FEAT_CMDHIST + // When history is in bar lines skip the old style history + // lines. + if (virp->vir_version < VIMINFO_VERSION_WITH_HISTORY) + eof = read_viminfo_history(virp, writing); + else +#endif + eof = viminfo_readline(virp); + break; + case '-': + case '\'': + // When file marks are in bar lines skip the old style lines. + if (virp->vir_version < VIMINFO_VERSION_WITH_MARKS) + eof = read_viminfo_filemark(virp, forceit); + else + eof = viminfo_readline(virp); + break; + default: + if (viminfo_error("E575: ", _("Illegal starting char"), + virp->vir_line)) + eof = TRUE; + else + eof = viminfo_readline(virp); + break; + } + } + +#ifdef FEAT_CMDHIST + // Finish reading history items. + if (!writing) + finish_viminfo_history(virp); +#endif + + // Change file names to buffer numbers for fmarks. + FOR_ALL_BUFFERS(buf) + fmarks_check_names(buf); + + return eof; +} + +/* + * do_viminfo() -- Should only be called from read_viminfo() & write_viminfo(). + */ + static void +do_viminfo(FILE *fp_in, FILE *fp_out, int flags) +{ + int eof = FALSE; + vir_T vir; + int merge = FALSE; + int do_copy_marks = FALSE; + garray_T buflist; + + if ((vir.vir_line = alloc(LSIZE)) == NULL) + return; + vir.vir_fd = fp_in; + vir.vir_conv.vc_type = CONV_NONE; + ga_init2(&vir.vir_barlines, (int)sizeof(char_u *), 100); + vir.vir_version = -1; + + if (fp_in != NULL) + { + if (flags & VIF_WANT_INFO) + { + if (fp_out != NULL) + { + // Registers and marks are read and kept separate from what + // this Vim is using. They are merged when writing. + prepare_viminfo_registers(); + prepare_viminfo_marks(); + } + + eof = read_viminfo_up_to_marks(&vir, + flags & VIF_FORCEIT, fp_out != NULL); + merge = TRUE; + } + else if (flags != 0) + // Skip info, find start of marks + while (!(eof = viminfo_readline(&vir)) + && vir.vir_line[0] != '>') + ; + + do_copy_marks = (flags & + (VIF_WANT_MARKS | VIF_GET_OLDFILES | VIF_FORCEIT)); + } + + if (fp_out != NULL) + { + // Write the info: + fprintf(fp_out, _("# This viminfo file was generated by Vim %s.\n"), + VIM_VERSION_MEDIUM); + fputs(_("# You may edit it if you're careful!\n\n"), fp_out); + write_viminfo_version(fp_out); + fputs(_("# Value of 'encoding' when this file was written\n"), fp_out); + fprintf(fp_out, "*encoding=%s\n\n", p_enc); + write_viminfo_search_pattern(fp_out); + write_viminfo_sub_string(fp_out); +#ifdef FEAT_CMDHIST + write_viminfo_history(fp_out, merge); +#endif + write_viminfo_registers(fp_out); + finish_viminfo_registers(); +#ifdef FEAT_EVAL + write_viminfo_varlist(fp_out); +#endif + write_viminfo_filemarks(fp_out); + finish_viminfo_marks(); + write_viminfo_bufferlist(fp_out); + write_viminfo_barlines(&vir, fp_out); + + if (do_copy_marks) + ga_init2(&buflist, sizeof(buf_T *), 50); + write_viminfo_marks(fp_out, do_copy_marks ? &buflist : NULL); + } + + if (do_copy_marks) + { + copy_viminfo_marks(&vir, fp_out, &buflist, eof, flags); + if (fp_out != NULL) + ga_clear(&buflist); + } + + vim_free(vir.vir_line); + if (vir.vir_conv.vc_type != CONV_NONE) + convert_setup(&vir.vir_conv, NULL, NULL); + ga_clear_strings(&vir.vir_barlines); +} + +/* + * read_viminfo() -- Read the viminfo file. Registers etc. which are already + * set are not over-written unless "flags" includes VIF_FORCEIT. -- webb + */ + int +read_viminfo( + char_u *file, // file name or NULL to use default name + int flags) // VIF_WANT_INFO et al. +{ + FILE *fp; + char_u *fname; + + if (no_viminfo()) + return FAIL; + + fname = viminfo_filename(file); // get file name in allocated buffer + if (fname == NULL) + return FAIL; + fp = mch_fopen((char *)fname, READBIN); + + if (p_verbose > 0) + { + verbose_enter(); + smsg(_("Reading viminfo file \"%s\"%s%s%s"), + fname, + (flags & VIF_WANT_INFO) ? _(" info") : "", + (flags & VIF_WANT_MARKS) ? _(" marks") : "", + (flags & VIF_GET_OLDFILES) ? _(" oldfiles") : "", + fp == NULL ? _(" FAILED") : ""); + verbose_leave(); + } + + vim_free(fname); + if (fp == NULL) + return FAIL; + + viminfo_errcnt = 0; + do_viminfo(fp, NULL, flags); + + fclose(fp); + return OK; +} + +/* + * Write the viminfo file. The old one is read in first so that effectively a + * merge of current info and old info is done. This allows multiple vims to + * run simultaneously, without losing any marks etc. + * If "forceit" is TRUE, then the old file is not read in, and only internal + * info is written to the file. + */ + void +write_viminfo(char_u *file, int forceit) +{ + char_u *fname; + FILE *fp_in = NULL; // input viminfo file, if any + FILE *fp_out = NULL; // output viminfo file + char_u *tempname = NULL; // name of temp viminfo file + stat_T st_new; // mch_stat() of potential new file +#if defined(UNIX) || defined(VMS) + mode_t umask_save; +#endif +#ifdef UNIX + int shortname = FALSE; // use 8.3 file name + stat_T st_old; // mch_stat() of existing viminfo file +#endif +#ifdef MSWIN + int hidden = FALSE; +#endif + + if (no_viminfo()) + return; + + fname = viminfo_filename(file); // may set to default if NULL + if (fname == NULL) + return; + + fp_in = mch_fopen((char *)fname, READBIN); + if (fp_in == NULL) + { + int fd; + + // if it does exist, but we can't read it, don't try writing + if (mch_stat((char *)fname, &st_new) == 0) + goto end; + + // Create the new .viminfo non-accessible for others, because it may + // contain text from non-accessible documents. It is up to the user to + // widen access (e.g. to a group). This may also fail if there is a + // race condition, then just give up. + fd = mch_open((char *)fname, + O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW, 0600); + if (fd < 0) + goto end; + fp_out = fdopen(fd, WRITEBIN); + } + else + { + /* + * There is an existing viminfo file. Create a temporary file to + * write the new viminfo into, in the same directory as the + * existing viminfo file, which will be renamed once all writing is + * successful. + */ +#ifdef UNIX + /* + * For Unix we check the owner of the file. It's not very nice to + * overwrite a user's viminfo file after a "su root", with a + * viminfo file that the user can't read. + */ + st_old.st_dev = (dev_t)0; + st_old.st_ino = 0; + st_old.st_mode = 0600; + if (mch_stat((char *)fname, &st_old) == 0 + && getuid() != ROOT_UID + && !(st_old.st_uid == getuid() + ? (st_old.st_mode & 0200) + : (st_old.st_gid == getgid() + ? (st_old.st_mode & 0020) + : (st_old.st_mode & 0002)))) + { + int tt = msg_didany; + + // avoid a wait_return for this message, it's annoying + semsg(_("E137: Viminfo file is not writable: %s"), fname); + msg_didany = tt; + fclose(fp_in); + goto end; + } +#endif +#ifdef MSWIN + // Get the file attributes of the existing viminfo file. + hidden = mch_ishidden(fname); +#endif + + /* + * Make tempname, find one that does not exist yet. + * Beware of a race condition: If someone logs out and all Vim + * instances exit at the same time a temp file might be created between + * stat() and open(). Use mch_open() with O_EXCL to avoid that. + * May try twice: Once normal and once with shortname set, just in + * case somebody puts his viminfo file in an 8.3 filesystem. + */ + for (;;) + { + int next_char = 'z'; + char_u *wp; + + tempname = buf_modname( +#ifdef UNIX + shortname, +#else + FALSE, +#endif + fname, +#ifdef VMS + (char_u *)"-tmp", +#else + (char_u *)".tmp", +#endif + FALSE); + if (tempname == NULL) // out of memory + break; + + /* + * Try a series of names. Change one character, just before + * the extension. This should also work for an 8.3 + * file name, when after adding the extension it still is + * the same file as the original. + */ + wp = tempname + STRLEN(tempname) - 5; + if (wp < gettail(tempname)) // empty file name? + wp = gettail(tempname); + for (;;) + { + /* + * Check if tempfile already exists. Never overwrite an + * existing file! + */ + if (mch_stat((char *)tempname, &st_new) == 0) + { +#ifdef UNIX + /* + * Check if tempfile is same as original file. May happen + * when modname() gave the same file back. E.g. silly + * link, or file name-length reached. Try again with + * shortname set. + */ + if (!shortname && st_new.st_dev == st_old.st_dev + && st_new.st_ino == st_old.st_ino) + { + VIM_CLEAR(tempname); + shortname = TRUE; + break; + } +#endif + } + else + { + // Try creating the file exclusively. This may fail if + // another Vim tries to do it at the same time. +#ifdef VMS + // fdopen() fails for some reason + umask_save = umask(077); + fp_out = mch_fopen((char *)tempname, WRITEBIN); + (void)umask(umask_save); +#else + int fd; + + // Use mch_open() to be able to use O_NOFOLLOW and set file + // protection: + // Unix: same as original file, but strip s-bit. Reset + // umask to avoid it getting in the way. + // Others: r&w for user only. +# ifdef UNIX + umask_save = umask(0); + fd = mch_open((char *)tempname, + O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW, + (int)((st_old.st_mode & 0777) | 0600)); + (void)umask(umask_save); +# else + fd = mch_open((char *)tempname, + O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW, 0600); +# endif + if (fd < 0) + { + fp_out = NULL; +# ifdef EEXIST + // Avoid trying lots of names while the problem is lack + // of permission, only retry if the file already + // exists. + if (errno != EEXIST) + break; +# endif + } + else + fp_out = fdopen(fd, WRITEBIN); +#endif // VMS + if (fp_out != NULL) + break; + } + + // Assume file exists, try again with another name. + if (next_char == 'a' - 1) + { + // They all exist? Must be something wrong! Don't write + // the viminfo file then. + semsg(_("E929: Too many viminfo temp files, like %s!"), + tempname); + break; + } + *wp = next_char; + --next_char; + } + + if (tempname != NULL) + break; + // continue if shortname was set + } + +#if defined(UNIX) && defined(HAVE_FCHOWN) + if (tempname != NULL && fp_out != NULL) + { + stat_T tmp_st; + + /* + * Make sure the original owner can read/write the tempfile and + * otherwise preserve permissions, making sure the group matches. + */ + if (mch_stat((char *)tempname, &tmp_st) >= 0) + { + if (st_old.st_uid != tmp_st.st_uid) + // Changing the owner might fail, in which case the + // file will now owned by the current user, oh well. + vim_ignored = fchown(fileno(fp_out), st_old.st_uid, -1); + if (st_old.st_gid != tmp_st.st_gid + && fchown(fileno(fp_out), -1, st_old.st_gid) == -1) + // can't set the group to what it should be, remove + // group permissions + (void)mch_setperm(tempname, 0600); + } + else + // can't stat the file, set conservative permissions + (void)mch_setperm(tempname, 0600); + } +#endif + } + + /* + * Check if the new viminfo file can be written to. + */ + if (fp_out == NULL) + { + semsg(_("E138: Can't write viminfo file %s!"), + (fp_in == NULL || tempname == NULL) ? fname : tempname); + if (fp_in != NULL) + fclose(fp_in); + goto end; + } + + if (p_verbose > 0) + { + verbose_enter(); + smsg(_("Writing viminfo file \"%s\""), fname); + verbose_leave(); + } + + viminfo_errcnt = 0; + do_viminfo(fp_in, fp_out, forceit ? 0 : (VIF_WANT_INFO | VIF_WANT_MARKS)); + + if (fclose(fp_out) == EOF) + ++viminfo_errcnt; + + if (fp_in != NULL) + { + fclose(fp_in); + + // In case of an error keep the original viminfo file. Otherwise + // rename the newly written file. Give an error if that fails. + if (viminfo_errcnt == 0) + { + if (vim_rename(tempname, fname) == -1) + { + ++viminfo_errcnt; + semsg(_("E886: Can't rename viminfo file to %s!"), fname); + } +# ifdef MSWIN + // If the viminfo file was hidden then also hide the new file. + else if (hidden) + mch_hide(fname); +# endif + } + if (viminfo_errcnt > 0) + mch_remove(tempname); + } + +end: + vim_free(fname); + vim_free(tempname); +} + +/* + * Read a line from the viminfo file. + * Returns TRUE for end-of-file; + */ + int +viminfo_readline(vir_T *virp) +{ + return vim_fgets(virp->vir_line, LSIZE, virp->vir_fd); +} + +/* + * Check string read from viminfo file. + * Remove '\n' at the end of the line. + * - replace CTRL-V CTRL-V with CTRL-V + * - replace CTRL-V 'n' with '\n' + * + * Check for a long line as written by viminfo_writestring(). + * + * Return the string in allocated memory (NULL when out of memory). + */ + char_u * +viminfo_readstring( + vir_T *virp, + int off, // offset for virp->vir_line + int convert UNUSED) // convert the string +{ + char_u *retval; + char_u *s, *d; + long len; + + if (virp->vir_line[off] == Ctrl_V && vim_isdigit(virp->vir_line[off + 1])) + { + len = atol((char *)virp->vir_line + off + 1); + retval = lalloc(len, TRUE); + if (retval == NULL) + { + // Line too long? File messed up? Skip next line. + (void)vim_fgets(virp->vir_line, 10, virp->vir_fd); + return NULL; + } + (void)vim_fgets(retval, (int)len, virp->vir_fd); + s = retval + 1; // Skip the leading '<' + } + else + { + retval = vim_strsave(virp->vir_line + off); + if (retval == NULL) + return NULL; + s = retval; + } + + // Change CTRL-V CTRL-V to CTRL-V and CTRL-V n to \n in-place. + d = retval; + while (*s != NUL && *s != '\n') + { + if (s[0] == Ctrl_V && s[1] != NUL) + { + if (s[1] == 'n') + *d++ = '\n'; + else + *d++ = Ctrl_V; + s += 2; + } + else + *d++ = *s++; + } + *d = NUL; + + if (convert && virp->vir_conv.vc_type != CONV_NONE && *retval != NUL) + { + d = string_convert(&virp->vir_conv, retval, NULL); + if (d != NULL) + { + vim_free(retval); + retval = d; + } + } + + return retval; +} + +/* + * write string to viminfo file + * - replace CTRL-V with CTRL-V CTRL-V + * - replace '\n' with CTRL-V 'n' + * - add a '\n' at the end + * + * For a long line: + * - write " CTRL-V \n " in first line + * - write " < \n " in second line + */ + void +viminfo_writestring(FILE *fd, char_u *p) +{ + int c; + char_u *s; + int len = 0; + + for (s = p; *s != NUL; ++s) + { + if (*s == Ctrl_V || *s == '\n') + ++len; + ++len; + } + + // If the string will be too long, write its length and put it in the next + // line. Take into account that some room is needed for what comes before + // the string (e.g., variable name). Add something to the length for the + // '<', NL and trailing NUL. + if (len > LSIZE / 2) + fprintf(fd, IF_EB("\026%d\n<", CTRL_V_STR "%d\n<"), len + 3); + + while ((c = *p++) != NUL) + { + if (c == Ctrl_V || c == '\n') + { + putc(Ctrl_V, fd); + if (c == '\n') + c = 'n'; + } + putc(c, fd); + } + putc('\n', fd); +} + +/* + * Write a string in quotes that barline_parse() can read back. + * Breaks the line in less than LSIZE pieces when needed. + * Returns remaining characters in the line. + */ + int +barline_writestring(FILE *fd, char_u *s, int remaining_start) +{ + char_u *p; + int remaining = remaining_start; + int len = 2; + + // Count the number of characters produced, including quotes. + for (p = s; *p != NUL; ++p) + { + if (*p == NL) + len += 2; + else if (*p == '"' || *p == '\\') + len += 2; + else + ++len; + } + if (len > remaining - 2) + { + fprintf(fd, ">%d\n|<", len); + remaining = LSIZE - 20; + } + + putc('"', fd); + for (p = s; *p != NUL; ++p) + { + if (*p == NL) + { + putc('\\', fd); + putc('n', fd); + --remaining; + } + else if (*p == '"' || *p == '\\') + { + putc('\\', fd); + putc(*p, fd); + --remaining; + } + else + putc(*p, fd); + --remaining; + + if (remaining < 3) + { + putc('\n', fd); + putc('|', fd); + putc('<', fd); + // Leave enough space for another continuation. + remaining = LSIZE - 20; + } + } + putc('"', fd); + return remaining - 2; +} + +/* + * ":rviminfo" and ":wviminfo". + */ + void +ex_viminfo( + exarg_T *eap) +{ + char_u *save_viminfo; + + save_viminfo = p_viminfo; + if (*p_viminfo == NUL) + p_viminfo = (char_u *)"'100"; + if (eap->cmdidx == CMD_rviminfo) + { + if (read_viminfo(eap->arg, VIF_WANT_INFO | VIF_WANT_MARKS + | (eap->forceit ? VIF_FORCEIT : 0)) == FAIL) + emsg(_("E195: Cannot open viminfo file for reading")); + } + else + write_viminfo(eap->arg, eap->forceit); + p_viminfo = save_viminfo; +} + +#endif // FEAT_VIMINFO