diff options
-rw-r--r-- | contrib/flake.lock | 43 | ||||
-rw-r--r-- | contrib/flake.nix | 11 | ||||
-rw-r--r-- | runtime/autoload/tar.vim | 277 | ||||
-rw-r--r-- | runtime/doc/eval.txt | 5 | ||||
-rw-r--r-- | runtime/doc/pi_tar.txt | 109 | ||||
-rw-r--r-- | runtime/filetype.vim | 6 | ||||
-rw-r--r-- | runtime/lua/vim/lsp.lua | 34 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/diagnostic.lua | 18 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 2 | ||||
-rw-r--r-- | runtime/plugin/tarPlugin.vim | 6 | ||||
-rw-r--r-- | src/nvim/eval.c | 13 | ||||
-rw-r--r-- | src/nvim/eval.h | 13 | ||||
-rw-r--r-- | src/nvim/ex_cmds.lua | 4 | ||||
-rw-r--r-- | src/nvim/ex_cmds2.c | 66 | ||||
-rw-r--r-- | src/nvim/testdir/test_exit.vim | 29 | ||||
-rw-r--r-- | src/nvim/testdir/test_filetype.vim | 2 | ||||
-rw-r--r-- | test/functional/ex_cmds/source_spec.lua | 47 | ||||
-rw-r--r-- | test/functional/plugin/lsp/diagnostic_spec.lua | 63 | ||||
-rw-r--r-- | test/functional/plugin/lsp_spec.lua | 14 |
19 files changed, 604 insertions, 158 deletions
diff --git a/contrib/flake.lock b/contrib/flake.lock new file mode 100644 index 0000000000..521b7629d9 --- /dev/null +++ b/contrib/flake.lock @@ -0,0 +1,43 @@ +{ + "nodes": { + "flake-utils": { + "locked": { + "lastModified": 1610051610, + "narHash": "sha256-U9rPz/usA1/Aohhk7Cmc2gBrEEKRzcW4nwPWMPwja4Y=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "3982c9903e93927c2164caa727cd3f6a0e6d14cc", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1613226215, + "narHash": "sha256-3rA5cGIrBHD6yeKhNhsF7/t461ww25oJY8KyBb0IhjU=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "ff96a0fa5635770390b184ae74debea75c3fd534", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/contrib/flake.nix b/contrib/flake.nix index d18534215c..08126a48e9 100644 --- a/contrib/flake.nix +++ b/contrib/flake.nix @@ -27,15 +27,20 @@ }); # a development binary to help debug issues - neovim-debug = (neovim.override { - stdenv = if pkgs.stdenv.isLinux then pkgs.llvmPackages_latest.stdenv else pkgs.stdenv; + neovim-debug = let + stdenv = pkgs.stdenvAdapters.keepDebugInfo (if pkgs.stdenv.isLinux then pkgs.llvmPackages_latest.stdenv else pkgs.stdenv); + in + pkgs.enableDebugging ((neovim.override { lua = pkgs.enableDebugging pkgs.luajit; + inherit stdenv; }).overrideAttrs (oa: { cmakeBuildType = "Debug"; cmakeFlags = oa.cmakeFlags ++ [ "-DMIN_LOG_LEVEL=0" ]; - }); + + disallowedReferences = []; + })); # for neovim developers, very slow # brings development tools as well diff --git a/runtime/autoload/tar.vim b/runtime/autoload/tar.vim index dc670dbd14..b6c4c660b8 100644 --- a/runtime/autoload/tar.vim +++ b/runtime/autoload/tar.vim @@ -1,13 +1,13 @@ " tar.vim: Handles browsing tarfiles " AUTOLOAD PORTION -" Date: Apr 17, 2013 -" Version: 29 -" Maintainer: Charles E Campbell <NdrOchip@ScampbellPfamily.AbizM-NOSPAM> -" License: Vim License (see vim's :help license) +" Date: Jan 07, 2020 +" Version: 32 +" Maintainer: Charles E Campbell <NcampObell@SdrPchip.AorgM-NOSPAM> +" License: Vim License (see vim's :help license) " " Contains many ideas from Michael Toren's <tar.vim> " -" Copyright: Copyright (C) 2005-2011 Charles E. Campbell {{{1 +" Copyright: Copyright (C) 2005-2017 Charles E. Campbell {{{1 " Permission is hereby granted to use and distribute this code, " with or without modifications, provided that this copyright " notice is copied with it. Like anything else that's free, @@ -22,7 +22,7 @@ if &cp || exists("g:loaded_tar") finish endif -let g:loaded_tar= "v29" +let g:loaded_tar= "v32" if v:version < 702 echohl WarningMsg echo "***warning*** this version of tar needs vim 7.2" @@ -48,6 +48,9 @@ endif if !exists("g:tar_writeoptions") let g:tar_writeoptions= "uf" endif +if !exists("g:tar_delfile") + let g:tar_delfile="--delete -f" +endif if !exists("g:netrw_cygwin") if has("win32") || has("win95") || has("win64") || has("win16") if &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$' @@ -109,6 +112,7 @@ fun! tar#Browse(tarfile) " sanity checks if !executable(g:tar_cmd) redraw! +" call Decho('***error*** (tar#Browse) "'.g:tar_cmd.'" not available on your system') echohl Error | echo '***error*** (tar#Browse) "'.g:tar_cmd.'" not available on your system' let &report= repkeep " call Dret("tar#Browse") @@ -119,6 +123,7 @@ fun! tar#Browse(tarfile) if a:tarfile !~# '^\a\+://' " if it's an url, don't complain, let url-handlers such as vim do its thing redraw! +" call Decho("***error*** (tar#Browse) File not readable<".a:tarfile.">") echohl Error | echo "***error*** (tar#Browse) File not readable<".a:tarfile.">" | echohl None endif let &report= repkeep @@ -152,12 +157,29 @@ fun! tar#Browse(tarfile) " assuming cygwin let tarfile=substitute(system("cygpath -u ".shellescape(tarfile,0)),'\n$','','e') endif - let curlast= line("$") - if tarfile =~# '\.\(gz\|tgz\)$' - let gzip_command = s:get_gzip_command(tarfile) + + if tarfile =~# '\.\(gz\)$' " call Decho("1: exe silent r! gzip -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - ") - exe "sil! r! " . gzip_command . " -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - " + exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - " + + elseif tarfile =~# '\.\(tgz\)$' || tarfile =~# '\.\(tbz\)$' || tarfile =~# '\.\(txz\)$' || tarfile =~# '\.\(tzs\)$' + if has("unix") && executable("file") + let filekind= system("file ".shellescape(tarfile,1)) =~ "bzip2" + else + let filekind= "" + endif + + if filekind =~ "bzip2" + exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - " + elseif filekind =~ "XZ" + exe "sil! r! xz -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - " + elseif filekind =~ "Zstandard" + exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - " + else + exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - " + endif + elseif tarfile =~# '\.lrp' " call Decho("2: exe silent r! cat -- ".shellescape(tarfile,1)."|gzip -d -c -|".g:tar_cmd." -".g:tar_browseoptions." - ") exe "sil! r! cat -- ".shellescape(tarfile,1)."|gzip -d -c -|".g:tar_cmd." -".g:tar_browseoptions." - " @@ -170,6 +192,8 @@ fun! tar#Browse(tarfile) elseif tarfile =~# '\.\(xz\|txz\)$' " call Decho("3: exe silent r! xz --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - ") exe "sil! r! xz --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - " + elseif tarfile =~# '\.\(zst\|tzs\)$' + exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - " else if tarfile =~ '^\s*-' " A file name starting with a dash is taken as an option. Prepend ./ to avoid that. @@ -184,7 +208,7 @@ fun! tar#Browse(tarfile) " call Dret("tar#Browse : a:tarfile<".a:tarfile.">") return endif - if line("$") == curlast || ( line("$") == (curlast + 1) && getline("$") =~ '\c\%(warning\|error\|inappropriate\|unrecognized\)') + if line("$") == curlast || ( line("$") == (curlast + 1) && getline("$") =~# '\c\%(warning\|error\|inappropriate\|unrecognized\)') redraw! echohl WarningMsg | echo "***warning*** (tar#Browse) ".a:tarfile." doesn't appear to be a tar file" | echohl None keepj sil! %d @@ -197,8 +221,13 @@ fun! tar#Browse(tarfile) return endif + " set up maps supported for tar setlocal noma nomod ro - noremap <silent> <buffer> <cr> :call <SID>TarBrowseSelect()<cr> + noremap <silent> <buffer> <cr> :call <SID>TarBrowseSelect()<cr> + noremap <silent> <buffer> x :call tar#Extract()<cr> + if &mouse != "" + noremap <silent> <buffer> <leftmouse> <leftmouse>:call <SID>TarBrowseSelect()<cr> + endif let &report= repkeep " call Dret("tar#Browse : b:tarfile<".b:tarfile.">") @@ -235,7 +264,8 @@ fun! s:TarBrowseSelect() let tarfile=substitute(system("cygpath -u ".shellescape(tarfile,0)),'\n$','','e') endif - new + " open a new window (tar#Read will read a file into it) + noswapfile new if !exists("g:tar_nomax") || g:tar_nomax == 0 wincmd _ endif @@ -267,7 +297,7 @@ fun! tar#Read(fname,mode) if fname =~ '\.bz2$' && executable("bzcat") let decmp= "|bzcat" let doro = 1 - elseif fname =~ '\.gz$' && executable("zcat") + elseif fname =~ '\.t\=gz$' && executable("zcat") let decmp= "|zcat" let doro = 1 elseif fname =~ '\.lzma$' && executable("lzcat") @@ -276,6 +306,9 @@ fun! tar#Read(fname,mode) elseif fname =~ '\.xz$' && executable("xzcat") let decmp= "|xzcat" let doro = 1 + elseif fname =~ '\.zst$' && executable("zstdcat") + let decmp= "|zstdcat" + let doro = 1 else let decmp="" let doro = 0 @@ -291,20 +324,31 @@ fun! tar#Read(fname,mode) endif if tarfile =~# '\.bz2$' -" call Decho("7: exe silent r! bzip2 -d -c ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp) exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp - elseif tarfile =~# '\.\(gz\|tgz\)$' - let gzip_command = s:get_gzip_command(tarfile) -" call Decho("5: exe silent r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd.' -'.g:tar_readoptions.' - '.tar_secure.shellescape(fname,1)) - exe "sil! r! " . gzip_command . " -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp + elseif tarfile =~# '\.\(gz\)$' + exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp + + elseif tarfile =~# '\(\.tgz\|\.tbz\|\.txz\)' + if has("unix") && executable("file") + let filekind= system("file ".shellescape(tarfile,1)) + else + let filekind= "" + endif + if filekind =~ "bzip2" + exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp + elseif filekind =~ "XZ" + exe "sil! r! xz -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp + elseif filekind =~ "Zstandard" + exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp + else + exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp + endif + elseif tarfile =~# '\.lrp$' -" call Decho("6: exe silent r! cat ".shellescape(tarfile,1)." | gzip -d -c - | ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp) exe "sil! r! cat -- ".shellescape(tarfile,1)." | gzip -d -c - | ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp elseif tarfile =~# '\.lzma$' -" call Decho("7: exe silent r! lzma -d -c ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp) exe "sil! r! lzma -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp elseif tarfile =~# '\.\(xz\|txz\)$' -" call Decho("3: exe silent r! xz --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp) exe "sil! r! xz --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp else if tarfile =~ '^\s*-' @@ -348,13 +392,14 @@ fun! tar#Write(fname) " sanity checks if !executable(g:tar_cmd) redraw! - echohl Error | echo '***error*** (tar#Browse) "'.g:tar_cmd.'" not available on your system' +" call Decho('***error*** (tar#Browse) "'.g:tar_cmd.'" not available on your system') let &report= repkeep " call Dret("tar#Write") return endif if !exists("*mkdir") redraw! +" call Decho("***error*** (tar#Write) sorry, mkdir() doesn't work on your system") echohl Error | echo "***error*** (tar#Write) sorry, mkdir() doesn't work on your system" | echohl None let &report= repkeep " call Dret("tar#Write") @@ -375,6 +420,7 @@ fun! tar#Write(fname) exe "cd ".fnameescape(tmpdir) catch /^Vim\%((\a\+)\)\=:E344/ redraw! +" call Decho("***error*** (tar#Write) cannot cd to temporary directory") echohl Error | echo "***error*** (tar#Write) cannot cd to temporary directory" | Echohl None let &report= repkeep " call Dret("tar#Write") @@ -393,8 +439,6 @@ fun! tar#Write(fname) let tarfile = substitute(b:tarfile,'tarfile:\(.\{-}\)::.*$','\1','') let fname = substitute(b:tarfile,'tarfile:.\{-}::\(.*\)$','\1','') - let gzip_command = s:get_gzip_command(tarfile) - " handle compressed archives if tarfile =~# '\.bz2' call system("bzip2 -d -- ".shellescape(tarfile,0)) @@ -402,12 +446,12 @@ fun! tar#Write(fname) let compress= "bzip2 -- ".shellescape(tarfile,0) " call Decho("compress<".compress.">") elseif tarfile =~# '\.gz' - call system(gzip_command . " -d -- ".shellescape(tarfile,0)) + call system("gzip -d -- ".shellescape(tarfile,0)) let tarfile = substitute(tarfile,'\.gz','','e') let compress= "gzip -- ".shellescape(tarfile,0) " call Decho("compress<".compress.">") elseif tarfile =~# '\.tgz' - call system(gzip_command . " -d -- ".shellescape(tarfile,0)) + call system("gzip -d -- ".shellescape(tarfile,0)) let tarfile = substitute(tarfile,'\.tgz','.tar','e') let compress= "gzip -- ".shellescape(tarfile,0) let tgz = 1 @@ -417,6 +461,10 @@ fun! tar#Write(fname) let tarfile = substitute(tarfile,'\.xz','','e') let compress= "xz -- ".shellescape(tarfile,0) " call Decho("compress<".compress.">") + elseif tarfile =~# '\.zst' + call system("zstd --decompress -- ".shellescape(tarfile,0)) + let tarfile = substitute(tarfile,'\.zst','','e') + let compress= "zstd -- ".shellescape(tarfile,0) elseif tarfile =~# '\.lzma' call system("lzma -d -- ".shellescape(tarfile,0)) let tarfile = substitute(tarfile,'\.lzma','','e') @@ -427,6 +475,7 @@ fun! tar#Write(fname) if v:shell_error != 0 redraw! +" call Decho("***error*** (tar#Write) sorry, unable to update ".tarfile." with ".fname) echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".tarfile." with ".fname | echohl None else @@ -459,10 +508,11 @@ fun! tar#Write(fname) endif " delete old file from tarfile -" call Decho("system(".g:tar_cmd." --delete -f ".shellescape(tarfile,0)." -- ".shellescape(fname,0).")") - call system(g:tar_cmd." --delete -f ".shellescape(tarfile,0).tar_secure.shellescape(fname,0)) +" call Decho("system(".g:tar_cmd." ".g:tar_delfile." ".shellescape(tarfile,0)." -- ".shellescape(fname,0).")") + call system(g:tar_cmd." ".g:tar_delfile." ".shellescape(tarfile,0).tar_secure.shellescape(fname,0)) if v:shell_error != 0 redraw! +" call Decho("***error*** (tar#Write) sorry, unable to update ".fnameescape(tarfile)." with ".fnameescape(fname)) echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".fnameescape(tarfile)." with ".fnameescape(fname) | echohl None else @@ -471,6 +521,7 @@ fun! tar#Write(fname) call system(g:tar_cmd." -".g:tar_writeoptions." ".shellescape(tarfile,0).tar_secure.shellescape(fname,0)) if v:shell_error != 0 redraw! +" call Decho("***error*** (tar#Write) sorry, unable to update ".fnameescape(tarfile)." with ".fnameescape(fname)) echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".fnameescape(tarfile)." with ".fnameescape(fname) | echohl None elseif exists("compress") " call Decho("call system(".compress.")") @@ -486,11 +537,11 @@ fun! tar#Write(fname) if s:tblfile_{winnr()} =~ '^\a\+://' " call Decho("handle writing <".tarfile."> across network to <".s:tblfile_{winnr()}.">") let tblfile= s:tblfile_{winnr()} - 1split|enew + 1split|noswapfile enew let binkeep= &l:binary let eikeep = &ei set binary ei=all - exe "e! ".fnameescape(tarfile) + exe "noswapfile e! ".fnameescape(tarfile) call netrw#NetWrite(tblfile) let &ei = eikeep let &l:binary = binkeep @@ -524,7 +575,7 @@ fun! tar#Diff(userfname,fname) " sets up b:tardiff_otherbuf variables so each buffer knows about the other (for closing purposes) diffthis wincmd v - exe "e ".fnameescape(fname) + exe "noswapfile e ".fnameescape(fname) diffthis else redraw! @@ -534,6 +585,141 @@ fun! tar#Diff(userfname,fname) endfun " --------------------------------------------------------------------- +" tar#Extract: extract a file from a (possibly compressed) tar archive {{{2 +fun! tar#Extract() +" call Dfunc("tar#Extract()") + + let repkeep= &report + set report=10 + let fname= getline(".") +" call Decho("fname<".fname.">") + + if !exists("g:tar_secure") && fname =~ '^\s*-\|\s\+-' + redraw! + echohl WarningMsg | echo '***warning*** (tar#BrowseSelect) rejecting tarfile member<'.fname.'> because of embedded "-"' +" call Dret('tar#BrowseSelect : rejecting tarfile member<'.fname.'> because of embedded "-"') + return + endif + + " sanity check + if fname =~ '^"' + let &report= repkeep +" call Dret("TarBrowseSelect") + return + endif + + let tarball = expand("%") +" call Decho("tarball<".tarball.">") + let tarbase = substitute(tarball,'\..*$','','') +" call Decho("tarbase<".tarbase.">") + + let extractcmd= netrw#WinPath(g:tar_extractcmd) + if filereadable(tarbase.".tar") +" call Decho("system(".extractcmd." ".shellescape(tarbase).".tar ".shellescape(fname).")") + call system(extractcmd." ".shellescape(tarbase).".tar ".shellescape(fname)) + if v:shell_error != 0 + echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar ".fname.": failed!" | echohl NONE +" call Decho("***error*** ".extractcmd." ".tarbase.".tar ".fname.": failed!") + else + echo "***note*** successfully extracted ".fname + endif + + elseif filereadable(tarbase.".tgz") + let extractcmd= substitute(extractcmd,"-","-z","") +" call Decho("system(".extractcmd." ".shellescape(tarbase).".tgz ".shellescape(fname).")") + call system(extractcmd." ".shellescape(tarbase).".tgz ".shellescape(fname)) + if v:shell_error != 0 + echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tgz ".fname.": failed!" | echohl NONE +" call Decho("***error*** ".extractcmd."t ".tarbase.".tgz ".fname.": failed!") + else + echo "***note*** successfully extracted ".fname + endif + + elseif filereadable(tarbase.".tar.gz") + let extractcmd= substitute(extractcmd,"-","-z","") +" call Decho("system(".extractcmd." ".shellescape(tarbase).".tar.gz ".shellescape(fname).")") + call system(extractcmd." ".shellescape(tarbase).".tar.gz ".shellescape(fname)) + if v:shell_error != 0 + echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.gz ".fname.": failed!" | echohl NONE +" call Decho("***error*** ".extractcmd." ".tarbase.".tar.gz ".fname.": failed!") + else + echo "***note*** successfully extracted ".fname + endif + + elseif filereadable(tarbase.".tbz") + let extractcmd= substitute(extractcmd,"-","-j","") +" call Decho("system(".extractcmd." ".shellescape(tarbase).".tbz ".shellescape(fname).")") + call system(extractcmd." ".shellescape(tarbase).".tbz ".shellescape(fname)) + if v:shell_error != 0 + echohl Error | echo "***error*** ".extractcmd."j ".tarbase.".tbz ".fname.": failed!" | echohl NONE +" call Decho("***error*** ".extractcmd."j ".tarbase.".tbz ".fname.": failed!") + else + echo "***note*** successfully extracted ".fname + endif + + elseif filereadable(tarbase.".tar.bz2") + let extractcmd= substitute(extractcmd,"-","-j","") +" call Decho("system(".extractcmd." ".shellescape(tarbase).".tar.bz2 ".shellescape(fname).")") + call system(extractcmd." ".shellescape(tarbase).".tar.bz2 ".shellescape(fname)) + if v:shell_error != 0 + echohl Error | echo "***error*** ".extractcmd."j ".tarbase.".tar.bz2 ".fname.": failed!" | echohl NONE +" call Decho("***error*** ".extractcmd."j ".tarbase.".tar.bz2 ".fname.": failed!") + else + echo "***note*** successfully extracted ".fname + endif + + elseif filereadable(tarbase.".txz") + let extractcmd= substitute(extractcmd,"-","-J","") +" call Decho("system(".extractcmd." ".shellescape(tarbase).".txz ".shellescape(fname).")") + call system(extractcmd." ".shellescape(tarbase).".txz ".shellescape(fname)) + if v:shell_error != 0 + echohl Error | echo "***error*** ".extractcmd." ".tarbase.".txz ".fname.": failed!" | echohl NONE +" call Decho("***error*** ".extractcmd." ".tarbase.".txz ".fname.": failed!") + else + echo "***note*** successfully extracted ".fname + endif + + elseif filereadable(tarbase.".tar.xz") + let extractcmd= substitute(extractcmd,"-","-J","") +" call Decho("system(".extractcmd." ".shellescape(tarbase).".tar.xz ".shellescape(fname).")") + call system(extractcmd." ".shellescape(tarbase).".tar.xz ".shellescape(fname)) + if v:shell_error != 0 + echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.xz ".fname.": failed!" | echohl NONE +" call Decho("***error*** ".extractcmd." ".tarbase.".tar.xz ".fname.": failed!") + else + echo "***note*** successfully extracted ".fname + endif + + elseif filereadable(tarbase.".tzs") + let extractcmd= substitute(extractcmd,"-","--zstd","") +" call Decho("system(".extractcmd." ".shellescape(tarbase).".tzs ".shellescape(fname).")") + call system(extractcmd." ".shellescape(tarbase).".txz ".shellescape(fname)) + if v:shell_error != 0 + echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tzs ".fname.": failed!" | echohl NONE +" call Decho("***error*** ".extractcmd." ".tarbase.".tzs ".fname.": failed!") + else + echo "***note*** successfully extracted ".fname + endif + + elseif filereadable(tarbase.".tar.zst") + let extractcmd= substitute(extractcmd,"-","--zstd","") +" call Decho("system(".extractcmd." ".shellescape(tarbase).".tar.zst ".shellescape(fname).")") + call system(extractcmd." ".shellescape(tarbase).".tar.xz ".shellescape(fname)) + if v:shell_error != 0 + echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.zst ".fname.": failed!" | echohl NONE +" call Decho("***error*** ".extractcmd." ".tarbase.".tar.zst ".fname.": failed!") + else + echo "***note*** successfully extracted ".fname + endif + endif + + " restore option + let &report= repkeep + +" call Dret("tar#Extract") +endfun + +" --------------------------------------------------------------------- " s:Rmdir: {{{2 fun! s:Rmdir(fname) " call Dfunc("Rmdir(fname<".a:fname.">)") @@ -587,10 +773,7 @@ fun! tar#Vimuntar(...) " if necessary, decompress the tarball; then, extract it if tartail =~ '\.tgz' - let gzip_command = s:get_gzip_command(tarfile) - if executable(gzip_command) - silent exe "!" . gzip_command . " -d ".shellescape(tartail) - elseif executable("gunzip") + if executable("gunzip") silent exe "!gunzip ".shellescape(tartail) elseif executable("gzip") silent exe "!gzip -d ".shellescape(tartail) @@ -628,28 +811,6 @@ fun! tar#Vimuntar(...) " call Dret("tar#Vimuntar") endfun -func s:get_gzip_command(file) - " Try using the "file" command to get the actual compression type, since - " there is no standard way for the naming: ".tgz", ".tbz", ".txz", etc. - " If the "file" command doesn't work fall back to just using the file name. - if a:file =~# 'z$' - let filetype = system('file ' . a:file) - if filetype =~ 'bzip2 compressed' && executable('bzip2') - return 'bzip2' - endif - if filetype =~ 'XZ compressed' && executable('xz') - return 'xz' - endif - endif - if a:file =~# 'bz2$' - return 'bzip2' - endif - if a:file =~# 'xz$' - return 'xz' - endif - return 'gzip' -endfunc - " ===================================================================== " Modelines And Restoration: {{{1 let &cpo= s:keepcpo diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index b96fc4ac01..84af7e4f32 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1541,7 +1541,10 @@ v:dying Normally zero. When a deadly signal is caught it's set to VimLeave autocommands will not be executed. *v:exiting* *exiting-variable* -v:exiting Exit code, or |v:null| if not exiting. |VimLeave| +v:exiting Exit code, or |v:null| before invoking the |VimLeavePre| + and |VimLeave| autocmds. See |:q|, |:x| and |:cquit|. + Example: > + :au VimLeave * echo "Exit value is " .. v:exiting *v:echospace* *echospace-variable* v:echospace Number of screen cells that can be used for an `:echo` message diff --git a/runtime/doc/pi_tar.txt b/runtime/doc/pi_tar.txt index 59b318b7fd..c6c0596ea0 100644 --- a/runtime/doc/pi_tar.txt +++ b/runtime/doc/pi_tar.txt @@ -1,12 +1,12 @@ -*pi_tar.txt* Nvim +*pi_tar.txt* For Vim version 8.2. Last change: 2020 Jan 07 +====================+ | Tar File Interface | +====================+ -Author: Charles E. Campbell <NdrOchip@ScampbellPfamily.AbizM> +Author: Charles E. Campbell <NcampObell@SdrPchip.AorgM-NOSPAM> (remove NOSPAM from Campbell's email first) -Copyright 2005-2012: *tar-copyright* +Copyright 2005-2017: *tar-copyright* The VIM LICENSE (see |copyright|) applies to the files in this package, including tarPlugin.vim, tar.vim, and pi_tar.txt. Like anything else that's except use "tar.vim" instead of "VIM". Like @@ -104,48 +104,67 @@ Copyright 2005-2012: *tar-copyright* ============================================================================== 4. History *tar-history* - - v28 Jun 23, 2011 * a few more decompression options (tbz tb2 txz) - v27 May 31, 2011 * moved cygwin detection before g:tar_copycmd handling - * inserted additional |:keepj| modifiers - * changed silent to sil! (|:silent|) - v26 Aug 09, 2010 * uses buffer-local instead of window variables to hold - tarfile name - * inserted keepj before 0d to protect jump list - v25 Jun 19, 2010 * (Jan Steffens) added support for xz compression - v24 Apr 07, 2009 * :Untarvim command implemented - Sep 28, 2009 * Added lzma support - v22 Aug 08, 2008 * security fixes - v16 Jun 06, 2008 * tarfile:: used instead of tarfile: when editing files - inside tarballs. Fixes a problem with tarballs called - things like c:\abc.tar. (tnx to Bill McCarthy) - v14 May 09, 2008 * arno caught a security bug - May 28, 2008 * various security improvements. Now requires patch 299 - which provides the fnameescape() function - May 30, 2008 * allows one to view *.gz and *.bz2 files that are in - *.tar files. - v12 Sep 07, 2007 * &shq now used if not the empty string for g:tar_shq - v10 May 02, 2006 * now using "redraw then echo" to show messages, instead - of "echo and prompt user" - v9 May 02, 2006 * improved detection of masquerading as tar file - v8 May 02, 2006 * allows editing of files that merely masquerade as tar - files - v7 Mar 22, 2006 * work on making tar plugin work across network - Mar 27, 2006 * g:tar_cmd now available for users to change the name - of the tar program to be used. By default, of course, - it's "tar". - v6 Dec 21, 2005 * writing to files not in directories caused problems - - fixed (pointed out by Christian Robinson) - v5 Nov 22, 2005 * report option workaround installed - v3 Sep 16, 2005 * handles writing files in an archive back to the - archive - Oct 18, 2005 * <amatch> used instead of <afile> in autocmds - Oct 18, 2005 * handles writing to compressed archives - Nov 03, 2005 * handles writing tarfiles across a network using - netrw#NetWrite() - v2 * converted to use Vim7's new autoload feature by - Bram Moolenaar - v1 (original) * Michael Toren (see http://michael.toren.net/code/) + v31 Apr 02, 2017 * (klartext) reported that browsing encrypted + files in a zip archive created unencrypted + swap files. I am applying a similar fix + used on zip.vim to tar.vim: new buffers + are opened with |:noswapfile|. + May 16, 2017 * When the mouse option isn't empty, the + leftmouse can be used to select a file + in the tar-file listing. + v30 Apr 22, 2014 * .tgz files are ambiguous: they may have been + compressed with either gzip or bzip2. Tar.vim + disambiguates by using unix's "file" command. + Feb 18, 2016 * Changed =~ to =~# where appropriate + Feb 18, 2017 * Now also permits xz decompression + v28 Jun 23, 2011 * a few more decompression options (tbz tb2 txz) + v27 May 31, 2011 * moved cygwin detection before g:tar_copycmd + handling + * inserted additional |:keepj| modifiers + * changed silent to sil! (|:silent|) + v26 Aug 09, 2010 * uses buffer-local instead of window variables + to hold tarfile name + * inserted keepj before 0d to protect jump list + v25 Jun 19, 2010 * (Jan Steffens) added support for xz + compression + v24 Apr 07, 2009 * :Untarvim command implemented + Sep 28, 2009 * Added lzma support + v22 Aug 08, 2008 * security fixes + v16 Jun 06, 2008 * tarfile:: used instead of tarfile: when + editing files inside tarballs. Fixes a + problem with tarballs called things like + c:\abc.tar. (tnx to Bill McCarthy) + v14 May 09, 2008 * arno caught a security bug + May 28, 2008 * various security improvements. Now requires + patch 299 which provides the fnameescape() + function + May 30, 2008 * allows one to view *.gz and *.bz2 files that + are in *.tar files. + v12 Sep 07, 2007 * &shq now used if not the empty string for + g:tar_shq + v10 May 02, 2006 * now using "redraw then echo" to show messages, + instead of "echo and prompt user" + v9 May 02, 2006 * improved detection of masquerading as tar file + v8 May 02, 2006 * allows editing of files that merely masquerade + as tar files + v7 Mar 22, 2006 * work on making tar plugin work across network + Mar 27, 2006 * g:tar_cmd now available for users to change + the name of the tar program to be used. By + default, of course, it's "tar". + v6 Dec 21, 2005 * writing to files not in directories caused + problems - fixed (pointed out by + Christian Robinson) + v5 Nov 22, 2005 * report option workaround installed + v3 Sep 16, 2005 * handles writing files in an archive back to + the archive + Oct 18, 2005 * <amatch> used instead of <afile> in autocmds + Oct 18, 2005 * handles writing to compressed archives + Nov 03, 2005 * handles writing tarfiles across a network + using netrw#NetWrite() + v2 * converted to use Vim7's new autoload feature + by Bram Moolenaar + v1 (original) * Michael Toren + (see http://michael.toren.net/code/) ============================================================================== vim:tw=78:ts=8:noet:ft=help diff --git a/runtime/filetype.vim b/runtime/filetype.vim index 53fd66c4df..6a13e67ac5 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -212,6 +212,9 @@ au BufNewFile,BufRead *.bc setf bc " BDF font au BufNewFile,BufRead *.bdf setf bdf +" Beancount +au BufNewFile,BufRead *.beancount setf beancount + " BibTeX bibliography database file au BufNewFile,BufRead *.bib setf bib @@ -1491,6 +1494,9 @@ au BufNewFile,BufRead *.sdl,*.pr setf sdl " sed au BufNewFile,BufRead *.sed setf sed +" svelte +au BufNewFile,BufRead *.svelte setf svelte + " Sieve (RFC 3028, 5228) au BufNewFile,BufRead *.siv,*.sieve setf sieve diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index a6f118abde..0c8d0bdc95 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -548,19 +548,13 @@ function lsp.start_client(config) function dispatch.on_exit(code, signal) active_clients[client_id] = nil uninitialized_clients[client_id] = nil - local active_buffers = {} - for bufnr, client_ids in pairs(all_buffer_active_clients) do - if client_ids[client_id] then - table.insert(active_buffers, bufnr) - end + + lsp.diagnostic.reset(client_id, all_buffer_active_clients) + all_client_active_buffers[client_id] = nil + for _, client_ids in pairs(all_buffer_active_clients) do client_ids[client_id] = nil end - -- Buffer level cleanup - vim.schedule(function() - for _, bufnr in ipairs(active_buffers) do - lsp.diagnostic.clear(bufnr) - end - end) + if config.on_exit then pcall(config.on_exit, code, signal, client_id) end @@ -751,6 +745,13 @@ function lsp.start_client(config) --- --@param force (bool, optional) function client.stop(force) + + lsp.diagnostic.reset(client_id, all_buffer_active_clients) + all_client_active_buffers[client_id] = nil + for _, client_ids in pairs(all_buffer_active_clients) do + client_ids[client_id] = nil + end + local handle = rpc.handle if handle:is_closing() then return @@ -1016,23 +1017,12 @@ end function lsp.stop_client(client_id, force) local ids = type(client_id) == 'table' and client_id or {client_id} for _, id in ipairs(ids) do - local resolved_client_id if type(id) == 'table' and id.stop ~= nil then id.stop(force) - resolved_client_id = id.id elseif active_clients[id] then active_clients[id].stop(force) - resolved_client_id = id elseif uninitialized_clients[id] then uninitialized_clients[id].stop(true) - resolved_client_id = id - end - if resolved_client_id then - local client_buffers = lsp.get_buffers_by_client_id(resolved_client_id) - for idx = 1, #client_buffers do - lsp.diagnostic.clear(client_buffers[idx], resolved_client_id) - end - all_client_active_buffers[resolved_client_id] = nil end end end diff --git a/runtime/lua/vim/lsp/diagnostic.lua b/runtime/lua/vim/lsp/diagnostic.lua index a625098bab..df25943ecd 100644 --- a/runtime/lua/vim/lsp/diagnostic.lua +++ b/runtime/lua/vim/lsp/diagnostic.lua @@ -1158,6 +1158,24 @@ local loclist_type_map = { [DiagnosticSeverity.Hint] = 'I', } + +--- Clear diagnotics and diagnostic cache +--- +--- Handles saving diagnostics from multiple clients in the same buffer. +---@param client_id number +---@param buffer_client_map table map of buffers to active clients +function M.reset(client_id, buffer_client_map) + buffer_client_map = vim.deepcopy(buffer_client_map) + vim.schedule(function() + for bufnr, client_ids in pairs(buffer_client_map) do + if client_ids[client_id] then + clear_diagnostic_cache(bufnr, client_id) + M.clear(bufnr, client_id) + end + end + end) +end + --- Sets the location list ---@param opts table|nil Configuration table. Keys: --- - {open_loclist}: (boolean, default true) diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 00bdeecef3..9c5e8ec8c3 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -211,7 +211,7 @@ function M.apply_text_edits(text_edits, bufnr) local lines = api.nvim_buf_get_lines(bufnr, start_line, finish_line + 1, false) local fix_eol = api.nvim_buf_get_option(bufnr, 'fixeol') local set_eol = fix_eol and api.nvim_buf_line_count(bufnr) <= finish_line + 1 - if set_eol and #lines[#lines] ~= 0 then + if set_eol and (#lines == 0 or #lines[#lines] ~= 0) then table.insert(lines, '') end diff --git a/runtime/plugin/tarPlugin.vim b/runtime/plugin/tarPlugin.vim index 6d9e6bd540..d55492a93e 100644 --- a/runtime/plugin/tarPlugin.vim +++ b/runtime/plugin/tarPlugin.vim @@ -14,7 +14,7 @@ if &cp || exists("g:loaded_tarPlugin") finish endif -let g:loaded_tarPlugin = "v29" +let g:loaded_tarPlugin = "v32" let s:keepcpo = &cpo set cpo&vim @@ -39,11 +39,13 @@ augroup tar au BufReadCmd *.lrp call tar#Browse(expand("<amatch>")) au BufReadCmd *.tar.bz2 call tar#Browse(expand("<amatch>")) au BufReadCmd *.tar.Z call tar#Browse(expand("<amatch>")) - au BufReadCmd *.tgz call tar#Browse(expand("<amatch>")) au BufReadCmd *.tbz call tar#Browse(expand("<amatch>")) + au BufReadCmd *.tgz call tar#Browse(expand("<amatch>")) au BufReadCmd *.tar.lzma call tar#Browse(expand("<amatch>")) au BufReadCmd *.tar.xz call tar#Browse(expand("<amatch>")) au BufReadCmd *.txz call tar#Browse(expand("<amatch>")) + au BufReadCmd *.tar.zst call tar#Browse(expand("<amatch>")) + au BufReadCmd *.tzs call tar#Browse(expand("<amatch>")) augroup END com! -nargs=? -complete=file Vimuntar call tar#Vimuntar(<q-args>) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d07618d2c0..6d97310c1c 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -176,7 +176,6 @@ static struct vimvar { VV(VV_DYING, "dying", VAR_NUMBER, VV_RO), VV(VV_EXCEPTION, "exception", VAR_STRING, VV_RO), VV(VV_THROWPOINT, "throwpoint", VAR_STRING, VV_RO), - VV(VV_STDERR, "stderr", VAR_NUMBER, VV_RO), VV(VV_REG, "register", VAR_STRING, VV_RO), VV(VV_CMDBANG, "cmdbang", VAR_NUMBER, VV_RO), VV(VV_INSERTMODE, "insertmode", VAR_STRING, VV_RO), @@ -211,13 +210,9 @@ static struct vimvar { VV(VV_OPTION_OLD, "option_old", VAR_STRING, VV_RO), VV(VV_OPTION_TYPE, "option_type", VAR_STRING, VV_RO), VV(VV_ERRORS, "errors", VAR_LIST, 0), - VV(VV_MSGPACK_TYPES, "msgpack_types", VAR_DICT, VV_RO), - VV(VV_EVENT, "event", VAR_DICT, VV_RO), VV(VV_FALSE, "false", VAR_BOOL, VV_RO), VV(VV_TRUE, "true", VAR_BOOL, VV_RO), VV(VV_NULL, "null", VAR_SPECIAL, VV_RO), - VV(VV__NULL_LIST, "_null_list", VAR_LIST, VV_RO), - VV(VV__NULL_DICT, "_null_dict", VAR_DICT, VV_RO), VV(VV_VIM_DID_ENTER, "vim_did_enter", VAR_NUMBER, VV_RO), VV(VV_TESTING, "testing", VAR_NUMBER, 0), VV(VV_TYPE_NUMBER, "t_number", VAR_NUMBER, VV_RO), @@ -227,10 +222,16 @@ static struct vimvar { VV(VV_TYPE_DICT, "t_dict", VAR_NUMBER, VV_RO), VV(VV_TYPE_FLOAT, "t_float", VAR_NUMBER, VV_RO), VV(VV_TYPE_BOOL, "t_bool", VAR_NUMBER, VV_RO), + VV(VV_EVENT, "event", VAR_DICT, VV_RO), VV(VV_ECHOSPACE, "echospace", VAR_NUMBER, VV_RO), + VV(VV_ARGV, "argv", VAR_LIST, VV_RO), VV(VV_EXITING, "exiting", VAR_NUMBER, VV_RO), + // Neovim + VV(VV_STDERR, "stderr", VAR_NUMBER, VV_RO), + VV(VV_MSGPACK_TYPES, "msgpack_types", VAR_DICT, VV_RO), + VV(VV__NULL_LIST, "_null_list", VAR_LIST, VV_RO), + VV(VV__NULL_DICT, "_null_dict", VAR_DICT, VV_RO), VV(VV_LUA, "lua", VAR_PARTIAL, VV_RO), - VV(VV_ARGV, "argv", VAR_LIST, VV_RO), }; #undef VV diff --git a/src/nvim/eval.h b/src/nvim/eval.h index c1891758ea..4f03d5d259 100644 --- a/src/nvim/eval.h +++ b/src/nvim/eval.h @@ -105,7 +105,6 @@ typedef enum { VV_DYING, VV_EXCEPTION, VV_THROWPOINT, - VV_STDERR, VV_REG, VV_CMDBANG, VV_INSERTMODE, @@ -140,13 +139,9 @@ typedef enum { VV_OPTION_OLD, VV_OPTION_TYPE, VV_ERRORS, - VV_MSGPACK_TYPES, - VV_EVENT, VV_FALSE, VV_TRUE, VV_NULL, - VV__NULL_LIST, // List with NULL value. For test purposes only. - VV__NULL_DICT, // Dictionary with NULL value. For test purposes only. VV_VIM_DID_ENTER, VV_TESTING, VV_TYPE_NUMBER, @@ -156,10 +151,16 @@ typedef enum { VV_TYPE_DICT, VV_TYPE_FLOAT, VV_TYPE_BOOL, + VV_EVENT, VV_ECHOSPACE, + VV_ARGV, VV_EXITING, + // Neovim + VV_STDERR, + VV_MSGPACK_TYPES, + VV__NULL_LIST, // List with NULL value. For test purposes only. + VV__NULL_DICT, // Dictionary with NULL value. For test purposes only. VV_LUA, - VV_ARGV, } VimVarIndex; /// All recognized msgpack types diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua index 10dd7d68ca..2965ea7496 100644 --- a/src/nvim/ex_cmds.lua +++ b/src/nvim/ex_cmds.lua @@ -2521,8 +2521,8 @@ module.cmds = { }, { command='source', - flags=bit.bor(BANG, FILE1, TRLBAR, SBOXOK, CMDWIN), - addr_type='ADDR_NONE', + flags=bit.bor(RANGE, DFLALL, WHOLEFOLD, BANG, FILE1, TRLBAR, SBOXOK, CMDWIN), + addr_type='ADDR_LINES', func='ex_source', }, { diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index bb53f4d373..c24ecde096 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -29,6 +29,7 @@ #include "nvim/getchar.h" #include "nvim/mark.h" #include "nvim/mbyte.h" +#include "nvim/memline.h" #include "nvim/message.h" #include "nvim/misc1.h" #include "nvim/garray.h" @@ -2526,7 +2527,7 @@ void ex_pyxdo(exarg_T *eap) } } -/// ":source {fname}" +/// ":source [{fname}]" void ex_source(exarg_T *eap) { cmd_source(eap->arg, eap); @@ -2535,7 +2536,7 @@ void ex_source(exarg_T *eap) static void cmd_source(char_u *fname, exarg_T *eap) { if (*fname == NUL) { - EMSG(_(e_argreq)); + cmd_source_buffer(eap); } else if (eap != NULL && eap->forceit) { // ":source!": read Normal mode commands // Need to execute the commands directly. This is required at least @@ -2553,6 +2554,37 @@ static void cmd_source(char_u *fname, exarg_T *eap) } } +typedef struct { + linenr_T curr_lnum; + const linenr_T final_lnum; +} GetBufferLineCookie; + +/// Get one line from the current selection in the buffer. +/// Called by do_cmdline() when it's called from cmd_source_buffer(). +/// +/// @return pointer to allocated line, or NULL for end-of-file or +/// some error. +static char_u *get_buffer_line(int c, void *cookie, int indent, bool do_concat) +{ + GetBufferLineCookie *p = cookie; + if (p->curr_lnum > p->final_lnum) { + return NULL; + } + char_u *curr_line = ml_get(p->curr_lnum); + p->curr_lnum++; + return (char_u *)xstrdup((const char *)curr_line); +} + +static void cmd_source_buffer(exarg_T *eap) +{ + GetBufferLineCookie cookie = { + .curr_lnum = eap->line1, + .final_lnum = eap->line2, + }; + source_using_linegetter((void *)&cookie, get_buffer_line, + ":source (no file)"); +} + /// ":source" and associated commands. /// /// @return address holding the next breakpoint line for a source cookie @@ -2624,10 +2656,9 @@ static char_u *get_str_line(int c, void *cookie, int indent, bool do_concat) return (char_u *)xstrdup(buf); } -/// Executes lines in `src` as Ex commands. -/// -/// @see do_source() -int do_source_str(const char *cmd, const char *traceback_name) +static int source_using_linegetter(void *cookie, + LineGetter fgetline, + const char *traceback_name) { char_u *save_sourcing_name = sourcing_name; linenr_T save_sourcing_lnum = sourcing_lnum; @@ -2642,22 +2673,33 @@ int do_source_str(const char *cmd, const char *traceback_name) } sourcing_lnum = 0; - GetStrLineCookie cookie = { - .buf = (char_u *)cmd, - .offset = 0, - }; const sctx_T save_current_sctx = current_sctx; current_sctx.sc_sid = SID_STR; current_sctx.sc_seq = 0; current_sctx.sc_lnum = save_sourcing_lnum; - int retval = do_cmdline(NULL, get_str_line, (void *)&cookie, + funccal_entry_T entry; + save_funccal(&entry); + int retval = do_cmdline(NULL, fgetline, cookie, DOCMD_VERBOSE | DOCMD_NOWAIT | DOCMD_REPEAT); - current_sctx = save_current_sctx; sourcing_lnum = save_sourcing_lnum; sourcing_name = save_sourcing_name; + current_sctx = save_current_sctx; + restore_funccal(); return retval; } +/// Executes lines in `src` as Ex commands. +/// +/// @see do_source() +int do_source_str(const char *cmd, const char *traceback_name) +{ + GetStrLineCookie cookie = { + .buf = (char_u *)cmd, + .offset = 0, + }; + return source_using_linegetter((void *)&cookie, get_str_line, traceback_name); +} + /// Reads the file `fname` and executes its lines as Ex commands. /// /// This function may be called recursively! diff --git a/src/nvim/testdir/test_exit.vim b/src/nvim/testdir/test_exit.vim index 99a401d4a4..bd3e9eb4d4 100644 --- a/src/nvim/testdir/test_exit.vim +++ b/src/nvim/testdir/test_exit.vim @@ -81,3 +81,32 @@ func Test_exiting() endif call delete('Xtestout') endfunc + +" Test for getting the Vim exit code from v:exiting +func Test_exit_code() + call assert_equal(v:null, v:exiting) + + let before =<< trim [CODE] + au QuitPre * call writefile(['qp = ' .. v:exiting], 'Xtestout', 'a') + au ExitPre * call writefile(['ep = ' .. v:exiting], 'Xtestout', 'a') + au VimLeavePre * call writefile(['lp = ' .. v:exiting], 'Xtestout', 'a') + au VimLeave * call writefile(['l = ' .. v:exiting], 'Xtestout', 'a') + [CODE] + + if RunVim(before, ['quit'], '') + call assert_equal(['qp = null', 'ep = null', 'lp = 0', 'l = 0'], readfile('Xtestout')) + endif + call delete('Xtestout') + + if RunVim(before, ['cquit'], '') + call assert_equal(['lp = 1', 'l = 1'], readfile('Xtestout')) + endif + call delete('Xtestout') + + if RunVim(before, ['cquit 4'], '') + call assert_equal(['lp = 4', 'l = 4'], readfile('Xtestout')) + endif + call delete('Xtestout') +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim index f9f0ade1f6..6bc5fba5db 100644 --- a/src/nvim/testdir/test_filetype.vim +++ b/src/nvim/testdir/test_filetype.vim @@ -79,6 +79,7 @@ let s:filename_checks = { \ 'bc': ['file.bc'], \ 'bdf': ['file.bdf'], \ 'bib': ['file.bib'], + \ 'beancount': ['file.beancount'], \ 'bindzone': ['named.root'], \ 'blank': ['file.bl'], \ 'bsdl': ['file.bsd', 'file.bsdl'], @@ -427,6 +428,7 @@ let s:filename_checks = { \ 'slrnrc': ['.slrnrc'], \ 'slrnsc': ['file.score'], \ 'sm': ['sendmail.cf'], + \ 'svelte': ['file.svelte'], \ 'smarty': ['file.tpl'], \ 'smcl': ['file.hlp', 'file.ihlp', 'file.smcl'], \ 'smith': ['file.smt', 'file.smith'], diff --git a/test/functional/ex_cmds/source_spec.lua b/test/functional/ex_cmds/source_spec.lua new file mode 100644 index 0000000000..16d0dfb6a1 --- /dev/null +++ b/test/functional/ex_cmds/source_spec.lua @@ -0,0 +1,47 @@ +local helpers = require('test.functional.helpers')(after_each) +local command = helpers.command +local insert = helpers.insert +local eq = helpers.eq +local clear = helpers.clear +local meths = helpers.meths +local feed = helpers.feed +local feed_command = helpers.feed_command + +describe(':source', function() + before_each(function() + clear() + end) + + it('current buffer', function() + insert('let a = 2') + command('source') + eq('2', meths.exec('echo a', true)) + end) + + it('selection in current buffer', function() + insert( + 'let a = 2\n'.. + 'let a = 3\n'.. + 'let a = 4\n') + + -- Source the 2nd line only + feed('ggjV') + feed_command(':source') + eq('3', meths.exec('echo a', true)) + + -- Source from 2nd line to end of file + feed('ggjVG') + feed_command(':source') + eq('4', meths.exec('echo a', true)) + end) + + it('multiline heredoc command', function() + insert( + 'lua << EOF\n'.. + 'y = 4\n'.. + 'EOF\n') + + command('source') + eq('4', meths.exec('echo luaeval("y")', true)) + end) +end) diff --git a/test/functional/plugin/lsp/diagnostic_spec.lua b/test/functional/plugin/lsp/diagnostic_spec.lua index 4705a76465..8c91c4ab2c 100644 --- a/test/functional/plugin/lsp/diagnostic_spec.lua +++ b/test/functional/plugin/lsp/diagnostic_spec.lua @@ -208,6 +208,69 @@ describe('vim.lsp.diagnostic', function() ]])) end) + describe('reset', function() + it('diagnostic count is 0 and displayed diagnostics are 0 after call', function() + -- 1 Error (1) + -- 1 Warning (2) + -- 1 Warning (2) + 1 Warning (1) + -- 2 highlights and 2 underlines (since error) + -- 1 highlight + 1 underline + local all_highlights = {1, 1, 2, 4, 2} + eq(all_highlights, exec_lua [[ + local server_1_diags = { + make_error("Error 1", 1, 1, 1, 5), + make_warning("Warning on Server 1", 2, 1, 2, 5), + } + local server_2_diags = { + make_warning("Warning 1", 2, 1, 2, 5), + } + + vim.lsp.diagnostic.on_publish_diagnostics(nil, nil, { uri = fake_uri, diagnostics = server_1_diags }, 1) + vim.lsp.diagnostic.on_publish_diagnostics(nil, nil, { uri = fake_uri, diagnostics = server_2_diags }, 2) + return { + vim.lsp.diagnostic.get_count(diagnostic_bufnr, "Error", 1), + vim.lsp.diagnostic.get_count(diagnostic_bufnr, "Warning", 2), + vim.lsp.diagnostic.get_count(diagnostic_bufnr, "Warning", nil), + count_of_extmarks_for_client(diagnostic_bufnr, 1), + count_of_extmarks_for_client(diagnostic_bufnr, 2), + } + ]]) + + -- Reset diagnostics from server 1 + exec_lua([[ vim.lsp.diagnostic.reset(1, { [ diagnostic_bufnr ] = { [ 1 ] = true ; [ 2 ] = true } } )]]) + + -- Make sure we have the right diagnostic count + eq({0, 1, 1, 0, 2} , exec_lua [[ + local diagnostic_count = {} + vim.wait(100, function () diagnostic_count = { + vim.lsp.diagnostic.get_count(diagnostic_bufnr, "Error", 1), + vim.lsp.diagnostic.get_count(diagnostic_bufnr, "Warning", 2), + vim.lsp.diagnostic.get_count(diagnostic_bufnr, "Warning", nil), + count_of_extmarks_for_client(diagnostic_bufnr, 1), + count_of_extmarks_for_client(diagnostic_bufnr, 2), + } end ) + return diagnostic_count + ]]) + + -- Reset diagnostics from server 2 + exec_lua([[ vim.lsp.diagnostic.reset(2, { [ diagnostic_bufnr ] = { [ 1 ] = true ; [ 2 ] = true } } )]]) + + -- Make sure we have the right diagnostic count + eq({0, 0, 0, 0, 0}, exec_lua [[ + local diagnostic_count = {} + vim.wait(100, function () diagnostic_count = { + vim.lsp.diagnostic.get_count(diagnostic_bufnr, "Error", 1), + vim.lsp.diagnostic.get_count(diagnostic_bufnr, "Warning", 2), + vim.lsp.diagnostic.get_count(diagnostic_bufnr, "Warning", nil), + count_of_extmarks_for_client(diagnostic_bufnr, 1), + count_of_extmarks_for_client(diagnostic_bufnr, 2), + } end ) + return diagnostic_count + ]]) + + end) + end) + describe('get_next_diagnostic_pos', function() it('can find the next pos with only one client', function() eq({1, 1}, exec_lua [[ diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 981e2a96a8..cec306eb39 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -1032,6 +1032,20 @@ describe('LSP', function() 'å ä ɧ 汉语 ↥ 🤦 🦄'; }, buf_lines(1)) end) + it('applies text edits at the end of the document', function() + local edits = { + make_edit(5, 0, 5, 0, "foobar"); + } + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1) + eq({ + 'First line of text'; + 'Second line of text'; + 'Third line of text'; + 'Fourth line of text'; + 'å å ɧ 汉语 ↥ 🤦 🦄'; + 'foobar'; + }, buf_lines(1)) + end) describe('with LSP end line after what Vim considers to be the end line', function() it('applies edits when the last linebreak is considered a new line', function() |