diff --git a/.hgignore b/.hgignore index 284a6839f2..f6d954a547 100644 --- a/.hgignore +++ b/.hgignore @@ -38,6 +38,15 @@ src/Obj*/pathdef.c gvimext.dll gvimext.lib +# Borland C++ +bcc.cfg +*.ilc +*.ild +*.ilf +*.ils +*.map +*.tds + # Mac OSX src/xxd/xxd.dSYM diff --git a/.hgtags b/.hgtags index a2667cb2b6..8b0306db8d 100644 --- a/.hgtags +++ b/.hgtags @@ -2826,3 +2826,83 @@ acbe5414cb7f302f548bc1cbdc1ddb029dbf9094 v7-4-095 ec5d11403c1952b2ed192f28afb6261d0867bb20 v7-4-101 9417f4de27a2a6acfa6b1660ac6ef2b5692e4554 v7-4-102 4db151014f93b7512919e452e6b3f4184758db7b v7-4-103 +dd7d1a86b311c11e9c03b7ca95c7b62206bbc7ab v7-4-104 +eed95874f30e9d9dad577f2361f2dfed93c5db4d v7-4-105 +de9a01851ebd1ce1d225b40c182b6f1e105863a7 v7-4-106 +064e2a080e2e158177acc017c318bc953fb7535b v7-4-107 +fa31c5b82424373885d2fa55b4f8531ac21baacd v7-4-108 +1cdf517067743dc33ebb9c7af8844abd9d9c7863 v7-4-109 +6e54d1b3408ca745341b0b219c588c265fa52494 v7-4-110 +3fbda56bb2008e2459951f3ad0258ff0500ba07c v7-4-111 +af8217e4ed7e28b797c628f067ebfd4433c07326 v7-4-112 +0e21e2a38ec6df5c4fe37d639906f56f9f445b96 v7-4-113 +6db758f82227989426560c19fdd234b154b54419 v7-4-114 +e35c69ad482370b2685bf1360a63fb27ce8b3819 v7-4-115 +40aff213baff00d43ea8c1b6a9734ccad63a3921 v7-4-116 +805ad8488dc88a575b841589f36c278aaead4e52 v7-4-117 +62c720661f81c17348636956c1158639d59e1e9f v7-4-118 +2f99966971b0556bc302ec809712f5ba3f030028 v7-4-119 +ca0e43bbf8f9e409130d5d1ce29621edbcdff92a v7-4-120 +4bf53c1ef37a5023e06f3c6b4f1c24857b4f52a6 v7-4-121 +270c62fe685ae943de64e1a4ab295dae6f4ccabe v7-4-122 +32e50f85d2c7a56c600a2c36107e56fa9f2952cb v7-4-123 +9faba192ea90a32ee137aa42f5027b098931ddb2 v7-4-124 +45ef9d2096e82d6a56a58606b6811620a61cb1ba v7-4-125 +b14554844756422a39c72e62b8c2391c2d5a2e17 v7-4-126 +6f5a7d3943007afc6bc03c445380776e18787f0c v7-4-127 +4b92012f6b18f56664c268200fb54f1316495dc5 v7-4-128 +1e28c0fad344549665c60c62374e6f511e5aec76 v7-4-129 +cf722c09236098ae585840d62eca68dbf8065247 v7-4-130 +4b23119cb58473ab70cf1a1204d4d3fad83881ec v7-4-131 +1b09d6792520cbe1c94c20f6c833ad57316e75bb v7-4-132 +6a28a9cf51537b81da7e9ec3f70fea55e393b345 v7-4-133 +0defb460a0ebbc954b0f22267cb06e9d210be43a v7-4-134 +1aeb7f4d6527369cf5f9101813ce8f10caf7a869 v7-4-135 +3881cd916014605875de128226b83a24d18afe46 v7-4-136 +6fdb1d6646b6b256623edb05f9dd770eeacaeb05 v7-4-137 +6eb60041548ce42748cd8d7d49bdbf9dd164c967 v7-4-138 +c8c80c9d2e2237fedeadfb1c6856c53c7a5e90d2 v7-4-139 +505cf1943dc238c2383dcbc37a93fbb136e1f08b v7-4-140 +2ca470c6096e3ec7cbbedeb1d0281056b088812b v7-4-141 +735b70faac4a54ca9d8ebc2303ba28d5d18017e2 v7-4-142 +d11f223f4c753889fa8f974f295c2a0a451c653c v7-4-143 +bcf25cc08236c2adc27a4d7d556e11e8ea6ddce2 v7-4-144 +1098b7b6e147cdd324ac665340540922c2cdceb3 v7-4-145 +ec93f50f1d93c4c279606117a9f3eb37301b051a v7-4-146 +d289f2167d702c87493d1934db863df29676e261 v7-4-147 +8507bf8874d816a79411bc74df71fa58b557b71d v7-4-148 +b43363a7b4c71a7a4e20dc21f4906f4595785983 v7-4-149 +15960ebc2ee8539a1f15f660d43df1a502c34829 v7-4-150 +ec02e1474bc2bbfd73349e7fedf62ae45f941ad9 v7-4-151 +2ace11abcfb59f6e88c3a40aa1d849d335cfd993 v7-4-152 +30e300c0b2c1c069d953afb258dba39c50772463 v7-4-153 +71837ace77dfdd6c01e0a334314a7c6c713a095c v7-4-154 +fa53233519c693591ce60f9270cf259c07d6cc26 v7-4-155 +05a5cb0d6b37eb7806eb902a72d8b00dde48bc1c v7-4-156 +be61f315eafe5cbadbd00bf7275e004fe09779db v7-4-157 +d59544f3022ba0a35af174d1085a321de6d3b9b4 v7-4-158 +a95a151402be5155cd89f8758e2e09ca95473ad1 v7-4-159 +f29febf858be9c7df896cc86ea89c3da8823b4fb v7-4-160 +91f3908748c29b0e8e759ac4cdafc95e536eab9a v7-4-161 +477665b4105fa80e3655981790e55fc9babfeed5 v7-4-162 +7db84aadd37aaf9d59f8f15dd6783a4e28dcb63c v7-4-163 +a01819fb6e2b5c270dac492ab2fe923ea9301651 v7-4-164 +c82339d8fdae0d43d51cde5216c979a5c9415bc4 v7-4-165 +5d03c374712128077ac4c342aad02120ed98df70 v7-4-166 +22387c8eec43ea8b1b704cad49c8f7187e2fd579 v7-4-167 +e61a2b709f693eea9108d475b9bab5ed10ac675d v7-4-168 +4e3a9dd25d428e7c08ed401afc244972e27e08e6 v7-4-169 +8122eab8fcdbbdaac62dfbf7c6458cb3e6f46b04 v7-4-170 +beb037a6c2708f539d50840637f70eed0811d93c v7-4-171 +391e10afccf6879dcfab8b28cb1587a13eb835c0 v7-4-172 +233ad7b960d0fbeb224b383918113b25c74ebe35 v7-4-173 +f2c8d86c460d75fec17a0527a2fe93ac7220693e v7-4-174 +6b69d8dde19e32909f4ee3a6337e6a2ecfbb6f72 v7-4-175 +ae228baaec2c5eda4cd948382c2bab498d1a34cc v7-4-176 +df3b0b70d8c1d29817597f45d19bb72755f86bd1 v7-4-177 +647e6bb15aa3f864eaf447fe77e3e3ae7e37b134 v7-4-178 +d1c8c1d6403485ff0135f0cf5c1ef07272a07173 v7-4-179 +b1b8b097539a001043d1f0aac4663d6ee358dee8 v7-4-180 +cb5683bcde03796baa7e845fd9a2fcaec3383538 v7-4-181 +708a6a5905217736a2a231e36ced82f9535c4954 v7-4-182 +1e2bfe4f3e903110f27cb6231f6642e721808837 v7-4-183 diff --git a/Filelist b/Filelist index b32493337a..7d7bf008e0 100644 --- a/Filelist +++ b/Filelist @@ -80,6 +80,7 @@ SRC_ALL = \ src/main.aap \ src/testdir/main.aap \ src/testdir/*.in \ + src/testdir/sautest/autoload/*.vim \ src/testdir/test[0-9]*.ok \ src/testdir/test49.vim \ src/testdir/test60.vim \ diff --git a/runtime/autoload/getscript.vim b/runtime/autoload/getscript.vim index 6b74d37da9..d50bc2edc0 100644 --- a/runtime/autoload/getscript.vim +++ b/runtime/autoload/getscript.vim @@ -1,8 +1,8 @@ " --------------------------------------------------------------------- " getscript.vim " Author: Charles E. Campbell -" Date: Apr 17, 2013 -" Version: 35 +" Date: Jan 21, 2014 +" Version: 36 " Installing: :help glvs-install " Usage: :help glvs " @@ -15,7 +15,7 @@ if exists("g:loaded_getscript") finish endif -let g:loaded_getscript= "v35" +let g:loaded_getscript= "v36" if &cp echoerr "GetLatestVimScripts is not vi-compatible; not loaded (you need to set nocp)" finish @@ -208,8 +208,8 @@ fun! getscript#GetLatestVimScripts() let lastline = line("$") " call Decho("lastline#".lastline) let firstdir = substitute(&rtp,',.*$','','') - let plugins = split(globpath(firstdir,"plugin/*.vim"),'\n') - let plugins = plugins + split(globpath(firstdir,"AsNeeded/*.vim"),'\n') + let plugins = split(globpath(firstdir,"plugin/**/*.vim"),'\n') + let plugins = plugins + split(globpath(firstdir,"AsNeeded/**/*.vim"),'\n') let foundscript = 0 " this loop updates the GetLatestVimScripts.dat file diff --git a/runtime/autoload/netrw.vim b/runtime/autoload/netrw.vim index b077bb73bb..4634a343c5 100644 --- a/runtime/autoload/netrw.vim +++ b/runtime/autoload/netrw.vim @@ -1,10 +1,10 @@ " netrw.vim: Handles file transfer and remote directory listing across " AUTOLOAD SECTION -" Date: May 18, 2013 -" Version: 149 +" Date: Jan 21, 2014 +" Version: 150 " Maintainer: Charles E Campbell " GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim -" Copyright: Copyright (C) 1999-2012 Charles E. Campbell {{{1 +" Copyright: Copyright (C) 1999-2013 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,13 +22,7 @@ if &cp || exists("g:loaded_netrw") finish endif -let g:loaded_netrw = "v149" -if v:version < 703 || (v:version == 703 && !has("patch465")) - echohl WarningMsg - echo "***warning*** this version of netrw needs vim 7.3.465 or later" - echohl Normal - finish -endif +let g:loaded_netrw = "v150" if !exists("s:NOTE") let s:NOTE = 0 let s:WARNING = 1 @@ -37,7 +31,7 @@ endif let s:keepcpo= &cpo set cpo&vim -"DechoTabOn +"DechoRemOn "call Decho("doing autoload/netrw.vim version ".g:loaded_netrw) " ====================== @@ -49,7 +43,7 @@ set cpo&vim " 0=note = s:NOTE " 1=warning = s:WARNING " 2=error = s:ERROR -" May 01, 2013 : max errnum currently is 93 +" Jan 03, 2014 : max errnum currently is 95 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) @@ -200,6 +194,7 @@ if !exists("g:netrw_http_cmd") let g:netrw_http_cmd = "" endif endif +call s:NetrwInit("g:netrw_http_put_cmd","curl -T") call s:NetrwInit("g:netrw_rcp_cmd" , "rcp") call s:NetrwInit("g:netrw_rsync_cmd", "rsync") if !exists("g:netrw_scp_cmd") @@ -260,6 +255,7 @@ endif call s:NetrwInit("g:netrw_cursor" , 2) let s:netrw_usercul = &cursorline let s:netrw_usercuc = &cursorcolumn +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) @@ -291,23 +287,19 @@ if !exists("g:netrw_ignorenetrc") endif call s:NetrwInit("g:netrw_keepdir",1) if !exists("g:netrw_list_cmd") - if g:netrw_scp_cmd =~ '^pscp' && executable("pscp") if (has("win32") || has("win95") || has("win64") || has("win16")) && filereadable("c:\\private.ppk") " provide a pscp-based listing command let g:netrw_scp_cmd ="pscp -i C:\\private.ppk" endif let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME:" - elseif executable(g:netrw_ssh_cmd) " provide a scp-based default listing command let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa" - else " call Decho(g:netrw_ssh_cmd." is not executable") let g:netrw_list_cmd= "" endif - endif call s:NetrwInit("g:netrw_list_hide","") " Default values - lh-lz ---------- {{{3 @@ -434,6 +426,11 @@ endif call s:NetrwInit("g:netrw_menu_escape",'.&? \') call s:NetrwInit("g:netrw_tmpfile_escape",' &;') call s:NetrwInit("s:netrw_map_escape","<|\n\r\\\\"") +if &enc == 'utf-8' || &enc == 'utf-16' || &enc == 'ucs-4' + let s:treedepthstring= "│ " +else + let s:treedepthstring= "| " +endif " BufEnter event ignored by decho when following variable is true " Has a side effect that doau BufReadPost doesn't work, so @@ -444,11 +441,18 @@ call s:NetrwInit("s:netrw_map_escape","<|\n\r\\\\"") " Netrw Initialization: {{{1 " ====================== if v:version >= 700 && has("balloon_eval") && !exists("s:initbeval") && !exists("g:netrw_nobeval") && has("syntax") && exists("g:syntax_on") - let s:initbeval = &beval -" let s:initbexpr = &l:bexpr - let &l:bexpr = "netrw#NetrwBalloonHelp()" - set beval - au BufWinEnter,WinEnter * if &ft == "netrw"|set beval|else|let &beval= s:initbeval|endif +" call Decho("installed beval events") + let &l:bexpr = "netrw#NetrwBalloonHelp()" + au FileType netrw set beval + au WinLeave * if &ft == "netrw" && exists("s:initbeval")|let &beval= s:initbeval|endif + au VimEnter * let s:initbeval= &beval +"else " Decho +" if v:version < 700 | call Decho("did not install beval events: v:version=".v:version." < 700") | endif +" if !has("balloon_eval") | call Decho("did not install beval events: does not have balloon_eval") | endif +" if exists("s:initbeval") | call Decho("did not install beval events: s:initbeval exists") | endif +" if exists("g:netrw_nobeval") | call Decho("did not install beval events: g:netrw_nobeval exists") | endif +" if !has("syntax") | call Decho("did not install beval events: does not have syntax highlighting") | endif +" if exists("g:syntax_on") | call Decho("did not install beval events: g:syntax_on exists") | endif endif au WinEnter * if &ft == "netrw"|call s:NetrwInsureWinVars()|endif @@ -458,33 +462,44 @@ au WinEnter * if &ft == "netrw"|call s:NetrwInsureWinVars()|endif " --------------------------------------------------------------------- " netrw#NetrwBalloonHelp: {{{2 -if v:version >= 700 && has("balloon_eval") && &beval == 1 && has("syntax") && exists("g:syntax_on") - fun! netrw#NetrwBalloonHelp() - if !exists("w:netrw_bannercnt") || v:beval_lnum >= w:netrw_bannercnt || (exists("g:netrw_nobeval") && g:netrw_nobeval) - let mesg= "" - elseif v:beval_text == "Netrw" || v:beval_text == "Directory" || v:beval_text == "Listing" - let mesg = "i: thin-long-wide-tree gh: quick hide/unhide of dot-files qf: quick file info %:open new file" - elseif getline(v:beval_lnum) =~ '^"\s*/' - let mesg = ": edit/enter o: edit/enter in horiz window t: edit/enter in new tab v:edit/enter in vert window" - elseif v:beval_text == "Sorted" || v:beval_text == "by" - let mesg = 's: sort by name, time, or file size r: reverse sorting order mt: mark target' - elseif v:beval_text == "Sort" || v:beval_text == "sequence" - let mesg = "S: edit sorting sequence" - elseif v:beval_text == "Hiding" || v:beval_text == "Showing" - let mesg = "a: hiding-showing-all ctrl-h: editing hiding list mh: hide/show by suffix" - elseif v:beval_text == "Quick" || v:beval_text == "Help" - let mesg = "Help: press " - elseif v:beval_text == "Copy/Move" || v:beval_text == "Tgt" - let mesg = "mt: mark target mc: copy marked file to target mm: move marked file to target" - else - let mesg= "" - endif - return mesg - endfun +if v:version >= 700 && has("balloon_eval") && has("syntax") && exists("g:syntax_on") && !exists("g:netrw_nobeval") +" call Decho("loading netrw#BalloonHelp()") + fun! netrw#NetrwBalloonHelp() + if &ft != "netrw" + return "" + endif + if !exists("w:netrw_bannercnt") || v:beval_lnum >= w:netrw_bannercnt || (exists("g:netrw_nobeval") && g:netrw_nobeval) + let mesg= "" + elseif v:beval_text == "Netrw" || v:beval_text == "Directory" || v:beval_text == "Listing" + let mesg = "i: thin-long-wide-tree gh: quick hide/unhide of dot-files qf: quick file info %:open new file" + elseif getline(v:beval_lnum) =~ '^"\s*/' + let mesg = ": edit/enter o: edit/enter in horiz window t: edit/enter in new tab v:edit/enter in vert window" + elseif v:beval_text == "Sorted" || v:beval_text == "by" + let mesg = 's: sort by name, time, or file size r: reverse sorting order mt: mark target' + elseif v:beval_text == "Sort" || v:beval_text == "sequence" + let mesg = "S: edit sorting sequence" + elseif v:beval_text == "Hiding" || v:beval_text == "Showing" + let mesg = "a: hiding-showing-all ctrl-h: editing hiding list mh: hide/show by suffix" + elseif v:beval_text == "Quick" || v:beval_text == "Help" + let mesg = "Help: press " + elseif v:beval_text == "Copy/Move" || v:beval_text == "Tgt" + let mesg = "mt: mark target mc: copy marked file to target mm: move marked file to target" + else + let mesg= "" + endif + return mesg + endfun +"else " Decho +" if v:version < 700 |call Decho("did not load netrw#BalloonHelp(): vim version ".v:version." < 700 -")|endif +" if !has("balloon_eval") |call Decho("did not load netrw#BalloonHelp(): does not have balloon eval") |endif +" if !has("syntax") |call Decho("did not load netrw#BalloonHelp(): syntax disabled") |endif +" if !exists("g:syntax_on") |call Decho("did not load netrw#BalloonHelp(): g:syntax_on=".g:syntax_on) |endif +" if exists("g:netrw_nobeval") |call Decho("did not load netrw#BalloonHelp(): g:netrw_nobeval exists") |endif endif " ------------------------------------------------------------------------ " 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 @@ -493,6 +508,7 @@ endif fun! s:NetrwOptionSave(vt) " call Dfunc("s:NetrwOptionSave(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")) +" call Decho("(s:NetrwOptionSave) 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) if !exists("{a:vt}netrw_optionsave") let {a:vt}netrw_optionsave= 1 @@ -500,7 +516,7 @@ fun! s:NetrwOptionSave(vt) " call Dret("s:NetrwOptionSave : options already saved") return endif -" call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." diff=".&l:diff) +" call Decho("(s:NetrwOptionSave) prior to save: fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." diff=".&l:diff) " Save current settings and current directory " call Decho("saving current settings and current directory") @@ -535,6 +551,7 @@ fun! s:NetrwOptionSave(vt) let {a:vt}netrw_rokeep = &l:ro let {a:vt}netrw_selkeep = &l:sel let {a:vt}netrw_spellkeep = &l:spell + let {a:vt}netrw_starkeep = @* let {a:vt}netrw_tskeep = &l:ts let {a:vt}netrw_twkeep = &l:tw " textwidth let {a:vt}netrw_wigkeep = &l:wig " wildignore @@ -555,13 +572,15 @@ fun! s:NetrwOptionSave(vt) if &go =~# 'a' | sil! let {a:vt}netrw_regstar = @* | endif sil! let {a:vt}netrw_regslash= @/ -" call Dret("s:NetrwOptionSave : tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")." modified=".&modified." modifiable=".&modifiable." readonly=".&readonly) +" call Decho("(s:NetrwOptionSave) 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) +" call Dret("s:NetrwOptionSave : tab#".tabpagenr()." win#".winnr()) endfun " ------------------------------------------------------------------------ -" s:NetrwOptionRestore: restore options {{{2 +" 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("(NetrwOptionRestore) 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) if !exists("{a:vt}netrw_optionsave") if exists("s:nbcd_curpos_{bufnr('%')}") " call Decho("(NetrwOptionRestore) restoring previous position (s:nbcd_curpos_".bufnr('%')." exists)") @@ -572,6 +591,7 @@ fun! s:NetrwOptionRestore(vt) else " call Decho("(NetrwOptionRestore) no previous position") endif +" call Decho("(NetrwOptionRestore) 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) " call Decho("(NetrwOptionRestore) ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)") " call Dret("s:NetrwOptionRestore : ".a:vt."netrw_optionsave doesn't exist") return @@ -627,6 +647,7 @@ fun! s:NetrwOptionRestore(vt) 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 exists("{a:vt}netrw_starkeep") |let @* = {a:vt}netrw_starkeep |unlet {a:vt}netrw_starkeep |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 @@ -639,7 +660,7 @@ fun! s:NetrwOptionRestore(vt) " 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() + let &l:directory= getcwd() sil! let &l:swf = {a:vt}netrw_swfkeep setl directory= unlet {a:vt}netrw_swfkeep @@ -659,7 +680,9 @@ fun! s:NetrwOptionRestore(vt) " call Decho("(NetrwOptionRestore) restoring previous position (s:nbcd_curpos_".bufnr('%')." exists)") keepj call netrw#NetrwRestorePosn(s:nbcd_curpos_{bufnr('%')}) " call Decho("(NetrwOptionRestore) unlet s:nbcd_curpos_".bufnr('%')) - unlet s:nbcd_curpos_{bufnr('%')} + if exists("s:nbcd_curpos_".bufnr('%')) + unlet s:nbcd_curpos_{bufnr('%')} + endif else " call Decho("no previous position") endif @@ -676,6 +699,7 @@ fun! s:NetrwOptionRestore(vt) " call Decho("(NetrwOptionRestore) filetype detect (ft=".&ft.")") filetype detect endif +" call Decho("(s:NetrwOptionRestore) 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) " call Dret("s:NetrwOptionRestore : tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> modified=".&modified." modifiable=".&modifiable." readonly=".&readonly) endfun @@ -685,10 +709,12 @@ endfun " Use s:NetrwOptionRestore() to restore user settings fun! s:NetrwSafeOptions() " call Dfunc("s:NetrwSafeOptions() win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%"))."> winnr($)=".winnr("$")) -" call Decho("win#".winnr()."'s ft=".&ft) +" call Decho("(s:NetrwSafeOptions) win#".winnr()."'s ft=".&ft) +" call Decho("(s:NetrwSafeOptions) 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) if exists("+acd") | setl noacd | endif setl noai setl noaw + setl nobl setl nobomb setl noci setl nocin @@ -700,7 +726,7 @@ fun! s:NetrwSafeOptions() setl cpo-=a setl cpo-=A setl fo=nroql2 - setl nohid + setl nohid setl noim setl isk+=@ isk+=* isk+=/ setl magic @@ -716,13 +742,14 @@ fun! s:NetrwSafeOptions() call s:NetrwCursor() " allow the user to override safe options -" call Decho("ft<".&ft."> ei=".&ei) +" call Decho("(s:NetrwSafeOptions) ft<".&ft."> ei=".&ei) if &ft == "netrw" -" call Decho("do any netrw FileType autocmds (doau FileType netrw)") +" call Decho("(s:NetrwSafeOptions) do any netrw FileType autocmds (doau FileType netrw)") sil! keepalt keepj doau FileType netrw endif -" call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." bh=".&l:bh) +" call Decho("(s:NetrwSafeOptions) fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." bh=".&l:bh) +" call Decho("(s:NetrwSafeOptions) 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) " call Dret("s:NetrwSafeOptions") endfun @@ -737,7 +764,7 @@ endfun " * If Hexplore or Vexplore, then this will override " g:netrw_winsize to specify the qty of rows or columns the " newly split window should have. -" dosplit==0: the window will be split iff the current file has been modified +" dosplit==0: the window will be split iff the current file has been modified and hidden not set " dosplit==1: the window will be split before running the local browser " style == 0: Explore style == 1: Explore! " == 2: Hexplore style == 3: Hexplore! @@ -747,9 +774,6 @@ fun! netrw#Explore(indx,dosplit,style,...) " call Dfunc("netrw#Explore(indx=".a:indx." dosplit=".a:dosplit." style=".a:style.",a:1<".a:1.">) &modified=".&modified." modifiable=".&modifiable." a:0=".a:0." win#".winnr()." buf#".bufnr("%")) if !exists("b:netrw_curdir") let b:netrw_curdir= getcwd() - if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16")) - let b:netrw_curdir= substitute(b:netrw_curdir,'\','/','g') - endif " call Decho("(Explore) set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)") endif let curdir = simplify(b:netrw_curdir) @@ -764,8 +788,10 @@ fun! netrw#Explore(indx,dosplit,style,...) sil! let keepregplus = @+ sil! let keepregslash= @/ - " if dosplit or file has been modified - if a:dosplit || &modified || a:style == 6 + " if dosplit + " -or- file has been modified AND file not hidden when abandoned + " -or- Texplore used + if a:dosplit || (&modified && &hidden == 0 && &bufhidden != "hide") || a:style == 6 " call Decho("(Explore) case dosplit=".a:dosplit." modified=".&modified." a:style=".a:style.": dosplit or file has been modified") call s:SaveWinVars() let winsz= g:netrw_winsize @@ -1151,11 +1177,11 @@ fun! netrw#Explore(indx,dosplit,style,...) if exists("w:netrw_explore_indx") && exists("b:netrw_curdir") " call Decho("(Explore) s:explore_prvdir<".(exists("s:explore_prvdir")? s:explore_prvdir : "-doesn't exist-")) if !exists("s:explore_prvdir") || s:explore_prvdir != b:netrw_curdir - " only update match list if current directory isn't the same as before -" call Decho("(Explore) only update match list if current directory not the same as before") + " only update match list when current directory isn't the same as before +" call Decho("(Explore) only update match list when current directory not the same as before") let s:explore_prvdir = b:netrw_curdir let s:explore_match = "" - let dirlen = s:Strlen(b:netrw_curdir) + let dirlen = strlen(b:netrw_curdir) if b:netrw_curdir !~ '/$' let dirlen= dirlen + 1 endif @@ -1195,6 +1221,37 @@ fun! netrw#Explore(indx,dosplit,style,...) " call Dret("netrw#Explore : @/<".@/.">") endfun +" --------------------------------------------------------------------- +" netrw#Lexplore: toggle Explorer window, keeping it on the left of the current tab {{{2 +fun! netrw#Lexplore(...) +" call Dfunc("netrw#Lexplore() a:0=".a:0) + if exists("t:netrw_lexbufnr") + " close down netrw explorer window + let lexwinnr = bufwinnr(t:netrw_lexbufnr) + if lexwinnr != -1 + let curwin = winnr() + exe lexwinnr."wincmd w" + close + exe curwin."wincmd w" + endif + unlet t:netrw_lexbufnr + + else + " open netrw explorer window + exe "1wincmd w" + let keep_altv = g:netrw_altv + let g:netrw_altv = 0 + if a:0 > 0 && a:1 != "" + Vexplore a:1 + else + Vexplore . + endif + let g:netrw_altv = keep_altv + let t:netrw_lexbufnr = bufnr("%") + endif +" call Dret("netrw#Lexplore") +endfun + " --------------------------------------------------------------------- " netrw#NetrwMakeTgt: make a target out of the directory name provided {{{2 fun! netrw#NetrwMakeTgt(dname) @@ -1637,7 +1694,7 @@ fun! netrw#NetRead(mode,...) endif let tmpfile= s:GetTempfile(b:netrw_fname) " apply correct suffix - " Check if NetrwBrowse() should be handling this request + " Check whether or not NetrwBrowse() should be handling this request " call Decho("checking if NetrwBrowse() should handle choice<".choice."> with netrw_list_cmd<".g:netrw_list_cmd.">") if choice =~ "^.*[\/]$" && b:netrw_method != 5 && choice !~ '^https\=://' " call Decho("yes, choice matches '^.*[\/]$'") @@ -1659,7 +1716,7 @@ fun! netrw#NetRead(mode,...) " call Decho("read via rcp (method #1)") " ER: nothing done with g:netrw_uid yet? " ER: on Win2K" rcp machine[.user]:file tmpfile - " ER: if machine contains '.' adding .user is required (use $USERNAME) + " ER: when machine contains '.' adding .user is required (use $USERNAME) " ER: the tmpfile is full path: rcp sees C:\... as host C if s:netrw_has_nt_rcp == 1 if exists("g:netrw_uid") && ( g:netrw_uid != "" ) @@ -1978,7 +2035,7 @@ fun! netrw#NetWrite(...) range exe "sil keepj w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile) elseif g:netrw_cygwin " write (selected portion of) file to temporary - let cygtmpfile= substitute(tmpfile,'/cygdrive/\(.\)','\1:','') + let cygtmpfile= substitute(tmpfile,g:netrw_cygdrive.'/\(.\)','\1:','') " call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile)) exe "sil keepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile) else @@ -1988,7 +2045,7 @@ fun! netrw#NetWrite(...) range endif if curbufname == "" - " if the file is [No Name], and one attempts to Nwrite it, the buffer takes + " when the file is [No Name], and one attempts to Nwrite it, the buffer takes " on the temporary file's name. Deletion of the temporary file during " cleanup then causes an error message. 0file! @@ -2006,7 +2063,7 @@ fun! netrw#NetWrite(...) range else exe "let choice= a:" . ichoice - " Reconstruct Choice if choice starts with '"' + " Reconstruct Choice when choice starts with '"' if match(choice,"?") == 0 echomsg 'NetWrite Usage:"' echomsg ':Nwrite machine:path uses rcp' @@ -2215,8 +2272,13 @@ fun! netrw#NetWrite(...) range " NetWrite: (http) NetWrite Method #5 {{{3 elseif b:netrw_method == 5 " call Decho("write via http (method #5)") - if !exists("g:netrw_quiet") - call netrw#ErrorMsg(s:ERROR,"currently does not support writing using http:",16) + let curl= substitute(g:netrw_http_put_cmd,'\s\+.*$',"","") + if executable(curl) + let url= g:netrw_choice +" call Decho("exe ".s:netrw_silentxfer."!".g:netrw_http_put_cmd." ".shellescape(tmpfile,1)." ".shellescape(url,1) ) + exe s:netrw_silentxfer."!".g:netrw_http_put_cmd." ".shellescape(tmpfile,1)." ".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) endif "......................................... @@ -2363,6 +2425,36 @@ fun! netrw#NetSource(...) " call Dret("netrw#NetSource") endfun +" --------------------------------------------------------------------- +" netrw#NetrwSetTreetop: resets the tree top to the current directory/specified directory {{{2 +fun! netrw#NetrwSetTreetop(...) +" call Dfunc("netrw#NetrwSetTreetop(".((a:0 > 0)? a:1 : "").") a:0=".a:0) + " clear out the current tree + if exists("w:netrw_treetop") + let inittreetop= w:netrw_treetop + unlet w:netrw_treetop + endif + if exists("w:netrw_treedict") + unlet w:netrw_treedict + endif + if a:1 == "" + let treedir= s:NetrwTreePath(inittreetop) + else + if isdirectory(a:1) + let treedir= a:1 + elseif exists("b:netrw_curdir") && isdirectory(b:netrw_curdir."/".a:1) + let treedir= b:netrw_curdir."/".a:1 + else + call netrw#ErrorMsg(s:ERROR,"sorry, ".a:1." doesn't seem to be a directory!",95) +" call Dret("netrw#NetrwSetTreetop") + return + endif + endif +" call Decho("treedir<".treedir.">") + sil! call netrw#LocalBrowseCheck(treedir) +" call Dret("netrw#NetrwSetTreetop") +endfun + " =========================================== " s:NetrwGetFile: Function to read temporary file "tfile" with command "readcmd". {{{2 " readcmd == %r : replace buffer with newly read file @@ -2394,7 +2486,7 @@ fun! s:NetrwGetFile(readcmd, tfile, method) " rename the current buffer to the temp file (ie. tfile) if g:netrw_cygwin - let tfile= substitute(a:tfile,'/cygdrive/\(.\)','\1:','') + let tfile= substitute(a:tfile,g:netrw_cygdrive.'/\(.\)','\1:','') else let tfile= a:tfile endif @@ -2435,11 +2527,18 @@ fun! s:NetrwGetFile(readcmd, tfile, method) " call Decho("detect filetype of local version of remote file") let iskkeep= &l:isk setl isk-=/ + " filetype detect " COMBAK - trying filetype detect in NetrwOptionRestore Jan 24, 2013 let &l:isk= iskkeep " call Dredir("renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">","ls!") let line1 = 1 let line2 = line("$") + elseif !&ma + " attempting to read a file after the current line in the file, but the buffer is not modifiable + keepj call netrw#ErrorMsg(s:WARNING,"attempt to read<".a:tfile."> into a non-modifiable buffer!",94) +" call Dret("NetrwGetFile : attempt to read<".a:tfile."> into a non-modifiable buffer!") + return + elseif s:FileReadable(a:tfile) " read file after current line " call Decho("read file<".a:tfile."> after current line") @@ -2912,7 +3011,7 @@ fun! s:NetrwMaps(islocal) " local normal-mode maps nnoremap a :call NetrwHide(1) nnoremap % :call NetrwOpenFile(1) - nnoremap c :exe "keepjumps lcd ".fnameescape(b:netrw_curdir) + nnoremap c :exe "keepj lcd ".fnameescape(b:netrw_curdir) nnoremap C :let g:netrw_chgwin= winnr() nnoremap :call netrw#LocalBrowseCheck(NetrwBrowseChgDir(1,NetrwGetWord())) nnoremap d :call NetrwMakeDir("") @@ -3029,22 +3128,22 @@ fun! s:NetrwMaps(islocal) endif let mapsafecurdir = escape(b:netrw_curdir, s:netrw_map_escape) if g:netrw_mousemaps == 1 - nmap NetrwLeftmouse - nno NetrwLeftmouse :call NetrwLeftmouse(1) - nmap NetrwRightdrag - nno NetrwRightdrag :call NetrwRightdrag(1) - nmap NetrwMiddlemouse - nno NetrwMiddlemouse :call NetrwPrevWinOpen(1) - nmap NetrwSLeftmouse - nno NetrwSLeftmouse :call NetrwMarkFile(1,NetrwGetWord()) - 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()) + nmap NetrwLeftmouse + nno NetrwLeftmouse :call NetrwLeftmouse(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.'")' @@ -3052,15 +3151,15 @@ fun! s:NetrwMaps(islocal) exe 'nnoremap :call NetrwLocalRm("'.mapsafecurdir.'")' exe 'nnoremap D :call NetrwLocalRm("'.mapsafecurdir.'")' exe 'nnoremap R :call NetrwLocalRename("'.mapsafecurdir.'")' - exe 'nnoremap m :call NetrwMakeDir("")' + exe 'nnoremap d :call NetrwMakeDir("")' 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 m :call NetrwMakeDir("")' - nnoremap :he netrw-quickhelp + exe 'inoremap d :call NetrwMakeDir("")' + nnoremap :he netrw-quickhelp else " remote " call Decho("(NetrwMaps) make remote maps") @@ -3181,10 +3280,12 @@ fun! s:NetrwMaps(islocal) nno NetrwLeftmouse :call NetrwLeftmouse(0) nmap NetrwLeftdrag nno NetrwLeftdrag :call NetrwLeftdrag(0) + nmap NetrwSLeftmouse + nno NetrwSLeftmouse :call NetrwSLeftmouse(0) + nmap NetrwSLeftdrag + nno NetrwSLeftdrag :call NetrwSLeftdrag(0) nmap NetrwMiddlemouse nno NetrwMiddlemouse :call NetrwPrevWinOpen(0) - nmap NetrwSLeftmouse - nno NetrwSLeftmouse :call NetrwMarkFile(0,NetrwGetWord()) nmap <2-leftmouse> Netrw2Leftmouse nmap Netrw2Leftmouse - imap ILeftmouse @@ -3344,7 +3445,7 @@ fun! s:NetrwBookHistHandler(chg,curdir) " call Decho("(NetrwBookHistHandler) setl nomod") " call Decho("(NetrwBookHistHandler) ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)") endif -" " call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt})) +" call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt})) exe "keepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt}) else if g:netrw_dirhistmax > 0 @@ -3506,6 +3607,7 @@ 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("(NetrwBrowse) tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")." modified=".&modified." modifiable=".&modifiable." readonly=".&readonly) +" call Dredir("ls!") " s:NetrwBrowse: initialize history {{{3 if !exists("s:netrw_initbookhist") keepj call s:NetrwBookHistRead() @@ -3625,11 +3727,14 @@ fun! s:NetrwBrowse(islocal,dirname) endif " set b:netrw_curdir to the new directory name {{{3 -" call Decho("(NetrwBrowse) set b:netrw_curdir to the new directory name: (buf#".bufnr("%").")") +" call Decho("(NetrwBrowse) set b:netrw_curdir to the new directory name<".dirname."> (buf#".bufnr("%").")") let b:netrw_curdir= dirname if b:netrw_curdir =~ '[/\\]$' let b:netrw_curdir= substitute(b:netrw_curdir,'[/\\]$','','e') endif + if b:netrw_curdir =~ '\a:$' && (has("win32") || has("win95") || has("win64") || has("win16")) + let b:netrw_curdir= b:netrw_curdir."/" + endif if b:netrw_curdir == '' if has("amiga") " On the Amiga, the empty string connotes the current directory @@ -3659,7 +3764,7 @@ fun! s:NetrwBrowse(islocal,dirname) " call Decho("(NetrwBrowse) handle g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd) " call Decho("(NetrwBrowse) l:acd".(exists("&l:acd")? "=".&l:acd : " doesn't exist")) if !exists("&l:acd") || !&l:acd -" call Decho('exe keepjumps lcd '.fnameescape(b:netrw_curdir)) +" call Decho('(NetrwBrowse) exe keepj lcd '.fnameescape(b:netrw_curdir)) try exe 'keepj lcd '.fnameescape(b:netrw_curdir) catch /^Vim\%((\a\+)\)\=:E472/ @@ -3746,20 +3851,33 @@ endfun " --------------------------------------------------------------------- " s:NetrwFileInfo: supports qf (query for file information) {{{2 fun! s:NetrwFileInfo(islocal,fname) -" call Dfunc("s:NetrwFileInfo(islocal=".a:islocal." fname<".a:fname.">)") +" call Dfunc("s:NetrwFileInfo(islocal=".a:islocal." fname<".a:fname.">) b:netrw_curdir<".b:netrw_curdir.">") let ykeep= @@ if a:islocal if (has("unix") || has("macunix")) && executable("/bin/ls") - if exists("b:netrw_curdir") -" call Decho('using ls with b:netrw_curdir<'.b:netrw_curdir.'>') + + if getline(".") == "../" + echo system("/bin/ls -lsad ".shellescape("..")) +" call Decho("#1: echo system(/bin/ls -lsad ".shellescape(..).")") + + elseif getline(".") !~ '^'.s:treedepthstring + echo system("/bin/ls -lsad ".shellescape(b:netrw_curdir)) +" call Decho("#2: echo system(/bin/ls -lsad ".shellescape(b:netrw_curdir).")") + + elseif exists("b:netrw_curdir") if b:netrw_curdir =~ '/$' echo system("/bin/ls -lsad ".shellescape(b:netrw_curdir.a:fname)) +" call Decho("#3: echo system(/bin/ls -lsad ".shellescape(b:netrw_curdir.a:fname).")") + else echo system("/bin/ls -lsad ".shellescape(b:netrw_curdir."/".a:fname)) +" call Decho("#4: echo system(/bin/ls -lsad ".shellescape(b:netrw_curdir."/".a:fname).")") endif + else " call Decho('using ls '.a:fname." using cwd<".getcwd().">") echo system("/bin/ls -lsad ".shellescape(a:fname)) +" call Decho("#5: echo system(/bin/ls -lsad ".shellescape(a:fname).")") endif else " use vim functions to return information about file below cursor @@ -3787,7 +3905,7 @@ endfun " 1=re-used buffer fun! s:NetrwGetBuffer(islocal,dirname) " call Dfunc("s:NetrwGetBuffer(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".g:netrw_liststyle) -" call Decho("(NetrwGetBuffer) modiable=".&mod." modifiable=".&ma." readonly=".&ro) +" call Decho("(NetrwGetBuffer) 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) let dirname= a:dirname " re-use buffer if possible {{{3 @@ -3797,12 +3915,13 @@ fun! s:NetrwGetBuffer(islocal,dirname) " call Decho("(NetrwGetBuffer) case liststyle=treelist: find NetrwTreeList buffer if there is one") if exists("w:netrw_treebufnr") && w:netrw_treebufnr > 0 " call Decho("(NetrwGetBuffer) re-using w:netrw_treebufnr=".w:netrw_treebufnr) - setl mod - sil! keepj %d let eikeep= &ei set ei=all exe "sil! keepalt b ".w:netrw_treebufnr let &ei= eikeep + setl ma + sil! keepj %d +" call Decho("(NetrwGetBuffer) 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) " call Dret("s:NetrwGetBuffer 0 : bufnum#".w:netrw_treebufnr."") return 0 endif @@ -3812,6 +3931,7 @@ fun! s:NetrwGetBuffer(islocal,dirname) else " find buffer number of buffer named precisely the same as dirname {{{3 " call Decho("(NetrwGetBuffer) case listtyle not treelist: find buffer numnber of buffer named precisely the same as dirname--") +" call Dredir("(NetrwGetBuffer) ls!","ls!") " get dirname and associated buffer number let bufnum = bufnr(escape(dirname,'\')) @@ -3933,11 +4053,13 @@ fun! s:NetrwGetBuffer(islocal,dirname) let &ei= eikeep if line("$") <= 1 keepj call s:NetrwListSettings(a:islocal) +" call Decho("(NetrwGetBuffer) 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) " call Dret("s:NetrwGetBuffer 0 : re-using buffer#".bufnr("%").", but its empty, so refresh it") return 0 elseif g:netrw_fastbrowse == 0 || (a:islocal && g:netrw_fastbrowse == 1) keepj call s:NetrwListSettings(a:islocal) sil keepj %d +" call Decho("(NetrwGetBuffer) 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) " call Dret("s:NetrwGetBuffer 0 : re-using buffer#".bufnr("%").", but refreshing due to g:netrw_fastbrowse=".g:netrw_fastbrowse) return 0 elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST @@ -3945,9 +4067,11 @@ fun! s:NetrwGetBuffer(islocal,dirname) " call Decho("(NetrwGetBuffer) clear buffer<".expand("%")."> with :%d") sil keepj %d keepj call s:NetrwListSettings(a:islocal) +" call Decho("(NetrwGetBuffer) 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) " call Dret("s:NetrwGetBuffer 0 : re-using buffer#".bufnr("%").", but treelist mode always needs a refresh") return 0 else +" call Decho("(NetrwGetBuffer) 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) " call Dret("s:NetrwGetBuffer 1 : buf#".bufnr("%")) return 1 endif @@ -3969,7 +4093,8 @@ fun! s:NetrwGetBuffer(islocal,dirname) " call Decho("(NetrwGetBuffer) clear buffer<".expand("%")."> with :%d") sil! keepalt keepj %d -" call Dret("s:NetrwGetBuffer 0 : tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> modified=".&modified." modifiable=".&modifiable." readonly=".&readonly) +" call Decho("(NetrwGetBuffer) 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) +" call Dret("s:NetrwGetBuffer 0 : tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")) return 0 endfun @@ -4048,7 +4173,7 @@ fun! s:NetrwGetWord() elseif w:netrw_liststyle == s:TREELIST " call Decho("treelist handling") - let dirname= substitute(getline('.'),'^\(| \)*','','e') + let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e') else " call Decho("obtain word from wide listing") @@ -4100,6 +4225,7 @@ endfun " s:NetrwListSettings: make standard settings for a netrw listing {{{2 fun! s:NetrwListSettings(islocal) " call Dfunc("s:NetrwListSettings(islocal=".a:islocal.")") +" call Decho("(s:NetrwListSettings) 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) let fname= bufname("%") " call Decho("(NetrwListSettings) setl bt=nofile nobl ma nonu nowrap noro") setl bt=nofile nobl ma nonu nowrap noro @@ -4108,6 +4234,7 @@ fun! s:NetrwListSettings(islocal) if g:netrw_use_noswf setl noswf endif +" call Dredir("ls!") " call Decho("(NetrwListSettings) exe setl ts=".(g:netrw_maxfilenamelen+1)) exe "setl ts=".(g:netrw_maxfilenamelen+1) setl isk+=.,~,- @@ -4116,6 +4243,7 @@ fun! s:NetrwListSettings(islocal) else setl bh=delete endif +" call Decho("(s:NetrwListSettings) 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) " call Dret("s:NetrwListSettings") endfun @@ -4239,14 +4367,14 @@ fun! s:NetrwBookmarkMenu() if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0 let cnt= 1 for bmd in g:netrw_bookmarklist - let ebmd= escape(bmd,g:netrw_menu_escape) -" call Decho('sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmark.'.ebmd.' :e '.bmd) +" call Decho('sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmark.'.bmd.' :e '.bmd) + let bmd= escape(bmd,g:netrw_menu_escape) " show bookmarks for goto menu - exe 'sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks.'.ebmd.' :e '.bmd."\" + exe 'sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks.'.bmd.' :e '.bmd."\" " show bookmarks for deletion menu - exe 'sil! menu '.g:NetrwMenuPriority.".8.2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete.'.ebmd.' '.cnt."mB" + exe 'sil! menu '.g:NetrwMenuPriority.".8.2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete.'.bmd.' '.cnt."mB" let cnt= cnt + 1 endfor @@ -4292,11 +4420,13 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...) let @@= ykeep " call Decho("(NetrwBrowseChgDir) b:netrw_curdir doesn't exist!") " call Decho("(NetrwBrowseChgDir) getcwd<".getcwd().">") +" call Dredir("ls!") " call Dret("s:NetrwBrowseChgDir") return endif " NetrwBrowseChgDir: save options and initialize {{{3 +" call Decho("(NetrwBrowseChgDir) saving options") keepj call s:NetrwOptionSave("s:") keepj call s:NetrwSafeOptions() let nbcd_curpos = netrw#NetrwSavePosn() @@ -4311,6 +4441,7 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...) let dolockout = 0 " set up o/s-dependent directory recognition pattern +" call Decho("(NetrwBrowseChgDir) set up o/s-dependent directory recognition pattern") if has("amiga") let dirpat= '[\/:]$' else @@ -4335,12 +4466,14 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...) let s:rexposn_{bufnr("%")}= netrw#NetrwSavePosn() " call Decho("(NetrwBrowseChgDir:edit-a-file) setting s:rexposn_".bufnr("%")." to SavePosn") +" call Decho("(NetrwBrowseChgDir:edit-a-file) win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> ft=".&ft) if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") && newdir !~ '^\(/\|\a:\)' +" call Decho("(NetrwBrowseChgDir:edit-a-file) handle tree listing: w:netrw_treedict<".(exists("w:netrw_treedict")? string(w:netrw_treedict) : 'n/a').">") let dirname= s:NetrwTreeDir() if dirname =~ '/$' let dirname= dirname.newdir else - let dirname= s:NetrwTreeDir()."/".newdir + let dirname= dirname."/".newdir endif " call Decho("(NetrwBrowseChgDir:edit-a-file) dirname<".dirname.">") " call Decho("(NetrwBrowseChgDir:edit-a-file) tree listing") @@ -4391,9 +4524,16 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...) " the point where netrw actually edits the (local) file " if its local only: LocalBrowseCheck() doesn't edit a file, but NetrwBrowse() will + " no keepalt to support :e # to return to a directory listing if a:islocal " call Decho("(NetrwBrowseChgDir:edit-a-file) edit local file: exe e! ".fnameescape(dirname)) - exe "keepj keepalt e! ".fnameescape(dirname) + " some like c-^ to return to the last edited file + " others like c-^ to return to the netrw buffer + if exists("g:netrw_altfile") && g:netrw_altfile + exe "keepj keepalt e! ".fnameescape(dirname) + else + exe "keepj e! ".fnameescape(dirname) + endif call s:NetrwCursor() else " call Decho("(NetrwBrowseChgDir:edit-a-file) remote file: NetrwBrowse will edit it") @@ -4461,6 +4601,21 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...) endif " call Decho("(NetrwBrowseChgDir:go-up) amiga: dirname<".dirname."> (go up one dir)") + elseif !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16")) + " windows + if a:islocal + let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','') + if dirname == "" + let dirname= '/' + endif + else + let dirname= substitute(dirname,'^\(\a\+://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','') + endif + if dirname =~ '^\a:$' + let dirname= dirname.'/' + endif +" call Decho("(NetrwBrowseChgDir:go-up) windows: dirname<".dirname."> (go up one dir)") + else " unix or cygwin " call Decho('(NetrwBrowseChgDir:go-up) case "go up one directory": newdir == "../" and unix or cygwin') @@ -5033,11 +5188,14 @@ fun! s:NetrwLeftmouse(islocal) " call Dret("s:NetrwLeftmouse : detected a status bar leftmouse click") return endif - if v:mouse_col != col('.') - let @@= ykeep + " NOTE: following test is preventing leftmouse selection/deselection of directories and files in treelist mode (Dec 04, 2013) + " Windows are separated by vertical separator bars - but the mouse seems to be doing what it should when dragging that bar + " without this test. +" if v:mouse_col != col('.') +" let @@= ykeep " call Dret("s:NetrwLeftmouse : detected a vertical separator bar leftmouse click") - return - endif +" return +" endif if a:islocal if exists("b:netrw_curdir") @@ -5053,44 +5211,53 @@ fun! s:NetrwLeftmouse(islocal) endfun " --------------------------------------------------------------------- -" s:NetrwRightdrag: {{{2 -"DechoTabOn -fun! s:NetrwRightdrag(islocal) -" call Dfunc("s:NetrwRightdrag(islocal=".a:islocal.")") - if !exists("s:netrwdrag") - let s:netrwdrag = winnr() - call s:NetrwMarkFile(a:islocal,s:NetrwGetWord()) - if a:islocal - nno :call NetrwRightrelease(1) - else - nno :call NetrwRightrelease(0) - endif - endif -" call Dret("s:NetrwRightdrag : s:netrwdrag=".s:netrwdrag." buf#".bufnr("%")) +" s:NetrwSLeftmouse: marks the file under the cursor. May be dragged to select additional files {{{2 +fun! s:NetrwSLeftmouse(islocal) +" call Dfunc("s:NetrwSLeftmouse(islocal=".a:islocal.")") + + let s:ngw= s:NetrwGetWord() + call s:NetrwMarkFile(a:islocal,s:ngw) + +" call Dret("s:NetrwSLeftmouse") endfun " --------------------------------------------------------------------- -" s:NetrwRightrelease: {{{2 -fun! s:NetrwRightrelease(islocal) -" call Dfunc("s:NetrwRightrelease(islocal=".a:islocal.") s:netrwdrag=".s:netrwdrag." buf#".bufnr("%")) - if exists("s:netrwdrag") - nunmap - let tgt = s:NetrwGetWord() -" call Decho("target#1: ".tgt) - if tgt =~ '/$' && tgt !~ '^\./$' - let tgt = b:netrw_curdir."/".tgt +" s:NetrwSLeftdrag: invoked via a shift-leftmouse and dragging {{{2 +" Used to mark multiple files. +fun! s:NetrwSLeftdrag(islocal) +" call Dfunc("s:NetrwSLeftdrag(islocal=".a:islocal.")") + if !exists("s:netrwdrag") + let s:netrwdrag = winnr() + if a:islocal + nno :call NetrwSLeftrelease(1) else - let tgt= b:netrw_curdir + nno :call NetrwSLeftrelease(0) + endif + endif + let ngw = s:NetrwGetWord() + if !exists("s:ngw") || s:ngw != ngw + call s:NetrwMarkFile(a:islocal,ngw) + endif + let s:ngw= ngw +" call Dret("s:NetrwSLeftdrag : s:netrwdrag=".s:netrwdrag." buf#".bufnr("%")) +endfun + +" --------------------------------------------------------------------- +" s:NetrwSLeftrelease: terminates shift-leftmouse dragging {{{2 +fun! s:NetrwSLeftrelease(islocal) +" call Dfunc("s:NetrwSLeftrelease(islocal=".a:islocal.") s:netrwdrag=".s:netrwdrag." buf#".bufnr("%")) + if exists("s:netrwdrag") + nunmap + let ngw = s:NetrwGetWord() + if !exists("s:ngw") || s:ngw != ngw + call s:NetrwMarkFile(a:islocal,ngw) + endif + if exists("s:ngw") + unlet s:ngw endif -" call Decho("target#2: ".tgt) - call netrw#NetrwMakeTgt(tgt) - let curwin= winnr() - exe s:netrwdrag."wincmd w" - call s:NetrwMarkFileMove(a:islocal) - exe curwin."wincmd w" unlet s:netrwdrag endif -" call Dret("s:NetrwRightrelease") +" call Dret("s:NetrwSLeftrelease") endfun " --------------------------------------------------------------------- @@ -5232,7 +5399,11 @@ fun! s:NetrwMakeDir(usrhost) " requested new local directory is neither a pre-existing file or " directory, so make it! if exists("*mkdir") - call mkdir(fullnewdir,"p") + if has("unix") + call mkdir(fullnewdir,"p",xor(0777, system("umask"))) + else + call mkdir(fullnewdir,"p") + endif else let netrw_origdir= s:NetrwGetcwd(1) exe 'keepj lcd '.fnameescape(b:netrw_curdir) @@ -5933,6 +6104,7 @@ fun! s:NetrwMarkFileVimCmd(islocal) exe cmd exe "sil! keepalt wq!" else + " COMBAK -- not supported yet " call Decho("remote<".fname.">: exe ".cmd." : NOT SUPPORTED YET") echo "sorry, \"mX\" not supported yet for remote files" endif @@ -6284,7 +6456,7 @@ fun! s:NetrwMarkFileRegexp(islocal) sil keepj %s/\s\{2,}/\r/ge call histdel("/",-1) elseif g:netrw_liststyle == s:TREELIST - sil keepj %s/^| //e + exe 'sil keepj %s/^'.s:treedepthstring.' //e' sil! keepj g/^ .*$/d call histdel("/",-1) call histdel("/",-1) @@ -6707,93 +6879,100 @@ endfun " choice = 2 : didn't save modified file, opened window " choice = 3 : cancel open fun! s:NetrwPrevWinOpen(islocal) -" call Dfunc("NetrwPrevWinOpen(islocal=".a:islocal.")") +" call Dfunc("s:NetrwPrevWinOpen(islocal=".a:islocal.")") let ykeep= @@ " grab a copy of the b:netrw_curdir to pass it along to newly split windows let curdir = b:netrw_curdir " get last window number and the word currently under the cursor + let origwin = winnr() let lastwinnr = winnr("$") let curword = s:NetrwGetWord() let choice = 0 -" call Decho("lastwinnr=".lastwinnr." curword<".curword.">") + let s:treedir = s:NetrwTreeDir() +" call Decho("(s:NetrwPrevWinOpen) winnr($)#".lastwinnr." curword<".curword.">") - let didsplit = 0 + let didsplit = 0 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.")") +" call Decho("(s:NetrwPrevWinOpen) only one window, so open a new one (g:netrw_alto=".g:netrw_alto.")") if g:netrw_preview let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize -" call Decho("exe ".(g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s") +" call Decho("(s:NetrwPrevWinOpen) exe ".(g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s") exe (g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s" else let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize -" call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s") +" call Decho("(s:NetrwPrevWinOpen) exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s") exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s" endif - let didsplit = 1 + let didsplit = 1 +" call Decho("(s:NetrwPrevWinOpen) did split") else keepj call s:SaveBufVars() -" call Decho("wincmd p") + let eikeep= &ei + set ei=all wincmd p +" call Decho("(s:NetrwPrevWinOpen) wincmd p (now in win#".winnr().")") + + " prevwinnr: the window number of the "prev" window + " prevbufnr: the buffer number of the buffer in the "prev" window + " bnrcnt : the qty of windows open on the "prev" buffer + let prevwinnr = winnr() + let prevbufnr = bufnr("%") + let prevbufname = bufname("%") + let prevmod = &mod + let bnrcnt = 0 keepj call s:RestoreBufVars() - " if the previous window's buffer has been changed (is modified), +" call Decho("(s:NetrwPrevWinOpen) after wincmd p: win#".winnr()." win($)#".winnr("$")." origwin#".origwin." &mod=".&mod." bufname(%)<".bufname("%")."> prevbufnr=".prevbufnr) + + " if the previous window's buffer has been changed (ie. its modified flag is set), " and it doesn't appear in any other extant window, then ask the " user if s/he wants to abandon modifications therein. - let bnr = winbufnr(0) - let bnrcnt = 0 - if &mod -" call Decho("detected: prev window's buffer has been modified: bnr=".bnr." winnr#".winnr()) - let eikeep= &ei - set ei=all - windo if winbufnr(0) == bnr | let bnrcnt=bnrcnt+1 | endif - exe bnr."wincmd p" - let &ei= eikeep -" call Decho("bnr=".bnr." bnrcnt=".bnrcnt." buftype=".&bt." winnr#".winnr()) - if bnrcnt == 1 - let bufname = bufname(winbufnr(winnr())) - let choice = confirm("Save modified file<".bufname.">?","&Yes\n&No\n&Cancel") -" call Decho("bufname<".bufname."> choice=".choice." winnr#".winnr()) + if prevmod +" call Decho("(s:NetrwPrevWinOpen) detected that prev window's buffer has been modified: prevbufnr=".prevbufnr." winnr()#".winnr()) + windo if winbufnr(0) == prevbufnr | let bnrcnt=bnrcnt+1 | endif +" call Decho("(s:NetrwPrevWinOpen) prevbufnr=".prevbufnr." bnrcnt=".bnrcnt." buftype=".&bt." winnr()=".winnr()." prevwinnr#".prevwinnr) + exe prevwinnr."wincmd w" + + if bnrcnt == 1 && &hidden == 0 + " 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()) + let &ei= eikeep if choice == 1 " Yes -- write file & then browse let v:errmsg= "" sil w if v:errmsg != "" - call netrw#ErrorMsg(s:ERROR,"unable to write <".bufname.">!",30) - if didsplit - q - else - wincmd p - endif - let @@= ykeep -" call Dret("NetrwPrevWinOpen ".choice." : unable to write <".bufname.">") + call netrw#ErrorMsg(s:ERROR,"unable to write <".prevbufname.">!",30) + exe origwin."wincmd w" + let &ei = eikeep + let @@ = ykeep +" call Dret("s:NetrwPrevWinOpen ".choice." : unable to write <".prevbufname.">") return choice endif elseif choice == 2 " No -- don't worry about changed file, just browse anyway -" call Decho("(NetrwPrevWinOpen) setl nomod") - setl nomod -" call Decho("(NetrwPrevWinOpen) ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)") - keepj call netrw#ErrorMsg(s:WARNING,bufname." changes to ".bufname." abandoned",31) - wincmd p +" call Decho("(s:NetrwPrevWinOpen) don't worry about chgd file, just browse anyway (winnr($)#".winnr("$").")") + echomsg "**note** changes to ".prevbufname." abandoned" else " Cancel -- don't do this - if didsplit - q - else - wincmd p - endif - let @@= ykeep -" call Dret("NetrwPrevWinOpen ".choice." : cancelled") +" call Decho("(s:NetrwPrevWinOpen) cancel, don't browse, switch to win#".origwin) + exe origwin."wincmd w" + let &ei= eikeep + let @@ = ykeep +" call Dret("s:NetrwPrevWinOpen ".choice." : cancelled") return choice endif endif endif + let &ei= eikeep endif " restore b:netrw_curdir (window split/enew may have lost it) @@ -6806,7 +6985,7 @@ fun! s:NetrwPrevWinOpen(islocal) endif endif let @@= ykeep -" call Dret("NetrwPrevWinOpen ".choice) +" call Dret("s:NetrwPrevWinOpen ".choice) return choice endfun @@ -7269,13 +7448,29 @@ fun! s:NetrwSplit(mode) elseif a:mode == 4 " local and t let cursorword = s:NetrwGetWord() + let eikeep = &ei + let netrw_winnr = winnr() + let netrw_line = line(".") + let netrw_col = virtcol(".") + keepj norm! H0 + let netrw_hline = line(".") + set ei=all + exe "keepj norm! ".netrw_hline."G0z\" + exe "keepj norm! ".netrw_line."G0".netrw_col."\" + let &ei= eikeep let netrw_curdir= s:NetrwTreeDir() " call Decho("tabnew") tabnew - let b:netrw_curdir= netrw_curdir - let s:didsplit= 1 + let b:netrw_curdir = netrw_curdir + let s:didsplit = 1 keepj call s:RestoreWinVars() keepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,cursorword)) + if &ft == "netrw" + set ei=all + exe "keepj norm! ".netrw_hline."G0z\" + exe "keepj norm! ".netrw_line."G0".netrw_col."\" + let &ei= eikeep + endif unlet s:didsplit elseif a:mode == 5 @@ -7350,60 +7545,57 @@ endfun " s:NetrwTreeDir: determine tree directory given current cursor position {{{2 " (full path directory with trailing slash returned) fun! s:NetrwTreeDir() -" call Dfunc("NetrwTreeDir() curline#".line(".")."<".getline('.')."> b:netrw_curdir<".b:netrw_curdir."> tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%").">") +" call Dfunc("s:NetrwTreeDir() getline(".line(".").")"."<".getline('.')."> b:netrw_curdir<".b:netrw_curdir."> tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> ft=".&ft) - let treedir= b:netrw_curdir -" call Decho("(NetrwTreeDir) set initial treedir<".treedir.">") + if exists("s:treedir") + " s:NetrwPrevWinOpen opens a "previous" window -- and thus needs to and does call s:NetrwTreeDir early + let treedir= s:treedir + unlet s:treedir +" call Dret("s:NetrwTreeDir ".treedir) + return treedir + endif + if !exists("b:netrw_curdir") || b:netrw_curdir == "" + let b:netrw_curdir= getcwd() + endif + let treedir = b:netrw_curdir +" call Decho("(s:NetrwTreeDir) set initial treedir<".treedir.">") let s:treecurpos= netrw#NetrwSavePosn() if w:netrw_liststyle == s:TREELIST -" call Decho("(NetrwTreeDir) w:netrw_liststyle is TREELIST:") -" call Decho("(NetrwTreeDir) line#".line(".")." getline(.)<".getline('.')."> treecurpos<".string(s:treecurpos).">") +" call Decho("(s:NetrwTreeDir) w:netrw_liststyle is TREELIST:") +" call Decho("(s:NetrwTreeDir) line#".line(".")." getline(.)<".getline('.')."> treecurpos<".string(s:treecurpos).">") " extract tree directory if on a line specifying a subdirectory (ie. ends with "/") if getline('.') =~ '/$' - let treedir= substitute(getline('.'),'^\%(| \)*\([^|].\{-}\)$','\1','e') +" call Decho("extract tree subdirectory from current line") + let treedir= substitute(getline('.'),'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e') +" call Decho("(s:NetrwTreeDir) treedir<".treedir.">") else +" call Decho("(s:NetrwTreeDir) do not extract tree subdirectory from current line and set treedir to empty") let treedir= "" endif -" call Decho("(NetrwTreeDir) treedir<".treedir.">") " detect user attempting to close treeroot - if getline('.') !~ '|' && getline('.') != '..' -" call Decho("user attempted to close treeroot") +" call Decho("(s:NetrwTreeDir) win#".winnr()." buf#".bufnr("%")."<".bufname("%").">") +" call Decho("(s:NetrwTreeDir) getline(".line(".").")<".getline('.').'> '.((getline('.') =~ '^'.s:treedepthstring)? '=~' : '!~').' ^'.s:treedepthstring) + if getline('.') !~ '^'.s:treedepthstring && getline('.') != '..' +" call Decho("user may have attempted to close treeroot") " now force a refresh -" call Decho("(NetrwTreeDir) clear buffer<".expand("%")."> with :%d") +" call Decho("(s:NetrwTreeDir) clear buffer<".expand("%")."> with :%d") sil! keepj %d -" call Dret("NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".string(s:treecurpos).">") +" call Dret("s:NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".string(s:treecurpos).">") return b:netrw_curdir +" else " Decho +" call Decho("user did not attempt to close treeroot") endif - " elide all non-depth information - let depth = substitute(getline('.'),'^\(\%(| \)*\)[^|].\{-}$','\1','e') -" call Decho("(NetrwTreeDir) depth<".depth."> 1st subst (non-depth info removed)") - - " elide first depth - let depth = substitute(depth,'^| ','','') -" call Decho("(NetrwTreeDir) depth<".depth."> 2nd subst (first depth removed)") - - " construct treedir by searching backwards at correct depth -" call Decho("(NetrwTreeDir) constructing treedir<".treedir."> depth<".depth.">") - while depth != "" && search('^'.depth.'[^|].\{-}/$','bW') - let dirname= substitute(getline('.'),'^\(| \)*','','e') - let treedir= dirname.treedir - let depth = substitute(depth,'^| ','','') -" call Decho("(NetrwTreeDir) constructing treedir<".treedir.">: dirname<".dirname."> while depth<".depth.">") - endwhile - if w:netrw_treetop =~ '/$' - let treedir= w:netrw_treetop.treedir - else - let treedir= w:netrw_treetop.'/'.treedir - endif -" call Decho("(NetrwTreeDir) bufnr(.)=".bufnr("%")." line($)=".line("$")." line(.)=".line(".")) + let treedir= s:NetrwTreePath(w:netrw_treetop) endif + + " sanity maintenance: keep those //s away... let treedir= substitute(treedir,'//$','/','') -" call Dret("NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".string(s:treecurpos).">") +" call Dret("s:NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".string(s:treecurpos).">") return treedir endfun @@ -7440,7 +7632,7 @@ fun! s:NetrwTreeDisplay(dir,depth) endif " display subtrees (if any) - let depth= "| ".a:depth + let depth= s:treedepthstring.a:depth " call Decho("display subtrees with depth<".depth."> and current leaves") for entry in w:netrw_treedict[a:dir] @@ -7457,6 +7649,7 @@ fun! s:NetrwTreeDisplay(dir,depth) sil! keepj call setline(line("$")+1,depth.entry) endif endfor + " call Dret("NetrwTreeDisplay") endfun @@ -7465,17 +7658,18 @@ endfun fun! s:NetrwTreeListing(dirname) if w:netrw_liststyle == s:TREELIST " call Dfunc("NetrwTreeListing() bufname<".expand("%").">") -" call Decho("curdir<".a:dirname.">") -" call Decho("win#".winnr().": w:netrw_treetop ".(exists("w:netrw_treetop")? "exists" : "doesn't exit")." w:netrw_treedict ".(exists("w:netrw_treedict")? "exists" : "doesn't exit")) +" call Decho("(s:NetrwTreeListing) curdir<".a:dirname.">") +" call Decho("(s:NetrwTreeListing) win#".winnr().": w:netrw_treetop ".(exists("w:netrw_treetop")? "exists" : "doesn't exist")." w:netrw_treedict ".(exists("w:netrw_treedict")? "exists" : "doesn't exit")) +" call Decho("(s:NetrwTreeListing) g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")") " update the treetop -" call Decho("update the treetop") +" call Decho("(s:NetrwTreeListing) update the treetop") if !exists("w:netrw_treetop") let w:netrw_treetop= a:dirname -" call Decho("w:netrw_treetop<".w:netrw_treetop."> (reusing)") +" call Decho("(s:NetrwTreeListing) w:netrw_treetop<".w:netrw_treetop."> (reusing)") elseif (w:netrw_treetop =~ ('^'.a:dirname) && s:Strlen(a:dirname) < s:Strlen(w:netrw_treetop)) || a:dirname !~ ('^'.w:netrw_treetop) let w:netrw_treetop= a:dirname -" call Decho("w:netrw_treetop<".w:netrw_treetop."> (went up)") +" call Decho("(s:NetrwTreeListing) w:netrw_treetop<".w:netrw_treetop."> (went up)") endif " insure that we have at least an empty treedict @@ -7484,11 +7678,11 @@ fun! s:NetrwTreeListing(dirname) endif " update the directory listing for the current directory -" call Decho("updating dictionary with ".a:dirname.":[..directory listing..]") -" call Decho("bannercnt=".w:netrw_bannercnt." line($)=".line("$")) +" call Decho("(s:NetrwTreeListing) updating dictionary with ".a:dirname.":[..directory listing..]") +" call Decho("(s:NetrwTreeListing) w:netrw_bannercnt=".w:netrw_bannercnt." line($)=".line("$")) exe "sil! keepj ".w:netrw_bannercnt.',$g@^\.\.\=/$@d' let w:netrw_treedict[a:dirname]= getline(w:netrw_bannercnt,line("$")) -" call Decho("w:treedict[".a:dirname."]= ".string(w:netrw_treedict[a:dirname])) +" call Decho("(s:NetrwTreeListing) w:treedict[".a:dirname."]= ".string(w:netrw_treedict[a:dirname])) exe "sil! keepj ".w:netrw_bannercnt.",$d" " if past banner, record word @@ -7497,10 +7691,20 @@ fun! s:NetrwTreeListing(dirname) else let fname= "" endif -" call Decho("fname<".fname.">") +" call Decho("(s:NetrwTreeListing) fname<".fname.">") +" call Decho("(s:NetrwTreeListing) g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")") " display from treetop on down keepj call s:NetrwTreeDisplay(w:netrw_treetop,"") +" call Decho("s:NetrwTreeDisplay) setl noma nomod ro") + + " remove any blank line remaining as line#1 (happens in treelisting mode with banner suppressed) + while getline(1) =~ '^\s*$' && byte2line(1) > 0 +" call Decho("(s:PerformListing) deleting blank line") + 1d + endwhile + + setl noma nomod ro " call Dret("NetrwTreeListing : bufname<".expand("%").">") return @@ -7578,16 +7782,53 @@ fun! s:NetrwWideListing() endfun +" --------------------------------------------------------------------- +" s:NetrwTreePath: returns path to current file in tree listing {{{2 +" Normally, treetop is w:netrw_treetop, but a +" user of this function ( netrw#NetrwSetTreetop() ) +" wipes that out prior to calling this function +fun! s:NetrwTreePath(treetop) +" call Dfunc("s:NetrwTreePath()") + let depth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e') + let depth = substitute(depth,'^'.s:treedepthstring,'','') +" call Decho("(s:NetrwTreePath) depth<".depth."> 2nd subst (first depth removed)") + if getline('.') =~ '/$' +" call Decho("extract tree directory from current line") + let treedir= substitute(getline('.'),'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e') +" call Decho("(s:NetrwTreePath) treedir<".treedir.">") + else +" call Decho("(s:NetrwTreePath) do not extract tree directory from current line and set treedir to empty") + let treedir= "" + endif + " construct treedir by searching backwards at correct depth +" call Decho("(s:NetrwTreePath) initial treedir<".treedir."> depth<".depth.">") + while depth != "" && search('^'.depth.'[^'.s:treedepthstring.'].\{-}/$','bW') + let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e') + let treedir= dirname.treedir + let depth = substitute(depth,'^'.s:treedepthstring,'','') +" call Decho("(s:NetrwTreePath) constructing treedir<".treedir.">: dirname<".dirname."> while depth<".depth.">") + endwhile + if a:treetop =~ '/$' + let treedir= a:treetop.treedir + else + let treedir= a:treetop.'/'.treedir + endif + let treedir= substitute(treedir,'//$','/','') +" call Dret("s:NetrwTreePath <".treedir.">") + return treedir +endfun + " --------------------------------------------------------------------- " s:PerformListing: {{{2 fun! s:PerformListing(islocal) " call Dfunc("s:PerformListing(islocal=".a:islocal.") bufnr(%)=".bufnr("%")."<".bufname("%").">") +" call Decho("(s:PerformListing) 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. " (enter)") " set up syntax highlighting {{{3 -" call Decho("(PerformListing) set up syntax highlighting") +" call Decho("(s:PerformListing) set up syntax highlighting") if has("syntax") if !exists("g:syntax_on") || !g:syntax_on -" call Decho("(PerformListing) but g:syntax_on".(exists("g:syntax_on")? "=".g:syntax_on : "")) +" call Decho("(s:PerformListing) but g:syntax_on".(exists("g:syntax_on")? "=".g:syntax_on : "")) setl ft= elseif &ft != "netrw" setl ft=netrw @@ -7596,16 +7837,16 @@ fun! s:PerformListing(islocal) keepj call s:NetrwSafeOptions() set noro ma -" call Decho("(PerformListing) setl noro ma bh=".&bh) +" call Decho("(s:PerformListing) setl noro ma bh=".&bh) " if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1 " Decho -" call Decho("(PerformListing) (netrw) Processing your browsing request...") +" call Decho("(s:PerformListing) (netrw) Processing your browsing request...") " endif " Decho " call Decho('w:netrw_liststyle='.(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a')) if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") " force a refresh for tree listings -" call Decho("(PerformListing) force refresh for treelisting: clear buffer<".expand("%")."> with :%d") +" call Decho("(s:PerformListing) force refresh for treelisting: clear buffer<".expand("%")."> with :%d") sil! keepj %d endif @@ -7614,7 +7855,7 @@ fun! s:PerformListing(islocal) " Set up the banner {{{3 if g:netrw_banner -" call Decho("(PerformListing) set up banner") +" call Decho("(s:PerformListing) set up banner") keepj call setline(1,'" ============================================================================') keepj call setline(2,'" Netrw Directory Listing (netrw '.g:loaded_netrw.')') if exists("g:netrw_bannerbackslash") && g:netrw_bannerbackslash @@ -7636,26 +7877,28 @@ fun! s:PerformListing(islocal) " Sorted by... {{{3 if g:netrw_banner -" call Decho("(PerformListing) handle specified sorting: g:netrw_sort_by<".g:netrw_sort_by.">") +" call Decho("(s:PerformListing) handle specified sorting: g:netrw_sort_by<".g:netrw_sort_by.">") if g:netrw_sort_by =~ "^n" -" call Decho("(PerformListing) directories will be sorted by name") +" call Decho("(s:PerformListing) directories will be sorted by name") " sorted by name keepj put ='\" Sorted by '.sortby keepj put ='\" Sort sequence: '.g:netrw_sort_sequence let w:netrw_bannercnt= w:netrw_bannercnt + 2 else -" call Decho("(PerformListing) directories will be sorted by size or time") +" call Decho("(s:PerformListing) directories will be sorted by size or time") " sorted by size or date keepj put ='\" Sorted by '.sortby let w:netrw_bannercnt= w:netrw_bannercnt + 1 endif exe "sil! keepj ".w:netrw_bannercnt +" else " Decho +" call Decho("(s:PerformListing) g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")") endif " show copy/move target, if any if g:netrw_banner if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal") -" call Decho("(PerformListing) show copy/move target<".s:netrwmftgt.">") +" call Decho("(s:PerformListing) show copy/move target<".s:netrwmftgt.">") keepj put ='' if s:netrwmftgt_islocal sil! keepj call setline(line("."),'" Copy/Move Tgt: '.s:netrwmftgt.' (local)') @@ -7664,14 +7907,14 @@ fun! s:PerformListing(islocal) endif let w:netrw_bannercnt= w:netrw_bannercnt + 1 else -" call Decho("(PerformListing) s:netrwmftgt does not exist, don't make Copy/Move Tgt") +" call Decho("(s:PerformListing) s:netrwmftgt does not exist, don't make Copy/Move Tgt") endif exe "sil! keepj ".w:netrw_bannercnt endif " Hiding... -or- Showing... {{{3 if g:netrw_banner -" call Decho("(PerformListing) handle hiding/showing (g:netrw_hide=".g:netrw_list_hide." g:netrw_list_hide<".g:netrw_list_hide.">)") +" call Decho("(s:PerformListing) handle hiding/showing (g:netrw_hide=".g:netrw_list_hide." g:netrw_list_hide<".g:netrw_list_hide.">)") if g:netrw_list_hide != "" && g:netrw_hide if g:netrw_hide == 1 keepj put ='\" Hiding: '.g:netrw_list_hide @@ -7684,44 +7927,48 @@ fun! s:PerformListing(islocal) keepj put ='\" Quick Help: :help -:go up dir D:delete R:rename s:sort-by x:exec' keepj put ='\" ============================================================================' let w:netrw_bannercnt= w:netrw_bannercnt + 2 +" else " Decho +" call Decho("(s:PerformListing) g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")") endif " bannercnt should index the line just after the banner if g:netrw_banner let w:netrw_bannercnt= w:netrw_bannercnt + 1 exe "sil! keepj ".w:netrw_bannercnt -" call Decho("(PerformListing) w:netrw_bannercnt=".w:netrw_bannercnt." (should index line just after banner) line($)=".line("$")) +" call Decho("(s:PerformListing) w:netrw_bannercnt=".w:netrw_bannercnt." (should index line just after banner) line($)=".line("$")) +" else " Decho +" call Decho("(s:PerformListing) g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")") endif " get list of files -" call Decho("(PerformListing) Get list of files - islocal=".a:islocal) +" call Decho("(s:PerformListing) Get list of files - islocal=".a:islocal) if a:islocal keepj call s:LocalListing() else " remote keepj call s:NetrwRemoteListing() endif +" call Decho("(s:PerformListing) g:netrw_banner=".g:netrw_banner." w:netrw_bannercnt=".w:netrw_bannercnt." (banner complete)") +" call Decho("(s:PerformListing) g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")") " manipulate the directory listing (hide, sort) {{{3 if !exists("w:netrw_bannercnt") let w:netrw_bannercnt= 0 endif -" call Decho("(PerformListing) g:netrw_banner=".g:netrw_banner." w:netrw_bannercnt=".w:netrw_bannercnt." (banner complete)") - if !g:netrw_banner || line("$") >= w:netrw_bannercnt -" call Decho("(PerformListing) manipulate directory listing (hide)") -" call Decho("(PerformListing) g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">") +" call Decho("(s:PerformListing) manipulate directory listing (hide)") +" call Decho("(s:PerformListing) g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">") if g:netrw_hide && g:netrw_list_hide != "" keepj call s:NetrwListHide() endif if !g:netrw_banner || line("$") >= w:netrw_bannercnt -" call Decho("(PerformListing) manipulate directory listing (sort) : g:netrw_sort_by<".g:netrw_sort_by.">") +" call Decho("(s:PerformListing) manipulate directory listing (sort) : g:netrw_sort_by<".g:netrw_sort_by.">") if g:netrw_sort_by =~ "^n" " sort by name keepj call s:NetrwSetSort() if !g:netrw_banner || w:netrw_bannercnt < line("$") -" call Decho("(PerformListing) g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")") +" call Decho("(s:PerformListing) g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")") if g:netrw_sort_direction =~ 'n' " normal direction sorting exe 'sil keepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options @@ -7731,13 +7978,13 @@ fun! s:PerformListing(islocal) endif endif " remove priority pattern prefix -" call Decho("(PerformListing) remove priority pattern prefix") +" call Decho("(s:PerformListing) remove priority pattern prefix") exe 'sil! keepj '.w:netrw_bannercnt.',$s/^\d\{3}'.g:netrw_sepchr.'//e' keepj call histdel("/",-1) elseif a:islocal if !g:netrw_banner || w:netrw_bannercnt < line("$") -" call Decho("(PerformListing) g:netrw_sort_direction=".g:netrw_sort_direction) +" call Decho("(s:PerformListing) g:netrw_sort_direction=".g:netrw_sort_direction) if g:netrw_sort_direction =~ 'n' " call Decho('exe sil keepjumps '.w:netrw_bannercnt.',$sort') exe 'sil! keepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options @@ -7751,47 +7998,57 @@ fun! s:PerformListing(islocal) endif elseif g:netrw_sort_direction =~ 'r' -" call Decho('reverse the sorted listing') +" call Decho('(s:PerformListing) reverse the sorted listing') if !g:netrw_banner || w:netrw_bannercnt < line('$') exe 'sil! keepj '.w:netrw_bannercnt.',$g/^/m '.w:netrw_bannercnt call histdel("/",-1) endif endif endif +" call Decho("(s:PerformListing) g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")") " convert to wide/tree listing {{{3 -" call Decho("(PerformListing) modify display if wide/tree listing style") +" call Decho("(s:PerformListing) modify display if wide/tree listing style") +" call Decho("(s:PerformListing) 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#1)") keepj call s:NetrwWideListing() +" call Decho("(s:PerformListing) 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#2)") keepj call s:NetrwTreeListing(b:netrw_curdir) +" call Decho("(s:PerformListing) 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#3)") if exists("w:netrw_bannercnt") && (line("$") > w:netrw_bannercnt || !g:netrw_banner) " place cursor on the top-left corner of the file listing -" call Decho("(PerformListing) place cursor on top-left corner of file listing") +" call Decho("(s:PerformListing) place cursor on top-left corner of file listing") exe 'sil! keepj '.w:netrw_bannercnt sil! keepj norm! 0 endif " record previous current directory let w:netrw_prvdir= b:netrw_curdir -" call Decho("(PerformListing) record netrw_prvdir<".w:netrw_prvdir.">") +" call Decho("(s:PerformListing) record netrw_prvdir<".w:netrw_prvdir.">") " save certain window-oriented variables into buffer-oriented variables {{{3 +" call Decho("(s:PerformListing) 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)") keepj call s:SetBufWinVars() +" call Decho("(s:PerformListing) 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)") keepj call s:NetrwOptionRestore("w:") +" call Decho("(s:PerformListing) 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)") " set display to netrw display settings -" call Decho("(PerformListing) set display to netrw display settings (".g:netrw_bufsettings.")") +" call Decho("(s:PerformListing) set display to netrw display settings (".g:netrw_bufsettings.")") exe "setl ".g:netrw_bufsettings +" call Decho("(s:PerformListing) 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#7)") if g:netrw_liststyle == s:LONGLIST -" call Decho("(PerformListing) exe setl ts=".(g:netrw_maxfilenamelen+1)) +" call Decho("(s:PerformListing) exe setl ts=".(g:netrw_maxfilenamelen+1)) exe "setl ts=".(g:netrw_maxfilenamelen+1) endif - if exists("s:treecurpos") + if exists("s:treecurpos") +" call Decho("(s:PerformListing) 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#8)") keepj call netrw#NetrwRestorePosn(s:treecurpos) unlet s:treecurpos endif +" call Decho("(s:PerformListing) 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. " (return)") " call Dret("s:PerformListing : curpos<".string(getpos(".")).">") endfun @@ -7848,18 +8105,10 @@ fun! s:NetrwRemoteListing() " call Dfunc("s:NetrwRemoteListing() b:netrw_curdir<".b:netrw_curdir.">)") call s:RemotePathAnalysis(b:netrw_curdir) -" call Decho("b:netrw_method#".(exists("b:netrw_method")? b:netrw_method : 'n/a')) -" call Decho("g:netrw_list_cmd<".(exists("g:netrw_list_cmd")? g:netrw_list_cmd : 'n/a').">") -" call Decho("ssh is ".(executable("ssh")? "" : "not ")."executable") -" call Decho("ftp is ".(executable("ftp")? "" : "not ")."executable") -" call Decho("sftp is ".(executable("sftp")? "" : "not ")."executable") " sanity check: if exists("b:netrw_method") && b:netrw_method =~ '[235]' - " b:netrw_method = 2: ftp+.netrc - " b:netrw_method = 3: ftp+machine,id,p/w,filename (ie. no .netrc) - " b:netrw_method = 5: wget (http) -" call Decho("b:netrw_method=".b:netrw_method." (for ".s:method.")") +" call Decho("b:netrw_method=".b:netrw_method) if !executable("ftp") if !exists("g:netrw_quiet") call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ftp",18) @@ -7869,11 +8118,10 @@ fun! s:NetrwRemoteListing() return endif - elseif s:method == "scp" && (!exists("g:netrw_list_cmd") || g:netrw_list_cmd == '') -" call Decho("g:netrw_list_cmd<".(exists("g:netrw_list_cmd")? g:netrw_list_cmd : 'n/a').">") + elseif !exists("g:netrw_list_cmd") || g:netrw_list_cmd == '' if !exists("g:netrw_quiet") - if !exists("g:netrw_list_cmd") || g:netrw_list_cmd == "" - keepj call netrw#ErrorMsg(s:ERROR,"neither ssh nor ftp"." is executable on your system",47) + if g:netrw_list_cmd == "" + keepj call netrw#ErrorMsg(s:ERROR,g:netrw_ssh_cmd." is not executable on your system",47) else keepj call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ".g:netrw_list_cmd,19) endif @@ -7889,11 +8137,11 @@ fun! s:NetrwRemoteListing() let w:netrw_method= b:netrw_method endif - if s:method == "ftp" + if s:method == "ftp" || s:method == "sftp" " use ftp to get remote file listing {{{3 " call Decho("use ftp to get remote file listing") - let s:method = "ftp" - let listcmd = g:netrw_ftp_list_cmd + let s:method = "ftp" + let listcmd = g:netrw_ftp_list_cmd if g:netrw_sort_by =~ '^t' let listcmd= g:netrw_ftp_timelist_cmd elseif g:netrw_sort_by =~ '^s' @@ -8197,6 +8445,7 @@ endfun fun! s:NetrwRemoteFtpCmd(path,listcmd) " call Dfunc("NetrwRemoteFtpCmd(path<".a:path."> listcmd<".a:listcmd.">) w:netrw_method=".(exists("w:netrw_method")? w:netrw_method : (exists("b:netrw_method")? b:netrw_method : "???"))) " call Decho("line($)=".line("$")." w:netrw_bannercnt=".w:netrw_bannercnt) + " sanity check: {{{3 if !exists("w:netrw_method") if exists("b:netrw_method") let w:netrw_method= b:netrw_method @@ -8207,18 +8456,18 @@ fun! s:NetrwRemoteFtpCmd(path,listcmd) endif endif - " because WinXX ftp uses unix style input + " WinXX ftp uses unix style input, so set ff to unix " {{{3 let ffkeep= &ff setl ma ff=unix noro " call Decho("setl ma ff=unix noro") - " clear off any older non-banner lines + " clear off any older non-banner lines " {{{3 " note that w:netrw_bannercnt indexes the line after the banner " call Decho('exe sil! keepjumps '.w:netrw_bannercnt.",$d (clear off old non-banner lines)") exe "sil! keepjumps ".w:netrw_bannercnt.",$d" "......................................... - if w:netrw_method == 2 || w:netrw_method == 5 + if w:netrw_method == 2 || w:netrw_method == 5 " {{{3 " ftp + <.netrc>: Method #2 if a:path != "" keepj put ='cd \"'.a:path.'\"' @@ -8237,8 +8486,8 @@ fun! s:NetrwRemoteFtpCmd(path,listcmd) exe s:netrw_silentxfer." keepj ".w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1) endif - "......................................... - elseif w:netrw_method == 3 + "......................................... + elseif w:netrw_method == 3 " {{{3 " ftp + machine,id,passwd,filename: Method #3 setl ff=unix if exists("g:netrw_port") && g:netrw_port != "" @@ -8281,12 +8530,24 @@ fun! s:NetrwRemoteFtpCmd(path,listcmd) " call Decho("exe ".s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." ".g:netrw_ftp_options) exe s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." ".g:netrw_ftp_options - "......................................... - else - keepj call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",23) + "......................................... + elseif w:netrw_method == 9 " {{{3 + " sftp username@machine: Method #9 + " s:netrw_sftp_cmd + setl ff=unix +" call Decho("COMBAK: still working on sftp remote listing") + + " restore settings + let &ff= ffkeep +" call Dret("NetrwRemoteFtpCmd") + return + + "......................................... + else " {{{3 + keepj call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . bufname("%") . ">",23) endif - " cleanup for Windows + " cleanup for Windows " {{{3 if has("win32") || has("win95") || has("win64") || has("win16") sil! keepj %s/\r$//e keepj call histdel("/",-1) @@ -8303,7 +8564,7 @@ fun! s:NetrwRemoteFtpCmd(path,listcmd) endif endif - " ftp's listing doesn't seem to include ./ or ../ + " ftp's listing doesn't seem to include ./ or ../ " {{{3 if !search('^\.\/$\|\s\.\/$','wn') exe 'keepj '.w:netrw_bannercnt keepj put ='./' @@ -8313,7 +8574,7 @@ fun! s:NetrwRemoteFtpCmd(path,listcmd) keepj put ='../' endif - " restore settings + " restore settings " {{{3 let &ff= ffkeep " call Dret("NetrwRemoteFtpCmd") endfun @@ -8457,23 +8718,31 @@ fun! netrw#LocalBrowseCheck(dirname) " would hit when re-entering netrw windows, creating unexpected " refreshes (and would do so in the middle of NetrwSaveOptions(), too) " call Decho("(LocalBrowseCheck) isdir<".a:dirname.">=".isdirectory(a:dirname).((exists("s:treeforceredraw")? " treeforceredraw" : ""))) -" call Dredir("LocalBrowseCheck","ls!")|redraw!|sleep 3 +" call Decho("(LocalBrowseCheck) 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) +" call Dredir("(LocalBrowseCheck) ls!","ls!") let ykeep= @@ if isdirectory(a:dirname) " call Decho("(LocalBrowseCheck) is-directory ft<".&ft."> b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : " doesn't exist")."> dirname<".a:dirname.">"." line($)=".line("$")." ft<".&ft."> g:netrw_fastbrowse=".g:netrw_fastbrowse) let svposn= netrw#NetrwSavePosn() if &ft != "netrw" || (exists("b:netrw_curdir") && b:netrw_curdir != a:dirname) || g:netrw_fastbrowse <= 1 +" call Decho("(LocalBrowseCheck) case 1 (ft!=netrw)") sil! keepj keepalt call s:NetrwBrowse(1,a:dirname) keepalt call netrw#NetrwRestorePosn(svposn) + elseif &ft == "netrw" && line("$") == 1 +" call Decho("(LocalBrowseCheck) case 2 (ft==netrw)") sil! keepj keepalt call s:NetrwBrowse(1,a:dirname) keepalt call netrw#NetrwRestorePosn(svposn) + elseif exists("s:treeforceredraw") +" call Decho("(LocalBrowseCheck) case 3 (treeforceredraw)") unlet s:treeforceredraw sil! keepj keepalt call s:NetrwBrowse(1,a:dirname) keepalt call netrw#NetrwRestorePosn(svposn) endif + endif + " 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 @@ -8488,6 +8757,7 @@ fun! netrw#LocalBrowseCheck(dirname) endwhile endif let @@= ykeep +" call Decho("(LocalBrowseCheck) 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) " not a directory, ignore it endfun @@ -8500,10 +8770,11 @@ fun! s:LocalListing() " if exists("b:netrw_curdir") |call Decho('(LocalListing) b:netrw_curdir<'.b:netrw_curdir.">") |else|call Decho("(LocalListing) b:netrw_curdir doesn't exist") |endif " if exists("g:netrw_sort_by")|call Decho('(LocalListing) g:netrw_sort_by<'.g:netrw_sort_by.">")|else|call Decho("(LocalListing) g:netrw_sort_by doesn't exist")|endif +" call Decho("(s:LocalListing) g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")") " get the list of files contained in the current directory let dirname = b:netrw_curdir - let dirnamelen = s:Strlen(b:netrw_curdir) + let dirnamelen = strlen(b:netrw_curdir) let filelist = glob(s:ComposePath(dirname,"*"),0,1) let filelist = filelist + glob(s:ComposePath(dirname,".*"),0,1) " call Decho("(LocalListing) filelist=".filelist) @@ -8527,10 +8798,11 @@ fun! s:LocalListing() " call Decho("(LocalListing) dynamic_maxfilenamelen: filenames =".string(filelistcopy)) " call Decho("(LocalListing) dynamic_maxfilenamelen: g:netrw_maxfilenamelen=".g:netrw_maxfilenamelen) endif +" call Decho("(s:LocalListing) g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")") for filename in filelist " call Decho("(LocalListing) ") -" call Decho("(LocalListing) (while) filename<".filename.">") +" call Decho("(LocalListing) for filename in filelist: filename<".filename.">") if getftype(filename) == "link" " indicate a symbolic link @@ -9012,7 +9284,7 @@ fun! netrw#WinPath(path) " call Dfunc("netrw#WinPath(path<".a:path.">)") if (!g:netrw_cygwin || &shell !~ '\%(\\|\\)\%(\.exe\)\=$') && (has("win32") || has("win95") || has("win64") || has("win16")) " remove cygdrive prefix, if present - let path = substitute(a:path,'/cygdrive/\(.\)','\1:','') + let path = substitute(a:path,g:netrw_cygdrive.'/\(.\)','\1:','') " remove trailing slash (Win95) let path = substitute(path, '\(\\\|/\)$', '', 'g') " remove escaped spaces @@ -9087,7 +9359,7 @@ fun! netrw#NetrwSavePosn() let ret = "let w:netrw_winnr=".w:netrw_winnr."|let w:netrw_line=".w:netrw_line."|let w:netrw_col=".w:netrw_col."|let w:netrw_hline=".w:netrw_hline keepj call netrw#NetrwRestorePosn() -" call Dret("netrw#NetrwSavePosn : winnr=".w:netrw_winnr." line=".w:netrw_line." col=".w:netrw_col." hline=".w:netrw_hline) +" call Dret("netrw#NetrwSavePosn : winnr=".(exists("w:netrw_winnr")? w:netrw_winnr : "n/a")." line=".(exists("w:netrw_line")? w:netrw_line : "n/a")." col=".(exists("w:netrw_col")? w:netrw_col : "n/a")." hline=".(exists("w:netrw_hline")? w:netrw_hline : "n/a")) return ret endfun @@ -9179,7 +9451,7 @@ fun! s:FileReadable(fname) " call Dfunc("s:FileReadable(fname<".a:fname.">)") if g:netrw_cygwin - let ret= filereadable(substitute(a:fname,'/cygdrive/\(.\)','\1:/','')) + let ret= filereadable(substitute(a:fname,g:netrw_cygdrive.'/\(.\)','\1:/','')) else let ret= filereadable(a:fname) endif @@ -9217,7 +9489,7 @@ fun! s:GetTempfile(fname) " o/s dependencies if g:netrw_cygwin != 0 - let tmpfile = substitute(tmpfile,'^\(\a\):','/cygdrive/\1','e') + let tmpfile = substitute(tmpfile,'^\(\a\):',g:netrw_cygdrive.'/\1','e') elseif has("win32") || has("win95") || has("win64") || has("win16") if !exists("+shellslash") || !&ssl let tmpfile = substitute(tmpfile,'/','\','g') @@ -9342,7 +9614,7 @@ fun! s:NetrwCursor() let &l:cursorcolumn = s:netrw_usercuc if w:netrw_liststyle == s:WIDELIST " call Decho("case g:netrw_cursor==2 and wide: setl cul (use user's cuc)") - set cursorline + setl cursorline else " call Decho("case g:netrw_cursor==2 and not wide: (use user's cul,cuc)") let &l:cursorline = s:netrw_usercul @@ -9361,7 +9633,7 @@ endfun " --------------------------------------------------------------------- " s:RestoreCursorline: restores cursorline/cursorcolumn to original user settings {{{2 fun! s:RestoreCursorline() -" call Dfunc("s:RestoreCursorline() currently, cul=".&l:cursorline." cuc=".&l:cursorcolumn." win#".winnr()." buf#".bufnr("%")." mod=".&mod) +" call Dfunc("s:RestoreCursorline() currently, cul=".&l:cursorline." cuc=".&l:cursorcolumn." win#".winnr()." buf#".bufnr("%")) if exists("s:netrw_usercul") let &l:cursorline = s:netrw_usercul endif @@ -9406,10 +9678,10 @@ endfun " 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 Decho("curdir<".((a:0>0)? a:1 : "")."> buf#".bufnr("%")."<".bufname("%").">") +" call Decho("(s:NetrwEnew) curdir<".((a:0>0)? a:1 : "")."> buf#".bufnr("%")."<".bufname("%").">") " grab a function-local-variable copy of buffer variables -" call Decho("make function-local copy of netrw variables") +" call Decho("(s:NetrwEnew) make function-local copy of netrw variables") if exists("b:netrw_bannercnt") |let netrw_bannercnt = b:netrw_bannercnt |endif if exists("b:netrw_browser_active") |let netrw_browser_active = b:netrw_browser_active |endif if exists("b:netrw_cpf") |let netrw_cpf = b:netrw_cpf |endif @@ -9428,15 +9700,15 @@ fun! s:NetrwEnew(...) if exists("b:netrw_prvdir") |let netrw_prvdir = b:netrw_prvdir |endif keepj call s:NetrwOptionRestore("w:") -" call Decho("generate a buffer with keepjumps keepalt enew!") +" call Decho("(s:NetrwEnew) generate a buffer with keepjumps keepalt enew!") let netrw_keepdiff= &l:diff keepj keepalt enew! let &l:diff= netrw_keepdiff -" call Decho("bufnr($)=".bufnr("$")) +" call Decho("(s:NetrwEnew) bufnr($)=".bufnr("$")." winnr($)=".winnr("$")) keepj call s:NetrwOptionSave("w:") " copy function-local-variables to buffer variable equivalents -" call Decho("copy function-local variables back to buffer netrw variables") +" call Decho("(s:NetrwEnew) copy function-local variables back to buffer netrw variables") if exists("netrw_bannercnt") |let b:netrw_bannercnt = netrw_bannercnt |endif if exists("netrw_browser_active") |let b:netrw_browser_active = netrw_browser_active |endif if exists("netrw_cpf") |let b:netrw_cpf = netrw_cpf |endif @@ -9468,7 +9740,7 @@ fun! s:NetrwEnew(...) endif endif -" call Dret("s:NetrwEnew : buf#".bufnr("%")."<".bufname("%")."> expand(%)<".expand("%")."> expand(#)<".expand("#")."> bh=".&bh) +" call Dret("s:NetrwEnew : buf#".bufnr("%")."<".bufname("%")."> expand(%)<".expand("%")."> expand(#)<".expand("#")."> bh=".&bh." win#".winnr()." winnr($)#".winnr("$")) endfun " --------------------------------------------------------------------- @@ -9537,12 +9809,12 @@ endfun fun! s:RemotePathAnalysis(dirname) " call Dfunc("s:RemotePathAnalysis(a:dirname<".a:dirname.">)") - let dirpat = '^\(\w\{-}\)://\(\w\+@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$' + let dirpat = '^\(\w\{-}\)://\(\(\w\+\)@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$' let s:method = substitute(a:dirname,dirpat,'\1','') - let s:user = substitute(a:dirname,dirpat,'\2','') - let s:machine = substitute(a:dirname,dirpat,'\3','') - let s:port = substitute(a:dirname,dirpat,'\4','') - let s:path = substitute(a:dirname,dirpat,'\5','') + let s:user = substitute(a:dirname,dirpat,'\3','') + let s:machine = substitute(a:dirname,dirpat,'\4','') + let s:port = substitute(a:dirname,dirpat,'\5','') + let s:path = substitute(a:dirname,dirpat,'\6','') let s:fname = substitute(a:dirname,'^.*/\ze.','','') " call Decho("set up s:method <".s:method .">") @@ -9621,9 +9893,10 @@ fun! s:NetrwRexplore(islocal,dirname) endif " call Dfunc("s:NetrwRexplore() w:netrw_rexlocal=".w:netrw_rexlocal." w:netrw_rexdir<".w:netrw_rexdir.">") if !exists("w:netrw_rexlocal") -" " call Dret("s:NetrwRexplore() w:netrw_rexlocal doesn't exist") +" call Dret("s:NetrwRexplore() w:netrw_rexlocal doesn't exist") return endif +" call Decho("(NetrwRexplore) 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) if w:netrw_rexlocal keepj call netrw#LocalBrowseCheck(w:netrw_rexdir) else @@ -9642,11 +9915,13 @@ fun! s:NetrwRexplore(islocal,dirname) if exists("s:explore_match") exe "2match netrwMarkFile /".s:explore_match."/" endif +" call Decho("(NetrwRexplore) 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) " call Dret("s:NetrwRexplore") endfun " --------------------------------------------------------------------- -" s:SaveBufVars: {{{2 +" s:SaveBufVars: save selected b: variables to s: variables {{{2 +" use s:RestoreBufVars() to restore b: variables from s: variables fun! s:SaveBufVars() " call Dfunc("s:SaveBufVars() buf#".bufnr("%")) @@ -9717,42 +9992,48 @@ fun! s:SetRexDir(islocal,dirname) endfun " --------------------------------------------------------------------- -" s:Strlen: this function returns the length of a string, even if its {{{2 -" using multiple-byte characters. -" Solution from Nicolai Weibull, vim docs (:help strlen()), Tony Mechelynck, -" and a bit from me. -" if g:netrw_xstrlen is zero (default), then the builtin strlen() function is used. +" s:Strlen: this function returns the length of a string, even if its using multi-byte characters. {{{2 +" Solution from Nicolai Weibull, vim docs (:help strlen()), +" Tony Mechelynck, and my own invention. fun! s:Strlen(x) -" call Dfunc("s:Strlen(x<".a:x.">") - if g:netrw_xstrlen == 1 +" "" call Dfunc("s:Strlen(x<".a:x."> g:Align_xstrlen=".g:Align_xstrlen.")") + + if v:version >= 703 && exists("*strdisplaywidth") + let ret= strdisplaywidth(a:x) + + elseif type(g:Align_xstrlen) == 1 + " allow user to specify a function to compute the string length (ie. let g:Align_xstrlen="mystrlenfunc") + exe "let ret= ".g:Align_xstrlen."('".substitute(a:x,"'","''","g")."')" + + elseif g:Align_xstrlen == 1 " number of codepoints (Latin a + combining circumflex is two codepoints) " (comment from TM, solution from NW) let ret= strlen(substitute(a:x,'.','c','g')) - - elseif g:netrw_xstrlen == 2 - " number of spacing codepoints (Latin a + combining circumflex is one spacing + + elseif g:Align_xstrlen == 2 + " number of spacing codepoints (Latin a + combining circumflex is one spacing " codepoint; a hard tab is one; wide and narrow CJK are one each; etc.) " (comment from TM, solution from TM) - let ret=strlen(substitute(a:x, '.\Z', 'x', 'g')) - - elseif g:netrw_xstrlen == 3 - " virtual length (counting, for instance, tabs as anything between 1 and - " 'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when immediately + let ret=strlen(substitute(a:x, '.\Z', 'x', 'g')) + + elseif g:Align_xstrlen == 3 + " virtual length (counting, for instance, tabs as anything between 1 and + " 'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when immediately " preceded by lam, one otherwise, etc.) " (comment from TM, solution from me) - let modkeep= &mod - exe "keepj norm! o\" + let modkeep= &l:mod + exe "norm! o\" call setline(line("."),a:x) let ret= virtcol("$") - 1 - keepj d + d keepj norm! k - let &mod= modkeep - + let &l:mod= modkeep + else " at least give a decent default - let ret= strlen(a:x) + let ret= strlen(a:x) endif -" call Dret("s:Strlen ".ret) +" "" call Dret("s:Strlen ".ret) return ret endfun @@ -9764,7 +10045,7 @@ fun! s:TreeListMove(dir) let prvline = (line(".") > 1)? getline(line(".")-1) : '' let nxtline = (line(".") < line("$"))? getline(line(".")+1) : '' let curindent= substitute(curline,'^\([| ]*\).\{-}$','\1','') - let indentm1 = substitute(curindent,'^| ','','') + let indentm1 = substitute(curindent,'^'.s:treedepthstring.' ','','') " call Decho("prvline <".prvline."> #".line(".")-1) " call Decho("curline <".curline."> #".line(".")) " call Decho("nxtline <".nxtline."> #".line(".")+1) @@ -9775,22 +10056,22 @@ fun! s:TreeListMove(dir) " call Decho('regfile') if a:dir == '[' && prvline != '' keepj norm! 0 - let nl = search('^'.indentm1.'[^|]','bWe') " search backwards from regular file + let nl = search('^'.indentm1.'[^'.s:treedepthstring.']','bWe') " search backwards from regular file " call Decho("regfile srch back: ".nl) elseif a:dir == ']' && nxtline != '' keepj norm! $ - let nl = search('^'.indentm1.'[^|]','We') " search forwards from regular file + let nl = search('^'.indentm1.'[^'.s:treedepthstring.']','We') " search forwards from regular file " call Decho("regfile srch fwd: ".nl) endif elseif a:dir == '[' && prvline != '' keepj norm! 0 let curline= line(".") - let nl = search('^'.curindent.'[^|]','bWe') " search backwards From directory, same indentation + let nl = search('^'.curindent.'[^'.s:treedepthstring.']','bWe') " search backwards From directory, same indentation " call Decho("dir srch back ind: ".nl) if nl != 0 if line(".") == curline-1 - let nl= search('^'.indentm1.'[^|]','bWe') " search backwards from directory, indentation - 1 + let nl= search('^'.indentm1.'[^'.s:treedepthstring.']','bWe') " search backwards from directory, indentation - 1 " call Decho("dir srch back ind-1: ".nl) endif endif @@ -9798,11 +10079,11 @@ fun! s:TreeListMove(dir) elseif a:dir == ']' && nxtline != '' keepj norm! $ let curline = line(".") - let nl = search('^'.curindent.'[^|]','We') " search forwards from directory, same indentation + let nl = search('^'.curindent.'[^'.s:treedepthstring.']','We') " search forwards from directory, same indentation " call Decho("dir srch fwd ind: ".nl) if nl != 0 if line(".") == curline+1 - let nl= search('^'.indentm1.'[^|]','We') " search forwards from directory, indentation - 1 + let nl= search('^'.indentm1.'[^'.s:treedepthstring.']','We') " search forwards from directory, indentation - 1 " call Decho("dir srch fwd ind-1: ".nl) endif endif diff --git a/runtime/autoload/netrwSettings.vim b/runtime/autoload/netrwSettings.vim index ee43059285..541ee65ccb 100644 --- a/runtime/autoload/netrwSettings.vim +++ b/runtime/autoload/netrwSettings.vim @@ -1,7 +1,7 @@ " netrwSettings.vim: makes netrw settings simpler -" Date: May 03, 2013 +" Date: Aug 27, 2013 " Maintainer: Charles E Campbell -" Version: 14a ASTRO-ONLY +" Version: 14 " 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 = "v14a" +let g:loaded_netrwSettings = "v14" if v:version < 700 echohl WarningMsg echo "***warning*** this version of netrwSettings needs vim 7.0" @@ -98,6 +98,11 @@ fun! netrwSettings#NetrwSettings() put = '' put ='+ Netrw Browser Control' + if exists("g:netrw_altfile") + put = 'let g:netrw_altfile = '.g:netrw_altfile + else + put = 'let g:netrw_altfile = 0' + endif put = 'let g:netrw_alto = '.g:netrw_alto put = 'let g:netrw_altv = '.g:netrw_altv put = 'let g:netrw_banner = '.g:netrw_banner diff --git a/runtime/autoload/netrw_gitignore.vim b/runtime/autoload/netrw_gitignore.vim new file mode 100644 index 0000000000..0de902cbb4 --- /dev/null +++ b/runtime/autoload/netrw_gitignore.vim @@ -0,0 +1,71 @@ +" netrw_gitignore#Hide: gitignore-based hiding +" Function returns a string of comma separated patterns convenient for +" assignment to `g:netrw_list_hide` option. +" Function can take additional filenames as arguments, example: +" netrw_gitignore#Hide('custom_gitignore1', 'custom_gitignore2') +" +" Usage examples: +" let g:netrw_list_hide = netrw_gitignore#Hide() +" let g:netrw_list_hide = netrw_gitignore#Hide() . 'more,hide,patterns' +" +" Copyright: Copyright (C) 2013 Bruno Sutic {{{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, +" netrw_gitignore.vim is provided *as is* and comes with no +" warranty of any kind, either expressed or implied. By using +" this plugin, you agree that in no event will the copyright +" holder be liable for any damages resulting from the use +" of this software. +function! netrw_gitignore#Hide(...) + let additional_files = a:000 + + let default_files = ['.gitignore', '.git/info/exclude'] + + " get existing global/system gitignore files + let global_gitignore = expand(substitute(system("git config --global core.excludesfile"), '\n', '', 'g')) + if global_gitignore !=# '' + let default_files = add(default_files, global_gitignore) + endif + let system_gitignore = expand(substitute(system("git config --system core.excludesfile"), '\n', '', 'g')) + if system_gitignore !=# '' + let default_files = add(default_files, system_gitignore) + endif + + " append additional files if given as function arguments + if additional_files !=# [] + let files = extend(default_files, additional_files) + else + let files = default_files + endif + + " keep only existing/readable files + let gitignore_files = [] + for file in files + if filereadable(file) + let gitignore_files = add(gitignore_files, file) + endif + endfor + + " get contents of gitignore patterns from those files + let gitignore_lines = [] + for file in gitignore_files + for line in readfile(file) + " filter empty lines and comments + if line !~# '^#' && line !~# '^$' + let gitignore_lines = add(gitignore_lines, line) + endif + endfor + endfor + + " convert gitignore patterns to Netrw/Vim regex patterns + let escaped_lines = [] + for line in gitignore_lines + let escaped = line + let escaped = substitute(escaped, '\.', '\\.', 'g') + let escaped = substitute(escaped, '*', '.*', 'g') + let escaped_lines = add(escaped_lines, escaped) + endfor + + return join(escaped_lines, ',') +endfunction diff --git a/runtime/colors/README.txt b/runtime/colors/README.txt index 988e2a048a..3b3445cbc9 100644 --- a/runtime/colors/README.txt +++ b/runtime/colors/README.txt @@ -36,6 +36,14 @@ Some attributes (e.g., bold) might be set in the defaults that you want removed in your color scheme. Use something like "gui=NONE" to remove the attributes. +In case you want to set 'background' depending on the colorscheme selected, +this autocmd might be useful: + autocmd SourcePre */colors/blue_sky.vim set background=dark +Replace "blue_sky" with the name of the colorscheme. + +In case you want to tweak a colorscheme after it was loaded, check out that +ColorScheme autocmd event. + To see which highlight group is used where, find the help for "highlight-groups" and "group-name". diff --git a/runtime/compiler/gcc.vim b/runtime/compiler/gcc.vim index 987a3a6260..aee31d92c2 100644 --- a/runtime/compiler/gcc.vim +++ b/runtime/compiler/gcc.vim @@ -25,10 +25,10 @@ CompilerSet errorformat= \%f:%l:\ %tarning:\ %m, \%f:%l:\ %m, \\"%f\"\\,\ line\ %l%*\\D%c%*[^\ ]\ %m, - \%D%*\\a[%*\\d]:\ Entering\ directory\ `%f', - \%X%*\\a[%*\\d]:\ Leaving\ directory\ `%f', - \%D%*\\a:\ Entering\ directory\ `%f', - \%X%*\\a:\ Leaving\ directory\ `%f', + \%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 --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index 3384051e2f..ecb5b963d2 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -1,4 +1,4 @@ -*autocmd.txt* For Vim version 7.4. Last change: 2013 Aug 04 +*autocmd.txt* For Vim version 7.4. Last change: 2014 Jan 23 VIM REFERENCE MANUAL by Bram Moolenaar @@ -304,6 +304,9 @@ Name triggered by ~ |InsertCharPre| when a character was typed in Insert mode, before inserting it +|TextChanged| after a change was made to the text in Normal mode +|TextChangedI| after a change was made to the text in Insert mode + |ColorScheme| after loading a color scheme |RemoteReply| a reply from a server Vim was received @@ -480,6 +483,12 @@ CmdwinLeave Before leaving the command-line window. |cmdwin-char| *ColorScheme* ColorScheme After loading a color scheme. |:colorscheme| + The pattern is matched against the + colorscheme name. can be used for the + name of the actual file where this option was + set, and for the new colorscheme + name. + *CompleteDone* CompleteDone After Insert mode completion is done. Either @@ -553,6 +562,9 @@ FileChangedRO Before making the first change to a read-only It is not allowed to change to another buffer here. You can reload the buffer but not edit another one. + *E881* + If the number of lines changes saving for undo + may fail and the change will be aborted. *FileChangedShell* FileChangedShell When Vim notices that the modification time of a file has changed since editing started. @@ -731,7 +743,7 @@ QuickFixCmdPost Like QuickFixCmdPre, but after a quickfix command is run, before jumping to the first location. For |:cfile| and |:lfile| commands it is run after error file is read and before - moving to the first error. + moving to the first error. See |QuickFixCmdPost-example|. *QuitPre* QuitPre When using `:quit`, `:wq` or `:qall`, before diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt index 687fe3a204..99cafaabce 100644 --- a/runtime/doc/change.txt +++ b/runtime/doc/change.txt @@ -1,4 +1,4 @@ -*change.txt* For Vim version 7.4. Last change: 2013 Nov 05 +*change.txt* For Vim version 7.4. Last change: 2014 Jan 23 VIM REFERENCE MANUAL by Bram Moolenaar @@ -824,7 +824,7 @@ either the first or second pattern in parentheses did not match, so either < Substitute with an expression *sub-replace-expression* - *sub-replace-\=* + *sub-replace-\=* *s/\=* When the substitute string starts with "\=" the remainder is interpreted as an expression. This does not work recursively: a |substitute()| function inside the expression cannot use "\=" for the substitute string. diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt index c309a0f7a1..9d7c5f56f0 100644 --- a/runtime/doc/cmdline.txt +++ b/runtime/doc/cmdline.txt @@ -1,4 +1,4 @@ -*cmdline.txt* For Vim version 7.4. Last change: 2013 Mar 16 +*cmdline.txt* For Vim version 7.4. Last change: 2013 Nov 25 VIM REFERENCE MANUAL by Bram Moolenaar @@ -758,6 +758,7 @@ characters have a special meaning. These can also be used in the expression function expand() |expand()|. % Is replaced with the current file name. *:_%* *c_%* # Is replaced with the alternate file name. *:_#* *c_#* + This is remembered for every window. #n (where n is a number) is replaced with *:_#0* *:_#n* the file name of buffer n. "#0" is the same as "#". *c_#n* ## Is replaced with all names in the argument list *:_##* *c_##* diff --git a/runtime/doc/digraph.txt b/runtime/doc/digraph.txt index ac84091c5f..be94b370e1 100644 --- a/runtime/doc/digraph.txt +++ b/runtime/doc/digraph.txt @@ -1,4 +1,4 @@ -*digraph.txt* For Vim version 7.4. Last change: 2011 Jan 15 +*digraph.txt* For Vim version 7.4. Last change: 2013 Dec 12 VIM REFERENCE MANUAL by Bram Moolenaar @@ -147,7 +147,7 @@ a standard meaning: Two 2 Hook Nine 9 Horn - Equals = Cyrillic + Equals = Cyrillic (= used as second char) Asterisk * Greek Percent sign % Greek/Cyrillic special Plus + smalls: Arabic, capitals: Hebrew diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt index 6cafa7fdea..cc3dcfac6b 100644 --- a/runtime/doc/editing.txt +++ b/runtime/doc/editing.txt @@ -1,4 +1,4 @@ -*editing.txt* For Vim version 7.4. Last change: 2013 Aug 03 +*editing.txt* For Vim version 7.4. Last change: 2013 Nov 25 VIM REFERENCE MANUAL by Bram Moolenaar @@ -38,6 +38,7 @@ If there already was a current file name, then that one becomes the alternate file name. It can be used with "#" on the command line |:_#| and you can use the |CTRL-^| command to toggle between the current and the alternate file. However, the alternate file name is not changed when |:keepalt| is used. +An alternate file name is remembered for each window. *:keepalt* *:keepa* :keepalt {cmd} Execute {cmd} while keeping the current alternate file diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 2cee6c2876..ce7c855f6a 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 7.4. Last change: 2013 Nov 08 +*eval.txt* For Vim version 7.4. Last change: 2014 Feb 11 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1519,6 +1519,7 @@ v:oldfiles List of file names that is loaded from the |viminfo| file on startup. These are the files that Vim remembers marks for. The length of the List is limited by the ' argument of the 'viminfo' option (default is 100). + When the |viminfo| file is not used the List is empty. Also see |:oldfiles| and |c_#<|. The List can be modified, but this has no effect on what is stored in the |viminfo| file later. If you use values other @@ -1744,7 +1745,7 @@ cscope_connection( [{num} , {dbpath} [, {prepend}]]) cursor( {lnum}, {col} [, {coladd}]) Number move cursor to {lnum}, {col}, {coladd} cursor( {list}) Number move cursor to position in {list} -deepcopy( {expr}) any make a full copy of {expr} +deepcopy( {expr} [, {noref}]) any make a full copy of {expr} delete( {fname}) Number delete file {fname} did_filetype() Number TRUE if FileType autocommand event used diff_filler( {lnum}) Number diff filler lines about {lnum} @@ -3200,7 +3201,7 @@ getchar([expr]) *getchar()* If [expr] is 1, only check if a character is available, it is not consumed. Return zero if no character available. - Without {expr} and when {expr} is 0 a whole character or + Without [expr] and when [expr] is 0 a whole character or special key is returned. If it is an 8-bit character, the result is a number. Use nr2char() to convert it to a String. Otherwise a String is returned with the encoded character. @@ -3210,7 +3211,7 @@ getchar([expr]) *getchar()* String when a modifier (shift, control, alt) was used that is not included in the character. - When {expr} is 1 only the first byte is returned. For a + When [expr] is 1 only the first byte is returned. For a one-byte character it is the character itself as a number. Use nr2char() to convert it to a String. @@ -3460,7 +3461,7 @@ getregtype([{regname}]) *getregtype()* "v" for |characterwise| text "V" for |linewise| text "{width}" for |blockwise-visual| text - 0 for an empty or unknown register + "" for an empty or unknown register is one character with value 0x16. If {regname} is not specified, |v:register| is used. @@ -4134,6 +4135,8 @@ maparg({name}[, {mode} [, {abbr} [, {dict}]]]) *maparg()* (|mapmode-ic|) "sid" The script local ID, used for mappings (||). + "nowait" Do not wait for other, longer mappings. + (|:map-|). The mappings local to the current buffer are checked first, then the global mappings. @@ -4447,6 +4450,9 @@ getpos({expr}) Get the position for {expr}. For possible values of {expr} it is the offset in screen columns from the start of the character. E.g., a position within a or after the last character. + Note that for '< and '> Visual mode matters: when it is "V" + (visual line mode) the column of '< is zero and the column of + '> is a large number. This can be used to save and restore the cursor position: > let save_cursor = getpos(".") MoveTheCursorAround @@ -5270,6 +5276,10 @@ setpos({expr}, {list}) character. E.g., a position within a or after the last character. + Note that for '< and '> changing the line number may result in + the marks to be effectively be swapped, so that '< is always + before '>. + Returns 0 when the position could be set, -1 otherwise. An error message is given if {expr} is invalid. @@ -5632,7 +5642,7 @@ strchars({expr}) *strchars()* strdisplaywidth({expr}[, {col}]) *strdisplaywidth()* The result is a Number, which is the number of display cells - String {expr} occupies on the screen. + String {expr} occupies on the screen when it starts a {col}. When {col} is omitted zero is used. Otherwise it is the screen column where to start. This matters for Tab characters. @@ -6634,7 +6644,7 @@ See |:verbose-cmd| for more information. For the {arguments} see |function-argument|. - *a:firstline* *a:lastline* + *:func-range* *a:firstline* *a:lastline* When the [range] argument is added, the function is expected to take care of a range itself. The range is passed as "a:firstline" and "a:lastline". If [range] @@ -6643,10 +6653,10 @@ See |:verbose-cmd| for more information. of each line. See |function-range-example|. The cursor is still moved to the first line of the range, as is the case with all Ex commands. - + *:func-abort* When the [abort] argument is added, the function will abort as soon as an error is detected. - + *:func-dict* When the [dict] argument is added, the function must be invoked through an entry in a |Dictionary|. The local variable "self" will then be set to the diff --git a/runtime/doc/filetype.txt b/runtime/doc/filetype.txt index 1cee25bcd6..94454fb469 100644 --- a/runtime/doc/filetype.txt +++ b/runtime/doc/filetype.txt @@ -1,4 +1,4 @@ -*filetype.txt* For Vim version 7.4. Last change: 2013 May 25 +*filetype.txt* For Vim version 7.4. Last change: 2013 Dec 15 VIM REFERENCE MANUAL by Bram Moolenaar @@ -447,23 +447,25 @@ g:changelog_new_date_format %% insert a single '%' character %d insert the date from above %u insert the user from above + %p insert result of b:changelog_entry_prefix %c where to position cursor when done - The default is "%d %u\n\n\t* %c\n\n", which produces + The default is "%d %u\n\n\t* %p%c\n\n", which produces something like (| is where cursor will be, unless at the start of the line where it denotes the beginning of the line) > |2003-01-14 Full Name | - | * | + | * prefix| < g:changelog_new_entry_format The format used when creating a new entry. The following table describes special tokens in the string: + %p insert result of b:changelog_entry_prefix %c where to position cursor when done The default is "\t*%c", which produces something similar to > - | * | + | * prefix| < g:changelog_date_entry_search The search pattern to use when searching for a diff --git a/runtime/doc/fold.txt b/runtime/doc/fold.txt index 240d912d99..6ae2ff8682 100644 --- a/runtime/doc/fold.txt +++ b/runtime/doc/fold.txt @@ -1,4 +1,4 @@ -*fold.txt* For Vim version 7.4. Last change: 2010 May 13 +*fold.txt* For Vim version 7.4. Last change: 2013 Dec 04 VIM REFERENCE MANUAL by Bram Moolenaar @@ -285,9 +285,10 @@ zF Create a fold for [count] lines. Works like "zf". *zd* *E351* zd Delete one fold at the cursor. When the cursor is on a folded line, that fold is deleted. Nested folds are moved one level - up. In Visual mode all folds (partially) in the selected area - are deleted. Careful: This easily deletes more folds than you - expect and there is no undo. + up. In Visual mode one level of all folds (partially) in the + selected area are deleted. + Careful: This easily deletes more folds than you expect and + there is no undo for manual folding. This only works when 'foldmethod' is "manual" or "marker". Also see |fold-delete-marker|. diff --git a/runtime/doc/indent.txt b/runtime/doc/indent.txt index 1f7754b580..749882ce4a 100644 --- a/runtime/doc/indent.txt +++ b/runtime/doc/indent.txt @@ -598,7 +598,6 @@ without limits. " Default let g:clojure_maxlines = 100 < - *g:clojure_fuzzy_indent* *g:clojure_fuzzy_indent_patterns* *g:clojure_fuzzy_indent_blacklist* @@ -652,7 +651,6 @@ default list below. let g:clojure_special_indent_words = \ 'deftype,defrecord,reify,proxy,extend-type,extend-protocol,letfn' < - *g:clojure_align_multiline_strings* Align subsequent lines in multiline strings to the column after the opening @@ -677,6 +675,28 @@ This option is off by default. " Default let g:clojure_align_multiline_strings = 0 < + *g:clojure_align_subforms* + +By default, parenthesized compound forms that look like function calls and +whose head subform is on its own line have subsequent subforms indented by +two spaces relative to the opening paren: +> + (foo + bar + baz) +< +Setting this option changes this behavior so that all subforms are aligned to +the same column: +> + (foo + bar + baz) +< +This option is off by default. +> + " Default + let g:clojure_align_subforms = 0 +< FORTRAN *ft-fortran-indent* diff --git a/runtime/doc/motion.txt b/runtime/doc/motion.txt index d40d825c2c..eaa2d8df35 100644 --- a/runtime/doc/motion.txt +++ b/runtime/doc/motion.txt @@ -1,4 +1,4 @@ -*motion.txt* For Vim version 7.4. Last change: 2013 Jul 17 +*motion.txt* For Vim version 7.4. Last change: 2014 Feb 11 VIM REFERENCE MANUAL by Bram Moolenaar @@ -343,7 +343,7 @@ gg Goto line [count], default first line, on the first See also 'startofline' option. {not in Vi} :[range]go[to] [count] *:go* *:goto* *go* -[count]go Go to {count} byte in the buffer. Default [count] is +[count]go Go to [count] byte in the buffer. Default [count] is one, start of the file. When giving [range], the last number in it used as the byte count. End-of-line characters are counted depending on the current diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index c9bb7e6b95..3992dd822c 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1,4 +1,4 @@ -*options.txt* For Vim version 7.4. Last change: 2013 Nov 12 +*options.txt* For Vim version 7.4. Last change: 2013 Dec 04 VIM REFERENCE MANUAL by Bram Moolenaar @@ -992,7 +992,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'backupdir'* *'bdir'* 'backupdir' 'bdir' string (default for Amiga: ".,t:", - for MS-DOS and Win32: ".,c:/tmp,c:/temp" + for MS-DOS and Win32: ".,$TEMP,c:/tmp,c:/temp" for Unix: ".,~/tmp,~/") global {not in Vi} @@ -2482,7 +2482,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'directory'* *'dir'* 'directory' 'dir' string (default for Amiga: ".,t:", - for MS-DOS and Win32: ".,c:\tmp,c:\temp" + for MS-DOS and Win32: ".,$TEMP,c:\tmp,c:\temp" for Unix: ".,~/tmp,/var/tmp,/tmp") global List of directory names for the swap file, separated with commas. diff --git a/runtime/doc/pattern.txt b/runtime/doc/pattern.txt index f2f0b34e32..80688f918c 100644 --- a/runtime/doc/pattern.txt +++ b/runtime/doc/pattern.txt @@ -1,4 +1,4 @@ -*pattern.txt* For Vim version 7.4. Last change: 2013 Nov 09 +*pattern.txt* For Vim version 7.4. Last change: 2014 Feb 08 VIM REFERENCE MANUAL by Bram Moolenaar @@ -192,10 +192,10 @@ affected. An example of how to search for matches with a pattern and change the match with another word: > /foo find "foo" - c//e change until end of match + c//e change until end of match bar type replacement // go to start of next match - c//e change until end of match + c//e change until end of match beep type another replacement etc. < diff --git a/runtime/doc/pi_getscript.txt b/runtime/doc/pi_getscript.txt index 6fed274022..628d9b74e5 100644 --- a/runtime/doc/pi_getscript.txt +++ b/runtime/doc/pi_getscript.txt @@ -1,4 +1,4 @@ -*pi_getscript.txt* For Vim version 7.4. Last change: 2012 Apr 07 +*pi_getscript.txt* For Vim version 7.0. Last change: 2013 Nov 29 > GETSCRIPT REFERENCE MANUAL by Charles E. Campbell < @@ -385,6 +385,10 @@ The AutoInstall process will: ============================================================================== 9. GetLatestVimScripts History *getscript-history* *glvs-hist* {{{1 +v36 Apr 22, 2013 : * (glts) suggested use of plugin/**/*.vim instead of + plugin/*.vim in globpath() call. + * (Andy Wokula) got warning message when setting + g:loaded_getscriptPlugin v35 Apr 07, 2012 : * (MengHuan Yu) pointed out that the script url has changed (somewhat). However, it doesn't work, and the original one does (under Linux). I'll make it diff --git a/runtime/doc/pi_netrw.txt b/runtime/doc/pi_netrw.txt index c9d8752e09..786933a045 100644 --- a/runtime/doc/pi_netrw.txt +++ b/runtime/doc/pi_netrw.txt @@ -1,4 +1,4 @@ -*pi_netrw.txt* For Vim version 7.4. Last change: 2013 May 18 +*pi_netrw.txt* For Vim version 7.4. Last change: 2014 Jan 21 ------------------------------------------------ NETRW REFERENCE MANUAL by Charles E. Campbell @@ -6,7 +6,7 @@ Author: Charles E. Campbell (remove NOSPAM from Campbell's email first) -Copyright: Copyright (C) 1999-2013 Charles E Campbell *netrw-copyright* +Copyright: Copyright (C) 1999-2014 Charles E Campbell *netrw-copyright* The VIM LICENSE applies to the files in this package, including netrw.vim, pi_netrw.txt, netrwFileHandlers.vim, netrwSettings.vim, and syntax/netrw.vim. Like anything else that's free, netrw.vim and its @@ -192,21 +192,22 @@ You may do so by placing the following two lines in your <.vimrc>: > EXTERNAL APPLICATIONS AND PROTOCOLS *netrw-externapp* {{{2 - Protocol Variable Default Value - -------- ---------------- ------------- - dav: *g:netrw_dav_cmd* = "cadaver" if cadaver is executable - dav: g:netrw_dav_cmd = "curl -o" elseif curl is available - fetch: *g:netrw_fetch_cmd* = "fetch -o" if fetch is available - ftp: *g:netrw_ftp_cmd* = "ftp" - http: *g:netrw_http_cmd* = "elinks" if elinks is available - http: g:netrw_http_cmd = "links" elseif links is available - http: g:netrw_http_cmd = "curl" elseif curl is available - http: g:netrw_http_cmd = "wget" elseif wget is available - http: g:netrw_http_cmd = "fetch" elseif fetch is available - rcp: *g:netrw_rcp_cmd* = "rcp" - rsync: *g:netrw_rsync_cmd* = "rsync -a" - scp: *g:netrw_scp_cmd* = "scp -q" - sftp: *g:netrw_sftp_cmd* = "sftp" + Protocol Variable Default Value + -------- ---------------- ------------- + dav: *g:netrw_dav_cmd* = "cadaver" if cadaver is executable + dav: g:netrw_dav_cmd = "curl -o" elseif curl is available + fetch: *g:netrw_fetch_cmd* = "fetch -o" if fetch is available + ftp: *g:netrw_ftp_cmd* = "ftp" + http: *g:netrw_http_cmd* = "elinks" if elinks is available + http: g:netrw_http_cmd = "links" elseif links is available + http: g:netrw_http_cmd = "curl" elseif curl is available + http: g:netrw_http_cmd = "wget" elseif wget is available + http: g:netrw_http_cmd = "fetch" elseif fetch is available + http: *g:netrw_http_put_cmd* = "curl -T" + rcp: *g:netrw_rcp_cmd* = "rcp" + rsync: *g:netrw_rsync_cmd* = "rsync -a" + scp: *g:netrw_scp_cmd* = "scp -q" + sftp: *g:netrw_sftp_cmd* = "sftp" *g:netrw_http_xcmd* : the option string for http://... protocols are specified via this variable and may be independently overridden. By @@ -223,6 +224,9 @@ EXTERNAL APPLICATIONS AND PROTOCOLS *netrw-externapp* {{{2 let g:netrw_http_xcmd= "-dump >" < in your .vimrc. + g:netrw_http_put_cmd: this option specifies both the executable and + any needed options. This command does a PUT operation to the url. + READING *netrw-read* *netrw-nread* {{{2 @@ -816,8 +820,7 @@ variables listed below, and may be modified by the user. ------------------------ Option Type Setting Meaning --------- -------- -------------- --------------------------- -< - netrw_ftp variable =doesn't exist userid set by "user userid" +< netrw_ftp variable =doesn't exist userid set by "user userid" =0 userid set by "user userid" =1 userid set by "userid" NetReadFixup function =doesn't exist no change @@ -825,17 +828,18 @@ variables listed below, and may be modified by the user. read via ftp automatically transformed however they wish by NetReadFixup() - g:netrw_dav_cmd variable ="cadaver" if cadaver is executable - g:netrw_dav_cmd variable ="curl -o" elseif curl is executable - g:netrw_fetch_cmd variable ="fetch -o" if fetch is available - g:netrw_ftp_cmd variable ="ftp" - g:netrw_http_cmd variable ="fetch -o" if fetch is available - g:netrw_http_cmd variable ="wget -O" else if wget is available - g:netrw_list_cmd variable ="ssh USEPORT HOSTNAME ls -Fa" - g:netrw_rcp_cmd variable ="rcp" - g:netrw_rsync_cmd variable ="rsync -a" - g:netrw_scp_cmd variable ="scp -q" - g:netrw_sftp_cmd variable ="sftp" > + g:netrw_dav_cmd var ="cadaver" if cadaver is executable + g:netrw_dav_cmd var ="curl -o" elseif curl is executable + g:netrw_fetch_cmd var ="fetch -o" if fetch is available + g:netrw_ftp_cmd var ="ftp" + g:netrw_http_cmd var ="fetch -o" if fetch is available + g:netrw_http_cmd var ="wget -O" else if wget is available + g:netrw_http_put_cmd var ="curl -T" + g:netrw_list_cmd var ="ssh USEPORT HOSTNAME ls -Fa" + g:netrw_rcp_cmd var ="rcp" + g:netrw_rsync_cmd var ="rsync -a" + g:netrw_scp_cmd var ="scp -q" + g:netrw_sftp_cmd var ="sftp" > ------------------------------------------------------------------------- < *netrw-ftp* @@ -1097,16 +1101,20 @@ QUICK REFERENCE: MAPS *netrw-browse-maps* {{{2 mapping defined before netrw is autoloaded, then a double clicked leftmouse button will return to the netrw browser window. See |g:netrw_retmap|. - (gvim only) like mf, will mark files + (gvim only) like mf, will mark files. Dragging + the shifted leftmouse will mark multiple files. + (see |netrw-mf|) (to disable mouse buttons while browsing: |g:netrw_mousemaps|) *netrw-quickcom* *netrw-quickcoms* QUICK REFERENCE: COMMANDS *netrw-explore-cmds* *netrw-browse-cmds* {{{2 - :NetrwClean[!] ...........................................|netrw-clean| - :NetrwSettings ...........................................|netrw-settings| + :NetrwClean[!]............................................|netrw-clean| + :NetrwSettings............................................|netrw-settings| + :Ntree....................................................|netrw-ntree| :Explore[!] [dir] Explore directory of current file......|netrw-explore| :Hexplore[!] [dir] Horizontal Split & Explore.............|netrw-explore| + :Lexplore [dir] Left Explorer Toggle...................|netrw-explore| :Nexplore[!] [dir] Vertical Split & Explore...............|netrw-explore| :Pexplore[!] [dir] Vertical Split & Explore...............|netrw-explore| :Rexplore Return to Explorer.....................|netrw-explore| @@ -1321,6 +1329,17 @@ See |g:netrw_dirhistmax| for how to control the quantity of history stack slots. +CHANGING TREE TOP *netrw-ntree* *:Ntree* + +One may specify a new tree top for tree listings using > + + :Ntree [dirname] + +Without a "dirname", the current line is used (and any leading depth +information is elided). +With a "dirname", the specified directory name is used. + + NETRW CLEAN *netrw-clean* *:NetrwClean* With :NetrwClean one may easily remove netrw from one's home directory; @@ -1458,7 +1477,7 @@ Associated setting variable: |g:netrw_localrmdir| |g:netrw_rm_cmd| *netrw-explore* *netrw-hexplore* *netrw-nexplore* *netrw-pexplore* -*netrw-rexplore* *netrw-sexplore* *netrw-texplore* *netrw-vexplore* +*netrw-rexplore* *netrw-sexplore* *netrw-texplore* *netrw-vexplore* *netrw-lexplore* DIRECTORY EXPLORATION COMMANDS {{{2 :[N]Explore[!] [dir]... Explore directory of current file *:Explore* @@ -1467,6 +1486,7 @@ DIRECTORY EXPLORATION COMMANDS {{{2 :[N]Sexplore[!] [dir]... Split&Explore current file's directory *:Sexplore* :Texplore [dir]... Tab & Explore *:Texplore* :[N]Vexplore[!] [dir]... Vertical Split & Explore *:Vexplore* + :Lexplore [dir]... Left Explorer Toggle *:Lexplore* Used with :Explore **/pattern : (also see |netrw-starstar|) :Nexplore............. go to next matching file *:Nexplore* @@ -1478,6 +1498,9 @@ DIRECTORY EXPLORATION COMMANDS {{{2 window will take over that window. Normally the splitting is taken horizontally. :Explore! is like :Explore, but will use vertical splitting. +:Lexplore [dir] toggles an Explorer window on the left hand side + of the current tab It will open a netrw window on the current + directory if [dir] is omitted. :Sexplore will always split the window before invoking the local-directory browser. As with Explore, the splitting is normally done horizontally. @@ -1486,7 +1509,7 @@ DIRECTORY EXPLORATION COMMANDS {{{2 :Hexplore! [dir] does an :Explore with |:aboveleft| horizontal splitting. :Vexplore [dir] does an :Explore with |:leftabove| vertical splitting. :Vexplore! [dir] does an :Explore with |:rightbelow| vertical splitting. -:Texplore [dir] does a tabnew before generating the browser window +:Texplore [dir] does a |:tabnew| before generating the browser window By default, these commands use the current file's directory. However, one may explicitly provide a directory (path) to use. @@ -1505,6 +1528,8 @@ windows should have. of the <2-leftmouse> map (which is only available under gvim and cooperative terms). +Also see: |g:netrw_alto| |g:netrw_altv| |g:netrw_winsize| + *netrw-star* *netrw-starpat* *netrw-starstar* *netrw-starstarpat* EXPLORING WITH STARS AND PATTERNS @@ -1696,9 +1721,36 @@ As a quick shortcut, one may press > to toggle between hiding files which begin with a period (dot) and not hiding them. -Associated setting variable: |g:netrw_list_hide| |g:netrw_hide| +Associated setting variables: |g:netrw_list_hide| |g:netrw_hide| Associated topics: |netrw-a| |netrw-ctrl-h| |netrw-mh| + *netrw-gitignore* +Netrw provides a helper function 'netrw_gitignore#Hide()' that, when used with +|g:netrw_list_hide| automatically hides all git-ignored files. + +'netrw_gitignore#Hide' searches for patterns in the following files: + './.gitignore' + './.git/info/exclude' + global gitignore file: `git config --global core.excludesfile` + system gitignore file: `git config --system core.excludesfile` + +Files that do not exist, are ignored. +Git-ignore patterns are taken from existing files, and converted to patterns for +hiding files. For example, if you had '*.log' in your '.gitignore' file, it +would be converted to '.*\.log'. + +To use this function, simply assign it's output to |g:netrw_list_hide| option. + + Example: let g:netrw_list_hide= netrw_gitignore#Hide() + Git-ignored files are hidden in Netrw. + + Example: let g:netrw_list_hide= netrw_gitignore#Hide('my_gitignore_file') + Function can take additional files with git-ignore patterns. + + Example: g:netrw_list_hide= netrw_gitignore#Hide() . '.*\.swp$' + Combining 'netrw_gitignore#Hide' with custom patterns. + + IMPROVING BROWSING *netrw-listhack* *netrw-ssh-hack* {{{2 Especially with the remote directory browser, constantly entering the password @@ -1778,6 +1830,15 @@ passwords: http://sial.org/howto/openssh/publickey-auth/ + Ssh hints: + + Thomer Gil has provided a hint on how to speed up netrw+ssh: + http://thomer.com/howtos/netrw_ssh.html + + Alex Young has several hints on speeding ssh up: + http://usevim.com/2012/03/16/editing-remote-files/ + + LISTING BOOKMARKS AND HISTORY *netrw-qb* *netrw-listbookmark* {{{2 Pressing "qb" (query bookmarks) will list both the bookmarked directories and @@ -1800,8 +1861,8 @@ directory. Attempts to make a local directory that already exists (as either a file or a directory) will be detected, reported on, and ignored. Related topics: |netrw-D| -Associated setting variables: |g:netrw_localmkdir| |g:netrw_mkdir_cmd| - |g:netrw_remote_mkdir| +Associated setting variables: |g:netrw_localmkdir| |g:netrw_mkdir_cmd| + |g:netrw_remote_mkdir| |netrw-%| MAKING THE BROWSING DIRECTORY THE CURRENT DIRECTORY *netrw-c* {{{2 @@ -1860,6 +1921,10 @@ like > < into $HOME/.vim/after/syntax/netrw.vim . +If the mouse is enabled and works with your vim, you may use to +mark one or more files. You may mark multiple files by dragging the shifted +leftmouse. (see |netrw-mouse|) + *markfilelist* *global_markfilelist* *local_markfilelist* All marked files are entered onto the global marked file list; there is only one such list. In addition, every netrw buffer also has its own local marked @@ -2114,7 +2179,15 @@ your browsing preferences. (see also: |netrw-settings|) --- ----------- Var Explanation --- ----------- -< *g:netrw_alto* change from above splitting to below splitting +< *g:netrw_altfile* some like |CTRL-^| to return to the last + edited file. Choose that by setting this + parameter to 1. + Others like |CTRL-^| to return to the + netrw browsing buffer. Choose that by setting + this parameter to 0. + default: =0 + + *g:netrw_alto* change from above splitting to below splitting by setting this variable (see |netrw-o|) default: =&sb (see |'sb'|) @@ -2142,6 +2215,10 @@ your browsing preferences. (see also: |netrw-settings|) to get vertical splitting instead of horizontal splitting. + Related topics: + |netrw-cr| |netrw-C| + |g:netrw_alto| |g:netrw_altv| + *g:netrw_browsex_viewer* specify user's preference for a viewer: > "kfmclient exec" "gnome-open" @@ -2303,10 +2380,19 @@ your browsing preferences. (see also: |netrw-settings|) stamp information and file size) = 2: wide listing (multiple files in columns) = 3: tree style listing + *g:netrw_list_hide* comma separated pattern list for hiding files Patterns are regular expressions (see |regexp|) - Example: let g:netrw_list_hide= '.*\.swp$' - default: "" + There's some special support for git-ignore + files: you may add the output from the helper + function 'netrw_gitignore#Hide() automatically + hiding all gitignored files. + For more details see |netrw-gitignore|. + + Examples: + let g:netrw_list_hide= '.*\.swp$' + let g:netrw_list_hide= netrw_gitignore#Hide().'.*\.swp$' + default: "" *g:netrw_localcopycmd* ="cp" Linux/Unix/MacOS/Cygwin ="copy" Windows @@ -2551,6 +2637,8 @@ To open a file in netrw's current directory, press "%". This map will query the user for a new filename; an empty file by that name will be placed in the netrw's current directory (ie. b:netrw_curdir). +Related topics: |netrw-d| + PREVIEW WINDOW *netrw-p* *netrw-preview* {{{2 @@ -2655,7 +2743,7 @@ One may select a netrw window for editing with the "C" mapping, or by setting g:netrw_chgwin to the selected window number. Subsequent selection of a file to edit (|netrw-cr|) will use that window. -Related topics: |netrw-cr| +Related topics: |netrw-cr| |g:netrw_browse_split| Associated setting variables: |g:netrw_chgwin| @@ -2988,15 +3076,78 @@ which is loaded automatically at startup (assuming :set nocp). read/write your file over the network in a separate tab. To save the file, use > + :tabnext :set bt= :w! DBG -< Please send that information to 's maintainer, > + +< Furthermore, it'd be helpful if you would type > + :Dsep +< after each command you issue, thereby making it easier to + associate which part of the debugging trace is due to which + command. + + Please send that information to 's maintainer, > NdrOchip at ScampbellPfamily.AbizM - NOSPAM < ============================================================================== 12. History *netrw-history* {{{1 + v150: Jul 12, 2013 * removed a "keepalt" to allow ":e #" to + return to the netrw directory listing + Jul 13, 2013 * (Jonas Diemer) suggested changing + a to . + Jul 21, 2013 * (Yuri Kanivetsky) reported that netrw's + use of mkdir did not produce directories + following umask. + Aug 27, 2013 * introduced |g:netrw_altfile| option + Sep 05, 2013 * s:Strlen() now uses |strdisplaywidth()| + when available, by default + Sep 12, 2013 * (Selyano Baldo) reported that netrw wasn't + opening some directories properly from the + command line. + Nov 09, 2013 * |:Lexplore| introduced + * (Ondrej Platek) reported an issue with + netrw's trees (P15). Fixed. + * (Jorge Solis) reported that "t" in + tree mode caused netrw to forget its + line position. + Dec 05, 2013 * Added file marking + (see |netrw-mf|) + Dec 05, 2013 * (Yasuhiro Matsumoto) Explore should use + strlen() instead s:Strlen() when handling + multibyte chars with strpart() + (ie. strpart() is byte oriented, not + display-width oriented). + Dec 09, 2013 * (Ken Takata) Provided a patch; File sizes + and a portion of timestamps were wrongly + highlighted with the directory color when + setting `:let g:netrw_liststyle=1` on Windows. + * (Paul Domaskis) noted that sometimes + cursorline was activating in non-netrw + windows. All but one setting of cursorline + was done via setl; there was one that was + overlooked. Fixed. + Dec 24, 2013 * (esquifit) asked that netrw allow the + /cygdrive prefix be a user-alterable + parameter. + Jan 02, 2014 * Fixed a problem with netrw-based ballon + evaluation (ie. netrw#NetrwBaloonHelp() + not having been loaded error messages) + Jan 03, 2014 * Fixed a problem with tree listings + * New command installed: |:Ntree| + Jan 06, 2014 * (Ivan Brennan) reported a problem with + |netrw-P|. Fixed. + Jan 06, 2014 * Fixed a problem with |netrw-P| when the + modified file was to be abandoned. + Jan 15, 2014 * (Matteo Cavalleri) reported that when the + banner is suppressed and tree listing is + used, a blank line was left at the top of + the display. Fixed. + Jan 20, 2014 * (Gideon Go) reported that, in tree listing + style, with a previous window open, that + the wrong directory was being used to open + a file. Fixed. (P21) v149: Apr 18, 2013 * in wide listing format, now have maps for w and b to move to next/previous file Apr 26, 2013 * one may now copy files in the same @@ -3009,7 +3160,8 @@ which is loaded automatically at startup (assuming :set nocp). May 01, 2013 * :Explore ftp://... wasn't working. Fixed. May 02, 2013 * introduced |g:netrw_bannerbackslash| as requested by Paul Domaskis. - May 18, 2013 * More fixes for windows (not cygwin) + Jul 03, 2013 * Explore now avoids splitting when a buffer + will be hidden. v148: Apr 16, 2013 * changed Netrw's Style menu to allow direct choice of listing style, hiding style, and sorting style diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt index 0697700246..25421a59db 100644 --- a/runtime/doc/repeat.txt +++ b/runtime/doc/repeat.txt @@ -1,4 +1,4 @@ -*repeat.txt* For Vim version 7.4. Last change: 2013 Jul 25 +*repeat.txt* For Vim version 7.4. Last change: 2014 Feb 11 VIM REFERENCE MANUAL by Bram Moolenaar @@ -26,10 +26,14 @@ Chapter 26 of the user manual introduces repeating |usr_26.txt|. Simple changes can be repeated with the "." command. Without a count, the count of the last change is used. If you enter a count, it will replace the -last one. If the last change included a specification of a numbered register, -the register number will be incremented. See |redo-register| for an example -how to use this. Note that when repeating a command that used a Visual -selection, the same SIZE of area is used, see |visual-repeat|. +last one. |v:count| and |v:count1| will be set. + +If the last change included a specification of a numbered register, the +register number will be incremented. See |redo-register| for an example how +to use this. + +Note that when repeating a command that used a Visual selection, the same SIZE +of area is used, see |visual-repeat|. *@:* @: Repeat last command-line [count] times. diff --git a/runtime/doc/sign.txt b/runtime/doc/sign.txt index 076bff0335..79c1011092 100644 --- a/runtime/doc/sign.txt +++ b/runtime/doc/sign.txt @@ -1,4 +1,4 @@ -*sign.txt* For Vim version 7.4. Last change: 2012 Jul 10 +*sign.txt* For Vim version 7.4. Last change: 2013 Nov 17 VIM REFERENCE MANUAL by Gordon Prieur @@ -173,7 +173,7 @@ REMOVING SIGNS *:sign-unplace* *E159* Remove the placed sign at the cursor position. -LISTING PLACED SIGNS +LISTING PLACED SIGNS *:sign-place-list* :sign place file={fname} List signs placed in file {fname}. diff --git a/runtime/doc/tags b/runtime/doc/tags index e515c89904..b8e6490e70 100644 --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -1844,6 +1844,7 @@ $VIMRUNTIME starting.txt /*$VIMRUNTIME* :GnatPretty ft_ada.txt /*:GnatPretty* :GnatTags ft_ada.txt /*:GnatTags* :Hexplore pi_netrw.txt /*:Hexplore* +:Lexplore pi_netrw.txt /*:Lexplore* :Man filetype.txt /*:Man* :MkVimball pi_vimball.txt /*:MkVimball* :N editing.txt /*:N* @@ -1855,6 +1856,7 @@ $VIMRUNTIME starting.txt /*$VIMRUNTIME* :Nread pi_netrw.txt /*:Nread* :Ns pi_netrw.txt /*:Ns* :Nsource pi_netrw.txt /*:Nsource* +:Ntree pi_netrw.txt /*:Ntree* :Nw pi_netrw.txt /*:Nw* :Nwrite pi_netrw.txt /*:Nwrite* :P various.txt /*:P* @@ -2231,6 +2233,9 @@ $VIMRUNTIME starting.txt /*$VIMRUNTIME* :foldopen fold.txt /*:foldopen* :for eval.txt /*:for* :fu eval.txt /*:fu* +:func-abort eval.txt /*:func-abort* +:func-dict eval.txt /*:func-dict* +:func-range eval.txt /*:func-range* :function eval.txt /*:function* :function-verbose eval.txt /*:function-verbose* :g repeat.txt /*:g* @@ -2763,6 +2768,7 @@ $VIMRUNTIME starting.txt /*$VIMRUNTIME* :sign-jump sign.txt /*:sign-jump* :sign-list sign.txt /*:sign-list* :sign-place sign.txt /*:sign-place* +:sign-place-list sign.txt /*:sign-place-list* :sign-undefine sign.txt /*:sign-undefine* :sign-unplace sign.txt /*:sign-unplace* :sil various.txt /*:sil* @@ -4345,6 +4351,7 @@ E878 pattern.txt /*E878* E879 syntax.txt /*E879* E88 windows.txt /*E88* E880 if_pyth.txt /*E880* +E881 autocmd.txt /*E881* E89 message.txt /*E89* E90 message.txt /*E90* E91 options.txt /*E91* @@ -5935,6 +5942,7 @@ g:ada_standard_types ft_ada.txt /*g:ada_standard_types* g:ada_with_gnat_project_files ft_ada.txt /*g:ada_with_gnat_project_files* g:ada_withuse_ordinary ft_ada.txt /*g:ada_withuse_ordinary* g:clojure_align_multiline_strings indent.txt /*g:clojure_align_multiline_strings* +g:clojure_align_subforms indent.txt /*g:clojure_align_subforms* g:clojure_fuzzy_indent indent.txt /*g:clojure_fuzzy_indent* g:clojure_fuzzy_indent_blacklist indent.txt /*g:clojure_fuzzy_indent_blacklist* g:clojure_fuzzy_indent_patterns indent.txt /*g:clojure_fuzzy_indent_patterns* @@ -5983,6 +5991,7 @@ g:html_use_css syntax.txt /*g:html_use_css* g:html_use_encoding syntax.txt /*g:html_use_encoding* g:html_use_xhtml syntax.txt /*g:html_use_xhtml* g:html_whole_filler syntax.txt /*g:html_whole_filler* +g:netrw_altfile pi_netrw.txt /*g:netrw_altfile* g:netrw_alto pi_netrw.txt /*g:netrw_alto* g:netrw_altv pi_netrw.txt /*g:netrw_altv* g:netrw_banner pi_netrw.txt /*g:netrw_banner* @@ -6017,6 +6026,7 @@ g:netrw_glob_escape pi_netrw.txt /*g:netrw_glob_escape* g:netrw_hide pi_netrw.txt /*g:netrw_hide* g:netrw_home pi_netrw.txt /*g:netrw_home* g:netrw_http_cmd pi_netrw.txt /*g:netrw_http_cmd* +g:netrw_http_put_cmd pi_netrw.txt /*g:netrw_http_put_cmd* g:netrw_http_xcmd pi_netrw.txt /*g:netrw_http_xcmd* g:netrw_ignorenetrc pi_netrw.txt /*g:netrw_ignorenetrc* g:netrw_keepdir pi_netrw.txt /*g:netrw_keepdir* @@ -7074,6 +7084,7 @@ netrw-gd pi_netrw.txt /*netrw-gd* netrw-getftype pi_netrw.txt /*netrw-getftype* netrw-gf pi_netrw.txt /*netrw-gf* netrw-gh pi_netrw.txt /*netrw-gh* +netrw-gitignore pi_netrw.txt /*netrw-gitignore* netrw-gp pi_netrw.txt /*netrw-gp* netrw-gx pi_netrw.txt /*netrw-gx* netrw-handler pi_netrw.txt /*netrw-handler* @@ -7088,6 +7099,7 @@ netrw-incompatible pi_netrw.txt /*netrw-incompatible* netrw-internal-variables pi_netrw.txt /*netrw-internal-variables* netrw-intro-browse pi_netrw.txt /*netrw-intro-browse* netrw-leftmouse pi_netrw.txt /*netrw-leftmouse* +netrw-lexplore pi_netrw.txt /*netrw-lexplore* netrw-list pi_netrw.txt /*netrw-list* netrw-listbookmark pi_netrw.txt /*netrw-listbookmark* netrw-listhack pi_netrw.txt /*netrw-listhack* @@ -7118,6 +7130,7 @@ netrw-netrc pi_netrw.txt /*netrw-netrc* netrw-nexplore pi_netrw.txt /*netrw-nexplore* netrw-noload pi_netrw.txt /*netrw-noload* netrw-nread pi_netrw.txt /*netrw-nread* +netrw-ntree pi_netrw.txt /*netrw-ntree* netrw-nwrite pi_netrw.txt /*netrw-nwrite* netrw-o pi_netrw.txt /*netrw-o* netrw-options pi_netrw.txt /*netrw-options* @@ -7674,6 +7687,7 @@ s/\2 change.txt /*s\/\\2* s/\3 change.txt /*s\/\\3* s/\9 change.txt /*s\/\\9* s/\ change.txt /*s\/\\* +s/\= change.txt /*s\/\\=* s/\E change.txt /*s\/\\E* s/\L change.txt /*s\/\\L* s/\U change.txt /*s\/\\U* diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt index 641af1c321..b15d633950 100644 --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -1,4 +1,4 @@ -*todo.txt* For Vim version 7.4. Last change: 2013 Nov 14 +*todo.txt* For Vim version 7.4. Last change: 2014 Feb 11 VIM REFERENCE MANUAL by Bram Moolenaar @@ -34,96 +34,133 @@ not be repeated below, unless there is extra information. *known-bugs* -------------------- Known bugs and current work ----------------------- -Patch From Lech Lorens doesn't quite work: -Problem: When using ":'<,'>del" errors may be given for the visual line - numbers being out of range. -Solution: Reset Visual mode in ":del". (Lech Lorens) -Files: src/ex_docmd.c +When 'paste' is changed with 'pastetoggle', the ruler doesn't reflect this +right away. (Samuel Ferencik, 2010 Dec 7) +Patch to fix that status line isn't redrawn when 'pastetoggle' is set. +(Nobuhiro Takasaki, 2014 Feb 11) - -Using \1 in pattern goes one line too far. (Bohr Shaw, 2013 Sep 5) -Column is OK. "/\v(^.+\n)\1/e" (John Little, Sep 5) -Also, matches start of 2nd line, not the whole line. - -NFA regexp doesn't handle backreference correctly. (Ryuichi Hayashida, 2013 -Oct 10) - -Error for incomplete help argument. (John Beckett, 2013 Sep 12) - -Should win_redr_custom() not be allowed to use recursively? -(Yasuhiro Matsumoto, 2013 Aug 15) - -NFA engine combining character mismatch. (glts, 2013 Aug 27) -Remark Dominique, Aug 27 +Regexp problems: +- NFA regexp doesn't count tab matches correctly. (Urtica Dioica / gaultheria + Shallon, 2013 Nov 18) +- After patch 7.4.100 there is still a difference between NFA and old engine. + 25 a's with pattern \v^(aa+)\1+$ (Urtica Dioica, 2013 Nov 21) Also: 9 a's + with pattern \v^(a{-2,})\1+$ (Nov 23) +- NFA engine combining character mismatch. (glts, 2013 Aug 27) + Remark from Dominique, Aug 27 +- Issue 164: freeze on regexp search. +- NFA problem with non-greedy match and branches. (Ingo Karkat, 2013 Nov 29) +- Ignorecase not handled properly for multi-byte characters. (Axel Bender, + 2013 Dec 11) +- Using \@> and \?. (Brett Stahlman, 2013 Dec 21) Remark from Marcin Szamotulski + Remark from Brett 2014 Jan 6 and 7. +- Bug with back references. (Lech Lorens, 2014 Feb 3) +- Bug when using \>. (Ramel, 2014 Feb 2) Problem that a previous silent ":throw" causes a following try/catch not to work. (ZyX, 2013 Sep 28) -Problem using ":try" inside ":execute". (ZyX, 2013 Sep 15) +":cd C:\Windows\System32\drivers\etc*" does not work, even though the +directory exists. (Sergio Gallelli, 2013 Dec 29) -Issue 164: freeze on regexp search. +Patch 7.4.085 breaks Visual insert in some situations. (Issue 193) +Patch by Christian Brabandt, 2014 Jan 16. + +Problem using ":try" inside ":execute". (ZyX, 2013 Sep 15) Update for Clojure ftplugin. (Sung Pae). Await discussion about formatting in ftplugins. Python: ":py raw_input('prompt')" doesn't work. (Manu Hack) -Patch to support slices in Python vim.List. (ZyX, 2013 Oct 20) +Patch to make "J" set '[ and '] marks. (Christian Brabandt, 2013 Dec 11) +Any compatibility problems? -Patch to support iterator on Python vim.options. (ZyX, 2013 Nov 2) +Patch to add :S modifier for excaping the current file name. +(ZyX, 2013 Nov 30) Update Dec 5. -Patch to make Dictionary.update() work without arguments. -(ZyX, 2013 Oct 19) - -Patch for Cobol ftplugin. (ZyX, 2013 Oct 20) -Await response from maintainer. - -Include systemverilog file? Two votes yes. +Issu 197: ]P doesn't paste over Visual selection. With patch from Christian +Brabandt, Feb 6. Problem with 'spellsuggest' file, only works for some words. (Cesar Romani, 2013 Aug 20) Depends on file name? (Aug 24) Additional remark by glts: the suggested words are marked bad? +8 non-ASCII font names don't work. Need to convert from 'encoding' and use + the wide functions. Patch by Ken Takata, 2013 Dec 22. + Update 2014 Jan 6. + Syntax highlighting slow (hangs) in SASS file. (Niek Bosch, 2013 Aug 21) +Patch for mksession. (Nobuhiro Takasaki, 2014 Jan 31) +Also fixes another problem (following email) + Adding "~" to 'cdpath' doesn't work for completion? (Davido, 2013 Aug 19) +Crash with ":%s/\n//g" on long file. (Aidan Marlin, 2014 Jan 15) +Christian Brabandt: patch to run this into a join. (2014 Jan 18) +Suggestion to not save replaced line for undo: Yukihiro Nakadaira, 2014 Jan +25. + +Add digraph for Rouble: =P. What's the Unicode? + Issue 174: Detect Mason files. +Phpcomplete.vim update. (Complex, 2014 Jan 15) + +PHP syntax is extremely slow. (Anhad Jai Singh, 2014 Jan 19) + +Can we make ":unlet $VAR" use unsetenv() to delete the env var? +What for systems that don't have unsetenv()? + +spec ftplugin: patch from Igor Gnatenko, 2014 Jan 26. +Include if maintainers don't respond. + Patch to make has() check for Vim version and patch at the same time. (Marc Weber, 2013 Jun 7) +Regression on pach 7.4.034. (Ingo Karkat, 2013 Nov 20) + +Patch to include smack support (Linux security library). (Jose Bollo, 2014 Jan +14) Update Jan 15. + +Tag list, as used for :tjump, does not unescape regexp. (Gary Johnson, 2014 Jan +6) With patch in another message. + VMS: Select() doesn't work properly, typing ESC may hang Vim. Use sys$qiow instead. (Samuel Ferencik, 2013 Sep 28) Series of patches for NL vs NUL handling. (ZyX, 2013 Nov 3, Nov 9) +Patch to add flag to shortmess to avoid giving completion messages. +(Shougo Matsu, 2014 Jan 6, update Jan 11) + +Patch to add v:completed_item. (Shougo Matsu, 2013 Nov 29). + +Patch to make test 100 work on MS-Windows. (Taro Muraoka, 2013 Dec 12) + +Patch to define macros for hardcoded values. (Elias Diem, 2013 Dec 14) + Perl: support for Activestate perl 5.18: Issue 170. Several syntax file match "^\s*" which may get underlined if that's in the highlight group. Add a "\zs" after it? +Patch to fix temp directories for Windows, so that it works without tweaking. +Issue 28. + Go through more coverity reports. Include Haiku port? (Adrien Destugues, Siarzhuk Zharski, 2013 Oct 24) Updated spec ftplugin. (MatÄ›j Cepl, 2013 Oct 16) -Patch to make ColorScheme autocommand match with the colorscheme name instead -of the buffer name. (Christian Brabandt, 2013 Sep 25) - Patch to right-align signs. (James Kolb (email james), 2013 Sep 23) +Patch to handle integer overflow. (Aaron Burrow, 2013 Dec 12) + With "$" in 'cpoptions' the popup menu isn't fully drawn. (Matti Niemenmaa, 2013 Sep 5) -"gUgn" cannot be repeated, while "dgn" can. (Dimitar Dimitrov) -Patch by Christian Brabandt (2013 Aug 12) -Also notes by Christian Wellenbrock, Nov 13. - -Several Win32 functions are not using Unicode. -Patches to fix this. (Ken Takata, 2013 Aug 9) - Patch to add item in 'listchars' to repeat first character. (Nathaniel Braun, pragm, 2013 Oct 13) @@ -132,27 +169,56 @@ Undo message is not always properly displayed. Patch by Ken Takata, 2013 oct /[b-a] gives error E16, should probably be E769. +7 Windows XP: When using "ClearType" for text smoothing, a column of yellow + pixels remains when typing spaces in front of a "D" ('guifont' set to + "lucida_console:h8"). +Patch by Thomas Tuegel, also for GTK, 2013 Nov 24 + :help gives example for z?, but it does not work. m? and t? do work. Python: Extended funcrefs: use func_T* structure in place of char_u* function -names. (ZyX, 2013 Jul 15, update Sep 22, 24, 28) +names. +(ZyX, 2013 Jul 15, update Sep 22, 24, 28; Update 2013 Dec 15, 2014 Jan 6) +Also fixes Bug: E685 error for func_unref(). (ZyX, 2010 Aug 5) Patch to add funcref to Lua. (Luis Carvalho, 2013 Sep 4) With tests: Sep 5. +Patch to fix that on suckless Terminal mousewheel up does not work. +(Ralph Eastwood, 2013 Nov 25) + Discussion about canonicalization of Hebrew. (Ron Aaron, 2011 April 10) -Patch to make external commands work with multi-byte characters on Win32 when -'encoding' differs from the active codepage. (Yasuhiro Matsumoto, 2013 Aug 5) - Checking runtime scripts: Thilo Six, 2012 Jun 6. +When evaluating expression in backticks, autoload doesn't work. +(Andy Wokula, 2013 Dec 14) + +Using ifoobar can slow down Vim. Patch by Christian Brabandt, 2013 +Dec 13. + Fold can't be opened after ":move". (Ein Brown) Patch from Christian Brabandt doesn't fix it completely. +Patch from Christian Brabandt to preserve upper case marks when wiping out a +buffer. (2013 Dec 9) + +Patch for drag&drop reordering of GUI tab pages reordering. +(Ken Takata, 2013 Nov 22, second one, also by Masamichi Abe) + +":sign-jump" uses first window in buffer instead of current window. +Patch by James McCoy, 2013 Nov 22. + GTK: problem with 'L' in 'guioptions' changing the window width. (Aaron Cornelius, 2012 Feb 6) +Patch to add option that tells whether small deletes go into the numbered +registers. (Aryeh Leib Taurog, 2013 Nov 18) + +Win32: use different args for SearchPath()? (Yasuhiro Matsumoto, 2009 Jan 30) +Also fixes wrong result from executable(). +Update from Ken Takata, 2014 Jan 10. + Javascript file where indent gets stuck on: GalaxyMaster, 2012 May 3. The BufUnload event is triggered when re-using the empty buffer. @@ -163,6 +229,10 @@ The CompleteDone autocommand needs some info passed to it: - The word that was selected (empty if abandoned complete) - Type of completion: tag, omnifunc, user func. +Patch to allow more types in remote_expr(). (Lech Lorens, 2014 Jan 5) +Doesn't work for string in list. Other way to pass all types of variables +reliably? + Using ":call foo#d.f()" doesn't autoload the "foo.vim" file. That is, calling a dictionary function on an autoloaded dict. Works OK for echo, just not for ":call" and ":call call()". (Ted, 2011 Mar @@ -177,6 +247,15 @@ Or should we add a more general mechanism, like lambda functions? Problem caused by patch 7.3.638: window->open does not update window correctly. Issue 91. +Patch to add {lhs} to :mapclear: clear all maps starting with {lhs}. +(Christian Brabandt, 2013 Dec 9) + +The garbage collector may use too much stack. Make set_ref_in_item() +iterative instead of recursive. Test program by Marc Weber (2013 Dec 10) + +Exception caused by argument of return is not caught by try/catch. +(David Barnett, 2013 Nov 19) + 8 'backupdir' and 'directory' should use $TMPDIR, $TMP and/or $TEMP when defined. Issue 28. @@ -243,8 +322,18 @@ a reboot. MS-Windows: Crash opening very long file name starting with "\\". (Christian Brock, 2012 Jun 29) +Patch to have text objects defined by arbitrary single characters. (Daniel +Thau, 2013 Nov 20, 2014 Jan 29, 2014 Jan 31) +Ben Fritz: problem with 'selection' set to "exclusive". + +Patch to select the next or previous text object if there isn't one under the +cursor. (Daniel Thau, 2013 Nov 20) + patch to add "combine" flag to syntax commands. (so8res, 2012 Dec 6) +Bug caused by patch 7.3.1288? Issue 183. +I can't reproduce it. + Syntax update problem in one buffer opened in two windows, bottom window is not correctly updated. (Paul Harris, 2012 Feb 27) @@ -370,6 +459,8 @@ Patch to add digraph() function. (Christian Brabandt, 2013 Aug 22, update Aug Patch for input method status. (Hirohito Higashi, 2012 Apr 18) +Update Vim app icon (for Gnome). (Jakub Steiner, 2013 Dec 6) + Patch to use .png icons for the toolbar on MS-Windows. (Martin Gieseking, 2013 Apr 18) @@ -388,8 +479,6 @@ And one for gui_x11.txt. finddir() has the same problem. (Yukihiro Nakadaira, 2012 Jan 10) Requires a rewrite of the file_file_in_path code. -Problem with l: dictionary being locked in a function. (ZyX, 2011 Jul 21) - Should use has("browsefilter") in ftplugins. Requires patch 7.3.593. Update for vim2html.pl. (Tyru, 2013 Feb 22) @@ -471,8 +560,6 @@ When using a Vim server, a # in the path causes an error message. Setting $HOME on MS-Windows is not very well documented. Suggestion by Ben Fritz (2011 Oct 27). -Bug: E685 error for func_unref(). (ZyX, 2010 Aug 5) - Bug: Windows 7 64 bit system freezes when 'clipboard' set to "unnamed" and doing ":g/test/d". Putting every delete on the clipboard? (Robert Chan, 2011 Jun 17) @@ -516,6 +603,8 @@ following "redir" command gives an error for not being able to access s:foo. When setqflist() uses a filename that triggers a BufReadCmd autocommand Vim doesn't jump to the correct line with :cfirst. (ZyX, 2011 Sep 18) +Behavior of i" and a" text objects isn't logical. (Ben Fritz, 2013 Nov 19) + 7 Make "ga" show the digraph for a character, if it exists. Patch from Christian Brabandt, 2011 Aug 19. @@ -656,7 +745,7 @@ Assume the system converts between the actual encoding of the filesystem to the system encoding (usually utf-8). Patch to add GUI colors to the terminal, when it supports it. (ZyX, 2013 Jan -26) +26, update 2013 Dec 14) Problem producing tags file when hebrew.frx is present. It has a BOM. Results in E670. (Tony Mechelynck, 2010 May 2) @@ -694,9 +783,6 @@ C-indenting: A matching { in a comment is ignored, but intermediate { are not checked to be in a comment. Implement FM_SKIPCOMM flag of findmatchlimit(). Issue 46. -When 'paste' is changed with 'pastetoggle', the ruler doesn't reflect this -right away. (Samuel Ferencik, 2010 Dec 7) - Mac with X11: clipboard doesn't work properly. (Raf, 2010 Aug 16) Using CompilerSet doesn't record where an option was set from. E.g., in the @@ -934,8 +1020,6 @@ system when 'encoding' is "utf-8". Win32 GUI: last message from startup doesn't show up when there is an echoerr command. (Cyril Slobin, 2009 Mar 13) -Win32: use different args for SearchPath()? (Yasuhiro Matsumoto, 2009 Jan 30) - Win32: completion of file name ":e c:\!test" results in ":e c:\\!test", which does not work. (Nieko Maatjes, 2009 Jan 8, Ingo Karkat, 2009 Jan 22) @@ -1399,6 +1483,10 @@ Does the conversion in the other direction work when 'fileencodings' is set properly? Add a few features to xxd. (Vadim Vygonets, 2013 Nov 11) +Patches: 2013 Nov 19 +1: Add -e: little endian hexdump +2: Add -o: add offset to displayed position +3: Change displayed file position width to 8 chars Cursor displayed in the wrong position when using 'numberwidth'. (James Vega, 2007 Jun 21) @@ -1555,6 +1643,9 @@ Completing with 'wildmenu' and using and to move through directory tree stops unexpectedly when using ":cd " and entering a directory that doesn't contain other directories. +Default for 'background' is wrong when using xterm with 256 colors. +Table with estimates from Matteo Cavalleri, 2014 Jan 10. + Setting 'background' resets the Normal background color: highlight Normal ctermbg=DarkGray set background=dark @@ -1960,8 +2051,6 @@ GTK+ GUI known bugs: Win32 GUI known bugs: - Win32: tearoff menu window should have a scrollbar when it's taller than the screen. -8 non-ASCII font names don't work. Need to convert from 'encoding' and use - the wide functions. 8 On Windows 98 the unicows library is needed to support functions with UCS2 file names. Can we load unicows.dll dynamically? 8 The -P argument doesn't work very well with many MDI applications. @@ -1969,9 +2058,6 @@ Win32 GUI known bugs: Tutorial: http://win32assembly.online.fr/tut32.html 8 In eval.c, io.h is included when MSWIN32 is defined. Shouldn't this be WIN32? Or can including io.h be moved to vim.h? (Dan Sharp) -7 Windows XP: When using "ClearType" for text smoothing, a column of yellow - pixels remains when typing spaces in front of a "D" ('guifont' set to - "lucida_console:h8"). 6 Win32 GUI: With "-u NONE -U NONE" and doing "CTRL-W v" "CTRL-W o", the ":" of ":only" is highlighted like the cursor. (Lipelis) 8 When 'encoding' is "utf-8", should use 'guifont' for both normal and wide diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt index 8db127fd95..736adf2572 100644 --- a/runtime/doc/usr_41.txt +++ b/runtime/doc/usr_41.txt @@ -1,4 +1,4 @@ -*usr_41.txt* For Vim version 7.4. Last change: 2013 Feb 20 +*usr_41.txt* For Vim version 7.4. Last change: 2014 Jan 10 VIM USER MANUAL - by Bram Moolenaar @@ -595,13 +595,17 @@ String manipulation: *string-functions* matchlist() like matchstr() and also return submatches stridx() first index of a short string in a long string strridx() last index of a short string in a long string - strlen() length of a string + strlen() length of a string in bytes + strchars() length of a string in characters + strwidth() size of string when displayed + strdisplaywidth() size of string when displayed, deals with tabs substitute() substitute a pattern match with a string submatch() get a specific match in ":s" and substitute() strpart() get part of a string expand() expand special keywords iconv() convert text from one encoding to another byteidx() byte index of a character in a string + byteidxcomp() like byteidx() but count composing characters repeat() repeat a string multiple times eval() evaluate a string expression @@ -656,6 +660,9 @@ Floating point computation: *float-functions* ceil() round up floor() round down trunc() remove value after decimal point + fmod() remainder of division + exp() exponential + log() natural logarithm (logarithm to base e) log10() logarithm to base 10 pow() value of x to the exponent y sqrt() square root @@ -675,6 +682,7 @@ Other computation: *bitwise-function* invert() bitwise invert or() bitwise OR xor() bitwise XOR + sha256() SHA-256 hash Variables: *var-functions* type() type of a variable @@ -697,11 +705,15 @@ Cursor and mark position: *cursor-functions* *mark-functions* wincol() window column number of the cursor winline() window line number of the cursor cursor() position the cursor at a line/column + screencol() get screen column of the cursor + screenrow() get screen row of the cursor getpos() get position of cursor, mark, etc. setpos() set position of cursor, mark, etc. byte2line() get line number at a specific byte count line2byte() byte count at a specific line diff_filler() get the number of filler lines above a line + screenattr() get attribute at a screen line/row + screenchar() get character code at a screen line/row Working with text in the current buffer: *text-functions* getline() get a line or list of lines from the buffer @@ -883,14 +895,22 @@ Various: *various-functions* libcall() call a function in an external library libcallnr() idem, returning a number + undofile() get the name of the undo file + undotree() return the state of the undo tree + getreg() get contents of a register getregtype() get type of a register setreg() set contents and type of a register + shiftwidth() effective value of 'shiftwidth' + taglist() get list of matching tags tagfiles() get a list of tags files + luaeval() evaluate Lua expression mzeval() evaluate |MzScheme| expression + py3eval() evaluate Python expression (|+python3|) + pyeval() evaluate Python expression (|+python|) ============================================================================== *41.7* Defining a function diff --git a/runtime/doc/version7.txt b/runtime/doc/version7.txt index 79188b5b3c..90cfc0bf89 100644 --- a/runtime/doc/version7.txt +++ b/runtime/doc/version7.txt @@ -1,4 +1,4 @@ -*version7.txt* For Vim version 7.4. Last change: 2013 Sep 03 +*version7.txt* For Vim version 7.4. Last change: 2013 Nov 18 VIM REFERENCE MANUAL by Bram Moolenaar @@ -7190,7 +7190,7 @@ More encryption *new-more-encryption* --------------- Support for Blowfish encryption. Added the 'cryptmethod' option. -Mostly by Moshin Ahmed. +Mostly by Mohsin Ahmed. Also encrypt the text in the swap file and the undo file. diff --git a/runtime/filetype.vim b/runtime/filetype.vim index 20775e9d21..96207e0b27 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -1,7 +1,7 @@ " Vim support file to detect file types " " Maintainer: Bram Moolenaar -" Last Change: 2013 Nov 13 +" Last Change: 2014 Feb 11 " Listen very carefully, I will say this only once if exists("did_load_filetypes") @@ -106,6 +106,9 @@ au BufNewFile,BufRead *.run setf ampl " Ant au BufNewFile,BufRead build.xml setf ant +" Arduino +au BufNewFile,BufRead *.ino,*.pde setf arduino + " Apache style config file au BufNewFile,BufRead proftpd.conf* call s:StarSetf('apachestyle') @@ -2240,6 +2243,9 @@ au BufNewFile,BufRead *.v setf verilog " Verilog-AMS HDL au BufNewFile,BufRead *.va,*.vams setf verilogams +" SystemVerilog +au BufNewFile,BufRead *.sv setf systemverilog + " VHDL au BufNewFile,BufRead *.hdl,*.vhd,*.vhdl,*.vbe,*.vst setf vhdl au BufNewFile,BufRead *.vhdl_[0-9]* call s:StarSetf('vhdl') diff --git a/runtime/ftplugin/changelog.vim b/runtime/ftplugin/changelog.vim index ee83c79175..244245e271 100644 --- a/runtime/ftplugin/changelog.vim +++ b/runtime/ftplugin/changelog.vim @@ -1,7 +1,7 @@ " Vim filetype plugin file " Language: generic Changelog file " Maintainer: Nikolai Weibull -" Latest Revision: 2012-08-23 +" Latest Revision: 2014-01-10 " Variables: " g:changelog_timeformat (deprecated: use g:changelog_dateformat instead) - " description: the timeformat used in ChangeLog entries. @@ -122,12 +122,12 @@ if &filetype == 'changelog' " Format used for new date entries. if !exists('g:changelog_new_date_format') - let g:changelog_new_date_format = "%d %u\n\n\t* %c\n\n" + let g:changelog_new_date_format = "%d %u\n\n\t* %p%c\n\n" endif " Format used for new entries to current date entry. if !exists('g:changelog_new_entry_format') - let g:changelog_new_entry_format = "\t* %c" + let g:changelog_new_entry_format = "\t* %p%c" endif " Regular expression used to find a given date entry. @@ -143,16 +143,16 @@ if &filetype == 'changelog' " Substitutes specific items in new date-entry formats and search strings. " Can be done with substitute of course, but unclean, and need \@! then. - function! s:substitute_items(str, date, user) + function! s:substitute_items(str, date, user, prefix) let str = a:str - let middles = {'%': '%', 'd': a:date, 'u': a:user, 'c': '{cursor}'} + let middles = {'%': '%', 'd': a:date, 'u': a:user, 'p': a:prefix, 'c': '{cursor}'} let i = stridx(str, '%') while i != -1 let inc = 0 if has_key(middles, str[i + 1]) let mid = middles[str[i + 1]] let str = strpart(str, 0, i) . mid . strpart(str, i + 2) - let inc = strlen(mid) + let inc = strlen(mid) - 1 endif let i = stridx(str, '%', i + 1 + inc) endwhile @@ -171,7 +171,7 @@ if &filetype == 'changelog' endfunction " Internal function to create a new entry in the ChangeLog. - function! s:new_changelog_entry() + function! s:new_changelog_entry(prefix) " Deal with 'paste' option. let save_paste = &paste let &paste = 1 @@ -179,7 +179,7 @@ if &filetype == 'changelog' " Look for an entry for today by our user. let date = strftime(g:changelog_dateformat) let search = s:substitute_items(g:changelog_date_entry_search, date, - \ s:username()) + \ s:username(), a:prefix) if search(search) > 0 " Ok, now we look for the end of the date entry, and add an entry. call cursor(nextnonblank(line('.') + 1), 1) @@ -188,7 +188,7 @@ if &filetype == 'changelog' else let p = line('.') endif - let ls = split(s:substitute_items(g:changelog_new_entry_format, '', ''), + let ls = split(s:substitute_items(g:changelog_new_entry_format, '', '', a:prefix), \ '\n') call append(p, ls) call cursor(p + 1, 1) @@ -198,7 +198,7 @@ if &filetype == 'changelog' " No entry today, so create a date-user header and insert an entry. let todays_entry = s:substitute_items(g:changelog_new_date_format, - \ date, s:username()) + \ date, s:username(), a:prefix) " Make sure we have a cursor positioning. if stridx(todays_entry, '{cursor}') == -1 let todays_entry = todays_entry . '{cursor}' @@ -206,7 +206,7 @@ if &filetype == 'changelog' " Now do the work. call append(0, split(todays_entry, '\n')) - + " Remove empty lines at end of file. if remove_empty $-/^\s*$/-1,$delete @@ -223,8 +223,8 @@ if &filetype == 'changelog' endfunction if exists(":NewChangelogEntry") != 2 - noremap o :call new_changelog_entry() - command! -nargs=0 NewChangelogEntry call s:new_changelog_entry() + noremap o :call new_changelog_entry('') + command! -nargs=0 NewChangelogEntry call s:new_changelog_entry('') endif let b:undo_ftplugin = "setl com< fo< et< ai<" @@ -277,10 +277,7 @@ else if exists('b:changelog_entry_prefix') let prefix = call(b:changelog_entry_prefix, []) else - let prefix = substitute(strpart(expand('%:p'), strlen(path)), '^/\+', "", "") . ':' - endif - if !empty(prefix) - let prefix = ' ' . prefix + let prefix = substitute(strpart(expand('%:p'), strlen(path)), '^/\+', "", "") endif let buf = bufnr(changelog) diff --git a/runtime/ftplugin/cobol.vim b/runtime/ftplugin/cobol.vim index 203d734750..11ad3ad727 100644 --- a/runtime/ftplugin/cobol.vim +++ b/runtime/ftplugin/cobol.vim @@ -1,7 +1,7 @@ " Vim filetype plugin file " Language: cobol " Author: Tim Pope -" $Id: cobol.vim,v 1.1 2007/05/05 17:24:38 vimboss Exp $ +" Last Update: By ZyX: use shiftwidth() " Insert mode mappings: " Normal mode mappings: < > << >> [[ ]] [] ][ @@ -113,7 +113,7 @@ endfunction function! s:increase(...) let lnum = '.' - let sw = &shiftwidth + let sw = shiftwidth() let i = a:0 ? a:1 : indent(lnum) if i >= 11 return sw - (i - 11) % sw @@ -128,7 +128,7 @@ endfunction function! s:decrease(...) let lnum = '.' - let sw = &shiftwidth + let sw = shiftwidth() let i = indent(a:0 ? a:1 : lnum) if i >= 11 + sw return 1 + (i + 12) % sw @@ -147,7 +147,7 @@ function! CobolIndentBlock(shift) let head = strpart(getline('.'),0,7) let tail = strpart(getline('.'),7) let indent = match(tail,'[^ ]') - let sw = &shiftwidth + let sw = shiftwidth() let shift = a:shift if shift > 0 if indent < 4 @@ -221,7 +221,8 @@ endfunction function! s:Tab() if (strpart(getline('.'),0,col('.')-1) =~ '^\s*$' && &sta) return s:IncreaseIndent() - elseif &sts == &sw && &sts != 8 && &et + " &softtabstop < 0: &softtabstop follows &shiftwidth + elseif (&sts < 0 || &sts == shiftwidth()) && &sts != 8 && &et return s:repeat(" ",s:increase(col('.')-1)) else return "\" diff --git a/runtime/ftplugin/debchangelog.vim b/runtime/ftplugin/debchangelog.vim index c74284fd41..d2718db88e 100644 --- a/runtime/ftplugin/debchangelog.vim +++ b/runtime/ftplugin/debchangelog.vim @@ -3,7 +3,7 @@ " Maintainer: Debian Vim Maintainers " Former Maintainers: Michael Piefel " Stefano Zacchiroli -" Last Change: 2012-01-31 +" Last Change: 2014-01-31 " License: Vim License " URL: http://hg.debian.org/hg/pkg-vim/vim/file/unstable/runtime/ftplugin/debchangelog.vim @@ -152,7 +152,7 @@ function CloseBug() endfunction function Distribution(dist) - call setline(1, substitute(getline(1), ") [[:lower:] ]*;", ") " . a:dist . ";", "")) + call setline(1, substitute(getline(1), ') *\%(UNRELEASED\|\l\+\);', ") " . a:dist . ";", "")) endfunction function Urgency(urg) diff --git a/runtime/ftplugin/jproperties.vim b/runtime/ftplugin/jproperties.vim new file mode 100644 index 0000000000..5bdd8a7cf3 --- /dev/null +++ b/runtime/ftplugin/jproperties.vim @@ -0,0 +1,15 @@ +" Vim filetype plugin +" Language: Java properties file +" Maintainer: David Bürgin <676c7473@gmail.com> +" Last Change: 2013-11-19 + +if exists("b:did_ftplugin") + finish +endif +let b:did_ftplugin = 1 + +setlocal formatoptions-=t +setlocal comments=:#,:! +setlocal commentstring=#\ %s + +let b:undo_ftplugin = "setl cms< com< fo<" diff --git a/runtime/ftplugin/python.vim b/runtime/ftplugin/python.vim index d823d68c9b..75c7e87996 100644 --- a/runtime/ftplugin/python.vim +++ b/runtime/ftplugin/python.vim @@ -1,7 +1,7 @@ " Vim filetype plugin file " Language: python " Maintainer: Johannes Zellner -" Last Change: 2013 Sep 25 +" Last Change: 2014 Feb 09 " Last Change By Johannes: Wed, 21 Apr 2004 13:13:08 CEST if exists("b:did_ftplugin") | finish | endif @@ -11,11 +11,11 @@ set cpo&vim setlocal cinkeys-=0# setlocal indentkeys-=0# -setlocal include=\s*\\(from\\\|import\\) +setlocal include=^\\s*\\(from\\\|import\\) setlocal includeexpr=substitute(v:fname,'\\.','/','g') setlocal suffixesadd=.py -setlocal comments-=:% -setlocal commentstring=#%s +setlocal comments=b:#,fb:- +setlocal commentstring=#\ %s setlocal omnifunc=pythoncomplete#Complete @@ -26,21 +26,21 @@ nnoremap [[ :call Python_jump('?^\(class\\|def\)') nnoremap ]m :call Python_jump('/^\s*\(class\\|def\)') nnoremap [m :call Python_jump('?^\s*\(class\\|def\)') -if exists('*Python_jump') | finish | endif +if !exists('*Python_jump') + fun! Python_jump(motion) range + let cnt = v:count1 + let save = @/ " save last search pattern + mark ' + while cnt > 0 + silent! exe a:motion + let cnt = cnt - 1 + endwhile + call histdel('/', -1) + let @/ = save " restore last search pattern + endfun +endif -fun! Python_jump(motion) range - let cnt = v:count1 - let save = @/ " save last search pattern - mark ' - while cnt > 0 - silent! exe a:motion - let cnt = cnt - 1 - endwhile - call histdel('/', -1) - let @/ = save " restore last search pattern -endfun - -if has("gui_win32") && !exists("b:browsefilter") +if has("browsefilter") && !exists("b:browsefilter") let b:browsefilter = "Python Files (*.py)\t*.py\n" . \ "All Files (*.*)\t*.*\n" endif diff --git a/runtime/ftplugin/registry.vim b/runtime/ftplugin/registry.vim new file mode 100644 index 0000000000..385785ac60 --- /dev/null +++ b/runtime/ftplugin/registry.vim @@ -0,0 +1,36 @@ +" Vim filetype plugin file +" Language: Windows Registry export with regedit (*.reg) +" Maintainer: Cade Forester +" Latest Revision: 2014-01-09 + +if exists("b:did_ftplugin") + finish +endif +let b:did_ftplugin = 1 + +let s:cpo_save = &cpo +set cpo&vim + +let b:undo_ftplugin = + \ 'let b:browsefilter = "" | ' . + \ 'setlocal ' . + \ 'comments< '. + \ 'commentstring< ' . + \ 'formatoptions< ' + + +if has( 'gui_win32' ) +\ && !exists( 'b:browsefilter' ) + let b:browsefilter = + \ 'registry files (*.reg)\t*.reg\n' . + \ 'All files (*.*)\t*.*\n' +endif + +setlocal comments=:; +setlocal commentstring=;\ %s + +setlocal formatoptions-=t +setlocal formatoptions+=croql + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/runtime/ftplugin/systemverilog.vim b/runtime/ftplugin/systemverilog.vim new file mode 100644 index 0000000000..4d0f565fcc --- /dev/null +++ b/runtime/ftplugin/systemverilog.vim @@ -0,0 +1,11 @@ +" Vim filetype plugin file +" Language: SystemVerilog +" Maintainer: kocha +" Last Change: 12-Aug-2013. + +if exists("b:did_ftplugin") + finish +endif + +" Behaves just like Verilog +runtime! ftplugin/verilog.vim diff --git a/runtime/indent/clojure.vim b/runtime/indent/clojure.vim index 7d0c2aa91f..df88cea942 100644 --- a/runtime/indent/clojure.vim +++ b/runtime/indent/clojure.vim @@ -6,7 +6,7 @@ " Maintainer: Sung Pae " URL: https://github.com/guns/vim-clojure-static " License: Same as Vim -" Last Change: 08 September 2013 +" Last Change: 16 December 2013 " TODO: Indenting after multibyte characters is broken: " (let [Δ (if foo @@ -53,6 +53,10 @@ if exists("*searchpairpos") let g:clojure_align_multiline_strings = 0 endif + if !exists('g:clojure_align_subforms') + let g:clojure_align_subforms = 0 + endif + function! s:SynIdName() return synIDattr(synID(line("."), col("."), 0), "name") endfunction @@ -284,7 +288,7 @@ if exists("*searchpairpos") call search('\v\_s', 'cW') call search('\v\S', 'W') if paren[0] < line(".") - return paren[1] + &shiftwidth - 1 + return paren[1] + (g:clojure_align_subforms ? 0 : &shiftwidth - 1) endif call search('\v\S', 'bW') diff --git a/runtime/indent/php.vim b/runtime/indent/php.vim index 4902b9e630..fd18664308 100644 --- a/runtime/indent/php.vim +++ b/runtime/indent/php.vim @@ -3,7 +3,7 @@ " Author: John Wellesz " URL: http://www.2072productions.com/vim/indent/php.vim " Home: https://github.com/2072/PHP-Indenting-for-VIm -" Last Change: 2013 August 7th +" Last Change: 2014 Jan 21 " Version: 1.39 " " @@ -642,7 +642,7 @@ function! GetPhpIndent() if previous_line =~ '^\s*}\|;\s*}'.endline " XXX call cursor(last_line_num, 1) - call search('}\|;\s*}'.endline, 'W') + call search('}\|;\s*}'.endline, 'cW') let oldLastLine = last_line_num let last_line_num = searchpair('{', '', '}', 'bW', 'Skippmatch()') diff --git a/runtime/indent/sh.vim b/runtime/indent/sh.vim index 49146c7e37..68f764ee69 100644 --- a/runtime/indent/sh.vim +++ b/runtime/indent/sh.vim @@ -1,7 +1,8 @@ " Vim indent file " Language: Shell Script -" Maintainer: Nikolai Weibull -" Latest Revision: 2010-01-06 +" Maintainer: Peter Aronoff +" Original Author: Nikolai Weibull +" Latest Revision: 2013-11-28 if exists("b:did_indent") finish @@ -77,6 +78,8 @@ function! GetShIndent() let line = getline(v:lnum) if line =~ '^\s*\%(then\|do\|else\|elif\|fi\|done\)\>' || line =~ '^\s*}' let ind -= s:indent_value('default') + elseif line =~ '^\s*esac\>' && s:is_case_empty(getline(v:lnum - 1)) + let ind -= s:indent_value('default') elseif line =~ '^\s*esac\>' let ind -= (s:is_case_label(pine, lnum) && s:is_case_ended(pine) ? \ 0 : s:indent_value('case-statements')) + @@ -154,5 +157,13 @@ function! s:is_case_ended(line) return s:is_case_break(a:line) || a:line =~ ';[;&]\s*\%(#.*\)\=$' endfunction +function! s:is_case_empty(line) + if a:line =~ '^\s*$' || a:line =~ '^\s*#' + return s:is_case_empty(getline(v:lnum - 1)) + else + return a:line =~ '^\s*case\>' + endif +endfunction + let &cpo = s:cpo_save unlet s:cpo_save diff --git a/runtime/indent/systemverilog.vim b/runtime/indent/systemverilog.vim new file mode 100644 index 0000000000..b017535535 --- /dev/null +++ b/runtime/indent/systemverilog.vim @@ -0,0 +1,230 @@ +" Vim indent file +" Language: SystemVerilog +" Maintainer: kocha +" Last Change: 12-Aug-2013. + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=SystemVerilogIndent() +setlocal indentkeys=!^F,o,O,0),0},=begin,=end,=join,=endcase,=join_any,=join_none +setlocal indentkeys+==endmodule,=endfunction,=endtask,=endspecify +setlocal indentkeys+==endclass,=endpackage,=endsequence,=endclocking +setlocal indentkeys+==endinterface,=endgroup,=endprogram,=endproperty,=endchecker +setlocal indentkeys+==`else,=`endif + +" Only define the function once. +if exists("*SystemVerilogIndent") + finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +function SystemVerilogIndent() + + if exists('b:systemverilog_indent_width') + let offset = b:systemverilog_indent_width + else + let offset = &sw + endif + if exists('b:systemverilog_indent_modules') + let indent_modules = offset + else + let indent_modules = 0 + endif + + " Find a non-blank line above the current line. + let lnum = prevnonblank(v:lnum - 1) + + " At the start of the file use zero indent. + if lnum == 0 + return 0 + endif + + let lnum2 = prevnonblank(lnum - 1) + let curr_line = getline(v:lnum) + let last_line = getline(lnum) + let last_line2 = getline(lnum2) + let ind = indent(lnum) + let ind2 = indent(lnum - 1) + let offset_comment1 = 1 + " Define the condition of an open statement + " Exclude the match of //, /* or */ + let sv_openstat = '\(\\|\([*/]\)\@<+-/%^&|!=?:]\([*/]\)\@!\)' + " Define the condition when the statement ends with a one-line comment + let sv_comment = '\(//.*\|/\*.*\*/\s*\)' + if exists('b:verilog_indent_verbose') + let vverb_str = 'INDENT VERBOSE:' + let vverb = 1 + else + let vverb = 0 + endif + + " Indent accoding to last line + " End of multiple-line comment + if last_line =~ '\*/\s*$' && last_line !~ '/\*.\{-}\*/' + let ind = ind - offset_comment1 + if vverb + echo vverb_str "De-indent after a multiple-line comment." + endif + + " Indent after if/else/for/case/always/initial/specify/fork blocks + elseif last_line =~ '`\@' || + \ last_line =~ '^\s*\<\(for\|case\%[[zx]]\|do\|foreach\|randcase\)\>' || + \ last_line =~ '^\s*\<\(always\|always_comb\|always_ff\|always_latch\)\>' || + \ last_line =~ '^\s*\<\(initial\|specify\|fork\|final\)\>' + if last_line !~ '\(;\|\\)\s*' . sv_comment . '*$' || + \ last_line =~ '\(//\|/\*\).*\(;\|\\)\s*' . sv_comment . '*$' + let ind = ind + offset + if vverb | echo vverb_str "Indent after a block statement." | endif + endif + " Indent after function/task/class/package/sequence/clocking/ + " interface/covergroup/property/checkerprogram blocks + elseif last_line =~ '^\s*\<\(function\|task\|class\|package\)\>' || + \ last_line =~ '^\s*\<\(sequence\|clocking\|interface\)\>' || + \ last_line =~ '^\s*\(\w\+\s*:\)\=\s*\' || + \ last_line =~ '^\s*\<\(property\|checker\|program\)\>' + if last_line !~ '\\s*' . sv_comment . '*$' || + \ last_line =~ '\(//\|/\*\).*\(;\|\\)\s*' . sv_comment . '*$' + let ind = ind + offset + if vverb + echo vverb_str "Indent after function/task/class block statement." + endif + endif + + " Indent after module/function/task/specify/fork blocks + elseif last_line =~ '^\s*\(\\s*\)\=\' + let ind = ind + indent_modules + if vverb && indent_modules + echo vverb_str "Indent after module statement." + endif + if last_line =~ '[(,]\s*' . sv_comment . '*$' && + \ last_line !~ '\(//\|/\*\).*[(,]\s*' . sv_comment . '*$' + let ind = ind + offset + if vverb + echo vverb_str "Indent after a multiple-line module statement." + endif + endif + + " Indent after a 'begin' statement + elseif last_line =~ '\(\\)\(\s*:\s*\w\+\)*' . sv_comment . '*$' && + \ last_line !~ '\(//\|/\*\).*\(\\)' && + \ ( last_line2 !~ sv_openstat . '\s*' . sv_comment . '*$' || + \ last_line2 =~ '^\s*[^=!]\+\s*:\s*' . sv_comment . '*$' ) + let ind = ind + offset + if vverb | echo vverb_str "Indent after begin statement." | endif + + " Indent after a '{' or a '(' + elseif last_line =~ '[{(]' . sv_comment . '*$' && + \ last_line !~ '\(//\|/\*\).*[{(]' && + \ ( last_line2 !~ sv_openstat . '\s*' . sv_comment . '*$' || + \ last_line2 =~ '^\s*[^=!]\+\s*:\s*' . sv_comment . '*$' ) + let ind = ind + offset + if vverb | echo vverb_str "Indent after begin statement." | endif + + " De-indent for the end of one-line block + elseif ( last_line !~ '\' || + \ last_line =~ '\(//\|/\*\).*\' ) && + \ last_line2 =~ '\<\(`\@.*' . + \ sv_comment . '*$' && + \ last_line2 !~ '\(//\|/\*\).*\<\(`\@' && + \ last_line2 !~ sv_openstat . '\s*' . sv_comment . '*$' && + \ ( last_line2 !~ '\' || + \ last_line2 =~ '\(//\|/\*\).*\' ) + let ind = ind - offset + if vverb + echo vverb_str "De-indent after the end of one-line statement." + endif + + " Multiple-line statement (including case statement) + " Open statement + " Ident the first open line + elseif last_line =~ sv_openstat . '\s*' . sv_comment . '*$' && + \ last_line !~ '\(//\|/\*\).*' . sv_openstat . '\s*$' && + \ last_line2 !~ sv_openstat . '\s*' . sv_comment . '*$' + let ind = ind + offset + if vverb | echo vverb_str "Indent after an open statement." | endif + + " Close statement + " De-indent for an optional close parenthesis and a semicolon, and only + " if there exists precedent non-whitespace char + elseif last_line =~ ')*\s*;\s*' . sv_comment . '*$' && + \ last_line !~ '^\s*)*\s*;\s*' . sv_comment . '*$' && + \ last_line !~ '\(//\|/\*\).*\S)*\s*;\s*' . sv_comment . '*$' && + \ ( last_line2 =~ sv_openstat . '\s*' . sv_comment . '*$' && + \ last_line2 !~ ';\s*//.*$') && + \ last_line2 !~ '^\s*' . sv_comment . '$' + let ind = ind - offset + if vverb | echo vverb_str "De-indent after a close statement." | endif + + " `ifdef and `else + elseif last_line =~ '^\s*`\<\(ifdef\|else\)\>' + let ind = ind + offset + if vverb + echo vverb_str "Indent after a `ifdef or `else statement." + endif + + endif + + " Re-indent current line + + " De-indent on the end of the block + " join/end/endcase/endfunction/endtask/endspecify + if curr_line =~ '^\s*\<\(join\|join_any\|join_none\|\|end\|endcase\|while\)\>' || + \ curr_line =~ '^\s*\<\(endfunction\|endtask\|endspecify\|endclass\)\>' || + \ curr_line =~ '^\s*\<\(endpackage\|endsequence\|endclocking\|endinterface\)\>' || + \ curr_line =~ '^\s*\<\(endgroup\|endproperty\|endchecker\|endprogram\)\>' || + \ curr_line =~ '^\s*}' + let ind = ind - offset + if vverb | echo vverb_str "De-indent the end of a block." | endif + elseif curr_line =~ '^\s*\' + let ind = ind - indent_modules + if vverb && indent_modules + echo vverb_str "De-indent the end of a module." + endif + + " De-indent on a stand-alone 'begin' + elseif curr_line =~ '^\s*\' + if last_line !~ '^\s*\<\(function\|task\|specify\|module\|class\|package\)\>' || + \ last_line !~ '^\s*\<\(sequence\|clocking\|interface\|covergroup\)\>' || + \ last_line !~ '^\s*\<\(property\|checker\|program\)\>' && + \ last_line !~ '^\s*\()*\s*;\|)\+\)\s*' . sv_comment . '*$' && + \ ( last_line =~ + \ '\<\(`\@' || + \ last_line =~ ')\s*' . sv_comment . '*$' || + \ last_line =~ sv_openstat . '\s*' . sv_comment . '*$' ) + let ind = ind - offset + if vverb + echo vverb_str "De-indent a stand alone begin statement." + endif + endif + + " De-indent after the end of multiple-line statement + elseif curr_line =~ '^\s*)' && + \ ( last_line =~ sv_openstat . '\s*' . sv_comment . '*$' || + \ last_line !~ sv_openstat . '\s*' . sv_comment . '*$' && + \ last_line2 =~ sv_openstat . '\s*' . sv_comment . '*$' ) + let ind = ind - offset + if vverb + echo vverb_str "De-indent the end of a multiple statement." + endif + + " De-indent `else and `endif + elseif curr_line =~ '^\s*`\<\(else\|endif\)\>' + let ind = ind - offset + if vverb | echo vverb_str "De-indent `else and `endif statement." | endif + + endif + + " Return the indention + return ind +endfunction + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vim:sw=2 diff --git a/runtime/plugin/getscriptPlugin.vim b/runtime/plugin/getscriptPlugin.vim index 45c858aac8..fb0fbeab7b 100644 --- a/runtime/plugin/getscriptPlugin.vim +++ b/runtime/plugin/getscriptPlugin.vim @@ -1,7 +1,7 @@ " --------------------------------------------------------------------- " getscriptPlugin.vim " Author: Charles E. Campbell -" Date: Jan 07, 2008 +" Date: Nov 29, 2013 " Installing: :help glvs-install " Usage: :help glvs " @@ -13,13 +13,16 @@ " Initialization: {{{1 " if you're sourcing this file, surely you can't be " expecting vim to be in its vi-compatible mode -if &cp || exists("g:loaded_getscriptPlugin") +if exists("g:loaded_getscriptPlugin") + finish +endif +if &cp if &verbose echo "GetLatestVimScripts is not vi-compatible; not loaded (you need to set nocp)" endif finish endif -let g:loaded_getscriptPlugin = "v35" +let g:loaded_getscriptPlugin = "v36" let s:keepcpo = &cpo set cpo&vim diff --git a/runtime/plugin/netrwPlugin.vim b/runtime/plugin/netrwPlugin.vim index 718bb663e7..d7439f828f 100644 --- a/runtime/plugin/netrwPlugin.vim +++ b/runtime/plugin/netrwPlugin.vim @@ -1,9 +1,9 @@ " netrwPlugin.vim: Handles file transfer and remote directory listing across a network " PLUGIN SECTION -" Date: Apr 30, 2013 +" Date: Dec 31, 2013 " Maintainer: Charles E Campbell " GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim -" Copyright: Copyright (C) 1999-2012 Charles E. Campbell {{{1 +" Copyright: Copyright (C) 1999-2013 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, @@ -20,27 +20,33 @@ if &cp || exists("g:loaded_netrwPlugin") finish endif -"DechoTabOn -let g:loaded_netrwPlugin = "v149" +let g:loaded_netrwPlugin = "v150" if v:version < 702 - echohl WarningMsg | echo "***netrw*** you need vim version 7.2 for this version of netrw" | echohl None + echohl WarningMsg + echo "***warning*** you need vim version 7.2 for this version of netrw" + echohl None + finish +endif +if v:version < 703 || (v:version == 703 && !has("patch465")) + echohl WarningMsg + echo "***warning*** this version of netrw needs vim 7.3.465 or later" + echohl Normal finish endif let s:keepcpo = &cpo set cpo&vim -"DechoTabOn +"DechoRemOn " --------------------------------------------------------------------- " Public Interface: {{{1 -" Local Browsing: {{{2 +" Local Browsing Autocmds: {{{2 augroup FileExplorer au! - " SEE Benzinger problem... - au BufEnter * sil! call s:LocalBrowse(expand("")) - au VimEnter * sil! call s:VimEnter(expand("")) + au BufEnter * sil call s:LocalBrowse(expand("")) + au VimEnter * sil call s:VimEnter(expand("")) if has("win32") || has("win95") || has("win64") || has("win16") - au BufEnter .* sil! call s:LocalBrowse(expand("")) + au BufEnter .* sil call s:LocalBrowse(expand("")) endif augroup END @@ -50,8 +56,8 @@ augroup Network au BufReadCmd file://* call netrw#FileUrlRead(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://*,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://*,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://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau FileWritePre ".fnameescape(expand(""))|exe "'[,']".'Nwrite '.fnameescape(expand(""))|exe "sil doau FileWritePost ".fnameescape(expand("")) + au BufWriteCmd ftp://*,rcp://*,scp://*,http://*,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://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau FileWritePre ".fnameescape(expand(""))|exe "'[,']".'Nwrite '.fnameescape(expand(""))|exe "sil doau FileWritePost ".fnameescape(expand("")) try au SourceCmd ftp://*,rcp://*,scp://*,http://*,https://*,dav://*,davs://*,rsync://*,sftp://* exe 'Nsource '.fnameescape(expand("")) catch /^Vim\%((\a\+)\)\=:E216/ @@ -64,8 +70,9 @@ com! -count=1 -nargs=* Nread call netrw#NetrwSavePosn()call netrw#NetRead( com! -range=% -nargs=* Nwrite call netrw#NetrwSavePosn(),call netrw#NetWrite()call netrw#NetrwRestorePosn() com! -nargs=* NetUserPass call NetUserPass() com! -nargs=* Nsource call netrw#NetrwSavePosn()call netrw#NetSource()call netrw#NetrwRestorePosn() +com! -nargs=? Ntree call netrw#NetrwSetTreetop() -" Commands: :Explore, :Sexplore, Hexplore, Vexplore {{{2 +" Commands: :Explore, :Sexplore, Hexplore, Vexplore, Lexplore {{{2 com! -nargs=* -bar -bang -count=0 -complete=dir Explore call netrw#Explore(,0,0+0,) com! -nargs=* -bar -bang -count=0 -complete=dir Sexplore call netrw#Explore(,1,0+0,) com! -nargs=* -bar -bang -count=0 -complete=dir Hexplore call netrw#Explore(,1,2+0,) @@ -73,6 +80,7 @@ com! -nargs=* -bar -bang -count=0 -complete=dir Vexplore call netrw#Explore(,0,6 ,) com! -nargs=* -bar -bang Nexplore call netrw#Explore(-1,0,0,) com! -nargs=* -bar -bang Pexplore call netrw#Explore(-2,0,0,) +com! -nargs=* -bar -complete=dir Lexplore call netrw#Lexplore() " Commands: NetrwSettings {{{2 com! -nargs=0 NetrwSettings call netrwSettings#NetrwSettings() @@ -83,46 +91,61 @@ if !exists("g:netrw_nogx") && maparg('gx','n') == "" if !hasmapto('NetrwBrowseX') nmap gx NetrwBrowseX endif - nno NetrwBrowseX :call netrw#NetrwBrowseX(expand(""),0) + nno NetrwBrowseX :call netrw#NetrwBrowseX(expand(""),0) endif " --------------------------------------------------------------------- -" LocalBrowse: {{{2 +" LocalBrowse: invokes netrw#LocalBrowseCheck() on directory buffers {{{2 fun! s:LocalBrowse(dirname) - " unfortunate interaction -- debugging calls can't be used here; - " the BufEnter event causes triggering when attempts to write to + " Unfortunate interaction -- only DechoMsg debugging calls can be safely used here. + " Otherwise, the BufEnter event gets triggered when attempts to write to " the DBG buffer are made. + if !exists("s:vimentered") + " If s:vimentered doesn't exist, then the VimEnter event hasn't fired. It will, + " and so s:VimEnter() will then be calling this routine, but this time with s:vimentered defined. +" call Dfunc("s:LocalBrowse(dirname<".a:dirname.">) (s:vimentered doesn't exist)") +" call Dret("s:LocalBrowse") return endif -" call Decho("s:LocalBrowse(dirname<".a:dirname.">){") -" echomsg "dirname<".a:dirname.">" + +" call Dfunc("s:LocalBrowse(dirname<".a:dirname.">) (s:vimentered=".s:vimentered.")") + if has("amiga") " The check against '' is made for the Amiga, where the empty " string is the current directory and not checking would break " things such as the help command. -" call Decho("(LocalBrowse) dirname<".a:dirname."> (amiga)") +" call Decho("(LocalBrowse) dirname<".a:dirname."> (isdirectory, amiga)") if a:dirname != '' && isdirectory(a:dirname) sil! call netrw#LocalBrowseCheck(a:dirname) endif + elseif isdirectory(a:dirname) -" echomsg "dirname<".dirname."> isdir" -" call Decho("(LocalBrowse) dirname<".a:dirname."> (not amiga)") +" call Decho("(LocalBrowse) dirname<".a:dirname."> (isdirectory, not amiga)") sil! call netrw#LocalBrowseCheck(a:dirname) + + else + " not a directory, ignore it +" call Decho("(LocalBrowse) dirname<".a:dirname."> not a directory, ignoring...") endif - " not a directory, ignore it -" call Decho("|return s:LocalBrowse }") + +" call Dret("s:LocalBrowse") endfun " --------------------------------------------------------------------- -" s:VimEnter: {{{2 +" s:VimEnter: after all vim startup stuff is done, this function is called. {{{2 +" Its purpose: to look over all windows and run s:LocalBrowse() on +" them, which checks if they're directories and will create a directory +" listing when appropriate. +" It also sets s:vimentered, letting s:LocalBrowse() know that s:VimEnter() +" has already been called. fun! s:VimEnter(dirname) -" call Decho("VimEnter(dirname<".a:dirname.">){") +" call Dfunc("s:VimEnter(dirname<".a:dirname.">) expand(%)<".expand("%").">") let curwin = winnr() let s:vimentered = 1 - windo if a:dirname != expand("%")|call s:LocalBrowse(expand("%:p"))|endif + windo call s:LocalBrowse(expand("%:p")) exe curwin."wincmd w" -" call Decho("|return VimEnter }") +" call Dret("s:VimEnter") endfun " --------------------------------------------------------------------- diff --git a/runtime/syntax/a65.vim b/runtime/syntax/a65.vim index dbf1cdb46d..94198e6a42 100644 --- a/runtime/syntax/a65.vim +++ b/runtime/syntax/a65.vim @@ -1,7 +1,7 @@ " Vim syntax file " Language: xa 6502 cross assembler -" Maintainer: Clemens Kirchgatterer -" Last Change: 2003 May 03 +" Maintainer: Clemens Kirchgatterer +" Last Change: 2014 Jan 05 " For version 5.x: Clear all syntax items " For version 6.x: Quit when a syntax file was already loaded diff --git a/runtime/syntax/arduino.vim b/runtime/syntax/arduino.vim new file mode 100644 index 0000000000..14299a441a --- /dev/null +++ b/runtime/syntax/arduino.vim @@ -0,0 +1,61 @@ +" Vim syntax file +" Language: Arduino +" Maintainer: Johannes Hoff +" Last Change: 2011 June 3 +" License: VIM license (:help license, replace vim by arduino.vim) + +" Syntax highlighting like in the Arduino IDE +" Keywords extracted from /build/shared/lib/keywords.txt (arduino +" version 0021) + +" Thanks to Rik, Erik Nomitch, Adam Obeng and Graeme Cross for helpful feedback! + +" For version 5.x: Clear all syntax items +" For version 6.x: Quit when a syntax file was already loaded +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish +endif + +" Read the C syntax to start with +if version < 600 + so :p:h/cpp.vim +else + runtime! syntax/cpp.vim +endif + +syn keyword arduinoConstant HIGH LOW INPUT OUTPUT +syn keyword arduinoConstant DEC BIN HEX OCT BYTE +syn keyword arduinoConstant PI HALF_PI TWO_PI +syn keyword arduinoConstant LSBFIRST MSBFIRST +syn keyword arduinoConstant CHANGE FALLING RISING +syn keyword arduinoConstant SERIAL DISPLAY +syn keyword arduinoConstant DEFAULT EXTERNAL INTERNAL INTERNAL1V1 INTERNAL2V56 + +syn keyword arduinoStdFunc abs acos asin atan atan2 ceil constrain +syn keyword arduinoStdFunc cos degrees exp floor log +syn keyword arduinoStdFunc map max min pow radians +syn keyword arduinoStdFunc round sin sq sqrt tan +syn keyword arduinoStdFunc randomSeed random + +syn keyword arduinoFunc analogReference analogRead analogWrite +syn keyword arduinoFunc attachInterrupt detachInterrupt interrupts noInterrupts +syn keyword arduinoFunc lowByte highByte bitRead bitWrite bitSet bitClear +syn keyword arduinoFunc millis micros delay delayMicroseconds +syn keyword arduinoFunc pinMode digitalWrite digitalRead +syn keyword arduinoFunc tone noTone pulseIn shiftOut + +syn keyword arduinoMethod setup loop +syn keyword arduinoMethod begin end available read flush print println write peek + +syn keyword arduinoType boolean byte word String + +syn keyword arduinoModule Serial Serial1 Serial2 Serial3 + +hi def link arduinoType Type +hi def link arduinoConstant Constant +hi def link arduinoStdFunc Function +hi def link arduinoFunc Function +hi def link arduinoMethod Function +hi def link arduinoModule Identifier diff --git a/runtime/syntax/asm.vim b/runtime/syntax/asm.vim index f208245ab1..e5f16c5bdc 100644 --- a/runtime/syntax/asm.vim +++ b/runtime/syntax/asm.vim @@ -3,7 +3,7 @@ " Maintainer: Erik Wognsen " Previous maintainer: " Kevin Dahlhausen -" Last Change: 2012 Apr 09 +" Last Change: 2014 Feb 04 " Thanks to Ori Avtalion for feedback on the comment markers! @@ -93,7 +93,11 @@ syn match asmCond "\.endif" syn match asmMacro "\.macro" syn match asmMacro "\.endm" -syn match asmDirective "\.[a-z][a-z]\+" +" Assembler directives start with a '.' and may contain upper case (e.g., +" .ABORT), numbers (e.g., .p2align), dash (e.g., .app-file) and underscore in +" CFI directives (e.g., .cfi_startproc). This will also match labels starting +" with '.', including the GCC auto-generated '.L' labels. +syn match asmDirective "\.[A-Za-z][0-9A-Za-z-_]*" syn case match diff --git a/runtime/syntax/clojure.vim b/runtime/syntax/clojure.vim index 09b8b1dd68..69117ff90c 100644 --- a/runtime/syntax/clojure.vim +++ b/runtime/syntax/clojure.vim @@ -9,13 +9,13 @@ " Maintainer: Sung Pae " URL: https://github.com/guns/vim-clojure-static " License: Same as Vim -" Last Change: 08 September 2013 +" Last Change: 16 December 2013 if exists("b:current_syntax") finish endif -" Generated from https://github.com/guns/vim-clojure-static/blob/vim-release-005/clj/src/vim_clojure_static/generate.clj +" Generated from https://github.com/guns/vim-clojure-static/blob/vim-release-007/clj/src/vim_clojure_static/generate.clj " Clojure version 1.5.1 syntax keyword clojureConstant nil syntax keyword clojureBoolean false true @@ -38,7 +38,7 @@ syntax match clojureKeyword "\v<:{1,2}%([^ \n\r\t()\[\]{}";@^`~\\%/]+/)*[^ \n\r\ syntax match clojureStringEscape "\v\\%([\\btnfr"]|u\x{4}|[0-3]\o{2}|\o{1,2})" contained -syntax region clojureString start=/"/ skip=/\\\\\|\\"/ end=/"/ contains=clojureStringEscape +syntax region clojureString start=/"/ skip=/\\\\\|\\"/ end=/"/ contains=clojureStringEscape,@Spell syntax match clojureCharacter "\\." syntax match clojureCharacter "\\o\%([0-3]\o\{2\}\|\o\{1,2\}\)" @@ -75,12 +75,12 @@ syntax match clojureDispatch "\v#[\^'=<_]?" " Clojure permits no more than 20 params. syntax match clojureAnonArg "%\(20\|1\d\|[1-9]\|&\)\?" -syntax match clojureRegexpEscape "\v\\%([\\tnrfae()\[\]{}^$*?+]|c\u|0[0-3]?\o{1,2}|x%(\x{2}|\{\x{1,6}\})|u\x{4})" contained display +syntax match clojureRegexpEscape "\v\\%([\\tnrfae.()\[\]{}^$*?+]|c\u|0[0-3]?\o{1,2}|x%(\x{2}|\{\x{1,6}\})|u\x{4})" contained display syntax region clojureRegexpQuoted start=/\\Q/ms=e+1 skip=/\\\\\|\\"/ end=/\\E/me=s-1 end=/"/me=s-1 contained syntax region clojureRegexpQuote start=/\\Q/ skip=/\\\\\|\\"/ end=/\\E/ end=/"/me=s-1 contains=clojureRegexpQuoted keepend contained " Character property classes -" Generated from https://github.com/guns/vim-clojure-static/blob/vim-release-005/clj/src/vim_clojure_static/generate.clj +" Generated from https://github.com/guns/vim-clojure-static/blob/vim-release-007/clj/src/vim_clojure_static/generate.clj " Java version 1.7.0_40 syntax match clojureRegexpPosixCharClass "\v\\[pP]\{%(Blank|P%(unct|rint)|Digit|Graph|A%(l%(pha|num)|SCII)|XDigit|Space|Upper|Lower|Cntrl)\}" contained display syntax match clojureRegexpJavaCharClass "\v\\[pP]\{java%(U%(pperCase|nicodeIdentifier%(Start|Part))|Mirrored|Alphabetic|SpaceChar|D%(efined|igit)|Whitespace|L%(etter%(OrDigit)?|owerCase)|TitleCase|I%(de%(ographic|ntifierIgnorable)|SOControl)|JavaIdentifier%(Start|Part))\}" contained display @@ -91,23 +91,23 @@ syntax match clojureRegexpUnicodeCharClass "\v\\[pP]\{%(Is|gc\=|general_category syntax match clojureRegexpUnicodeCharClass "\v\\[pP]\{\c%(Is|sc\=|script\=)%(h%(ira%(gana)?|an%([io]|g%(ul)?|unoo)?|ebr%(ew)?)|yi%(ii)?|java%(nese)?|c%(prt|y%(r%(illic|l)|priot)|h%(er%(okee)?|am)|uneiform|o%(mmon|pt%(ic)?)|a%(n%(adian_aboriginal|s)|ri%(an)?))|i%(mperial_aramaic|tal|n%(herited|scriptional_pa%(rthian|hlavi)))|a%(r%(ab%(ic)?|m%([in]|enian))|v%(st|estan))|g%(oth%(ic)?|u%(j%(arati|r)|r%(mukhi|u))|lag%(olitic)?|eor%(gian)?|re%(k|ek))|b%(u%(gi%(nese)?|h%(d|id))|ra%(i%(lle)?|h%(mi)?)|a%(mum?|t%(k|ak)|li%(nese)?)|opo%(mofo)?|eng%(ali)?)|s%(ha%(w|vian)|und%(anese)?|y%(r%(iac|c)|lo%(ti_nagri)?)|inh%(ala)?|a%(ur%(ashtra)?|rb|m%(r|aritan)))|d%(srt|e%(va%(nagari)?|seret))|l%(a%(na|oo?|t%(n|in))|epc%(ha)?|i%(n%(ear_b|b)|mbu?|su)|y%([dc]i%(an)?))|p%(h%(oenician|nx|li|ag%(s_pa)?)|rti)|e%(gyp%(tian_hieroglyphs)?|thi%(opic)?)|r%(jng|un%(ic|r)|ejang)|u%(nknown|gar%(itic)?)|vaii?|n%(koo?|ew_tai_lue)|m%(y%(mr|anmar)|tei|a%(nd%(aic)?|layalam)|ong%(olian)?|eetei_mayek|lym)|z%(inh|yyy|zzz)|t%(glg|fng|i%(finagh|b%(t|etan))|ha%(i|a%(na)?)|elu%(gu)?|a%(i_%(viet|le|tham)|l[eu]|g%(alog|b%(anwa)?)|vt|m%(l|il)))|x%(sux|peo)|o%(r%(iya|kh|ya)|sma%(nya)?|g%(am|ham)|l%(ck|d_%(south_arabian|turkic|italic|persian)|_chiki))|k%(a%(takana|yah_li|n%(nada|a)|li|ithi)|h%(m%(r|er)|ar%(oshthi)?)|thi|nda))\}" contained display syntax match clojureRegexpUnicodeCharClass "\v\\[pP]\{\c%(In|blk\=|block\=)%(s%(a%(maritan|urashtra)|mall%(_form_variants| form variants|formvariants)|inhala|y%(loti%(nagri|[_ ]nagri)|riac)|havian|p%(ecials|acing%(modifierletters|_modifier_letters| modifier letters))|u%(p%(erscripts%(andsubscripts|_and_subscripts| and subscripts)|plementa%(ry%( private use area-[ab]|_private_use_area_[ab]|privateusearea-[ab])|l%( %(arrows-[ab]|punctuation|mathematical operators)|arrows-[ab]|_%(punctuation|mathematical_operators|arrows_[ab])|punctuation|mathematicaloperators)))|ndanese|rrogates_area))|l%(a%(o|tin%(_%(extended_%(a%(dditional)?|[dcb])|1_supplement)| extended%(-[dacb]| additional)|-1%( supplement|supplement)|extended%(additional|-[dacb])))|e%(pcha|tterlike%(symbols|[_ ]symbols))|y[cd]ian|i%(su|mbu|near%(b%(ideograms|syllabary)|_b_%(ideograms|syllabary)| b %(ideograms|syllabary)))|ow%([_ ]surrogates|surrogates))|b%(a%(sic%(latin|[_ ]latin)|tak|linese|mum%([_ ]supplement|supplement)?)|yzantine%(_musical_symbols| musical symbols|musicalsymbols)|engali|u%(ginese|hid)|lock%(elements|[_ ]elements)|ra%(hmi|ille%([ _]patterns|patterns))|o%(x%(drawing|[_ ]drawing)|pomofo%([ _]extended|extended)?))|t%(a%(g%(s|alog|banwa)|mil|i%( %(viet|xuan jing symbols|le|tham)|viet|le|_%(xuan_jing_symbols|viet|le|tham)|tham|xuanjingsymbols))|ha%(i|ana)|elugu|i%(finagh|betan)|ransport%(_and_map_symbols| and map symbols|andmapsymbols))|n%(ew%(_tai_lue| tai lue|tailue)|umber%([ _]forms|forms)|ko)|m%(iscellaneous%(_%(mathematical_symbols_[ab]|symbols%(_and_%(arrows|pictographs))?|technical)|mathematicalsymbols-[ab]|technical| %(symbols%( and %(arrows|pictographs))?|mathematical symbols-[ab]|technical)|symbols%(and%(arrows|pictographs))?)|eetei%(mayek|[_ ]mayek)|a%(ndaic|thematical%(alphanumericsymbols|operators|_%(alphanumeric_symbols|operators)| %(operators|alphanumeric symbols))|hjong%(tiles|[_ ]tiles)|layalam)|yanmar%(_extended_a|extended-a| extended-a)?|o%(difier%( tone letters|toneletters|_tone_letters)|ngolian)|usical%(symbols|[_ ]symbols))|p%(h%(a%(gs[-_]pa|istos%(disc|[_ ]disc))|o%(netic%(_extensions%(_supplement)?| extensions%( supplement)?|extensions%(supplement)?)|enician))|rivate%(usearea|_use_area| use area)|laying%(cards|[_ ]cards))|javanese|u%(garitic|nified%(_canadian_aboriginal_syllabics%(_extended)?| canadian aboriginal syllabics%( extended)?|canadianaboriginalsyllabics%(extended)?))|o%(riya|gham|l%([ _]chiki|d%(turkic|_%(south_arabian|turkic|italic|persian)|italic|persian| %(south arabian|turkic|italic|persian)|southarabian)|chiki)|smanya|ptical%(_character_recognition| character recognition|characterrecognition))|v%(e%(dic%(extensions|[_ ]extensions)|rtical%([ _]forms|forms))|a%(i|riation%(_selectors%(_supplement)?| selectors%( supplement)?|selectors%(supplement)?)))|a%(vestan|l%(phabetic%(_presentation_forms| presentation forms|presentationforms)|chemical%(symbols|[_ ]symbols))|ncient%( %(symbols|greek %(musical notation|numbers))|symbols|greek%(musicalnotation|numbers)|_%(symbols|greek_%(musical_notation|numbers)))|egean%([ _]numbers|numbers)|r%(menian|rows|abic%( %(presentation forms-[ab]|supplement)|_%(presentation_forms_[ab]|supplement)|presentationforms-[ab]|supplement)?))|i%(nscriptional%(pa%(rthian|hlavi)|%([_ ]pa%(rthian|hlavi)))|deographic%( description characters|descriptioncharacters|_description_characters)|pa%(extensions|[_ ]extensions)|mperial%(aramaic|[_ ]aramaic))|yi%(%([_ ]%(radicals|syllables))|radicals|syllables|jing%(hexagramsymbols|_hexagram_symbols| hexagram symbols))|k%(a%(yah%(li|[_ ]li)|n%(nada|bun|a%([_ ]supplement|supplement)|gxi%(radicals|[_ ]radicals))|ithi|takana%(phoneticextensions|_phonetic_extensions| phonetic extensions)?)|h%(aroshthi|mer%(symbols|[_ ]symbols)?))|d%(e%(vanagari%([ _]extended|extended)?|seret)|omino%(tiles|[_ ]tiles)|ingbats)|g%(lagolitic|othic|reek%(andcoptic| %(and coptic|extended)|extended|_extended)?|u%(rmukhi|jarati)|e%(o%(metric%([_ ]shapes|shapes)|rgian%([_ ]supplement|supplement)?)|neral%(punctuation|[_ ]punctuation)))|e%(nclosed%( %(ideographic supplement|cjk letters and months|alphanumeric%( supplement|s))|cjklettersandmonths|_%(ideographic_supplement|alphanumeric%(_supplement|s)|cjk_letters_and_months)|alphanumerics%(upplement)?|ideographicsupplement)|moticons|thiopic%(extended%(-a)?| %(extended%(-a)?|supplement)|_%(extended%(_a)?|supplement)|supplement)?|gyptian%(hieroglyphs|[_ ]hieroglyphs))|r%(ejang|u%(nic|mi%(numeralsymbols|_numeral_symbols| numeral symbols)))|c%(jk%(_%(compatibility%(_%(ideographs%(_supplement)?|forms))?|radicals_supplement|unified_ideographs%(_extension_[dacb])?|s%(trokes|ymbols_and_punctuation))|compatibility%(ideographs%(supplement)?|forms)?|unifiedideographs%(extension[dacb])?|radicalssupplement|s%(ymbolsandpunctuation|trokes)| %(unified ideographs%( extension [dacb])?|s%(trokes|ymbols and punctuation)|radicals supplement|compatibility%( %(forms|ideographs%( supplement)?))?))|h%(am|erokee)|u%(neiform%(_numbers_and_punctuation| numbers and punctuation|numbersandpunctuation)?|rrency%(symbols|[_ ]symbols))|y%(rillic%(_%(extended_[ab]|supplementary)| %(extended-[ab]|supplement%(ary)?)|extended-[ab]|supplement%(ary)?)?|priot%([_ ]syllabary|syllabary))|o%(ntrol%(pictures|[_ ]pictures)|unting%(rodnumerals|_rod_numerals| rod numerals)|m%(bining%(halfmarks|diacriticalmarks%(forsymbols|supplement)?| %(marks for symbols|half marks|diacritical marks%( %(for symbols|supplement))?)|marksforsymbols|_%(marks_for_symbols|half_marks|diacritical_marks%(_supplement)?))|mon%( indic number forms|indicnumberforms|_indic_number_forms))|ptic)|arian)|h%(i%(ragana|gh%(_%(private_use_surrogates|surrogates)| %(private use surrogates|surrogates)|surrogates|privateusesurrogates))|ebrew|a%(n%(unoo|gul%(jamo%(extended-[ab])?| %(jamo%( extended-[ab])?|syllables|compatibility jamo)|_%(syllables|jamo%(_extended_[ab])?|compatibility_jamo)|syllables|compatibilityjamo))|lfwidth%( and fullwidth forms|andfullwidthforms|_and_fullwidth_forms))))\}" contained display -syntax match clojureRegexpPredefinedCharClass "\v%(\\[dDsSwW]|\.)" contained display -syntax cluster clojureRegexpCharPropertyClasses contains=clojureRegexpPosixCharClass,clojureRegexpJavaCharClass,clojureRegexpUnicodeCharClass -syntax cluster clojureRegexpCharClasses contains=clojureRegexpPredefinedCharClass,clojureRegexpCharClass,@clojureRegexpCharPropertyClasses -syntax region clojureRegexpCharClass start="\[" skip=/\\\\\|\\]/ end="]" contained contains=clojureRegexpPredefinedCharClass,@clojureRegexpCharPropertyClasses -syntax match clojureRegexpBoundary "\\[bBAGZz]" contained display -syntax match clojureRegexpBoundary "[$^]" contained display -syntax match clojureRegexpQuantifier "[?*+][?+]\=" contained display -syntax match clojureRegexpQuantifier "\v\{\d+%(,|,\d+)?}\??" contained display -syntax match clojureRegexpOr "|" contained display -syntax match clojureRegexpBackRef "\v\\%([1-9]\d*|k\<[a-zA-z]+\>)" contained display +syntax match clojureRegexpPredefinedCharClass "\v%(\\[dDsSwW]|\.)" contained display +syntax cluster clojureRegexpCharPropertyClasses contains=clojureRegexpPosixCharClass,clojureRegexpJavaCharClass,clojureRegexpUnicodeCharClass +syntax cluster clojureRegexpCharClasses contains=clojureRegexpPredefinedCharClass,clojureRegexpCharClass,@clojureRegexpCharPropertyClasses +syntax region clojureRegexpCharClass start="\[" skip=/\\\\\|\\]/ end="]" contained contains=clojureRegexpPredefinedCharClass,@clojureRegexpCharPropertyClasses +syntax match clojureRegexpBoundary "\\[bBAGZz]" contained display +syntax match clojureRegexpBoundary "[$^]" contained display +syntax match clojureRegexpQuantifier "[?*+][?+]\=" contained display +syntax match clojureRegexpQuantifier "\v\{\d+%(,|,\d+)?}\??" contained display +syntax match clojureRegexpOr "|" contained display +syntax match clojureRegexpBackRef "\v\\%([1-9]\d*|k\<[a-zA-z]+\>)" contained display " Mode modifiers, mode-modified spans, lookaround, regular and atomic " grouping, and named-capturing. -syntax match clojureRegexpMod "\v\(@<=\?:" contained display +syntax match clojureRegexpMod "\v\(@<=\?:" contained display syntax match clojureRegexpMod "\v\(@<=\?[xdsmiuU]*-?[xdsmiuU]+:?" contained display -syntax match clojureRegexpMod "\v\(@<=\?%(\)" contained display -syntax match clojureRegexpMod "\v\(@<=\?\<[a-zA-Z]+\>" contained display +syntax match clojureRegexpMod "\v\(@<=\?%(\)" contained display +syntax match clojureRegexpMod "\v\(@<=\?\<[a-zA-Z]+\>" contained display syntax region clojureRegexpGroup start="(" skip=/\\\\\|\\)/ end=")" matchgroup=clojureRegexpGroup contained contains=clojureRegexpMod,clojureRegexpQuantifier,clojureRegexpBoundary,clojureRegexpEscape,@clojureRegexpCharClasses syntax region clojureRegexp start=/\#"/ skip=/\\\\\|\\"/ end=/"/ contains=@clojureRegexpCharClasses,clojureRegexpEscape,clojureRegexpQuote,clojureRegexpBoundary,clojureRegexpQuantifier,clojureRegexpOr,clojureRegexpBackRef,clojureRegexpGroup keepend @@ -126,13 +126,13 @@ syntax match clojureError "]\|}\|)" syntax sync fromstart -highlight default link clojureConstant Constant -highlight default link clojureBoolean Boolean -highlight default link clojureCharacter Character -highlight default link clojureKeyword Keyword -highlight default link clojureNumber Number -highlight default link clojureString String -highlight default link clojureStringEscape Character +highlight default link clojureConstant Constant +highlight default link clojureBoolean Boolean +highlight default link clojureCharacter Character +highlight default link clojureKeyword Keyword +highlight default link clojureNumber Number +highlight default link clojureString String +highlight default link clojureStringEscape Character highlight default link clojureRegexp Constant highlight default link clojureRegexpEscape Character @@ -150,29 +150,29 @@ highlight default link clojureRegexpGroup clojureRegexp highlight default link clojureRegexpQuoted clojureString highlight default link clojureRegexpQuote clojureRegexpBoundary -highlight default link clojureVariable Identifier -highlight default link clojureCond Conditional -highlight default link clojureDefine Define -highlight default link clojureException Exception -highlight default link clojureFunc Function -highlight default link clojureMacro Macro -highlight default link clojureRepeat Repeat +highlight default link clojureVariable Identifier +highlight default link clojureCond Conditional +highlight default link clojureDefine Define +highlight default link clojureException Exception +highlight default link clojureFunc Function +highlight default link clojureMacro Macro +highlight default link clojureRepeat Repeat -highlight default link clojureSpecial Special -highlight default link clojureVarArg Special -highlight default link clojureQuote SpecialChar -highlight default link clojureUnquote SpecialChar -highlight default link clojureMeta SpecialChar -highlight default link clojureDeref SpecialChar -highlight default link clojureAnonArg SpecialChar -highlight default link clojureDispatch SpecialChar +highlight default link clojureSpecial Special +highlight default link clojureVarArg Special +highlight default link clojureQuote SpecialChar +highlight default link clojureUnquote SpecialChar +highlight default link clojureMeta SpecialChar +highlight default link clojureDeref SpecialChar +highlight default link clojureAnonArg SpecialChar +highlight default link clojureDispatch SpecialChar -highlight default link clojureComment Comment -highlight default link clojureCommentTodo Todo +highlight default link clojureComment Comment +highlight default link clojureCommentTodo Todo -highlight default link clojureError Error +highlight default link clojureError Error -highlight default link clojureParen Delimiter +highlight default link clojureParen Delimiter let b:current_syntax = "clojure" diff --git a/runtime/syntax/css.vim b/runtime/syntax/css.vim index 1a70765382..c6fc6a7ae2 100644 --- a/runtime/syntax/css.vim +++ b/runtime/syntax/css.vim @@ -6,7 +6,7 @@ " Nikolai Weibull (Add CSS2 support) " Maintainer: Jules Wang " URL: https://github.com/JulesWang/css.vim -" Last Change: 2013 Sep 24 +" Last Change: 2013 Nov.27 " For version 5.x: Clear all syntax items " For version 6.x: Quit when a syntax file was already loaded @@ -58,7 +58,8 @@ syn match cssSelectorOp2 "[~|^$*]\?=" contained syn region cssAttributeSelector matchgroup=cssSelectorOp start="\[" end="]" contains=cssUnicodeEscape,cssSelectorOp2,cssStringQ,cssStringQQ " .class and #id -syn match cssClassName "\.[A-Za-z][A-Za-z0-9_-]\+" +syn match cssClassName "\.[A-Za-z][A-Za-z0-9_-]\+" contains=cssClassNameDot +syn match cssClassNameDot contained '\.' try syn match cssIdentifier "#[A-Za-zÀ-ÿ_@][A-Za-zÀ-ÿ0-9_@-]*" @@ -74,13 +75,14 @@ syn match cssValueAngle contained "[-+]\=\d\+\(\.\d*\)\=\(deg\|grad\|rad\)" cont syn match cssValueTime contained "+\=\d\+\(\.\d*\)\=\(ms\|s\)" contains=cssUnitDecorators syn match cssValueFrequency contained "+\=\d\+\(\.\d*\)\=\(Hz\|kHz\)" contains=cssUnitDecorators + +syn match cssIncludeKeyword /@\(-[a-z]+-\)\=\(media\|keyframes\|import\|charset\|namespace\|page\)/ contained " @media -syn match cssMedia "@media\>" nextgroup=cssMediaQuery,cssMediaBlock skipwhite skipnl -syn match cssMediaQuery /\(only\|not\)\=\s*[a-z]*\(\s\|,\)\@=\(\(\s\+and\)\=\s\+(.\{-})\)*/ contained skipwhite skipnl contains=cssMediaProp,cssValueLength,cssMediaKeyword,cssValueInteger,cssMediaAttr,cssVendor,cssMediaType nextgroup=cssMediaBlock,cssMediaComma +syn region cssInclude start=/@media\>/ end=/\ze{/ skipwhite skipnl contains=cssMediaProp,cssValueLength,cssMediaKeyword,cssValueInteger,cssMediaAttr,cssVendor,cssMediaType,cssIncludeKeyword,cssMediaComma,cssComment nextgroup=cssMediaBlock syn keyword cssMediaType contained screen print aural braille embossed handheld projection tty tv speech all contained skipwhite skipnl syn keyword cssMediaKeyword only not and contained syn region cssMediaBlock transparent matchgroup=cssBraces start='{' end='}' contains=css.*Attr,css.*Prop,cssComment,cssValue.*,cssColor,cssURL,cssImportant,cssError,cssStringQ,cssStringQQ,cssFunction,cssUnicodeEscape,cssVendor,cssDefinition,cssTagName,cssClassName,cssIdentifier,cssPseudoClass,cssSelectorOp,cssSelectorOp2,cssAttributeSelector fold -syn match cssMediaComma "," nextgroup=cssMediaQuery skipwhite skipnl contained +syn match cssMediaComma "," skipwhite skipnl contained " Reference: http://www.w3.org/TR/css3-mediaqueries/ syn keyword cssMediaProp contained width height orientation scan grid @@ -91,21 +93,25 @@ syn match cssMediaProp contained /\(\(max\|min\)-\)\=\(height\|width\|resolution syn keyword cssMediaAttr contained portrait landscape progressive interlace " @page -syn match cssPage "@page\>" nextgroup=cssPagePseudo,cssDefinition skipwhite skipnl -syn match cssPagePseudo /:\(left\|right\|first\|\)/ nextgroup=cssDefinition contained skipwhite skipnl -syn match cssPageHeaderProp /@\(\(top\|left\|right\|bottom\)-\(left\|center\|right\|middle\|bottom\)\)\(-corner\)\=/ contained -syn keyword cssPageProp content size contained +" http://www.w3.org/TR/css3-page/ +syn match cssPage "@page\>[^{]*{\@=" contains=cssPagePseudo,cssIncludeKeyword nextgroup=cssPageWrap transparent skipwhite skipnl +syn match cssPagePseudo /:\(left\|right\|first\|blank\)/ contained skipwhite skipnl +syn region cssPageWrap contained transparent matchgroup=cssBraces start="{" end="}" contains=cssPageMargin,cssPageProp,cssAttrRegion,css.*Prop,cssComment,cssValue.*,cssColor,cssURL,cssImportant,cssError,cssStringQ,cssStringQQ,cssFunction,cssUnicodeEscape,cssVendor,cssDefinition,cssHacks +syn match cssPageMargin /@\(\(top\|left\|right\|bottom\)-\(left\|center\|right\|middle\|bottom\)\)\(-corner\)\=/ contained nextgroup=cssDefinition skipwhite skipnl +syn keyword cssPageProp contained content size +" http://www.w3.org/TR/CSS2/page.html#break-inside +syn keyword cssPageProp contained orphans widows " @keyframe -syn match cssKeyFrame "@\(-[a-z]*-\)\=keyframes\>\(\s*\<\S*\>\)\=" nextgroup=cssKeyFrameBlock contains=cssVendor skipwhite skipnl -syn region cssKeyFrameBlock contained transparent matchgroup=cssBraces start="{" end="}" contains=cssKeyFrameSelector,cssDefinition -syn match cssKeyFrameSelector /\(\d*%\|from\|to\)\=/ contained skipwhite skipnl +" http://www.w3.org/TR/css3-animations/#keyframes +syn match cssKeyFrame "@\(-[a-z]+-\)\=keyframes\>[^{]*{\@=" nextgroup=cssKeyFrameWrap contains=cssVendor,cssIncludeKeyword skipwhite skipnl transparent +syn region cssKeyFrameWrap contained transparent matchgroup=cssBraces start="{" end="}" contains=cssKeyFrameSelector +syn match cssKeyFrameSelector /\(\d*%\|from\|to\)\=/ contained skipwhite skipnl nextgroup=cssDefinition " @import -syn region cssInclude start=/@import\>/ end=/\ze;/ contains=cssComment,cssURL,cssUnicodeEscape,cssMediaQuery,cssStringQ,cssStringQQ,cssIncludeKeyword -syn region cssInclude start=/@charset\>/ end=/\ze;/ contains=cssStringQ,cssStringQQ,cssUnicodeEscape,cssComment,cssIncludeKeyword -syn region cssInclude start=/@namespace\>/ end=/\ze;/ contains=cssStringQ,cssStringQQ,cssUnicodeEscape,cssComment,cssIncludeKeyword -syn match cssIncludeKeyword /\(@import\|@charset\|@namespace\)/ contained +syn region cssInclude start=/@import\>/ end=/\ze;/ transparent contains=cssStringQ,cssStringQQ,cssUnicodeEscape,cssComment,cssIncludeKeyword,cssURL,cssMediaProp,cssValueLength,cssMediaKeyword,cssValueInteger,cssMediaAttr,cssVendor,cssMediaType +syn region cssInclude start=/@charset\>/ end=/\ze;/ transparent contains=cssStringQ,cssStringQQ,cssUnicodeEscape,cssComment,cssIncludeKeyword +syn region cssInclude start=/@namespace\>/ end=/\ze;/ transparent contains=cssStringQ,cssStringQQ,cssUnicodeEscape,cssComment,cssIncludeKeyword " @font-face " http://www.w3.org/TR/css3-fonts/#at-font-face-rule @@ -179,7 +185,7 @@ syn keyword cssCommonAttr contained top bottom center stretch hidden visible "------------------------------------------------ " CSS Animations " http://www.w3.org/TR/css3-animations/ -syn match cssAnimationProp contained "\" +syn match cssAnimationProp contained "\" " animation-direction attributes syn keyword cssAnimationAttr contained alternate reverse @@ -215,7 +221,7 @@ syn match cssBorderProp contained "\" syn match cssBorderProp contained "\" " border-image attributes -syn keyword cssBorderAttr contained stretch repeat round space fill +syn keyword cssBorderAttr contained stretch round space fill " border-style attributes syn keyword cssBorderAttr contained dotted dashed solid double groove ridge inset outset @@ -230,7 +236,7 @@ syn keyword cssBorderAttr contained clone slice syn match cssBoxProp contained "\" syn match cssBoxProp contained "\" syn match cssBoxProp contained "\" -syn match cssBoxProp contained "\" +syn match cssBoxProp contained "\" syn keyword cssBoxAttr contained visible hidden scroll auto syn match cssBoxAttr contained "\" @@ -289,13 +295,26 @@ syn keyword cssFontAttr contained bold bolder lighter syn match cssFontProp contained "\" syn match cssFontAttr contained "\<\(subpixel-\)\=\antialiased\>" + +" CSS Multi-column Layout Module +" http://www.w3.org/TR/css3-multicol/ +syn match cssMultiColumnProp contained "\" +syn match cssMultiColumnProp contained "\" +syn keyword cssMultiColumnProp contained columns +syn keyword cssMultiColumnAttr contained balance medium +syn keyword cssMultiColumnAttr contained always avoid left right page column +syn match cssMultiColumnAttr contained "\" + +" http://www.w3.org/TR/css3-break/#page-break +syn match cssMultiColumnProp contained "\" + +" TODO find following items in w3c docs. syn keyword cssGeneratedContentProp contained quotes crop syn match cssGeneratedContentProp contained "\" syn match cssGeneratedContentProp contained "\" syn match cssGeneratedContentProp contained "\" syn match cssGeneratedContentAttr contained "\<\(no-\)\=\(open\|close\)-quote\>" - syn match cssGridProp contained "\" syn match cssHyerlinkProp contained "\" @@ -307,8 +326,6 @@ syn match cssListAttr contained "\<\(decimal\(-leading-zero\)\=\|cjk-ideographic syn keyword cssListAttr contained disc circle square hebrew armenian georgian syn keyword cssListAttr contained inside outside -syn match cssMultiColumnProp contained "\" - syn keyword cssPositioningProp contained bottom clear clip display float left syn keyword cssPositioningProp contained position right top visibility syn match cssPositioningProp contained "\" @@ -319,8 +336,6 @@ syn match cssPositioningAttr contained "\" syn match cssPositioningAttr contained "\" syn keyword cssPositioningAttr contained static relative absolute fixed -syn match cssPrintProp contained "\" -syn keyword cssPrintProp contained orphans widows syn keyword cssPrintAttr contained landscape portrait crop cross always avoid syn match cssTableProp contained "\<\(caption-side\|table-layout\|border-collapse\|border-spacing\|empty-cells\)\>" @@ -394,7 +409,7 @@ syn keyword cssUIAttr contained both horizontal vertical syn match cssUIProp contained "\" syn keyword cssUIAttr contained clip ellipsis -" Already highlighted Props: font content +" Already highlighted Props: font content "------------------------------------------------ " Webkit/iOS specific attributes syn match cssUIAttr contained '\(preserve-3d\)' @@ -456,8 +471,8 @@ syn match cssPseudoClassId contained "\<\(input-\)\=placeholder\>" syn region cssComment start="/\*" end="\*/" contains=@Spell fold syn match cssUnicodeEscape "\\\x\{1,6}\s\?" -syn match cssSpecialCharQQ +\\"+ contained -syn match cssSpecialCharQ +\\'+ contained +syn match cssSpecialCharQQ +\\\\\|\\"+ contained +syn match cssSpecialCharQ +\\\\\|\\'+ contained syn region cssStringQQ start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=cssUnicodeEscape,cssSpecialCharQQ syn region cssStringQ start=+'+ skip=+\\\\\|\\'+ end=+'+ contains=cssUnicodeEscape,cssSpecialCharQ @@ -478,11 +493,11 @@ syntax match cssNoise contained /\(:\|;\|\/\)/ " Attr Enhance " Some keywords are both Prop and Attr, so we have to handle them -syn region cssAttrRegion start=/:/ end=/;/ contained keepend contains=css.*Attr,cssColor,cssImportant,cssValue.*,cssFunction,cssString.*,cssURL,cssComment,cssUnicodeEscape,cssVendor,cssError,cssTransitionHackProp,cssAttrComma,cssNoise +syn region cssAttrRegion start=/:/ end=/;/ contained keepend contains=css.*Attr,cssColor,cssImportant,cssValue.*,cssFunction,cssString.*,cssURL,cssComment,cssUnicodeEscape,cssVendor,cssError,cssAttrComma,cssNoise " Hack for transition " The 'transition' Prop has Props after ':'. -syn region cssAttrRegion start=/transition\s*:/ end=/;/ contained keepend contains=css.*Prop,css.*Attr,cssColor,cssImportant,cssValue.*,cssFunction,cssString.*,cssURL,cssComment,cssUnicodeEscape,cssVendor,cssError,cssTransitionHackProp,cssAttrComma,cssNoise +syn region cssAttrRegion start=/transition\s*:/ end=/;/ contained keepend contains=css.*Prop,css.*Attr,cssColor,cssImportant,cssValue.*,cssFunction,cssString.*,cssURL,cssComment,cssUnicodeEscape,cssVendor,cssError,cssAttrComma,cssNoise if main_syntax == "css" @@ -593,7 +608,6 @@ if version >= 508 || !exists("did_css_syn_inits") HiLink cssBraces Function HiLink cssBraceError Error HiLink cssError Error - HiLink cssInclude Include HiLink cssUnicodeEscape Special HiLink cssStringQQ String HiLink cssStringQ String @@ -606,7 +620,7 @@ if version >= 508 || !exists("did_css_syn_inits") HiLink cssMediaAttr cssAttr HiLink cssPage atKeyword HiLink cssPagePseudo PreProc - HiLink cssPageHeaderProp PreProc + HiLink cssPageMargin atKeyword HiLink cssPageProp cssProp HiLink cssKeyFrame atKeyword HiLink cssKeyFrameSelector Constant @@ -616,6 +630,7 @@ if version >= 508 || !exists("did_css_syn_inits") HiLink cssFontDescriptorAttr cssAttr HiLink cssUnicodeRange Constant HiLink cssClassName Function + HiLink cssClassNameDot Function HiLink cssProp StorageClass HiLink cssAttr Constant HiLink cssUnitDecorators Number diff --git a/runtime/syntax/debchangelog.vim b/runtime/syntax/debchangelog.vim index b1d7a31390..4b3cbc7b34 100644 --- a/runtime/syntax/debchangelog.vim +++ b/runtime/syntax/debchangelog.vim @@ -3,7 +3,7 @@ " Maintainer: Debian Vim Maintainers " Former Maintainers: Gerfried Fuchs " Wichert Akkerman -" Last Change: 2013 May 05 +" Last Change: 2014 Jan 20 " URL: http://anonscm.debian.org/hg/pkg-vim/vim/raw-file/unstable/runtime/syntax/debchangelog.vim " Standard syntax initialization @@ -19,7 +19,7 @@ syn case ignore " Define some common expressions we can use later on syn match debchangelogName contained "^[[:alnum:]][[:alnum:].+-]\+ " syn match debchangelogUrgency contained "; urgency=\(low\|medium\|high\|critical\|emergency\)\( \S.*\)\=" -syn match debchangelogTarget contained "\v %(frozen|unstable|%(testing|%(old)=stable)%(-proposed-updates|-security)=|experimental|squeeze-%(backports%(-sloppy)=|volatile)|wheezy-backports|%(lucid|precise|quantal|raring|saucy)%(-%(security|proposed|updates|backports|commercial|partner))=)+" +syn match debchangelogTarget contained "\v %(frozen|unstable|%(testing|%(old)=stable)%(-proposed-updates|-security)=|experimental|squeeze-%(backports%(-sloppy)=|volatile)|wheezy-backports|%(lucid|precise|quantal|saucy|trusty)%(-%(security|proposed|updates|backports|commercial|partner))=)+" syn match debchangelogVersion contained "(.\{-})" syn match debchangelogCloses contained "closes:\_s*\(bug\)\=#\=\_s\=\d\+\(,\_s*\(bug\)\=#\=\_s\=\d\+\)*" syn match debchangelogLP contained "\clp:\s\+#\d\+\(,\s*#\d\+\)*" diff --git a/runtime/syntax/debcontrol.vim b/runtime/syntax/debcontrol.vim index 3ca17a86e9..2a14b67f0e 100644 --- a/runtime/syntax/debcontrol.vim +++ b/runtime/syntax/debcontrol.vim @@ -3,7 +3,7 @@ " Maintainer: Debian Vim Maintainers " Former Maintainers: Gerfried Fuchs " Wichert Akkerman -" Last Change: 2013 May 05 +" Last Change: 2013 Oct 28 " URL: http://anonscm.debian.org/hg/pkg-vim/vim/raw-file/unstable/runtime/syntax/debcontrol.vim " Standard syntax initialization @@ -24,7 +24,7 @@ syn match debControlComma ", *" syn match debControlSpace " " " Define some common expressions we can use later on -syn match debcontrolArchitecture contained "\%(all\|linux-any\|\%(any-\)\=\%(alpha\|amd64\|arm\%(e[bl]\|hf\)\=\|avr32\|hppa\|i386\|ia64\|lpia\|m32r\|m68k\|mips\%(el\)\=\|powerpc\|ppc64\|s390x\=\|sh[34]\(eb\)\=\|sh\|sparc\%(64\)\=\)\|hurd-\%(i386\|any\)\|kfreebsd-\%(i386\|amd64\|any\)\|knetbsd-\%(i386\|any\)\|kopensolaris-\%(i386\|any\)\|netbsd-\%(alpha\|i386\|any\)\|any\)" +syn match debcontrolArchitecture contained "\%(all\|linux-any\|\%(any-\)\=\%(alpha\|amd64\|arm\%(e[bl]\|hf\|64\)\=\|avr32\|hppa\|i386\|ia64\|lpia\|m32r\|m68k\|mips\%(el\)\=\|powerpc\%(spe\)\=\|ppc64\|s390x\=\|sh[34]\(eb\)\=\|sh\|sparc\%(64\)\=\)\|x32\|hurd-\%(i386\|any\)\|kfreebsd-\%(i386\|amd64\|any\)\|knetbsd-\%(i386\|any\)\|kopensolaris-\%(i386\|any\)\|netbsd-\%(alpha\|i386\|any\)\|any\)" syn match debcontrolMultiArch contained "\%(no\|foreign\|allowed\|same\)" syn match debcontrolName contained "[a-z0-9][a-z0-9+.-]\+" syn match debcontrolPriority contained "\(extra\|important\|optional\|required\|standard\)" diff --git a/runtime/syntax/debsources.vim b/runtime/syntax/debsources.vim index f3dd2a5fc1..0146d3d00f 100644 --- a/runtime/syntax/debsources.vim +++ b/runtime/syntax/debsources.vim @@ -2,7 +2,7 @@ " Language: Debian sources.list " Maintainer: Debian Vim Maintainers " Former Maintainer: Matthijs Mohlmann -" Last Change: 2013 May 05 +" Last Change: 2014 Jan 20 " URL: http://anonscm.debian.org/hg/pkg-vim/vim/raw-file/unstable/runtime/syntax/debsources.vim " Standard syntax initialization @@ -23,7 +23,7 @@ syn match debsourcesComment /#.*/ contains=@Spell " Match uri's syn match debsourcesUri +\(http://\|ftp://\|[rs]sh://\|debtorrent://\|\(cdrom\|copy\|file\):\)[^' <>"]\++ -syn match debsourcesDistrKeyword +\([[:alnum:]_./]*\)\(squeeze\|wheezy\|\(old\)\=stable\|testing\|unstable\|sid\|rc-buggy\|experimental\|lucid\|precise\|quantal\|raring\|saucy\)\([-[:alnum:]_./]*\)+ +syn match debsourcesDistrKeyword +\([[:alnum:]_./]*\)\(squeeze\|wheezy\|\(old\)\=stable\|testing\|unstable\|sid\|rc-buggy\|experimental\|lucid\|precise\|quantal\|saucy\|trusty\)\([-[:alnum:]_./]*\)+ " Associate our matches and regions with pretty colours hi def link debsourcesLine Error diff --git a/runtime/syntax/help.vim b/runtime/syntax/help.vim index 27f7ff1810..52c96fc66b 100644 --- a/runtime/syntax/help.vim +++ b/runtime/syntax/help.vim @@ -1,7 +1,7 @@ " Vim syntax file " Language: Vim help file " Maintainer: Bram Moolenaar (Bram@vim.org) -" Last Change: 2013 Sep 05 +" Last Change: 2013 Nov 17 " Quit when a (custom) syntax file was already loaded if exists("b:current_syntax") @@ -153,7 +153,7 @@ syn sync minlines=40 " Define the default highlighting. " Only used when an item doesn't have highlighting yet hi def link helpIgnore Ignore -hi def link helpHyperTextJump Subtitle +hi def link helpHyperTextJump Identifier hi def link helpBar Ignore hi def link helpBacktick Ignore hi def link helpStar Ignore @@ -168,7 +168,6 @@ hi def link helpOption Type hi def link helpNotVi Special hi def link helpSpecial Special hi def link helpNote Todo -hi def link Subtitle Identifier hi def link helpComment Comment hi def link helpConstant Constant diff --git a/runtime/syntax/netrw.vim b/runtime/syntax/netrw.vim index a319d7cb19..f049c5ba46 100644 --- a/runtime/syntax/netrw.vim +++ b/runtime/syntax/netrw.vim @@ -19,11 +19,12 @@ syn cluster NetrwTreeGroup contains=netrwDir,netrwSymLink,netrwExe syn match netrwPlain "\(\S\+ \)*\S\+" contains=@NoSpell syn match netrwSpecial "\%(\S\+ \)*\S\+[*|=]\ze\%(\s\{2,}\|$\)" contains=netrwClassify,@NoSpell syn match netrwDir "\.\{1,2}/" contains=netrwClassify,@NoSpell -syn match netrwDir "\%(\S\+ \)*\S\+/" contains=netrwClassify,@NoSpell +"syn match netrwDir "\%(\S\+ \)*\S\+/" contains=netrwClassify,@NoSpell +syn match netrwDir "\%(\S\+ \)*\S\+/\ze\%(\s\{2,}\|$\)" contains=netrwClassify,@NoSpell syn match netrwSizeDate "\<\d\+\s\d\{1,2}/\d\{1,2}/\d\{4}\s" skipwhite contains=netrwDateSep,@NoSpell nextgroup=netrwTime syn match netrwSymLink "\%(\S\+ \)*\S\+@\ze\%(\s\{2,}\|$\)" contains=netrwClassify,@NoSpell syn match netrwExe "\%(\S\+ \)*\S*[^~]\*\ze\%(\s\{2,}\|$\)" contains=netrwClassify,@NoSpell -syn match netrwTreeBar "^\%([-+|] \)\+" contains=netrwTreeBarSpace nextgroup=@netrwTreeGroup +syn match netrwTreeBar "^\%([-+|│] \)\+" contains=netrwTreeBarSpace nextgroup=@netrwTreeGroup syn match netrwTreeBarSpace " " contained syn match netrwClassify "[*=|@/]\ze\%(\s\{2,}\|$\)" contained diff --git a/runtime/syntax/rst.vim b/runtime/syntax/rst.vim index 159d14ef37..425d225113 100644 --- a/runtime/syntax/rst.vim +++ b/runtime/syntax/rst.vim @@ -1,7 +1,7 @@ " Vim syntax file " Language: reStructuredText documentation format " Maintainer: Nikolai Weibull -" Latest Revision: 2013-06-03 +" Latest Revision: 2013-11-26 if exists("b:current_syntax") finish @@ -152,7 +152,7 @@ for code in g:rst_syntax_code_list exe 'syn region rstDirective'.code.' matchgroup=rstDirective fold ' \.'start=#\%(sourcecode\|code\%(-block\)\=\)::\s\+'.code.'\s*$# ' \.'skip=#^$# ' - \.'end=#^\s\@!# contains=@NoSpell,@rst'.code + \.'end=#^\s\@!# contains=@NoSpell,@rst'.code.' keepend' exe 'syn cluster rstDirectives add=rstDirective'.code endfor diff --git a/runtime/syntax/systemverilog.vim b/runtime/syntax/systemverilog.vim new file mode 100644 index 0000000000..5bf2935078 --- /dev/null +++ b/runtime/syntax/systemverilog.vim @@ -0,0 +1,101 @@ +" Vim syntax file +" Language: SystemVerilog +" Maintainer: kocha +" Last Change: 12-Aug-2013. + +" For version 5.x: Clear all syntax items +" For version 6.x: Quit when a syntax file was already loaded +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish +endif + +" Read in Verilog syntax files +if version < 600 + so :p:h/verilog.vim +else + runtime! syntax/verilog.vim + unlet b:current_syntax +endif + +" IEEE1800-2005 +syn keyword systemverilogStatement always_comb always_ff always_latch +syn keyword systemverilogStatement class endclass new +syn keyword systemverilogStatement virtual local const protected +syn keyword systemverilogStatement package endpackage +syn keyword systemverilogStatement rand randc constraint randomize +syn keyword systemverilogStatement with inside dist +syn keyword systemverilogStatement sequence endsequence randsequence +syn keyword systemverilogStatement srandom +syn keyword systemverilogStatement logic bit byte +syn keyword systemverilogStatement int longint shortint +syn keyword systemverilogStatement struct packed +syn keyword systemverilogStatement final +syn keyword systemverilogStatement import export +syn keyword systemverilogStatement context pure +syn keyword systemverilogStatement void shortreal chandle string +syn keyword systemverilogStatement clocking endclocking iff +syn keyword systemverilogStatement interface endinterface modport +syn keyword systemverilogStatement cover covergroup coverpoint endgroup +syn keyword systemverilogStatement property endproperty +syn keyword systemverilogStatement program endprogram +syn keyword systemverilogStatement bins binsof illegal_bins ignore_bins +syn keyword systemverilogStatement alias matches solve static assert +syn keyword systemverilogStatement assume super before expect bind +syn keyword systemverilogStatement extends null tagged extern this +syn keyword systemverilogStatement first_match throughout timeprecision +syn keyword systemverilogStatement timeunit type union +syn keyword systemverilogStatement uwire var cross ref wait_order intersect +syn keyword systemverilogStatement wildcard within + +syn keyword systemverilogTypeDef typedef enum + +syn keyword systemverilogConditional randcase +syn keyword systemverilogConditional unique priority + +syn keyword systemverilogRepeat return break continue +syn keyword systemverilogRepeat do foreach + +syn keyword systemverilogLabel join_any join_none forkjoin + +" IEEE1800-2009 add +syn keyword systemverilogStatement checker endchecker +syn keyword systemverilogStatement accept_on reject_on +syn keyword systemverilogStatement sync_accept_on sync_reject_on +syn keyword systemverilogStatement eventually nexttime until until_with +syn keyword systemverilogStatement s_always s_eventually s_nexttime s_until s_until_with +syn keyword systemverilogStatement let untyped +syn keyword systemverilogStatement strong weak +syn keyword systemverilogStatement restrict global implies + +syn keyword systemverilogConditional unique0 + +" IEEE1800-2012 add +syn keyword systemverilogStatement implements +syn keyword systemverilogStatement interconnect soft nettype + +" Define the default highlighting. +if version >= 508 || !exists("did_systemverilog_syn_inits") + if version < 508 + let did_systemverilog_syn_inits = 1 + command -nargs=+ HiLink hi link + else + command -nargs=+ HiLink hi def link + endif + + " The default highlighting. + HiLink systemverilogStatement Statement + HiLink systemverilogTypeDef TypeDef + HiLink systemverilogConditional Conditional + HiLink systemverilogRepeat Repeat + HiLink systemverilogLabel Label + HiLink systemverilogGlobal Define + HiLink systemverilogNumber Number + + delcommand HiLink +endif + +let b:current_syntax = "systemverilog" + +" vim: ts=8 diff --git a/runtime/tutor/tutor b/runtime/tutor/tutor index da28a15313..64a27d1c0d 100644 --- a/runtime/tutor/tutor +++ b/runtime/tutor/tutor @@ -55,8 +55,8 @@ NOTE: The cursor keys should also work. But using hjkl you will be able to 2. Type: :q! . This exits the editor, DISCARDING any changes you have made. - 3. When you see the shell prompt, type the command that got you into this - tutor. That would be: vimtutor + 3. Get back here by executing the command that got you into this tutor. That + might be: vimtutor 4. If you have these steps memorized and are confident, execute steps 1 through 3 to exit and re-enter the editor. diff --git a/runtime/vimrc_example.vim b/runtime/vimrc_example.vim index 3e9b56f0db..27a5cfc222 100644 --- a/runtime/vimrc_example.vim +++ b/runtime/vimrc_example.vim @@ -1,7 +1,7 @@ " An example for a vimrc file. " " Maintainer: Bram Moolenaar -" Last change: 2011 Apr 15 +" Last change: 2014 Feb 05 " " To use it, copy it to " for Unix and OS/2: ~/.vimrc @@ -24,7 +24,8 @@ set backspace=indent,eol,start if has("vms") set nobackup " do not keep a backup file, use versions instead else - set backup " keep a backup file + set backup " keep a backup file (restore to previous version) + set undofile " keep an undo file (undo changes after closing) endif set history=50 " keep 50 lines of command line history set ruler " show the cursor position all the time diff --git a/src/Make_bc5.mak b/src/Make_bc5.mak index 8172c1f4cc..5769bd64ba 100644 --- a/src/Make_bc5.mak +++ b/src/Make_bc5.mak @@ -419,7 +419,7 @@ CPUARG = -$(CPUNR) ALIGNARG = -a$(ALIGN) # !if ("$(DEBUG)"=="yes") -DEFINES=$(DEFINES) -DDEBUG +DEFINES=$(DEFINES) -DDEBUG -D_DEBUG !endif # !if ("$(OLE)"=="yes") diff --git a/src/Make_cyg.mak b/src/Make_cyg.mak index ee51c24050..f349798078 100644 --- a/src/Make_cyg.mak +++ b/src/Make_cyg.mak @@ -1,6 +1,6 @@ # # Makefile for VIM on Win32, using Cygnus gcc -# Last updated by Dan Sharp. Last Change: 2013 Sep 19 +# Last updated by Dan Sharp. Last Change: 2013 Dec 11 # # Also read INSTALLpc.txt! # @@ -155,7 +155,7 @@ endif ifeq (yes, $(DYNAMIC_PERL)) DEFINES += -DDYNAMIC_PERL -DDYNAMIC_PERL_DLL=\"perl$(PERL_VER).dll\" else -EXTRA_LIBS += $(PERL)/lib/CORE/perl$(PERL_VER).lib +EXTRA_LIBS += -L$(PERL)/lib/CORE -lperl$(PERL_VER) endif endif @@ -272,7 +272,7 @@ ifeq (yes, $(DYNAMIC_RUBY)) DEFINES += -DDYNAMIC_RUBY -DDYNAMIC_RUBY_DLL=\"$(RUBY_INSTALL_NAME).dll\" DEFINES += -DDYNAMIC_RUBY_VER=$(RUBY_VER) else -EXTRA_LIBS += $(RUBY)/lib/$(RUBY_INSTALL_NAME).lib +EXTRA_LIBS += $(RUBY)/lib/$(RUBY_INSTALL_NAME) endif endif diff --git a/src/Make_ming.mak b/src/Make_ming.mak index 7aa3994d4f..f7088ad58e 100644 --- a/src/Make_ming.mak +++ b/src/Make_ming.mak @@ -359,6 +359,7 @@ WINDRES_CC = $(CC) CFLAGS = -Iproto $(DEFINES) -pipe -w -march=$(ARCH) -Wall WINDRES_FLAGS = --preprocessor="$(WINDRES_CC) -E -xc" -DRC_INVOKED +EXTRA_LIBS = ifdef GETTEXT DEFINES += -DHAVE_GETTEXT -DHAVE_LOCALE_H @@ -377,9 +378,10 @@ endif endif ifdef PERL -CFLAGS += -I$(PERLLIBS) -DFEAT_PERL -L$(PERLLIBS) +CFLAGS += -I$(PERLLIBS) -DFEAT_PERL ifeq (yes, $(DYNAMIC_PERL)) CFLAGS += -DDYNAMIC_PERL -DDYNAMIC_PERL_DLL=\"perl$(PERL_VER).dll\" +EXTRA_LIBS += -L$(PERLLIBS) -lperl$(PERL_VER) endif endif @@ -596,7 +598,7 @@ ifdef XPM ifeq (yes, $(GUI)) OBJ += $(OUTDIR)/xpm_w32.o # You'll need libXpm.a from http://gnuwin32.sf.net -LIB += -L $(XPM)/lib -lXpm +LIB += -L$(XPM)/lib -lXpm endif endif @@ -632,7 +634,7 @@ endif ifdef PERL ifeq (no, $(DYNAMIC_PERL)) -LIB += -lperl$(PERL_VER) +LIB += -L$(PERLLIBS) -lperl$(PERL_VER) endif endif diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak index 5a07cd095d..ab02890134 100644 --- a/src/Make_mvc.mak +++ b/src/Make_mvc.mak @@ -424,6 +424,9 @@ MSVCVER = 11.0 !if "$(_NMAKE_VER)" == "11.00.60610.1" MSVCVER = 11.0 !endif +!if "$(_NMAKE_VER)" == "11.00.61030.0" +MSVCVER = 11.0 +!endif !if "$(_NMAKE_VER)" == "12.00.21005.1" MSVCVER = 12.0 !endif @@ -825,7 +828,12 @@ PERL_INCDIR = $(PERL)\Lib$(PERL_ARCH)\Core PERL_LIB = $(PERL_INCDIR)\perl.lib !else PERL_DLL = perl$(PERL_VER).dll +!if exist($(PERL_INCDIR)\perl$(PERL_VER).lib) PERL_LIB = $(PERL_INCDIR)\perl$(PERL_VER).lib +!else +# For ActivePerl 5.18 and later +PERL_LIB = $(PERL_INCDIR)\libperl$(PERL_VER).a +!endif !endif CFLAGS = $(CFLAGS) -DFEAT_PERL diff --git a/src/Makefile b/src/Makefile index 9726c130a6..6aeb57264c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2397,6 +2397,7 @@ shadow: runtime pixmaps ../../testdir/*.in \ ../../testdir/*.vim \ ../../testdir/python* \ + ../../testdir/sautest \ ../../testdir/test83-tags? \ ../../testdir/*.ok . diff --git a/src/blowfish.c b/src/blowfish.c index 573a1da48b..3d9ba5566a 100644 --- a/src/blowfish.c +++ b/src/blowfish.c @@ -6,7 +6,7 @@ * Do ":help credits" in Vim to see a list of people who contributed. * See README.txt for an overview of the Vim source code. * - * Blowfish encryption for Vim; in Blowfish output feedback mode. + * Blowfish encryption for Vim; in Blowfish cipher feedback mode. * Contributed by Mohsin Ahmed, http://www.cs.albany.edu/~mosh * Based on http://www.schneier.com/blowfish.html by Bruce Schneier. */ @@ -19,7 +19,7 @@ #define BF_BLOCK 8 #define BF_BLOCK_MASK 7 -#define BF_OFB_LEN (8*(BF_BLOCK)) +#define BF_CFB_LEN (8*(BF_BLOCK)) typedef union { UINT32_T ul[2]; @@ -554,42 +554,42 @@ bf_self_test() return err > 0 ? FAIL : OK; } -/* Output feedback mode. */ +/* Cipher feedback mode. */ static int randbyte_offset = 0; static int update_offset = 0; -static char_u ofb_buffer[BF_OFB_LEN]; /* 64 bytes */ +static char_u cfb_buffer[BF_CFB_LEN]; /* 64 bytes */ /* * Initialize with seed "iv[iv_len]". */ void -bf_ofb_init(iv, iv_len) +bf_cfb_init(iv, iv_len) char_u *iv; int iv_len; { int i, mi; randbyte_offset = update_offset = 0; - vim_memset(ofb_buffer, 0, BF_OFB_LEN); + vim_memset(cfb_buffer, 0, BF_CFB_LEN); if (iv_len > 0) { - mi = iv_len > BF_OFB_LEN ? iv_len : BF_OFB_LEN; + mi = iv_len > BF_CFB_LEN ? iv_len : BF_CFB_LEN; for (i = 0; i < mi; i++) - ofb_buffer[i % BF_OFB_LEN] ^= iv[i % iv_len]; + cfb_buffer[i % BF_CFB_LEN] ^= iv[i % iv_len]; } } -#define BF_OFB_UPDATE(c) { \ - ofb_buffer[update_offset] ^= (char_u)c; \ - if (++update_offset == BF_OFB_LEN) \ +#define BF_CFB_UPDATE(c) { \ + cfb_buffer[update_offset] ^= (char_u)c; \ + if (++update_offset == BF_CFB_LEN) \ update_offset = 0; \ } #define BF_RANBYTE(t) { \ if ((randbyte_offset & BF_BLOCK_MASK) == 0) \ - bf_e_cblock(&ofb_buffer[randbyte_offset]); \ - t = ofb_buffer[randbyte_offset]; \ - if (++randbyte_offset == BF_OFB_LEN) \ + bf_e_cblock(&cfb_buffer[randbyte_offset]); \ + t = cfb_buffer[randbyte_offset]; \ + if (++randbyte_offset == BF_CFB_LEN) \ randbyte_offset = 0; \ } @@ -610,7 +610,7 @@ bf_crypt_encode(from, len, to) { ztemp = from[i]; BF_RANBYTE(t); - BF_OFB_UPDATE(ztemp); + BF_CFB_UPDATE(ztemp); to[i] = t ^ ztemp; } } @@ -630,7 +630,7 @@ bf_crypt_decode(ptr, len) { BF_RANBYTE(t); *p ^= t; - BF_OFB_UPDATE(*p); + BF_CFB_UPDATE(*p); } } @@ -646,13 +646,13 @@ bf_crypt_init_keys(passwd) for (p = passwd; *p != NUL; ++p) { - BF_OFB_UPDATE(*p); + BF_CFB_UPDATE(*p); } } static int save_randbyte_offset; static int save_update_offset; -static char_u save_ofb_buffer[BF_OFB_LEN]; +static char_u save_cfb_buffer[BF_CFB_LEN]; static UINT32_T save_pax[18]; static UINT32_T save_sbx[4][256]; @@ -665,7 +665,7 @@ bf_crypt_save() { save_randbyte_offset = randbyte_offset; save_update_offset = update_offset; - mch_memmove(save_ofb_buffer, ofb_buffer, BF_OFB_LEN); + mch_memmove(save_cfb_buffer, cfb_buffer, BF_CFB_LEN); mch_memmove(save_pax, pax, 4 * 18); mch_memmove(save_sbx, sbx, 4 * 4 * 256); } @@ -679,7 +679,7 @@ bf_crypt_restore() { randbyte_offset = save_randbyte_offset; update_offset = save_update_offset; - mch_memmove(ofb_buffer, save_ofb_buffer, BF_OFB_LEN); + mch_memmove(cfb_buffer, save_cfb_buffer, BF_CFB_LEN); mch_memmove(pax, save_pax, 4 * 18); mch_memmove(sbx, save_sbx, 4 * 4 * 256); } diff --git a/src/buffer.c b/src/buffer.c index f910e0fd84..e4ae0282d2 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -998,6 +998,50 @@ do_bufdel(command, arg, addr_count, start_bnr, end_bnr, forceit) #if defined(FEAT_LISTCMDS) || defined(FEAT_PYTHON) \ || defined(FEAT_PYTHON3) || defined(PROTO) +static int empty_curbuf __ARGS((int close_others, int forceit, int action)); + +/* + * Make the current buffer empty. + * Used when it is wiped out and it's the last buffer. + */ + static int +empty_curbuf(close_others, forceit, action) + int close_others; + int forceit; + int action; +{ + int retval; + buf_T *buf = curbuf; + + if (action == DOBUF_UNLOAD) + { + EMSG(_("E90: Cannot unload last buffer")); + return FAIL; + } + + if (close_others) + { + /* Close any other windows on this buffer, then make it empty. */ +#ifdef FEAT_WINDOWS + close_windows(buf, TRUE); +#endif + } + + setpcmark(); + retval = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, + forceit ? ECMD_FORCEIT : 0, curwin); + + /* + * do_ecmd() may create a new buffer, then we have to delete + * the old one. But do_ecmd() may have done that already, check + * if the buffer still exists. + */ + if (buf != curbuf && buf_valid(buf) && buf->b_nwindows == 0) + close_buffer(NULL, buf, action, FALSE); + if (!close_others) + need_fileinfo = FALSE; + return retval; +} /* * Implementation of the commands for the buffer list. * @@ -1118,7 +1162,6 @@ do_buffer(action, start, dir, count, forceit) if (unload) { int forward; - int retval; /* When unloading or deleting a buffer that's already unloaded and * unlisted: fail silently. */ @@ -1159,30 +1202,7 @@ do_buffer(action, start, dir, count, forceit) if (bp->b_p_bl && bp != buf) break; if (bp == NULL && buf == curbuf) - { - if (action == DOBUF_UNLOAD) - { - EMSG(_("E90: Cannot unload last buffer")); - return FAIL; - } - - /* Close any other windows on this buffer, then make it empty. */ -#ifdef FEAT_WINDOWS - close_windows(buf, TRUE); -#endif - setpcmark(); - retval = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, - forceit ? ECMD_FORCEIT : 0, curwin); - - /* - * do_ecmd() may create a new buffer, then we have to delete - * the old one. But do_ecmd() may have done that already, check - * if the buffer still exists. - */ - if (buf != curbuf && buf_valid(buf) && buf->b_nwindows == 0) - close_buffer(NULL, buf, action, FALSE); - return retval; - } + return empty_curbuf(TRUE, forceit, action); #ifdef FEAT_WINDOWS /* @@ -1216,7 +1236,8 @@ do_buffer(action, start, dir, count, forceit) /* * Deleting the current buffer: Need to find another buffer to go to. - * There must be another, otherwise it would have been handled above. + * There should be another, otherwise it would have been handled + * above. However, autocommands may have deleted all buffers. * First use au_new_curbuf, if it is valid. * Then prefer the buffer we most recently visited. * Else try to find one that is loaded, after the current buffer, @@ -1315,6 +1336,13 @@ do_buffer(action, start, dir, count, forceit) } } + if (buf == NULL) + { + /* Autocommands must have wiped out all other buffers. Only option + * now is to make the current buffer empty. */ + return empty_curbuf(FALSE, forceit, action); + } + /* * make buf current buffer */ diff --git a/src/configure.in b/src/configure.in index 49e54f1f1d..77d791a730 100644 --- a/src/configure.in +++ b/src/configure.in @@ -816,9 +816,19 @@ if test "$enable_mzschemeinterp" = "yes"; then AC_MSG_CHECKING(for mzscheme_base.c) if test -f "${SCHEME_COLLECTS}collects/scheme/base.ss" ; then MZSCHEME_EXTRA="mzscheme_base.c" + MZSCHEME_MZC="${vi_cv_path_mzscheme_pfx}/bin/mzc" + MZSCHEME_MOD="++lib scheme/base" else if test -f "${SCHEME_COLLECTS}collects/scheme/base.rkt" ; then MZSCHEME_EXTRA="mzscheme_base.c" + MZSCHEME_MZC="${vi_cv_path_mzscheme_pfx}/bin/mzc" + MZSCHEME_MOD="++lib scheme/base" + else + if test -f "${SCHEME_COLLECTS}collects/racket/base.rkt" ; then + MZSCHEME_EXTRA="mzscheme_base.c" + MZSCHEME_MZC="${vi_cv_path_mzscheme_pfx}/bin/raco ctool" + MZSCHEME_MOD="" + fi fi fi if test "X$MZSCHEME_EXTRA" != "X" ; then diff --git a/src/edit.c b/src/edit.c index 13761ac0ae..63a6165c86 100644 --- a/src/edit.c +++ b/src/edit.c @@ -1566,87 +1566,89 @@ ins_redraw(ready) int conceal_update_lines = FALSE; #endif - if (!char_avail()) - { + if (char_avail()) + return; + #if defined(FEAT_AUTOCMD) || defined(FEAT_CONCEAL) - /* Trigger CursorMoved if the cursor moved. Not when the popup menu is - * visible, the command might delete it. */ - if (ready && ( + /* Trigger CursorMoved if the cursor moved. Not when the popup menu is + * visible, the command might delete it. */ + if (ready && ( # ifdef FEAT_AUTOCMD - has_cursormovedI() + has_cursormovedI() # endif # if defined(FEAT_AUTOCMD) && defined(FEAT_CONCEAL) - || + || # endif # ifdef FEAT_CONCEAL - curwin->w_p_cole > 0 + curwin->w_p_cole > 0 # endif - ) - && !equalpos(last_cursormoved, curwin->w_cursor) + ) + && !equalpos(last_cursormoved, curwin->w_cursor) +# ifdef FEAT_INS_EXPAND + && !pum_visible() +# endif + ) + { +# ifdef FEAT_SYN_HL + /* Need to update the screen first, to make sure syntax + * highlighting is correct after making a change (e.g., inserting + * a "(". The autocommand may also require a redraw, so it's done + * again below, unfortunately. */ + if (syntax_present(curwin) && must_redraw) + update_screen(0); +# endif +# ifdef FEAT_AUTOCMD + if (has_cursormovedI()) + apply_autocmds(EVENT_CURSORMOVEDI, NULL, NULL, FALSE, curbuf); +# endif +# ifdef FEAT_CONCEAL + if (curwin->w_p_cole > 0) + { + conceal_old_cursor_line = last_cursormoved.lnum; + conceal_new_cursor_line = curwin->w_cursor.lnum; + conceal_update_lines = TRUE; + } +# endif + last_cursormoved = curwin->w_cursor; + } +#endif + +#ifdef FEAT_AUTOCMD + /* Trigger TextChangedI if b_changedtick differs. */ + if (ready && has_textchangedI() + && last_changedtick != curbuf->b_changedtick # ifdef FEAT_INS_EXPAND && !pum_visible() # endif - ) - { -# ifdef FEAT_SYN_HL - /* Need to update the screen first, to make sure syntax - * highlighting is correct after making a change (e.g., inserting - * a "(". The autocommand may also require a redraw, so it's done - * again below, unfortunately. */ - if (syntax_present(curwin) && must_redraw) - update_screen(0); -# endif -# ifdef FEAT_AUTOCMD - if (has_cursormovedI()) - apply_autocmds(EVENT_CURSORMOVEDI, NULL, NULL, FALSE, curbuf); -# endif -# ifdef FEAT_CONCEAL - if (curwin->w_p_cole > 0) - { - conceal_old_cursor_line = last_cursormoved.lnum; - conceal_new_cursor_line = curwin->w_cursor.lnum; - conceal_update_lines = TRUE; - } -# endif - last_cursormoved = curwin->w_cursor; - } -#endif -#ifdef FEAT_AUTOCMD - /* Trigger TextChangedI if b_changedtick differs. */ - if (!ready && has_textchangedI() - && last_changedtick != curbuf->b_changedtick -# ifdef FEAT_INS_EXPAND - && !pum_visible() -# endif - ) - { - if (last_changedtick_buf == curbuf) - apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf); - last_changedtick_buf = curbuf; - last_changedtick = curbuf->b_changedtick; - } -#endif - if (must_redraw) - update_screen(0); - else if (clear_cmdline || redraw_cmdline) - showmode(); /* clear cmdline and show mode */ -# if defined(FEAT_CONCEAL) - if ((conceal_update_lines - && (conceal_old_cursor_line != conceal_new_cursor_line - || conceal_cursor_line(curwin))) - || need_cursor_line_redraw) - { - if (conceal_old_cursor_line != conceal_new_cursor_line) - update_single_line(curwin, conceal_old_cursor_line); - update_single_line(curwin, conceal_new_cursor_line == 0 - ? curwin->w_cursor.lnum : conceal_new_cursor_line); - curwin->w_valid &= ~VALID_CROW; - } -# endif - showruler(FALSE); - setcursor(); - emsg_on_display = FALSE; /* may remove error message now */ + ) + { + if (last_changedtick_buf == curbuf) + apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf); + last_changedtick_buf = curbuf; + last_changedtick = curbuf->b_changedtick; } +#endif + + if (must_redraw) + update_screen(0); + else if (clear_cmdline || redraw_cmdline) + showmode(); /* clear cmdline and show mode */ +# if defined(FEAT_CONCEAL) + if ((conceal_update_lines + && (conceal_old_cursor_line != conceal_new_cursor_line + || conceal_cursor_line(curwin))) + || need_cursor_line_redraw) + { + if (conceal_old_cursor_line != conceal_new_cursor_line) + update_single_line(curwin, conceal_old_cursor_line); + update_single_line(curwin, conceal_new_cursor_line == 0 + ? curwin->w_cursor.lnum : conceal_new_cursor_line); + curwin->w_valid &= ~VALID_CROW; + } +# endif + showruler(FALSE); + setcursor(); + emsg_on_display = FALSE; /* may remove error message now */ } /* @@ -4193,6 +4195,7 @@ ins_compl_get_exp(ini) char_u *dict = NULL; int dict_f = 0; compl_T *old_match; + int set_match_pos; if (!compl_started) { @@ -4211,6 +4214,7 @@ ins_compl_get_exp(ini) for (;;) { found_new_match = FAIL; + set_match_pos = FALSE; /* For ^N/^P pick a new entry from e_cpt if compl_started is off, * or if found_all says this entry is done. For ^X^L only use the @@ -4230,6 +4234,10 @@ ins_compl_get_exp(ini) dec(&first_match_pos); last_match_pos = first_match_pos; type = 0; + + /* Remember the first match so that the loop stops when we + * wrap and come back there a second time. */ + set_match_pos = TRUE; } else if (vim_strchr((char_u *)"buwU", *e_cpt) != NULL && (ins_buf = ins_compl_next_buf(ins_buf, *e_cpt)) != curbuf) @@ -4394,7 +4402,7 @@ ins_compl_get_exp(ini) if (ins_buf->b_p_inf) p_scs = FALSE; - /* buffers other than curbuf are scanned from the beginning or the + /* Buffers other than curbuf are scanned from the beginning or the * end but never from the middle, thus setting nowrapscan in this * buffers is a good idea, on the other hand, we always set * wrapscan for curbuf to avoid missing matches -- Acevedo,Webb */ @@ -4421,12 +4429,13 @@ ins_compl_get_exp(ini) compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG, RE_LAST, (linenr_T)0, NULL); --msg_silent; - if (!compl_started) + if (!compl_started || set_match_pos) { /* set "compl_started" even on fail */ compl_started = TRUE; first_match_pos = *pos; last_match_pos = *pos; + set_match_pos = FALSE; } else if (first_match_pos.lnum == last_match_pos.lnum && first_match_pos.col == last_match_pos.col) diff --git a/src/eval.c b/src/eval.c index fc96828c97..b5f9014d95 100644 --- a/src/eval.c +++ b/src/eval.c @@ -125,9 +125,6 @@ static dictitem_T globvars_var; /* variable used for g: */ */ static hashtab_T compat_hashtab; -/* When using exists() don't auto-load a script. */ -static int no_autoload = FALSE; - /* * When recursively copying lists and dicts we need to remember which ones we * have done to avoid endless recursiveness. This unique ID is used for that. @@ -156,6 +153,11 @@ static int echo_attr = 0; /* attributes used for ":echo" */ /* Values for trans_function_name() argument: */ #define TFN_INT 1 /* internal function name OK */ #define TFN_QUIET 2 /* no error messages */ +#define TFN_NO_AUTOLOAD 4 /* do not use script autoloading */ + +/* Values for get_lval() flags argument: */ +#define GLV_QUIET TFN_QUIET /* no error messages */ +#define GLV_NO_AUTOLOAD TFN_NO_AUTOLOAD /* do not use script autoloading */ /* * Structure to hold info for a user function. @@ -390,7 +392,7 @@ static void list_func_vars __ARGS((int *first)); static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg, int *first)); static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op)); static int check_changedtick __ARGS((char_u *arg)); -static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags)); +static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int flags, int fne_flags)); static void clear_lval __ARGS((lval_T *lp)); static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op)); static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u *op)); @@ -445,7 +447,7 @@ static int string2float __ARGS((char_u *text, float_T *value)); #endif static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); static int find_internal_func __ARGS((char_u *name)); -static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); +static char_u *deref_func_name __ARGS((char_u *name, int *lenp, int no_autoload)); static int get_func_tv __ARGS((char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict)); static int call_func __ARGS((char_u *funcname, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict)); static void emsg_funcname __ARGS((char *ermsg, char_u *name)); @@ -770,7 +772,7 @@ static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u ** static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); static int eval_isnamec __ARGS((int c)); static int eval_isnamec1 __ARGS((int c)); -static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose)); +static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose, int no_autoload)); static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); static typval_T *alloc_tv __ARGS((void)); static typval_T *alloc_string_tv __ARGS((char_u *string)); @@ -781,8 +783,8 @@ static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf)); static char_u *get_tv_string __ARGS((typval_T *varp)); static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf)); -static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); -static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, int htname, char_u *varname, int writing)); +static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp, int no_autoload)); +static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, int htname, char_u *varname, int no_autoload)); static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); @@ -1059,7 +1061,7 @@ var_redir_start(name, append) ga_init2(&redir_ga, (int)sizeof(char), 500); /* Parse the variable name (can be a dict or list entry). */ - redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE, + redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, 0, FNE_CHECK_START); if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) { @@ -1150,7 +1152,7 @@ var_redir_stop() /* Call get_lval() again, if it's inside a Dict or List it may * have changed. */ redir_endp = get_lval(redir_varname, NULL, redir_lval, - FALSE, FALSE, FALSE, FNE_CHECK_START); + FALSE, FALSE, 0, FNE_CHECK_START); if (redir_endp != NULL && redir_lval->ll_name != NULL) set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); clear_lval(redir_lval); @@ -2239,7 +2241,7 @@ list_arg_vars(eap, arg, first) { if (tofree != NULL) name = tofree; - if (get_var_tv(name, len, &tv, TRUE) == FAIL) + if (get_var_tv(name, len, &tv, TRUE, FALSE) == FAIL) error = TRUE; else { @@ -2474,7 +2476,7 @@ ex_let_one(arg, tv, copy, endchars, op) { lval_T lv; - p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START); + p = get_lval(arg, tv, &lv, FALSE, FALSE, 0, FNE_CHECK_START); if (p != NULL && lv.ll_name != NULL) { if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) @@ -2519,18 +2521,22 @@ check_changedtick(arg) * "unlet" is TRUE for ":unlet": slightly different behavior when something is * wrong; must end in space or cmd separator. * + * flags: + * GLV_QUIET: do not give error messages + * GLV_NO_AUTOLOAD: do not use script autoloading + * * Returns a pointer to just after the name, including indexes. * When an evaluation error occurs "lp->ll_name" is NULL; * Returns NULL for a parsing error. Still need to free items in "lp"! */ static char_u * -get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) +get_lval(name, rettv, lp, unlet, skip, flags, fne_flags) char_u *name; typval_T *rettv; lval_T *lp; int unlet; int skip; - int quiet; /* don't give error messages */ + int flags; /* GLV_ values */ int fne_flags; /* flags for find_name_end() */ { char_u *p; @@ -2544,6 +2550,7 @@ get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) char_u *key = NULL; int len; hashtab_T *ht; + int quiet = flags & GLV_QUIET; /* Clear everything in "lp". */ vim_memset(lp, 0, sizeof(lval_T)); @@ -2591,7 +2598,7 @@ get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) cc = *p; *p = NUL; - v = find_var(lp->ll_name, &ht); + v = find_var(lp->ll_name, &ht, flags & GLV_NO_AUTOLOAD); if (v == NULL && !quiet) EMSG2(_(e_undefvar), lp->ll_name); *p = cc; @@ -2904,7 +2911,7 @@ set_var_lval(lp, endp, rettv, copy, op) /* handle +=, -= and .= */ if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name), - &tv, TRUE) == OK) + &tv, TRUE, FALSE) == OK) { if (tv_op(&tv, rettv, op) == OK) set_var(lp->ll_name, &tv, FALSE); @@ -3425,7 +3432,7 @@ ex_call(eap) /* If it is the name of a variable of type VAR_FUNC use its contents. */ len = (int)STRLEN(tofree); - name = deref_func_name(tofree, &len); + name = deref_func_name(tofree, &len, FALSE); /* Skip white space to allow ":call func ()". Not good, but required for * backward compatibility. */ @@ -3556,7 +3563,7 @@ ex_unletlock(eap, argstart, deep) do { /* Parse the name and find the end. */ - name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE, + name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, 0, FNE_CHECK_START); if (lv.ll_name == NULL) error = TRUE; /* error but continue parsing */ @@ -3709,7 +3716,7 @@ do_lock_var(lp, name_end, deep, lock) ret = FAIL; else { - di = find_var(lp->ll_name, NULL); + di = find_var(lp->ll_name, NULL, TRUE); if (di == NULL) ret = FAIL; else @@ -5152,7 +5159,7 @@ eval7(arg, rettv, evaluate, want_string) { /* If "s" is the name of a variable of type VAR_FUNC * use its contents. */ - s = deref_func_name(s, &len); + s = deref_func_name(s, &len, !evaluate); /* Invoke the function. */ ret = get_func_tv(s, len, rettv, arg, @@ -5179,7 +5186,7 @@ eval7(arg, rettv, evaluate, want_string) } } else if (evaluate) - ret = get_var_tv(s, len, rettv, TRUE); + ret = get_var_tv(s, len, rettv, TRUE, FALSE); else ret = OK; } @@ -6419,6 +6426,16 @@ list_insert_tv(l, tv, item) if (ni == NULL) return FAIL; copy_tv(tv, &ni->li_tv); + list_insert(l, ni, item); + return OK; +} + + void +list_insert(l, ni, item) + list_T *l; + listitem_T *ni; + listitem_T *item; +{ if (item == NULL) /* Append new item at end of list. */ list_append(l, ni); @@ -6440,7 +6457,6 @@ list_insert_tv(l, tv, item) item->li_prev = ni; ++l->lv_len; } - return OK; } /* @@ -8276,16 +8292,17 @@ find_internal_func(name) * name it contains, otherwise return "name". */ static char_u * -deref_func_name(name, lenp) +deref_func_name(name, lenp, no_autoload) char_u *name; int *lenp; + int no_autoload; { dictitem_T *v; int cc; cc = name[*lenp]; name[*lenp] = NUL; - v = find_var(name, NULL); + v = find_var(name, NULL, no_autoload); name[*lenp] = cc; if (v != NULL && v->di_tv.v_type == VAR_FUNC) { @@ -10040,8 +10057,6 @@ f_exists(argvars, rettv) int n = FALSE; int len = 0; - no_autoload = TRUE; - p = get_tv_string(&argvars[0]); if (*p == '$') /* environment variable */ { @@ -10092,7 +10107,7 @@ f_exists(argvars, rettv) { if (tofree != NULL) name = tofree; - n = (get_var_tv(name, len, &tv, FALSE) == OK); + n = (get_var_tv(name, len, &tv, FALSE, TRUE) == OK); if (n) { /* handle d.key, l[idx], f(expr) */ @@ -10108,8 +10123,6 @@ f_exists(argvars, rettv) } rettv->vval.v_number = n; - - no_autoload = FALSE; } #ifdef FEAT_FLOAT @@ -11120,6 +11133,8 @@ get_buffer_lines(buf, start, end, retlist, rettv) { char_u *p; + rettv->v_type = VAR_STRING; + rettv->vval.v_string = NULL; if (retlist && rettv_list_alloc(rettv) == FAIL) return; @@ -11132,8 +11147,6 @@ get_buffer_lines(buf, start, end, retlist, rettv) p = ml_get_buf(buf, start, FALSE); else p = (char_u *)""; - - rettv->v_type = VAR_STRING; rettv->vval.v_string = vim_strsave(p); } else @@ -13364,8 +13377,8 @@ f_islocked(argvars, rettv) dictitem_T *di; rettv->vval.v_number = -1; - end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, - FNE_CHECK_START); + end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, + GLV_NO_AUTOLOAD, FNE_CHECK_START); if (end != NULL && lv.ll_name != NULL) { if (*end != NUL) @@ -13378,7 +13391,7 @@ f_islocked(argvars, rettv) rettv->vval.v_number = 1; /* always locked */ else { - di = find_var(lv.ll_name, NULL); + di = find_var(lv.ll_name, NULL, TRUE); if (di != NULL) { /* Consider a variable locked when: @@ -14161,8 +14174,8 @@ f_matcharg(argvars, rettv) } else { - list_append_string(rettv->vval.v_list, NUL, -1); - list_append_string(rettv->vval.v_list, NUL, -1); + list_append_string(rettv->vval.v_list, NULL, -1); + list_append_string(rettv->vval.v_list, NULL, -1); } } #endif @@ -19802,11 +19815,12 @@ set_cmdarg(eap, oldarg) * Return OK or FAIL. */ static int -get_var_tv(name, len, rettv, verbose) +get_var_tv(name, len, rettv, verbose, no_autoload) char_u *name; int len; /* length of "name" */ typval_T *rettv; /* NULL when only checking existence */ int verbose; /* may give error message */ + int no_autoload; /* do not use script autoloading */ { int ret = OK; typval_T *tv = NULL; @@ -19833,7 +19847,7 @@ get_var_tv(name, len, rettv, verbose) */ else { - v = find_var(name, NULL); + v = find_var(name, NULL, no_autoload); if (v != NULL) tv = &v->di_tv; } @@ -20235,9 +20249,10 @@ get_tv_string_buf_chk(varp, buf) * hashtab_T used. */ static dictitem_T * -find_var(name, htp) +find_var(name, htp, no_autoload) char_u *name; hashtab_T **htp; + int no_autoload; { char_u *varname; hashtab_T *ht; @@ -20247,7 +20262,7 @@ find_var(name, htp) *htp = ht; if (ht == NULL) return NULL; - return find_var_in_ht(ht, *name, varname, htp != NULL); + return find_var_in_ht(ht, *name, varname, no_autoload || htp != NULL); } /* @@ -20255,11 +20270,11 @@ find_var(name, htp) * Returns NULL if not found. */ static dictitem_T * -find_var_in_ht(ht, htname, varname, writing) +find_var_in_ht(ht, htname, varname, no_autoload) hashtab_T *ht; int htname; char_u *varname; - int writing; + int no_autoload; { hashitem_T *hi; @@ -20291,7 +20306,7 @@ find_var_in_ht(ht, htname, varname, writing) * worked find the variable again. Don't auto-load a script if it was * loaded already, otherwise it would be loaded every time when * checking if a function name is a Funcref variable. */ - if (ht == &globvarht && !writing) + if (ht == &globvarht && !no_autoload) { /* Note: script_autoload() may make "hi" invalid. It must either * be obtained again or not used. */ @@ -20371,7 +20386,7 @@ get_var_value(name) { dictitem_T *v; - v = find_var(name, NULL); + v = find_var(name, NULL, FALSE); if (v == NULL) return NULL; return get_tv_string(&v->di_tv); @@ -21700,7 +21715,7 @@ ex_function(eap) */ if (fudi.fd_dict == NULL) { - v = find_var(name, &ht); + v = find_var(name, &ht, FALSE); if (v != NULL && v->di_tv.v_type == VAR_FUNC) { emsg_funcname(N_("E707: Function name conflicts with variable: %s"), @@ -21858,8 +21873,9 @@ ret_free: * Also handles a Funcref in a List or Dictionary. * Returns the function name in allocated memory, or NULL for failure. * flags: - * TFN_INT: internal function name OK - * TFN_QUIET: be quiet + * TFN_INT: internal function name OK + * TFN_QUIET: be quiet + * TFN_NO_AUTOLOAD: do not use script autoloading * Advances "pp" to just after the function name (if no error). */ static char_u * @@ -21897,7 +21913,8 @@ trans_function_name(pp, skip, flags, fdp) if (lead > 2) start += lead; - end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, + /* Note that TFN_ flags use the same values as GLV_ flags. */ + end = get_lval(start, NULL, &lv, FALSE, skip, flags, lead > 2 ? 0 : FNE_CHECK_START); if (end == start) { @@ -21959,14 +21976,14 @@ trans_function_name(pp, skip, flags, fdp) if (lv.ll_exp_name != NULL) { len = (int)STRLEN(lv.ll_exp_name); - name = deref_func_name(lv.ll_exp_name, &len); + name = deref_func_name(lv.ll_exp_name, &len, flags & TFN_NO_AUTOLOAD); if (name == lv.ll_exp_name) name = NULL; } else { len = (int)(end - *pp); - name = deref_func_name(*pp, &len); + name = deref_func_name(*pp, &len, flags & TFN_NO_AUTOLOAD); if (name == *pp) name = NULL; } @@ -22174,7 +22191,8 @@ function_exists(name) char_u *p; int n = FALSE; - p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL); + p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET|TFN_NO_AUTOLOAD, + NULL); nm = skipwhite(nm); /* Only accept "funcname", "funcname ", "funcname (..." and @@ -22421,10 +22439,6 @@ script_autoload(name, reload) int ret = FALSE; int i; - /* Return quickly when autoload disabled. */ - if (no_autoload) - return FALSE; - /* If there is no '#' after name[0] there is no package name. */ p = vim_strchr(name, AUTOLOAD_CHAR); if (p == NULL || p == name) @@ -24379,7 +24393,7 @@ do_string_sub(str, pat, sub, flags) garray_T ga; char_u *ret; char_u *save_cpo; - int zero_width; + char_u *zero_width = NULL; /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ save_cpo = p_cpo; @@ -24396,6 +24410,19 @@ do_string_sub(str, pat, sub, flags) tail = str; while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) { + /* Skip empty match except for first match. */ + if (regmatch.startp[0] == regmatch.endp[0]) + { + if (zero_width == regmatch.startp[0]) + { + /* avoid getting stuck on a match with an empty string */ + *((char_u *)ga.ga_data + ga.ga_len) = *tail++; + ++ga.ga_len; + continue; + } + zero_width = regmatch.startp[0]; + } + /* * Get some space for a temporary buffer to do the substitution * into. It will contain: @@ -24418,17 +24445,9 @@ do_string_sub(str, pat, sub, flags) (void)vim_regsub(®match, sub, (char_u *)ga.ga_data + ga.ga_len + i, TRUE, TRUE, FALSE); ga.ga_len += i + sublen - 1; - zero_width = (tail == regmatch.endp[0] - || regmatch.startp[0] == regmatch.endp[0]); tail = regmatch.endp[0]; if (*tail == NUL) break; - if (zero_width) - { - /* avoid getting stuck on a match with an empty string */ - *((char_u *)ga.ga_data + ga.ga_len) = *tail++; - ++ga.ga_len; - } if (!do_all) break; } diff --git a/src/ex_cmds.c b/src/ex_cmds.c index 8f85911bad..70cdd349d8 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -5936,14 +5936,18 @@ find_help_tags(arg, num_matches, matches, keep_lang) "?", ":?", "?", "g?", "g?g?", "g??", "z?", "/\\?", "/\\z(\\)", "\\=", ":s\\=", "[count]", "[quotex]", "[range]", - "[pattern]", "\\|", "\\%$"}; + "[pattern]", "\\|", "\\%$", + "s/\\~", "s/\\U", "s/\\L", + "s/\\1", "s/\\2", "s/\\3", "s/\\9"}; static char *(rtable[]) = {"star", "gstar", "[star", "]star", ":star", "/star", "/\\\\star", "quotestar", "starstar", "cpo-star", "/\\\\(\\\\)", "/\\\\%(\\\\)", "?", ":?", "?", "g?", "g?g?", "g??", "z?", "/\\\\?", "/\\\\z(\\\\)", "\\\\=", ":s\\\\=", "\\[count]", "\\[quotex]", "\\[range]", - "\\[pattern]", "\\\\bar", "/\\\\%\\$"}; + "\\[pattern]", "\\\\bar", "/\\\\%\\$", + "s/\\\\\\~", "s/\\\\U", "s/\\\\L", + "s/\\\\1", "s/\\\\2", "s/\\\\3", "s/\\\\9"}; int flags; d = IObuff; /* assume IObuff is long enough! */ @@ -5982,7 +5986,7 @@ find_help_tags(arg, num_matches, matches, keep_lang) /* Replace: * "[:...:]" with "\[:...:]" * "[++...]" with "\[++...]" - * "\{" with "\\{" + * "\{" with "\\{" -- matching "} \}" */ if ((arg[0] == '[' && (arg[1] == ':' || (arg[1] == '+' && arg[2] == '+'))) diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 117247d689..b93dc1f698 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -3268,7 +3268,11 @@ set_one_cmd_context(xp, buff) ++p; /* for python 3.x: ":py3*" commands completion */ if (cmd[0] == 'p' && cmd[1] == 'y' && p == cmd + 2 && *p == '3') + { ++p; + while (ASCII_ISALPHA(*p) || *p == '*') + ++p; + } len = (int)(p - cmd); if (len == 0) @@ -8069,6 +8073,8 @@ ex_syncbind(eap) { #ifdef FEAT_SCROLLBIND win_T *wp; + win_T *save_curwin = curwin; + buf_T *save_curbuf = curbuf; long topline; long y; linenr_T old_linenr = curwin->w_cursor.lnum; @@ -8100,13 +8106,13 @@ ex_syncbind(eap) /* - * set all scrollbind windows to the same topline + * Set all scrollbind windows to the same topline. */ - wp = curwin; for (curwin = firstwin; curwin; curwin = curwin->w_next) { if (curwin->w_p_scb) { + curbuf = curwin->w_buffer; y = topline - curwin->w_topline; if (y > 0) scrollup(y, TRUE); @@ -8120,7 +8126,8 @@ ex_syncbind(eap) #endif } } - curwin = wp; + curwin = save_curwin; + curbuf = save_curbuf; if (curwin->w_p_scb) { did_syncbind = TRUE; @@ -8240,6 +8247,7 @@ post_chdir(local) int local; { vim_free(curwin->w_localdir); + curwin->w_localdir = NULL; if (local) { /* If still in global directory, need to remember current @@ -8256,7 +8264,6 @@ post_chdir(local) * name. */ vim_free(globaldir); globaldir = NULL; - curwin->w_localdir = NULL; } shorten_fnames(TRUE); @@ -8383,7 +8390,7 @@ ex_sleep(eap) { n = W_WINROW(curwin) + curwin->w_wrow - msg_scrolled; if (n >= 0) - windgoto((int)n, curwin->w_wcol); + windgoto((int)n, W_WINCOL(curwin) + curwin->w_wcol); } len = eap->line2; diff --git a/src/ex_eval.c b/src/ex_eval.c index 1ad696f497..04c31c21f9 100644 --- a/src/ex_eval.c +++ b/src/ex_eval.c @@ -320,6 +320,17 @@ free_msglist(l) } } +/* + * Free global "*msg_list" and the messages it contains, then set "*msg_list" + * to NULL. + */ + void +free_global_msglist() +{ + free_msglist(*msg_list); + *msg_list = NULL; +} + /* * Throw the message specified in the call to cause_errthrow() above as an * error exception. If cstack is NULL, postpone the throw until do_cmdline() @@ -410,66 +421,41 @@ do_intthrow(cstack) return TRUE; } - /* - * Throw a new exception. Return FAIL when out of memory or it was tried to - * throw an illegal user exception. "value" is the exception string for a user - * or interrupt exception, or points to a message list in case of an error - * exception. + * Get an exception message that is to be stored in current_exception->value. */ - static int -throw_exception(value, type, cmdname) + char_u * +get_exception_string(value, type, cmdname, should_free) void *value; int type; char_u *cmdname; + int *should_free; { - except_T *excp; - char_u *p, *mesg, *val; + char_u *ret, *mesg; int cmdlen; - - /* - * Disallow faking Interrupt or error exceptions as user exceptions. They - * would be treated differently from real interrupt or error exceptions when - * no active try block is found, see do_cmdline(). - */ - if (type == ET_USER) - { - if (STRNCMP((char_u *)value, "Vim", 3) == 0 && - (((char_u *)value)[3] == NUL || ((char_u *)value)[3] == ':' || - ((char_u *)value)[3] == '(')) - { - EMSG(_("E608: Cannot :throw exceptions with 'Vim' prefix")); - goto fail; - } - } - - excp = (except_T *)alloc((unsigned)sizeof(except_T)); - if (excp == NULL) - goto nomem; + char_u *p, *val; if (type == ET_ERROR) { - /* Store the original message and prefix the exception value with - * "Vim:" or, if a command name is given, "Vim(cmdname):". */ - excp->messages = (struct msglist *)value; - mesg = excp->messages->throw_msg; + *should_free = FALSE; + mesg = ((struct msglist *)value)->throw_msg; if (cmdname != NULL && *cmdname != NUL) { cmdlen = (int)STRLEN(cmdname); - excp->value = vim_strnsave((char_u *)"Vim(", + ret = vim_strnsave((char_u *)"Vim(", 4 + cmdlen + 2 + (int)STRLEN(mesg)); - if (excp->value == NULL) - goto nomem; - STRCPY(&excp->value[4], cmdname); - STRCPY(&excp->value[4 + cmdlen], "):"); - val = excp->value + 4 + cmdlen + 2; + if (ret == NULL) + return ret; + STRCPY(&ret[4], cmdname); + STRCPY(&ret[4 + cmdlen], "):"); + val = ret + 4 + cmdlen + 2; } else { - excp->value = vim_strnsave((char_u *)"Vim:", 4 + (int)STRLEN(mesg)); - if (excp->value == NULL) - goto nomem; - val = excp->value + 4; + ret = vim_strnsave((char_u *)"Vim:", 4 + (int)STRLEN(mesg)); + if (ret == NULL) + return ret; + val = ret + 4; } /* msg_add_fname may have been used to prefix the message with a file @@ -506,14 +492,65 @@ throw_exception(value, type, cmdname) } } else - excp->value = value; + { + *should_free = FALSE; + ret = (char_u *) value; + } + + return ret; +} + + +/* + * Throw a new exception. Return FAIL when out of memory or it was tried to + * throw an illegal user exception. "value" is the exception string for a + * user or interrupt exception, or points to a message list in case of an + * error exception. + */ + static int +throw_exception(value, type, cmdname) + void *value; + int type; + char_u *cmdname; +{ + except_T *excp; + int should_free; + + /* + * Disallow faking Interrupt or error exceptions as user exceptions. They + * would be treated differently from real interrupt or error exceptions + * when no active try block is found, see do_cmdline(). + */ + if (type == ET_USER) + { + if (STRNCMP((char_u *)value, "Vim", 3) == 0 + && (((char_u *)value)[3] == NUL || ((char_u *)value)[3] == ':' + || ((char_u *)value)[3] == '(')) + { + EMSG(_("E608: Cannot :throw exceptions with 'Vim' prefix")); + goto fail; + } + } + + excp = (except_T *)alloc((unsigned)sizeof(except_T)); + if (excp == NULL) + goto nomem; + + if (type == ET_ERROR) + /* Store the original message and prefix the exception value with + * "Vim:" or, if a command name is given, "Vim(cmdname):". */ + excp->messages = (struct msglist *)value; + + excp->value = get_exception_string(value, type, cmdname, &should_free); + if (excp->value == NULL && should_free) + goto nomem; excp->type = type; excp->throw_name = vim_strsave(sourcing_name == NULL ? (char_u *)"" : sourcing_name); if (excp->throw_name == NULL) { - if (type == ET_ERROR) + if (should_free) vim_free(excp->value); goto nomem; } @@ -2033,10 +2070,7 @@ leave_cleanup(csp) /* If an error was about to be converted to an exception when * enter_cleanup() was called, free the message list. */ if (msg_list != NULL) - { - free_msglist(*msg_list); - *msg_list = NULL; - } + free_global_msglist(); } /* diff --git a/src/fileio.c b/src/fileio.c index 3992959478..63ea04d8bf 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -2973,7 +2973,7 @@ check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile, fname, did_ask) else { bf_key_init(cryptkey, ptr + CRYPT_MAGIC_LEN, salt_len); - bf_ofb_init(ptr + CRYPT_MAGIC_LEN + salt_len, seed_len); + bf_cfb_init(ptr + CRYPT_MAGIC_LEN + salt_len, seed_len); } /* Remove magic number from the text */ @@ -3025,7 +3025,7 @@ prepare_crypt_read(fp) if (fread(buffer, salt_len + seed_len, 1, fp) != 1) return FAIL; bf_key_init(curbuf->b_p_key, buffer, salt_len); - bf_ofb_init(buffer + salt_len, seed_len); + bf_cfb_init(buffer + salt_len, seed_len); } return OK; } @@ -3064,7 +3064,7 @@ prepare_crypt_write(buf, lenp) seed = salt + salt_len; sha2_seed(salt, salt_len, seed, seed_len); bf_key_init(buf->b_p_key, salt, salt_len); - bf_ofb_init(seed, seed_len); + bf_cfb_init(seed, seed_len); } } *lenp = CRYPT_MAGIC_LEN + salt_len + seed_len; @@ -9368,7 +9368,9 @@ apply_autocmds_group(event, fname, fname_io, force, group, buf, eap) */ if (fname_io == NULL) { - if (fname != NULL && *fname != NUL) + if (event == EVENT_COLORSCHEME) + autocmd_fname = NULL; + else if (fname != NULL && *fname != NUL) autocmd_fname = fname; else if (buf != NULL) autocmd_fname = buf->b_ffname; @@ -9421,14 +9423,15 @@ apply_autocmds_group(event, fname, fname_io, force, group, buf, eap) else { sfname = vim_strsave(fname); - /* Don't try expanding FileType, Syntax, FuncUndefined, WindowID or - * QuickFixCmd* */ + /* Don't try expanding FileType, Syntax, FuncUndefined, WindowID, + * ColorScheme or QuickFixCmd* */ if (event == EVENT_FILETYPE || event == EVENT_SYNTAX || event == EVENT_FUNCUNDEFINED || event == EVENT_REMOTEREPLY || event == EVENT_SPELLFILEMISSING || event == EVENT_QUICKFIXCMDPRE + || event == EVENT_COLORSCHEME || event == EVENT_QUICKFIXCMDPOST) fname = vim_strsave(fname); else diff --git a/src/getchar.c b/src/getchar.c index 12914b42c0..e8f48fe1c7 100644 --- a/src/getchar.c +++ b/src/getchar.c @@ -40,13 +40,13 @@ #define MINIMAL_SIZE 20 /* minimal size for b_str */ -static struct buffheader redobuff = {{NULL, {NUL}}, NULL, 0, 0}; -static struct buffheader old_redobuff = {{NULL, {NUL}}, NULL, 0, 0}; +static buffheader_T redobuff = {{NULL, {NUL}}, NULL, 0, 0}; +static buffheader_T old_redobuff = {{NULL, {NUL}}, NULL, 0, 0}; #if defined(FEAT_AUTOCMD) || defined(FEAT_EVAL) || defined(PROTO) -static struct buffheader save_redobuff = {{NULL, {NUL}}, NULL, 0, 0}; -static struct buffheader save_old_redobuff = {{NULL, {NUL}}, NULL, 0, 0}; +static buffheader_T save_redobuff = {{NULL, {NUL}}, NULL, 0, 0}; +static buffheader_T save_old_redobuff = {{NULL, {NUL}}, NULL, 0, 0}; #endif -static struct buffheader recordbuff = {{NULL, {NUL}}, NULL, 0, 0}; +static buffheader_T recordbuff = {{NULL, {NUL}}, NULL, 0, 0}; static int typeahead_char = 0; /* typeahead char that's not flushed */ @@ -112,11 +112,12 @@ static char_u noremapbuf_init[TYPELEN_INIT]; /* initial typebuf.tb_noremap */ static int last_recorded_len = 0; /* number of last recorded chars */ -static char_u *get_buffcont __ARGS((struct buffheader *, int)); -static void add_buff __ARGS((struct buffheader *, char_u *, long n)); -static void add_num_buff __ARGS((struct buffheader *, long)); -static void add_char_buff __ARGS((struct buffheader *, int)); -static int read_stuff __ARGS((int advance)); +static char_u *get_buffcont __ARGS((buffheader_T *, int)); +static void add_buff __ARGS((buffheader_T *, char_u *, long n)); +static void add_num_buff __ARGS((buffheader_T *, long)); +static void add_char_buff __ARGS((buffheader_T *, int)); +static int read_readbuffers __ARGS((int advance)); +static int read_readbuf __ARGS((buffheader_T *buf, int advance)); static void start_stuff __ARGS((void)); static int read_redo __ARGS((int, int)); static void copy_redo __ARGS((int)); @@ -137,9 +138,9 @@ static char_u *eval_map_expr __ARGS((char_u *str, int c)); */ void free_buff(buf) - struct buffheader *buf; + buffheader_T *buf; { - struct buffblock *p, *np; + buffblock_T *p, *np; for (p = buf->bh_first.b_next; p != NULL; p = np) { @@ -155,14 +156,14 @@ free_buff(buf) */ static char_u * get_buffcont(buffer, dozero) - struct buffheader *buffer; + buffheader_T *buffer; int dozero; /* count == zero is not an error */ { long_u count = 0; char_u *p = NULL; char_u *p2; char_u *str; - struct buffblock *bp; + buffblock_T *bp; /* compute the total length of the string */ for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next) @@ -230,11 +231,11 @@ get_inserted() */ static void add_buff(buf, s, slen) - struct buffheader *buf; + buffheader_T *buf; char_u *s; long slen; /* length of "s" or -1 */ { - struct buffblock *p; + buffblock_T *p; long_u len; if (slen < 0) @@ -270,7 +271,7 @@ add_buff(buf, s, slen) len = MINIMAL_SIZE; else len = slen; - p = (struct buffblock *)lalloc((long_u)(sizeof(struct buffblock) + len), + p = (buffblock_T *)lalloc((long_u)(sizeof(buffblock_T) + len), TRUE); if (p == NULL) return; /* no space, just forget it */ @@ -289,7 +290,7 @@ add_buff(buf, s, slen) */ static void add_num_buff(buf, n) - struct buffheader *buf; + buffheader_T *buf; long n; { char_u number[32]; @@ -304,7 +305,7 @@ add_num_buff(buf, n) */ static void add_char_buff(buf, c) - struct buffheader *buf; + buffheader_T *buf; int c; { #ifdef FEAT_MBYTE @@ -354,46 +355,71 @@ add_char_buff(buf, c) #endif } +/* First read ahead buffer. Used for translated commands. */ +static buffheader_T readbuf1 = {{NULL, {NUL}}, NULL, 0, 0}; + +/* Second read ahead buffer. Used for redo. */ +static buffheader_T readbuf2 = {{NULL, {NUL}}, NULL, 0, 0}; + /* - * Get one byte from the stuff buffer. + * Get one byte from the read buffers. Use readbuf1 one first, use readbuf2 + * if that one is empty. * If advance == TRUE go to the next char. * No translation is done K_SPECIAL and CSI are escaped. */ static int -read_stuff(advance) +read_readbuffers(advance) int advance; { - char_u c; - struct buffblock *curr; + int c; - if (stuffbuff.bh_first.b_next == NULL) /* buffer is empty */ + c = read_readbuf(&readbuf1, advance); + if (c == NUL) + c = read_readbuf(&readbuf2, advance); + return c; +} + + static int +read_readbuf(buf, advance) + buffheader_T *buf; + int advance; +{ + char_u c; + buffblock_T *curr; + + if (buf->bh_first.b_next == NULL) /* buffer is empty */ return NUL; - curr = stuffbuff.bh_first.b_next; - c = curr->b_str[stuffbuff.bh_index]; + curr = buf->bh_first.b_next; + c = curr->b_str[buf->bh_index]; if (advance) { - if (curr->b_str[++stuffbuff.bh_index] == NUL) + if (curr->b_str[++buf->bh_index] == NUL) { - stuffbuff.bh_first.b_next = curr->b_next; + buf->bh_first.b_next = curr->b_next; vim_free(curr); - stuffbuff.bh_index = 0; + buf->bh_index = 0; } } return c; } /* - * Prepare the stuff buffer for reading (if it contains something). + * Prepare the read buffers for reading (if they contain something). */ static void start_stuff() { - if (stuffbuff.bh_first.b_next != NULL) + if (readbuf1.bh_first.b_next != NULL) { - stuffbuff.bh_curr = &(stuffbuff.bh_first); - stuffbuff.bh_space = 0; + readbuf1.bh_curr = &(readbuf1.bh_first); + readbuf1.bh_space = 0; + } + if (readbuf2.bh_first.b_next != NULL) + { + readbuf2.bh_curr = &(readbuf2.bh_first); + readbuf2.bh_space = 0; } } @@ -403,7 +429,18 @@ start_stuff() int stuff_empty() { - return (stuffbuff.bh_first.b_next == NULL); + return (readbuf1.bh_first.b_next == NULL + && readbuf2.bh_first.b_next == NULL); +} + +/* + * Return TRUE if readbuf1 is empty. There may still be redo characters in + * redbuf2. + */ + int +readbuf1_empty() +{ + return (readbuf1.bh_first.b_next == NULL); } /* @@ -428,7 +465,7 @@ flush_buffers(flush_typeahead) init_typebuf(); start_stuff(); - while (read_stuff(TRUE) != NUL) + while (read_readbuffers(TRUE) != NUL) ; if (flush_typeahead) /* remove all typeahead */ @@ -483,7 +520,7 @@ CancelRedo() redobuff = old_redobuff; old_redobuff.bh_first.b_next = NULL; start_stuff(); - while (read_stuff(TRUE) != NUL) + while (read_readbuffers(TRUE) != NUL) ; } } @@ -638,7 +675,7 @@ AppendNumberToRedobuff(n) stuffReadbuff(s) char_u *s; { - add_buff(&stuffbuff, s, -1L); + add_buff(&readbuf1, s, -1L); } void @@ -646,7 +683,7 @@ stuffReadbuffLen(s, len) char_u *s; long len; { - add_buff(&stuffbuff, s, len); + add_buff(&readbuf1, s, len); } #if defined(FEAT_EVAL) || defined(PROTO) @@ -692,7 +729,7 @@ stuffReadbuffSpec(s) stuffcharReadbuff(c) int c; { - add_char_buff(&stuffbuff, c); + add_char_buff(&readbuf1, c); } /* @@ -702,7 +739,7 @@ stuffcharReadbuff(c) stuffnumReadbuff(n) long n; { - add_num_buff(&stuffbuff, n); + add_num_buff(&readbuf1, n); } /* @@ -718,13 +755,13 @@ read_redo(init, old_redo) int init; int old_redo; { - static struct buffblock *bp; - static char_u *p; - int c; + static buffblock_T *bp; + static char_u *p; + int c; #ifdef FEAT_MBYTE - int n; - char_u buf[MB_MAXBYTES + 1]; - int i; + int n; + char_u buf[MB_MAXBYTES + 1]; + int i; #endif if (init) @@ -795,11 +832,11 @@ copy_redo(old_redo) int c; while ((c = read_redo(FALSE, old_redo)) != NUL) - stuffcharReadbuff(c); + add_char_buff(&readbuf2, c); } /* - * Stuff the redo buffer into the stuffbuff. + * Stuff the redo buffer into readbuf2. * Insert the redo count into the command. * If "old_redo" is TRUE, the last but one command is repeated * instead of the last command (inserting text). This is used for @@ -823,13 +860,13 @@ start_redo(count, old_redo) /* copy the buffer name, if present */ if (c == '"') { - add_buff(&stuffbuff, (char_u *)"\"", 1L); + add_buff(&readbuf2, (char_u *)"\"", 1L); c = read_redo(FALSE, old_redo); /* if a numbered buffer is used, increment the number */ if (c >= '1' && c < '9') ++c; - add_char_buff(&stuffbuff, c); + add_char_buff(&readbuf2, c); c = read_redo(FALSE, old_redo); } @@ -850,18 +887,18 @@ start_redo(count, old_redo) { while (VIM_ISDIGIT(c)) /* skip "old" count */ c = read_redo(FALSE, old_redo); - add_num_buff(&stuffbuff, count); + add_num_buff(&readbuf2, count); } /* copy from the redo buffer into the stuff buffer */ - add_char_buff(&stuffbuff, c); + add_char_buff(&readbuf2, c); copy_redo(old_redo); return OK; } /* * Repeat the last insert (R, o, O, a, A, i or I command) by stuffing - * the redo buffer into the stuffbuff. + * the redo buffer into readbuf2. * return FAIL for failure, OK otherwise */ int @@ -879,7 +916,7 @@ start_redo_ins() if (vim_strchr((char_u *)"AaIiRrOo", c) != NULL) { if (c == 'O' || c == 'o') - stuffReadbuff(NL_STR); + add_buff(&readbuf2, NL_STR, -1L); break; } } @@ -1360,8 +1397,10 @@ save_typeahead(tp) tp->old_mod_mask = old_mod_mask; old_char = -1; - tp->save_stuffbuff = stuffbuff; - stuffbuff.bh_first.b_next = NULL; + tp->save_readbuf1 = readbuf1; + readbuf1.bh_first.b_next = NULL; + tp->save_readbuf2 = readbuf2; + readbuf2.bh_first.b_next = NULL; # ifdef USE_INPUT_BUF tp->save_inputbuf = get_input_buf(); # endif @@ -1384,8 +1423,10 @@ restore_typeahead(tp) old_char = tp->old_char; old_mod_mask = tp->old_mod_mask; - free_buff(&stuffbuff); - stuffbuff = tp->save_stuffbuff; + free_buff(&readbuf1); + readbuf1 = tp->save_readbuf1; + free_buff(&readbuf2); + readbuf2 = tp->save_readbuf2; # ifdef USE_INPUT_BUF set_input_buf(tp->save_inputbuf); # endif @@ -1992,7 +2033,7 @@ vgetorpeek(advance) typeahead_char = 0; } else - c = read_stuff(advance); + c = read_readbuffers(advance); if (c != NUL && !got_int) { if (advance) @@ -2261,6 +2302,10 @@ vgetorpeek(advance) msg_row = Rows - 1; msg_clr_eos(); /* clear ruler */ } +#ifdef FEAT_WINDOWS + status_redraw_all(); + redraw_statuslines(); +#endif showmode(); setcursor(); continue; diff --git a/src/globals.h b/src/globals.h index 662f6aa673..176ff63566 100644 --- a/src/globals.h +++ b/src/globals.h @@ -981,11 +981,6 @@ EXTERN int RedrawingDisabled INIT(= 0); EXTERN int readonlymode INIT(= FALSE); /* Set to TRUE for "view" */ EXTERN int recoverymode INIT(= FALSE); /* Set to TRUE for "-r" option */ -EXTERN struct buffheader stuffbuff /* stuff buffer */ -#ifdef DO_INIT - = {{NULL, {NUL}}, NULL, 0, 0} -#endif - ; EXTERN typebuf_T typebuf /* typeahead buffer */ #ifdef DO_INIT = {NULL, NULL, 0, 0, 0, 0, 0, 0, 0} diff --git a/src/if_perl.xs b/src/if_perl.xs index a2247f022c..57a3b8fd14 100644 --- a/src/if_perl.xs +++ b/src/if_perl.xs @@ -14,7 +14,8 @@ #define IN_PERL_FILE /* don't include if_perl.pro from proto.h */ /* - * Currently 32-bit version of ActivePerl is built with VC6. + * Currently 32-bit version of ActivePerl is built with VC6 (or MinGW since + * ActivePerl 5.18). * (http://community.activestate.com/faq/windows-compilers-perl-modules) * It means that time_t should be 32-bit. However the default size of * time_t is 64-bit since VC8. So we have to define _USE_32BIT_TIME_T. @@ -23,8 +24,31 @@ # define _USE_32BIT_TIME_T #endif +/* + * Prevent including winsock.h. perl.h tries to detect whether winsock.h is + * already included before including winsock2.h, because winsock2.h isn't + * compatible with winsock.h. However the detection doesn't work with some + * versions of MinGW. If WIN32_LEAN_AND_MEAN is defined, windows.h will not + * include winsock.h. + */ +#ifdef WIN32 +# define WIN32_LEAN_AND_MEAN +#endif + #include "vim.h" +/* Work around for perl-5.18. + * Don't include "perl\lib\CORE\inline.h" for now, + * include it after Perl_sv_free2 is defined. */ +#ifdef DYNAMIC_PERL +# define PERL_NO_INLINE_FUNCTIONS +#endif + +/* Work around for using MSVC and ActivePerl 5.18. */ +#ifdef _MSC_VER +# define __inline__ __inline +#endif + #include #include #include @@ -81,10 +105,6 @@ # define PERL5101_OR_LATER #endif -#if (PERL_REVISION == 5) && (PERL_VERSION >= 18) -# define PERL5180_OR_LATER -#endif - #ifndef pTHX # define pTHX void # define pTHX_ @@ -145,11 +165,9 @@ typedef int perl_key; # define perl_free dll_perl_free # define Perl_get_context dll_Perl_get_context # define Perl_croak dll_Perl_croak -# ifndef PERL5180_OR_LATER # ifdef PERL5101_OR_LATER # define Perl_croak_xs_usage dll_Perl_croak_xs_usage # endif -# endif # ifndef PROTO # define Perl_croak_nocontext dll_Perl_croak_nocontext # define Perl_call_argv dll_Perl_call_argv @@ -262,10 +280,13 @@ static int (*perl_run)(PerlInterpreter*); static int (*perl_parse)(PerlInterpreter*, XSINIT_t, int, char**, char**); static void* (*Perl_get_context)(void); static void (*Perl_croak)(pTHX_ const char*, ...); -#ifndef PERL5180_OR_LATER #ifdef PERL5101_OR_LATER +/* Perl-5.18 has a different Perl_croak_xs_usage signature. */ +# if (PERL_REVISION == 5) && (PERL_VERSION >= 18) +static void (*Perl_croak_xs_usage)(const CV *const, const char *const params); +# else static void (*Perl_croak_xs_usage)(pTHX_ const CV *const, const char *const params); -#endif +# endif #endif static void (*Perl_croak_nocontext)(const char*, ...); static I32 (*Perl_dowantarray)(pTHX); @@ -337,7 +358,12 @@ static SV** (*Perl_TSv_ptr)(register PerlInterpreter*); static XPV** (*Perl_TXpv_ptr)(register PerlInterpreter*); static STRLEN* (*Perl_Tna_ptr)(register PerlInterpreter*); #else +/* Perl-5.18 has a different Perl_sv_free2 signature. */ +# if (PERL_REVISION == 5) && (PERL_VERSION >= 18) +static void (*Perl_sv_free2)(pTHX_ SV*, const U32); +# else static void (*Perl_sv_free2)(pTHX_ SV*); +# endif static void (*Perl_sys_init)(int* argc, char*** argv); static void (*Perl_sys_term)(void); static void (*Perl_call_list)(pTHX_ I32, AV*); @@ -384,10 +410,8 @@ static struct { {"perl_parse", (PERL_PROC*)&perl_parse}, {"Perl_get_context", (PERL_PROC*)&Perl_get_context}, {"Perl_croak", (PERL_PROC*)&Perl_croak}, -#ifndef PERL5180_OR_LATER #ifdef PERL5101_OR_LATER {"Perl_croak_xs_usage", (PERL_PROC*)&Perl_croak_xs_usage}, -#endif #endif {"Perl_croak_nocontext", (PERL_PROC*)&Perl_croak_nocontext}, {"Perl_dowantarray", (PERL_PROC*)&Perl_dowantarray}, @@ -492,6 +516,14 @@ static struct { {"", NULL}, }; +/* Work around for perl-5.18. + * The definitions of S_SvREFCNT_inc and S_SvREFCNT_dec are needed, so include + * "perl\lib\CORE\inline.h", after Perl_sv_free2 is defined. + * The linker won't complain about undefined __impl_Perl_sv_free2. */ +#if (PERL_REVISION == 5) && (PERL_VERSION >= 18) +# include +#endif + /* * Make all runtime-links of perl. * diff --git a/src/if_py_both.h b/src/if_py_both.h index e6db4a3d03..2442220c08 100644 --- a/src/if_py_both.h +++ b/src/if_py_both.h @@ -13,6 +13,11 @@ * Common code for if_python.c and if_python3.c. */ +#ifdef __BORLANDC__ +/* Disable Warning W8060: Possibly incorrect assignment in function ... */ +# pragma warn -8060 +#endif + static char_u e_py_systemexit[] = "E880: Can't handle SystemExit of %s exception in vim"; #if PY_VERSION_HEX < 0x02050000 @@ -31,8 +36,9 @@ static const char *vim_special_path = "_vim_path_"; #define PyErr_SET_STRING(exc, str) PyErr_SetString(exc, _(str)) #define PyErr_SetVim(str) PyErr_SetString(VimError, str) #define PyErr_SET_VIM(str) PyErr_SET_STRING(VimError, str) -#define PyErr_FORMAT(exc, str, tail) PyErr_Format(exc, _(str), tail) -#define PyErr_VIM_FORMAT(str, tail) PyErr_FORMAT(VimError, str, tail) +#define PyErr_FORMAT(exc, str, arg) PyErr_Format(exc, _(str), arg) +#define PyErr_FORMAT2(exc, str, arg1, arg2) PyErr_Format(exc, _(str), arg1,arg2) +#define PyErr_VIM_FORMAT(str, arg) PyErr_FORMAT(VimError, str, arg) #define Py_TYPE_NAME(obj) (obj->ob_type->tp_name == NULL \ ? "(NULL)" \ @@ -558,23 +564,40 @@ VimTryEnd(void) /* Keyboard interrupt should be preferred over anything else */ if (got_int) { - if (current_exception != NULL) + if (did_throw) discard_current_exception(); - else - need_rethrow = did_throw = FALSE; got_int = FALSE; PyErr_SetNone(PyExc_KeyboardInterrupt); return -1; } + else if (msg_list != NULL && *msg_list != NULL) + { + int should_free; + char_u *msg; + + msg = get_exception_string(*msg_list, ET_ERROR, NULL, &should_free); + + if (msg == NULL) + { + PyErr_NoMemory(); + return -1; + } + + PyErr_SetVim((char *) msg); + + free_global_msglist(); + + if (should_free) + vim_free(msg); + + return -1; + } else if (!did_throw) return (PyErr_Occurred() ? -1 : 0); /* Python exception is preferred over vim one; unlikely to occur though */ else if (PyErr_Occurred()) { - if (current_exception != NULL) - discard_current_exception(); - else - need_rethrow = did_throw = FALSE; + discard_current_exception(); return -1; } /* Finally transform VimL exception to python one */ @@ -1594,8 +1617,9 @@ _DictionaryItem(DictionaryObject *self, PyObject *args, int flags) } else if (flags & DICT_FLAG_RETURN_BOOL) { - Py_INCREF(Py_True); - return Py_True; + ret = Py_True; + Py_INCREF(ret); + return ret; } di = dict_lookup(hi); @@ -1895,11 +1919,17 @@ DictionaryUpdate(DictionaryObject *self, PyObject *args, PyObject *kwargs) } else { - PyObject *obj; + PyObject *obj = NULL; - if (!PyArg_ParseTuple(args, "O", &obj)) + if (!PyArg_ParseTuple(args, "|O", &obj)) return NULL; + if (obj == NULL) + { + Py_INCREF(Py_None); + return Py_None; + } + if (PyObject_HasAttrString(obj, "keys")) return DictionaryUpdate(self, NULL, obj); else @@ -2081,8 +2111,6 @@ static struct PyMethodDef DictionaryMethods[] = { }; static PyTypeObject ListType; -static PySequenceMethods ListAsSeq; -static PyMappingMethods ListAsMapping; typedef struct { @@ -2226,7 +2254,7 @@ ListLength(ListObject *self) } static PyObject * -ListItem(ListObject *self, Py_ssize_t index) +ListIndex(ListObject *self, Py_ssize_t index) { listitem_T *li; @@ -2246,53 +2274,389 @@ ListItem(ListObject *self, Py_ssize_t index) return ConvertToPyObject(&li->li_tv); } -#define PROC_RANGE \ - if (last < 0) {\ - if (last < -size) \ - last = 0; \ - else \ - last += size; \ - } \ - if (first < 0) \ - first = 0; \ - if (first > size) \ - first = size; \ - if (last > size) \ - last = size; - static PyObject * -ListSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last) +ListSlice(ListObject *self, Py_ssize_t first, Py_ssize_t step, + Py_ssize_t slicelen) { PyInt i; - PyInt size = ListLength(self); - PyInt n; PyObject *list; - int reversed = 0; - PROC_RANGE - if (first >= last) - first = last; + if (step == 0) + { + PyErr_SET_STRING(PyExc_ValueError, N_("slice step cannot be zero")); + return NULL; + } - n = last-first; - list = PyList_New(n); + list = PyList_New(slicelen); if (list == NULL) return NULL; - for (i = 0; i < n; ++i) + for (i = 0; i < slicelen; ++i) { - PyObject *item = ListItem(self, first + i); + PyObject *item; + + item = ListIndex(self, first + i*step); if (item == NULL) { Py_DECREF(list); return NULL; } - PyList_SET_ITEM(list, ((reversed)?(n-i-1):(i)), item); + PyList_SET_ITEM(list, i, item); } return list; } + static PyObject * +ListItem(ListObject *self, PyObject* idx) +{ +#if PY_MAJOR_VERSION < 3 + if (PyInt_Check(idx)) + { + long _idx = PyInt_AsLong(idx); + return ListIndex(self, _idx); + } + else +#endif + if (PyLong_Check(idx)) + { + long _idx = PyLong_AsLong(idx); + return ListIndex(self, _idx); + } + else if (PySlice_Check(idx)) + { + Py_ssize_t start, stop, step, slicelen; + + if (PySlice_GetIndicesEx((PySliceObject *)idx, ListLength(self), + &start, &stop, &step, &slicelen) < 0) + return NULL; + return ListSlice(self, start, step, slicelen); + } + else + { + RAISE_INVALID_INDEX_TYPE(idx); + return NULL; + } +} + + static void +list_restore(Py_ssize_t numadded, Py_ssize_t numreplaced, Py_ssize_t slicelen, + list_T *l, listitem_T **lis, listitem_T *lastaddedli) +{ + while (numreplaced--) + { + list_insert(l, lis[numreplaced], lis[slicelen + numreplaced]); + listitem_remove(l, lis[slicelen + numreplaced]); + } + while (numadded--) + { + listitem_T *next; + + next = lastaddedli->li_prev; + listitem_remove(l, lastaddedli); + lastaddedli = next; + } +} + + static int +ListAssSlice(ListObject *self, Py_ssize_t first, + Py_ssize_t step, Py_ssize_t slicelen, PyObject *obj) +{ + PyObject *iterator; + PyObject *item; + listitem_T *li; + listitem_T *lastaddedli = NULL; + listitem_T *next; + typval_T v; + list_T *l = self->list; + PyInt i; + PyInt j; + PyInt numreplaced = 0; + PyInt numadded = 0; + PyInt size; + listitem_T **lis = NULL; + + size = ListLength(self); + + if (l->lv_lock) + { + RAISE_LOCKED_LIST; + return -1; + } + + if (step == 0) + { + PyErr_SET_STRING(PyExc_ValueError, N_("slice step cannot be zero")); + return -1; + } + + if (step != 1 && slicelen == 0) + { + /* Nothing to do. Only error out if obj has some items. */ + int ret = 0; + + if (obj == NULL) + return 0; + + if (!(iterator = PyObject_GetIter(obj))) + return -1; + + if ((item = PyIter_Next(iterator))) + { + PyErr_FORMAT(PyExc_ValueError, + N_("attempt to assign sequence of size greater then %d " + "to extended slice"), 0); + Py_DECREF(item); + ret = -1; + } + Py_DECREF(iterator); + return ret; + } + + if (obj != NULL) + /* XXX May allocate zero bytes. */ + if (!(lis = PyMem_New(listitem_T *, slicelen * 2))) + { + PyErr_NoMemory(); + return -1; + } + + if (first == size) + li = NULL; + else + { + li = list_find(l, (long) first); + if (li == NULL) + { + PyErr_VIM_FORMAT(N_("internal error: no vim list item %d"), + (int)first); + if (obj != NULL) + PyMem_Free(lis); + return -1; + } + i = slicelen; + while (i-- && li != NULL) + { + j = step; + next = li; + if (step > 0) + while (next != NULL && ((next = next->li_next) != NULL) && --j); + else + while (next != NULL && ((next = next->li_prev) != NULL) && ++j); + + if (obj == NULL) + listitem_remove(l, li); + else + lis[slicelen - i - 1] = li; + + li = next; + } + if (li == NULL && i != -1) + { + PyErr_SET_VIM(N_("internal error: not enough list items")); + if (obj != NULL) + PyMem_Free(lis); + return -1; + } + } + + if (obj == NULL) + return 0; + + if (!(iterator = PyObject_GetIter(obj))) + { + PyMem_Free(lis); + return -1; + } + + i = 0; + while ((item = PyIter_Next(iterator))) + { + if (ConvertFromPyObject(item, &v) == -1) + { + Py_DECREF(iterator); + Py_DECREF(item); + PyMem_Free(lis); + return -1; + } + Py_DECREF(item); + if (list_insert_tv(l, &v, numreplaced < slicelen + ? lis[numreplaced] + : li) == FAIL) + { + clear_tv(&v); + PyErr_SET_VIM(N_("internal error: failed to add item to list")); + list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli); + PyMem_Free(lis); + return -1; + } + if (numreplaced < slicelen) + { + lis[slicelen + numreplaced] = lis[numreplaced]->li_prev; + list_remove(l, lis[numreplaced], lis[numreplaced]); + numreplaced++; + } + else + { + if (li) + lastaddedli = li->li_prev; + else + lastaddedli = l->lv_last; + numadded++; + } + clear_tv(&v); + if (step != 1 && i >= slicelen) + { + Py_DECREF(iterator); + PyErr_FORMAT(PyExc_ValueError, + N_("attempt to assign sequence of size greater then %d " + "to extended slice"), (int) slicelen); + list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli); + PyMem_Free(lis); + return -1; + } + ++i; + } + Py_DECREF(iterator); + + if (step != 1 && i != slicelen) + { + PyErr_FORMAT2(PyExc_ValueError, + N_("attempt to assign sequence of size %d to extended slice " + "of size %d"), (int) i, (int) slicelen); + list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli); + PyMem_Free(lis); + return -1; + } + + if (PyErr_Occurred()) + { + list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli); + PyMem_Free(lis); + return -1; + } + + for (i = 0; i < numreplaced; i++) + listitem_free(lis[i]); + if (step == 1) + for (i = numreplaced; i < slicelen; i++) + listitem_remove(l, lis[i]); + + PyMem_Free(lis); + + return 0; +} + + static int +ListAssIndex(ListObject *self, Py_ssize_t index, PyObject *obj) +{ + typval_T tv; + list_T *l = self->list; + listitem_T *li; + Py_ssize_t length = ListLength(self); + + if (l->lv_lock) + { + RAISE_LOCKED_LIST; + return -1; + } + if (index > length || (index == length && obj == NULL)) + { + PyErr_SET_STRING(PyExc_IndexError, N_("list index out of range")); + return -1; + } + + if (obj == NULL) + { + li = list_find(l, (long) index); + list_remove(l, li, li); + clear_tv(&li->li_tv); + vim_free(li); + return 0; + } + + if (ConvertFromPyObject(obj, &tv) == -1) + return -1; + + if (index == length) + { + if (list_append_tv(l, &tv) == FAIL) + { + clear_tv(&tv); + PyErr_SET_VIM(N_("failed to add item to list")); + return -1; + } + } + else + { + li = list_find(l, (long) index); + clear_tv(&li->li_tv); + copy_tv(&tv, &li->li_tv); + clear_tv(&tv); + } + return 0; +} + + static Py_ssize_t +ListAssItem(ListObject *self, PyObject *idx, PyObject *obj) +{ +#if PY_MAJOR_VERSION < 3 + if (PyInt_Check(idx)) + { + long _idx = PyInt_AsLong(idx); + return ListAssIndex(self, _idx, obj); + } + else +#endif + if (PyLong_Check(idx)) + { + long _idx = PyLong_AsLong(idx); + return ListAssIndex(self, _idx, obj); + } + else if (PySlice_Check(idx)) + { + Py_ssize_t start, stop, step, slicelen; + + if (PySlice_GetIndicesEx((PySliceObject *)idx, ListLength(self), + &start, &stop, &step, &slicelen) < 0) + return -1; + return ListAssSlice(self, start, step, slicelen, + obj); + } + else + { + RAISE_INVALID_INDEX_TYPE(idx); + return -1; + } +} + + static PyObject * +ListConcatInPlace(ListObject *self, PyObject *obj) +{ + list_T *l = self->list; + PyObject *lookup_dict; + + if (l->lv_lock) + { + RAISE_LOCKED_LIST; + return NULL; + } + + if (!(lookup_dict = PyDict_New())) + return NULL; + + if (list_py_concat(l, obj, lookup_dict) == -1) + { + Py_DECREF(lookup_dict); + return NULL; + } + Py_DECREF(lookup_dict); + + Py_INCREF(self); + return (PyObject *)(self); +} + typedef struct { listwatch_T lw; @@ -2343,156 +2707,6 @@ ListIter(ListObject *self) NULL, NULL); } - static int -ListAssItem(ListObject *self, Py_ssize_t index, PyObject *obj) -{ - typval_T tv; - list_T *l = self->list; - listitem_T *li; - Py_ssize_t length = ListLength(self); - - if (l->lv_lock) - { - RAISE_LOCKED_LIST; - return -1; - } - if (index > length || (index == length && obj == NULL)) - { - PyErr_SET_STRING(PyExc_IndexError, N_("list index out of range")); - return -1; - } - - if (obj == NULL) - { - li = list_find(l, (long) index); - list_remove(l, li, li); - clear_tv(&li->li_tv); - vim_free(li); - return 0; - } - - if (ConvertFromPyObject(obj, &tv) == -1) - return -1; - - if (index == length) - { - if (list_append_tv(l, &tv) == FAIL) - { - clear_tv(&tv); - PyErr_SET_VIM(N_("failed to add item to list")); - return -1; - } - } - else - { - li = list_find(l, (long) index); - clear_tv(&li->li_tv); - copy_tv(&tv, &li->li_tv); - clear_tv(&tv); - } - return 0; -} - - static int -ListAssSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *obj) -{ - PyInt size = ListLength(self); - PyObject *iterator; - PyObject *item; - listitem_T *li; - listitem_T *next; - typval_T v; - list_T *l = self->list; - PyInt i; - - if (l->lv_lock) - { - RAISE_LOCKED_LIST; - return -1; - } - - PROC_RANGE - - if (first == size) - li = NULL; - else - { - li = list_find(l, (long) first); - if (li == NULL) - { - PyErr_VIM_FORMAT(N_("internal error: no vim list item %d"), - (int)first); - return -1; - } - if (last > first) - { - i = last - first; - while (i-- && li != NULL) - { - next = li->li_next; - listitem_remove(l, li); - li = next; - } - } - } - - if (obj == NULL) - return 0; - - if (!(iterator = PyObject_GetIter(obj))) - return -1; - - while ((item = PyIter_Next(iterator))) - { - if (ConvertFromPyObject(item, &v) == -1) - { - Py_DECREF(iterator); - Py_DECREF(item); - return -1; - } - Py_DECREF(item); - if (list_insert_tv(l, &v, li) == FAIL) - { - clear_tv(&v); - PyErr_SET_VIM(N_("internal error: failed to add item to list")); - return -1; - } - clear_tv(&v); - } - Py_DECREF(iterator); - - if (PyErr_Occurred()) - return -1; - - return 0; -} - - static PyObject * -ListConcatInPlace(ListObject *self, PyObject *obj) -{ - list_T *l = self->list; - PyObject *lookup_dict; - - if (l->lv_lock) - { - RAISE_LOCKED_LIST; - return NULL; - } - - if (!(lookup_dict = PyDict_New())) - return NULL; - - if (list_py_concat(l, obj, lookup_dict) == -1) - { - Py_DECREF(lookup_dict); - return NULL; - } - Py_DECREF(lookup_dict); - - Py_INCREF(self); - return (PyObject *)(self); -} - static char *ListAttrs[] = { "locked", NULL @@ -2540,6 +2754,25 @@ ListSetattr(ListObject *self, char *name, PyObject *valObject) } } +static PySequenceMethods ListAsSeq = { + (lenfunc) ListLength, /* sq_length, len(x) */ + (binaryfunc) 0, /* RangeConcat, sq_concat, x+y */ + 0, /* RangeRepeat, sq_repeat, x*n */ + (PyIntArgFunc) ListIndex, /* sq_item, x[i] */ + 0, /* was_sq_slice, x[i:j] */ + (PyIntObjArgProc) ListAssIndex, /* sq_as_item, x[i]=v */ + 0, /* was_sq_ass_slice, x[i:j]=v */ + 0, /* sq_contains */ + (binaryfunc) ListConcatInPlace,/* sq_inplace_concat */ + 0, /* sq_inplace_repeat */ +}; + +static PyMappingMethods ListAsMapping = { + /* mp_length */ (lenfunc) ListLength, + /* mp_subscript */ (binaryfunc) ListItem, + /* mp_ass_subscript */ (objobjargproc) ListAssItem, +}; + static struct PyMethodDef ListMethods[] = { {"extend", (PyCFunction)ListConcatInPlace, METH_O, ""}, {"__dir__", (PyCFunction)ListDir, METH_NOARGS, ""}, @@ -2718,10 +2951,10 @@ typedef int (*checkfun)(void *); typedef struct { PyObject_HEAD - int opt_type; - void *from; - checkfun Check; - PyObject *fromObj; + int opt_type; + void *from; + checkfun Check; + PyObject *fromObj; } OptionsObject; static int @@ -2840,6 +3073,69 @@ OptionsItem(OptionsObject *self, PyObject *keyObject) } } + static int +OptionsContains(OptionsObject *self, PyObject *keyObject) +{ + char_u *key; + PyObject *todecref; + + if (!(key = StringToChars(keyObject, &todecref))) + return -1; + + if (*key == NUL) + { + Py_XDECREF(todecref); + return 0; + } + + if (get_option_value_strict(key, NULL, NULL, self->opt_type, NULL)) + { + Py_XDECREF(todecref); + return 1; + } + else + { + Py_XDECREF(todecref); + return 0; + } +} + +typedef struct +{ + void *lastoption; + int opt_type; +} optiterinfo_T; + + static PyObject * +OptionsIterNext(optiterinfo_T **oii) +{ + char_u *name; + + if ((name = option_iter_next(&((*oii)->lastoption), (*oii)->opt_type))) + return PyString_FromString((char *)name); + + return NULL; +} + + static PyObject * +OptionsIter(OptionsObject *self) +{ + optiterinfo_T *oii; + + if (!(oii = PyMem_New(optiterinfo_T, 1))) + { + PyErr_NoMemory(); + return NULL; + } + + oii->opt_type = self->opt_type; + oii->lastoption = NULL; + + return IterNew(oii, + (destructorfun) PyMem_Free, (nextfun) OptionsIterNext, + NULL, NULL); +} + static int set_option_value_err(char_u *key, int numval, char_u *stringval, int opt_flags) { @@ -2983,11 +3279,14 @@ OptionsAssItem(OptionsObject *self, PyObject *keyObject, PyObject *valObject) else { char_u *val; - PyObject *todecref; + PyObject *todecref2; - if ((val = StringToChars(valObject, &todecref))) + if ((val = StringToChars(valObject, &todecref2))) + { ret = set_option_value_for(key, 0, val, opt_flags, self->opt_type, self->from); + Py_XDECREF(todecref2); + } else ret = -1; } @@ -2997,6 +3296,19 @@ OptionsAssItem(OptionsObject *self, PyObject *keyObject, PyObject *valObject) return ret; } +static PySequenceMethods OptionsAsSeq = { + 0, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + 0, /* sq_item */ + 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ + (objobjproc) OptionsContains, /* sq_contains */ + 0, /* sq_inplace_concat */ + 0, /* sq_inplace_repeat */ +}; + static PyMappingMethods OptionsAsMapping = { (lenfunc) NULL, (binaryfunc) OptionsItem, @@ -5887,8 +6199,10 @@ init_structs(void) vim_memset(&OptionsType, 0, sizeof(OptionsType)); OptionsType.tp_name = "vim.options"; OptionsType.tp_basicsize = sizeof(OptionsObject); + OptionsType.tp_as_sequence = &OptionsAsSeq; OptionsType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC; OptionsType.tp_doc = "object for manipulating options"; + OptionsType.tp_iter = (getiterfunc)OptionsIter; OptionsType.tp_as_mapping = &OptionsAsMapping; OptionsType.tp_dealloc = (destructor)OptionsDestructor; OptionsType.tp_traverse = (traverseproc)OptionsTraverse; diff --git a/src/if_python.c b/src/if_python.c index 530654e499..2707b1a81d 100644 --- a/src/if_python.c +++ b/src/if_python.c @@ -200,6 +200,7 @@ struct PyMethodDef { Py_ssize_t a; }; # define PyTuple_Size dll_PyTuple_Size # define PyTuple_GetItem dll_PyTuple_GetItem # define PyTuple_Type (*dll_PyTuple_Type) +# define PySlice_GetIndicesEx dll_PySlice_GetIndicesEx # define PyImport_ImportModule dll_PyImport_ImportModule # define PyDict_New dll_PyDict_New # define PyDict_GetItemString dll_PyDict_GetItemString @@ -245,6 +246,7 @@ struct PyMethodDef { Py_ssize_t a; }; # define PySys_GetObject dll_PySys_GetObject # define PySys_SetArgv dll_PySys_SetArgv # define PyType_Type (*dll_PyType_Type) +# define PySlice_Type (*dll_PySlice_Type) # define PyType_Ready (*dll_PyType_Ready) # define PyType_GenericAlloc dll_PyType_GenericAlloc # define Py_BuildValue dll_Py_BuildValue @@ -345,6 +347,9 @@ static PyObject*(*dll_PySequence_Fast)(PyObject *, const char *); static PyInt(*dll_PyTuple_Size)(PyObject *); static PyObject*(*dll_PyTuple_GetItem)(PyObject *, PyInt); static PyTypeObject* dll_PyTuple_Type; +static int (*dll_PySlice_GetIndicesEx)(PySliceObject *r, PyInt length, + PyInt *start, PyInt *stop, PyInt *step, + PyInt *slicelen); static PyObject*(*dll_PyImport_ImportModule)(const char *); static PyObject*(*dll_PyDict_New)(void); static PyObject*(*dll_PyDict_GetItemString)(PyObject *, const char *); @@ -386,6 +391,7 @@ static int(*dll_PySys_SetObject)(char *, PyObject *); static PyObject *(*dll_PySys_GetObject)(char *); static int(*dll_PySys_SetArgv)(int, char **); static PyTypeObject* dll_PyType_Type; +static PyTypeObject* dll_PySlice_Type; static int (*dll_PyType_Ready)(PyTypeObject *type); static PyObject* (*dll_PyType_GenericAlloc)(PyTypeObject *type, PyInt nitems); static PyObject*(*dll_Py_BuildValue)(char *, ...); @@ -525,6 +531,7 @@ static struct {"PyTuple_GetItem", (PYTHON_PROC*)&dll_PyTuple_GetItem}, {"PyTuple_Size", (PYTHON_PROC*)&dll_PyTuple_Size}, {"PyTuple_Type", (PYTHON_PROC*)&dll_PyTuple_Type}, + {"PySlice_GetIndicesEx", (PYTHON_PROC*)&dll_PySlice_GetIndicesEx}, {"PyImport_ImportModule", (PYTHON_PROC*)&dll_PyImport_ImportModule}, {"PyDict_GetItemString", (PYTHON_PROC*)&dll_PyDict_GetItemString}, {"PyDict_Next", (PYTHON_PROC*)&dll_PyDict_Next}, @@ -566,6 +573,7 @@ static struct {"PySys_GetObject", (PYTHON_PROC*)&dll_PySys_GetObject}, {"PySys_SetArgv", (PYTHON_PROC*)&dll_PySys_SetArgv}, {"PyType_Type", (PYTHON_PROC*)&dll_PyType_Type}, + {"PySlice_Type", (PYTHON_PROC*)&dll_PySlice_Type}, {"PyType_Ready", (PYTHON_PROC*)&dll_PyType_Ready}, {"PyType_GenericAlloc", (PYTHON_PROC*)&dll_PyType_GenericAlloc}, {"Py_FindMethod", (PYTHON_PROC*)&dll_Py_FindMethod}, @@ -1476,21 +1484,6 @@ DictionaryGetattr(PyObject *self, char *name) return Py_FindMethod(DictionaryMethods, self, name); } -static PySequenceMethods ListAsSeq = { - (PyInquiry) ListLength, - (binaryfunc) 0, - (PyIntArgFunc) 0, - (PyIntArgFunc) ListItem, - (PyIntIntArgFunc) ListSlice, - (PyIntObjArgProc) ListAssItem, - (PyIntIntObjArgProc) ListAssSlice, - (objobjproc) 0, -#if PY_MAJOR_VERSION >= 2 - (binaryfunc) ListConcatInPlace, - 0, -#endif -}; - static PyObject * ListGetattr(PyObject *self, char *name) { diff --git a/src/if_python3.c b/src/if_python3.c index 40bc97bc8c..99781fcc80 100644 --- a/src/if_python3.c +++ b/src/if_python3.c @@ -97,6 +97,9 @@ #define Py_ssize_t_fmt "n" #define Py_bytes_fmt "y" +#define PyIntArgFunc ssizeargfunc +#define PyIntObjArgProc ssizeobjargproc + #if defined(DYNAMIC_PYTHON3) || defined(PROTO) # ifndef WIN3264 @@ -291,8 +294,9 @@ static Py_ssize_t (*py3_PyTuple_Size)(PyObject *); static PyObject* (*py3_PyTuple_GetItem)(PyObject *, Py_ssize_t); static int (*py3_PyMapping_Check)(PyObject *); static PyObject* (*py3_PyMapping_Keys)(PyObject *); -static int (*py3_PySlice_GetIndicesEx)(PyObject *r, Py_ssize_t length, - Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength); +static int (*py3_PySlice_GetIndicesEx)(PySliceObject *r, Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, + Py_ssize_t *slicelen); static PyObject* (*py3_PyErr_NoMemory)(void); static void (*py3_Py_Finalize)(void); static void (*py3_PyErr_SetString)(PyObject *, const char *); @@ -1186,7 +1190,7 @@ BufferSubscript(PyObject *self, PyObject* idx) if (CheckBuffer((BufferObject *) self)) return NULL; - if (PySlice_GetIndicesEx((PyObject *)idx, + if (PySlice_GetIndicesEx((PySliceObject *)idx, (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count, &start, &stop, &step, &slicelen) < 0) @@ -1218,7 +1222,7 @@ BufferAsSubscript(PyObject *self, PyObject* idx, PyObject* val) if (CheckBuffer((BufferObject *) self)) return -1; - if (PySlice_GetIndicesEx((PyObject *)idx, + if (PySlice_GetIndicesEx((PySliceObject *)idx, (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count, &start, &stop, &step, &slicelen) < 0) @@ -1302,7 +1306,7 @@ RangeSubscript(PyObject *self, PyObject* idx) { Py_ssize_t start, stop, step, slicelen; - if (PySlice_GetIndicesEx((PyObject *)idx, + if (PySlice_GetIndicesEx((PySliceObject *)idx, ((RangeObject *)(self))->end-((RangeObject *)(self))->start+1, &start, &stop, &step, &slicelen) < 0) @@ -1329,7 +1333,7 @@ RangeAsSubscript(PyObject *self, PyObject *idx, PyObject *val) { Py_ssize_t start, stop, step, slicelen; - if (PySlice_GetIndicesEx((PyObject *)idx, + if (PySlice_GetIndicesEx((PySliceObject *)idx, ((RangeObject *)(self))->end-((RangeObject *)(self))->start+1, &start, &stop, &step, &slicelen) < 0) @@ -1478,76 +1482,6 @@ DictionarySetattro(PyObject *self, PyObject *nameobj, PyObject *val) /* List object - Definitions */ -static PySequenceMethods ListAsSeq = { - (lenfunc) ListLength, /* sq_length, len(x) */ - (binaryfunc) 0, /* RangeConcat, sq_concat, x+y */ - (ssizeargfunc) 0, /* RangeRepeat, sq_repeat, x*n */ - (ssizeargfunc) ListItem, /* sq_item, x[i] */ - (void *) 0, /* was_sq_slice, x[i:j] */ - (ssizeobjargproc) ListAssItem, /* sq_as_item, x[i]=v */ - (void *) 0, /* was_sq_ass_slice, x[i:j]=v */ - 0, /* sq_contains */ - (binaryfunc) ListConcatInPlace,/* sq_inplace_concat */ - 0, /* sq_inplace_repeat */ -}; - -static PyObject *ListSubscript(PyObject *, PyObject *); -static Py_ssize_t ListAsSubscript(PyObject *, PyObject *, PyObject *); - -static PyMappingMethods ListAsMapping = { - /* mp_length */ (lenfunc) ListLength, - /* mp_subscript */ (binaryfunc) ListSubscript, - /* mp_ass_subscript */ (objobjargproc) ListAsSubscript, -}; - - static PyObject * -ListSubscript(PyObject *self, PyObject* idx) -{ - if (PyLong_Check(idx)) - { - long _idx = PyLong_AsLong(idx); - return ListItem((ListObject *)(self), _idx); - } - else if (PySlice_Check(idx)) - { - Py_ssize_t start, stop, step, slicelen; - - if (PySlice_GetIndicesEx(idx, ListLength((ListObject *)(self)), - &start, &stop, &step, &slicelen) < 0) - return NULL; - return ListSlice((ListObject *)(self), start, stop); - } - else - { - RAISE_INVALID_INDEX_TYPE(idx); - return NULL; - } -} - - static Py_ssize_t -ListAsSubscript(PyObject *self, PyObject *idx, PyObject *obj) -{ - if (PyLong_Check(idx)) - { - long _idx = PyLong_AsLong(idx); - return ListAssItem((ListObject *)(self), _idx, obj); - } - else if (PySlice_Check(idx)) - { - Py_ssize_t start, stop, step, slicelen; - - if (PySlice_GetIndicesEx(idx, ListLength((ListObject *)(self)), - &start, &stop, &step, &slicelen) < 0) - return -1; - return ListAssSlice((ListObject *)(self), start, stop, obj); - } - else - { - RAISE_INVALID_INDEX_TYPE(idx); - return -1; - } -} - static PyObject * ListGetattro(PyObject *self, PyObject *nameobj) { diff --git a/src/if_ruby.c b/src/if_ruby.c index b2bf6a9f26..e138c68c2d 100644 --- a/src/if_ruby.c +++ b/src/if_ruby.c @@ -96,6 +96,12 @@ # define rb_num2int rb_num2int_stub #endif +# if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 21 +/* Ruby 2.1 adds new GC called RGenGC and RARRAY_PTR uses + * rb_gc_writebarrier_unprotect_promoted if USE_RGENGC */ +# define rb_gc_writebarrier_unprotect_promoted rb_gc_writebarrier_unprotect_promoted_stub +# endif + #ifdef FEAT_GUI_MACVIM # include #else @@ -381,6 +387,10 @@ static VALUE (*dll_rb_require) (const char*); static void* (*ruby_process_options)(int, char**); # endif +# if defined(USE_RGENGC) && USE_RGENGC +static void (*dll_rb_gc_writebarrier_unprotect_promoted)(VALUE); +# endif + # if defined(RUBY19_OR_LATER) && !defined(PROTO) SIGNED_VALUE rb_num2long_stub(VALUE x) { @@ -414,6 +424,13 @@ VALUE rb_num2ulong(VALUE x) # endif # endif +# if defined(USE_RGENGC) && USE_RGENGC +void rb_gc_writebarrier_unprotect_promoted_stub(VALUE obj) +{ + return dll_rb_gc_writebarrier_unprotect_promoted(obj); +} +# endif + static HINSTANCE hinstRuby = NULL; /* Instance of ruby.dll */ /* @@ -528,6 +545,9 @@ static struct {"rb_ia64_bsp", (RUBY_PROC*)&dll_rb_ia64_bsp}, # endif {"ruby_init_stack", (RUBY_PROC*)&dll_ruby_init_stack}, +# endif +# if defined(USE_RGENGC) && USE_RGENGC + {"rb_gc_writebarrier_unprotect_promoted", (RUBY_PROC*)&dll_rb_gc_writebarrier_unprotect_promoted}, # endif {"", NULL}, }; diff --git a/src/main.c b/src/main.c index 965f372006..c60ed6f045 100644 --- a/src/main.c +++ b/src/main.c @@ -718,6 +718,11 @@ vim_main2(int argc UNUSED, char **argv UNUSED) TIME_MSG("reading viminfo"); } #endif +#ifdef FEAT_EVAL + /* It's better to make v:oldfiles an empty list than NULL. */ + if (get_vim_var_list(VV_OLDFILES) == NULL) + set_vim_var_list(VV_OLDFILES, list_alloc()); +#endif #ifdef FEAT_QUICKFIX /* @@ -1105,7 +1110,7 @@ main_loop(cmdwin, noexmode) /* Setup to catch a terminating error from the X server. Just ignore * it, restore the state and continue. This might not always work * properly, but at least we don't exit unexpectedly when the X server - * exists while Vim is running in a console. */ + * exits while Vim is running in a console. */ if (!cmdwin && !noexmode && SETJMP(x_jump_env)) { State = NORMAL; diff --git a/src/mbyte.c b/src/mbyte.c index 4140223e09..dd0e055f70 100644 --- a/src/mbyte.c +++ b/src/mbyte.c @@ -83,10 +83,18 @@ # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN # endif -# include +# if defined(FEAT_GUI) || defined(FEAT_XCLIPBOARD) +# include +# define WINBYTE wBYTE +# else +# include +# define WINBYTE BYTE +# endif # ifdef WIN32 # undef WIN32 /* Some windows.h define WIN32, we don't want that here. */ # endif +#else +# define WINBYTE BYTE #endif #if (defined(WIN3264) || defined(WIN32UNIX)) && !defined(__MINGW32__) @@ -698,7 +706,7 @@ codepage_invalid: /* enc_dbcs is set by setting 'fileencoding'. It becomes a Windows * CodePage identifier, which we can pass directly in to Windows * API */ - n = IsDBCSLeadByteEx(enc_dbcs, (BYTE)i) ? 2 : 1; + n = IsDBCSLeadByteEx(enc_dbcs, (WINBYTE)i) ? 2 : 1; #else # if defined(MACOS) || defined(__amigaos4__) /* diff --git a/src/memline.c b/src/memline.c index 2f08557f82..8f6c0e01e8 100644 --- a/src/memline.c +++ b/src/memline.c @@ -841,8 +841,11 @@ ml_close_all(del_file) for (buf = firstbuf; buf != NULL; buf = buf->b_next) ml_close(buf, del_file && ((buf->b_flags & BF_PRESERVED) == 0 || vim_strchr(p_cpo, CPO_PRESERVE) == NULL)); +#ifdef FEAT_SPELL + spell_delete_wordlist(); /* delete the internal wordlist */ +#endif #ifdef TEMPDIRNAMES - vim_deltempdir(); /* delete created temp directory */ + vim_deltempdir(); /* delete created temp directory */ #endif } @@ -4911,7 +4914,7 @@ ml_crypt_prepare(mfp, offset, reading) * block for the salt. */ vim_snprintf((char *)salt, sizeof(salt), "%ld", (long)offset); bf_key_init(key, salt, (int)STRLEN(salt)); - bf_ofb_init(seed, MF_SEED_LEN); + bf_cfb_init(seed, MF_SEED_LEN); } } diff --git a/src/misc2.c b/src/misc2.c index 5908623b09..bb0d4c9ac4 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -487,7 +487,7 @@ get_cursor_rel_lnum(wp, lnum) { while (lnum > cursor) { - (void)hasFolding(lnum, &lnum, NULL); + (void)hasFoldingWin(wp, lnum, &lnum, NULL, TRUE, NULL); /* if lnum and cursor are in the same fold, * now lnum <= cursor */ if (lnum > cursor) @@ -499,7 +499,7 @@ get_cursor_rel_lnum(wp, lnum) { while (lnum < cursor) { - (void)hasFolding(lnum, NULL, &lnum); + (void)hasFoldingWin(wp, lnum, NULL, &lnum, TRUE, NULL); /* if lnum and cursor are in the same fold, * now lnum >= cursor */ if (lnum < cursor) @@ -4701,8 +4701,8 @@ vim_findfile_init(path, filename, stopdirs, level, free_visited, find_what, else { char_u *p = gettail(search_ctx->ffsc_fix_path); - char_u *wc_path = NUL; - char_u *temp = NUL; + char_u *wc_path = NULL; + char_u *temp = NULL; int len = 0; if (p > search_ctx->ffsc_fix_path) diff --git a/src/move.c b/src/move.c index 5c8257449c..67e214bf97 100644 --- a/src/move.c +++ b/src/move.c @@ -2101,6 +2101,9 @@ scroll_cursor_halfway(atend) int used; lineoff_T loff; lineoff_T boff; +#ifdef FEAT_DIFF + linenr_T old_topline = curwin->w_topline; +#endif loff.lnum = boff.lnum = curwin->w_cursor.lnum; #ifdef FEAT_FOLDING @@ -2156,6 +2159,8 @@ scroll_cursor_halfway(atend) curwin->w_topline = topline; #ifdef FEAT_DIFF curwin->w_topfill = topfill; + if (old_topline > curwin->w_topline + curwin->w_height) + curwin->w_botfill = FALSE; check_topfill(curwin, FALSE); #endif curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP); diff --git a/src/normal.c b/src/normal.c index 5eca2cd63e..7654f87bdc 100644 --- a/src/normal.c +++ b/src/normal.c @@ -655,8 +655,8 @@ normal_cmd(oap, toplevel) #ifdef FEAT_EVAL /* Set v:count here, when called from main() and not a stuffed * command, so that v:count can be used in an expression mapping - * when there is no count. */ - if (toplevel && stuff_empty()) + * when there is no count. Do set it for redo. */ + if (toplevel && readbuf1_empty()) set_vcount_ca(&ca, &set_prevcount); #endif @@ -736,8 +736,8 @@ getcount: #ifdef FEAT_EVAL /* Set v:count here, when called from main() and not a stuffed * command, so that v:count can be used in an expression mapping - * right after the count. */ - if (toplevel && stuff_empty()) + * right after the count. Do set it for redo. */ + if (toplevel && readbuf1_empty()) set_vcount_ca(&ca, &set_prevcount); #endif if (ctrl_w) @@ -819,8 +819,9 @@ getcount: #ifdef FEAT_EVAL /* * Only set v:count when called from main() and not a stuffed command. + * Do set it for redo. */ - if (toplevel && stuff_empty()) + if (toplevel && readbuf1_empty()) set_vcount(ca.count0, ca.count1, set_prevcount); #endif @@ -962,11 +963,8 @@ getcount: #ifdef FEAT_CMDL_INFO need_flushbuf |= add_to_showcmd(ca.nchar); #endif - /* For "gn" from redo, need to get one more char to determine the - * operator */ if (ca.nchar == 'r' || ca.nchar == '\'' || ca.nchar == '`' - || ca.nchar == Ctrl_BSL - || ((ca.nchar == 'n' || ca.nchar == 'N') && !stuff_empty())) + || ca.nchar == Ctrl_BSL) { cp = &ca.extra_char; /* need to get a third character */ if (ca.nchar != 'r') @@ -1797,10 +1795,9 @@ do_pending_operator(cap, old_col, gui_yank) * otherwise it might be the second char of the operator. */ if (cap->cmdchar == 'g' && (cap->nchar == 'n' || cap->nchar == 'N')) - /* "gn" and "gN" are a bit different */ - prep_redo(oap->regname, 0L, NUL, cap->cmdchar, cap->nchar, - get_op_char(oap->op_type), - get_extra_op_char(oap->op_type)); + prep_redo(oap->regname, cap->count0, + get_op_char(oap->op_type), get_extra_op_char(oap->op_type), + oap->motion_force, cap->cmdchar, cap->nchar); else if (cap->cmdchar != ':') prep_redo(oap->regname, 0L, NUL, 'v', get_op_char(oap->op_type), @@ -4030,6 +4027,8 @@ add_to_showcmd(c) #endif p = transchar(c); + if (*p == ' ') + STRCPY(p, "<20>"); old_len = (int)STRLEN(showcmd_buf); extra_len = (int)STRLEN(p); overflow = old_len + extra_len - SHOWCMD_COLS; @@ -4651,7 +4650,10 @@ nv_screengo(oap, dir, dist) } #endif - coladvance(curwin->w_curswant); + if (virtual_active() && atend) + coladvance(MAXCOL); + else + coladvance(curwin->w_curswant); #if defined(FEAT_LINEBREAK) || defined(FEAT_MBYTE) if (curwin->w_cursor.col > 0 && curwin->w_p_wrap) diff --git a/src/ops.c b/src/ops.c index d2060a47e8..8505f64a5b 100644 --- a/src/ops.c +++ b/src/ops.c @@ -4452,6 +4452,12 @@ do_join(count, insert_space, save_undo, use_formatoptions) for (t = 0; t < count; ++t) { curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t)); + if (t == 0) + { + /* Set the '[ mark. */ + curwin->w_buffer->b_op_start.lnum = curwin->w_cursor.lnum; + curwin->w_buffer->b_op_start.col = (colnr_T)STRLEN(curr); + } #if defined(FEAT_COMMENTS) || defined(PROTO) if (remove_comments) { @@ -4568,6 +4574,10 @@ do_join(count, insert_space, save_undo, use_formatoptions) } ml_replace(curwin->w_cursor.lnum, newp, FALSE); + /* Set the '] mark. */ + curwin->w_buffer->b_op_end.lnum = curwin->w_cursor.lnum; + curwin->w_buffer->b_op_end.col = (colnr_T)STRLEN(newp); + /* Only report the change in the first line here, del_lines() will report * the deleted line. */ changed_lines(curwin->w_cursor.lnum, currsize, @@ -6240,7 +6250,9 @@ get_reg_type(regname, reglen) regname = may_get_selection(regname); #endif - /* Should we check for a valid name? */ + if (regname != NUL && !valid_yank_reg(regname, FALSE)) + return MAUTO; + get_yank_register(regname, FALSE); if (y_current->y_array != NULL) diff --git a/src/option.c b/src/option.c index cc23944cb6..5d835e0061 100644 --- a/src/option.c +++ b/src/option.c @@ -8999,7 +8999,7 @@ get_option_value(name, numval, stringval, opt_flags) } #endif -#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) +#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) || defined(PROTO) /* * Returns the option attributes and its value. Unlike the above function it * will return either global value or local value of the option depending on @@ -9012,7 +9012,8 @@ get_option_value(name, numval, stringval, opt_flags) * opt_type). Uses * * Returned flags: - * 0 hidden or unknown option + * 0 hidden or unknown option, also option that does not have requested + * type (see SREQ_* in vim.h) * see SOPT_* in vim.h for other flags * * Possible opt_type values: see SREQ_* in vim.h @@ -9135,6 +9136,68 @@ get_option_value_strict(name, numval, stringval, opt_type, from) return r; } + +/* + * Iterate over options. First argument is a pointer to a pointer to a structure + * inside options[] array, second is option type like in the above function. + * + * If first argument points to NULL it is assumed that iteration just started + * and caller needs the very first value. + * If first argument points to the end marker function returns NULL and sets + * first argument to NULL. + * + * Returns full option name for current option on each call. + */ + char_u * +option_iter_next(option, opt_type) + void **option; + int opt_type; +{ + struct vimoption *ret = NULL; + do + { + if (*option == NULL) + *option = (void *) options; + else if (((struct vimoption *) (*option))->fullname == NULL) + { + *option = NULL; + return NULL; + } + else + *option = (void *) (((struct vimoption *) (*option)) + 1); + + ret = ((struct vimoption *) (*option)); + + /* Hidden option */ + if (ret->var == NULL) + { + ret = NULL; + continue; + } + + switch (opt_type) + { + case SREQ_GLOBAL: + if (!(ret->indir == PV_NONE || ret->indir & PV_BOTH)) + ret = NULL; + break; + case SREQ_BUF: + if (!(ret->indir & PV_BUF)) + ret = NULL; + break; + case SREQ_WIN: + if (!(ret->indir & PV_WIN)) + ret = NULL; + break; + default: + EMSG2(_(e_intern2), "option_iter_next()"); + return NULL; + } + } + while (ret == NULL); + + return (char_u *)ret->fullname; +} #endif /* diff --git a/src/option.h b/src/option.h index 432054375a..d822f9d4c5 100644 --- a/src/option.h +++ b/src/option.h @@ -31,9 +31,9 @@ # define DFLT_EFM "%A%p^,%C%%CC-%t-%m,%Cat line number %l in file %f,%f|%l| %m" # 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" +#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 -#define DFLT_EFM "%*[^\"]\"%f\"%*\\D%l: %m,\"%f\"%*\\D%l: %m,%-G%f:%l: (Each undeclared identifier is reported only once,%-G%f:%l: for each function it appears in.),%-GIn file included from %f:%l:%c:,%-GIn file included from %f:%l:%c\\,,%-GIn file included from %f:%l:%c,%-GIn file included from %f:%l,%-G%*[ ]from %f:%l:%c,%-G%*[ ]from %f:%l:,%-G%*[ ]from %f:%l\\,,%-G%*[ ]from %f:%l,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,\"%f\"\\, line %l%*\\D%c%*[^ ] %m,%D%*\\a[%*\\d]: Entering directory `%f',%X%*\\a[%*\\d]: Leaving directory `%f',%D%*\\a: Entering directory `%f',%X%*\\a: Leaving directory `%f',%DMaking %*\\a in %f,%f|%l| %m" +#define DFLT_EFM "%*[^\"]\"%f\"%*\\D%l: %m,\"%f\"%*\\D%l: %m,%-G%f:%l: (Each undeclared identifier is reported only once,%-G%f:%l: for each function it appears in.),%-GIn file included from %f:%l:%c:,%-GIn file included from %f:%l:%c\\,,%-GIn file included from %f:%l:%c,%-GIn file included from %f:%l,%-G%*[ ]from %f:%l:%c,%-G%*[ ]from %f:%l:,%-G%*[ ]from %f:%l\\,,%-G%*[ ]from %f:%l,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,\"%f\"\\, line %l%*\\D%c%*[^ ] %m,%D%*\\a[%*\\d]: Entering directory %*[`']%f',%X%*\\a[%*\\d]: Leaving directory %*[`']%f',%D%*\\a: Entering directory %*[`']%f',%X%*\\a: Leaving directory %*[`']%f',%DMaking %*\\a in %f,%f|%l| %m" # endif # endif # endif diff --git a/src/os_dos.h b/src/os_dos.h index 17246d4f70..19748c4963 100644 --- a/src/os_dos.h +++ b/src/os_dos.h @@ -109,7 +109,7 @@ #endif #ifndef DFLT_BDIR -# define DFLT_BDIR ".,c:\\tmp,c:\\temp" /* default for 'backupdir' */ +# define DFLT_BDIR ".,$TEMP,c:\\tmp,c:\\temp" /* default for 'backupdir' */ #endif #ifndef DFLT_VDIR @@ -117,7 +117,7 @@ #endif #ifndef DFLT_DIR -# define DFLT_DIR ".,c:\\tmp,c:\\temp" /* default for 'directory' */ +# define DFLT_DIR ".,$TEMP,c:\\tmp,c:\\temp" /* default for 'directory' */ #endif #define DFLT_ERRORFILE "errors.err" diff --git a/src/os_mswin.c b/src/os_mswin.c index 95c3d17380..bf9acdbbf4 100644 --- a/src/os_mswin.c +++ b/src/os_mswin.c @@ -498,7 +498,7 @@ slash_adjust(p) } } -#if (_MSC_VER >= 1300) +#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__MINGW32__) # define OPEN_OH_ARGTYPE intptr_t #else # define OPEN_OH_ARGTYPE long @@ -617,8 +617,22 @@ vim_stat(const char *name, struct stat *stp) p = buf + strlen(buf); if (p > buf) mb_ptr_back(buf, p); + + /* Remove trailing '\\' except root path. */ if (p > buf && (*p == '\\' || *p == '/') && p[-1] != ':') *p = NUL; + + if ((buf[0] == '\\' && buf[1] == '\\') || (buf[0] == '/' && buf[1] == '/')) + { + /* UNC root path must be followed by '\\'. */ + p = vim_strpbrk(buf + 2, "\\/"); + if (p != NULL) + { + p = vim_strpbrk(p + 1, "\\/"); + if (p == NULL) + STRCAT(buf, "\\"); + } + } #ifdef FEAT_MBYTE if (enc_codepage >= 0 && (int)GetACP() != enc_codepage # ifdef __BORLANDC__ @@ -634,7 +648,7 @@ vim_stat(const char *name, struct stat *stp) { n = wstat_symlink_aware(wp, (struct _stat *)stp); vim_free(wp); - if (n >= 0) + if (n >= 0 || g_PlatformId == VER_PLATFORM_WIN32_NT) return n; /* Retry with non-wide function (for Windows 98). Can't use * GetLastError() here and it's unclear what errno gets set to if @@ -801,8 +815,8 @@ mch_chdir(char *path) { n = _wchdir(p); vim_free(p); - if (n == 0) - return 0; + if (n == 0 || g_PlatformId == VER_PLATFORM_WIN32_NT) + return n; /* Retry with non-wide function (for Windows 98). */ } } @@ -1928,8 +1942,7 @@ mch_resolve_shortcut(char_u *fname) shortcut_errorw: vim_free(p); - if (hr == S_OK) - goto shortcut_end; + goto shortcut_end; } } /* Retry with non-wide function (for Windows 98). */ diff --git a/src/os_unix.c b/src/os_unix.c index d382fe4928..412582eaed 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -168,7 +168,7 @@ typedef int waitstatus; static pid_t wait4pid __ARGS((pid_t, waitstatus *)); static int WaitForChar __ARGS((long)); -#if defined(__BEOS__) +#if defined(__BEOS__) || defined(VMS) int RealWaitForChar __ARGS((int, long, int *)); #else static int RealWaitForChar __ARGS((int, long, int *)); @@ -435,7 +435,6 @@ mch_inchar(buf, maxlen, wtime, tb_change_cnt) /* Process the queued netbeans messages. */ netbeans_parse_messages(); #endif -#ifndef VMS /* VMS: must try reading, WaitForChar() does nothing. */ /* * We want to be interrupted by the winch signal * or by an event on the monitored file descriptors. @@ -446,7 +445,6 @@ mch_inchar(buf, maxlen, wtime, tb_change_cnt) handle_resize(); return 0; } -#endif /* If input was put directly in typeahead buffer bail out here. */ if (typebuf_changed(tb_change_cnt)) @@ -5061,6 +5059,7 @@ WaitForChar(msec) return avail; } +#ifndef VMS /* * Wait "msec" msec until a character is available from file descriptor "fd". * "msec" == 0 will check for characters once. @@ -5360,13 +5359,7 @@ select_eintr: } # endif -# ifdef OLD_VMS - /* Old VMS as v6.2 and older have broken select(). It waits more than - * required. Should not be used */ - ret = 0; -# else ret = select(maxfd + 1, &rfds, NULL, &efds, tvp); -# endif # ifdef EINTR if (ret == -1 && errno == EINTR) { @@ -5488,8 +5481,6 @@ select_eintr: return (ret > 0); } -#ifndef VMS - #ifndef NO_EXPANDPATH /* * Expand a path into all matching files and/or directories. Handles "*", @@ -6012,7 +6003,7 @@ mch_expand_wildcards(num_pat, pat, num_file, file, flags) { /* If there is a NUL, set did_find_nul, else set check_spaces */ buffer[len] = NUL; - if (len && (int)STRLEN(buffer) < (int)len - 1) + if (len && (int)STRLEN(buffer) < (int)len) did_find_nul = TRUE; else check_spaces = TRUE; diff --git a/src/os_unix.h b/src/os_unix.h index 16dd9451da..26e07b1593 100644 --- a/src/os_unix.h +++ b/src/os_unix.h @@ -225,6 +225,8 @@ # include # include # include +# include +# include # ifdef FEAT_GUI_GTK # include "gui_gtk_vms.h" diff --git a/src/os_vms.c b/src/os_vms.c index 59d9810e24..24ff5d07d4 100644 --- a/src/os_vms.c +++ b/src/os_vms.c @@ -11,6 +11,23 @@ #include "vim.h" +/* define _generic_64 for use in time functions */ +#ifndef VAX +# include +#else +/* based on Alpha's gen64def.h; the file is absent on VAX */ +typedef struct _generic_64 { +# pragma __nomember_alignment + __union { /* You can treat me as... */ + /* long long is not available on VAXen */ + /* unsigned __int64 gen64$q_quadword; ...a single 64-bit value, or */ + + unsigned int gen64$l_longword [2]; /* ...two 32-bit values, or */ + unsigned short int gen64$w_word [4]; /* ...four 16-bit values */ + } gen64$r_quad_overlay; +} GENERIC_64; +#endif + typedef struct { char class; @@ -669,3 +686,92 @@ vms_remove_version(void * fname) } return ; } + +struct typeahead_st { + unsigned short numchars; + unsigned char firstchar; + unsigned char reserved0; + unsigned long reserved1; +} typeahead; + +/* + * Wait "msec" msec until a character is available from file descriptor "fd". + * "msec" == 0 will check for characters once. + * "msec" == -1 will block until a character is available. + */ + int +RealWaitForChar(fd, msec, check_for_gpm) + int fd UNUSED; /* always read from iochan */ + long msec; + int *check_for_gpm UNUSED; +{ + int status; + struct _generic_64 time_curr; + struct _generic_64 time_diff; + struct _generic_64 time_out; + unsigned int convert_operation = LIB$K_DELTA_SECONDS_F; + float sec = (float) msec / 1000; + + /* make sure the iochan is set */ + if (!iochan) + get_tty(); + + if (msec > 0) { + /* time-out specified; convert it to absolute time */ + + /* get current time (number of 100ns ticks since the VMS Epoch) */ + status = sys$gettim(&time_curr); + if (status != SS$_NORMAL) + return 0; /* error */ + + /* construct the delta time */ + status = lib$cvtf_to_internal_time( + &convert_operation, &sec, &time_diff); + if (status != LIB$_NORMAL) + return 0; /* error */ + + /* add them up */ + status = lib$add_times( + &time_curr, + &time_diff, + &time_out); + if (status != LIB$_NORMAL) + return 0; /* error */ + } + + while (TRUE) { + /* select() */ + status = sys$qiow(0, iochan, IO$_SENSEMODE | IO$M_TYPEAHDCNT, iosb, + 0, 0, &typeahead, 8, 0, 0, 0, 0); + if (status != SS$_NORMAL || (iosb[0] & 0xFFFF) != SS$_NORMAL) + return 0; /* error */ + + if (typeahead.numchars) + return 1; /* ready to read */ + + /* there's nothing to read; what now? */ + if (msec == 0) { + /* immediate time-out; return impatiently */ + return 0; + } + else if (msec < 0) { + /* no time-out; wait on indefinitely */ + continue; + } + else { + /* time-out needs to be checked */ + status = sys$gettim(&time_curr); + if (status != SS$_NORMAL) + return 0; /* error */ + + status = lib$sub_times( + &time_out, + &time_curr, + &time_diff); + if (status != LIB$_NORMAL) + return 0; /* error, incl. time_diff < 0 (i.e. time-out) */ + + /* otherwise wait some more */ + } + } +} diff --git a/src/os_win32.c b/src/os_win32.c index 413dbfa0b9..c23b791ae7 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -232,6 +232,94 @@ static int suppress_winsize = 1; /* don't fiddle with console */ static char_u *exe_path = NULL; +static BOOL win8_or_later = FALSE; + +/* + * Version of ReadConsoleInput() that works with IME. + * Works around problems on Windows 8. + */ + static BOOL +read_console_input( + HANDLE hInput, + INPUT_RECORD *lpBuffer, + DWORD nLength, + LPDWORD lpEvents) +{ + enum + { + IRSIZE = 10 + }; + static INPUT_RECORD s_irCache[IRSIZE]; + static DWORD s_dwIndex = 0; + static DWORD s_dwMax = 0; + DWORD dwEvents; + int head; + int tail; + int i; + + if (!win8_or_later) + { + if (nLength == -1) + return PeekConsoleInput(hInput, lpBuffer, 1, lpEvents); + return ReadConsoleInput(hInput, lpBuffer, 1, &dwEvents); + } + + if (s_dwMax == 0) + { + if (nLength == -1) + return PeekConsoleInput(hInput, lpBuffer, 1, lpEvents); + if (!ReadConsoleInput(hInput, s_irCache, IRSIZE, &dwEvents)) + return FALSE; + s_dwIndex = 0; + s_dwMax = dwEvents; + if (dwEvents == 0) + { + *lpEvents = 0; + return TRUE; + } + + if (s_dwMax > 1) + { + head = 0; + tail = s_dwMax - 1; + while (head != tail) + { + if (s_irCache[head].EventType == WINDOW_BUFFER_SIZE_EVENT + && s_irCache[head + 1].EventType + == WINDOW_BUFFER_SIZE_EVENT) + { + /* Remove duplicate event to avoid flicker. */ + for (i = head; i < tail; ++i) + s_irCache[i] = s_irCache[i + 1]; + --tail; + continue; + } + head++; + } + s_dwMax = tail + 1; + } + } + + *lpBuffer = s_irCache[s_dwIndex]; + if (nLength != -1 && ++s_dwIndex >= s_dwMax) + s_dwMax = 0; + *lpEvents = 1; + return TRUE; +} + +/* + * Version of PeekConsoleInput() that works with IME. + */ + static BOOL +peek_console_input( + HANDLE hInput, + INPUT_RECORD *lpBuffer, + DWORD nLength, + LPDWORD lpEvents) +{ + return read_console_input(hInput, lpBuffer, -1, lpEvents); +} + static void get_exe_name(void) { @@ -516,10 +604,10 @@ static PSETHANDLEINFORMATION pSetHandleInformation; static BOOL win32_enable_privilege(LPTSTR lpszPrivilege, BOOL bEnable) { - BOOL bResult; - LUID luid; - HANDLE hToken; - TOKEN_PRIVILEGES tokenPrivileges; + BOOL bResult; + LUID luid; + HANDLE hToken; + TOKEN_PRIVILEGES tokenPrivileges; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) @@ -563,6 +651,10 @@ PlatformId(void) g_PlatformId = ovi.dwPlatformId; + if ((ovi.dwMajorVersion == 6 && ovi.dwMinorVersion >= 2) + || ovi.dwMajorVersion > 6) + win8_or_later = TRUE; + #ifdef HAVE_ACL /* * Load the ADVAPI runtime if we are on anything @@ -1117,7 +1209,7 @@ decode_mouse_event( INPUT_RECORD ir; MOUSE_EVENT_RECORD* pmer2 = &ir.Event.MouseEvent; - PeekConsoleInput(g_hConIn, &ir, 1, &cRecords); + peek_console_input(g_hConIn, &ir, 1, &cRecords); if (cRecords == 0 || ir.EventType != MOUSE_EVENT || !(pmer2->dwButtonState & LEFT_RIGHT)) @@ -1126,7 +1218,7 @@ decode_mouse_event( { if (pmer2->dwEventFlags != MOUSE_MOVED) { - ReadConsoleInput(g_hConIn, &ir, 1, &cRecords); + read_console_input(g_hConIn, &ir, 1, &cRecords); return decode_mouse_event(pmer2); } @@ -1134,10 +1226,10 @@ decode_mouse_event( s_yOldMouse == pmer2->dwMousePosition.Y) { /* throw away spurious mouse move */ - ReadConsoleInput(g_hConIn, &ir, 1, &cRecords); + read_console_input(g_hConIn, &ir, 1, &cRecords); /* are there any more mouse events in queue? */ - PeekConsoleInput(g_hConIn, &ir, 1, &cRecords); + peek_console_input(g_hConIn, &ir, 1, &cRecords); if (cRecords==0 || ir.EventType != MOUSE_EVENT) break; @@ -1374,7 +1466,7 @@ WaitForChar(long msec) } cRecords = 0; - PeekConsoleInput(g_hConIn, &ir, 1, &cRecords); + peek_console_input(g_hConIn, &ir, 1, &cRecords); #ifdef FEAT_MBYTE_IME if (State & CMDLINE && msg_row == Rows - 1) @@ -1405,7 +1497,7 @@ WaitForChar(long msec) if (ir.Event.KeyEvent.uChar.UnicodeChar == 0 && ir.Event.KeyEvent.wVirtualKeyCode == 13) { - ReadConsoleInput(g_hConIn, &ir, 1, &cRecords); + read_console_input(g_hConIn, &ir, 1, &cRecords); continue; } #endif @@ -1414,7 +1506,7 @@ WaitForChar(long msec) return TRUE; } - ReadConsoleInput(g_hConIn, &ir, 1, &cRecords); + read_console_input(g_hConIn, &ir, 1, &cRecords); if (ir.EventType == FOCUS_EVENT) handle_focus_event(ir); @@ -1484,7 +1576,7 @@ tgetch(int *pmodifiers, char_u *pch2) return 0; # endif #endif - if (ReadConsoleInput(g_hConIn, &ir, 1, &cRecords) == 0) + if (read_console_input(g_hConIn, &ir, 1, &cRecords) == 0) { if (did_create_conin) read_error_exit(); @@ -2509,7 +2601,7 @@ fname_casew( WCHAR *porig, *porigPrev; int flen; WIN32_FIND_DATAW fb; - HANDLE hFind; + HANDLE hFind = INVALID_HANDLE_VALUE; int c; int slen; @@ -2528,8 +2620,8 @@ fname_casew( /* copy leading drive letter */ *ptrue++ = *porig++; *ptrue++ = *porig++; - *ptrue = NUL; /* in case nothing follows */ } + *ptrue = NUL; /* in case nothing follows */ while (*porig != NUL) { @@ -2673,8 +2765,8 @@ fname_case( /* copy leading drive letter */ *ptrue++ = *porig++; *ptrue++ = *porig++; - *ptrue = NUL; /* in case nothing follows */ } + *ptrue = NUL; /* in case nothing follows */ while (*porig != NUL) { @@ -2768,6 +2860,28 @@ mch_get_user_name( char szUserName[256 + 1]; /* UNLEN is 256 */ DWORD cch = sizeof szUserName; +#ifdef FEAT_MBYTE + if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) + { + WCHAR wszUserName[256 + 1]; /* UNLEN is 256 */ + DWORD wcch = sizeof(wszUserName) / sizeof(WCHAR); + + if (GetUserNameW(wszUserName, &wcch)) + { + char_u *p = utf16_to_enc(wszUserName, NULL); + + if (p != NULL) + { + vim_strncpy(s, p, len - 1); + vim_free(p); + return OK; + } + } + else if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return FAIL; + /* Retry with non-wide function (for Windows 98). */ + } +#endif if (GetUserName(szUserName, &cch)) { vim_strncpy(s, szUserName, len - 1); @@ -2788,6 +2902,28 @@ mch_get_host_name( { DWORD cch = len; +#ifdef FEAT_MBYTE + if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) + { + WCHAR wszHostName[256 + 1]; + DWORD wcch = sizeof(wszHostName) / sizeof(WCHAR); + + if (GetComputerNameW(wszHostName, &wcch)) + { + char_u *p = utf16_to_enc(wszHostName, NULL); + + if (p != NULL) + { + vim_strncpy(s, p, len - 1); + vim_free(p); + return; + } + } + else if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return; + /* Retry with non-wide function (for Windows 98). */ + } +#endif if (!GetComputerName(s, &cch)) vim_strncpy(s, "PC (Win32 Vim)", len - 1); } @@ -2834,6 +2970,8 @@ mch_dirname( return OK; } } + else if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return FAIL; /* Retry with non-wide function (for Windows 98). */ } #endif @@ -2850,11 +2988,8 @@ mch_getperm(char_u *name) struct stat st; int n; - if (name[0] == '\\' && name[1] == '\\') - /* UNC path */ - return (long)win32_getattrs(name); n = mch_stat(name, &st); - return n == 0 ? (long)st.st_mode : -1L; + return n == 0 ? (long)(unsigned short)st.st_mode : -1L; } @@ -2877,7 +3012,7 @@ mch_setperm(char_u *name, long perm) { n = _wchmod(p, perm); vim_free(p); - if (n == -1 && GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + if (n == -1 && g_PlatformId == VER_PLATFORM_WIN32_NT) return FAIL; /* Retry with non-wide function (for Windows 98). */ } @@ -3788,6 +3923,50 @@ mch_set_winsize_now(void) } #endif /* FEAT_GUI_W32 */ + static BOOL +vim_create_process( + char *cmd, + BOOL inherit_handles, + DWORD flags, + STARTUPINFO *si, + PROCESS_INFORMATION *pi) +{ +# ifdef FEAT_MBYTE + if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) + { + WCHAR *wcmd = enc_to_utf16(cmd, NULL); + + if (wcmd != NULL) + { + BOOL ret; + ret = CreateProcessW( + NULL, /* Executable name */ + wcmd, /* Command to execute */ + NULL, /* Process security attributes */ + NULL, /* Thread security attributes */ + inherit_handles, /* Inherit handles */ + flags, /* Creation flags */ + NULL, /* Environment */ + NULL, /* Current directory */ + (LPSTARTUPINFOW)si, /* Startup information */ + pi); /* Process information */ + vim_free(wcmd); + return ret; + } + } +#endif + return CreateProcess( + NULL, /* Executable name */ + cmd, /* Command to execute */ + NULL, /* Process security attributes */ + NULL, /* Thread security attributes */ + inherit_handles, /* Inherit handles */ + flags, /* Creation flags */ + NULL, /* Environment */ + NULL, /* Current directory */ + si, /* Startup information */ + pi); /* Process information */ +} #if defined(FEAT_GUI_W32) || defined(PROTO) @@ -3834,18 +4013,8 @@ mch_system_classic(char *cmd, int options) cmd += 3; /* Now, run the command */ - CreateProcess(NULL, /* Executable name */ - cmd, /* Command to execute */ - NULL, /* Process security attributes */ - NULL, /* Thread security attributes */ - FALSE, /* Inherit handles */ - CREATE_DEFAULT_ERROR_MODE | /* Creation flags */ - CREATE_NEW_CONSOLE, - NULL, /* Environment */ - NULL, /* Current directory */ - &si, /* Startup information */ - &pi); /* Process information */ - + vim_create_process(cmd, FALSE, + CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_CONSOLE, &si, &pi); /* Wait for the command to terminate before continuing */ if (g_PlatformId != VER_PLATFORM_WIN32s) @@ -4177,22 +4346,11 @@ mch_system_piped(char *cmd, int options) p = cmd; } - /* Now, run the command */ - CreateProcess(NULL, /* Executable name */ - p, /* Command to execute */ - NULL, /* Process security attributes */ - NULL, /* Thread security attributes */ - - // this command can be litigious, handle inheritance was - // deactivated for pending temp file, but, if we deactivate - // it, the pipes don't work for some reason. - TRUE, /* Inherit handles, first deactivated, - * but needed */ - CREATE_DEFAULT_ERROR_MODE, /* Creation flags */ - NULL, /* Environment */ - NULL, /* Current directory */ - &si, /* Startup information */ - &pi); /* Process information */ + /* Now, run the command. + * About "Inherit handles" being TRUE: this command can be litigious, + * handle inheritance was deactivated for pending temp file, but, if we + * deactivate it, the pipes don't work for some reason. */ + vim_create_process(p, TRUE, CREATE_DEFAULT_ERROR_MODE, &si, &pi); if (p != cmd) vim_free(p); @@ -4219,10 +4377,10 @@ mch_system_piped(char *cmd, int options) { MSG msg; - if (PeekMessage(&msg, (HWND)NULL, 0, 0, PM_REMOVE)) + if (pPeekMessage(&msg, (HWND)NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); - DispatchMessage(&msg); + pDispatchMessage(&msg); } /* write pipe information in the window */ @@ -4410,7 +4568,25 @@ mch_system(char *cmd, int options) } #else -# define mch_system(c, o) system(c) +# ifdef FEAT_MBYTE + static int +mch_system(char *cmd, int options) +{ + if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) + { + WCHAR *wcmd = enc_to_utf16(cmd, NULL); + if (wcmd != NULL) + { + int ret = _wsystem(wcmd); + vim_free(wcmd); + return ret; + } + } + return system(cmd); +} +# else +# define mch_system(c, o) system(c) +# endif #endif @@ -4495,6 +4671,7 @@ mch_call_shell( DWORD flags = CREATE_NEW_CONSOLE; char_u *p; + ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); si.lpReserved = NULL; si.lpDesktop = NULL; @@ -4578,16 +4755,7 @@ mch_call_shell( * inherit our handles which causes unpleasant dangling swap * files if we exit before the spawned process */ - if (CreateProcess(NULL, // Executable name - newcmd, // Command to execute - NULL, // Process security attributes - NULL, // Thread security attributes - FALSE, // Inherit handles - flags, // Creation flags - NULL, // Environment - NULL, // Current directory - &si, // Startup information - &pi)) // Process information + if (vim_create_process(newcmd, FALSE, flags, &si, &pi)) x = 0; else { @@ -4600,9 +4768,9 @@ mch_call_shell( if (newcmd != cmdbase) vim_free(newcmd); - if (si.hStdInput != NULL) + if (si.dwFlags == STARTF_USESTDHANDLES && si.hStdInput != NULL) { - /* Close the handle to \\.\NUL */ + /* Close the handle to \\.\NUL created above. */ CloseHandle(si.hStdInput); } /* Close the handles to the subprocess, so that it goes away */ @@ -5886,7 +6054,7 @@ mch_open(char *name, int flags, int mode) { f = _wopen(wn, flags, mode); vim_free(wn); - if (f >= 0) + if (f >= 0 || g_PlatformId == VER_PLATFORM_WIN32_NT) return f; /* Retry with non-wide function (for Windows 98). Can't use * GetLastError() here and it's unclear what errno gets set to if @@ -5937,7 +6105,7 @@ mch_fopen(char *name, char *mode) _set_fmode(oldMode); # endif - if (f != NULL) + if (f != NULL || g_PlatformId == VER_PLATFORM_WIN32_NT) return f; /* Retry with non-wide function (for Windows 98). Can't use * GetLastError() here and it's unclear what errno gets set to if @@ -6272,6 +6440,7 @@ get_cmd_argsW(char ***argvp) while (i > 0) free(argv[--i]); free(argv); + argv = NULL; argc = 0; } } diff --git a/src/proto/blowfish.pro b/src/proto/blowfish.pro index 51e4fa9ec5..4d64e10e80 100644 --- a/src/proto/blowfish.pro +++ b/src/proto/blowfish.pro @@ -1,6 +1,6 @@ /* blowfish.c */ void bf_key_init __ARGS((char_u *password, char_u *salt, int salt_len)); -void bf_ofb_init __ARGS((char_u *iv, int iv_len)); +void bf_cfb_init __ARGS((char_u *iv, int iv_len)); void bf_crypt_encode __ARGS((char_u *from, size_t len, char_u *to)); void bf_crypt_decode __ARGS((char_u *ptr, long len)); void bf_crypt_init_keys __ARGS((char_u *passwd)); diff --git a/src/proto/eval.pro b/src/proto/eval.pro index ee2da1b026..3fa265ef74 100644 --- a/src/proto/eval.pro +++ b/src/proto/eval.pro @@ -60,6 +60,7 @@ int list_append_dict __ARGS((list_T *list, dict_T *dict)); int list_append_string __ARGS((list_T *l, char_u *str, int len)); int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); +void list_insert __ARGS((list_T *l, listitem_T *ni, listitem_T *item)); int garbage_collect __ARGS((void)); void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID)); void set_ref_in_list __ARGS((list_T *l, int copyID)); diff --git a/src/proto/ex_eval.pro b/src/proto/ex_eval.pro index 8fb234283e..6c63f67240 100644 --- a/src/proto/ex_eval.pro +++ b/src/proto/ex_eval.pro @@ -4,8 +4,10 @@ void update_force_abort __ARGS((void)); int should_abort __ARGS((int retcode)); int aborted_in_try __ARGS((void)); int cause_errthrow __ARGS((char_u *mesg, int severe, int *ignore)); +void free_global_msglist __ARGS((void)); void do_errthrow __ARGS((struct condstack *cstack, char_u *cmdname)); int do_intthrow __ARGS((struct condstack *cstack)); +char_u *get_exception_string __ARGS((void *value, int type, char_u *cmdname, int *should_free)); void discard_current_exception __ARGS((void)); void report_make_pending __ARGS((int pending, void *value)); void report_resume_pending __ARGS((int pending, void *value)); diff --git a/src/proto/getchar.pro b/src/proto/getchar.pro index 371f77002c..897cad37fc 100644 --- a/src/proto/getchar.pro +++ b/src/proto/getchar.pro @@ -1,8 +1,9 @@ /* getchar.c */ -void free_buff __ARGS((struct buffheader *buf)); +void free_buff __ARGS((buffheader_T *buf)); char_u *get_recorded __ARGS((void)); char_u *get_inserted __ARGS((void)); int stuff_empty __ARGS((void)); +int readbuf1_empty __ARGS((void)); void typeahead_noflush __ARGS((int c)); void flush_buffers __ARGS((int flush_typeahead)); void ResetRedobuff __ARGS((void)); diff --git a/src/proto/option.pro b/src/proto/option.pro index cd3afbf79b..4347d65919 100644 --- a/src/proto/option.pro +++ b/src/proto/option.pro @@ -23,6 +23,7 @@ char_u *check_colorcolumn __ARGS((win_T *wp)); char_u *check_stl_option __ARGS((char_u *s)); int get_option_value __ARGS((char_u *name, long *numval, char_u **stringval, int opt_flags)); int get_option_value_strict __ARGS((char_u *name, long *numval, char_u **stringval, int opt_type, void *from)); +char_u *option_iter_next __ARGS((void **option, int opt_type)); char_u *set_option_value __ARGS((char_u *name, long number, char_u *string, int opt_flags)); char_u *get_term_code __ARGS((char_u *tname)); char_u *get_highlight_default __ARGS((void)); diff --git a/src/proto/spell.pro b/src/proto/spell.pro index 9ed775b53e..5c399b3709 100644 --- a/src/proto/spell.pro +++ b/src/proto/spell.pro @@ -3,6 +3,7 @@ int spell_check __ARGS((win_T *wp, char_u *ptr, hlf_T *attrp, int *capcol, int d int spell_move_to __ARGS((win_T *wp, int dir, int allwords, int curline, hlf_T *attrp)); void spell_cat_line __ARGS((char_u *buf, char_u *line, int maxlen)); char_u *did_set_spelllang __ARGS((win_T *wp)); +void spell_delete_wordlist __ARGS((void)); void spell_free_all __ARGS((void)); void spell_reload __ARGS((void)); int spell_check_msm __ARGS((void)); diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c index cf7694bb0b..787b34366a 100644 --- a/src/regexp_nfa.c +++ b/src/regexp_nfa.c @@ -239,7 +239,9 @@ static int nfa_classcodes[] = { NFA_UPPER, NFA_NUPPER }; +static char_u e_nul_found[] = N_("E865: (NFA) Regexp end encountered prematurely"); static char_u e_misplaced[] = N_("E866: (NFA regexp) Misplaced %c"); +static char_u e_ill_char_class[] = N_("E877: (NFA regexp) Invalid character class: %ld"); /* NFA regexp \ze operator encountered. */ static int nfa_has_zend; @@ -1137,7 +1139,7 @@ nfa_regatom() switch (c) { case NUL: - EMSG_RET_FAIL(_("E865: (NFA) Regexp end encountered prematurely")); + EMSG_RET_FAIL(_(e_nul_found)); case Magic('^'): EMIT(NFA_BOL); @@ -1160,6 +1162,9 @@ nfa_regatom() case Magic('_'): c = no_Magic(getchr()); + if (c == NUL) + EMSG_RET_FAIL(_(e_nul_found)); + if (c == '^') /* "\_^" is start-of-line */ { EMIT(NFA_BOL); @@ -1216,6 +1221,12 @@ nfa_regatom() p = vim_strchr(classchars, no_Magic(c)); if (p == NULL) { + if (extra == NFA_ADD_NL) + { + EMSGN(_(e_ill_char_class), c); + rc_did_emsg = TRUE; + return FAIL; + } EMSGN("INTERNAL: Unknown character class char: %ld", c); return FAIL; } @@ -4733,7 +4744,7 @@ check_char_class(class, c) default: /* should not be here :P */ - EMSGN("E877: (NFA regexp) Invalid character class: %ld", class); + EMSGN(_(e_ill_char_class), class); return FAIL; } return FAIL; diff --git a/src/screen.c b/src/screen.c index 98b135cbe0..29c28c568c 100644 --- a/src/screen.c +++ b/src/screen.c @@ -6664,6 +6664,7 @@ win_redr_custom(wp, draw_ruler) win_T *wp; int draw_ruler; /* TRUE or FALSE */ { + static int entered = FALSE; int attr; int curattr; int row; @@ -6682,6 +6683,13 @@ win_redr_custom(wp, draw_ruler) win_T *ewp; int p_crb_save; + /* There is a tiny chance that this gets called recursively: When + * redrawing a status line triggers redrawing the ruler or tabline. + * Avoid trouble by not allowing recursion. */ + if (entered) + return; + entered = TRUE; + /* setup environment for the task at hand */ if (wp == NULL) { @@ -6757,7 +6765,7 @@ win_redr_custom(wp, draw_ruler) } if (maxwidth <= 0) - return; + goto theend; /* Temporarily reset 'cursorbind', we don't want a side effect from moving * the cursor away and back. */ @@ -6838,6 +6846,9 @@ win_redr_custom(wp, draw_ruler) while (col < Columns) TabPageIdxs[col++] = fillchar; } + +theend: + entered = FALSE; } #endif /* FEAT_STL_OPT */ diff --git a/src/search.c b/src/search.c index efd63c135e..28ea33ae7d 100644 --- a/src/search.c +++ b/src/search.c @@ -201,7 +201,7 @@ search_regcomp(pat, pat_save, pat_use, options, regmatch) * Save the currently used pattern in the appropriate place, * unless the pattern should not be remembered. */ - if (!(options & SEARCH_KEEP)) + if (!(options & SEARCH_KEEP) && !cmdmod.keeppatterns) { /* search or global command */ if (pat_save == RE_SEARCH || pat_save == RE_BOTH) @@ -1446,7 +1446,7 @@ do_search(oap, dirc, pat, count, options, tm) curwin->w_set_curswant = TRUE; end_do_search: - if (options & SEARCH_KEEP) + if ((options & SEARCH_KEEP) || cmdmod.keeppatterns) spats[0].off = old_off; vim_free(strcopy); @@ -4553,7 +4553,10 @@ current_search(count, forward) /* Is the pattern is zero-width? */ one_char = is_one_char(spats[last_idx].pat); if (one_char == -1) - return FAIL; /* invalid pattern */ + { + p_ws = old_p_ws; + return FAIL; /* pattern not found */ + } /* * The trick is to first search backwards and then search forward again, diff --git a/src/spell.c b/src/spell.c index 18a39570d8..66ccecb07a 100644 --- a/src/spell.c +++ b/src/spell.c @@ -2180,9 +2180,9 @@ spell_move_to(wp, dir, allwords, curline, attrp) char_u *endp; hlf_T attr; int len; -# ifdef FEAT_SYN_HL +#ifdef FEAT_SYN_HL int has_syntax = syntax_present(wp); -# endif +#endif int col; int can_spell; char_u *buf = NULL; @@ -2280,7 +2280,7 @@ spell_move_to(wp, dir, allwords, curline, attrp) : p - buf) > wp->w_cursor.col))) { -# ifdef FEAT_SYN_HL +#ifdef FEAT_SYN_HL if (has_syntax) { col = (int)(p - buf); @@ -4701,7 +4701,25 @@ badword_captype(word, end) return flags; } -# if defined(FEAT_MBYTE) || defined(EXITFREE) || defined(PROTO) +/* + * Delete the internal wordlist and its .spl file. + */ + void +spell_delete_wordlist() +{ + char_u fname[MAXPATHL]; + + if (int_wordlist != NULL) + { + mch_remove(int_wordlist); + int_wordlist_spl(fname); + mch_remove(fname); + vim_free(int_wordlist); + int_wordlist = NULL; + } +} + +#if defined(FEAT_MBYTE) || defined(EXITFREE) || defined(PROTO) /* * Free all languages. */ @@ -4710,7 +4728,6 @@ spell_free_all() { slang_T *slang; buf_T *buf; - char_u fname[MAXPATHL]; /* Go through all buffers and handle 'spelllang'. */ for (buf = firstbuf; buf != NULL; buf = buf->b_next) @@ -4723,24 +4740,16 @@ spell_free_all() slang_free(slang); } - if (int_wordlist != NULL) - { - /* Delete the internal wordlist and its .spl file */ - mch_remove(int_wordlist); - int_wordlist_spl(fname); - mch_remove(fname); - vim_free(int_wordlist); - int_wordlist = NULL; - } + spell_delete_wordlist(); vim_free(repl_to); repl_to = NULL; vim_free(repl_from); repl_from = NULL; } -# endif +#endif -# if defined(FEAT_MBYTE) || defined(PROTO) +#if defined(FEAT_MBYTE) || defined(PROTO) /* * Clear all spelling tables and reload them. * Used after 'encoding' is set and when ":mkspell" was used. @@ -4773,7 +4782,7 @@ spell_reload() } } } -# endif +#endif /* * Reload the spell file "fname" if it's loaded. diff --git a/src/structs.h b/src/structs.h index a657302eb6..c437c58648 100644 --- a/src/structs.h +++ b/src/structs.h @@ -471,13 +471,17 @@ struct nr_trans blocknr_T nt_new_bnum; /* new, positive, number */ }; + +typedef struct buffblock buffblock_T; +typedef struct buffheader buffheader_T; + /* * structure used to store one block of the stuff/redo/recording buffers */ struct buffblock { - struct buffblock *b_next; /* pointer to next buffblock */ - char_u b_str[1]; /* contents (actually longer) */ + buffblock_T *b_next; /* pointer to next buffblock */ + char_u b_str[1]; /* contents (actually longer) */ }; /* @@ -485,10 +489,10 @@ struct buffblock */ struct buffheader { - struct buffblock bh_first; /* first (dummy) block of list */ - struct buffblock *bh_curr; /* buffblock for appending */ - int bh_index; /* index for reading */ - int bh_space; /* space in bh_curr for appending */ + buffblock_T bh_first; /* first (dummy) block of list */ + buffblock_T *bh_curr; /* buffblock for appending */ + int bh_index; /* index for reading */ + int bh_space; /* space in bh_curr for appending */ }; /* @@ -964,7 +968,8 @@ typedef struct int typebuf_valid; /* TRUE when save_typebuf valid */ int old_char; int old_mod_mask; - struct buffheader save_stuffbuff; + buffheader_T save_readbuf1; + buffheader_T save_readbuf2; #ifdef USE_INPUT_BUF char_u *save_inputbuf; #endif diff --git a/src/syntax.c b/src/syntax.c index a715bdc2fb..0fd2a76cff 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -7071,7 +7071,7 @@ load_colors(name) retval = source_runtime(buf, FALSE); vim_free(buf); #ifdef FEAT_AUTOCMD - apply_autocmds(EVENT_COLORSCHEME, NULL, NULL, FALSE, curbuf); + apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, FALSE, curbuf); #endif } recursive = FALSE; diff --git a/src/tag.c b/src/tag.c index e7ea52a293..be80a11651 100644 --- a/src/tag.c +++ b/src/tag.c @@ -1326,6 +1326,7 @@ find_tags(pat, num_matches, matchesp, flags, mincount, buf_ffname) int match_no_ic = 0;/* matches with rm_ic == FALSE */ int match_re; /* match with regexp */ int matchoff = 0; + int save_emsg_off; #ifdef FEAT_EMACS_TAGS /* @@ -1442,7 +1443,10 @@ find_tags(pat, num_matches, matchesp, flags, mincount, buf_ffname) if (p_tl != 0 && orgpat.len > p_tl) /* adjust for 'taglength' */ orgpat.len = p_tl; + save_emsg_off = emsg_off; + emsg_off = TRUE; /* don't want error for invalid RE here */ prepare_pats(&orgpat, has_re); + emsg_off = save_emsg_off; if (has_re && orgpat.regmatch.regprog == NULL) goto findtag_end; diff --git a/src/testdir/Make_amiga.mak b/src/testdir/Make_amiga.mak index 0fd1e86891..e76ecb07d1 100644 --- a/src/testdir/Make_amiga.mak +++ b/src/testdir/Make_amiga.mak @@ -34,7 +34,8 @@ SCRIPTS = test1.out test3.out test4.out test5.out test6.out \ test81.out test82.out test83.out test84.out test88.out \ test89.out test90.out test91.out test92.out test93.out \ test94.out test95.out test96.out test97.out test98.out \ - test99.out test100.out test101.out test102.out test103.out + test99.out test100.out test101.out test102.out test103.out \ + test104.out .SUFFIXES: .in .out @@ -154,3 +155,4 @@ test100.out: test100.in test101.out: test101.in test102.out: test102.in test103.out: test103.in +test104.out: test104.in diff --git a/src/testdir/Make_dos.mak b/src/testdir/Make_dos.mak index 05e1422470..5855359853 100644 --- a/src/testdir/Make_dos.mak +++ b/src/testdir/Make_dos.mak @@ -33,7 +33,7 @@ SCRIPTS = test3.out test4.out test5.out test6.out test7.out \ test84.out test85.out test86.out test87.out test88.out \ test89.out test90.out test91.out test92.out test93.out \ test94.out test95.out test96.out test98.out test99.out \ - test100.out test101.out test102.out test103.out + test100.out test101.out test102.out test103.out test104.out SCRIPTS32 = test50.out test70.out diff --git a/src/testdir/Make_ming.mak b/src/testdir/Make_ming.mak index da6d5e8dc7..4b93279777 100644 --- a/src/testdir/Make_ming.mak +++ b/src/testdir/Make_ming.mak @@ -53,7 +53,7 @@ SCRIPTS = test3.out test4.out test5.out test6.out test7.out \ test84.out test85.out test86.out test87.out test88.out \ test89.out test90.out test91.out test92.out test93.out \ test94.out test95.out test96.out test98.out test99.out \ - test100out test101.out test102.out test103.out + test100.out test101.out test102.out test103.out test104.out SCRIPTS32 = test50.out test70.out diff --git a/src/testdir/Make_os2.mak b/src/testdir/Make_os2.mak index 7af826d361..7e37df70b1 100644 --- a/src/testdir/Make_os2.mak +++ b/src/testdir/Make_os2.mak @@ -35,7 +35,7 @@ SCRIPTS = test1.out test3.out test4.out test5.out test6.out \ test81.out test82.out test83.out test84.out test88.out \ test89.out test90.out test91.out test92.out test93.out \ test94.out test95.out test96.out test98.out test99.out \ - test100.out test101.out test102.out test103.out + test100.out test101.out test102.out test103.out test104.out .SUFFIXES: .in .out diff --git a/src/testdir/Make_vms.mms b/src/testdir/Make_vms.mms index 370406145e..f3483da437 100644 --- a/src/testdir/Make_vms.mms +++ b/src/testdir/Make_vms.mms @@ -79,7 +79,7 @@ SCRIPT = test1.out test2.out test3.out test4.out test5.out \ test82.out test83.out test84.out test88.out test89.out \ test90.out test91.out test92.out test93.out test94.out \ test95.out test96.out test97.out test98.out test99.out \ - test100.out test101.out test102.out test103.out + test100.out test101.out test102.out test103.out test104.out # Known problems: # Test 30: a problem around mac format - unknown reason diff --git a/src/testdir/Makefile b/src/testdir/Makefile index bae4f44ff1..bd298369c5 100644 --- a/src/testdir/Makefile +++ b/src/testdir/Makefile @@ -30,7 +30,8 @@ SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \ test84.out test85.out test86.out test87.out test88.out \ test89.out test90.out test91.out test92.out test93.out \ test94.out test95.out test96.out test97.out test98.out \ - test99.out test100.out test101.out test102.out test103.out + test99.out test100.out test101.out test102.out test103.out \ + test104.out SCRIPTS_GUI = test16.out diff --git a/src/testdir/sautest/autoload/Test104.vim b/src/testdir/sautest/autoload/Test104.vim new file mode 100644 index 0000000000..d1e0e17a3b --- /dev/null +++ b/src/testdir/sautest/autoload/Test104.vim @@ -0,0 +1 @@ +let Test104#numvar = 123 diff --git a/src/testdir/sautest/autoload/footest.vim b/src/testdir/sautest/autoload/footest.vim new file mode 100644 index 0000000000..f467bc376d --- /dev/null +++ b/src/testdir/sautest/autoload/footest.vim @@ -0,0 +1,5 @@ +" Autoload script used by test55 and test60 +let footest#x = 1 +func footest#F() + return 0 +endfunc diff --git a/src/testdir/test104.in b/src/testdir/test104.in new file mode 100644 index 0000000000..f329d2dbed --- /dev/null +++ b/src/testdir/test104.in @@ -0,0 +1,16 @@ +Tests for autoload. vim: set ft=vim ts=8 : + +STARTTEST +:so small.vim +:set runtimepath+=./sautest +:" Test to not autoload when assigning. It causes internal error. +:try +: let Test104#numvar = function('tr') +: $put ='OK: ' . string(Test104#numvar) +:catch +: $put ='FAIL: ' . v:exception +:endtry +:/^Results/,$wq! test.out +ENDTEST + +Results of test104: diff --git a/src/testdir/test104.ok b/src/testdir/test104.ok new file mode 100644 index 0000000000..5c16509af9 --- /dev/null +++ b/src/testdir/test104.ok @@ -0,0 +1,2 @@ +Results of test104: +OK: function('tr') diff --git a/src/testdir/test14.in b/src/testdir/test14.in index ebcb58c9d0..fb987ebc88 100644 --- a/src/testdir/test14.in +++ b/src/testdir/test14.in @@ -47,7 +47,19 @@ j:call search('^$', 'c') /two :call search('.', 'c') :call append(line('$'), getline('.')[col('.') - 1:]) -:/^search()/,$w >>test.out +:" +/^substitute +:s/foo/bar/ +:$put =@/ +/^substitute +:keeppatterns s/asdf/xyz/ +:$put =@/ +/^substitute +Y:$put =@0 +/bar /e +:$put =@0 +-:keeppatterns /xyz +0dn:/^search()/,$w >>test.out :qa! ENDTEST @@ -81,6 +93,7 @@ Piece of Java foobar +substitute foo asdf one two search() diff --git a/src/testdir/test14.ok b/src/testdir/test14.ok index 1fd89165e1..0aa2db3f97 100644 --- a/src/testdir/test14.ok +++ b/src/testdir/test14.ok @@ -20,3 +20,7 @@ search() 1 1 two +foo +^substitute +substitute bar xyz +xyz diff --git a/src/testdir/test37.ok b/src/testdir/test37.ok index a9092a402c..d0b74853b3 100644 --- a/src/testdir/test37.ok +++ b/src/testdir/test37.ok @@ -27,7 +27,7 @@ UTSRQPONMLKJIHGREDCBA9876543210 02 . line 16 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 16 :set scrollbind -zt: -. line 15 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 15 :set scrollbind -. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11 +. line 16 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 16 +j: +. line 12 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 12 diff --git a/src/testdir/test39.in b/src/testdir/test39.in index 4f42a13a5e..8f45f47dc3 100644 --- a/src/testdir/test39.in +++ b/src/testdir/test39.in @@ -52,6 +52,12 @@ ddppi333k0i222fyllvjfuUk G3o1234567892k05l2jr G3o987652k02l2jr G3o1234567892k05l2jr G3o987652k02l2jr +:" +:" Test cursor position. When ve=block and Visual block mode and $gj +:set ve=block +:exe ":norm! 2k\$gj\" +:let cpos=getpos("'>") +:$put ='col:'.cpos[2].' off:'.cpos[3] :/^the/,$w >> test.out :qa! ENDTEST diff --git a/src/testdir/test39.ok b/src/testdir/test39.ok index 3469f52b65..b459355c6a 100644 Binary files a/src/testdir/test39.ok and b/src/testdir/test39.ok differ diff --git a/src/testdir/test55.in b/src/testdir/test55.in index 991c4605c0..4b20de403f 100644 --- a/src/testdir/test55.in +++ b/src/testdir/test55.in @@ -282,6 +282,13 @@ let l = [0, 1, 2, 3] : $put =ps : endfor :endfor +:" :lockvar/islocked() triggering script autoloading +:set rtp+=./sautest +:lockvar g:footest#x +:unlockvar g:footest#x +:$put ='locked g:footest#x:'.islocked('g:footest#x') +:$put ='exists g:footest#x:'.exists('g:footest#x') +:$put ='g:footest#x: '.g:footest#x :" :" a:000 function argument :" first the tests that should fail diff --git a/src/testdir/test55.ok b/src/testdir/test55.ok index 7375007a70..396c9bed19 100644 --- a/src/testdir/test55.ok +++ b/src/testdir/test55.ok @@ -86,6 +86,9 @@ FFFFFFF FFpFFpp 0000-000 ppppppp +locked g:footest#x:-1 +exists g:footest#x:0 +g:footest#x: 1 caught a:000 caught a:000[0] caught a:000[2] diff --git a/src/testdir/test60.in b/src/testdir/test60.in index 3a5b73ee6e..0f30142dcf 100644 --- a/src/testdir/test60.in +++ b/src/testdir/test60.in @@ -1,4 +1,4 @@ -Tests for the exists() function. vim: set ft=vim : +Tests for the exists() function. vim: set ft=vim ts=8 : STARTTEST :so small.vim @@ -11,8 +11,10 @@ STARTTEST endfunction :function! TestExists() augroup myagroup - autocmd! BufEnter *.my echo 'myfile edited' + autocmd! BufEnter *.my echo "myfile edited" + autocmd! FuncUndefined UndefFun exec "fu UndefFun()\nendfu" augroup END + set rtp+=./sautest let test_cases = [] @@ -95,10 +97,15 @@ endfunction " Non-existing user defined function let test_cases += [['*MyxyzFunc', 0]] + " Function that may be created by FuncUndefined event + let test_cases += [['*UndefFun', 0]] + " Function that may be created by script autoloading + let test_cases += [['*footest#F', 0]] + redir! > test.out for [test_case, result] in test_cases - echo test_case . ": " . result + echo test_case . ": " . result call RunTest(test_case, result) endfor @@ -207,6 +214,14 @@ endfunction echo "FAILED" endif + " Non-existing autoload variable that may be autoloaded + echo 'footest#x: 0' + if !exists('footest#x') + echo "OK" + else + echo "FAILED" + endif + " Valid local list let local_list = ["blue", "orange"] echo 'local_list: 1' @@ -566,6 +581,10 @@ endfunction call TestFuncArg("arg1", "arg2") + echo ' g:footest#x =' g:footest#x + echo ' footest#F()' footest#F() + echo 'UndefFun()' UndefFun() + redir END endfunction :call TestExists() @@ -576,5 +595,6 @@ endfunction :set ff=unix :w :qa! +:while getchar(1) | call getchar() | endwhile ENDTEST diff --git a/src/testdir/test60.ok b/src/testdir/test60.ok index 10dc579dbe..0c382ad281 100644 --- a/src/testdir/test60.ok +++ b/src/testdir/test60.ok @@ -71,6 +71,10 @@ OK OK *MyxyzFunc: 0 OK +*UndefFun: 0 +OK +*footest#F: 0 +OK :edit: 2 OK :edit/a: 0 @@ -95,6 +99,8 @@ local_var%n: 0 OK local_var: 0 OK +footest#x: 0 +OK local_list: 1 OK local_list[1]: 1 @@ -195,3 +201,6 @@ a:1: 1 OK a:2: 0 OK + g:footest#x = 1 + footest#F() 0 +UndefFun() 0 diff --git a/src/testdir/test80.in b/src/testdir/test80.in index 5491a90092..c62fdc02b2 100644 --- a/src/testdir/test80.in +++ b/src/testdir/test80.in @@ -175,6 +175,23 @@ ENDTEST TEST_10: +STARTTEST +:set magic& +:set cpo& +:$put =\"\n\nTEST_10:\" +:let y = substitute('123', '\zs', 'a', 'g') | $put =y +:let y = substitute('123', '\zs.', 'a', 'g') | $put =y +:let y = substitute('123', '.\zs', 'a', 'g') | $put =y +:let y = substitute('123', '\ze', 'a', 'g') | $put =y +:let y = substitute('123', '\ze.', 'a', 'g') | $put =y +:let y = substitute('123', '.\ze', 'a', 'g') | $put =y +:let y = substitute('123', '1\|\ze', 'a', 'g') | $put =y +:let y = substitute('123', '1\zs\|[23]', 'a', 'g') | $put =y +/^TEST_11 +ENDTEST + +TEST_11: + STARTTEST :/^Results/,$wq! test.out ENDTEST diff --git a/src/testdir/test80.ok b/src/testdir/test80.ok index 562bbf249c..2b79d377a7 100644 --- a/src/testdir/test80.ok +++ b/src/testdir/test80.ok @@ -115,3 +115,14 @@ N,,NZ TEST_9: XXx + + +TEST_10: +a1a2a3a +aaa +1a2a3a +a1a2a3a +a1a2a3 +aaa +aa2a3a +1aaa diff --git a/src/testdir/test86.in b/src/testdir/test86.in index 91f771dcf0..ab5541faf2 100644 --- a/src/testdir/test86.in +++ b/src/testdir/test86.in @@ -39,6 +39,7 @@ STARTTEST py << EOF d=vim.bindeval('d') d['1']='asd' +d.update() # Must not do anything, including throwing errors d.update(b=[1, 2, f]) d.update((('-1', {'a': 1}),)) d.update({'0': -1}) @@ -135,6 +136,18 @@ EOF :py l=vim.bindeval('l') :py del l[-6:2] :$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py del l[::2] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py del l[3:0:-2] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py del l[2:4:-2] +:$put =string(l) :" :" Slice assignment to a list :let l = [0, 1, 2, 3] @@ -169,6 +182,26 @@ EOF :py l=vim.bindeval('l') :py l[0:0]=['h'] :$put =string(l) +:let l = range(8) +:py l=vim.bindeval('l') +:py l[2:6:2] = [10, 20] +:$put =string(l) +:let l = range(8) +:py l=vim.bindeval('l') +:py l[6:2:-2] = [10, 20] +:$put =string(l) +:let l = range(8) +:py l=vim.bindeval('l') +:py l[6:2] = () +:$put =string(l) +:let l = range(8) +:py l=vim.bindeval('l') +:py l[6:2:1] = () +:$put =string(l) +:let l = range(8) +:py l=vim.bindeval('l') +:py l[2:2:1] = () +:$put =string(l) :" :" Locked variables :let l = [0, 1, 2, 3] @@ -179,6 +212,32 @@ EOF :unlockvar! l :" :" Function calls +py << EOF +import sys +def ee(expr, g=globals(), l=locals()): + try: + exec(expr, g, l) + except: + ei = sys.exc_info() + msg = sys.exc_info()[0].__name__ + ':' + repr(sys.exc_info()[1].args) + msg = msg.replace('TypeError:(\'argument 1 ', 'TypeError:(\'') + if expr.find('None') > -1: + msg = msg.replace('TypeError:(\'iteration over non-sequence\',)', + 'TypeError:("\'NoneType\' object is not iterable",)') + if expr.find('FailingNumber') > -1: + msg = msg.replace(', not \'FailingNumber\'', '').replace('"', '\'') + msg = msg.replace('TypeError:(\'iteration over non-sequence\',)', + 'TypeError:("\'FailingNumber\' object is not iterable",)') + if msg.find('(\'\'') > -1 or msg.find('(\'can\'t') > -1: + msg = msg.replace('(\'', '("').replace('\',)', '",)') + if expr == 'fd(self=[])': + # HACK: PyMapping_Check changed meaning + msg = msg.replace('AttributeError:(\'keys\',)', + 'TypeError:(\'unable to convert list to vim dictionary\',)') + vim.current.buffer.append(expr + ':' + msg) + else: + vim.current.buffer.append(expr + ':NOT FAILED') +EOF :fun New(...) : return ['NewStart']+a:000+['NewEnd'] :endfun @@ -193,18 +252,10 @@ EOF :$put =string(l) :py l.extend([l[0].name]) :$put =string(l) -:try -: py l[1](1, 2, 3) -:catch -: $put =v:exception[:16] -:endtry +:py ee('l[1](1, 2, 3)') :py f=l[0] :delfunction New -:try -: py f(1, 2, 3) -:catch -: $put =v:exception[:16] -:endtry +:py ee('f(1, 2, 3)') :if has('float') : let l=[0.0] : py l=vim.bindeval('l') @@ -216,7 +267,6 @@ EOF :let messages=[] :delfunction DictNew py < 8 # check if the background thread is working :py del time :py del threading +:py del t :$put =string(l) :" :" settrace @@ -372,6 +423,13 @@ EOF :$put =string(pyeval('l')) :py l = ll[-10:10] :$put =string(pyeval('l')) +:py l = ll[4:2:-1] +:$put =string(pyeval('l')) +:py l = ll[::2] +:$put =string(pyeval('l')) +:py l = ll[4:2:1] +:$put =string(pyeval('l')) +:py del l :" :" Vars :let g:foo = 'bac' @@ -449,6 +507,11 @@ EOF :py bopts1=vim.buffers[vim.bindeval("g:bufs")[2]].options :py bopts2=vim.buffers[vim.bindeval("g:bufs")[1]].options :py bopts3=vim.buffers[vim.bindeval("g:bufs")[0]].options +:$put ='wopts iters equal: '.pyeval('list(wopts1) == list(wopts2)') +:$put ='bopts iters equal: '.pyeval('list(bopts1) == list(bopts2)') +:py gset=set(iter(gopts1)) +:py wset=set(iter(wopts1)) +:py bset=set(iter(bopts1)) :set path=.,..,, :let lst=[] :let lst+=[['paste', 1, 0, 1, 2, 1, 1, 0 ]] @@ -479,6 +542,8 @@ EOF : py oval3=bool(oval3) : endif : put ='>>> '.oname +: $put =' g/w/b:'.pyeval('oname in gset').'/'.pyeval('oname in wset').'/'.pyeval('oname in bset') +: $put =' g/w/b (in):'.pyeval('oname in gopts1').'/'.pyeval('oname in wopts1').'/'.pyeval('oname in bopts1') : for v in ['gopts1', 'wopts1', 'bopts1'] : try : put =' p/'.v.': '.Ev('repr('.v.'['''.oname.'''])') @@ -882,29 +947,6 @@ EOF :fun D() :endfun py << EOF -def ee(expr, g=globals(), l=locals()): - try: - exec(expr, g, l) - except: - ei = sys.exc_info() - msg = sys.exc_info()[0].__name__ + ':' + repr(sys.exc_info()[1].args) - msg = msg.replace('TypeError:(\'argument 1 ', 'TypeError:(\'') - if expr.find('None') > -1: - msg = msg.replace('TypeError:(\'iteration over non-sequence\',)', - 'TypeError:("\'NoneType\' object is not iterable",)') - if expr.find('FailingNumber') > -1: - msg = msg.replace(', not \'FailingNumber\'', '').replace('"', '\'') - msg = msg.replace('TypeError:(\'iteration over non-sequence\',)', - 'TypeError:("\'FailingNumber\' object is not iterable",)') - if msg.find('(\'\'') > -1 or msg.find('(\'can\'t') > -1: - msg = msg.replace('(\'', '("').replace('\',)', '",)') - if expr == 'fd(self=[])': - # HACK: PyMapping_Check changed meaning - msg = msg.replace('AttributeError:(\'keys\',)', - 'TypeError:(\'unable to convert list to vim dictionary\',)') - cb.append(expr + ':' + msg) - else: - cb.append(expr + ':NOT FAILED') d = vim.Dictionary() ned = vim.Dictionary(foo='bar', baz='abcD') dl = vim.Dictionary(a=1) @@ -912,6 +954,7 @@ dl.locked = True l = vim.List() ll = vim.List('abcE') ll.locked = True +nel = vim.List('abcO') f = vim.Function('string') fd = vim.Function('F') fdel = vim.Function('D') @@ -999,6 +1042,20 @@ class FailingIterNext(object): def next(self): raise NotImplementedError('next') +class FailingIterNextN(object): + def __init__(self, n): + self.n = n + + def __iter__(self): + return self + + def next(self): + if self.n: + self.n -= 1 + return 1 + else: + raise NotImplementedError('next N') + class FailingMappingKey(object): def __getitem__(self, item): raise NotImplementedError('getitem:mappingkey') @@ -1073,6 +1130,13 @@ ee('import failing_import') ee('import failing') vim.options['rtp'] = old_rtp del old_rtp +cb.append("> Options") +cb.append(">> OptionsItem") +ee('vim.options["abcQ"]') +ee('vim.options[""]') +stringtochars_test('vim.options[%s]') +cb.append(">> OptionsContains") +stringtochars_test('%s in vim.options') cb.append("> Dictionary") cb.append(">> DictionaryConstructor") ee('vim.Dictionary("abcI")') @@ -1103,6 +1167,7 @@ cb.append(">>> kwargs") cb.append(">>> iter") ee('d.update(FailingMapping())') ee('d.update([FailingIterNext()])') +ee('d.update([FailingIterNextN(1)])') iter_test('d.update(%s)') convertfrompyobject_test('d.update(%s)') stringtochars_test('d.update(((%s, 0),))') @@ -1125,6 +1190,14 @@ ee('l[1000] = 3') cb.append(">> ListAssSlice") ee('ll[1:100] = "abcJ"') iter_test('l[:] = %s') +ee('nel[1:10:2] = "abcK"') +cb.append(repr(tuple(nel))) +ee('nel[1:10:2] = "a"') +cb.append(repr(tuple(nel))) +ee('nel[1:1:-1] = "a"') +cb.append(repr(tuple(nel))) +ee('nel[:] = FailingIterNextN(2)') +cb.append(repr(tuple(nel))) convertfrompyobject_test('l[:] = [%s]') cb.append(">> ListConcatInPlace") iter_test('l.extend(%s)') @@ -1206,6 +1279,7 @@ del ned del dl del l del ll +del nel del f del fd del fdel @@ -1219,6 +1293,7 @@ del number_test del FailingTrue del FailingIter del FailingIterNext +del FailingIterNextN del FailingMapping del FailingMappingKey del FailingList @@ -1276,6 +1351,7 @@ ee('Exe("throw \'def\'")') ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")') ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")') ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")') +ee('vim.eval("xxx_unknown_function_xxx()")') ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")') del Exe EOF diff --git a/src/testdir/test86.ok b/src/testdir/test86.ok index 2d5b1619e9..257a5ee4cd 100644 --- a/src/testdir/test86.ok +++ b/src/testdir/test86.ok @@ -41,6 +41,9 @@ None [2, 3] [2, 3] [2, 3] +[1, 3] +[0, 2] +[0, 1, 2, 3] ['a', 0, 1, 2, 3] [0, 'b', 2, 3] [0, 1, 'c'] @@ -49,12 +52,17 @@ None ['f', 2, 3] [0, 1, 'g', 2, 3] ['h'] +[0, 1, 10, 3, 20, 5, 6, 7] +[0, 1, 2, 3, 20, 5, 10, 7] +[0, 1, 2, 3, 4, 5, 6, 7] +[0, 1, 2, 3, 4, 5, 6, 7] +[0, 1, 2, 3, 4, 5, 6, 7] [0, 1, 2, 3] [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd'] [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}] [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}, 'New'] -Vim(python):E725: -Vim(python):E117: +l[1](1, 2, 3):error:('Vim:E725: Calling dict function without Dictionary: DictNew',) +f(1, 2, 3):error:('Vim:E117: Unknown function: New',) [0.0, 0.0] KeyError TypeError @@ -96,12 +104,19 @@ vim: Vim(let):E859: [0, 1, 2, 3, 4, 5] [0, 1, 2, 3, 4, 5] [0, 1, 2, 3, 4, 5] +[4, 3] +[0, 2, 4] +[] Abc bac def bar jkl +wopts iters equal: 1 +bopts iters equal: 1 >>> paste + g/w/b:1/0/0 + g/w/b (in):1/0/0 p/gopts1: False p/wopts1! KeyError inv: 2! KeyError @@ -122,6 +137,8 @@ jkl W: 1:1 2:1 3:1 4:1 B: 1:1 2:1 3:1 4:1 >>> previewheight + g/w/b:1/0/0 + g/w/b (in):1/0/0 p/gopts1: 12 inv: 'a'! TypeError p/wopts1! KeyError @@ -143,6 +160,8 @@ jkl W: 1:5 2:5 3:5 4:5 B: 1:5 2:5 3:5 4:5 >>> operatorfunc + g/w/b:1/0/0 + g/w/b (in):1/0/0 p/gopts1: '' inv: 2! TypeError p/wopts1! KeyError @@ -164,6 +183,8 @@ jkl W: 1:'A' 2:'A' 3:'A' 4:'A' B: 1:'A' 2:'A' 3:'A' 4:'A' >>> number + g/w/b:0/1/0 + g/w/b (in):0/1/0 p/gopts1! KeyError inv: 0! KeyError gopts1! KeyError @@ -182,6 +203,8 @@ jkl W: 1:1 2:1 3:0 4:0 B: 1:1 2:1 3:0 4:0 >>> numberwidth + g/w/b:0/1/0 + g/w/b (in):0/1/0 p/gopts1! KeyError inv: -100! KeyError gopts1! KeyError @@ -201,6 +224,8 @@ jkl W: 1:3 2:5 3:2 4:8 B: 1:3 2:5 3:2 4:8 >>> colorcolumn + g/w/b:0/1/0 + g/w/b (in):0/1/0 p/gopts1! KeyError inv: 'abc4'! KeyError gopts1! KeyError @@ -220,6 +245,8 @@ jkl W: 1:'+2' 2:'+3' 3:'+1' 4:'' B: 1:'+2' 2:'+3' 3:'+1' 4:'' >>> statusline + g/w/b:1/1/0 + g/w/b (in):1/1/0 p/gopts1: '' inv: 0! TypeError p/wopts1: None @@ -237,6 +264,8 @@ jkl W: 1:'2' 2:'1' 3:'1' 4:'1' B: 1:'2' 2:'1' 3:'1' 4:'1' >>> autoindent + g/w/b:0/0/1 + g/w/b (in):0/0/1 p/gopts1! KeyError inv: 2! KeyError gopts1! KeyError @@ -255,6 +284,8 @@ jkl W: 1:0 2:1 3:0 4:1 B: 1:0 2:1 3:0 4:1 >>> shiftwidth + g/w/b:0/0/1 + g/w/b (in):0/0/1 p/gopts1! KeyError inv: 3! KeyError gopts1! KeyError @@ -273,6 +304,8 @@ jkl W: 1:0 2:2 3:8 4:1 B: 1:0 2:2 3:8 4:1 >>> omnifunc + g/w/b:0/0/1 + g/w/b (in):0/0/1 p/gopts1! KeyError inv: 1! KeyError gopts1! KeyError @@ -292,6 +325,8 @@ jkl W: 1:'A' 2:'B' 3:'' 4:'C' B: 1:'A' 2:'B' 3:'' 4:'C' >>> preserveindent + g/w/b:0/0/1 + g/w/b (in):0/0/1 p/gopts1! KeyError inv: 2! KeyError gopts1! KeyError @@ -310,6 +345,8 @@ jkl W: 1:0 2:1 3:0 4:1 B: 1:0 2:1 3:0 4:1 >>> path + g/w/b:1/0/1 + g/w/b (in):1/0/1 p/gopts1: '.,..,,' inv: 0! TypeError p/wopts1! KeyError @@ -498,6 +535,21 @@ vim.foreach_rtp(int, 2):TypeError:('foreach_rtp() takes exactly one argument (2 import xxx_no_such_module_xxx:ImportError:('No module named xxx_no_such_module_xxx',) import failing_import:ImportError:('No module named failing_import',) import failing:NotImplementedError:() +> Options +>> OptionsItem +vim.options["abcQ"]:KeyError:('abcQ',) +vim.options[""]:ValueError:('empty keys are not allowed',) +>>> Testing StringToChars using vim.options[%s] +vim.options[1]:TypeError:('expected str() or unicode() instance, but got int',) +vim.options[u"\0"]:TypeError:('expected string without null bytes',) +vim.options["\0"]:TypeError:('expected string without null bytes',) +<<< Finished +>> OptionsContains +>>> Testing StringToChars using %s in vim.options +1 in vim.options:TypeError:('expected str() or unicode() instance, but got int',) +u"\0" in vim.options:TypeError:('expected string without null bytes',) +"\0" in vim.options:TypeError:('expected string without null bytes',) +<<< Finished > Dictionary >> DictionaryConstructor vim.Dictionary("abcI"):ValueError:('expected sequence element of size 2, but got sequence of size 1',) @@ -599,6 +651,7 @@ d["a"] = FailingNumber():TypeError:('long() argument must be a string or a numbe >>> iter d.update(FailingMapping()):NotImplementedError:('keys',) d.update([FailingIterNext()]):NotImplementedError:('next',) +d.update([FailingIterNextN(1)]):NotImplementedError:('next N',) >>> Testing *Iter* using d.update(%s) d.update(FailingIter()):NotImplementedError:('iter',) d.update(FailingIterNext()):NotImplementedError:('next',) @@ -829,6 +882,14 @@ ll[1:100] = "abcJ":error:('list is locked',) l[:] = FailingIter():NotImplementedError:('iter',) l[:] = FailingIterNext():NotImplementedError:('next',) <<< Finished +nel[1:10:2] = "abcK":ValueError:('attempt to assign sequence of size greater then 2 to extended slice',) +('a', 'b', 'c', 'O') +nel[1:10:2] = "a":ValueError:('attempt to assign sequence of size 1 to extended slice of size 2',) +('a', 'b', 'c', 'O') +nel[1:1:-1] = "a":ValueError:('attempt to assign sequence of size greater then 0 to extended slice',) +('a', 'b', 'c', 'O') +nel[:] = FailingIterNextN(2):NotImplementedError:('next N',) +('a', 'b', 'c', 'O') >>> Testing StringToChars using l[:] = [{%s : 1}] l[:] = [{1 : 1}]:TypeError:('expected str() or unicode() instance, but got int',) l[:] = [{u"\0" : 1}]:TypeError:('expected string without null bytes',) @@ -1197,6 +1258,7 @@ Exe("throw 'def'"):error:('def',) vim.eval("Exe('throw ''ghi''')"):error:('ghi',) vim.eval("Exe('echoerr ''jkl''')"):error:('Vim(echoerr):jkl',) vim.eval("Exe('xxx_non_existent_command_xxx')"):error:('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',) +vim.eval("xxx_unknown_function_xxx()"):error:('Vim:E117: Unknown function: xxx_unknown_function_xxx',) vim.bindeval("Exe('xxx_non_existent_command_xxx')"):error:('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',) Caught KeyboardInterrupt Running :put diff --git a/src/testdir/test87.in b/src/testdir/test87.in index 899e4f3389..1515a906bb 100644 --- a/src/testdir/test87.in +++ b/src/testdir/test87.in @@ -33,6 +33,7 @@ STARTTEST py3 << EOF d=vim.bindeval('d') d['1']='asd' +d.update() # Must not do anything, including throwing errors d.update(b=[1, 2, f]) d.update((('-1', {'a': 1}),)) d.update({'0': -1}) @@ -128,6 +129,18 @@ EOF :py3 l=vim.bindeval('l') :py3 del l[-6:2] :$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 del l[::2] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 del l[3:0:-2] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 del l[2:4:-2] +:$put =string(l) :" :" Slice assignment to a list :let l = [0, 1, 2, 3] @@ -162,6 +175,26 @@ EOF :py3 l=vim.bindeval('l') :py3 l[0:0]=['h'] :$put =string(l) +:let l = range(8) +:py3 l=vim.bindeval('l') +:py3 l[2:6:2] = [10, 20] +:$put =string(l) +:let l = range(8) +:py3 l=vim.bindeval('l') +:py3 l[6:2:-2] = [10, 20] +:$put =string(l) +:let l = range(8) +:py3 l=vim.bindeval('l') +:py3 l[6:2] = () +:$put =string(l) +:let l = range(8) +:py3 l=vim.bindeval('l') +:py3 l[6:2:1] = () +:$put =string(l) +:let l = range(8) +:py3 l=vim.bindeval('l') +:py3 l[2:2:1] = () +:$put =string(l) :" :" Locked variables :let l = [0, 1, 2, 3] @@ -172,6 +205,36 @@ EOF :unlockvar! l :" :" Function calls +py3 << EOF +import sys +import re + +py33_type_error_pattern = re.compile('^__call__\(\) takes (\d+) positional argument but (\d+) were given$') + +def ee(expr, g=globals(), l=locals()): + cb = vim.current.buffer + try: + try: + exec(expr, g, l) + except Exception as e: + if sys.version_info >= (3, 3) and e.__class__ is AttributeError and str(e).find('has no attribute')>=0 and not str(e).startswith("'vim."): + cb.append(expr + ':' + repr((e.__class__, AttributeError(str(e)[str(e).rfind(" '") + 2:-1])))) + elif sys.version_info >= (3, 3) and e.__class__ is ImportError and str(e).find('No module named \'') >= 0: + cb.append(expr + ':' + repr((e.__class__, ImportError(str(e).replace("'", ''))))) + elif sys.version_info >= (3, 3) and e.__class__ is TypeError: + m = py33_type_error_pattern.search(str(e)) + if m: + msg = '__call__() takes exactly {0} positional argument ({1} given)'.format(m.group(1), m.group(2)) + cb.append(expr + ':' + repr((e.__class__, TypeError(msg)))) + else: + cb.append(expr + ':' + repr((e.__class__, e))) + else: + cb.append(expr + ':' + repr((e.__class__, e))) + else: + cb.append(expr + ':NOT FAILED') + except Exception as e: + cb.append(expr + '::' + repr((e.__class__, e))) +EOF :fun New(...) : return ['NewStart']+a:000+['NewEnd'] :endfun @@ -186,18 +249,10 @@ EOF :$put =string(l) :py3 l+=[l[0].name] :$put =string(l) -:try -: py3 l[1](1, 2, 3) -:catch -: $put =v:exception[:13] -:endtry +:py3 ee('l[1](1, 2, 3)') :py3 f=l[0] :delfunction New -:try -: py3 f(1, 2, 3) -:catch -: $put =v:exception[:13] -:endtry +:py3 ee('f(1, 2, 3)') :if has('float') : let l=[0.0] : py3 l=vim.bindeval('l') @@ -315,6 +370,7 @@ EOF :py3 l[0] = t.t > 8 # check if the background thread is working :py3 del time :py3 del threading +:py3 del t :$put =string(l) :" :" settrace @@ -340,6 +396,38 @@ EOF :py3 del trace_main :$put =string(l) :" +:" Slice +:py3 ll = vim.bindeval('[0, 1, 2, 3, 4, 5]') +:py3 l = ll[:4] +:$put =string(py3eval('l')) +:py3 l = ll[2:] +:$put =string(py3eval('l')) +:py3 l = ll[:-4] +:$put =string(py3eval('l')) +:py3 l = ll[-2:] +:$put =string(py3eval('l')) +:py3 l = ll[2:4] +:$put =string(py3eval('l')) +:py3 l = ll[4:2] +:$put =string(py3eval('l')) +:py3 l = ll[-4:-2] +:$put =string(py3eval('l')) +:py3 l = ll[-2:-4] +:$put =string(py3eval('l')) +:py3 l = ll[:] +:$put =string(py3eval('l')) +:py3 l = ll[0:6] +:$put =string(py3eval('l')) +:py3 l = ll[-10:10] +:$put =string(py3eval('l')) +:py3 l = ll[4:2:-1] +:$put =string(py3eval('l')) +:py3 l = ll[::2] +:$put =string(py3eval('l')) +:py3 l = ll[4:2:1] +:$put =string(py3eval('l')) +:py3 del l +:" :" Vars :let g:foo = 'bac' :let w:abc3 = 'def' @@ -416,6 +504,11 @@ EOF :py3 bopts1=vim.buffers[vim.bindeval("g:bufs")[2]].options :py3 bopts2=vim.buffers[vim.bindeval("g:bufs")[1]].options :py3 bopts3=vim.buffers[vim.bindeval("g:bufs")[0]].options +:$put ='wopts iters equal: '.py3eval('list(wopts1) == list(wopts2)') +:$put ='bopts iters equal: '.py3eval('list(bopts1) == list(bopts2)') +:py3 gset=set(iter(gopts1)) +:py3 wset=set(iter(wopts1)) +:py3 bset=set(iter(bopts1)) :set path=.,..,, :let lst=[] :let lst+=[['paste', 1, 0, 1, 2, 1, 1, 0 ]] @@ -446,6 +539,8 @@ EOF : py3 oval3=bool(oval3) : endif : put ='>>> '.oname +: $put =' g/w/b:'.py3eval('oname in gset').'/'.py3eval('oname in wset').'/'.py3eval('oname in bset') +: $put =' g/w/b (in):'.py3eval('oname in gopts1').'/'.py3eval('oname in wopts1').'/'.py3eval('oname in bopts1') : for v in ['gopts1', 'wopts1', 'bopts1'] : try : put =' p/'.v.': '.Ev('repr('.v.'['''.oname.'''])') @@ -829,33 +924,6 @@ EOF :fun D() :endfun py3 << EOF -import re - -py33_type_error_pattern = re.compile('^__call__\(\) takes (\d+) positional argument but (\d+) were given$') - -def ee(expr, g=globals(), l=locals()): - try: - try: - exec(expr, g, l) - except Exception as e: - if sys.version_info >= (3, 3) and e.__class__ is AttributeError and str(e).find('has no attribute')>=0 and not str(e).startswith("'vim."): - cb.append(expr + ':' + repr((e.__class__, AttributeError(str(e)[str(e).rfind(" '") + 2:-1])))) - elif sys.version_info >= (3, 3) and e.__class__ is ImportError and str(e).find('No module named \'') >= 0: - cb.append(expr + ':' + repr((e.__class__, ImportError(str(e).replace("'", ''))))) - elif sys.version_info >= (3, 3) and e.__class__ is TypeError: - m = py33_type_error_pattern.search(str(e)) - if m: - msg = '__call__() takes exactly {0} positional argument ({1} given)'.format(m.group(1), m.group(2)) - cb.append(expr + ':' + repr((e.__class__, TypeError(msg)))) - else: - cb.append(expr + ':' + repr((e.__class__, e))) - else: - cb.append(expr + ':' + repr((e.__class__, e))) - else: - cb.append(expr + ':NOT FAILED') - except Exception as e: - cb.append(expr + '::' + repr((e.__class__, e))) - d = vim.Dictionary() ned = vim.Dictionary(foo='bar', baz='abcD') dl = vim.Dictionary(a=1) @@ -863,6 +931,7 @@ dl.locked = True l = vim.List() ll = vim.List('abcE') ll.locked = True +nel = vim.List('abcO') f = vim.Function('string') fd = vim.Function('F') fdel = vim.Function('D') @@ -950,6 +1019,20 @@ class FailingIterNext(object): def __next__(self): raise NotImplementedError('next') +class FailingIterNextN(object): + def __init__(self, n): + self.n = n + + def __iter__(self): + return self + + def __next__(self): + if self.n: + self.n -= 1 + return 1 + else: + raise NotImplementedError('next N') + class FailingMappingKey(object): def __getitem__(self, item): raise NotImplementedError('getitem:mappingkey') @@ -1024,6 +1107,13 @@ ee('import failing_import') ee('import failing') vim.options['rtp'] = old_rtp del old_rtp +cb.append("> Options") +cb.append(">> OptionsItem") +ee('vim.options["abcQ"]') +ee('vim.options[""]') +stringtochars_test('vim.options[%s]') +cb.append(">> OptionsContains") +stringtochars_test('%s in vim.options') cb.append("> Dictionary") cb.append(">> DictionaryConstructor") ee('vim.Dictionary("abcI")') @@ -1054,6 +1144,7 @@ cb.append(">>> kwargs") cb.append(">>> iter") ee('d.update(FailingMapping())') ee('d.update([FailingIterNext()])') +ee('d.update([FailingIterNextN(1)])') iter_test('d.update(%s)') convertfrompyobject_test('d.update(%s)') stringtochars_test('d.update(((%s, 0),))') @@ -1076,6 +1167,14 @@ ee('l[1000] = 3') cb.append(">> ListAssSlice") ee('ll[1:100] = "abcJ"') iter_test('l[:] = %s') +ee('nel[1:10:2] = "abcK"') +cb.append(repr(tuple(nel))) +ee('nel[1:10:2] = "a"') +cb.append(repr(tuple(nel))) +ee('nel[1:1:-1] = "a"') +cb.append(repr(tuple(nel))) +ee('nel[:] = FailingIterNextN(2)') +cb.append(repr(tuple(nel))) convertfrompyobject_test('l[:] = [%s]') cb.append(">> ListConcatInPlace") iter_test('l.extend(%s)') @@ -1157,6 +1256,7 @@ del ned del dl del l del ll +del nel del f del fd del fdel @@ -1170,6 +1270,7 @@ del number_test del FailingTrue del FailingIter del FailingIterNext +del FailingIterNextN del FailingMapping del FailingMappingKey del FailingList @@ -1227,6 +1328,7 @@ ee('Exe("throw \'def\'")') ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")') ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")') ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")') +ee('vim.eval("xxx_unknown_function_xxx()")') ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")') del Exe EOF diff --git a/src/testdir/test87.ok b/src/testdir/test87.ok index 970818c997..d1ec84c6b8 100644 --- a/src/testdir/test87.ok +++ b/src/testdir/test87.ok @@ -41,6 +41,9 @@ None [2, 3] [2, 3] [2, 3] +[1, 3] +[0, 2] +[0, 1, 2, 3] ['a', 0, 1, 2, 3] [0, 'b', 2, 3] [0, 1, 'c'] @@ -49,12 +52,17 @@ None ['f', 2, 3] [0, 1, 'g', 2, 3] ['h'] +[0, 1, 10, 3, 20, 5, 6, 7] +[0, 1, 2, 3, 20, 5, 10, 7] +[0, 1, 2, 3, 4, 5, 6, 7] +[0, 1, 2, 3, 4, 5, 6, 7] +[0, 1, 2, 3, 4, 5, 6, 7] [0, 1, 2, 3] [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd'] [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}] [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}, 'New'] -Vim(py3):E725: -Vim(py3):E117: +l[1](1, 2, 3):(, error('Vim:E725: Calling dict function without Dictionary: DictNew',)) +f(1, 2, 3):(, error('Vim:E117: Unknown function: New',)) [0.0, 0.0] KeyError TypeError @@ -85,12 +93,30 @@ undefined_name: Vim(let):Trace vim: Vim(let):E859: [1] [1, 10, 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, 1] +[0, 1, 2, 3] +[2, 3, 4, 5] +[0, 1] +[4, 5] +[2, 3] +[] +[2, 3] +[] +[0, 1, 2, 3, 4, 5] +[0, 1, 2, 3, 4, 5] +[0, 1, 2, 3, 4, 5] +[4, 3] +[0, 2, 4] +[] Abc bac def bar jkl +wopts iters equal: 1 +bopts iters equal: 1 >>> paste + g/w/b:1/0/0 + g/w/b (in):1/0/0 p/gopts1: False p/wopts1! KeyError inv: 2! KeyError @@ -111,6 +137,8 @@ jkl W: 1:1 2:1 3:1 4:1 B: 1:1 2:1 3:1 4:1 >>> previewheight + g/w/b:1/0/0 + g/w/b (in):1/0/0 p/gopts1: 12 inv: 'a'! TypeError p/wopts1! KeyError @@ -132,6 +160,8 @@ jkl W: 1:5 2:5 3:5 4:5 B: 1:5 2:5 3:5 4:5 >>> operatorfunc + g/w/b:1/0/0 + g/w/b (in):1/0/0 p/gopts1: b'' inv: 2! TypeError p/wopts1! KeyError @@ -153,6 +183,8 @@ jkl W: 1:'A' 2:'A' 3:'A' 4:'A' B: 1:'A' 2:'A' 3:'A' 4:'A' >>> number + g/w/b:0/1/0 + g/w/b (in):0/1/0 p/gopts1! KeyError inv: 0! KeyError gopts1! KeyError @@ -171,6 +203,8 @@ jkl W: 1:1 2:1 3:0 4:0 B: 1:1 2:1 3:0 4:0 >>> numberwidth + g/w/b:0/1/0 + g/w/b (in):0/1/0 p/gopts1! KeyError inv: -100! KeyError gopts1! KeyError @@ -190,6 +224,8 @@ jkl W: 1:3 2:5 3:2 4:8 B: 1:3 2:5 3:2 4:8 >>> colorcolumn + g/w/b:0/1/0 + g/w/b (in):0/1/0 p/gopts1! KeyError inv: 'abc4'! KeyError gopts1! KeyError @@ -209,6 +245,8 @@ jkl W: 1:'+2' 2:'+3' 3:'+1' 4:'' B: 1:'+2' 2:'+3' 3:'+1' 4:'' >>> statusline + g/w/b:1/1/0 + g/w/b (in):1/1/0 p/gopts1: b'' inv: 0! TypeError p/wopts1: None @@ -226,6 +264,8 @@ jkl W: 1:'2' 2:'1' 3:'1' 4:'1' B: 1:'2' 2:'1' 3:'1' 4:'1' >>> autoindent + g/w/b:0/0/1 + g/w/b (in):0/0/1 p/gopts1! KeyError inv: 2! KeyError gopts1! KeyError @@ -244,6 +284,8 @@ jkl W: 1:0 2:1 3:0 4:1 B: 1:0 2:1 3:0 4:1 >>> shiftwidth + g/w/b:0/0/1 + g/w/b (in):0/0/1 p/gopts1! KeyError inv: 3! KeyError gopts1! KeyError @@ -262,6 +304,8 @@ jkl W: 1:0 2:2 3:8 4:1 B: 1:0 2:2 3:8 4:1 >>> omnifunc + g/w/b:0/0/1 + g/w/b (in):0/0/1 p/gopts1! KeyError inv: 1! KeyError gopts1! KeyError @@ -281,6 +325,8 @@ jkl W: 1:'A' 2:'B' 3:'' 4:'C' B: 1:'A' 2:'B' 3:'' 4:'C' >>> preserveindent + g/w/b:0/0/1 + g/w/b (in):0/0/1 p/gopts1! KeyError inv: 2! KeyError gopts1! KeyError @@ -299,6 +345,8 @@ jkl W: 1:0 2:1 3:0 4:1 B: 1:0 2:1 3:0 4:1 >>> path + g/w/b:1/0/1 + g/w/b (in):1/0/1 p/gopts1: b'.,..,,' inv: 0! TypeError p/wopts1! KeyError @@ -487,6 +535,21 @@ vim.foreach_rtp(int, 2):(, TypeError('foreach_rtp() takes exa import xxx_no_such_module_xxx:(, ImportError('No module named xxx_no_such_module_xxx',)) import failing_import:(, ImportError('No module named failing_import',)) import failing:(, NotImplementedError()) +> Options +>> OptionsItem +vim.options["abcQ"]:(, KeyError('abcQ',)) +vim.options[""]:(, ValueError('empty keys are not allowed',)) +>>> Testing StringToChars using vim.options[%s] +vim.options[1]:(, TypeError('expected bytes() or str() instance, but got int',)) +vim.options[b"\0"]:(, TypeError('expected bytes with no null',)) +vim.options["\0"]:(, TypeError('expected bytes with no null',)) +<<< Finished +>> OptionsContains +>>> Testing StringToChars using %s in vim.options +1 in vim.options:(, TypeError('expected bytes() or str() instance, but got int',)) +b"\0" in vim.options:(, TypeError('expected bytes with no null',)) +"\0" in vim.options:(, TypeError('expected bytes with no null',)) +<<< Finished > Dictionary >> DictionaryConstructor vim.Dictionary("abcI"):(, ValueError('expected sequence element of size 2, but got sequence of size 1',)) @@ -588,6 +651,7 @@ d["a"] = FailingNumber():(, NotImplementedError('in >>> iter d.update(FailingMapping()):(, NotImplementedError('keys',)) d.update([FailingIterNext()]):(, NotImplementedError('next',)) +d.update([FailingIterNextN(1)]):(, NotImplementedError('next N',)) >>> Testing *Iter* using d.update(%s) d.update(FailingIter()):(, NotImplementedError('iter',)) d.update(FailingIterNext()):(, NotImplementedError('next',)) @@ -818,6 +882,14 @@ ll[1:100] = "abcJ":(, error('list is locked',)) l[:] = FailingIter():(, NotImplementedError('iter',)) l[:] = FailingIterNext():(, NotImplementedError('next',)) <<< Finished +nel[1:10:2] = "abcK":(, ValueError('attempt to assign sequence of size greater then 2 to extended slice',)) +(b'a', b'b', b'c', b'O') +nel[1:10:2] = "a":(, ValueError('attempt to assign sequence of size 1 to extended slice of size 2',)) +(b'a', b'b', b'c', b'O') +nel[1:1:-1] = "a":(, ValueError('attempt to assign sequence of size greater then 0 to extended slice',)) +(b'a', b'b', b'c', b'O') +nel[:] = FailingIterNextN(2):(, NotImplementedError('next N',)) +(b'a', b'b', b'c', b'O') >>> Testing StringToChars using l[:] = [{%s : 1}] l[:] = [{1 : 1}]:(, TypeError('expected bytes() or str() instance, but got int',)) l[:] = [{b"\0" : 1}]:(, TypeError('expected bytes with no null',)) @@ -1186,6 +1258,7 @@ Exe("throw 'def'"):(, error('def',)) vim.eval("Exe('throw ''ghi''')"):(, error('ghi',)) vim.eval("Exe('echoerr ''jkl''')"):(, error('Vim(echoerr):jkl',)) vim.eval("Exe('xxx_non_existent_command_xxx')"):(, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',)) +vim.eval("xxx_unknown_function_xxx()"):(, error('Vim:E117: Unknown function: xxx_unknown_function_xxx',)) vim.bindeval("Exe('xxx_non_existent_command_xxx')"):(, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',)) Caught KeyboardInterrupt Running :put diff --git a/src/undo.c b/src/undo.c index 6b087aac2d..adc7e027f6 100644 --- a/src/undo.c +++ b/src/undo.c @@ -409,7 +409,7 @@ u_savecommon(top, bot, newbot, reload) { /* This happens when the FileChangedRO autocommand changes the * file in a way it becomes shorter. */ - EMSG(_("E834: Line count changed unexpectedly")); + EMSG(_("E881: Line count changed unexpectedly")); return FAIL; } #endif diff --git a/src/version.c b/src/version.c index 4db38b98a4..ba3a37a33b 100644 --- a/src/version.c +++ b/src/version.c @@ -753,6 +753,166 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 183, +/**/ + 182, +/**/ + 181, +/**/ + 180, +/**/ + 179, +/**/ + 178, +/**/ + 177, +/**/ + 176, +/**/ + 175, +/**/ + 174, +/**/ + 173, +/**/ + 172, +/**/ + 171, +/**/ + 170, +/**/ + 169, +/**/ + 168, +/**/ + 167, +/**/ + 166, +/**/ + 165, +/**/ + 164, +/**/ + 163, +/**/ + 162, +/**/ + 161, +/**/ + 160, +/**/ + 159, +/**/ + 158, +/**/ + 157, +/**/ + 156, +/**/ + 155, +/**/ + 154, +/**/ + 153, +/**/ + 152, +/**/ + 151, +/**/ + 150, +/**/ + 149, +/**/ + 148, +/**/ + 147, +/**/ + 146, +/**/ + 145, +/**/ + 144, +/**/ + 143, +/**/ + 142, +/**/ + 141, +/**/ + 140, +/**/ + 139, +/**/ + 138, +/**/ + 137, +/**/ + 136, +/**/ + 135, +/**/ + 134, +/**/ + 133, +/**/ + 132, +/**/ + 131, +/**/ + 130, +/**/ + 129, +/**/ + 128, +/**/ + 127, +/**/ + 126, +/**/ + 125, +/**/ + 124, +/**/ + 123, +/**/ + 122, +/**/ + 121, +/**/ + 120, +/**/ + 119, +/**/ + 118, +/**/ + 117, +/**/ + 116, +/**/ + 115, +/**/ + 114, +/**/ + 113, +/**/ + 112, +/**/ + 111, +/**/ + 110, +/**/ + 109, +/**/ + 108, +/**/ + 107, +/**/ + 106, +/**/ + 105, +/**/ + 104, /**/ 103, /**/ diff --git a/src/vim.h b/src/vim.h index b357b75b9b..245a44c8d2 100644 --- a/src/vim.h +++ b/src/vim.h @@ -2252,6 +2252,7 @@ typedef int VimClipboard; /* This is required for the prototypes. */ #define SOPT_BUF 0x20 /* Option has buffer-local value */ #define SOPT_UNSET 0x40 /* Option does not have local value set */ +/* Option types for various functions in option.c */ #define SREQ_GLOBAL 0 /* Request global option */ #define SREQ_WIN 1 /* Request window-local option */ #define SREQ_BUF 2 /* Request buffer-local option */ diff --git a/src/window.c b/src/window.c index b9de230950..a3314d976c 100644 --- a/src/window.c +++ b/src/window.c @@ -1221,8 +1221,8 @@ win_init(newp, oldp, flags) else copy_loclist(oldp, newp); #endif - if (oldp->w_localdir != NULL) - newp->w_localdir = vim_strsave(oldp->w_localdir); + newp->w_localdir = (oldp->w_localdir == NULL) + ? NULL : vim_strsave(oldp->w_localdir); /* copy tagstack and folds */ for (i = 0; i < oldp->w_tagstacklen; i++)